source: trunk/admin/inc/ckeditor/_source/plugins/panel/plugin.js@ 364

Last change on this file since 364 was 239, checked in by luc, 9 years ago

Admin: correzione visulaizzazione immissione dati spoglio per Chrome e Safari - Aggiornamento dell'editor da FCKeditor a CKeditor , accessibili anche a Chrome e Safari.

  • Property svn:executable set to *
File size: 9.6 KB
Line 
1/*
2Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved.
3For licensing, see LICENSE.html or http://ckeditor.com/license
4*/
5
6CKEDITOR.plugins.add( 'panel',
7{
8 beforeInit : function( editor )
9 {
10 editor.ui.addHandler( CKEDITOR.UI_PANEL, CKEDITOR.ui.panel.handler );
11 }
12});
13
14/**
15 * Panel UI element.
16 * @constant
17 * @example
18 */
19CKEDITOR.UI_PANEL = 'panel';
20
21CKEDITOR.ui.panel = function( document, definition )
22{
23 // Copy all definition properties to this object.
24 if ( definition )
25 CKEDITOR.tools.extend( this, definition );
26
27 // Set defaults.
28 CKEDITOR.tools.extend( this,
29 {
30 className : '',
31 css : []
32 });
33
34 this.id = CKEDITOR.tools.getNextId();
35 this.document = document;
36
37 this._ =
38 {
39 blocks : {}
40 };
41};
42
43/**
44 * Transforms a rich combo definition in a {@link CKEDITOR.ui.richCombo}
45 * instance.
46 * @type Object
47 * @example
48 */
49CKEDITOR.ui.panel.handler =
50{
51 create : function( definition )
52 {
53 return new CKEDITOR.ui.panel( definition );
54 }
55};
56
57CKEDITOR.ui.panel.prototype =
58{
59 renderHtml : function( editor )
60 {
61 var output = [];
62 this.render( editor, output );
63 return output.join( '' );
64 },
65
66 /**
67 * Renders the combo.
68 * @param {CKEDITOR.editor} editor The editor instance which this button is
69 * to be used by.
70 * @param {Array} output The output array to which append the HTML relative
71 * to this button.
72 * @example
73 */
74 render : function( editor, output )
75 {
76 var id = this.id;
77
78 output.push(
79 '<div class="', editor.skinClass ,'"' +
80 ' lang="', editor.langCode, '"' +
81 ' role="presentation"' +
82 // iframe loading need sometime, keep the panel hidden(#4186).
83 ' style="display:none;z-index:' + ( editor.config.baseFloatZIndex + 1 ) + '">' +
84 '<div' +
85 ' id=', id,
86 ' dir=', editor.lang.dir,
87 ' role="presentation"' +
88 ' class="cke_panel cke_', editor.lang.dir );
89
90 if ( this.className )
91 output.push( ' ', this.className );
92
93 output.push(
94 '">' );
95
96 if ( this.forceIFrame || this.css.length )
97 {
98 output.push(
99 '<iframe id="', id, '_frame"' +
100 ' frameborder="0"' +
101 ' role="application" src="javascript:void(' );
102
103 output.push(
104 // Support for custom document.domain in IE.
105 CKEDITOR.env.isCustomDomain() ?
106 '(function(){' +
107 'document.open();' +
108 'document.domain=\'' + document.domain + '\';' +
109 'document.close();' +
110 '})()'
111 :
112 '0' );
113
114 output.push(
115 ')"></iframe>' );
116 }
117
118 output.push(
119 '</div>' +
120 '</div>' );
121
122 return id;
123 },
124
125 getHolderElement : function()
126 {
127 var holder = this._.holder;
128
129 if ( !holder )
130 {
131 if ( this.forceIFrame || this.css.length )
132 {
133 var iframe = this.document.getById( this.id + '_frame' ),
134 parentDiv = iframe.getParent(),
135 dir = parentDiv.getAttribute( 'dir' ),
136 className = parentDiv.getParent().getAttribute( 'class' ),
137 langCode = parentDiv.getParent().getAttribute( 'lang' ),
138 doc = iframe.getFrameDocument();
139
140 // Make it scrollable on iOS. (#8308)
141 CKEDITOR.env.iOS && parentDiv.setStyles(
142 {
143 'overflow' : 'scroll',
144 '-webkit-overflow-scrolling' : 'touch'
145 });
146
147 var onLoad = CKEDITOR.tools.addFunction( CKEDITOR.tools.bind( function( ev )
148 {
149 this.isLoaded = true;
150 if ( this.onLoad )
151 this.onLoad();
152 }, this ) );
153
154 var data =
155 '<!DOCTYPE html>' +
156 '<html dir="' + dir + '" class="' + className + '_container" lang="' + langCode + '">' +
157 '<head>' +
158 '<style>.' + className + '_container{visibility:hidden}</style>' +
159 '</head>' +
160 '<body class="cke_' + dir + ' cke_panel_frame ' + CKEDITOR.env.cssClass + '" style="margin:0;padding:0"' +
161 ' onload="( window.CKEDITOR || window.parent.CKEDITOR ).tools.callFunction(' + onLoad + ');"></body>' +
162 // It looks strange, but for FF2, the styles must go
163 // after <body>, so it (body) becames immediatelly
164 // available. (#3031)
165 CKEDITOR.tools.buildStyleHtml( this.css ) +
166 '<\/html>';
167
168 doc.write( data );
169
170 var win = doc.getWindow();
171
172 // Register the CKEDITOR global.
173 win.$.CKEDITOR = CKEDITOR;
174
175 // Arrow keys for scrolling is only preventable with 'keypress' event in Opera (#4534).
176 doc.on( 'key' + ( CKEDITOR.env.opera? 'press':'down' ), function( evt )
177 {
178 var keystroke = evt.data.getKeystroke(),
179 dir = this.document.getById( this.id ).getAttribute( 'dir' );
180
181 // Delegate key processing to block.
182 if ( this._.onKeyDown && this._.onKeyDown( keystroke ) === false )
183 {
184 evt.data.preventDefault();
185 return;
186 }
187
188 // ESC/ARROW-LEFT(ltr) OR ARROW-RIGHT(rtl)
189 if ( keystroke == 27 || keystroke == ( dir == 'rtl' ? 39 : 37 ) )
190 {
191 if ( this.onEscape && this.onEscape( keystroke ) === false )
192 evt.data.preventDefault();
193 }
194 },
195 this );
196
197 holder = doc.getBody();
198 holder.unselectable();
199 CKEDITOR.env.air && CKEDITOR.tools.callFunction( onLoad );
200 }
201 else
202 holder = this.document.getById( this.id );
203
204 this._.holder = holder;
205 }
206
207 return holder;
208 },
209
210 addBlock : function( name, block )
211 {
212 block = this._.blocks[ name ] = block instanceof CKEDITOR.ui.panel.block ? block
213 : new CKEDITOR.ui.panel.block( this.getHolderElement(), block );
214
215 if ( !this._.currentBlock )
216 this.showBlock( name );
217
218 return block;
219 },
220
221 getBlock : function( name )
222 {
223 return this._.blocks[ name ];
224 },
225
226 showBlock : function( name )
227 {
228 var blocks = this._.blocks,
229 block = blocks[ name ],
230 current = this._.currentBlock,
231 holder = this.forceIFrame ?
232 this.document.getById( this.id + '_frame' )
233 : this._.holder;
234
235 // Disable context menu for block panel.
236 holder.getParent().getParent().disableContextMenu();
237
238 if ( current )
239 {
240 // Clean up the current block's effects on holder.
241 holder.removeAttributes( current.attributes );
242 current.hide();
243 }
244
245 this._.currentBlock = block;
246
247 holder.setAttributes( block.attributes );
248 CKEDITOR.fire( 'ariaWidget', holder );
249
250 // Reset the focus index, so it will always go into the first one.
251 block._.focusIndex = -1;
252
253 this._.onKeyDown = block.onKeyDown && CKEDITOR.tools.bind( block.onKeyDown, block );
254
255 block.show();
256
257 return block;
258 },
259
260 destroy : function()
261 {
262 this.element && this.element.remove();
263 }
264};
265
266CKEDITOR.ui.panel.block = CKEDITOR.tools.createClass(
267{
268 $ : function( blockHolder, blockDefinition )
269 {
270 this.element = blockHolder.append(
271 blockHolder.getDocument().createElement( 'div',
272 {
273 attributes :
274 {
275 'tabIndex' : -1,
276 'class' : 'cke_panel_block',
277 'role' : 'presentation'
278 },
279 styles :
280 {
281 display : 'none'
282 }
283 }) );
284
285 // Copy all definition properties to this object.
286 if ( blockDefinition )
287 CKEDITOR.tools.extend( this, blockDefinition );
288
289 if ( !this.attributes.title )
290 this.attributes.title = this.attributes[ 'aria-label' ];
291
292 this.keys = {};
293
294 this._.focusIndex = -1;
295
296 // Disable context menu for panels.
297 this.element.disableContextMenu();
298 },
299
300 _ : {
301
302 /**
303 * Mark the item specified by the index as current activated.
304 */
305 markItem: function( index )
306 {
307 if ( index == -1 )
308 return;
309 var links = this.element.getElementsByTag( 'a' );
310 var item = links.getItem( this._.focusIndex = index );
311
312 // Safari need focus on the iframe window first(#3389), but we need
313 // lock the blur to avoid hiding the panel.
314 if ( CKEDITOR.env.webkit || CKEDITOR.env.opera )
315 item.getDocument().getWindow().focus();
316 item.focus();
317
318 this.onMark && this.onMark( item );
319 }
320 },
321
322 proto :
323 {
324 show : function()
325 {
326 this.element.setStyle( 'display', '' );
327 },
328
329 hide : function()
330 {
331 if ( !this.onHide || this.onHide.call( this ) !== true )
332 this.element.setStyle( 'display', 'none' );
333 },
334
335 onKeyDown : function( keystroke )
336 {
337 var keyAction = this.keys[ keystroke ];
338 switch ( keyAction )
339 {
340 // Move forward.
341 case 'next' :
342 var index = this._.focusIndex,
343 links = this.element.getElementsByTag( 'a' ),
344 link;
345
346 while ( ( link = links.getItem( ++index ) ) )
347 {
348 // Move the focus only if the element is marked with
349 // the _cke_focus and it it's visible (check if it has
350 // width).
351 if ( link.getAttribute( '_cke_focus' ) && link.$.offsetWidth )
352 {
353 this._.focusIndex = index;
354 link.focus();
355 break;
356 }
357 }
358 return false;
359
360 // Move backward.
361 case 'prev' :
362 index = this._.focusIndex;
363 links = this.element.getElementsByTag( 'a' );
364
365 while ( index > 0 && ( link = links.getItem( --index ) ) )
366 {
367 // Move the focus only if the element is marked with
368 // the _cke_focus and it it's visible (check if it has
369 // width).
370 if ( link.getAttribute( '_cke_focus' ) && link.$.offsetWidth )
371 {
372 this._.focusIndex = index;
373 link.focus();
374 break;
375 }
376 }
377 return false;
378
379 case 'click' :
380 case 'mouseup' :
381 index = this._.focusIndex;
382 link = index >= 0 && this.element.getElementsByTag( 'a' ).getItem( index );
383
384 if ( link )
385 link.$[ keyAction ] ? link.$[ keyAction ]() : link.$[ 'on' + keyAction ]();
386
387 return false;
388 }
389
390 return true;
391 }
392 }
393});
394
395/**
396 * Fired when a panel is added to the document
397 * @name CKEDITOR#ariaWidget
398 * @event
399 * @param {Object} holder The element wrapping the panel
400 */
Note: See TracBrowser for help on using the repository browser.