diff options
author | Ismaël Bouya <ismael.bouya@normalesup.org> | 2017-01-20 00:55:51 +0100 |
---|---|---|
committer | Ismaël Bouya <ismael.bouya@normalesup.org> | 2017-01-20 00:55:51 +0100 |
commit | c63493c899de714b05b0521bb38aab60d19030ef (patch) | |
tree | fcb2b261afa0f3c2bd6b48929b64724c71192bae /sources/plugins/floatingspace | |
download | ludivine-ckeditor-component-c63493c899de714b05b0521bb38aab60d19030ef.tar.gz ludivine-ckeditor-component-c63493c899de714b05b0521bb38aab60d19030ef.tar.zst ludivine-ckeditor-component-c63493c899de714b05b0521bb38aab60d19030ef.zip |
Validation initiale4.6.2.1
Diffstat (limited to 'sources/plugins/floatingspace')
-rw-r--r-- | sources/plugins/floatingspace/plugin.js | 406 |
1 files changed, 406 insertions, 0 deletions
diff --git a/sources/plugins/floatingspace/plugin.js b/sources/plugins/floatingspace/plugin.js new file mode 100644 index 0000000..878d952 --- /dev/null +++ b/sources/plugins/floatingspace/plugin.js | |||
@@ -0,0 +1,406 @@ | |||
1 | /** | ||
2 | * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved. | ||
3 | * For licensing, see LICENSE.md or http://ckeditor.com/license | ||
4 | */ | ||
5 | |||
6 | ( function() { | ||
7 | var win = CKEDITOR.document.getWindow(), | ||
8 | pixelate = CKEDITOR.tools.cssLength; | ||
9 | |||
10 | CKEDITOR.plugins.add( 'floatingspace', { | ||
11 | init: function( editor ) { | ||
12 | // Add listener with lower priority than that in themedui creator. | ||
13 | // Thereby floatingspace will be created only if themedui wasn't used. | ||
14 | editor.on( 'loaded', function() { | ||
15 | attach( this ); | ||
16 | }, null, null, 20 ); | ||
17 | } | ||
18 | } ); | ||
19 | |||
20 | function scrollOffset( side ) { | ||
21 | var pageOffset = side == 'left' ? 'pageXOffset' : 'pageYOffset', | ||
22 | docScrollOffset = side == 'left' ? 'scrollLeft' : 'scrollTop'; | ||
23 | |||
24 | return ( pageOffset in win.$ ) ? win.$[ pageOffset ] : CKEDITOR.document.$.documentElement[ docScrollOffset ]; | ||
25 | } | ||
26 | |||
27 | function attach( editor ) { | ||
28 | var config = editor.config, | ||
29 | |||
30 | // Get the HTML for the predefined spaces. | ||
31 | topHtml = editor.fire( 'uiSpace', { space: 'top', html: '' } ).html, | ||
32 | |||
33 | // Re-positioning of the space. | ||
34 | layout = ( function() { | ||
35 | // Mode indicates the vertical aligning mode. | ||
36 | var mode, editable, | ||
37 | spaceRect, editorRect, viewRect, spaceHeight, pageScrollX, | ||
38 | |||
39 | // Allow minor adjustments of the float space from custom configs. | ||
40 | dockedOffsetX = config.floatSpaceDockedOffsetX || 0, | ||
41 | dockedOffsetY = config.floatSpaceDockedOffsetY || 0, | ||
42 | pinnedOffsetX = config.floatSpacePinnedOffsetX || 0, | ||
43 | pinnedOffsetY = config.floatSpacePinnedOffsetY || 0; | ||
44 | |||
45 | // Update the float space position. | ||
46 | function updatePos( pos, prop, val ) { | ||
47 | floatSpace.setStyle( prop, pixelate( val ) ); | ||
48 | floatSpace.setStyle( 'position', pos ); | ||
49 | } | ||
50 | |||
51 | // Change the current mode and update float space position accordingly. | ||
52 | function changeMode( newMode ) { | ||
53 | var editorPos = editable.getDocumentPosition(); | ||
54 | |||
55 | switch ( newMode ) { | ||
56 | case 'top': | ||
57 | updatePos( 'absolute', 'top', editorPos.y - spaceHeight - dockedOffsetY ); | ||
58 | break; | ||
59 | case 'pin': | ||
60 | updatePos( 'fixed', 'top', pinnedOffsetY ); | ||
61 | break; | ||
62 | case 'bottom': | ||
63 | updatePos( 'absolute', 'top', editorPos.y + ( editorRect.height || editorRect.bottom - editorRect.top ) + dockedOffsetY ); | ||
64 | break; | ||
65 | } | ||
66 | |||
67 | mode = newMode; | ||
68 | } | ||
69 | |||
70 | return function( evt ) { | ||
71 | // #10112 Do not fail on editable-less editor. | ||
72 | if ( !( editable = editor.editable() ) ) | ||
73 | return; | ||
74 | |||
75 | var show = ( evt && evt.name == 'focus' ); | ||
76 | |||
77 | // Show up the space on focus gain. | ||
78 | if ( show ) { | ||
79 | floatSpace.show(); | ||
80 | } | ||
81 | |||
82 | editor.fire( 'floatingSpaceLayout', { show: show } ); | ||
83 | |||
84 | // Reset the horizontal position for below measurement. | ||
85 | floatSpace.removeStyle( 'left' ); | ||
86 | floatSpace.removeStyle( 'right' ); | ||
87 | |||
88 | // Compute the screen position from the TextRectangle object would | ||
89 | // be very simple, even though the "width"/"height" property is not | ||
90 | // available for all, it's safe to figure that out from the rest. | ||
91 | |||
92 | // http://help.dottoro.com/ljgupwlp.php | ||
93 | spaceRect = floatSpace.getClientRect(); | ||
94 | editorRect = editable.getClientRect(); | ||
95 | viewRect = win.getViewPaneSize(); | ||
96 | spaceHeight = spaceRect.height; | ||
97 | pageScrollX = scrollOffset( 'left' ); | ||
98 | |||
99 | // We initialize it as pin mode. | ||
100 | if ( !mode ) { | ||
101 | mode = 'pin'; | ||
102 | changeMode( 'pin' ); | ||
103 | // Call for a refresh to the actual layout. | ||
104 | layout( evt ); | ||
105 | return; | ||
106 | } | ||
107 | |||
108 | // +------------------------ Viewport -+ \ | ||
109 | // | | |-> floatSpaceDockedOffsetY | ||
110 | // | ................................. | / | ||
111 | // | | | ||
112 | // | +------ Space -+ | | ||
113 | // | | | | | ||
114 | // | +--------------+ | | ||
115 | // | +------------------ Editor -+ | | ||
116 | // | | | | | ||
117 | // | ||
118 | if ( spaceHeight + dockedOffsetY <= editorRect.top ) | ||
119 | changeMode( 'top' ); | ||
120 | |||
121 | // +- - - - - - - - - Editor -+ | ||
122 | // | | | ||
123 | // +------------------------ Viewport -+ \ | ||
124 | // | | | | |-> floatSpacePinnedOffsetY | ||
125 | // | ................................. | / | ||
126 | // | +------ Space -+ | | | ||
127 | // | | | | | | ||
128 | // | +--------------+ | | | ||
129 | // | | | | | ||
130 | // | +---------------------------+ | | ||
131 | // +-----------------------------------+ | ||
132 | // | ||
133 | else if ( spaceHeight + dockedOffsetY > viewRect.height - editorRect.bottom ) | ||
134 | changeMode( 'pin' ); | ||
135 | |||
136 | // +- - - - - - - - - Editor -+ | ||
137 | // | | | ||
138 | // +------------------------ Viewport -+ \ | ||
139 | // | | | | |-> floatSpacePinnedOffsetY | ||
140 | // | ................................. | / | ||
141 | // | | | | | ||
142 | // | | | | | ||
143 | // | +---------------------------+ | | ||
144 | // | +------ Space -+ | | ||
145 | // | | | | | ||
146 | // | +--------------+ | | ||
147 | // | ||
148 | else | ||
149 | changeMode( 'bottom' ); | ||
150 | |||
151 | var mid = viewRect.width / 2, | ||
152 | alignSide, offset; | ||
153 | |||
154 | if ( config.floatSpacePreferRight ) { | ||
155 | alignSide = 'right'; | ||
156 | } else if ( editorRect.left > 0 && editorRect.right < viewRect.width && editorRect.width > spaceRect.width ) { | ||
157 | alignSide = config.contentsLangDirection == 'rtl' ? 'right' : 'left'; | ||
158 | } else { | ||
159 | alignSide = mid - editorRect.left > editorRect.right - mid ? 'left' : 'right'; | ||
160 | } | ||
161 | |||
162 | // (#9769) If viewport width is less than space width, | ||
163 | // make sure space never cross the left boundary of the viewport. | ||
164 | // In other words: top-left corner of the space is always visible. | ||
165 | if ( spaceRect.width > viewRect.width ) { | ||
166 | alignSide = 'left'; | ||
167 | offset = 0; | ||
168 | } | ||
169 | else { | ||
170 | if ( alignSide == 'left' ) { | ||
171 | // If the space rect fits into viewport, align it | ||
172 | // to the left edge of editor: | ||
173 | // | ||
174 | // +------------------------ Viewport -+ | ||
175 | // | | | ||
176 | // | +------------- Space -+ | | ||
177 | // | | | | | ||
178 | // | +---------------------+ | | ||
179 | // | +------------------ Editor -+ | | ||
180 | // | | | | | ||
181 | // | ||
182 | if ( editorRect.left > 0 ) | ||
183 | offset = editorRect.left; | ||
184 | |||
185 | // If the left part of the editor is cut off by the left | ||
186 | // edge of the viewport, stick the space to the viewport: | ||
187 | // | ||
188 | // +------------------------ Viewport -+ | ||
189 | // | | | ||
190 | // +---------------- Space -+ | | ||
191 | // | | | | ||
192 | // +------------------------+ | | ||
193 | // +----|------------- Editor -+ | | ||
194 | // | | | | | ||
195 | // | ||
196 | else | ||
197 | offset = 0; | ||
198 | } | ||
199 | else { | ||
200 | // If the space rect fits into viewport, align it | ||
201 | // to the right edge of editor: | ||
202 | // | ||
203 | // +------------------------ Viewport -+ | ||
204 | // | | | ||
205 | // | +------------- Space -+ | | ||
206 | // | | | | | ||
207 | // | +---------------------+ | | ||
208 | // | +------------------ Editor -+ | | ||
209 | // | | | | | ||
210 | // | ||
211 | if ( editorRect.right < viewRect.width ) | ||
212 | offset = viewRect.width - editorRect.right; | ||
213 | |||
214 | // If the right part of the editor is cut off by the right | ||
215 | // edge of the viewport, stick the space to the viewport: | ||
216 | // | ||
217 | // +------------------------ Viewport -+ | ||
218 | // | | | ||
219 | // | +------------- Space -+ | ||
220 | // | | | | ||
221 | // | +---------------------+ | ||
222 | // | +-----------------|- Editor -+ | ||
223 | // | | | | | ||
224 | // | ||
225 | else | ||
226 | offset = 0; | ||
227 | } | ||
228 | |||
229 | // (#9769) Finally, stick the space to the opposite side of | ||
230 | // the viewport when it's cut off horizontally on the left/right | ||
231 | // side like below. | ||
232 | // | ||
233 | // This trick reveals cut off space in some edge cases and | ||
234 | // hence it improves accessibility. | ||
235 | // | ||
236 | // +------------------------ Viewport -+ | ||
237 | // | | | ||
238 | // | +--------------------|-- Space -+ | ||
239 | // | | | | | ||
240 | // | +--------------------|----------+ | ||
241 | // | +------- Editor -+ | | ||
242 | // | | | | | ||
243 | // | ||
244 | // becomes: | ||
245 | // | ||
246 | // +------------------------ Viewport -+ | ||
247 | // | | | ||
248 | // | +----------------------- Space -+ | ||
249 | // | | | | ||
250 | // | +-------------------------------+ | ||
251 | // | +------- Editor -+ | | ||
252 | // | | | | | ||
253 | // | ||
254 | if ( offset + spaceRect.width > viewRect.width ) { | ||
255 | alignSide = alignSide == 'left' ? 'right' : 'left'; | ||
256 | offset = 0; | ||
257 | } | ||
258 | } | ||
259 | |||
260 | // Pin mode is fixed, so don't include scroll-x. | ||
261 | // (#9903) For mode is "top" or "bottom", add opposite scroll-x for right-aligned space. | ||
262 | var scroll = mode == 'pin' ? 0 : alignSide == 'left' ? pageScrollX : -pageScrollX; | ||
263 | |||
264 | floatSpace.setStyle( alignSide, pixelate( ( mode == 'pin' ? pinnedOffsetX : dockedOffsetX ) + offset + scroll ) ); | ||
265 | }; | ||
266 | } )(); | ||
267 | |||
268 | if ( topHtml ) { | ||
269 | var floatSpaceTpl = new CKEDITOR.template( | ||
270 | '<div' + | ||
271 | ' id="cke_{name}"' + | ||
272 | ' class="cke {id} cke_reset_all cke_chrome cke_editor_{name} cke_float cke_{langDir} ' + CKEDITOR.env.cssClass + '"' + | ||
273 | ' dir="{langDir}"' + | ||
274 | ' title="' + ( CKEDITOR.env.gecko ? ' ' : '' ) + '"' + | ||
275 | ' lang="{langCode}"' + | ||
276 | ' role="application"' + | ||
277 | ' style="{style}"' + | ||
278 | ( editor.title ? ' aria-labelledby="cke_{name}_arialbl"' : ' ' ) + | ||
279 | '>' + | ||
280 | ( editor.title ? '<span id="cke_{name}_arialbl" class="cke_voice_label">{voiceLabel}</span>' : ' ' ) + | ||
281 | '<div class="cke_inner">' + | ||
282 | '<div id="{topId}" class="cke_top" role="presentation">{content}</div>' + | ||
283 | '</div>' + | ||
284 | '</div>' ), | ||
285 | floatSpace = CKEDITOR.document.getBody().append( CKEDITOR.dom.element.createFromHtml( floatSpaceTpl.output( { | ||
286 | content: topHtml, | ||
287 | id: editor.id, | ||
288 | langDir: editor.lang.dir, | ||
289 | langCode: editor.langCode, | ||
290 | name: editor.name, | ||
291 | style: 'display:none;z-index:' + ( config.baseFloatZIndex - 1 ), | ||
292 | topId: editor.ui.spaceId( 'top' ), | ||
293 | voiceLabel: editor.title | ||
294 | } ) ) ), | ||
295 | |||
296 | // Use event buffers to reduce CPU load when tons of events are fired. | ||
297 | changeBuffer = CKEDITOR.tools.eventsBuffer( 500, layout ), | ||
298 | uiBuffer = CKEDITOR.tools.eventsBuffer( 100, layout ); | ||
299 | |||
300 | // There's no need for the floatSpace to be selectable. | ||
301 | floatSpace.unselectable(); | ||
302 | |||
303 | // Prevent clicking on non-buttons area of the space from blurring editor. | ||
304 | floatSpace.on( 'mousedown', function( evt ) { | ||
305 | evt = evt.data; | ||
306 | if ( !evt.getTarget().hasAscendant( 'a', 1 ) ) | ||
307 | evt.preventDefault(); | ||
308 | } ); | ||
309 | |||
310 | editor.on( 'focus', function( evt ) { | ||
311 | layout( evt ); | ||
312 | editor.on( 'change', changeBuffer.input ); | ||
313 | win.on( 'scroll', uiBuffer.input ); | ||
314 | win.on( 'resize', uiBuffer.input ); | ||
315 | } ); | ||
316 | |||
317 | editor.on( 'blur', function() { | ||
318 | floatSpace.hide(); | ||
319 | editor.removeListener( 'change', changeBuffer.input ); | ||
320 | win.removeListener( 'scroll', uiBuffer.input ); | ||
321 | win.removeListener( 'resize', uiBuffer.input ); | ||
322 | } ); | ||
323 | |||
324 | editor.on( 'destroy', function() { | ||
325 | win.removeListener( 'scroll', uiBuffer.input ); | ||
326 | win.removeListener( 'resize', uiBuffer.input ); | ||
327 | floatSpace.clearCustomData(); | ||
328 | floatSpace.remove(); | ||
329 | } ); | ||
330 | |||
331 | // Handle initial focus. | ||
332 | if ( editor.focusManager.hasFocus ) | ||
333 | floatSpace.show(); | ||
334 | |||
335 | // Register this UI space to the focus manager. | ||
336 | editor.focusManager.add( floatSpace, 1 ); | ||
337 | } | ||
338 | } | ||
339 | } )(); | ||
340 | |||
341 | /** | ||
342 | * Along with {@link #floatSpaceDockedOffsetY} it defines the | ||
343 | * amount of offset (in pixels) between the float space and the editable left/right | ||
344 | * boundaries when the space element is docked on either side of the editable. | ||
345 | * | ||
346 | * config.floatSpaceDockedOffsetX = 10; | ||
347 | * | ||
348 | * @cfg {Number} [floatSpaceDockedOffsetX=0] | ||
349 | * @member CKEDITOR.config | ||
350 | */ | ||
351 | |||
352 | /** | ||
353 | * Along with {@link #floatSpaceDockedOffsetX} it defines the | ||
354 | * amount of offset (in pixels) between the float space and the editable top/bottom | ||
355 | * boundaries when the space element is docked on either side of the editable. | ||
356 | * | ||
357 | * config.floatSpaceDockedOffsetY = 10; | ||
358 | * | ||
359 | * @cfg {Number} [floatSpaceDockedOffsetY=0] | ||
360 | * @member CKEDITOR.config | ||
361 | */ | ||
362 | |||
363 | /** | ||
364 | * Along with {@link #floatSpacePinnedOffsetY} it defines the | ||
365 | * amount of offset (in pixels) between the float space and the viewport boundaries | ||
366 | * when the space element is pinned. | ||
367 | * | ||
368 | * config.floatSpacePinnedOffsetX = 20; | ||
369 | * | ||
370 | * @cfg {Number} [floatSpacePinnedOffsetX=0] | ||
371 | * @member CKEDITOR.config | ||
372 | */ | ||
373 | |||
374 | /** | ||
375 | * Along with {@link #floatSpacePinnedOffsetX} it defines the | ||
376 | * amount of offset (in pixels) between the float space and the viewport boundaries | ||
377 | * when the space element is pinned. | ||
378 | * | ||
379 | * config.floatSpacePinnedOffsetY = 20; | ||
380 | * | ||
381 | * @cfg {Number} [floatSpacePinnedOffsetY=0] | ||
382 | * @member CKEDITOR.config | ||
383 | */ | ||
384 | |||
385 | /** | ||
386 | * Indicates that the float space should be aligned to the right side | ||
387 | * of the editable area rather than to the left (if possible). | ||
388 | * | ||
389 | * config.floatSpacePreferRight = true; | ||
390 | * | ||
391 | * @since 4.5 | ||
392 | * @cfg {Boolean} [floatSpacePreferRight=false] | ||
393 | * @member CKEDITOR.config | ||
394 | */ | ||
395 | |||
396 | /** | ||
397 | * Fired when the viewport or editor parameters change and the floating space needs to check and | ||
398 | * eventually update its position and dimensions. | ||
399 | * | ||
400 | * @since 4.5 | ||
401 | * @event floatingSpaceLayout | ||
402 | * @member CKEDITOR.editor | ||
403 | * @param {CKEDITOR.editor} editor The editor instance. | ||
404 | * @param data | ||
405 | * @param {Boolean} data.show True if the float space should show up as a result of this event. | ||
406 | */ | ||