@progress/kendo-editor-common 1.10.3-dev.202309121208 → 1.10.3
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 +188 -0
- package/dist/es/main.js +1 -0
- package/dist/es/plugins/csp-fix.js +51 -0
- package/dist/es/plugins/table-resize/column-resize.js +2 -1
- package/dist/es/plugins/table-resize/row-resize.js +2 -1
- package/dist/es/plugins/table-resize/table-resize.js +2 -1
- package/dist/es/plugins/table-resize/table-view.js +3 -17
- package/dist/es/plugins/table-resize/utils.js +0 -8
- package/dist/es/source.js +29 -19
- package/dist/es/utils.js +31 -0
- package/dist/es2015/DOMSerializer.js +181 -0
- package/dist/es2015/main.js +1 -0
- package/dist/es2015/plugins/csp-fix.js +48 -0
- package/dist/es2015/plugins/table-resize/column-resize.js +2 -1
- package/dist/es2015/plugins/table-resize/row-resize.js +2 -1
- package/dist/es2015/plugins/table-resize/table-resize.js +2 -1
- package/dist/es2015/plugins/table-resize/table-view.js +3 -17
- package/dist/es2015/plugins/table-resize/utils.js +0 -7
- package/dist/es2015/source.js +27 -19
- package/dist/es2015/utils.js +30 -0
- package/dist/npm/DOMSerializer.d.ts +35 -0
- package/dist/npm/DOMSerializer.js +191 -0
- package/dist/npm/main.d.ts +1 -0
- package/dist/npm/main.js +4 -2
- package/dist/npm/plugins/csp-fix.d.ts +2 -0
- package/dist/npm/plugins/csp-fix.js +55 -0
- package/dist/npm/plugins/table-resize/column-resize.js +23 -22
- package/dist/npm/plugins/table-resize/row-resize.js +3 -2
- package/dist/npm/plugins/table-resize/table-resize.js +7 -6
- package/dist/npm/plugins/table-resize/table-view.js +3 -17
- package/dist/npm/plugins/table-resize/utils.d.ts +0 -3
- package/dist/npm/plugins/table-resize/utils.js +1 -10
- package/dist/npm/source.js +29 -19
- package/dist/npm/utils.d.ts +4 -0
- package/dist/npm/utils.js +34 -1
- package/dist/systemjs/kendo-editor-common.js +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { setAttribute } from "./utils";
|
|
2
|
+
var DOMSerializer = /** @class */ (function () {
|
|
3
|
+
/// Create a serializer. `nodes` should map node names to functions
|
|
4
|
+
/// that take a node and return a description of the corresponding
|
|
5
|
+
/// DOM. `marks` does the same for mark names, but also gets an
|
|
6
|
+
/// argument that tells it whether the mark's content is block or
|
|
7
|
+
/// inline content (for typical use, it'll always be inline). A mark
|
|
8
|
+
/// serializer may be `null` to indicate that marks of that type
|
|
9
|
+
/// should not be serialized.
|
|
10
|
+
function DOMSerializer(
|
|
11
|
+
/// The node serialization functions.
|
|
12
|
+
nodes,
|
|
13
|
+
/// The mark serialization functions.
|
|
14
|
+
marks) {
|
|
15
|
+
this.nodes = nodes;
|
|
16
|
+
this.marks = marks;
|
|
17
|
+
}
|
|
18
|
+
/// Render an [output spec](#model.DOMOutputSpec) to a DOM node. If
|
|
19
|
+
/// the spec has a hole (zero) in it, `contentDOM` will point at the
|
|
20
|
+
/// node with the hole.
|
|
21
|
+
DOMSerializer.renderSpec = function (docum, structure, xmlNS) {
|
|
22
|
+
if (xmlNS === void 0) { xmlNS = null; }
|
|
23
|
+
if (typeof structure === "string") {
|
|
24
|
+
return { dom: docum.createTextNode(structure) };
|
|
25
|
+
}
|
|
26
|
+
if (structure.nodeType != null) {
|
|
27
|
+
return { dom: structure };
|
|
28
|
+
}
|
|
29
|
+
if (structure.dom && structure.dom.nodeType != null) {
|
|
30
|
+
return structure;
|
|
31
|
+
}
|
|
32
|
+
var tagName = structure[0], space = tagName.indexOf(" ");
|
|
33
|
+
if (space > 0) {
|
|
34
|
+
xmlNS = tagName.slice(0, space);
|
|
35
|
+
tagName = tagName.slice(space + 1);
|
|
36
|
+
}
|
|
37
|
+
var contentDOM;
|
|
38
|
+
var dom = (xmlNS ? docum.createElementNS(xmlNS, tagName) : docum.createElement(tagName));
|
|
39
|
+
var attrs = structure[1], start = 1;
|
|
40
|
+
if (attrs && typeof attrs === "object" && attrs.nodeType == null && !Array.isArray(attrs)) {
|
|
41
|
+
start = 2;
|
|
42
|
+
for (var name_1 in attrs) {
|
|
43
|
+
if (attrs[name_1] != null) {
|
|
44
|
+
space = name_1.indexOf(" ");
|
|
45
|
+
if (space > 0) {
|
|
46
|
+
dom.setAttributeNS(name_1.slice(0, space), name_1.slice(space + 1), attrs[name_1]);
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
setAttribute(dom, name_1, attrs[name_1]);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
for (var i = start; i < structure.length; i++) {
|
|
55
|
+
var child = structure[i];
|
|
56
|
+
if (child === 0) {
|
|
57
|
+
if (i < structure.length - 1 || i > start) {
|
|
58
|
+
throw new RangeError("Content hole must be the only child of its parent node");
|
|
59
|
+
}
|
|
60
|
+
return { dom: dom, contentDOM: dom };
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
var _a = DOMSerializer.renderSpec(docum, child, xmlNS), inner = _a.dom, innerContent = _a.contentDOM;
|
|
64
|
+
dom.appendChild(inner);
|
|
65
|
+
if (innerContent) {
|
|
66
|
+
if (contentDOM) {
|
|
67
|
+
throw new RangeError("Multiple content holes");
|
|
68
|
+
}
|
|
69
|
+
contentDOM = innerContent;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return { dom: dom, contentDOM: contentDOM };
|
|
74
|
+
};
|
|
75
|
+
/// Build a serializer using the [`toDOM`](#model.NodeSpec.toDOM)
|
|
76
|
+
/// properties in a schema's node and mark specs.
|
|
77
|
+
DOMSerializer.fromSchema = function (schema) {
|
|
78
|
+
return schema.cached.domSerializer ||
|
|
79
|
+
(schema.cached.domSerializer = new DOMSerializer(this.nodesFromSchema(schema), this.marksFromSchema(schema)));
|
|
80
|
+
};
|
|
81
|
+
/// Gather the serializers in a schema's node specs into an object.
|
|
82
|
+
/// This can be useful as a base to build a custom serializer from.
|
|
83
|
+
DOMSerializer.nodesFromSchema = function (schema) {
|
|
84
|
+
var result = gatherToDOM(schema.nodes);
|
|
85
|
+
if (!result.text) {
|
|
86
|
+
result.text = function (node) { return node.text; };
|
|
87
|
+
}
|
|
88
|
+
return result;
|
|
89
|
+
};
|
|
90
|
+
/// Gather the serializers in a schema's mark specs into an object.
|
|
91
|
+
DOMSerializer.marksFromSchema = function (schema) {
|
|
92
|
+
return gatherToDOM(schema.marks);
|
|
93
|
+
};
|
|
94
|
+
/// Serialize the content of this fragment to a DOM fragment. When
|
|
95
|
+
/// not in the browser, the `document` option, containing a DOM
|
|
96
|
+
/// document, should be passed so that the serializer can create
|
|
97
|
+
/// nodes.
|
|
98
|
+
DOMSerializer.prototype.serializeFragment = function (fragment, options, target) {
|
|
99
|
+
var _this = this;
|
|
100
|
+
if (options === void 0) { options = {}; }
|
|
101
|
+
if (!target) {
|
|
102
|
+
target = doc(options).createDocumentFragment();
|
|
103
|
+
}
|
|
104
|
+
var top = target, active = [];
|
|
105
|
+
fragment.forEach(function (node) {
|
|
106
|
+
if (active.length || node.marks.length) {
|
|
107
|
+
var keep = 0, rendered = 0;
|
|
108
|
+
while (keep < active.length && rendered < node.marks.length) {
|
|
109
|
+
var next = node.marks[rendered];
|
|
110
|
+
if (!_this.marks[next.type.name]) {
|
|
111
|
+
rendered++;
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
if (!next.eq(active[keep][0]) || next.type.spec.spanning === false) {
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
keep++;
|
|
118
|
+
rendered++;
|
|
119
|
+
}
|
|
120
|
+
while (keep < active.length) {
|
|
121
|
+
top = active.pop()[1];
|
|
122
|
+
}
|
|
123
|
+
while (rendered < node.marks.length) {
|
|
124
|
+
var add = node.marks[rendered++];
|
|
125
|
+
var markDOM = _this.serializeMark(add, node.isInline, options);
|
|
126
|
+
if (markDOM) {
|
|
127
|
+
active.push([add, top]);
|
|
128
|
+
top.appendChild(markDOM.dom);
|
|
129
|
+
top = markDOM.contentDOM || markDOM.dom;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
top.appendChild(_this.serializeNodeInner(node, options));
|
|
134
|
+
});
|
|
135
|
+
return target;
|
|
136
|
+
};
|
|
137
|
+
/// Serialize this node to a DOM node. This can be useful when you
|
|
138
|
+
/// need to serialize a part of a document, as opposed to the whole
|
|
139
|
+
/// document. To serialize a whole document, use
|
|
140
|
+
/// [`serializeFragment`](#model.DOMSerializer.serializeFragment) on
|
|
141
|
+
/// its [content](#model.Node.content).
|
|
142
|
+
DOMSerializer.prototype.serializeNode = function (node, options) {
|
|
143
|
+
if (options === void 0) { options = {}; }
|
|
144
|
+
var dom = this.serializeNodeInner(node, options);
|
|
145
|
+
for (var i = node.marks.length - 1; i >= 0; i--) {
|
|
146
|
+
var wrap = this.serializeMark(node.marks[i], node.isInline, options);
|
|
147
|
+
if (wrap) {
|
|
148
|
+
(wrap.contentDOM || wrap.dom).appendChild(dom);
|
|
149
|
+
dom = wrap.dom;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return dom;
|
|
153
|
+
};
|
|
154
|
+
/// @internal
|
|
155
|
+
DOMSerializer.prototype.serializeMark = function (mark, inline, options) {
|
|
156
|
+
if (options === void 0) { options = {}; }
|
|
157
|
+
var toDOM = this.marks[mark.type.name];
|
|
158
|
+
return toDOM && DOMSerializer.renderSpec(doc(options), toDOM(mark, inline));
|
|
159
|
+
};
|
|
160
|
+
/// @internal
|
|
161
|
+
DOMSerializer.prototype.serializeNodeInner = function (node, options) {
|
|
162
|
+
var _a = DOMSerializer.renderSpec(doc(options), this.nodes[node.type.name](node)), dom = _a.dom, contentDOM = _a.contentDOM;
|
|
163
|
+
if (contentDOM) {
|
|
164
|
+
if (node.isLeaf) {
|
|
165
|
+
throw new RangeError("Content hole not allowed in a leaf node spec");
|
|
166
|
+
}
|
|
167
|
+
this.serializeFragment(node.content, options, contentDOM);
|
|
168
|
+
}
|
|
169
|
+
return dom;
|
|
170
|
+
};
|
|
171
|
+
return DOMSerializer;
|
|
172
|
+
}());
|
|
173
|
+
export { DOMSerializer };
|
|
174
|
+
function gatherToDOM(obj) {
|
|
175
|
+
var result = {};
|
|
176
|
+
for (var name_2 in obj) {
|
|
177
|
+
if (obj[name_2]) {
|
|
178
|
+
var toDOM = obj[name_2].spec.toDOM;
|
|
179
|
+
if (toDOM) {
|
|
180
|
+
result[name_2] = toDOM;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return result;
|
|
185
|
+
}
|
|
186
|
+
function doc(options) {
|
|
187
|
+
return options.document || window.document;
|
|
188
|
+
}
|
package/dist/es/main.js
CHANGED
|
@@ -21,6 +21,7 @@ export { convertMsLists } from './listConvert';
|
|
|
21
21
|
export { find, findAt, findAll, replace, replaceAll } from './find-replace';
|
|
22
22
|
export { placeholder } from './plugins/placeholder';
|
|
23
23
|
export { spacesFix } from './plugins/spaces-fix';
|
|
24
|
+
export { cspFix } from './plugins/csp-fix';
|
|
24
25
|
export { textHighlight, textHighlightKey } from './plugins/highlight';
|
|
25
26
|
export { imageResizing, imageResizeKey } from './plugins/image-resize';
|
|
26
27
|
export { caretColor, caretColorKey } from './plugins/caret-color';
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { Plugin, PluginKey } from "prosemirror-state";
|
|
2
|
+
import { setAttribute } from "../utils";
|
|
3
|
+
var setAttributes = function (dom, attrs) {
|
|
4
|
+
for (var attrName in attrs) {
|
|
5
|
+
if (attrName) {
|
|
6
|
+
setAttribute(dom, attrName, attrs[attrName]);
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
};
|
|
10
|
+
var CustomNodeView = /** @class */ (function () {
|
|
11
|
+
function CustomNodeView(node, view, nodeName, isLeaf) {
|
|
12
|
+
if (isLeaf === void 0) { 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
|
+
return CustomNodeView;
|
|
20
|
+
}());
|
|
21
|
+
var StyleView = /** @class */ (function () {
|
|
22
|
+
function StyleView(mark, view, _inline) {
|
|
23
|
+
this.mark = mark;
|
|
24
|
+
this.view = view;
|
|
25
|
+
this.dom = document.createElement('span');
|
|
26
|
+
setAttributes(this.dom, mark.attrs);
|
|
27
|
+
this.contentDOM = this.dom;
|
|
28
|
+
}
|
|
29
|
+
return StyleView;
|
|
30
|
+
}());
|
|
31
|
+
export var cspFix = function () {
|
|
32
|
+
return new Plugin({
|
|
33
|
+
key: new PluginKey('csp-fix'),
|
|
34
|
+
props: {
|
|
35
|
+
nodeViews: {
|
|
36
|
+
paragraph: function (node, view) { return new CustomNodeView(node, view, 'p'); },
|
|
37
|
+
div: function (node, view) { return new CustomNodeView(node, view, 'div'); },
|
|
38
|
+
table_wrapper: function (node, view) { return new CustomNodeView(node, view, 'div'); },
|
|
39
|
+
table_caption_external: function (node, view) { return new CustomNodeView(node, view, 'div'); },
|
|
40
|
+
table: function (node, view) { return new CustomNodeView(node, view, 'table'); },
|
|
41
|
+
table_row: function (node, view) { return new CustomNodeView(node, view, 'tr'); },
|
|
42
|
+
table_cell: function (node, view) { return new CustomNodeView(node, view, 'td'); },
|
|
43
|
+
table_header: function (node, view) { return new CustomNodeView(node, view, 'th'); },
|
|
44
|
+
image: function (node, view) { return new CustomNodeView(node, view, 'img', true); }
|
|
45
|
+
},
|
|
46
|
+
markViews: {
|
|
47
|
+
style: function (mark, view, inline) { return new StyleView(mark, view, inline); }
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
};
|
|
@@ -4,7 +4,8 @@ import { TableMap } from 'prosemirror-tables';
|
|
|
4
4
|
import { Decoration, DecorationSet } from 'prosemirror-view';
|
|
5
5
|
import { colgroupAttr } from '../../config/constants';
|
|
6
6
|
import { TableView, TableWrapperView } from './table-view';
|
|
7
|
-
import {
|
|
7
|
+
import { parseStyle } from './../../utils';
|
|
8
|
+
import { cellIndexes, domCellAround, otherResizeHandle, otherResizing, edgeCell, setNodeStyle, tableColumnResizeKey as key } from './utils';
|
|
8
9
|
export function columnResizing() {
|
|
9
10
|
var handleWidth = 5, cellMinWidth = 25;
|
|
10
11
|
var plugin = new Plugin({
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { Plugin } from 'prosemirror-state';
|
|
2
2
|
import { TableMap, tableNodeTypes } from 'prosemirror-tables';
|
|
3
3
|
import { Decoration, DecorationSet } from 'prosemirror-view';
|
|
4
|
-
import { cellIndexes, domCellAround, otherResizeHandle, otherResizing,
|
|
4
|
+
import { cellIndexes, domCellAround, otherResizeHandle, otherResizing, setNodeStyle, tableRowResizeKey as key, edgeCell } from './utils';
|
|
5
|
+
import { parseStyle } from './../../utils';
|
|
5
6
|
var TableRowView = /** @class */ (function () {
|
|
6
7
|
function TableRowView() {
|
|
7
8
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { __assign } from "tslib";
|
|
2
2
|
import { NodeSelection, Plugin } from 'prosemirror-state';
|
|
3
3
|
import { colgroupAttr, dataResizeDirTable, resizableAttr } from '../../config/constants';
|
|
4
|
-
import { getTable, parentNode,
|
|
4
|
+
import { getTable, parentNode, setNodeStyle, tableResizeKey as key } from './utils';
|
|
5
|
+
import { parseStyle } from './../../utils';
|
|
5
6
|
import { directions } from './../resize-utils';
|
|
6
7
|
var commonDir = {
|
|
7
8
|
'southeast': true,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { colgroupAttr, dataResizeDirTable, resizableAttr, resizableWrap, resizeHandle } from '../../config/constants';
|
|
2
2
|
import { parseStrColgroup } from '../../config/schema';
|
|
3
3
|
import { handles } from './../resize-utils';
|
|
4
|
-
import { parseStyle } from '
|
|
4
|
+
import { parseStyle, setAttribute } from './../../utils';
|
|
5
5
|
var TableView = /** @class */ (function () {
|
|
6
6
|
function TableView(node, view) {
|
|
7
7
|
this.node = node;
|
|
@@ -72,14 +72,7 @@ var TableView = /** @class */ (function () {
|
|
|
72
72
|
var skip = [colgroupAttr, resizableAttr];
|
|
73
73
|
for (var attrName in attrs) {
|
|
74
74
|
if (attrName && skip.indexOf(attrName) === -1) {
|
|
75
|
-
|
|
76
|
-
var next = attrs[attrName];
|
|
77
|
-
if (next && next !== current) {
|
|
78
|
-
table.setAttribute(attrName, next);
|
|
79
|
-
}
|
|
80
|
-
else if (!next) {
|
|
81
|
-
table.removeAttribute(attrName);
|
|
82
|
-
}
|
|
75
|
+
setAttribute(table, attrName, attrs[attrName]);
|
|
83
76
|
}
|
|
84
77
|
}
|
|
85
78
|
if (/%$/.test(table.style.width)) {
|
|
@@ -119,14 +112,7 @@ var TableWrapperView = /** @class */ (function () {
|
|
|
119
112
|
TableWrapperView.prototype.setAttributes = function (dom, attrs) {
|
|
120
113
|
for (var attrName in attrs) {
|
|
121
114
|
if (attrName) {
|
|
122
|
-
|
|
123
|
-
var next = attrs[attrName];
|
|
124
|
-
if (next && next !== current) {
|
|
125
|
-
dom.setAttribute(attrName, next);
|
|
126
|
-
}
|
|
127
|
-
else if (!next) {
|
|
128
|
-
dom.removeAttribute(attrName);
|
|
129
|
-
}
|
|
115
|
+
setAttribute(dom, attrName, attrs[attrName]);
|
|
130
116
|
}
|
|
131
117
|
}
|
|
132
118
|
dom.setAttribute('table', '');
|
|
@@ -3,14 +3,6 @@ import { PluginKey } from 'prosemirror-state';
|
|
|
3
3
|
import { TableMap } from 'prosemirror-tables';
|
|
4
4
|
import { changeStylesString } from '../../utils';
|
|
5
5
|
export var reAnyValue = /^.+$/;
|
|
6
|
-
export var parseStyle = function (styleText) {
|
|
7
|
-
var styles = (styleText || '').split(/\s*;\s*/).filter(Boolean).map(function (s) {
|
|
8
|
-
var _a;
|
|
9
|
-
var nameValue = s.split(/\s*:\s*/);
|
|
10
|
-
return _a = {}, _a[nameValue[0]] = nameValue[1], _a;
|
|
11
|
-
}).reduce(function (acc, val) { return (__assign(__assign({}, acc), val)); }, {});
|
|
12
|
-
return styles;
|
|
13
|
-
};
|
|
14
6
|
export function setNodeStyle(nodeAttrs, styleType, value) {
|
|
15
7
|
var attrs;
|
|
16
8
|
if (new RegExp('[^-]?' + styleType + ':').test(nodeAttrs.style || '')) {
|
package/dist/es/source.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DOMParser as ProseMirrorDOMParser } from 'prosemirror-model';
|
|
2
2
|
import { AllSelection } from 'prosemirror-state';
|
|
3
3
|
import { rowTypeAttr, colgroupAttr } from './config/constants';
|
|
4
|
+
import { DOMSerializer } from './DOMSerializer';
|
|
4
5
|
var blockWrappers = [
|
|
5
6
|
'div', 'ol', 'ul', 'li', 'table', 'tbody', 'thead', 'tfoot', 'caption', 'td', 'th', 'p',
|
|
6
7
|
'tr', 'col', 'colgroup', 'article', 'main', 'nav', 'header', 'footer', 'aside', 'section'
|
|
@@ -128,6 +129,29 @@ export var trimWhitespace = function (html, trimAroundTags) {
|
|
|
128
129
|
return html.replace(new RegExp('\\s*(<(?:' + tags + ')(?:\\s[^>]*?)?>)', 'g'), '$1')
|
|
129
130
|
.replace(new RegExp('(<\\/(?:' + tags + ')(?:\\s[^>]*?)?>)\\s*', 'g'), '$1');
|
|
130
131
|
};
|
|
132
|
+
var styleAttr = 'data-style';
|
|
133
|
+
var styleReplace = ' ' + styleAttr + '=';
|
|
134
|
+
var reTag = /<[^>]+>/gm;
|
|
135
|
+
var reStyle = /\sstyle=/gm;
|
|
136
|
+
var replacer = function (match) {
|
|
137
|
+
return match.replace(reStyle, styleReplace);
|
|
138
|
+
};
|
|
139
|
+
var replaceStyleAttr = function (html) {
|
|
140
|
+
return html.replace(reTag, replacer);
|
|
141
|
+
};
|
|
142
|
+
var applyStyle = function (styleString, element) {
|
|
143
|
+
return styleString.split(';').filter(function (s) { return s !== ''; }).forEach(function (s) {
|
|
144
|
+
var parts = s.split(':');
|
|
145
|
+
element.style[parts[0].trim()] = parts[1].trim();
|
|
146
|
+
});
|
|
147
|
+
};
|
|
148
|
+
var restoreStyleAttr = function (container) {
|
|
149
|
+
Array.from(container.querySelectorAll('[' + styleAttr + ']')).forEach(function (element) {
|
|
150
|
+
var styleString = element.getAttribute(styleAttr);
|
|
151
|
+
element.removeAttribute(styleAttr);
|
|
152
|
+
applyStyle(styleString, element);
|
|
153
|
+
});
|
|
154
|
+
};
|
|
131
155
|
/**
|
|
132
156
|
* Creates a DocumentFragment from the given HTML content.
|
|
133
157
|
*
|
|
@@ -136,21 +160,9 @@ export var trimWhitespace = function (html, trimAroundTags) {
|
|
|
136
160
|
*/
|
|
137
161
|
export var htmlToFragment = function (html) {
|
|
138
162
|
var template = document.createElement('template');
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
fragment = template.content;
|
|
143
|
-
}
|
|
144
|
-
else {
|
|
145
|
-
// Internet Explorer
|
|
146
|
-
var parsedDocument = new DOMParser().parseFromString(html, 'text/html');
|
|
147
|
-
fragment = document.createDocumentFragment();
|
|
148
|
-
var dom = parsedDocument.body;
|
|
149
|
-
while (dom && dom.firstChild) {
|
|
150
|
-
fragment.appendChild(dom.firstChild);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
return fragment;
|
|
163
|
+
template.innerHTML = replaceStyleAttr(html);
|
|
164
|
+
restoreStyleAttr(template.content);
|
|
165
|
+
return template.content;
|
|
154
166
|
};
|
|
155
167
|
/**
|
|
156
168
|
* @hidden
|
|
@@ -200,9 +212,7 @@ export var parseContent = function (content, schema, parseOptions) {
|
|
|
200
212
|
*/
|
|
201
213
|
export var getHtml = function (state) {
|
|
202
214
|
var fragment = pmDocToFragment(state.doc);
|
|
203
|
-
|
|
204
|
-
container.appendChild(fragment);
|
|
205
|
-
return container.innerHTML;
|
|
215
|
+
return fragmentToHtml(fragment);
|
|
206
216
|
};
|
|
207
217
|
/**
|
|
208
218
|
* Replaces the content of the editor with a new one.
|
package/dist/es/utils.js
CHANGED
|
@@ -232,3 +232,34 @@ export var expandToWordWrap = function (command, options) {
|
|
|
232
232
|
return command(options)(cmdState, cmdDispatch);
|
|
233
233
|
};
|
|
234
234
|
};
|
|
235
|
+
export var parseStyle = function (styleText) {
|
|
236
|
+
var styles = (styleText || '').split(/\s*;\s*/).filter(Boolean).map(function (s) {
|
|
237
|
+
var _a;
|
|
238
|
+
var nameValue = s.split(/\s*:\s*/);
|
|
239
|
+
return _a = {}, _a[nameValue[0]] = nameValue[1], _a;
|
|
240
|
+
}).reduce(function (acc, val) { return (__assign(__assign({}, acc), val)); }, {});
|
|
241
|
+
return styles;
|
|
242
|
+
};
|
|
243
|
+
var setStyleAttr = function (element, styleString) {
|
|
244
|
+
var styles = parseStyle(styleString);
|
|
245
|
+
for (var style in styles) {
|
|
246
|
+
if (style && typeof element.style[style] !== 'undefined') {
|
|
247
|
+
element.style[style] = styles[style];
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
export var setAttribute = function (node, attrName, value) {
|
|
252
|
+
var current = node.getAttribute(attrName);
|
|
253
|
+
if (value !== undefined && value !== current) {
|
|
254
|
+
if (attrName === 'style') {
|
|
255
|
+
node.removeAttribute(attrName);
|
|
256
|
+
setStyleAttr(node, value);
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
node.setAttribute(attrName, value);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
else if (value === undefined) {
|
|
263
|
+
node.removeAttribute(attrName);
|
|
264
|
+
}
|
|
265
|
+
};
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { setAttribute } from "./utils";
|
|
2
|
+
export class DOMSerializer {
|
|
3
|
+
/// Create a serializer. `nodes` should map node names to functions
|
|
4
|
+
/// that take a node and return a description of the corresponding
|
|
5
|
+
/// DOM. `marks` does the same for mark names, but also gets an
|
|
6
|
+
/// argument that tells it whether the mark's content is block or
|
|
7
|
+
/// inline content (for typical use, it'll always be inline). A mark
|
|
8
|
+
/// serializer may be `null` to indicate that marks of that type
|
|
9
|
+
/// should not be serialized.
|
|
10
|
+
constructor(
|
|
11
|
+
/// The node serialization functions.
|
|
12
|
+
nodes,
|
|
13
|
+
/// The mark serialization functions.
|
|
14
|
+
marks) {
|
|
15
|
+
this.nodes = nodes;
|
|
16
|
+
this.marks = marks;
|
|
17
|
+
}
|
|
18
|
+
/// Render an [output spec](#model.DOMOutputSpec) to a DOM node. If
|
|
19
|
+
/// the spec has a hole (zero) in it, `contentDOM` will point at the
|
|
20
|
+
/// node with the hole.
|
|
21
|
+
static renderSpec(docum, structure, xmlNS = null) {
|
|
22
|
+
if (typeof structure === "string") {
|
|
23
|
+
return { dom: docum.createTextNode(structure) };
|
|
24
|
+
}
|
|
25
|
+
if (structure.nodeType != null) {
|
|
26
|
+
return { dom: structure };
|
|
27
|
+
}
|
|
28
|
+
if (structure.dom && structure.dom.nodeType != null) {
|
|
29
|
+
return structure;
|
|
30
|
+
}
|
|
31
|
+
let tagName = structure[0], space = tagName.indexOf(" ");
|
|
32
|
+
if (space > 0) {
|
|
33
|
+
xmlNS = tagName.slice(0, space);
|
|
34
|
+
tagName = tagName.slice(space + 1);
|
|
35
|
+
}
|
|
36
|
+
let contentDOM;
|
|
37
|
+
let dom = (xmlNS ? docum.createElementNS(xmlNS, tagName) : docum.createElement(tagName));
|
|
38
|
+
let attrs = structure[1], start = 1;
|
|
39
|
+
if (attrs && typeof attrs === "object" && attrs.nodeType == null && !Array.isArray(attrs)) {
|
|
40
|
+
start = 2;
|
|
41
|
+
for (let name in attrs) {
|
|
42
|
+
if (attrs[name] != null) {
|
|
43
|
+
space = name.indexOf(" ");
|
|
44
|
+
if (space > 0) {
|
|
45
|
+
dom.setAttributeNS(name.slice(0, space), name.slice(space + 1), attrs[name]);
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
setAttribute(dom, name, attrs[name]);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
for (let i = start; i < structure.length; i++) {
|
|
54
|
+
let child = structure[i];
|
|
55
|
+
if (child === 0) {
|
|
56
|
+
if (i < structure.length - 1 || i > start) {
|
|
57
|
+
throw new RangeError("Content hole must be the only child of its parent node");
|
|
58
|
+
}
|
|
59
|
+
return { dom, contentDOM: dom };
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
let { dom: inner, contentDOM: innerContent } = DOMSerializer.renderSpec(docum, child, xmlNS);
|
|
63
|
+
dom.appendChild(inner);
|
|
64
|
+
if (innerContent) {
|
|
65
|
+
if (contentDOM) {
|
|
66
|
+
throw new RangeError("Multiple content holes");
|
|
67
|
+
}
|
|
68
|
+
contentDOM = innerContent;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return { dom, contentDOM };
|
|
73
|
+
}
|
|
74
|
+
/// Build a serializer using the [`toDOM`](#model.NodeSpec.toDOM)
|
|
75
|
+
/// properties in a schema's node and mark specs.
|
|
76
|
+
static fromSchema(schema) {
|
|
77
|
+
return schema.cached.domSerializer ||
|
|
78
|
+
(schema.cached.domSerializer = new DOMSerializer(this.nodesFromSchema(schema), this.marksFromSchema(schema)));
|
|
79
|
+
}
|
|
80
|
+
/// Gather the serializers in a schema's node specs into an object.
|
|
81
|
+
/// This can be useful as a base to build a custom serializer from.
|
|
82
|
+
static nodesFromSchema(schema) {
|
|
83
|
+
let result = gatherToDOM(schema.nodes);
|
|
84
|
+
if (!result.text) {
|
|
85
|
+
result.text = node => node.text;
|
|
86
|
+
}
|
|
87
|
+
return result;
|
|
88
|
+
}
|
|
89
|
+
/// Gather the serializers in a schema's mark specs into an object.
|
|
90
|
+
static marksFromSchema(schema) {
|
|
91
|
+
return gatherToDOM(schema.marks);
|
|
92
|
+
}
|
|
93
|
+
/// Serialize the content of this fragment to a DOM fragment. When
|
|
94
|
+
/// not in the browser, the `document` option, containing a DOM
|
|
95
|
+
/// document, should be passed so that the serializer can create
|
|
96
|
+
/// nodes.
|
|
97
|
+
serializeFragment(fragment, options = {}, target) {
|
|
98
|
+
if (!target) {
|
|
99
|
+
target = doc(options).createDocumentFragment();
|
|
100
|
+
}
|
|
101
|
+
let top = target, active = [];
|
|
102
|
+
fragment.forEach(node => {
|
|
103
|
+
if (active.length || node.marks.length) {
|
|
104
|
+
let keep = 0, rendered = 0;
|
|
105
|
+
while (keep < active.length && rendered < node.marks.length) {
|
|
106
|
+
let next = node.marks[rendered];
|
|
107
|
+
if (!this.marks[next.type.name]) {
|
|
108
|
+
rendered++;
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
if (!next.eq(active[keep][0]) || next.type.spec.spanning === false) {
|
|
112
|
+
break;
|
|
113
|
+
}
|
|
114
|
+
keep++;
|
|
115
|
+
rendered++;
|
|
116
|
+
}
|
|
117
|
+
while (keep < active.length) {
|
|
118
|
+
top = active.pop()[1];
|
|
119
|
+
}
|
|
120
|
+
while (rendered < node.marks.length) {
|
|
121
|
+
let add = node.marks[rendered++];
|
|
122
|
+
let markDOM = this.serializeMark(add, node.isInline, options);
|
|
123
|
+
if (markDOM) {
|
|
124
|
+
active.push([add, top]);
|
|
125
|
+
top.appendChild(markDOM.dom);
|
|
126
|
+
top = markDOM.contentDOM || markDOM.dom;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
top.appendChild(this.serializeNodeInner(node, options));
|
|
131
|
+
});
|
|
132
|
+
return target;
|
|
133
|
+
}
|
|
134
|
+
/// Serialize this node to a DOM node. This can be useful when you
|
|
135
|
+
/// need to serialize a part of a document, as opposed to the whole
|
|
136
|
+
/// document. To serialize a whole document, use
|
|
137
|
+
/// [`serializeFragment`](#model.DOMSerializer.serializeFragment) on
|
|
138
|
+
/// its [content](#model.Node.content).
|
|
139
|
+
serializeNode(node, options = {}) {
|
|
140
|
+
let dom = this.serializeNodeInner(node, options);
|
|
141
|
+
for (let i = node.marks.length - 1; i >= 0; i--) {
|
|
142
|
+
let wrap = this.serializeMark(node.marks[i], node.isInline, options);
|
|
143
|
+
if (wrap) {
|
|
144
|
+
(wrap.contentDOM || wrap.dom).appendChild(dom);
|
|
145
|
+
dom = wrap.dom;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return dom;
|
|
149
|
+
}
|
|
150
|
+
/// @internal
|
|
151
|
+
serializeMark(mark, inline, options = {}) {
|
|
152
|
+
let toDOM = this.marks[mark.type.name];
|
|
153
|
+
return toDOM && DOMSerializer.renderSpec(doc(options), toDOM(mark, inline));
|
|
154
|
+
}
|
|
155
|
+
/// @internal
|
|
156
|
+
serializeNodeInner(node, options) {
|
|
157
|
+
let { dom, contentDOM } = DOMSerializer.renderSpec(doc(options), this.nodes[node.type.name](node));
|
|
158
|
+
if (contentDOM) {
|
|
159
|
+
if (node.isLeaf) {
|
|
160
|
+
throw new RangeError("Content hole not allowed in a leaf node spec");
|
|
161
|
+
}
|
|
162
|
+
this.serializeFragment(node.content, options, contentDOM);
|
|
163
|
+
}
|
|
164
|
+
return dom;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
function gatherToDOM(obj) {
|
|
168
|
+
let result = {};
|
|
169
|
+
for (let name in obj) {
|
|
170
|
+
if (obj[name]) {
|
|
171
|
+
let toDOM = obj[name].spec.toDOM;
|
|
172
|
+
if (toDOM) {
|
|
173
|
+
result[name] = toDOM;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return result;
|
|
178
|
+
}
|
|
179
|
+
function doc(options) {
|
|
180
|
+
return options.document || window.document;
|
|
181
|
+
}
|
package/dist/es2015/main.js
CHANGED
|
@@ -21,6 +21,7 @@ export { convertMsLists } from './listConvert';
|
|
|
21
21
|
export { find, findAt, findAll, replace, replaceAll } from './find-replace';
|
|
22
22
|
export { placeholder } from './plugins/placeholder';
|
|
23
23
|
export { spacesFix } from './plugins/spaces-fix';
|
|
24
|
+
export { cspFix } from './plugins/csp-fix';
|
|
24
25
|
export { textHighlight, textHighlightKey } from './plugins/highlight';
|
|
25
26
|
export { imageResizing, imageResizeKey } from './plugins/image-resize';
|
|
26
27
|
export { caretColor, caretColorKey } from './plugins/caret-color';
|