@ckeditor/ckeditor5-list 35.4.0 → 36.0.0
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/LICENSE.md +1 -1
- package/build/list.js +2 -2
- package/package.json +43 -39
- package/src/documentlist/converters.js +303 -419
- package/src/documentlist/documentlistcommand.js +136 -207
- package/src/documentlist/documentlistediting.js +538 -698
- package/src/documentlist/documentlistindentcommand.js +115 -168
- package/src/documentlist/documentlistmergecommand.js +161 -222
- package/src/documentlist/documentlistsplitcommand.js +59 -103
- package/src/documentlist/documentlistutils.js +31 -45
- package/src/documentlist/utils/listwalker.js +138 -236
- package/src/documentlist/utils/model.js +322 -421
- package/src/documentlist/utils/postfixers.js +98 -126
- package/src/documentlist/utils/view.js +74 -105
- package/src/documentlist.js +13 -19
- package/src/documentlistproperties/converters.js +33 -47
- package/src/documentlistproperties/documentlistpropertiesediting.js +265 -356
- package/src/documentlistproperties/documentlistpropertiesutils.js +32 -57
- package/src/documentlistproperties/documentlistreversedcommand.js +40 -61
- package/src/documentlistproperties/documentliststartcommand.js +42 -61
- package/src/documentlistproperties/documentliststylecommand.js +97 -147
- package/src/documentlistproperties/utils/style.js +27 -47
- package/src/documentlistproperties.js +13 -19
- package/src/index.js +1 -3
- package/src/list/converters.js +772 -929
- package/src/list/indentcommand.js +105 -140
- package/src/list/listcommand.js +262 -315
- package/src/list/listediting.js +141 -200
- package/src/list/listui.js +16 -25
- package/src/list/listutils.js +37 -59
- package/src/list/utils.js +295 -378
- package/src/list.js +13 -44
- package/src/listcommands.js +5 -0
- package/src/listconfig.js +5 -0
- package/src/listproperties/listpropertiesediting.js +656 -803
- package/src/listproperties/listpropertiesui.js +244 -296
- package/src/listproperties/listreversedcommand.js +37 -49
- package/src/listproperties/liststartcommand.js +37 -49
- package/src/listproperties/liststylecommand.js +82 -115
- package/src/listproperties/ui/collapsibleview.js +75 -138
- package/src/listproperties/ui/listpropertiesview.js +289 -415
- package/src/listproperties.js +13 -118
- package/src/liststyle.js +18 -24
- package/src/todolist/checktodolistcommand.js +60 -102
- package/src/todolist/todolistconverters.js +189 -271
- package/src/todolist/todolistediting.js +141 -206
- package/src/todolist/todolistui.js +14 -21
- package/src/todolist.js +13 -19
- package/theme/collapsible.css +1 -1
- package/theme/documentlist.css +1 -1
- package/theme/list.css +40 -0
- package/theme/listproperties.css +1 -1
- package/theme/liststyles.css +1 -37
- package/theme/todolist.css +1 -1
|
@@ -1,18 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @license Copyright (c) 2003-
|
|
2
|
+
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
3
|
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
4
|
*/
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* @module list/todolist/todolistconverters
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
/* global document */
|
|
11
|
-
|
|
12
5
|
import { createElement } from 'ckeditor5/src/utils';
|
|
13
|
-
|
|
14
6
|
import { generateLiInUl, injectViewList, positionAfterUiElements, findNestedList } from '../list/utils';
|
|
15
|
-
|
|
16
7
|
/**
|
|
17
8
|
* A model-to-view converter for the `listItem` model element insertion.
|
|
18
9
|
*
|
|
@@ -22,111 +13,86 @@ import { generateLiInUl, injectViewList, positionAfterUiElements, findNestedList
|
|
|
22
13
|
* It is used by {@link module:engine/controller/editingcontroller~EditingController}.
|
|
23
14
|
*
|
|
24
15
|
* @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:insert
|
|
25
|
-
* @param
|
|
26
|
-
* @param
|
|
27
|
-
* @returns
|
|
16
|
+
* @param model Model instance.
|
|
17
|
+
* @param onCheckboxChecked Callback function.
|
|
18
|
+
* @returns Returns a conversion callback.
|
|
28
19
|
*/
|
|
29
|
-
export function modelViewInsertion(
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
const span = viewWriter.createContainerElement( 'span', {
|
|
58
|
-
class: 'todo-list__label__description'
|
|
59
|
-
} );
|
|
60
|
-
|
|
61
|
-
viewWriter.addClass( 'todo-list', viewItem.parent );
|
|
62
|
-
viewWriter.insert( viewWriter.createPositionAt( viewItem, 0 ), checkmarkElement );
|
|
63
|
-
viewWriter.insert( viewWriter.createPositionAfter( checkmarkElement ), span );
|
|
64
|
-
|
|
65
|
-
injectViewList( modelItem, viewItem, conversionApi, model );
|
|
66
|
-
};
|
|
20
|
+
export function modelViewInsertion(model, onCheckboxChecked) {
|
|
21
|
+
return (evt, data, conversionApi) => {
|
|
22
|
+
const consumable = conversionApi.consumable;
|
|
23
|
+
if (!consumable.test(data.item, 'insert') ||
|
|
24
|
+
!consumable.test(data.item, 'attribute:listType') ||
|
|
25
|
+
!consumable.test(data.item, 'attribute:listIndent')) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
if (data.item.getAttribute('listType') != 'todo') {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const modelItem = data.item;
|
|
32
|
+
consumable.consume(modelItem, 'insert');
|
|
33
|
+
consumable.consume(modelItem, 'attribute:listType');
|
|
34
|
+
consumable.consume(modelItem, 'attribute:listIndent');
|
|
35
|
+
consumable.consume(modelItem, 'attribute:todoListChecked');
|
|
36
|
+
const viewWriter = conversionApi.writer;
|
|
37
|
+
const viewItem = generateLiInUl(modelItem, conversionApi);
|
|
38
|
+
const isChecked = !!modelItem.getAttribute('todoListChecked');
|
|
39
|
+
const checkmarkElement = createCheckmarkElement(modelItem, viewWriter, isChecked, onCheckboxChecked);
|
|
40
|
+
const span = viewWriter.createContainerElement('span', {
|
|
41
|
+
class: 'todo-list__label__description'
|
|
42
|
+
});
|
|
43
|
+
viewWriter.addClass('todo-list', viewItem.parent);
|
|
44
|
+
viewWriter.insert(viewWriter.createPositionAt(viewItem, 0), checkmarkElement);
|
|
45
|
+
viewWriter.insert(viewWriter.createPositionAfter(checkmarkElement), span);
|
|
46
|
+
injectViewList(modelItem, viewItem, conversionApi, model);
|
|
47
|
+
};
|
|
67
48
|
}
|
|
68
|
-
|
|
69
49
|
/**
|
|
70
50
|
* A model-to-view converter for the `listItem` model element insertion.
|
|
71
51
|
*
|
|
72
52
|
* It is used by {@link module:engine/controller/datacontroller~DataController}.
|
|
73
53
|
*
|
|
74
54
|
* @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:insert
|
|
75
|
-
* @param
|
|
76
|
-
* @returns
|
|
55
|
+
* @param model Model instance.
|
|
56
|
+
* @returns Returns a conversion callback.
|
|
77
57
|
*/
|
|
78
|
-
export function dataModelViewInsertion(
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
class: 'todo-list__label__description'
|
|
116
|
-
} );
|
|
117
|
-
|
|
118
|
-
if ( modelItem.getAttribute( 'todoListChecked' ) ) {
|
|
119
|
-
viewWriter.setAttribute( 'checked', 'checked', checkbox );
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
viewWriter.insert( viewWriter.createPositionAt( viewItem, 0 ), label );
|
|
123
|
-
viewWriter.insert( viewWriter.createPositionAt( label, 0 ), checkbox );
|
|
124
|
-
viewWriter.insert( viewWriter.createPositionAfter( checkbox ), span );
|
|
125
|
-
|
|
126
|
-
injectViewList( modelItem, viewItem, conversionApi, model );
|
|
127
|
-
};
|
|
58
|
+
export function dataModelViewInsertion(model) {
|
|
59
|
+
return (evt, data, conversionApi) => {
|
|
60
|
+
const consumable = conversionApi.consumable;
|
|
61
|
+
if (!consumable.test(data.item, 'insert') ||
|
|
62
|
+
!consumable.test(data.item, 'attribute:listType') ||
|
|
63
|
+
!consumable.test(data.item, 'attribute:listIndent')) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
if (data.item.getAttribute('listType') != 'todo') {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
const modelItem = data.item;
|
|
70
|
+
consumable.consume(modelItem, 'insert');
|
|
71
|
+
consumable.consume(modelItem, 'attribute:listType');
|
|
72
|
+
consumable.consume(modelItem, 'attribute:listIndent');
|
|
73
|
+
consumable.consume(modelItem, 'attribute:todoListChecked');
|
|
74
|
+
const viewWriter = conversionApi.writer;
|
|
75
|
+
const viewItem = generateLiInUl(modelItem, conversionApi);
|
|
76
|
+
viewWriter.addClass('todo-list', viewItem.parent);
|
|
77
|
+
const label = viewWriter.createContainerElement('label', {
|
|
78
|
+
class: 'todo-list__label'
|
|
79
|
+
});
|
|
80
|
+
const checkbox = viewWriter.createEmptyElement('input', {
|
|
81
|
+
type: 'checkbox',
|
|
82
|
+
disabled: 'disabled'
|
|
83
|
+
});
|
|
84
|
+
const span = viewWriter.createContainerElement('span', {
|
|
85
|
+
class: 'todo-list__label__description'
|
|
86
|
+
});
|
|
87
|
+
if (modelItem.getAttribute('todoListChecked')) {
|
|
88
|
+
viewWriter.setAttribute('checked', 'checked', checkbox);
|
|
89
|
+
}
|
|
90
|
+
viewWriter.insert(viewWriter.createPositionAt(viewItem, 0), label);
|
|
91
|
+
viewWriter.insert(viewWriter.createPositionAt(label, 0), checkbox);
|
|
92
|
+
viewWriter.insert(viewWriter.createPositionAfter(checkbox), span);
|
|
93
|
+
injectViewList(modelItem, viewItem, conversionApi, model);
|
|
94
|
+
};
|
|
128
95
|
}
|
|
129
|
-
|
|
130
96
|
/**
|
|
131
97
|
* A view-to-model converter for the checkbox element inside a view list item.
|
|
132
98
|
*
|
|
@@ -136,34 +102,24 @@ export function dataModelViewInsertion( model ) {
|
|
|
136
102
|
* It is used by {@link module:engine/controller/datacontroller~DataController}.
|
|
137
103
|
*
|
|
138
104
|
* @see module:engine/conversion/upcastdispatcher~UpcastDispatcher#event:element
|
|
139
|
-
* @param {module:utils/eventinfo~EventInfo} evt An object containing information about the fired event.
|
|
140
|
-
* @param {Object} data An object containing conversion input, a placeholder for conversion output and possibly other values.
|
|
141
|
-
* @param {module:engine/conversion/upcastdispatcher~UpcastConversionApi} conversionApi Conversion interface to be used by the callback.
|
|
142
105
|
*/
|
|
143
|
-
export
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
if ( data.viewItem.hasAttribute( 'checked' ) ) {
|
|
161
|
-
writer.setAttribute( 'todoListChecked', true, modelItem );
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
data.modelRange = writer.createRange( modelCursor );
|
|
165
|
-
}
|
|
166
|
-
|
|
106
|
+
export const dataViewModelCheckmarkInsertion = (evt, data, conversionApi) => {
|
|
107
|
+
const modelCursor = data.modelCursor;
|
|
108
|
+
const modelItem = modelCursor.parent;
|
|
109
|
+
const viewItem = data.viewItem;
|
|
110
|
+
if (viewItem.getAttribute('type') != 'checkbox' || modelItem.name != 'listItem' || !modelCursor.isAtStart) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
if (!conversionApi.consumable.consume(viewItem, { name: true })) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
const writer = conversionApi.writer;
|
|
117
|
+
writer.setAttribute('listType', 'todo', modelItem);
|
|
118
|
+
if (data.viewItem.hasAttribute('checked')) {
|
|
119
|
+
writer.setAttribute('todoListChecked', true, modelItem);
|
|
120
|
+
}
|
|
121
|
+
data.modelRange = writer.createRange(modelCursor);
|
|
122
|
+
};
|
|
167
123
|
/**
|
|
168
124
|
* A model-to-view converter for the `listType` attribute change on the `listItem` model element.
|
|
169
125
|
*
|
|
@@ -177,51 +133,43 @@ export function dataViewModelCheckmarkInsertion( evt, data, conversionApi ) {
|
|
|
177
133
|
* It is used by {@link module:engine/controller/editingcontroller~EditingController}.
|
|
178
134
|
*
|
|
179
135
|
* @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:attribute
|
|
180
|
-
* @param
|
|
181
|
-
* @param
|
|
182
|
-
* @returns
|
|
136
|
+
* @param onCheckedChange Callback fired after clicking the checkbox UI element.
|
|
137
|
+
* @param view Editing view controller.
|
|
138
|
+
* @returns Returns a conversion callback.
|
|
183
139
|
*/
|
|
184
|
-
export function modelViewChangeType(
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
viewWriter.removeClass( 'todo-list', viewItem.parent );
|
|
218
|
-
viewWriter.remove( labelElement );
|
|
219
|
-
viewWriter.move( viewWriter.createRangeIn( descriptionSpan ), viewWriter.createPositionBefore( descriptionSpan ) );
|
|
220
|
-
viewWriter.remove( descriptionSpan );
|
|
221
|
-
}
|
|
222
|
-
};
|
|
140
|
+
export function modelViewChangeType(onCheckedChange, view) {
|
|
141
|
+
return (evt, data, conversionApi) => {
|
|
142
|
+
if (!conversionApi.consumable.consume(data.item, evt.name)) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
const viewItem = conversionApi.mapper.toViewElement(data.item);
|
|
146
|
+
const viewWriter = conversionApi.writer;
|
|
147
|
+
const labelElement = findLabel(viewItem, view);
|
|
148
|
+
if (data.attributeNewValue == 'todo') {
|
|
149
|
+
const isChecked = !!data.item.getAttribute('todoListChecked');
|
|
150
|
+
const checkmarkElement = createCheckmarkElement(data.item, viewWriter, isChecked, onCheckedChange);
|
|
151
|
+
const span = viewWriter.createContainerElement('span', {
|
|
152
|
+
class: 'todo-list__label__description'
|
|
153
|
+
});
|
|
154
|
+
const itemRange = viewWriter.createRangeIn(viewItem);
|
|
155
|
+
const nestedList = findNestedList(viewItem);
|
|
156
|
+
const descriptionStart = positionAfterUiElements(itemRange.start);
|
|
157
|
+
const descriptionEnd = nestedList ? viewWriter.createPositionBefore(nestedList) : itemRange.end;
|
|
158
|
+
const descriptionRange = viewWriter.createRange(descriptionStart, descriptionEnd);
|
|
159
|
+
viewWriter.addClass('todo-list', viewItem.parent);
|
|
160
|
+
viewWriter.move(descriptionRange, viewWriter.createPositionAt(span, 0));
|
|
161
|
+
viewWriter.insert(viewWriter.createPositionAt(viewItem, 0), checkmarkElement);
|
|
162
|
+
viewWriter.insert(viewWriter.createPositionAfter(checkmarkElement), span);
|
|
163
|
+
}
|
|
164
|
+
else if (data.attributeOldValue == 'todo') {
|
|
165
|
+
const descriptionSpan = findDescription(viewItem, view);
|
|
166
|
+
viewWriter.removeClass('todo-list', viewItem.parent);
|
|
167
|
+
viewWriter.remove(labelElement);
|
|
168
|
+
viewWriter.move(viewWriter.createRangeIn(descriptionSpan), viewWriter.createPositionBefore(descriptionSpan));
|
|
169
|
+
viewWriter.remove(descriptionSpan);
|
|
170
|
+
}
|
|
171
|
+
};
|
|
223
172
|
}
|
|
224
|
-
|
|
225
173
|
/**
|
|
226
174
|
* A model-to-view converter for the `todoListChecked` attribute change on the `listItem` model element.
|
|
227
175
|
*
|
|
@@ -230,113 +178,83 @@ export function modelViewChangeType( onCheckedChange, view ) {
|
|
|
230
178
|
* It is used by {@link module:engine/controller/editingcontroller~EditingController}.
|
|
231
179
|
*
|
|
232
180
|
* @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:attribute
|
|
233
|
-
* @param
|
|
234
|
-
* @returns
|
|
181
|
+
* @param onCheckedChange Callback fired after clicking the checkbox UI element.
|
|
182
|
+
* @returns Returns a conversion callback.
|
|
235
183
|
*/
|
|
236
|
-
export function modelViewChangeChecked(
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
viewWriter.insert( viewWriter.createPositionAfter( oldCheckmarkElement ), newCheckmarkElement );
|
|
256
|
-
viewWriter.remove( oldCheckmarkElement );
|
|
257
|
-
};
|
|
184
|
+
export function modelViewChangeChecked(onCheckedChange) {
|
|
185
|
+
return (evt, data, conversionApi) => {
|
|
186
|
+
// Do not convert `todoListChecked` attribute when to-do list item has changed to other list item.
|
|
187
|
+
// This attribute will be removed by the model post fixer.
|
|
188
|
+
if (data.item.getAttribute('listType') != 'todo') {
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
if (!conversionApi.consumable.consume(data.item, 'attribute:todoListChecked')) {
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
const { mapper, writer: viewWriter } = conversionApi;
|
|
195
|
+
const isChecked = !!data.item.getAttribute('todoListChecked');
|
|
196
|
+
const viewItem = mapper.toViewElement(data.item);
|
|
197
|
+
// Because of m -> v position mapper we can be sure checkbox is always at the beginning.
|
|
198
|
+
const oldCheckmarkElement = viewItem.getChild(0);
|
|
199
|
+
const newCheckmarkElement = createCheckmarkElement(data.item, viewWriter, isChecked, onCheckedChange);
|
|
200
|
+
viewWriter.insert(viewWriter.createPositionAfter(oldCheckmarkElement), newCheckmarkElement);
|
|
201
|
+
viewWriter.remove(oldCheckmarkElement);
|
|
202
|
+
};
|
|
258
203
|
}
|
|
259
|
-
|
|
260
204
|
/**
|
|
261
205
|
* A model-to-view position at zero offset mapper.
|
|
262
206
|
*
|
|
263
207
|
* This helper ensures that position inside todo-list in the view is mapped after the checkbox.
|
|
264
208
|
*
|
|
265
209
|
* It only handles the position at the beginning of a list item as other positions are properly mapped be the default mapper.
|
|
266
|
-
*
|
|
267
|
-
* @param {module:engine/view/view~View} view
|
|
268
|
-
* @return {Function}
|
|
269
210
|
*/
|
|
270
|
-
export function mapModelToViewPosition(
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
data.viewPosition = data.mapper.findPositionIn( descSpan, modelPosition.offset );
|
|
284
|
-
}
|
|
285
|
-
};
|
|
211
|
+
export function mapModelToViewPosition(view) {
|
|
212
|
+
return (evt, data) => {
|
|
213
|
+
const modelPosition = data.modelPosition;
|
|
214
|
+
const parent = modelPosition.parent;
|
|
215
|
+
if (!parent.is('element', 'listItem') || parent.getAttribute('listType') != 'todo') {
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
const viewLi = data.mapper.toViewElement(parent);
|
|
219
|
+
const descSpan = findDescription(viewLi, view);
|
|
220
|
+
if (descSpan) {
|
|
221
|
+
data.viewPosition = data.mapper.findPositionIn(descSpan, modelPosition.offset);
|
|
222
|
+
}
|
|
223
|
+
};
|
|
286
224
|
}
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
if ( isChecked ) {
|
|
307
|
-
checkbox.setAttribute( 'checked', 'checked' );
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
checkbox.addEventListener( 'change', () => onChange( modelItem ) );
|
|
311
|
-
|
|
312
|
-
const domElement = this.toDomElement( domDocument );
|
|
313
|
-
|
|
314
|
-
domElement.appendChild( checkbox );
|
|
315
|
-
|
|
316
|
-
return domElement;
|
|
317
|
-
}
|
|
318
|
-
);
|
|
319
|
-
|
|
320
|
-
return uiElement;
|
|
225
|
+
/**
|
|
226
|
+
* Creates a checkbox UI element.
|
|
227
|
+
*/
|
|
228
|
+
function createCheckmarkElement(modelItem, viewWriter, isChecked, onChange) {
|
|
229
|
+
const uiElement = viewWriter.createUIElement('label', {
|
|
230
|
+
class: 'todo-list__label',
|
|
231
|
+
contenteditable: false
|
|
232
|
+
}, function (domDocument) {
|
|
233
|
+
const checkbox = createElement(document, 'input', { type: 'checkbox', tabindex: '-1' });
|
|
234
|
+
if (isChecked) {
|
|
235
|
+
checkbox.setAttribute('checked', 'checked');
|
|
236
|
+
}
|
|
237
|
+
checkbox.addEventListener('change', () => onChange(modelItem));
|
|
238
|
+
const domElement = this.toDomElement(domDocument);
|
|
239
|
+
domElement.appendChild(checkbox);
|
|
240
|
+
return domElement;
|
|
241
|
+
});
|
|
242
|
+
return uiElement;
|
|
321
243
|
}
|
|
322
|
-
|
|
323
244
|
// Helper method to find label element inside li.
|
|
324
|
-
function findLabel(
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
}
|
|
245
|
+
function findLabel(viewItem, view) {
|
|
246
|
+
const range = view.createRangeIn(viewItem);
|
|
247
|
+
for (const value of range) {
|
|
248
|
+
if (value.item.is('uiElement', 'label')) {
|
|
249
|
+
return value.item;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
332
252
|
}
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
}
|
|
341
|
-
}
|
|
253
|
+
function findDescription(viewItem, view) {
|
|
254
|
+
const range = view.createRangeIn(viewItem);
|
|
255
|
+
for (const value of range) {
|
|
256
|
+
if (value.item.is('containerElement', 'span') && value.item.hasClass('todo-list__label__description')) {
|
|
257
|
+
return value.item;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
342
260
|
}
|