@progress/kendo-editor-common 1.5.0 → 1.6.0-dev.202110271424
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 +2 -2
- package/dist/cdn/main.js +1 -1
- package/dist/es/blockquote.js +23 -0
- package/dist/es/indent.js +7 -2
- package/dist/es/main.js +2 -0
- package/dist/es/plugins/image-resize.js +234 -0
- package/dist/es2015/blockquote.js +23 -0
- package/dist/es2015/indent.js +7 -2
- package/dist/es2015/main.js +2 -0
- package/dist/es2015/plugins/image-resize.js +231 -0
- package/dist/npm/blockquote.d.ts +3 -0
- package/dist/npm/blockquote.js +25 -0
- package/dist/npm/indent.js +7 -2
- package/dist/npm/main.d.ts +2 -0
- package/dist/npm/main.js +6 -0
- package/dist/npm/plugins/image-resize.d.ts +7 -0
- package/dist/npm/plugins/image-resize.js +236 -0
- package/dist/systemjs/kendo-editor-common.js +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { wrapIn } from 'prosemirror-commands';
|
|
2
|
+
export var blockquote = function (state, dispatch) {
|
|
3
|
+
return wrapIn(state.schema.nodes.blockquote)(state, dispatch);
|
|
4
|
+
};
|
|
5
|
+
export var liftBlockquote = function (state, dispatch) {
|
|
6
|
+
var _a = state.selection, $from = _a.$from, $to = _a.$to;
|
|
7
|
+
var nodeType = state.schema.nodes.blockquote;
|
|
8
|
+
var doc = state.doc;
|
|
9
|
+
var target = -1;
|
|
10
|
+
var range = $from.blockRange($to);
|
|
11
|
+
if (range) {
|
|
12
|
+
doc.nodesBetween(range.start, range.end, function (node, pos, _parent, _index) {
|
|
13
|
+
if (node.type === nodeType) {
|
|
14
|
+
target = pos;
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
var result = target !== -1;
|
|
19
|
+
if (dispatch && result) {
|
|
20
|
+
dispatch(state.tr.lift(range, doc.resolve(target).depth));
|
|
21
|
+
}
|
|
22
|
+
return result;
|
|
23
|
+
};
|
package/dist/es/indent.js
CHANGED
|
@@ -2,6 +2,7 @@ import { sinkListItem, liftListItem } from 'prosemirror-schema-list';
|
|
|
2
2
|
import { indentRules, outdentRules } from './config/indent-rules';
|
|
3
3
|
import { blockNodes, addStyles, changeTextBlock, hasNode } from './blockNode';
|
|
4
4
|
import { findNthParentNodeOfType } from './utils';
|
|
5
|
+
import { liftBlockquote } from './blockquote';
|
|
5
6
|
/**
|
|
6
7
|
* Indenting block elements in the selection.
|
|
7
8
|
*
|
|
@@ -86,9 +87,13 @@ export var indent = function (state, dispatch) {
|
|
|
86
87
|
}
|
|
87
88
|
};
|
|
88
89
|
export var outdent = function (state, dispatch) {
|
|
89
|
-
var
|
|
90
|
+
var nodes = state.schema.nodes;
|
|
91
|
+
var listItem = nodes[outdentRules.listsTypes.listItem];
|
|
90
92
|
var isIndentableBlock = canBeIndented(state, outdentRules);
|
|
91
|
-
if (
|
|
93
|
+
if (hasNode(state, nodes.blockquote)) {
|
|
94
|
+
liftBlockquote(state, dispatch);
|
|
95
|
+
}
|
|
96
|
+
else if (canOutdentAsListItem(state, outdentRules)) {
|
|
92
97
|
liftListItem(listItem)(state, dispatch);
|
|
93
98
|
}
|
|
94
99
|
else if (isIndentableBlock) {
|
package/dist/es/main.js
CHANGED
|
@@ -9,6 +9,7 @@ export { hasNode, activeNode, formatBlockElements, getBlockFormats, parentBlockF
|
|
|
9
9
|
export { hasMark, getMark, getActiveMarks, removeAllMarks, cleanMarks, selectionMarks } from './mark';
|
|
10
10
|
export { indent, canIndentAsListItem, outdent, canOutdentAsListItem, isIndented, canBeIndented, indentBlocks } from './indent';
|
|
11
11
|
export { toggleOrderedList, toggleUnorderedList, toggleList } from './lists';
|
|
12
|
+
export { blockquote, liftBlockquote } from './blockquote';
|
|
12
13
|
export { hasSameMarkup, getSelectionText, getNodeFromSelection, selectedLineTextOnly, expandSelection, expandToWordWrap, canInsert, insertNode, indentHtml } from './utils';
|
|
13
14
|
export { alignLeftRules, alignCenterRules, alignRightRules, alignJustifyRules, alignRemoveRules } from './config/align-rules';
|
|
14
15
|
export { indentRules, outdentRules } from './config/indent-rules';
|
|
@@ -22,6 +23,7 @@ export { find, findAt, findAll, replace, replaceAll } from './find-replace';
|
|
|
22
23
|
export { placeholder } from './plugins/placeholder';
|
|
23
24
|
export { spacesFix } from './plugins/spaces-fix';
|
|
24
25
|
export { textHighlight, textHighlightKey } from './plugins/highlight';
|
|
26
|
+
export { imageResizing, imageResizeKey } from './plugins/image-resize';
|
|
25
27
|
// ProseMirror re-exports
|
|
26
28
|
export * from 'prosemirror-commands';
|
|
27
29
|
export * from 'prosemirror-dropcursor';
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import * as tslib_1 from "tslib";
|
|
2
|
+
import { NodeSelection, Plugin, PluginKey } from "prosemirror-state";
|
|
3
|
+
import { Decoration, DecorationSet } from "prosemirror-view";
|
|
4
|
+
import { changeStylesString } from "../utils";
|
|
5
|
+
export var imageResizeKey = new PluginKey('image-resize');
|
|
6
|
+
var directions = {
|
|
7
|
+
'southeast': { x: 1, y: 1 },
|
|
8
|
+
'east': { x: 1, y: 0 },
|
|
9
|
+
'south': { x: 0, y: 1 },
|
|
10
|
+
'north': { x: 0, y: -1 },
|
|
11
|
+
'west': { x: -1, y: 0 },
|
|
12
|
+
'southwest': { x: -1, y: 1 },
|
|
13
|
+
'northwest': { x: -1, y: -1 },
|
|
14
|
+
'northeast': { x: 1, y: -1 } // top right
|
|
15
|
+
};
|
|
16
|
+
var handles = Object.keys(directions);
|
|
17
|
+
var setSize = function (domNode, sizeType, value) {
|
|
18
|
+
domNode.style[sizeType] = value + 'px';
|
|
19
|
+
};
|
|
20
|
+
var reSize = /[^\-]width:|[^\-]height:/;
|
|
21
|
+
var reAnyValue = /^.+$/;
|
|
22
|
+
var ResizeState = /** @class */ (function () {
|
|
23
|
+
function ResizeState(activeHandle, dragging, rect, nodePosition) {
|
|
24
|
+
this.activeHandle = activeHandle;
|
|
25
|
+
this.dragging = dragging;
|
|
26
|
+
this.rect = rect;
|
|
27
|
+
this.nodePosition = nodePosition;
|
|
28
|
+
}
|
|
29
|
+
ResizeState.prototype.apply = function (tr) {
|
|
30
|
+
var state = this, next = tr.getMeta(imageResizeKey);
|
|
31
|
+
if (next) {
|
|
32
|
+
return new ResizeState(next.activeHandle, next.setDragging, next.rect, next.nodePosition);
|
|
33
|
+
}
|
|
34
|
+
return state;
|
|
35
|
+
};
|
|
36
|
+
return ResizeState;
|
|
37
|
+
}());
|
|
38
|
+
var handleMouseMove = function (view, event, options) {
|
|
39
|
+
var state = imageResizeKey.getState(view.state);
|
|
40
|
+
var rect = state.rect, dragging = state.dragging, nodePosition = state.nodePosition, activeHandle = state.activeHandle;
|
|
41
|
+
if (!dragging || !rect) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
var img = view.nodeDOM(nodePosition);
|
|
45
|
+
var dir = directions[activeHandle];
|
|
46
|
+
var diffX = (event.clientX - dragging.startX) * dir.x;
|
|
47
|
+
var diffY = (event.clientY - dragging.startY) * dir.y;
|
|
48
|
+
var width = dir.x ? diffX + img.width : rect.width;
|
|
49
|
+
var height = dir.y ? diffY + img.height : rect.height;
|
|
50
|
+
if (options.lockRatio && dir.x && dir.y) {
|
|
51
|
+
var ratio = Math.min(width / img.width, height / img.height);
|
|
52
|
+
var lockWidth = img.width * ratio;
|
|
53
|
+
var lockHeight = img.height * ratio;
|
|
54
|
+
dragging.startX = event.clientX - (width - lockWidth) * dir.x;
|
|
55
|
+
dragging.startY = event.clientY - (height - lockHeight) * dir.y;
|
|
56
|
+
width = lockWidth;
|
|
57
|
+
height = lockHeight;
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
dragging.startX = dir.x ? event.clientX : dragging.startX;
|
|
61
|
+
dragging.startY = dir.y ? event.clientY : dragging.startY;
|
|
62
|
+
}
|
|
63
|
+
setSize(img, 'width', width);
|
|
64
|
+
setSize(img, 'height', height);
|
|
65
|
+
rect.top = img.offsetTop;
|
|
66
|
+
rect.left = img.offsetLeft;
|
|
67
|
+
rect.width = img.offsetWidth;
|
|
68
|
+
rect.height = img.offsetHeight;
|
|
69
|
+
var handlesWrapper = img.nextElementSibling;
|
|
70
|
+
handlesWrapper.style.width = rect.width + 'px';
|
|
71
|
+
handlesWrapper.style.height = rect.height + 'px';
|
|
72
|
+
handlesWrapper.style.top = rect.top + 'px';
|
|
73
|
+
handlesWrapper.style.left = rect.left + 'px';
|
|
74
|
+
};
|
|
75
|
+
var handleMouseUp = function (view) {
|
|
76
|
+
var _a = imageResizeKey.getState(view.state), rect = _a.rect, dragging = _a.dragging, nodePosition = _a.nodePosition;
|
|
77
|
+
if (dragging && rect) {
|
|
78
|
+
var selection = view.state.selection;
|
|
79
|
+
if (selection instanceof NodeSelection) {
|
|
80
|
+
var currAttrs = selection.node.attrs;
|
|
81
|
+
var width = rect.width;
|
|
82
|
+
var height = rect.height;
|
|
83
|
+
var attrs = void 0;
|
|
84
|
+
if (reSize.test(currAttrs.style || '')) {
|
|
85
|
+
var changedWidth = changeStylesString(currAttrs.style, { style: 'width', value: reAnyValue, newValue: width + 'px' });
|
|
86
|
+
var style = changeStylesString(changedWidth.style || '', { style: 'height', value: reAnyValue, newValue: height + 'px' }).style;
|
|
87
|
+
attrs = tslib_1.__assign({}, currAttrs, { style: style });
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
attrs = tslib_1.__assign({}, currAttrs, { width: width, height: height });
|
|
91
|
+
}
|
|
92
|
+
var newImage = selection.node.type.createAndFill(attrs);
|
|
93
|
+
if (newImage) {
|
|
94
|
+
var tr = view.state.tr;
|
|
95
|
+
tr.replaceWith(nodePosition, nodePosition + 1, newImage);
|
|
96
|
+
tr.setSelection(NodeSelection.create(tr.doc, nodePosition));
|
|
97
|
+
tr.setMeta('commandName', 'image-resize');
|
|
98
|
+
tr.setMeta('args', attrs);
|
|
99
|
+
tr.setMeta(imageResizeKey, {
|
|
100
|
+
setDragging: null,
|
|
101
|
+
activeHandle: null,
|
|
102
|
+
rect: rect,
|
|
103
|
+
nodePosition: nodePosition
|
|
104
|
+
});
|
|
105
|
+
view.dispatch(tr);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
var handleMouseDown = function (view, event, options) {
|
|
111
|
+
var target = event.target;
|
|
112
|
+
var activeHandle = target.getAttribute('data-direction');
|
|
113
|
+
if (!activeHandle) {
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
var resizeState = imageResizeKey.getState(view.state);
|
|
117
|
+
event.preventDefault();
|
|
118
|
+
var transaction = view.state.tr;
|
|
119
|
+
transaction.setMeta(imageResizeKey, {
|
|
120
|
+
setDragging: { startX: event.clientX, startY: event.clientY },
|
|
121
|
+
activeHandle: activeHandle,
|
|
122
|
+
rect: resizeState.rect,
|
|
123
|
+
nodePosition: resizeState.nodePosition
|
|
124
|
+
});
|
|
125
|
+
transaction.setMeta('addToHistory', false);
|
|
126
|
+
view.dispatch(transaction);
|
|
127
|
+
function move(e) {
|
|
128
|
+
handleMouseMove(view, e, options);
|
|
129
|
+
}
|
|
130
|
+
function finish(e) {
|
|
131
|
+
e.view.removeEventListener('mouseup', finish);
|
|
132
|
+
e.view.removeEventListener('mousemove', move);
|
|
133
|
+
handleMouseUp(view);
|
|
134
|
+
}
|
|
135
|
+
event.view.addEventListener('mouseup', finish);
|
|
136
|
+
event.view.addEventListener('mousemove', move);
|
|
137
|
+
return true;
|
|
138
|
+
};
|
|
139
|
+
export var imageResizing = function (options) {
|
|
140
|
+
if (options === void 0) { options = { node: 'image', lockRatio: true }; }
|
|
141
|
+
return new Plugin({
|
|
142
|
+
key: imageResizeKey,
|
|
143
|
+
view: function (viewObj) { return ({
|
|
144
|
+
resize: function () {
|
|
145
|
+
if (imageResizeKey.getState(viewObj.state).rect) {
|
|
146
|
+
viewObj.dispatch(viewObj.state.tr.setMeta('resize', true));
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
get window() {
|
|
150
|
+
return viewObj.dom.ownerDocument && viewObj.dom.ownerDocument.defaultView;
|
|
151
|
+
},
|
|
152
|
+
attachResize: function () {
|
|
153
|
+
var win = this.window;
|
|
154
|
+
if (win) {
|
|
155
|
+
win.removeEventListener('resize', this.resize);
|
|
156
|
+
win.addEventListener('resize', this.resize);
|
|
157
|
+
}
|
|
158
|
+
},
|
|
159
|
+
removeResize: function () {
|
|
160
|
+
var win = this.window;
|
|
161
|
+
if (win) {
|
|
162
|
+
win.removeEventListener('resize', this.resize);
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
update: function (view, prevState) {
|
|
166
|
+
var state = view.state;
|
|
167
|
+
var selection = state.selection;
|
|
168
|
+
var nodeType = state.schema.nodes[options.node];
|
|
169
|
+
var pluginState = imageResizeKey.getState(state);
|
|
170
|
+
var prevRect = pluginState.rect;
|
|
171
|
+
if (selection instanceof NodeSelection && nodeType === selection.node.type) {
|
|
172
|
+
var img = view.nodeDOM(selection.from);
|
|
173
|
+
var rect = {
|
|
174
|
+
top: img.offsetTop,
|
|
175
|
+
left: img.offsetLeft,
|
|
176
|
+
width: img.offsetWidth,
|
|
177
|
+
height: img.offsetHeight
|
|
178
|
+
};
|
|
179
|
+
if (!prevState.selection.eq(selection) ||
|
|
180
|
+
(prevRect && (prevRect.width !== rect.width || prevRect.height !== rect.height ||
|
|
181
|
+
prevRect.top !== rect.top || prevRect.left !== rect.left))) {
|
|
182
|
+
var tr = state.tr;
|
|
183
|
+
tr.setMeta(imageResizeKey, { rect: rect, nodePosition: selection.from });
|
|
184
|
+
view.dispatch(tr);
|
|
185
|
+
this.attachResize();
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
else if (prevRect) {
|
|
189
|
+
pluginState.rect = null;
|
|
190
|
+
pluginState.nodePosition = -1;
|
|
191
|
+
}
|
|
192
|
+
},
|
|
193
|
+
destroy: function () {
|
|
194
|
+
this.removeResize();
|
|
195
|
+
}
|
|
196
|
+
}); },
|
|
197
|
+
state: {
|
|
198
|
+
init: function () {
|
|
199
|
+
return new ResizeState('', null, null, -1);
|
|
200
|
+
},
|
|
201
|
+
apply: function (tr, prev) {
|
|
202
|
+
return prev.apply(tr);
|
|
203
|
+
}
|
|
204
|
+
},
|
|
205
|
+
props: {
|
|
206
|
+
handleDOMEvents: {
|
|
207
|
+
mousedown: function (view, event) {
|
|
208
|
+
return handleMouseDown(view, event, options);
|
|
209
|
+
}
|
|
210
|
+
},
|
|
211
|
+
decorations: function (state) {
|
|
212
|
+
var selection = state.selection;
|
|
213
|
+
var nodeType = state.schema.nodes[options.node];
|
|
214
|
+
var rect = imageResizeKey.getState(state).rect;
|
|
215
|
+
if (rect && selection instanceof NodeSelection && nodeType === selection.node.type) {
|
|
216
|
+
var wrapper = document.createElement('div');
|
|
217
|
+
wrapper.className = 'k-editor-resize-handles-wrapper';
|
|
218
|
+
wrapper.style.width = rect.width + 'px';
|
|
219
|
+
wrapper.style.height = rect.height + 'px';
|
|
220
|
+
wrapper.style.top = rect.top + 'px';
|
|
221
|
+
wrapper.style.left = rect.left + 'px';
|
|
222
|
+
for (var i = 0; i < handles.length; i++) {
|
|
223
|
+
var dom = document.createElement('div');
|
|
224
|
+
dom.className = 'k-editor-resize-handle ' + handles[i];
|
|
225
|
+
dom.setAttribute('data-direction', handles[i]);
|
|
226
|
+
wrapper.appendChild(dom);
|
|
227
|
+
}
|
|
228
|
+
return DecorationSet.create(state.doc, [Decoration.widget(state.selection.from + 1, wrapper)]);
|
|
229
|
+
}
|
|
230
|
+
return DecorationSet.empty;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
});
|
|
234
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { wrapIn } from 'prosemirror-commands';
|
|
2
|
+
export const blockquote = (state, dispatch) => {
|
|
3
|
+
return wrapIn(state.schema.nodes.blockquote)(state, dispatch);
|
|
4
|
+
};
|
|
5
|
+
export const liftBlockquote = (state, dispatch) => {
|
|
6
|
+
const { $from, $to } = state.selection;
|
|
7
|
+
const nodeType = state.schema.nodes.blockquote;
|
|
8
|
+
const doc = state.doc;
|
|
9
|
+
let target = -1;
|
|
10
|
+
const range = $from.blockRange($to);
|
|
11
|
+
if (range) {
|
|
12
|
+
doc.nodesBetween(range.start, range.end, (node, pos, _parent, _index) => {
|
|
13
|
+
if (node.type === nodeType) {
|
|
14
|
+
target = pos;
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
const result = target !== -1;
|
|
19
|
+
if (dispatch && result) {
|
|
20
|
+
dispatch(state.tr.lift(range, doc.resolve(target).depth));
|
|
21
|
+
}
|
|
22
|
+
return result;
|
|
23
|
+
};
|
package/dist/es2015/indent.js
CHANGED
|
@@ -2,6 +2,7 @@ import { sinkListItem, liftListItem } from 'prosemirror-schema-list';
|
|
|
2
2
|
import { indentRules, outdentRules } from './config/indent-rules';
|
|
3
3
|
import { blockNodes, addStyles, changeTextBlock, hasNode } from './blockNode';
|
|
4
4
|
import { findNthParentNodeOfType } from './utils';
|
|
5
|
+
import { liftBlockquote } from './blockquote';
|
|
5
6
|
/**
|
|
6
7
|
* Indenting block elements in the selection.
|
|
7
8
|
*
|
|
@@ -86,9 +87,13 @@ export const indent = (state, dispatch) => {
|
|
|
86
87
|
}
|
|
87
88
|
};
|
|
88
89
|
export const outdent = (state, dispatch) => {
|
|
89
|
-
const
|
|
90
|
+
const nodes = state.schema.nodes;
|
|
91
|
+
const listItem = nodes[outdentRules.listsTypes.listItem];
|
|
90
92
|
const isIndentableBlock = canBeIndented(state, outdentRules);
|
|
91
|
-
if (
|
|
93
|
+
if (hasNode(state, nodes.blockquote)) {
|
|
94
|
+
liftBlockquote(state, dispatch);
|
|
95
|
+
}
|
|
96
|
+
else if (canOutdentAsListItem(state, outdentRules)) {
|
|
92
97
|
liftListItem(listItem)(state, dispatch);
|
|
93
98
|
}
|
|
94
99
|
else if (isIndentableBlock) {
|
package/dist/es2015/main.js
CHANGED
|
@@ -9,6 +9,7 @@ export { hasNode, activeNode, formatBlockElements, getBlockFormats, parentBlockF
|
|
|
9
9
|
export { hasMark, getMark, getActiveMarks, removeAllMarks, cleanMarks, selectionMarks } from './mark';
|
|
10
10
|
export { indent, canIndentAsListItem, outdent, canOutdentAsListItem, isIndented, canBeIndented, indentBlocks } from './indent';
|
|
11
11
|
export { toggleOrderedList, toggleUnorderedList, toggleList } from './lists';
|
|
12
|
+
export { blockquote, liftBlockquote } from './blockquote';
|
|
12
13
|
export { hasSameMarkup, getSelectionText, getNodeFromSelection, selectedLineTextOnly, expandSelection, expandToWordWrap, canInsert, insertNode, indentHtml } from './utils';
|
|
13
14
|
export { alignLeftRules, alignCenterRules, alignRightRules, alignJustifyRules, alignRemoveRules } from './config/align-rules';
|
|
14
15
|
export { indentRules, outdentRules } from './config/indent-rules';
|
|
@@ -22,6 +23,7 @@ export { find, findAt, findAll, replace, replaceAll } from './find-replace';
|
|
|
22
23
|
export { placeholder } from './plugins/placeholder';
|
|
23
24
|
export { spacesFix } from './plugins/spaces-fix';
|
|
24
25
|
export { textHighlight, textHighlightKey } from './plugins/highlight';
|
|
26
|
+
export { imageResizing, imageResizeKey } from './plugins/image-resize';
|
|
25
27
|
// ProseMirror re-exports
|
|
26
28
|
export * from 'prosemirror-commands';
|
|
27
29
|
export * from 'prosemirror-dropcursor';
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import { NodeSelection, Plugin, PluginKey } from "prosemirror-state";
|
|
2
|
+
import { Decoration, DecorationSet } from "prosemirror-view";
|
|
3
|
+
import { changeStylesString } from "../utils";
|
|
4
|
+
export const imageResizeKey = new PluginKey('image-resize');
|
|
5
|
+
const directions = {
|
|
6
|
+
'southeast': { x: 1, y: 1 },
|
|
7
|
+
'east': { x: 1, y: 0 },
|
|
8
|
+
'south': { x: 0, y: 1 },
|
|
9
|
+
'north': { x: 0, y: -1 },
|
|
10
|
+
'west': { x: -1, y: 0 },
|
|
11
|
+
'southwest': { x: -1, y: 1 },
|
|
12
|
+
'northwest': { x: -1, y: -1 },
|
|
13
|
+
'northeast': { x: 1, y: -1 } // top right
|
|
14
|
+
};
|
|
15
|
+
const handles = Object.keys(directions);
|
|
16
|
+
const setSize = (domNode, sizeType, value) => {
|
|
17
|
+
domNode.style[sizeType] = value + 'px';
|
|
18
|
+
};
|
|
19
|
+
const reSize = /[^\-]width:|[^\-]height:/;
|
|
20
|
+
const reAnyValue = /^.+$/;
|
|
21
|
+
class ResizeState {
|
|
22
|
+
constructor(activeHandle, dragging, rect, nodePosition) {
|
|
23
|
+
this.activeHandle = activeHandle;
|
|
24
|
+
this.dragging = dragging;
|
|
25
|
+
this.rect = rect;
|
|
26
|
+
this.nodePosition = nodePosition;
|
|
27
|
+
}
|
|
28
|
+
apply(tr) {
|
|
29
|
+
let state = this, next = tr.getMeta(imageResizeKey);
|
|
30
|
+
if (next) {
|
|
31
|
+
return new ResizeState(next.activeHandle, next.setDragging, next.rect, next.nodePosition);
|
|
32
|
+
}
|
|
33
|
+
return state;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
const handleMouseMove = (view, event, options) => {
|
|
37
|
+
const state = imageResizeKey.getState(view.state);
|
|
38
|
+
const { rect, dragging, nodePosition: nodePosition, activeHandle } = state;
|
|
39
|
+
if (!dragging || !rect) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const img = view.nodeDOM(nodePosition);
|
|
43
|
+
const dir = directions[activeHandle];
|
|
44
|
+
const diffX = (event.clientX - dragging.startX) * dir.x;
|
|
45
|
+
const diffY = (event.clientY - dragging.startY) * dir.y;
|
|
46
|
+
let width = dir.x ? diffX + img.width : rect.width;
|
|
47
|
+
let height = dir.y ? diffY + img.height : rect.height;
|
|
48
|
+
if (options.lockRatio && dir.x && dir.y) {
|
|
49
|
+
let ratio = Math.min(width / img.width, height / img.height);
|
|
50
|
+
let lockWidth = img.width * ratio;
|
|
51
|
+
let lockHeight = img.height * ratio;
|
|
52
|
+
dragging.startX = event.clientX - (width - lockWidth) * dir.x;
|
|
53
|
+
dragging.startY = event.clientY - (height - lockHeight) * dir.y;
|
|
54
|
+
width = lockWidth;
|
|
55
|
+
height = lockHeight;
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
dragging.startX = dir.x ? event.clientX : dragging.startX;
|
|
59
|
+
dragging.startY = dir.y ? event.clientY : dragging.startY;
|
|
60
|
+
}
|
|
61
|
+
setSize(img, 'width', width);
|
|
62
|
+
setSize(img, 'height', height);
|
|
63
|
+
rect.top = img.offsetTop;
|
|
64
|
+
rect.left = img.offsetLeft;
|
|
65
|
+
rect.width = img.offsetWidth;
|
|
66
|
+
rect.height = img.offsetHeight;
|
|
67
|
+
const handlesWrapper = img.nextElementSibling;
|
|
68
|
+
handlesWrapper.style.width = rect.width + 'px';
|
|
69
|
+
handlesWrapper.style.height = rect.height + 'px';
|
|
70
|
+
handlesWrapper.style.top = rect.top + 'px';
|
|
71
|
+
handlesWrapper.style.left = rect.left + 'px';
|
|
72
|
+
};
|
|
73
|
+
const handleMouseUp = (view) => {
|
|
74
|
+
const { rect, dragging, nodePosition } = imageResizeKey.getState(view.state);
|
|
75
|
+
if (dragging && rect) {
|
|
76
|
+
const selection = view.state.selection;
|
|
77
|
+
if (selection instanceof NodeSelection) {
|
|
78
|
+
const currAttrs = selection.node.attrs;
|
|
79
|
+
const width = rect.width;
|
|
80
|
+
const height = rect.height;
|
|
81
|
+
let attrs;
|
|
82
|
+
if (reSize.test(currAttrs.style || '')) {
|
|
83
|
+
const changedWidth = changeStylesString(currAttrs.style, { style: 'width', value: reAnyValue, newValue: width + 'px' });
|
|
84
|
+
const { style } = changeStylesString(changedWidth.style || '', { style: 'height', value: reAnyValue, newValue: height + 'px' });
|
|
85
|
+
attrs = Object.assign({}, currAttrs, { style });
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
attrs = Object.assign({}, currAttrs, { width, height });
|
|
89
|
+
}
|
|
90
|
+
const newImage = selection.node.type.createAndFill(attrs);
|
|
91
|
+
if (newImage) {
|
|
92
|
+
const tr = view.state.tr;
|
|
93
|
+
tr.replaceWith(nodePosition, nodePosition + 1, newImage);
|
|
94
|
+
tr.setSelection(NodeSelection.create(tr.doc, nodePosition));
|
|
95
|
+
tr.setMeta('commandName', 'image-resize');
|
|
96
|
+
tr.setMeta('args', attrs);
|
|
97
|
+
tr.setMeta(imageResizeKey, {
|
|
98
|
+
setDragging: null,
|
|
99
|
+
activeHandle: null,
|
|
100
|
+
rect,
|
|
101
|
+
nodePosition
|
|
102
|
+
});
|
|
103
|
+
view.dispatch(tr);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
const handleMouseDown = (view, event, options) => {
|
|
109
|
+
const target = event.target;
|
|
110
|
+
const activeHandle = target.getAttribute('data-direction');
|
|
111
|
+
if (!activeHandle) {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
const resizeState = imageResizeKey.getState(view.state);
|
|
115
|
+
event.preventDefault();
|
|
116
|
+
const transaction = view.state.tr;
|
|
117
|
+
transaction.setMeta(imageResizeKey, {
|
|
118
|
+
setDragging: { startX: event.clientX, startY: event.clientY },
|
|
119
|
+
activeHandle,
|
|
120
|
+
rect: resizeState.rect,
|
|
121
|
+
nodePosition: resizeState.nodePosition
|
|
122
|
+
});
|
|
123
|
+
transaction.setMeta('addToHistory', false);
|
|
124
|
+
view.dispatch(transaction);
|
|
125
|
+
function move(e) {
|
|
126
|
+
handleMouseMove(view, e, options);
|
|
127
|
+
}
|
|
128
|
+
function finish(e) {
|
|
129
|
+
e.view.removeEventListener('mouseup', finish);
|
|
130
|
+
e.view.removeEventListener('mousemove', move);
|
|
131
|
+
handleMouseUp(view);
|
|
132
|
+
}
|
|
133
|
+
event.view.addEventListener('mouseup', finish);
|
|
134
|
+
event.view.addEventListener('mousemove', move);
|
|
135
|
+
return true;
|
|
136
|
+
};
|
|
137
|
+
export const imageResizing = (options = { node: 'image', lockRatio: true }) => {
|
|
138
|
+
return new Plugin({
|
|
139
|
+
key: imageResizeKey,
|
|
140
|
+
view: (viewObj) => ({
|
|
141
|
+
resize() {
|
|
142
|
+
if (imageResizeKey.getState(viewObj.state).rect) {
|
|
143
|
+
viewObj.dispatch(viewObj.state.tr.setMeta('resize', true));
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
get window() {
|
|
147
|
+
return viewObj.dom.ownerDocument && viewObj.dom.ownerDocument.defaultView;
|
|
148
|
+
},
|
|
149
|
+
attachResize() {
|
|
150
|
+
const win = this.window;
|
|
151
|
+
if (win) {
|
|
152
|
+
win.removeEventListener('resize', this.resize);
|
|
153
|
+
win.addEventListener('resize', this.resize);
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
removeResize() {
|
|
157
|
+
const win = this.window;
|
|
158
|
+
if (win) {
|
|
159
|
+
win.removeEventListener('resize', this.resize);
|
|
160
|
+
}
|
|
161
|
+
},
|
|
162
|
+
update(view, prevState) {
|
|
163
|
+
const state = view.state;
|
|
164
|
+
const selection = state.selection;
|
|
165
|
+
const nodeType = state.schema.nodes[options.node];
|
|
166
|
+
const pluginState = imageResizeKey.getState(state);
|
|
167
|
+
const prevRect = pluginState.rect;
|
|
168
|
+
if (selection instanceof NodeSelection && nodeType === selection.node.type) {
|
|
169
|
+
const img = view.nodeDOM(selection.from);
|
|
170
|
+
const rect = {
|
|
171
|
+
top: img.offsetTop,
|
|
172
|
+
left: img.offsetLeft,
|
|
173
|
+
width: img.offsetWidth,
|
|
174
|
+
height: img.offsetHeight
|
|
175
|
+
};
|
|
176
|
+
if (!prevState.selection.eq(selection) ||
|
|
177
|
+
(prevRect && (prevRect.width !== rect.width || prevRect.height !== rect.height ||
|
|
178
|
+
prevRect.top !== rect.top || prevRect.left !== rect.left))) {
|
|
179
|
+
const tr = state.tr;
|
|
180
|
+
tr.setMeta(imageResizeKey, { rect, nodePosition: selection.from });
|
|
181
|
+
view.dispatch(tr);
|
|
182
|
+
this.attachResize();
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
else if (prevRect) {
|
|
186
|
+
pluginState.rect = null;
|
|
187
|
+
pluginState.nodePosition = -1;
|
|
188
|
+
}
|
|
189
|
+
},
|
|
190
|
+
destroy() {
|
|
191
|
+
this.removeResize();
|
|
192
|
+
}
|
|
193
|
+
}),
|
|
194
|
+
state: {
|
|
195
|
+
init() {
|
|
196
|
+
return new ResizeState('', null, null, -1);
|
|
197
|
+
},
|
|
198
|
+
apply(tr, prev) {
|
|
199
|
+
return prev.apply(tr);
|
|
200
|
+
}
|
|
201
|
+
},
|
|
202
|
+
props: {
|
|
203
|
+
handleDOMEvents: {
|
|
204
|
+
mousedown(view, event) {
|
|
205
|
+
return handleMouseDown(view, event, options);
|
|
206
|
+
}
|
|
207
|
+
},
|
|
208
|
+
decorations(state) {
|
|
209
|
+
const selection = state.selection;
|
|
210
|
+
const nodeType = state.schema.nodes[options.node];
|
|
211
|
+
const rect = imageResizeKey.getState(state).rect;
|
|
212
|
+
if (rect && selection instanceof NodeSelection && nodeType === selection.node.type) {
|
|
213
|
+
const wrapper = document.createElement('div');
|
|
214
|
+
wrapper.className = 'k-editor-resize-handles-wrapper';
|
|
215
|
+
wrapper.style.width = rect.width + 'px';
|
|
216
|
+
wrapper.style.height = rect.height + 'px';
|
|
217
|
+
wrapper.style.top = rect.top + 'px';
|
|
218
|
+
wrapper.style.left = rect.left + 'px';
|
|
219
|
+
for (let i = 0; i < handles.length; i++) {
|
|
220
|
+
let dom = document.createElement('div');
|
|
221
|
+
dom.className = 'k-editor-resize-handle ' + handles[i];
|
|
222
|
+
dom.setAttribute('data-direction', handles[i]);
|
|
223
|
+
wrapper.appendChild(dom);
|
|
224
|
+
}
|
|
225
|
+
return DecorationSet.create(state.doc, [Decoration.widget(state.selection.from + 1, wrapper)]);
|
|
226
|
+
}
|
|
227
|
+
return DecorationSet.empty;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { EditorState, Transaction } from 'prosemirror-state';
|
|
2
|
+
export declare const blockquote: (state: EditorState<any>, dispatch?: (tr: Transaction<any>) => void) => boolean;
|
|
3
|
+
export declare const liftBlockquote: (state: EditorState<any>, dispatch?: (tr: Transaction<any>) => void) => boolean;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
var prosemirror_commands_1 = require("prosemirror-commands");
|
|
4
|
+
exports.blockquote = function (state, dispatch) {
|
|
5
|
+
return prosemirror_commands_1.wrapIn(state.schema.nodes.blockquote)(state, dispatch);
|
|
6
|
+
};
|
|
7
|
+
exports.liftBlockquote = function (state, dispatch) {
|
|
8
|
+
var _a = state.selection, $from = _a.$from, $to = _a.$to;
|
|
9
|
+
var nodeType = state.schema.nodes.blockquote;
|
|
10
|
+
var doc = state.doc;
|
|
11
|
+
var target = -1;
|
|
12
|
+
var range = $from.blockRange($to);
|
|
13
|
+
if (range) {
|
|
14
|
+
doc.nodesBetween(range.start, range.end, function (node, pos, _parent, _index) {
|
|
15
|
+
if (node.type === nodeType) {
|
|
16
|
+
target = pos;
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
var result = target !== -1;
|
|
21
|
+
if (dispatch && result) {
|
|
22
|
+
dispatch(state.tr.lift(range, doc.resolve(target).depth));
|
|
23
|
+
}
|
|
24
|
+
return result;
|
|
25
|
+
};
|
package/dist/npm/indent.js
CHANGED
|
@@ -4,6 +4,7 @@ var prosemirror_schema_list_1 = require("prosemirror-schema-list");
|
|
|
4
4
|
var indent_rules_1 = require("./config/indent-rules");
|
|
5
5
|
var blockNode_1 = require("./blockNode");
|
|
6
6
|
var utils_1 = require("./utils");
|
|
7
|
+
var blockquote_1 = require("./blockquote");
|
|
7
8
|
/**
|
|
8
9
|
* Indenting block elements in the selection.
|
|
9
10
|
*
|
|
@@ -88,9 +89,13 @@ exports.indent = function (state, dispatch) {
|
|
|
88
89
|
}
|
|
89
90
|
};
|
|
90
91
|
exports.outdent = function (state, dispatch) {
|
|
91
|
-
var
|
|
92
|
+
var nodes = state.schema.nodes;
|
|
93
|
+
var listItem = nodes[indent_rules_1.outdentRules.listsTypes.listItem];
|
|
92
94
|
var isIndentableBlock = exports.canBeIndented(state, indent_rules_1.outdentRules);
|
|
93
|
-
if (
|
|
95
|
+
if (blockNode_1.hasNode(state, nodes.blockquote)) {
|
|
96
|
+
blockquote_1.liftBlockquote(state, dispatch);
|
|
97
|
+
}
|
|
98
|
+
else if (exports.canOutdentAsListItem(state, indent_rules_1.outdentRules)) {
|
|
94
99
|
prosemirror_schema_list_1.liftListItem(listItem)(state, dispatch);
|
|
95
100
|
}
|
|
96
101
|
else if (isIndentableBlock) {
|
package/dist/npm/main.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ export { hasNode, activeNode, formatBlockElements, getBlockFormats, parentBlockF
|
|
|
9
9
|
export { hasMark, getMark, getActiveMarks, removeAllMarks, cleanMarks, selectionMarks } from './mark';
|
|
10
10
|
export { indent, canIndentAsListItem, outdent, canOutdentAsListItem, isIndented, canBeIndented, indentBlocks } from './indent';
|
|
11
11
|
export { toggleOrderedList, toggleUnorderedList, toggleList } from './lists';
|
|
12
|
+
export { blockquote, liftBlockquote } from './blockquote';
|
|
12
13
|
export { hasSameMarkup, getSelectionText, getNodeFromSelection, selectedLineTextOnly, expandSelection, expandToWordWrap, canInsert, insertNode, indentHtml } from './utils';
|
|
13
14
|
export { Command } from './types/command';
|
|
14
15
|
export { alignLeftRules, alignCenterRules, alignRightRules, alignJustifyRules, alignRemoveRules } from './config/align-rules';
|
|
@@ -24,6 +25,7 @@ export { find, findAt, findAll, replace, replaceAll, SearchOptions } from './fin
|
|
|
24
25
|
export { placeholder } from './plugins/placeholder';
|
|
25
26
|
export { spacesFix } from './plugins/spaces-fix';
|
|
26
27
|
export { textHighlight, textHighlightKey, InlineDecoration } from './plugins/highlight';
|
|
28
|
+
export { imageResizing, imageResizeKey, ImageResizeOptions } from './plugins/image-resize';
|
|
27
29
|
export * from 'prosemirror-commands';
|
|
28
30
|
export * from 'prosemirror-dropcursor';
|
|
29
31
|
export * from 'prosemirror-gapcursor';
|