@@ -16,20 +16,51 @@ import type View from '../view.js';
16
16
import { createElement , type Locale } from '@ckeditor/ckeditor5-utils' ;
17
17
18
18
/**
19
- * This is a special {@link module:ui/viewcollection~ViewCollection} dedicated to elements that are detached
20
- * from the DOM structure of the editor, like panels, icons , etc.
19
+ * This is a special {@link module:ui/viewcollection~ViewCollection} dedicated to elements that are detached from the DOM structure of
20
+ * the editor, like floating panels, floating toolbars, dialogs , etc.
21
21
*
22
- * The body collection is available in the {@link module:ui/editorui/editoruiview~EditorUIView#body `editor.ui.view.body`} property.
22
+ * The body collection is available under the {@link module:ui/editorui/editoruiview~EditorUIView#body `editor.ui.view.body`} property.
23
23
* Any plugin can add a {@link module:ui/view~View view} to this collection.
24
- * These views will render in a container placed directly in the `<body>` element.
25
- * The editor will detach and destroy this collection when the editor will be {@link module:core/editor/editor~Editor#destroy destroyed}.
26
24
*
27
- * If you need to control the life cycle of the body collection on your own, you can create your own instance of this class.
25
+ * All views added to a body collection render in a dedicated DOM container (`<div class="ck ck-body ...">...</div>`). All body collection
26
+ * containers render in a common shared (`<div class="ck-body-wrapper">...</div>`) in the DOM to limit the pollution of
27
+ * the `<body>` element. The resulting DOM structure is as follows:
28
28
*
29
- * A body collection will render itself automatically in the DOM body element as soon as you call {@link ~BodyCollection#attachToDom}.
30
- * If you create multiple body collections, this class will create a special wrapper element in the DOM to limit the number of
31
- * elements created directly in the body and remove it when the last body collection will be
32
- * {@link ~BodyCollection#detachFromDom detached}.
29
+ * ```html
30
+ * <body>
31
+ * <!-- Content of the webpage... -->
32
+ *
33
+ * <!-- The shared wrapper for all body collection containers. -->
34
+ * <div class="ck-body-wrapper">
35
+ * <!-- The container of the first body collection instance. -->
36
+ * <div class="ck ck-body ...">
37
+ * <!-- View elements belonging to the first body collection -->
38
+ * </div>
39
+ *
40
+ * <!-- The container of the second body collection instance. -->
41
+ * <div class="ck ck-body ...">...</div>
42
+ *
43
+ * <!-- More body collection containers for the rest of instances... -->
44
+ * </div>
45
+ * </body>
46
+ * ```
47
+ *
48
+ * By default, the {@link module:ui/editorui/editoruiview~EditorUIView `editor.ui.view`} manages the life cycle of the
49
+ * {@link module:ui/editorui/editoruiview~EditorUIView#body `editor.ui.view.body`} collection, attaching and detaching it
50
+ * when the editor gets created or {@link module:core/editor/editor~Editor#destroy destroyed}.
51
+ *
52
+ * # Custom body collection instances
53
+ *
54
+ * Even though most editor instances come with a built-in body collection
55
+ * ({@link module:ui/editorui/editoruiview~EditorUIView#body `editor.ui.view.body`}), you can create your own instance of this
56
+ * class if you need to control their life cycle.
57
+ *
58
+ * The life cycle of a custom body collection must be handled manually by the developer using the dedicated API:
59
+ * * A body collection will render itself automatically in the DOM as soon as you call {@link ~BodyCollection#attachToDom}.
60
+ * * Calling {@link ~BodyCollection#detachFromDom} will remove the collection from the DOM.
61
+ *
62
+ * **Note**: The shared collection wrapper (`<div class="ck-body-wrapper">...</div>`) gets automatically removed from DOM when the
63
+ * last body collection is {@link ~BodyCollection#detachFromDom detached} and does not require any special handling.
33
64
*/
34
65
export default class BodyCollection extends ViewCollection {
35
66
/**
@@ -39,10 +70,15 @@ export default class BodyCollection extends ViewCollection {
39
70
public readonly locale : Locale ;
40
71
41
72
/**
42
- * The element holding elements of the body region .
73
+ * The element holding elements of the body collection .
43
74
*/
44
75
private _bodyCollectionContainer ?: HTMLElement ;
45
76
77
+ /**
78
+ * The wrapper element that holds all of the {@link #_bodyCollectionContainer} elements.
79
+ */
80
+ private static _bodyWrapper ?: HTMLElement ;
81
+
46
82
/**
47
83
* Creates a new instance of the {@link module:ui/editorui/bodycollection~BodyCollection}.
48
84
*
@@ -56,7 +92,7 @@ export default class BodyCollection extends ViewCollection {
56
92
}
57
93
58
94
/**
59
- * The element holding elements of the body region .
95
+ * The element holding elements of the body collection .
60
96
*/
61
97
public get bodyCollectionContainer ( ) : HTMLElement | undefined {
62
98
return this . _bodyCollectionContainer ;
@@ -82,14 +118,12 @@ export default class BodyCollection extends ViewCollection {
82
118
children : this
83
119
} ) . render ( ) as HTMLElement ;
84
120
85
- let wrapper = document . querySelector ( '.ck-body-wrapper' ) ;
86
-
87
- if ( ! wrapper ) {
88
- wrapper = createElement ( document , 'div' , { class : 'ck-body-wrapper' } ) ;
89
- document . body . appendChild ( wrapper ) ;
121
+ if ( ! BodyCollection . _bodyWrapper ) {
122
+ BodyCollection . _bodyWrapper = createElement ( document , 'div' , { class : 'ck-body-wrapper' } ) ;
123
+ document . body . appendChild ( BodyCollection . _bodyWrapper ) ;
90
124
}
91
125
92
- wrapper . appendChild ( this . _bodyCollectionContainer ) ;
126
+ BodyCollection . _bodyWrapper . appendChild ( this . _bodyCollectionContainer ) ;
93
127
}
94
128
95
129
/**
@@ -103,10 +137,9 @@ export default class BodyCollection extends ViewCollection {
103
137
this . _bodyCollectionContainer . remove ( ) ;
104
138
}
105
139
106
- const wrapper = document . querySelector ( '.ck-body-wrapper' ) ;
107
-
108
- if ( wrapper && wrapper . childElementCount == 0 ) {
109
- wrapper . remove ( ) ;
140
+ if ( BodyCollection . _bodyWrapper && ! BodyCollection . _bodyWrapper . childElementCount ) {
141
+ BodyCollection . _bodyWrapper . remove ( ) ;
142
+ delete BodyCollection . _bodyWrapper ;
110
143
}
111
144
}
112
145
}
0 commit comments