Ticket #2056: validhtml.patch
File validhtml.patch, 70.0 KB (added by , 15 years ago) |
---|
-
editor/dialog/fck_paste/fck_paste.js
1 /* 2 * FCKeditor - The text editor for Internet - http://www.fckeditor.net 3 * Copyright (C) 2003-2008 Frederico Caldeira Knabben 4 * 5 * == BEGIN LICENSE == 6 * 7 * Licensed under the terms of any of the following licenses at your 8 * choice: 9 * 10 * - GNU General Public License Version 2 or later (the "GPL") 11 * http://www.gnu.org/licenses/gpl.html 12 * 13 * - GNU Lesser General Public License Version 2.1 or later (the "LGPL") 14 * http://www.gnu.org/licenses/lgpl.html 15 * 16 * - Mozilla Public License Version 1.1 or later (the "MPL") 17 * http://www.mozilla.org/MPL/MPL-1.1.html 18 * 19 * == END LICENSE == 20 */ 21 22 var dialog = window.parent ; 23 var oEditor = dialog.InnerDialogLoaded() ; 24 var FCK = oEditor.FCK; 25 var FCKTools = oEditor.FCKTools ; 26 var FCKConfig = oEditor.FCKConfig ; 27 var FCKBrowserInfo = oEditor.FCKBrowserInfo ; 28 29 window.onload = function () 30 { 31 // First of all, translate the dialog box texts 32 oEditor.FCKLanguageManager.TranslatePage(document) ; 33 34 var sPastingType = dialog.Args().CustomValue ; 35 36 if ( sPastingType == 'Word' || sPastingType == 'Security' ) 37 { 38 if ( sPastingType == 'Security' ) 39 document.getElementById( 'xSecurityMsg' ).style.display = '' ; 40 41 // For document.domain compatibility (#123) we must do all the magic in 42 // the URL for IE. 43 var sFrameUrl = !oEditor.FCK_IS_CUSTOM_DOMAIN || !FCKBrowserInfo.IsIE ? 44 'javascript:void(0)' : 45 'javascript:void( (function(){' + 46 'document.open() ;' + 47 'document.domain=\'' + document.domain + '\' ;' + 48 'document.write(\'<html><head><script>window.onerror = function() { return true ; };<\/script><\/head><body><\/body><\/html>\') ;' + 49 'document.close() ;' + 50 'document.body.contentEditable = true ;' + 51 'window.focus() ;' + 52 '})() )' ; 53 54 var eFrameSpace = document.getElementById( 'xFrameSpace' ) ; 55 eFrameSpace.innerHTML = '<iframe id="frmData" src="' + sFrameUrl + '" ' + 56 'height="98%" width="99%" frameborder="0" style="border: #000000 1px; background-color: #ffffff"></iframe>' ; 57 58 var oFrame = eFrameSpace.firstChild ; 59 60 if ( !oEditor.FCK_IS_CUSTOM_DOMAIN || !FCKBrowserInfo.IsIE ) 61 { 62 // Avoid errors if the pasted content has any script that fails: #389 63 var oDoc = oFrame.contentWindow.document ; 64 oDoc.open() ; 65 oDoc.write('<html><head><script>window.onerror = function() { return true ; };<\/script><\/head><body><\/body><\/html>') ; 66 oDoc.close() ; 67 68 if ( FCKBrowserInfo.IsIE ) 69 oDoc.body.contentEditable = true ; 70 else 71 oDoc.designMode = 'on' ; 72 73 oFrame.contentWindow.focus(); 74 } 75 } 76 else 77 { 78 document.getElementById('txtData').style.display = '' ; 79 } 80 81 if ( sPastingType != 'Word' ) 82 document.getElementById('oWordCommands').style.display = 'none' ; 83 84 dialog.SetOkButton( true ) ; 85 dialog.SetAutoSize( true ) ; 86 } 87 88 function Ok() 89 { 90 // Before doing anything, save undo snapshot. 91 oEditor.FCKUndo.SaveUndoStep() ; 92 93 var sHtml ; 94 95 var sPastingType = dialog.Args().CustomValue ; 96 97 if ( sPastingType == 'Word' || sPastingType == 'Security' ) 98 { 99 var oFrame = document.getElementById('frmData') ; 100 var oBody ; 101 102 if ( oFrame.contentDocument ) 103 oBody = oFrame.contentDocument.body ; 104 else 105 oBody = oFrame.contentWindow.document.body ; 106 107 if ( sPastingType == 'Word' ) 108 { 109 // If a plugin creates a FCK.CustomCleanWord function it will be called instead of the default one 110 if ( typeof( FCK.CustomCleanWord ) == 'function' ) 111 sHtml = FCK.CustomCleanWord( oBody, document.getElementById('chkRemoveFont').checked, document.getElementById('chkRemoveStyles').checked ) ; 112 else 113 sHtml = CleanWord( oBody, document.getElementById('chkRemoveFont').checked, document.getElementById('chkRemoveStyles').checked ) ; 114 } 115 else 116 sHtml = oBody.innerHTML ; 117 118 // Fix relative anchor URLs (IE automatically adds the current page URL). 119 var re = new RegExp( window.location + "#", "g" ) ; 120 sHtml = sHtml.replace( re, '#') ; 121 } 122 else 123 { 124 sHtml = oEditor.FCKTools.HTMLEncode( document.getElementById('txtData').value ) ; 125 sHtml = FCKTools.ProcessLineBreaks( oEditor, FCKConfig, sHtml ) ; 126 127 // FCK.InsertHtml() does not work for us, since document fragments cannot contain node fragments. :( 128 // Use the marker method instead. It's primitive, but it works. 129 var range = new oEditor.FCKDomRange( oEditor.FCK.EditorWindow ) ; 130 var oDoc = oEditor.FCK.EditorDocument ; 131 dialog.Selection.EnsureSelection() ; 132 range.MoveToSelection() ; 133 range.DeleteContents() ; 134 var marker = [] ; 135 for ( var i = 0 ; i < 5 ; i++ ) 136 marker.push( parseInt(Math.random() * 100000, 10 ) ) ; 137 marker = marker.join( "" ) ; 138 range.InsertNode ( oDoc.createTextNode( marker ) ) ; 139 var bookmark = range.CreateBookmark() ; 140 141 // Now we've got a marker indicating the paste position in the editor document. 142 // Find its position in the HTML code. 143 var htmlString = oDoc.body.innerHTML ; 144 var index = htmlString.indexOf( marker ) ; 145 146 // Split it the HTML code up, add the code we generated, and put them back together. 147 var htmlList = [] ; 148 htmlList.push( htmlString.substr( 0, index ) ) ; 149 htmlList.push( sHtml ) ; 150 htmlList.push( htmlString.substr( index + marker.length ) ) ; 151 htmlString = htmlList.join( "" ) ; 152 153 if ( oEditor.FCKBrowserInfo.IsIE ) 154 oEditor.FCK.SetInnerHtml( htmlString ) ; 155 else 156 oDoc.body.innerHTML = htmlString ; 157 158 range.MoveToBookmark( bookmark ) ; 159 range.Collapse( false ) ; 160 range.Select() ; 161 range.Release() ; 162 return true ; 163 } 164 165 oEditor.FCK.InsertHtml( sHtml ) ; 166 167 return true ; 168 } 169 170 // This function will be called from the PasteFromWord dialog (fck_paste.html) 171 // Input: oNode a DOM node that contains the raw paste from the clipboard 172 // bIgnoreFont, bRemoveStyles booleans according to the values set in the dialog 173 // Output: the cleaned string 174 function CleanWord( oNode, bIgnoreFont, bRemoveStyles ) 175 { 176 var html = oNode.innerHTML ; 177 178 html = html.replace(/<o:p>\s*<\/o:p>/g, '') ; 179 html = html.replace(/<o:p>.*?<\/o:p>/g, ' ') ; 180 181 // Remove mso-xxx styles. 182 html = html.replace( /\s*mso-[^:]+:[^;"]+;?/gi, '' ) ; 183 184 // Remove margin styles. 185 html = html.replace( /\s*MARGIN: 0cm 0cm 0pt\s*;/gi, '' ) ; 186 html = html.replace( /\s*MARGIN: 0cm 0cm 0pt\s*"/gi, "\"" ) ; 187 188 html = html.replace( /\s*TEXT-INDENT: 0cm\s*;/gi, '' ) ; 189 html = html.replace( /\s*TEXT-INDENT: 0cm\s*"/gi, "\"" ) ; 190 191 html = html.replace( /\s*TEXT-ALIGN: [^\s;]+;?"/gi, "\"" ) ; 192 193 html = html.replace( /\s*PAGE-BREAK-BEFORE: [^\s;]+;?"/gi, "\"" ) ; 194 195 html = html.replace( /\s*FONT-VARIANT: [^\s;]+;?"/gi, "\"" ) ; 196 197 html = html.replace( /\s*tab-stops:[^;"]*;?/gi, '' ) ; 198 html = html.replace( /\s*tab-stops:[^"]*/gi, '' ) ; 199 200 // Remove FONT face attributes. 201 if ( bIgnoreFont ) 202 { 203 html = html.replace( /\s*face="[^"]*"/gi, '' ) ; 204 html = html.replace( /\s*face=[^ >]*/gi, '' ) ; 205 206 html = html.replace( /\s*FONT-FAMILY:[^;"]*;?/gi, '' ) ; 207 } 208 209 // Remove Class attributes 210 html = html.replace(/<(\w[^>]*) class=([^ |>]*)([^>]*)/gi, "<$1$3") ; 211 212 // Remove styles. 213 if ( bRemoveStyles ) 214 html = html.replace( /<(\w[^>]*) style="([^\"]*)"([^>]*)/gi, "<$1$3" ) ; 215 216 // Remove empty styles. 217 html = html.replace( /\s*style="\s*"/gi, '' ) ; 218 219 html = html.replace( /<SPAN\s*[^>]*>\s* \s*<\/SPAN>/gi, ' ' ) ; 220 221 html = html.replace( /<SPAN\s*[^>]*><\/SPAN>/gi, '' ) ; 222 223 // Remove Lang attributes 224 html = html.replace(/<(\w[^>]*) lang=([^ |>]*)([^>]*)/gi, "<$1$3") ; 225 226 html = html.replace( /<SPAN\s*>(.*?)<\/SPAN>/gi, '$1' ) ; 227 228 html = html.replace( /<FONT\s*>(.*?)<\/FONT>/gi, '$1' ) ; 229 230 // Remove XML elements and declarations 231 html = html.replace(/<\\?\?xml[^>]*>/gi, '' ) ; 232 233 // Remove Tags with XML namespace declarations: <o:p><\/o:p> 234 html = html.replace(/<\/?\w+:[^>]*>/gi, '' ) ; 235 236 // Remove comments [SF BUG-1481861]. 237 html = html.replace(/<\!--.*?-->/g, '' ) ; 238 239 html = html.replace( /<(U|I|STRIKE)> <\/\1>/g, ' ' ) ; 240 241 html = html.replace( /<H\d>\s*<\/H\d>/gi, '' ) ; 242 243 // Remove "display:none" tags. 244 html = html.replace( /<(\w+)[^>]*\sstyle="[^"]*DISPLAY\s?:\s?none(.*?)<\/\1>/ig, '' ) ; 245 246 // Remove language tags 247 html = html.replace( /<(\w[^>]*) language=([^ |>]*)([^>]*)/gi, "<$1$3") ; 248 249 // Remove onmouseover and onmouseout events (from MS Word comments effect) 250 html = html.replace( /<(\w[^>]*) onmouseover="([^\"]*)"([^>]*)/gi, "<$1$3") ; 251 html = html.replace( /<(\w[^>]*) onmouseout="([^\"]*)"([^>]*)/gi, "<$1$3") ; 252 253 if ( FCKConfig.CleanWordKeepsStructure ) 254 { 255 // The original <Hn> tag send from Word is something like this: <Hn style="margin-top:0px;margin-bottom:0px"> 256 html = html.replace( /<H(\d)([^>]*)>/gi, '<h$1>' ) ; 257 258 // Word likes to insert extra <font> tags, when using MSIE. (Wierd). 259 html = html.replace( /<(H\d)><FONT[^>]*>(.*?)<\/FONT><\/\1>/gi, '<$1>$2<\/$1>' ); 260 html = html.replace( /<(H\d)><EM>(.*?)<\/EM><\/\1>/gi, '<$1>$2<\/$1>' ); 261 } 262 else 263 { 264 html = html.replace( /<H1([^>]*)>/gi, '<div$1><b><font size="6">' ) ; 265 html = html.replace( /<H2([^>]*)>/gi, '<div$1><b><font size="5">' ) ; 266 html = html.replace( /<H3([^>]*)>/gi, '<div$1><b><font size="4">' ) ; 267 html = html.replace( /<H4([^>]*)>/gi, '<div$1><b><font size="3">' ) ; 268 html = html.replace( /<H5([^>]*)>/gi, '<div$1><b><font size="2">' ) ; 269 html = html.replace( /<H6([^>]*)>/gi, '<div$1><b><font size="1">' ) ; 270 271 html = html.replace( /<\/H\d>/gi, '<\/font><\/b><\/div>' ) ; 272 273 // Transform <P> to <DIV> 274 var re = new RegExp( '(<P)([^>]*>.*?)(<\/P>)', 'gi' ) ; // Different because of a IE 5.0 error 275 html = html.replace( re, '<div$2<\/div>' ) ; 276 277 // Remove empty tags (three times, just to be sure). 278 // This also removes any empty anchor 279 html = html.replace( /<([^\s>]+)(\s[^>]*)?>\s*<\/\1>/g, '' ) ; 280 html = html.replace( /<([^\s>]+)(\s[^>]*)?>\s*<\/\1>/g, '' ) ; 281 html = html.replace( /<([^\s>]+)(\s[^>]*)?>\s*<\/\1>/g, '' ) ; 282 } 283 284 return html ; 285 } -
editor/dialog/fck_paste.html
29 29 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 30 30 <meta name="robots" content="noindex, nofollow" /> 31 31 <script src="common/fck_dialog_common.js" type="text/javascript"></script> 32 <script type="text/javascript"> 33 var dialog = window.parent ; 34 var oEditor = dialog.InnerDialogLoaded() ; 35 var FCK = oEditor.FCK; 36 var FCKTools = oEditor.FCKTools ; 37 var FCKConfig = oEditor.FCKConfig ; 38 var FCKBrowserInfo = oEditor.FCKBrowserInfo ; 32 <script type="text/javascript" src="fck_paste/fck_paste.js"></script> 39 33 40 window.onload = function ()41 {42 // First of all, translate the dialog box texts43 oEditor.FCKLanguageManager.TranslatePage(document) ;44 45 var sPastingType = dialog.Args().CustomValue ;46 47 if ( sPastingType == 'Word' || sPastingType == 'Security' )48 {49 if ( sPastingType == 'Security' )50 document.getElementById( 'xSecurityMsg' ).style.display = '' ;51 52 // For document.domain compatibility (#123) we must do all the magic in53 // the URL for IE.54 var sFrameUrl = !oEditor.FCK_IS_CUSTOM_DOMAIN || !FCKBrowserInfo.IsIE ?55 'javascript:void(0)' :56 'javascript:void( (function(){' +57 'document.open() ;' +58 'document.domain=\'' + document.domain + '\' ;' +59 'document.write(\'<html><head><script>window.onerror = function() { return true ; };<\/script><\/head><body><\/body><\/html>\') ;' +60 'document.close() ;' +61 'document.body.contentEditable = true ;' +62 'window.focus() ;' +63 '})() )' ;64 65 var eFrameSpace = document.getElementById( 'xFrameSpace' ) ;66 eFrameSpace.innerHTML = '<iframe id="frmData" src="' + sFrameUrl + '" ' +67 'height="98%" width="99%" frameborder="0" style="border: #000000 1px; background-color: #ffffff"></iframe>' ;68 69 var oFrame = eFrameSpace.firstChild ;70 71 if ( !oEditor.FCK_IS_CUSTOM_DOMAIN || !FCKBrowserInfo.IsIE )72 {73 // Avoid errors if the pasted content has any script that fails: #38974 var oDoc = oFrame.contentWindow.document ;75 oDoc.open() ;76 oDoc.write('<html><head><script>window.onerror = function() { return true ; };<\/script><\/head><body><\/body><\/html>') ;77 oDoc.close() ;78 79 if ( FCKBrowserInfo.IsIE )80 oDoc.body.contentEditable = true ;81 else82 oDoc.designMode = 'on' ;83 84 oFrame.contentWindow.focus();85 }86 }87 else88 {89 document.getElementById('txtData').style.display = '' ;90 }91 92 if ( sPastingType != 'Word' )93 document.getElementById('oWordCommands').style.display = 'none' ;94 95 dialog.SetOkButton( true ) ;96 dialog.SetAutoSize( true ) ;97 }98 99 function Ok()100 {101 // Before doing anything, save undo snapshot.102 oEditor.FCKUndo.SaveUndoStep() ;103 104 var sHtml ;105 106 var sPastingType = dialog.Args().CustomValue ;107 108 if ( sPastingType == 'Word' || sPastingType == 'Security' )109 {110 var oFrame = document.getElementById('frmData') ;111 var oBody ;112 113 if ( oFrame.contentDocument )114 oBody = oFrame.contentDocument.body ;115 else116 oBody = oFrame.contentWindow.document.body ;117 118 if ( sPastingType == 'Word' )119 {120 // If a plugin creates a FCK.CustomCleanWord function it will be called instead of the default one121 if ( typeof( FCK.CustomCleanWord ) == 'function' )122 sHtml = FCK.CustomCleanWord( oBody, document.getElementById('chkRemoveFont').checked, document.getElementById('chkRemoveStyles').checked ) ;123 else124 sHtml = CleanWord( oBody, document.getElementById('chkRemoveFont').checked, document.getElementById('chkRemoveStyles').checked ) ;125 }126 else127 sHtml = oBody.innerHTML ;128 129 // Fix relative anchor URLs (IE automatically adds the current page URL).130 var re = new RegExp( window.location + "#", "g" ) ;131 sHtml = sHtml.replace( re, '#') ;132 }133 else134 {135 sHtml = oEditor.FCKTools.HTMLEncode( document.getElementById('txtData').value ) ;136 sHtml = FCKTools.ProcessLineBreaks( oEditor, FCKConfig, sHtml ) ;137 138 // FCK.InsertHtml() does not work for us, since document fragments cannot contain node fragments. :(139 // Use the marker method instead. It's primitive, but it works.140 var range = new oEditor.FCKDomRange( oEditor.FCK.EditorWindow ) ;141 var oDoc = oEditor.FCK.EditorDocument ;142 dialog.Selection.EnsureSelection() ;143 range.MoveToSelection() ;144 range.DeleteContents() ;145 var marker = [] ;146 for ( var i = 0 ; i < 5 ; i++ )147 marker.push( parseInt(Math.random() * 100000, 10 ) ) ;148 marker = marker.join( "" ) ;149 range.InsertNode ( oDoc.createTextNode( marker ) ) ;150 var bookmark = range.CreateBookmark() ;151 152 // Now we've got a marker indicating the paste position in the editor document.153 // Find its position in the HTML code.154 var htmlString = oDoc.body.innerHTML ;155 var index = htmlString.indexOf( marker ) ;156 157 // Split it the HTML code up, add the code we generated, and put them back together.158 var htmlList = [] ;159 htmlList.push( htmlString.substr( 0, index ) ) ;160 htmlList.push( sHtml ) ;161 htmlList.push( htmlString.substr( index + marker.length ) ) ;162 htmlString = htmlList.join( "" ) ;163 164 if ( oEditor.FCKBrowserInfo.IsIE )165 oEditor.FCK.SetInnerHtml( htmlString ) ;166 else167 oDoc.body.innerHTML = htmlString ;168 169 range.MoveToBookmark( bookmark ) ;170 range.Collapse( false ) ;171 range.Select() ;172 range.Release() ;173 return true ;174 }175 176 oEditor.FCK.InsertHtml( sHtml ) ;177 178 return true ;179 }180 181 // This function will be called from the PasteFromWord dialog (fck_paste.html)182 // Input: oNode a DOM node that contains the raw paste from the clipboard183 // bIgnoreFont, bRemoveStyles booleans according to the values set in the dialog184 // Output: the cleaned string185 function CleanWord( oNode, bIgnoreFont, bRemoveStyles )186 {187 var html = oNode.innerHTML ;188 189 html = html.replace(/<o:p>\s*<\/o:p>/g, '') ;190 html = html.replace(/<o:p>.*?<\/o:p>/g, ' ') ;191 192 // Remove mso-xxx styles.193 html = html.replace( /\s*mso-[^:]+:[^;"]+;?/gi, '' ) ;194 195 // Remove margin styles.196 html = html.replace( /\s*MARGIN: 0cm 0cm 0pt\s*;/gi, '' ) ;197 html = html.replace( /\s*MARGIN: 0cm 0cm 0pt\s*"/gi, "\"" ) ;198 199 html = html.replace( /\s*TEXT-INDENT: 0cm\s*;/gi, '' ) ;200 html = html.replace( /\s*TEXT-INDENT: 0cm\s*"/gi, "\"" ) ;201 202 html = html.replace( /\s*TEXT-ALIGN: [^\s;]+;?"/gi, "\"" ) ;203 204 html = html.replace( /\s*PAGE-BREAK-BEFORE: [^\s;]+;?"/gi, "\"" ) ;205 206 html = html.replace( /\s*FONT-VARIANT: [^\s;]+;?"/gi, "\"" ) ;207 208 html = html.replace( /\s*tab-stops:[^;"]*;?/gi, '' ) ;209 html = html.replace( /\s*tab-stops:[^"]*/gi, '' ) ;210 211 // Remove FONT face attributes.212 if ( bIgnoreFont )213 {214 html = html.replace( /\s*face="[^"]*"/gi, '' ) ;215 html = html.replace( /\s*face=[^ >]*/gi, '' ) ;216 217 html = html.replace( /\s*FONT-FAMILY:[^;"]*;?/gi, '' ) ;218 }219 220 // Remove Class attributes221 html = html.replace(/<(\w[^>]*) class=([^ |>]*)([^>]*)/gi, "<$1$3") ;222 223 // Remove styles.224 if ( bRemoveStyles )225 html = html.replace( /<(\w[^>]*) style="([^\"]*)"([^>]*)/gi, "<$1$3" ) ;226 227 // Remove empty styles.228 html = html.replace( /\s*style="\s*"/gi, '' ) ;229 230 html = html.replace( /<SPAN\s*[^>]*>\s* \s*<\/SPAN>/gi, ' ' ) ;231 232 html = html.replace( /<SPAN\s*[^>]*><\/SPAN>/gi, '' ) ;233 234 // Remove Lang attributes235 html = html.replace(/<(\w[^>]*) lang=([^ |>]*)([^>]*)/gi, "<$1$3") ;236 237 html = html.replace( /<SPAN\s*>(.*?)<\/SPAN>/gi, '$1' ) ;238 239 html = html.replace( /<FONT\s*>(.*?)<\/FONT>/gi, '$1' ) ;240 241 // Remove XML elements and declarations242 html = html.replace(/<\\?\?xml[^>]*>/gi, '' ) ;243 244 // Remove Tags with XML namespace declarations: <o:p><\/o:p>245 html = html.replace(/<\/?\w+:[^>]*>/gi, '' ) ;246 247 // Remove comments [SF BUG-1481861].248 html = html.replace(/<\!--.*?-->/g, '' ) ;249 250 html = html.replace( /<(U|I|STRIKE)> <\/\1>/g, ' ' ) ;251 252 html = html.replace( /<H\d>\s*<\/H\d>/gi, '' ) ;253 254 // Remove "display:none" tags.255 html = html.replace( /<(\w+)[^>]*\sstyle="[^"]*DISPLAY\s?:\s?none(.*?)<\/\1>/ig, '' ) ;256 257 // Remove language tags258 html = html.replace( /<(\w[^>]*) language=([^ |>]*)([^>]*)/gi, "<$1$3") ;259 260 // Remove onmouseover and onmouseout events (from MS Word comments effect)261 html = html.replace( /<(\w[^>]*) onmouseover="([^\"]*)"([^>]*)/gi, "<$1$3") ;262 html = html.replace( /<(\w[^>]*) onmouseout="([^\"]*)"([^>]*)/gi, "<$1$3") ;263 264 if ( FCKConfig.CleanWordKeepsStructure )265 {266 // The original <Hn> tag send from Word is something like this: <Hn style="margin-top:0px;margin-bottom:0px">267 html = html.replace( /<H(\d)([^>]*)>/gi, '<h$1>' ) ;268 269 // Word likes to insert extra <font> tags, when using MSIE. (Wierd).270 html = html.replace( /<(H\d)><FONT[^>]*>(.*?)<\/FONT><\/\1>/gi, '<$1>$2<\/$1>' );271 html = html.replace( /<(H\d)><EM>(.*?)<\/EM><\/\1>/gi, '<$1>$2<\/$1>' );272 }273 else274 {275 html = html.replace( /<H1([^>]*)>/gi, '<div$1><b><font size="6">' ) ;276 html = html.replace( /<H2([^>]*)>/gi, '<div$1><b><font size="5">' ) ;277 html = html.replace( /<H3([^>]*)>/gi, '<div$1><b><font size="4">' ) ;278 html = html.replace( /<H4([^>]*)>/gi, '<div$1><b><font size="3">' ) ;279 html = html.replace( /<H5([^>]*)>/gi, '<div$1><b><font size="2">' ) ;280 html = html.replace( /<H6([^>]*)>/gi, '<div$1><b><font size="1">' ) ;281 282 html = html.replace( /<\/H\d>/gi, '<\/font><\/b><\/div>' ) ;283 284 // Transform <P> to <DIV>285 var re = new RegExp( '(<P)([^>]*>.*?)(<\/P>)', 'gi' ) ; // Different because of a IE 5.0 error286 html = html.replace( re, '<div$2<\/div>' ) ;287 288 // Remove empty tags (three times, just to be sure).289 // This also removes any empty anchor290 html = html.replace( /<([^\s>]+)(\s[^>]*)?>\s*<\/\1>/g, '' ) ;291 html = html.replace( /<([^\s>]+)(\s[^>]*)?>\s*<\/\1>/g, '' ) ;292 html = html.replace( /<([^\s>]+)(\s[^>]*)?>\s*<\/\1>/g, '' ) ;293 }294 295 return html ;296 }297 298 </script>299 300 34 </head> 301 35 <body style="overflow: hidden"> 302 36 <table cellspacing="0" cellpadding="0" width="100%" border="0" style="height: 98%"> -
editor/dialog/fck_image.html
165 165 <br /> 166 166 <input id="btnUpload" type="submit" value="Send it to the Server" fcklang="DlgLnkBtnUpload" /> 167 167 <script type="text/javascript"> 168 document.write( '<iframe name="UploadWindow" style="display: none" src="' + FCKTools.GetVoidUrl() + '"></iframe>' ) ;168 document.write( '<iframe name="UploadWindow" style="display: none" src="' + FCKTools.GetVoidUrl() + '"></iframe>' ) ; 169 169 </script> 170 170 </form> 171 171 </div> -
editor/fckdialog.html
26 26 <title></title> 27 27 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 28 28 <meta name="robots" content="noindex, nofollow" /> 29 <script type="text/javascript"> 30 // Domain relaxation logic. 31 (function() 32 { 33 var d = document.domain ; 34 35 while ( true ) 36 { 37 // Test if we can access a parent property. 38 try 39 { 40 var parentDomain = ( Args().TopWindow || E ).document.domain ; 41 42 if ( document.domain != parentDomain ) 43 document.domain = parentDomain ; 44 45 break ; 46 } 47 catch( e ) {} 48 49 // Remove a domain part: www.mytest.example.com => mytest.example.com => example.com ... 50 d = d.replace( /.*?(?:\.|$)/, '' ) ; 51 52 if ( d.length == 0 ) 53 break ; // It was not able to detect the domain. 54 55 document.domain = d ; 56 } 57 })() ; 58 59 var E = frameElement._DialogArguments.Editor ; 60 61 // It seems referencing to frameElement._DialogArguments directly would lead to memory leaks in IE. 62 // So let's use functions to access its members instead. 63 function Args() 64 { 65 return frameElement._DialogArguments ; 66 } 67 68 function ParentDialog( dialog ) 69 { 70 return dialog ? dialog._ParentDialog : frameElement._ParentDialog ; 71 } 72 73 var FCK = E.FCK ; 74 var FCKTools = E.FCKTools ; 75 var FCKDomTools = E.FCKDomTools ; 76 var FCKDialog = E.FCKDialog ; 77 var FCKBrowserInfo = E.FCKBrowserInfo ; 78 var FCKConfig = E.FCKConfig ; 79 80 // Steal the focus so that the caret would no longer stay in the editor iframe. 81 window.focus() ; 82 83 // Sets the Skin CSS 84 document.write( FCKTools.GetStyleHtml( FCKConfig.SkinDialogCSS ) ) ; 85 86 // Sets the language direction. 87 var langDir = document.documentElement.dir = E.FCKLang.Dir ; 88 89 // For IE6-, the fck_dialog_ie6.js is loaded, used to fix limitations in the browser. 90 if ( FCKBrowserInfo.IsIE && !FCKBrowserInfo.IsIE7 ) 91 document.write( '<' + 'script type="text/javascript" src="' + FCKConfig.SkinPath + 'fck_dialog_ie6.js"><' + '\/script>' ) ; 92 93 FCKTools.RegisterDollarFunction( window ) ; 94 95 // Resize related functions. 96 var Sizer = function() 97 { 98 var bAutoSize = false ; 99 100 var retval = { 101 // Sets whether the dialog should auto-resize according to its content's height. 102 SetAutoSize : function( autoSize ) 103 { 104 bAutoSize = autoSize ; 105 this.RefreshSize() ; 106 }, 107 108 // Fit the dialog container's layout to the inner iframe's external size. 109 RefreshContainerSize : function() 110 { 111 var frmMain = $( 'frmMain' ) ; 112 113 if ( frmMain ) 114 { 115 // Get the container size. 116 var height = $( 'contents' ).offsetHeight ; 117 118 // Subtract the size of other elements. 119 height -= $( 'TitleArea' ).offsetHeight ; 120 height -= $( 'TabsRow' ).offsetHeight ; 121 height -= $( 'PopupButtons' ).offsetHeight ; 122 123 frmMain.style.height = Math.max( height, 0 ) + 'px' ; 124 } 125 }, 126 127 // Resize and re-layout the dialog. 128 // Triggers the onresize event for the layout logic. 129 ResizeDialog : function( width, height ) 130 { 131 FCKDomTools.SetElementStyles( window.frameElement, 132 { 133 'width' : width + 'px', 134 'height' : height + 'px' 135 } ) ; 136 137 // If the skin have defined a function for resize fixes, call it now. 138 if ( typeof window.DoResizeFixes == 'function' ) 139 window.DoResizeFixes() ; 140 }, 141 142 // if bAutoSize is true, automatically fit the dialog size and layout to 143 // accomodate the inner iframe's internal height. 144 // if bAutoSize is false, then only the layout logic for the dialog decorations 145 // is run to accomodate the inner iframe's external height. 146 RefreshSize : function() 147 { 148 if ( bAutoSize ) 149 { 150 var frmMain = $( 'frmMain' ) ; 151 var innerDoc = frmMain.contentWindow.document ; 152 var isStrict = FCKTools.IsStrictMode( innerDoc ) ; 153 154 // Get the size of the frame contents. 155 var innerWidth = isStrict ? innerDoc.documentElement.scrollWidth : innerDoc.body.scrollWidth ; 156 var innerHeight = isStrict ? innerDoc.documentElement.scrollHeight : innerDoc.body.scrollHeight ; 157 158 // Get the current frame size. 159 var frameSize = FCKTools.GetViewPaneSize( frmMain.contentWindow ) ; 160 161 var deltaWidth = innerWidth - frameSize.Width ; 162 var deltaHeight = innerHeight - frameSize.Height ; 163 164 // If the contents fits the current size. 165 if ( deltaWidth <= 0 && deltaHeight <= 0 ) 166 return ; 167 168 var dialogWidth = frameElement.offsetWidth + Math.max( deltaWidth, 0 ) ; 169 var dialogHeight = frameElement.offsetHeight + Math.max( deltaHeight, 0 ) ; 170 171 this.ResizeDialog( dialogWidth, dialogHeight ) ; 172 } 173 this.RefreshContainerSize() ; 174 } 175 } 176 177 /** 178 * Safari seems to have a bug with the time when RefreshSize() is executed - it 179 * thinks frmMain's innerHeight is 0 if we query the value too soon after the 180 * page is loaded in some circumstances. (#1316) 181 * TODO : Maybe this is not needed anymore after #35. 182 */ 183 if ( FCKBrowserInfo.IsSafari ) 184 { 185 var originalRefreshSize = retval.RefreshSize ; 186 187 retval.RefreshSize = function() 188 { 189 FCKTools.SetTimeout( originalRefreshSize, 1, retval ) ; 190 } 191 } 192 193 window.onresize = function() 194 { 195 retval.RefreshContainerSize() ; 196 } 197 198 window.SetAutoSize = FCKTools.Bind( retval, retval.SetAutoSize ) ; 199 200 return retval ; 201 }() ; 202 203 // Manages the throbber image that appears if the inner part of dialog is taking too long to load. 204 var Throbber = function() 205 { 206 var timer ; 207 208 var updateThrobber = function() 209 { 210 var throbberParent = $( 'throbberBlock' ) ; 211 var throbberBlocks = throbberParent.childNodes ; 212 var lastClass = throbberParent.lastChild.className ; 213 214 // From the last to the second one, copy the class from the previous one. 215 for ( var i = throbberBlocks.length - 1 ; i > 0 ; i-- ) 216 throbberBlocks[i].className = throbberBlocks[i-1].className ; 217 218 // For the first one, copy the last class (rotation). 219 throbberBlocks[0].className = lastClass ; 220 } 221 222 return { 223 Show : function( waitMilliseconds ) 224 { 225 // Auto-setup the Show function to be called again after the 226 // requested amount of time. 227 if ( waitMilliseconds && waitMilliseconds > 0 ) 228 { 229 timer = FCKTools.SetTimeout( this.Show, waitMilliseconds, this, null, window ) ; 230 return ; 231 } 232 233 var throbberParent = $( 'throbberBlock' ) ; 234 235 // Create the throbber blocks. 236 var classIds = [ 1,2,3,4,5,4,3,2 ] ; 237 while ( classIds.length > 0 ) 238 throbberParent.appendChild( document.createElement( 'div' ) ).className = ' throbber_' + classIds.shift() ; 239 240 // Center the throbber. 241 var frm = $( 'contents' ) ; 242 var frmCoords = FCKTools.GetDocumentPosition( window, frm ) ; 243 var x = frmCoords.x + ( frm.offsetWidth - throbberParent.offsetWidth ) / 2 ; 244 var y = frmCoords.y + ( frm.offsetHeight - throbberParent.offsetHeight ) / 2 ; 245 throbberParent.style.left = parseInt( x, 10 ) + 'px' ; 246 throbberParent.style.top = parseInt( y, 10 ) + 'px' ; 247 248 // Show it. 249 throbberParent.style.visibility = '' ; 250 251 // Setup the animation interval. 252 timer = setInterval( updateThrobber, 100 ) ; 253 }, 254 255 Hide : function() 256 { 257 if ( timer ) 258 { 259 clearInterval( timer ) ; 260 timer = null ; 261 } 262 263 var throbberParent = document.getElementById( 'throbberBlock' ) ; 264 if ( throbberParent ) 265 FCKDomTools.RemoveNode( throbberParent ) ; 266 } 267 } ; 268 }() ; 269 270 // Drag and drop handlers. 271 var DragAndDrop = function() 272 { 273 var registeredWindows = [] ; 274 var lastCoords ; 275 var currentPos ; 276 277 var cleanUpHandlers = function() 278 { 279 for ( var i = 0 ; i < registeredWindows.length ; i++ ) 280 { 281 FCKTools.RemoveEventListener( registeredWindows[i].document, 'mousemove', dragMouseMoveHandler ) ; 282 FCKTools.RemoveEventListener( registeredWindows[i].document, 'mouseup', dragMouseUpHandler ) ; 283 } 284 } 285 286 var dragMouseMoveHandler = function( evt ) 287 { 288 if ( !lastCoords ) 289 return ; 290 291 if ( !evt ) 292 evt = FCKTools.GetElementDocument( this ).parentWindow.event ; 293 294 // Updated the last coordinates. 295 var currentCoords = 296 { 297 x : evt.screenX, 298 y : evt.screenY 299 } ; 300 301 currentPos = 302 { 303 x : currentPos.x + ( currentCoords.x - lastCoords.x ), 304 y : currentPos.y + ( currentCoords.y - lastCoords.y ) 305 } ; 306 307 lastCoords = currentCoords ; 308 309 frameElement.style.left = currentPos.x + 'px' ; 310 frameElement.style.top = currentPos.y + 'px' ; 311 312 if ( evt.preventDefault ) 313 evt.preventDefault() ; 314 else 315 evt.returnValue = false ; 316 } 317 318 var dragMouseUpHandler = function( evt ) 319 { 320 if ( !lastCoords ) 321 return ; 322 if ( !evt ) 323 evt = FCKTools.GetElementDocument( this ).parentWindow.event ; 324 cleanUpHandlers() ; 325 lastCoords = null ; 326 } 327 328 return { 329 330 MouseDownHandler : function( evt ) 331 { 332 var view = null ; 333 if ( !evt ) 334 { 335 view = FCKTools.GetElementDocument( this ).parentWindow ; 336 evt = view.event ; 337 } 338 else 339 view = evt.view ; 340 341 var target = evt.srcElement || evt.target ; 342 if ( target.id == 'closeButton' || target.className == 'PopupTab' || target.className == 'PopupTabSelected' ) 343 return ; 344 345 lastCoords = 346 { 347 x : evt.screenX, 348 y : evt.screenY 349 } ; 350 351 // Save the current IFRAME position. 352 currentPos = 353 { 354 x : parseInt( FCKDomTools.GetCurrentElementStyle( frameElement, 'left' ), 10 ), 355 y : parseInt( FCKDomTools.GetCurrentElementStyle( frameElement, 'top' ), 10 ) 356 } ; 357 358 for ( var i = 0 ; i < registeredWindows.length ; i++ ) 359 { 360 FCKTools.AddEventListener( registeredWindows[i].document, 'mousemove', dragMouseMoveHandler ) ; 361 FCKTools.AddEventListener( registeredWindows[i].document, 'mouseup', dragMouseUpHandler ) ; 362 } 363 364 if ( evt.preventDefault ) 365 evt.preventDefault() ; 366 else 367 evt.returnValue = false ; 368 }, 369 370 RegisterHandlers : function( w ) 371 { 372 registeredWindows.push( w ) ; 373 } 374 } 375 }() ; 376 377 // Selection related functions. 378 //(Became simple shortcuts after the fix for #1990) 379 var Selection = 380 { 381 /** 382 * Ensures that the editing area contains an active selection. This is a 383 * requirement for IE, as it looses the selection when the focus moves to other 384 * frames. 385 */ 386 EnsureSelection : function() 387 { 388 FCK.Selection.Restore() ; 389 }, 390 391 /** 392 * Get the FCKSelection object for the editor instance. 393 */ 394 GetSelection : function() 395 { 396 return FCK.Selection ; 397 }, 398 399 /** 400 * Get the selected element in the editing area (for object selections). 401 */ 402 GetSelectedElement : function() 403 { 404 return FCK.Selection.GetSelectedElement() ; 405 } 406 } 407 408 // Tab related functions. 409 var Tabs = function() 410 { 411 // Only element ids should be stored here instead of element references since setSelectedTab and TabDiv_OnClick 412 // would build circular references with the element references inside and cause memory leaks in IE6. 413 var oTabs = new Object() ; 414 415 var setSelectedTab = function( tabCode ) 416 { 417 for ( var sCode in oTabs ) 418 { 419 if ( sCode == tabCode ) 420 $( oTabs[sCode] ).className = 'PopupTabSelected' ; 421 else 422 $( oTabs[sCode] ).className = 'PopupTab' ; 423 } 424 425 if ( typeof( window.frames["frmMain"].OnDialogTabChange ) == 'function' ) 426 window.frames["frmMain"].OnDialogTabChange( tabCode ) ; 427 } 428 429 function TabDiv_OnClick() 430 { 431 setSelectedTab( this.TabCode ) ; 432 } 433 434 window.AddTab = function( tabCode, tabText, startHidden ) 435 { 436 if ( typeof( oTabs[ tabCode ] ) != 'undefined' ) 437 return ; 438 439 var eTabsRow = $( 'Tabs' ) ; 440 441 var oCell = eTabsRow.insertCell( eTabsRow.cells.length - 1 ) ; 442 oCell.noWrap = true ; 443 444 var oDiv = document.createElement( 'DIV' ) ; 445 oDiv.className = 'PopupTab' ; 446 oDiv.innerHTML = tabText ; 447 oDiv.TabCode = tabCode ; 448 oDiv.onclick = TabDiv_OnClick ; 449 oDiv.id = Math.random() ; 450 451 if ( startHidden ) 452 oDiv.style.display = 'none' ; 453 454 eTabsRow = $( 'TabsRow' ) ; 455 456 oCell.appendChild( oDiv ) ; 457 458 if ( eTabsRow.style.display == 'none' ) 459 { 460 var eTitleArea = $( 'TitleArea' ) ; 461 eTitleArea.className = 'PopupTitle' ; 462 463 oDiv.className = 'PopupTabSelected' ; 464 eTabsRow.style.display = '' ; 465 466 if ( window.onresize ) 467 window.onresize() ; 468 } 469 470 oTabs[ tabCode ] = oDiv.id ; 471 472 FCKTools.DisableSelection( oDiv ) ; 473 } ; 474 475 window.SetSelectedTab = setSelectedTab ; 476 477 window.SetTabVisibility = function( tabCode, isVisible ) 478 { 479 var oTab = $( oTabs[ tabCode ] ) ; 480 oTab.style.display = isVisible ? '' : 'none' ; 481 482 if ( ! isVisible && oTab.className == 'PopupTabSelected' ) 483 { 484 for ( var sCode in oTabs ) 485 { 486 if ( $( oTabs[sCode] ).style.display != 'none' ) 487 { 488 setSelectedTab( sCode ) ; 489 break ; 490 } 491 } 492 } 493 } ; 494 }() ; 495 496 // readystatechange handler for registering drag and drop handlers in cover 497 // iframes, defined out here to avoid memory leak. 498 // Do NOT put this function as a private function as it will induce memory leak 499 // in IE and it's not detectable with Drip or sIEve and undetectable leaks are 500 // really nasty (sigh). 501 var onReadyRegister = function() 502 { 503 if ( this.readyState != 'complete' ) 504 return ; 505 DragAndDrop.RegisterHandlers( this.contentWindow ) ; 506 } ; 507 508 // The business logic of the dialog, dealing with operational things like 509 // dialog open/dialog close/enable/disable/etc. 510 (function() 511 { 512 var setOnKeyDown = function( targetDocument ) 513 { 514 targetDocument.onkeydown = function ( e ) 515 { 516 e = e || event || this.parentWindow.event ; 517 switch ( e.keyCode ) 518 { 519 case 13 : // ENTER 520 var oTarget = e.srcElement || e.target ; 521 if ( oTarget.tagName == 'TEXTAREA' ) 522 return true ; 523 Ok() ; 524 return false ; 525 526 case 27 : // ESC 527 Cancel() ; 528 return false ; 529 } 530 return true ; 531 } 532 } ; 533 534 var contextMenuBlocker = function( e ) 535 { 536 var sTagName = e.target.tagName ; 537 if ( ! ( ( sTagName == "INPUT" && e.target.type == "text" ) || sTagName == "TEXTAREA" ) ) 538 e.preventDefault() ; 539 } ; 540 541 var disableContextMenu = function( targetDocument ) 542 { 543 if ( FCKBrowserInfo.IsIE ) 544 return ; 545 546 targetDocument.addEventListener( 'contextmenu', contextMenuBlocker, true ) ; 547 } ; 548 549 // Program entry point. 550 window.Init = function() 551 { 552 // Start the throbber timer. 553 Throbber.Show( 1000 ) ; 554 555 Sizer.RefreshContainerSize() ; 556 LoadInnerDialog() ; 557 558 FCKTools.DisableSelection( document.body ) ; 559 560 // Make the title area draggable. 561 var titleElement = $( 'header' ) ; 562 titleElement.onmousedown = DragAndDrop.MouseDownHandler ; 563 564 // Connect mousemove and mouseup events from dialog frame and outer window to dialog dragging logic. 565 DragAndDrop.RegisterHandlers( window ) ; 566 DragAndDrop.RegisterHandlers( Args().TopWindow ) ; 567 568 // Disable the previous dialog if it exists. 569 if ( ParentDialog() ) 570 { 571 ParentDialog().contentWindow.SetEnabled( false ) ; 572 if ( FCKBrowserInfo.IsIE && !FCKBrowserInfo.IsIE7 ) 573 { 574 var currentParent = ParentDialog() ; 575 while ( currentParent ) 576 { 577 var blockerFrame = currentParent.contentWindow.$( 'blocker' ) ; 578 if ( blockerFrame.readyState == 'complete' ) 579 DragAndDrop.RegisterHandlers( blockerFrame.contentWindow ) ; 580 else 581 blockerFrame.onreadystatechange = onReadyRegister ; 582 currentParent = ParentDialog( currentParent ) ; 583 } 584 } 585 else 586 { 587 var currentParent = ParentDialog() ; 588 while ( currentParent ) 589 { 590 DragAndDrop.RegisterHandlers( currentParent.contentWindow ) ; 591 currentParent = ParentDialog( currentParent ) ; 592 } 593 } 594 } 595 596 // If this is the only dialog on screen, enable the background cover. 597 if ( FCKBrowserInfo.IsIE && !FCKBrowserInfo.IsIE7 ) 598 { 599 var blockerFrame = FCKDialog.GetCover().firstChild ; 600 if ( blockerFrame.readyState == 'complete' ) 601 DragAndDrop.RegisterHandlers( blockerFrame.contentWindow ) ; 602 else 603 blockerFrame.onreadystatechange = onReadyRegister; 604 } 605 606 // Add Enter/Esc hotkeys and disable context menu for the dialog. 607 setOnKeyDown( document ) ; 608 disableContextMenu( document ) ; 609 } ; 610 611 window.LoadInnerDialog = function() 612 { 613 if ( window.onresize ) 614 window.onresize() ; 615 616 // First of all, translate the dialog box contents. 617 E.FCKLanguageManager.TranslatePage( document ) ; 618 619 // Create the IFRAME that holds the dialog contents. 620 $( 'innerContents' ).innerHTML = '<iframe id="frmMain" src="' + Args().Page + '" name="frmMain" frameborder="0" width="100%" height="100%" scrolling="auto" style="visibility: hidden;" allowtransparency="true"></iframe>' ; 621 } ; 622 623 window.InnerDialogLoaded = function() 624 { 625 // If the dialog has been closed before the iframe is loaded, do nothing. 626 if ( !frameElement.parentNode ) 627 return null ; 628 629 Throbber.Hide() ; 630 631 var frmMain = $('frmMain') ; 632 var innerWindow = frmMain.contentWindow ; 633 var innerDoc = innerWindow.document ; 634 635 // Show the loaded iframe. 636 frmMain.style.visibility = '' ; 637 638 // Set the language direction. 639 innerDoc.documentElement.dir = langDir ; 640 641 // Sets the Skin CSS. 642 innerDoc.write( FCKTools.GetStyleHtml( FCKConfig.SkinDialogCSS ) ) ; 643 644 setOnKeyDown( innerDoc ) ; 645 disableContextMenu( innerDoc ) ; 646 647 Sizer.RefreshContainerSize(); 648 649 DragAndDrop.RegisterHandlers( innerWindow ) ; 650 651 innerWindow.focus() ; 652 653 return E ; 654 } ; 655 656 window.SetOkButton = function( showIt ) 657 { 658 $('btnOk').style.visibility = ( showIt ? '' : 'hidden' ) ; 659 } ; 660 661 window.Ok = function() 662 { 663 Selection.EnsureSelection() ; 664 665 var frmMain = window.frames["frmMain"] ; 666 667 if ( frmMain.Ok && frmMain.Ok() ) 668 CloseDialog() ; 669 else 670 frmMain.focus() ; 671 } ; 672 673 window.Cancel = function( dontFireChange ) 674 { 675 Selection.EnsureSelection() ; 676 return CloseDialog( dontFireChange ) ; 677 } ; 678 679 window.CloseDialog = function( dontFireChange ) 680 { 681 Throbber.Hide() ; 682 683 // Points the src to a non-existent location to avoid loading errors later, in case the dialog 684 // haven't been completed loaded at this point. 685 if ( $( 'frmMain' ) ) 686 $( 'frmMain' ).src = FCKTools.GetVoidUrl() ; 687 688 if ( !dontFireChange && !FCK.EditMode ) 689 { 690 // All dialog windows, by default, will fire the "OnSelectionChange" 691 // event, no matter the Ok or Cancel button has been pressed. 692 // It seems that OnSelectionChange may enter on a concurrency state 693 // on some situations (#1965), so we should put the event firing in 694 // the execution queue instead of executing it immediately. 695 setTimeout( function() 696 { 697 FCK.Events.FireEvent( 'OnSelectionChange' ) ; 698 }, 0 ) ; 699 } 700 701 FCKDialog.OnDialogClose( window ) ; 702 } ; 703 704 window.SetEnabled = function( isEnabled ) 705 { 706 var cover = $( 'cover' ) ; 707 cover.style.display = isEnabled ? 'none' : '' ; 708 709 if ( FCKBrowserInfo.IsIE && !FCKBrowserInfo.IsIE7 ) 710 { 711 if ( !isEnabled ) 712 { 713 // Inser the blocker IFRAME before the cover. 714 var blocker = document.createElement( 'iframe' ) ; 715 blocker.src = FCKTools.GetVoidUrl() ; 716 blocker.hideFocus = true ; 717 blocker.frameBorder = 0 ; 718 blocker.id = blocker.className = 'blocker' ; 719 cover.appendChild( blocker ) ; 720 } 721 else 722 { 723 var blocker = $( 'blocker' ) ; 724 if ( blocker && blocker.parentNode ) 725 blocker.parentNode.removeChild( blocker ) ; 726 } 727 } 728 } ; 729 })() ; 730 </script> 29 <script src="js/fckdialog.js" type="text/javascript"></script> 731 30 </head> 732 31 <body onload="Init();" class="PopupBody"> 733 32 <div class="contents" id="contents"> -
editor/filemanager/browser/default/frmfolders.html
27 27 <link href="browser.css" type="text/css" rel="stylesheet"> 28 28 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 29 29 <script type="text/javascript" src="js/common.js"></script> 30 <script language="javascript"> 31 32 var sActiveFolder ; 33 34 var bIsLoaded = false ; 35 var iIntervalId ; 36 37 var oListManager = new Object() ; 38 39 oListManager.Init = function() 40 { 41 this.Table = document.getElementById('tableFiles') ; 42 this.UpRow = document.getElementById('trUp') ; 43 44 this.TableRows = new Object() ; 45 } 46 47 oListManager.Clear = function() 48 { 49 // Remove all other rows available. 50 while ( this.Table.rows.length > 1 ) 51 this.Table.deleteRow(1) ; 52 53 // Reset the TableRows collection. 54 this.TableRows = new Object() ; 55 } 56 57 oListManager.AddItem = function( folderName, folderPath ) 58 { 59 // Create the new row. 60 var oRow = this.Table.insertRow(-1) ; 61 oRow.className = 'FolderListFolder' ; 62 63 // Build the link to view the folder. 64 var sLink = '<a href="#" onclick="OpenFolder(\'' + folderPath + '\');return false;">' ; 65 66 // Add the folder icon cell. 67 var oCell = oRow.insertCell(-1) ; 68 oCell.width = 16 ; 69 oCell.innerHTML = sLink + '<img alt="" src="images/spacer.gif" width="16" height="16" border="0"></a>' ; 70 71 // Add the folder name cell. 72 oCell = oRow.insertCell(-1) ; 73 oCell.noWrap = true ; 74 oCell.innerHTML = ' ' + sLink + folderName + '</a>' ; 75 76 this.TableRows[ folderPath ] = oRow ; 77 } 78 79 oListManager.ShowUpFolder = function( upFolderPath ) 80 { 81 this.UpRow.style.display = ( upFolderPath != null ? '' : 'none' ) ; 82 83 if ( upFolderPath != null ) 84 { 85 document.getElementById('linkUpIcon').onclick = document.getElementById('linkUp').onclick = function() 86 { 87 LoadFolders( upFolderPath ) ; 88 return false ; 89 } 90 } 91 } 92 93 function CheckLoaded() 94 { 95 if ( window.top.IsLoadedActualFolder 96 && window.top.IsLoadedCreateFolder 97 && window.top.IsLoadedUpload 98 && window.top.IsLoadedResourcesList ) 99 { 100 window.clearInterval( iIntervalId ) ; 101 bIsLoaded = true ; 102 OpenFolder( sActiveFolder ) ; 103 } 104 } 105 106 function OpenFolder( folderPath ) 107 { 108 sActiveFolder = folderPath ; 109 110 if ( ! bIsLoaded ) 111 { 112 if ( ! iIntervalId ) 113 iIntervalId = window.setInterval( CheckLoaded, 100 ) ; 114 return ; 115 } 116 117 // Change the style for the select row (to show the opened folder). 118 for ( var sFolderPath in oListManager.TableRows ) 119 { 120 oListManager.TableRows[ sFolderPath ].className = 121 ( sFolderPath == folderPath ? 'FolderListCurrentFolder' : 'FolderListFolder' ) ; 122 } 123 124 // Set the current folder in all frames. 125 window.parent.frames['frmActualFolder'].SetCurrentFolder( oConnector.ResourceType, folderPath ) ; 126 window.parent.frames['frmCreateFolder'].SetCurrentFolder( oConnector.ResourceType, folderPath ) ; 127 window.parent.frames['frmUpload'].SetCurrentFolder( oConnector.ResourceType, folderPath ) ; 128 129 // Load the resources list for this folder. 130 window.parent.frames['frmResourcesList'].LoadResources( oConnector.ResourceType, folderPath ) ; 131 } 132 133 function LoadFolders( folderPath ) 134 { 135 // Clear the folders list. 136 oListManager.Clear() ; 137 138 // Get the parent folder path. 139 var sParentFolderPath ; 140 if ( folderPath != '/' ) 141 sParentFolderPath = folderPath.substring( 0, folderPath.lastIndexOf( '/', folderPath.length - 2 ) + 1 ) ; 142 143 // Show/Hide the Up Folder. 144 oListManager.ShowUpFolder( sParentFolderPath ) ; 145 146 if ( folderPath != '/' ) 147 { 148 sActiveFolder = folderPath ; 149 oConnector.CurrentFolder = sParentFolderPath ; 150 oConnector.SendCommand( 'GetFolders', null, GetFoldersCallBack ) ; 151 } 152 else 153 OpenFolder( '/' ) ; 154 } 155 156 function GetFoldersCallBack( fckXml ) 157 { 158 if ( oConnector.CheckError( fckXml ) != 0 ) 159 return ; 160 161 // Get the current folder path. 162 var oNode = fckXml.SelectSingleNode( 'Connector/CurrentFolder' ) ; 163 var sCurrentFolderPath = oNode.attributes.getNamedItem('path').value ; 164 165 var oNodes = fckXml.SelectNodes( 'Connector/Folders/Folder' ) ; 166 167 for ( var i = 0 ; i < oNodes.length ; i++ ) 168 { 169 var sFolderName = oNodes[i].attributes.getNamedItem('name').value ; 170 oListManager.AddItem( sFolderName, sCurrentFolderPath + sFolderName + '/' ) ; 171 } 172 173 OpenFolder( sActiveFolder ) ; 174 } 175 176 function SetResourceType( type ) 177 { 178 oConnector.ResourceType = type ; 179 LoadFolders( '/' ) ; 180 } 181 182 window.onload = function() 183 { 184 oListManager.Init() ; 185 LoadFolders( '/' ) ; 186 } 187 </script> 30 <script type="text/javascript" src="js/frmfolders.js"></script> 188 31 </head> 189 32 <body class="FileArea" bottomMargin="10" leftMargin="10" topMargin="10" rightMargin="10"> 190 33 <table id="tableFiles" cellSpacing="0" cellPadding="0" width="100%" border="0"> -
editor/filemanager/browser/default/js/frmfolders.js
1 /* 2 * FCKeditor - The text editor for Internet - http://www.fckeditor.net 3 * Copyright (C) 2003-2008 Frederico Caldeira Knabben 4 * 5 * == BEGIN LICENSE == 6 * 7 * Licensed under the terms of any of the following licenses at your 8 * choice: 9 * 10 * - GNU General Public License Version 2 or later (the "GPL") 11 * http://www.gnu.org/licenses/gpl.html 12 * 13 * - GNU Lesser General Public License Version 2.1 or later (the "LGPL") 14 * http://www.gnu.org/licenses/lgpl.html 15 * 16 * - Mozilla Public License Version 1.1 or later (the "MPL") 17 * http://www.mozilla.org/MPL/MPL-1.1.html 18 * 19 * == END LICENSE == 20 */ 21 22 var sActiveFolder ; 23 24 var bIsLoaded = false ; 25 var iIntervalId ; 26 27 var oListManager = new Object() ; 28 29 oListManager.Init = function() 30 { 31 this.Table = document.getElementById('tableFiles') ; 32 this.UpRow = document.getElementById('trUp') ; 33 34 this.TableRows = new Object() ; 35 } 36 37 oListManager.Clear = function() 38 { 39 // Remove all other rows available. 40 while ( this.Table.rows.length > 1 ) 41 this.Table.deleteRow(1) ; 42 43 // Reset the TableRows collection. 44 this.TableRows = new Object() ; 45 } 46 47 oListManager.AddItem = function( folderName, folderPath ) 48 { 49 // Create the new row. 50 var oRow = this.Table.insertRow(-1) ; 51 oRow.className = 'FolderListFolder' ; 52 53 // Build the link to view the folder. 54 var sLink = '<a href="#" onclick="OpenFolder(\'' + folderPath + '\');return false;">' ; 55 56 // Add the folder icon cell. 57 var oCell = oRow.insertCell(-1) ; 58 oCell.width = 16 ; 59 oCell.innerHTML = sLink + '<img alt="" src="images/spacer.gif" width="16" height="16" border="0"></a>' ; 60 61 // Add the folder name cell. 62 oCell = oRow.insertCell(-1) ; 63 oCell.noWrap = true ; 64 oCell.innerHTML = ' ' + sLink + folderName + '</a>' ; 65 66 this.TableRows[ folderPath ] = oRow ; 67 } 68 69 oListManager.ShowUpFolder = function( upFolderPath ) 70 { 71 this.UpRow.style.display = ( upFolderPath != null ? '' : 'none' ) ; 72 73 if ( upFolderPath != null ) 74 { 75 document.getElementById('linkUpIcon').onclick = document.getElementById('linkUp').onclick = function() 76 { 77 LoadFolders( upFolderPath ) ; 78 return false ; 79 } 80 } 81 } 82 83 function CheckLoaded() 84 { 85 if ( window.top.IsLoadedActualFolder 86 && window.top.IsLoadedCreateFolder 87 && window.top.IsLoadedUpload 88 && window.top.IsLoadedResourcesList ) 89 { 90 window.clearInterval( iIntervalId ) ; 91 bIsLoaded = true ; 92 OpenFolder( sActiveFolder ) ; 93 } 94 } 95 96 function OpenFolder( folderPath ) 97 { 98 sActiveFolder = folderPath ; 99 100 if ( ! bIsLoaded ) 101 { 102 if ( ! iIntervalId ) 103 iIntervalId = window.setInterval( CheckLoaded, 100 ) ; 104 return ; 105 } 106 107 // Change the style for the select row (to show the opened folder). 108 for ( var sFolderPath in oListManager.TableRows ) 109 { 110 oListManager.TableRows[ sFolderPath ].className = 111 ( sFolderPath == folderPath ? 'FolderListCurrentFolder' : 'FolderListFolder' ) ; 112 } 113 114 // Set the current folder in all frames. 115 window.parent.frames['frmActualFolder'].SetCurrentFolder( oConnector.ResourceType, folderPath ) ; 116 window.parent.frames['frmCreateFolder'].SetCurrentFolder( oConnector.ResourceType, folderPath ) ; 117 window.parent.frames['frmUpload'].SetCurrentFolder( oConnector.ResourceType, folderPath ) ; 118 119 // Load the resources list for this folder. 120 window.parent.frames['frmResourcesList'].LoadResources( oConnector.ResourceType, folderPath ) ; 121 } 122 123 function LoadFolders( folderPath ) 124 { 125 // Clear the folders list. 126 oListManager.Clear() ; 127 128 // Get the parent folder path. 129 var sParentFolderPath ; 130 if ( folderPath != '/' ) 131 sParentFolderPath = folderPath.substring( 0, folderPath.lastIndexOf( '/', folderPath.length - 2 ) + 1 ) ; 132 133 // Show/Hide the Up Folder. 134 oListManager.ShowUpFolder( sParentFolderPath ) ; 135 136 if ( folderPath != '/' ) 137 { 138 sActiveFolder = folderPath ; 139 oConnector.CurrentFolder = sParentFolderPath ; 140 oConnector.SendCommand( 'GetFolders', null, GetFoldersCallBack ) ; 141 } 142 else 143 OpenFolder( '/' ) ; 144 } 145 146 function GetFoldersCallBack( fckXml ) 147 { 148 if ( oConnector.CheckError( fckXml ) != 0 ) 149 return ; 150 151 // Get the current folder path. 152 var oNode = fckXml.SelectSingleNode( 'Connector/CurrentFolder' ) ; 153 var sCurrentFolderPath = oNode.attributes.getNamedItem('path').value ; 154 155 var oNodes = fckXml.SelectNodes( 'Connector/Folders/Folder' ) ; 156 157 for ( var i = 0 ; i < oNodes.length ; i++ ) 158 { 159 var sFolderName = oNodes[i].attributes.getNamedItem('name').value ; 160 oListManager.AddItem( sFolderName, sCurrentFolderPath + sFolderName + '/' ) ; 161 } 162 163 OpenFolder( sActiveFolder ) ; 164 } 165 166 function SetResourceType( type ) 167 { 168 oConnector.ResourceType = type ; 169 LoadFolders( '/' ) ; 170 } 171 172 window.onload = function() 173 { 174 oListManager.Init() ; 175 LoadFolders( '/' ) ; 176 } -
editor/js/fckdialog.js
1 /* 2 * FCKeditor - The text editor for Internet - http://www.fckeditor.net 3 * Copyright (C) 2003-2008 Frederico Caldeira Knabben 4 * 5 * == BEGIN LICENSE == 6 * 7 * Licensed under the terms of any of the following licenses at your 8 * choice: 9 * 10 * - GNU General Public License Version 2 or later (the "GPL") 11 * http://www.gnu.org/licenses/gpl.html 12 * 13 * - GNU Lesser General Public License Version 2.1 or later (the "LGPL") 14 * http://www.gnu.org/licenses/lgpl.html 15 * 16 * - Mozilla Public License Version 1.1 or later (the "MPL") 17 * http://www.mozilla.org/MPL/MPL-1.1.html 18 * 19 * == END LICENSE == 20 */ 21 22 // Domain relaxation logic. 23 (function() 24 { 25 var d = document.domain ; 26 27 while ( true ) 28 { 29 // Test if we can access a parent property. 30 try 31 { 32 var parentDomain = ( Args().TopWindow || E ).document.domain ; 33 34 if ( document.domain != parentDomain ) 35 document.domain = parentDomain ; 36 37 break ; 38 } 39 catch( e ) {} 40 41 // Remove a domain part: www.mytest.example.com => mytest.example.com => example.com ... 42 d = d.replace( /.*?(?:\.|$)/, '' ) ; 43 44 if ( d.length == 0 ) 45 break ; // It was not able to detect the domain. 46 47 document.domain = d ; 48 } 49 })() ; 50 51 var E = frameElement._DialogArguments.Editor ; 52 53 // It seems referencing to frameElement._DialogArguments directly would lead to memory leaks in IE. 54 // So let's use functions to access its members instead. 55 function Args() 56 { 57 return frameElement._DialogArguments ; 58 } 59 60 function ParentDialog( dialog ) 61 { 62 return dialog ? dialog._ParentDialog : frameElement._ParentDialog ; 63 } 64 65 var FCK = E.FCK ; 66 var FCKTools = E.FCKTools ; 67 var FCKDomTools = E.FCKDomTools ; 68 var FCKDialog = E.FCKDialog ; 69 var FCKBrowserInfo = E.FCKBrowserInfo ; 70 var FCKConfig = E.FCKConfig ; 71 72 // Steal the focus so that the caret would no longer stay in the editor iframe. 73 window.focus() ; 74 75 // Sets the Skin CSS 76 document.write( FCKTools.GetStyleHtml( FCKConfig.SkinDialogCSS ) ) ; 77 78 // Sets the language direction. 79 var langDir = document.documentElement.dir = E.FCKLang.Dir ; 80 81 // For IE6-, the fck_dialog_ie6.js is loaded, used to fix limitations in the browser. 82 if ( FCKBrowserInfo.IsIE && !FCKBrowserInfo.IsIE7 ) 83 document.write( '<' + 'script type="text/javascript" src="' + FCKConfig.SkinPath + 'fck_dialog_ie6.js"><' + '\/script>' ) ; 84 85 FCKTools.RegisterDollarFunction( window ) ; 86 87 // Resize related functions. 88 var Sizer = function() 89 { 90 var bAutoSize = false ; 91 92 var retval = { 93 // Sets whether the dialog should auto-resize according to its content's height. 94 SetAutoSize : function( autoSize ) 95 { 96 bAutoSize = autoSize ; 97 this.RefreshSize() ; 98 }, 99 100 // Fit the dialog container's layout to the inner iframe's external size. 101 RefreshContainerSize : function() 102 { 103 var frmMain = $( 'frmMain' ) ; 104 105 if ( frmMain ) 106 { 107 // Get the container size. 108 var height = $( 'contents' ).offsetHeight ; 109 110 // Subtract the size of other elements. 111 height -= $( 'TitleArea' ).offsetHeight ; 112 height -= $( 'TabsRow' ).offsetHeight ; 113 height -= $( 'PopupButtons' ).offsetHeight ; 114 115 frmMain.style.height = Math.max( height, 0 ) + 'px' ; 116 } 117 }, 118 119 // Resize and re-layout the dialog. 120 // Triggers the onresize event for the layout logic. 121 ResizeDialog : function( width, height ) 122 { 123 FCKDomTools.SetElementStyles( window.frameElement, 124 { 125 'width' : width + 'px', 126 'height' : height + 'px' 127 } ) ; 128 129 // If the skin have defined a function for resize fixes, call it now. 130 if ( typeof window.DoResizeFixes == 'function' ) 131 window.DoResizeFixes() ; 132 }, 133 134 // if bAutoSize is true, automatically fit the dialog size and layout to 135 // accomodate the inner iframe's internal height. 136 // if bAutoSize is false, then only the layout logic for the dialog decorations 137 // is run to accomodate the inner iframe's external height. 138 RefreshSize : function() 139 { 140 if ( bAutoSize ) 141 { 142 var frmMain = $( 'frmMain' ) ; 143 var innerDoc = frmMain.contentWindow.document ; 144 var isStrict = FCKTools.IsStrictMode( innerDoc ) ; 145 146 // Get the size of the frame contents. 147 var innerWidth = isStrict ? innerDoc.documentElement.scrollWidth : innerDoc.body.scrollWidth ; 148 var innerHeight = isStrict ? innerDoc.documentElement.scrollHeight : innerDoc.body.scrollHeight ; 149 150 // Get the current frame size. 151 var frameSize = FCKTools.GetViewPaneSize( frmMain.contentWindow ) ; 152 153 var deltaWidth = innerWidth - frameSize.Width ; 154 var deltaHeight = innerHeight - frameSize.Height ; 155 156 // If the contents fits the current size. 157 if ( deltaWidth <= 0 && deltaHeight <= 0 ) 158 return ; 159 160 var dialogWidth = frameElement.offsetWidth + Math.max( deltaWidth, 0 ) ; 161 var dialogHeight = frameElement.offsetHeight + Math.max( deltaHeight, 0 ) ; 162 163 this.ResizeDialog( dialogWidth, dialogHeight ) ; 164 } 165 this.RefreshContainerSize() ; 166 } 167 } 168 169 /** 170 * Safari seems to have a bug with the time when RefreshSize() is executed - it 171 * thinks frmMain's innerHeight is 0 if we query the value too soon after the 172 * page is loaded in some circumstances. (#1316) 173 * TODO : Maybe this is not needed anymore after #35. 174 */ 175 if ( FCKBrowserInfo.IsSafari ) 176 { 177 var originalRefreshSize = retval.RefreshSize ; 178 179 retval.RefreshSize = function() 180 { 181 FCKTools.SetTimeout( originalRefreshSize, 1, retval ) ; 182 } 183 } 184 185 window.onresize = function() 186 { 187 retval.RefreshContainerSize() ; 188 } 189 190 window.SetAutoSize = FCKTools.Bind( retval, retval.SetAutoSize ) ; 191 192 return retval ; 193 }() ; 194 195 // Manages the throbber image that appears if the inner part of dialog is taking too long to load. 196 var Throbber = function() 197 { 198 var timer ; 199 200 var updateThrobber = function() 201 { 202 var throbberParent = $( 'throbberBlock' ) ; 203 var throbberBlocks = throbberParent.childNodes ; 204 var lastClass = throbberParent.lastChild.className ; 205 206 // From the last to the second one, copy the class from the previous one. 207 for ( var i = throbberBlocks.length - 1 ; i > 0 ; i-- ) 208 throbberBlocks[i].className = throbberBlocks[i-1].className ; 209 210 // For the first one, copy the last class (rotation). 211 throbberBlocks[0].className = lastClass ; 212 } 213 214 return { 215 Show : function( waitMilliseconds ) 216 { 217 // Auto-setup the Show function to be called again after the 218 // requested amount of time. 219 if ( waitMilliseconds && waitMilliseconds > 0 ) 220 { 221 timer = FCKTools.SetTimeout( this.Show, waitMilliseconds, this, null, window ) ; 222 return ; 223 } 224 225 var throbberParent = $( 'throbberBlock' ) ; 226 227 // Create the throbber blocks. 228 var classIds = [ 1,2,3,4,5,4,3,2 ] ; 229 while ( classIds.length > 0 ) 230 throbberParent.appendChild( document.createElement( 'div' ) ).className = ' throbber_' + classIds.shift() ; 231 232 // Center the throbber. 233 var frm = $( 'contents' ) ; 234 var frmCoords = FCKTools.GetDocumentPosition( window, frm ) ; 235 var x = frmCoords.x + ( frm.offsetWidth - throbberParent.offsetWidth ) / 2 ; 236 var y = frmCoords.y + ( frm.offsetHeight - throbberParent.offsetHeight ) / 2 ; 237 throbberParent.style.left = parseInt( x, 10 ) + 'px' ; 238 throbberParent.style.top = parseInt( y, 10 ) + 'px' ; 239 240 // Show it. 241 throbberParent.style.visibility = '' ; 242 243 // Setup the animation interval. 244 timer = setInterval( updateThrobber, 100 ) ; 245 }, 246 247 Hide : function() 248 { 249 if ( timer ) 250 { 251 clearInterval( timer ) ; 252 timer = null ; 253 } 254 255 var throbberParent = document.getElementById( 'throbberBlock' ) ; 256 if ( throbberParent ) 257 FCKDomTools.RemoveNode( throbberParent ) ; 258 } 259 } ; 260 }() ; 261 262 // Drag and drop handlers. 263 var DragAndDrop = function() 264 { 265 var registeredWindows = [] ; 266 var lastCoords ; 267 var currentPos ; 268 269 var cleanUpHandlers = function() 270 { 271 for ( var i = 0 ; i < registeredWindows.length ; i++ ) 272 { 273 FCKTools.RemoveEventListener( registeredWindows[i].document, 'mousemove', dragMouseMoveHandler ) ; 274 FCKTools.RemoveEventListener( registeredWindows[i].document, 'mouseup', dragMouseUpHandler ) ; 275 } 276 } 277 278 var dragMouseMoveHandler = function( evt ) 279 { 280 if ( !lastCoords ) 281 return ; 282 283 if ( !evt ) 284 evt = FCKTools.GetElementDocument( this ).parentWindow.event ; 285 286 // Updated the last coordinates. 287 var currentCoords = 288 { 289 x : evt.screenX, 290 y : evt.screenY 291 } ; 292 293 currentPos = 294 { 295 x : currentPos.x + ( currentCoords.x - lastCoords.x ), 296 y : currentPos.y + ( currentCoords.y - lastCoords.y ) 297 } ; 298 299 lastCoords = currentCoords ; 300 301 frameElement.style.left = currentPos.x + 'px' ; 302 frameElement.style.top = currentPos.y + 'px' ; 303 304 if ( evt.preventDefault ) 305 evt.preventDefault() ; 306 else 307 evt.returnValue = false ; 308 } 309 310 var dragMouseUpHandler = function( evt ) 311 { 312 if ( !lastCoords ) 313 return ; 314 if ( !evt ) 315 evt = FCKTools.GetElementDocument( this ).parentWindow.event ; 316 cleanUpHandlers() ; 317 lastCoords = null ; 318 } 319 320 return { 321 322 MouseDownHandler : function( evt ) 323 { 324 var view = null ; 325 if ( !evt ) 326 { 327 view = FCKTools.GetElementDocument( this ).parentWindow ; 328 evt = view.event ; 329 } 330 else 331 view = evt.view ; 332 333 var target = evt.srcElement || evt.target ; 334 if ( target.id == 'closeButton' || target.className == 'PopupTab' || target.className == 'PopupTabSelected' ) 335 return ; 336 337 lastCoords = 338 { 339 x : evt.screenX, 340 y : evt.screenY 341 } ; 342 343 // Save the current IFRAME position. 344 currentPos = 345 { 346 x : parseInt( FCKDomTools.GetCurrentElementStyle( frameElement, 'left' ), 10 ), 347 y : parseInt( FCKDomTools.GetCurrentElementStyle( frameElement, 'top' ), 10 ) 348 } ; 349 350 for ( var i = 0 ; i < registeredWindows.length ; i++ ) 351 { 352 FCKTools.AddEventListener( registeredWindows[i].document, 'mousemove', dragMouseMoveHandler ) ; 353 FCKTools.AddEventListener( registeredWindows[i].document, 'mouseup', dragMouseUpHandler ) ; 354 } 355 356 if ( evt.preventDefault ) 357 evt.preventDefault() ; 358 else 359 evt.returnValue = false ; 360 }, 361 362 RegisterHandlers : function( w ) 363 { 364 registeredWindows.push( w ) ; 365 } 366 } 367 }() ; 368 369 // Selection related functions. 370 //(Became simple shortcuts after the fix for #1990) 371 var Selection = 372 { 373 /** 374 * Ensures that the editing area contains an active selection. This is a 375 * requirement for IE, as it looses the selection when the focus moves to other 376 * frames. 377 */ 378 EnsureSelection : function() 379 { 380 FCK.Selection.Restore() ; 381 }, 382 383 /** 384 * Get the FCKSelection object for the editor instance. 385 */ 386 GetSelection : function() 387 { 388 return FCK.Selection ; 389 }, 390 391 /** 392 * Get the selected element in the editing area (for object selections). 393 */ 394 GetSelectedElement : function() 395 { 396 return FCK.Selection.GetSelectedElement() ; 397 } 398 } 399 400 // Tab related functions. 401 var Tabs = function() 402 { 403 // Only element ids should be stored here instead of element references since setSelectedTab and TabDiv_OnClick 404 // would build circular references with the element references inside and cause memory leaks in IE6. 405 var oTabs = new Object() ; 406 407 var setSelectedTab = function( tabCode ) 408 { 409 for ( var sCode in oTabs ) 410 { 411 if ( sCode == tabCode ) 412 $( oTabs[sCode] ).className = 'PopupTabSelected' ; 413 else 414 $( oTabs[sCode] ).className = 'PopupTab' ; 415 } 416 417 if ( typeof( window.frames["frmMain"].OnDialogTabChange ) == 'function' ) 418 window.frames["frmMain"].OnDialogTabChange( tabCode ) ; 419 } 420 421 function TabDiv_OnClick() 422 { 423 setSelectedTab( this.TabCode ) ; 424 } 425 426 window.AddTab = function( tabCode, tabText, startHidden ) 427 { 428 if ( typeof( oTabs[ tabCode ] ) != 'undefined' ) 429 return ; 430 431 var eTabsRow = $( 'Tabs' ) ; 432 433 var oCell = eTabsRow.insertCell( eTabsRow.cells.length - 1 ) ; 434 oCell.noWrap = true ; 435 436 var oDiv = document.createElement( 'DIV' ) ; 437 oDiv.className = 'PopupTab' ; 438 oDiv.innerHTML = tabText ; 439 oDiv.TabCode = tabCode ; 440 oDiv.onclick = TabDiv_OnClick ; 441 oDiv.id = Math.random() ; 442 443 if ( startHidden ) 444 oDiv.style.display = 'none' ; 445 446 eTabsRow = $( 'TabsRow' ) ; 447 448 oCell.appendChild( oDiv ) ; 449 450 if ( eTabsRow.style.display == 'none' ) 451 { 452 var eTitleArea = $( 'TitleArea' ) ; 453 eTitleArea.className = 'PopupTitle' ; 454 455 oDiv.className = 'PopupTabSelected' ; 456 eTabsRow.style.display = '' ; 457 458 if ( window.onresize ) 459 window.onresize() ; 460 } 461 462 oTabs[ tabCode ] = oDiv.id ; 463 464 FCKTools.DisableSelection( oDiv ) ; 465 } ; 466 467 window.SetSelectedTab = setSelectedTab ; 468 469 window.SetTabVisibility = function( tabCode, isVisible ) 470 { 471 var oTab = $( oTabs[ tabCode ] ) ; 472 oTab.style.display = isVisible ? '' : 'none' ; 473 474 if ( ! isVisible && oTab.className == 'PopupTabSelected' ) 475 { 476 for ( var sCode in oTabs ) 477 { 478 if ( $( oTabs[sCode] ).style.display != 'none' ) 479 { 480 setSelectedTab( sCode ) ; 481 break ; 482 } 483 } 484 } 485 } ; 486 }() ; 487 488 // readystatechange handler for registering drag and drop handlers in cover 489 // iframes, defined out here to avoid memory leak. 490 // Do NOT put this function as a private function as it will induce memory leak 491 // in IE and it's not detectable with Drip or sIEve and undetectable leaks are 492 // really nasty (sigh). 493 var onReadyRegister = function() 494 { 495 if ( this.readyState != 'complete' ) 496 return ; 497 DragAndDrop.RegisterHandlers( this.contentWindow ) ; 498 } ; 499 500 // The business logic of the dialog, dealing with operational things like 501 // dialog open/dialog close/enable/disable/etc. 502 (function() 503 { 504 var setOnKeyDown = function( targetDocument ) 505 { 506 targetDocument.onkeydown = function ( e ) 507 { 508 e = e || event || this.parentWindow.event ; 509 switch ( e.keyCode ) 510 { 511 case 13 : // ENTER 512 var oTarget = e.srcElement || e.target ; 513 if ( oTarget.tagName == 'TEXTAREA' ) 514 return true ; 515 Ok() ; 516 return false ; 517 518 case 27 : // ESC 519 Cancel() ; 520 return false ; 521 } 522 return true ; 523 } 524 } ; 525 526 var contextMenuBlocker = function( e ) 527 { 528 var sTagName = e.target.tagName ; 529 if ( ! ( ( sTagName == "INPUT" && e.target.type == "text" ) || sTagName == "TEXTAREA" ) ) 530 e.preventDefault() ; 531 } ; 532 533 var disableContextMenu = function( targetDocument ) 534 { 535 if ( FCKBrowserInfo.IsIE ) 536 return ; 537 538 targetDocument.addEventListener( 'contextmenu', contextMenuBlocker, true ) ; 539 } ; 540 541 // Program entry point. 542 window.Init = function() 543 { 544 // Start the throbber timer. 545 Throbber.Show( 1000 ) ; 546 547 Sizer.RefreshContainerSize() ; 548 LoadInnerDialog() ; 549 550 FCKTools.DisableSelection( document.body ) ; 551 552 // Make the title area draggable. 553 var titleElement = $( 'header' ) ; 554 titleElement.onmousedown = DragAndDrop.MouseDownHandler ; 555 556 // Connect mousemove and mouseup events from dialog frame and outer window to dialog dragging logic. 557 DragAndDrop.RegisterHandlers( window ) ; 558 DragAndDrop.RegisterHandlers( Args().TopWindow ) ; 559 560 // Disable the previous dialog if it exists. 561 if ( ParentDialog() ) 562 { 563 ParentDialog().contentWindow.SetEnabled( false ) ; 564 if ( FCKBrowserInfo.IsIE && !FCKBrowserInfo.IsIE7 ) 565 { 566 var currentParent = ParentDialog() ; 567 while ( currentParent ) 568 { 569 var blockerFrame = currentParent.contentWindow.$( 'blocker' ) ; 570 if ( blockerFrame.readyState == 'complete' ) 571 DragAndDrop.RegisterHandlers( blockerFrame.contentWindow ) ; 572 else 573 blockerFrame.onreadystatechange = onReadyRegister ; 574 currentParent = ParentDialog( currentParent ) ; 575 } 576 } 577 else 578 { 579 var currentParent = ParentDialog() ; 580 while ( currentParent ) 581 { 582 DragAndDrop.RegisterHandlers( currentParent.contentWindow ) ; 583 currentParent = ParentDialog( currentParent ) ; 584 } 585 } 586 } 587 588 // If this is the only dialog on screen, enable the background cover. 589 if ( FCKBrowserInfo.IsIE && !FCKBrowserInfo.IsIE7 ) 590 { 591 var blockerFrame = FCKDialog.GetCover().firstChild ; 592 if ( blockerFrame.readyState == 'complete' ) 593 DragAndDrop.RegisterHandlers( blockerFrame.contentWindow ) ; 594 else 595 blockerFrame.onreadystatechange = onReadyRegister; 596 } 597 598 // Add Enter/Esc hotkeys and disable context menu for the dialog. 599 setOnKeyDown( document ) ; 600 disableContextMenu( document ) ; 601 } ; 602 603 window.LoadInnerDialog = function() 604 { 605 if ( window.onresize ) 606 window.onresize() ; 607 608 // First of all, translate the dialog box contents. 609 E.FCKLanguageManager.TranslatePage( document ) ; 610 611 // Create the IFRAME that holds the dialog contents. 612 $( 'innerContents' ).innerHTML = '<iframe id="frmMain" src="' + Args().Page + '" name="frmMain" frameborder="0" width="100%" height="100%" scrolling="auto" style="visibility: hidden;" allowtransparency="true"></iframe>' ; 613 } ; 614 615 window.InnerDialogLoaded = function() 616 { 617 // If the dialog has been closed before the iframe is loaded, do nothing. 618 if ( !frameElement.parentNode ) 619 return null ; 620 621 Throbber.Hide() ; 622 623 var frmMain = $('frmMain') ; 624 var innerWindow = frmMain.contentWindow ; 625 var innerDoc = innerWindow.document ; 626 627 // Show the loaded iframe. 628 frmMain.style.visibility = '' ; 629 630 // Set the language direction. 631 innerDoc.documentElement.dir = langDir ; 632 633 // Sets the Skin CSS. 634 innerDoc.write( FCKTools.GetStyleHtml( FCKConfig.SkinDialogCSS ) ) ; 635 636 setOnKeyDown( innerDoc ) ; 637 disableContextMenu( innerDoc ) ; 638 639 Sizer.RefreshContainerSize(); 640 641 DragAndDrop.RegisterHandlers( innerWindow ) ; 642 643 innerWindow.focus() ; 644 645 return E ; 646 } ; 647 648 window.SetOkButton = function( showIt ) 649 { 650 $('btnOk').style.visibility = ( showIt ? '' : 'hidden' ) ; 651 } ; 652 653 window.Ok = function() 654 { 655 Selection.EnsureSelection() ; 656 657 var frmMain = window.frames["frmMain"] ; 658 659 if ( frmMain.Ok && frmMain.Ok() ) 660 CloseDialog() ; 661 else 662 frmMain.focus() ; 663 } ; 664 665 window.Cancel = function( dontFireChange ) 666 { 667 Selection.EnsureSelection() ; 668 return CloseDialog( dontFireChange ) ; 669 } ; 670 671 window.CloseDialog = function( dontFireChange ) 672 { 673 Throbber.Hide() ; 674 675 // Points the src to a non-existent location to avoid loading errors later, in case the dialog 676 // haven't been completed loaded at this point. 677 if ( $( 'frmMain' ) ) 678 $( 'frmMain' ).src = FCKTools.GetVoidUrl() ; 679 680 if ( !dontFireChange && !FCK.EditMode ) 681 { 682 // All dialog windows, by default, will fire the "OnSelectionChange" 683 // event, no matter the Ok or Cancel button has been pressed. 684 // It seems that OnSelectionChange may enter on a concurrency state 685 // on some situations (#1965), so we should put the event firing in 686 // the execution queue instead of executing it immediately. 687 setTimeout( function() 688 { 689 FCK.Events.FireEvent( 'OnSelectionChange' ) ; 690 }, 0 ) ; 691 } 692 693 FCKDialog.OnDialogClose( window ) ; 694 } ; 695 696 window.SetEnabled = function( isEnabled ) 697 { 698 var cover = $( 'cover' ) ; 699 cover.style.display = isEnabled ? 'none' : '' ; 700 701 if ( FCKBrowserInfo.IsIE && !FCKBrowserInfo.IsIE7 ) 702 { 703 if ( !isEnabled ) 704 { 705 // Inser the blocker IFRAME before the cover. 706 var blocker = document.createElement( 'iframe' ) ; 707 blocker.src = FCKTools.GetVoidUrl() ; 708 blocker.hideFocus = true ; 709 blocker.frameBorder = 0 ; 710 blocker.id = blocker.className = 'blocker' ; 711 cover.appendChild( blocker ) ; 712 } 713 else 714 { 715 var blocker = $( 'blocker' ) ; 716 if ( blocker && blocker.parentNode ) 717 blocker.parentNode.removeChild( blocker ) ; 718 } 719 } 720 } ; 721 })() ;