roosterjs-content-model-plugins 9.36.0 → 9.37.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/lib/autoFormat/list/getListTypeStyle.js +3 -2
  2. package/lib/autoFormat/list/getListTypeStyle.js.map +1 -1
  3. package/lib/edit/EditPlugin.d.ts +8 -0
  4. package/lib/edit/EditPlugin.js +22 -6
  5. package/lib/edit/EditPlugin.js.map +1 -1
  6. package/lib/edit/keyboardDelete.js +5 -10
  7. package/lib/edit/keyboardDelete.js.map +1 -1
  8. package/lib/edit/keyboardInput.js +3 -1
  9. package/lib/edit/keyboardInput.js.map +1 -1
  10. package/lib/imageEdit/ImageEditPlugin.d.ts +1 -1
  11. package/lib/imageEdit/ImageEditPlugin.js +5 -4
  12. package/lib/imageEdit/ImageEditPlugin.js.map +1 -1
  13. package/lib/imageEdit/types/ImageEditOptions.d.ts +1 -1
  14. package/lib/imageEdit/types/ImageEditOptions.js.map +1 -1
  15. package/lib/imageEdit/utils/imageEditUtils.d.ts +13 -1
  16. package/lib/imageEdit/utils/imageEditUtils.js +23 -2
  17. package/lib/imageEdit/utils/imageEditUtils.js.map +1 -1
  18. package/lib/imageEdit/utils/updateWrapper.d.ts +1 -1
  19. package/lib/imageEdit/utils/updateWrapper.js +10 -7
  20. package/lib/imageEdit/utils/updateWrapper.js.map +1 -1
  21. package/lib/index.d.ts +1 -0
  22. package/lib/index.js +3 -1
  23. package/lib/index.js.map +1 -1
  24. package/lib/paste/WordDesktop/processPastedContentFromWordDesktop.js +4 -1
  25. package/lib/paste/WordDesktop/processPastedContentFromWordDesktop.js.map +1 -1
  26. package/lib/paste/WordDesktop/processWordLists.js +2 -2
  27. package/lib/paste/WordDesktop/processWordLists.js.map +1 -1
  28. package/lib/tableEdit/editors/features/TableMover.js +3 -29
  29. package/lib/tableEdit/editors/features/TableMover.js.map +1 -1
  30. package/lib/touch/TouchPlugin.d.ts +32 -0
  31. package/lib/touch/TouchPlugin.js +214 -0
  32. package/lib/touch/TouchPlugin.js.map +1 -0
  33. package/lib/utils/getNodePositionFromEvent.d.ts +5 -0
  34. package/lib/utils/getNodePositionFromEvent.js +34 -0
  35. package/lib/utils/getNodePositionFromEvent.js.map +1 -0
  36. package/lib-amd/autoFormat/list/getListTypeStyle.js +3 -2
  37. package/lib-amd/autoFormat/list/getListTypeStyle.js.map +1 -1
  38. package/lib-amd/edit/EditPlugin.d.ts +8 -0
  39. package/lib-amd/edit/EditPlugin.js +22 -6
  40. package/lib-amd/edit/EditPlugin.js.map +1 -1
  41. package/lib-amd/edit/keyboardDelete.js +5 -10
  42. package/lib-amd/edit/keyboardDelete.js.map +1 -1
  43. package/lib-amd/edit/keyboardInput.js +3 -1
  44. package/lib-amd/edit/keyboardInput.js.map +1 -1
  45. package/lib-amd/imageEdit/ImageEditPlugin.d.ts +1 -1
  46. package/lib-amd/imageEdit/ImageEditPlugin.js +5 -4
  47. package/lib-amd/imageEdit/ImageEditPlugin.js.map +1 -1
  48. package/lib-amd/imageEdit/types/ImageEditOptions.d.ts +1 -1
  49. package/lib-amd/imageEdit/types/ImageEditOptions.js.map +1 -1
  50. package/lib-amd/imageEdit/utils/imageEditUtils.d.ts +13 -1
  51. package/lib-amd/imageEdit/utils/imageEditUtils.js +23 -2
  52. package/lib-amd/imageEdit/utils/imageEditUtils.js.map +1 -1
  53. package/lib-amd/imageEdit/utils/updateWrapper.d.ts +1 -1
  54. package/lib-amd/imageEdit/utils/updateWrapper.js +10 -7
  55. package/lib-amd/imageEdit/utils/updateWrapper.js.map +1 -1
  56. package/lib-amd/index.d.ts +1 -0
  57. package/lib-amd/index.js +3 -2
  58. package/lib-amd/index.js.map +1 -1
  59. package/lib-amd/paste/WordDesktop/processPastedContentFromWordDesktop.js +4 -1
  60. package/lib-amd/paste/WordDesktop/processPastedContentFromWordDesktop.js.map +1 -1
  61. package/lib-amd/paste/WordDesktop/processWordLists.js +2 -2
  62. package/lib-amd/paste/WordDesktop/processWordLists.js.map +1 -1
  63. package/lib-amd/tableEdit/editors/features/TableMover.js +3 -30
  64. package/lib-amd/tableEdit/editors/features/TableMover.js.map +1 -1
  65. package/lib-amd/touch/TouchPlugin.d.ts +32 -0
  66. package/lib-amd/touch/TouchPlugin.js +215 -0
  67. package/lib-amd/touch/TouchPlugin.js.map +1 -0
  68. package/lib-amd/utils/getNodePositionFromEvent.d.ts +5 -0
  69. package/lib-amd/utils/getNodePositionFromEvent.js +36 -0
  70. package/lib-amd/utils/getNodePositionFromEvent.js.map +1 -0
  71. package/lib-mjs/autoFormat/list/getListTypeStyle.js +3 -2
  72. package/lib-mjs/autoFormat/list/getListTypeStyle.js.map +1 -1
  73. package/lib-mjs/edit/EditPlugin.d.ts +8 -0
  74. package/lib-mjs/edit/EditPlugin.js +22 -6
  75. package/lib-mjs/edit/EditPlugin.js.map +1 -1
  76. package/lib-mjs/edit/keyboardDelete.js +5 -10
  77. package/lib-mjs/edit/keyboardDelete.js.map +1 -1
  78. package/lib-mjs/edit/keyboardInput.js +3 -1
  79. package/lib-mjs/edit/keyboardInput.js.map +1 -1
  80. package/lib-mjs/imageEdit/ImageEditPlugin.d.ts +1 -1
  81. package/lib-mjs/imageEdit/ImageEditPlugin.js +5 -4
  82. package/lib-mjs/imageEdit/ImageEditPlugin.js.map +1 -1
  83. package/lib-mjs/imageEdit/types/ImageEditOptions.d.ts +1 -1
  84. package/lib-mjs/imageEdit/types/ImageEditOptions.js.map +1 -1
  85. package/lib-mjs/imageEdit/utils/imageEditUtils.d.ts +13 -1
  86. package/lib-mjs/imageEdit/utils/imageEditUtils.js +21 -1
  87. package/lib-mjs/imageEdit/utils/imageEditUtils.js.map +1 -1
  88. package/lib-mjs/imageEdit/utils/updateWrapper.d.ts +1 -1
  89. package/lib-mjs/imageEdit/utils/updateWrapper.js +11 -8
  90. package/lib-mjs/imageEdit/utils/updateWrapper.js.map +1 -1
  91. package/lib-mjs/index.d.ts +1 -0
  92. package/lib-mjs/index.js +1 -0
  93. package/lib-mjs/index.js.map +1 -1
  94. package/lib-mjs/paste/WordDesktop/processPastedContentFromWordDesktop.js +4 -1
  95. package/lib-mjs/paste/WordDesktop/processPastedContentFromWordDesktop.js.map +1 -1
  96. package/lib-mjs/paste/WordDesktop/processWordLists.js +2 -2
  97. package/lib-mjs/paste/WordDesktop/processWordLists.js.map +1 -1
  98. package/lib-mjs/tableEdit/editors/features/TableMover.js +1 -27
  99. package/lib-mjs/tableEdit/editors/features/TableMover.js.map +1 -1
  100. package/lib-mjs/touch/TouchPlugin.d.ts +32 -0
  101. package/lib-mjs/touch/TouchPlugin.js +211 -0
  102. package/lib-mjs/touch/TouchPlugin.js.map +1 -0
  103. package/lib-mjs/utils/getNodePositionFromEvent.d.ts +5 -0
  104. package/lib-mjs/utils/getNodePositionFromEvent.js +30 -0
  105. package/lib-mjs/utils/getNodePositionFromEvent.js.map +1 -0
  106. package/package.json +5 -5
@@ -156,10 +156,10 @@ function getLastNotEmptyBlock(listParent) {
156
156
  return undefined;
157
157
  }
158
158
  function wordListPaddingParser(format, element) {
159
- if (element.style.marginLeft && element.style.marginLeft != '0in') {
159
+ if (element.style.marginLeft && parseInt(element.style.marginLeft) != 0) {
160
160
  format.paddingLeft = '0px';
161
161
  }
162
- if (element.style.marginRight && element.style.marginRight != '0in') {
162
+ if (element.style.marginRight && parseInt(element.style.marginRight) != 0) {
163
163
  format.paddingRight = '0px';
164
164
  }
165
165
  }
@@ -1 +1 @@
1
- {"version":3,"file":"processWordLists.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/paste/WordDesktop/processWordLists.ts"],"names":[],"mappings":"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","sourcesContent":["import { getStyles } from '../utils/getStyles';\nimport { processAsListItem, setupListFormat } from '../utils/customListUtils';\nimport {\n getListStyleTypeFromString,\n isElementOfType,\n isEmpty,\n isNodeOfType,\n} from 'roosterjs-content-model-dom';\nimport type { WordMetadata } from './WordMetadata';\nimport type {\n ContentModelBlockGroup,\n ContentModelListItem,\n ContentModelListItemFormat,\n ContentModelListItemLevelFormat,\n ContentModelListLevel,\n DomToModelContext,\n DomToModelListFormat,\n} from 'roosterjs-content-model-types';\n\n/** Word list metadata style name */\nconst MSO_LIST = 'mso-list';\nconst MSO_LIST_IGNORE = 'ignore';\nconst WORD_FIRST_LIST = 'l0';\nconst TEMPLATE_VALUE_REGEX = /%[0-9a-zA-Z]+/g;\nconst BULLET_METADATA = 'bullet';\n\ninterface WordDesktopListFormat extends DomToModelListFormat {\n wordLevel?: number | '';\n wordList?: string;\n wordKnownLevels?: Map<string, ContentModelListLevel[]>;\n}\n\ninterface WordListFormat extends ContentModelListItemFormat {\n wordList?: string;\n}\n\n/**\n * @internal\n * @param styles\n * @param group\n * @param element\n * @param context\n * @returns\n */\nexport function processWordList(\n styles: Record<string, string>,\n group: ContentModelBlockGroup,\n element: HTMLElement,\n context: DomToModelContext,\n metadata: Map<string, WordMetadata>\n) {\n const listFormat = context.listFormat as WordDesktopListFormat;\n if (!listFormat.wordKnownLevels) {\n listFormat.wordKnownLevels = new Map<string, ContentModelListLevel[]>();\n }\n const wordListStyle = styles[MSO_LIST] || '';\n\n // If the element contains Ignore style, do not process it,\n // Usually this element contains the fake bullet used in Word Desktop.\n if (wordListStyle.toLowerCase() === MSO_LIST_IGNORE) {\n return true;\n }\n\n const [lNumber, level] = wordListStyle.split(' ');\n // Try get the list metadata from word, which follows this format: l1 level1 lfo2\n // If we are able to get the level property means we can process this element to be a list\n listFormat.wordLevel = level && parseInt(level.substr('level'.length));\n listFormat.wordList = lNumber || WORD_FIRST_LIST;\n\n if (listFormat.levels.length == 0) {\n listFormat.levels =\n (listFormat.wordList && listFormat.wordKnownLevels.get(listFormat.wordList)) || [];\n }\n\n if (wordListStyle && group && typeof listFormat.wordLevel === 'number') {\n const { wordLevel, wordList } = listFormat;\n // Retrieve the Fake bullet on the element and also the list type\n const listMetadata = metadata.get(`${lNumber}:${level}`);\n const listType =\n listMetadata?.['mso-level-number-format']?.toLowerCase() != BULLET_METADATA\n ? 'OL'\n : 'UL';\n\n // Create the new level of the list item and parse the format\n setupListFormat(listType, element, context, wordLevel, listFormat, group, [\n wordListPaddingParser,\n ]);\n (listFormat.levels[listFormat.levels.length - 1]\n .format as WordListFormat).wordList = wordList;\n\n const bullet = getBulletFromMetadata(listMetadata, listType);\n const listFormatMetadata = bullet\n ? {\n unorderedStyleType: listType == 'UL' ? bullet : undefined,\n orderedStyleType: listType == 'OL' ? bullet : undefined,\n }\n : undefined;\n\n processAsListItem(\n context,\n element,\n group,\n listFormatMetadata,\n getBulletElement(element),\n listItem => {\n if (listType == 'OL') {\n setStartNumber(listItem, context, listMetadata, element);\n }\n }\n );\n\n if (\n listFormat.levels.length > 0 &&\n listFormat.wordKnownLevels.get(wordList) != listFormat.levels\n ) {\n listFormat.wordKnownLevels.set(wordList, [...listFormat.levels]);\n }\n return true;\n }\n\n return false;\n}\n\nfunction getBulletFromMetadata(listMetadata: WordMetadata | undefined, listType: 'OL' | 'UL') {\n const templateType = listMetadata?.['mso-level-number-format'] || 'decimal';\n let templateFinal: string;\n\n if (listMetadata?.['mso-level-text']) {\n let templateValue: string = '';\n switch (templateType) {\n case 'alpha-upper':\n templateValue = 'UpperAlpha';\n break;\n case 'alpha-lower':\n templateValue = 'LowerAlpha';\n break;\n case 'roman-lower':\n templateValue = 'LowerRoman';\n break;\n case 'roman-upper':\n templateValue = 'UpperRoman';\n break;\n default:\n templateValue = 'Number';\n break;\n }\n const template = (listMetadata['mso-level-text'] || '')\n .replace('\\\\', '')\n .replace('\"', '')\n .replace(TEMPLATE_VALUE_REGEX, '${' + templateValue + '}');\n\n templateFinal = '\"' + template + ' \"';\n } else {\n switch (templateType) {\n case 'alpha-lower':\n templateFinal = 'lower-alpha';\n break;\n case 'roman-lower':\n templateFinal = 'lower-roman';\n break;\n case 'roman-upper':\n templateFinal = 'upper-roman';\n break;\n default:\n templateFinal = 'decimal';\n break;\n }\n }\n\n return getListStyleTypeFromString(listType, templateFinal);\n}\n\nfunction setStartNumber(\n listItem: ContentModelListItem,\n context: DomToModelContext,\n listMetadata: WordMetadata | undefined,\n element: HTMLElement\n) {\n const {\n listParent,\n wordList,\n wordKnownLevels,\n wordLevel,\n levels,\n } = context.listFormat as WordDesktopListFormat;\n\n const block = getLastNotEmptyBlock(listParent);\n if (\n (block?.blockType != 'BlockGroup' ||\n block.blockGroupType != 'ListItem' ||\n (wordLevel &&\n (block.levels[wordLevel]?.format as WordListFormat)?.wordList != wordList)) &&\n wordList\n ) {\n const start = listMetadata?.['mso-level-start-at']\n ? parseInt(listMetadata['mso-level-start-at'])\n : NaN;\n const knownLevel = wordKnownLevels?.get(wordList) || [];\n\n if (start != undefined && !isNaN(start) && knownLevel.length != levels.length) {\n listItem.levels[listItem.levels.length - 1].format.startNumberOverride = start;\n } else if (\n isElementOfType(element, 'li') &&\n isNodeOfType(element.parentElement, 'ELEMENT_NODE') &&\n isElementOfType(element.parentElement, 'ol') &&\n element.parentElement.firstElementChild == element &&\n knownLevel.length != element.parentElement.start\n ) {\n listItem.levels[listItem.levels.length - 1].format.startNumberOverride =\n element.parentElement.start;\n }\n }\n}\n\nfunction getLastNotEmptyBlock(listParent: ContentModelBlockGroup | undefined) {\n for (let index = (listParent?.blocks.length || 0) - 1; index > 0; index--) {\n const result = listParent?.blocks[index];\n if (result && !isEmpty(result)) {\n return result;\n }\n }\n\n return undefined;\n}\n\nfunction wordListPaddingParser(\n format: ContentModelListItemLevelFormat,\n element: HTMLElement\n): void {\n if (element.style.marginLeft && element.style.marginLeft != '0in') {\n format.paddingLeft = '0px';\n }\n if (element.style.marginRight && element.style.marginRight != '0in') {\n format.paddingRight = '0px';\n }\n}\n/**\n * Get the bullet element from word list item.\n * The first element of the list contains the bullet element, which contains the mso-list:ignore style.\n * @example\n * <p class=MsoListParagraphCxSpFirst style='text-indent:-18.0pt;mso-list:l0 level1 lfo1'>\n * <![if !supportLists]>\n * <span lang=EN-US style='mso-fareast-font-family:Aptos;mso-fareast-theme-font:minor-latin; mso-bidi-font-family:Aptos;mso-bidi-theme-font:minor-latin;color:#C00000; mso-ansi-language:EN-US'>\n * <span style='mso-list:Ignore'> <-- This is the bullet element\n * 1.\n * <span style='font:7.0pt \"Times New Roman\"'>\n * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\n * </span>\n * </span>\n * </span>\n * <![endif]>\n * <span lang=EN-US style='color:#C00000; mso-ansi-language:EN-US'>\n * Content in list<o:p></o:p>\n * </span>\n * </p>\n * @returns\n */\nfunction getBulletElement(element: HTMLElement): HTMLElement | undefined {\n const firstChild = element.firstElementChild;\n let isBulletElement = false;\n\n if (firstChild) {\n for (let i = 0; i < firstChild.childNodes.length; i++) {\n const child = firstChild.childNodes[i];\n if (isNodeOfType(child, 'ELEMENT_NODE')) {\n const styles = getStyles(child);\n const wordListStyle = styles[MSO_LIST] || '';\n\n if (wordListStyle.toLowerCase() === MSO_LIST_IGNORE) {\n isBulletElement = true;\n break;\n }\n }\n }\n }\n\n return firstChild && isBulletElement ? (firstChild as HTMLElement) : undefined;\n}\n"]}
1
+ {"version":3,"file":"processWordLists.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/paste/WordDesktop/processWordLists.ts"],"names":[],"mappings":";;;;AAAA,gDAA+C;AAC/C,4DAA8E;AAC9E,2EAKqC;AAYrC,oCAAoC;AACpC,IAAM,QAAQ,GAAG,UAAU,CAAC;AAC5B,IAAM,eAAe,GAAG,QAAQ,CAAC;AACjC,IAAM,eAAe,GAAG,IAAI,CAAC;AAC7B,IAAM,oBAAoB,GAAG,gBAAgB,CAAC;AAC9C,IAAM,eAAe,GAAG,QAAQ,CAAC;AAYjC;;;;;;;GAOG;AACH,SAAgB,eAAe,CAC3B,MAA8B,EAC9B,KAA6B,EAC7B,OAAoB,EACpB,OAA0B,EAC1B,QAAmC;;IAEnC,IAAM,UAAU,GAAG,OAAO,CAAC,UAAmC,CAAC;IAC/D,IAAI,CAAC,UAAU,CAAC,eAAe,EAAE;QAC7B,UAAU,CAAC,eAAe,GAAG,IAAI,GAAG,EAAmC,CAAC;KAC3E;IACD,IAAM,aAAa,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;IAE7C,2DAA2D;IAC3D,sEAAsE;IACtE,IAAI,aAAa,CAAC,WAAW,EAAE,KAAK,eAAe,EAAE;QACjD,OAAO,IAAI,CAAC;KACf;IAEK,IAAA,KAAA,oBAAmB,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,IAAA,EAA1C,OAAO,QAAA,EAAE,KAAK,QAA4B,CAAC;IAClD,iFAAiF;IACjF,0FAA0F;IAC1F,UAAU,CAAC,SAAS,GAAG,KAAK,IAAI,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IACvE,UAAU,CAAC,QAAQ,GAAG,OAAO,IAAI,eAAe,CAAC;IAEjD,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,EAAE;QAC/B,UAAU,CAAC,MAAM;YACb,CAAC,UAAU,CAAC,QAAQ,IAAI,UAAU,CAAC,eAAe,CAAC,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;KAC1F;IAED,IAAI,aAAa,IAAI,KAAK,IAAI,OAAO,UAAU,CAAC,SAAS,KAAK,QAAQ,EAAE;QAC5D,IAAA,SAAS,GAAe,UAAU,UAAzB,EAAE,QAAQ,GAAK,UAAU,SAAf,CAAgB;QAC3C,iEAAiE;QACjE,IAAM,cAAY,GAAG,QAAQ,CAAC,GAAG,CAAI,OAAO,SAAI,KAAO,CAAC,CAAC;QACzD,IAAM,UAAQ,GACV,CAAA,MAAA,cAAY,aAAZ,cAAY,uBAAZ,cAAY,CAAG,yBAAyB,CAAC,0CAAE,WAAW,EAAE,KAAI,eAAe;YACvE,CAAC,CAAC,IAAI;YACN,CAAC,CAAC,IAAI,CAAC;QAEf,6DAA6D;QAC7D,IAAA,iCAAe,EAAC,UAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,KAAK,EAAE;YACtE,qBAAqB;SACxB,CAAC,CAAC;QACF,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;aAC3C,MAAyB,CAAC,QAAQ,GAAG,QAAQ,CAAC;QAEnD,IAAM,MAAM,GAAG,qBAAqB,CAAC,cAAY,EAAE,UAAQ,CAAC,CAAC;QAC7D,IAAM,kBAAkB,GAAG,MAAM;YAC7B,CAAC,CAAC;gBACI,kBAAkB,EAAE,UAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;gBACzD,gBAAgB,EAAE,UAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;aAC1D;YACH,CAAC,CAAC,SAAS,CAAC;QAEhB,IAAA,mCAAiB,EACb,OAAO,EACP,OAAO,EACP,KAAK,EACL,kBAAkB,EAClB,gBAAgB,CAAC,OAAO,CAAC,EACzB,UAAA,QAAQ;YACJ,IAAI,UAAQ,IAAI,IAAI,EAAE;gBAClB,cAAc,CAAC,QAAQ,EAAE,OAAO,EAAE,cAAY,EAAE,OAAO,CAAC,CAAC;aAC5D;QACL,CAAC,CACJ,CAAC;QAEF,IACI,UAAU,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC;YAC5B,UAAU,CAAC,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,UAAU,CAAC,MAAM,EAC/D;YACE,UAAU,CAAC,eAAe,CAAC,GAAG,CAAC,QAAQ,qDAAM,UAAU,CAAC,MAAM,UAAE,CAAC;SACpE;QACD,OAAO,IAAI,CAAC;KACf;IAED,OAAO,KAAK,CAAC;AACjB,CAAC;AA7ED,0CA6EC;AAED,SAAS,qBAAqB,CAAC,YAAsC,EAAE,QAAqB;IACxF,IAAM,YAAY,GAAG,CAAA,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAG,yBAAyB,CAAC,KAAI,SAAS,CAAC;IAC5E,IAAI,aAAqB,CAAC;IAE1B,IAAI,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAG,gBAAgB,CAAC,EAAE;QAClC,IAAI,aAAa,GAAW,EAAE,CAAC;QAC/B,QAAQ,YAAY,EAAE;YAClB,KAAK,aAAa;gBACd,aAAa,GAAG,YAAY,CAAC;gBAC7B,MAAM;YACV,KAAK,aAAa;gBACd,aAAa,GAAG,YAAY,CAAC;gBAC7B,MAAM;YACV,KAAK,aAAa;gBACd,aAAa,GAAG,YAAY,CAAC;gBAC7B,MAAM;YACV,KAAK,aAAa;gBACd,aAAa,GAAG,YAAY,CAAC;gBAC7B,MAAM;YACV;gBACI,aAAa,GAAG,QAAQ,CAAC;gBACzB,MAAM;SACb;QACD,IAAM,QAAQ,GAAG,CAAC,YAAY,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC;aAClD,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;aACjB,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC;aAChB,OAAO,CAAC,oBAAoB,EAAE,IAAI,GAAG,aAAa,GAAG,GAAG,CAAC,CAAC;QAE/D,aAAa,GAAG,GAAG,GAAG,QAAQ,GAAG,IAAI,CAAC;KACzC;SAAM;QACH,QAAQ,YAAY,EAAE;YAClB,KAAK,aAAa;gBACd,aAAa,GAAG,aAAa,CAAC;gBAC9B,MAAM;YACV,KAAK,aAAa;gBACd,aAAa,GAAG,aAAa,CAAC;gBAC9B,MAAM;YACV,KAAK,aAAa;gBACd,aAAa,GAAG,aAAa,CAAC;gBAC9B,MAAM;YACV;gBACI,aAAa,GAAG,SAAS,CAAC;gBAC1B,MAAM;SACb;KACJ;IAED,OAAO,IAAA,wDAA0B,EAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;AAC/D,CAAC;AAED,SAAS,cAAc,CACnB,QAA8B,EAC9B,OAA0B,EAC1B,YAAsC,EACtC,OAAoB;;IAEd,IAAA,KAMF,OAAO,CAAC,UAAmC,EAL3C,UAAU,gBAAA,EACV,QAAQ,cAAA,EACR,eAAe,qBAAA,EACf,SAAS,eAAA,EACT,MAAM,YACqC,CAAC;IAEhD,IAAM,KAAK,GAAG,oBAAoB,CAAC,UAAU,CAAC,CAAC;IAC/C,IACI,CAAC,CAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,SAAS,KAAI,YAAY;QAC7B,KAAK,CAAC,cAAc,IAAI,UAAU;QAClC,CAAC,SAAS;YACN,CAAA,MAAC,MAAA,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,0CAAE,MAAyB,0CAAE,QAAQ,KAAI,QAAQ,CAAC,CAAC;QACnF,QAAQ,EACV;QACE,IAAM,KAAK,GAAG,CAAA,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAG,oBAAoB,CAAC;YAC9C,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC,oBAAoB,CAAC,CAAC;YAC9C,CAAC,CAAC,GAAG,CAAC;QACV,IAAM,UAAU,GAAG,CAAA,eAAe,aAAf,eAAe,uBAAf,eAAe,CAAE,GAAG,CAAC,QAAQ,CAAC,KAAI,EAAE,CAAC;QAExD,IAAI,KAAK,IAAI,SAAS,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,UAAU,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE;YAC3E,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,mBAAmB,GAAG,KAAK,CAAC;SAClF;aAAM,IACH,IAAA,6CAAe,EAAC,OAAO,EAAE,IAAI,CAAC;YAC9B,IAAA,0CAAY,EAAC,OAAO,CAAC,aAAa,EAAE,cAAc,CAAC;YACnD,IAAA,6CAAe,EAAC,OAAO,CAAC,aAAa,EAAE,IAAI,CAAC;YAC5C,OAAO,CAAC,aAAa,CAAC,iBAAiB,IAAI,OAAO;YAClD,UAAU,CAAC,MAAM,IAAI,OAAO,CAAC,aAAa,CAAC,KAAK,EAClD;YACE,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,mBAAmB;gBAClE,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC;SACnC;KACJ;AACL,CAAC;AAED,SAAS,oBAAoB,CAAC,UAA8C;IACxE,KAAK,IAAI,KAAK,GAAG,CAAC,CAAA,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,MAAM,CAAC,MAAM,KAAI,CAAC,CAAC,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,EAAE,KAAK,EAAE,EAAE;QACvE,IAAM,MAAM,GAAG,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,MAAM,CAAC,KAAK,CAAC,CAAC;QACzC,IAAI,MAAM,IAAI,CAAC,IAAA,qCAAO,EAAC,MAAM,CAAC,EAAE;YAC5B,OAAO,MAAM,CAAC;SACjB;KACJ;IAED,OAAO,SAAS,CAAC;AACrB,CAAC;AAED,SAAS,qBAAqB,CAC1B,MAAuC,EACvC,OAAoB;IAEpB,IAAI,OAAO,CAAC,KAAK,CAAC,UAAU,IAAI,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE;QACrE,MAAM,CAAC,WAAW,GAAG,KAAK,CAAC;KAC9B;IACD,IAAI,OAAO,CAAC,KAAK,CAAC,WAAW,IAAI,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE;QACvE,MAAM,CAAC,YAAY,GAAG,KAAK,CAAC;KAC/B;AACL,CAAC;AACD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,SAAS,gBAAgB,CAAC,OAAoB;IAC1C,IAAM,UAAU,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAC7C,IAAI,eAAe,GAAG,KAAK,CAAC;IAE5B,IAAI,UAAU,EAAE;QACZ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YACnD,IAAM,KAAK,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YACvC,IAAI,IAAA,0CAAY,EAAC,KAAK,EAAE,cAAc,CAAC,EAAE;gBACrC,IAAM,MAAM,GAAG,IAAA,qBAAS,EAAC,KAAK,CAAC,CAAC;gBAChC,IAAM,aAAa,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;gBAE7C,IAAI,aAAa,CAAC,WAAW,EAAE,KAAK,eAAe,EAAE;oBACjD,eAAe,GAAG,IAAI,CAAC;oBACvB,MAAM;iBACT;aACJ;SACJ;KACJ;IAED,OAAO,UAAU,IAAI,eAAe,CAAC,CAAC,CAAE,UAA0B,CAAC,CAAC,CAAC,SAAS,CAAC;AACnF,CAAC","sourcesContent":["import { getStyles } from '../utils/getStyles';\nimport { processAsListItem, setupListFormat } from '../utils/customListUtils';\nimport {\n getListStyleTypeFromString,\n isElementOfType,\n isEmpty,\n isNodeOfType,\n} from 'roosterjs-content-model-dom';\nimport type { WordMetadata } from './WordMetadata';\nimport type {\n ContentModelBlockGroup,\n ContentModelListItem,\n ContentModelListItemFormat,\n ContentModelListItemLevelFormat,\n ContentModelListLevel,\n DomToModelContext,\n DomToModelListFormat,\n} from 'roosterjs-content-model-types';\n\n/** Word list metadata style name */\nconst MSO_LIST = 'mso-list';\nconst MSO_LIST_IGNORE = 'ignore';\nconst WORD_FIRST_LIST = 'l0';\nconst TEMPLATE_VALUE_REGEX = /%[0-9a-zA-Z]+/g;\nconst BULLET_METADATA = 'bullet';\n\ninterface WordDesktopListFormat extends DomToModelListFormat {\n wordLevel?: number | '';\n wordList?: string;\n wordKnownLevels?: Map<string, ContentModelListLevel[]>;\n}\n\ninterface WordListFormat extends ContentModelListItemFormat {\n wordList?: string;\n}\n\n/**\n * @internal\n * @param styles\n * @param group\n * @param element\n * @param context\n * @returns\n */\nexport function processWordList(\n styles: Record<string, string>,\n group: ContentModelBlockGroup,\n element: HTMLElement,\n context: DomToModelContext,\n metadata: Map<string, WordMetadata>\n) {\n const listFormat = context.listFormat as WordDesktopListFormat;\n if (!listFormat.wordKnownLevels) {\n listFormat.wordKnownLevels = new Map<string, ContentModelListLevel[]>();\n }\n const wordListStyle = styles[MSO_LIST] || '';\n\n // If the element contains Ignore style, do not process it,\n // Usually this element contains the fake bullet used in Word Desktop.\n if (wordListStyle.toLowerCase() === MSO_LIST_IGNORE) {\n return true;\n }\n\n const [lNumber, level] = wordListStyle.split(' ');\n // Try get the list metadata from word, which follows this format: l1 level1 lfo2\n // If we are able to get the level property means we can process this element to be a list\n listFormat.wordLevel = level && parseInt(level.substr('level'.length));\n listFormat.wordList = lNumber || WORD_FIRST_LIST;\n\n if (listFormat.levels.length == 0) {\n listFormat.levels =\n (listFormat.wordList && listFormat.wordKnownLevels.get(listFormat.wordList)) || [];\n }\n\n if (wordListStyle && group && typeof listFormat.wordLevel === 'number') {\n const { wordLevel, wordList } = listFormat;\n // Retrieve the Fake bullet on the element and also the list type\n const listMetadata = metadata.get(`${lNumber}:${level}`);\n const listType =\n listMetadata?.['mso-level-number-format']?.toLowerCase() != BULLET_METADATA\n ? 'OL'\n : 'UL';\n\n // Create the new level of the list item and parse the format\n setupListFormat(listType, element, context, wordLevel, listFormat, group, [\n wordListPaddingParser,\n ]);\n (listFormat.levels[listFormat.levels.length - 1]\n .format as WordListFormat).wordList = wordList;\n\n const bullet = getBulletFromMetadata(listMetadata, listType);\n const listFormatMetadata = bullet\n ? {\n unorderedStyleType: listType == 'UL' ? bullet : undefined,\n orderedStyleType: listType == 'OL' ? bullet : undefined,\n }\n : undefined;\n\n processAsListItem(\n context,\n element,\n group,\n listFormatMetadata,\n getBulletElement(element),\n listItem => {\n if (listType == 'OL') {\n setStartNumber(listItem, context, listMetadata, element);\n }\n }\n );\n\n if (\n listFormat.levels.length > 0 &&\n listFormat.wordKnownLevels.get(wordList) != listFormat.levels\n ) {\n listFormat.wordKnownLevels.set(wordList, [...listFormat.levels]);\n }\n return true;\n }\n\n return false;\n}\n\nfunction getBulletFromMetadata(listMetadata: WordMetadata | undefined, listType: 'OL' | 'UL') {\n const templateType = listMetadata?.['mso-level-number-format'] || 'decimal';\n let templateFinal: string;\n\n if (listMetadata?.['mso-level-text']) {\n let templateValue: string = '';\n switch (templateType) {\n case 'alpha-upper':\n templateValue = 'UpperAlpha';\n break;\n case 'alpha-lower':\n templateValue = 'LowerAlpha';\n break;\n case 'roman-lower':\n templateValue = 'LowerRoman';\n break;\n case 'roman-upper':\n templateValue = 'UpperRoman';\n break;\n default:\n templateValue = 'Number';\n break;\n }\n const template = (listMetadata['mso-level-text'] || '')\n .replace('\\\\', '')\n .replace('\"', '')\n .replace(TEMPLATE_VALUE_REGEX, '${' + templateValue + '}');\n\n templateFinal = '\"' + template + ' \"';\n } else {\n switch (templateType) {\n case 'alpha-lower':\n templateFinal = 'lower-alpha';\n break;\n case 'roman-lower':\n templateFinal = 'lower-roman';\n break;\n case 'roman-upper':\n templateFinal = 'upper-roman';\n break;\n default:\n templateFinal = 'decimal';\n break;\n }\n }\n\n return getListStyleTypeFromString(listType, templateFinal);\n}\n\nfunction setStartNumber(\n listItem: ContentModelListItem,\n context: DomToModelContext,\n listMetadata: WordMetadata | undefined,\n element: HTMLElement\n) {\n const {\n listParent,\n wordList,\n wordKnownLevels,\n wordLevel,\n levels,\n } = context.listFormat as WordDesktopListFormat;\n\n const block = getLastNotEmptyBlock(listParent);\n if (\n (block?.blockType != 'BlockGroup' ||\n block.blockGroupType != 'ListItem' ||\n (wordLevel &&\n (block.levels[wordLevel]?.format as WordListFormat)?.wordList != wordList)) &&\n wordList\n ) {\n const start = listMetadata?.['mso-level-start-at']\n ? parseInt(listMetadata['mso-level-start-at'])\n : NaN;\n const knownLevel = wordKnownLevels?.get(wordList) || [];\n\n if (start != undefined && !isNaN(start) && knownLevel.length != levels.length) {\n listItem.levels[listItem.levels.length - 1].format.startNumberOverride = start;\n } else if (\n isElementOfType(element, 'li') &&\n isNodeOfType(element.parentElement, 'ELEMENT_NODE') &&\n isElementOfType(element.parentElement, 'ol') &&\n element.parentElement.firstElementChild == element &&\n knownLevel.length != element.parentElement.start\n ) {\n listItem.levels[listItem.levels.length - 1].format.startNumberOverride =\n element.parentElement.start;\n }\n }\n}\n\nfunction getLastNotEmptyBlock(listParent: ContentModelBlockGroup | undefined) {\n for (let index = (listParent?.blocks.length || 0) - 1; index > 0; index--) {\n const result = listParent?.blocks[index];\n if (result && !isEmpty(result)) {\n return result;\n }\n }\n\n return undefined;\n}\n\nfunction wordListPaddingParser(\n format: ContentModelListItemLevelFormat,\n element: HTMLElement\n): void {\n if (element.style.marginLeft && parseInt(element.style.marginLeft) != 0) {\n format.paddingLeft = '0px';\n }\n if (element.style.marginRight && parseInt(element.style.marginRight) != 0) {\n format.paddingRight = '0px';\n }\n}\n/**\n * Get the bullet element from word list item.\n * The first element of the list contains the bullet element, which contains the mso-list:ignore style.\n * @example\n * <p class=MsoListParagraphCxSpFirst style='text-indent:-18.0pt;mso-list:l0 level1 lfo1'>\n * <![if !supportLists]>\n * <span lang=EN-US style='mso-fareast-font-family:Aptos;mso-fareast-theme-font:minor-latin; mso-bidi-font-family:Aptos;mso-bidi-theme-font:minor-latin;color:#C00000; mso-ansi-language:EN-US'>\n * <span style='mso-list:Ignore'> <-- This is the bullet element\n * 1.\n * <span style='font:7.0pt \"Times New Roman\"'>\n * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\n * </span>\n * </span>\n * </span>\n * <![endif]>\n * <span lang=EN-US style='color:#C00000; mso-ansi-language:EN-US'>\n * Content in list<o:p></o:p>\n * </span>\n * </p>\n * @returns\n */\nfunction getBulletElement(element: HTMLElement): HTMLElement | undefined {\n const firstChild = element.firstElementChild;\n let isBulletElement = false;\n\n if (firstChild) {\n for (let i = 0; i < firstChild.childNodes.length; i++) {\n const child = firstChild.childNodes[i];\n if (isNodeOfType(child, 'ELEMENT_NODE')) {\n const styles = getStyles(child);\n const wordListStyle = styles[MSO_LIST] || '';\n\n if (wordListStyle.toLowerCase() === MSO_LIST_IGNORE) {\n isBulletElement = true;\n break;\n }\n }\n }\n }\n\n return firstChild && isBulletElement ? (firstChild as HTMLElement) : undefined;\n}\n"]}
@@ -7,6 +7,7 @@ var DragAndDropHelper_1 = require("../../../pluginUtils/DragAndDrop/DragAndDropH
7
7
  var roosterjs_content_model_api_1 = require("roosterjs-content-model-api");
8
8
  var getTableFromContentModel_1 = require("../utils/getTableFromContentModel");
9
9
  var roosterjs_content_model_dom_1 = require("roosterjs-content-model-dom");
10
+ var getNodePositionFromEvent_1 = require("../../../utils/getNodePositionFromEvent");
10
11
  var TABLE_MOVER_LENGTH = 12;
11
12
  /**
12
13
  * @internal
@@ -91,33 +92,6 @@ function setTableMoverCursor(editor, state, type) {
91
92
  var _a;
92
93
  editor === null || editor === void 0 ? void 0 : editor.setEditorStyle(TABLE_MOVER_STYLE_KEY, state ? (_a = 'cursor: ' + type) !== null && _a !== void 0 ? _a : 'move' : null);
93
94
  }
94
- // Get insertion point from coordinate.
95
- function getNodePositionFromEvent(editor, x, y) {
96
- var doc = editor.getDocument();
97
- var domHelper = editor.getDOMHelper();
98
- if (doc.caretRangeFromPoint) {
99
- // Chrome, Edge, Safari, Opera
100
- var range = doc.caretRangeFromPoint(x, y);
101
- if (range && domHelper.isNodeInEditor(range.startContainer)) {
102
- return { node: range.startContainer, offset: range.startOffset };
103
- }
104
- }
105
- if ('caretPositionFromPoint' in doc) {
106
- // Firefox
107
- var pos = doc.caretPositionFromPoint(x, y);
108
- if (pos && domHelper.isNodeInEditor(pos.offsetNode)) {
109
- return { node: pos.offsetNode, offset: pos.offset };
110
- }
111
- }
112
- if (doc.elementFromPoint) {
113
- // Fallback
114
- var element = doc.elementFromPoint(x, y);
115
- if (element && domHelper.isNodeInEditor(element)) {
116
- return { node: element, offset: 0 };
117
- }
118
- }
119
- return null;
120
- }
121
95
  /**
122
96
  * @internal
123
97
  * Exported for testing
@@ -160,7 +134,7 @@ function onDragging(context, event, initValue) {
160
134
  // Move table outline rectangle
161
135
  tableRect.style.top = event.clientY + TABLE_MOVER_LENGTH + "px";
162
136
  tableRect.style.left = event.clientX + TABLE_MOVER_LENGTH + "px";
163
- var pos = getNodePositionFromEvent(editor, event.clientX, event.clientY);
137
+ var pos = (0, getNodePositionFromEvent_1.getNodePositionFromEvent)(editor, event.clientX, event.clientY);
164
138
  if (pos) {
165
139
  var range = editor.getDocument().createRange();
166
140
  range.setStart(pos.node, pos.offset);
@@ -200,7 +174,7 @@ function onDragEnd(context, event, initValue) {
200
174
  }
201
175
  var insertionSuccess_1 = false;
202
176
  // Get position to insert table
203
- var insertPosition = getNodePositionFromEvent(editor, event.clientX, event.clientY);
177
+ var insertPosition = (0, getNodePositionFromEvent_1.getNodePositionFromEvent)(editor, event.clientX, event.clientY);
204
178
  if (insertPosition) {
205
179
  // Move table to new position
206
180
  (0, roosterjs_content_model_api_1.formatInsertPointWithContentModel)(editor, insertPosition, function (model, context, ip) {
@@ -1 +1 @@
1
- {"version":3,"file":"TableMover.js","sourceRoot":"","sources":["../../../../../../packages/roosterjs-content-model-plugins/lib/tableEdit/editors/features/TableMover.ts"],"names":[],"mappings":"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","sourcesContent":["import { createElement } from '../../../pluginUtils/CreateElement/createElement';\nimport { DragAndDropHelper } from '../../../pluginUtils/DragAndDrop/DragAndDropHelper';\nimport { formatInsertPointWithContentModel } from 'roosterjs-content-model-api';\nimport { getCMTableFromTable } from '../utils/getTableFromContentModel';\nimport type { TableEditFeature } from './TableEditFeature';\nimport type { OnTableEditorCreatedCallback } from '../../OnTableEditorCreatedCallback';\nimport type { DragAndDropHandler } from '../../../pluginUtils/DragAndDrop/DragAndDropHandler';\nimport {\n cloneModel,\n createContentModelDocument,\n createSelectionMarker,\n getFirstSelectedTable,\n isNodeOfType,\n mergeModel,\n mutateBlock,\n normalizeRect,\n setParagraphNotImplicit,\n setSelection,\n} from 'roosterjs-content-model-dom';\nimport type {\n DOMInsertPoint,\n DOMSelection,\n IEditor,\n ReadonlyContentModelTable,\n Rect,\n ShallowMutableContentModelDocument,\n} from 'roosterjs-content-model-types';\n\nconst TABLE_MOVER_LENGTH = 12;\n/**\n * @internal\n */\nexport const TABLE_MOVER_ID = '_Table_Mover';\nconst TABLE_MOVER_STYLE_KEY = '_TableMoverCursorStyle';\n\n/**\n * @internal\n * Allows user to move table to another position\n * Contains the function to select whole table\n */\nexport function createTableMover(\n table: HTMLTableElement,\n editor: IEditor,\n isRTL: boolean,\n onFinishDragging: (table: HTMLTableElement) => void,\n onStart: () => void,\n onEnd: (disposeHandler: boolean) => void,\n contentDiv?: EventTarget | null,\n anchorContainer?: HTMLElement,\n onTableEditorCreated?: OnTableEditorCreatedCallback,\n disableMovement?: boolean\n): TableEditFeature | null {\n const rect = normalizeRect(table.getBoundingClientRect());\n\n if (!isTableTopVisible(editor, rect, contentDiv as Node)) {\n return null;\n }\n\n const zoomScale = editor.getDOMHelper().calculateZoomScale();\n const document = table.ownerDocument;\n const createElementData = {\n tag: 'div',\n style: 'position: fixed; cursor: move; user-select: none; border: 1px solid #808080',\n };\n\n const div = createElement(createElementData, document) as HTMLDivElement;\n\n div.id = TABLE_MOVER_ID;\n div.style.width = `${TABLE_MOVER_LENGTH}px`;\n div.style.height = `${TABLE_MOVER_LENGTH}px`;\n\n (anchorContainer || document.body).appendChild(div);\n\n const context: TableMoverContext = {\n table,\n zoomScale,\n rect,\n isRTL,\n editor,\n div,\n onFinishDragging,\n onStart,\n onEnd,\n disableMovement,\n };\n\n setDivPosition(context, div);\n\n const featureHandler = new TableMoverFeature(\n div,\n context,\n () => {},\n disableMovement\n ? { onDragEnd }\n : {\n onDragStart,\n onDragging,\n onDragEnd,\n },\n context.zoomScale,\n onTableEditorCreated,\n editor.getEnvironment().isMobileOrTablet\n );\n\n return { node: table, div, featureHandler };\n}\n\n/**\n * @internal\n * Exported for testing\n */\nexport interface TableMoverContext {\n table: HTMLTableElement;\n zoomScale: number;\n rect: Rect | null;\n isRTL: boolean;\n editor: IEditor;\n div: HTMLElement;\n onFinishDragging: (table: HTMLTableElement) => void;\n onStart: () => void;\n onEnd: (disposeHandler: boolean) => void;\n disableMovement?: boolean;\n}\n\n/**\n * @internal\n * Exported for testing\n */\nexport interface TableMoverInitValue {\n cmTable: ReadonlyContentModelTable | undefined;\n initialSelection: DOMSelection | null;\n tableRect: HTMLDivElement;\n}\n\nclass TableMoverFeature extends DragAndDropHelper<TableMoverContext, TableMoverInitValue> {\n private disposer: undefined | (() => void);\n\n constructor(\n div: HTMLElement,\n context: TableMoverContext,\n onSubmit: (\n context: TableMoverContext,\n trigger: HTMLElement,\n container?: HTMLElement\n ) => void,\n handler: DragAndDropHandler<TableMoverContext, TableMoverInitValue>,\n zoomScale: number,\n onTableEditorCreated?: OnTableEditorCreatedCallback,\n forceMobile?: boolean | undefined\n ) {\n super(div, context, onSubmit, handler, zoomScale, forceMobile);\n this.disposer = onTableEditorCreated?.('TableMover', div);\n }\n\n dispose(): void {\n this.disposer?.();\n this.disposer = undefined;\n super.dispose();\n }\n}\n\nfunction setDivPosition(context: TableMoverContext, trigger: HTMLElement) {\n const { rect } = context;\n if (rect) {\n trigger.style.top = `${rect.top - TABLE_MOVER_LENGTH}px`;\n trigger.style.left = `${rect.left - TABLE_MOVER_LENGTH - 2}px`;\n }\n}\n\nfunction isTableTopVisible(editor: IEditor, rect: Rect | null, contentDiv?: Node | null): boolean {\n const visibleViewport = editor.getVisibleViewport();\n if (isNodeOfType(contentDiv, 'ELEMENT_NODE') && visibleViewport && rect) {\n const containerRect = normalizeRect(contentDiv.getBoundingClientRect());\n\n return !!containerRect && containerRect.top <= rect.top && visibleViewport.top <= rect.top;\n }\n\n return true;\n}\n\nfunction setTableMoverCursor(editor: IEditor, state: boolean, type?: 'move' | 'copy') {\n editor?.setEditorStyle(TABLE_MOVER_STYLE_KEY, state ? 'cursor: ' + type ?? 'move' : null);\n}\n\n// Get insertion point from coordinate.\nfunction getNodePositionFromEvent(editor: IEditor, x: number, y: number): DOMInsertPoint | null {\n const doc = editor.getDocument();\n const domHelper = editor.getDOMHelper();\n\n if (doc.caretRangeFromPoint) {\n // Chrome, Edge, Safari, Opera\n const range = doc.caretRangeFromPoint(x, y);\n if (range && domHelper.isNodeInEditor(range.startContainer)) {\n return { node: range.startContainer, offset: range.startOffset };\n }\n }\n\n if ('caretPositionFromPoint' in doc) {\n // Firefox\n const pos = (doc as any).caretPositionFromPoint(x, y);\n if (pos && domHelper.isNodeInEditor(pos.offsetNode)) {\n return { node: pos.offsetNode, offset: pos.offset };\n }\n }\n\n if (doc.elementFromPoint) {\n // Fallback\n const element = doc.elementFromPoint(x, y);\n if (element && domHelper.isNodeInEditor(element)) {\n return { node: element, offset: 0 };\n }\n }\n\n return null;\n}\n\n/**\n * @internal\n * Exported for testing\n */\nexport function onDragStart(context: TableMoverContext): TableMoverInitValue {\n context.onStart();\n\n const { editor, table, div } = context;\n\n setTableMoverCursor(editor, true, 'move');\n\n // Create table outline rectangle\n const trect = table.getBoundingClientRect();\n const createElementData = {\n tag: 'div',\n style: 'position: fixed; user-select: none; border: 1px solid #808080',\n };\n const tableRect = createElement(createElementData, document) as HTMLDivElement;\n tableRect.style.width = `${trect.width}px`;\n tableRect.style.height = `${trect.height}px`;\n tableRect.style.top = `${trect.top}px`;\n tableRect.style.left = `${trect.left}px`;\n div.parentNode?.appendChild(tableRect);\n\n // Get drag start selection\n const initialSelection = editor.getDOMSelection();\n\n // Get Table block in content model\n const cmTable = getCMTableFromTable(editor, table);\n\n return {\n cmTable,\n initialSelection,\n tableRect,\n };\n}\n\n/**\n * @internal\n * Exported for testing\n */\nexport function onDragging(\n context: TableMoverContext,\n event: MouseEvent,\n initValue: TableMoverInitValue\n) {\n const { tableRect } = initValue;\n const { editor } = context;\n\n // Move table outline rectangle\n tableRect.style.top = `${event.clientY + TABLE_MOVER_LENGTH}px`;\n tableRect.style.left = `${event.clientX + TABLE_MOVER_LENGTH}px`;\n\n const pos = getNodePositionFromEvent(editor, event.clientX, event.clientY);\n if (pos) {\n const range = editor.getDocument().createRange();\n range.setStart(pos.node, pos.offset);\n range.collapse(true);\n\n editor.setDOMSelection({ type: 'range', range, isReverted: false });\n return true;\n }\n return false;\n}\n\n/**\n * @internal\n * Exported for testing\n */\nexport function onDragEnd(\n context: TableMoverContext,\n event: MouseEvent,\n initValue: TableMoverInitValue | undefined\n) {\n const { editor, table, onFinishDragging: selectWholeTable, disableMovement } = context;\n const element = event.target;\n\n // Remove table outline rectangle\n initValue?.tableRect.remove();\n\n // Reset cursor\n setTableMoverCursor(editor, false);\n\n if (element == context.div) {\n // Table mover was only clicked, select whole table and do not dismiss the handler element.\n selectWholeTable(table);\n context.onEnd(false /* disposeHandler */);\n return true;\n } else {\n // Check if table was dragged on itself, element is not in editor, or movement is disabled\n if (\n table.contains(element as Node) ||\n !editor.getDOMHelper().isNodeInEditor(element as Node) ||\n disableMovement\n ) {\n editor.setDOMSelection(initValue?.initialSelection ?? null);\n context.onEnd(true /* disposeHandler */);\n return false;\n }\n\n let insertionSuccess: boolean = false;\n\n // Get position to insert table\n const insertPosition = getNodePositionFromEvent(editor, event.clientX, event.clientY);\n if (insertPosition) {\n // Move table to new position\n formatInsertPointWithContentModel(\n editor,\n insertPosition,\n (model, context, ip) => {\n // Remove old table\n const [oldTable, path] = getFirstSelectedTable(model);\n if (oldTable) {\n const index = path[0].blocks.indexOf(oldTable);\n mutateBlock(path[0]).blocks.splice(index, 1);\n }\n\n if (ip && initValue?.cmTable) {\n // Insert new table\n const doc: ShallowMutableContentModelDocument = createContentModelDocument();\n doc.blocks.push(oldTable ?? mutateBlock(initValue.cmTable));\n insertionSuccess = !!mergeModel(model, cloneModel(doc), context, {\n mergeFormat: 'none',\n insertPosition: ip,\n });\n\n if (insertionSuccess) {\n // After mergeModel, the new table should be selected\n const finalTable = getFirstSelectedTable(model)[0] ?? initValue.cmTable;\n if (finalTable) {\n // Add selection marker to the first cell of the table\n const firstCell = finalTable.rows[0].cells[0];\n const markerParagraph = firstCell?.blocks[0];\n\n if (markerParagraph?.blockType == 'Paragraph') {\n const marker = createSelectionMarker(model.format);\n\n mutateBlock(markerParagraph).segments.unshift(marker);\n setParagraphNotImplicit(markerParagraph);\n setSelection(model, marker);\n }\n }\n }\n return insertionSuccess;\n }\n },\n {\n // Select first cell of the old table\n selectionOverride: {\n type: 'table',\n firstColumn: 0,\n firstRow: 0,\n lastColumn: 0,\n lastRow: 0,\n table: table,\n },\n apiName: 'TableMover',\n }\n );\n } else {\n // No movement, restore initial selection\n editor.setDOMSelection(initValue?.initialSelection ?? null);\n }\n context.onEnd(true /* disposeHandler */);\n return insertionSuccess;\n }\n}\n"]}
1
+ {"version":3,"file":"TableMover.js","sourceRoot":"","sources":["../../../../../../packages/roosterjs-content-model-plugins/lib/tableEdit/editors/features/TableMover.ts"],"names":[],"mappings":"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","sourcesContent":["import { createElement } from '../../../pluginUtils/CreateElement/createElement';\nimport { DragAndDropHelper } from '../../../pluginUtils/DragAndDrop/DragAndDropHelper';\nimport { formatInsertPointWithContentModel } from 'roosterjs-content-model-api';\nimport { getCMTableFromTable } from '../utils/getTableFromContentModel';\nimport type { TableEditFeature } from './TableEditFeature';\nimport type { OnTableEditorCreatedCallback } from '../../OnTableEditorCreatedCallback';\nimport type { DragAndDropHandler } from '../../../pluginUtils/DragAndDrop/DragAndDropHandler';\nimport {\n cloneModel,\n createContentModelDocument,\n createSelectionMarker,\n getFirstSelectedTable,\n isNodeOfType,\n mergeModel,\n mutateBlock,\n normalizeRect,\n setParagraphNotImplicit,\n setSelection,\n} from 'roosterjs-content-model-dom';\nimport type {\n DOMSelection,\n IEditor,\n ReadonlyContentModelTable,\n Rect,\n ShallowMutableContentModelDocument,\n} from 'roosterjs-content-model-types';\nimport { getNodePositionFromEvent } from '../../../utils/getNodePositionFromEvent';\n\nconst TABLE_MOVER_LENGTH = 12;\n/**\n * @internal\n */\nexport const TABLE_MOVER_ID = '_Table_Mover';\nconst TABLE_MOVER_STYLE_KEY = '_TableMoverCursorStyle';\n\n/**\n * @internal\n * Allows user to move table to another position\n * Contains the function to select whole table\n */\nexport function createTableMover(\n table: HTMLTableElement,\n editor: IEditor,\n isRTL: boolean,\n onFinishDragging: (table: HTMLTableElement) => void,\n onStart: () => void,\n onEnd: (disposeHandler: boolean) => void,\n contentDiv?: EventTarget | null,\n anchorContainer?: HTMLElement,\n onTableEditorCreated?: OnTableEditorCreatedCallback,\n disableMovement?: boolean\n): TableEditFeature | null {\n const rect = normalizeRect(table.getBoundingClientRect());\n\n if (!isTableTopVisible(editor, rect, contentDiv as Node)) {\n return null;\n }\n\n const zoomScale = editor.getDOMHelper().calculateZoomScale();\n const document = table.ownerDocument;\n const createElementData = {\n tag: 'div',\n style: 'position: fixed; cursor: move; user-select: none; border: 1px solid #808080',\n };\n\n const div = createElement(createElementData, document) as HTMLDivElement;\n\n div.id = TABLE_MOVER_ID;\n div.style.width = `${TABLE_MOVER_LENGTH}px`;\n div.style.height = `${TABLE_MOVER_LENGTH}px`;\n\n (anchorContainer || document.body).appendChild(div);\n\n const context: TableMoverContext = {\n table,\n zoomScale,\n rect,\n isRTL,\n editor,\n div,\n onFinishDragging,\n onStart,\n onEnd,\n disableMovement,\n };\n\n setDivPosition(context, div);\n\n const featureHandler = new TableMoverFeature(\n div,\n context,\n () => {},\n disableMovement\n ? { onDragEnd }\n : {\n onDragStart,\n onDragging,\n onDragEnd,\n },\n context.zoomScale,\n onTableEditorCreated,\n editor.getEnvironment().isMobileOrTablet\n );\n\n return { node: table, div, featureHandler };\n}\n\n/**\n * @internal\n * Exported for testing\n */\nexport interface TableMoverContext {\n table: HTMLTableElement;\n zoomScale: number;\n rect: Rect | null;\n isRTL: boolean;\n editor: IEditor;\n div: HTMLElement;\n onFinishDragging: (table: HTMLTableElement) => void;\n onStart: () => void;\n onEnd: (disposeHandler: boolean) => void;\n disableMovement?: boolean;\n}\n\n/**\n * @internal\n * Exported for testing\n */\nexport interface TableMoverInitValue {\n cmTable: ReadonlyContentModelTable | undefined;\n initialSelection: DOMSelection | null;\n tableRect: HTMLDivElement;\n}\n\nclass TableMoverFeature extends DragAndDropHelper<TableMoverContext, TableMoverInitValue> {\n private disposer: undefined | (() => void);\n\n constructor(\n div: HTMLElement,\n context: TableMoverContext,\n onSubmit: (\n context: TableMoverContext,\n trigger: HTMLElement,\n container?: HTMLElement\n ) => void,\n handler: DragAndDropHandler<TableMoverContext, TableMoverInitValue>,\n zoomScale: number,\n onTableEditorCreated?: OnTableEditorCreatedCallback,\n forceMobile?: boolean | undefined\n ) {\n super(div, context, onSubmit, handler, zoomScale, forceMobile);\n this.disposer = onTableEditorCreated?.('TableMover', div);\n }\n\n dispose(): void {\n this.disposer?.();\n this.disposer = undefined;\n super.dispose();\n }\n}\n\nfunction setDivPosition(context: TableMoverContext, trigger: HTMLElement) {\n const { rect } = context;\n if (rect) {\n trigger.style.top = `${rect.top - TABLE_MOVER_LENGTH}px`;\n trigger.style.left = `${rect.left - TABLE_MOVER_LENGTH - 2}px`;\n }\n}\n\nfunction isTableTopVisible(editor: IEditor, rect: Rect | null, contentDiv?: Node | null): boolean {\n const visibleViewport = editor.getVisibleViewport();\n if (isNodeOfType(contentDiv, 'ELEMENT_NODE') && visibleViewport && rect) {\n const containerRect = normalizeRect(contentDiv.getBoundingClientRect());\n\n return !!containerRect && containerRect.top <= rect.top && visibleViewport.top <= rect.top;\n }\n\n return true;\n}\n\nfunction setTableMoverCursor(editor: IEditor, state: boolean, type?: 'move' | 'copy') {\n editor?.setEditorStyle(TABLE_MOVER_STYLE_KEY, state ? 'cursor: ' + type ?? 'move' : null);\n}\n\n/**\n * @internal\n * Exported for testing\n */\nexport function onDragStart(context: TableMoverContext): TableMoverInitValue {\n context.onStart();\n\n const { editor, table, div } = context;\n\n setTableMoverCursor(editor, true, 'move');\n\n // Create table outline rectangle\n const trect = table.getBoundingClientRect();\n const createElementData = {\n tag: 'div',\n style: 'position: fixed; user-select: none; border: 1px solid #808080',\n };\n const tableRect = createElement(createElementData, document) as HTMLDivElement;\n tableRect.style.width = `${trect.width}px`;\n tableRect.style.height = `${trect.height}px`;\n tableRect.style.top = `${trect.top}px`;\n tableRect.style.left = `${trect.left}px`;\n div.parentNode?.appendChild(tableRect);\n\n // Get drag start selection\n const initialSelection = editor.getDOMSelection();\n\n // Get Table block in content model\n const cmTable = getCMTableFromTable(editor, table);\n\n return {\n cmTable,\n initialSelection,\n tableRect,\n };\n}\n\n/**\n * @internal\n * Exported for testing\n */\nexport function onDragging(\n context: TableMoverContext,\n event: MouseEvent,\n initValue: TableMoverInitValue\n) {\n const { tableRect } = initValue;\n const { editor } = context;\n\n // Move table outline rectangle\n tableRect.style.top = `${event.clientY + TABLE_MOVER_LENGTH}px`;\n tableRect.style.left = `${event.clientX + TABLE_MOVER_LENGTH}px`;\n\n const pos = getNodePositionFromEvent(editor, event.clientX, event.clientY);\n if (pos) {\n const range = editor.getDocument().createRange();\n range.setStart(pos.node, pos.offset);\n range.collapse(true);\n\n editor.setDOMSelection({ type: 'range', range, isReverted: false });\n return true;\n }\n return false;\n}\n\n/**\n * @internal\n * Exported for testing\n */\nexport function onDragEnd(\n context: TableMoverContext,\n event: MouseEvent,\n initValue: TableMoverInitValue | undefined\n) {\n const { editor, table, onFinishDragging: selectWholeTable, disableMovement } = context;\n const element = event.target;\n\n // Remove table outline rectangle\n initValue?.tableRect.remove();\n\n // Reset cursor\n setTableMoverCursor(editor, false);\n\n if (element == context.div) {\n // Table mover was only clicked, select whole table and do not dismiss the handler element.\n selectWholeTable(table);\n context.onEnd(false /* disposeHandler */);\n return true;\n } else {\n // Check if table was dragged on itself, element is not in editor, or movement is disabled\n if (\n table.contains(element as Node) ||\n !editor.getDOMHelper().isNodeInEditor(element as Node) ||\n disableMovement\n ) {\n editor.setDOMSelection(initValue?.initialSelection ?? null);\n context.onEnd(true /* disposeHandler */);\n return false;\n }\n\n let insertionSuccess: boolean = false;\n\n // Get position to insert table\n const insertPosition = getNodePositionFromEvent(editor, event.clientX, event.clientY);\n if (insertPosition) {\n // Move table to new position\n formatInsertPointWithContentModel(\n editor,\n insertPosition,\n (model, context, ip) => {\n // Remove old table\n const [oldTable, path] = getFirstSelectedTable(model);\n if (oldTable) {\n const index = path[0].blocks.indexOf(oldTable);\n mutateBlock(path[0]).blocks.splice(index, 1);\n }\n\n if (ip && initValue?.cmTable) {\n // Insert new table\n const doc: ShallowMutableContentModelDocument = createContentModelDocument();\n doc.blocks.push(oldTable ?? mutateBlock(initValue.cmTable));\n insertionSuccess = !!mergeModel(model, cloneModel(doc), context, {\n mergeFormat: 'none',\n insertPosition: ip,\n });\n\n if (insertionSuccess) {\n // After mergeModel, the new table should be selected\n const finalTable = getFirstSelectedTable(model)[0] ?? initValue.cmTable;\n if (finalTable) {\n // Add selection marker to the first cell of the table\n const firstCell = finalTable.rows[0].cells[0];\n const markerParagraph = firstCell?.blocks[0];\n\n if (markerParagraph?.blockType == 'Paragraph') {\n const marker = createSelectionMarker(model.format);\n\n mutateBlock(markerParagraph).segments.unshift(marker);\n setParagraphNotImplicit(markerParagraph);\n setSelection(model, marker);\n }\n }\n }\n return insertionSuccess;\n }\n },\n {\n // Select first cell of the old table\n selectionOverride: {\n type: 'table',\n firstColumn: 0,\n firstRow: 0,\n lastColumn: 0,\n lastRow: 0,\n table: table,\n },\n apiName: 'TableMover',\n }\n );\n } else {\n // No movement, restore initial selection\n editor.setDOMSelection(initValue?.initialSelection ?? null);\n }\n context.onEnd(true /* disposeHandler */);\n return insertionSuccess;\n }\n}\n"]}
@@ -0,0 +1,32 @@
1
+ import type { EditorPlugin, IEditor, PluginEvent } from 'roosterjs-content-model-types';
2
+ /**
3
+ * Touch plugin to manage touch behaviors
4
+ */
5
+ export declare class TouchPlugin implements EditorPlugin {
6
+ private editor;
7
+ private timer;
8
+ private isDblClicked;
9
+ private isTouchPenPointerEvent;
10
+ /**
11
+ * Create an instance of Touch plugin
12
+ */
13
+ constructor();
14
+ /**
15
+ * Get a friendly name of this plugin
16
+ */
17
+ getName(): string;
18
+ /**
19
+ * Initialize this plugin. This should only be called from Editor
20
+ * @param editor Editor instance
21
+ */
22
+ initialize(editor: IEditor): void;
23
+ /**
24
+ * Dispose this plugin
25
+ */
26
+ dispose(): void;
27
+ /**
28
+ * Handle events triggered from editor
29
+ * @param event PluginEvent object
30
+ */
31
+ onPluginEvent(event: PluginEvent): void;
32
+ }
@@ -0,0 +1,214 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TouchPlugin = void 0;
4
+ var getNodePositionFromEvent_1 = require("../utils/getNodePositionFromEvent");
5
+ var MAX_TOUCH_MOVE_DISTANCE = 6; // the max number of offsets for the touch selection to move
6
+ var POINTER_DETECTION_DELAY = 150; // Delay time to wait for selection to be updated and also detect if pointerup is a tap or part of double tap
7
+ var PUNCTUATION_MATCHING_REGEX = /[.,;:!]/;
8
+ var SPACE_MATCHING_REGEX = /\s/;
9
+ /**
10
+ * Touch plugin to manage touch behaviors
11
+ */
12
+ var TouchPlugin = /** @class */ (function () {
13
+ /**
14
+ * Create an instance of Touch plugin
15
+ */
16
+ function TouchPlugin() {
17
+ this.editor = null;
18
+ this.timer = 0;
19
+ this.isDblClicked = false;
20
+ this.isTouchPenPointerEvent = false;
21
+ }
22
+ /**
23
+ * Get a friendly name of this plugin
24
+ */
25
+ TouchPlugin.prototype.getName = function () {
26
+ return 'Touch';
27
+ };
28
+ /**
29
+ * Initialize this plugin. This should only be called from Editor
30
+ * @param editor Editor instance
31
+ */
32
+ TouchPlugin.prototype.initialize = function (editor) {
33
+ this.editor = editor;
34
+ this.isDblClicked = false;
35
+ };
36
+ /**
37
+ * Dispose this plugin
38
+ */
39
+ TouchPlugin.prototype.dispose = function () {
40
+ var _a, _b, _c;
41
+ if (this.timer) {
42
+ (_c = (_b = (_a = this.editor) === null || _a === void 0 ? void 0 : _a.getDocument()) === null || _b === void 0 ? void 0 : _b.defaultView) === null || _c === void 0 ? void 0 : _c.clearTimeout(this.timer);
43
+ this.timer = 0;
44
+ }
45
+ this.editor = null;
46
+ };
47
+ /**
48
+ * Handle events triggered from editor
49
+ * @param event PluginEvent object
50
+ */
51
+ TouchPlugin.prototype.onPluginEvent = function (event) {
52
+ var _this = this;
53
+ var _a, _b, _c, _d;
54
+ if (!this.editor) {
55
+ return;
56
+ }
57
+ switch (event.eventType) {
58
+ case 'pointerDown':
59
+ this.isDblClicked = false;
60
+ this.isTouchPenPointerEvent = true;
61
+ event.originalEvent.preventDefault();
62
+ var targetWindow = ((_a = this.editor.getDocument()) === null || _a === void 0 ? void 0 : _a.defaultView) || window;
63
+ if (this.timer) {
64
+ targetWindow.clearTimeout(this.timer);
65
+ }
66
+ this.timer = targetWindow.setTimeout(function () {
67
+ _this.timer = 0;
68
+ if (!_this.isDblClicked && _this.editor) {
69
+ var caretPosition = (0, getNodePositionFromEvent_1.getNodePositionFromEvent)(_this.editor, event.rawEvent.x, event.rawEvent.y);
70
+ if (caretPosition) {
71
+ var node = caretPosition.node, offset = caretPosition.offset;
72
+ var nodeTextContent = node.textContent || '';
73
+ var charAtSelection = nodeTextContent[offset];
74
+ if (node.nodeType === Node.TEXT_NODE &&
75
+ charAtSelection &&
76
+ !SPACE_MATCHING_REGEX.test(charAtSelection) &&
77
+ !PUNCTUATION_MATCHING_REGEX.test(charAtSelection)) {
78
+ var _a = findWordBoundaries(nodeTextContent, offset), wordStart = _a.wordStart, wordEnd = _a.wordEnd;
79
+ // Move cursor to the calculated offset
80
+ var leftCursorWordLength = offset - wordStart;
81
+ var rightCursorWordLength = wordEnd - offset;
82
+ var movingOffset = leftCursorWordLength >= rightCursorWordLength
83
+ ? rightCursorWordLength
84
+ : -leftCursorWordLength;
85
+ movingOffset =
86
+ Math.abs(movingOffset) > MAX_TOUCH_MOVE_DISTANCE
87
+ ? 0
88
+ : movingOffset;
89
+ var newOffsetPosition = offset + movingOffset;
90
+ if (movingOffset !== 0 &&
91
+ nodeTextContent.length >= newOffsetPosition) {
92
+ var newRange_1 = _this.editor.getDocument().createRange();
93
+ newRange_1.setStart(node, newOffsetPosition);
94
+ newRange_1.setEnd(node, newOffsetPosition);
95
+ _this.editor.setDOMSelection({
96
+ type: 'range',
97
+ range: newRange_1,
98
+ isReverted: false,
99
+ });
100
+ return;
101
+ }
102
+ }
103
+ // Place cursor at same position of browser handler
104
+ var newRange = _this.editor.getDocument().createRange();
105
+ newRange.setStart(node, offset);
106
+ newRange.setEnd(node, offset);
107
+ _this.editor.setDOMSelection({
108
+ type: 'range',
109
+ range: newRange,
110
+ isReverted: false,
111
+ });
112
+ }
113
+ // reset values
114
+ _this.isTouchPenPointerEvent = false;
115
+ }
116
+ }, POINTER_DETECTION_DELAY);
117
+ break;
118
+ case 'doubleClick':
119
+ if (this.isTouchPenPointerEvent) {
120
+ event.rawEvent.preventDefault();
121
+ this.isDblClicked = true;
122
+ var caretPosition = (0, getNodePositionFromEvent_1.getNodePositionFromEvent)(this.editor, event.rawEvent.x, event.rawEvent.y);
123
+ if (caretPosition) {
124
+ var node = caretPosition.node, offset = caretPosition.offset;
125
+ if (node.nodeType !== Node.TEXT_NODE) {
126
+ return;
127
+ }
128
+ var nodeTextContent = node.nodeValue || '';
129
+ var char = nodeTextContent.charAt(offset);
130
+ // Check if the clicked character is a punctuation mark, then highlight that character only
131
+ if (PUNCTUATION_MATCHING_REGEX.test(char)) {
132
+ var newRange = (_b = this.editor.getDocument()) === null || _b === void 0 ? void 0 : _b.createRange();
133
+ if (newRange) {
134
+ newRange.setStart(node, offset);
135
+ newRange.setEnd(node, offset + 1);
136
+ this.editor.setDOMSelection({
137
+ type: 'range',
138
+ range: newRange,
139
+ isReverted: false,
140
+ });
141
+ }
142
+ }
143
+ else if (SPACE_MATCHING_REGEX.test(char)) {
144
+ // If the clicked character is an open space with no word of right side
145
+ var rightSideOfChar = nodeTextContent.substring(offset, nodeTextContent.length);
146
+ var isRightSideAllSpaces = rightSideOfChar.length > 0 && !/\S/.test(rightSideOfChar);
147
+ if (isRightSideAllSpaces) {
148
+ // select the first space only
149
+ var start = offset;
150
+ while (start > 0 &&
151
+ SPACE_MATCHING_REGEX.test(nodeTextContent.charAt(start - 1))) {
152
+ start--;
153
+ }
154
+ var newRange = (_c = this.editor.getDocument()) === null || _c === void 0 ? void 0 : _c.createRange();
155
+ if (newRange) {
156
+ newRange.setStart(node, start);
157
+ newRange.setEnd(node, start + 1);
158
+ this.editor.setDOMSelection({
159
+ type: 'range',
160
+ range: newRange,
161
+ isReverted: false,
162
+ });
163
+ }
164
+ }
165
+ }
166
+ else {
167
+ var _e = findWordBoundaries(nodeTextContent, offset), wordStart = _e.wordStart, wordEnd = _e.wordEnd;
168
+ var newRange = (_d = this.editor.getDocument()) === null || _d === void 0 ? void 0 : _d.createRange();
169
+ if (newRange) {
170
+ newRange.setStart(node, wordStart);
171
+ newRange.setEnd(node, wordEnd);
172
+ this.editor.setDOMSelection({
173
+ type: 'range',
174
+ range: newRange,
175
+ isReverted: false,
176
+ });
177
+ }
178
+ }
179
+ }
180
+ }
181
+ break;
182
+ }
183
+ };
184
+ return TouchPlugin;
185
+ }());
186
+ exports.TouchPlugin = TouchPlugin;
187
+ /**
188
+ * @internal
189
+ * Finds the start and end indices of the word at the given offset in the text.
190
+ * @param text The string to search within.
191
+ * @param offset The index within the string to find the word boundaries around.
192
+ * @returns An object containing wordStart and wordEnd indices.
193
+ */
194
+ function findWordBoundaries(text, offset) {
195
+ var start = offset;
196
+ var end = offset;
197
+ // Move start backwards to find word start
198
+ while (start > 0 &&
199
+ !SPACE_MATCHING_REGEX.test(text[start - 1]) &&
200
+ !PUNCTUATION_MATCHING_REGEX.test(text[start - 1])) {
201
+ start--;
202
+ }
203
+ // Move end forward to find word end
204
+ while (end < text.length &&
205
+ !SPACE_MATCHING_REGEX.test(text[end]) &&
206
+ !PUNCTUATION_MATCHING_REGEX.test(text[end])) {
207
+ end++;
208
+ }
209
+ return {
210
+ wordStart: start,
211
+ wordEnd: end,
212
+ };
213
+ }
214
+ //# sourceMappingURL=TouchPlugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TouchPlugin.js","sourceRoot":"","sources":["../../../../packages/roosterjs-content-model-plugins/lib/touch/TouchPlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import type { EditorPlugin, IEditor, PluginEvent } from 'roosterjs-content-model-types';\nimport { getNodePositionFromEvent } from '../utils/getNodePositionFromEvent';\n\nconst MAX_TOUCH_MOVE_DISTANCE = 6; // the max number of offsets for the touch selection to move\nconst POINTER_DETECTION_DELAY = 150; // Delay time to wait for selection to be updated and also detect if pointerup is a tap or part of double tap\nconst PUNCTUATION_MATCHING_REGEX = /[.,;:!]/;\nconst SPACE_MATCHING_REGEX = /\\s/;\n\n/**\n * Touch plugin to manage touch behaviors\n */\nexport class TouchPlugin implements EditorPlugin {\n private editor: IEditor | null = null;\n private timer = 0;\n private isDblClicked: boolean = false;\n private isTouchPenPointerEvent: boolean = false;\n\n /**\n * Create an instance of Touch plugin\n */\n constructor() {}\n\n /**\n * Get a friendly name of this plugin\n */\n getName() {\n return 'Touch';\n }\n\n /**\n * Initialize this plugin. This should only be called from Editor\n * @param editor Editor instance\n */\n initialize(editor: IEditor) {\n this.editor = editor;\n this.isDblClicked = false;\n }\n\n /**\n * Dispose this plugin\n */\n dispose() {\n if (this.timer) {\n this.editor?.getDocument()?.defaultView?.clearTimeout(this.timer);\n this.timer = 0;\n }\n this.editor = null;\n }\n\n /**\n * Handle events triggered from editor\n * @param event PluginEvent object\n */\n onPluginEvent(event: PluginEvent) {\n if (!this.editor) {\n return;\n }\n switch (event.eventType) {\n case 'pointerDown':\n this.isDblClicked = false;\n this.isTouchPenPointerEvent = true;\n event.originalEvent.preventDefault();\n\n const targetWindow = this.editor.getDocument()?.defaultView || window;\n if (this.timer) {\n targetWindow.clearTimeout(this.timer);\n }\n\n this.timer = targetWindow.setTimeout(() => {\n this.timer = 0;\n\n if (!this.isDblClicked && this.editor) {\n const caretPosition = getNodePositionFromEvent(\n this.editor,\n event.rawEvent.x,\n event.rawEvent.y\n );\n\n if (caretPosition) {\n const { node, offset } = caretPosition;\n\n const nodeTextContent = node.textContent || '';\n const charAtSelection = nodeTextContent[offset];\n if (\n node.nodeType === Node.TEXT_NODE &&\n charAtSelection &&\n !SPACE_MATCHING_REGEX.test(charAtSelection) &&\n !PUNCTUATION_MATCHING_REGEX.test(charAtSelection)\n ) {\n const { wordStart, wordEnd } = findWordBoundaries(\n nodeTextContent,\n offset\n );\n\n // Move cursor to the calculated offset\n const leftCursorWordLength = offset - wordStart;\n const rightCursorWordLength = wordEnd - offset;\n let movingOffset: number =\n leftCursorWordLength >= rightCursorWordLength\n ? rightCursorWordLength\n : -leftCursorWordLength;\n movingOffset =\n Math.abs(movingOffset) > MAX_TOUCH_MOVE_DISTANCE\n ? 0\n : movingOffset;\n const newOffsetPosition = offset + movingOffset;\n if (\n movingOffset !== 0 &&\n nodeTextContent.length >= newOffsetPosition\n ) {\n const newRange = this.editor.getDocument().createRange();\n newRange.setStart(node, newOffsetPosition);\n newRange.setEnd(node, newOffsetPosition);\n this.editor.setDOMSelection({\n type: 'range',\n range: newRange,\n isReverted: false,\n });\n return;\n }\n }\n\n // Place cursor at same position of browser handler\n const newRange = this.editor.getDocument().createRange();\n newRange.setStart(node, offset);\n newRange.setEnd(node, offset);\n this.editor.setDOMSelection({\n type: 'range',\n range: newRange,\n isReverted: false,\n });\n }\n\n // reset values\n this.isTouchPenPointerEvent = false;\n }\n }, POINTER_DETECTION_DELAY);\n\n break;\n case 'doubleClick':\n if (this.isTouchPenPointerEvent) {\n event.rawEvent.preventDefault();\n\n this.isDblClicked = true;\n const caretPosition = getNodePositionFromEvent(\n this.editor,\n event.rawEvent.x,\n event.rawEvent.y\n );\n\n if (caretPosition) {\n const { node, offset } = caretPosition;\n\n if (node.nodeType !== Node.TEXT_NODE) {\n return;\n }\n\n const nodeTextContent = node.nodeValue || '';\n const char = nodeTextContent.charAt(offset);\n\n // Check if the clicked character is a punctuation mark, then highlight that character only\n if (PUNCTUATION_MATCHING_REGEX.test(char)) {\n const newRange = this.editor.getDocument()?.createRange();\n if (newRange) {\n newRange.setStart(node, offset);\n newRange.setEnd(node, offset + 1);\n this.editor.setDOMSelection({\n type: 'range',\n range: newRange,\n isReverted: false,\n });\n }\n } else if (SPACE_MATCHING_REGEX.test(char)) {\n // If the clicked character is an open space with no word of right side\n const rightSideOfChar = nodeTextContent.substring(\n offset,\n nodeTextContent.length\n );\n const isRightSideAllSpaces =\n rightSideOfChar.length > 0 && !/\\S/.test(rightSideOfChar);\n if (isRightSideAllSpaces) {\n // select the first space only\n let start = offset;\n while (\n start > 0 &&\n SPACE_MATCHING_REGEX.test(nodeTextContent.charAt(start - 1))\n ) {\n start--;\n }\n const newRange = this.editor.getDocument()?.createRange();\n if (newRange) {\n newRange.setStart(node, start);\n newRange.setEnd(node, start + 1);\n this.editor.setDOMSelection({\n type: 'range',\n range: newRange,\n isReverted: false,\n });\n }\n }\n } else {\n const { wordStart, wordEnd } = findWordBoundaries(\n nodeTextContent,\n offset\n );\n const newRange = this.editor.getDocument()?.createRange();\n if (newRange) {\n newRange.setStart(node, wordStart);\n newRange.setEnd(node, wordEnd);\n this.editor.setDOMSelection({\n type: 'range',\n range: newRange,\n isReverted: false,\n });\n }\n }\n }\n }\n break;\n }\n }\n}\n\n/**\n * @internal\n * Finds the start and end indices of the word at the given offset in the text.\n * @param text The string to search within.\n * @param offset The index within the string to find the word boundaries around.\n * @returns An object containing wordStart and wordEnd indices.\n */\nfunction findWordBoundaries(text: string, offset: number) {\n let start = offset;\n let end = offset;\n\n // Move start backwards to find word start\n while (\n start > 0 &&\n !SPACE_MATCHING_REGEX.test(text[start - 1]) &&\n !PUNCTUATION_MATCHING_REGEX.test(text[start - 1])\n ) {\n start--;\n }\n\n // Move end forward to find word end\n while (\n end < text.length &&\n !SPACE_MATCHING_REGEX.test(text[end]) &&\n !PUNCTUATION_MATCHING_REGEX.test(text[end])\n ) {\n end++;\n }\n\n return {\n wordStart: start,\n wordEnd: end,\n };\n}\n"]}
@@ -0,0 +1,5 @@
1
+ import type { DOMInsertPoint, IEditor } from 'roosterjs-content-model-types';
2
+ /**
3
+ * @internal Get insertion point from coordinate.
4
+ */
5
+ export declare function getNodePositionFromEvent(editor: IEditor, x: number, y: number): DOMInsertPoint | null;
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getNodePositionFromEvent = void 0;
4
+ /**
5
+ * @internal Get insertion point from coordinate.
6
+ */
7
+ function getNodePositionFromEvent(editor, x, y) {
8
+ var doc = editor.getDocument();
9
+ var domHelper = editor.getDOMHelper();
10
+ if ('caretPositionFromPoint' in doc) {
11
+ // Firefox, Chrome, Edge, Safari, Opera
12
+ var pos = doc.caretPositionFromPoint(x, y);
13
+ if (pos && domHelper.isNodeInEditor(pos.offsetNode)) {
14
+ return { node: pos.offsetNode, offset: pos.offset };
15
+ }
16
+ }
17
+ if (doc.caretRangeFromPoint) {
18
+ // Safari
19
+ var range = doc.caretRangeFromPoint(x, y);
20
+ if (range && domHelper.isNodeInEditor(range.startContainer)) {
21
+ return { node: range.startContainer, offset: range.startOffset };
22
+ }
23
+ }
24
+ if (doc.elementFromPoint) {
25
+ // Fallback
26
+ var element = doc.elementFromPoint(x, y);
27
+ if (element && domHelper.isNodeInEditor(element)) {
28
+ return { node: element, offset: 0 };
29
+ }
30
+ }
31
+ return null;
32
+ }
33
+ exports.getNodePositionFromEvent = getNodePositionFromEvent;
34
+ //# sourceMappingURL=getNodePositionFromEvent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getNodePositionFromEvent.js","sourceRoot":"","sources":["../../../../packages/roosterjs-content-model-plugins/lib/utils/getNodePositionFromEvent.ts"],"names":[],"mappings":";;;AAEA;;GAEG;AACH,SAAgB,wBAAwB,CACpC,MAAe,EACf,CAAS,EACT,CAAS;IAET,IAAM,GAAG,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;IACjC,IAAM,SAAS,GAAG,MAAM,CAAC,YAAY,EAAE,CAAC;IAExC,IAAI,wBAAwB,IAAI,GAAG,EAAE;QACjC,uCAAuC;QACvC,IAAM,GAAG,GAAI,GAAW,CAAC,sBAAsB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACtD,IAAI,GAAG,IAAI,SAAS,CAAC,cAAc,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE;YACjD,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC;SACvD;KACJ;IAED,IAAI,GAAG,CAAC,mBAAmB,EAAE;QACzB,SAAS;QACT,IAAM,KAAK,GAAG,GAAG,CAAC,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC5C,IAAI,KAAK,IAAI,SAAS,CAAC,cAAc,CAAC,KAAK,CAAC,cAAc,CAAC,EAAE;YACzD,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,cAAc,EAAE,MAAM,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC;SACpE;KACJ;IAED,IAAI,GAAG,CAAC,gBAAgB,EAAE;QACtB,WAAW;QACX,IAAM,OAAO,GAAG,GAAG,CAAC,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC3C,IAAI,OAAO,IAAI,SAAS,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE;YAC9C,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;SACvC;KACJ;IAED,OAAO,IAAI,CAAC;AAChB,CAAC;AAjCD,4DAiCC","sourcesContent":["import type { DOMInsertPoint, IEditor } from 'roosterjs-content-model-types';\n\n/**\n * @internal Get insertion point from coordinate.\n */\nexport function getNodePositionFromEvent(\n editor: IEditor,\n x: number,\n y: number\n): DOMInsertPoint | null {\n const doc = editor.getDocument();\n const domHelper = editor.getDOMHelper();\n\n if ('caretPositionFromPoint' in doc) {\n // Firefox, Chrome, Edge, Safari, Opera\n const pos = (doc as any).caretPositionFromPoint(x, y);\n if (pos && domHelper.isNodeInEditor(pos.offsetNode)) {\n return { node: pos.offsetNode, offset: pos.offset };\n }\n }\n\n if (doc.caretRangeFromPoint) {\n // Safari\n const range = doc.caretRangeFromPoint(x, y);\n if (range && domHelper.isNodeInEditor(range.startContainer)) {\n return { node: range.startContainer, offset: range.startOffset };\n }\n }\n\n if (doc.elementFromPoint) {\n // Fallback\n const element = doc.elementFromPoint(x, y);\n if (element && domHelper.isNodeInEditor(element)) {\n return { node: element, offset: 0 };\n }\n }\n\n return null;\n}\n"]}
@@ -75,9 +75,10 @@ define(["require", "exports", "roosterjs-content-model-api", "./getNumberingList
75
75
  };
76
76
  var getPreviousListStyle = function (list) {
77
77
  var _a;
78
- if (list === null || list === void 0 ? void 0 : list.levels[0].dataset) {
79
- return (_a = (0, roosterjs_content_model_dom_1.updateListMetadata)(list.levels[0])) === null || _a === void 0 ? void 0 : _a.orderedStyleType;
78
+ if (!list || list.levels.length < 1) {
79
+ return undefined;
80
80
  }
81
+ return (_a = (0, roosterjs_content_model_dom_1.updateListMetadata)(list.levels[0])) === null || _a === void 0 ? void 0 : _a.orderedStyleType;
81
82
  };
82
83
  var bulletListType = new Map([
83
84
  ['*', roosterjs_content_model_dom_1.BulletListType.Disc],