@progress/kendo-editor-common 1.12.7 → 1.12.8-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/paste.js +49 -1
- package/dist/es/plugins/table-resize/table-resize.js +1 -2
- package/dist/es/source.js +1 -2
- package/dist/npm/paste.js +49 -1
- package/dist/npm/plugins/table-resize/table-resize.js +1 -2
- package/dist/npm/source.js +1 -2
- package/package.json +17 -13
package/dist/es/paste.js
CHANGED
|
@@ -1,11 +1,59 @@
|
|
|
1
1
|
import { convertMsLists } from './listConvert';
|
|
2
2
|
import { fragmentToHtml, htmlToFragment } from './source';
|
|
3
3
|
import { parseStyle } from './utils';
|
|
4
|
+
const unwrapStyleComment = (css) => css
|
|
5
|
+
.replace(/^\s*<!--/, '')
|
|
6
|
+
.replace(/--(?:!?)>\s*$/, '');
|
|
7
|
+
const parseStyleSheet = (css) => {
|
|
8
|
+
const sheet = new CSSStyleSheet();
|
|
9
|
+
sheet.replaceSync(css);
|
|
10
|
+
return sheet.cssRules;
|
|
11
|
+
};
|
|
12
|
+
const extractStyles = (html) => Array.from(html.matchAll(/<style\b[^>]*>([\s\S]*?)<\/style>/gi))
|
|
13
|
+
.map(match => unwrapStyleComment(match[1]))
|
|
14
|
+
.join('\n');
|
|
15
|
+
const reSpreadsheetContent = /<body\b[^>]*>([\s\S]*?<table\b[\s\S]*?<!--StartFragment-->[\s\S]*?<!--EndFragment-->[\s\S]*?<\/table>[\s\S]*?)<\/body>/i;
|
|
16
|
+
const applyCssRulesInline = (fragment, cssRules) => {
|
|
17
|
+
if (!cssRules) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
fragment.querySelectorAll('*').forEach(element => {
|
|
21
|
+
const currentStyle = Array.from(element.style).map(property => ({
|
|
22
|
+
property,
|
|
23
|
+
value: element.style.getPropertyValue(property),
|
|
24
|
+
priority: element.style.getPropertyPriority(property)
|
|
25
|
+
}));
|
|
26
|
+
Array.from(cssRules).forEach(rule => {
|
|
27
|
+
if (rule instanceof CSSStyleRule &&
|
|
28
|
+
element.matches(rule.selectorText)) {
|
|
29
|
+
Array.from(rule.style).forEach(property => {
|
|
30
|
+
element.style.setProperty(property, rule.style.getPropertyValue(property), rule.style.getPropertyPriority(property));
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
currentStyle.forEach(({ property, value, priority }) => {
|
|
35
|
+
element.style.setProperty(property, value, priority);
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
};
|
|
4
39
|
/**
|
|
5
40
|
* Removes the invalid HTML. Use it as a first step for cleaning the HTML.
|
|
6
41
|
*/
|
|
7
42
|
export const sanitize = (html) => {
|
|
8
|
-
|
|
43
|
+
const bodyWithTableFragment = html.match(reSpreadsheetContent);
|
|
44
|
+
if (bodyWithTableFragment) {
|
|
45
|
+
const trimmed = bodyWithTableFragment[1]
|
|
46
|
+
.replace(/<!--StartFragment-->/gi, '')
|
|
47
|
+
.replace(/<!--EndFragment-->/gi, '');
|
|
48
|
+
const tableFragment = htmlToFragment(trimmed);
|
|
49
|
+
const css = extractStyles(html);
|
|
50
|
+
const cssRules = parseStyleSheet(css);
|
|
51
|
+
applyCssRulesInline(tableFragment, cssRules);
|
|
52
|
+
html = fragmentToHtml(tableFragment);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
html = html.replace(/^[\s\S]+?<!--StartFragment-->\s*([\s\S]*?)\s*<!--EndFragment-->[\s\S]+$/, '$1');
|
|
56
|
+
}
|
|
9
57
|
html = html.replace(/<\/?[ovw]:[^>]*?>/gi, ''); // MS elements, e.g. <o:p>, <w:sdtPr>, <v:
|
|
10
58
|
html = html.replace(/<\\?\??xml[^>]*>/gi, ''); // XML namespaces
|
|
11
59
|
html = html.replace(/<(?:link|meta) [^>]+?>/ig, '');
|
|
@@ -35,7 +35,6 @@ class ResizeState {
|
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
const handleMouseMove = (view, event) => {
|
|
38
|
-
var _a;
|
|
39
38
|
const state = key.getState(view.state);
|
|
40
39
|
const { dragging, nodePosition, activeHandle } = state;
|
|
41
40
|
if (nodePosition < 0 || !dragging) {
|
|
@@ -61,7 +60,7 @@ const handleMouseMove = (view, event) => {
|
|
|
61
60
|
tableDom.style.height = height + 'px';
|
|
62
61
|
}
|
|
63
62
|
if (/px/.test(tableDom.style.width)) {
|
|
64
|
-
const wrapper =
|
|
63
|
+
const wrapper = tableDom.parentNode?.parentNode;
|
|
65
64
|
if (wrapper instanceof HTMLDivElement && wrapper.matches('div[table]') && /%/.test(wrapper.style.width)) {
|
|
66
65
|
wrapper.style.width = '';
|
|
67
66
|
}
|
package/dist/es/source.js
CHANGED
|
@@ -238,11 +238,10 @@ export const removeComments = (html) => {
|
|
|
238
238
|
return fragmentToHtml(fragment);
|
|
239
239
|
};
|
|
240
240
|
const removeCommentsFromDom = (dom) => {
|
|
241
|
-
var _a;
|
|
242
241
|
const iterator = dom.ownerDocument.createNodeIterator(dom, NodeFilter.SHOW_COMMENT);
|
|
243
242
|
let commentNode = iterator.nextNode();
|
|
244
243
|
while (commentNode) {
|
|
245
|
-
|
|
244
|
+
commentNode.parentNode?.removeChild(commentNode);
|
|
246
245
|
commentNode = iterator.nextNode();
|
|
247
246
|
}
|
|
248
247
|
};
|
package/dist/npm/paste.js
CHANGED
|
@@ -4,11 +4,59 @@ exports.replaceImageSourcesFromRtf = exports.pasteCleanup = exports.sanitizeStyl
|
|
|
4
4
|
const listConvert_1 = require("./listConvert");
|
|
5
5
|
const source_1 = require("./source");
|
|
6
6
|
const utils_1 = require("./utils");
|
|
7
|
+
const unwrapStyleComment = (css) => css
|
|
8
|
+
.replace(/^\s*<!--/, '')
|
|
9
|
+
.replace(/--(?:!?)>\s*$/, '');
|
|
10
|
+
const parseStyleSheet = (css) => {
|
|
11
|
+
const sheet = new CSSStyleSheet();
|
|
12
|
+
sheet.replaceSync(css);
|
|
13
|
+
return sheet.cssRules;
|
|
14
|
+
};
|
|
15
|
+
const extractStyles = (html) => Array.from(html.matchAll(/<style\b[^>]*>([\s\S]*?)<\/style>/gi))
|
|
16
|
+
.map(match => unwrapStyleComment(match[1]))
|
|
17
|
+
.join('\n');
|
|
18
|
+
const reSpreadsheetContent = /<body\b[^>]*>([\s\S]*?<table\b[\s\S]*?<!--StartFragment-->[\s\S]*?<!--EndFragment-->[\s\S]*?<\/table>[\s\S]*?)<\/body>/i;
|
|
19
|
+
const applyCssRulesInline = (fragment, cssRules) => {
|
|
20
|
+
if (!cssRules) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
fragment.querySelectorAll('*').forEach(element => {
|
|
24
|
+
const currentStyle = Array.from(element.style).map(property => ({
|
|
25
|
+
property,
|
|
26
|
+
value: element.style.getPropertyValue(property),
|
|
27
|
+
priority: element.style.getPropertyPriority(property)
|
|
28
|
+
}));
|
|
29
|
+
Array.from(cssRules).forEach(rule => {
|
|
30
|
+
if (rule instanceof CSSStyleRule &&
|
|
31
|
+
element.matches(rule.selectorText)) {
|
|
32
|
+
Array.from(rule.style).forEach(property => {
|
|
33
|
+
element.style.setProperty(property, rule.style.getPropertyValue(property), rule.style.getPropertyPriority(property));
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
currentStyle.forEach(({ property, value, priority }) => {
|
|
38
|
+
element.style.setProperty(property, value, priority);
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
};
|
|
7
42
|
/**
|
|
8
43
|
* Removes the invalid HTML. Use it as a first step for cleaning the HTML.
|
|
9
44
|
*/
|
|
10
45
|
const sanitize = (html) => {
|
|
11
|
-
|
|
46
|
+
const bodyWithTableFragment = html.match(reSpreadsheetContent);
|
|
47
|
+
if (bodyWithTableFragment) {
|
|
48
|
+
const trimmed = bodyWithTableFragment[1]
|
|
49
|
+
.replace(/<!--StartFragment-->/gi, '')
|
|
50
|
+
.replace(/<!--EndFragment-->/gi, '');
|
|
51
|
+
const tableFragment = (0, source_1.htmlToFragment)(trimmed);
|
|
52
|
+
const css = extractStyles(html);
|
|
53
|
+
const cssRules = parseStyleSheet(css);
|
|
54
|
+
applyCssRulesInline(tableFragment, cssRules);
|
|
55
|
+
html = (0, source_1.fragmentToHtml)(tableFragment);
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
html = html.replace(/^[\s\S]+?<!--StartFragment-->\s*([\s\S]*?)\s*<!--EndFragment-->[\s\S]+$/, '$1');
|
|
59
|
+
}
|
|
12
60
|
html = html.replace(/<\/?[ovw]:[^>]*?>/gi, ''); // MS elements, e.g. <o:p>, <w:sdtPr>, <v:
|
|
13
61
|
html = html.replace(/<\\?\??xml[^>]*>/gi, ''); // XML namespaces
|
|
14
62
|
html = html.replace(/<(?:link|meta) [^>]+?>/ig, '');
|
|
@@ -38,7 +38,6 @@ class ResizeState {
|
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
const handleMouseMove = (view, event) => {
|
|
41
|
-
var _a;
|
|
42
41
|
const state = utils_1.tableResizeKey.getState(view.state);
|
|
43
42
|
const { dragging, nodePosition, activeHandle } = state;
|
|
44
43
|
if (nodePosition < 0 || !dragging) {
|
|
@@ -64,7 +63,7 @@ const handleMouseMove = (view, event) => {
|
|
|
64
63
|
tableDom.style.height = height + 'px';
|
|
65
64
|
}
|
|
66
65
|
if (/px/.test(tableDom.style.width)) {
|
|
67
|
-
const wrapper =
|
|
66
|
+
const wrapper = tableDom.parentNode?.parentNode;
|
|
68
67
|
if (wrapper instanceof HTMLDivElement && wrapper.matches('div[table]') && /%/.test(wrapper.style.width)) {
|
|
69
68
|
wrapper.style.width = '';
|
|
70
69
|
}
|
package/dist/npm/source.js
CHANGED
|
@@ -251,11 +251,10 @@ const removeComments = (html) => {
|
|
|
251
251
|
};
|
|
252
252
|
exports.removeComments = removeComments;
|
|
253
253
|
const removeCommentsFromDom = (dom) => {
|
|
254
|
-
var _a;
|
|
255
254
|
const iterator = dom.ownerDocument.createNodeIterator(dom, NodeFilter.SHOW_COMMENT);
|
|
256
255
|
let commentNode = iterator.nextNode();
|
|
257
256
|
while (commentNode) {
|
|
258
|
-
|
|
257
|
+
commentNode.parentNode?.removeChild(commentNode);
|
|
259
258
|
commentNode = iterator.nextNode();
|
|
260
259
|
}
|
|
261
260
|
};
|
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.12.
|
|
4
|
+
"version": "1.12.8-develop.1",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Kendo UI"
|
|
7
7
|
],
|
|
@@ -15,10 +15,14 @@
|
|
|
15
15
|
"scripts": {
|
|
16
16
|
"start": "vite --config vite.config.playground.ts",
|
|
17
17
|
"start:e2e": "vite --config vite.config.e2e.ts",
|
|
18
|
-
"test:ci": "
|
|
19
|
-
"test": "
|
|
20
|
-
"e2e": "
|
|
21
|
-
"e2e-visual:test": "
|
|
18
|
+
"test:ci": "vitest run",
|
|
19
|
+
"test": "vitest run",
|
|
20
|
+
"e2e": "vitest run --config ./vitest.e2e.config.ts",
|
|
21
|
+
"e2e-visual:test": "vitest run --config ./vitest.e2e-visual.config.ts",
|
|
22
|
+
"coverage:all": "npm run coverage:clean && (npm run coverage:run-tests; npm run coverage:html)",
|
|
23
|
+
"coverage:clean": "rm -rf coverage coverage-html",
|
|
24
|
+
"coverage:run-tests": "COLLECT_COVERAGE=true vitest run",
|
|
25
|
+
"coverage:html": "node tools/generate-coverage-html.mjs",
|
|
22
26
|
"e2e-visual": "./tools/run-e2e-visual",
|
|
23
27
|
"lint": "eslint .",
|
|
24
28
|
"build": "gulp build",
|
|
@@ -48,20 +52,20 @@
|
|
|
48
52
|
"@progress/kendo-package-tasks": "dev",
|
|
49
53
|
"@progress/kendo-typescript-tasks": "dev",
|
|
50
54
|
"@telerik/dx-metrics": "^2.1.8",
|
|
51
|
-
"@
|
|
52
|
-
"es-jest": "^2.1.0",
|
|
55
|
+
"@vitest/coverage-v8": "^3.2.7",
|
|
53
56
|
"eslint": "^9.3.0",
|
|
54
57
|
"eslint-config-prettier": "^9.1.0",
|
|
55
|
-
"eslint-plugin-jest": "^28.5.0",
|
|
56
58
|
"eslint-plugin-prettier": "^5.1.3",
|
|
59
|
+
"eslint-plugin-vitest": "^0.5.4",
|
|
57
60
|
"husky": "^9.1.7",
|
|
58
|
-
"
|
|
59
|
-
"
|
|
60
|
-
"
|
|
61
|
-
"
|
|
61
|
+
"istanbul-lib-coverage": "^3.2.2",
|
|
62
|
+
"istanbul-lib-report": "^3.0.1",
|
|
63
|
+
"istanbul-reports": "^3.2.0",
|
|
64
|
+
"jsdom": "^25.0.1",
|
|
62
65
|
"typescript": "^5.7.2",
|
|
63
66
|
"typescript-eslint": "^8.12.2",
|
|
64
|
-
"vite": "^6.3.5"
|
|
67
|
+
"vite": "^6.3.5",
|
|
68
|
+
"vitest": "^3.2.7"
|
|
65
69
|
},
|
|
66
70
|
"repository": {
|
|
67
71
|
"type": "git",
|