@contentstack/live-preview-utils
Version:
Contentstack provides the Live Preview SDK to establish a communication channel between the various Contentstack SDKs and your website, transmitting live changes to the preview pane.
220 lines (219 loc) • 8.71 kB
JavaScript
;
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/visualBuilder/utils/collabUtils.ts
var collabUtils_exports = {};
__export(collabUtils_exports, {
adjustPositionToViewport: () => adjustPositionToViewport,
filterOutInvalidMentions: () => filterOutInvalidMentions,
fixSvgXPath: () => fixSvgXPath,
formatDate: () => formatDate,
getCommentBody: () => getCommentBody,
getMessageWithDisplayName: () => getMessageWithDisplayName,
getThreadTitle: () => getThreadTitle,
getUserName: () => getUserName,
normalizePath: () => normalizePath,
positionTooltip: () => positionTooltip,
sanitizeData: () => sanitizeData,
validateCommentAndMentions: () => validateCommentAndMentions
});
module.exports = __toCommonJS(collabUtils_exports);
var import_constants = require("./constants.cjs");
var import_lodash_es = require("lodash-es");
var import_dompurify = __toESM(require("dompurify"), 1);
var import_dayjs = __toESM(require("dayjs"), 1);
var escapeRegExp = (string) => {
return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
};
var getThreadTitle = (commentCount) => {
if (commentCount === 0) return "Add New Comment";
return commentCount === 1 ? "1 Comment" : `${commentCount} Comments`;
};
var getUserName = (user) => {
return user.firstName && user.lastName ? `${user.firstName} ${user.lastName}` : user.firstName || user.lastName || user.email;
};
var validateCommentAndMentions = (comment, toUsers) => {
if (comment.length > import_constants.maxMessageLength) {
return `Limit exceeded. You can have a maximum length of ${import_constants.maxMessageLength} characters.`;
}
if (toUsers.length > import_constants.mentionLimit) {
return `Limit exceeded. You can tag a maximum of ${import_constants.mentionLimit} users.`;
}
return "";
};
var filterOutInvalidMentions = (message, toUsers) => {
const to_users_temp = toUsers.filter(
(user) => message.includes(user.display)
);
return {
toUsers: (0, import_lodash_es.uniqBy)(to_users_temp, "id")
};
};
var getMessageWithDisplayName = (comment, userState, profile) => {
if (!comment) return void 0;
let tempText = sanitizeData(comment.message).replace(/<[^>]*>/g, "");
comment.toUsers?.forEach((user) => {
const userPattern = new RegExp(`{{${user}}}`, "g");
const userData = userState.userMap[user];
const displayName = userData ? userData.display || getUserName(userData) : `unknown user`;
const replacement = profile === "html" ? `<b class="collab-thread-comment--message">@${displayName}</b>` : `@${displayName}`;
tempText = tempText.replace(userPattern, replacement);
});
return tempText;
};
var sanitizeData = (dirty) => {
return import_dompurify.default.sanitize(dirty, { USE_PROFILES: { html: true } });
};
var getCommentBody = (state) => {
let finalMessage = sanitizeData(state.message).replace(/[^\S\r\n]+/g, " ").replace(/ *\n */g, "\n").replace(/<[^>]*>/g, "").trim();
const comment = {
message: finalMessage,
toUsers: [],
images: [],
createdBy: state.createdBy,
author: state.author
};
const updateMentionToUID = (entity, result) => {
const displayName = entity.display;
const escapedDisplayName = escapeRegExp(`@${displayName}`);
const regexUser = new RegExp(escapedDisplayName, "g");
finalMessage = finalMessage.replace(regexUser, `{{${entity.id}}}`);
result.push(entity.id);
};
state.toUsers?.forEach((user) => updateMentionToUID(user, comment.toUsers));
comment.message = finalMessage;
return comment;
};
function normalizePath(path) {
if (path === "/") return path;
return path.endsWith("/") ? path.slice(0, -1) : path;
}
function fixSvgXPath(xpath) {
if (!xpath) return "";
return xpath.replace(/\/svg/g, "/*[name()='svg']");
}
function adjustPositionToViewport(position, options = {}) {
const { top, left } = position;
const viewportWidth = window.innerWidth;
const safeMargin = options.safeMargin ?? 16;
const topSafeMargin = options.topSafeMargin ?? 42;
const threadWidth = options.threadWidth ?? 16;
let adjustedLeft = left;
let adjustedTop = top;
if (adjustedLeft + threadWidth > viewportWidth - safeMargin) {
adjustedLeft = viewportWidth - safeMargin - threadWidth;
}
if (adjustedTop - window.scrollY < topSafeMargin) {
adjustedTop = window.scrollY + topSafeMargin;
}
return { top: adjustedTop, left: adjustedLeft };
}
function formatDate(dateString) {
if (!dateString) return "";
return (0, import_dayjs.default)(dateString).format("MMM DD, YYYY, hh:mm A");
}
var positionTooltip = (tooltipRef, targetRef, position, setActualPosition) => {
if (!tooltipRef.current || !targetRef.current) return;
const targetRect = targetRef.current.getBoundingClientRect();
const tooltipRect = tooltipRef.current.getBoundingClientRect();
const margin = 8;
const positions = {
bottom: {
top: targetRect.bottom + margin,
left: targetRect.left + (targetRect.width - tooltipRect.width) / 2
},
top: {
top: targetRect.top - tooltipRect.height - margin,
left: targetRect.left + (targetRect.width - tooltipRect.width) / 2
},
left: {
top: targetRect.top + (targetRect.height - tooltipRect.height) / 2,
left: targetRect.left - tooltipRect.width - margin
},
right: {
top: targetRect.top + (targetRect.height - tooltipRect.height) / 2,
left: targetRect.right + margin
}
};
let bestPosition = position;
let coords = positions[position];
const viewportWidth = window.innerWidth;
const viewportHeight = window.innerHeight;
const wouldBeOutsideViewport = {
bottom: coords.top + tooltipRect.height > viewportHeight,
top: coords.top < 0,
left: coords.left < 0,
right: coords.left + tooltipRect.width > viewportWidth
};
const horizontalOutOfBounds = coords.left < 0 || coords.left + tooltipRect.width > viewportWidth;
if (wouldBeOutsideViewport[position] || horizontalOutOfBounds) {
const positionPriority = ["bottom", "top", "right", "left"];
positionPriority.splice(positionPriority.indexOf(position), 1);
positionPriority.push(position);
for (const pos of positionPriority) {
const testCoords = positions[pos];
const isVisible = testCoords.top >= 0 && testCoords.top + tooltipRect.height <= viewportHeight && testCoords.left >= 0 && testCoords.left + tooltipRect.width <= viewportWidth;
if (isVisible) {
bestPosition = pos;
coords = testCoords;
break;
}
}
}
if (coords.left < 0) {
coords.left = margin;
} else if (coords.left + tooltipRect.width > viewportWidth) {
coords.left = viewportWidth - tooltipRect.width - margin;
}
if (coords.top < 0) {
coords.top = margin;
} else if (coords.top + tooltipRect.height > viewportHeight) {
coords.top = viewportHeight - tooltipRect.height - margin;
}
setActualPosition(bestPosition);
Object.assign(tooltipRef.current.style, {
top: `${coords.top}px`,
left: `${coords.left}px`
});
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
adjustPositionToViewport,
filterOutInvalidMentions,
fixSvgXPath,
formatDate,
getCommentBody,
getMessageWithDisplayName,
getThreadTitle,
getUserName,
normalizePath,
positionTooltip,
sanitizeData,
validateCommentAndMentions
});
//# sourceMappingURL=collabUtils.cjs.map