@ckeditor/ckeditor5-bookmark 0.0.1 → 44.0.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -0
- package/LICENSE.md +4 -5
- package/README.md +31 -3
- package/build/bookmark.js +5 -0
- package/build/translations/af.js +1 -0
- package/build/translations/ar.js +1 -0
- package/build/translations/ast.js +1 -0
- package/build/translations/az.js +1 -0
- package/build/translations/bg.js +1 -0
- package/build/translations/bn.js +1 -0
- package/build/translations/bs.js +1 -0
- package/build/translations/ca.js +1 -0
- package/build/translations/cs.js +1 -0
- package/build/translations/da.js +1 -0
- package/build/translations/de-ch.js +1 -0
- package/build/translations/de.js +1 -0
- package/build/translations/el.js +1 -0
- package/build/translations/en-au.js +1 -0
- package/build/translations/en-gb.js +1 -0
- package/build/translations/eo.js +1 -0
- package/build/translations/es-co.js +1 -0
- package/build/translations/es.js +1 -0
- package/build/translations/et.js +1 -0
- package/build/translations/eu.js +1 -0
- package/build/translations/fa.js +1 -0
- package/build/translations/fi.js +1 -0
- package/build/translations/fr.js +1 -0
- package/build/translations/gl.js +1 -0
- package/build/translations/gu.js +1 -0
- package/build/translations/he.js +1 -0
- package/build/translations/hi.js +1 -0
- package/build/translations/hr.js +1 -0
- package/build/translations/hu.js +1 -0
- package/build/translations/hy.js +1 -0
- package/build/translations/id.js +1 -0
- package/build/translations/it.js +1 -0
- package/build/translations/ja.js +1 -0
- package/build/translations/jv.js +1 -0
- package/build/translations/kk.js +1 -0
- package/build/translations/km.js +1 -0
- package/build/translations/kn.js +1 -0
- package/build/translations/ko.js +1 -0
- package/build/translations/ku.js +1 -0
- package/build/translations/lt.js +1 -0
- package/build/translations/lv.js +1 -0
- package/build/translations/ms.js +1 -0
- package/build/translations/nb.js +1 -0
- package/build/translations/ne.js +1 -0
- package/build/translations/nl.js +1 -0
- package/build/translations/no.js +1 -0
- package/build/translations/oc.js +1 -0
- package/build/translations/pl.js +1 -0
- package/build/translations/pt-br.js +1 -0
- package/build/translations/pt.js +1 -0
- package/build/translations/ro.js +1 -0
- package/build/translations/ru.js +1 -0
- package/build/translations/si.js +1 -0
- package/build/translations/sk.js +1 -0
- package/build/translations/sl.js +1 -0
- package/build/translations/sq.js +1 -0
- package/build/translations/sr-latn.js +1 -0
- package/build/translations/sr.js +1 -0
- package/build/translations/sv.js +1 -0
- package/build/translations/th.js +1 -0
- package/build/translations/ti.js +1 -0
- package/build/translations/tk.js +1 -0
- package/build/translations/tr.js +1 -0
- package/build/translations/tt.js +1 -0
- package/build/translations/ug.js +1 -0
- package/build/translations/uk.js +1 -0
- package/build/translations/ur.js +1 -0
- package/build/translations/uz.js +1 -0
- package/build/translations/vi.js +1 -0
- package/build/translations/zh-cn.js +1 -0
- package/build/translations/zh.js +1 -0
- package/ckeditor5-metadata.json +24 -0
- package/dist/augmentation.d.ts +28 -0
- package/dist/bookmark.d.ts +34 -0
- package/dist/bookmarkconfig.d.ts +52 -0
- package/dist/bookmarkediting.d.ts +55 -0
- package/dist/bookmarkui.d.ts +170 -0
- package/dist/index-content.css +4 -0
- package/dist/index-editor.css +150 -0
- package/dist/index.css +195 -0
- package/dist/index.css.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +1320 -0
- package/dist/index.js.map +1 -0
- package/dist/insertbookmarkcommand.d.ts +42 -0
- package/dist/translations/af.d.ts +8 -0
- package/dist/translations/af.js +5 -0
- package/dist/translations/af.umd.js +11 -0
- package/dist/translations/ar.d.ts +8 -0
- package/dist/translations/ar.js +5 -0
- package/dist/translations/ar.umd.js +11 -0
- package/dist/translations/ast.d.ts +8 -0
- package/dist/translations/ast.js +5 -0
- package/dist/translations/ast.umd.js +11 -0
- package/dist/translations/az.d.ts +8 -0
- package/dist/translations/az.js +5 -0
- package/dist/translations/az.umd.js +11 -0
- package/dist/translations/bg.d.ts +8 -0
- package/dist/translations/bg.js +5 -0
- package/dist/translations/bg.umd.js +11 -0
- package/dist/translations/bn.d.ts +8 -0
- package/dist/translations/bn.js +5 -0
- package/dist/translations/bn.umd.js +11 -0
- package/dist/translations/bs.d.ts +8 -0
- package/dist/translations/bs.js +5 -0
- package/dist/translations/bs.umd.js +11 -0
- package/dist/translations/ca.d.ts +8 -0
- package/dist/translations/ca.js +5 -0
- package/dist/translations/ca.umd.js +11 -0
- package/dist/translations/cs.d.ts +8 -0
- package/dist/translations/cs.js +5 -0
- package/dist/translations/cs.umd.js +11 -0
- package/dist/translations/da.d.ts +8 -0
- package/dist/translations/da.js +5 -0
- package/dist/translations/da.umd.js +11 -0
- package/dist/translations/de-ch.d.ts +8 -0
- package/dist/translations/de-ch.js +5 -0
- package/dist/translations/de-ch.umd.js +11 -0
- package/dist/translations/de.d.ts +8 -0
- package/dist/translations/de.js +5 -0
- package/dist/translations/de.umd.js +11 -0
- package/dist/translations/el.d.ts +8 -0
- package/dist/translations/el.js +5 -0
- package/dist/translations/el.umd.js +11 -0
- package/dist/translations/en-au.d.ts +8 -0
- package/dist/translations/en-au.js +5 -0
- package/dist/translations/en-au.umd.js +11 -0
- package/dist/translations/en-gb.d.ts +8 -0
- package/dist/translations/en-gb.js +5 -0
- package/dist/translations/en-gb.umd.js +11 -0
- package/dist/translations/en.d.ts +8 -0
- package/dist/translations/en.js +5 -0
- package/dist/translations/en.umd.js +11 -0
- package/dist/translations/eo.d.ts +8 -0
- package/dist/translations/eo.js +5 -0
- package/dist/translations/eo.umd.js +11 -0
- package/dist/translations/es-co.d.ts +8 -0
- package/dist/translations/es-co.js +5 -0
- package/dist/translations/es-co.umd.js +11 -0
- package/dist/translations/es.d.ts +8 -0
- package/dist/translations/es.js +5 -0
- package/dist/translations/es.umd.js +11 -0
- package/dist/translations/et.d.ts +8 -0
- package/dist/translations/et.js +5 -0
- package/dist/translations/et.umd.js +11 -0
- package/dist/translations/eu.d.ts +8 -0
- package/dist/translations/eu.js +5 -0
- package/dist/translations/eu.umd.js +11 -0
- package/dist/translations/fa.d.ts +8 -0
- package/dist/translations/fa.js +5 -0
- package/dist/translations/fa.umd.js +11 -0
- package/dist/translations/fi.d.ts +8 -0
- package/dist/translations/fi.js +5 -0
- package/dist/translations/fi.umd.js +11 -0
- package/dist/translations/fr.d.ts +8 -0
- package/dist/translations/fr.js +5 -0
- package/dist/translations/fr.umd.js +11 -0
- package/dist/translations/gl.d.ts +8 -0
- package/dist/translations/gl.js +5 -0
- package/dist/translations/gl.umd.js +11 -0
- package/dist/translations/gu.d.ts +8 -0
- package/dist/translations/gu.js +5 -0
- package/dist/translations/gu.umd.js +11 -0
- package/dist/translations/he.d.ts +8 -0
- package/dist/translations/he.js +5 -0
- package/dist/translations/he.umd.js +11 -0
- package/dist/translations/hi.d.ts +8 -0
- package/dist/translations/hi.js +5 -0
- package/dist/translations/hi.umd.js +11 -0
- package/dist/translations/hr.d.ts +8 -0
- package/dist/translations/hr.js +5 -0
- package/dist/translations/hr.umd.js +11 -0
- package/dist/translations/hu.d.ts +8 -0
- package/dist/translations/hu.js +5 -0
- package/dist/translations/hu.umd.js +11 -0
- package/dist/translations/hy.d.ts +8 -0
- package/dist/translations/hy.js +5 -0
- package/dist/translations/hy.umd.js +11 -0
- package/dist/translations/id.d.ts +8 -0
- package/dist/translations/id.js +5 -0
- package/dist/translations/id.umd.js +11 -0
- package/dist/translations/it.d.ts +8 -0
- package/dist/translations/it.js +5 -0
- package/dist/translations/it.umd.js +11 -0
- package/dist/translations/ja.d.ts +8 -0
- package/dist/translations/ja.js +5 -0
- package/dist/translations/ja.umd.js +11 -0
- package/dist/translations/jv.d.ts +8 -0
- package/dist/translations/jv.js +5 -0
- package/dist/translations/jv.umd.js +11 -0
- package/dist/translations/kk.d.ts +8 -0
- package/dist/translations/kk.js +5 -0
- package/dist/translations/kk.umd.js +11 -0
- package/dist/translations/km.d.ts +8 -0
- package/dist/translations/km.js +5 -0
- package/dist/translations/km.umd.js +11 -0
- package/dist/translations/kn.d.ts +8 -0
- package/dist/translations/kn.js +5 -0
- package/dist/translations/kn.umd.js +11 -0
- package/dist/translations/ko.d.ts +8 -0
- package/dist/translations/ko.js +5 -0
- package/dist/translations/ko.umd.js +11 -0
- package/dist/translations/ku.d.ts +8 -0
- package/dist/translations/ku.js +5 -0
- package/dist/translations/ku.umd.js +11 -0
- package/dist/translations/lt.d.ts +8 -0
- package/dist/translations/lt.js +5 -0
- package/dist/translations/lt.umd.js +11 -0
- package/dist/translations/lv.d.ts +8 -0
- package/dist/translations/lv.js +5 -0
- package/dist/translations/lv.umd.js +11 -0
- package/dist/translations/ms.d.ts +8 -0
- package/dist/translations/ms.js +5 -0
- package/dist/translations/ms.umd.js +11 -0
- package/dist/translations/nb.d.ts +8 -0
- package/dist/translations/nb.js +5 -0
- package/dist/translations/nb.umd.js +11 -0
- package/dist/translations/ne.d.ts +8 -0
- package/dist/translations/ne.js +5 -0
- package/dist/translations/ne.umd.js +11 -0
- package/dist/translations/nl.d.ts +8 -0
- package/dist/translations/nl.js +5 -0
- package/dist/translations/nl.umd.js +11 -0
- package/dist/translations/no.d.ts +8 -0
- package/dist/translations/no.js +5 -0
- package/dist/translations/no.umd.js +11 -0
- package/dist/translations/oc.d.ts +8 -0
- package/dist/translations/oc.js +5 -0
- package/dist/translations/oc.umd.js +11 -0
- package/dist/translations/pl.d.ts +8 -0
- package/dist/translations/pl.js +5 -0
- package/dist/translations/pl.umd.js +11 -0
- package/dist/translations/pt-br.d.ts +8 -0
- package/dist/translations/pt-br.js +5 -0
- package/dist/translations/pt-br.umd.js +11 -0
- package/dist/translations/pt.d.ts +8 -0
- package/dist/translations/pt.js +5 -0
- package/dist/translations/pt.umd.js +11 -0
- package/dist/translations/ro.d.ts +8 -0
- package/dist/translations/ro.js +5 -0
- package/dist/translations/ro.umd.js +11 -0
- package/dist/translations/ru.d.ts +8 -0
- package/dist/translations/ru.js +5 -0
- package/dist/translations/ru.umd.js +11 -0
- package/dist/translations/si.d.ts +8 -0
- package/dist/translations/si.js +5 -0
- package/dist/translations/si.umd.js +11 -0
- package/dist/translations/sk.d.ts +8 -0
- package/dist/translations/sk.js +5 -0
- package/dist/translations/sk.umd.js +11 -0
- package/dist/translations/sl.d.ts +8 -0
- package/dist/translations/sl.js +5 -0
- package/dist/translations/sl.umd.js +11 -0
- package/dist/translations/sq.d.ts +8 -0
- package/dist/translations/sq.js +5 -0
- package/dist/translations/sq.umd.js +11 -0
- package/dist/translations/sr-latn.d.ts +8 -0
- package/dist/translations/sr-latn.js +5 -0
- package/dist/translations/sr-latn.umd.js +11 -0
- package/dist/translations/sr.d.ts +8 -0
- package/dist/translations/sr.js +5 -0
- package/dist/translations/sr.umd.js +11 -0
- package/dist/translations/sv.d.ts +8 -0
- package/dist/translations/sv.js +5 -0
- package/dist/translations/sv.umd.js +11 -0
- package/dist/translations/th.d.ts +8 -0
- package/dist/translations/th.js +5 -0
- package/dist/translations/th.umd.js +11 -0
- package/dist/translations/ti.d.ts +8 -0
- package/dist/translations/ti.js +5 -0
- package/dist/translations/ti.umd.js +11 -0
- package/dist/translations/tk.d.ts +8 -0
- package/dist/translations/tk.js +5 -0
- package/dist/translations/tk.umd.js +11 -0
- package/dist/translations/tr.d.ts +8 -0
- package/dist/translations/tr.js +5 -0
- package/dist/translations/tr.umd.js +11 -0
- package/dist/translations/tt.d.ts +8 -0
- package/dist/translations/tt.js +5 -0
- package/dist/translations/tt.umd.js +11 -0
- package/dist/translations/ug.d.ts +8 -0
- package/dist/translations/ug.js +5 -0
- package/dist/translations/ug.umd.js +11 -0
- package/dist/translations/uk.d.ts +8 -0
- package/dist/translations/uk.js +5 -0
- package/dist/translations/uk.umd.js +11 -0
- package/dist/translations/ur.d.ts +8 -0
- package/dist/translations/ur.js +5 -0
- package/dist/translations/ur.umd.js +11 -0
- package/dist/translations/uz.d.ts +8 -0
- package/dist/translations/uz.js +5 -0
- package/dist/translations/uz.umd.js +11 -0
- package/dist/translations/vi.d.ts +8 -0
- package/dist/translations/vi.js +5 -0
- package/dist/translations/vi.umd.js +11 -0
- package/dist/translations/zh-cn.d.ts +8 -0
- package/dist/translations/zh-cn.js +5 -0
- package/dist/translations/zh-cn.umd.js +11 -0
- package/dist/translations/zh.d.ts +8 -0
- package/dist/translations/zh.js +5 -0
- package/dist/translations/zh.umd.js +11 -0
- package/dist/ui/bookmarkactionsview.d.ts +106 -0
- package/dist/ui/bookmarkformview.d.ts +122 -0
- package/dist/updatebookmarkcommand.d.ts +46 -0
- package/dist/utils.d.ts +15 -0
- package/lang/contexts.json +13 -0
- package/lang/translations/af.po +56 -0
- package/lang/translations/ar.po +56 -0
- package/lang/translations/ast.po +56 -0
- package/lang/translations/az.po +56 -0
- package/lang/translations/bg.po +56 -0
- package/lang/translations/bn.po +56 -0
- package/lang/translations/bs.po +56 -0
- package/lang/translations/ca.po +56 -0
- package/lang/translations/cs.po +56 -0
- package/lang/translations/da.po +56 -0
- package/lang/translations/de-ch.po +56 -0
- package/lang/translations/de.po +56 -0
- package/lang/translations/el.po +56 -0
- package/lang/translations/en-au.po +56 -0
- package/lang/translations/en-gb.po +56 -0
- package/lang/translations/en.po +56 -0
- package/lang/translations/eo.po +56 -0
- package/lang/translations/es-co.po +56 -0
- package/lang/translations/es.po +56 -0
- package/lang/translations/et.po +56 -0
- package/lang/translations/eu.po +56 -0
- package/lang/translations/fa.po +56 -0
- package/lang/translations/fi.po +56 -0
- package/lang/translations/fr.po +56 -0
- package/lang/translations/gl.po +56 -0
- package/lang/translations/gu.po +56 -0
- package/lang/translations/he.po +56 -0
- package/lang/translations/hi.po +56 -0
- package/lang/translations/hr.po +56 -0
- package/lang/translations/hu.po +56 -0
- package/lang/translations/hy.po +56 -0
- package/lang/translations/id.po +56 -0
- package/lang/translations/it.po +56 -0
- package/lang/translations/ja.po +56 -0
- package/lang/translations/jv.po +56 -0
- package/lang/translations/kk.po +56 -0
- package/lang/translations/km.po +56 -0
- package/lang/translations/kn.po +56 -0
- package/lang/translations/ko.po +56 -0
- package/lang/translations/ku.po +56 -0
- package/lang/translations/lt.po +56 -0
- package/lang/translations/lv.po +56 -0
- package/lang/translations/ms.po +56 -0
- package/lang/translations/nb.po +56 -0
- package/lang/translations/ne.po +56 -0
- package/lang/translations/nl.po +56 -0
- package/lang/translations/no.po +56 -0
- package/lang/translations/oc.po +56 -0
- package/lang/translations/pl.po +56 -0
- package/lang/translations/pt-br.po +56 -0
- package/lang/translations/pt.po +56 -0
- package/lang/translations/ro.po +56 -0
- package/lang/translations/ru.po +56 -0
- package/lang/translations/si.po +56 -0
- package/lang/translations/sk.po +56 -0
- package/lang/translations/sl.po +56 -0
- package/lang/translations/sq.po +56 -0
- package/lang/translations/sr-latn.po +56 -0
- package/lang/translations/sr.po +56 -0
- package/lang/translations/sv.po +56 -0
- package/lang/translations/th.po +56 -0
- package/lang/translations/ti.po +56 -0
- package/lang/translations/tk.po +56 -0
- package/lang/translations/tr.po +56 -0
- package/lang/translations/tt.po +56 -0
- package/lang/translations/ug.po +56 -0
- package/lang/translations/uk.po +56 -0
- package/lang/translations/ur.po +56 -0
- package/lang/translations/uz.po +56 -0
- package/lang/translations/vi.po +56 -0
- package/lang/translations/zh-cn.po +56 -0
- package/lang/translations/zh.po +56 -0
- package/package.json +32 -3
- package/src/augmentation.d.ts +24 -0
- package/src/augmentation.js +5 -0
- package/src/bookmark.d.ts +30 -0
- package/src/bookmark.js +36 -0
- package/src/bookmarkconfig.d.ts +48 -0
- package/src/bookmarkconfig.js +5 -0
- package/src/bookmarkediting.d.ts +51 -0
- package/src/bookmarkediting.js +211 -0
- package/src/bookmarkui.d.ts +166 -0
- package/src/bookmarkui.js +582 -0
- package/src/index.d.ts +14 -0
- package/src/index.js +13 -0
- package/src/insertbookmarkcommand.d.ts +38 -0
- package/src/insertbookmarkcommand.js +113 -0
- package/src/ui/bookmarkactionsview.d.ts +102 -0
- package/src/ui/bookmarkactionsview.js +154 -0
- package/src/ui/bookmarkformview.d.ts +118 -0
- package/src/ui/bookmarkformview.js +203 -0
- package/src/updatebookmarkcommand.d.ts +42 -0
- package/src/updatebookmarkcommand.js +75 -0
- package/src/utils.d.ts +11 -0
- package/src/utils.js +19 -0
- package/theme/bookmark.css +50 -0
- package/theme/bookmarkactions.css +44 -0
- package/theme/bookmarkform.css +42 -0
|
@@ -0,0 +1,582 @@
|
|
|
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 bookmark/bookmarkui
|
|
7
|
+
*/
|
|
8
|
+
import { Plugin, icons } from 'ckeditor5/src/core.js';
|
|
9
|
+
import { ButtonView, ContextualBalloon, CssTransitionDisablerMixin, MenuBarMenuListItemButtonView, clickOutsideHandler } from 'ckeditor5/src/ui.js';
|
|
10
|
+
import { ClickObserver } from 'ckeditor5/src/engine.js';
|
|
11
|
+
import BookmarkFormView from './ui/bookmarkformview.js';
|
|
12
|
+
import BookmarkActionsView from './ui/bookmarkactionsview.js';
|
|
13
|
+
import BookmarkEditing from './bookmarkediting.js';
|
|
14
|
+
const VISUAL_SELECTION_MARKER_NAME = 'bookmark-ui';
|
|
15
|
+
/**
|
|
16
|
+
* The UI plugin of the bookmark feature.
|
|
17
|
+
*
|
|
18
|
+
* It registers the `'bookmark'` UI button in the editor's {@link module:ui/componentfactory~ComponentFactory component factory}
|
|
19
|
+
* which inserts the `bookmark` element upon selection.
|
|
20
|
+
*/
|
|
21
|
+
export default class BookmarkUI extends Plugin {
|
|
22
|
+
constructor() {
|
|
23
|
+
super(...arguments);
|
|
24
|
+
/**
|
|
25
|
+
* The actions view displayed inside of the balloon.
|
|
26
|
+
*/
|
|
27
|
+
this.actionsView = null;
|
|
28
|
+
/**
|
|
29
|
+
* The form view displayed inside the balloon.
|
|
30
|
+
*/
|
|
31
|
+
this.formView = null;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* @inheritDoc
|
|
35
|
+
*/
|
|
36
|
+
static get requires() {
|
|
37
|
+
return [BookmarkEditing, ContextualBalloon];
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* @inheritDoc
|
|
41
|
+
*/
|
|
42
|
+
static get pluginName() {
|
|
43
|
+
return 'BookmarkUI';
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* @inheritDoc
|
|
47
|
+
*/
|
|
48
|
+
static get isOfficialPlugin() {
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* @inheritDoc
|
|
53
|
+
*/
|
|
54
|
+
init() {
|
|
55
|
+
const editor = this.editor;
|
|
56
|
+
editor.editing.view.addObserver(ClickObserver);
|
|
57
|
+
this._balloon = editor.plugins.get(ContextualBalloon);
|
|
58
|
+
// Create toolbar buttons.
|
|
59
|
+
this._createToolbarBookmarkButton();
|
|
60
|
+
this._enableBalloonActivators();
|
|
61
|
+
// Renders a fake visual selection marker on an expanded selection.
|
|
62
|
+
editor.conversion.for('editingDowncast').markerToHighlight({
|
|
63
|
+
model: VISUAL_SELECTION_MARKER_NAME,
|
|
64
|
+
view: {
|
|
65
|
+
classes: ['ck-fake-bookmark-selection']
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
// Renders a fake visual selection marker on a collapsed selection.
|
|
69
|
+
editor.conversion.for('editingDowncast').markerToElement({
|
|
70
|
+
model: VISUAL_SELECTION_MARKER_NAME,
|
|
71
|
+
view: (data, { writer }) => {
|
|
72
|
+
if (!data.markerRange.isCollapsed) {
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
const markerElement = writer.createUIElement('span');
|
|
76
|
+
writer.addClass(['ck-fake-bookmark-selection', 'ck-fake-bookmark-selection_collapsed'], markerElement);
|
|
77
|
+
return markerElement;
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* @inheritDoc
|
|
83
|
+
*/
|
|
84
|
+
destroy() {
|
|
85
|
+
super.destroy();
|
|
86
|
+
// Destroy created UI components as they are not automatically destroyed (see ckeditor5#1341).
|
|
87
|
+
if (this.formView) {
|
|
88
|
+
this.formView.destroy();
|
|
89
|
+
}
|
|
90
|
+
if (this.actionsView) {
|
|
91
|
+
this.actionsView.destroy();
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Creates views.
|
|
96
|
+
*/
|
|
97
|
+
_createViews() {
|
|
98
|
+
this.actionsView = this._createActionsView();
|
|
99
|
+
this.formView = this._createFormView();
|
|
100
|
+
// Attach lifecycle actions to the the balloon.
|
|
101
|
+
this._enableUserBalloonInteractions();
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Creates the {@link module:bookmark/ui/bookmarkactionsview~BookmarkActionsView} instance.
|
|
105
|
+
*/
|
|
106
|
+
_createActionsView() {
|
|
107
|
+
const editor = this.editor;
|
|
108
|
+
const actionsView = new BookmarkActionsView(editor.locale);
|
|
109
|
+
const updateBookmarkCommand = editor.commands.get('updateBookmark');
|
|
110
|
+
const deleteCommand = editor.commands.get('delete');
|
|
111
|
+
actionsView.bind('id').to(updateBookmarkCommand, 'value');
|
|
112
|
+
actionsView.editButtonView.bind('isEnabled').to(updateBookmarkCommand);
|
|
113
|
+
actionsView.removeButtonView.bind('isEnabled').to(deleteCommand);
|
|
114
|
+
// Display edit form view after clicking on the "Edit" button.
|
|
115
|
+
this.listenTo(actionsView, 'edit', () => {
|
|
116
|
+
this._addFormView();
|
|
117
|
+
});
|
|
118
|
+
// Execute remove command after clicking on the "Remove" button.
|
|
119
|
+
this.listenTo(actionsView, 'remove', () => {
|
|
120
|
+
this._hideUI();
|
|
121
|
+
editor.execute('delete');
|
|
122
|
+
});
|
|
123
|
+
// Close the panel on esc key press when the **actions have focus**.
|
|
124
|
+
actionsView.keystrokes.set('Esc', (data, cancel) => {
|
|
125
|
+
this._hideUI();
|
|
126
|
+
cancel();
|
|
127
|
+
});
|
|
128
|
+
return actionsView;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Creates the {@link module:bookmark/ui/bookmarkformview~BookmarkFormView} instance.
|
|
132
|
+
*/
|
|
133
|
+
_createFormView() {
|
|
134
|
+
const editor = this.editor;
|
|
135
|
+
const locale = editor.locale;
|
|
136
|
+
const insertBookmarkCommand = editor.commands.get('insertBookmark');
|
|
137
|
+
const updateBookmarkCommand = editor.commands.get('updateBookmark');
|
|
138
|
+
const commands = [insertBookmarkCommand, updateBookmarkCommand];
|
|
139
|
+
const formView = new (CssTransitionDisablerMixin(BookmarkFormView))(locale, getFormValidators(editor));
|
|
140
|
+
formView.idInputView.fieldView.bind('value').to(updateBookmarkCommand, 'value');
|
|
141
|
+
// Form elements should be read-only when corresponding commands are disabled.
|
|
142
|
+
formView.idInputView.bind('isEnabled').toMany(commands, 'isEnabled', (...areEnabled) => areEnabled.some(isEnabled => isEnabled));
|
|
143
|
+
// Disable the "save" button if the command is disabled.
|
|
144
|
+
formView.buttonView.bind('isEnabled').toMany(commands, 'isEnabled', (...areEnabled) => areEnabled.some(isEnabled => isEnabled));
|
|
145
|
+
// Execute link command after clicking the "Save" button.
|
|
146
|
+
this.listenTo(formView, 'submit', () => {
|
|
147
|
+
if (formView.isValid()) {
|
|
148
|
+
const value = formView.id;
|
|
149
|
+
if (this._getSelectedBookmarkElement()) {
|
|
150
|
+
editor.execute('updateBookmark', { bookmarkId: value });
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
editor.execute('insertBookmark', { bookmarkId: value });
|
|
154
|
+
}
|
|
155
|
+
this._closeFormView();
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
// Update balloon position when form error changes.
|
|
159
|
+
this.listenTo(formView.idInputView, 'change:errorText', () => {
|
|
160
|
+
editor.ui.update();
|
|
161
|
+
});
|
|
162
|
+
// Close the panel on esc key press when the **form has focus**.
|
|
163
|
+
formView.keystrokes.set('Esc', (data, cancel) => {
|
|
164
|
+
this._closeFormView();
|
|
165
|
+
cancel();
|
|
166
|
+
});
|
|
167
|
+
return formView;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Creates a toolbar Bookmark button. Clicking this button will show
|
|
171
|
+
* a {@link #_balloon} attached to the selection.
|
|
172
|
+
*/
|
|
173
|
+
_createToolbarBookmarkButton() {
|
|
174
|
+
const editor = this.editor;
|
|
175
|
+
editor.ui.componentFactory.add('bookmark', () => {
|
|
176
|
+
const buttonView = this._createButton(ButtonView);
|
|
177
|
+
buttonView.set({
|
|
178
|
+
tooltip: true
|
|
179
|
+
});
|
|
180
|
+
return buttonView;
|
|
181
|
+
});
|
|
182
|
+
editor.ui.componentFactory.add('menuBar:bookmark', () => {
|
|
183
|
+
return this._createButton(MenuBarMenuListItemButtonView);
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Creates a button for `bookmark` command to use either in toolbar or in menu bar.
|
|
188
|
+
*/
|
|
189
|
+
_createButton(ButtonClass) {
|
|
190
|
+
const editor = this.editor;
|
|
191
|
+
const locale = editor.locale;
|
|
192
|
+
const view = new ButtonClass(locale);
|
|
193
|
+
const insertCommand = editor.commands.get('insertBookmark');
|
|
194
|
+
const updateCommand = editor.commands.get('updateBookmark');
|
|
195
|
+
const t = locale.t;
|
|
196
|
+
view.set({
|
|
197
|
+
label: t('Bookmark'),
|
|
198
|
+
icon: icons.bookmark
|
|
199
|
+
});
|
|
200
|
+
// Execute the command.
|
|
201
|
+
this.listenTo(view, 'execute', () => this._showUI(true));
|
|
202
|
+
view.bind('isEnabled').toMany([insertCommand, updateCommand], 'isEnabled', (...areEnabled) => areEnabled.some(isEnabled => isEnabled));
|
|
203
|
+
view.bind('isOn').to(updateCommand, 'value', value => !!value);
|
|
204
|
+
return view;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Attaches actions that control whether the balloon panel containing the
|
|
208
|
+
* {@link #formView} should be displayed.
|
|
209
|
+
*/
|
|
210
|
+
_enableBalloonActivators() {
|
|
211
|
+
const editor = this.editor;
|
|
212
|
+
const viewDocument = editor.editing.view.document;
|
|
213
|
+
// Handle click on view document and show panel when selection is placed inside the bookmark element.
|
|
214
|
+
// Keep panel open until selection will be inside the same bookmark element.
|
|
215
|
+
this.listenTo(viewDocument, 'click', () => {
|
|
216
|
+
const bookmark = this._getSelectedBookmarkElement();
|
|
217
|
+
if (bookmark) {
|
|
218
|
+
// Then show panel but keep focus inside editor editable.
|
|
219
|
+
this._showUI();
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Attaches actions that control whether the balloon panel containing the
|
|
225
|
+
* {@link #formView} is visible or not.
|
|
226
|
+
*/
|
|
227
|
+
_enableUserBalloonInteractions() {
|
|
228
|
+
// Focus the form if the balloon is visible and the Tab key has been pressed.
|
|
229
|
+
this.editor.keystrokes.set('Tab', (data, cancel) => {
|
|
230
|
+
if (this._areActionsVisible && !this.actionsView.focusTracker.isFocused) {
|
|
231
|
+
this.actionsView.focus();
|
|
232
|
+
cancel();
|
|
233
|
+
}
|
|
234
|
+
}, {
|
|
235
|
+
// Use the high priority because the bookmark UI navigation is more important
|
|
236
|
+
// than other feature's actions, e.g. list indentation.
|
|
237
|
+
priority: 'high'
|
|
238
|
+
});
|
|
239
|
+
// Close the panel on the Esc key press when the editable has focus and the balloon is visible.
|
|
240
|
+
this.editor.keystrokes.set('Esc', (data, cancel) => {
|
|
241
|
+
if (this._isUIVisible) {
|
|
242
|
+
this._hideUI();
|
|
243
|
+
cancel();
|
|
244
|
+
}
|
|
245
|
+
});
|
|
246
|
+
// Close on click outside of balloon panel element.
|
|
247
|
+
clickOutsideHandler({
|
|
248
|
+
emitter: this.formView,
|
|
249
|
+
activator: () => this._isUIInPanel,
|
|
250
|
+
contextElements: () => [this._balloon.view.element],
|
|
251
|
+
callback: () => this._hideUI()
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Updates the button label. If bookmark is selected label is set to 'Update' otherwise
|
|
256
|
+
* it is 'Insert'.
|
|
257
|
+
*/
|
|
258
|
+
_updateFormButtonLabel(isBookmarkSelected) {
|
|
259
|
+
const t = this.editor.locale.t;
|
|
260
|
+
this.formView.buttonView.label = isBookmarkSelected ? t('Update') : t('Insert');
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Adds the {@link #actionsView} to the {@link #_balloon}.
|
|
264
|
+
*
|
|
265
|
+
* @internal
|
|
266
|
+
*/
|
|
267
|
+
_addActionsView() {
|
|
268
|
+
if (!this.actionsView) {
|
|
269
|
+
this._createViews();
|
|
270
|
+
}
|
|
271
|
+
if (this._areActionsInPanel) {
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
this._balloon.add({
|
|
275
|
+
view: this.actionsView,
|
|
276
|
+
position: this._getBalloonPositionData()
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Adds the {@link #formView} to the {@link #_balloon}.
|
|
281
|
+
*/
|
|
282
|
+
_addFormView() {
|
|
283
|
+
if (!this.formView) {
|
|
284
|
+
this._createViews();
|
|
285
|
+
}
|
|
286
|
+
if (this._isFormInPanel) {
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
const editor = this.editor;
|
|
290
|
+
const updateBookmarkCommand = editor.commands.get('updateBookmark');
|
|
291
|
+
this.formView.disableCssTransitions();
|
|
292
|
+
this.formView.resetFormStatus();
|
|
293
|
+
this._balloon.add({
|
|
294
|
+
view: this.formView,
|
|
295
|
+
position: this._getBalloonPositionData()
|
|
296
|
+
});
|
|
297
|
+
this.formView.idInputView.fieldView.value = updateBookmarkCommand.value || '';
|
|
298
|
+
// Select input when form view is currently visible.
|
|
299
|
+
if (this._balloon.visibleView === this.formView) {
|
|
300
|
+
this.formView.idInputView.fieldView.select();
|
|
301
|
+
}
|
|
302
|
+
this.formView.enableCssTransitions();
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Closes the form view. Decides whether the balloon should be hidden completely.
|
|
306
|
+
*/
|
|
307
|
+
_closeFormView() {
|
|
308
|
+
const updateBookmarkCommand = this.editor.commands.get('updateBookmark');
|
|
309
|
+
if (updateBookmarkCommand.value !== undefined) {
|
|
310
|
+
this._removeFormView();
|
|
311
|
+
}
|
|
312
|
+
else {
|
|
313
|
+
this._hideUI();
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Removes the {@link #formView} from the {@link #_balloon}.
|
|
318
|
+
*/
|
|
319
|
+
_removeFormView() {
|
|
320
|
+
if (this._isFormInPanel) {
|
|
321
|
+
// Blur the input element before removing it from DOM to prevent issues in some browsers.
|
|
322
|
+
// See https://github.com/ckeditor/ckeditor5/issues/1501.
|
|
323
|
+
this.formView.buttonView.focus();
|
|
324
|
+
// Reset the ID field to update the state of the submit button.
|
|
325
|
+
this.formView.idInputView.fieldView.reset();
|
|
326
|
+
this._balloon.remove(this.formView);
|
|
327
|
+
// Because the form has an input which has focus, the focus must be brought back
|
|
328
|
+
// to the editor. Otherwise, it would be lost.
|
|
329
|
+
this.editor.editing.view.focus();
|
|
330
|
+
this._hideFakeVisualSelection();
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Shows the correct UI type. It is either {@link #formView} or {@link #actionsView}.
|
|
335
|
+
*/
|
|
336
|
+
_showUI(forceVisible = false) {
|
|
337
|
+
if (!this.formView) {
|
|
338
|
+
this._createViews();
|
|
339
|
+
}
|
|
340
|
+
// When there's no bookmark under the selection, go straight to the editing UI.
|
|
341
|
+
if (!this._getSelectedBookmarkElement()) {
|
|
342
|
+
// Show visual selection on a text without a bookmark when the contextual balloon is displayed.
|
|
343
|
+
this._showFakeVisualSelection();
|
|
344
|
+
this._addActionsView();
|
|
345
|
+
// Be sure panel with bookmark is visible.
|
|
346
|
+
if (forceVisible) {
|
|
347
|
+
this._balloon.showStack('main');
|
|
348
|
+
}
|
|
349
|
+
this._addFormView();
|
|
350
|
+
}
|
|
351
|
+
// If there's a bookmark under the selection...
|
|
352
|
+
else {
|
|
353
|
+
// Go to the editing UI if actions are already visible.
|
|
354
|
+
if (this._areActionsVisible) {
|
|
355
|
+
this._addFormView();
|
|
356
|
+
}
|
|
357
|
+
// Otherwise display just the actions UI.
|
|
358
|
+
else {
|
|
359
|
+
this._addActionsView();
|
|
360
|
+
}
|
|
361
|
+
// Be sure panel with bookmark is visible.
|
|
362
|
+
if (forceVisible) {
|
|
363
|
+
this._balloon.showStack('main');
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
// Begin responding to ui#update once the UI is added.
|
|
367
|
+
this._startUpdatingUI();
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* Removes the {@link #formView} from the {@link #_balloon}.
|
|
371
|
+
*
|
|
372
|
+
* See {@link #_addFormView}, {@link #_addActionsView}.
|
|
373
|
+
*/
|
|
374
|
+
_hideUI() {
|
|
375
|
+
if (!this._isUIInPanel) {
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
const editor = this.editor;
|
|
379
|
+
this.stopListening(editor.ui, 'update');
|
|
380
|
+
this.stopListening(this._balloon, 'change:visibleView');
|
|
381
|
+
// Make sure the focus always gets back to the editable _before_ removing the focused form view.
|
|
382
|
+
// Doing otherwise causes issues in some browsers. See https://github.com/ckeditor/ckeditor5-link/issues/193.
|
|
383
|
+
editor.editing.view.focus();
|
|
384
|
+
// Remove form first because it's on top of the stack.
|
|
385
|
+
this._removeFormView();
|
|
386
|
+
// Then remove the actions view because it's beneath the form.
|
|
387
|
+
this._balloon.remove(this.actionsView);
|
|
388
|
+
this._hideFakeVisualSelection();
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* Makes the UI react to the {@link module:ui/editorui/editorui~EditorUI#event:update} event to
|
|
392
|
+
* reposition itself when the editor UI should be refreshed.
|
|
393
|
+
*
|
|
394
|
+
* See: {@link #_hideUI} to learn when the UI stops reacting to the `update` event.
|
|
395
|
+
*/
|
|
396
|
+
_startUpdatingUI() {
|
|
397
|
+
const editor = this.editor;
|
|
398
|
+
const viewDocument = editor.editing.view.document;
|
|
399
|
+
let prevSelectedBookmark = this._getSelectedBookmarkElement();
|
|
400
|
+
let prevSelectionParent = getSelectionParent();
|
|
401
|
+
this._updateFormButtonLabel(!!prevSelectedBookmark);
|
|
402
|
+
const update = () => {
|
|
403
|
+
const selectedBookmark = this._getSelectedBookmarkElement();
|
|
404
|
+
const selectionParent = getSelectionParent();
|
|
405
|
+
// Hide the panel if:
|
|
406
|
+
//
|
|
407
|
+
// * the selection went out of the EXISTING bookmark element. E.g. user moved the caret out
|
|
408
|
+
// of the bookmark,
|
|
409
|
+
// * the selection went to a different parent when creating a NEW bookmark. E.g. someone
|
|
410
|
+
// else modified the document.
|
|
411
|
+
// * the selection has expanded (e.g. displaying bookmark actions then pressing SHIFT+Right arrow).
|
|
412
|
+
//
|
|
413
|
+
if ((prevSelectedBookmark && !selectedBookmark) ||
|
|
414
|
+
(!prevSelectedBookmark && selectionParent !== prevSelectionParent)) {
|
|
415
|
+
this._hideUI();
|
|
416
|
+
}
|
|
417
|
+
// Update the position of the panel when:
|
|
418
|
+
// * bookmark panel is in the visible stack
|
|
419
|
+
// * the selection remains on the original bookmark element,
|
|
420
|
+
// * there was no bookmark element in the first place, i.e. creating a new bookmark
|
|
421
|
+
else if (this._isUIVisible) {
|
|
422
|
+
// If still in a bookmark element, simply update the position of the balloon.
|
|
423
|
+
// If there was no bookmark (e.g. inserting one), the balloon must be moved
|
|
424
|
+
// to the new position in the editing view (a new native DOM range).
|
|
425
|
+
this._balloon.updatePosition(this._getBalloonPositionData());
|
|
426
|
+
}
|
|
427
|
+
this._updateFormButtonLabel(!!prevSelectedBookmark);
|
|
428
|
+
prevSelectedBookmark = selectedBookmark;
|
|
429
|
+
prevSelectionParent = selectionParent;
|
|
430
|
+
};
|
|
431
|
+
function getSelectionParent() {
|
|
432
|
+
return viewDocument.selection.focus.getAncestors()
|
|
433
|
+
.reverse()
|
|
434
|
+
.find((node) => node.is('element'));
|
|
435
|
+
}
|
|
436
|
+
this.listenTo(editor.ui, 'update', update);
|
|
437
|
+
this.listenTo(this._balloon, 'change:visibleView', update);
|
|
438
|
+
}
|
|
439
|
+
/**
|
|
440
|
+
* Returns `true` when {@link #formView} is in the {@link #_balloon}.
|
|
441
|
+
*/
|
|
442
|
+
get _isFormInPanel() {
|
|
443
|
+
return !!this.formView && this._balloon.hasView(this.formView);
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* Returns `true` when {@link #actionsView} is in the {@link #_balloon}.
|
|
447
|
+
*/
|
|
448
|
+
get _areActionsInPanel() {
|
|
449
|
+
return !!this.actionsView && this._balloon.hasView(this.actionsView);
|
|
450
|
+
}
|
|
451
|
+
/**
|
|
452
|
+
* Returns `true` when {@link #actionsView} is in the {@link #_balloon} and it is
|
|
453
|
+
* currently visible.
|
|
454
|
+
*/
|
|
455
|
+
get _areActionsVisible() {
|
|
456
|
+
return !!this.actionsView && this._balloon.visibleView === this.actionsView;
|
|
457
|
+
}
|
|
458
|
+
/**
|
|
459
|
+
* Returns `true` when {@link #actionsView} or {@link #formView} is in the {@link #_balloon}.
|
|
460
|
+
*/
|
|
461
|
+
get _isUIInPanel() {
|
|
462
|
+
return this._isFormInPanel || this._areActionsInPanel;
|
|
463
|
+
}
|
|
464
|
+
/**
|
|
465
|
+
* Returns `true` when {@link #actionsView} or {@link #formView} is in the {@link #_balloon} and it is
|
|
466
|
+
* currently visible.
|
|
467
|
+
*/
|
|
468
|
+
get _isUIVisible() {
|
|
469
|
+
const visibleView = this._balloon.visibleView;
|
|
470
|
+
return !!this.formView && visibleView == this.formView || this._areActionsVisible;
|
|
471
|
+
}
|
|
472
|
+
/**
|
|
473
|
+
* Returns positioning options for the {@link #_balloon}. They control the way the balloon is attached
|
|
474
|
+
* to the target element or selection.
|
|
475
|
+
*/
|
|
476
|
+
_getBalloonPositionData() {
|
|
477
|
+
const view = this.editor.editing.view;
|
|
478
|
+
const model = this.editor.model;
|
|
479
|
+
let target;
|
|
480
|
+
const bookmarkElement = this._getSelectedBookmarkElement();
|
|
481
|
+
if (model.markers.has(VISUAL_SELECTION_MARKER_NAME)) {
|
|
482
|
+
// There are cases when we highlight selection using a marker (#7705, #4721).
|
|
483
|
+
const markerViewElements = Array.from(this.editor.editing.mapper.markerNameToElements(VISUAL_SELECTION_MARKER_NAME));
|
|
484
|
+
const newRange = view.createRange(view.createPositionBefore(markerViewElements[0]), view.createPositionAfter(markerViewElements[markerViewElements.length - 1]));
|
|
485
|
+
target = view.domConverter.viewRangeToDom(newRange);
|
|
486
|
+
}
|
|
487
|
+
else if (bookmarkElement) {
|
|
488
|
+
target = () => {
|
|
489
|
+
const mapper = this.editor.editing.mapper;
|
|
490
|
+
const domConverter = view.domConverter;
|
|
491
|
+
const viewElement = mapper.toViewElement(bookmarkElement);
|
|
492
|
+
return domConverter.mapViewToDom(viewElement);
|
|
493
|
+
};
|
|
494
|
+
}
|
|
495
|
+
return target && { target };
|
|
496
|
+
}
|
|
497
|
+
/**
|
|
498
|
+
* Returns the bookmark {@link module:engine/view/attributeelement~AttributeElement} under
|
|
499
|
+
* the {@link module:engine/view/document~Document editing view's} selection or `null`
|
|
500
|
+
* if there is none.
|
|
501
|
+
*/
|
|
502
|
+
_getSelectedBookmarkElement() {
|
|
503
|
+
const selection = this.editor.model.document.selection;
|
|
504
|
+
const element = selection.getSelectedElement();
|
|
505
|
+
if (element && element.is('element', 'bookmark')) {
|
|
506
|
+
return element;
|
|
507
|
+
}
|
|
508
|
+
return null;
|
|
509
|
+
}
|
|
510
|
+
/**
|
|
511
|
+
* Displays a fake visual selection when the contextual balloon is displayed.
|
|
512
|
+
*
|
|
513
|
+
* This adds a 'bookmark-ui' marker into the document that is rendered as a highlight on selected text fragment.
|
|
514
|
+
*/
|
|
515
|
+
_showFakeVisualSelection() {
|
|
516
|
+
const model = this.editor.model;
|
|
517
|
+
model.change(writer => {
|
|
518
|
+
const range = model.document.selection.getFirstRange();
|
|
519
|
+
if (model.markers.has(VISUAL_SELECTION_MARKER_NAME)) {
|
|
520
|
+
writer.updateMarker(VISUAL_SELECTION_MARKER_NAME, { range });
|
|
521
|
+
}
|
|
522
|
+
else {
|
|
523
|
+
if (range.start.isAtEnd) {
|
|
524
|
+
const startPosition = range.start.getLastMatchingPosition(({ item }) => !model.schema.isContent(item), { boundaries: range });
|
|
525
|
+
writer.addMarker(VISUAL_SELECTION_MARKER_NAME, {
|
|
526
|
+
usingOperation: false,
|
|
527
|
+
affectsData: false,
|
|
528
|
+
range: writer.createRange(startPosition, range.end)
|
|
529
|
+
});
|
|
530
|
+
}
|
|
531
|
+
else {
|
|
532
|
+
writer.addMarker(VISUAL_SELECTION_MARKER_NAME, {
|
|
533
|
+
usingOperation: false,
|
|
534
|
+
affectsData: false,
|
|
535
|
+
range
|
|
536
|
+
});
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
});
|
|
540
|
+
}
|
|
541
|
+
/**
|
|
542
|
+
* Hides the fake visual selection created in {@link #_showFakeVisualSelection}.
|
|
543
|
+
*/
|
|
544
|
+
_hideFakeVisualSelection() {
|
|
545
|
+
const model = this.editor.model;
|
|
546
|
+
if (model.markers.has(VISUAL_SELECTION_MARKER_NAME)) {
|
|
547
|
+
model.change(writer => {
|
|
548
|
+
writer.removeMarker(VISUAL_SELECTION_MARKER_NAME);
|
|
549
|
+
});
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
/**
|
|
554
|
+
* Returns bookmark form validation callbacks.
|
|
555
|
+
*/
|
|
556
|
+
function getFormValidators(editor) {
|
|
557
|
+
const { t } = editor;
|
|
558
|
+
const bookmarkEditing = editor.plugins.get(BookmarkEditing);
|
|
559
|
+
return [
|
|
560
|
+
form => {
|
|
561
|
+
if (!form.id) {
|
|
562
|
+
return t('Bookmark must not be empty.');
|
|
563
|
+
}
|
|
564
|
+
},
|
|
565
|
+
form => {
|
|
566
|
+
if (form.id && /\s/.test(form.id)) {
|
|
567
|
+
return t('Bookmark name cannot contain space characters.');
|
|
568
|
+
}
|
|
569
|
+
},
|
|
570
|
+
form => {
|
|
571
|
+
const selectedElement = editor.model.document.selection.getSelectedElement();
|
|
572
|
+
const existingBookmarkForId = bookmarkEditing.getElementForBookmarkId(form.id);
|
|
573
|
+
// Accept change of bookmark ID if no real change is happening (edit -> submit, without changes).
|
|
574
|
+
if (selectedElement === existingBookmarkForId) {
|
|
575
|
+
return;
|
|
576
|
+
}
|
|
577
|
+
if (existingBookmarkForId) {
|
|
578
|
+
return t('Bookmark name already exists.');
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
];
|
|
582
|
+
}
|
package/src/index.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
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 bookmark
|
|
7
|
+
*/
|
|
8
|
+
export { default as Bookmark } from './bookmark.js';
|
|
9
|
+
export { default as BookmarkEditing } from './bookmarkediting.js';
|
|
10
|
+
export { default as BookmarkUI } from './bookmarkui.js';
|
|
11
|
+
export { default as InsertBookmarkCommand } from './insertbookmarkcommand.js';
|
|
12
|
+
export { default as UpdateBookmarkCommand } from './updatebookmarkcommand.js';
|
|
13
|
+
export type { BookmarkConfig } from './bookmarkconfig.js';
|
|
14
|
+
import './augmentation.js';
|
package/src/index.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
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 bookmark
|
|
7
|
+
*/
|
|
8
|
+
export { default as Bookmark } from './bookmark.js';
|
|
9
|
+
export { default as BookmarkEditing } from './bookmarkediting.js';
|
|
10
|
+
export { default as BookmarkUI } from './bookmarkui.js';
|
|
11
|
+
export { default as InsertBookmarkCommand } from './insertbookmarkcommand.js';
|
|
12
|
+
export { default as UpdateBookmarkCommand } from './updatebookmarkcommand.js';
|
|
13
|
+
import './augmentation.js';
|
|
@@ -0,0 +1,38 @@
|
|
|
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
|
+
import { Command } from 'ckeditor5/src/core.js';
|
|
6
|
+
/**
|
|
7
|
+
* The insert bookmark command.
|
|
8
|
+
*
|
|
9
|
+
* The command is registered by {@link module:bookmark/bookmarkediting~BookmarkEditing} as `'insertBookmark'`.
|
|
10
|
+
*
|
|
11
|
+
* To insert a bookmark element at place where is the current collapsed selection or where is the beginning of document selection,
|
|
12
|
+
* execute the command passing the bookmark id as a parameter:
|
|
13
|
+
*
|
|
14
|
+
* ```ts
|
|
15
|
+
* editor.execute( 'insertBookmark', { bookmarkId: 'foo_bar' } );
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export default class InsertBookmarkCommand extends Command {
|
|
19
|
+
/**
|
|
20
|
+
* @inheritDoc
|
|
21
|
+
*/
|
|
22
|
+
refresh(): void;
|
|
23
|
+
/**
|
|
24
|
+
* Executes the command.
|
|
25
|
+
*
|
|
26
|
+
* @fires execute
|
|
27
|
+
* @param options Command options.
|
|
28
|
+
* @param options.bookmarkId The value of the `bookmarkId` attribute.
|
|
29
|
+
*/
|
|
30
|
+
execute(options: {
|
|
31
|
+
bookmarkId: string;
|
|
32
|
+
}): void;
|
|
33
|
+
/**
|
|
34
|
+
* Returns the position where the bookmark can be inserted. And if it is not possible to insert a bookmark,
|
|
35
|
+
* check if it is possible to insert a paragraph.
|
|
36
|
+
*/
|
|
37
|
+
private _getPositionToInsertBookmark;
|
|
38
|
+
}
|