@ckeditor/ckeditor5-html-support 47.6.0-alpha.8 → 47.6.0-alpha.9

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ckeditor/ckeditor5-html-support",
3
- "version": "47.6.0-alpha.8",
3
+ "version": "47.6.0-alpha.9",
4
4
  "description": "HTML Support feature for CKEditor 5.",
5
5
  "keywords": [
6
6
  "ckeditor",
@@ -17,17 +17,17 @@
17
17
  "type": "module",
18
18
  "main": "src/index.js",
19
19
  "dependencies": {
20
- "@ckeditor/ckeditor5-core": "47.6.0-alpha.8",
21
- "@ckeditor/ckeditor5-engine": "47.6.0-alpha.8",
22
- "@ckeditor/ckeditor5-enter": "47.6.0-alpha.8",
23
- "@ckeditor/ckeditor5-heading": "47.6.0-alpha.8",
24
- "@ckeditor/ckeditor5-image": "47.6.0-alpha.8",
25
- "@ckeditor/ckeditor5-list": "47.6.0-alpha.8",
26
- "@ckeditor/ckeditor5-remove-format": "47.6.0-alpha.8",
27
- "@ckeditor/ckeditor5-table": "47.6.0-alpha.8",
28
- "@ckeditor/ckeditor5-utils": "47.6.0-alpha.8",
29
- "@ckeditor/ckeditor5-widget": "47.6.0-alpha.8",
30
- "ckeditor5": "47.6.0-alpha.8",
20
+ "@ckeditor/ckeditor5-core": "47.6.0-alpha.9",
21
+ "@ckeditor/ckeditor5-engine": "47.6.0-alpha.9",
22
+ "@ckeditor/ckeditor5-enter": "47.6.0-alpha.9",
23
+ "@ckeditor/ckeditor5-heading": "47.6.0-alpha.9",
24
+ "@ckeditor/ckeditor5-image": "47.6.0-alpha.9",
25
+ "@ckeditor/ckeditor5-list": "47.6.0-alpha.9",
26
+ "@ckeditor/ckeditor5-remove-format": "47.6.0-alpha.9",
27
+ "@ckeditor/ckeditor5-table": "47.6.0-alpha.9",
28
+ "@ckeditor/ckeditor5-utils": "47.6.0-alpha.9",
29
+ "@ckeditor/ckeditor5-widget": "47.6.0-alpha.9",
30
+ "ckeditor5": "47.6.0-alpha.9",
31
31
  "es-toolkit": "1.39.5"
32
32
  },
33
33
  "author": "CKSource (http://cksource.com/)",
@@ -18,6 +18,7 @@ import { TableElementSupport } from './integrations/table.js';
18
18
  import { StyleElementSupport } from './integrations/style.js';
19
19
  import { ListElementSupport } from './integrations/list.js';
20
20
  import { HorizontalLineElementSupport } from './integrations/horizontalline.js';
21
+ import { IframeElementSupport } from './integrations/iframe.js';
21
22
  import { CustomElementSupport } from './integrations/customelement.js';
22
23
  import type { ModelSelectable } from 'ckeditor5/src/engine.js';
23
24
  /**
@@ -38,7 +39,7 @@ export declare class GeneralHtmlSupport extends Plugin {
38
39
  /**
39
40
  * @inheritDoc
40
41
  */
41
- static get requires(): readonly [typeof DataFilter, typeof CodeBlockElementSupport, typeof DualContentModelElementSupport, typeof HeadingElementSupport, typeof ImageElementSupport, typeof MediaEmbedElementSupport, typeof ScriptElementSupport, typeof TableElementSupport, typeof StyleElementSupport, typeof ListElementSupport, typeof HorizontalLineElementSupport, typeof CustomElementSupport];
42
+ static get requires(): readonly [typeof DataFilter, typeof CodeBlockElementSupport, typeof DualContentModelElementSupport, typeof HeadingElementSupport, typeof ImageElementSupport, typeof MediaEmbedElementSupport, typeof ScriptElementSupport, typeof TableElementSupport, typeof StyleElementSupport, typeof ListElementSupport, typeof HorizontalLineElementSupport, typeof IframeElementSupport, typeof CustomElementSupport];
42
43
  /**
43
44
  * @inheritDoc
44
45
  */
@@ -18,6 +18,7 @@ import { TableElementSupport } from './integrations/table.js';
18
18
  import { StyleElementSupport } from './integrations/style.js';
19
19
  import { ListElementSupport } from './integrations/list.js';
20
20
  import { HorizontalLineElementSupport } from './integrations/horizontalline.js';
21
+ import { IframeElementSupport } from './integrations/iframe.js';
21
22
  import { CustomElementSupport } from './integrations/customelement.js';
22
23
  import { getHtmlAttributeName, modifyGhsAttribute, removeFormatting } from './utils.js';
23
24
  /**
@@ -55,6 +56,7 @@ export class GeneralHtmlSupport extends Plugin {
55
56
  StyleElementSupport,
56
57
  ListElementSupport,
57
58
  HorizontalLineElementSupport,
59
+ IframeElementSupport,
58
60
  CustomElementSupport
59
61
  ];
60
62
  }
@@ -102,6 +102,40 @@ export interface GeneralHtmlSupportConfig {
102
102
  * ```
103
103
  */
104
104
  fullPage?: GHSFullPageConfig;
105
+ /**
106
+ * Controls the `sandbox` attribute on iframe elements by specifying allowed sandbox flags.
107
+ *
108
+ * **Note:** This option only affects the editing view and does not modify the data output.
109
+ *
110
+ * When set to `false`:
111
+ *
112
+ * * The sandbox attribute will not be modified or added to iframe elements.
113
+ *
114
+ * When set to `true`:
115
+ *
116
+ * * All restrictions are enforced by adding an empty `sandbox` attribute to iframe elements.
117
+ *
118
+ * When set to an array of strings:
119
+ *
120
+ * * Only the specified sandbox flags will be preserved on iframe elements.
121
+ * * Any sandbox flags not in the list will be automatically removed.
122
+ * * If an empty array is provided, the `sandbox` attribute will be added with no flags (enforcing all restrictions).
123
+ *
124
+ * ```ts
125
+ * ClassicEditor
126
+ * .create( {
127
+ * htmlSupport: {
128
+ * // All restrictions are enforced (empty sandbox attribute).
129
+ * htmlIframeSandbox: true
130
+ * }
131
+ * } )
132
+ * .then( ... )
133
+ * .catch( ... );
134
+ * ```
135
+ *
136
+ * @default true
137
+ */
138
+ htmlIframeSandbox?: boolean | Array<string>;
105
139
  }
106
140
  /**
107
141
  * The configuration of the Full page editing feature.
package/src/index.d.ts CHANGED
@@ -23,6 +23,7 @@ export { MediaEmbedElementSupport } from './integrations/mediaembed.js';
23
23
  export { ScriptElementSupport } from './integrations/script.js';
24
24
  export { StyleElementSupport } from './integrations/style.js';
25
25
  export { TableElementSupport } from './integrations/table.js';
26
+ export { IframeElementSupport } from './integrations/iframe.js';
26
27
  export { HorizontalLineElementSupport } from './integrations/horizontalline.js';
27
28
  export { viewToModelObjectConverter as _viewToModelObjectContentHtmlSupportConverter, toObjectWidgetConverter as _toObjectWidgetHtmlSupportConverter, createObjectView as _createObjectHtmlSupportView, viewToAttributeInlineConverter as _viewToAttributeInlineHtmlSupportConverter, emptyInlineModelElementToViewConverter as _emptyInlineModelElementToViewHtmlSupportConverter, attributeToViewInlineConverter as _attributeToInlineHtmlSupportConverter, viewToModelBlockAttributeConverter as _viewToModelBlockAttributeHtmlSupportConverter, modelToViewBlockAttributeConverter as _modelToViewBlockAttributeHtmlSupportConverter } from './converters.js';
28
29
  export { getDescendantElement as _getHtmlSupportDescendantElement } from './integrations/integrationutils.js';
package/src/index.js CHANGED
@@ -22,6 +22,7 @@ export { MediaEmbedElementSupport } from './integrations/mediaembed.js';
22
22
  export { ScriptElementSupport } from './integrations/script.js';
23
23
  export { StyleElementSupport } from './integrations/style.js';
24
24
  export { TableElementSupport } from './integrations/table.js';
25
+ export { IframeElementSupport } from './integrations/iframe.js';
25
26
  export { HorizontalLineElementSupport } from './integrations/horizontalline.js';
26
27
  export { viewToModelObjectConverter as _viewToModelObjectContentHtmlSupportConverter, toObjectWidgetConverter as _toObjectWidgetHtmlSupportConverter, createObjectView as _createObjectHtmlSupportView, viewToAttributeInlineConverter as _viewToAttributeInlineHtmlSupportConverter, emptyInlineModelElementToViewConverter as _emptyInlineModelElementToViewHtmlSupportConverter, attributeToViewInlineConverter as _attributeToInlineHtmlSupportConverter, viewToModelBlockAttributeConverter as _viewToModelBlockAttributeHtmlSupportConverter, modelToViewBlockAttributeConverter as _modelToViewBlockAttributeHtmlSupportConverter } from './converters.js';
27
28
  export { getDescendantElement as _getHtmlSupportDescendantElement } from './integrations/integrationutils.js';
@@ -0,0 +1,31 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
4
+ */
5
+ import { Plugin } from 'ckeditor5/src/core.js';
6
+ import { DataFilter } from '../datafilter.js';
7
+ /**
8
+ * Provides the General HTML Support integration for `iframe` elements with a mandatory sandbox attribute.
9
+ */
10
+ export declare class IframeElementSupport extends Plugin {
11
+ /**
12
+ * @inheritDoc
13
+ */
14
+ static get requires(): readonly [typeof DataFilter];
15
+ /**
16
+ * @inheritDoc
17
+ */
18
+ static get pluginName(): "IframeElementSupport";
19
+ /**
20
+ * @inheritDoc
21
+ */
22
+ static get isOfficialPlugin(): true;
23
+ /**
24
+ * @inheritDoc
25
+ */
26
+ init(): void;
27
+ /**
28
+ * Sets up the conversion to enforce the sandbox attribute on `iframe` elements.
29
+ */
30
+ private _setupSandboxConversion;
31
+ }
@@ -0,0 +1,76 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
4
+ */
5
+ import { Plugin } from 'ckeditor5/src/core.js';
6
+ import { DataFilter } from '../datafilter.js';
7
+ /**
8
+ * Provides the General HTML Support integration for `iframe` elements with a mandatory sandbox attribute.
9
+ */
10
+ export class IframeElementSupport extends Plugin {
11
+ /**
12
+ * @inheritDoc
13
+ */
14
+ static get requires() {
15
+ return [DataFilter];
16
+ }
17
+ /**
18
+ * @inheritDoc
19
+ */
20
+ static get pluginName() {
21
+ return 'IframeElementSupport';
22
+ }
23
+ /**
24
+ * @inheritDoc
25
+ */
26
+ static get isOfficialPlugin() {
27
+ return true;
28
+ }
29
+ /**
30
+ * @inheritDoc
31
+ */
32
+ init() {
33
+ this.editor.config.define('htmlSupport.htmlIframeSandbox', true);
34
+ this._setupSandboxConversion();
35
+ }
36
+ /**
37
+ * Sets up the conversion to enforce the sandbox attribute on `iframe` elements.
38
+ */
39
+ _setupSandboxConversion() {
40
+ const { plugins, config, conversion } = this.editor;
41
+ const dataFilter = plugins.get(DataFilter);
42
+ const iframeSandboxConfig = config.get('htmlSupport.htmlIframeSandbox');
43
+ if (iframeSandboxConfig === false) {
44
+ return;
45
+ }
46
+ const allowedSandboxFlags = Array.isArray(iframeSandboxConfig) ? Array.from(iframeSandboxConfig) : [];
47
+ dataFilter.on('register:iframe', (_, definition) => {
48
+ conversion.for('editingDowncast').add((dispatcher) => {
49
+ dispatcher.on(`insert:${definition.model}`, (_, data, conversionApi) => {
50
+ const { mapper, writer } = conversionApi;
51
+ const viewElement = mapper.toViewElement(data.item);
52
+ for (const { item } of writer.createRangeOn(viewElement)) {
53
+ if (!item.is('element', 'iframe')) {
54
+ continue;
55
+ }
56
+ if (item.hasAttribute('sandbox')) {
57
+ // If there is an existing sandbox attribute, read and filter out disallowed values.
58
+ const sandboxValues = new Set();
59
+ const existingSandbox = item.getAttribute('sandbox');
60
+ for (const value of existingSandbox.trim().split(/\s+/)) {
61
+ if (allowedSandboxFlags.includes(value)) {
62
+ sandboxValues.add(value);
63
+ }
64
+ }
65
+ writer.setAttribute('sandbox', Array.from(sandboxValues).join(' '), item);
66
+ }
67
+ else {
68
+ // If there was no existing sandbox attribute, just use the configured one.
69
+ writer.setAttribute('sandbox', allowedSandboxFlags.join(' '), item);
70
+ }
71
+ }
72
+ }, { priority: 'lowest' });
73
+ });
74
+ });
75
+ }
76
+ }