@ckeditor/ckeditor5-media-embed 47.6.1 → 48.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.
Files changed (184) hide show
  1. package/ckeditor5-metadata.json +3 -3
  2. package/{src → dist}/automediaembed.d.ts +4 -4
  3. package/{src → dist}/converters.d.ts +1 -1
  4. package/dist/index-content.css +4 -4
  5. package/dist/index-editor.css +136 -75
  6. package/dist/index.css +128 -116
  7. package/dist/index.css.map +1 -1
  8. package/dist/index.js +1 -1
  9. package/dist/index.js.map +1 -1
  10. package/{src → dist}/mediaembed.d.ts +2 -2
  11. package/{src → dist}/mediaembedcommand.d.ts +1 -1
  12. package/{src → dist}/mediaembedconfig.d.ts +2 -2
  13. package/{src → dist}/mediaembedediting.d.ts +1 -1
  14. package/{src → dist}/mediaembedtoolbar.d.ts +2 -2
  15. package/{src → dist}/mediaembedui.d.ts +2 -2
  16. package/{src → dist}/mediaregistry.d.ts +2 -2
  17. package/{src → dist}/ui/mediaformview.d.ts +2 -3
  18. package/{src → dist}/utils.d.ts +1 -1
  19. package/package.json +27 -51
  20. package/build/media-embed.js +0 -5
  21. package/build/translations/af.js +0 -1
  22. package/build/translations/ar.js +0 -1
  23. package/build/translations/ast.js +0 -1
  24. package/build/translations/az.js +0 -1
  25. package/build/translations/be.js +0 -1
  26. package/build/translations/bg.js +0 -1
  27. package/build/translations/bn.js +0 -1
  28. package/build/translations/bs.js +0 -1
  29. package/build/translations/ca.js +0 -1
  30. package/build/translations/cs.js +0 -1
  31. package/build/translations/da.js +0 -1
  32. package/build/translations/de-ch.js +0 -1
  33. package/build/translations/de.js +0 -1
  34. package/build/translations/el.js +0 -1
  35. package/build/translations/en-au.js +0 -1
  36. package/build/translations/en-gb.js +0 -1
  37. package/build/translations/eo.js +0 -1
  38. package/build/translations/es-co.js +0 -1
  39. package/build/translations/es.js +0 -1
  40. package/build/translations/et.js +0 -1
  41. package/build/translations/eu.js +0 -1
  42. package/build/translations/fa.js +0 -1
  43. package/build/translations/fi.js +0 -1
  44. package/build/translations/fr.js +0 -1
  45. package/build/translations/gl.js +0 -1
  46. package/build/translations/gu.js +0 -1
  47. package/build/translations/he.js +0 -1
  48. package/build/translations/hi.js +0 -1
  49. package/build/translations/hr.js +0 -1
  50. package/build/translations/hu.js +0 -1
  51. package/build/translations/hy.js +0 -1
  52. package/build/translations/id.js +0 -1
  53. package/build/translations/it.js +0 -1
  54. package/build/translations/ja.js +0 -1
  55. package/build/translations/jv.js +0 -1
  56. package/build/translations/kk.js +0 -1
  57. package/build/translations/km.js +0 -1
  58. package/build/translations/kn.js +0 -1
  59. package/build/translations/ko.js +0 -1
  60. package/build/translations/ku.js +0 -1
  61. package/build/translations/lt.js +0 -1
  62. package/build/translations/lv.js +0 -1
  63. package/build/translations/ms.js +0 -1
  64. package/build/translations/nb.js +0 -1
  65. package/build/translations/ne.js +0 -1
  66. package/build/translations/nl.js +0 -1
  67. package/build/translations/no.js +0 -1
  68. package/build/translations/oc.js +0 -1
  69. package/build/translations/pl.js +0 -1
  70. package/build/translations/pt-br.js +0 -1
  71. package/build/translations/pt.js +0 -1
  72. package/build/translations/ro.js +0 -1
  73. package/build/translations/ru.js +0 -1
  74. package/build/translations/si.js +0 -1
  75. package/build/translations/sk.js +0 -1
  76. package/build/translations/sl.js +0 -1
  77. package/build/translations/sq.js +0 -1
  78. package/build/translations/sr-latn.js +0 -1
  79. package/build/translations/sr.js +0 -1
  80. package/build/translations/sv.js +0 -1
  81. package/build/translations/th.js +0 -1
  82. package/build/translations/ti.js +0 -1
  83. package/build/translations/tk.js +0 -1
  84. package/build/translations/tr.js +0 -1
  85. package/build/translations/tt.js +0 -1
  86. package/build/translations/ug.js +0 -1
  87. package/build/translations/uk.js +0 -1
  88. package/build/translations/ur.js +0 -1
  89. package/build/translations/uz.js +0 -1
  90. package/build/translations/vi.js +0 -1
  91. package/build/translations/zh-cn.js +0 -1
  92. package/build/translations/zh.js +0 -1
  93. package/lang/contexts.json +0 -13
  94. package/lang/translations/af.po +0 -56
  95. package/lang/translations/ar.po +0 -56
  96. package/lang/translations/ast.po +0 -56
  97. package/lang/translations/az.po +0 -56
  98. package/lang/translations/be.po +0 -56
  99. package/lang/translations/bg.po +0 -56
  100. package/lang/translations/bn.po +0 -56
  101. package/lang/translations/bs.po +0 -56
  102. package/lang/translations/ca.po +0 -56
  103. package/lang/translations/cs.po +0 -56
  104. package/lang/translations/da.po +0 -56
  105. package/lang/translations/de-ch.po +0 -56
  106. package/lang/translations/de.po +0 -56
  107. package/lang/translations/el.po +0 -56
  108. package/lang/translations/en-au.po +0 -56
  109. package/lang/translations/en-gb.po +0 -56
  110. package/lang/translations/en.po +0 -56
  111. package/lang/translations/eo.po +0 -56
  112. package/lang/translations/es-co.po +0 -56
  113. package/lang/translations/es.po +0 -56
  114. package/lang/translations/et.po +0 -56
  115. package/lang/translations/eu.po +0 -56
  116. package/lang/translations/fa.po +0 -56
  117. package/lang/translations/fi.po +0 -56
  118. package/lang/translations/fr.po +0 -56
  119. package/lang/translations/gl.po +0 -56
  120. package/lang/translations/gu.po +0 -56
  121. package/lang/translations/he.po +0 -56
  122. package/lang/translations/hi.po +0 -56
  123. package/lang/translations/hr.po +0 -56
  124. package/lang/translations/hu.po +0 -56
  125. package/lang/translations/hy.po +0 -56
  126. package/lang/translations/id.po +0 -56
  127. package/lang/translations/it.po +0 -56
  128. package/lang/translations/ja.po +0 -56
  129. package/lang/translations/jv.po +0 -56
  130. package/lang/translations/kk.po +0 -56
  131. package/lang/translations/km.po +0 -56
  132. package/lang/translations/kn.po +0 -56
  133. package/lang/translations/ko.po +0 -56
  134. package/lang/translations/ku.po +0 -56
  135. package/lang/translations/lt.po +0 -56
  136. package/lang/translations/lv.po +0 -56
  137. package/lang/translations/ms.po +0 -56
  138. package/lang/translations/nb.po +0 -56
  139. package/lang/translations/ne.po +0 -56
  140. package/lang/translations/nl.po +0 -56
  141. package/lang/translations/no.po +0 -56
  142. package/lang/translations/oc.po +0 -56
  143. package/lang/translations/pl.po +0 -56
  144. package/lang/translations/pt-br.po +0 -56
  145. package/lang/translations/pt.po +0 -56
  146. package/lang/translations/ro.po +0 -56
  147. package/lang/translations/ru.po +0 -56
  148. package/lang/translations/si.po +0 -56
  149. package/lang/translations/sk.po +0 -56
  150. package/lang/translations/sl.po +0 -56
  151. package/lang/translations/sq.po +0 -56
  152. package/lang/translations/sr-latn.po +0 -56
  153. package/lang/translations/sr.po +0 -56
  154. package/lang/translations/sv.po +0 -56
  155. package/lang/translations/th.po +0 -56
  156. package/lang/translations/ti.po +0 -56
  157. package/lang/translations/tk.po +0 -56
  158. package/lang/translations/tr.po +0 -56
  159. package/lang/translations/tt.po +0 -56
  160. package/lang/translations/ug.po +0 -56
  161. package/lang/translations/uk.po +0 -56
  162. package/lang/translations/ur.po +0 -56
  163. package/lang/translations/uz.po +0 -56
  164. package/lang/translations/vi.po +0 -56
  165. package/lang/translations/zh-cn.po +0 -56
  166. package/lang/translations/zh.po +0 -56
  167. package/src/augmentation.js +0 -5
  168. package/src/automediaembed.js +0 -147
  169. package/src/converters.js +0 -55
  170. package/src/index.js +0 -18
  171. package/src/mediaembed.js +0 -44
  172. package/src/mediaembedcommand.js +0 -71
  173. package/src/mediaembedconfig.js +0 -5
  174. package/src/mediaembedediting.js +0 -252
  175. package/src/mediaembedtoolbar.js +0 -50
  176. package/src/mediaembedui.js +0 -134
  177. package/src/mediaregistry.js +0 -262
  178. package/src/ui/mediaformview.js +0 -157
  179. package/src/utils.js +0 -96
  180. package/theme/mediaembed.css +0 -23
  181. package/theme/mediaembedediting.css +0 -48
  182. package/theme/mediaform.css +0 -39
  183. /package/{src → dist}/augmentation.d.ts +0 -0
  184. /package/{src → dist}/index.d.ts +0 -0
package/src/index.js DELETED
@@ -1,18 +0,0 @@
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
- /**
6
- * @module media-embed
7
- */
8
- export { MediaEmbed } from './mediaembed.js';
9
- export { MediaEmbedEditing } from './mediaembedediting.js';
10
- export { MediaEmbedUI } from './mediaembedui.js';
11
- export { AutoMediaEmbed } from './automediaembed.js';
12
- export { MediaEmbedToolbar } from './mediaembedtoolbar.js';
13
- export { MediaEmbedCommand } from './mediaembedcommand.js';
14
- export { modelToViewUrlAttributeConverter as _modelToViewUrlAttributeMediaConverter } from './converters.js';
15
- export { MediaFormView as _MediaFormView } from './ui/mediaformview.js';
16
- export { toMediaWidget as _toMediaWidget, getSelectedMediaViewWidget as _getSelectedMediaViewWidget, isMediaWidget as _isMediaWidget, createMediaFigureElement as _createMediaFigureElement, getSelectedMediaModelWidget as _getSelectedMediaModelWidget, insertMedia as _insertMedia } from './utils.js';
17
- export { MediaRegistry } from './mediaregistry.js';
18
- import './augmentation.js';
package/src/mediaembed.js DELETED
@@ -1,44 +0,0 @@
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
- /**
6
- * @module media-embed/mediaembed
7
- */
8
- import { Plugin } from 'ckeditor5/src/core.js';
9
- import { Widget } from 'ckeditor5/src/widget.js';
10
- import { MediaEmbedEditing } from './mediaembedediting.js';
11
- import { AutoMediaEmbed } from './automediaembed.js';
12
- import { MediaEmbedUI } from './mediaembedui.js';
13
- import '../theme/mediaembed.css';
14
- /**
15
- * The media embed plugin.
16
- *
17
- * For a detailed overview, check the {@glink features/media-embed Media Embed feature documentation}.
18
- *
19
- * This is a "glue" plugin which loads the following plugins:
20
- *
21
- * * The {@link module:media-embed/mediaembedediting~MediaEmbedEditing media embed editing feature},
22
- * * The {@link module:media-embed/mediaembedui~MediaEmbedUI media embed UI feature} and
23
- * * The {@link module:media-embed/automediaembed~AutoMediaEmbed auto-media embed feature}.
24
- */
25
- export class MediaEmbed extends Plugin {
26
- /**
27
- * @inheritDoc
28
- */
29
- static get requires() {
30
- return [MediaEmbedEditing, MediaEmbedUI, AutoMediaEmbed, Widget];
31
- }
32
- /**
33
- * @inheritDoc
34
- */
35
- static get pluginName() {
36
- return 'MediaEmbed';
37
- }
38
- /**
39
- * @inheritDoc
40
- */
41
- static get isOfficialPlugin() {
42
- return true;
43
- }
44
- }
@@ -1,71 +0,0 @@
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 { Command } from 'ckeditor5/src/core.js';
6
- import { findOptimalInsertionRange } from 'ckeditor5/src/widget.js';
7
- import { getSelectedMediaModelWidget, insertMedia } from './utils.js';
8
- /**
9
- * The insert media command.
10
- *
11
- * The command is registered by the {@link module:media-embed/mediaembedediting~MediaEmbedEditing} as `'mediaEmbed'`.
12
- *
13
- * To insert media at the current selection, execute the command and specify the URL:
14
- *
15
- * ```ts
16
- * editor.execute( 'mediaEmbed', 'http://url.to.the/media' );
17
- * ```
18
- */
19
- export class MediaEmbedCommand extends Command {
20
- /**
21
- * @inheritDoc
22
- */
23
- refresh() {
24
- const model = this.editor.model;
25
- const selection = model.document.selection;
26
- const selectedMedia = getSelectedMediaModelWidget(selection);
27
- this.value = selectedMedia ? selectedMedia.getAttribute('url') : undefined;
28
- this.isEnabled = isMediaSelected(selection) || isAllowedInParent(selection, model);
29
- }
30
- /**
31
- * Executes the command, which either:
32
- *
33
- * * updates the URL of the selected media,
34
- * * inserts the new media into the editor and puts the selection around it.
35
- *
36
- * @fires execute
37
- * @param url The URL of the media.
38
- */
39
- execute(url) {
40
- const model = this.editor.model;
41
- const selection = model.document.selection;
42
- const selectedMedia = getSelectedMediaModelWidget(selection);
43
- if (selectedMedia) {
44
- model.change(writer => {
45
- writer.setAttribute('url', url, selectedMedia);
46
- });
47
- }
48
- else {
49
- insertMedia(model, url, selection, true);
50
- }
51
- }
52
- }
53
- /**
54
- * Checks if the media embed is allowed in the parent.
55
- */
56
- function isAllowedInParent(selection, model) {
57
- const insertionRange = findOptimalInsertionRange(selection, model);
58
- let parent = insertionRange.start.parent;
59
- // The model.insertContent() will remove empty parent (unless it is a $root or a limit).
60
- if (parent.isEmpty && !model.schema.isLimit(parent)) {
61
- parent = parent.parent;
62
- }
63
- return model.schema.checkChild(parent, 'media');
64
- }
65
- /**
66
- * Checks if the media object is selected.
67
- */
68
- function isMediaSelected(selection) {
69
- const element = selection.getSelectedElement();
70
- return !!element && element.name === 'media';
71
- }
@@ -1,5 +0,0 @@
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
- export {};
@@ -1,252 +0,0 @@
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
- /**
6
- * @module media-embed/mediaembedediting
7
- */
8
- import { Plugin } from 'ckeditor5/src/core.js';
9
- import { first } from 'ckeditor5/src/utils.js';
10
- import { modelToViewUrlAttributeConverter } from './converters.js';
11
- import { MediaEmbedCommand } from './mediaembedcommand.js';
12
- import { MediaRegistry } from './mediaregistry.js';
13
- import { toMediaWidget, createMediaFigureElement } from './utils.js';
14
- import '../theme/mediaembedediting.css';
15
- /**
16
- * The media embed editing feature.
17
- */
18
- export class MediaEmbedEditing extends Plugin {
19
- /**
20
- * @inheritDoc
21
- */
22
- static get pluginName() {
23
- return 'MediaEmbedEditing';
24
- }
25
- /**
26
- * @inheritDoc
27
- */
28
- static get isOfficialPlugin() {
29
- return true;
30
- }
31
- /**
32
- * The media registry managing the media providers in the editor.
33
- */
34
- registry;
35
- /**
36
- * @inheritDoc
37
- */
38
- constructor(editor) {
39
- super(editor);
40
- editor.config.define('mediaEmbed', {
41
- elementName: 'oembed',
42
- providers: [
43
- {
44
- name: 'dailymotion',
45
- url: [
46
- /^dailymotion\.com\/video\/(\w+)/,
47
- /^dai.ly\/(\w+)/
48
- ],
49
- html: match => {
50
- const id = match[1];
51
- return ('<div style="position: relative; padding-bottom: 100%; height: 0; ">' +
52
- `<iframe src="https://www.dailymotion.com/embed/video/${id}" ` +
53
- 'style="position: absolute; width: 100%; height: 100%; top: 0; left: 0;" ' +
54
- 'frameborder="0" width="480" height="270" allowfullscreen allow="autoplay">' +
55
- '</iframe>' +
56
- '</div>');
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
- return ('<div style="position: relative; padding-bottom: 100%; height: 0; padding-bottom: 126%;">' +
69
- `<iframe src="https://open.spotify.com/embed/${id}" ` +
70
- 'style="position: absolute; width: 100%; height: 100%; top: 0; left: 0;" ' +
71
- 'frameborder="0" allowtransparency="true" allow="encrypted-media">' +
72
- '</iframe>' +
73
- '</div>');
74
- }
75
- },
76
- {
77
- name: 'youtube',
78
- url: [
79
- /^(?:m\.)?youtube\.com\/watch\?v=([\w-]+)(?:&t=(\d+))?/,
80
- /^(?:m\.)?youtube\.com\/shorts\/([\w-]+)(?:\?t=(\d+))?/,
81
- /^(?:m\.)?youtube\.com\/v\/([\w-]+)(?:\?t=(\d+))?/,
82
- /^youtube\.com\/embed\/([\w-]+)(?:\?start=(\d+))?/,
83
- /^youtu\.be\/([\w-]+)(?:\?t=(\d+))?/
84
- ],
85
- html: match => {
86
- const id = match[1];
87
- const time = match[2];
88
- return ('<div style="position: relative; padding-bottom: 100%; height: 0; padding-bottom: 56.2493%;">' +
89
- `<iframe src="https://www.youtube.com/embed/${id}${time ? `?start=${time}` : ''}" ` +
90
- 'style="position: absolute; width: 100%; height: 100%; top: 0; left: 0;" ' +
91
- 'frameborder="0" allow="autoplay; encrypted-media" referrerpolicy="strict-origin-when-cross-origin" ' +
92
- 'allowfullscreen>' +
93
- '</iframe>' +
94
- '</div>');
95
- }
96
- },
97
- {
98
- name: 'vimeo',
99
- url: [
100
- /^vimeo\.com\/(\d+)/,
101
- /^vimeo\.com\/[^/]+\/[^/]+\/video\/(\d+)/,
102
- /^vimeo\.com\/album\/[^/]+\/video\/(\d+)/,
103
- /^vimeo\.com\/channels\/[^/]+\/(\d+)/,
104
- /^vimeo\.com\/groups\/[^/]+\/videos\/(\d+)/,
105
- /^vimeo\.com\/ondemand\/[^/]+\/(\d+)/,
106
- /^player\.vimeo\.com\/video\/(\d+)/
107
- ],
108
- html: match => {
109
- const id = match[1];
110
- return ('<div style="position: relative; padding-bottom: 100%; height: 0; padding-bottom: 56.2493%;">' +
111
- `<iframe src="https://player.vimeo.com/video/${id}" ` +
112
- 'style="position: absolute; width: 100%; height: 100%; top: 0; left: 0;" ' +
113
- 'frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen>' +
114
- '</iframe>' +
115
- '</div>');
116
- }
117
- },
118
- {
119
- name: 'instagram',
120
- url: [
121
- /^instagram\.com\/p\/(\w+)/,
122
- /^instagram\.com\/reel\/(\w+)/
123
- ]
124
- },
125
- {
126
- name: 'twitter',
127
- url: [
128
- /^twitter\.com/,
129
- /^x\.com/
130
- ]
131
- },
132
- {
133
- name: 'googleMaps',
134
- url: [
135
- /^google\.com\/maps/,
136
- /^goo\.gl\/maps/,
137
- /^maps\.google\.com/,
138
- /^maps\.app\.goo\.gl/
139
- ]
140
- },
141
- {
142
- name: 'flickr',
143
- url: /^flickr\.com/
144
- },
145
- {
146
- name: 'facebook',
147
- url: /^facebook\.com/
148
- }
149
- ]
150
- });
151
- this.registry = new MediaRegistry(editor.locale, editor.config.get('mediaEmbed'));
152
- }
153
- /**
154
- * @inheritDoc
155
- */
156
- init() {
157
- const editor = this.editor;
158
- const schema = editor.model.schema;
159
- const t = editor.t;
160
- const conversion = editor.conversion;
161
- const renderMediaPreview = editor.config.get('mediaEmbed.previewsInData');
162
- const elementName = editor.config.get('mediaEmbed.elementName');
163
- const registry = this.registry;
164
- editor.commands.add('mediaEmbed', new MediaEmbedCommand(editor));
165
- // Configure the schema.
166
- schema.register('media', {
167
- inheritAllFrom: '$blockObject',
168
- allowAttributes: ['url']
169
- });
170
- // Model -> Data
171
- conversion.for('dataDowncast').elementToStructure({
172
- model: 'media',
173
- view: (modelElement, { writer }) => {
174
- const url = modelElement.getAttribute('url');
175
- return createMediaFigureElement(writer, registry, url, {
176
- elementName,
177
- renderMediaPreview: !!url && renderMediaPreview
178
- });
179
- }
180
- });
181
- // Model -> Data (url -> data-oembed-url)
182
- conversion.for('dataDowncast').add(modelToViewUrlAttributeConverter(registry, {
183
- elementName,
184
- renderMediaPreview
185
- }));
186
- // Model -> View (element)
187
- conversion.for('editingDowncast').elementToStructure({
188
- model: 'media',
189
- view: (modelElement, { writer }) => {
190
- const url = modelElement.getAttribute('url');
191
- const figure = createMediaFigureElement(writer, registry, url, {
192
- elementName,
193
- renderForEditingView: true
194
- });
195
- return toMediaWidget(figure, writer, t('media widget'));
196
- }
197
- });
198
- // Model -> View (url -> data-oembed-url)
199
- conversion.for('editingDowncast').add(modelToViewUrlAttributeConverter(registry, {
200
- elementName,
201
- renderForEditingView: true
202
- }));
203
- // View -> Model (data-oembed-url -> url)
204
- conversion.for('upcast')
205
- // Upcast semantic media.
206
- .elementToElement({
207
- view: element => ['oembed', elementName].includes(element.name) && element.getAttribute('url') ?
208
- { name: true } :
209
- null,
210
- model: (viewMedia, { writer }) => {
211
- const url = viewMedia.getAttribute('url');
212
- if (registry.hasMedia(url)) {
213
- return writer.createElement('media', { url });
214
- }
215
- return null;
216
- }
217
- })
218
- // Upcast non-semantic media.
219
- .elementToElement({
220
- view: {
221
- name: 'div',
222
- attributes: {
223
- 'data-oembed-url': true
224
- }
225
- },
226
- model: (viewMedia, { writer }) => {
227
- const url = viewMedia.getAttribute('data-oembed-url');
228
- if (registry.hasMedia(url)) {
229
- return writer.createElement('media', { url });
230
- }
231
- return null;
232
- }
233
- })
234
- // Consume `<figure class="media">` elements, that were left after upcast.
235
- .add(dispatcher => {
236
- const converter = (evt, data, conversionApi) => {
237
- if (!conversionApi.consumable.consume(data.viewItem, { name: true, classes: 'media' })) {
238
- return;
239
- }
240
- const { modelRange, modelCursor } = conversionApi.convertChildren(data.viewItem, data.modelCursor);
241
- data.modelRange = modelRange;
242
- data.modelCursor = modelCursor;
243
- const modelElement = first(modelRange.getItems());
244
- if (!modelElement) {
245
- // Revert consumed figure so other features can convert it.
246
- conversionApi.consumable.revert(data.viewItem, { name: true, classes: 'media' });
247
- }
248
- };
249
- dispatcher.on('element:figure', converter);
250
- });
251
- }
252
- }
@@ -1,50 +0,0 @@
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
- /**
6
- * @module media-embed/mediaembedtoolbar
7
- */
8
- import { Plugin } from 'ckeditor5/src/core.js';
9
- import { WidgetToolbarRepository } from 'ckeditor5/src/widget.js';
10
- import { getSelectedMediaViewWidget } from './utils.js';
11
- import './mediaembedconfig.js';
12
- /**
13
- * The media embed toolbar plugin. It creates a toolbar for media embed that shows up when the media element is selected.
14
- *
15
- * Instances of toolbar components (e.g. buttons) are created based on the
16
- * {@link module:media-embed/mediaembedconfig~MediaEmbedConfig#toolbar `media.toolbar` configuration option}.
17
- */
18
- export class MediaEmbedToolbar extends Plugin {
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
- static get isOfficialPlugin() {
35
- return true;
36
- }
37
- /**
38
- * @inheritDoc
39
- */
40
- afterInit() {
41
- const editor = this.editor;
42
- const t = editor.t;
43
- const widgetToolbarRepository = editor.plugins.get(WidgetToolbarRepository);
44
- widgetToolbarRepository.register('mediaEmbed', {
45
- ariaLabel: t('Media toolbar'),
46
- items: editor.config.get('mediaEmbed.toolbar') || [],
47
- getRelatedElement: getSelectedMediaViewWidget
48
- });
49
- }
50
- }
@@ -1,134 +0,0 @@
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
- /**
6
- * @module media-embed/mediaembedui
7
- */
8
- import { Plugin } from 'ckeditor5/src/core.js';
9
- import { IconMedia } from 'ckeditor5/src/icons.js';
10
- import { ButtonView, CssTransitionDisablerMixin, MenuBarMenuListItemButtonView, Dialog } from 'ckeditor5/src/ui.js';
11
- import { MediaFormView } from './ui/mediaformview.js';
12
- import { MediaEmbedEditing } from './mediaembedediting.js';
13
- /**
14
- * The media embed UI plugin.
15
- */
16
- export class MediaEmbedUI extends Plugin {
17
- /**
18
- * @inheritDoc
19
- */
20
- static get requires() {
21
- return [MediaEmbedEditing, Dialog];
22
- }
23
- /**
24
- * @inheritDoc
25
- */
26
- static get pluginName() {
27
- return 'MediaEmbedUI';
28
- }
29
- /**
30
- * @inheritDoc
31
- */
32
- static get isOfficialPlugin() {
33
- return true;
34
- }
35
- _formView;
36
- /**
37
- * @inheritDoc
38
- */
39
- init() {
40
- const editor = this.editor;
41
- editor.ui.componentFactory.add('mediaEmbed', () => {
42
- const t = this.editor.locale.t;
43
- const button = this._createDialogButton(ButtonView);
44
- button.tooltip = true;
45
- button.label = t('Insert media');
46
- return button;
47
- });
48
- editor.ui.componentFactory.add('menuBar:mediaEmbed', () => {
49
- const t = this.editor.locale.t;
50
- const button = this._createDialogButton(MenuBarMenuListItemButtonView);
51
- button.label = t('Media');
52
- return button;
53
- });
54
- }
55
- /**
56
- * Creates a button for menu bar that will show media embed dialog.
57
- */
58
- _createDialogButton(ButtonClass) {
59
- const editor = this.editor;
60
- const buttonView = new ButtonClass(editor.locale);
61
- const command = editor.commands.get('mediaEmbed');
62
- const dialogPlugin = this.editor.plugins.get('Dialog');
63
- buttonView.icon = IconMedia;
64
- buttonView.bind('isEnabled').to(command, 'isEnabled');
65
- buttonView.on('execute', () => {
66
- if (dialogPlugin.id === 'mediaEmbed') {
67
- dialogPlugin.hide();
68
- }
69
- else {
70
- this._showDialog();
71
- }
72
- });
73
- return buttonView;
74
- }
75
- _showDialog() {
76
- const editor = this.editor;
77
- const dialog = editor.plugins.get('Dialog');
78
- const command = editor.commands.get('mediaEmbed');
79
- const t = editor.locale.t;
80
- const isMediaSelected = command.value !== undefined;
81
- if (!this._formView) {
82
- const registry = editor.plugins.get(MediaEmbedEditing).registry;
83
- this._formView = new (CssTransitionDisablerMixin(MediaFormView))(getFormValidators(editor.t, registry), editor.locale);
84
- this._formView.on('submit', () => this._handleSubmitForm());
85
- }
86
- dialog.show({
87
- id: 'mediaEmbed',
88
- title: t('Media embed'),
89
- content: this._formView,
90
- isModal: true,
91
- onShow: () => {
92
- this._formView.url = command.value || '';
93
- this._formView.resetFormStatus();
94
- this._formView.urlInputView.fieldView.select();
95
- },
96
- actionButtons: [
97
- {
98
- label: t('Cancel'),
99
- withText: true,
100
- onExecute: () => dialog.hide()
101
- },
102
- {
103
- label: isMediaSelected ? t('Save') : t('Insert'),
104
- class: 'ck-button-action',
105
- withText: true,
106
- onExecute: () => this._handleSubmitForm()
107
- }
108
- ]
109
- });
110
- }
111
- _handleSubmitForm() {
112
- const editor = this.editor;
113
- const dialog = editor.plugins.get('Dialog');
114
- if (this._formView.isValid()) {
115
- editor.execute('mediaEmbed', this._formView.url);
116
- dialog.hide();
117
- editor.editing.view.focus();
118
- }
119
- }
120
- }
121
- function getFormValidators(t, registry) {
122
- return [
123
- form => {
124
- if (!form.url.length) {
125
- return t('The URL must not be empty.');
126
- }
127
- },
128
- form => {
129
- if (!registry.hasMedia(form.url)) {
130
- return t('This media URL is not supported.');
131
- }
132
- }
133
- ];
134
- }