1 | import Parchment from 'parchment';
|
2 | import TextBlot from './text';
|
3 |
|
4 | const GUARD_TEXT = "\uFEFF";
|
5 |
|
6 |
|
7 | class Embed extends Parchment.Embed {
|
8 | constructor(node) {
|
9 | super(node);
|
10 | const wrapper = document.createElement('span');
|
11 | wrapper.setAttribute('contenteditable', false);
|
12 | [].slice.call(this.domNode.childNodes).forEach(function(childNode) {
|
13 | wrapper.appendChild(childNode);
|
14 | });
|
15 | this.leftGuard = document.createTextNode(GUARD_TEXT);
|
16 | this.rightGuard = document.createTextNode(GUARD_TEXT);
|
17 | this.domNode.appendChild(this.leftGuard);
|
18 | this.domNode.appendChild(wrapper);
|
19 | this.domNode.appendChild(this.rightGuard);
|
20 | }
|
21 |
|
22 | index(node, offset) {
|
23 | if (node === this.leftGuard) return 0;
|
24 | if (node === this.rightGuard) return 1;
|
25 | return super.index(node, offset);
|
26 | }
|
27 |
|
28 | restore(node) {
|
29 | let range, textNode;
|
30 | let text = node.data.split(GUARD_TEXT).join('');
|
31 | if (node === this.leftGuard) {
|
32 | if (this.prev instanceof TextBlot) {
|
33 | let prevLength = this.prev.length();
|
34 | this.prev.insertAt(prevLength, text);
|
35 | range = {
|
36 | startNode: this.prev.domNode,
|
37 | startOffset: prevLength + text.length
|
38 | };
|
39 | } else {
|
40 | textNode = document.createTextNode(text);
|
41 | this.parent.insertBefore(Parchment.create(textNode), this);
|
42 | range = {
|
43 | startNode: textNode,
|
44 | startOffset: text.length
|
45 | };
|
46 | }
|
47 | } else if (node === this.rightGuard) {
|
48 | if (this.next instanceof TextBlot) {
|
49 | this.next.insertAt(0, text);
|
50 | range = {
|
51 | startNode: this.next.domNode,
|
52 | startOffset: text.length
|
53 | }
|
54 | } else {
|
55 | textNode = document.createTextNode(text);
|
56 | this.parent.insertBefore(Parchment.create(textNode), this.next);
|
57 | range = {
|
58 | startNode: textNode,
|
59 | startOffset: text.length
|
60 | };
|
61 | }
|
62 | }
|
63 | node.data = GUARD_TEXT;
|
64 | return range;
|
65 | }
|
66 |
|
67 | update(mutations, context) {
|
68 | mutations.forEach((mutation) => {
|
69 | if (mutation.type === 'characterData' &&
|
70 | (mutation.target === this.leftGuard || mutation.target === this.rightGuard)) {
|
71 | let range = this.restore(mutation.target);
|
72 | if (range) context.range = range;
|
73 | }
|
74 | });
|
75 | }
|
76 | }
|
77 |
|
78 |
|
79 | export default Embed;
|