UNPKG

4.12 kBJavaScriptView Raw
1/**
2 * @license Copyright (c) 2003-2024, 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 image/imageinsert/ui/imageinsertformview
7 */
8import { View, ViewCollection, submitHandler, FocusCycler, CollapsibleView } from 'ckeditor5/src/ui.js';
9import { FocusTracker, KeystrokeHandler } from 'ckeditor5/src/utils.js';
10import '../../../theme/imageinsert.css';
11/**
12 * The view displayed in the insert image dropdown.
13 *
14 * See {@link module:image/imageinsert/imageinsertui~ImageInsertUI}.
15 */
16export default class ImageInsertFormView extends View {
17 /**
18 * Creates a view for the dropdown panel of {@link module:image/imageinsert/imageinsertui~ImageInsertUI}.
19 *
20 * @param locale The localization services instance.
21 * @param integrations An integrations object that contains components (or tokens for components) to be shown in the panel view.
22 */
23 constructor(locale, integrations = []) {
24 super(locale);
25 this.focusTracker = new FocusTracker();
26 this.keystrokes = new KeystrokeHandler();
27 this._focusables = new ViewCollection();
28 this.children = this.createCollection();
29 this._focusCycler = new FocusCycler({
30 focusables: this._focusables,
31 focusTracker: this.focusTracker,
32 keystrokeHandler: this.keystrokes,
33 actions: {
34 // Navigate form fields backwards using the Shift + Tab keystroke.
35 focusPrevious: 'shift + tab',
36 // Navigate form fields forwards using the Tab key.
37 focusNext: 'tab'
38 }
39 });
40 for (const view of integrations) {
41 this.children.add(view);
42 this._focusables.add(view);
43 if (view instanceof CollapsibleView) {
44 this._focusables.addMany(view.children);
45 }
46 }
47 if (this._focusables.length > 1) {
48 for (const view of this._focusables) {
49 if (isViewWithFocusCycler(view)) {
50 view.focusCycler.on('forwardCycle', evt => {
51 this._focusCycler.focusNext();
52 evt.stop();
53 });
54 view.focusCycler.on('backwardCycle', evt => {
55 this._focusCycler.focusPrevious();
56 evt.stop();
57 });
58 }
59 }
60 }
61 this.setTemplate({
62 tag: 'form',
63 attributes: {
64 class: [
65 'ck',
66 'ck-image-insert-form'
67 ],
68 tabindex: -1
69 },
70 children: this.children
71 });
72 }
73 /**
74 * @inheritDoc
75 */
76 render() {
77 super.render();
78 submitHandler({
79 view: this
80 });
81 for (const view of this._focusables) {
82 this.focusTracker.add(view.element);
83 }
84 // Start listening for the keystrokes coming from #element.
85 this.keystrokes.listenTo(this.element);
86 const stopPropagation = (data) => data.stopPropagation();
87 // Since the form is in the dropdown panel which is a child of the toolbar, the toolbar's
88 // keystroke handler would take over the key management in the URL input. We need to prevent
89 // this ASAP. Otherwise, the basic caret movement using the arrow keys will be impossible.
90 this.keystrokes.set('arrowright', stopPropagation);
91 this.keystrokes.set('arrowleft', stopPropagation);
92 this.keystrokes.set('arrowup', stopPropagation);
93 this.keystrokes.set('arrowdown', stopPropagation);
94 }
95 /**
96 * @inheritDoc
97 */
98 destroy() {
99 super.destroy();
100 this.focusTracker.destroy();
101 this.keystrokes.destroy();
102 }
103 /**
104 * Focuses the first {@link #_focusables focusable} in the form.
105 */
106 focus() {
107 this._focusCycler.focusFirst();
108 }
109}
110function isViewWithFocusCycler(view) {
111 return 'focusCycler' in view;
112}