UNPKG

3.85 kBJavaScriptView Raw
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/mediaembedui
8 */
9
10import { Plugin } from 'ckeditor5/src/core';
11import { createDropdown } from 'ckeditor5/src/ui';
12
13import MediaFormView from './ui/mediaformview';
14import MediaEmbedEditing from './mediaembedediting';
15import mediaIcon from '../theme/icons/media.svg';
16
17/**
18 * The media embed UI plugin.
19 *
20 * @extends module:core/plugin~Plugin
21 */
22export default class MediaEmbedUI extends Plugin {
23 /**
24 * @inheritDoc
25 */
26 static get requires() {
27 return [ MediaEmbedEditing ];
28 }
29
30 /**
31 * @inheritDoc
32 */
33 static get pluginName() {
34 return 'MediaEmbedUI';
35 }
36
37 /**
38 * @inheritDoc
39 */
40 init() {
41 const editor = this.editor;
42 const command = editor.commands.get( 'mediaEmbed' );
43 const registry = editor.plugins.get( MediaEmbedEditing ).registry;
44
45 editor.ui.componentFactory.add( 'mediaEmbed', locale => {
46 const dropdown = createDropdown( locale );
47
48 const mediaForm = new MediaFormView( getFormValidators( editor.t, registry ), editor.locale );
49
50 this._setUpDropdown( dropdown, mediaForm, command, editor );
51 this._setUpForm( dropdown, mediaForm, command );
52
53 return dropdown;
54 } );
55 }
56
57 /**
58 * @private
59 * @param {module:ui/dropdown/dropdownview~DropdownView} dropdown
60 * @param {module:ui/view~View} form
61 * @param {module:media-embed/mediaembedcommand~MediaEmbedCommand} command
62 */
63 _setUpDropdown( dropdown, form, command ) {
64 const editor = this.editor;
65 const t = editor.t;
66 const button = dropdown.buttonView;
67
68 dropdown.bind( 'isEnabled' ).to( command );
69 dropdown.panelView.children.add( form );
70
71 button.set( {
72 label: t( 'Insert media' ),
73 icon: mediaIcon,
74 tooltip: true
75 } );
76
77 // Note: Use the low priority to make sure the following listener starts working after the
78 // default action of the drop-down is executed (i.e. the panel showed up). Otherwise, the
79 // invisible form/input cannot be focused/selected.
80 button.on( 'open', () => {
81 form.disableCssTransitions();
82
83 // Make sure that each time the panel shows up, the URL field remains in sync with the value of
84 // the command. If the user typed in the input, then canceled (`urlInputView#fieldView#value` stays
85 // unaltered) and re-opened it without changing the value of the media command (e.g. because they
86 // didn't change the selection), they would see the old value instead of the actual value of the
87 // command.
88 form.url = command.value || '';
89 form.urlInputView.fieldView.select();
90 form.focus();
91 form.enableCssTransitions();
92 }, { priority: 'low' } );
93
94 dropdown.on( 'submit', () => {
95 if ( form.isValid() ) {
96 editor.execute( 'mediaEmbed', form.url );
97 closeUI();
98 }
99 } );
100
101 dropdown.on( 'change:isOpen', () => form.resetFormStatus() );
102 dropdown.on( 'cancel', () => closeUI() );
103
104 function closeUI() {
105 editor.editing.view.focus();
106 dropdown.isOpen = false;
107 }
108 }
109
110 /**
111 * @private
112 * @param {module:ui/dropdown/dropdownview~DropdownView} dropdown
113 * @param {module:ui/view~View} form
114 * @param {module:media-embed/mediaembedcommand~MediaEmbedCommand} command
115 */
116 _setUpForm( dropdown, form, command ) {
117 form.delegate( 'submit', 'cancel' ).to( dropdown );
118 form.urlInputView.bind( 'value' ).to( command, 'value' );
119
120 // Form elements should be read-only when corresponding commands are disabled.
121 form.urlInputView.bind( 'isReadOnly' ).to( command, 'isEnabled', value => !value );
122 }
123}
124
125function getFormValidators( t, registry ) {
126 return [
127 form => {
128 if ( !form.url.length ) {
129 return t( 'The URL must not be empty.' );
130 }
131 },
132 form => {
133 if ( !registry.hasMedia( form.url ) ) {
134 return t( 'This media URL is not supported.' );
135 }
136 }
137 ];
138}