2 * FCKeditor - The text editor for Internet - http://www.fckeditor.net
\r
3 * Copyright (C) 2003-2009 Frederico Caldeira Knabben
\r
5 * == BEGIN LICENSE ==
\r
7 * Licensed under the terms of any of the following licenses at your
\r
10 * - GNU General Public License Version 2 or later (the "GPL")
\r
11 * http://www.gnu.org/licenses/gpl.html
\r
13 * - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
\r
14 * http://www.gnu.org/licenses/lgpl.html
\r
16 * - Mozilla Public License Version 1.1 or later (the "MPL")
\r
17 * http://www.mozilla.org/MPL/MPL-1.1.html
\r
21 * FCKSpecialCombo Class: represents a special combo.
\r
24 var FCKSpecialCombo = function( caption, fieldWidth, panelWidth, panelMaxHeight, parentWindow )
\r
26 // Default properties values.
\r
27 this.FieldWidth = fieldWidth || 100 ;
\r
28 this.PanelWidth = panelWidth || 150 ;
\r
29 this.PanelMaxHeight = panelMaxHeight || 150 ;
\r
30 this.Label = ' ' ;
\r
31 this.Caption = caption ;
\r
32 this.Tooltip = caption ;
\r
33 this.Style = FCK_TOOLBARITEM_ICONTEXT ;
\r
35 this.Enabled = true ;
\r
37 this.Items = new Object() ;
\r
39 this._Panel = new FCKPanel( parentWindow || window ) ;
\r
40 this._Panel.AppendStyleSheet( FCKConfig.SkinEditorCSS ) ;
\r
41 this._PanelBox = this._Panel.MainNode.appendChild( this._Panel.Document.createElement( 'DIV' ) ) ;
\r
42 this._PanelBox.className = 'SC_Panel' ;
\r
43 this._PanelBox.style.width = this.PanelWidth + 'px' ;
\r
45 this._PanelBox.innerHTML = '<table cellpadding="0" cellspacing="0" width="100%" style="TABLE-LAYOUT: fixed"><tr><td nowrap></td></tr></table>' ;
\r
47 this._ItemsHolderEl = this._PanelBox.getElementsByTagName('TD')[0] ;
\r
49 if ( FCK.IECleanup )
\r
50 FCK.IECleanup.AddItem( this, FCKSpecialCombo_Cleanup ) ;
\r
52 // this._Panel.StyleSheet = FCKConfig.SkinPath + 'fck_contextmenu.css' ;
\r
53 // this._Panel.Create() ;
\r
54 // this._Panel.PanelDiv.className += ' SC_Panel' ;
\r
55 // this._Panel.PanelDiv.innerHTML = '<table cellpadding="0" cellspacing="0" width="100%" style="TABLE-LAYOUT: fixed"><tr><td nowrap></td></tr></table>' ;
\r
56 // this._ItemsHolderEl = this._Panel.PanelDiv.getElementsByTagName('TD')[0] ;
\r
59 function FCKSpecialCombo_ItemOnMouseOver()
\r
61 this.className += ' SC_ItemOver' ;
\r
64 function FCKSpecialCombo_ItemOnMouseOut()
\r
66 this.className = this.originalClass ;
\r
69 function FCKSpecialCombo_ItemOnClick( ev, specialCombo, itemId )
\r
71 this.className = this.originalClass ;
\r
73 specialCombo._Panel.Hide() ;
\r
75 specialCombo.SetLabel( this.FCKItemLabel ) ;
\r
77 if ( typeof( specialCombo.OnSelect ) == 'function' )
\r
78 specialCombo.OnSelect( itemId, this ) ;
\r
81 FCKSpecialCombo.prototype.ClearItems = function ()
\r
86 var itemsholder = this._ItemsHolderEl ;
\r
87 while ( itemsholder.firstChild )
\r
88 itemsholder.removeChild( itemsholder.firstChild ) ;
\r
91 FCKSpecialCombo.prototype.AddItem = function( id, html, label, bgColor )
\r
93 // <div class="SC_Item" onmouseover="this.className='SC_Item SC_ItemOver';" onmouseout="this.className='SC_Item';"><b>Bold 1</b></div>
\r
94 var oDiv = this._ItemsHolderEl.appendChild( this._Panel.Document.createElement( 'DIV' ) ) ;
\r
95 oDiv.className = oDiv.originalClass = 'SC_Item' ;
\r
96 oDiv.innerHTML = html ;
\r
97 oDiv.FCKItemLabel = label || id ;
\r
98 oDiv.Selected = false ;
\r
100 // In IE, the width must be set so the borders are shown correctly when the content overflows.
\r
101 if ( FCKBrowserInfo.IsIE )
\r
102 oDiv.style.width = '100%' ;
\r
105 oDiv.style.backgroundColor = bgColor ;
\r
107 FCKTools.AddEventListenerEx( oDiv, 'mouseover', FCKSpecialCombo_ItemOnMouseOver ) ;
\r
108 FCKTools.AddEventListenerEx( oDiv, 'mouseout', FCKSpecialCombo_ItemOnMouseOut ) ;
\r
109 FCKTools.AddEventListenerEx( oDiv, 'click', FCKSpecialCombo_ItemOnClick, [ this, id ] ) ;
\r
111 this.Items[ id.toString().toLowerCase() ] = oDiv ;
\r
116 FCKSpecialCombo.prototype.SelectItem = function( item )
\r
118 if ( typeof item == 'string' )
\r
119 item = this.Items[ item.toString().toLowerCase() ] ;
\r
123 item.className = item.originalClass = 'SC_ItemSelected' ;
\r
124 item.Selected = true ;
\r
128 FCKSpecialCombo.prototype.SelectItemByLabel = function( itemLabel, setLabel )
\r
130 for ( var id in this.Items )
\r
132 var oDiv = this.Items[id] ;
\r
134 if ( oDiv.FCKItemLabel == itemLabel )
\r
136 oDiv.className = oDiv.originalClass = 'SC_ItemSelected' ;
\r
137 oDiv.Selected = true ;
\r
140 this.SetLabel( itemLabel ) ;
\r
145 FCKSpecialCombo.prototype.DeselectAll = function( clearLabel )
\r
147 for ( var i in this.Items )
\r
149 if ( !this.Items[i] ) continue;
\r
150 this.Items[i].className = this.Items[i].originalClass = 'SC_Item' ;
\r
151 this.Items[i].Selected = false ;
\r
155 this.SetLabel( '' ) ;
\r
158 FCKSpecialCombo.prototype.SetLabelById = function( id )
\r
160 id = id ? id.toString().toLowerCase() : '' ;
\r
162 var oDiv = this.Items[ id ] ;
\r
163 this.SetLabel( oDiv ? oDiv.FCKItemLabel : '' ) ;
\r
166 FCKSpecialCombo.prototype.SetLabel = function( text )
\r
168 text = ( !text || text.length == 0 ) ? ' ' : text ;
\r
170 if ( text == this.Label )
\r
173 this.Label = text ;
\r
175 var labelEl = this._LabelEl ;
\r
178 labelEl.innerHTML = text ;
\r
180 // It may happen that the label is some HTML, including tags. This
\r
181 // would be a problem because when the user click on those tags, the
\r
182 // combo will get the selection from the editing area. So we must
\r
183 // disable any kind of selection here.
\r
184 FCKTools.DisableSelection( labelEl ) ;
\r
188 FCKSpecialCombo.prototype.SetEnabled = function( isEnabled )
\r
190 this.Enabled = isEnabled ;
\r
192 // In IE it can happen when the page is reloaded that _OuterTable is null, so check its existence
\r
193 if ( this._OuterTable )
\r
194 this._OuterTable.className = isEnabled ? '' : 'SC_FieldDisabled' ;
\r
197 FCKSpecialCombo.prototype.Create = function( targetElement )
\r
199 var oDoc = FCKTools.GetElementDocument( targetElement ) ;
\r
200 var eOuterTable = this._OuterTable = targetElement.appendChild( oDoc.createElement( 'TABLE' ) ) ;
\r
201 eOuterTable.cellPadding = 0 ;
\r
202 eOuterTable.cellSpacing = 0 ;
\r
204 eOuterTable.insertRow(-1) ;
\r
209 switch ( this.Style )
\r
211 case FCK_TOOLBARITEM_ONLYICON :
\r
212 sClass = 'TB_ButtonType_Icon' ;
\r
213 bShowLabel = false;
\r
215 case FCK_TOOLBARITEM_ONLYTEXT :
\r
216 sClass = 'TB_ButtonType_Text' ;
\r
217 bShowLabel = false;
\r
219 case FCK_TOOLBARITEM_ICONTEXT :
\r
224 if ( this.Caption && this.Caption.length > 0 && bShowLabel )
\r
226 var oCaptionCell = eOuterTable.rows[0].insertCell(-1) ;
\r
227 oCaptionCell.innerHTML = this.Caption ;
\r
228 oCaptionCell.className = 'SC_FieldCaption' ;
\r
231 // Create the main DIV element.
\r
232 var oField = FCKTools.AppendElement( eOuterTable.rows[0].insertCell(-1), 'div' ) ;
\r
235 oField.className = 'SC_Field' ;
\r
236 oField.style.width = this.FieldWidth + 'px' ;
\r
237 oField.innerHTML = '<table width="100%" cellpadding="0" cellspacing="0" style="TABLE-LAYOUT: fixed;"><tbody><tr><td class="SC_FieldLabel"><label> </label></td><td class="SC_FieldButton"> </td></tr></tbody></table>' ;
\r
239 this._LabelEl = oField.getElementsByTagName('label')[0] ; // Memory Leak
\r
240 this._LabelEl.innerHTML = this.Label ;
\r
244 oField.className = 'TB_Button_Off' ;
\r
245 //oField.innerHTML = '<span className="SC_FieldCaption">' + this.Caption + '<table cellpadding="0" cellspacing="0" style="TABLE-LAYOUT: fixed;"><tbody><tr><td class="SC_FieldButton" style="border-left: none;"> </td></tr></tbody></table>' ;
\r
246 //oField.innerHTML = '<table cellpadding="0" cellspacing="0" style="TABLE-LAYOUT: fixed;"><tbody><tr><td class="SC_FieldButton" style="border-left: none;"> </td></tr></tbody></table>' ;
\r
248 // Gets the correct CSS class to use for the specified style (param).
\r
249 oField.innerHTML = '<table title="' + this.Tooltip + '" class="' + sClass + '" cellspacing="0" cellpadding="0" border="0">' +
\r
251 //'<td class="TB_Icon"><img src="' + FCKConfig.SkinPath + 'toolbar/' + this.Command.Name.toLowerCase() + '.gif" width="21" height="21"></td>' +
\r
252 '<td><img class="TB_Button_Padding" src="' + FCK_SPACER_PATH + '" /></td>' +
\r
253 '<td class="TB_Text">' + this.Caption + '</td>' +
\r
254 '<td><img class="TB_Button_Padding" src="' + FCK_SPACER_PATH + '" /></td>' +
\r
255 '<td class="TB_ButtonArrow"><img src="' + FCKConfig.SkinPath + 'images/toolbar.buttonarrow.gif" width="5" height="3"></td>' +
\r
256 '<td><img class="TB_Button_Padding" src="' + FCK_SPACER_PATH + '" /></td>' +
\r
264 FCKTools.AddEventListenerEx( oField, 'mouseover', FCKSpecialCombo_OnMouseOver, this ) ;
\r
265 FCKTools.AddEventListenerEx( oField, 'mouseout', FCKSpecialCombo_OnMouseOut, this ) ;
\r
266 FCKTools.AddEventListenerEx( oField, 'click', FCKSpecialCombo_OnClick, this ) ;
\r
268 FCKTools.DisableSelection( this._Panel.Document.body ) ;
\r
271 function FCKSpecialCombo_Cleanup()
\r
273 this._LabelEl = null ;
\r
274 this._OuterTable = null ;
\r
275 this._ItemsHolderEl = null ;
\r
276 this._PanelBox = null ;
\r
280 for ( var key in this.Items )
\r
281 this.Items[key] = null ;
\r
285 function FCKSpecialCombo_OnMouseOver( ev, specialCombo )
\r
287 if ( specialCombo.Enabled )
\r
289 switch ( specialCombo.Style )
\r
291 case FCK_TOOLBARITEM_ONLYICON :
\r
292 this.className = 'TB_Button_On_Over';
\r
294 case FCK_TOOLBARITEM_ONLYTEXT :
\r
295 this.className = 'TB_Button_On_Over';
\r
297 case FCK_TOOLBARITEM_ICONTEXT :
\r
298 this.className = 'SC_Field SC_FieldOver' ;
\r
304 function FCKSpecialCombo_OnMouseOut( ev, specialCombo )
\r
306 switch ( specialCombo.Style )
\r
308 case FCK_TOOLBARITEM_ONLYICON :
\r
309 this.className = 'TB_Button_Off';
\r
311 case FCK_TOOLBARITEM_ONLYTEXT :
\r
312 this.className = 'TB_Button_Off';
\r
314 case FCK_TOOLBARITEM_ICONTEXT :
\r
315 this.className='SC_Field' ;
\r
320 function FCKSpecialCombo_OnClick( e, specialCombo )
\r
322 // For Mozilla we must stop the event propagation to avoid it hiding
\r
323 // the panel because of a click outside of it.
\r
326 // e.stopPropagation() ;
\r
327 // FCKPanelEventHandlers.OnDocumentClick( e ) ;
\r
330 if ( specialCombo.Enabled )
\r
332 var oPanel = specialCombo._Panel ;
\r
333 var oPanelBox = specialCombo._PanelBox ;
\r
334 var oItemsHolder = specialCombo._ItemsHolderEl ;
\r
335 var iMaxHeight = specialCombo.PanelMaxHeight ;
\r
337 if ( specialCombo.OnBeforeClick )
\r
338 specialCombo.OnBeforeClick( specialCombo ) ;
\r
340 // This is a tricky thing. We must call the "Load" function, otherwise
\r
341 // it will not be possible to retrieve "oItemsHolder.offsetHeight" (IE only).
\r
342 if ( FCKBrowserInfo.IsIE )
\r
343 oPanel.Preload( 0, this.offsetHeight, this ) ;
\r
345 if ( oItemsHolder.offsetHeight > iMaxHeight )
\r
347 oPanelBox.style.height = iMaxHeight + 'px' ;
\r
349 // if ( FCKBrowserInfo.IsGecko )
\r
350 // oPanelBox.style.overflow = '-moz-scrollbars-vertical' ;
\r
353 oPanelBox.style.height = '' ;
\r
355 // oPanel.PanelDiv.style.width = specialCombo.PanelWidth + 'px' ;
\r
357 oPanel.Show( 0, this.offsetHeight, this ) ;
\r
364 Sample Combo Field HTML output:
\r
366 <div class="SC_Field" style="width: 80px;">
\r
367 <table width="100%" cellpadding="0" cellspacing="0" style="table-layout: fixed;">
\r
370 <td class="SC_FieldLabel"><label> </label></td>
\r
371 <td class="SC_FieldButton"> </td>
\r