1 | import Parchment from 'parchment';
|
2 | import Block from '../blots/block';
|
3 | import Container from '../blots/container';
|
4 |
|
5 |
|
6 | class ListItem extends Block {
|
7 | static formats(domNode) {
|
8 | return domNode.tagName === this.tagName ? undefined : super.formats(domNode);
|
9 | }
|
10 |
|
11 | format(name, value) {
|
12 | if (name === List.blotName && !value) {
|
13 | this.replaceWith(Parchment.create(this.statics.scope));
|
14 | } else {
|
15 | super.format(name, value);
|
16 | }
|
17 | }
|
18 |
|
19 | remove() {
|
20 | if (this.prev == null && this.next == null) {
|
21 | this.parent.remove();
|
22 | } else {
|
23 | super.remove();
|
24 | }
|
25 | }
|
26 |
|
27 | replaceWith(name, value) {
|
28 | this.parent.isolate(this.offset(this.parent), this.length());
|
29 | if (name === this.parent.statics.blotName) {
|
30 | this.parent.replaceWith(name, value);
|
31 | return this;
|
32 | } else {
|
33 | this.parent.unwrap();
|
34 | return super.replaceWith(name, value);
|
35 | }
|
36 | }
|
37 | }
|
38 | ListItem.blotName = 'list-item';
|
39 | ListItem.tagName = 'LI';
|
40 |
|
41 |
|
42 | class List extends Container {
|
43 | static create(value) {
|
44 | let tagName = value === 'ordered' ? 'OL' : 'UL';
|
45 | let node = super.create(tagName);
|
46 | if (value === 'checked' || value === 'unchecked') {
|
47 | node.setAttribute('data-checked', value === 'checked');
|
48 | }
|
49 | return node;
|
50 | }
|
51 |
|
52 | static formats(domNode) {
|
53 | if (domNode.tagName === 'OL') return 'ordered';
|
54 | if (domNode.tagName === 'UL') {
|
55 | if (domNode.hasAttribute('data-checked')) {
|
56 | return domNode.getAttribute('data-checked') === 'true' ? 'checked' : 'unchecked';
|
57 | } else {
|
58 | return 'bullet';
|
59 | }
|
60 | }
|
61 | return undefined;
|
62 | }
|
63 |
|
64 | constructor(domNode) {
|
65 | super(domNode);
|
66 | domNode.addEventListener('click', (e) => {
|
67 | if (e.target.parentNode !== domNode) return;
|
68 | let format = this.statics.formats(domNode);
|
69 | let blot = Parchment.find(e.target);
|
70 | if (format === 'checked') {
|
71 | blot.format('list', 'unchecked');
|
72 | } else if(format === 'unchecked') {
|
73 | blot.format('list', 'checked');
|
74 | }
|
75 | });
|
76 | }
|
77 |
|
78 | format(name, value) {
|
79 | if (this.children.length > 0) {
|
80 | this.children.tail.format(name, value);
|
81 | }
|
82 | }
|
83 |
|
84 | formats() {
|
85 |
|
86 | return { [this.statics.blotName]: this.statics.formats(this.domNode) };
|
87 | }
|
88 |
|
89 | insertBefore(blot, ref) {
|
90 | if (blot instanceof ListItem) {
|
91 | super.insertBefore(blot, ref);
|
92 | } else {
|
93 | let index = ref == null ? this.length() : ref.offset(this);
|
94 | let after = this.split(index);
|
95 | after.parent.insertBefore(blot, after);
|
96 | }
|
97 | }
|
98 |
|
99 | optimize(context) {
|
100 | super.optimize(context);
|
101 | let next = this.next;
|
102 | if (next != null && next.prev === this &&
|
103 | next.statics.blotName === this.statics.blotName &&
|
104 | next.domNode.tagName === this.domNode.tagName &&
|
105 | next.domNode.getAttribute('data-checked') === this.domNode.getAttribute('data-checked')) {
|
106 | next.moveChildren(this);
|
107 | next.remove();
|
108 | }
|
109 | }
|
110 |
|
111 | replace(target) {
|
112 | if (target.statics.blotName !== this.statics.blotName) {
|
113 | let item = Parchment.create(this.statics.defaultChild);
|
114 | target.moveChildren(item);
|
115 | this.appendChild(item);
|
116 | }
|
117 | super.replace(target);
|
118 | }
|
119 | }
|
120 | List.blotName = 'list';
|
121 | List.scope = Parchment.Scope.BLOCK_BLOT;
|
122 | List.tagName = ['OL', 'UL'];
|
123 | List.defaultChild = 'list-item';
|
124 | List.allowedChildren = [ListItem];
|
125 |
|
126 |
|
127 | export { ListItem, List as default };
|