]>
git.immae.eu Git - perso/Immae/Projets/packagist/piedsjaloux-ckeditor-component.git/blob - sources/plugins/panel/plugin.js
816ccc48b2ae4d2fd1710626172b5dd47030d7b6
2 * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
3 * For licensing, see LICENSE.md or http://ckeditor.com/license
7 CKEDITOR
.plugins
.add( 'panel', {
8 beforeInit: function( editor
) {
9 editor
.ui
.addHandler( CKEDITOR
.UI_PANEL
, CKEDITOR
.ui
.panel
.handler
);
17 * @property {String} [='panel']
20 CKEDITOR
.UI_PANEL
= 'panel';
24 * @constructor Creates a panel class instance.
25 * @param {CKEDITOR.dom.document} document
26 * @param {Object} definition
28 CKEDITOR
.ui
.panel = function( document
, definition
) {
29 // Copy all definition properties to this object.
31 CKEDITOR
.tools
.extend( this, definition
);
34 CKEDITOR
.tools
.extend( this, {
39 this.id
= CKEDITOR
.tools
.getNextId();
40 this.document
= document
;
41 this.isFramed
= this.forceIFrame
|| this.css
.length
;
49 * Represents panel handler object.
53 * @extends CKEDITOR.ui.handlerDefinition
55 CKEDITOR
.ui
.panel
.handler
= {
57 * Transforms a panel definition in a {@link CKEDITOR.ui.panel} instance.
59 * @param {Object} definition
60 * @returns {CKEDITOR.ui.panel}
62 create: function( definition
) {
63 return new CKEDITOR
.ui
.panel( definition
);
67 var panelTpl
= CKEDITOR
.addTemplate( 'panel', '<div lang="{langCode}" id="{id}" dir={dir}' +
68 ' class="cke cke_reset_all {editorId} cke_panel cke_panel {cls} cke_{dir}"' +
69 ' style="z-index:{z-index}" role="presentation">' +
73 var frameTpl
= CKEDITOR
.addTemplate( 'panel-frame', '<iframe id="{id}" class="cke_panel_frame" role="presentation" frameborder="0" src="{src}"></iframe>' );
75 var frameDocTpl
= CKEDITOR
.addTemplate( 'panel-frame-inner', '<!DOCTYPE html>' +
76 '<html class="cke_panel_container {env}" dir="{dir}" lang="{langCode}">' +
77 '<head>{css}</head>' +
78 '<body class="cke_{dir}"' +
79 ' style="margin:0;padding:0" onload="{onload}"></body>' +
82 /** @class CKEDITOR.ui.panel */
83 CKEDITOR
.ui
.panel
.prototype = {
87 * @param {CKEDITOR.editor} editor The editor instance which this button is
89 * @param {Array} [output] The output array to which append the HTML relative
92 render: function( editor
, output
) {
93 this.getHolderElement = function() {
94 var holder
= this._
.holder
;
97 if ( this.isFramed
) {
98 var iframe
= this.document
.getById( this.id
+ '_frame' ),
99 parentDiv
= iframe
.getParent(),
100 doc
= iframe
.getFrameDocument();
102 // Make it scrollable on iOS. (http://dev.ckeditor.com/ticket/8308)
103 CKEDITOR
.env
.iOS
&& parentDiv
.setStyles( {
104 'overflow': 'scroll',
105 '-webkit-overflow-scrolling': 'touch'
108 var onLoad
= CKEDITOR
.tools
.addFunction( CKEDITOR
.tools
.bind( function() {
109 this.isLoaded
= true;
114 doc
.write( frameDocTpl
.output( CKEDITOR
.tools
.extend( {
115 css: CKEDITOR
.tools
.buildStyleHtml( this.css
),
116 onload: 'window.parent.CKEDITOR.tools.callFunction(' + onLoad
+ ');'
119 var win
= doc
.getWindow();
121 // Register the CKEDITOR global.
122 win
.$.CKEDITOR
= CKEDITOR
;
124 // Arrow keys for scrolling is only preventable with 'keypress' event in Opera (http://dev.ckeditor.com/ticket/4534).
125 doc
.on( 'keydown', function( evt
) {
126 var keystroke
= evt
.data
.getKeystroke(),
127 dir
= this.document
.getById( this.id
).getAttribute( 'dir' );
129 // Delegate key processing to block.
130 if ( this._
.onKeyDown
&& this._
.onKeyDown( keystroke
) === false ) {
131 evt
.data
.preventDefault();
135 // ESC/ARROW-LEFT(ltr) OR ARROW-RIGHT(rtl)
136 if ( keystroke
== 27 || keystroke
== ( dir
== 'rtl' ? 39 : 37 ) ) {
137 if ( this.onEscape
&& this.onEscape( keystroke
) === false )
138 evt
.data
.preventDefault();
142 holder
= doc
.getBody();
143 holder
.unselectable();
144 CKEDITOR
.env
.air
&& CKEDITOR
.tools
.callFunction( onLoad
);
146 holder
= this.document
.getById( this.id
);
149 this._
.holder
= holder
;
158 langCode: editor
.langCode
,
159 dir: editor
.lang
.dir
,
162 env: CKEDITOR
.env
.cssClass
,
163 'z-index': editor
.config
.baseFloatZIndex
+ 1
166 if ( this.isFramed
) {
167 // With IE, the custom domain has to be taken care at first,
168 // for other browers, the 'src' attribute should be left empty to
169 // trigger iframe's 'load' event.
171 CKEDITOR
.env
.air
? 'javascript:void(0)' : // jshint ignore:line
172 CKEDITOR
.env
.ie
? 'javascript:void(function(){' + encodeURIComponent( // jshint ignore:line
174 // In IE, the document domain must be set any time we call document.open().
175 '(' + CKEDITOR
.tools
.fixDomain
+ ')();' +
180 data
.frame
= frameTpl
.output( {
181 id: this.id
+ '_frame',
186 var html
= panelTpl
.output( data
);
197 addBlock: function( name
, block
) {
198 block
= this._
.blocks
[ name
] = block
instanceof CKEDITOR
.ui
.panel
.block
? block : new CKEDITOR
.ui
.panel
.block( this.getHolderElement(), block
);
200 if ( !this._
.currentBlock
)
201 this.showBlock( name
);
209 getBlock: function( name
) {
210 return this._
.blocks
[ name
];
216 showBlock: function( name
) {
217 var blocks
= this._
.blocks
,
218 block
= blocks
[ name
],
219 current
= this._
.currentBlock
;
221 // ARIA role works better in IE on the body element, while on the iframe
222 // for FF. (http://dev.ckeditor.com/ticket/8864)
223 var holder
= !this.forceIFrame
|| CKEDITOR
.env
.ie
? this._
.holder : this.document
.getById( this.id
+ '_frame' );
228 this._
.currentBlock
= block
;
230 CKEDITOR
.fire( 'ariaWidget', holder
);
232 // Reset the focus index, so it will always go into the first one.
233 block
._
.focusIndex
= -1;
235 this._
.onKeyDown
= block
.onKeyDown
&& CKEDITOR
.tools
.bind( block
.onKeyDown
, block
);
245 destroy: function() {
246 this.element
&& this.element
.remove();
253 * @todo class and all methods
255 CKEDITOR
.ui
.panel
.block
= CKEDITOR
.tools
.createClass( {
257 * Creates a block class instances.
262 $: function( blockHolder
, blockDefinition
) {
263 this.element
= blockHolder
.append( blockHolder
.getDocument().createElement( 'div', {
266 'class': 'cke_panel_block'
273 // Copy all definition properties to this object.
274 if ( blockDefinition
)
275 CKEDITOR
.tools
.extend( this, blockDefinition
);
277 // Set the a11y attributes of this element ...
278 this.element
.setAttributes( {
279 'role': this.attributes
.role
|| 'presentation',
280 'aria-label': this.attributes
[ 'aria-label' ],
281 'title': this.attributes
.title
|| this.attributes
[ 'aria-label' ]
286 this._
.focusIndex
= -1;
288 // Disable context menu for panels.
289 this.element
.disableContextMenu();
295 * Mark the item specified by the index as current activated.
297 markItem: function( index
) {
300 var links
= this.element
.getElementsByTag( 'a' );
301 var item
= links
.getItem( this._
.focusIndex
= index
);
303 // Safari need focus on the iframe window first(http://dev.ckeditor.com/ticket/3389), but we need
304 // lock the blur to avoid hiding the panel.
305 if ( CKEDITOR
.env
.webkit
)
306 item
.getDocument().getWindow().focus();
309 this.onMark
&& this.onMark( item
);
313 * Marks the first visible item or the one whose `aria-selected` attribute is set to `true`.
314 * The latter has priority over the former.
317 * @param beforeMark function to be executed just before marking.
318 * Used in cases when any preparatory cleanup (like unmarking all items) would simultaneously
319 * destroy the information that is needed to determine the focused item.
321 markFirstDisplayed: function( beforeMark
) {
322 var notDisplayed = function( element
) {
323 return element
.type
== CKEDITOR
.NODE_ELEMENT
&& element
.getStyle( 'display' ) == 'none';
325 links
= this._
.getItems(),
328 for ( var i
= links
.count() - 1; i
>= 0; i
-- ) {
329 item
= links
.getItem( i
);
331 if ( !item
.getAscendant( notDisplayed
) ) {
333 this._
.focusIndex
= i
;
336 if ( item
.getAttribute( 'aria-selected' ) == 'true' ) {
338 this._
.focusIndex
= i
;
351 if ( CKEDITOR
.env
.webkit
)
352 focused
.getDocument().getWindow().focus();
355 this.onMark
&& this.onMark( focused
);
359 * Returns a `CKEDITOR.dom.nodeList` of block items.
361 * @returns {*|CKEDITOR.dom.nodeList}
363 getItems: function() {
364 return this.element
.getElementsByTag( 'a' );
370 this.element
.setStyle( 'display', '' );
374 if ( !this.onHide
|| this.onHide
.call( this ) !== true )
375 this.element
.setStyle( 'display', 'none' );
378 onKeyDown: function( keystroke
, noCycle
) {
379 var keyAction
= this.keys
[ keystroke
];
380 switch ( keyAction
) {
383 var index
= this._
.focusIndex
,
384 links
= this.element
.getElementsByTag( 'a' ),
387 while ( ( link
= links
.getItem( ++index
) ) ) {
388 // Move the focus only if the element is marked with
389 // the _cke_focus and it it's visible (check if it has
391 if ( link
.getAttribute( '_cke_focus' ) && link
.$.offsetWidth
) {
392 this._
.focusIndex
= index
;
398 // If no link was found, cycle and restart from the top. (http://dev.ckeditor.com/ticket/11125)
399 if ( !link
&& !noCycle
) {
400 this._
.focusIndex
= -1;
401 return this.onKeyDown( keystroke
, 1 );
408 index
= this._
.focusIndex
;
409 links
= this.element
.getElementsByTag( 'a' );
411 while ( index
> 0 && ( link
= links
.getItem( --index
) ) ) {
412 // Move the focus only if the element is marked with
413 // the _cke_focus and it it's visible (check if it has
415 if ( link
.getAttribute( '_cke_focus' ) && link
.$.offsetWidth
) {
416 this._
.focusIndex
= index
;
421 // Make sure link is null when the loop ends and nothing was
422 // found (http://dev.ckeditor.com/ticket/11125).
426 // If no link was found, cycle and restart from the bottom. (http://dev.ckeditor.com/ticket/11125)
427 if ( !link
&& !noCycle
) {
428 this._
.focusIndex
= links
.count();
429 return this.onKeyDown( keystroke
, 1 );
436 index
= this._
.focusIndex
;
437 link
= index
>= 0 && this.element
.getElementsByTag( 'a' ).getItem( index
);
440 link
.$[ keyAction
] ? link
.$[ keyAction
]() : link
.$[ 'on' + keyAction
]();
453 * Fired when a panel is added to the document.
457 * @param {Object} data The element wrapping the panel.