1 /* 2 Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved. 3 For licensing, see LICENSE.html or http://ckeditor.com/license 4 */ 5 6 CKEDITOR.plugins.add( 'floatpanel', 7 { 8 requires : [ 'panel' ] 9 }); 10 11 (function() 12 { 13 var panels = {}; 14 15 function getPanel( editor, doc, parentElement, definition, level ) 16 { 17 // Generates the panel key: docId-eleId-CSSs 18 var key = 19 doc.getUniqueId() + 20 '-' + parentElement.getUniqueId() + 21 '-' + editor.skinName + 22 ( ( definition.css && ( '-' + definition.css ) ) || '' ) + 23 ( ( level && ( '-' + level ) ) || '' ); 24 25 var panel = panels[ key ]; 26 27 if ( !panel ) 28 { 29 panel = panels[ key ] = new CKEDITOR.ui.panel( doc, definition ); 30 panel.element = parentElement.append( CKEDITOR.dom.element.createFromHtml( panel.renderHtml( editor ), doc ) ); 31 32 panel.element.setStyles( 33 { 34 display : 'none', 35 position : 'absolute' 36 }); 37 } 38 39 return panel; 40 } 41 42 CKEDITOR.ui.floatPanel = CKEDITOR.tools.createClass( 43 { 44 $ : function( editor, parentElement, definition, level ) 45 { 46 definition.forceIFrame = true; 47 48 var doc = parentElement.getDocument(), 49 panel = getPanel( editor, doc, parentElement, definition, level || 0 ), 50 element = panel.element, 51 iframe = element.getFirst().getFirst(); 52 53 this.element = element; 54 55 this._ = 56 { 57 // The panel that will be floating. 58 panel : panel, 59 parentElement : parentElement, 60 definition : definition, 61 document : doc, 62 iframe : iframe, 63 children : [] 64 } 65 }, 66 67 proto : 68 { 69 addBlock : function( name, block ) 70 { 71 return this._.panel.addBlock( name, block ); 72 }, 73 74 addListBlock : function( name, multiSelect ) 75 { 76 return this._.panel.addListBlock( name, multiSelect ); 77 }, 78 79 getBlock : function( name ) 80 { 81 return this._.panel.getBlock( name ); 82 }, 83 84 showBlock : function( name, offsetParent, corner, offsetX, offsetY ) 85 { 86 var panel = this._.panel, 87 block = panel.showBlock( name ); 88 89 var element = this.element, 90 iframe = this._.iframe, 91 position = offsetParent.getDocumentPosition( element.getDocument() ); 92 93 var left = position.x + ( offsetX || 0 ), 94 top = position.y + ( offsetY || 0 ); 95 96 if ( corner == 2 || corner == 3 ) 97 left += offsetParent.$.offsetWidth - 1; 98 99 if ( corner == 3 || corner == 4 ) 100 top += offsetParent.$.offsetHeight - 1; 101 102 element.setStyles( 103 { 104 left : left + 'px', 105 top : top + 'px', 106 display : '' 107 }); 108 109 if ( block.autoSize ) 110 { 111 function setHeight() 112 { 113 element.getFirst().setStyle( 'height', block.element.$.scrollHeight + 'px' ); 114 } 115 116 if ( !CKEDITOR.env.gecko || panel.isLoaded ) 117 setHeight(); 118 else 119 panel.onLoad = setHeight; 120 } 121 else 122 element.getFirst().removeStyle( 'height' ); 123 124 // Configure the IFrame blur event. Do that only once. 125 if ( !this._.blurSet ) 126 { 127 // Non IE prefer the event into a window object. 128 var focused = CKEDITOR.env.ie ? iframe : new CKEDITOR.dom.window( iframe.$.contentWindow ); 129 130 focused.on( 'blur', function() 131 { 132 if ( !this._.activeChild ) 133 this.hide(); 134 }, 135 this ); 136 137 focused.on( 'focus', function() 138 { 139 this._.focused = true; 140 this.hideChild(); 141 }, 142 this ); 143 144 this._.blurSet = 1; 145 } 146 147 // Set the IFrame focus, so the blur event gets fired. 148 setTimeout( function() 149 { 150 iframe.$.contentWindow.focus(); 151 }, 0); 152 153 panel.onEscape = CKEDITOR.tools.bind( function() 154 { 155 this.onEscape && this.onEscape(); 156 }, 157 this ); 158 159 if ( this.onShow ) 160 this.onShow.call( this ); 161 }, 162 163 hide : function() 164 { 165 if ( !this.onHide || this.onHide.call( this ) !== true ) 166 { 167 this.hideChild(); 168 this.element.setStyle( 'display', 'none' ); 169 } 170 }, 171 172 showAsChild : function( panel, blockName, offsetParent, corner, offsetX, offsetY ) 173 { 174 this.hideChild(); 175 176 panel.onHide = CKEDITOR.tools.bind( function() 177 { 178 // Use a timeout, so we give time for this menu to get 179 // potentially focused. 180 CKEDITOR.tools.setTimeout( function() 181 { 182 if ( !this._.focused ) 183 this.hide(); 184 }, 185 0, this ); 186 }, 187 this ); 188 189 this._.activeChild = panel; 190 this._.focused = false; 191 192 panel.showBlock( blockName, offsetParent, corner, offsetX, offsetY ); 193 }, 194 195 hideChild : function() 196 { 197 var activeChild = this._.activeChild; 198 199 if ( activeChild ) 200 { 201 delete activeChild.onHide; 202 delete this._.activeChild; 203 activeChild.hide(); 204 } 205 } 206 } 207 }); 208 })(); 209