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/mediaembedcommand
|
8 | */
|
9 |
|
10 | import { Command } from 'ckeditor5/src/core';
|
11 | import { findOptimalInsertionRange } from 'ckeditor5/src/widget';
|
12 | import { getSelectedMediaModelWidget, insertMedia } from './utils';
|
13 |
|
14 | /**
|
15 | * The insert media command.
|
16 | *
|
17 | * The command is registered by the {@link module:media-embed/mediaembedediting~MediaEmbedEditing} as `'mediaEmbed'`.
|
18 | *
|
19 | * To insert media at the current selection, execute the command and specify the URL:
|
20 | *
|
21 | * editor.execute( 'mediaEmbed', 'http://url.to.the/media' );
|
22 | *
|
23 | * @extends module:core/command~Command
|
24 | */
|
25 | export default class MediaEmbedCommand extends Command {
|
26 | /**
|
27 | * @inheritDoc
|
28 | */
|
29 | refresh() {
|
30 | const model = this.editor.model;
|
31 | const selection = model.document.selection;
|
32 | const selectedMedia = getSelectedMediaModelWidget( selection );
|
33 |
|
34 | this.value = selectedMedia ? selectedMedia.getAttribute( 'url' ) : null;
|
35 |
|
36 | this.isEnabled = isMediaSelected( selection ) || isAllowedInParent( selection, model );
|
37 | }
|
38 |
|
39 | /**
|
40 | * Executes the command, which either:
|
41 | *
|
42 | * * updates the URL of the selected media,
|
43 | * * inserts the new media into the editor and puts the selection around it.
|
44 | *
|
45 | * @fires execute
|
46 | * @param {String} url The URL of the media.
|
47 | */
|
48 | execute( url ) {
|
49 | const model = this.editor.model;
|
50 | const selection = model.document.selection;
|
51 | const selectedMedia = getSelectedMediaModelWidget( selection );
|
52 |
|
53 | if ( selectedMedia ) {
|
54 | model.change( writer => {
|
55 | writer.setAttribute( 'url', url, selectedMedia );
|
56 | } );
|
57 | } else {
|
58 | insertMedia( model, url, selection, true );
|
59 | }
|
60 | }
|
61 | }
|
62 |
|
63 | // Checks if the table is allowed in the parent.
|
64 | //
|
65 | // @param {module:engine/model/selection~Selection|module:engine/model/documentselection~DocumentSelection} selection
|
66 | // @param {module:engine/model/model~Model} model
|
67 | // @returns {Boolean}
|
68 | function isAllowedInParent( selection, model ) {
|
69 | const insertionRange = findOptimalInsertionRange( selection, model );
|
70 | let parent = insertionRange.start.parent;
|
71 |
|
72 | // The model.insertContent() will remove empty parent (unless it is a $root or a limit).
|
73 | if ( parent.isEmpty && !model.schema.isLimit( parent ) ) {
|
74 | parent = parent.parent;
|
75 | }
|
76 |
|
77 | return model.schema.checkChild( parent, 'media' );
|
78 | }
|
79 |
|
80 | // Checks if the media object is selected.
|
81 | //
|
82 | // @param {module:engine/model/selection~Selection|module:engine/model/documentselection~DocumentSelection} selection
|
83 | // @returns {Boolean}
|
84 | function isMediaSelected( selection ) {
|
85 | const element = selection.getSelectedElement();
|
86 | return !!element && element.name === 'media';
|
87 | }
|