1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 | import { ButtonView, View, ViewCollection, FocusCycler } from 'ckeditor5/src/ui';
|
9 | import { FocusTracker, KeystrokeHandler } from 'ckeditor5/src/utils';
|
10 | import { icons } from 'ckeditor5/src/core';
|
11 | import { ensureSafeUrl } from '../utils';
|
12 |
|
13 |
|
14 | import '@ckeditor/ckeditor5-ui/theme/components/responsive-form/responsiveform.css';
|
15 | import '../../theme/linkactions.css';
|
16 | import unlinkIcon from '../../theme/icons/unlink.svg';
|
17 |
|
18 |
|
19 |
|
20 |
|
21 | export default class LinkActionsView extends View {
|
22 | |
23 |
|
24 |
|
25 | constructor(locale) {
|
26 | super(locale);
|
27 | |
28 |
|
29 |
|
30 | this.focusTracker = new FocusTracker();
|
31 | |
32 |
|
33 |
|
34 | this.keystrokes = new KeystrokeHandler();
|
35 | |
36 |
|
37 |
|
38 | this._focusables = new ViewCollection();
|
39 | const t = locale.t;
|
40 | this.previewButtonView = this._createPreviewButton();
|
41 | this.unlinkButtonView = this._createButton(t('Unlink'), unlinkIcon, 'unlink');
|
42 | this.editButtonView = this._createButton(t('Edit link'), icons.pencil, 'edit');
|
43 | this.set('href', undefined);
|
44 | this._focusCycler = new FocusCycler({
|
45 | focusables: this._focusables,
|
46 | focusTracker: this.focusTracker,
|
47 | keystrokeHandler: this.keystrokes,
|
48 | actions: {
|
49 |
|
50 | focusPrevious: 'shift + tab',
|
51 |
|
52 | focusNext: 'tab'
|
53 | }
|
54 | });
|
55 | this.setTemplate({
|
56 | tag: 'div',
|
57 | attributes: {
|
58 | class: [
|
59 | 'ck',
|
60 | 'ck-link-actions',
|
61 | 'ck-responsive-form'
|
62 | ],
|
63 |
|
64 | tabindex: '-1'
|
65 | },
|
66 | children: [
|
67 | this.previewButtonView,
|
68 | this.editButtonView,
|
69 | this.unlinkButtonView
|
70 | ]
|
71 | });
|
72 | }
|
73 | |
74 |
|
75 |
|
76 | render() {
|
77 | super.render();
|
78 | const childViews = [
|
79 | this.previewButtonView,
|
80 | this.editButtonView,
|
81 | this.unlinkButtonView
|
82 | ];
|
83 | childViews.forEach(v => {
|
84 |
|
85 | this._focusables.add(v);
|
86 |
|
87 | this.focusTracker.add(v.element);
|
88 | });
|
89 |
|
90 | this.keystrokes.listenTo(this.element);
|
91 | }
|
92 | |
93 |
|
94 |
|
95 | destroy() {
|
96 | super.destroy();
|
97 | this.focusTracker.destroy();
|
98 | this.keystrokes.destroy();
|
99 | }
|
100 | |
101 |
|
102 |
|
103 | focus() {
|
104 | this._focusCycler.focusFirst();
|
105 | }
|
106 | |
107 |
|
108 |
|
109 |
|
110 |
|
111 |
|
112 |
|
113 |
|
114 | _createButton(label, icon, eventName) {
|
115 | const button = new ButtonView(this.locale);
|
116 | button.set({
|
117 | label,
|
118 | icon,
|
119 | tooltip: true
|
120 | });
|
121 | button.delegate('execute').to(this, eventName);
|
122 | return button;
|
123 | }
|
124 | |
125 |
|
126 |
|
127 |
|
128 |
|
129 | _createPreviewButton() {
|
130 | const button = new ButtonView(this.locale);
|
131 | const bind = this.bindTemplate;
|
132 | const t = this.t;
|
133 | button.set({
|
134 | withText: true,
|
135 | tooltip: t('Open link in new tab')
|
136 | });
|
137 | button.extendTemplate({
|
138 | attributes: {
|
139 | class: [
|
140 | 'ck',
|
141 | 'ck-link-actions__preview'
|
142 | ],
|
143 | href: bind.to('href', href => href && ensureSafeUrl(href)),
|
144 | target: '_blank',
|
145 | rel: 'noopener noreferrer'
|
146 | }
|
147 | });
|
148 | button.bind('label').to(this, 'href', href => {
|
149 | return href || t('This link has no URL');
|
150 | });
|
151 | button.bind('isEnabled').to(this, 'href', href => !!href);
|
152 | button.template.tag = 'a';
|
153 | button.template.eventListeners = {};
|
154 | return button;
|
155 | }
|
156 | }
|