UNPKG

@limetech/lime-elements

Version:
114 lines (113 loc) 3.56 kB
/** * Extracts metadata from a ProseMirror document node * * This function traverses the entire document tree and collects information about * special elements like images and links. * * @param doc - The ProseMirror document node to extract metadata from * @returns A metadata object containing arrays of images and links found in the document */ export function getMetadataFromDoc(doc) { const metadata = { images: [], links: [] }; doc.descendants((node) => { if (isImageNode(node)) { metadata.images.push(extractImageMetadata(node)); } else if (isTextNodeWithMarks(node)) { for (const link of extractLinkMetadata(node)) metadata.links.push(link); } return true; }); return metadata; } function isImageNode(node) { return node.type.name === 'image' && !!node.attrs; } function extractImageMetadata(node) { return { src: node.attrs.src, state: node.attrs.state, fileInfoId: node.attrs.fileInfoId, }; } function isTextNodeWithMarks(node) { var _a; return node.isText && ((_a = node.marks) === null || _a === void 0 ? void 0 : _a.length) > 0; } function extractLinkMetadata(node) { return node.marks .filter((mark) => mark.type.name === 'link' && mark.attrs) .map((mark) => ({ href: mark.attrs.href, text: node.text, })); } /** * Determines if metadata has changed between two states * Handles duplicates correctly but is order-insensitive * * @param oldMetadata - The previous metadata state to compare against * @param newMetadata - The current metadata state * @returns True if there are any differences between the metadata objects, false otherwise */ export function hasMetadataChanged(oldMetadata, newMetadata) { return (hasDifferentLengths(oldMetadata, newMetadata) || hasDifferentLinks(oldMetadata.links, newMetadata.links) || hasDifferentImages(oldMetadata.images, newMetadata.images)); } function hasDifferentLengths(oldMetadata, newMetadata) { return (oldMetadata.images.length !== newMetadata.images.length || oldMetadata.links.length !== newMetadata.links.length); } function hasDifferentLinks(oldLinks, newLinks) { const oldLinkCounts = getLinkFrequencyMap(oldLinks); const newLinkCounts = getLinkFrequencyMap(newLinks); return !areFrequencyMapsEqual(oldLinkCounts, newLinkCounts); } function hasDifferentImages(oldImages, newImages) { const oldImageCounts = getImageFrequencyMap(oldImages); const newImageCounts = getImageFrequencyMap(newImages); return !areFrequencyMapsEqual(oldImageCounts, newImageCounts); } /** * Creates a frequency map for images based on their key properties * @param images */ function getImageFrequencyMap(images) { const countMap = new Map(); for (const image of images) { const key = `${image.fileInfoId}|${image.state}|${image.src}`; countMap.set(key, (countMap.get(key) || 0) + 1); } return countMap; } /** * Creates a frequency map for links based on their key properties * @param links */ function getLinkFrequencyMap(links) { const countMap = new Map(); for (const link of links) { const key = `${link.href}|${link.text}`; countMap.set(key, (countMap.get(key) || 0) + 1); } return countMap; } /** * Compares two frequency maps for equality * @param map1 * @param map2 */ function areFrequencyMapsEqual(map1, map2) { if (map1.size !== map2.size) { return false; } for (const [key, count] of map1.entries()) { if (map2.get(key) !== count) { return false; } } return true; } //# sourceMappingURL=metadata-utils.js.map