1 | /**
|
2 | * @license Copyright (c) 2003-2022, 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 | /**
|
7 | * @module media-embed/mediaembed
|
8 | */
|
9 |
|
10 | import { Plugin } from 'ckeditor5/src/core';
|
11 | import { Widget } from 'ckeditor5/src/widget';
|
12 |
|
13 | import MediaEmbedEditing from './mediaembedediting';
|
14 | import AutoMediaEmbed from './automediaembed';
|
15 | import MediaEmbedUI from './mediaembedui';
|
16 |
|
17 | import '../theme/mediaembed.css';
|
18 |
|
19 | /**
|
20 | * The media embed plugin.
|
21 | *
|
22 | * For a detailed overview, check the {@glink features/media-embed Media Embed feature documentation}.
|
23 | *
|
24 | * This is a "glue" plugin which loads the following plugins:
|
25 | *
|
26 | * * The {@link module:media-embed/mediaembedediting~MediaEmbedEditing media embed editing feature},
|
27 | * * The {@link module:media-embed/mediaembedui~MediaEmbedUI media embed UI feature} and
|
28 | * * The {@link module:media-embed/automediaembed~AutoMediaEmbed auto-media embed feature}.
|
29 | *
|
30 | * @extends module:core/plugin~Plugin
|
31 | */
|
32 | export default class MediaEmbed extends Plugin {
|
33 | /**
|
34 | * @inheritDoc
|
35 | */
|
36 | static get requires() {
|
37 | return [ MediaEmbedEditing, MediaEmbedUI, AutoMediaEmbed, Widget ];
|
38 | }
|
39 |
|
40 | /**
|
41 | * @inheritDoc
|
42 | */
|
43 | static get pluginName() {
|
44 | return 'MediaEmbed';
|
45 | }
|
46 | }
|
47 |
|
48 | /**
|
49 | * The media embed provider descriptor. Used in
|
50 | * {@link module:media-embed/mediaembed~MediaEmbedConfig#providers `config.mediaEmbed.providers`} and
|
51 | * {@link module:media-embed/mediaembed~MediaEmbedConfig#extraProviders `config.mediaEmbed.extraProviders`}.
|
52 | *
|
53 | * See {@link module:media-embed/mediaembed~MediaEmbedConfig} to learn more.
|
54 | *
|
55 | * {
|
56 | * name: 'example',
|
57 | *
|
58 | * // The following RegExp matches https://www.example.com/media/{media id},
|
59 | * // (either with "http(s)://" and "www" or without), so the valid URLs are:
|
60 | * //
|
61 | * // * https://www.example.com/media/{media id},
|
62 | * // * http://www.example.com/media/{media id},
|
63 | * // * www.example.com/media/{media id},
|
64 | * // * example.com/media/{media id}
|
65 | * url: /^example\.com\/media\/(\w+)/,
|
66 | *
|
67 | * // The rendering function of the provider.
|
68 | * // Used to represent the media when editing the content (i.e. in the view)
|
69 | * // and also in the data output of the editor if semantic data output is disabled.
|
70 | * html: match => `The HTML representing the media with ID=${ match[ 1 ] }.`
|
71 | * }
|
72 | *
|
73 | * You can allow any sort of media in the editor using the "allow–all" `RegExp`.
|
74 | * But mind that, since URLs are processed in the order of configuration, if one of the previous
|
75 | * `RegExps` matches the URL, it will have a precedence over this one.
|
76 | *
|
77 | * {
|
78 | * name: 'allow-all',
|
79 | * url: /^.+/
|
80 | * }
|
81 | *
|
82 | * To implement responsive media, you can use the following HTML structure:
|
83 | *
|
84 | * {
|
85 | * ...
|
86 | * html: match =>
|
87 | * '<div style="position:relative; padding-bottom:100%; height:0">' +
|
88 | * '<iframe src="..." frameborder="0" ' +
|
89 | * 'style="position:absolute; width:100%; height:100%; top:0; left:0">' +
|
90 | * '</iframe>' +
|
91 | * '</div>'
|
92 | * }
|
93 | *
|
94 | * @typedef {Object} module:media-embed/mediaembed~MediaEmbedProvider
|
95 | * @property {String} name The name of the provider. Used e.g. when
|
96 | * {@link module:media-embed/mediaembed~MediaEmbedConfig#removeProviders removing providers}.
|
97 | * @property {RegExp|Array.<RegExp>} url The `RegExp` object (or array of objects) defining the URL of the media.
|
98 | * If any URL matches the `RegExp`, it becomes the media in the editor model, as defined by the provider. The result
|
99 | * of matching (output of `String.prototype.match()`) is passed to the `html` rendering function of the media.
|
100 | *
|
101 | * **Note:** You do not need to include the protocol (`http://`, `https://`) and `www` subdomain in your `RegExps`,
|
102 | * they are stripped from the URLs before matching anyway.
|
103 | * @property {Function} [html] (optional) The rendering function of the media. The function receives the entire matching
|
104 | * array from the corresponding `url` `RegExp` as an argument, allowing rendering a dedicated
|
105 | * preview of the media identified by a certain ID or a hash. When not defined, the media embed feature
|
106 | * will use a generic media representation in the view and output data.
|
107 | * Note that when
|
108 | * {@link module:media-embed/mediaembed~MediaEmbedConfig#previewsInData `config.mediaEmbed.previewsInData`}
|
109 | * is `true`, the rendering function **will always** be used for the media in the editor data output.
|
110 | */
|
111 |
|
112 | /**
|
113 | * The configuration of the {@link module:media-embed/mediaembed~MediaEmbed} feature.
|
114 | *
|
115 | * Read more in {@link module:media-embed/mediaembed~MediaEmbedConfig}.
|
116 | *
|
117 | * @member {module:media-embed/mediaembed~MediaEmbedConfig} module:core/editor/editorconfig~EditorConfig#mediaEmbed
|
118 | */
|
119 |
|
120 | /**
|
121 | * The configuration of the media embed features.
|
122 | *
|
123 | * Read more about {@glink features/media-embed#configuration configuring the media embed feature}.
|
124 | *
|
125 | * ClassicEditor
|
126 | * .create( editorElement, {
|
127 | * mediaEmbed: ... // Media embed feature options.
|
128 | * } )
|
129 | * .then( ... )
|
130 | * .catch( ... );
|
131 | *
|
132 | * See {@link module:core/editor/editorconfig~EditorConfig all editor options}.
|
133 | *
|
134 | * @interface MediaEmbedConfig
|
135 | */
|
136 |
|
137 | /**
|
138 | * The default media providers supported by the editor.
|
139 | *
|
140 | * The names of providers with rendering functions (previews):
|
141 | *
|
142 | * * "dailymotion",
|
143 | * * "spotify",
|
144 | * * "youtube",
|
145 | * * "vimeo"
|
146 | *
|
147 | * The names of providers without rendering functions:
|
148 | *
|
149 | * * "instagram",
|
150 | * * "twitter",
|
151 | * * "googleMaps",
|
152 | * * "flickr",
|
153 | * * "facebook"
|
154 | *
|
155 | * See the {@link module:media-embed/mediaembed~MediaEmbedProvider provider syntax} to learn more about
|
156 | * different kinds of media and media providers.
|
157 | *
|
158 | * **Note**: The default media provider configuration may not support all possible media URLs,
|
159 | * only the most common are included.
|
160 | *
|
161 | * Media without rendering functions are always represented in the data using the "semantic" markup. See
|
162 | * {@link module:media-embed/mediaembed~MediaEmbedConfig#previewsInData `config.mediaEmbed.previewsInData`} to
|
163 | * learn more about possible data outputs.
|
164 | *
|
165 | * The priority of media providers corresponds to the order of configuration. The first provider
|
166 | * to match the URL is always used, even if there are other providers that support a particular URL.
|
167 | * The URL is never matched against the remaining providers.
|
168 | *
|
169 | * To discard **all** default media providers, simply override this configuration with your own
|
170 | * {@link module:media-embed/mediaembed~MediaEmbedProvider definitions}:
|
171 | *
|
172 | * ClassicEditor
|
173 | * .create( editorElement, {
|
174 | * plugins: [ MediaEmbed, ... ],
|
175 | * mediaEmbed: {
|
176 | * providers: [
|
177 | * {
|
178 | * name: 'myProvider',
|
179 | * url: /^example\.com\/media\/(\w+)/,
|
180 | * html: match => '...'
|
181 | * },
|
182 | * ...
|
183 | * ]
|
184 | * }
|
185 | * } )
|
186 | * .then( ... )
|
187 | * .catch( ... );
|
188 | *
|
189 | * You can take inspiration from the default configuration of this feature which you can find in:
|
190 | * https://github.com/ckeditor/ckeditor5-media-embed/blob/master/src/mediaembedediting.js
|
191 | *
|
192 | * To **extend** the list of default providers, use
|
193 | * {@link module:media-embed/mediaembed~MediaEmbedConfig#extraProviders `config.mediaEmbed.extraProviders`}.
|
194 | *
|
195 | * To **remove** certain providers, use
|
196 | * {@link module:media-embed/mediaembed~MediaEmbedConfig#removeProviders `config.mediaEmbed.removeProviders`}.
|
197 | *
|
198 | * @member {Array.<module:media-embed/mediaembed~MediaEmbedProvider>} module:media-embed/mediaembed~MediaEmbedConfig#providers
|
199 | */
|
200 |
|
201 | /**
|
202 | * The additional media providers supported by the editor. This configuration helps extend the default
|
203 | * {@link module:media-embed/mediaembed~MediaEmbedConfig#providers}.
|
204 | *
|
205 | * ClassicEditor
|
206 | * .create( editorElement, {
|
207 | * plugins: [ MediaEmbed, ... ],
|
208 | * mediaEmbed: {
|
209 | * extraProviders: [
|
210 | * {
|
211 | * name: 'extraProvider',
|
212 | * url: /^example\.com\/media\/(\w+)/,
|
213 | * html: match => '...'
|
214 | * },
|
215 | * ...
|
216 | * ]
|
217 | * }
|
218 | * } )
|
219 | * .then( ... )
|
220 | * .catch( ... );
|
221 | *
|
222 | * See the {@link module:media-embed/mediaembed~MediaEmbedProvider provider syntax} to learn more.
|
223 | *
|
224 | * @member {Array.<module:media-embed/mediaembed~MediaEmbedProvider>} module:media-embed/mediaembed~MediaEmbedConfig#extraProviders
|
225 | */
|
226 |
|
227 | /**
|
228 | * The list of media providers that should not be used despite being available in
|
229 | * {@link module:media-embed/mediaembed~MediaEmbedConfig#providers `config.mediaEmbed.providers`} and
|
230 | * {@link module:media-embed/mediaembed~MediaEmbedConfig#extraProviders `config.mediaEmbed.extraProviders`}
|
231 | *
|
232 | * mediaEmbed: {
|
233 | * removeProviders: [ 'youtube', 'twitter' ]
|
234 | * }
|
235 | *
|
236 | * @member {Array.<String>} module:media-embed/mediaembed~MediaEmbedConfig#removeProviders
|
237 | */
|
238 |
|
239 | /**
|
240 | * Overrides the element name used for "semantic" data.
|
241 | *
|
242 | * This is not relevant if {@link module:media-embed/mediaembed~MediaEmbedConfig#previewsInData `config.mediaEmbed.previewsInData`}
|
243 | * is set to `true`.
|
244 | *
|
245 | * When not set, the feature produces the `<oembed>` tag:
|
246 | *
|
247 | * <figure class="media">
|
248 | * <oembed url="https://url"></oembed>
|
249 | * </figure>
|
250 | *
|
251 | * To override the element name with, for instance, the `o-embed` name:
|
252 | *
|
253 | * mediaEmbed: {
|
254 | * elementName: 'o-embed'
|
255 | * }
|
256 | *
|
257 | * This will produce semantic data with the `<o-embed>` tag:
|
258 | *
|
259 | * <figure class="media">
|
260 | * <o-embed url="https://url"></o-embed>
|
261 | * </figure>
|
262 | *
|
263 | * @default 'oembed'
|
264 | * @member {String} [module:media-embed/mediaembed~MediaEmbedConfig#elementName]
|
265 | */
|
266 |
|
267 | /**
|
268 | * Controls the data format produced by the feature.
|
269 | *
|
270 | * When `false` (default), the feature produces "semantic" data, i.e. it does not include the preview of
|
271 | * the media, just the `<oembed>` tag with the `url` attribute:
|
272 | *
|
273 | * <figure class="media">
|
274 | * <oembed url="https://url"></oembed>
|
275 | * </figure>
|
276 | *
|
277 | * When `true`, the media is represented in the output in the same way it looks in the editor,
|
278 | * i.e. the media preview is saved to the database:
|
279 | *
|
280 | * <figure class="media">
|
281 | * <div data-oembed-url="https://url">
|
282 | * <iframe src="https://preview"></iframe>
|
283 | * </div>
|
284 | * </figure>
|
285 | *
|
286 | * **Note:** Media without preview are always represented in the data using the "semantic" markup
|
287 | * regardless of the value of the `previewsInData`. Learn more about different kinds of media
|
288 | * in the {@link module:media-embed/mediaembed~MediaEmbedConfig#providers `config.mediaEmbed.providers`}
|
289 | * configuration description.
|
290 | *
|
291 | * @member {Boolean} [module:media-embed/mediaembed~MediaEmbedConfig#previewsInData=false]
|
292 | */
|