@progress/kendo-editor-common 1.12.2-develop.5 → 1.12.2-develop.7
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/DOMSerializer.js +6 -7
- package/dist/es/align.js +3 -6
- package/dist/es/blockNode.js +11 -14
- package/dist/es/blockquote.js +2 -5
- package/dist/es/cleanFormatting.js +3 -6
- package/dist/es/config/align-rules.js +5 -7
- package/dist/es/config/commands.js +13 -9
- package/dist/es/config/constants.js +7 -9
- package/dist/es/config/indent-rules.js +3 -6
- package/dist/es/config/keymap.js +7 -10
- package/dist/es/config/list-settings.js +3 -5
- package/dist/es/config/schema.js +4 -6
- package/dist/es/find-replace.js +8 -10
- package/dist/es/flatten-spans.js +2 -5
- package/dist/es/image.js +2 -5
- package/dist/es/indent.js +11 -14
- package/dist/es/inline-style.js +10 -12
- package/dist/es/link.js +5 -8
- package/dist/es/listConvert.js +8 -9
- package/dist/es/lists.js +12 -15
- package/dist/es/main.js +34 -33
- package/dist/es/mark.js +16 -17
- package/dist/es/paste.js +10 -13
- package/dist/es/plugins/caret-color.js +5 -8
- package/dist/es/plugins/csp-fix.js +2 -5
- package/dist/es/plugins/highlight.js +3 -6
- package/dist/es/plugins/image-resize.js +8 -11
- package/dist/es/plugins/list-markers-styles.js +2 -5
- package/dist/es/plugins/placeholder.js +2 -5
- package/dist/es/plugins/resize-utils.js +2 -4
- package/dist/es/plugins/spaces-fix.js +1 -4
- package/dist/es/plugins/table-resize/column-resize.js +21 -24
- package/dist/es/plugins/table-resize/index.js +6 -9
- package/dist/es/plugins/table-resize/row-resize.js +23 -24
- package/dist/es/plugins/table-resize/table-resize.js +17 -20
- package/dist/es/plugins/table-resize/table-view.js +6 -9
- package/dist/es/plugins/table-resize/utils.js +10 -13
- package/dist/es/source.js +15 -18
- package/dist/es/table.js +15 -18
- package/dist/es/text.js +1 -3
- package/dist/es/types/active-marks.js +1 -0
- package/dist/es/types/command.js +1 -0
- package/dist/es/types/dispatchFn.js +1 -0
- package/dist/es/types/paste-cleanup-settings.js +1 -0
- package/dist/es/types/predicate.js +1 -0
- package/dist/es/utils.js +18 -21
- package/dist/npm/DOMSerializer.d.ts +35 -0
- package/dist/npm/DOMSerializer.js +10 -9
- package/dist/npm/align.d.ts +4 -7
- package/dist/npm/align.js +9 -10
- package/dist/npm/blockNode.d.ts +15 -12
- package/dist/npm/blockNode.js +28 -29
- package/dist/npm/blockquote.d.ts +2 -5
- package/dist/npm/blockquote.js +6 -7
- package/dist/npm/cleanFormatting.d.ts +3 -6
- package/dist/npm/cleanFormatting.js +7 -8
- package/dist/npm/config/align-rules.d.ts +6 -8
- package/dist/npm/config/align-rules.js +8 -13
- package/dist/npm/config/commands.d.ts +19 -11
- package/dist/npm/config/commands.js +16 -17
- package/dist/npm/config/constants.d.ts +7 -0
- package/dist/npm/config/constants.js +10 -17
- package/dist/npm/config/indent-rules.d.ts +4 -6
- package/dist/npm/config/indent-rules.js +8 -11
- package/dist/npm/config/keymap.d.ts +2 -5
- package/dist/npm/config/keymap.js +21 -22
- package/dist/npm/config/list-settings.d.ts +30 -0
- package/dist/npm/config/list-settings.js +10 -13
- package/dist/npm/config/schema.d.ts +2 -3
- package/dist/npm/config/schema.js +19 -20
- package/dist/npm/find-replace.d.ts +7 -10
- package/dist/npm/find-replace.js +20 -20
- package/dist/npm/flatten-spans.d.ts +1 -3
- package/dist/npm/flatten-spans.js +6 -7
- package/dist/npm/image.d.ts +3 -6
- package/dist/npm/image.js +5 -6
- package/dist/npm/indent.d.ts +9 -12
- package/dist/npm/indent.js +37 -38
- package/dist/npm/inline-style.d.ts +4 -7
- package/dist/npm/inline-style.js +28 -28
- package/dist/npm/link.d.ts +2 -4
- package/dist/npm/link.js +21 -22
- package/dist/npm/listConvert.d.ts +1 -3
- package/dist/npm/listConvert.js +13 -12
- package/dist/npm/lists.d.ts +8 -8
- package/dist/npm/lists.js +26 -27
- package/dist/npm/main.d.ts +34 -35
- package/dist/npm/main.js +214 -391
- package/dist/npm/mark.d.ts +17 -12
- package/dist/npm/mark.js +30 -29
- package/dist/npm/paste.d.ts +8 -11
- package/dist/npm/paste.js +19 -20
- package/dist/npm/plugins/caret-color.d.ts +2 -5
- package/dist/npm/plugins/caret-color.js +15 -17
- package/dist/npm/plugins/csp-fix.d.ts +1 -4
- package/dist/npm/plugins/csp-fix.js +8 -9
- package/dist/npm/plugins/highlight.d.ts +4 -7
- package/dist/npm/plugins/highlight.js +11 -13
- package/dist/npm/plugins/image-resize.d.ts +5 -7
- package/dist/npm/plugins/image-resize.js +35 -37
- package/dist/npm/plugins/list-markers-styles.d.ts +2 -5
- package/dist/npm/plugins/list-markers-styles.js +14 -16
- package/dist/npm/plugins/placeholder.d.ts +1 -4
- package/dist/npm/plugins/placeholder.js +10 -12
- package/dist/npm/plugins/resize-utils.d.ts +35 -0
- package/dist/npm/plugins/resize-utils.js +5 -7
- package/dist/npm/plugins/spaces-fix.d.ts +1 -4
- package/dist/npm/plugins/spaces-fix.js +9 -10
- package/dist/npm/plugins/table-resize/column-resize.d.ts +2 -0
- package/dist/npm/plugins/table-resize/column-resize.js +44 -46
- package/dist/npm/plugins/table-resize/index.d.ts +2 -5
- package/dist/npm/plugins/table-resize/index.js +13 -14
- package/dist/npm/plugins/table-resize/row-resize.d.ts +2 -0
- package/dist/npm/plugins/table-resize/row-resize.js +40 -40
- package/dist/npm/plugins/table-resize/table-resize.d.ts +18 -0
- package/dist/npm/plugins/table-resize/table-resize.js +51 -52
- package/dist/npm/plugins/table-resize/table-view.d.ts +28 -0
- package/dist/npm/plugins/table-resize/table-view.js +23 -24
- package/dist/npm/plugins/table-resize/utils.d.ts +17 -7
- package/dist/npm/plugins/table-resize/utils.js +24 -28
- package/dist/npm/source.d.ts +13 -16
- package/dist/npm/source.js +35 -36
- package/dist/npm/table.d.ts +9 -10
- package/dist/npm/table.js +33 -49
- package/dist/npm/text.d.ts +3 -6
- package/dist/npm/text.js +3 -3
- package/dist/npm/types/active-marks.d.ts +1 -4
- package/dist/npm/types/active-marks.js +2 -0
- package/dist/npm/types/command.d.ts +2 -5
- package/dist/npm/types/command.js +2 -0
- package/dist/npm/types/dispatchFn.d.ts +1 -4
- package/dist/npm/types/dispatchFn.js +2 -0
- package/dist/npm/types/paste-cleanup-settings.d.ts +1 -3
- package/dist/npm/types/paste-cleanup-settings.js +2 -0
- package/dist/npm/types/predicate.d.ts +1 -0
- package/dist/npm/types/predicate.js +2 -0
- package/dist/npm/utils.d.ts +33 -14
- package/dist/npm/utils.js +38 -39
- package/package.json +4 -51
- package/dist/es2015/DOMSerializer.js +0 -184
- package/dist/es2015/align.js +0 -43
- package/dist/es2015/blockNode.js +0 -180
- package/dist/es2015/blockquote.js +0 -26
- package/dist/es2015/cleanFormatting.js +0 -20
- package/dist/es2015/config/align-rules.js +0 -30
- package/dist/es2015/config/commands.js +0 -50
- package/dist/es2015/config/constants.js +0 -9
- package/dist/es2015/config/indent-rules.js +0 -42
- package/dist/es2015/config/keymap.js +0 -51
- package/dist/es2015/config/list-settings.js +0 -21
- package/dist/es2015/config/schema.js +0 -314
- package/dist/es2015/find-replace.js +0 -122
- package/dist/es2015/flatten-spans.js +0 -112
- package/dist/es2015/image.js +0 -10
- package/dist/es2015/indent.js +0 -105
- package/dist/es2015/inline-style.js +0 -177
- package/dist/es2015/link.js +0 -105
- package/dist/es2015/listConvert.js +0 -184
- package/dist/es2015/lists.js +0 -266
- package/dist/es2015/main.js +0 -44
- package/dist/es2015/mark.js +0 -239
- package/dist/es2015/node_modules/tslib/tslib.es6.js +0 -35
- package/dist/es2015/paste.js +0 -162
- package/dist/es2015/plugins/caret-color.js +0 -34
- package/dist/es2015/plugins/csp-fix.js +0 -51
- package/dist/es2015/plugins/highlight.js +0 -23
- package/dist/es2015/plugins/image-resize.js +0 -225
- package/dist/es2015/plugins/list-markers-styles.js +0 -104
- package/dist/es2015/plugins/placeholder.js +0 -27
- package/dist/es2015/plugins/resize-utils.js +0 -13
- package/dist/es2015/plugins/spaces-fix.js +0 -46
- package/dist/es2015/plugins/table-resize/column-resize.js +0 -267
- package/dist/es2015/plugins/table-resize/index.js +0 -12
- package/dist/es2015/plugins/table-resize/row-resize.js +0 -234
- package/dist/es2015/plugins/table-resize/table-resize.js +0 -278
- package/dist/es2015/plugins/table-resize/table-view.js +0 -128
- package/dist/es2015/plugins/table-resize/utils.js +0 -93
- package/dist/es2015/source.js +0 -251
- package/dist/es2015/table.js +0 -132
- package/dist/es2015/text.js +0 -5
- package/dist/es2015/utils.js +0 -289
package/dist/es2015/paste.js
DELETED
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
import { convertMsLists } from './listConvert.js';
|
|
2
|
-
import { htmlToFragment, fragmentToHtml } from './source.js';
|
|
3
|
-
import { parseStyle } from './utils.js';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Removes the invalid HTML. Use it as a first step for cleaning the HTML.
|
|
7
|
-
*/
|
|
8
|
-
const sanitize = (html) => {
|
|
9
|
-
html = html.replace(/^[\s\S]+?<!--StartFragment-->\s*([\s\S]*?)\s*<!--EndFragment-->[\s\S]+$/, '$1');
|
|
10
|
-
html = html.replace(/<\/?[ovw]:[^>]*?>/gi, ''); // MS elements, e.g. <o:p>, <w:sdtPr>, <v:
|
|
11
|
-
html = html.replace(/<\\?\??xml[^>]*>/gi, ''); // XML namespaces
|
|
12
|
-
html = html.replace(/<(?:link|meta) [^>]+?>/ig, '');
|
|
13
|
-
let previousHtml;
|
|
14
|
-
do {
|
|
15
|
-
previousHtml = html;
|
|
16
|
-
html = html.replace(/<style[^>]*?>\s*<\/style>/ig, '');
|
|
17
|
-
} while (html !== previousHtml);
|
|
18
|
-
html = html.replace(/<\/?st1:.*?>/gi, '');
|
|
19
|
-
html = html.replace(/<a name="[a-zA-Z0-9_]+">/gmi, '');
|
|
20
|
-
html = html.replace(/v:shapes?="[^"]+"/ig, '');
|
|
21
|
-
html = html.replace(/<!\[if !supportLists\]>/ig, '');
|
|
22
|
-
html = html.replace(/<!\[endif\]>/ig, '');
|
|
23
|
-
return html;
|
|
24
|
-
};
|
|
25
|
-
/**
|
|
26
|
-
* Removes the specified tag(s).
|
|
27
|
-
*/
|
|
28
|
-
const removeTag = (html, tagPattern) => {
|
|
29
|
-
return html.replace(new RegExp('<\\/?(' + tagPattern + ')(?:\\s[^>]*?)?>', 'gi'), '');
|
|
30
|
-
};
|
|
31
|
-
/**
|
|
32
|
-
* Removes the passed attribute.
|
|
33
|
-
*/
|
|
34
|
-
const removeAttribute = (attr) => {
|
|
35
|
-
if (attr.ownerElement) {
|
|
36
|
-
attr.ownerElement.removeAttribute(attr.name);
|
|
37
|
-
}
|
|
38
|
-
};
|
|
39
|
-
/**
|
|
40
|
-
* Remove the attribute if its value matches /^Mso/ regex.
|
|
41
|
-
*/
|
|
42
|
-
const sanitizeClassAttr = (attr) => {
|
|
43
|
-
if (/^Mso/.test(attr.value)) {
|
|
44
|
-
removeAttribute(attr);
|
|
45
|
-
}
|
|
46
|
-
};
|
|
47
|
-
/**
|
|
48
|
-
* Removes invalid HTML styles.
|
|
49
|
-
*/
|
|
50
|
-
const sanitizeStyleAttr = (attr) => {
|
|
51
|
-
const styles = parseStyle(attr.value);
|
|
52
|
-
const element = attr.ownerElement;
|
|
53
|
-
const supportedStyles = element.style;
|
|
54
|
-
let result = '';
|
|
55
|
-
Object.keys(styles).forEach(name => {
|
|
56
|
-
if (supportedStyles[name] !== undefined) {
|
|
57
|
-
result += `${name}: ${styles[name]}; `;
|
|
58
|
-
}
|
|
59
|
-
});
|
|
60
|
-
result = result.trim();
|
|
61
|
-
if (result) {
|
|
62
|
-
attr.value = result;
|
|
63
|
-
}
|
|
64
|
-
else {
|
|
65
|
-
removeAttribute(attr);
|
|
66
|
-
}
|
|
67
|
-
};
|
|
68
|
-
const removeNode = (node) => {
|
|
69
|
-
const parentNode = node.parentNode;
|
|
70
|
-
if (parentNode) {
|
|
71
|
-
while (node.firstChild) {
|
|
72
|
-
parentNode.insertBefore(node.firstChild, node);
|
|
73
|
-
}
|
|
74
|
-
parentNode.removeChild(node);
|
|
75
|
-
}
|
|
76
|
-
};
|
|
77
|
-
const sanitizeNode = (node, attributes) => {
|
|
78
|
-
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
79
|
-
for (let i = node.attributes.length - 1; i >= 0; i--) {
|
|
80
|
-
const attr = node.attributes[i];
|
|
81
|
-
if (attributes[attr.name]) {
|
|
82
|
-
attributes[attr.name](attr);
|
|
83
|
-
}
|
|
84
|
-
else if (attributes['*']) {
|
|
85
|
-
attributes['*'](attr);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
if (node.nodeName === 'SPAN' && node.attributes.length === 0) {
|
|
89
|
-
removeNode(node);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
};
|
|
93
|
-
/**
|
|
94
|
-
* Cleans the HTML based on passed settings.
|
|
95
|
-
* Before using it, clean the HTML with the `sanitize` function.
|
|
96
|
-
*/
|
|
97
|
-
const pasteCleanup = (html, settings) => {
|
|
98
|
-
let result = html;
|
|
99
|
-
if (settings.convertMsLists) {
|
|
100
|
-
result = convertMsLists(result);
|
|
101
|
-
}
|
|
102
|
-
if (settings.stripTags) {
|
|
103
|
-
result = removeTag(result, settings.stripTags);
|
|
104
|
-
}
|
|
105
|
-
if (settings.attributes) {
|
|
106
|
-
const fragment = htmlToFragment(result);
|
|
107
|
-
Array.from(fragment.querySelectorAll('*')).forEach(node => sanitizeNode(node, settings.attributes));
|
|
108
|
-
result = fragmentToHtml(fragment);
|
|
109
|
-
}
|
|
110
|
-
return result;
|
|
111
|
-
};
|
|
112
|
-
function convertHexToBase64(hex) {
|
|
113
|
-
const length = hex.length;
|
|
114
|
-
const data = new Array(length / 2);
|
|
115
|
-
for (let i = 0; i < length; i += 2) {
|
|
116
|
-
data[i] = String.fromCharCode(parseInt(hex.substring(i, i + 2), 16));
|
|
117
|
-
}
|
|
118
|
-
return btoa(data.join(''));
|
|
119
|
-
}
|
|
120
|
-
const reHtmlImg = /<img\s[^>]*?src=(?:'|")file:\/[^'"]+(?:'|")[^>]*>/gi;
|
|
121
|
-
const reRtfImgHeader = /{\\pict[\s\S]+?\\bliptag-?\d+(\\blipupi-?\d+)?({\\\*\\blipuid\s?[\da-fA-F]+)?[\s}]*?/;
|
|
122
|
-
const reRtfImg = new RegExp('(?:(' + reRtfImgHeader.source + '))([\\da-fA-F\\s]+)\\}', 'g');
|
|
123
|
-
const reNonHex = /[^\da-fA-F]/g;
|
|
124
|
-
const reLocalFile = /file:\/[^'"]+\.(jpg|png|gif)/i;
|
|
125
|
-
const reExtension = /\\(png|jpeg)blip\\/;
|
|
126
|
-
const textRtfType = 'text/rtf';
|
|
127
|
-
/**
|
|
128
|
-
* If the input HTML contains images with 'src' pointing to local file system (it happens when pasting images and text from MS Word),
|
|
129
|
-
* the function will extract the image sources form the RTF and replace the image 'src' with extracted base64 format data in `html` string.
|
|
130
|
-
*
|
|
131
|
-
* @param html - The input HTML (pasted HTML).
|
|
132
|
-
* @param clipboardData - The paste event clipboardData object (event.clipboardData).
|
|
133
|
-
* @returns - The html with the replaced images sources.
|
|
134
|
-
*/
|
|
135
|
-
const replaceImageSourcesFromRtf = (html, clipboardData) => {
|
|
136
|
-
const htmlImages = html.match(reHtmlImg);
|
|
137
|
-
if (!htmlImages || clipboardData.types.indexOf(textRtfType) === -1) {
|
|
138
|
-
return html;
|
|
139
|
-
}
|
|
140
|
-
const rtf = clipboardData.getData(textRtfType);
|
|
141
|
-
const base64Sources = [];
|
|
142
|
-
const rtfImages = rtf.match(reRtfImg);
|
|
143
|
-
if (!rtf || !rtfImages) {
|
|
144
|
-
return html;
|
|
145
|
-
}
|
|
146
|
-
for (const image of rtfImages) {
|
|
147
|
-
const extension = reExtension.exec(image);
|
|
148
|
-
if (extension) {
|
|
149
|
-
const hex = image.replace(reRtfImgHeader, '').replace(reNonHex, '');
|
|
150
|
-
base64Sources.push(`data:image/${extension[1]};base64,${convertHexToBase64(hex)}`);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
if (htmlImages.length !== base64Sources.length) {
|
|
154
|
-
return html;
|
|
155
|
-
}
|
|
156
|
-
return html.replace(reHtmlImg, img => {
|
|
157
|
-
const src = base64Sources.shift() || '';
|
|
158
|
-
return img.replace(reLocalFile, src);
|
|
159
|
-
});
|
|
160
|
-
};
|
|
161
|
-
|
|
162
|
-
export { pasteCleanup, removeAttribute, removeTag, replaceImageSourcesFromRtf, sanitize, sanitizeClassAttr, sanitizeStyleAttr };
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { PluginKey, Plugin } from 'prosemirror-state';
|
|
2
|
-
import { DecorationSet, Decoration } from 'prosemirror-view';
|
|
3
|
-
import { styleValue } from '../mark.js';
|
|
4
|
-
|
|
5
|
-
const caretColorKey = new PluginKey('caret-color');
|
|
6
|
-
function caretColor() {
|
|
7
|
-
return new Plugin({
|
|
8
|
-
key: caretColorKey,
|
|
9
|
-
props: {
|
|
10
|
-
decorations: (state) => {
|
|
11
|
-
const { doc, selection, storedMarks } = state;
|
|
12
|
-
if (!selection.empty || !storedMarks) {
|
|
13
|
-
return DecorationSet.empty;
|
|
14
|
-
}
|
|
15
|
-
const color = styleValue((storedMarks || []).find((m) => m.type.name === 'style'), { name: 'color', value: /^.+$/ });
|
|
16
|
-
if (!color) {
|
|
17
|
-
return DecorationSet.empty;
|
|
18
|
-
}
|
|
19
|
-
const parentNode = selection.$anchor.parent;
|
|
20
|
-
const decorations = [];
|
|
21
|
-
doc.descendants((node, pos) => {
|
|
22
|
-
if (node.eq(parentNode)) {
|
|
23
|
-
decorations.push(Decoration.node(pos, pos + node.nodeSize, {
|
|
24
|
-
style: 'caret-color: ' + color
|
|
25
|
-
}));
|
|
26
|
-
}
|
|
27
|
-
});
|
|
28
|
-
return DecorationSet.create(doc, decorations);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export { caretColor, caretColorKey };
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { Plugin, PluginKey } from 'prosemirror-state';
|
|
2
|
-
import { setAttribute } from '../utils.js';
|
|
3
|
-
|
|
4
|
-
const setAttributes = (dom, attrs) => {
|
|
5
|
-
for (const attrName in attrs) {
|
|
6
|
-
if (attrName) {
|
|
7
|
-
setAttribute(dom, attrName, attrs[attrName]);
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
};
|
|
11
|
-
class CustomNodeView {
|
|
12
|
-
constructor(node, view, nodeName, isLeaf = false) {
|
|
13
|
-
this.node = node;
|
|
14
|
-
this.view = view;
|
|
15
|
-
this.dom = document.createElement(nodeName);
|
|
16
|
-
setAttributes(this.dom, node.attrs);
|
|
17
|
-
this.contentDOM = !isLeaf ? this.dom : undefined;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
class StyleView {
|
|
21
|
-
constructor(mark, view) {
|
|
22
|
-
this.mark = mark;
|
|
23
|
-
this.view = view;
|
|
24
|
-
this.dom = document.createElement('span');
|
|
25
|
-
setAttributes(this.dom, mark.attrs);
|
|
26
|
-
this.contentDOM = this.dom;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
const cspFix = () => {
|
|
30
|
-
return new Plugin({
|
|
31
|
-
key: new PluginKey('csp-fix'),
|
|
32
|
-
props: {
|
|
33
|
-
nodeViews: {
|
|
34
|
-
paragraph: (node, view) => new CustomNodeView(node, view, 'p'),
|
|
35
|
-
div: (node, view) => new CustomNodeView(node, view, 'div'),
|
|
36
|
-
table_wrapper: (node, view) => new CustomNodeView(node, view, 'div'),
|
|
37
|
-
table_caption_external: (node, view) => new CustomNodeView(node, view, 'div'),
|
|
38
|
-
table: (node, view) => new CustomNodeView(node, view, 'table'),
|
|
39
|
-
table_row: (node, view) => new CustomNodeView(node, view, 'tr'),
|
|
40
|
-
table_cell: (node, view) => new CustomNodeView(node, view, 'td'),
|
|
41
|
-
table_header: (node, view) => new CustomNodeView(node, view, 'th'),
|
|
42
|
-
image: (node, view) => new CustomNodeView(node, view, 'img', true)
|
|
43
|
-
},
|
|
44
|
-
markViews: {
|
|
45
|
-
style: (mark, view) => new StyleView(mark, view)
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
});
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
export { cspFix };
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { PluginKey, Plugin } from 'prosemirror-state';
|
|
2
|
-
import { Decoration, DecorationSet } from 'prosemirror-view';
|
|
3
|
-
|
|
4
|
-
// https://discuss.prosemirror.net/t/passing-data-between-plugins/1843
|
|
5
|
-
const textHighlightKey = new PluginKey('highlight');
|
|
6
|
-
function textHighlight(key = textHighlightKey) {
|
|
7
|
-
return new Plugin({
|
|
8
|
-
key,
|
|
9
|
-
state: {
|
|
10
|
-
init() { return null; },
|
|
11
|
-
apply(tr) { return tr.getMeta(this.spec.key); }
|
|
12
|
-
},
|
|
13
|
-
props: {
|
|
14
|
-
decorations(state) {
|
|
15
|
-
const decorations = (this.spec.key.getState(state) || [])
|
|
16
|
-
.map((d) => Decoration.inline(d.from, d.to, d.attrs));
|
|
17
|
-
return DecorationSet.create(state.doc, decorations);
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export { textHighlight, textHighlightKey };
|
|
@@ -1,225 +0,0 @@
|
|
|
1
|
-
import { PluginKey, Plugin, NodeSelection } from 'prosemirror-state';
|
|
2
|
-
import { DecorationSet, Decoration } from 'prosemirror-view';
|
|
3
|
-
import { resizeHandle, dataResizeDirImage } from '../config/constants.js';
|
|
4
|
-
import { changeStylesString } from '../utils.js';
|
|
5
|
-
import { handles, directions } from './resize-utils.js';
|
|
6
|
-
|
|
7
|
-
const imageResizeKey = new PluginKey('image-resize');
|
|
8
|
-
const setSize = (domNode, sizeType, value) => {
|
|
9
|
-
domNode.style[sizeType] = value + 'px';
|
|
10
|
-
};
|
|
11
|
-
const reSize = /[^\-]width:|[^\-]height:/;
|
|
12
|
-
const reAnyValue = /^.+$/;
|
|
13
|
-
class ResizeState {
|
|
14
|
-
constructor(activeHandle, dragging, rect, nodePosition) {
|
|
15
|
-
this.activeHandle = activeHandle;
|
|
16
|
-
this.dragging = dragging;
|
|
17
|
-
this.rect = rect;
|
|
18
|
-
this.nodePosition = nodePosition;
|
|
19
|
-
}
|
|
20
|
-
apply(tr) {
|
|
21
|
-
const next = tr.getMeta(imageResizeKey);
|
|
22
|
-
if (next) {
|
|
23
|
-
return new ResizeState(next.activeHandle, next.setDragging, next.rect, next.nodePosition);
|
|
24
|
-
}
|
|
25
|
-
return this;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
const handleMouseMove = (view, event, options) => {
|
|
29
|
-
const state = imageResizeKey.getState(view.state);
|
|
30
|
-
const { rect, dragging, nodePosition: nodePosition, activeHandle } = state;
|
|
31
|
-
if (!dragging || !rect) {
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
|
-
const img = view.nodeDOM(nodePosition);
|
|
35
|
-
const dir = directions[activeHandle];
|
|
36
|
-
const diffX = (event.clientX - dragging.startX) * dir.x;
|
|
37
|
-
const diffY = (event.clientY - dragging.startY) * dir.y;
|
|
38
|
-
let width = dir.x ? diffX + img.width : rect.width;
|
|
39
|
-
let height = dir.y ? diffY + img.height : rect.height;
|
|
40
|
-
if (options.lockRatio && dir.x && dir.y) {
|
|
41
|
-
const ratio = Math.min(width / img.width, height / img.height);
|
|
42
|
-
const lockWidth = img.width * ratio;
|
|
43
|
-
const lockHeight = img.height * ratio;
|
|
44
|
-
dragging.startX = event.clientX - (width - lockWidth) * dir.x;
|
|
45
|
-
dragging.startY = event.clientY - (height - lockHeight) * dir.y;
|
|
46
|
-
width = lockWidth;
|
|
47
|
-
height = lockHeight;
|
|
48
|
-
}
|
|
49
|
-
else {
|
|
50
|
-
dragging.startX = dir.x ? event.clientX : dragging.startX;
|
|
51
|
-
dragging.startY = dir.y ? event.clientY : dragging.startY;
|
|
52
|
-
}
|
|
53
|
-
setSize(img, 'width', width);
|
|
54
|
-
setSize(img, 'height', height);
|
|
55
|
-
rect.top = img.offsetTop;
|
|
56
|
-
rect.left = img.offsetLeft;
|
|
57
|
-
rect.width = img.offsetWidth;
|
|
58
|
-
rect.height = img.offsetHeight;
|
|
59
|
-
const handlesWrapper = img.nextElementSibling;
|
|
60
|
-
handlesWrapper.style.width = rect.width + 'px';
|
|
61
|
-
handlesWrapper.style.height = rect.height + 'px';
|
|
62
|
-
handlesWrapper.style.top = rect.top + 'px';
|
|
63
|
-
handlesWrapper.style.left = rect.left + 'px';
|
|
64
|
-
};
|
|
65
|
-
const handleMouseUp = (view) => {
|
|
66
|
-
const { rect, dragging, nodePosition } = imageResizeKey.getState(view.state);
|
|
67
|
-
if (dragging && rect) {
|
|
68
|
-
const selection = view.state.selection;
|
|
69
|
-
if (selection instanceof NodeSelection) {
|
|
70
|
-
const currAttrs = selection.node.attrs;
|
|
71
|
-
const width = rect.width;
|
|
72
|
-
const height = rect.height;
|
|
73
|
-
let attrs;
|
|
74
|
-
if (reSize.test(currAttrs.style || '')) {
|
|
75
|
-
const changedWidth = changeStylesString(currAttrs.style, { style: 'width', value: reAnyValue, newValue: width + 'px' });
|
|
76
|
-
const { style } = changeStylesString(changedWidth.style || '', { style: 'height', value: reAnyValue, newValue: height + 'px' });
|
|
77
|
-
attrs = Object.assign(Object.assign({}, currAttrs), { style });
|
|
78
|
-
}
|
|
79
|
-
else {
|
|
80
|
-
attrs = Object.assign(Object.assign({}, currAttrs), { width, height });
|
|
81
|
-
}
|
|
82
|
-
const newImage = selection.node.type.createAndFill(attrs);
|
|
83
|
-
if (newImage) {
|
|
84
|
-
const tr = view.state.tr;
|
|
85
|
-
tr.replaceWith(nodePosition, nodePosition + 1, newImage);
|
|
86
|
-
tr.setSelection(NodeSelection.create(tr.doc, nodePosition));
|
|
87
|
-
tr.setMeta('commandName', 'image-resize');
|
|
88
|
-
tr.setMeta('args', attrs);
|
|
89
|
-
tr.setMeta(imageResizeKey, {
|
|
90
|
-
setDragging: null,
|
|
91
|
-
activeHandle: null,
|
|
92
|
-
rect,
|
|
93
|
-
nodePosition
|
|
94
|
-
});
|
|
95
|
-
view.dispatch(tr);
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
};
|
|
100
|
-
const handleMouseDown = (view, event, options) => {
|
|
101
|
-
const target = event.target;
|
|
102
|
-
const activeHandle = target.getAttribute(dataResizeDirImage);
|
|
103
|
-
if (!activeHandle) {
|
|
104
|
-
return false;
|
|
105
|
-
}
|
|
106
|
-
const resizeState = imageResizeKey.getState(view.state);
|
|
107
|
-
event.preventDefault();
|
|
108
|
-
const transaction = view.state.tr;
|
|
109
|
-
transaction.setMeta(imageResizeKey, {
|
|
110
|
-
setDragging: { startX: event.clientX, startY: event.clientY },
|
|
111
|
-
activeHandle,
|
|
112
|
-
rect: resizeState.rect,
|
|
113
|
-
nodePosition: resizeState.nodePosition
|
|
114
|
-
});
|
|
115
|
-
transaction.setMeta('addToHistory', false);
|
|
116
|
-
view.dispatch(transaction);
|
|
117
|
-
function move(e) {
|
|
118
|
-
handleMouseMove(view, e, options);
|
|
119
|
-
}
|
|
120
|
-
function finish(e) {
|
|
121
|
-
e.view.removeEventListener('mouseup', finish);
|
|
122
|
-
e.view.removeEventListener('mousemove', move);
|
|
123
|
-
handleMouseUp(view);
|
|
124
|
-
}
|
|
125
|
-
event.view.addEventListener('mouseup', finish);
|
|
126
|
-
event.view.addEventListener('mousemove', move);
|
|
127
|
-
return true;
|
|
128
|
-
};
|
|
129
|
-
const imageResizing = (options = { node: 'image', lockRatio: true }) => {
|
|
130
|
-
return new Plugin({
|
|
131
|
-
key: imageResizeKey,
|
|
132
|
-
view: (viewObj) => ({
|
|
133
|
-
resize() {
|
|
134
|
-
if (imageResizeKey.getState(viewObj.state).rect) {
|
|
135
|
-
viewObj.dispatch(viewObj.state.tr.setMeta('resize', true));
|
|
136
|
-
}
|
|
137
|
-
},
|
|
138
|
-
get window() {
|
|
139
|
-
return viewObj.dom.ownerDocument && viewObj.dom.ownerDocument.defaultView;
|
|
140
|
-
},
|
|
141
|
-
attachResize() {
|
|
142
|
-
const win = this.window;
|
|
143
|
-
if (win) {
|
|
144
|
-
win.removeEventListener('resize', this.resize);
|
|
145
|
-
win.addEventListener('resize', this.resize);
|
|
146
|
-
}
|
|
147
|
-
},
|
|
148
|
-
removeResize() {
|
|
149
|
-
const win = this.window;
|
|
150
|
-
if (win) {
|
|
151
|
-
win.removeEventListener('resize', this.resize);
|
|
152
|
-
}
|
|
153
|
-
},
|
|
154
|
-
update(view, prevState) {
|
|
155
|
-
const state = view.state;
|
|
156
|
-
const selection = state.selection;
|
|
157
|
-
const nodeType = state.schema.nodes[options.node];
|
|
158
|
-
const pluginState = imageResizeKey.getState(state);
|
|
159
|
-
const prevRect = pluginState.rect;
|
|
160
|
-
if (selection instanceof NodeSelection && nodeType === selection.node.type) {
|
|
161
|
-
const img = view.nodeDOM(selection.from);
|
|
162
|
-
const rect = {
|
|
163
|
-
top: img.offsetTop,
|
|
164
|
-
left: img.offsetLeft,
|
|
165
|
-
width: img.offsetWidth,
|
|
166
|
-
height: img.offsetHeight
|
|
167
|
-
};
|
|
168
|
-
if (!prevState.selection.eq(selection) ||
|
|
169
|
-
(prevRect && (prevRect.width !== rect.width || prevRect.height !== rect.height ||
|
|
170
|
-
prevRect.top !== rect.top || prevRect.left !== rect.left))) {
|
|
171
|
-
const tr = state.tr;
|
|
172
|
-
tr.setMeta(imageResizeKey, { rect, nodePosition: selection.from });
|
|
173
|
-
view.dispatch(tr);
|
|
174
|
-
this.attachResize();
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
else if (prevRect) {
|
|
178
|
-
pluginState.rect = null;
|
|
179
|
-
pluginState.nodePosition = -1;
|
|
180
|
-
}
|
|
181
|
-
},
|
|
182
|
-
destroy() {
|
|
183
|
-
this.removeResize();
|
|
184
|
-
}
|
|
185
|
-
}),
|
|
186
|
-
state: {
|
|
187
|
-
init() {
|
|
188
|
-
return new ResizeState('', null, null, -1);
|
|
189
|
-
},
|
|
190
|
-
apply(tr, prev) {
|
|
191
|
-
return prev.apply(tr);
|
|
192
|
-
}
|
|
193
|
-
},
|
|
194
|
-
props: {
|
|
195
|
-
handleDOMEvents: {
|
|
196
|
-
mousedown(view, event) {
|
|
197
|
-
return handleMouseDown(view, event, options);
|
|
198
|
-
}
|
|
199
|
-
},
|
|
200
|
-
decorations(state) {
|
|
201
|
-
const selection = state.selection;
|
|
202
|
-
const nodeType = state.schema.nodes[options.node];
|
|
203
|
-
const rect = imageResizeKey.getState(state).rect;
|
|
204
|
-
if (rect && selection instanceof NodeSelection && nodeType === selection.node.type) {
|
|
205
|
-
const wrapper = document.createElement('div');
|
|
206
|
-
wrapper.className = 'k-editor-resize-handles-wrapper';
|
|
207
|
-
wrapper.style.width = rect.width + 'px';
|
|
208
|
-
wrapper.style.height = rect.height + 'px';
|
|
209
|
-
wrapper.style.top = rect.top + 'px';
|
|
210
|
-
wrapper.style.left = rect.left + 'px';
|
|
211
|
-
for (let i = 0; i < handles.length; i++) {
|
|
212
|
-
const dom = document.createElement('div');
|
|
213
|
-
dom.className = resizeHandle + ' ' + handles[i];
|
|
214
|
-
dom.setAttribute(dataResizeDirImage, handles[i]);
|
|
215
|
-
wrapper.appendChild(dom);
|
|
216
|
-
}
|
|
217
|
-
return DecorationSet.create(state.doc, [Decoration.widget(state.selection.from + 1, wrapper)]);
|
|
218
|
-
}
|
|
219
|
-
return DecorationSet.empty;
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
});
|
|
223
|
-
};
|
|
224
|
-
|
|
225
|
-
export { imageResizeKey, imageResizing };
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
import { Plugin, PluginKey } from 'prosemirror-state';
|
|
2
|
-
import { RemoveMarkStep } from 'prosemirror-transform';
|
|
3
|
-
import { applyStyle, parseStyle, parentNode } from '../utils.js';
|
|
4
|
-
|
|
5
|
-
const inSelection = (from, to, nodePos, node, doc) => {
|
|
6
|
-
const $from = doc.resolve(from);
|
|
7
|
-
const $to = doc.resolve(to);
|
|
8
|
-
const nodeName = node.type.name;
|
|
9
|
-
let wrapper, parentLi;
|
|
10
|
-
if (!$from.nodeBefore) {
|
|
11
|
-
wrapper = $from.node($from.depth);
|
|
12
|
-
parentLi = $from.node($from.depth - 1);
|
|
13
|
-
if (wrapper && parentLi && parentLi.firstChild === wrapper && parentLi.type.name === nodeName) {
|
|
14
|
-
return nodePos + node.content.size <= to;
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
if (!$to.nodeAfter) {
|
|
18
|
-
wrapper = $to.node($to.depth);
|
|
19
|
-
parentLi = $to.node($to.depth - 1);
|
|
20
|
-
if (wrapper && parentLi && parentLi.lastChild === wrapper && parentLi.type.name === nodeName) {
|
|
21
|
-
return from <= nodePos;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
return from <= nodePos && nodePos + node.content.size <= to;
|
|
25
|
-
};
|
|
26
|
-
const applyToListItems = (tr, state, options) => {
|
|
27
|
-
const { tr: transaction, doc, selection: { from, to } } = state;
|
|
28
|
-
const args = tr.getMeta('args');
|
|
29
|
-
doc.nodesBetween(from, to, (node, pos) => {
|
|
30
|
-
if ((node.type.name === options.listItem) && inSelection(from, to, pos, node, doc)) {
|
|
31
|
-
transaction.setNodeMarkup(pos, null, Object.assign(Object.assign({}, node.attrs), { style: applyStyle(node.attrs.style, args.style, args.value) }));
|
|
32
|
-
}
|
|
33
|
-
});
|
|
34
|
-
return transaction.docChanged ? transaction : undefined;
|
|
35
|
-
};
|
|
36
|
-
const cleanListItems = (tr, state, options) => {
|
|
37
|
-
const stylesToClean = Object.keys(options.resetValues);
|
|
38
|
-
const { tr: transaction, doc, selection: { from, to } } = state;
|
|
39
|
-
doc.nodesBetween(from, to, (node, pos) => {
|
|
40
|
-
if (node.type.name === options.listItem && inSelection(from, to, pos, node, doc)) {
|
|
41
|
-
let attrs = node.attrs;
|
|
42
|
-
const nodeStyles = parseStyle(node.attrs.style);
|
|
43
|
-
stylesToClean.forEach(style => {
|
|
44
|
-
if (nodeStyles[style]) {
|
|
45
|
-
attrs = Object.assign(Object.assign({}, attrs), { style: applyStyle(attrs.style, style, '') });
|
|
46
|
-
}
|
|
47
|
-
});
|
|
48
|
-
if (attrs !== node.attrs) {
|
|
49
|
-
transaction.setNodeMarkup(pos, null, attrs);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
});
|
|
53
|
-
tr.steps.forEach((step) => {
|
|
54
|
-
if (step instanceof RemoveMarkStep) {
|
|
55
|
-
const mark = step.mark;
|
|
56
|
-
if (mark.type.name === 'style' && mark.attrs.style) {
|
|
57
|
-
const [name] = mark.attrs.style.split(/\s*:\s*/);
|
|
58
|
-
const $pos = transaction.doc.resolve(step.from);
|
|
59
|
-
const li = parentNode($pos, n => n.type.name === options.listItem);
|
|
60
|
-
if (li) {
|
|
61
|
-
const liStyles = parseStyle(li.node.attrs.style);
|
|
62
|
-
if (liStyles[name] && options.resetValues[name]) {
|
|
63
|
-
const newMark = mark.type.create({ style: `${name}: ${options.resetValues[name]};` });
|
|
64
|
-
transaction.addMark(step.from, step.to, newMark);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
});
|
|
70
|
-
return transaction.docChanged ? transaction : undefined;
|
|
71
|
-
};
|
|
72
|
-
const DEFAULT_OPTIONS = {
|
|
73
|
-
listItem: 'list_item',
|
|
74
|
-
resetValues: {
|
|
75
|
-
'font-size': '', // 'initial' or '16px'
|
|
76
|
-
'font-family': '',
|
|
77
|
-
'color': ''
|
|
78
|
-
}
|
|
79
|
-
};
|
|
80
|
-
/**
|
|
81
|
-
* Returns a plugin which applies font-size, font-family, color styles to list item marker.
|
|
82
|
-
*/
|
|
83
|
-
function listMarkersStyles(options = DEFAULT_OPTIONS) {
|
|
84
|
-
return new Plugin({
|
|
85
|
-
key: new PluginKey('list-markers-styles'),
|
|
86
|
-
appendTransaction: (transactions, _oldState, newState) => {
|
|
87
|
-
const tr = transactions.slice().pop();
|
|
88
|
-
const commandName = tr.getMeta('commandName');
|
|
89
|
-
let transaction;
|
|
90
|
-
if (commandName === 'FontSize' || commandName === 'FontName' || commandName === 'ForeColor') {
|
|
91
|
-
transaction = applyToListItems(tr, newState, options);
|
|
92
|
-
}
|
|
93
|
-
else if (commandName === 'CleanFormatting') {
|
|
94
|
-
transaction = cleanListItems(tr, newState, options);
|
|
95
|
-
}
|
|
96
|
-
if (transaction) {
|
|
97
|
-
transaction.setMeta('addToHistory', true);
|
|
98
|
-
}
|
|
99
|
-
return transaction;
|
|
100
|
-
}
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
export { listMarkersStyles };
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { Plugin, PluginKey } from 'prosemirror-state';
|
|
2
|
-
import { DecorationSet, Decoration } from 'prosemirror-view';
|
|
3
|
-
|
|
4
|
-
function placeholder(message) {
|
|
5
|
-
const decAttrs = { class: 'k-placeholder', 'data-placeholder': message };
|
|
6
|
-
return new Plugin({
|
|
7
|
-
key: new PluginKey('placeholder'),
|
|
8
|
-
props: {
|
|
9
|
-
decorations: (state) => {
|
|
10
|
-
const { doc } = state;
|
|
11
|
-
const firstChild = doc.content.firstChild;
|
|
12
|
-
const empty = doc.childCount === 0 ||
|
|
13
|
-
(doc.childCount === 1 && firstChild.inlineContent && firstChild.childCount === 0);
|
|
14
|
-
if (!empty) {
|
|
15
|
-
return DecorationSet.empty;
|
|
16
|
-
}
|
|
17
|
-
const decorations = [];
|
|
18
|
-
doc.descendants((node, pos) => {
|
|
19
|
-
decorations.push(Decoration.node(pos, pos + node.nodeSize, decAttrs));
|
|
20
|
-
});
|
|
21
|
-
return DecorationSet.create(doc, decorations);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export { placeholder };
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
const directions = {
|
|
2
|
-
'southeast': { x: 1, y: 1 }, // bottom right
|
|
3
|
-
'east': { x: 1, y: 0 }, // right
|
|
4
|
-
'south': { x: 0, y: 1 }, // bottom
|
|
5
|
-
'north': { x: 0, y: -1 }, // top
|
|
6
|
-
'west': { x: -1, y: 0 }, // left
|
|
7
|
-
'southwest': { x: -1, y: 1 }, // bottom left
|
|
8
|
-
'northwest': { x: -1, y: -1 }, // top left
|
|
9
|
-
'northeast': { x: 1, y: -1 } // top right
|
|
10
|
-
};
|
|
11
|
-
const handles = Object.keys(directions);
|
|
12
|
-
|
|
13
|
-
export { directions, handles };
|