@progress/kendo-editor-common 1.11.10-develop.2 → 1.12.0-develop.1
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.
- package/dist/cdn/js/kendo-editor-common.js +1 -1
- package/dist/cdn/main.js +1 -1
- package/dist/es/flatten-spans.js +109 -0
- package/dist/es/main.js +1 -0
- package/dist/es2015/flatten-spans.js +109 -0
- package/dist/es2015/main.js +1 -0
- package/dist/npm/flatten-spans.d.ts +10 -0
- package/dist/npm/flatten-spans.js +111 -0
- package/dist/npm/main.d.ts +1 -0
- package/dist/npm/main.js +2 -0
- package/package.json +2 -2
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { htmlToFragment, fragmentToHtml } from './source.js';
|
|
2
|
+
|
|
3
|
+
class DomTreeExtractor {
|
|
4
|
+
constructor(top) {
|
|
5
|
+
this.extractBefore = (edgeNode) => {
|
|
6
|
+
return this._traverseSide({
|
|
7
|
+
edge: edgeNode,
|
|
8
|
+
next: function (node) {
|
|
9
|
+
return node.previousSibling;
|
|
10
|
+
},
|
|
11
|
+
insert: function (fragment, node) {
|
|
12
|
+
fragment.insertBefore(node, fragment.firstChild);
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
};
|
|
16
|
+
this.extractAfter = (edgeNode) => {
|
|
17
|
+
return this._traverseSide({
|
|
18
|
+
edge: edgeNode,
|
|
19
|
+
next: function (node) {
|
|
20
|
+
return node.nextSibling;
|
|
21
|
+
},
|
|
22
|
+
insert: function (fragment, node) {
|
|
23
|
+
fragment.appendChild(node);
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
this._traverseSide = (options) => {
|
|
28
|
+
const top = this.top, doc = top.ownerDocument, fragment = doc.createDocumentFragment();
|
|
29
|
+
let current = options.edge;
|
|
30
|
+
do {
|
|
31
|
+
const parentNode = current.parentNode;
|
|
32
|
+
current = options.next(current);
|
|
33
|
+
while (current) {
|
|
34
|
+
const next = options.next(current);
|
|
35
|
+
options.insert(fragment, current);
|
|
36
|
+
current = next;
|
|
37
|
+
}
|
|
38
|
+
if (top === parentNode || top.contains(parentNode)) {
|
|
39
|
+
const container = parentNode.cloneNode(false);
|
|
40
|
+
container.innerHTML = '';
|
|
41
|
+
container.appendChild(fragment);
|
|
42
|
+
options.insert(fragment, container);
|
|
43
|
+
}
|
|
44
|
+
current = parentNode;
|
|
45
|
+
} while (current && current !== top);
|
|
46
|
+
return fragment;
|
|
47
|
+
};
|
|
48
|
+
this.top = top;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
const getInnerSpan = (dom) => {
|
|
52
|
+
return dom.querySelector('span span');
|
|
53
|
+
};
|
|
54
|
+
const isEmptySpan = (fragment) => {
|
|
55
|
+
var _a;
|
|
56
|
+
return fragment.childNodes.length === 1 && ((_a = fragment.firstChild) === null || _a === void 0 ? void 0 : _a.nodeName) === 'SPAN' && fragment.firstChild.childNodes.length === 0;
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* Flattens nested <span> elements in the given HTML string while preserving
|
|
60
|
+
* the original styling and formatting.
|
|
61
|
+
*
|
|
62
|
+
* @param content - The HTML content to normalize.
|
|
63
|
+
* @returns The normalized HTML content with flattened <span> elements.
|
|
64
|
+
*/
|
|
65
|
+
const flattenNestedSpans = (content) => {
|
|
66
|
+
var _a, _b, _c;
|
|
67
|
+
const dom = htmlToFragment(content);
|
|
68
|
+
let innerSpan = getInnerSpan(dom);
|
|
69
|
+
while (innerSpan) {
|
|
70
|
+
const parentSpan = innerSpan.parentNode.closest('span');
|
|
71
|
+
if (parentSpan) {
|
|
72
|
+
const extractor = new DomTreeExtractor(parentSpan);
|
|
73
|
+
const right = extractor.extractAfter(innerSpan);
|
|
74
|
+
const left = extractor.extractBefore(innerSpan);
|
|
75
|
+
for (let i = 0; i < innerSpan.style.length; i++) {
|
|
76
|
+
parentSpan.style[innerSpan.style.item(i)] = innerSpan.style[innerSpan.style.item(i)];
|
|
77
|
+
}
|
|
78
|
+
innerSpan.removeAttribute('style');
|
|
79
|
+
if (innerSpan.classList.length) {
|
|
80
|
+
Array.from(innerSpan.classList).forEach((classValue) => {
|
|
81
|
+
if (!parentSpan.classList.contains(classValue)) {
|
|
82
|
+
parentSpan.classList.add(classValue);
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
innerSpan.removeAttribute('class');
|
|
87
|
+
for (let index = 0; index < innerSpan.attributes.length; index++) {
|
|
88
|
+
const attr = innerSpan.attributes.item(index);
|
|
89
|
+
if (attr && attr.nodeValue !== null) {
|
|
90
|
+
parentSpan.setAttribute(attr.nodeName, attr.nodeValue);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
while (innerSpan.firstChild && innerSpan.parentNode) {
|
|
94
|
+
innerSpan.parentNode.insertBefore(innerSpan.firstChild, innerSpan);
|
|
95
|
+
}
|
|
96
|
+
(_a = innerSpan.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(innerSpan);
|
|
97
|
+
if (!isEmptySpan(left)) {
|
|
98
|
+
(_b = parentSpan.parentNode) === null || _b === void 0 ? void 0 : _b.insertBefore(left, parentSpan);
|
|
99
|
+
}
|
|
100
|
+
if (!isEmptySpan(right)) {
|
|
101
|
+
(_c = parentSpan.parentNode) === null || _c === void 0 ? void 0 : _c.insertBefore(right, parentSpan.nextSibling);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
innerSpan = getInnerSpan(dom);
|
|
105
|
+
}
|
|
106
|
+
return fragmentToHtml(dom);
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
export { flattenNestedSpans };
|
package/dist/es2015/main.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { domToPmDoc, fragmentToHtml, getHtml, hasSameMarkup, htmlToFragment, parseContent, pmDocToFragment, setHtml, trimWhitespace } from './source.js';
|
|
2
|
+
export { flattenNestedSpans } from './flatten-spans.js';
|
|
2
3
|
export { applyInlineStyle, getInlineStyles, toggleInlineFormat } from './inline-style.js';
|
|
3
4
|
export { applyLink, removeLink } from './link.js';
|
|
4
5
|
export { insertText } from './text.js';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Flattens nested <span> elements in the given HTML string while preserving
|
|
3
|
+
* the original styling and formatting.
|
|
4
|
+
*
|
|
5
|
+
* @param content - The HTML content to normalize.
|
|
6
|
+
* @returns The normalized HTML content with flattened <span> elements.
|
|
7
|
+
*/
|
|
8
|
+
declare const flattenNestedSpans: (content: string) => string;
|
|
9
|
+
|
|
10
|
+
export { flattenNestedSpans };
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var source = require('./source.js');
|
|
4
|
+
|
|
5
|
+
class DomTreeExtractor {
|
|
6
|
+
constructor(top) {
|
|
7
|
+
this.extractBefore = (edgeNode) => {
|
|
8
|
+
return this._traverseSide({
|
|
9
|
+
edge: edgeNode,
|
|
10
|
+
next: function (node) {
|
|
11
|
+
return node.previousSibling;
|
|
12
|
+
},
|
|
13
|
+
insert: function (fragment, node) {
|
|
14
|
+
fragment.insertBefore(node, fragment.firstChild);
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
};
|
|
18
|
+
this.extractAfter = (edgeNode) => {
|
|
19
|
+
return this._traverseSide({
|
|
20
|
+
edge: edgeNode,
|
|
21
|
+
next: function (node) {
|
|
22
|
+
return node.nextSibling;
|
|
23
|
+
},
|
|
24
|
+
insert: function (fragment, node) {
|
|
25
|
+
fragment.appendChild(node);
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
this._traverseSide = (options) => {
|
|
30
|
+
const top = this.top, doc = top.ownerDocument, fragment = doc.createDocumentFragment();
|
|
31
|
+
let current = options.edge;
|
|
32
|
+
do {
|
|
33
|
+
const parentNode = current.parentNode;
|
|
34
|
+
current = options.next(current);
|
|
35
|
+
while (current) {
|
|
36
|
+
const next = options.next(current);
|
|
37
|
+
options.insert(fragment, current);
|
|
38
|
+
current = next;
|
|
39
|
+
}
|
|
40
|
+
if (top === parentNode || top.contains(parentNode)) {
|
|
41
|
+
const container = parentNode.cloneNode(false);
|
|
42
|
+
container.innerHTML = '';
|
|
43
|
+
container.appendChild(fragment);
|
|
44
|
+
options.insert(fragment, container);
|
|
45
|
+
}
|
|
46
|
+
current = parentNode;
|
|
47
|
+
} while (current && current !== top);
|
|
48
|
+
return fragment;
|
|
49
|
+
};
|
|
50
|
+
this.top = top;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
const getInnerSpan = (dom) => {
|
|
54
|
+
return dom.querySelector('span span');
|
|
55
|
+
};
|
|
56
|
+
const isEmptySpan = (fragment) => {
|
|
57
|
+
var _a;
|
|
58
|
+
return fragment.childNodes.length === 1 && ((_a = fragment.firstChild) === null || _a === void 0 ? void 0 : _a.nodeName) === 'SPAN' && fragment.firstChild.childNodes.length === 0;
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Flattens nested <span> elements in the given HTML string while preserving
|
|
62
|
+
* the original styling and formatting.
|
|
63
|
+
*
|
|
64
|
+
* @param content - The HTML content to normalize.
|
|
65
|
+
* @returns The normalized HTML content with flattened <span> elements.
|
|
66
|
+
*/
|
|
67
|
+
const flattenNestedSpans = (content) => {
|
|
68
|
+
var _a, _b, _c;
|
|
69
|
+
const dom = source.htmlToFragment(content);
|
|
70
|
+
let innerSpan = getInnerSpan(dom);
|
|
71
|
+
while (innerSpan) {
|
|
72
|
+
const parentSpan = innerSpan.parentNode.closest('span');
|
|
73
|
+
if (parentSpan) {
|
|
74
|
+
const extractor = new DomTreeExtractor(parentSpan);
|
|
75
|
+
const right = extractor.extractAfter(innerSpan);
|
|
76
|
+
const left = extractor.extractBefore(innerSpan);
|
|
77
|
+
for (let i = 0; i < innerSpan.style.length; i++) {
|
|
78
|
+
parentSpan.style[innerSpan.style.item(i)] = innerSpan.style[innerSpan.style.item(i)];
|
|
79
|
+
}
|
|
80
|
+
innerSpan.removeAttribute('style');
|
|
81
|
+
if (innerSpan.classList.length) {
|
|
82
|
+
Array.from(innerSpan.classList).forEach((classValue) => {
|
|
83
|
+
if (!parentSpan.classList.contains(classValue)) {
|
|
84
|
+
parentSpan.classList.add(classValue);
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
innerSpan.removeAttribute('class');
|
|
89
|
+
for (let index = 0; index < innerSpan.attributes.length; index++) {
|
|
90
|
+
const attr = innerSpan.attributes.item(index);
|
|
91
|
+
if (attr && attr.nodeValue !== null) {
|
|
92
|
+
parentSpan.setAttribute(attr.nodeName, attr.nodeValue);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
while (innerSpan.firstChild && innerSpan.parentNode) {
|
|
96
|
+
innerSpan.parentNode.insertBefore(innerSpan.firstChild, innerSpan);
|
|
97
|
+
}
|
|
98
|
+
(_a = innerSpan.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(innerSpan);
|
|
99
|
+
if (!isEmptySpan(left)) {
|
|
100
|
+
(_b = parentSpan.parentNode) === null || _b === void 0 ? void 0 : _b.insertBefore(left, parentSpan);
|
|
101
|
+
}
|
|
102
|
+
if (!isEmptySpan(right)) {
|
|
103
|
+
(_c = parentSpan.parentNode) === null || _c === void 0 ? void 0 : _c.insertBefore(right, parentSpan.nextSibling);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
innerSpan = getInnerSpan(dom);
|
|
107
|
+
}
|
|
108
|
+
return source.fragmentToHtml(dom);
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
exports.flattenNestedSpans = flattenNestedSpans;
|
package/dist/npm/main.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { domToPmDoc, fragmentToHtml, getHtml, hasSameMarkup, htmlToFragment, parseContent, pmDocToFragment, setHtml, trimWhitespace } from './source.js';
|
|
2
|
+
export { flattenNestedSpans } from './flatten-spans.js';
|
|
2
3
|
export { applyInlineStyle, getInlineStyles, toggleInlineFormat } from './inline-style.js';
|
|
3
4
|
export { applyLink, removeLink } from './link.js';
|
|
4
5
|
export { insertText } from './text.js';
|
package/dist/npm/main.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var source = require('./source.js');
|
|
4
|
+
var flattenSpans = require('./flatten-spans.js');
|
|
4
5
|
var inlineStyle = require('./inline-style.js');
|
|
5
6
|
var link = require('./link.js');
|
|
6
7
|
var text = require('./text.js');
|
|
@@ -55,6 +56,7 @@ exports.parseContent = source.parseContent;
|
|
|
55
56
|
exports.pmDocToFragment = source.pmDocToFragment;
|
|
56
57
|
exports.setHtml = source.setHtml;
|
|
57
58
|
exports.trimWhitespace = source.trimWhitespace;
|
|
59
|
+
exports.flattenNestedSpans = flattenSpans.flattenNestedSpans;
|
|
58
60
|
exports.applyInlineStyle = inlineStyle.applyInlineStyle;
|
|
59
61
|
exports.getInlineStyles = inlineStyle.getInlineStyles;
|
|
60
62
|
exports.toggleInlineFormat = inlineStyle.toggleInlineFormat;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@progress/kendo-editor-common",
|
|
3
3
|
"description": "Kendo UI TypeScript package exporting functions for Editor component",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.12.0-develop.1",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Kendo UI"
|
|
7
7
|
],
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"prosemirror-model": "1.24.1",
|
|
35
35
|
"prosemirror-schema-list": "1.5.0",
|
|
36
36
|
"prosemirror-state": "1.4.3",
|
|
37
|
-
"prosemirror-tables": "1.6.
|
|
37
|
+
"prosemirror-tables": "1.6.2",
|
|
38
38
|
"prosemirror-transform": "1.10.2",
|
|
39
39
|
"prosemirror-view": "1.37.1",
|
|
40
40
|
"tslib": "^2.8.1"
|