Ticket #2056: validhtml.patch

File validhtml.patch, 70.0 KB (added by Christian Zagrodnick, 15 years ago)

Patch for valid html

  • 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
     22var dialog = window.parent ;
     23var oEditor = dialog.InnerDialogLoaded() ;
     24var FCK = oEditor.FCK;
     25var FCKTools    = oEditor.FCKTools ;
     26var FCKConfig   = oEditor.FCKConfig ;
     27var FCKBrowserInfo = oEditor.FCKBrowserInfo ;
     28
     29window.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
     88function 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
     174function 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, '&nbsp;') ;
     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*&nbsp;\s*<\/SPAN>/gi, '&nbsp;' ) ;
     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)>&nbsp;<\/\1>/g, '&nbsp;' ) ;
     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

     
    2929        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    3030        <meta name="robots" content="noindex, nofollow" />
    3131        <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>
    3933
    40 window.onload = function ()
    41 {
    42         // First of all, translate the dialog box texts
    43         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 in
    53                 // 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: #389
    74                         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                         else
    82                                 oDoc.designMode = 'on' ;
    83 
    84                         oFrame.contentWindow.focus();
    85                 }
    86         }
    87         else
    88         {
    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                 else
    116                         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 one
    121                         if ( typeof( FCK.CustomCleanWord ) == 'function' )
    122                                 sHtml = FCK.CustomCleanWord( oBody, document.getElementById('chkRemoveFont').checked, document.getElementById('chkRemoveStyles').checked ) ;
    123                         else
    124                                 sHtml = CleanWord( oBody, document.getElementById('chkRemoveFont').checked, document.getElementById('chkRemoveStyles').checked ) ;
    125                 }
    126                 else
    127                         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         else
    134         {
    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                 else
    167                         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 clipboard
    183 // bIgnoreFont, bRemoveStyles booleans according to the values set in the dialog
    184 // Output: the cleaned string
    185 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, '&nbsp;') ;
    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 attributes
    221         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*&nbsp;\s*<\/SPAN>/gi, '&nbsp;' ) ;
    231 
    232         html = html.replace( /<SPAN\s*[^>]*><\/SPAN>/gi, '' ) ;
    233 
    234         // Remove Lang attributes
    235         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 declarations
    242         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)>&nbsp;<\/\1>/g, '&nbsp;' ) ;
    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 tags
    258         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         else
    274         {
    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 error
    286                 html = html.replace( re, '<div$2<\/div>' ) ;
    287 
    288                 // Remove empty tags (three times, just to be sure).
    289                 // This also removes any empty anchor
    290                 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 
    30034</head>
    30135<body style="overflow: hidden">
    30236        <table cellspacing="0" cellpadding="0" width="100%" border="0" style="height: 98%">
  • editor/dialog/fck_image.html

     
    165165                        <br />
    166166                        <input id="btnUpload" type="submit" value="Send it to the Server" fcklang="DlgLnkBtnUpload" />
    167167                        <script type="text/javascript">
    168                                 document.write( '<iframe name="UploadWindow" style="display: none" src="' + FCKTools.GetVoidUrl() + '"></iframe>' ) ;
     168                          document.write( '&lt;iframe name="UploadWindow" style="display: none" src="' + FCKTools.GetVoidUrl() + '"&gt;&lt;/iframe&gt;' ) ;
    169169                        </script>
    170170                </form>
    171171        </div>
  • editor/fckdialog.html

     
    2626                <title></title>
    2727                <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    2828                <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>
    73130        </head>
    73231        <body onload="Init();" class="PopupBody">
    73332                <div class="contents" id="contents">
  • editor/filemanager/browser/default/frmfolders.html

     
    2727                <link href="browser.css" type="text/css" rel="stylesheet">
    2828                <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    2929                <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 = '&nbsp;' + 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>
    18831        </head>
    18932        <body class="FileArea" bottomMargin="10" leftMargin="10" topMargin="10" rightMargin="10">
    19033                <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
     22var sActiveFolder ;
     23
     24var bIsLoaded = false ;
     25var iIntervalId ;
     26
     27var oListManager = new Object() ;
     28
     29oListManager.Init = function()
     30{
     31        this.Table = document.getElementById('tableFiles') ;
     32        this.UpRow = document.getElementById('trUp') ;
     33
     34        this.TableRows = new Object() ;
     35}
     36
     37oListManager.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
     47oListManager.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 = '&nbsp;' + sLink + folderName + '</a>' ;
     65
     66        this.TableRows[ folderPath ] = oRow ;
     67}
     68
     69oListManager.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
     83function 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
     96function 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
     123function 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
     146function 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
     166function SetResourceType( type )
     167{
     168        oConnector.ResourceType = type ;
     169        LoadFolders( '/' ) ;
     170}
     171
     172window.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
     51var 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.
     55function Args()
     56{
     57        return frameElement._DialogArguments ;
     58}
     59
     60function ParentDialog( dialog )
     61{
     62        return dialog ? dialog._ParentDialog : frameElement._ParentDialog ;
     63}
     64
     65var FCK                         = E.FCK ;
     66var FCKTools            = E.FCKTools ;
     67var FCKDomTools         = E.FCKDomTools ;
     68var FCKDialog           = E.FCKDialog ;
     69var FCKBrowserInfo      = E.FCKBrowserInfo ;
     70var FCKConfig           = E.FCKConfig ;
     71
     72// Steal the focus so that the caret would no longer stay in the editor iframe.
     73window.focus() ;
     74
     75// Sets the Skin CSS
     76document.write( FCKTools.GetStyleHtml( FCKConfig.SkinDialogCSS ) ) ;
     77
     78// Sets the language direction.
     79var 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.
     82if ( FCKBrowserInfo.IsIE && !FCKBrowserInfo.IsIE7 )
     83        document.write( '<' + 'script type="text/javascript" src="' + FCKConfig.SkinPath + 'fck_dialog_ie6.js"><' + '\/script>' ) ;
     84
     85FCKTools.RegisterDollarFunction( window ) ;
     86
     87// Resize related functions.
     88var 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.
     196var 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.
     263var 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)
     371var 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.
     401var 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).
     493var 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})() ;
© 2003 – 2022, CKSource sp. z o.o. sp.k. All rights reserved. | Terms of use | Privacy policy