@akilli/editor-src 5.1.5
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/abbreviation/Abbreviation.js +32 -0
- package/abbreviation/AbbreviationDialog.js +21 -0
- package/audio/Audio.js +47 -0
- package/audio/AudioDialog.js +18 -0
- package/audio/AudioListener.js +50 -0
- package/base/AlignCommand.js +34 -0
- package/base/AlignableListener.js +45 -0
- package/base/Alignment.js +36 -0
- package/base/BarListener.js +95 -0
- package/base/Base.js +127 -0
- package/base/Command.js +139 -0
- package/base/CommandManager.js +60 -0
- package/base/ContentFilter.js +109 -0
- package/base/DeletableListener.js +36 -0
- package/base/DeleteCommand.js +18 -0
- package/base/Dialog.js +153 -0
- package/base/DialogManager.js +44 -0
- package/base/Dispatcher.js +88 -0
- package/base/Dom.js +790 -0
- package/base/EditableListener.js +82 -0
- package/base/Editor.js +448 -0
- package/base/Filter.js +35 -0
- package/base/FilterManager.js +44 -0
- package/base/FocusableListener.js +22 -0
- package/base/FocusbarListener.js +99 -0
- package/base/FormCreator.js +162 -0
- package/base/FormatbarListener.js +32 -0
- package/base/Key.js +258 -0
- package/base/Listener.js +51 -0
- package/base/NavigableListener.js +81 -0
- package/base/Plugin.js +176 -0
- package/base/PluginManager.js +51 -0
- package/base/SlotableListener.js +40 -0
- package/base/SortCommand.js +30 -0
- package/base/SortableListener.js +135 -0
- package/base/Sorting.js +36 -0
- package/base/Tag.js +113 -0
- package/base/TagGroup.js +183 -0
- package/base/TagListener.js +34 -0
- package/base/TagManager.js +61 -0
- package/base/TagName.js +470 -0
- package/base/ToolbarListener.js +11 -0
- package/base/util.js +59 -0
- package/block/Block.js +51 -0
- package/block/BlockDialog.js +11 -0
- package/block/BlockElement.js +21 -0
- package/block/BlockListener.js +60 -0
- package/blockquote/Blockquote.js +43 -0
- package/blockquote/BlockquoteFilter.js +22 -0
- package/blockquote/BlockquoteListener.js +34 -0
- package/bold/Bold.js +30 -0
- package/break/Break.js +33 -0
- package/break/BreakFilter.js +24 -0
- package/build/BuildEditor.js +97 -0
- package/build/editor.css +548 -0
- package/build/editor.woff2 +0 -0
- package/cite/Cite.js +30 -0
- package/code/Code.js +30 -0
- package/data/Data.js +32 -0
- package/data/DataDialog.js +13 -0
- package/definition/Definition.js +32 -0
- package/definition/DefinitionDialog.js +13 -0
- package/deletion/Deletion.js +30 -0
- package/details/Details.js +63 -0
- package/details/DetailsFilter.js +17 -0
- package/details/DetailsListener.js +102 -0
- package/division/Division.js +53 -0
- package/division/DivisionDialog.js +13 -0
- package/emphasis/Emphasis.js +30 -0
- package/figure/Figure.js +58 -0
- package/figure/FigureFilter.js +14 -0
- package/figure/FigureListener.js +23 -0
- package/heading/Heading.js +38 -0
- package/horizontalrule/HorizontalRule.js +37 -0
- package/i18n/I18n.js +26 -0
- package/i18n/de.js +167 -0
- package/iframe/Iframe.js +49 -0
- package/iframe/IframeDialog.js +20 -0
- package/iframe/IframeListener.js +48 -0
- package/image/Image.js +47 -0
- package/image/ImageDialog.js +23 -0
- package/image/ImageListener.js +47 -0
- package/insertion/Insertion.js +30 -0
- package/italic/Italic.js +30 -0
- package/keyboard/Keyboard.js +30 -0
- package/link/Link.js +34 -0
- package/link/LinkDialog.js +14 -0
- package/link/LinkListener.js +45 -0
- package/list/List.js +40 -0
- package/list/ListListener.js +91 -0
- package/mark/Mark.js +30 -0
- package/orderedlist/OrderedList.js +39 -0
- package/package.json +24 -0
- package/paragraph/Paragraph.js +42 -0
- package/paragraph/ParagraphListener.js +40 -0
- package/preformat/Preformat.js +43 -0
- package/preformat/PreformatFilter.js +22 -0
- package/preformat/PreformatListener.js +34 -0
- package/quote/Quote.js +30 -0
- package/sample/Sample.js +30 -0
- package/section/Section.js +55 -0
- package/section/SectionDialog.js +13 -0
- package/small/Small.js +30 -0
- package/strikethrough/Strikethrough.js +30 -0
- package/strong/Strong.js +30 -0
- package/subheading/Subheading.js +38 -0
- package/subscript/Subscript.js +30 -0
- package/superscript/Superscript.js +30 -0
- package/table/Table.js +113 -0
- package/table/TableCellListener.js +125 -0
- package/table/TableColumnAddCommand.js +19 -0
- package/table/TableColumnListener.js +34 -0
- package/table/TableCommand.js +23 -0
- package/table/TableDialog.js +14 -0
- package/table/TableFilter.js +35 -0
- package/table/TableListener.js +39 -0
- package/table/TableRowAddCommand.js +18 -0
- package/table/TableRowListener.js +34 -0
- package/time/Time.js +32 -0
- package/time/TimeDialog.js +13 -0
- package/underline/Underline.js +30 -0
- package/unorderedlist/UnorderedList.js +39 -0
- package/variable/Variable.js +30 -0
- package/video/Video.js +47 -0
- package/video/VideoDialog.js +20 -0
- package/video/VideoListener.js +48 -0
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import Key from '../base/Key.js';
|
|
2
|
+
import Listener from '../base/Listener.js';
|
|
3
|
+
import TagName from '../base/TagName.js';
|
|
4
|
+
|
|
5
|
+
export default class TableCellListener extends Listener {
|
|
6
|
+
/**
|
|
7
|
+
* @param {Editor} editor
|
|
8
|
+
*/
|
|
9
|
+
constructor(editor) {
|
|
10
|
+
super(editor);
|
|
11
|
+
this.editor.root.addEventListener('inserttd', this);
|
|
12
|
+
this.editor.root.addEventListener('insertth', this);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @param {CustomEvent} event
|
|
17
|
+
* @param {HTMLTableCellElement} event.detail.element
|
|
18
|
+
* @return {void}
|
|
19
|
+
*/
|
|
20
|
+
inserttd({ detail: { element } }) {
|
|
21
|
+
element.addEventListener('keydown', this);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* @param {CustomEvent} event
|
|
26
|
+
* @param {HTMLTableCellElement} event.detail.element
|
|
27
|
+
* @return {void}
|
|
28
|
+
*/
|
|
29
|
+
insertth({ detail: { element } }) {
|
|
30
|
+
element.addEventListener('keydown', this);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* @param {KeyboardEvent} event
|
|
35
|
+
* @param {HTMLTableCellElement} event.target
|
|
36
|
+
* @return {void}
|
|
37
|
+
*/
|
|
38
|
+
keydown(event) {
|
|
39
|
+
const cell = event.target;
|
|
40
|
+
const row = cell.parentElement;
|
|
41
|
+
const table = cell.closest(TagName.TABLE);
|
|
42
|
+
|
|
43
|
+
if (
|
|
44
|
+
cell instanceof HTMLTableCellElement &&
|
|
45
|
+
row instanceof HTMLTableRowElement &&
|
|
46
|
+
table instanceof HTMLTableElement &&
|
|
47
|
+
Key.isEventFor(event, [Key.ARROWLEFT, Key.ARROWRIGHT, Key.ARROWUP, Key.ARROWDOWN]) &&
|
|
48
|
+
this.#enabled(cell, event.key)
|
|
49
|
+
) {
|
|
50
|
+
const cellIndex = cell.cellIndex;
|
|
51
|
+
const cellLength = row.cells.length;
|
|
52
|
+
const isFirst = cellIndex === 0;
|
|
53
|
+
const isLast = cellIndex === cellLength - 1;
|
|
54
|
+
const isFirstTableRow = row.rowIndex === 0;
|
|
55
|
+
const isLastTableRow = row.rowIndex === table.rows.length - 1;
|
|
56
|
+
|
|
57
|
+
event.preventDefault();
|
|
58
|
+
event.stopPropagation();
|
|
59
|
+
|
|
60
|
+
if (event.key === Key.ARROWLEFT && !isFirst) {
|
|
61
|
+
this.editor.dom.focusEnd(row.cells[cellIndex - 1]);
|
|
62
|
+
} else if (event.key === Key.ARROWLEFT && isFirstTableRow) {
|
|
63
|
+
this.editor.dom.focusEnd(table.rows[table.rows.length - 1].cells[cellLength - 1]);
|
|
64
|
+
} else if (event.key === Key.ARROWLEFT) {
|
|
65
|
+
this.editor.dom.focusEnd(table.rows[row.rowIndex - 1].cells[cellLength - 1]);
|
|
66
|
+
} else if (event.key === Key.ARROWRIGHT && !isLast) {
|
|
67
|
+
row.cells[cellIndex + 1].focus();
|
|
68
|
+
} else if (event.key === Key.ARROWRIGHT && isLastTableRow) {
|
|
69
|
+
table.rows[0].cells[0].focus();
|
|
70
|
+
} else if (event.key === Key.ARROWRIGHT) {
|
|
71
|
+
table.rows[row.rowIndex + 1].cells[0].focus();
|
|
72
|
+
} else if (event.key === Key.ARROWUP && isFirstTableRow) {
|
|
73
|
+
table.rows[table.rows.length - 1].cells[cellIndex].focus();
|
|
74
|
+
} else if (event.key === Key.ARROWUP) {
|
|
75
|
+
table.rows[row.rowIndex - 1].cells[cellIndex].focus();
|
|
76
|
+
} else if (event.key === Key.ARROWDOWN && isLastTableRow) {
|
|
77
|
+
table.rows[0].cells[cellIndex].focus();
|
|
78
|
+
} else if (event.key === Key.ARROWDOWN) {
|
|
79
|
+
table.rows[row.rowIndex + 1].cells[cellIndex].focus();
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Enables or disables navigation for table cell elements
|
|
86
|
+
*
|
|
87
|
+
* @param {HTMLTableCellElement} element
|
|
88
|
+
* @param {string} key
|
|
89
|
+
* @return {boolean}
|
|
90
|
+
*/
|
|
91
|
+
#enabled(element, key) {
|
|
92
|
+
if ([Key.ARROWUP, Key.ARROWDOWN].includes(key)) {
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const sel = this.editor.dom.getSelection();
|
|
97
|
+
const anc = sel.anchorNode instanceof HTMLElement ? sel.anchorNode : element;
|
|
98
|
+
|
|
99
|
+
if (!sel.isCollapsed) {
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (key === Key.ARROWLEFT) {
|
|
104
|
+
let first = element.firstChild;
|
|
105
|
+
|
|
106
|
+
if (first instanceof HTMLElement) {
|
|
107
|
+
first = first.firstChild;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return sel.anchorOffset === 0 && [element, first].includes(anc);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
let last = element.lastChild;
|
|
114
|
+
|
|
115
|
+
if (element.lastChild instanceof HTMLBRElement && element.lastChild.previousSibling) {
|
|
116
|
+
last = element.lastChild.previousSibling;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (last instanceof HTMLElement) {
|
|
120
|
+
last = last.lastChild;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return sel.anchorOffset === anc.textContent.length && [element, last].includes(anc);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import Command from '../base/Command.js';
|
|
2
|
+
import TagName from '../base/TagName.js';
|
|
3
|
+
|
|
4
|
+
export default class TableColumnAddCommand extends Command {
|
|
5
|
+
/**
|
|
6
|
+
* @param {Editor} editor
|
|
7
|
+
*/
|
|
8
|
+
constructor(editor) {
|
|
9
|
+
super(editor, 'tablecolumn-add');
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @return {void}
|
|
14
|
+
*/
|
|
15
|
+
execute() {
|
|
16
|
+
const element = this.editor.dom.getActiveElement();
|
|
17
|
+
element?.localName === TagName.COL && this.editor.dom.createTableColumnAfter(element);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import Key from '../base/Key.js';
|
|
2
|
+
import Listener from '../base/Listener.js';
|
|
3
|
+
|
|
4
|
+
export default class TableColumnListener extends Listener {
|
|
5
|
+
/**
|
|
6
|
+
* @param {Editor} editor
|
|
7
|
+
*/
|
|
8
|
+
constructor(editor) {
|
|
9
|
+
super(editor);
|
|
10
|
+
this.editor.root.addEventListener('insertcol', this);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @param {CustomEvent} event
|
|
15
|
+
* @param {HTMLTableColElement} event.detail.element
|
|
16
|
+
* @return {void}
|
|
17
|
+
*/
|
|
18
|
+
insertcol({ detail: { element } }) {
|
|
19
|
+
element.addEventListener('keydown', this);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @param {KeyboardEvent} event
|
|
24
|
+
* @param {HTMLTableColElement} event.target
|
|
25
|
+
* @return {void}
|
|
26
|
+
*/
|
|
27
|
+
keydown(event) {
|
|
28
|
+
if (Key.isEventFor(event, Key.ENTER)) {
|
|
29
|
+
this.editor.dom.createTableColumnAfter(event.target);
|
|
30
|
+
} else if (Key.isEventFor(event, Key.BACKSPACE)) {
|
|
31
|
+
this.editor.dom.delete(event.target);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import Command from '../base/Command.js';
|
|
2
|
+
import Table from './Table.js';
|
|
3
|
+
import TagName from '../base/TagName.js';
|
|
4
|
+
|
|
5
|
+
export default class TableCommand extends Command {
|
|
6
|
+
/**
|
|
7
|
+
* @param {Editor} editor
|
|
8
|
+
*/
|
|
9
|
+
constructor(editor) {
|
|
10
|
+
super(editor, Table.name, TagName.TABLE);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @protected
|
|
15
|
+
* @param {Object.<string, string>} [attributes = {}]
|
|
16
|
+
* @param {string} attributes.rows
|
|
17
|
+
* @param {string} attributes.cols
|
|
18
|
+
* @return {void}
|
|
19
|
+
*/
|
|
20
|
+
_insert({ rows, cols } = {}) {
|
|
21
|
+
this.editor.dom.insert(this.editor.dom.createTable(parseInt(rows, 10) || 1, parseInt(cols, 10) || 1));
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import Dialog from '../base/Dialog.js';
|
|
2
|
+
|
|
3
|
+
export default class TableDialog extends Dialog {
|
|
4
|
+
/**
|
|
5
|
+
* @protected
|
|
6
|
+
* @return {void}
|
|
7
|
+
*/
|
|
8
|
+
_prepareForm() {
|
|
9
|
+
this.formCreator
|
|
10
|
+
.addLegend(this._('Table'))
|
|
11
|
+
.addNumberInput('rows', this._('Rows'), { min: '1', required: 'required', value: '1' })
|
|
12
|
+
.addNumberInput('cols', this._('Columns'), { min: '1', required: 'required', value: '1' });
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import Filter from '../base/Filter.js';
|
|
2
|
+
import Table from './Table.js';
|
|
3
|
+
import TagName from '../base/TagName.js';
|
|
4
|
+
|
|
5
|
+
export default class TableFilter extends Filter {
|
|
6
|
+
/**
|
|
7
|
+
* @param {HTMLElement} element
|
|
8
|
+
* @return {void}
|
|
9
|
+
*/
|
|
10
|
+
filter(element) {
|
|
11
|
+
if (
|
|
12
|
+
element instanceof HTMLElement &&
|
|
13
|
+
element.localName === TagName.FIGURE &&
|
|
14
|
+
element.classList.contains(Table.name) &&
|
|
15
|
+
element.querySelector(':scope > ' + TagName.TABLE) &&
|
|
16
|
+
!element.querySelector(':scope > ' + TagName.FIGCAPTION)
|
|
17
|
+
) {
|
|
18
|
+
this.editor.dom.insertBefore(element.querySelector(':scope > ' + TagName.TABLE), element);
|
|
19
|
+
element.parentElement.removeChild(element);
|
|
20
|
+
} else if (
|
|
21
|
+
element instanceof HTMLTableElement &&
|
|
22
|
+
element.querySelector(`:scope > ${TagName.THEAD}, :scope > ${TagName.TFOOT}`) &&
|
|
23
|
+
!element.querySelector(':scope > ' + TagName.TBODY)
|
|
24
|
+
) {
|
|
25
|
+
element.parentElement.removeChild(element);
|
|
26
|
+
} else if (element instanceof HTMLTableSectionElement && element.rows.length <= 0) {
|
|
27
|
+
element.parentElement.removeChild(element);
|
|
28
|
+
} else if (
|
|
29
|
+
element instanceof HTMLTableRowElement &&
|
|
30
|
+
!element.querySelector(`:scope > ${TagName.TH}:not(:empty), :scope > ${TagName.TD}:not(:empty)`)
|
|
31
|
+
) {
|
|
32
|
+
element.parentElement.removeChild(element);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import Listener from '../base/Listener.js';
|
|
2
|
+
import Table from './Table.js';
|
|
3
|
+
import TagName from '../base/TagName.js';
|
|
4
|
+
|
|
5
|
+
export default class TableListener extends Listener {
|
|
6
|
+
/**
|
|
7
|
+
* @param {Editor} editor
|
|
8
|
+
*/
|
|
9
|
+
constructor(editor) {
|
|
10
|
+
super(editor);
|
|
11
|
+
this.editor.root.addEventListener('inserttable', this);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @param {CustomEvent} event
|
|
16
|
+
* @param {HTMLTableElement} event.detail.element
|
|
17
|
+
* @return {void}
|
|
18
|
+
*/
|
|
19
|
+
inserttable({ detail: { element } }) {
|
|
20
|
+
this.editor.dom.wrap(element, TagName.FIGURE, { attributes: { class: Table.name } });
|
|
21
|
+
|
|
22
|
+
if (element.tBodies.length > 0 && element.tBodies[0].rows[0]) {
|
|
23
|
+
const tbody = element.tBodies[0];
|
|
24
|
+
const cols = tbody.rows[0].cells.length;
|
|
25
|
+
|
|
26
|
+
if (!element.querySelector(':scope > ' + TagName.COLGROUP)) {
|
|
27
|
+
this.editor.dom.insertFirstChild(this.editor.dom.createTableColumnGroup(cols), element);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (!element.tHead) {
|
|
31
|
+
this.editor.dom.insertBefore(this.editor.dom.createTableHeader(1, cols), tbody);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (!element.tFoot) {
|
|
35
|
+
this.editor.dom.insertLastChild(this.editor.dom.createTableFooter(1, cols), element);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import Command from '../base/Command.js';
|
|
2
|
+
|
|
3
|
+
export default class TableRowAddCommand extends Command {
|
|
4
|
+
/**
|
|
5
|
+
* @param {Editor} editor
|
|
6
|
+
*/
|
|
7
|
+
constructor(editor) {
|
|
8
|
+
super(editor, 'tablerow-add');
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @return {void}
|
|
13
|
+
*/
|
|
14
|
+
execute() {
|
|
15
|
+
const element = this.editor.dom.getActiveElement();
|
|
16
|
+
element instanceof HTMLTableRowElement && this.editor.dom.createTableRowAfter(element);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import Key from '../base/Key.js';
|
|
2
|
+
import Listener from '../base/Listener.js';
|
|
3
|
+
|
|
4
|
+
export default class TableRowListener extends Listener {
|
|
5
|
+
/**
|
|
6
|
+
* @param {Editor} editor
|
|
7
|
+
*/
|
|
8
|
+
constructor(editor) {
|
|
9
|
+
super(editor);
|
|
10
|
+
this.editor.root.addEventListener('inserttr', this);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @param {CustomEvent} event
|
|
15
|
+
* @param {HTMLTableRowElement} event.detail.element
|
|
16
|
+
* @return {void}
|
|
17
|
+
*/
|
|
18
|
+
inserttr({ detail: { element } }) {
|
|
19
|
+
element.addEventListener('keydown', this);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @param {KeyboardEvent} event
|
|
24
|
+
* @param {HTMLTableRowElement} event.target
|
|
25
|
+
* @return {void}
|
|
26
|
+
*/
|
|
27
|
+
keydown(event) {
|
|
28
|
+
if (Key.isEventFor(event, Key.ENTER)) {
|
|
29
|
+
this.editor.dom.createTableRowAfter(event.target);
|
|
30
|
+
} else if (Key.isEventFor(event, Key.BACKSPACE)) {
|
|
31
|
+
this.editor.dom.delete(event.target);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
package/time/Time.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import Base from '../base/Base.js';
|
|
2
|
+
import Key from '../base/Key.js';
|
|
3
|
+
import Plugin from '../base/Plugin.js';
|
|
4
|
+
import TagGroup from '../base/TagGroup.js';
|
|
5
|
+
import TagName from '../base/TagName.js';
|
|
6
|
+
import TimeDialog from './TimeDialog.js';
|
|
7
|
+
|
|
8
|
+
export default class Time extends Plugin {
|
|
9
|
+
/**
|
|
10
|
+
* @type {string}
|
|
11
|
+
*/
|
|
12
|
+
static get name() {
|
|
13
|
+
return 'time';
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @type {Plugin[]}
|
|
18
|
+
*/
|
|
19
|
+
static get dependencies() {
|
|
20
|
+
return [Base];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @return {void}
|
|
25
|
+
*/
|
|
26
|
+
init() {
|
|
27
|
+
this._tag({ name: TagName.TIME, group: TagGroup.FORMAT, attributes: ['datetime'] });
|
|
28
|
+
this.editor.dialogs.set(new TimeDialog(this.editor, this.constructor.name));
|
|
29
|
+
this._command(TagName.TIME);
|
|
30
|
+
this._formatbar('Time', Key.T);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import Dialog from '../base/Dialog.js';
|
|
2
|
+
|
|
3
|
+
export default class TimeDialog extends Dialog {
|
|
4
|
+
/**
|
|
5
|
+
* @protected
|
|
6
|
+
* @return {void}
|
|
7
|
+
*/
|
|
8
|
+
_prepareForm() {
|
|
9
|
+
this.formCreator.addLegend(this._('Data')).addTextInput('datetime', this._('Machine-readable Datetime'), {
|
|
10
|
+
placeholder: this._('Insert date/time or leave empty to remove it'),
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import Base from '../base/Base.js';
|
|
2
|
+
import Key from '../base/Key.js';
|
|
3
|
+
import Plugin from '../base/Plugin.js';
|
|
4
|
+
import TagGroup from '../base/TagGroup.js';
|
|
5
|
+
import TagName from '../base/TagName.js';
|
|
6
|
+
|
|
7
|
+
export default class Underline extends Plugin {
|
|
8
|
+
/**
|
|
9
|
+
* @type {string}
|
|
10
|
+
*/
|
|
11
|
+
static get name() {
|
|
12
|
+
return 'underline';
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @type {Plugin[]}
|
|
17
|
+
*/
|
|
18
|
+
static get dependencies() {
|
|
19
|
+
return [Base];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @return {void}
|
|
24
|
+
*/
|
|
25
|
+
init() {
|
|
26
|
+
this._tag({ name: TagName.U, group: TagGroup.FORMAT });
|
|
27
|
+
this._command(TagName.U);
|
|
28
|
+
this._formatbar('underline', Key.U);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import Base from '../base/Base.js';
|
|
2
|
+
import List from '../list/List.js';
|
|
3
|
+
import Plugin from '../base/Plugin.js';
|
|
4
|
+
import TagGroup from '../base/TagGroup.js';
|
|
5
|
+
import TagName from '../base/TagName.js';
|
|
6
|
+
|
|
7
|
+
export default class UnorderedList extends Plugin {
|
|
8
|
+
/**
|
|
9
|
+
* @type {string}
|
|
10
|
+
*/
|
|
11
|
+
static get name() {
|
|
12
|
+
return 'unorderedlist';
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @type {Plugin[]}
|
|
17
|
+
*/
|
|
18
|
+
static get dependencies() {
|
|
19
|
+
return [Base, List];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @return {void}
|
|
24
|
+
*/
|
|
25
|
+
init() {
|
|
26
|
+
this._tag({
|
|
27
|
+
name: TagName.UL,
|
|
28
|
+
group: TagGroup.LIST,
|
|
29
|
+
children: [TagGroup.LISTITEM],
|
|
30
|
+
arbitrary: true,
|
|
31
|
+
deletable: true,
|
|
32
|
+
focusable: true,
|
|
33
|
+
navigable: true,
|
|
34
|
+
sortable: true,
|
|
35
|
+
});
|
|
36
|
+
this._command(TagName.UL);
|
|
37
|
+
this._toolbar('Unordered List');
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import Base from '../base/Base.js';
|
|
2
|
+
import Key from '../base/Key.js';
|
|
3
|
+
import Plugin from '../base/Plugin.js';
|
|
4
|
+
import TagGroup from '../base/TagGroup.js';
|
|
5
|
+
import TagName from '../base/TagName.js';
|
|
6
|
+
|
|
7
|
+
export default class Variable extends Plugin {
|
|
8
|
+
/**
|
|
9
|
+
* @type {string}
|
|
10
|
+
*/
|
|
11
|
+
static get name() {
|
|
12
|
+
return 'variable';
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @type {Plugin[]}
|
|
17
|
+
*/
|
|
18
|
+
static get dependencies() {
|
|
19
|
+
return [Base];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @return {void}
|
|
24
|
+
*/
|
|
25
|
+
init() {
|
|
26
|
+
this._tag({ name: TagName.VAR, group: TagGroup.FORMAT });
|
|
27
|
+
this._command(TagName.VAR);
|
|
28
|
+
this._formatbar('Variable', Key.V);
|
|
29
|
+
}
|
|
30
|
+
}
|
package/video/Video.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import Base from '../base/Base.js';
|
|
2
|
+
import Figure from '../figure/Figure.js';
|
|
3
|
+
import Plugin from '../base/Plugin.js';
|
|
4
|
+
import TagGroup from '../base/TagGroup.js';
|
|
5
|
+
import TagName from '../base/TagName.js';
|
|
6
|
+
import VideoDialog from './VideoDialog.js';
|
|
7
|
+
import VideoListener from './VideoListener.js';
|
|
8
|
+
|
|
9
|
+
export default class Video extends Plugin {
|
|
10
|
+
/**
|
|
11
|
+
* @type {string}
|
|
12
|
+
*/
|
|
13
|
+
static get name() {
|
|
14
|
+
return 'video';
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @type {Plugin[]}
|
|
19
|
+
*/
|
|
20
|
+
static get dependencies() {
|
|
21
|
+
return [Base, Figure];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* @type {Object.<string, any>}
|
|
26
|
+
*/
|
|
27
|
+
static get config() {
|
|
28
|
+
return { browser: undefined };
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* @return {void}
|
|
33
|
+
*/
|
|
34
|
+
init() {
|
|
35
|
+
this._tag({
|
|
36
|
+
name: TagName.VIDEO,
|
|
37
|
+
group: TagGroup.VIDEO,
|
|
38
|
+
attributes: ['controls', 'height', 'id', 'src', 'width'],
|
|
39
|
+
empty: true,
|
|
40
|
+
navigable: true,
|
|
41
|
+
});
|
|
42
|
+
new VideoListener(this.editor);
|
|
43
|
+
this.editor.dialogs.set(new VideoDialog(this.editor, this.constructor.name, this.editor.config.video.browser));
|
|
44
|
+
this._command(TagName.VIDEO);
|
|
45
|
+
this._toolbar('Video');
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import Dialog from '../base/Dialog.js';
|
|
2
|
+
|
|
3
|
+
export default class VideoDialog extends Dialog {
|
|
4
|
+
/**
|
|
5
|
+
* @protected
|
|
6
|
+
* @return {void}
|
|
7
|
+
*/
|
|
8
|
+
_prepareForm() {
|
|
9
|
+
this.formCreator
|
|
10
|
+
.addLegend(this._('Video'))
|
|
11
|
+
.addTextInput('src', this._('URL'), {
|
|
12
|
+
pattern: '(https?|/).+',
|
|
13
|
+
placeholder: this._('Insert URL to video'),
|
|
14
|
+
required: 'required',
|
|
15
|
+
})
|
|
16
|
+
.addNumberInput('width', this._('Width'))
|
|
17
|
+
.addNumberInput('height', this._('Height'))
|
|
18
|
+
.addTextInput('id', this._('ID'));
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import Listener from '../base/Listener.js';
|
|
2
|
+
import TagName from '../base/TagName.js';
|
|
3
|
+
import Video from './Video.js';
|
|
4
|
+
|
|
5
|
+
export default class VideoListener extends Listener {
|
|
6
|
+
/**
|
|
7
|
+
* @param {Editor} editor
|
|
8
|
+
*/
|
|
9
|
+
constructor(editor) {
|
|
10
|
+
super(editor);
|
|
11
|
+
this.editor.root.addEventListener('sethtml', this);
|
|
12
|
+
this.editor.root.addEventListener('insertvideo', this);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @param {CustomEvent} event
|
|
17
|
+
* @param {HTMLElement} event.detail.element
|
|
18
|
+
* @return {void}
|
|
19
|
+
*/
|
|
20
|
+
sethtml({ detail: { element } }) {
|
|
21
|
+
Array.from(element.getElementsByTagName(TagName.VIDEO)).forEach((item) => this.#init(item));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* @param {CustomEvent} event
|
|
26
|
+
* @param {HTMLVideoElement} event.detail.element
|
|
27
|
+
* @return {void}
|
|
28
|
+
*/
|
|
29
|
+
insertvideo({ detail: { element } }) {
|
|
30
|
+
this.#init(element);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* @param {HTMLVideoElement} element
|
|
35
|
+
* @return {void}
|
|
36
|
+
*/
|
|
37
|
+
#init(element) {
|
|
38
|
+
const src = element.getAttribute('src');
|
|
39
|
+
|
|
40
|
+
if (!src) {
|
|
41
|
+
element.parentElement.removeChild(element);
|
|
42
|
+
} else {
|
|
43
|
+
element.setAttribute('src', this.editor.url(src));
|
|
44
|
+
element.controls = true;
|
|
45
|
+
this.editor.dom.wrap(element, TagName.FIGURE, { attributes: { class: Video.name } });
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|