roosterjs-content-model-dom 9.6.0 → 9.8.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.
@@ -9,16 +9,14 @@ var normalizeRect_1 = require("../normalizeRect");
9
9
  * @param pos The input DOM insert point
10
10
  */
11
11
  function getDOMInsertPointRect(doc, pos) {
12
- var _a;
13
- var node = pos.node, offset = pos.offset;
12
+ var _a, _b;
14
13
  var range = doc.createRange();
15
- range.setStart(node, offset);
16
- // 1) try to get rect using range.getBoundingClientRect()
17
- var rect = (0, normalizeRect_1.normalizeRect)(range.getBoundingClientRect());
18
- if (rect) {
19
- return rect;
20
- }
21
- // 2) try to get rect using range.getClientRects
14
+ return ((_b = (_a = tryGetRectFromPos(pos, range)) !== null && _a !== void 0 ? _a : tryGetRectFromPos((pos = normalizeInsertPoint(pos)), range)) !== null && _b !== void 0 ? _b : tryGetRectFromNode(pos.node) // 3. fallback to node rect using getBoundingClientRect
15
+ );
16
+ }
17
+ exports.getDOMInsertPointRect = getDOMInsertPointRect;
18
+ function normalizeInsertPoint(pos) {
19
+ var node = pos.node, offset = pos.offset;
22
20
  while (node.lastChild) {
23
21
  if (offset == node.childNodes.length) {
24
22
  node = node.lastChild;
@@ -29,30 +27,24 @@ function getDOMInsertPointRect(doc, pos) {
29
27
  offset = 0;
30
28
  }
31
29
  }
32
- var rects = range.getClientRects && range.getClientRects();
33
- rect = rects && rects.length == 1 ? (0, normalizeRect_1.normalizeRect)(rects[0]) : null;
30
+ return { node: node, offset: offset };
31
+ }
32
+ function tryGetRectFromPos(pos, range) {
33
+ var node = pos.node, offset = pos.offset;
34
+ range.setStart(node, offset);
35
+ range.setEnd(node, offset);
36
+ var rect = (0, normalizeRect_1.normalizeRect)(range.getBoundingClientRect());
34
37
  if (rect) {
35
38
  return rect;
36
39
  }
37
- // 3) if node is text node, try inserting a SPAN and get the rect of SPAN for others
38
- if ((0, isNodeOfType_1.isNodeOfType)(node, 'TEXT_NODE')) {
39
- var span = node.ownerDocument.createElement('span');
40
- span.textContent = '\u200b';
41
- range.insertNode(span);
42
- rect = (0, normalizeRect_1.normalizeRect)(span.getBoundingClientRect());
43
- (_a = span.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(span);
44
- if (rect) {
45
- return rect;
46
- }
40
+ else {
41
+ var rects = range.getClientRects && range.getClientRects();
42
+ return rects && rects.length == 1 ? (0, normalizeRect_1.normalizeRect)(rects[0]) : null;
47
43
  }
48
- // 4) try getBoundingClientRect on element
49
- if ((0, isNodeOfType_1.isNodeOfType)(node, 'ELEMENT_NODE') && node.getBoundingClientRect) {
50
- rect = (0, normalizeRect_1.normalizeRect)(node.getBoundingClientRect());
51
- if (rect) {
52
- return rect;
53
- }
54
- }
55
- return null;
56
44
  }
57
- exports.getDOMInsertPointRect = getDOMInsertPointRect;
45
+ function tryGetRectFromNode(node) {
46
+ return (0, isNodeOfType_1.isNodeOfType)(node, 'ELEMENT_NODE') && node.getBoundingClientRect
47
+ ? (0, normalizeRect_1.normalizeRect)(node.getBoundingClientRect())
48
+ : null;
49
+ }
58
50
  //# sourceMappingURL=getDOMInsertPointRect.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"getDOMInsertPointRect.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/domUtils/selection/getDOMInsertPointRect.ts"],"names":[],"mappings":";;;AAAA,gDAA+C;AAC/C,kDAAiD;AAGjD;;;;GAIG;AACH,SAAgB,qBAAqB,CAAC,GAAa,EAAE,GAAmB;;IAC9D,IAAA,IAAI,GAAa,GAAG,KAAhB,EAAE,MAAM,GAAK,GAAG,OAAR,CAAS;IAC3B,IAAM,KAAK,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;IAEhC,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAE7B,yDAAyD;IACzD,IAAI,IAAI,GAAG,IAAA,6BAAa,EAAC,KAAK,CAAC,qBAAqB,EAAE,CAAC,CAAC;IAExD,IAAI,IAAI,EAAE;QACN,OAAO,IAAI,CAAC;KACf;IAED,gDAAgD;IAChD,OAAO,IAAI,CAAC,SAAS,EAAE;QACnB,IAAI,MAAM,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE;YAClC,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC;YACtB,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;SACnC;aAAM;YACH,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;YAC/B,MAAM,GAAG,CAAC,CAAC;SACd;KACJ;IAED,IAAM,KAAK,GAAG,KAAK,CAAC,cAAc,IAAI,KAAK,CAAC,cAAc,EAAE,CAAC;IAC7D,IAAI,GAAG,KAAK,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,IAAA,6BAAa,EAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACnE,IAAI,IAAI,EAAE;QACN,OAAO,IAAI,CAAC;KACf;IAED,oFAAoF;IACpF,IAAI,IAAA,2BAAY,EAAC,IAAI,EAAE,WAAW,CAAC,EAAE;QACjC,IAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAEtD,IAAI,CAAC,WAAW,GAAG,QAAQ,CAAC;QAC5B,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACvB,IAAI,GAAG,IAAA,6BAAa,EAAC,IAAI,CAAC,qBAAqB,EAAE,CAAC,CAAC;QACnD,MAAA,IAAI,CAAC,UAAU,0CAAE,WAAW,CAAC,IAAI,CAAC,CAAC;QAEnC,IAAI,IAAI,EAAE;YACN,OAAO,IAAI,CAAC;SACf;KACJ;IAED,0CAA0C;IAC1C,IAAI,IAAA,2BAAY,EAAC,IAAI,EAAE,cAAc,CAAC,IAAI,IAAI,CAAC,qBAAqB,EAAE;QAClE,IAAI,GAAG,IAAA,6BAAa,EAAC,IAAI,CAAC,qBAAqB,EAAE,CAAC,CAAC;QAEnD,IAAI,IAAI,EAAE;YACN,OAAO,IAAI,CAAC;SACf;KACJ;IAED,OAAO,IAAI,CAAC;AAChB,CAAC;AAtDD,sDAsDC","sourcesContent":["import { isNodeOfType } from '../isNodeOfType';\nimport { normalizeRect } from '../normalizeRect';\nimport type { DOMInsertPoint, Rect } from 'roosterjs-content-model-types';\n\n/**\n * Get bounding rect of the given DOM insert point\n * @param doc The document object\n * @param pos The input DOM insert point\n */\nexport function getDOMInsertPointRect(doc: Document, pos: DOMInsertPoint): Rect | null {\n let { node, offset } = pos;\n const range = doc.createRange();\n\n range.setStart(node, offset);\n\n // 1) try to get rect using range.getBoundingClientRect()\n let rect = normalizeRect(range.getBoundingClientRect());\n\n if (rect) {\n return rect;\n }\n\n // 2) try to get rect using range.getClientRects\n while (node.lastChild) {\n if (offset == node.childNodes.length) {\n node = node.lastChild;\n offset = node.childNodes.length;\n } else {\n node = node.childNodes[offset];\n offset = 0;\n }\n }\n\n const rects = range.getClientRects && range.getClientRects();\n rect = rects && rects.length == 1 ? normalizeRect(rects[0]) : null;\n if (rect) {\n return rect;\n }\n\n // 3) if node is text node, try inserting a SPAN and get the rect of SPAN for others\n if (isNodeOfType(node, 'TEXT_NODE')) {\n const span = node.ownerDocument.createElement('span');\n\n span.textContent = '\\u200b';\n range.insertNode(span);\n rect = normalizeRect(span.getBoundingClientRect());\n span.parentNode?.removeChild(span);\n\n if (rect) {\n return rect;\n }\n }\n\n // 4) try getBoundingClientRect on element\n if (isNodeOfType(node, 'ELEMENT_NODE') && node.getBoundingClientRect) {\n rect = normalizeRect(node.getBoundingClientRect());\n\n if (rect) {\n return rect;\n }\n }\n\n return null;\n}\n"]}
1
+ {"version":3,"file":"getDOMInsertPointRect.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/domUtils/selection/getDOMInsertPointRect.ts"],"names":[],"mappings":";;;AAAA,gDAA+C;AAC/C,kDAAiD;AAGjD;;;;GAIG;AACH,SAAgB,qBAAqB,CAAC,GAAa,EAAE,GAAmB;;IACpE,IAAM,KAAK,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;IAEhC,OAAO,CACH,MAAA,MAAA,iBAAiB,CAAC,GAAG,EAAE,KAAK,CAAC,mCAC7B,iBAAiB,CAAC,CAAC,GAAG,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,mCAC3D,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,uDAAuD;KACvF,CAAC;AACN,CAAC;AARD,sDAQC;AAED,SAAS,oBAAoB,CAAC,GAAmB;IACvC,IAAA,IAAI,GAAa,GAAG,KAAhB,EAAE,MAAM,GAAK,GAAG,OAAR,CAAS;IAE3B,OAAO,IAAI,CAAC,SAAS,EAAE;QACnB,IAAI,MAAM,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE;YAClC,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC;YACtB,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;SACnC;aAAM;YACH,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;YAC/B,MAAM,GAAG,CAAC,CAAC;SACd;KACJ;IAED,OAAO,EAAE,IAAI,MAAA,EAAE,MAAM,QAAA,EAAE,CAAC;AAC5B,CAAC;AAED,SAAS,iBAAiB,CAAC,GAAmB,EAAE,KAAY;IAChD,IAAA,IAAI,GAAa,GAAG,KAAhB,EAAE,MAAM,GAAK,GAAG,OAAR,CAAS;IAE7B,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC7B,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAE3B,IAAM,IAAI,GAAG,IAAA,6BAAa,EAAC,KAAK,CAAC,qBAAqB,EAAE,CAAC,CAAC;IAE1D,IAAI,IAAI,EAAE;QACN,OAAO,IAAI,CAAC;KACf;SAAM;QACH,IAAM,KAAK,GAAG,KAAK,CAAC,cAAc,IAAI,KAAK,CAAC,cAAc,EAAE,CAAC;QAE7D,OAAO,KAAK,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,IAAA,6BAAa,EAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;KACtE;AACL,CAAC;AAED,SAAS,kBAAkB,CAAC,IAAU;IAClC,OAAO,IAAA,2BAAY,EAAC,IAAI,EAAE,cAAc,CAAC,IAAI,IAAI,CAAC,qBAAqB;QACnE,CAAC,CAAC,IAAA,6BAAa,EAAC,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAC7C,CAAC,CAAC,IAAI,CAAC;AACf,CAAC","sourcesContent":["import { isNodeOfType } from '../isNodeOfType';\nimport { normalizeRect } from '../normalizeRect';\nimport type { DOMInsertPoint, Rect } from 'roosterjs-content-model-types';\n\n/**\n * Get bounding rect of the given DOM insert point\n * @param doc The document object\n * @param pos The input DOM insert point\n */\nexport function getDOMInsertPointRect(doc: Document, pos: DOMInsertPoint): Rect | null {\n const range = doc.createRange();\n\n return (\n tryGetRectFromPos(pos, range) ?? // 1. try get from the pos directly using getBoundingClientRect or getClientRects\n tryGetRectFromPos((pos = normalizeInsertPoint(pos)), range) ?? // 2. try get normalized pos, this can work when insert point is inside text node\n tryGetRectFromNode(pos.node) // 3. fallback to node rect using getBoundingClientRect\n );\n}\n\nfunction normalizeInsertPoint(pos: DOMInsertPoint) {\n let { node, offset } = pos;\n\n while (node.lastChild) {\n if (offset == node.childNodes.length) {\n node = node.lastChild;\n offset = node.childNodes.length;\n } else {\n node = node.childNodes[offset];\n offset = 0;\n }\n }\n\n return { node, offset };\n}\n\nfunction tryGetRectFromPos(pos: DOMInsertPoint, range: Range): Rect | null {\n const { node, offset } = pos;\n\n range.setStart(node, offset);\n range.setEnd(node, offset);\n\n const rect = normalizeRect(range.getBoundingClientRect());\n\n if (rect) {\n return rect;\n } else {\n const rects = range.getClientRects && range.getClientRects();\n\n return rects && rects.length == 1 ? normalizeRect(rects[0]) : null;\n }\n}\n\nfunction tryGetRectFromNode(node: Node) {\n return isNodeOfType(node, 'ELEMENT_NODE') && node.getBoundingClientRect\n ? normalizeRect(node.getBoundingClientRect())\n : null;\n}\n"]}
@@ -9,8 +9,7 @@ function removeUnnecessarySpan(root) {
9
9
  for (var child = root.firstChild; child;) {
10
10
  if ((0, isNodeOfType_1.isNodeOfType)(child, 'ELEMENT_NODE') &&
11
11
  child.tagName == 'SPAN' &&
12
- child.attributes.length == 0 &&
13
- !isImageSpan(child)) {
12
+ child.attributes.length == 0) {
14
13
  var node = child;
15
14
  var refNode = child.nextSibling;
16
15
  child = child.nextSibling;
@@ -27,9 +26,4 @@ function removeUnnecessarySpan(root) {
27
26
  }
28
27
  }
29
28
  exports.removeUnnecessarySpan = removeUnnecessarySpan;
30
- var isImageSpan = function (child) {
31
- return ((0, isNodeOfType_1.isNodeOfType)(child.firstChild, 'ELEMENT_NODE') &&
32
- child.firstChild.tagName == 'IMG' &&
33
- child.firstChild == child.lastChild);
34
- };
35
29
  //# sourceMappingURL=removeUnnecessarySpan.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"removeUnnecessarySpan.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/modelToDom/optimizers/removeUnnecessarySpan.ts"],"names":[],"mappings":";;;AAAA,4DAA2D;AAE3D;;GAEG;AACH,SAAgB,qBAAqB,CAAC,IAAU;IAC5C,KAAK,IAAI,KAAK,GAAG,IAAI,CAAC,UAAU,EAAE,KAAK,GAAI;QACvC,IACI,IAAA,2BAAY,EAAC,KAAK,EAAE,cAAc,CAAC;YACnC,KAAK,CAAC,OAAO,IAAI,MAAM;YACvB,KAAK,CAAC,UAAU,CAAC,MAAM,IAAI,CAAC;YAC5B,CAAC,WAAW,CAAC,KAAK,CAAC,EACrB;YACE,IAAM,IAAI,GAAG,KAAK,CAAC;YACnB,IAAI,OAAO,GAAG,KAAK,CAAC,WAAW,CAAC;YAChC,KAAK,GAAG,KAAK,CAAC,WAAW,CAAC;YAE1B,OAAO,IAAI,CAAC,SAAS,EAAE;gBACnB,IAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC;gBAC/B,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;gBACpC,OAAO,GAAG,OAAO,CAAC;aACrB;YAED,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;SAC1B;aAAM;YACH,KAAK,GAAG,KAAK,CAAC,WAAW,CAAC;SAC7B;KACJ;AACL,CAAC;AAvBD,sDAuBC;AAED,IAAM,WAAW,GAAG,UAAC,KAAkB;IACnC,OAAO,CACH,IAAA,2BAAY,EAAC,KAAK,CAAC,UAAU,EAAE,cAAc,CAAC;QAC9C,KAAK,CAAC,UAAU,CAAC,OAAO,IAAI,KAAK;QACjC,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,SAAS,CACtC,CAAC;AACN,CAAC,CAAC","sourcesContent":["import { isNodeOfType } from '../../domUtils/isNodeOfType';\n\n/**\n * @internal\n */\nexport function removeUnnecessarySpan(root: Node) {\n for (let child = root.firstChild; child; ) {\n if (\n isNodeOfType(child, 'ELEMENT_NODE') &&\n child.tagName == 'SPAN' &&\n child.attributes.length == 0 &&\n !isImageSpan(child)\n ) {\n const node = child;\n let refNode = child.nextSibling;\n child = child.nextSibling;\n\n while (node.lastChild) {\n const newNode = node.lastChild;\n root.insertBefore(newNode, refNode);\n refNode = newNode;\n }\n\n root.removeChild(node);\n } else {\n child = child.nextSibling;\n }\n }\n}\n\nconst isImageSpan = (child: HTMLElement) => {\n return (\n isNodeOfType(child.firstChild, 'ELEMENT_NODE') &&\n child.firstChild.tagName == 'IMG' &&\n child.firstChild == child.lastChild\n );\n};\n"]}
1
+ {"version":3,"file":"removeUnnecessarySpan.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/modelToDom/optimizers/removeUnnecessarySpan.ts"],"names":[],"mappings":";;;AAAA,4DAA2D;AAE3D;;GAEG;AACH,SAAgB,qBAAqB,CAAC,IAAU;IAC5C,KAAK,IAAI,KAAK,GAAG,IAAI,CAAC,UAAU,EAAE,KAAK,GAAI;QACvC,IACI,IAAA,2BAAY,EAAC,KAAK,EAAE,cAAc,CAAC;YACnC,KAAK,CAAC,OAAO,IAAI,MAAM;YACvB,KAAK,CAAC,UAAU,CAAC,MAAM,IAAI,CAAC,EAC9B;YACE,IAAM,IAAI,GAAG,KAAK,CAAC;YACnB,IAAI,OAAO,GAAG,KAAK,CAAC,WAAW,CAAC;YAChC,KAAK,GAAG,KAAK,CAAC,WAAW,CAAC;YAE1B,OAAO,IAAI,CAAC,SAAS,EAAE;gBACnB,IAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC;gBAC/B,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;gBACpC,OAAO,GAAG,OAAO,CAAC;aACrB;YAED,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;SAC1B;aAAM;YACH,KAAK,GAAG,KAAK,CAAC,WAAW,CAAC;SAC7B;KACJ;AACL,CAAC;AAtBD,sDAsBC","sourcesContent":["import { isNodeOfType } from '../../domUtils/isNodeOfType';\n\n/**\n * @internal\n */\nexport function removeUnnecessarySpan(root: Node) {\n for (let child = root.firstChild; child; ) {\n if (\n isNodeOfType(child, 'ELEMENT_NODE') &&\n child.tagName == 'SPAN' &&\n child.attributes.length == 0\n ) {\n const node = child;\n let refNode = child.nextSibling;\n child = child.nextSibling;\n\n while (node.lastChild) {\n const newNode = node.lastChild;\n root.insertBefore(newNode, refNode);\n refNode = newNode;\n }\n\n root.removeChild(node);\n } else {\n child = child.nextSibling;\n }\n }\n}\n"]}
@@ -8,16 +8,14 @@ define(["require", "exports", "../isNodeOfType", "../normalizeRect"], function (
8
8
  * @param pos The input DOM insert point
9
9
  */
10
10
  function getDOMInsertPointRect(doc, pos) {
11
- var _a;
12
- var node = pos.node, offset = pos.offset;
11
+ var _a, _b;
13
12
  var range = doc.createRange();
14
- range.setStart(node, offset);
15
- // 1) try to get rect using range.getBoundingClientRect()
16
- var rect = (0, normalizeRect_1.normalizeRect)(range.getBoundingClientRect());
17
- if (rect) {
18
- return rect;
19
- }
20
- // 2) try to get rect using range.getClientRects
13
+ return ((_b = (_a = tryGetRectFromPos(pos, range)) !== null && _a !== void 0 ? _a : tryGetRectFromPos((pos = normalizeInsertPoint(pos)), range)) !== null && _b !== void 0 ? _b : tryGetRectFromNode(pos.node) // 3. fallback to node rect using getBoundingClientRect
14
+ );
15
+ }
16
+ exports.getDOMInsertPointRect = getDOMInsertPointRect;
17
+ function normalizeInsertPoint(pos) {
18
+ var node = pos.node, offset = pos.offset;
21
19
  while (node.lastChild) {
22
20
  if (offset == node.childNodes.length) {
23
21
  node = node.lastChild;
@@ -28,31 +26,25 @@ define(["require", "exports", "../isNodeOfType", "../normalizeRect"], function (
28
26
  offset = 0;
29
27
  }
30
28
  }
31
- var rects = range.getClientRects && range.getClientRects();
32
- rect = rects && rects.length == 1 ? (0, normalizeRect_1.normalizeRect)(rects[0]) : null;
29
+ return { node: node, offset: offset };
30
+ }
31
+ function tryGetRectFromPos(pos, range) {
32
+ var node = pos.node, offset = pos.offset;
33
+ range.setStart(node, offset);
34
+ range.setEnd(node, offset);
35
+ var rect = (0, normalizeRect_1.normalizeRect)(range.getBoundingClientRect());
33
36
  if (rect) {
34
37
  return rect;
35
38
  }
36
- // 3) if node is text node, try inserting a SPAN and get the rect of SPAN for others
37
- if ((0, isNodeOfType_1.isNodeOfType)(node, 'TEXT_NODE')) {
38
- var span = node.ownerDocument.createElement('span');
39
- span.textContent = '\u200b';
40
- range.insertNode(span);
41
- rect = (0, normalizeRect_1.normalizeRect)(span.getBoundingClientRect());
42
- (_a = span.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(span);
43
- if (rect) {
44
- return rect;
45
- }
39
+ else {
40
+ var rects = range.getClientRects && range.getClientRects();
41
+ return rects && rects.length == 1 ? (0, normalizeRect_1.normalizeRect)(rects[0]) : null;
46
42
  }
47
- // 4) try getBoundingClientRect on element
48
- if ((0, isNodeOfType_1.isNodeOfType)(node, 'ELEMENT_NODE') && node.getBoundingClientRect) {
49
- rect = (0, normalizeRect_1.normalizeRect)(node.getBoundingClientRect());
50
- if (rect) {
51
- return rect;
52
- }
53
- }
54
- return null;
55
43
  }
56
- exports.getDOMInsertPointRect = getDOMInsertPointRect;
44
+ function tryGetRectFromNode(node) {
45
+ return (0, isNodeOfType_1.isNodeOfType)(node, 'ELEMENT_NODE') && node.getBoundingClientRect
46
+ ? (0, normalizeRect_1.normalizeRect)(node.getBoundingClientRect())
47
+ : null;
48
+ }
57
49
  });
58
50
  //# sourceMappingURL=getDOMInsertPointRect.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"getDOMInsertPointRect.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/domUtils/selection/getDOMInsertPointRect.ts"],"names":[],"mappings":";;;;IAIA;;;;OAIG;IACH,SAAgB,qBAAqB,CAAC,GAAa,EAAE,GAAmB;;QAC9D,IAAA,IAAI,GAAa,GAAG,KAAhB,EAAE,MAAM,GAAK,GAAG,OAAR,CAAS;QAC3B,IAAM,KAAK,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;QAEhC,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAE7B,yDAAyD;QACzD,IAAI,IAAI,GAAG,IAAA,6BAAa,EAAC,KAAK,CAAC,qBAAqB,EAAE,CAAC,CAAC;QAExD,IAAI,IAAI,EAAE;YACN,OAAO,IAAI,CAAC;SACf;QAED,gDAAgD;QAChD,OAAO,IAAI,CAAC,SAAS,EAAE;YACnB,IAAI,MAAM,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE;gBAClC,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC;gBACtB,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;aACnC;iBAAM;gBACH,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;gBAC/B,MAAM,GAAG,CAAC,CAAC;aACd;SACJ;QAED,IAAM,KAAK,GAAG,KAAK,CAAC,cAAc,IAAI,KAAK,CAAC,cAAc,EAAE,CAAC;QAC7D,IAAI,GAAG,KAAK,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,IAAA,6BAAa,EAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACnE,IAAI,IAAI,EAAE;YACN,OAAO,IAAI,CAAC;SACf;QAED,oFAAoF;QACpF,IAAI,IAAA,2BAAY,EAAC,IAAI,EAAE,WAAW,CAAC,EAAE;YACjC,IAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;YAEtD,IAAI,CAAC,WAAW,GAAG,QAAQ,CAAC;YAC5B,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YACvB,IAAI,GAAG,IAAA,6BAAa,EAAC,IAAI,CAAC,qBAAqB,EAAE,CAAC,CAAC;YACnD,MAAA,IAAI,CAAC,UAAU,0CAAE,WAAW,CAAC,IAAI,CAAC,CAAC;YAEnC,IAAI,IAAI,EAAE;gBACN,OAAO,IAAI,CAAC;aACf;SACJ;QAED,0CAA0C;QAC1C,IAAI,IAAA,2BAAY,EAAC,IAAI,EAAE,cAAc,CAAC,IAAI,IAAI,CAAC,qBAAqB,EAAE;YAClE,IAAI,GAAG,IAAA,6BAAa,EAAC,IAAI,CAAC,qBAAqB,EAAE,CAAC,CAAC;YAEnD,IAAI,IAAI,EAAE;gBACN,OAAO,IAAI,CAAC;aACf;SACJ;QAED,OAAO,IAAI,CAAC;IAChB,CAAC;IAtDD,sDAsDC","sourcesContent":["import { isNodeOfType } from '../isNodeOfType';\nimport { normalizeRect } from '../normalizeRect';\nimport type { DOMInsertPoint, Rect } from 'roosterjs-content-model-types';\n\n/**\n * Get bounding rect of the given DOM insert point\n * @param doc The document object\n * @param pos The input DOM insert point\n */\nexport function getDOMInsertPointRect(doc: Document, pos: DOMInsertPoint): Rect | null {\n let { node, offset } = pos;\n const range = doc.createRange();\n\n range.setStart(node, offset);\n\n // 1) try to get rect using range.getBoundingClientRect()\n let rect = normalizeRect(range.getBoundingClientRect());\n\n if (rect) {\n return rect;\n }\n\n // 2) try to get rect using range.getClientRects\n while (node.lastChild) {\n if (offset == node.childNodes.length) {\n node = node.lastChild;\n offset = node.childNodes.length;\n } else {\n node = node.childNodes[offset];\n offset = 0;\n }\n }\n\n const rects = range.getClientRects && range.getClientRects();\n rect = rects && rects.length == 1 ? normalizeRect(rects[0]) : null;\n if (rect) {\n return rect;\n }\n\n // 3) if node is text node, try inserting a SPAN and get the rect of SPAN for others\n if (isNodeOfType(node, 'TEXT_NODE')) {\n const span = node.ownerDocument.createElement('span');\n\n span.textContent = '\\u200b';\n range.insertNode(span);\n rect = normalizeRect(span.getBoundingClientRect());\n span.parentNode?.removeChild(span);\n\n if (rect) {\n return rect;\n }\n }\n\n // 4) try getBoundingClientRect on element\n if (isNodeOfType(node, 'ELEMENT_NODE') && node.getBoundingClientRect) {\n rect = normalizeRect(node.getBoundingClientRect());\n\n if (rect) {\n return rect;\n }\n }\n\n return null;\n}\n"]}
1
+ {"version":3,"file":"getDOMInsertPointRect.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/domUtils/selection/getDOMInsertPointRect.ts"],"names":[],"mappings":";;;;IAIA;;;;OAIG;IACH,SAAgB,qBAAqB,CAAC,GAAa,EAAE,GAAmB;;QACpE,IAAM,KAAK,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;QAEhC,OAAO,CACH,MAAA,MAAA,iBAAiB,CAAC,GAAG,EAAE,KAAK,CAAC,mCAC7B,iBAAiB,CAAC,CAAC,GAAG,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,mCAC3D,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,uDAAuD;SACvF,CAAC;IACN,CAAC;IARD,sDAQC;IAED,SAAS,oBAAoB,CAAC,GAAmB;QACvC,IAAA,IAAI,GAAa,GAAG,KAAhB,EAAE,MAAM,GAAK,GAAG,OAAR,CAAS;QAE3B,OAAO,IAAI,CAAC,SAAS,EAAE;YACnB,IAAI,MAAM,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE;gBAClC,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC;gBACtB,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;aACnC;iBAAM;gBACH,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;gBAC/B,MAAM,GAAG,CAAC,CAAC;aACd;SACJ;QAED,OAAO,EAAE,IAAI,MAAA,EAAE,MAAM,QAAA,EAAE,CAAC;IAC5B,CAAC;IAED,SAAS,iBAAiB,CAAC,GAAmB,EAAE,KAAY;QAChD,IAAA,IAAI,GAAa,GAAG,KAAhB,EAAE,MAAM,GAAK,GAAG,OAAR,CAAS;QAE7B,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC7B,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAE3B,IAAM,IAAI,GAAG,IAAA,6BAAa,EAAC,KAAK,CAAC,qBAAqB,EAAE,CAAC,CAAC;QAE1D,IAAI,IAAI,EAAE;YACN,OAAO,IAAI,CAAC;SACf;aAAM;YACH,IAAM,KAAK,GAAG,KAAK,CAAC,cAAc,IAAI,KAAK,CAAC,cAAc,EAAE,CAAC;YAE7D,OAAO,KAAK,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,IAAA,6BAAa,EAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;SACtE;IACL,CAAC;IAED,SAAS,kBAAkB,CAAC,IAAU;QAClC,OAAO,IAAA,2BAAY,EAAC,IAAI,EAAE,cAAc,CAAC,IAAI,IAAI,CAAC,qBAAqB;YACnE,CAAC,CAAC,IAAA,6BAAa,EAAC,IAAI,CAAC,qBAAqB,EAAE,CAAC;YAC7C,CAAC,CAAC,IAAI,CAAC;IACf,CAAC","sourcesContent":["import { isNodeOfType } from '../isNodeOfType';\nimport { normalizeRect } from '../normalizeRect';\nimport type { DOMInsertPoint, Rect } from 'roosterjs-content-model-types';\n\n/**\n * Get bounding rect of the given DOM insert point\n * @param doc The document object\n * @param pos The input DOM insert point\n */\nexport function getDOMInsertPointRect(doc: Document, pos: DOMInsertPoint): Rect | null {\n const range = doc.createRange();\n\n return (\n tryGetRectFromPos(pos, range) ?? // 1. try get from the pos directly using getBoundingClientRect or getClientRects\n tryGetRectFromPos((pos = normalizeInsertPoint(pos)), range) ?? // 2. try get normalized pos, this can work when insert point is inside text node\n tryGetRectFromNode(pos.node) // 3. fallback to node rect using getBoundingClientRect\n );\n}\n\nfunction normalizeInsertPoint(pos: DOMInsertPoint) {\n let { node, offset } = pos;\n\n while (node.lastChild) {\n if (offset == node.childNodes.length) {\n node = node.lastChild;\n offset = node.childNodes.length;\n } else {\n node = node.childNodes[offset];\n offset = 0;\n }\n }\n\n return { node, offset };\n}\n\nfunction tryGetRectFromPos(pos: DOMInsertPoint, range: Range): Rect | null {\n const { node, offset } = pos;\n\n range.setStart(node, offset);\n range.setEnd(node, offset);\n\n const rect = normalizeRect(range.getBoundingClientRect());\n\n if (rect) {\n return rect;\n } else {\n const rects = range.getClientRects && range.getClientRects();\n\n return rects && rects.length == 1 ? normalizeRect(rects[0]) : null;\n }\n}\n\nfunction tryGetRectFromNode(node: Node) {\n return isNodeOfType(node, 'ELEMENT_NODE') && node.getBoundingClientRect\n ? normalizeRect(node.getBoundingClientRect())\n : null;\n}\n"]}
@@ -9,8 +9,7 @@ define(["require", "exports", "../../domUtils/isNodeOfType"], function (require,
9
9
  for (var child = root.firstChild; child;) {
10
10
  if ((0, isNodeOfType_1.isNodeOfType)(child, 'ELEMENT_NODE') &&
11
11
  child.tagName == 'SPAN' &&
12
- child.attributes.length == 0 &&
13
- !isImageSpan(child)) {
12
+ child.attributes.length == 0) {
14
13
  var node = child;
15
14
  var refNode = child.nextSibling;
16
15
  child = child.nextSibling;
@@ -27,10 +26,5 @@ define(["require", "exports", "../../domUtils/isNodeOfType"], function (require,
27
26
  }
28
27
  }
29
28
  exports.removeUnnecessarySpan = removeUnnecessarySpan;
30
- var isImageSpan = function (child) {
31
- return ((0, isNodeOfType_1.isNodeOfType)(child.firstChild, 'ELEMENT_NODE') &&
32
- child.firstChild.tagName == 'IMG' &&
33
- child.firstChild == child.lastChild);
34
- };
35
29
  });
36
30
  //# sourceMappingURL=removeUnnecessarySpan.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"removeUnnecessarySpan.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/modelToDom/optimizers/removeUnnecessarySpan.ts"],"names":[],"mappings":";;;;IAEA;;OAEG;IACH,SAAgB,qBAAqB,CAAC,IAAU;QAC5C,KAAK,IAAI,KAAK,GAAG,IAAI,CAAC,UAAU,EAAE,KAAK,GAAI;YACvC,IACI,IAAA,2BAAY,EAAC,KAAK,EAAE,cAAc,CAAC;gBACnC,KAAK,CAAC,OAAO,IAAI,MAAM;gBACvB,KAAK,CAAC,UAAU,CAAC,MAAM,IAAI,CAAC;gBAC5B,CAAC,WAAW,CAAC,KAAK,CAAC,EACrB;gBACE,IAAM,IAAI,GAAG,KAAK,CAAC;gBACnB,IAAI,OAAO,GAAG,KAAK,CAAC,WAAW,CAAC;gBAChC,KAAK,GAAG,KAAK,CAAC,WAAW,CAAC;gBAE1B,OAAO,IAAI,CAAC,SAAS,EAAE;oBACnB,IAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC;oBAC/B,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;oBACpC,OAAO,GAAG,OAAO,CAAC;iBACrB;gBAED,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;aAC1B;iBAAM;gBACH,KAAK,GAAG,KAAK,CAAC,WAAW,CAAC;aAC7B;SACJ;IACL,CAAC;IAvBD,sDAuBC;IAED,IAAM,WAAW,GAAG,UAAC,KAAkB;QACnC,OAAO,CACH,IAAA,2BAAY,EAAC,KAAK,CAAC,UAAU,EAAE,cAAc,CAAC;YAC9C,KAAK,CAAC,UAAU,CAAC,OAAO,IAAI,KAAK;YACjC,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,SAAS,CACtC,CAAC;IACN,CAAC,CAAC","sourcesContent":["import { isNodeOfType } from '../../domUtils/isNodeOfType';\n\n/**\n * @internal\n */\nexport function removeUnnecessarySpan(root: Node) {\n for (let child = root.firstChild; child; ) {\n if (\n isNodeOfType(child, 'ELEMENT_NODE') &&\n child.tagName == 'SPAN' &&\n child.attributes.length == 0 &&\n !isImageSpan(child)\n ) {\n const node = child;\n let refNode = child.nextSibling;\n child = child.nextSibling;\n\n while (node.lastChild) {\n const newNode = node.lastChild;\n root.insertBefore(newNode, refNode);\n refNode = newNode;\n }\n\n root.removeChild(node);\n } else {\n child = child.nextSibling;\n }\n }\n}\n\nconst isImageSpan = (child: HTMLElement) => {\n return (\n isNodeOfType(child.firstChild, 'ELEMENT_NODE') &&\n child.firstChild.tagName == 'IMG' &&\n child.firstChild == child.lastChild\n );\n};\n"]}
1
+ {"version":3,"file":"removeUnnecessarySpan.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/modelToDom/optimizers/removeUnnecessarySpan.ts"],"names":[],"mappings":";;;;IAEA;;OAEG;IACH,SAAgB,qBAAqB,CAAC,IAAU;QAC5C,KAAK,IAAI,KAAK,GAAG,IAAI,CAAC,UAAU,EAAE,KAAK,GAAI;YACvC,IACI,IAAA,2BAAY,EAAC,KAAK,EAAE,cAAc,CAAC;gBACnC,KAAK,CAAC,OAAO,IAAI,MAAM;gBACvB,KAAK,CAAC,UAAU,CAAC,MAAM,IAAI,CAAC,EAC9B;gBACE,IAAM,IAAI,GAAG,KAAK,CAAC;gBACnB,IAAI,OAAO,GAAG,KAAK,CAAC,WAAW,CAAC;gBAChC,KAAK,GAAG,KAAK,CAAC,WAAW,CAAC;gBAE1B,OAAO,IAAI,CAAC,SAAS,EAAE;oBACnB,IAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC;oBAC/B,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;oBACpC,OAAO,GAAG,OAAO,CAAC;iBACrB;gBAED,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;aAC1B;iBAAM;gBACH,KAAK,GAAG,KAAK,CAAC,WAAW,CAAC;aAC7B;SACJ;IACL,CAAC;IAtBD,sDAsBC","sourcesContent":["import { isNodeOfType } from '../../domUtils/isNodeOfType';\n\n/**\n * @internal\n */\nexport function removeUnnecessarySpan(root: Node) {\n for (let child = root.firstChild; child; ) {\n if (\n isNodeOfType(child, 'ELEMENT_NODE') &&\n child.tagName == 'SPAN' &&\n child.attributes.length == 0\n ) {\n const node = child;\n let refNode = child.nextSibling;\n child = child.nextSibling;\n\n while (node.lastChild) {\n const newNode = node.lastChild;\n root.insertBefore(newNode, refNode);\n refNode = newNode;\n }\n\n root.removeChild(node);\n } else {\n child = child.nextSibling;\n }\n }\n}\n"]}
@@ -6,16 +6,13 @@ import { normalizeRect } from '../normalizeRect';
6
6
  * @param pos The input DOM insert point
7
7
  */
8
8
  export function getDOMInsertPointRect(doc, pos) {
9
- var _a;
10
- var node = pos.node, offset = pos.offset;
9
+ var _a, _b;
11
10
  var range = doc.createRange();
12
- range.setStart(node, offset);
13
- // 1) try to get rect using range.getBoundingClientRect()
14
- var rect = normalizeRect(range.getBoundingClientRect());
15
- if (rect) {
16
- return rect;
17
- }
18
- // 2) try to get rect using range.getClientRects
11
+ return ((_b = (_a = tryGetRectFromPos(pos, range)) !== null && _a !== void 0 ? _a : tryGetRectFromPos((pos = normalizeInsertPoint(pos)), range)) !== null && _b !== void 0 ? _b : tryGetRectFromNode(pos.node) // 3. fallback to node rect using getBoundingClientRect
12
+ );
13
+ }
14
+ function normalizeInsertPoint(pos) {
15
+ var node = pos.node, offset = pos.offset;
19
16
  while (node.lastChild) {
20
17
  if (offset == node.childNodes.length) {
21
18
  node = node.lastChild;
@@ -26,29 +23,24 @@ export function getDOMInsertPointRect(doc, pos) {
26
23
  offset = 0;
27
24
  }
28
25
  }
29
- var rects = range.getClientRects && range.getClientRects();
30
- rect = rects && rects.length == 1 ? normalizeRect(rects[0]) : null;
26
+ return { node: node, offset: offset };
27
+ }
28
+ function tryGetRectFromPos(pos, range) {
29
+ var node = pos.node, offset = pos.offset;
30
+ range.setStart(node, offset);
31
+ range.setEnd(node, offset);
32
+ var rect = normalizeRect(range.getBoundingClientRect());
31
33
  if (rect) {
32
34
  return rect;
33
35
  }
34
- // 3) if node is text node, try inserting a SPAN and get the rect of SPAN for others
35
- if (isNodeOfType(node, 'TEXT_NODE')) {
36
- var span = node.ownerDocument.createElement('span');
37
- span.textContent = '\u200b';
38
- range.insertNode(span);
39
- rect = normalizeRect(span.getBoundingClientRect());
40
- (_a = span.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(span);
41
- if (rect) {
42
- return rect;
43
- }
44
- }
45
- // 4) try getBoundingClientRect on element
46
- if (isNodeOfType(node, 'ELEMENT_NODE') && node.getBoundingClientRect) {
47
- rect = normalizeRect(node.getBoundingClientRect());
48
- if (rect) {
49
- return rect;
50
- }
36
+ else {
37
+ var rects = range.getClientRects && range.getClientRects();
38
+ return rects && rects.length == 1 ? normalizeRect(rects[0]) : null;
51
39
  }
52
- return null;
40
+ }
41
+ function tryGetRectFromNode(node) {
42
+ return isNodeOfType(node, 'ELEMENT_NODE') && node.getBoundingClientRect
43
+ ? normalizeRect(node.getBoundingClientRect())
44
+ : null;
53
45
  }
54
46
  //# sourceMappingURL=getDOMInsertPointRect.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"getDOMInsertPointRect.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/domUtils/selection/getDOMInsertPointRect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGjD;;;;GAIG;AACH,MAAM,UAAU,qBAAqB,CAAC,GAAa,EAAE,GAAmB;;IAC9D,IAAA,IAAI,GAAa,GAAG,KAAhB,EAAE,MAAM,GAAK,GAAG,OAAR,CAAS;IAC3B,IAAM,KAAK,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;IAEhC,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAE7B,yDAAyD;IACzD,IAAI,IAAI,GAAG,aAAa,CAAC,KAAK,CAAC,qBAAqB,EAAE,CAAC,CAAC;IAExD,IAAI,IAAI,EAAE;QACN,OAAO,IAAI,CAAC;KACf;IAED,gDAAgD;IAChD,OAAO,IAAI,CAAC,SAAS,EAAE;QACnB,IAAI,MAAM,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE;YAClC,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC;YACtB,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;SACnC;aAAM;YACH,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;YAC/B,MAAM,GAAG,CAAC,CAAC;SACd;KACJ;IAED,IAAM,KAAK,GAAG,KAAK,CAAC,cAAc,IAAI,KAAK,CAAC,cAAc,EAAE,CAAC;IAC7D,IAAI,GAAG,KAAK,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACnE,IAAI,IAAI,EAAE;QACN,OAAO,IAAI,CAAC;KACf;IAED,oFAAoF;IACpF,IAAI,YAAY,CAAC,IAAI,EAAE,WAAW,CAAC,EAAE;QACjC,IAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAEtD,IAAI,CAAC,WAAW,GAAG,QAAQ,CAAC;QAC5B,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACvB,IAAI,GAAG,aAAa,CAAC,IAAI,CAAC,qBAAqB,EAAE,CAAC,CAAC;QACnD,MAAA,IAAI,CAAC,UAAU,0CAAE,WAAW,CAAC,IAAI,CAAC,CAAC;QAEnC,IAAI,IAAI,EAAE;YACN,OAAO,IAAI,CAAC;SACf;KACJ;IAED,0CAA0C;IAC1C,IAAI,YAAY,CAAC,IAAI,EAAE,cAAc,CAAC,IAAI,IAAI,CAAC,qBAAqB,EAAE;QAClE,IAAI,GAAG,aAAa,CAAC,IAAI,CAAC,qBAAqB,EAAE,CAAC,CAAC;QAEnD,IAAI,IAAI,EAAE;YACN,OAAO,IAAI,CAAC;SACf;KACJ;IAED,OAAO,IAAI,CAAC;AAChB,CAAC","sourcesContent":["import { isNodeOfType } from '../isNodeOfType';\nimport { normalizeRect } from '../normalizeRect';\nimport type { DOMInsertPoint, Rect } from 'roosterjs-content-model-types';\n\n/**\n * Get bounding rect of the given DOM insert point\n * @param doc The document object\n * @param pos The input DOM insert point\n */\nexport function getDOMInsertPointRect(doc: Document, pos: DOMInsertPoint): Rect | null {\n let { node, offset } = pos;\n const range = doc.createRange();\n\n range.setStart(node, offset);\n\n // 1) try to get rect using range.getBoundingClientRect()\n let rect = normalizeRect(range.getBoundingClientRect());\n\n if (rect) {\n return rect;\n }\n\n // 2) try to get rect using range.getClientRects\n while (node.lastChild) {\n if (offset == node.childNodes.length) {\n node = node.lastChild;\n offset = node.childNodes.length;\n } else {\n node = node.childNodes[offset];\n offset = 0;\n }\n }\n\n const rects = range.getClientRects && range.getClientRects();\n rect = rects && rects.length == 1 ? normalizeRect(rects[0]) : null;\n if (rect) {\n return rect;\n }\n\n // 3) if node is text node, try inserting a SPAN and get the rect of SPAN for others\n if (isNodeOfType(node, 'TEXT_NODE')) {\n const span = node.ownerDocument.createElement('span');\n\n span.textContent = '\\u200b';\n range.insertNode(span);\n rect = normalizeRect(span.getBoundingClientRect());\n span.parentNode?.removeChild(span);\n\n if (rect) {\n return rect;\n }\n }\n\n // 4) try getBoundingClientRect on element\n if (isNodeOfType(node, 'ELEMENT_NODE') && node.getBoundingClientRect) {\n rect = normalizeRect(node.getBoundingClientRect());\n\n if (rect) {\n return rect;\n }\n }\n\n return null;\n}\n"]}
1
+ {"version":3,"file":"getDOMInsertPointRect.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/domUtils/selection/getDOMInsertPointRect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGjD;;;;GAIG;AACH,MAAM,UAAU,qBAAqB,CAAC,GAAa,EAAE,GAAmB;;IACpE,IAAM,KAAK,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;IAEhC,OAAO,CACH,MAAA,MAAA,iBAAiB,CAAC,GAAG,EAAE,KAAK,CAAC,mCAC7B,iBAAiB,CAAC,CAAC,GAAG,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,mCAC3D,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,uDAAuD;KACvF,CAAC;AACN,CAAC;AAED,SAAS,oBAAoB,CAAC,GAAmB;IACvC,IAAA,IAAI,GAAa,GAAG,KAAhB,EAAE,MAAM,GAAK,GAAG,OAAR,CAAS;IAE3B,OAAO,IAAI,CAAC,SAAS,EAAE;QACnB,IAAI,MAAM,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE;YAClC,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC;YACtB,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;SACnC;aAAM;YACH,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;YAC/B,MAAM,GAAG,CAAC,CAAC;SACd;KACJ;IAED,OAAO,EAAE,IAAI,MAAA,EAAE,MAAM,QAAA,EAAE,CAAC;AAC5B,CAAC;AAED,SAAS,iBAAiB,CAAC,GAAmB,EAAE,KAAY;IAChD,IAAA,IAAI,GAAa,GAAG,KAAhB,EAAE,MAAM,GAAK,GAAG,OAAR,CAAS;IAE7B,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC7B,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAE3B,IAAM,IAAI,GAAG,aAAa,CAAC,KAAK,CAAC,qBAAqB,EAAE,CAAC,CAAC;IAE1D,IAAI,IAAI,EAAE;QACN,OAAO,IAAI,CAAC;KACf;SAAM;QACH,IAAM,KAAK,GAAG,KAAK,CAAC,cAAc,IAAI,KAAK,CAAC,cAAc,EAAE,CAAC;QAE7D,OAAO,KAAK,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;KACtE;AACL,CAAC;AAED,SAAS,kBAAkB,CAAC,IAAU;IAClC,OAAO,YAAY,CAAC,IAAI,EAAE,cAAc,CAAC,IAAI,IAAI,CAAC,qBAAqB;QACnE,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAC7C,CAAC,CAAC,IAAI,CAAC;AACf,CAAC","sourcesContent":["import { isNodeOfType } from '../isNodeOfType';\nimport { normalizeRect } from '../normalizeRect';\nimport type { DOMInsertPoint, Rect } from 'roosterjs-content-model-types';\n\n/**\n * Get bounding rect of the given DOM insert point\n * @param doc The document object\n * @param pos The input DOM insert point\n */\nexport function getDOMInsertPointRect(doc: Document, pos: DOMInsertPoint): Rect | null {\n const range = doc.createRange();\n\n return (\n tryGetRectFromPos(pos, range) ?? // 1. try get from the pos directly using getBoundingClientRect or getClientRects\n tryGetRectFromPos((pos = normalizeInsertPoint(pos)), range) ?? // 2. try get normalized pos, this can work when insert point is inside text node\n tryGetRectFromNode(pos.node) // 3. fallback to node rect using getBoundingClientRect\n );\n}\n\nfunction normalizeInsertPoint(pos: DOMInsertPoint) {\n let { node, offset } = pos;\n\n while (node.lastChild) {\n if (offset == node.childNodes.length) {\n node = node.lastChild;\n offset = node.childNodes.length;\n } else {\n node = node.childNodes[offset];\n offset = 0;\n }\n }\n\n return { node, offset };\n}\n\nfunction tryGetRectFromPos(pos: DOMInsertPoint, range: Range): Rect | null {\n const { node, offset } = pos;\n\n range.setStart(node, offset);\n range.setEnd(node, offset);\n\n const rect = normalizeRect(range.getBoundingClientRect());\n\n if (rect) {\n return rect;\n } else {\n const rects = range.getClientRects && range.getClientRects();\n\n return rects && rects.length == 1 ? normalizeRect(rects[0]) : null;\n }\n}\n\nfunction tryGetRectFromNode(node: Node) {\n return isNodeOfType(node, 'ELEMENT_NODE') && node.getBoundingClientRect\n ? normalizeRect(node.getBoundingClientRect())\n : null;\n}\n"]}
@@ -6,8 +6,7 @@ export function removeUnnecessarySpan(root) {
6
6
  for (var child = root.firstChild; child;) {
7
7
  if (isNodeOfType(child, 'ELEMENT_NODE') &&
8
8
  child.tagName == 'SPAN' &&
9
- child.attributes.length == 0 &&
10
- !isImageSpan(child)) {
9
+ child.attributes.length == 0) {
11
10
  var node = child;
12
11
  var refNode = child.nextSibling;
13
12
  child = child.nextSibling;
@@ -23,9 +22,4 @@ export function removeUnnecessarySpan(root) {
23
22
  }
24
23
  }
25
24
  }
26
- var isImageSpan = function (child) {
27
- return (isNodeOfType(child.firstChild, 'ELEMENT_NODE') &&
28
- child.firstChild.tagName == 'IMG' &&
29
- child.firstChild == child.lastChild);
30
- };
31
25
  //# sourceMappingURL=removeUnnecessarySpan.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"removeUnnecessarySpan.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/modelToDom/optimizers/removeUnnecessarySpan.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAE3D;;GAEG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAAU;IAC5C,KAAK,IAAI,KAAK,GAAG,IAAI,CAAC,UAAU,EAAE,KAAK,GAAI;QACvC,IACI,YAAY,CAAC,KAAK,EAAE,cAAc,CAAC;YACnC,KAAK,CAAC,OAAO,IAAI,MAAM;YACvB,KAAK,CAAC,UAAU,CAAC,MAAM,IAAI,CAAC;YAC5B,CAAC,WAAW,CAAC,KAAK,CAAC,EACrB;YACE,IAAM,IAAI,GAAG,KAAK,CAAC;YACnB,IAAI,OAAO,GAAG,KAAK,CAAC,WAAW,CAAC;YAChC,KAAK,GAAG,KAAK,CAAC,WAAW,CAAC;YAE1B,OAAO,IAAI,CAAC,SAAS,EAAE;gBACnB,IAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC;gBAC/B,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;gBACpC,OAAO,GAAG,OAAO,CAAC;aACrB;YAED,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;SAC1B;aAAM;YACH,KAAK,GAAG,KAAK,CAAC,WAAW,CAAC;SAC7B;KACJ;AACL,CAAC;AAED,IAAM,WAAW,GAAG,UAAC,KAAkB;IACnC,OAAO,CACH,YAAY,CAAC,KAAK,CAAC,UAAU,EAAE,cAAc,CAAC;QAC9C,KAAK,CAAC,UAAU,CAAC,OAAO,IAAI,KAAK;QACjC,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,SAAS,CACtC,CAAC;AACN,CAAC,CAAC","sourcesContent":["import { isNodeOfType } from '../../domUtils/isNodeOfType';\n\n/**\n * @internal\n */\nexport function removeUnnecessarySpan(root: Node) {\n for (let child = root.firstChild; child; ) {\n if (\n isNodeOfType(child, 'ELEMENT_NODE') &&\n child.tagName == 'SPAN' &&\n child.attributes.length == 0 &&\n !isImageSpan(child)\n ) {\n const node = child;\n let refNode = child.nextSibling;\n child = child.nextSibling;\n\n while (node.lastChild) {\n const newNode = node.lastChild;\n root.insertBefore(newNode, refNode);\n refNode = newNode;\n }\n\n root.removeChild(node);\n } else {\n child = child.nextSibling;\n }\n }\n}\n\nconst isImageSpan = (child: HTMLElement) => {\n return (\n isNodeOfType(child.firstChild, 'ELEMENT_NODE') &&\n child.firstChild.tagName == 'IMG' &&\n child.firstChild == child.lastChild\n );\n};\n"]}
1
+ {"version":3,"file":"removeUnnecessarySpan.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/modelToDom/optimizers/removeUnnecessarySpan.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAE3D;;GAEG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAAU;IAC5C,KAAK,IAAI,KAAK,GAAG,IAAI,CAAC,UAAU,EAAE,KAAK,GAAI;QACvC,IACI,YAAY,CAAC,KAAK,EAAE,cAAc,CAAC;YACnC,KAAK,CAAC,OAAO,IAAI,MAAM;YACvB,KAAK,CAAC,UAAU,CAAC,MAAM,IAAI,CAAC,EAC9B;YACE,IAAM,IAAI,GAAG,KAAK,CAAC;YACnB,IAAI,OAAO,GAAG,KAAK,CAAC,WAAW,CAAC;YAChC,KAAK,GAAG,KAAK,CAAC,WAAW,CAAC;YAE1B,OAAO,IAAI,CAAC,SAAS,EAAE;gBACnB,IAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC;gBAC/B,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;gBACpC,OAAO,GAAG,OAAO,CAAC;aACrB;YAED,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;SAC1B;aAAM;YACH,KAAK,GAAG,KAAK,CAAC,WAAW,CAAC;SAC7B;KACJ;AACL,CAAC","sourcesContent":["import { isNodeOfType } from '../../domUtils/isNodeOfType';\n\n/**\n * @internal\n */\nexport function removeUnnecessarySpan(root: Node) {\n for (let child = root.firstChild; child; ) {\n if (\n isNodeOfType(child, 'ELEMENT_NODE') &&\n child.tagName == 'SPAN' &&\n child.attributes.length == 0\n ) {\n const node = child;\n let refNode = child.nextSibling;\n child = child.nextSibling;\n\n while (node.lastChild) {\n const newNode = node.lastChild;\n root.insertBefore(newNode, refNode);\n refNode = newNode;\n }\n\n root.removeChild(node);\n } else {\n child = child.nextSibling;\n }\n }\n}\n"]}
package/package.json CHANGED
@@ -3,9 +3,9 @@
3
3
  "description": "Content Model for roosterjs",
4
4
  "dependencies": {
5
5
  "tslib": "^2.3.1",
6
- "roosterjs-content-model-types": "^9.6.0"
6
+ "roosterjs-content-model-types": "^9.8.0"
7
7
  },
8
- "version": "9.6.0",
8
+ "version": "9.8.0",
9
9
  "main": "./lib/index.js",
10
10
  "typings": "./lib/index.d.ts",
11
11
  "module": "./lib-mjs/index.js",