@ckeditor/ckeditor5-media-embed 36.0.0 → 37.0.0-alpha.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.
@@ -2,279 +2,230 @@
2
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 media-embed/mediaembedediting
8
7
  */
9
-
10
8
  import { Plugin } from 'ckeditor5/src/core';
11
9
  import { first } from 'ckeditor5/src/utils';
12
-
13
10
  import { modelToViewUrlAttributeConverter } from './converters';
14
11
  import MediaEmbedCommand from './mediaembedcommand';
15
12
  import MediaRegistry from './mediaregistry';
16
13
  import { toMediaWidget, createMediaFigureElement } from './utils';
17
-
18
14
  import '../theme/mediaembedediting.css';
19
-
20
15
  /**
21
16
  * The media embed editing feature.
22
- *
23
- * @extends module:core/plugin~Plugin
24
17
  */
25
18
  export default class MediaEmbedEditing extends Plugin {
26
- /**
27
- * @inheritDoc
28
- */
29
- static get pluginName() {
30
- return 'MediaEmbedEditing';
31
- }
32
-
33
- /**
34
- * @inheritDoc
35
- */
36
- constructor( editor ) {
37
- super( editor );
38
-
39
- editor.config.define( 'mediaEmbed', {
40
- elementName: 'oembed',
41
- providers: [
42
- {
43
- name: 'dailymotion',
44
- url: /^dailymotion\.com\/video\/(\w+)/,
45
- html: match => {
46
- const id = match[ 1 ];
47
-
48
- return (
49
- '<div style="position: relative; padding-bottom: 100%; height: 0; ">' +
50
- `<iframe src="https://www.dailymotion.com/embed/video/${ id }" ` +
51
- 'style="position: absolute; width: 100%; height: 100%; top: 0; left: 0;" ' +
52
- 'frameborder="0" width="480" height="270" allowfullscreen allow="autoplay">' +
53
- '</iframe>' +
54
- '</div>'
55
- );
56
- }
57
- },
58
-
59
- {
60
- name: 'spotify',
61
- url: [
62
- /^open\.spotify\.com\/(artist\/\w+)/,
63
- /^open\.spotify\.com\/(album\/\w+)/,
64
- /^open\.spotify\.com\/(track\/\w+)/
65
- ],
66
- html: match => {
67
- const id = match[ 1 ];
68
-
69
- return (
70
- '<div style="position: relative; padding-bottom: 100%; height: 0; padding-bottom: 126%;">' +
71
- `<iframe src="https://open.spotify.com/embed/${ id }" ` +
72
- 'style="position: absolute; width: 100%; height: 100%; top: 0; left: 0;" ' +
73
- 'frameborder="0" allowtransparency="true" allow="encrypted-media">' +
74
- '</iframe>' +
75
- '</div>'
76
- );
77
- }
78
- },
79
-
80
- {
81
- name: 'youtube',
82
- url: [
83
- /^(?:m\.)?youtube\.com\/watch\?v=([\w-]+)(?:&t=(\d+))?/,
84
- /^(?:m\.)?youtube\.com\/v\/([\w-]+)(?:\?t=(\d+))?/,
85
- /^youtube\.com\/embed\/([\w-]+)(?:\?start=(\d+))?/,
86
- /^youtu\.be\/([\w-]+)(?:\?t=(\d+))?/
87
- ],
88
- html: match => {
89
- const id = match[ 1 ];
90
- const time = match[ 2 ];
91
-
92
- return (
93
- '<div style="position: relative; padding-bottom: 100%; height: 0; padding-bottom: 56.2493%;">' +
94
- `<iframe src="https://www.youtube.com/embed/${ id }${ time ? `?start=${ time }` : '' }" ` +
95
- 'style="position: absolute; width: 100%; height: 100%; top: 0; left: 0;" ' +
96
- 'frameborder="0" allow="autoplay; encrypted-media" allowfullscreen>' +
97
- '</iframe>' +
98
- '</div>'
99
- );
100
- }
101
- },
102
-
103
- {
104
- name: 'vimeo',
105
- url: [
106
- /^vimeo\.com\/(\d+)/,
107
- /^vimeo\.com\/[^/]+\/[^/]+\/video\/(\d+)/,
108
- /^vimeo\.com\/album\/[^/]+\/video\/(\d+)/,
109
- /^vimeo\.com\/channels\/[^/]+\/(\d+)/,
110
- /^vimeo\.com\/groups\/[^/]+\/videos\/(\d+)/,
111
- /^vimeo\.com\/ondemand\/[^/]+\/(\d+)/,
112
- /^player\.vimeo\.com\/video\/(\d+)/
113
- ],
114
- html: match => {
115
- const id = match[ 1 ];
116
-
117
- return (
118
- '<div style="position: relative; padding-bottom: 100%; height: 0; padding-bottom: 56.2493%;">' +
119
- `<iframe src="https://player.vimeo.com/video/${ id }" ` +
120
- 'style="position: absolute; width: 100%; height: 100%; top: 0; left: 0;" ' +
121
- 'frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen>' +
122
- '</iframe>' +
123
- '</div>'
124
- );
125
- }
126
- },
127
-
128
- {
129
- name: 'instagram',
130
- url: /^instagram\.com\/p\/(\w+)/
131
- },
132
- {
133
- name: 'twitter',
134
- url: /^twitter\.com/
135
- },
136
- {
137
- name: 'googleMaps',
138
- url: [
139
- /^google\.com\/maps/,
140
- /^goo\.gl\/maps/,
141
- /^maps\.google\.com/,
142
- /^maps\.app\.goo\.gl/
143
- ]
144
- },
145
- {
146
- name: 'flickr',
147
- url: /^flickr\.com/
148
- },
149
- {
150
- name: 'facebook',
151
- url: /^facebook\.com/
152
- }
153
- ]
154
- } );
155
-
156
- /**
157
- * The media registry managing the media providers in the editor.
158
- *
159
- * @member {module:media-embed/mediaregistry~MediaRegistry} #registry
160
- */
161
- this.registry = new MediaRegistry( editor.locale, editor.config.get( 'mediaEmbed' ) );
162
- }
163
-
164
- /**
165
- * @inheritDoc
166
- */
167
- init() {
168
- const editor = this.editor;
169
- const schema = editor.model.schema;
170
- const t = editor.t;
171
- const conversion = editor.conversion;
172
- const renderMediaPreview = editor.config.get( 'mediaEmbed.previewsInData' );
173
- const elementName = editor.config.get( 'mediaEmbed.elementName' );
174
-
175
- const registry = this.registry;
176
-
177
- editor.commands.add( 'mediaEmbed', new MediaEmbedCommand( editor ) );
178
-
179
- // Configure the schema.
180
- schema.register( 'media', {
181
- inheritAllFrom: '$blockObject',
182
- allowAttributes: [ 'url' ]
183
- } );
184
-
185
- // Model -> Data
186
- conversion.for( 'dataDowncast' ).elementToStructure( {
187
- model: 'media',
188
- view: ( modelElement, { writer } ) => {
189
- const url = modelElement.getAttribute( 'url' );
190
-
191
- return createMediaFigureElement( writer, registry, url, {
192
- elementName,
193
- renderMediaPreview: url && renderMediaPreview
194
- } );
195
- }
196
- } );
197
-
198
- // Model -> Data (url -> data-oembed-url)
199
- conversion.for( 'dataDowncast' ).add(
200
- modelToViewUrlAttributeConverter( registry, {
201
- elementName,
202
- renderMediaPreview
203
- } ) );
204
-
205
- // Model -> View (element)
206
- conversion.for( 'editingDowncast' ).elementToStructure( {
207
- model: 'media',
208
- view: ( modelElement, { writer } ) => {
209
- const url = modelElement.getAttribute( 'url' );
210
- const figure = createMediaFigureElement( writer, registry, url, {
211
- elementName,
212
- renderForEditingView: true
213
- } );
214
-
215
- return toMediaWidget( figure, writer, t( 'media widget' ) );
216
- }
217
- } );
218
-
219
- // Model -> View (url -> data-oembed-url)
220
- conversion.for( 'editingDowncast' ).add(
221
- modelToViewUrlAttributeConverter( registry, {
222
- elementName,
223
- renderForEditingView: true
224
- } ) );
225
-
226
- // View -> Model (data-oembed-url -> url)
227
- conversion.for( 'upcast' )
228
- // Upcast semantic media.
229
- .elementToElement( {
230
- view: element => [ 'oembed', elementName ].includes( element.name ) && element.getAttribute( 'url' ) ?
231
- { name: true } :
232
- null,
233
- model: ( viewMedia, { writer } ) => {
234
- const url = viewMedia.getAttribute( 'url' );
235
-
236
- if ( registry.hasMedia( url ) ) {
237
- return writer.createElement( 'media', { url } );
238
- }
239
- }
240
- } )
241
- // Upcast non-semantic media.
242
- .elementToElement( {
243
- view: {
244
- name: 'div',
245
- attributes: {
246
- 'data-oembed-url': true
247
- }
248
- },
249
- model: ( viewMedia, { writer } ) => {
250
- const url = viewMedia.getAttribute( 'data-oembed-url' );
251
-
252
- if ( registry.hasMedia( url ) ) {
253
- return writer.createElement( 'media', { url } );
254
- }
255
- }
256
- } )
257
- // Consume `<figure class="media">` elements, that were left after upcast.
258
- .add( dispatcher => {
259
- dispatcher.on( 'element:figure', converter );
260
-
261
- function converter( evt, data, conversionApi ) {
262
- if ( !conversionApi.consumable.consume( data.viewItem, { name: true, classes: 'media' } ) ) {
263
- return;
264
- }
265
-
266
- const { modelRange, modelCursor } = conversionApi.convertChildren( data.viewItem, data.modelCursor );
267
-
268
- data.modelRange = modelRange;
269
- data.modelCursor = modelCursor;
270
-
271
- const modelElement = first( modelRange.getItems() );
272
-
273
- if ( !modelElement ) {
274
- // Revert consumed figure so other features can convert it.
275
- conversionApi.consumable.revert( data.viewItem, { name: true, classes: 'media' } );
276
- }
277
- }
278
- } );
279
- }
19
+ /**
20
+ * @inheritDoc
21
+ */
22
+ static get pluginName() {
23
+ return 'MediaEmbedEditing';
24
+ }
25
+ /**
26
+ * @inheritDoc
27
+ */
28
+ constructor(editor) {
29
+ super(editor);
30
+ editor.config.define('mediaEmbed', {
31
+ elementName: 'oembed',
32
+ providers: [
33
+ {
34
+ name: 'dailymotion',
35
+ url: /^dailymotion\.com\/video\/(\w+)/,
36
+ html: match => {
37
+ const id = match[1];
38
+ return ('<div style="position: relative; padding-bottom: 100%; height: 0; ">' +
39
+ `<iframe src="https://www.dailymotion.com/embed/video/${id}" ` +
40
+ 'style="position: absolute; width: 100%; height: 100%; top: 0; left: 0;" ' +
41
+ 'frameborder="0" width="480" height="270" allowfullscreen allow="autoplay">' +
42
+ '</iframe>' +
43
+ '</div>');
44
+ }
45
+ },
46
+ {
47
+ name: 'spotify',
48
+ url: [
49
+ /^open\.spotify\.com\/(artist\/\w+)/,
50
+ /^open\.spotify\.com\/(album\/\w+)/,
51
+ /^open\.spotify\.com\/(track\/\w+)/
52
+ ],
53
+ html: match => {
54
+ const id = match[1];
55
+ return ('<div style="position: relative; padding-bottom: 100%; height: 0; padding-bottom: 126%;">' +
56
+ `<iframe src="https://open.spotify.com/embed/${id}" ` +
57
+ 'style="position: absolute; width: 100%; height: 100%; top: 0; left: 0;" ' +
58
+ 'frameborder="0" allowtransparency="true" allow="encrypted-media">' +
59
+ '</iframe>' +
60
+ '</div>');
61
+ }
62
+ },
63
+ {
64
+ name: 'youtube',
65
+ url: [
66
+ /^(?:m\.)?youtube\.com\/watch\?v=([\w-]+)(?:&t=(\d+))?/,
67
+ /^(?:m\.)?youtube\.com\/v\/([\w-]+)(?:\?t=(\d+))?/,
68
+ /^youtube\.com\/embed\/([\w-]+)(?:\?start=(\d+))?/,
69
+ /^youtu\.be\/([\w-]+)(?:\?t=(\d+))?/
70
+ ],
71
+ html: match => {
72
+ const id = match[1];
73
+ const time = match[2];
74
+ return ('<div style="position: relative; padding-bottom: 100%; height: 0; padding-bottom: 56.2493%;">' +
75
+ `<iframe src="https://www.youtube.com/embed/${id}${time ? `?start=${time}` : ''}" ` +
76
+ 'style="position: absolute; width: 100%; height: 100%; top: 0; left: 0;" ' +
77
+ 'frameborder="0" allow="autoplay; encrypted-media" allowfullscreen>' +
78
+ '</iframe>' +
79
+ '</div>');
80
+ }
81
+ },
82
+ {
83
+ name: 'vimeo',
84
+ url: [
85
+ /^vimeo\.com\/(\d+)/,
86
+ /^vimeo\.com\/[^/]+\/[^/]+\/video\/(\d+)/,
87
+ /^vimeo\.com\/album\/[^/]+\/video\/(\d+)/,
88
+ /^vimeo\.com\/channels\/[^/]+\/(\d+)/,
89
+ /^vimeo\.com\/groups\/[^/]+\/videos\/(\d+)/,
90
+ /^vimeo\.com\/ondemand\/[^/]+\/(\d+)/,
91
+ /^player\.vimeo\.com\/video\/(\d+)/
92
+ ],
93
+ html: match => {
94
+ const id = match[1];
95
+ return ('<div style="position: relative; padding-bottom: 100%; height: 0; padding-bottom: 56.2493%;">' +
96
+ `<iframe src="https://player.vimeo.com/video/${id}" ` +
97
+ 'style="position: absolute; width: 100%; height: 100%; top: 0; left: 0;" ' +
98
+ 'frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen>' +
99
+ '</iframe>' +
100
+ '</div>');
101
+ }
102
+ },
103
+ {
104
+ name: 'instagram',
105
+ url: /^instagram\.com\/p\/(\w+)/
106
+ },
107
+ {
108
+ name: 'twitter',
109
+ url: /^twitter\.com/
110
+ },
111
+ {
112
+ name: 'googleMaps',
113
+ url: [
114
+ /^google\.com\/maps/,
115
+ /^goo\.gl\/maps/,
116
+ /^maps\.google\.com/,
117
+ /^maps\.app\.goo\.gl/
118
+ ]
119
+ },
120
+ {
121
+ name: 'flickr',
122
+ url: /^flickr\.com/
123
+ },
124
+ {
125
+ name: 'facebook',
126
+ url: /^facebook\.com/
127
+ }
128
+ ]
129
+ });
130
+ this.registry = new MediaRegistry(editor.locale, editor.config.get('mediaEmbed'));
131
+ }
132
+ /**
133
+ * @inheritDoc
134
+ */
135
+ init() {
136
+ const editor = this.editor;
137
+ const schema = editor.model.schema;
138
+ const t = editor.t;
139
+ const conversion = editor.conversion;
140
+ const renderMediaPreview = editor.config.get('mediaEmbed.previewsInData');
141
+ const elementName = editor.config.get('mediaEmbed.elementName');
142
+ const registry = this.registry;
143
+ editor.commands.add('mediaEmbed', new MediaEmbedCommand(editor));
144
+ // Configure the schema.
145
+ schema.register('media', {
146
+ inheritAllFrom: '$blockObject',
147
+ allowAttributes: ['url']
148
+ });
149
+ // Model -> Data
150
+ conversion.for('dataDowncast').elementToStructure({
151
+ model: 'media',
152
+ view: (modelElement, { writer }) => {
153
+ const url = modelElement.getAttribute('url');
154
+ return createMediaFigureElement(writer, registry, url, {
155
+ elementName,
156
+ renderMediaPreview: !!url && renderMediaPreview
157
+ });
158
+ }
159
+ });
160
+ // Model -> Data (url -> data-oembed-url)
161
+ conversion.for('dataDowncast').add(modelToViewUrlAttributeConverter(registry, {
162
+ elementName,
163
+ renderMediaPreview
164
+ }));
165
+ // Model -> View (element)
166
+ conversion.for('editingDowncast').elementToStructure({
167
+ model: 'media',
168
+ view: (modelElement, { writer }) => {
169
+ const url = modelElement.getAttribute('url');
170
+ const figure = createMediaFigureElement(writer, registry, url, {
171
+ elementName,
172
+ renderForEditingView: true
173
+ });
174
+ return toMediaWidget(figure, writer, t('media widget'));
175
+ }
176
+ });
177
+ // Model -> View (url -> data-oembed-url)
178
+ conversion.for('editingDowncast').add(modelToViewUrlAttributeConverter(registry, {
179
+ elementName,
180
+ renderForEditingView: true
181
+ }));
182
+ // View -> Model (data-oembed-url -> url)
183
+ conversion.for('upcast')
184
+ // Upcast semantic media.
185
+ .elementToElement({
186
+ view: element => ['oembed', elementName].includes(element.name) && element.getAttribute('url') ?
187
+ { name: true } :
188
+ null,
189
+ model: (viewMedia, { writer }) => {
190
+ const url = viewMedia.getAttribute('url');
191
+ if (registry.hasMedia(url)) {
192
+ return writer.createElement('media', { url });
193
+ }
194
+ return null;
195
+ }
196
+ })
197
+ // Upcast non-semantic media.
198
+ .elementToElement({
199
+ view: {
200
+ name: 'div',
201
+ attributes: {
202
+ 'data-oembed-url': true
203
+ }
204
+ },
205
+ model: (viewMedia, { writer }) => {
206
+ const url = viewMedia.getAttribute('data-oembed-url');
207
+ if (registry.hasMedia(url)) {
208
+ return writer.createElement('media', { url });
209
+ }
210
+ return null;
211
+ }
212
+ })
213
+ // Consume `<figure class="media">` elements, that were left after upcast.
214
+ .add(dispatcher => {
215
+ const converter = (evt, data, conversionApi) => {
216
+ if (!conversionApi.consumable.consume(data.viewItem, { name: true, classes: 'media' })) {
217
+ return;
218
+ }
219
+ const { modelRange, modelCursor } = conversionApi.convertChildren(data.viewItem, data.modelCursor);
220
+ data.modelRange = modelRange;
221
+ data.modelCursor = modelCursor;
222
+ const modelElement = first(modelRange.getItems());
223
+ if (!modelElement) {
224
+ // Revert consumed figure so other features can convert it.
225
+ conversionApi.consumable.revert(data.viewItem, { name: true, classes: 'media' });
226
+ }
227
+ };
228
+ dispatcher.on('element:figure', converter);
229
+ });
230
+ }
280
231
  }
@@ -0,0 +1,34 @@
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 media-embed/mediaembedtoolbar
7
+ */
8
+ import { Plugin, type PluginDependencies } from 'ckeditor5/src/core';
9
+ import './mediaembedconfig';
10
+ /**
11
+ * The media embed toolbar plugin. It creates a toolbar for media embed that shows up when the media element is selected.
12
+ *
13
+ * Instances of toolbar components (e.g. buttons) are created based on the
14
+ * {@link module:media-embed/mediaembed~MediaEmbedConfig#toolbar `media.toolbar` configuration option}.
15
+ */
16
+ export default class MediaEmbedToolbar extends Plugin {
17
+ /**
18
+ * @inheritDoc
19
+ */
20
+ static get requires(): PluginDependencies;
21
+ /**
22
+ * @inheritDoc
23
+ */
24
+ static get pluginName(): 'MediaEmbedToolbar';
25
+ /**
26
+ * @inheritDoc
27
+ */
28
+ afterInit(): void;
29
+ }
30
+ declare module '@ckeditor/ckeditor5-core' {
31
+ interface PluginsMap {
32
+ [MediaEmbedToolbar.pluginName]: MediaEmbedToolbar;
33
+ }
34
+ }
@@ -2,60 +2,43 @@
2
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 media-embed/mediaembedtoolbar
8
7
  */
9
-
10
8
  import { Plugin } from 'ckeditor5/src/core';
11
9
  import { WidgetToolbarRepository } from 'ckeditor5/src/widget';
12
-
13
10
  import { getSelectedMediaViewWidget } from './utils';
14
-
11
+ import './mediaembedconfig';
15
12
  /**
16
13
  * The media embed toolbar plugin. It creates a toolbar for media embed that shows up when the media element is selected.
17
14
  *
18
15
  * Instances of toolbar components (e.g. buttons) are created based on the
19
16
  * {@link module:media-embed/mediaembed~MediaEmbedConfig#toolbar `media.toolbar` configuration option}.
20
- *
21
- * @extends module:core/plugin~Plugin
22
17
  */
23
18
  export default class MediaEmbedToolbar extends Plugin {
24
- /**
25
- * @inheritDoc
26
- */
27
- static get requires() {
28
- return [ WidgetToolbarRepository ];
29
- }
30
-
31
- /**
32
- * @inheritDoc
33
- */
34
- static get pluginName() {
35
- return 'MediaEmbedToolbar';
36
- }
37
-
38
- /**
39
- * @inheritDoc
40
- */
41
- afterInit() {
42
- const editor = this.editor;
43
- const t = editor.t;
44
- const widgetToolbarRepository = editor.plugins.get( WidgetToolbarRepository );
45
-
46
- widgetToolbarRepository.register( 'mediaEmbed', {
47
- ariaLabel: t( 'Media toolbar' ),
48
- items: editor.config.get( 'mediaEmbed.toolbar' ) || [],
49
- getRelatedElement: getSelectedMediaViewWidget
50
- } );
51
- }
19
+ /**
20
+ * @inheritDoc
21
+ */
22
+ static get requires() {
23
+ return [WidgetToolbarRepository];
24
+ }
25
+ /**
26
+ * @inheritDoc
27
+ */
28
+ static get pluginName() {
29
+ return 'MediaEmbedToolbar';
30
+ }
31
+ /**
32
+ * @inheritDoc
33
+ */
34
+ afterInit() {
35
+ const editor = this.editor;
36
+ const t = editor.t;
37
+ const widgetToolbarRepository = editor.plugins.get(WidgetToolbarRepository);
38
+ widgetToolbarRepository.register('mediaEmbed', {
39
+ ariaLabel: t('Media toolbar'),
40
+ items: editor.config.get('mediaEmbed.toolbar') || [],
41
+ getRelatedElement: getSelectedMediaViewWidget
42
+ });
43
+ }
52
44
  }
53
-
54
- /**
55
- * Items to be placed in the media embed toolbar.
56
- * This option requires adding {@link module:media-embed/mediaembedtoolbar~MediaEmbedToolbar} to the plugin list.
57
- *
58
- * Read more about configuring toolbar in {@link module:core/editor/editorconfig~EditorConfig#toolbar}.
59
- *
60
- * @member {Array.<String>} module:media-embed/mediaembed~MediaEmbedConfig#toolbar
61
- */
@@ -0,0 +1,31 @@
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 media-embed/mediaembedui
7
+ */
8
+ import { Plugin, type PluginDependencies } from 'ckeditor5/src/core';
9
+ /**
10
+ * The media embed UI plugin.
11
+ */
12
+ export default class MediaEmbedUI extends Plugin {
13
+ /**
14
+ * @inheritDoc
15
+ */
16
+ static get requires(): PluginDependencies;
17
+ /**
18
+ * @inheritDoc
19
+ */
20
+ static get pluginName(): 'MediaEmbedUI';
21
+ /**
22
+ * @inheritDoc
23
+ */
24
+ init(): void;
25
+ private _setUpDropdown;
26
+ }
27
+ declare module '@ckeditor/ckeditor5-core' {
28
+ interface PluginsMap {
29
+ [MediaEmbedUI.pluginName]: MediaEmbedUI;
30
+ }
31
+ }