@ckeditor/ckeditor5-html-support 45.2.1 → 46.0.0-alpha.1
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/build/html-support.js +2 -2
- package/dist/index.js +110 -54
- package/dist/index.js.map +1 -1
- package/package.json +13 -12
- package/src/converters.d.ts +21 -11
- package/src/converters.js +10 -0
- package/src/datafilter.d.ts +6 -6
- package/src/datafilter.js +7 -5
- package/src/dataschema.d.ts +14 -14
- package/src/dataschema.js +2 -2
- package/src/emptyblock.d.ts +1 -1
- package/src/emptyblock.js +1 -1
- package/src/fullpage.d.ts +1 -1
- package/src/fullpage.js +4 -4
- package/src/generalhtmlsupport.d.ts +20 -16
- package/src/generalhtmlsupport.js +21 -14
- package/src/generalhtmlsupportconfig.d.ts +5 -5
- package/src/htmlcomment.d.ts +6 -6
- package/src/htmlcomment.js +1 -1
- package/src/htmlpagedataprocessor.d.ts +1 -1
- package/src/htmlpagedataprocessor.js +3 -3
- package/src/index.d.ts +23 -19
- package/src/index.js +11 -7
- package/src/integrations/codeblock.d.ts +2 -2
- package/src/integrations/codeblock.js +2 -2
- package/src/integrations/customelement.d.ts +3 -3
- package/src/integrations/customelement.js +7 -6
- package/src/integrations/dualcontent.d.ts +6 -5
- package/src/integrations/dualcontent.js +6 -5
- package/src/integrations/heading.d.ts +2 -2
- package/src/integrations/heading.js +2 -2
- package/src/integrations/horizontalline.d.ts +2 -2
- package/src/integrations/horizontalline.js +2 -2
- package/src/integrations/image.d.ts +2 -2
- package/src/integrations/image.js +2 -2
- package/src/integrations/integrationutils.d.ts +2 -2
- package/src/integrations/list.d.ts +2 -2
- package/src/integrations/list.js +2 -2
- package/src/integrations/mediaembed.d.ts +2 -2
- package/src/integrations/mediaembed.js +3 -3
- package/src/integrations/script.d.ts +2 -2
- package/src/integrations/script.js +4 -3
- package/src/integrations/style.d.ts +2 -2
- package/src/integrations/style.js +4 -3
- package/src/integrations/table.d.ts +2 -2
- package/src/integrations/table.js +2 -2
- package/src/schemadefinitions.d.ts +49 -5
- package/src/schemadefinitions.js +50 -43
- package/src/utils.d.ts +26 -7
- package/src/utils.js +30 -0
package/dist/index.js
CHANGED
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { Plugin } from '@ckeditor/ckeditor5-core/dist/index.js';
|
|
6
6
|
import { toArray, priorities, CKEditorError, isValidAttributeName, uid, logWarning, global } from '@ckeditor/ckeditor5-utils/dist/index.js';
|
|
7
|
-
import { Matcher, StylesMap,
|
|
7
|
+
import { Matcher, StylesMap, ViewUpcastWriter, HtmlDataProcessor } from '@ckeditor/ckeditor5-engine/dist/index.js';
|
|
8
8
|
import { toWidget, Widget } from '@ckeditor/ckeditor5-widget/dist/index.js';
|
|
9
|
-
import {
|
|
9
|
+
import { cloneDeep, startCase, mergeWith, isPlainObject, isEqual } from 'es-toolkit/compat';
|
|
10
10
|
import { Enter } from '@ckeditor/ckeditor5-enter/dist/index.js';
|
|
11
11
|
|
|
12
12
|
/**
|
|
@@ -16,6 +16,7 @@ import { Enter } from '@ckeditor/ckeditor5-enter/dist/index.js';
|
|
|
16
16
|
* @param oldViewAttributes The previous GHS attribute value.
|
|
17
17
|
* @param newViewAttributes The current GHS attribute value.
|
|
18
18
|
* @param viewElement The view element to update.
|
|
19
|
+
* @internal
|
|
19
20
|
*/ function updateViewAttributes(writer, oldViewAttributes, newViewAttributes, viewElement) {
|
|
20
21
|
if (oldViewAttributes) {
|
|
21
22
|
removeViewAttributes(writer, oldViewAttributes, viewElement);
|
|
@@ -30,6 +31,7 @@ import { Enter } from '@ckeditor/ckeditor5-enter/dist/index.js';
|
|
|
30
31
|
* @param writer The view writer.
|
|
31
32
|
* @param viewAttributes The GHS attribute value.
|
|
32
33
|
* @param viewElement The view element to update.
|
|
34
|
+
* @internal
|
|
33
35
|
*/ function setViewAttributes(writer, viewAttributes, viewElement) {
|
|
34
36
|
if (viewAttributes.attributes) {
|
|
35
37
|
for (const [key, value] of Object.entries(viewAttributes.attributes)){
|
|
@@ -49,6 +51,7 @@ import { Enter } from '@ckeditor/ckeditor5-enter/dist/index.js';
|
|
|
49
51
|
* @param writer The view writer.
|
|
50
52
|
* @param viewAttributes The GHS attribute value.
|
|
51
53
|
* @param viewElement The view element to update.
|
|
54
|
+
* @internal
|
|
52
55
|
*/ function removeViewAttributes(writer, viewAttributes, viewElement) {
|
|
53
56
|
if (viewAttributes.attributes) {
|
|
54
57
|
for (const [key] of Object.entries(viewAttributes.attributes)){
|
|
@@ -66,6 +69,8 @@ import { Enter } from '@ckeditor/ckeditor5-enter/dist/index.js';
|
|
|
66
69
|
}
|
|
67
70
|
/**
|
|
68
71
|
* Merges view element attribute objects.
|
|
72
|
+
*
|
|
73
|
+
* @internal
|
|
69
74
|
*/ function mergeViewElementAttributes(target, source) {
|
|
70
75
|
const result = cloneDeep(target);
|
|
71
76
|
let key = 'attributes';
|
|
@@ -129,16 +134,43 @@ function modifyGhsAttribute(writer, item, ghsAttributeName, subject, callback) {
|
|
|
129
134
|
}
|
|
130
135
|
}
|
|
131
136
|
}
|
|
137
|
+
/**
|
|
138
|
+
* Strips the `styles`, and `classes` keys from the GHS attribute value on the given item.
|
|
139
|
+
*
|
|
140
|
+
* @internal
|
|
141
|
+
*/ function removeFormatting(ghsAttributeName, itemRange, writer) {
|
|
142
|
+
for (const item of itemRange.getItems({
|
|
143
|
+
shallow: true
|
|
144
|
+
})){
|
|
145
|
+
const value = item.getAttribute(ghsAttributeName);
|
|
146
|
+
// Copy only attributes to the new attribute value.
|
|
147
|
+
if (value && value.attributes && Object.keys(value.attributes).length) {
|
|
148
|
+
// But reset the GHS attribute only when there is anything more than just attributes.
|
|
149
|
+
if (Object.keys(value).length > 1) {
|
|
150
|
+
writer.setAttribute(ghsAttributeName, {
|
|
151
|
+
attributes: value.attributes
|
|
152
|
+
}, item);
|
|
153
|
+
}
|
|
154
|
+
} else {
|
|
155
|
+
// There are no attributes, so remove the GHS attribute completely.
|
|
156
|
+
writer.removeAttribute(ghsAttributeName, item);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
132
160
|
/**
|
|
133
161
|
* Transforms passed string to PascalCase format. Examples:
|
|
134
162
|
* * `div` => `Div`
|
|
135
163
|
* * `h1` => `H1`
|
|
136
164
|
* * `table` => `Table`
|
|
165
|
+
*
|
|
166
|
+
* @internal
|
|
137
167
|
*/ function toPascalCase(data) {
|
|
138
168
|
return startCase(data).replace(/ /g, '');
|
|
139
169
|
}
|
|
140
170
|
/**
|
|
141
171
|
* Returns the attribute name of the model element that holds raw HTML attributes.
|
|
172
|
+
*
|
|
173
|
+
* @internal
|
|
142
174
|
*/ function getHtmlAttributeName(viewElementName) {
|
|
143
175
|
return `html${toPascalCase(viewElementName)}Attributes`;
|
|
144
176
|
}
|
|
@@ -149,6 +181,7 @@ function modifyGhsAttribute(writer, item, ghsAttributeName, subject, callback) {
|
|
|
149
181
|
* Preserves object element content in `htmlContent` attribute.
|
|
150
182
|
*
|
|
151
183
|
* @returns Returns a conversion callback.
|
|
184
|
+
* @internal
|
|
152
185
|
*/ function viewToModelObjectConverter({ model: modelName }) {
|
|
153
186
|
return (viewElement, conversionApi)=>{
|
|
154
187
|
// Let's keep element HTML and its attributes, so we can rebuild element in downcast conversions.
|
|
@@ -161,6 +194,7 @@ function modifyGhsAttribute(writer, item, ghsAttributeName, subject, callback) {
|
|
|
161
194
|
* Conversion helper converting an object element to an HTML object widget.
|
|
162
195
|
*
|
|
163
196
|
* @returns Returns a conversion callback.
|
|
197
|
+
* @internal
|
|
164
198
|
*/ function toObjectWidgetConverter(editor, { view: viewName, isInline }) {
|
|
165
199
|
const t = editor.t;
|
|
166
200
|
return (modelElement, { writer })=>{
|
|
@@ -184,6 +218,8 @@ function modifyGhsAttribute(writer, item, ghsAttributeName, subject, callback) {
|
|
|
184
218
|
}
|
|
185
219
|
/**
|
|
186
220
|
* Creates object view element from the given model element.
|
|
221
|
+
*
|
|
222
|
+
* @internal
|
|
187
223
|
*/ function createObjectView(viewName, modelElement, writer) {
|
|
188
224
|
return writer.createRawElement(viewName, null, (domElement, domConverter)=>{
|
|
189
225
|
domConverter.setContentOf(domElement, modelElement.getAttribute('htmlContent'));
|
|
@@ -193,6 +229,7 @@ function modifyGhsAttribute(writer, item, ghsAttributeName, subject, callback) {
|
|
|
193
229
|
* View-to-attribute conversion helper preserving inline element attributes on `$text`.
|
|
194
230
|
*
|
|
195
231
|
* @returns Returns a conversion callback.
|
|
232
|
+
* @internal
|
|
196
233
|
*/ function viewToAttributeInlineConverter({ view: viewName, model: attributeKey, allowEmpty }, dataFilter) {
|
|
197
234
|
return (dispatcher)=>{
|
|
198
235
|
dispatcher.on(`element:${viewName}`, (evt, data, conversionApi)=>{
|
|
@@ -247,6 +284,8 @@ function modifyGhsAttribute(writer, item, ghsAttributeName, subject, callback) {
|
|
|
247
284
|
}
|
|
248
285
|
/**
|
|
249
286
|
* Conversion helper converting an empty inline model element to an HTML element or widget.
|
|
287
|
+
*
|
|
288
|
+
* @internal
|
|
250
289
|
*/ function emptyInlineModelElementToViewConverter({ model: attributeKey, view: viewName }, asWidget) {
|
|
251
290
|
return (item, { writer, consumable })=>{
|
|
252
291
|
if (!item.hasAttribute(attributeKey)) {
|
|
@@ -264,6 +303,7 @@ function modifyGhsAttribute(writer, item, ghsAttributeName, subject, callback) {
|
|
|
264
303
|
* Attribute-to-view conversion helper applying attributes to view element preserved on `$text`.
|
|
265
304
|
*
|
|
266
305
|
* @returns Returns a conversion callback.
|
|
306
|
+
* @internal
|
|
267
307
|
*/ function attributeToViewInlineConverter({ priority, view: viewName }) {
|
|
268
308
|
return (attributeValue, conversionApi)=>{
|
|
269
309
|
if (!attributeValue) {
|
|
@@ -283,6 +323,7 @@ function modifyGhsAttribute(writer, item, ghsAttributeName, subject, callback) {
|
|
|
283
323
|
* All matched attributes will be preserved on `html*Attributes` attribute.
|
|
284
324
|
*
|
|
285
325
|
* @returns Returns a conversion callback.
|
|
326
|
+
* @internal
|
|
286
327
|
*/ function viewToModelBlockAttributeConverter({ view: viewName }, dataFilter) {
|
|
287
328
|
return (dispatcher)=>{
|
|
288
329
|
dispatcher.on(`element:${viewName}`, (evt, data, conversionApi)=>{
|
|
@@ -308,6 +349,7 @@ function modifyGhsAttribute(writer, item, ghsAttributeName, subject, callback) {
|
|
|
308
349
|
* for block elements.
|
|
309
350
|
*
|
|
310
351
|
* @returns Returns a conversion callback.
|
|
352
|
+
* @internal
|
|
311
353
|
*/ function modelToViewBlockAttributeConverter({ view: viewName, model: modelName }) {
|
|
312
354
|
return (dispatcher)=>{
|
|
313
355
|
dispatcher.on(`attribute:${getHtmlAttributeName(viewName)}:${modelName}`, (evt, data, conversionApi)=>{
|
|
@@ -327,48 +369,51 @@ function modifyGhsAttribute(writer, item, ghsAttributeName, subject, callback) {
|
|
|
327
369
|
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
328
370
|
*/ /**
|
|
329
371
|
* @module html-support/schemadefinitions
|
|
330
|
-
*/
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
+
*/ /**
|
|
373
|
+
* Skipped elements due to HTML deprecation:
|
|
374
|
+
* * noframes (not sure if we should provide support for this element. CKE4 is not supporting frameset and frame,
|
|
375
|
+
* but it will unpack <frameset><noframes>foobar</noframes></frameset> to <noframes>foobar</noframes>, so there
|
|
376
|
+
* may be some content loss. Although using noframes as a standalone element seems invalid)
|
|
377
|
+
* * keygen (this one is also empty)
|
|
378
|
+
* * applet (support is limited mostly to old IE)
|
|
379
|
+
* * basefont (this one is also empty)
|
|
380
|
+
* * isindex (basically no support for modern browsers at all)
|
|
381
|
+
*
|
|
382
|
+
* Skipped elements due to lack empty element support:
|
|
383
|
+
* * hr
|
|
384
|
+
* * area
|
|
385
|
+
* * br
|
|
386
|
+
* * command
|
|
387
|
+
* * map
|
|
388
|
+
* * wbr
|
|
389
|
+
* * colgroup -> col
|
|
390
|
+
*
|
|
391
|
+
* Skipped elements due to complexity:
|
|
392
|
+
* * datalist with option elements used as a data source for input[list] element
|
|
393
|
+
*
|
|
394
|
+
* Skipped elements as they are handled as an object content:
|
|
395
|
+
* * track
|
|
396
|
+
* * source
|
|
397
|
+
* * option
|
|
398
|
+
* * param
|
|
399
|
+
* * optgroup
|
|
400
|
+
*
|
|
401
|
+
* Skipped full page HTML elements:
|
|
402
|
+
* * body
|
|
403
|
+
* * html
|
|
404
|
+
* * title
|
|
405
|
+
* * head
|
|
406
|
+
* * meta
|
|
407
|
+
* * link
|
|
408
|
+
* * etc...
|
|
409
|
+
*
|
|
410
|
+
* Skipped hidden elements:
|
|
411
|
+
* noscript
|
|
412
|
+
*
|
|
413
|
+
* When adding elements to this list, update the feature guide listing, too.
|
|
414
|
+
*
|
|
415
|
+
* @internal
|
|
416
|
+
*/ const defaultConfig = {
|
|
372
417
|
block: [
|
|
373
418
|
// Existing features.
|
|
374
419
|
{
|
|
@@ -1029,7 +1074,10 @@ var defaultConfig = {
|
|
|
1029
1074
|
model: 'htmlA',
|
|
1030
1075
|
view: 'a',
|
|
1031
1076
|
priority: 5,
|
|
1032
|
-
coupledAttribute: 'linkHref'
|
|
1077
|
+
coupledAttribute: 'linkHref',
|
|
1078
|
+
attributeProperties: {
|
|
1079
|
+
isFormatting: true
|
|
1080
|
+
}
|
|
1033
1081
|
},
|
|
1034
1082
|
{
|
|
1035
1083
|
model: 'htmlStrong',
|
|
@@ -2075,7 +2123,7 @@ var defaultConfig = {
|
|
|
2075
2123
|
const schema = editor.model.schema;
|
|
2076
2124
|
const conversion = editor.conversion;
|
|
2077
2125
|
const attributeKey = definition.model;
|
|
2078
|
-
// This element is stored in the model as an attribute on a block element, for example
|
|
2126
|
+
// This element is stored in the model as an attribute on a block element, for example Lists.
|
|
2079
2127
|
if (definition.appliesToBlock) {
|
|
2080
2128
|
return;
|
|
2081
2129
|
}
|
|
@@ -2431,9 +2479,10 @@ var defaultConfig = {
|
|
|
2431
2479
|
* * model element HTML is semantically correct and easier to work with.
|
|
2432
2480
|
*
|
|
2433
2481
|
* If element contains any block element, it will be treated as a sectioning element and registered using
|
|
2434
|
-
* {@link module:html-support/dataschema~
|
|
2435
|
-
* {@link module:html-support/dataschema~
|
|
2436
|
-
* Otherwise, it will be registered under
|
|
2482
|
+
* {@link module:html-support/dataschema~HtmlSupportDataSchemaDefinition#model} and
|
|
2483
|
+
* {@link module:html-support/dataschema~HtmlSupportDataSchemaDefinition#modelSchema} in editor schema.
|
|
2484
|
+
* Otherwise, it will be registered under
|
|
2485
|
+
* {@link module:html-support/dataschema~HtmlSupportDataSchemaBlockElementDefinition#paragraphLikeModel} model
|
|
2437
2486
|
* name with model schema accepting only inline content (inheriting from `$block`).
|
|
2438
2487
|
*/ class DualContentModelElementSupport extends Plugin {
|
|
2439
2488
|
/**
|
|
@@ -3567,8 +3616,9 @@ const STYLE_ATTRIBUTES_TO_PROPAGATE = [
|
|
|
3567
3616
|
if (viewElement.is('element', 'template') && viewElement.getCustomProperty('$rawContent')) {
|
|
3568
3617
|
htmlContent = viewElement.getCustomProperty('$rawContent');
|
|
3569
3618
|
} else {
|
|
3570
|
-
// Store the whole element in the attribute so that
|
|
3571
|
-
|
|
3619
|
+
// Store the whole element in the attribute so that ViewDomConverter
|
|
3620
|
+
// will be able to use the pre like element context.
|
|
3621
|
+
const viewWriter = new ViewUpcastWriter(viewElement.document);
|
|
3572
3622
|
const documentFragment = viewWriter.createDocumentFragment(viewElement);
|
|
3573
3623
|
const domFragment = editor.data.htmlProcessor.domConverter.viewToDom(documentFragment);
|
|
3574
3624
|
const domElement = domFragment.firstChild;
|
|
@@ -3690,6 +3740,12 @@ const STYLE_ATTRIBUTES_TO_PROPAGATE = [
|
|
|
3690
3740
|
dataFilter.loadAllowedConfig(editor.config.get('htmlSupport.allow') || []);
|
|
3691
3741
|
dataFilter.loadDisallowedConfig(editor.config.get('htmlSupport.disallow') || []);
|
|
3692
3742
|
}
|
|
3743
|
+
/**
|
|
3744
|
+
* @inheritDoc
|
|
3745
|
+
*/ afterInit() {
|
|
3746
|
+
const removeFormatCommand = this.editor.commands.get('removeFormat');
|
|
3747
|
+
removeFormatCommand?.registerCustomAttribute((attributeName)=>attributeName.startsWith('html') && attributeName.endsWith('Attributes'), removeFormatting);
|
|
3748
|
+
}
|
|
3693
3749
|
/**
|
|
3694
3750
|
* Returns a GHS model attribute name related to a given view element name.
|
|
3695
3751
|
*
|
|
@@ -4095,7 +4151,7 @@ const STYLE_ATTRIBUTES_TO_PROPAGATE = [
|
|
|
4095
4151
|
const viewFragment = this.domConverter.domToView(domFragment, {
|
|
4096
4152
|
skipComments: this.skipComments
|
|
4097
4153
|
});
|
|
4098
|
-
const writer = new
|
|
4154
|
+
const writer = new ViewUpcastWriter(viewFragment.document);
|
|
4099
4155
|
// Using the DOM document with body content extracted as a skeleton of the page.
|
|
4100
4156
|
writer.setCustomProperty('$fullPageDocument', domFragment.ownerDocument.documentElement.outerHTML, viewFragment);
|
|
4101
4157
|
// List of `<style>` elements extracted from document's `<head>` element.
|
|
@@ -4206,7 +4262,7 @@ const STYLE_ATTRIBUTES_TO_PROPAGATE = [
|
|
|
4206
4262
|
if (!root.hasAttribute('$fullPageDocument')) {
|
|
4207
4263
|
return;
|
|
4208
4264
|
}
|
|
4209
|
-
const writer = new
|
|
4265
|
+
const writer = new ViewUpcastWriter(viewFragment.document);
|
|
4210
4266
|
for (const name of properties){
|
|
4211
4267
|
const value = root.getAttribute(name);
|
|
4212
4268
|
if (value) {
|
|
@@ -4439,5 +4495,5 @@ const EMPTY_BLOCK_MODEL_ATTRIBUTE = 'htmlEmptyBlock';
|
|
|
4439
4495
|
};
|
|
4440
4496
|
}
|
|
4441
4497
|
|
|
4442
|
-
export { DataFilter, DataSchema, EmptyBlock, FullPage, GeneralHtmlSupport, HtmlComment, HtmlPageDataProcessor };
|
|
4498
|
+
export { DataFilter, DataSchema, EmptyBlock, FullPage, GeneralHtmlSupport, HtmlComment, HtmlPageDataProcessor, defaultConfig as _HTML_SUPPORT_SCHEMA_DEFINITIONS, attributeToViewInlineConverter as _attributeToInlineHtmlSupportConverter, createObjectView as _createObjectHtmlSupportView, emptyInlineModelElementToViewConverter as _emptyInlineModelElementToViewHtmlSupportConverter, getHtmlAttributeName as _getHtmlSupportAttributeName, getDescendantElement as _getHtmlSupportDescendantElement, mergeViewElementAttributes as _mergeHtmlSupportViewElementAttributes, modelToViewBlockAttributeConverter as _modelToViewBlockAttributeHtmlSupportConverter, modifyGhsAttribute as _modifyHtmlSupportGhsAttribute, removeViewAttributes as _removeHtmlSupportViewAttributes, setViewAttributes as _setHtmlSupportViewAttributes, toPascalCase as _toHtmlSupportPascalCase, toObjectWidgetConverter as _toObjectWidgetHtmlSupportConverter, updateViewAttributes as _updateHtmlSupportViewAttributes, viewToAttributeInlineConverter as _viewToAttributeInlineHtmlSupportConverter, viewToModelBlockAttributeConverter as _viewToModelBlockAttributeHtmlSupportConverter, viewToModelObjectConverter as _viewToModelObjectContentHtmlSupportConverter };
|
|
4443
4499
|
//# sourceMappingURL=index.js.map
|