diff --git a/packages/super-editor/src/core/super-converter/exporter.js b/packages/super-editor/src/core/super-converter/exporter.js index 6c8d772dc5..f9b99b13e2 100644 --- a/packages/super-editor/src/core/super-converter/exporter.js +++ b/packages/super-editor/src/core/super-converter/exporter.js @@ -10,6 +10,7 @@ import { pixelsToEightPoints, pixelsToEmu, pixelsToTwips, + rgbToHex } from './helpers.js'; import { generateDocxRandomId } from '@helpers/generateDocxRandomId.js'; import { DEFAULT_DOCX_DEFS } from './exporter-docx-defs.js'; @@ -1117,6 +1118,9 @@ function translateMark(mark) { case 'color': let processedColor = attrs.color.replace(/^#/, '').replace(/;$/, ''); // Remove `#` and `;` if present + if (processedColor.startsWith('rgb')) { + processedColor = rgbToHex(processedColor); + } markElement.attributes['w:val'] = processedColor; break; diff --git a/packages/super-editor/src/core/super-converter/helpers.js b/packages/super-editor/src/core/super-converter/helpers.js index 25aaa1cc9e..72b1a82b25 100644 --- a/packages/super-editor/src/core/super-converter/helpers.js +++ b/packages/super-editor/src/core/super-converter/helpers.js @@ -118,6 +118,18 @@ function isValidHexColor(color) { } } +const componentToHex = (val) => { + const a = Number(val).toString(16); + return a.length === 1 ? '0' + a : a; +} + +const rgbToHex = (rgb) => { + return '#' + rgb + .match(/\d+/g) + .map(componentToHex) + .join(''); +} + export { inchesToTwips, twipsToInches, @@ -135,5 +147,6 @@ export { getArrayBufferFromUrl, getContentTypesFromXml, getHexColorFromDocxSystem, - isValidHexColor + isValidHexColor, + rgbToHex }; diff --git a/packages/super-editor/src/core/super-converter/v2/exporter/commentsExporter.js b/packages/super-editor/src/core/super-converter/v2/exporter/commentsExporter.js index 4dfd4a9a3f..7623d822ec 100644 --- a/packages/super-editor/src/core/super-converter/v2/exporter/commentsExporter.js +++ b/packages/super-editor/src/core/super-converter/v2/exporter/commentsExporter.js @@ -99,6 +99,7 @@ export const getCommentDefinition = (comment, commentId, allComments) => { 'w:initials': getInitials(comment.creatorName), 'w:done': comment.resolvedTime ? '1' : '0', 'w15:paraId': comment.commentParaId, + 'custom:internalId': comment.commentId || comment.internalId, }; // Add the w15:paraIdParent attribute if the comment has a parent @@ -165,6 +166,8 @@ export const updateCommentsXml = (commentDefs = [], commentsXml) => { 'w:author': commentDef.attributes['w:author'], 'w:date': commentDef.attributes['w:date'], 'w:initials': commentDef.attributes['w:initials'], + 'custom:internalId': commentDef.attributes['custom:internalId'], + 'xmlns:custom': 'http://schemas.openxmlformats.org/wordprocessingml/2006/main', }; }); @@ -193,8 +196,7 @@ export const updateCommentsExtendedXml = (comments = [], commentsExtendedXml) => const parentId = comment.parentCommentId; if (parentId) { const parentComment = comments.find((c) => c.commentId === parentId); - const parentParaId = parentComment.commentParaId; - attributes['w15:paraIdParent'] = parentParaId; + attributes['w15:paraIdParent'] = parentComment.commentParaId; } return { diff --git a/packages/super-editor/src/core/super-converter/v2/importer/documentCommentsImporter.js b/packages/super-editor/src/core/super-converter/v2/importer/documentCommentsImporter.js index ae4896342d..88c6885f82 100644 --- a/packages/super-editor/src/core/super-converter/v2/importer/documentCommentsImporter.js +++ b/packages/super-editor/src/core/super-converter/v2/importer/documentCommentsImporter.js @@ -13,8 +13,8 @@ import { defaultNodeListHandler } from "./docxImporter"; * @returns {Array} The parsed comments */ export function importCommentData({ docx }) { - const nodeListHandler = defaultNodeListHandler() - const comments = docx['word/comments.xml']; + const nodeListHandler = defaultNodeListHandler(); + const comments = docx['word/comments.xml']; if (!comments) return; const { elements } = comments; @@ -29,6 +29,7 @@ export function importCommentData({ docx }) { const authorEmail = attributes['w:email']; const initials = attributes['w:initials']; const createdDate = attributes['w:date']; + const internalId = attributes['custom:internalId']; const date = new Date(createdDate); const unixTimestampMs = date.getTime(); @@ -44,7 +45,7 @@ export function importCommentData({ docx }) { const paraId = attrs['w14:paraId']; return { - commentId: uuidv4(), + commentId: internalId || uuidv4(), importedId, creatorName: authorName, creatorEmail: authorEmail, @@ -57,7 +58,7 @@ export function importCommentData({ docx }) { const extendedComments = generateCommentsWithExtendedData({ docx, comments: extractedComments }); return extendedComments; -}; +} /** * Import the commentsExtended.xml file to get the extended comment details @@ -88,9 +89,8 @@ const generateCommentsWithExtendedData = ({ docx, comments }) => { const newComment = { ...comment, - commentId: superdocCommentId || uuidv4(), isDone, - parentCommentId: parentComment?.id, + parentCommentId: parentComment?.commentId, }; return newComment; }); @@ -107,6 +107,5 @@ const getExtendedDetails = (commentEx) => { const paraId = attributes['w15:paraId']; const isDone = attributes['w15:done'] === '1' ? true : false; const paraIdParent = attributes['w15:paraIdParent']; - const superdocCommentId = attributes['w:rsid']; - return { paraId, isDone, paraIdParent, superdocCommentId }; + return { paraId, isDone, paraIdParent }; }; diff --git a/packages/super-editor/src/extensions/comment/comments-helpers.js b/packages/super-editor/src/extensions/comment/comments-helpers.js index 1f22bcf135..7abac374f8 100644 --- a/packages/super-editor/src/extensions/comment/comments-helpers.js +++ b/packages/super-editor/src/extensions/comment/comments-helpers.js @@ -90,12 +90,13 @@ export const prepareCommentsForExport = (doc, tr, schema, comments = []) => { const parentId = commentId; if (parentId) { const childComments = comments - .filter((c) => c.parentCommentId == parentId || c.parentCommentId == parentId) + .filter((c) => c.parentCommentId === parentId) .sort((a, b) => a.createdTime - b.createdTime); childComments.forEach((c) => { const childMark = getPreparedComment(c); const childStartNode = schema.nodes.commentRangeStart.create(childMark); + seen.add(c.commentId); startNodes.push({ pos: pos, node: childStartNode, @@ -296,4 +297,4 @@ export const getHighlightColor = ({ activeThreadId, threadId, isInternal, editor const color = isInternal ? pluginState.internalColor : pluginState.externalColor; const alpha = activeThreadId == threadId ? '44' : '22'; return `${color}${alpha}`; -} \ No newline at end of file +}