@ckeditor/ckeditor5-restricted-editing 47.1.0 → 47.2.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.
Files changed (313) hide show
  1. package/README.md +1 -1
  2. package/build/restricted-editing.js +2 -2
  3. package/build/translations/af.js +1 -1
  4. package/build/translations/ar.js +1 -1
  5. package/build/translations/ast.js +1 -1
  6. package/build/translations/az.js +1 -1
  7. package/build/translations/be.js +1 -1
  8. package/build/translations/bg.js +1 -1
  9. package/build/translations/bn.js +1 -1
  10. package/build/translations/bs.js +1 -1
  11. package/build/translations/ca.js +1 -1
  12. package/build/translations/cs.js +1 -1
  13. package/build/translations/da.js +1 -1
  14. package/build/translations/de-ch.js +1 -1
  15. package/build/translations/de.js +1 -1
  16. package/build/translations/el.js +1 -1
  17. package/build/translations/en-au.js +1 -1
  18. package/build/translations/en-gb.js +1 -1
  19. package/build/translations/eo.js +1 -1
  20. package/build/translations/es-co.js +1 -1
  21. package/build/translations/es.js +1 -1
  22. package/build/translations/et.js +1 -1
  23. package/build/translations/eu.js +1 -1
  24. package/build/translations/fa.js +1 -1
  25. package/build/translations/fi.js +1 -1
  26. package/build/translations/fr.js +1 -1
  27. package/build/translations/gl.js +1 -1
  28. package/build/translations/gu.js +1 -1
  29. package/build/translations/he.js +1 -1
  30. package/build/translations/hi.js +1 -1
  31. package/build/translations/hr.js +1 -1
  32. package/build/translations/hu.js +1 -1
  33. package/build/translations/hy.js +1 -1
  34. package/build/translations/id.js +1 -1
  35. package/build/translations/it.js +1 -1
  36. package/build/translations/ja.js +1 -1
  37. package/build/translations/jv.js +1 -1
  38. package/build/translations/kk.js +1 -1
  39. package/build/translations/km.js +1 -1
  40. package/build/translations/kn.js +1 -1
  41. package/build/translations/ko.js +1 -1
  42. package/build/translations/ku.js +1 -1
  43. package/build/translations/lt.js +1 -1
  44. package/build/translations/lv.js +1 -1
  45. package/build/translations/ms.js +1 -1
  46. package/build/translations/nb.js +1 -1
  47. package/build/translations/ne.js +1 -1
  48. package/build/translations/nl.js +1 -1
  49. package/build/translations/no.js +1 -1
  50. package/build/translations/oc.js +1 -1
  51. package/build/translations/pl.js +1 -1
  52. package/build/translations/pt-br.js +1 -1
  53. package/build/translations/pt.js +1 -1
  54. package/build/translations/ro.js +1 -1
  55. package/build/translations/ru.js +1 -1
  56. package/build/translations/si.js +1 -1
  57. package/build/translations/sk.js +1 -1
  58. package/build/translations/sl.js +1 -1
  59. package/build/translations/sq.js +1 -1
  60. package/build/translations/sr-latn.js +1 -1
  61. package/build/translations/sr.js +1 -1
  62. package/build/translations/sv.js +1 -1
  63. package/build/translations/th.js +1 -1
  64. package/build/translations/ti.js +1 -1
  65. package/build/translations/tk.js +1 -1
  66. package/build/translations/tr.js +1 -1
  67. package/build/translations/tt.js +1 -1
  68. package/build/translations/ug.js +1 -1
  69. package/build/translations/uk.js +1 -1
  70. package/build/translations/ur.js +1 -1
  71. package/build/translations/uz.js +1 -1
  72. package/build/translations/vi.js +1 -1
  73. package/build/translations/zh-cn.js +1 -1
  74. package/build/translations/zh.js +1 -1
  75. package/ckeditor5-metadata.json +20 -2
  76. package/dist/index.js +564 -105
  77. package/dist/index.js.map +1 -1
  78. package/dist/translations/af.js +1 -1
  79. package/dist/translations/af.umd.js +1 -1
  80. package/dist/translations/ar.js +1 -1
  81. package/dist/translations/ar.umd.js +1 -1
  82. package/dist/translations/ast.js +1 -1
  83. package/dist/translations/ast.umd.js +1 -1
  84. package/dist/translations/az.js +1 -1
  85. package/dist/translations/az.umd.js +1 -1
  86. package/dist/translations/be.js +1 -1
  87. package/dist/translations/be.umd.js +1 -1
  88. package/dist/translations/bg.js +1 -1
  89. package/dist/translations/bg.umd.js +1 -1
  90. package/dist/translations/bn.js +1 -1
  91. package/dist/translations/bn.umd.js +1 -1
  92. package/dist/translations/bs.js +1 -1
  93. package/dist/translations/bs.umd.js +1 -1
  94. package/dist/translations/ca.js +1 -1
  95. package/dist/translations/ca.umd.js +1 -1
  96. package/dist/translations/cs.js +1 -1
  97. package/dist/translations/cs.umd.js +1 -1
  98. package/dist/translations/da.js +1 -1
  99. package/dist/translations/da.umd.js +1 -1
  100. package/dist/translations/de-ch.js +1 -1
  101. package/dist/translations/de-ch.umd.js +1 -1
  102. package/dist/translations/de.js +1 -1
  103. package/dist/translations/de.umd.js +1 -1
  104. package/dist/translations/el.js +1 -1
  105. package/dist/translations/el.umd.js +1 -1
  106. package/dist/translations/en-au.js +1 -1
  107. package/dist/translations/en-au.umd.js +1 -1
  108. package/dist/translations/en-gb.js +1 -1
  109. package/dist/translations/en-gb.umd.js +1 -1
  110. package/dist/translations/en.js +1 -1
  111. package/dist/translations/en.umd.js +1 -1
  112. package/dist/translations/eo.js +1 -1
  113. package/dist/translations/eo.umd.js +1 -1
  114. package/dist/translations/es-co.js +1 -1
  115. package/dist/translations/es-co.umd.js +1 -1
  116. package/dist/translations/es.js +1 -1
  117. package/dist/translations/es.umd.js +1 -1
  118. package/dist/translations/et.js +1 -1
  119. package/dist/translations/et.umd.js +1 -1
  120. package/dist/translations/eu.js +1 -1
  121. package/dist/translations/eu.umd.js +1 -1
  122. package/dist/translations/fa.js +1 -1
  123. package/dist/translations/fa.umd.js +1 -1
  124. package/dist/translations/fi.js +1 -1
  125. package/dist/translations/fi.umd.js +1 -1
  126. package/dist/translations/fr.js +1 -1
  127. package/dist/translations/fr.umd.js +1 -1
  128. package/dist/translations/gl.js +1 -1
  129. package/dist/translations/gl.umd.js +1 -1
  130. package/dist/translations/gu.js +1 -1
  131. package/dist/translations/gu.umd.js +1 -1
  132. package/dist/translations/he.js +1 -1
  133. package/dist/translations/he.umd.js +1 -1
  134. package/dist/translations/hi.js +1 -1
  135. package/dist/translations/hi.umd.js +1 -1
  136. package/dist/translations/hr.js +1 -1
  137. package/dist/translations/hr.umd.js +1 -1
  138. package/dist/translations/hu.js +1 -1
  139. package/dist/translations/hu.umd.js +1 -1
  140. package/dist/translations/hy.js +1 -1
  141. package/dist/translations/hy.umd.js +1 -1
  142. package/dist/translations/id.js +1 -1
  143. package/dist/translations/id.umd.js +1 -1
  144. package/dist/translations/it.js +1 -1
  145. package/dist/translations/it.umd.js +1 -1
  146. package/dist/translations/ja.js +1 -1
  147. package/dist/translations/ja.umd.js +1 -1
  148. package/dist/translations/jv.js +1 -1
  149. package/dist/translations/jv.umd.js +1 -1
  150. package/dist/translations/kk.js +1 -1
  151. package/dist/translations/kk.umd.js +1 -1
  152. package/dist/translations/km.js +1 -1
  153. package/dist/translations/km.umd.js +1 -1
  154. package/dist/translations/kn.js +1 -1
  155. package/dist/translations/kn.umd.js +1 -1
  156. package/dist/translations/ko.js +1 -1
  157. package/dist/translations/ko.umd.js +1 -1
  158. package/dist/translations/ku.js +1 -1
  159. package/dist/translations/ku.umd.js +1 -1
  160. package/dist/translations/lt.js +1 -1
  161. package/dist/translations/lt.umd.js +1 -1
  162. package/dist/translations/lv.js +1 -1
  163. package/dist/translations/lv.umd.js +1 -1
  164. package/dist/translations/ms.js +1 -1
  165. package/dist/translations/ms.umd.js +1 -1
  166. package/dist/translations/nb.js +1 -1
  167. package/dist/translations/nb.umd.js +1 -1
  168. package/dist/translations/ne.js +1 -1
  169. package/dist/translations/ne.umd.js +1 -1
  170. package/dist/translations/nl.js +1 -1
  171. package/dist/translations/nl.umd.js +1 -1
  172. package/dist/translations/no.js +1 -1
  173. package/dist/translations/no.umd.js +1 -1
  174. package/dist/translations/oc.js +1 -1
  175. package/dist/translations/oc.umd.js +1 -1
  176. package/dist/translations/pl.js +1 -1
  177. package/dist/translations/pl.umd.js +1 -1
  178. package/dist/translations/pt-br.js +1 -1
  179. package/dist/translations/pt-br.umd.js +1 -1
  180. package/dist/translations/pt.js +1 -1
  181. package/dist/translations/pt.umd.js +1 -1
  182. package/dist/translations/ro.js +1 -1
  183. package/dist/translations/ro.umd.js +1 -1
  184. package/dist/translations/ru.js +1 -1
  185. package/dist/translations/ru.umd.js +1 -1
  186. package/dist/translations/si.js +1 -1
  187. package/dist/translations/si.umd.js +1 -1
  188. package/dist/translations/sk.js +1 -1
  189. package/dist/translations/sk.umd.js +1 -1
  190. package/dist/translations/sl.js +1 -1
  191. package/dist/translations/sl.umd.js +1 -1
  192. package/dist/translations/sq.js +1 -1
  193. package/dist/translations/sq.umd.js +1 -1
  194. package/dist/translations/sr-latn.js +1 -1
  195. package/dist/translations/sr-latn.umd.js +1 -1
  196. package/dist/translations/sr.js +1 -1
  197. package/dist/translations/sr.umd.js +1 -1
  198. package/dist/translations/sv.js +1 -1
  199. package/dist/translations/sv.umd.js +1 -1
  200. package/dist/translations/th.js +1 -1
  201. package/dist/translations/th.umd.js +1 -1
  202. package/dist/translations/ti.js +1 -1
  203. package/dist/translations/ti.umd.js +1 -1
  204. package/dist/translations/tk.js +1 -1
  205. package/dist/translations/tk.umd.js +1 -1
  206. package/dist/translations/tr.js +1 -1
  207. package/dist/translations/tr.umd.js +1 -1
  208. package/dist/translations/tt.js +1 -1
  209. package/dist/translations/tt.umd.js +1 -1
  210. package/dist/translations/ug.js +1 -1
  211. package/dist/translations/ug.umd.js +1 -1
  212. package/dist/translations/uk.js +1 -1
  213. package/dist/translations/uk.umd.js +1 -1
  214. package/dist/translations/ur.js +1 -1
  215. package/dist/translations/ur.umd.js +1 -1
  216. package/dist/translations/uz.js +1 -1
  217. package/dist/translations/uz.umd.js +1 -1
  218. package/dist/translations/vi.js +1 -1
  219. package/dist/translations/vi.umd.js +1 -1
  220. package/dist/translations/zh-cn.js +1 -1
  221. package/dist/translations/zh-cn.umd.js +1 -1
  222. package/dist/translations/zh.js +1 -1
  223. package/dist/translations/zh.umd.js +1 -1
  224. package/lang/contexts.json +4 -1
  225. package/lang/translations/af.po +16 -4
  226. package/lang/translations/ar.po +16 -4
  227. package/lang/translations/ast.po +16 -4
  228. package/lang/translations/az.po +16 -4
  229. package/lang/translations/be.po +16 -4
  230. package/lang/translations/bg.po +16 -4
  231. package/lang/translations/bn.po +16 -4
  232. package/lang/translations/bs.po +16 -4
  233. package/lang/translations/ca.po +16 -4
  234. package/lang/translations/cs.po +16 -4
  235. package/lang/translations/da.po +16 -4
  236. package/lang/translations/de-ch.po +16 -4
  237. package/lang/translations/de.po +16 -4
  238. package/lang/translations/el.po +16 -4
  239. package/lang/translations/en-au.po +16 -4
  240. package/lang/translations/en-gb.po +16 -4
  241. package/lang/translations/en.po +16 -4
  242. package/lang/translations/eo.po +16 -4
  243. package/lang/translations/es-co.po +16 -4
  244. package/lang/translations/es.po +16 -4
  245. package/lang/translations/et.po +16 -4
  246. package/lang/translations/eu.po +16 -4
  247. package/lang/translations/fa.po +16 -4
  248. package/lang/translations/fi.po +16 -4
  249. package/lang/translations/fr.po +16 -4
  250. package/lang/translations/gl.po +16 -4
  251. package/lang/translations/gu.po +16 -4
  252. package/lang/translations/he.po +16 -4
  253. package/lang/translations/hi.po +16 -4
  254. package/lang/translations/hr.po +16 -4
  255. package/lang/translations/hu.po +16 -4
  256. package/lang/translations/hy.po +16 -4
  257. package/lang/translations/id.po +16 -4
  258. package/lang/translations/it.po +16 -4
  259. package/lang/translations/ja.po +16 -4
  260. package/lang/translations/jv.po +16 -4
  261. package/lang/translations/kk.po +16 -4
  262. package/lang/translations/km.po +16 -4
  263. package/lang/translations/kn.po +16 -4
  264. package/lang/translations/ko.po +16 -4
  265. package/lang/translations/ku.po +16 -4
  266. package/lang/translations/lt.po +16 -4
  267. package/lang/translations/lv.po +16 -4
  268. package/lang/translations/ms.po +16 -4
  269. package/lang/translations/nb.po +16 -4
  270. package/lang/translations/ne.po +16 -4
  271. package/lang/translations/nl.po +16 -4
  272. package/lang/translations/no.po +16 -4
  273. package/lang/translations/oc.po +16 -4
  274. package/lang/translations/pl.po +16 -4
  275. package/lang/translations/pt-br.po +16 -4
  276. package/lang/translations/pt.po +16 -4
  277. package/lang/translations/ro.po +16 -4
  278. package/lang/translations/ru.po +16 -4
  279. package/lang/translations/si.po +16 -4
  280. package/lang/translations/sk.po +16 -4
  281. package/lang/translations/sl.po +16 -4
  282. package/lang/translations/sq.po +16 -4
  283. package/lang/translations/sr-latn.po +16 -4
  284. package/lang/translations/sr.po +16 -4
  285. package/lang/translations/sv.po +16 -4
  286. package/lang/translations/th.po +16 -4
  287. package/lang/translations/ti.po +16 -4
  288. package/lang/translations/tk.po +16 -4
  289. package/lang/translations/tr.po +16 -4
  290. package/lang/translations/tt.po +16 -4
  291. package/lang/translations/ug.po +16 -4
  292. package/lang/translations/uk.po +16 -4
  293. package/lang/translations/ur.po +16 -4
  294. package/lang/translations/uz.po +16 -4
  295. package/lang/translations/vi.po +16 -4
  296. package/lang/translations/zh-cn.po +16 -4
  297. package/lang/translations/zh.po +16 -4
  298. package/package.json +7 -7
  299. package/src/augmentation.d.ts +2 -1
  300. package/src/index.d.ts +1 -0
  301. package/src/index.js +1 -0
  302. package/src/restrictededitingconfig.d.ts +2 -2
  303. package/src/restrictededitingexceptionblockcommand.d.ts +57 -0
  304. package/src/restrictededitingexceptionblockcommand.js +203 -0
  305. package/src/restrictededitingmode/converters.d.ts +1 -0
  306. package/src/restrictededitingmode/converters.js +33 -6
  307. package/src/restrictededitingmode/utils.d.ts +8 -2
  308. package/src/restrictededitingmode/utils.js +16 -3
  309. package/src/restrictededitingmodeediting.d.ts +4 -0
  310. package/src/restrictededitingmodeediting.js +83 -35
  311. package/src/restrictededitingmodenavigationcommand.js +2 -1
  312. package/src/standardeditingmodeediting.js +135 -3
  313. package/src/standardeditingmodeui.js +75 -11
@@ -11,10 +11,6 @@ msgstr ""
11
11
  "Plural-Forms: nplurals=1; plural=0;\n"
12
12
  "Content-Type: text/plain; charset=UTF-8\n"
13
13
 
14
- msgctxt "A label of the button indicating that using this button will make a selected text non–editable."
15
- msgid "Disable editing"
16
- msgstr "Tắt tính năng chỉnh sửa"
17
-
18
14
  msgctxt "A label of the button indicating that using this button will make a selected text editable."
19
15
  msgid "Enable editing"
20
16
  msgstr "Bật tính năng chỉnh sửa"
@@ -30,3 +26,19 @@ msgstr "Vùng có thể chỉnh sửa tiếp theo"
30
26
  msgctxt "A label of the dropdown that provides controls to navigate editable regions in the content."
31
27
  msgid "Navigate editable regions"
32
28
  msgstr "Di chuyển giữa các vùng có thể chỉnh sửa"
29
+
30
+ msgctxt "A label of the button indicating that using this button will make a selected text non–editable."
31
+ msgid "Disable inline editing"
32
+ msgstr ""
33
+
34
+ msgctxt "A label of the button indicating that using this button will make a selected text editable."
35
+ msgid "Enable inline editing"
36
+ msgstr ""
37
+
38
+ msgctxt "A label of the button indicating that using this button will make a selected blocks non–editable."
39
+ msgid "Disable block editing"
40
+ msgstr ""
41
+
42
+ msgctxt "A label of the button indicating that using this button will make a selected blocks editable."
43
+ msgid "Enable block editing"
44
+ msgstr ""
@@ -11,10 +11,6 @@ msgstr ""
11
11
  "Plural-Forms: nplurals=1; plural=0;\n"
12
12
  "Content-Type: text/plain; charset=UTF-8\n"
13
13
 
14
- msgctxt "A label of the button indicating that using this button will make a selected text non–editable."
15
- msgid "Disable editing"
16
- msgstr "禁用编辑"
17
-
18
14
  msgctxt "A label of the button indicating that using this button will make a selected text editable."
19
15
  msgid "Enable editing"
20
16
  msgstr "允许编辑"
@@ -30,3 +26,19 @@ msgstr "下一个可编辑区域"
30
26
  msgctxt "A label of the dropdown that provides controls to navigate editable regions in the content."
31
27
  msgid "Navigate editable regions"
32
28
  msgstr "导航至可编辑区域"
29
+
30
+ msgctxt "A label of the button indicating that using this button will make a selected text non–editable."
31
+ msgid "Disable inline editing"
32
+ msgstr ""
33
+
34
+ msgctxt "A label of the button indicating that using this button will make a selected text editable."
35
+ msgid "Enable inline editing"
36
+ msgstr ""
37
+
38
+ msgctxt "A label of the button indicating that using this button will make a selected blocks non–editable."
39
+ msgid "Disable block editing"
40
+ msgstr ""
41
+
42
+ msgctxt "A label of the button indicating that using this button will make a selected blocks editable."
43
+ msgid "Enable block editing"
44
+ msgstr ""
@@ -11,10 +11,6 @@ msgstr ""
11
11
  "Plural-Forms: nplurals=1; plural=0;\n"
12
12
  "Content-Type: text/plain; charset=UTF-8\n"
13
13
 
14
- msgctxt "A label of the button indicating that using this button will make a selected text non–editable."
15
- msgid "Disable editing"
16
- msgstr "停用編輯"
17
-
18
14
  msgctxt "A label of the button indicating that using this button will make a selected text editable."
19
15
  msgid "Enable editing"
20
16
  msgstr "啟用編輯"
@@ -30,3 +26,19 @@ msgstr "下一個可編輯區域"
30
26
  msgctxt "A label of the dropdown that provides controls to navigate editable regions in the content."
31
27
  msgid "Navigate editable regions"
32
28
  msgstr "編輯區域導航"
29
+
30
+ msgctxt "A label of the button indicating that using this button will make a selected text non–editable."
31
+ msgid "Disable inline editing"
32
+ msgstr ""
33
+
34
+ msgctxt "A label of the button indicating that using this button will make a selected text editable."
35
+ msgid "Enable inline editing"
36
+ msgstr ""
37
+
38
+ msgctxt "A label of the button indicating that using this button will make a selected blocks non–editable."
39
+ msgid "Disable block editing"
40
+ msgstr ""
41
+
42
+ msgctxt "A label of the button indicating that using this button will make a selected blocks editable."
43
+ msgid "Enable block editing"
44
+ msgstr ""
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ckeditor/ckeditor5-restricted-editing",
3
- "version": "47.1.0",
3
+ "version": "47.2.0-alpha.0",
4
4
  "description": "Restricted editing feature for CKEditor 5 editors.",
5
5
  "keywords": [
6
6
  "ckeditor",
@@ -12,12 +12,12 @@
12
12
  "type": "module",
13
13
  "main": "src/index.js",
14
14
  "dependencies": {
15
- "@ckeditor/ckeditor5-core": "47.1.0",
16
- "@ckeditor/ckeditor5-engine": "47.1.0",
17
- "@ckeditor/ckeditor5-icons": "47.1.0",
18
- "@ckeditor/ckeditor5-ui": "47.1.0",
19
- "@ckeditor/ckeditor5-utils": "47.1.0",
20
- "ckeditor5": "47.1.0"
15
+ "@ckeditor/ckeditor5-core": "47.2.0-alpha.0",
16
+ "@ckeditor/ckeditor5-engine": "47.2.0-alpha.0",
17
+ "@ckeditor/ckeditor5-icons": "47.2.0-alpha.0",
18
+ "@ckeditor/ckeditor5-ui": "47.2.0-alpha.0",
19
+ "@ckeditor/ckeditor5-utils": "47.2.0-alpha.0",
20
+ "ckeditor5": "47.2.0-alpha.0"
21
21
  },
22
22
  "author": "CKSource (http://cksource.com/)",
23
23
  "license": "SEE LICENSE IN LICENSE.md",
@@ -2,7 +2,7 @@
2
2
  * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
4
4
  */
5
- import type { RestrictedEditingMode, RestrictedEditingModeEditing, RestrictedEditingModeUI, StandardEditingMode, StandardEditingModeEditing, StandardEditingModeUI, RestrictedEditingConfig, RestrictedEditingExceptionCommand, RestrictedEditingModeNavigationCommand } from './index.js';
5
+ import type { RestrictedEditingMode, RestrictedEditingModeEditing, RestrictedEditingModeUI, StandardEditingMode, StandardEditingModeEditing, StandardEditingModeUI, RestrictedEditingConfig, RestrictedEditingExceptionCommand, RestrictedEditingModeNavigationCommand, RestrictedEditingExceptionBlockCommand } from './index.js';
6
6
  declare module '@ckeditor/ckeditor5-core' {
7
7
  interface PluginsMap {
8
8
  [RestrictedEditingMode.pluginName]: RestrictedEditingMode;
@@ -16,6 +16,7 @@ declare module '@ckeditor/ckeditor5-core' {
16
16
  restrictedEditingException: RestrictedEditingExceptionCommand;
17
17
  goToPreviousRestrictedEditingException: RestrictedEditingModeNavigationCommand;
18
18
  goToNextRestrictedEditingException: RestrictedEditingModeNavigationCommand;
19
+ restrictedEditingExceptionBlock: RestrictedEditingExceptionBlockCommand;
19
20
  }
20
21
  interface EditorConfig {
21
22
  /**
package/src/index.d.ts CHANGED
@@ -10,6 +10,7 @@ export { RestrictedEditingModeEditing } from './restrictededitingmodeediting.js'
10
10
  export { RestrictedEditingModeUI } from './restrictededitingmodeui.js';
11
11
  export { RestrictedEditingExceptionCommand, type RestrictedEditingExceptionCommandParams } from './restrictededitingexceptioncommand.js';
12
12
  export { RestrictedEditingModeNavigationCommand, type RestrictedEditingModeNavigationDirection } from './restrictededitingmodenavigationcommand.js';
13
+ export { RestrictedEditingExceptionBlockCommand } from './restrictededitingexceptionblockcommand.js';
13
14
  export { StandardEditingMode } from './standardeditingmode.js';
14
15
  export { StandardEditingModeEditing } from './standardeditingmodeediting.js';
15
16
  export { StandardEditingModeUI } from './standardeditingmodeui.js';
package/src/index.js CHANGED
@@ -10,6 +10,7 @@ export { RestrictedEditingModeEditing } from './restrictededitingmodeediting.js'
10
10
  export { RestrictedEditingModeUI } from './restrictededitingmodeui.js';
11
11
  export { RestrictedEditingExceptionCommand } from './restrictededitingexceptioncommand.js';
12
12
  export { RestrictedEditingModeNavigationCommand } from './restrictededitingmodenavigationcommand.js';
13
+ export { RestrictedEditingExceptionBlockCommand } from './restrictededitingexceptionblockcommand.js';
13
14
  export { StandardEditingMode } from './standardeditingmode.js';
14
15
  export { StandardEditingModeEditing } from './standardeditingmodeediting.js';
15
16
  export { StandardEditingModeUI } from './standardeditingmodeui.js';
@@ -25,7 +25,7 @@
25
25
  */
26
26
  export interface RestrictedEditingConfig {
27
27
  /**
28
- * The command names allowed in non-restricted areas of the content.
28
+ * The command names allowed in inline non-restricted areas of the content.
29
29
  *
30
30
  * Defines which feature commands should be enabled in the restricted editing mode. The commands used for typing and deleting text
31
31
  * (`'input'`, `'delete'` and `'deleteForward'`) are allowed by the feature inside non-restricted regions and do not need to be defined.
@@ -49,7 +49,7 @@ export interface RestrictedEditingConfig {
49
49
  */
50
50
  allowedCommands: Array<string>;
51
51
  /**
52
- * The text attribute names allowed when pasting content ot non-restricted areas.
52
+ * The text attribute names allowed when pasting content in inline non-restricted areas.
53
53
  *
54
54
  * The default value is:
55
55
  *
@@ -0,0 +1,57 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
4
+ */
5
+ /**
6
+ * @module restricted-editing/restrictededitingexceptionblockcommand
7
+ */
8
+ import { Command } from 'ckeditor5/src/core.js';
9
+ /**
10
+ * The command that toggles exception blocks for the restricted editing.
11
+ */
12
+ export declare class RestrictedEditingExceptionBlockCommand extends Command {
13
+ /**
14
+ * Whether the selection starts in a block exception.
15
+ *
16
+ * @observable
17
+ * @readonly
18
+ */
19
+ value: boolean;
20
+ /**
21
+ * @inheritDoc
22
+ */
23
+ refresh(): void;
24
+ /**
25
+ * Wraps or unwraps the selected blocks with non-restricted area.
26
+ *
27
+ * @fires execute
28
+ * @param options Command options.
29
+ * @param options.forceValue If set, it will force the command behavior. If `true`, the command will apply a block exception,
30
+ * otherwise the command will remove the block exception. If not set, the command will act basing on its current value.
31
+ */
32
+ execute(options?: {
33
+ forceValue?: boolean;
34
+ }): void;
35
+ /**
36
+ * Checks the command's {@link #value}.
37
+ */
38
+ private _getValue;
39
+ /**
40
+ * Checks whether the command can be enabled in the current context.
41
+ *
42
+ * @returns Whether the command should be enabled.
43
+ */
44
+ private _checkEnabled;
45
+ /**
46
+ * Unwraps the exception from given blocks.
47
+ *
48
+ * If blocks which are supposed to be unwrapped are in the middle of an exception,
49
+ * start it or end it, then the exception will be split (if needed) and the blocks
50
+ * will be moved out of it, so other exception blocks remained wrapped.
51
+ */
52
+ private _removeException;
53
+ /**
54
+ * Applies the exception to given blocks.
55
+ */
56
+ private _applyException;
57
+ }
@@ -0,0 +1,203 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
4
+ */
5
+ /**
6
+ * @module restricted-editing/restrictededitingexceptionblockcommand
7
+ */
8
+ import { Command } from 'ckeditor5/src/core.js';
9
+ import { first } from 'ckeditor5/src/utils.js';
10
+ /**
11
+ * The command that toggles exception blocks for the restricted editing.
12
+ */
13
+ export class RestrictedEditingExceptionBlockCommand extends Command {
14
+ /**
15
+ * @inheritDoc
16
+ */
17
+ refresh() {
18
+ this.value = this._getValue();
19
+ this.isEnabled = this._checkEnabled();
20
+ }
21
+ /**
22
+ * Wraps or unwraps the selected blocks with non-restricted area.
23
+ *
24
+ * @fires execute
25
+ * @param options Command options.
26
+ * @param options.forceValue If set, it will force the command behavior. If `true`, the command will apply a block exception,
27
+ * otherwise the command will remove the block exception. If not set, the command will act basing on its current value.
28
+ */
29
+ execute(options = {}) {
30
+ const model = this.editor.model;
31
+ const schema = model.schema;
32
+ const selection = model.document.selection;
33
+ const blocks = Array.from(selection.getSelectedBlocks());
34
+ const value = (options.forceValue === undefined) ? !this.value : options.forceValue;
35
+ model.change(writer => {
36
+ if (!value) {
37
+ const blocksToUnwrap = blocks.map(block => {
38
+ // Find blocks directly nested inside an exception.
39
+ return findExceptionContentBlock(block);
40
+ }).filter((exception) => !!exception);
41
+ this._removeException(writer, blocksToUnwrap);
42
+ }
43
+ else {
44
+ const blocksToWrap = blocks.filter(block => {
45
+ // Already wrapped blocks needs to be considered while wrapping too
46
+ // in order to reuse their wrapper elements.
47
+ return findException(block) || checkCanBeWrapped(schema, block);
48
+ });
49
+ this._applyException(writer, blocksToWrap);
50
+ }
51
+ });
52
+ }
53
+ /**
54
+ * Checks the command's {@link #value}.
55
+ */
56
+ _getValue() {
57
+ const selection = this.editor.model.document.selection;
58
+ const firstBlock = first(selection.getSelectedBlocks());
59
+ return !!(firstBlock && findException(firstBlock));
60
+ }
61
+ /**
62
+ * Checks whether the command can be enabled in the current context.
63
+ *
64
+ * @returns Whether the command should be enabled.
65
+ */
66
+ _checkEnabled() {
67
+ if (this.value) {
68
+ return true;
69
+ }
70
+ const selection = this.editor.model.document.selection;
71
+ const schema = this.editor.model.schema;
72
+ const firstBlock = first(selection.getSelectedBlocks());
73
+ if (!firstBlock) {
74
+ return false;
75
+ }
76
+ return checkCanBeWrapped(schema, firstBlock);
77
+ }
78
+ /**
79
+ * Unwraps the exception from given blocks.
80
+ *
81
+ * If blocks which are supposed to be unwrapped are in the middle of an exception,
82
+ * start it or end it, then the exception will be split (if needed) and the blocks
83
+ * will be moved out of it, so other exception blocks remained wrapped.
84
+ */
85
+ _removeException(writer, blocks) {
86
+ // Unwrap all groups of block. Iterate in the reverse order to not break following ranges.
87
+ getRangesOfBlockGroups(writer, blocks).reverse().forEach(groupRange => {
88
+ if (groupRange.start.isAtStart && groupRange.end.isAtEnd) {
89
+ writer.unwrap(groupRange.start.parent);
90
+ return;
91
+ }
92
+ // The group of blocks are at the beginning of an exception so let's move them left (out of the exception).
93
+ if (groupRange.start.isAtStart) {
94
+ const positionBefore = writer.createPositionBefore(groupRange.start.parent);
95
+ writer.move(groupRange, positionBefore);
96
+ return;
97
+ }
98
+ // The blocks are in the middle of an exception so we need to split the exception after the last block
99
+ // so we move the items there.
100
+ if (!groupRange.end.isAtEnd) {
101
+ writer.split(groupRange.end);
102
+ }
103
+ // Now we are sure that groupRange.end.isAtEnd is true, so let's move the blocks right.
104
+ const positionAfter = writer.createPositionAfter(groupRange.end.parent);
105
+ writer.move(groupRange, positionAfter);
106
+ });
107
+ }
108
+ /**
109
+ * Applies the exception to given blocks.
110
+ */
111
+ _applyException(writer, blocks) {
112
+ const schema = this.editor.model.schema;
113
+ const exceptionsToMerge = [];
114
+ // Wrap all groups of block. Iterate in the reverse order to not break following ranges.
115
+ getRangesOfBlockGroups(writer, blocks).reverse().forEach(groupRange => {
116
+ let exception = findException(groupRange.start);
117
+ if (!exception) {
118
+ exception = writer.createElement('restrictedEditingException');
119
+ writer.wrap(groupRange, exception);
120
+ }
121
+ exceptionsToMerge.push(exception);
122
+ });
123
+ // Merge subsequent exception elements. Reverse the order again because this time we want to go through
124
+ // the exception elements in the source order (due to how merge works – it moves the right element's content
125
+ // to the first element and removes the right one. Since we may need to merge a couple of subsequent exception elements
126
+ // we want to keep the reference to the first (furthest left) one.
127
+ exceptionsToMerge.reverse();
128
+ // But first add any neighbouring block exceptions to the list.
129
+ if (exceptionsToMerge.length) {
130
+ const previousSibling = exceptionsToMerge.at(0).previousSibling;
131
+ const nextSibling = exceptionsToMerge.at(-1).nextSibling;
132
+ if (previousSibling?.is('element', 'restrictedEditingException')) {
133
+ exceptionsToMerge.unshift(previousSibling);
134
+ }
135
+ if (nextSibling?.is('element', 'restrictedEditingException')) {
136
+ exceptionsToMerge.push(nextSibling);
137
+ }
138
+ }
139
+ // Merge subsequent exceptions.
140
+ exceptionsToMerge.reduce((currentException, nextException) => {
141
+ if (currentException.nextSibling == nextException) {
142
+ writer.merge(writer.createPositionAfter(currentException));
143
+ return currentException;
144
+ }
145
+ return nextException;
146
+ });
147
+ // Remove inline exceptions from block exception.
148
+ schema.removeDisallowedAttributes(blocks, writer);
149
+ }
150
+ }
151
+ function findException(elementOrPosition) {
152
+ return elementOrPosition.findAncestor('restrictedEditingException', { includeSelf: true });
153
+ }
154
+ function findExceptionContentBlock(element) {
155
+ let node = element;
156
+ while (node.parent) {
157
+ if (node.parent.name == 'restrictedEditingException') {
158
+ return node;
159
+ }
160
+ node = node.parent;
161
+ }
162
+ return null;
163
+ }
164
+ /**
165
+ * Returns a minimal array of ranges containing groups of subsequent blocks.
166
+ *
167
+ * content: abcdefgh
168
+ * blocks: [ a, b, d, f, g, h ]
169
+ * output ranges: [ab]c[d]e[fgh]
170
+ */
171
+ function getRangesOfBlockGroups(writer, blocks) {
172
+ let startPosition;
173
+ let i = 0;
174
+ const ranges = [];
175
+ while (i < blocks.length) {
176
+ const block = blocks[i];
177
+ const nextBlock = blocks[i + 1];
178
+ if (!startPosition) {
179
+ startPosition = writer.createPositionBefore(block);
180
+ }
181
+ if (!nextBlock || block.nextSibling != nextBlock) {
182
+ ranges.push(writer.createRange(startPosition, writer.createPositionAfter(block)));
183
+ startPosition = null;
184
+ }
185
+ i++;
186
+ }
187
+ return ranges;
188
+ }
189
+ /**
190
+ * Checks whether exception can wrap the block.
191
+ */
192
+ function checkCanBeWrapped(schema, block) {
193
+ const parentContext = schema.createContext(block.parent);
194
+ // Is block exception allowed in parent of block.
195
+ if (!schema.checkChild(parentContext, 'restrictedEditingException')) {
196
+ return false;
197
+ }
198
+ // Is block allowed inside block exception.
199
+ if (!schema.checkChild(parentContext.push('restrictedEditingException'), block)) {
200
+ return false;
201
+ }
202
+ return true;
203
+ }
@@ -43,4 +43,5 @@ export declare function extendMarkerOnTypingPostFixer(editor: Editor): ModelPost
43
43
  export declare function upcastHighlightToMarker(config: {
44
44
  view: MatcherPattern;
45
45
  model: () => string;
46
+ useWrapperElement?: boolean;
46
47
  }): (dispatcher: UpcastDispatcher) => void;
@@ -30,10 +30,18 @@ export function setupExceptionHighlighting(editor) {
30
30
  if (!marker) {
31
31
  return false;
32
32
  }
33
- for (const viewElement of editor.editing.mapper.markerNameToElements(marker.name)) {
33
+ const modelWrapperElement = marker.getRange().getContainedElement();
34
+ if (modelWrapperElement && modelWrapperElement.is('element', 'restrictedEditingException')) {
35
+ const viewElement = editor.editing.mapper.toViewElement(modelWrapperElement);
34
36
  writer.addClass(HIGHLIGHT_CLASS, viewElement);
35
37
  highlightedMarkers.add(viewElement);
36
38
  }
39
+ else {
40
+ for (const viewElement of editor.editing.mapper.markerNameToElements(marker.name)) {
41
+ writer.addClass(HIGHLIGHT_CLASS, viewElement);
42
+ highlightedMarkers.add(viewElement);
43
+ }
44
+ }
37
45
  return false;
38
46
  });
39
47
  // Removing the class.
@@ -99,7 +107,7 @@ export function extendMarkerOnTypingPostFixer(editor) {
99
107
  * @internal
100
108
  */
101
109
  export function upcastHighlightToMarker(config) {
102
- return (dispatcher) => dispatcher.on('element:span', (evt, data, conversionApi) => {
110
+ return (dispatcher) => dispatcher.on('element', (evt, data, conversionApi) => {
103
111
  const { writer } = conversionApi;
104
112
  const matcher = new Matcher(config.view);
105
113
  const matcherResult = matcher.match(data.viewItem);
@@ -110,14 +118,33 @@ export function upcastHighlightToMarker(config) {
110
118
  const match = matcherResult.match;
111
119
  // Force consuming element's name (taken from upcast helpers elementToElement converter).
112
120
  match.name = true;
113
- const { modelRange: convertedChildrenRange } = conversionApi.convertChildren(data.viewItem, data.modelCursor);
121
+ if (!conversionApi.consumable.test(data.viewItem, match)) {
122
+ return;
123
+ }
124
+ let position = data.modelCursor;
125
+ let wrapperElement = null;
126
+ if (config.useWrapperElement) {
127
+ if (!conversionApi.schema.checkChild(position, 'restrictedEditingException')) {
128
+ return;
129
+ }
130
+ wrapperElement = writer.createElement('restrictedEditingException');
131
+ writer.insert(wrapperElement, position);
132
+ position = writer.createPositionAt(wrapperElement, 0);
133
+ }
134
+ const { modelRange: convertedChildrenRange } = conversionApi.convertChildren(data.viewItem, position);
114
135
  conversionApi.consumable.consume(data.viewItem, match);
115
136
  const markerName = config.model();
116
137
  const fakeMarkerStart = writer.createElement('$marker', { 'data-name': markerName });
117
138
  const fakeMarkerEnd = writer.createElement('$marker', { 'data-name': markerName });
118
- // Insert in reverse order to use converter content positions directly (without recalculating).
119
- writer.insert(fakeMarkerEnd, convertedChildrenRange.end);
120
- writer.insert(fakeMarkerStart, convertedChildrenRange.start);
139
+ if (wrapperElement) {
140
+ writer.insert(fakeMarkerStart, writer.createPositionBefore(wrapperElement));
141
+ writer.insert(fakeMarkerEnd, writer.createPositionAfter(wrapperElement));
142
+ }
143
+ else {
144
+ // Insert in reverse order to use converter content positions directly (without recalculating).
145
+ writer.insert(fakeMarkerEnd, convertedChildrenRange.end);
146
+ writer.insert(fakeMarkerStart, convertedChildrenRange.start);
147
+ }
121
148
  data.modelRange = writer.createRange(writer.createPositionBefore(fakeMarkerStart), writer.createPositionAfter(fakeMarkerEnd));
122
149
  data.modelCursor = data.modelRange.end;
123
150
  });
@@ -3,7 +3,7 @@
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
4
4
  */
5
5
  import type { Editor } from 'ckeditor5/src/core.js';
6
- import type { ModelDocumentSelection, Marker, ModelPosition, ModelRange } from 'ckeditor5/src/engine.js';
6
+ import type { ModelDocumentSelection, Marker, ModelPosition, ModelRange, Model } from 'ckeditor5/src/engine.js';
7
7
  /**
8
8
  * @module restricted-editing/restrictededitingmode/utils
9
9
  */
@@ -33,4 +33,10 @@ export declare function isPositionInRangeBoundaries(range: ModelRange, position:
33
33
  *
34
34
  * @internal
35
35
  */
36
- export declare function isSelectionInMarker(selection: ModelDocumentSelection, marker?: Marker): boolean;
36
+ export declare function isSelectionInMarker(selection: ModelDocumentSelection, model: Model, marker?: Marker): boolean;
37
+ /**
38
+ * Returns the marker range asjusted to the inside of exception wrapper element if needed.
39
+ *
40
+ * @internal
41
+ */
42
+ export declare function getExceptionRange(marker: Marker, model: Model): ModelRange;
@@ -14,7 +14,7 @@
14
14
  */
15
15
  export function getMarkerAtPosition(editor, position) {
16
16
  for (const marker of editor.model.markers) {
17
- const markerRange = marker.getRange();
17
+ const markerRange = getExceptionRange(marker, editor.model);
18
18
  if (isPositionInRangeBoundaries(markerRange, position)) {
19
19
  if (marker.name.startsWith('restrictedEditingException:')) {
20
20
  return marker;
@@ -44,13 +44,26 @@ export function isPositionInRangeBoundaries(range, position) {
44
44
  *
45
45
  * @internal
46
46
  */
47
- export function isSelectionInMarker(selection, marker) {
47
+ export function isSelectionInMarker(selection, model, marker) {
48
48
  if (!marker) {
49
49
  return false;
50
50
  }
51
- const markerRange = marker.getRange();
51
+ const markerRange = getExceptionRange(marker, model);
52
52
  if (selection.isCollapsed) {
53
53
  return isPositionInRangeBoundaries(markerRange, selection.focus);
54
54
  }
55
55
  return markerRange.containsRange(selection.getFirstRange(), true);
56
56
  }
57
+ /**
58
+ * Returns the marker range asjusted to the inside of exception wrapper element if needed.
59
+ *
60
+ * @internal
61
+ */
62
+ export function getExceptionRange(marker, model) {
63
+ const markerRange = marker.getRange();
64
+ const wrapperElement = markerRange.getContainedElement();
65
+ if (wrapperElement && wrapperElement.is('element', 'restrictedEditingException')) {
66
+ return model.createRangeIn(wrapperElement);
67
+ }
68
+ return markerRange;
69
+ }
@@ -60,6 +60,10 @@ export declare class RestrictedEditingModeEditing extends Plugin {
60
60
  * @param commandName Name of the command to enable.
61
61
  */
62
62
  enableCommand(commandName: string): void;
63
+ /**
64
+ * Registers block exception wrapper in the schema.
65
+ */
66
+ private _setupSchema;
63
67
  /**
64
68
  * Sets up the restricted mode editing conversion:
65
69
  *