@ckeditor/ckeditor5-bookmark 0.0.1 → 44.0.0-alpha.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (408) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/LICENSE.md +4 -5
  3. package/README.md +31 -3
  4. package/build/bookmark.js +5 -0
  5. package/build/translations/af.js +1 -0
  6. package/build/translations/ar.js +1 -0
  7. package/build/translations/ast.js +1 -0
  8. package/build/translations/az.js +1 -0
  9. package/build/translations/bg.js +1 -0
  10. package/build/translations/bn.js +1 -0
  11. package/build/translations/bs.js +1 -0
  12. package/build/translations/ca.js +1 -0
  13. package/build/translations/cs.js +1 -0
  14. package/build/translations/da.js +1 -0
  15. package/build/translations/de-ch.js +1 -0
  16. package/build/translations/de.js +1 -0
  17. package/build/translations/el.js +1 -0
  18. package/build/translations/en-au.js +1 -0
  19. package/build/translations/en-gb.js +1 -0
  20. package/build/translations/eo.js +1 -0
  21. package/build/translations/es-co.js +1 -0
  22. package/build/translations/es.js +1 -0
  23. package/build/translations/et.js +1 -0
  24. package/build/translations/eu.js +1 -0
  25. package/build/translations/fa.js +1 -0
  26. package/build/translations/fi.js +1 -0
  27. package/build/translations/fr.js +1 -0
  28. package/build/translations/gl.js +1 -0
  29. package/build/translations/gu.js +1 -0
  30. package/build/translations/he.js +1 -0
  31. package/build/translations/hi.js +1 -0
  32. package/build/translations/hr.js +1 -0
  33. package/build/translations/hu.js +1 -0
  34. package/build/translations/hy.js +1 -0
  35. package/build/translations/id.js +1 -0
  36. package/build/translations/it.js +1 -0
  37. package/build/translations/ja.js +1 -0
  38. package/build/translations/jv.js +1 -0
  39. package/build/translations/kk.js +1 -0
  40. package/build/translations/km.js +1 -0
  41. package/build/translations/kn.js +1 -0
  42. package/build/translations/ko.js +1 -0
  43. package/build/translations/ku.js +1 -0
  44. package/build/translations/lt.js +1 -0
  45. package/build/translations/lv.js +1 -0
  46. package/build/translations/ms.js +1 -0
  47. package/build/translations/nb.js +1 -0
  48. package/build/translations/ne.js +1 -0
  49. package/build/translations/nl.js +1 -0
  50. package/build/translations/no.js +1 -0
  51. package/build/translations/oc.js +1 -0
  52. package/build/translations/pl.js +1 -0
  53. package/build/translations/pt-br.js +1 -0
  54. package/build/translations/pt.js +1 -0
  55. package/build/translations/ro.js +1 -0
  56. package/build/translations/ru.js +1 -0
  57. package/build/translations/si.js +1 -0
  58. package/build/translations/sk.js +1 -0
  59. package/build/translations/sl.js +1 -0
  60. package/build/translations/sq.js +1 -0
  61. package/build/translations/sr-latn.js +1 -0
  62. package/build/translations/sr.js +1 -0
  63. package/build/translations/sv.js +1 -0
  64. package/build/translations/th.js +1 -0
  65. package/build/translations/ti.js +1 -0
  66. package/build/translations/tk.js +1 -0
  67. package/build/translations/tr.js +1 -0
  68. package/build/translations/tt.js +1 -0
  69. package/build/translations/ug.js +1 -0
  70. package/build/translations/uk.js +1 -0
  71. package/build/translations/ur.js +1 -0
  72. package/build/translations/uz.js +1 -0
  73. package/build/translations/vi.js +1 -0
  74. package/build/translations/zh-cn.js +1 -0
  75. package/build/translations/zh.js +1 -0
  76. package/ckeditor5-metadata.json +24 -0
  77. package/dist/augmentation.d.ts +28 -0
  78. package/dist/bookmark.d.ts +34 -0
  79. package/dist/bookmarkconfig.d.ts +52 -0
  80. package/dist/bookmarkediting.d.ts +55 -0
  81. package/dist/bookmarkui.d.ts +170 -0
  82. package/dist/index-content.css +4 -0
  83. package/dist/index-editor.css +150 -0
  84. package/dist/index.css +195 -0
  85. package/dist/index.css.map +1 -0
  86. package/dist/index.d.ts +18 -0
  87. package/dist/index.js +1320 -0
  88. package/dist/index.js.map +1 -0
  89. package/dist/insertbookmarkcommand.d.ts +42 -0
  90. package/dist/translations/af.d.ts +8 -0
  91. package/dist/translations/af.js +5 -0
  92. package/dist/translations/af.umd.js +11 -0
  93. package/dist/translations/ar.d.ts +8 -0
  94. package/dist/translations/ar.js +5 -0
  95. package/dist/translations/ar.umd.js +11 -0
  96. package/dist/translations/ast.d.ts +8 -0
  97. package/dist/translations/ast.js +5 -0
  98. package/dist/translations/ast.umd.js +11 -0
  99. package/dist/translations/az.d.ts +8 -0
  100. package/dist/translations/az.js +5 -0
  101. package/dist/translations/az.umd.js +11 -0
  102. package/dist/translations/bg.d.ts +8 -0
  103. package/dist/translations/bg.js +5 -0
  104. package/dist/translations/bg.umd.js +11 -0
  105. package/dist/translations/bn.d.ts +8 -0
  106. package/dist/translations/bn.js +5 -0
  107. package/dist/translations/bn.umd.js +11 -0
  108. package/dist/translations/bs.d.ts +8 -0
  109. package/dist/translations/bs.js +5 -0
  110. package/dist/translations/bs.umd.js +11 -0
  111. package/dist/translations/ca.d.ts +8 -0
  112. package/dist/translations/ca.js +5 -0
  113. package/dist/translations/ca.umd.js +11 -0
  114. package/dist/translations/cs.d.ts +8 -0
  115. package/dist/translations/cs.js +5 -0
  116. package/dist/translations/cs.umd.js +11 -0
  117. package/dist/translations/da.d.ts +8 -0
  118. package/dist/translations/da.js +5 -0
  119. package/dist/translations/da.umd.js +11 -0
  120. package/dist/translations/de-ch.d.ts +8 -0
  121. package/dist/translations/de-ch.js +5 -0
  122. package/dist/translations/de-ch.umd.js +11 -0
  123. package/dist/translations/de.d.ts +8 -0
  124. package/dist/translations/de.js +5 -0
  125. package/dist/translations/de.umd.js +11 -0
  126. package/dist/translations/el.d.ts +8 -0
  127. package/dist/translations/el.js +5 -0
  128. package/dist/translations/el.umd.js +11 -0
  129. package/dist/translations/en-au.d.ts +8 -0
  130. package/dist/translations/en-au.js +5 -0
  131. package/dist/translations/en-au.umd.js +11 -0
  132. package/dist/translations/en-gb.d.ts +8 -0
  133. package/dist/translations/en-gb.js +5 -0
  134. package/dist/translations/en-gb.umd.js +11 -0
  135. package/dist/translations/en.d.ts +8 -0
  136. package/dist/translations/en.js +5 -0
  137. package/dist/translations/en.umd.js +11 -0
  138. package/dist/translations/eo.d.ts +8 -0
  139. package/dist/translations/eo.js +5 -0
  140. package/dist/translations/eo.umd.js +11 -0
  141. package/dist/translations/es-co.d.ts +8 -0
  142. package/dist/translations/es-co.js +5 -0
  143. package/dist/translations/es-co.umd.js +11 -0
  144. package/dist/translations/es.d.ts +8 -0
  145. package/dist/translations/es.js +5 -0
  146. package/dist/translations/es.umd.js +11 -0
  147. package/dist/translations/et.d.ts +8 -0
  148. package/dist/translations/et.js +5 -0
  149. package/dist/translations/et.umd.js +11 -0
  150. package/dist/translations/eu.d.ts +8 -0
  151. package/dist/translations/eu.js +5 -0
  152. package/dist/translations/eu.umd.js +11 -0
  153. package/dist/translations/fa.d.ts +8 -0
  154. package/dist/translations/fa.js +5 -0
  155. package/dist/translations/fa.umd.js +11 -0
  156. package/dist/translations/fi.d.ts +8 -0
  157. package/dist/translations/fi.js +5 -0
  158. package/dist/translations/fi.umd.js +11 -0
  159. package/dist/translations/fr.d.ts +8 -0
  160. package/dist/translations/fr.js +5 -0
  161. package/dist/translations/fr.umd.js +11 -0
  162. package/dist/translations/gl.d.ts +8 -0
  163. package/dist/translations/gl.js +5 -0
  164. package/dist/translations/gl.umd.js +11 -0
  165. package/dist/translations/gu.d.ts +8 -0
  166. package/dist/translations/gu.js +5 -0
  167. package/dist/translations/gu.umd.js +11 -0
  168. package/dist/translations/he.d.ts +8 -0
  169. package/dist/translations/he.js +5 -0
  170. package/dist/translations/he.umd.js +11 -0
  171. package/dist/translations/hi.d.ts +8 -0
  172. package/dist/translations/hi.js +5 -0
  173. package/dist/translations/hi.umd.js +11 -0
  174. package/dist/translations/hr.d.ts +8 -0
  175. package/dist/translations/hr.js +5 -0
  176. package/dist/translations/hr.umd.js +11 -0
  177. package/dist/translations/hu.d.ts +8 -0
  178. package/dist/translations/hu.js +5 -0
  179. package/dist/translations/hu.umd.js +11 -0
  180. package/dist/translations/hy.d.ts +8 -0
  181. package/dist/translations/hy.js +5 -0
  182. package/dist/translations/hy.umd.js +11 -0
  183. package/dist/translations/id.d.ts +8 -0
  184. package/dist/translations/id.js +5 -0
  185. package/dist/translations/id.umd.js +11 -0
  186. package/dist/translations/it.d.ts +8 -0
  187. package/dist/translations/it.js +5 -0
  188. package/dist/translations/it.umd.js +11 -0
  189. package/dist/translations/ja.d.ts +8 -0
  190. package/dist/translations/ja.js +5 -0
  191. package/dist/translations/ja.umd.js +11 -0
  192. package/dist/translations/jv.d.ts +8 -0
  193. package/dist/translations/jv.js +5 -0
  194. package/dist/translations/jv.umd.js +11 -0
  195. package/dist/translations/kk.d.ts +8 -0
  196. package/dist/translations/kk.js +5 -0
  197. package/dist/translations/kk.umd.js +11 -0
  198. package/dist/translations/km.d.ts +8 -0
  199. package/dist/translations/km.js +5 -0
  200. package/dist/translations/km.umd.js +11 -0
  201. package/dist/translations/kn.d.ts +8 -0
  202. package/dist/translations/kn.js +5 -0
  203. package/dist/translations/kn.umd.js +11 -0
  204. package/dist/translations/ko.d.ts +8 -0
  205. package/dist/translations/ko.js +5 -0
  206. package/dist/translations/ko.umd.js +11 -0
  207. package/dist/translations/ku.d.ts +8 -0
  208. package/dist/translations/ku.js +5 -0
  209. package/dist/translations/ku.umd.js +11 -0
  210. package/dist/translations/lt.d.ts +8 -0
  211. package/dist/translations/lt.js +5 -0
  212. package/dist/translations/lt.umd.js +11 -0
  213. package/dist/translations/lv.d.ts +8 -0
  214. package/dist/translations/lv.js +5 -0
  215. package/dist/translations/lv.umd.js +11 -0
  216. package/dist/translations/ms.d.ts +8 -0
  217. package/dist/translations/ms.js +5 -0
  218. package/dist/translations/ms.umd.js +11 -0
  219. package/dist/translations/nb.d.ts +8 -0
  220. package/dist/translations/nb.js +5 -0
  221. package/dist/translations/nb.umd.js +11 -0
  222. package/dist/translations/ne.d.ts +8 -0
  223. package/dist/translations/ne.js +5 -0
  224. package/dist/translations/ne.umd.js +11 -0
  225. package/dist/translations/nl.d.ts +8 -0
  226. package/dist/translations/nl.js +5 -0
  227. package/dist/translations/nl.umd.js +11 -0
  228. package/dist/translations/no.d.ts +8 -0
  229. package/dist/translations/no.js +5 -0
  230. package/dist/translations/no.umd.js +11 -0
  231. package/dist/translations/oc.d.ts +8 -0
  232. package/dist/translations/oc.js +5 -0
  233. package/dist/translations/oc.umd.js +11 -0
  234. package/dist/translations/pl.d.ts +8 -0
  235. package/dist/translations/pl.js +5 -0
  236. package/dist/translations/pl.umd.js +11 -0
  237. package/dist/translations/pt-br.d.ts +8 -0
  238. package/dist/translations/pt-br.js +5 -0
  239. package/dist/translations/pt-br.umd.js +11 -0
  240. package/dist/translations/pt.d.ts +8 -0
  241. package/dist/translations/pt.js +5 -0
  242. package/dist/translations/pt.umd.js +11 -0
  243. package/dist/translations/ro.d.ts +8 -0
  244. package/dist/translations/ro.js +5 -0
  245. package/dist/translations/ro.umd.js +11 -0
  246. package/dist/translations/ru.d.ts +8 -0
  247. package/dist/translations/ru.js +5 -0
  248. package/dist/translations/ru.umd.js +11 -0
  249. package/dist/translations/si.d.ts +8 -0
  250. package/dist/translations/si.js +5 -0
  251. package/dist/translations/si.umd.js +11 -0
  252. package/dist/translations/sk.d.ts +8 -0
  253. package/dist/translations/sk.js +5 -0
  254. package/dist/translations/sk.umd.js +11 -0
  255. package/dist/translations/sl.d.ts +8 -0
  256. package/dist/translations/sl.js +5 -0
  257. package/dist/translations/sl.umd.js +11 -0
  258. package/dist/translations/sq.d.ts +8 -0
  259. package/dist/translations/sq.js +5 -0
  260. package/dist/translations/sq.umd.js +11 -0
  261. package/dist/translations/sr-latn.d.ts +8 -0
  262. package/dist/translations/sr-latn.js +5 -0
  263. package/dist/translations/sr-latn.umd.js +11 -0
  264. package/dist/translations/sr.d.ts +8 -0
  265. package/dist/translations/sr.js +5 -0
  266. package/dist/translations/sr.umd.js +11 -0
  267. package/dist/translations/sv.d.ts +8 -0
  268. package/dist/translations/sv.js +5 -0
  269. package/dist/translations/sv.umd.js +11 -0
  270. package/dist/translations/th.d.ts +8 -0
  271. package/dist/translations/th.js +5 -0
  272. package/dist/translations/th.umd.js +11 -0
  273. package/dist/translations/ti.d.ts +8 -0
  274. package/dist/translations/ti.js +5 -0
  275. package/dist/translations/ti.umd.js +11 -0
  276. package/dist/translations/tk.d.ts +8 -0
  277. package/dist/translations/tk.js +5 -0
  278. package/dist/translations/tk.umd.js +11 -0
  279. package/dist/translations/tr.d.ts +8 -0
  280. package/dist/translations/tr.js +5 -0
  281. package/dist/translations/tr.umd.js +11 -0
  282. package/dist/translations/tt.d.ts +8 -0
  283. package/dist/translations/tt.js +5 -0
  284. package/dist/translations/tt.umd.js +11 -0
  285. package/dist/translations/ug.d.ts +8 -0
  286. package/dist/translations/ug.js +5 -0
  287. package/dist/translations/ug.umd.js +11 -0
  288. package/dist/translations/uk.d.ts +8 -0
  289. package/dist/translations/uk.js +5 -0
  290. package/dist/translations/uk.umd.js +11 -0
  291. package/dist/translations/ur.d.ts +8 -0
  292. package/dist/translations/ur.js +5 -0
  293. package/dist/translations/ur.umd.js +11 -0
  294. package/dist/translations/uz.d.ts +8 -0
  295. package/dist/translations/uz.js +5 -0
  296. package/dist/translations/uz.umd.js +11 -0
  297. package/dist/translations/vi.d.ts +8 -0
  298. package/dist/translations/vi.js +5 -0
  299. package/dist/translations/vi.umd.js +11 -0
  300. package/dist/translations/zh-cn.d.ts +8 -0
  301. package/dist/translations/zh-cn.js +5 -0
  302. package/dist/translations/zh-cn.umd.js +11 -0
  303. package/dist/translations/zh.d.ts +8 -0
  304. package/dist/translations/zh.js +5 -0
  305. package/dist/translations/zh.umd.js +11 -0
  306. package/dist/ui/bookmarkactionsview.d.ts +106 -0
  307. package/dist/ui/bookmarkformview.d.ts +122 -0
  308. package/dist/updatebookmarkcommand.d.ts +46 -0
  309. package/dist/utils.d.ts +15 -0
  310. package/lang/contexts.json +13 -0
  311. package/lang/translations/af.po +56 -0
  312. package/lang/translations/ar.po +56 -0
  313. package/lang/translations/ast.po +56 -0
  314. package/lang/translations/az.po +56 -0
  315. package/lang/translations/bg.po +56 -0
  316. package/lang/translations/bn.po +56 -0
  317. package/lang/translations/bs.po +56 -0
  318. package/lang/translations/ca.po +56 -0
  319. package/lang/translations/cs.po +56 -0
  320. package/lang/translations/da.po +56 -0
  321. package/lang/translations/de-ch.po +56 -0
  322. package/lang/translations/de.po +56 -0
  323. package/lang/translations/el.po +56 -0
  324. package/lang/translations/en-au.po +56 -0
  325. package/lang/translations/en-gb.po +56 -0
  326. package/lang/translations/en.po +56 -0
  327. package/lang/translations/eo.po +56 -0
  328. package/lang/translations/es-co.po +56 -0
  329. package/lang/translations/es.po +56 -0
  330. package/lang/translations/et.po +56 -0
  331. package/lang/translations/eu.po +56 -0
  332. package/lang/translations/fa.po +56 -0
  333. package/lang/translations/fi.po +56 -0
  334. package/lang/translations/fr.po +56 -0
  335. package/lang/translations/gl.po +56 -0
  336. package/lang/translations/gu.po +56 -0
  337. package/lang/translations/he.po +56 -0
  338. package/lang/translations/hi.po +56 -0
  339. package/lang/translations/hr.po +56 -0
  340. package/lang/translations/hu.po +56 -0
  341. package/lang/translations/hy.po +56 -0
  342. package/lang/translations/id.po +56 -0
  343. package/lang/translations/it.po +56 -0
  344. package/lang/translations/ja.po +56 -0
  345. package/lang/translations/jv.po +56 -0
  346. package/lang/translations/kk.po +56 -0
  347. package/lang/translations/km.po +56 -0
  348. package/lang/translations/kn.po +56 -0
  349. package/lang/translations/ko.po +56 -0
  350. package/lang/translations/ku.po +56 -0
  351. package/lang/translations/lt.po +56 -0
  352. package/lang/translations/lv.po +56 -0
  353. package/lang/translations/ms.po +56 -0
  354. package/lang/translations/nb.po +56 -0
  355. package/lang/translations/ne.po +56 -0
  356. package/lang/translations/nl.po +56 -0
  357. package/lang/translations/no.po +56 -0
  358. package/lang/translations/oc.po +56 -0
  359. package/lang/translations/pl.po +56 -0
  360. package/lang/translations/pt-br.po +56 -0
  361. package/lang/translations/pt.po +56 -0
  362. package/lang/translations/ro.po +56 -0
  363. package/lang/translations/ru.po +56 -0
  364. package/lang/translations/si.po +56 -0
  365. package/lang/translations/sk.po +56 -0
  366. package/lang/translations/sl.po +56 -0
  367. package/lang/translations/sq.po +56 -0
  368. package/lang/translations/sr-latn.po +56 -0
  369. package/lang/translations/sr.po +56 -0
  370. package/lang/translations/sv.po +56 -0
  371. package/lang/translations/th.po +56 -0
  372. package/lang/translations/ti.po +56 -0
  373. package/lang/translations/tk.po +56 -0
  374. package/lang/translations/tr.po +56 -0
  375. package/lang/translations/tt.po +56 -0
  376. package/lang/translations/ug.po +56 -0
  377. package/lang/translations/uk.po +56 -0
  378. package/lang/translations/ur.po +56 -0
  379. package/lang/translations/uz.po +56 -0
  380. package/lang/translations/vi.po +56 -0
  381. package/lang/translations/zh-cn.po +56 -0
  382. package/lang/translations/zh.po +56 -0
  383. package/package.json +32 -3
  384. package/src/augmentation.d.ts +24 -0
  385. package/src/augmentation.js +5 -0
  386. package/src/bookmark.d.ts +30 -0
  387. package/src/bookmark.js +36 -0
  388. package/src/bookmarkconfig.d.ts +48 -0
  389. package/src/bookmarkconfig.js +5 -0
  390. package/src/bookmarkediting.d.ts +51 -0
  391. package/src/bookmarkediting.js +211 -0
  392. package/src/bookmarkui.d.ts +166 -0
  393. package/src/bookmarkui.js +582 -0
  394. package/src/index.d.ts +14 -0
  395. package/src/index.js +13 -0
  396. package/src/insertbookmarkcommand.d.ts +38 -0
  397. package/src/insertbookmarkcommand.js +113 -0
  398. package/src/ui/bookmarkactionsview.d.ts +102 -0
  399. package/src/ui/bookmarkactionsview.js +154 -0
  400. package/src/ui/bookmarkformview.d.ts +118 -0
  401. package/src/ui/bookmarkformview.js +203 -0
  402. package/src/updatebookmarkcommand.d.ts +42 -0
  403. package/src/updatebookmarkcommand.js +75 -0
  404. package/src/utils.d.ts +11 -0
  405. package/src/utils.js +19 -0
  406. package/theme/bookmark.css +50 -0
  407. package/theme/bookmarkactions.css +44 -0
  408. 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
+ }