UNPKG

2.94 kBJavaScriptView Raw
1/**
2 * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
3 * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4 */
5/**
6 * @module list/todolist/checktodolistcommand
7 */
8import { Command } from 'ckeditor5/src/core';
9const attributeKey = 'todoListChecked';
10/**
11 * The check to-do command.
12 *
13 * The command is registered by the {@link module:list/todolist/todolistediting~TodoListEditing} as
14 * the `checkTodoList` editor command and it is also available via aliased `todoListCheck` name.
15 */
16export default class CheckTodoListCommand extends Command {
17 /**
18 * @inheritDoc
19 */
20 constructor(editor) {
21 super(editor);
22 this._selectedElements = [];
23 // Refresh command before executing to be sure all values are up to date.
24 // It is needed when selection has changed before command execution, in the same change block.
25 this.on('execute', () => {
26 this.refresh();
27 }, { priority: 'highest' });
28 }
29 /**
30 * Updates the command's {@link #value} and {@link #isEnabled} properties based on the current selection.
31 */
32 refresh() {
33 this._selectedElements = this._getSelectedItems();
34 this.value = this._selectedElements.every(element => !!element.getAttribute(attributeKey));
35 this.isEnabled = !!this._selectedElements.length;
36 }
37 /**
38 * Gets all to-do list items selected by the {@link module:engine/model/selection~Selection}.
39 */
40 _getSelectedItems() {
41 const model = this.editor.model;
42 const schema = model.schema;
43 const selectionRange = model.document.selection.getFirstRange();
44 const startElement = selectionRange.start.parent;
45 const elements = [];
46 if (schema.checkAttribute(startElement, attributeKey)) {
47 elements.push(startElement);
48 }
49 for (const item of selectionRange.getItems()) {
50 if (schema.checkAttribute(item, attributeKey) && !elements.includes(item)) {
51 elements.push(item);
52 }
53 }
54 return elements;
55 }
56 /**
57 * Executes the command.
58 *
59 * @param options.forceValue If set, it will force the command behavior. If `true`, the command will apply
60 * the attribute. Otherwise, the command will remove the attribute. If not set, the command will look for its current
61 * value to decide what it should do.
62 */
63 execute(options = {}) {
64 this.editor.model.change(writer => {
65 for (const element of this._selectedElements) {
66 const value = (options.forceValue === undefined) ? !this.value : options.forceValue;
67 if (value) {
68 writer.setAttribute(attributeKey, true, element);
69 }
70 else {
71 writer.removeAttribute(attributeKey, element);
72 }
73 }
74 });
75 }
76}