@ckeditor/ckeditor5-heading 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/heading.js +2 -2
- package/package.json +25 -21
- package/src/heading.js +13 -96
- package/src/headingbuttonsui.js +54 -68
- package/src/headingcommand.js +51 -82
- package/src/headingediting.js +83 -104
- package/src/headingui.js +85 -99
- package/src/index.js +1 -3
- package/src/title.js +397 -570
- package/src/utils.js +19 -30
- package/theme/heading.css +1 -1
package/src/headingediting.js
CHANGED
|
@@ -1,122 +1,101 @@
|
|
|
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
5
|
/**
|
|
7
6
|
* @module heading/headingediting
|
|
8
7
|
*/
|
|
9
|
-
|
|
10
8
|
import { Plugin } from 'ckeditor5/src/core';
|
|
11
9
|
import { Paragraph } from 'ckeditor5/src/paragraph';
|
|
12
10
|
import { priorities } from 'ckeditor5/src/utils';
|
|
13
|
-
|
|
14
11
|
import HeadingCommand from './headingcommand';
|
|
15
|
-
|
|
16
12
|
const defaultModelElement = 'paragraph';
|
|
17
|
-
|
|
18
13
|
/**
|
|
19
14
|
* The headings engine feature. It handles switching between block formats – headings and paragraph.
|
|
20
15
|
* This class represents the engine part of the heading feature. See also {@link module:heading/heading~Heading}.
|
|
21
16
|
* It introduces `heading1`-`headingN` commands which allow to convert paragraphs into headings.
|
|
22
|
-
*
|
|
23
|
-
* @extends module:core/plugin~Plugin
|
|
24
17
|
*/
|
|
25
18
|
export default class HeadingEditing extends Plugin {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
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
|
-
* Adds default conversion for `h1` -> `heading1` with a low priority.
|
|
109
|
-
*
|
|
110
|
-
* @private
|
|
111
|
-
* @param {module:core/editor/editor~Editor} editor Editor instance on which to add the `h1` conversion.
|
|
112
|
-
*/
|
|
113
|
-
_addDefaultH1Conversion( editor ) {
|
|
114
|
-
editor.conversion.for( 'upcast' ).elementToElement( {
|
|
115
|
-
model: 'heading1',
|
|
116
|
-
view: 'h1',
|
|
117
|
-
// With a `low` priority, `paragraph` plugin autoparagraphing mechanism is executed. Make sure
|
|
118
|
-
// this listener is called before it. If not, `h1` will be transformed into a paragraph.
|
|
119
|
-
converterPriority: priorities.get( 'low' ) + 1
|
|
120
|
-
} );
|
|
121
|
-
}
|
|
19
|
+
/**
|
|
20
|
+
* @inheritDoc
|
|
21
|
+
*/
|
|
22
|
+
static get pluginName() {
|
|
23
|
+
return 'HeadingEditing';
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* @inheritDoc
|
|
27
|
+
*/
|
|
28
|
+
constructor(editor) {
|
|
29
|
+
super(editor);
|
|
30
|
+
editor.config.define('heading', {
|
|
31
|
+
options: [
|
|
32
|
+
{ model: 'paragraph', title: 'Paragraph', class: 'ck-heading_paragraph' },
|
|
33
|
+
{ model: 'heading1', view: 'h2', title: 'Heading 1', class: 'ck-heading_heading1' },
|
|
34
|
+
{ model: 'heading2', view: 'h3', title: 'Heading 2', class: 'ck-heading_heading2' },
|
|
35
|
+
{ model: 'heading3', view: 'h4', title: 'Heading 3', class: 'ck-heading_heading3' }
|
|
36
|
+
]
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* @inheritDoc
|
|
41
|
+
*/
|
|
42
|
+
static get requires() {
|
|
43
|
+
return [Paragraph];
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* @inheritDoc
|
|
47
|
+
*/
|
|
48
|
+
init() {
|
|
49
|
+
const editor = this.editor;
|
|
50
|
+
const options = editor.config.get('heading.options');
|
|
51
|
+
const modelElements = [];
|
|
52
|
+
for (const option of options) {
|
|
53
|
+
// Skip paragraph - it is defined in required Paragraph feature.
|
|
54
|
+
if (option.model === 'paragraph') {
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
// Schema.
|
|
58
|
+
editor.model.schema.register(option.model, {
|
|
59
|
+
inheritAllFrom: '$block'
|
|
60
|
+
});
|
|
61
|
+
editor.conversion.elementToElement(option);
|
|
62
|
+
modelElements.push(option.model);
|
|
63
|
+
}
|
|
64
|
+
this._addDefaultH1Conversion(editor);
|
|
65
|
+
// Register the heading command for this option.
|
|
66
|
+
editor.commands.add('heading', new HeadingCommand(editor, modelElements));
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* @inheritDoc
|
|
70
|
+
*/
|
|
71
|
+
afterInit() {
|
|
72
|
+
// If the enter command is added to the editor, alter its behavior.
|
|
73
|
+
// Enter at the end of a heading element should create a paragraph.
|
|
74
|
+
const editor = this.editor;
|
|
75
|
+
const enterCommand = editor.commands.get('enter');
|
|
76
|
+
const options = editor.config.get('heading.options');
|
|
77
|
+
if (enterCommand) {
|
|
78
|
+
this.listenTo(enterCommand, 'afterExecute', (evt, data) => {
|
|
79
|
+
const positionParent = editor.model.document.selection.getFirstPosition().parent;
|
|
80
|
+
const isHeading = options.some(option => positionParent.is('element', option.model));
|
|
81
|
+
if (isHeading && !positionParent.is('element', defaultModelElement) && positionParent.childCount === 0) {
|
|
82
|
+
data.writer.rename(positionParent, defaultModelElement);
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Adds default conversion for `h1` -> `heading1` with a low priority.
|
|
89
|
+
*
|
|
90
|
+
* @param editor Editor instance on which to add the `h1` conversion.
|
|
91
|
+
*/
|
|
92
|
+
_addDefaultH1Conversion(editor) {
|
|
93
|
+
editor.conversion.for('upcast').elementToElement({
|
|
94
|
+
model: 'heading1',
|
|
95
|
+
view: 'h1',
|
|
96
|
+
// With a `low` priority, `paragraph` plugin autoparagraphing mechanism is executed. Make sure
|
|
97
|
+
// this listener is called before it. If not, `h1` will be transformed into a paragraph.
|
|
98
|
+
converterPriority: priorities.get('low') + 1
|
|
99
|
+
});
|
|
100
|
+
}
|
|
122
101
|
}
|
package/src/headingui.js
CHANGED
|
@@ -1,115 +1,101 @@
|
|
|
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
5
|
/**
|
|
7
6
|
* @module heading/headingui
|
|
8
7
|
*/
|
|
9
|
-
|
|
10
8
|
import { Plugin } from 'ckeditor5/src/core';
|
|
11
9
|
import { Model, createDropdown, addListToDropdown } from 'ckeditor5/src/ui';
|
|
12
10
|
import { Collection } from 'ckeditor5/src/utils';
|
|
13
|
-
|
|
14
11
|
import { getLocalizedOptions } from './utils';
|
|
15
|
-
|
|
16
12
|
import '../theme/heading.css';
|
|
17
|
-
|
|
18
13
|
/**
|
|
19
14
|
* The headings UI feature. It introduces the `headings` dropdown.
|
|
20
|
-
*
|
|
21
|
-
* @extends module:core/plugin~Plugin
|
|
22
15
|
*/
|
|
23
16
|
export default class HeadingUI extends Plugin {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
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
|
-
editor.execute( evt.source.commandName, evt.source.commandValue ? { value: evt.source.commandValue } : undefined );
|
|
109
|
-
editor.editing.view.focus();
|
|
110
|
-
} );
|
|
111
|
-
|
|
112
|
-
return dropdownView;
|
|
113
|
-
} );
|
|
114
|
-
}
|
|
17
|
+
/**
|
|
18
|
+
* @inheritDoc
|
|
19
|
+
*/
|
|
20
|
+
static get pluginName() {
|
|
21
|
+
return 'HeadingUI';
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* @inheritDoc
|
|
25
|
+
*/
|
|
26
|
+
init() {
|
|
27
|
+
const editor = this.editor;
|
|
28
|
+
const t = editor.t;
|
|
29
|
+
const options = getLocalizedOptions(editor);
|
|
30
|
+
const defaultTitle = t('Choose heading');
|
|
31
|
+
const dropdownTooltip = t('Heading');
|
|
32
|
+
// Register UI component.
|
|
33
|
+
editor.ui.componentFactory.add('heading', locale => {
|
|
34
|
+
const titles = {};
|
|
35
|
+
const itemDefinitions = new Collection();
|
|
36
|
+
const headingCommand = editor.commands.get('heading');
|
|
37
|
+
const paragraphCommand = editor.commands.get('paragraph');
|
|
38
|
+
const commands = [headingCommand];
|
|
39
|
+
for (const option of options) {
|
|
40
|
+
const def = {
|
|
41
|
+
type: 'button',
|
|
42
|
+
model: new Model({
|
|
43
|
+
label: option.title,
|
|
44
|
+
class: option.class,
|
|
45
|
+
withText: true
|
|
46
|
+
})
|
|
47
|
+
};
|
|
48
|
+
if (option.model === 'paragraph') {
|
|
49
|
+
def.model.bind('isOn').to(paragraphCommand, 'value');
|
|
50
|
+
def.model.set('commandName', 'paragraph');
|
|
51
|
+
commands.push(paragraphCommand);
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
def.model.bind('isOn').to(headingCommand, 'value', value => value === option.model);
|
|
55
|
+
def.model.set({
|
|
56
|
+
commandName: 'heading',
|
|
57
|
+
commandValue: option.model
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
// Add the option to the collection.
|
|
61
|
+
itemDefinitions.add(def);
|
|
62
|
+
titles[option.model] = option.title;
|
|
63
|
+
}
|
|
64
|
+
const dropdownView = createDropdown(locale);
|
|
65
|
+
addListToDropdown(dropdownView, itemDefinitions);
|
|
66
|
+
dropdownView.buttonView.set({
|
|
67
|
+
isOn: false,
|
|
68
|
+
withText: true,
|
|
69
|
+
tooltip: dropdownTooltip
|
|
70
|
+
});
|
|
71
|
+
dropdownView.extendTemplate({
|
|
72
|
+
attributes: {
|
|
73
|
+
class: [
|
|
74
|
+
'ck-heading-dropdown'
|
|
75
|
+
]
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
dropdownView.bind('isEnabled').toMany(commands, 'isEnabled', (...areEnabled) => {
|
|
79
|
+
return areEnabled.some(isEnabled => isEnabled);
|
|
80
|
+
});
|
|
81
|
+
dropdownView.buttonView.bind('label').to(headingCommand, 'value', paragraphCommand, 'value', (value, para) => {
|
|
82
|
+
const whichModel = value || para && 'paragraph';
|
|
83
|
+
if (typeof whichModel === 'boolean') {
|
|
84
|
+
return defaultTitle;
|
|
85
|
+
}
|
|
86
|
+
// If none of the commands is active, display default title.
|
|
87
|
+
if (!titles[whichModel]) {
|
|
88
|
+
return defaultTitle;
|
|
89
|
+
}
|
|
90
|
+
return titles[whichModel];
|
|
91
|
+
});
|
|
92
|
+
// Execute command when an item from the dropdown is selected.
|
|
93
|
+
this.listenTo(dropdownView, 'execute', evt => {
|
|
94
|
+
const { commandName, commandValue } = evt.source;
|
|
95
|
+
editor.execute(commandName, commandValue ? { value: commandValue } : undefined);
|
|
96
|
+
editor.editing.view.focus();
|
|
97
|
+
});
|
|
98
|
+
return dropdownView;
|
|
99
|
+
});
|
|
100
|
+
}
|
|
115
101
|
}
|
package/src/index.js
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
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
5
|
/**
|
|
7
6
|
* @module heading
|
|
8
7
|
*/
|
|
9
|
-
|
|
10
8
|
export { default as Heading } from './heading';
|
|
11
9
|
export { default as HeadingEditing } from './headingediting';
|
|
12
10
|
export { default as HeadingUI } from './headingui';
|