1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 | 'use strict';
|
12 |
|
13 | function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }
|
14 |
|
15 | function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
16 |
|
17 | var BlockTree = require("./BlockTree");
|
18 |
|
19 | var ContentState = require("./ContentState");
|
20 |
|
21 | var EditorBidiService = require("./EditorBidiService");
|
22 |
|
23 | var SelectionState = require("./SelectionState");
|
24 |
|
25 | var Immutable = require("immutable");
|
26 |
|
27 | var OrderedSet = Immutable.OrderedSet,
|
28 | Record = Immutable.Record,
|
29 | Stack = Immutable.Stack,
|
30 | OrderedMap = Immutable.OrderedMap,
|
31 | List = Immutable.List;
|
32 |
|
33 |
|
34 |
|
35 | var defaultRecord = {
|
36 | allowUndo: true,
|
37 | currentContent: null,
|
38 | decorator: null,
|
39 | directionMap: null,
|
40 | forceSelection: false,
|
41 | inCompositionMode: false,
|
42 | inlineStyleOverride: null,
|
43 | lastChangeType: null,
|
44 | nativelyRenderedContent: null,
|
45 | redoStack: Stack(),
|
46 | selection: null,
|
47 | treeMap: null,
|
48 | undoStack: Stack()
|
49 | };
|
50 | var EditorStateRecord = Record(defaultRecord);
|
51 |
|
52 | var EditorState = function () {
|
53 | EditorState.createEmpty = function createEmpty(decorator) {
|
54 | return this.createWithText('', decorator);
|
55 | };
|
56 |
|
57 | EditorState.createWithText = function createWithText(text, decorator) {
|
58 | return EditorState.createWithContent(ContentState.createFromText(text), decorator);
|
59 | };
|
60 |
|
61 | EditorState.createWithContent = function createWithContent(contentState, decorator) {
|
62 | if (contentState.getBlockMap().count() === 0) {
|
63 | return EditorState.createEmpty(decorator);
|
64 | }
|
65 |
|
66 | var firstKey = contentState.getBlockMap().first().getKey();
|
67 | return EditorState.create({
|
68 | currentContent: contentState,
|
69 | undoStack: Stack(),
|
70 | redoStack: Stack(),
|
71 | decorator: decorator || null,
|
72 | selection: SelectionState.createEmpty(firstKey)
|
73 | });
|
74 | };
|
75 |
|
76 | EditorState.create = function create(config) {
|
77 | var currentContent = config.currentContent,
|
78 | decorator = config.decorator;
|
79 |
|
80 | var recordConfig = _objectSpread({}, config, {
|
81 | treeMap: generateNewTreeMap(currentContent, decorator),
|
82 | directionMap: EditorBidiService.getDirectionMap(currentContent)
|
83 | });
|
84 |
|
85 | return new EditorState(new EditorStateRecord(recordConfig));
|
86 | };
|
87 |
|
88 | EditorState.fromJS = function fromJS(config) {
|
89 | return new EditorState(new EditorStateRecord(_objectSpread({}, config, {
|
90 | directionMap: config.directionMap != null ? OrderedMap(config.directionMap) : config.directionMap,
|
91 | inlineStyleOverride: config.inlineStyleOverride != null ? OrderedSet(config.inlineStyleOverride) : config.inlineStyleOverride,
|
92 | nativelyRenderedContent: config.nativelyRenderedContent != null ? ContentState.fromJS(config.nativelyRenderedContent) : config.nativelyRenderedContent,
|
93 | redoStack: config.redoStack != null ? Stack(config.redoStack.map(function (v) {
|
94 | return ContentState.fromJS(v);
|
95 | })) : config.redoStack,
|
96 | selection: config.selection != null ? new SelectionState(config.selection) : config.selection,
|
97 | treeMap: config.treeMap != null ? OrderedMap(config.treeMap).map(function (v) {
|
98 | return List(v).map(function (v) {
|
99 | return BlockTree.fromJS(v);
|
100 | });
|
101 | }) : config.treeMap,
|
102 | undoStack: config.undoStack != null ? Stack(config.undoStack.map(function (v) {
|
103 | return ContentState.fromJS(v);
|
104 | })) : config.undoStack,
|
105 | currentContent: ContentState.fromJS(config.currentContent)
|
106 | })));
|
107 | };
|
108 |
|
109 | EditorState.set = function set(editorState, put) {
|
110 | var map = editorState.getImmutable().withMutations(function (state) {
|
111 | var existingDecorator = state.get('decorator');
|
112 | var decorator = existingDecorator;
|
113 |
|
114 | if (put.decorator === null) {
|
115 | decorator = null;
|
116 | } else if (put.decorator) {
|
117 | decorator = put.decorator;
|
118 | }
|
119 |
|
120 | var newContent = put.currentContent || editorState.getCurrentContent();
|
121 |
|
122 | if (decorator !== existingDecorator) {
|
123 | var treeMap = state.get('treeMap');
|
124 | var newTreeMap;
|
125 |
|
126 | if (decorator && existingDecorator) {
|
127 | newTreeMap = regenerateTreeForNewDecorator(newContent, newContent.getBlockMap(), treeMap, decorator, existingDecorator);
|
128 | } else {
|
129 | newTreeMap = generateNewTreeMap(newContent, decorator);
|
130 | }
|
131 |
|
132 | state.merge({
|
133 | decorator: decorator,
|
134 | treeMap: newTreeMap,
|
135 | nativelyRenderedContent: null
|
136 | });
|
137 | return;
|
138 | }
|
139 |
|
140 | var existingContent = editorState.getCurrentContent();
|
141 |
|
142 | if (newContent !== existingContent) {
|
143 | state.set('treeMap', regenerateTreeForNewBlocks(editorState, newContent.getBlockMap(), newContent.getEntityMap(), decorator));
|
144 | }
|
145 |
|
146 | state.merge(put);
|
147 | });
|
148 | return new EditorState(map);
|
149 | };
|
150 |
|
151 | var _proto = EditorState.prototype;
|
152 |
|
153 | _proto.toJS = function toJS() {
|
154 | return this.getImmutable().toJS();
|
155 | };
|
156 |
|
157 | _proto.getAllowUndo = function getAllowUndo() {
|
158 | return this.getImmutable().get('allowUndo');
|
159 | };
|
160 |
|
161 | _proto.getCurrentContent = function getCurrentContent() {
|
162 | return this.getImmutable().get('currentContent');
|
163 | };
|
164 |
|
165 | _proto.getUndoStack = function getUndoStack() {
|
166 | return this.getImmutable().get('undoStack');
|
167 | };
|
168 |
|
169 | _proto.getRedoStack = function getRedoStack() {
|
170 | return this.getImmutable().get('redoStack');
|
171 | };
|
172 |
|
173 | _proto.getSelection = function getSelection() {
|
174 | return this.getImmutable().get('selection');
|
175 | };
|
176 |
|
177 | _proto.getDecorator = function getDecorator() {
|
178 | return this.getImmutable().get('decorator');
|
179 | };
|
180 |
|
181 | _proto.isInCompositionMode = function isInCompositionMode() {
|
182 | return this.getImmutable().get('inCompositionMode');
|
183 | };
|
184 |
|
185 | _proto.mustForceSelection = function mustForceSelection() {
|
186 | return this.getImmutable().get('forceSelection');
|
187 | };
|
188 |
|
189 | _proto.getNativelyRenderedContent = function getNativelyRenderedContent() {
|
190 | return this.getImmutable().get('nativelyRenderedContent');
|
191 | };
|
192 |
|
193 | _proto.getLastChangeType = function getLastChangeType() {
|
194 | return this.getImmutable().get('lastChangeType');
|
195 | }
|
196 | |
197 |
|
198 |
|
199 |
|
200 |
|
201 |
|
202 |
|
203 |
|
204 | ;
|
205 |
|
206 | _proto.getInlineStyleOverride = function getInlineStyleOverride() {
|
207 | return this.getImmutable().get('inlineStyleOverride');
|
208 | };
|
209 |
|
210 | EditorState.setInlineStyleOverride = function setInlineStyleOverride(editorState, inlineStyleOverride) {
|
211 | return EditorState.set(editorState, {
|
212 | inlineStyleOverride: inlineStyleOverride
|
213 | });
|
214 | }
|
215 | |
216 |
|
217 |
|
218 |
|
219 |
|
220 | ;
|
221 |
|
222 | _proto.getCurrentInlineStyle = function getCurrentInlineStyle() {
|
223 | var override = this.getInlineStyleOverride();
|
224 |
|
225 | if (override != null) {
|
226 | return override;
|
227 | }
|
228 |
|
229 | var content = this.getCurrentContent();
|
230 | var selection = this.getSelection();
|
231 |
|
232 | if (selection.isCollapsed()) {
|
233 | return getInlineStyleForCollapsedSelection(content, selection);
|
234 | }
|
235 |
|
236 | return getInlineStyleForNonCollapsedSelection(content, selection);
|
237 | };
|
238 |
|
239 | _proto.getBlockTree = function getBlockTree(blockKey) {
|
240 | return this.getImmutable().getIn(['treeMap', blockKey]);
|
241 | };
|
242 |
|
243 | _proto.isSelectionAtStartOfContent = function isSelectionAtStartOfContent() {
|
244 | var firstKey = this.getCurrentContent().getBlockMap().first().getKey();
|
245 | return this.getSelection().hasEdgeWithin(firstKey, 0, 0);
|
246 | };
|
247 |
|
248 | _proto.isSelectionAtEndOfContent = function isSelectionAtEndOfContent() {
|
249 | var content = this.getCurrentContent();
|
250 | var blockMap = content.getBlockMap();
|
251 | var last = blockMap.last();
|
252 | var end = last.getLength();
|
253 | return this.getSelection().hasEdgeWithin(last.getKey(), end, end);
|
254 | };
|
255 |
|
256 | _proto.getDirectionMap = function getDirectionMap() {
|
257 | return this.getImmutable().get('directionMap');
|
258 | }
|
259 | |
260 |
|
261 |
|
262 |
|
263 |
|
264 |
|
265 |
|
266 |
|
267 | ;
|
268 |
|
269 | EditorState.acceptSelection = function acceptSelection(editorState, selection) {
|
270 | return updateSelection(editorState, selection, false);
|
271 | }
|
272 | |
273 |
|
274 |
|
275 |
|
276 |
|
277 |
|
278 |
|
279 |
|
280 |
|
281 |
|
282 |
|
283 |
|
284 | ;
|
285 |
|
286 | EditorState.forceSelection = function forceSelection(editorState, selection) {
|
287 | if (!selection.getHasFocus()) {
|
288 | selection = selection.set('hasFocus', true);
|
289 | }
|
290 |
|
291 | return updateSelection(editorState, selection, true);
|
292 | }
|
293 | |
294 |
|
295 |
|
296 | ;
|
297 |
|
298 | EditorState.moveSelectionToEnd = function moveSelectionToEnd(editorState) {
|
299 | var content = editorState.getCurrentContent();
|
300 | var lastBlock = content.getLastBlock();
|
301 | var lastKey = lastBlock.getKey();
|
302 | var length = lastBlock.getLength();
|
303 | return EditorState.acceptSelection(editorState, new SelectionState({
|
304 | anchorKey: lastKey,
|
305 | anchorOffset: length,
|
306 | focusKey: lastKey,
|
307 | focusOffset: length,
|
308 | isBackward: false
|
309 | }));
|
310 | }
|
311 | |
312 |
|
313 |
|
314 |
|
315 |
|
316 | ;
|
317 |
|
318 | EditorState.moveFocusToEnd = function moveFocusToEnd(editorState) {
|
319 | var afterSelectionMove = EditorState.moveSelectionToEnd(editorState);
|
320 | return EditorState.forceSelection(afterSelectionMove, afterSelectionMove.getSelection());
|
321 | }
|
322 | |
323 |
|
324 |
|
325 |
|
326 |
|
327 | ;
|
328 |
|
329 | EditorState.push = function push(editorState, contentState, changeType) {
|
330 | var forceSelection = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;
|
331 |
|
332 | if (editorState.getCurrentContent() === contentState) {
|
333 | return editorState;
|
334 | }
|
335 |
|
336 | var directionMap = EditorBidiService.getDirectionMap(contentState, editorState.getDirectionMap());
|
337 |
|
338 | if (!editorState.getAllowUndo()) {
|
339 | return EditorState.set(editorState, {
|
340 | currentContent: contentState,
|
341 | directionMap: directionMap,
|
342 | lastChangeType: changeType,
|
343 | selection: contentState.getSelectionAfter(),
|
344 | forceSelection: forceSelection,
|
345 | inlineStyleOverride: null
|
346 | });
|
347 | }
|
348 |
|
349 | var selection = editorState.getSelection();
|
350 | var currentContent = editorState.getCurrentContent();
|
351 | var undoStack = editorState.getUndoStack();
|
352 | var newContent = contentState;
|
353 |
|
354 | if (selection !== currentContent.getSelectionAfter() || mustBecomeBoundary(editorState, changeType)) {
|
355 | undoStack = undoStack.push(currentContent);
|
356 | newContent = newContent.set('selectionBefore', selection);
|
357 | } else if (changeType === 'insert-characters' || changeType === 'backspace-character' || changeType === 'delete-character') {
|
358 |
|
359 | newContent = newContent.set('selectionBefore', currentContent.getSelectionBefore());
|
360 | }
|
361 |
|
362 | var inlineStyleOverride = editorState.getInlineStyleOverride();
|
363 |
|
364 | var overrideChangeTypes = ['adjust-depth', 'change-block-type', 'split-block'];
|
365 |
|
366 | if (overrideChangeTypes.indexOf(changeType) === -1) {
|
367 | inlineStyleOverride = null;
|
368 | }
|
369 |
|
370 | var editorStateChanges = {
|
371 | currentContent: newContent,
|
372 | directionMap: directionMap,
|
373 | undoStack: undoStack,
|
374 | redoStack: Stack(),
|
375 | lastChangeType: changeType,
|
376 | selection: contentState.getSelectionAfter(),
|
377 | forceSelection: forceSelection,
|
378 | inlineStyleOverride: inlineStyleOverride
|
379 | };
|
380 | return EditorState.set(editorState, editorStateChanges);
|
381 | }
|
382 | |
383 |
|
384 |
|
385 |
|
386 | ;
|
387 |
|
388 | EditorState.undo = function undo(editorState) {
|
389 | if (!editorState.getAllowUndo()) {
|
390 | return editorState;
|
391 | }
|
392 |
|
393 | var undoStack = editorState.getUndoStack();
|
394 | var newCurrentContent = undoStack.peek();
|
395 |
|
396 | if (!newCurrentContent) {
|
397 | return editorState;
|
398 | }
|
399 |
|
400 | var currentContent = editorState.getCurrentContent();
|
401 | var directionMap = EditorBidiService.getDirectionMap(newCurrentContent, editorState.getDirectionMap());
|
402 | return EditorState.set(editorState, {
|
403 | currentContent: newCurrentContent,
|
404 | directionMap: directionMap,
|
405 | undoStack: undoStack.shift(),
|
406 | redoStack: editorState.getRedoStack().push(currentContent),
|
407 | forceSelection: true,
|
408 | inlineStyleOverride: null,
|
409 | lastChangeType: 'undo',
|
410 | nativelyRenderedContent: null,
|
411 | selection: currentContent.getSelectionBefore()
|
412 | });
|
413 | }
|
414 | |
415 |
|
416 |
|
417 |
|
418 | ;
|
419 |
|
420 | EditorState.redo = function redo(editorState) {
|
421 | if (!editorState.getAllowUndo()) {
|
422 | return editorState;
|
423 | }
|
424 |
|
425 | var redoStack = editorState.getRedoStack();
|
426 | var newCurrentContent = redoStack.peek();
|
427 |
|
428 | if (!newCurrentContent) {
|
429 | return editorState;
|
430 | }
|
431 |
|
432 | var currentContent = editorState.getCurrentContent();
|
433 | var directionMap = EditorBidiService.getDirectionMap(newCurrentContent, editorState.getDirectionMap());
|
434 | return EditorState.set(editorState, {
|
435 | currentContent: newCurrentContent,
|
436 | directionMap: directionMap,
|
437 | undoStack: editorState.getUndoStack().push(currentContent),
|
438 | redoStack: redoStack.shift(),
|
439 | forceSelection: true,
|
440 | inlineStyleOverride: null,
|
441 | lastChangeType: 'redo',
|
442 | nativelyRenderedContent: null,
|
443 | selection: newCurrentContent.getSelectionAfter()
|
444 | });
|
445 | }
|
446 | |
447 |
|
448 |
|
449 | ;
|
450 |
|
451 | function EditorState(immutable) {
|
452 | _defineProperty(this, "_immutable", void 0);
|
453 |
|
454 | this._immutable = immutable;
|
455 | }
|
456 | |
457 |
|
458 |
|
459 |
|
460 |
|
461 | _proto.getImmutable = function getImmutable() {
|
462 | return this._immutable;
|
463 | };
|
464 |
|
465 | return EditorState;
|
466 | }();
|
467 |
|
468 |
|
469 |
|
470 |
|
471 |
|
472 |
|
473 | function updateSelection(editorState, selection, forceSelection) {
|
474 | return EditorState.set(editorState, {
|
475 | selection: selection,
|
476 | forceSelection: forceSelection,
|
477 | nativelyRenderedContent: null,
|
478 | inlineStyleOverride: null
|
479 | });
|
480 | }
|
481 |
|
482 |
|
483 |
|
484 |
|
485 |
|
486 |
|
487 | function generateNewTreeMap(contentState, decorator) {
|
488 | return contentState.getBlockMap().map(function (block) {
|
489 | return BlockTree.generate(contentState, block, decorator);
|
490 | }).toOrderedMap();
|
491 | }
|
492 |
|
493 |
|
494 |
|
495 |
|
496 |
|
497 |
|
498 |
|
499 | function regenerateTreeForNewBlocks(editorState, newBlockMap, newEntityMap, decorator) {
|
500 | var contentState = editorState.getCurrentContent().set('entityMap', newEntityMap);
|
501 | var prevBlockMap = contentState.getBlockMap();
|
502 | var prevTreeMap = editorState.getImmutable().get('treeMap');
|
503 | return prevTreeMap.merge(newBlockMap.toSeq().filter(function (block, key) {
|
504 | return block !== prevBlockMap.get(key);
|
505 | }).map(function (block) {
|
506 | return BlockTree.generate(contentState, block, decorator);
|
507 | }));
|
508 | }
|
509 |
|
510 |
|
511 |
|
512 |
|
513 |
|
514 |
|
515 |
|
516 |
|
517 |
|
518 |
|
519 | function regenerateTreeForNewDecorator(content, blockMap, previousTreeMap, decorator, existingDecorator) {
|
520 | return previousTreeMap.merge(blockMap.toSeq().filter(function (block) {
|
521 | return decorator.getDecorations(block, content) !== existingDecorator.getDecorations(block, content);
|
522 | }).map(function (block) {
|
523 | return BlockTree.generate(content, block, decorator);
|
524 | }));
|
525 | }
|
526 |
|
527 |
|
528 |
|
529 |
|
530 |
|
531 |
|
532 |
|
533 | function mustBecomeBoundary(editorState, changeType) {
|
534 | var lastChangeType = editorState.getLastChangeType();
|
535 | return changeType !== lastChangeType || changeType !== 'insert-characters' && changeType !== 'backspace-character' && changeType !== 'delete-character';
|
536 | }
|
537 |
|
538 | function getInlineStyleForCollapsedSelection(content, selection) {
|
539 | var startKey = selection.getStartKey();
|
540 | var startOffset = selection.getStartOffset();
|
541 | var startBlock = content.getBlockForKey(startKey);
|
542 |
|
543 |
|
544 | if (startOffset > 0) {
|
545 | return startBlock.getInlineStyleAt(startOffset - 1);
|
546 | }
|
547 |
|
548 |
|
549 |
|
550 | if (startBlock.getLength()) {
|
551 | return startBlock.getInlineStyleAt(0);
|
552 | }
|
553 |
|
554 |
|
555 | return lookUpwardForInlineStyle(content, startKey);
|
556 | }
|
557 |
|
558 | function getInlineStyleForNonCollapsedSelection(content, selection) {
|
559 | var startKey = selection.getStartKey();
|
560 | var startOffset = selection.getStartOffset();
|
561 | var startBlock = content.getBlockForKey(startKey);
|
562 |
|
563 | if (startOffset < startBlock.getLength()) {
|
564 | return startBlock.getInlineStyleAt(startOffset);
|
565 | }
|
566 |
|
567 |
|
568 |
|
569 | if (startOffset > 0) {
|
570 | return startBlock.getInlineStyleAt(startOffset - 1);
|
571 | }
|
572 |
|
573 |
|
574 | return lookUpwardForInlineStyle(content, startKey);
|
575 | }
|
576 |
|
577 | function lookUpwardForInlineStyle(content, fromKey) {
|
578 | var lastNonEmpty = content.getBlockMap().reverse().skipUntil(function (_, k) {
|
579 | return k === fromKey;
|
580 | }).skip(1).skipUntil(function (block, _) {
|
581 | return block.getLength();
|
582 | }).first();
|
583 |
|
584 | if (lastNonEmpty) {
|
585 | return lastNonEmpty.getInlineStyleAt(lastNonEmpty.getLength() - 1);
|
586 | }
|
587 |
|
588 | return OrderedSet();
|
589 | }
|
590 |
|
591 | module.exports = EditorState; |
\ | No newline at end of file |