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

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,113 @@
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 { logWarning } from 'ckeditor5/src/utils.js';
6
+ import { Command } from 'ckeditor5/src/core.js';
7
+ import { isBookmarkIdValid } from './utils.js';
8
+ /**
9
+ * The insert bookmark command.
10
+ *
11
+ * The command is registered by {@link module:bookmark/bookmarkediting~BookmarkEditing} as `'insertBookmark'`.
12
+ *
13
+ * To insert a bookmark element at place where is the current collapsed selection or where is the beginning of document selection,
14
+ * execute the command passing the bookmark id as a parameter:
15
+ *
16
+ * ```ts
17
+ * editor.execute( 'insertBookmark', { bookmarkId: 'foo_bar' } );
18
+ * ```
19
+ */
20
+ export default class InsertBookmarkCommand extends Command {
21
+ /**
22
+ * @inheritDoc
23
+ */
24
+ refresh() {
25
+ const model = this.editor.model;
26
+ const selection = model.document.selection;
27
+ const position = this._getPositionToInsertBookmark(selection);
28
+ this.isEnabled = !!position;
29
+ }
30
+ /**
31
+ * Executes the command.
32
+ *
33
+ * @fires execute
34
+ * @param options Command options.
35
+ * @param options.bookmarkId The value of the `bookmarkId` attribute.
36
+ */
37
+ execute(options) {
38
+ if (!options) {
39
+ return;
40
+ }
41
+ const { bookmarkId } = options;
42
+ if (!isBookmarkIdValid(bookmarkId)) {
43
+ /**
44
+ * Insert bookmark command can be executed only with a valid name.
45
+ *
46
+ * A valid bookmark name must be a non-empty string and must not contain any spaces.
47
+ *
48
+ * @error insert-bookmark-command-executed-with-invalid-name
49
+ */
50
+ logWarning('insert-bookmark-command-executed-with-invalid-name');
51
+ return;
52
+ }
53
+ const editor = this.editor;
54
+ const model = editor.model;
55
+ const selection = model.document.selection;
56
+ model.change(writer => {
57
+ let position = this._getPositionToInsertBookmark(selection);
58
+ const isBookmarkAllowed = model.schema.checkChild(position, 'bookmark');
59
+ // If the position does not allow for `bookmark` but allows for a `paragraph`
60
+ // then insert a `paragraph` then we will insert a `bookmark` inside.
61
+ if (!isBookmarkAllowed) {
62
+ const newPosition = editor.execute('insertParagraph', { position });
63
+ if (!newPosition) {
64
+ return;
65
+ }
66
+ position = newPosition;
67
+ }
68
+ const bookmarkElement = writer.createElement('bookmark', {
69
+ ...Object.fromEntries(selection.getAttributes()),
70
+ bookmarkId
71
+ });
72
+ model.insertObject(bookmarkElement, position, null, { setSelection: 'on' });
73
+ });
74
+ }
75
+ /**
76
+ * Returns the position where the bookmark can be inserted. And if it is not possible to insert a bookmark,
77
+ * check if it is possible to insert a paragraph.
78
+ */
79
+ _getPositionToInsertBookmark(selection) {
80
+ const model = this.editor.model;
81
+ const schema = model.schema;
82
+ const firstRange = selection.getFirstRange();
83
+ const startPosition = firstRange.start;
84
+ // Return position if it is allowed to insert bookmark or if it is allowed to insert paragraph.
85
+ if (isBookmarkAllowed(startPosition, schema)) {
86
+ return startPosition;
87
+ }
88
+ for (const { previousPosition, item } of firstRange) {
89
+ // When the table cell is selected (from the outside) we look for the first paragraph-like element inside.
90
+ if (item.is('element') &&
91
+ schema.checkChild(item, '$text') &&
92
+ isBookmarkAllowed(item, schema)) {
93
+ return model.createPositionAt(item, 0);
94
+ }
95
+ if (isBookmarkAllowed(previousPosition, schema)) {
96
+ return previousPosition;
97
+ }
98
+ }
99
+ return null;
100
+ }
101
+ }
102
+ /**
103
+ * Verify if the given position allows for bookmark insertion. Verify if auto-paragraphing could help.
104
+ */
105
+ function isBookmarkAllowed(position, schema) {
106
+ if (schema.checkChild(position, 'bookmark')) {
107
+ return true;
108
+ }
109
+ if (!schema.checkChild(position, 'paragraph')) {
110
+ return false;
111
+ }
112
+ return schema.checkChild('paragraph', 'bookmark');
113
+ }
@@ -0,0 +1,102 @@
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/ui/bookmarkactionsview
7
+ */
8
+ import { LabelView, ButtonView, View } from 'ckeditor5/src/ui.js';
9
+ import { FocusTracker, KeystrokeHandler, type LocaleTranslate, type Locale } from 'ckeditor5/src/utils.js';
10
+ import '@ckeditor/ckeditor5-ui/theme/components/responsive-form/responsiveform.css';
11
+ import '../../theme/bookmarkactions.css';
12
+ /**
13
+ * The bookmark actions view class. This view displays the bookmark preview, allows
14
+ * removing or editing the bookmark.
15
+ */
16
+ export default class BookmarkActionsView extends View {
17
+ /**
18
+ * Tracks information about DOM focus in the actions.
19
+ */
20
+ readonly focusTracker: FocusTracker;
21
+ /**
22
+ * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.
23
+ */
24
+ readonly keystrokes: KeystrokeHandler;
25
+ /**
26
+ * The bookmark preview view.
27
+ */
28
+ bookmarkPreviewView: LabelView;
29
+ /**
30
+ * The remove button view.
31
+ */
32
+ removeButtonView: ButtonView;
33
+ /**
34
+ * The edit bookmark button view.
35
+ */
36
+ editButtonView: ButtonView;
37
+ /**
38
+ * The id preview view.
39
+ *
40
+ * @observable
41
+ */
42
+ id: string | undefined;
43
+ /**
44
+ * A collection of views that can be focused in the view.
45
+ */
46
+ private readonly _focusables;
47
+ /**
48
+ * Helps cycling over {@link #_focusables} in the view.
49
+ */
50
+ private readonly _focusCycler;
51
+ t: LocaleTranslate;
52
+ /**
53
+ * @inheritDoc
54
+ */
55
+ constructor(locale: Locale);
56
+ /**
57
+ * @inheritDoc
58
+ */
59
+ render(): void;
60
+ /**
61
+ * @inheritDoc
62
+ */
63
+ destroy(): void;
64
+ /**
65
+ * Focuses the fist {@link #_focusables} in the actions.
66
+ */
67
+ focus(): void;
68
+ /**
69
+ * Creates a button view.
70
+ *
71
+ * @param label The button label.
72
+ * @param icon The button icon.
73
+ * @param eventName An event name that the `ButtonView#execute` event will be delegated to.
74
+ * @param additionalLabel An additional label outside the button.
75
+ * @returns The button view instance.
76
+ */
77
+ private _createButton;
78
+ /**
79
+ * Creates a bookmark name preview label.
80
+ *
81
+ * @returns The label view instance.
82
+ */
83
+ private _createBookmarkPreviewView;
84
+ }
85
+ /**
86
+ * Fired when the {@link ~BookmarkActionsView#editButtonView} is clicked.
87
+ *
88
+ * @eventName ~BookmarkActionsView#edit
89
+ */
90
+ export type EditEvent = {
91
+ name: 'edit';
92
+ args: [];
93
+ };
94
+ /**
95
+ * Fired when the {@link ~BookmarkActionsView#removeButtonView} is clicked.
96
+ *
97
+ * @eventName ~BookmarkActionsView#remove
98
+ */
99
+ export type RemoveEvent = {
100
+ name: 'remove';
101
+ args: [];
102
+ };
@@ -0,0 +1,154 @@
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/ui/bookmarkactionsview
7
+ */
8
+ import { LabelView, ButtonView, View, ViewCollection, FocusCycler } from 'ckeditor5/src/ui.js';
9
+ import { FocusTracker, KeystrokeHandler } from 'ckeditor5/src/utils.js';
10
+ import { icons } from 'ckeditor5/src/core.js';
11
+ // eslint-disable-next-line ckeditor5-rules/ckeditor-imports
12
+ import '@ckeditor/ckeditor5-ui/theme/components/responsive-form/responsiveform.css';
13
+ import '../../theme/bookmarkactions.css';
14
+ /**
15
+ * The bookmark actions view class. This view displays the bookmark preview, allows
16
+ * removing or editing the bookmark.
17
+ */
18
+ export default class BookmarkActionsView extends View {
19
+ /**
20
+ * @inheritDoc
21
+ */
22
+ constructor(locale) {
23
+ super(locale);
24
+ /**
25
+ * Tracks information about DOM focus in the actions.
26
+ */
27
+ this.focusTracker = new FocusTracker();
28
+ /**
29
+ * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.
30
+ */
31
+ this.keystrokes = new KeystrokeHandler();
32
+ /**
33
+ * A collection of views that can be focused in the view.
34
+ */
35
+ this._focusables = new ViewCollection();
36
+ const t = locale.t;
37
+ this.bookmarkPreviewView = this._createBookmarkPreviewView();
38
+ this.removeButtonView = this._createButton(t('Remove bookmark'), icons.remove, 'remove', this.bookmarkPreviewView);
39
+ this.editButtonView = this._createButton(t('Edit bookmark'), icons.pencil, 'edit', this.bookmarkPreviewView);
40
+ this.set('id', undefined);
41
+ this._focusCycler = new FocusCycler({
42
+ focusables: this._focusables,
43
+ focusTracker: this.focusTracker,
44
+ keystrokeHandler: this.keystrokes,
45
+ actions: {
46
+ // Navigate fields backwards using the Shift + Tab keystroke.
47
+ focusPrevious: 'shift + tab',
48
+ // Navigate fields forwards using the Tab key.
49
+ focusNext: 'tab'
50
+ }
51
+ });
52
+ this.setTemplate({
53
+ tag: 'div',
54
+ attributes: {
55
+ class: [
56
+ 'ck',
57
+ 'ck-bookmark-actions',
58
+ 'ck-responsive-form'
59
+ ],
60
+ // https://github.com/ckeditor/ckeditor5-link/issues/90
61
+ tabindex: '-1'
62
+ },
63
+ children: [
64
+ this.bookmarkPreviewView,
65
+ this.editButtonView,
66
+ this.removeButtonView
67
+ ]
68
+ });
69
+ }
70
+ /**
71
+ * @inheritDoc
72
+ */
73
+ render() {
74
+ super.render();
75
+ const childViews = [
76
+ this.editButtonView,
77
+ this.removeButtonView
78
+ ];
79
+ childViews.forEach(v => {
80
+ // Register the view as focusable.
81
+ this._focusables.add(v);
82
+ // Register the view in the focus tracker.
83
+ this.focusTracker.add(v.element);
84
+ });
85
+ // Start listening for the keystrokes coming from #element.
86
+ this.keystrokes.listenTo(this.element);
87
+ }
88
+ /**
89
+ * @inheritDoc
90
+ */
91
+ destroy() {
92
+ super.destroy();
93
+ this.focusTracker.destroy();
94
+ this.keystrokes.destroy();
95
+ }
96
+ /**
97
+ * Focuses the fist {@link #_focusables} in the actions.
98
+ */
99
+ focus() {
100
+ this._focusCycler.focusFirst();
101
+ }
102
+ /**
103
+ * Creates a button view.
104
+ *
105
+ * @param label The button label.
106
+ * @param icon The button icon.
107
+ * @param eventName An event name that the `ButtonView#execute` event will be delegated to.
108
+ * @param additionalLabel An additional label outside the button.
109
+ * @returns The button view instance.
110
+ */
111
+ _createButton(label, icon, eventName, additionalLabel) {
112
+ const button = new ButtonView(this.locale);
113
+ button.set({
114
+ label,
115
+ icon,
116
+ tooltip: true
117
+ });
118
+ button.delegate('execute').to(this, eventName);
119
+ // Since button label `id` is bound to the `ariaLabelledBy` property
120
+ // we need to modify this binding to include only the first ID token
121
+ // as this button will be labeled by multiple labels.
122
+ button.labelView.unbind('id');
123
+ button.labelView.bind('id').to(button, 'ariaLabelledBy', ariaLabelledBy => {
124
+ return getFirstToken(ariaLabelledBy);
125
+ });
126
+ button.ariaLabelledBy = `${button.ariaLabelledBy} ${additionalLabel.id}`;
127
+ return button;
128
+ }
129
+ /**
130
+ * Creates a bookmark name preview label.
131
+ *
132
+ * @returns The label view instance.
133
+ */
134
+ _createBookmarkPreviewView() {
135
+ const label = new LabelView(this.locale);
136
+ label.extendTemplate({
137
+ attributes: {
138
+ class: [
139
+ 'ck',
140
+ 'ck-bookmark-actions__preview'
141
+ ]
142
+ }
143
+ });
144
+ // Bind label text with the bookmark ID.
145
+ label.bind('text').to(this, 'id');
146
+ return label;
147
+ }
148
+ }
149
+ /**
150
+ * Returns the first token from space separated token list.
151
+ */
152
+ function getFirstToken(tokenList) {
153
+ return tokenList.split(' ')[0];
154
+ }
@@ -0,0 +1,118 @@
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/ui/bookmarkformview
7
+ */
8
+ import { ButtonView, LabeledFieldView, View, ViewCollection, type InputTextView } from 'ckeditor5/src/ui.js';
9
+ import { FocusTracker, KeystrokeHandler, type Locale } from 'ckeditor5/src/utils.js';
10
+ import '@ckeditor/ckeditor5-ui/theme/components/responsive-form/responsiveform.css';
11
+ import '../../theme/bookmarkform.css';
12
+ /**
13
+ * The bookmark form view controller class.
14
+ *
15
+ * See {@link module:bookmark/ui/bookmarkformview~BookmarkFormView}.
16
+ */
17
+ export default class BookmarkFormView extends View {
18
+ /**
19
+ * Tracks information about DOM focus in the form.
20
+ */
21
+ readonly focusTracker: FocusTracker;
22
+ /**
23
+ * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.
24
+ */
25
+ readonly keystrokes: KeystrokeHandler;
26
+ /**
27
+ * The ID input view.
28
+ */
29
+ idInputView: LabeledFieldView<InputTextView>;
30
+ /**
31
+ * The Submit button view.
32
+ */
33
+ buttonView: ButtonView;
34
+ /**
35
+ * A collection of form child views in the form.
36
+ */
37
+ readonly children: ViewCollection;
38
+ /**
39
+ * An array of form validators used by {@link #isValid}.
40
+ */
41
+ private readonly _validators;
42
+ /**
43
+ * A collection of views that can be focused in the form.
44
+ */
45
+ private readonly _focusables;
46
+ /**
47
+ * Helps cycling over {@link #_focusables} in the form.
48
+ */
49
+ private readonly _focusCycler;
50
+ /**
51
+ * Creates an instance of the {@link module:bookmark/ui/bookmarkformview~BookmarkFormView} class.
52
+ *
53
+ * Also see {@link #render}.
54
+ *
55
+ * @param locale The localization services instance.
56
+ * @param validators Form validators used by {@link #isValid}.
57
+ */
58
+ constructor(locale: Locale, validators: Array<BookmarkFormValidatorCallback>);
59
+ /**
60
+ * @inheritDoc
61
+ */
62
+ render(): void;
63
+ /**
64
+ * @inheritDoc
65
+ */
66
+ destroy(): void;
67
+ /**
68
+ * Focuses the fist {@link #_focusables} in the form.
69
+ */
70
+ focus(): void;
71
+ /**
72
+ * Validates the form and returns `false` when some fields are invalid.
73
+ */
74
+ isValid(): boolean;
75
+ /**
76
+ * Cleans up the supplementary error and information text of the {@link #idInputView}
77
+ * bringing them back to the state when the form has been displayed for the first time.
78
+ *
79
+ * See {@link #isValid}.
80
+ */
81
+ resetFormStatus(): void;
82
+ /**
83
+ * Creates header and form view.
84
+ */
85
+ private _createViewChildren;
86
+ /**
87
+ * Creates form content view with input and button.
88
+ */
89
+ private _createFormContentView;
90
+ /**
91
+ * Creates a labeled input view.
92
+ *
93
+ * @returns Labeled field view instance.
94
+ */
95
+ private _createIdInput;
96
+ /**
97
+ * Creates a button view.
98
+ *
99
+ * @param label The button label.
100
+ * @param className The additional button CSS class name.
101
+ * @returns The button view instance.
102
+ */
103
+ private _createButton;
104
+ /**
105
+ * The native DOM `value` of the {@link #idInputView} element.
106
+ *
107
+ * **Note**: Do not confuse it with the {@link module:ui/inputtext/inputtextview~InputTextView#value}
108
+ * which works one way only and may not represent the actual state of the component in the DOM.
109
+ */
110
+ get id(): string | null;
111
+ }
112
+ /**
113
+ * Callback used by {@link ~BookmarkFormView} to check if passed form value is valid.
114
+ *
115
+ * If `undefined` is returned, it is assumed that the form value is correct and there is no error.
116
+ * If string is returned, it is assumed that the form value is incorrect and the returned string is displayed in the error label
117
+ */
118
+ export type BookmarkFormValidatorCallback = (form: BookmarkFormView) => string | undefined;
@@ -0,0 +1,203 @@
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/ui/bookmarkformview
7
+ */
8
+ import { ButtonView, FocusCycler, LabeledFieldView, View, ViewCollection, createLabeledInputText, submitHandler, FormHeaderView } from 'ckeditor5/src/ui.js';
9
+ import { FocusTracker, KeystrokeHandler } from 'ckeditor5/src/utils.js';
10
+ // See: #8833.
11
+ // eslint-disable-next-line ckeditor5-rules/ckeditor-imports
12
+ import '@ckeditor/ckeditor5-ui/theme/components/responsive-form/responsiveform.css';
13
+ import '../../theme/bookmarkform.css';
14
+ /**
15
+ * The bookmark form view controller class.
16
+ *
17
+ * See {@link module:bookmark/ui/bookmarkformview~BookmarkFormView}.
18
+ */
19
+ export default class BookmarkFormView extends View {
20
+ /**
21
+ * Creates an instance of the {@link module:bookmark/ui/bookmarkformview~BookmarkFormView} class.
22
+ *
23
+ * Also see {@link #render}.
24
+ *
25
+ * @param locale The localization services instance.
26
+ * @param validators Form validators used by {@link #isValid}.
27
+ */
28
+ constructor(locale, validators) {
29
+ super(locale);
30
+ /**
31
+ * Tracks information about DOM focus in the form.
32
+ */
33
+ this.focusTracker = new FocusTracker();
34
+ /**
35
+ * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.
36
+ */
37
+ this.keystrokes = new KeystrokeHandler();
38
+ /**
39
+ * A collection of views that can be focused in the form.
40
+ */
41
+ this._focusables = new ViewCollection();
42
+ const t = locale.t;
43
+ this._validators = validators;
44
+ this.idInputView = this._createIdInput();
45
+ this.buttonView = this._createButton(t('Insert'), 'ck-button-action ck-button-bold');
46
+ this.buttonView.type = 'submit';
47
+ this.children = this._createViewChildren();
48
+ this._focusCycler = new FocusCycler({
49
+ focusables: this._focusables,
50
+ focusTracker: this.focusTracker,
51
+ keystrokeHandler: this.keystrokes,
52
+ actions: {
53
+ // Navigate form fields backwards using the Shift + Tab keystroke.
54
+ focusPrevious: 'shift + tab',
55
+ // Navigate form fields forwards using the Tab key.
56
+ focusNext: 'tab'
57
+ }
58
+ });
59
+ const classList = ['ck', 'ck-bookmark-view'];
60
+ this.setTemplate({
61
+ tag: 'form',
62
+ attributes: {
63
+ class: classList,
64
+ // https://github.com/ckeditor/ckeditor5-link/issues/90
65
+ tabindex: '-1'
66
+ },
67
+ children: this.children
68
+ });
69
+ }
70
+ /**
71
+ * @inheritDoc
72
+ */
73
+ render() {
74
+ super.render();
75
+ submitHandler({
76
+ view: this
77
+ });
78
+ const childViews = [
79
+ this.idInputView,
80
+ this.buttonView
81
+ ];
82
+ childViews.forEach(v => {
83
+ // Register the view as focusable.
84
+ this._focusables.add(v);
85
+ // Register the view in the focus tracker.
86
+ this.focusTracker.add(v.element);
87
+ });
88
+ // Start listening for the keystrokes coming from #element.
89
+ this.keystrokes.listenTo(this.element);
90
+ }
91
+ /**
92
+ * @inheritDoc
93
+ */
94
+ destroy() {
95
+ super.destroy();
96
+ this.focusTracker.destroy();
97
+ this.keystrokes.destroy();
98
+ }
99
+ /**
100
+ * Focuses the fist {@link #_focusables} in the form.
101
+ */
102
+ focus() {
103
+ this._focusCycler.focusFirst();
104
+ }
105
+ /**
106
+ * Validates the form and returns `false` when some fields are invalid.
107
+ */
108
+ isValid() {
109
+ this.resetFormStatus();
110
+ for (const validator of this._validators) {
111
+ const errorText = validator(this);
112
+ // One error per field is enough.
113
+ if (errorText) {
114
+ // Apply updated error.
115
+ this.idInputView.errorText = errorText;
116
+ return false;
117
+ }
118
+ }
119
+ return true;
120
+ }
121
+ /**
122
+ * Cleans up the supplementary error and information text of the {@link #idInputView}
123
+ * bringing them back to the state when the form has been displayed for the first time.
124
+ *
125
+ * See {@link #isValid}.
126
+ */
127
+ resetFormStatus() {
128
+ this.idInputView.errorText = null;
129
+ }
130
+ /**
131
+ * Creates header and form view.
132
+ */
133
+ _createViewChildren() {
134
+ const children = this.createCollection();
135
+ const t = this.t;
136
+ children.add(new FormHeaderView(this.locale, { label: t('Bookmark') }));
137
+ children.add(this._createFormContentView());
138
+ return children;
139
+ }
140
+ /**
141
+ * Creates form content view with input and button.
142
+ */
143
+ _createFormContentView() {
144
+ const view = new View(this.locale);
145
+ const children = this.createCollection();
146
+ const classList = ['ck', 'ck-bookmark-form', 'ck-responsive-form'];
147
+ children.add(this.idInputView);
148
+ children.add(this.buttonView);
149
+ view.setTemplate({
150
+ tag: 'div',
151
+ attributes: {
152
+ class: classList
153
+ },
154
+ children
155
+ });
156
+ return view;
157
+ }
158
+ /**
159
+ * Creates a labeled input view.
160
+ *
161
+ * @returns Labeled field view instance.
162
+ */
163
+ _createIdInput() {
164
+ const t = this.locale.t;
165
+ const labeledInput = new LabeledFieldView(this.locale, createLabeledInputText);
166
+ labeledInput.label = t('Bookmark name');
167
+ labeledInput.infoText = t('Enter the bookmark name without spaces.');
168
+ return labeledInput;
169
+ }
170
+ /**
171
+ * Creates a button view.
172
+ *
173
+ * @param label The button label.
174
+ * @param className The additional button CSS class name.
175
+ * @returns The button view instance.
176
+ */
177
+ _createButton(label, className) {
178
+ const button = new ButtonView(this.locale);
179
+ button.set({
180
+ label,
181
+ withText: true
182
+ });
183
+ button.extendTemplate({
184
+ attributes: {
185
+ class: className
186
+ }
187
+ });
188
+ return button;
189
+ }
190
+ /**
191
+ * The native DOM `value` of the {@link #idInputView} element.
192
+ *
193
+ * **Note**: Do not confuse it with the {@link module:ui/inputtext/inputtextview~InputTextView#value}
194
+ * which works one way only and may not represent the actual state of the component in the DOM.
195
+ */
196
+ get id() {
197
+ const { element } = this.idInputView.fieldView;
198
+ if (!element) {
199
+ return null;
200
+ }
201
+ return element.value.trim();
202
+ }
203
+ }