@ckeditor/ckeditor5-fullscreen 45.0.0-alpha.0 → 45.0.0-alpha.10

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 (164) hide show
  1. package/build/fullscreen.js +1 -1
  2. package/build/translations/ar.js +1 -1
  3. package/build/translations/bg.js +1 -1
  4. package/build/translations/bn.js +1 -1
  5. package/build/translations/ca.js +1 -1
  6. package/build/translations/cs.js +1 -1
  7. package/build/translations/da.js +1 -1
  8. package/build/translations/de.js +1 -1
  9. package/build/translations/el.js +1 -1
  10. package/build/translations/es.js +1 -1
  11. package/build/translations/et.js +1 -1
  12. package/build/translations/fi.js +1 -1
  13. package/build/translations/fr.js +1 -1
  14. package/build/translations/he.js +1 -1
  15. package/build/translations/hi.js +1 -1
  16. package/build/translations/hu.js +1 -1
  17. package/build/translations/id.js +1 -1
  18. package/build/translations/it.js +1 -1
  19. package/build/translations/ja.js +1 -1
  20. package/build/translations/ko.js +1 -1
  21. package/build/translations/lt.js +1 -1
  22. package/build/translations/lv.js +1 -1
  23. package/build/translations/ms.js +1 -1
  24. package/build/translations/nl.js +1 -1
  25. package/build/translations/no.js +1 -1
  26. package/build/translations/pl.js +1 -1
  27. package/build/translations/pt-br.js +1 -1
  28. package/build/translations/pt.js +1 -1
  29. package/build/translations/ro.js +1 -1
  30. package/build/translations/ru.js +1 -1
  31. package/build/translations/sk.js +1 -1
  32. package/build/translations/sr.js +1 -1
  33. package/build/translations/sv.js +1 -1
  34. package/build/translations/th.js +1 -1
  35. package/build/translations/tr.js +1 -1
  36. package/build/translations/uk.js +1 -1
  37. package/build/translations/vi.js +1 -1
  38. package/build/translations/zh-cn.js +1 -1
  39. package/build/translations/zh.js +1 -1
  40. package/ckeditor5-metadata.json +8 -1
  41. package/dist/index.js +72 -10
  42. package/dist/index.js.map +1 -1
  43. package/dist/translations/ar.js +1 -1
  44. package/dist/translations/ar.umd.js +1 -1
  45. package/dist/translations/bg.js +1 -1
  46. package/dist/translations/bg.umd.js +1 -1
  47. package/dist/translations/bn.js +1 -1
  48. package/dist/translations/bn.umd.js +1 -1
  49. package/dist/translations/ca.js +1 -1
  50. package/dist/translations/ca.umd.js +1 -1
  51. package/dist/translations/cs.js +1 -1
  52. package/dist/translations/cs.umd.js +1 -1
  53. package/dist/translations/da.js +1 -1
  54. package/dist/translations/da.umd.js +1 -1
  55. package/dist/translations/de.js +1 -1
  56. package/dist/translations/de.umd.js +1 -1
  57. package/dist/translations/el.js +1 -1
  58. package/dist/translations/el.umd.js +1 -1
  59. package/dist/translations/es.js +1 -1
  60. package/dist/translations/es.umd.js +1 -1
  61. package/dist/translations/et.js +1 -1
  62. package/dist/translations/et.umd.js +1 -1
  63. package/dist/translations/fi.js +1 -1
  64. package/dist/translations/fi.umd.js +1 -1
  65. package/dist/translations/fr.js +1 -1
  66. package/dist/translations/fr.umd.js +1 -1
  67. package/dist/translations/he.js +1 -1
  68. package/dist/translations/he.umd.js +1 -1
  69. package/dist/translations/hi.js +1 -1
  70. package/dist/translations/hi.umd.js +1 -1
  71. package/dist/translations/hu.js +1 -1
  72. package/dist/translations/hu.umd.js +1 -1
  73. package/dist/translations/id.js +1 -1
  74. package/dist/translations/id.umd.js +1 -1
  75. package/dist/translations/it.js +1 -1
  76. package/dist/translations/it.umd.js +1 -1
  77. package/dist/translations/ja.js +1 -1
  78. package/dist/translations/ja.umd.js +1 -1
  79. package/dist/translations/ko.js +1 -1
  80. package/dist/translations/ko.umd.js +1 -1
  81. package/dist/translations/lt.js +1 -1
  82. package/dist/translations/lt.umd.js +1 -1
  83. package/dist/translations/lv.js +1 -1
  84. package/dist/translations/lv.umd.js +1 -1
  85. package/dist/translations/ms.js +1 -1
  86. package/dist/translations/ms.umd.js +1 -1
  87. package/dist/translations/nl.js +1 -1
  88. package/dist/translations/nl.umd.js +1 -1
  89. package/dist/translations/no.js +1 -1
  90. package/dist/translations/no.umd.js +1 -1
  91. package/dist/translations/pl.js +1 -1
  92. package/dist/translations/pl.umd.js +1 -1
  93. package/dist/translations/pt-br.js +1 -1
  94. package/dist/translations/pt-br.umd.js +1 -1
  95. package/dist/translations/pt.js +1 -1
  96. package/dist/translations/pt.umd.js +1 -1
  97. package/dist/translations/ro.js +1 -1
  98. package/dist/translations/ro.umd.js +1 -1
  99. package/dist/translations/ru.js +1 -1
  100. package/dist/translations/ru.umd.js +1 -1
  101. package/dist/translations/sk.js +1 -1
  102. package/dist/translations/sk.umd.js +1 -1
  103. package/dist/translations/sr.js +1 -1
  104. package/dist/translations/sr.umd.js +1 -1
  105. package/dist/translations/sv.js +1 -1
  106. package/dist/translations/sv.umd.js +1 -1
  107. package/dist/translations/th.js +1 -1
  108. package/dist/translations/th.umd.js +1 -1
  109. package/dist/translations/tr.js +1 -1
  110. package/dist/translations/tr.umd.js +1 -1
  111. package/dist/translations/uk.js +1 -1
  112. package/dist/translations/uk.umd.js +1 -1
  113. package/dist/translations/vi.js +1 -1
  114. package/dist/translations/vi.umd.js +1 -1
  115. package/dist/translations/zh-cn.js +1 -1
  116. package/dist/translations/zh-cn.umd.js +1 -1
  117. package/dist/translations/zh.js +1 -1
  118. package/dist/translations/zh.umd.js +1 -1
  119. package/lang/contexts.json +3 -1
  120. package/lang/translations/ar.po +4 -4
  121. package/lang/translations/bg.po +4 -4
  122. package/lang/translations/bn.po +4 -4
  123. package/lang/translations/ca.po +4 -4
  124. package/lang/translations/cs.po +4 -4
  125. package/lang/translations/da.po +4 -4
  126. package/lang/translations/de.po +4 -4
  127. package/lang/translations/el.po +4 -4
  128. package/lang/translations/es.po +4 -4
  129. package/lang/translations/et.po +4 -4
  130. package/lang/translations/fi.po +4 -4
  131. package/lang/translations/fr.po +4 -4
  132. package/lang/translations/he.po +4 -4
  133. package/lang/translations/hi.po +4 -4
  134. package/lang/translations/hu.po +4 -4
  135. package/lang/translations/id.po +4 -4
  136. package/lang/translations/it.po +4 -4
  137. package/lang/translations/ja.po +4 -4
  138. package/lang/translations/ko.po +4 -4
  139. package/lang/translations/lt.po +4 -4
  140. package/lang/translations/lv.po +4 -4
  141. package/lang/translations/ms.po +4 -4
  142. package/lang/translations/nl.po +4 -4
  143. package/lang/translations/no.po +4 -4
  144. package/lang/translations/pl.po +4 -4
  145. package/lang/translations/pt-br.po +4 -4
  146. package/lang/translations/pt.po +4 -4
  147. package/lang/translations/ro.po +4 -4
  148. package/lang/translations/ru.po +4 -4
  149. package/lang/translations/sk.po +4 -4
  150. package/lang/translations/sr.po +4 -4
  151. package/lang/translations/sv.po +4 -4
  152. package/lang/translations/th.po +4 -4
  153. package/lang/translations/tr.po +4 -4
  154. package/lang/translations/uk.po +4 -4
  155. package/lang/translations/vi.po +4 -4
  156. package/lang/translations/zh-cn.po +4 -4
  157. package/lang/translations/zh.po +4 -4
  158. package/package.json +13 -13
  159. package/src/fullscreenediting.js +10 -0
  160. package/src/fullscreenui.js +9 -0
  161. package/src/handlers/abstracteditorhandler.d.ts +8 -0
  162. package/src/handlers/abstracteditorhandler.js +52 -8
  163. package/src/handlers/classiceditorhandler.js +9 -3
  164. package/src/handlers/decouplededitorhandler.js +3 -2
package/dist/index.js CHANGED
@@ -3,10 +3,10 @@
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
4
4
  */
5
5
  import { Command, Plugin } from '@ckeditor/ckeditor5-core/dist/index.js';
6
+ import { global, createElement, Rect, env } from '@ckeditor/ckeditor5-utils/dist/index.js';
6
7
  import { ClassicEditor } from '@ckeditor/ckeditor5-editor-classic/dist/index.js';
7
8
  import { DecoupledEditor } from '@ckeditor/ckeditor5-editor-decoupled/dist/index.js';
8
9
  import { BodyCollection, DialogViewPosition, MenuBarView, ButtonView, MenuBarMenuListItemButtonView } from '@ckeditor/ckeditor5-ui/dist/index.js';
9
- import { global, createElement, Rect } from '@ckeditor/ckeditor5-utils/dist/index.js';
10
10
  import { IconFullscreenLeave, IconFullscreenEnter } from '@ckeditor/ckeditor5-icons/dist/index.js';
11
11
 
12
12
  const DIALOG_OFFSET = 28;
@@ -40,6 +40,9 @@ const DIALOG_OFFSET = 28;
40
40
  * It is used to restore their previous visibility when leaving the fullscreen mode and avoid showing elements
41
41
  * that were hidden before entering the fullscreen mode.
42
42
  */ _hiddenElements = new Map();
43
+ /**
44
+ * A map matching the ancestors of the editable element with their scroll positions before entering fullscreen mode.
45
+ */ _savedAncestorsScrollPositions = new Map();
43
46
  /**
44
47
  * A callback that shows the revision viewer, stored to restore the original one after exiting the fullscreen mode.
45
48
  */ _showRevisionViewerCallback = null;
@@ -122,6 +125,7 @@ const DIALOG_OFFSET = 28;
122
125
  /**
123
126
  * Enables the fullscreen mode. It executes the editor-specific enable handler and then the configured callback.
124
127
  */ enable() {
128
+ this._saveAncestorsScrollPositions(this._editor.ui.getEditableElement());
125
129
  this._defaultOnEnter();
126
130
  // Block scroll if the fullscreen container is the body element. Otherwise the document has to stay scrollable.
127
131
  if (this._editor.config.get('fullscreen.container') === this._document.body) {
@@ -140,7 +144,7 @@ const DIALOG_OFFSET = 28;
140
144
  this._generateDocumentOutlineContainer();
141
145
  }
142
146
  // Code coverage is provided in the commercial package repository as integration unit tests.
143
- /* istanbul ignore if -- @preserve */ if (this._editor.plugins.has('Pagination')) {
147
+ /* istanbul ignore next -- @preserve */ if (this._editor.plugins.has('Pagination') && this._editor.plugins.get('Pagination').isEnabled) {
144
148
  const paginationRenderer = this._editor.plugins.get('PaginationRenderer');
145
149
  paginationRenderer.setupScrollableAncestor();
146
150
  this._paginationBodyCollection = new BodyCollection(this._editor.locale);
@@ -208,9 +212,16 @@ const DIALOG_OFFSET = 28;
208
212
  if (this._placeholderMap.size === 0) {
209
213
  this._destroyContainer();
210
214
  }
215
+ // Restore scroll positions of all ancestors. It may include the closest editable wrapper causing the editor to change
216
+ // the visible content, which is not what we want. Thus, after executing the command, we use
217
+ // `editor.editing.view.scrollToTheSelection()` to scroll the editor viewport to the current selection.
218
+ for (const [ancestor, value] of this._savedAncestorsScrollPositions){
219
+ ancestor.scrollTo(value.scrollLeft, value.scrollTop);
220
+ }
221
+ this._savedAncestorsScrollPositions.clear();
211
222
  // Pagination has to be restored after leaving fullscreen mode to ensure proper rendering.
212
223
  // Code coverage is provided in the commercial package repository as integration unit tests.
213
- /* istanbul ignore if -- @preserve */ if (this._editor.plugins.has('Pagination')) {
224
+ /* istanbul ignore next -- @preserve */ if (this._editor.plugins.has('Pagination') && this._editor.plugins.get('Pagination').isEnabled) {
214
225
  const paginationRenderer = this._editor.plugins.get('PaginationRenderer');
215
226
  paginationRenderer.setupScrollableAncestor();
216
227
  paginationRenderer.linesRepository.setViewCollection(this._editor.ui.view.body);
@@ -259,13 +270,15 @@ const DIALOG_OFFSET = 28;
259
270
  * Checks if the PresenceListUI plugin is available and moves its elements to fullscreen mode.
260
271
  */ // Code coverage is provided in the commercial package repository as integration unit tests.
261
272
  /* istanbul ignore next -- @preserve */ _generatePresenceListContainer() {
273
+ const t = this._editor.t;
262
274
  const presenceListElement = createElement(document, 'div', {
263
275
  class: 'ck ck-fullscreen__left-sidebar-item'
264
276
  });
265
277
  presenceListElement.innerHTML = `
266
- <div class="ck ck-fullscreen__left-sidebar-header">Connected users</div>
278
+ <div class="ck ck-fullscreen__left-sidebar-header"></div>
267
279
  <div class="ck ck-fullscreen__presence-list" data-ck-fullscreen="presence-list"></div>
268
280
  `;
281
+ presenceListElement.firstElementChild.innerText = t('Connected users');
269
282
  document.querySelector('[data-ck-fullscreen="left-sidebar-sticky"]').appendChild(presenceListElement);
270
283
  const presenceListUI = this._editor.plugins.get('PresenceListUI');
271
284
  this.moveToFullscreen(presenceListUI.view.element, 'presence-list');
@@ -274,14 +287,14 @@ const DIALOG_OFFSET = 28;
274
287
  * Checks if the DocumentOutlineUI plugin is available and moves its elements to fullscreen mode.
275
288
  */ // Code coverage is provided in the commercial package repository as integration unit tests.
276
289
  /* istanbul ignore next -- @preserve */ _generateDocumentOutlineContainer() {
290
+ const t = this._editor.t;
277
291
  const documentOutlineHeaderElement = createElement(document, 'div', {
278
292
  class: 'ck-fullscreen__left-sidebar-item ck-fullscreen__left-sidebar-item--no-margin'
279
293
  });
280
294
  documentOutlineHeaderElement.innerHTML = `
281
- <div class="ck ck-fullscreen__left-sidebar-header ck-fullscreen__document-outline-header">
282
- Document outline
283
- </div>
295
+ <div class="ck ck-fullscreen__left-sidebar-header ck-fullscreen__document-outline-header"></div>
284
296
  `;
297
+ documentOutlineHeaderElement.firstElementChild.innerText = t('Document outline');
285
298
  const documentOutlineBodyWrapper = createElement(document, 'div', {
286
299
  class: 'ck ck-fullscreen__left-sidebar-item ck-fullscreen__document-outline-wrapper'
287
300
  });
@@ -459,6 +472,31 @@ const DIALOG_OFFSET = 28;
459
472
  dialogView.moveTo(fullscreenViewContainerRect.left + fullscreenViewContainerRect.width - dialogRect.width - DIALOG_OFFSET + scrollOffset, editorContainerRect.top);
460
473
  }
461
474
  }
475
+ /**
476
+ * Saves the scroll positions of all ancestors of the given element.
477
+ */ _saveAncestorsScrollPositions(domElement) {
478
+ let element = domElement.parentElement;
479
+ if (!element) {
480
+ return;
481
+ }
482
+ while(element){
483
+ const overflowY = element.style.overflowY || global.window.getComputedStyle(element).overflowY;
484
+ const overflowX = element.style.overflowX || global.window.getComputedStyle(element).overflowX;
485
+ // Out of 5 possible keyword values: visible, hidden, clip, scroll and auto - only the last two allow for scrolling.
486
+ if (overflowY === 'auto' || overflowY === 'scroll' || overflowX === 'auto' || overflowX === 'scroll') {
487
+ this._savedAncestorsScrollPositions.set(element, {
488
+ scrollLeft: element.scrollLeft,
489
+ scrollTop: element.scrollTop
490
+ });
491
+ } else if (element.tagName === 'HTML') {
492
+ this._savedAncestorsScrollPositions.set(element, {
493
+ scrollLeft: element.scrollLeft,
494
+ scrollTop: element.scrollTop
495
+ });
496
+ }
497
+ element = element.parentElement;
498
+ }
499
+ }
462
500
  }
463
501
 
464
502
  /**
@@ -478,7 +516,8 @@ const DIALOG_OFFSET = 28;
478
516
  */ _defaultOnEnter() {
479
517
  const editorUI = this._editor.ui;
480
518
  const editorUIView = editorUI.view;
481
- /* istanbul ignore if -- @preserve */ if (this._editor.plugins.has('Pagination')) {
519
+ // Code coverage is provided in the commercial package repository as integration unit tests.
520
+ /* istanbul ignore next -- @preserve */ if (this._editor.plugins.has('Pagination') && this._editor.plugins.get('Pagination').isEnabled) {
482
521
  this.moveToFullscreen(editorUI.getEditableElement().parentElement.querySelector('.ck-pagination-view'), 'pagination-view');
483
522
  }
484
523
  this.moveToFullscreen(editorUI.getEditableElement(), 'editable');
@@ -488,8 +527,13 @@ const DIALOG_OFFSET = 28;
488
527
  // in both menu bar and toolbar (adding the side padding to the elements).
489
528
  // Since we don't move the whole container but only parts, we need to reapply the attribute value manually.
490
529
  // Decupled editor doesn't have this issue because there is no top-level container,
491
- // so `dir` is set on each component separately.
530
+ // so `dir` attribute is set on each component separately.
492
531
  this.getWrapper().setAttribute('dir', editorUIView.element.getAttribute('dir'));
532
+ // The `ck-rounded-corners` class is added to the wrapper element to ensure that the corners in menu bar, toolbar etc are rounded
533
+ // when the editor is in fullscreen mode.
534
+ // Decupled editor doesn't have this issue because there is no top-level container,
535
+ // so `ck-rounded-corners` class is set on each component separately.
536
+ this.getWrapper().classList.add('ck-rounded-corners');
493
537
  if (this._editor.config.get('fullscreen.menuBar.isVisible')) {
494
538
  if (!editorUIView.menuBarView) {
495
539
  editorUIView.menuBarView = new MenuBarView(this._editor.locale);
@@ -517,7 +561,8 @@ const DIALOG_OFFSET = 28;
517
561
  /**
518
562
  * A function that moves the editor UI elements to the fullscreen mode.
519
563
  */ _defaultOnEnter() {
520
- /* istanbul ignore if -- @preserve */ if (this._editor.plugins.has('Pagination')) {
564
+ // Code coverage is provided in the commercial package repository as integration unit tests.
565
+ /* istanbul ignore next -- @preserve */ if (this._editor.plugins.has('Pagination') && this._editor.plugins.get('Pagination').isEnabled) {
521
566
  this.moveToFullscreen(this._editor.ui.getEditableElement().parentElement.querySelector('.ck-pagination-view'), 'pagination-view');
522
567
  }
523
568
  this.moveToFullscreen(this._editor.ui.getEditableElement(), 'editable');
@@ -607,6 +652,15 @@ const DIALOG_OFFSET = 28;
607
652
  // Set the Ctrl+Shift+F keystroke.
608
653
  this.editor.keystrokes.set('Ctrl+Shift+F', (evt, cancel)=>{
609
654
  this.editor.execute('toggleFullscreen');
655
+ // On non-Chromium browsers, the editor view and toolbar are not blurred properly after moving the editable,
656
+ // even though the `document.activeElement` is changed. Hence we need to blur them manually.
657
+ // Fixes https://github.com/ckeditor/ckeditor5/issues/18250 and https://github.com/ckeditor/ckeditor5/issues/18247.
658
+ if (!env.isBlink) {
659
+ this.editor.editing.view.document.isFocused = false;
660
+ this.editor.ui.view.toolbar.focusTracker.focusedElement = null;
661
+ }
662
+ // The order of scroll and focus is not important here.
663
+ this.editor.editing.view.scrollToTheSelection();
610
664
  this.editor.editing.view.focus();
611
665
  cancel();
612
666
  });
@@ -677,6 +731,14 @@ const COMMAND_NAME = 'toggleFullscreen';
677
731
  }
678
732
  this.listenTo(view, 'execute', ()=>{
679
733
  editor.execute(COMMAND_NAME);
734
+ // On non-Chromium browsers, toolbar is not blurred properly after moving the editable,
735
+ // even though the `document.activeElement` is changed. Hence we need to blur the view manually.
736
+ // Fixes https://github.com/ckeditor/ckeditor5/issues/18250 and https://github.com/ckeditor/ckeditor5/issues/18247.
737
+ if (!env.isBlink) {
738
+ this.editor.ui.view.toolbar.focusTracker.focusedElement = null;
739
+ }
740
+ // The order of scroll and focus is not important here.
741
+ editor.editing.view.scrollToTheSelection();
680
742
  editor.editing.view.focus();
681
743
  });
682
744
  return view;