2 Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.
3 For licensing, see LICENSE.html or http://ckeditor.com/license
6 CKEDITOR
.themes
.add( 'default', (function()
8 function checkSharedSpace( editor
, spaceName
)
13 // Try to retrieve the target element from the sharedSpaces settings.
14 element
= editor
.config
.sharedSpaces
;
15 element
= element
&& element
[ spaceName
];
16 element
= element
&& CKEDITOR
.document
.getById( element
);
18 // If the element is available, we'll then create the container for
22 // Creates an HTML structure that reproduces the editor class hierarchy.
24 '<span class="cke_shared">' +
25 '<span class="' + editor
.skinClass
+ ' cke_editor_' + editor
.name
+ '">' +
26 '<span class="' + CKEDITOR
.env
.cssClass
+ '">' +
27 '<span class="cke_wrapper cke_' + editor
.lang
.dir
+ '">' +
28 '<span class="cke_editor">' +
29 '<div class="cke_' + spaceName
+ '">' +
30 '</div></span></span></span></span></span>';
32 var mainContainer
= element
.append( CKEDITOR
.dom
.element
.createFromHtml( html
, element
.getDocument() ) );
34 // Only the first container starts visible. Others get hidden.
35 if ( element
.getCustomData( 'cke_hasshared' ) )
38 element
.setCustomData( 'cke_hasshared', 1 );
40 // Get the deeper inner <div>.
41 container
= mainContainer
.getChild( [0,0,0,0] );
43 // When the editor gets focus, we show the space container, hiding others.
44 editor
.on( 'focus', function()
46 for ( var i
= 0, sibling
, children
= element
.getChildren() ; ( sibling
= children
.getItem( i
) ) ; i
++ )
48 if ( sibling
.type
== CKEDITOR
.NODE_ELEMENT
49 && !sibling
.equals( mainContainer
)
50 && sibling
.hasClass( 'cke_shared' ) )
59 editor
.on( 'destroy', function()
61 mainContainer
.remove();
69 build : function( editor
, themePath
)
71 var name
= editor
.name
,
72 element
= editor
.element
,
73 elementMode
= editor
.elementMode
;
75 if ( !element
|| elementMode
== CKEDITOR
.ELEMENT_MODE_NONE
)
78 if ( elementMode
== CKEDITOR
.ELEMENT_MODE_REPLACE
)
81 // Get the HTML for the predefined spaces.
82 var topHtml
= editor
.fire( 'themeSpace', { space
: 'top', html
: '' } ).html
;
83 var contentsHtml
= editor
.fire( 'themeSpace', { space
: 'contents', html
: '' } ).html
;
84 var bottomHtml
= editor
.fireOnce( 'themeSpace', { space
: 'bottom', html
: '' } ).html
;
86 var height
= contentsHtml
&& editor
.config
.height
;
88 var tabIndex
= editor
.config
.tabIndex
|| editor
.element
.getAttribute( 'tabindex' ) || 0;
90 // The editor height is considered only if the contents space got filled.
93 else if ( !isNaN( height
) )
97 var width
= editor
.config
.width
;
101 if ( !isNaN( width
) )
104 style
+= "width: " + width
+ ";";
107 var sharedTop
= topHtml
&& checkSharedSpace( editor
, 'top' ),
108 sharedBottoms
= checkSharedSpace( editor
, 'bottom' );
110 sharedTop
&& ( sharedTop
.setHtml( topHtml
) , topHtml
= '' );
111 sharedBottoms
&& ( sharedBottoms
.setHtml( bottomHtml
), bottomHtml
= '' );
113 var container
= CKEDITOR
.dom
.element
.createFromHtml( [
115 ' id="cke_', name
, '"' +
116 ' onmousedown="return false;"' +
117 ' class="', editor
.skinClass
, ' cke_editor_', name
, '"' +
118 ' dir="', editor
.lang
.dir
, '"' +
119 ' title="', ( CKEDITOR
.env
.gecko
? ' ' : '' ), '"' +
120 ' lang="', editor
.langCode
, '"' +
121 ' role="application"' +
122 ' aria-labelledby="cke_', name
, '_arialbl"' +
123 ( style
? ' style="' + style
+ '"' : '' ) +
125 '<span id="cke_', name
, '_arialbl" class="cke_voice_label">' + editor
.lang
.editor
+ '</span>' +
126 '<span class="' , CKEDITOR
.env
.cssClass
, '" role="presentation">' +
127 '<span class="cke_wrapper cke_', editor
.lang
.dir
, '" role="presentation">' +
128 '<table class="cke_editor" border="0" cellspacing="0" cellpadding="0" role="presentation"><tbody>' +
129 '<tr', topHtml
? '' : ' style="display:none"', '><td id="cke_top_' , name
, '" class="cke_top" role="presentation">' , topHtml
, '</td></tr>' +
130 '<tr', contentsHtml
? '' : ' style="display:none"', '><td id="cke_contents_', name
, '" class="cke_contents" style="height:', height
, '" role="presentation">', contentsHtml
, '</td></tr>' +
131 '<tr', bottomHtml
? '' : ' style="display:none"', '><td id="cke_bottom_' , name
, '" class="cke_bottom" role="presentation">' , bottomHtml
, '</td></tr>' +
133 //Hide the container when loading skins, later restored by skin css.
134 '<style>.', editor
.skinClass
, '{visibility:hidden;}</style>' +
137 '</span>' ].join( '' ) );
139 container
.getChild( [1, 0, 0, 0, 0] ).unselectable();
140 container
.getChild( [1, 0, 0, 0, 2] ).unselectable();
142 if ( elementMode
== CKEDITOR
.ELEMENT_MODE_REPLACE
)
143 container
.insertAfter( element
);
145 element
.append( container
);
148 * The DOM element that holds the main editor interface.
149 * @name CKEDITOR.editor.prototype.container
150 * @type CKEDITOR.dom.element
152 * var editor = CKEDITOR.instances.editor1;
153 * alert( <b>editor.container</b>.getName() ); "span"
155 editor
.container
= container
;
157 // Disable browser context menu for editor's chrome.
158 container
.disableContextMenu();
160 editor
.fireOnce( 'themeLoaded' );
161 editor
.fireOnce( 'uiReady' );
164 buildDialog : function( editor
)
166 var baseIdNumber
= CKEDITOR
.tools
.getNextNumber();
168 var element
= CKEDITOR
.dom
.element
.createFromHtml( [
169 '<div class="cke_editor_' + editor
.name
.replace('.', '\\.') + '_dialog cke_skin_', editor
.skinName
,
170 '" dir="', editor
.lang
.dir
, '"' +
171 ' lang="', editor
.langCode
, '"' +
173 ' aria-labelledby="%title#"' +
175 '<table class="cke_dialog', ' ' + CKEDITOR
.env
.cssClass
,
176 ' cke_', editor
.lang
.dir
, '" style="position:absolute" role="presentation">' +
177 '<tr><td role="presentation">' +
178 '<div class="%body" role="presentation">' +
179 '<div id="%title#" class="%title" role="presentation"></div>' +
180 '<a id="%close_button#" class="%close_button" href="javascript:void(0)" title="' + editor
.lang
.common
.close
+'" role="button"><span class="cke_label">X</span></a>' +
181 '<div id="%tabs#" class="%tabs" role="tablist"></div>' +
182 '<table class="%contents" role="presentation"><tr>' +
183 '<td id="%contents#" class="%contents" role="presentation"></td>' +
185 '<div id="%footer#" class="%footer" role="presentation"></div>' +
187 '<div id="%tl#" class="%tl"></div>' +
188 '<div id="%tc#" class="%tc"></div>' +
189 '<div id="%tr#" class="%tr"></div>' +
190 '<div id="%ml#" class="%ml"></div>' +
191 '<div id="%mr#" class="%mr"></div>' +
192 '<div id="%bl#" class="%bl"></div>' +
193 '<div id="%bc#" class="%bc"></div>' +
194 '<div id="%br#" class="%br"></div>' +
198 //Hide the container when loading skins, later restored by skin css.
199 ( CKEDITOR
.env
.ie
? '' : '<style>.cke_dialog{visibility:hidden;}</style>' ),
203 .replace( /#/g
, '_' + baseIdNumber
)
204 .replace( /%/g
, 'cke_dialog_' ) );
206 var body
= element
.getChild( [ 0, 0, 0, 0, 0 ] ),
207 title
= body
.getChild( 0 ),
208 close
= body
.getChild( 1 );
210 // Make the Title and Close Button unselectable.
211 title
.unselectable();
212 close
.unselectable();
219 dialog
: element
.getChild( 0 ),
222 tabs
: body
.getChild( 2 ),
223 contents
: body
.getChild( [ 3, 0, 0, 0 ] ),
224 footer
: body
.getChild( 4 )
229 destroy : function( editor
)
231 var container
= editor
.container
;
232 container
.clearCustomData();
233 editor
.element
.clearCustomData();
236 * IE BUG: Removing the editor DOM elements while the selection is inside
237 * the editing area would break IE7/8's selection system. So we need to put
238 * the selection back to the parent document without scrolling the window.
241 if ( CKEDITOR
.env
.ie
)
243 container
.setStyle( 'display', 'none' );
245 var $range
= document
.body
.createTextRange();
246 $range
.moveToElementText( container
.$ );
249 // Putting the selection to a display:none element - this will certainly
250 // fail. But! We've just put the selection document back to the parent
251 // document without scrolling the window!
260 if ( editor
.elementMode
== CKEDITOR
.ELEMENT_MODE_REPLACE
)
261 editor
.element
.show();
263 delete editor
.element
;
268 CKEDITOR
.editor
.prototype.getThemeSpace = function( spaceName
)
270 var spacePrefix
= 'cke_' + spaceName
;
271 var space
= this._
[ spacePrefix
] ||
272 ( this._
[ spacePrefix
] = CKEDITOR
.document
.getById( spacePrefix
+ '_' + this.name
) );
276 CKEDITOR
.editor
.prototype.resize = function( width
, height
, isContentHeight
, resizeInner
)
278 var numberRegex
= /^\d+$/;
279 if ( numberRegex
.test( width
) )
282 var container
= this.container
,
283 contents
= CKEDITOR
.document
.getById( 'cke_contents_' + this.name
),
284 outer
= resizeInner
? container
.getChild( 1 ) : container
;
286 // Resize the width first.
287 // WEBKIT BUG: Webkit requires that we put the editor off from display when we
288 // resize it. If we don't, the browser crashes!
289 CKEDITOR
.env
.webkit
&& outer
.setStyle( 'display', 'none' );
290 outer
.setStyle( 'width', width
);
291 if ( CKEDITOR
.env
.webkit
)
294 outer
.setStyle( 'display', '' );
297 // Get the height delta between the outer table and the content area.
298 // If we're setting the content area's height, then we don't need the delta.
299 var delta
= isContentHeight
? 0 : ( outer
.$.offsetHeight
|| 0 ) - ( contents
.$.clientHeight
|| 0 );
300 contents
.setStyle( 'height', Math
.max( height
- delta
, 0 ) + 'px' );
302 // Emit a resize event.
303 this.fire( 'resize' );
306 CKEDITOR
.editor
.prototype.getResizable = function()
308 return this.container
.getChild( 1 );
312 * Makes it possible to place some of the editor UI blocks, like the toolbar
313 * and the elements path, into any element in the page.
314 * The elements used to hold the UI blocks can be shared among several editor
315 * instances. In that case, only the blocks of the active editor instance will
317 * @name CKEDITOR.config.sharedSpaces
321 * // Place the toolbar inside the element with ID "someElementId" and the
322 * // elements path into the element with ID "anotherId".
323 * config.sharedSpaces =
325 * top : 'someElementId',
326 * bottom : 'anotherId'
329 * // Place the toolbar inside the element with ID "someElementId". The
330 * // elements path will remain attached to the editor UI.
331 * config.sharedSpaces =
333 * top : 'someElementId'