Ticket #2852: 2852_fakeobjects.patch

File 2852_fakeobjects.patch, 25.1 KB (added by Martin Kou, 16 years ago)

Temporary fakeobjects plugin for making the patch work.

  • _source/plugins/fakeobjects/plugin.js

     
     1/*
     2Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
     3For licensing, see LICENSE.html or http://ckeditor.com/license
     4*/
     5
     6/**
     7 * @fileoverview The "fakeobjects" plugin. It handles placeholder DOM nodes
     8 *      in WYSIWYG mode.
     9 */
     10
     11(function()
     12{
     13        var flashExtensionRegex = /\.swf($|#|\?)/i,
     14                emptyElements = { base:1,col:1,meta:1,link:1,hr:1,br:1,param:1,img:1,area:1,input:1 },
     15                makeTagOpenerHtml = function( tagName, attributes, selfClosing )
     16                {
     17                        var attribStr = [], html = [ '<' + tagName ];
     18                        for ( var i in attributes )
     19                                attribStr.push( i + '="' + CKEDITOR.tools.htmlEncode( attributes[i] ) + '"');
     20                        if ( attribStr.length > 0 )
     21                                html.push( ' ', attribStr.join( ' ' ) );
     22                        if ( emptyElements[ tagName ] || selfClosing )
     23                                html.push( ' /' );
     24                        html.push( '>' );
     25                        return html.join( '' );
     26                },
     27                cssWidthRegex = /width\s*:\s*([0-9]+)\s*(?:[\w%]+)?\s*;?/i,
     28                cssHeightRegex = /height\s*:\s*([0-9]+)\s*(?:[\w%]+)?\s*;?/i;
     29
     30        var copyParser = function()
     31        {
     32                this._ = { html : null };
     33                this.output = [];
     34
     35                CKEDITOR.htmlParser.call( this );
     36        };
     37        copyParser.prototype = {
     38                onTagOpen : function( tagName, attributes, selfClosing )
     39                {
     40                        this.output.push( makeTagOpenerHtml( tagName, attributes, selfClosing ) );
     41                },
     42
     43                onTagClose : function( tagName )
     44                {
     45                        if ( !emptyElements[ tagName] )
     46                                this.output.push( '</' + tagName + '>' );
     47                },
     48
     49                onText : function( text )
     50                {
     51                        this.output.push( text );
     52                },
     53
     54                onComment : function( comment )
     55                {
     56                        this.output.push( '<!--' + comment + '-->' );
     57                },
     58
     59                parse : function( html )
     60                {
     61                        this._.html = html;
     62                        return CKEDITOR.htmlParser.prototype.parse.apply( this, arguments );
     63                }
     64        };
     65
     66        /**
     67         * Manages element placeholders in WYSIWYG area.
     68         * @constructor
     69         * @example
     70         */
     71        CKEDITOR.plugins.fakeobjects = function( editor )
     72        {
     73                this._ =
     74                {
     75                        editor : editor,
     76                        objectTypes : [
     77                                {
     78                                        match : function( nodeName, attributes )
     79                                        {
     80                                                return nodeName == 'embed' &&
     81                                                        ( attributes.type == 'application/x-shockwave-flash' || flashExtensionRegex.test( attributes.src || '' ) );
     82                                        },
     83                                        cssClass : 'flash',
     84                                        priority : 10
     85                                },
     86                                {
     87                                        match : function( nodeName, attributes )
     88                                        {
     89                                                return ( nodeName == 'a' && attributes.name != null && attributes.name != '' );
     90                                        },
     91                                        cssClass : 'anchor',
     92                                        priority : 10
     93                                },
     94                                {
     95                                        match : function( nodeName, attributes )
     96                                        {
     97                                                if ( nodeName == 'div' && attributes.style && attributes.style.pageBreakAfter == 'always' )
     98                                                        if ( attributes.firstChild )
     99                                                        {
     100                                                                var element = new CKEDITOR.dom.element( attributes.firstChild );
     101                                                                return ( element && element.getName() == 'span');
     102                                                        }
     103                                                return false;
     104                                        },
     105                                        cssClass : 'pagebreak',
     106                                        priority : 10
     107                                },
     108                                {
     109                                        match : function( nodeName, attributes )
     110                                        {
     111                                                return nodeName == 'embed' || nodeName == 'object';
     112                                        },
     113                                        cssClass : 'object',
     114                                        priority : 0x100000000
     115                                }
     116                        ]
     117                };
     118        };
     119        CKEDITOR.plugins.fakeobjects.prototype =
     120        {
     121                /**
     122                 * Converts an element into a placeholder &lt;img&gt; element, for adding
     123                 * into the WYSIWYG area.
     124                 * @param {CKEDITOR.dom.element} element Input DOM element.
     125                 * @returns {CKEDITOR.dom.element} The placeholder &lt;img&gt; element.
     126                 * @example
     127                 */
     128                protectElement : function( element )
     129                {
     130                        var $ = element.$.cloneNode( true ),
     131                                doc = $.ownerDocument,
     132                                temp = doc.createElement( 'div' ),
     133                                html;
     134
     135                        // Get the object's HTML code.
     136                        temp.appendChild( $ );
     137                        html = temp.innerHTML;
     138
     139                        // Get the fake element's CSS class.
     140                        var cssClass = 'unknown';
     141                        var realElementType = element.getName();
     142                        for ( var i = 0 ; i < this._.objectTypes.length ; i++ )
     143                        {
     144                                if ( this._.objectTypes[i].match( element.getName(), element.$ ) )
     145                                {
     146                                        cssClass = 'cke_fakeobject' + ' ' + this._.objectTypes[i].cssClass;
     147                                        realElementType = this._.objectTypes[i].cssClass;
     148                                        break;
     149                                }
     150                        }
     151
     152                        // Make the fake element.
     153                        var fakeRawElement = doc.createElement( 'img' ),
     154                                cssText = $.style.cssText,
     155                                widthMatch = cssText.match( cssWidthRegex ),
     156                                heightMatch = cssText.match( cssHeightRegex );
     157                        fakeRawElement.className = cssClass;
     158                        fakeRawElement.src = CKEDITOR.getUrl( 'images/spacer.gif' );
     159                        if ( widthMatch)
     160                                fakeRawElement.style.width = widthMatch[1] + 'px';
     161                        if ( heightMatch )
     162                                fakeRawElement.style.height = heightMatch[1] + 'px';
     163                        fakeRawElement.setAttribute( '_cke_protected_html', encodeURIComponent( html ) );
     164                        fakeRawElement.setAttribute( '_cke_real_element_type', realElementType );
     165                        return new CKEDITOR.dom.element( fakeRawElement );
     166                },
     167
     168                /**
     169                 * Converts a placeholder &lt;img&gt; element back to the real element.
     170                 * @param {CKEDITOR.dom.element} fakeImgElement The placeholder &lt;img&gt;.
     171                 * @returns {CKEDITOR.dom.element} The real element.
     172                 * @example
     173                 */
     174                restoreElement : function( fakeImgElement )
     175                {
     176                        var html = decodeURIComponent( fakeImgElement.getAttribute( '_cke_protected_html' ) ),
     177                                realElement = CKEDITOR.dom.element.createFromHtml( html, this._.editor.document );
     178
     179                        if ( fakeImgElement.$.style.width )
     180                                realElement.setStyle( 'width', fakeImgElement.$.style.width );
     181                        if ( fakeImgElement.$.style.height )
     182                                realElement.setStyle( 'height', fakeImgElement.$.style.height );
     183
     184                        return realElement;
     185                },
     186
     187                /**
     188                 * Converts protectable elements in an HTML string to placeholders.
     189                 * @param {String} html HTML with protectable elements.
     190                 * @returns {String} HTML with placeholders.
     191                 * @example
     192                 */
     193                protectHtml : function( html )
     194                {
     195                        var parser = new CKEDITOR.htmlParser(),
     196                                tagDepth = 0, processedHtml = [],
     197                                protectedHtml = [], inProtection = false,
     198                                objectTypes = this._.objectTypes;
     199
     200                        parser.onTagOpen = function( tagName, attributes, selfClosing )
     201                        {
     202                                if ( inProtection )
     203                                {
     204                                        protectedHtml.push( makeTagOpenerHtml( tagName, attributes, selfClosing ) );
     205                                        if ( !( emptyElements[ tagName ] || selfClosing ) )
     206                                                tagDepth++;
     207                                        if ( tagDepth < 1 )
     208                                        {
     209                                                inProtection = false;
     210                                                processedHtml.push( encodeURIComponent( protectedHtml.join( '' ) ), '" />' );
     211                                                protectedHtml = [];
     212                                        }
     213                                        return;
     214                                }
     215
     216                                for ( var i = 0 ; i < objectTypes.length ; i++ )
     217                                {
     218                                        if ( objectTypes[i].match( tagName, attributes ) )
     219                                        {
     220                                                inProtection = true;
     221                                                tagDepth = 0;
     222
     223                                                // Get the original object's width and height.
     224                                                var styles = attributes.style || '',
     225                                                        widthMatch = styles.match( cssWidthRegex ),
     226                                                        heightMatch = styles.match( cssHeightRegex );
     227
     228                                                // Create the fake <img> tag.
     229                                                processedHtml.push( '<img src="',
     230                                                        CKEDITOR.getUrl( 'images/spacer.gif' ),
     231                                                        '" ',
     232                                                        'class="cke_fakeobject ' + objectTypes[i].cssClass + '" ',
     233                                                        '_cke_real_element_type="' + objectTypes[i].cssClass + '"' );
     234
     235                                                if ( widthMatch || heightMatch )
     236                                                {
     237                                                        processedHtml.push( 'style="',
     238                                                                widthMatch ? 'width:' + widthMatch[1] + 'px;' : '',
     239                                                                heightMatch ? 'height:' + heightMatch[1] + 'px;' : '',
     240                                                                '" ' );
     241                                                }
     242
     243                                                processedHtml.push( '_cke_protected_html="' );
     244                                                arguments.callee.call( this, tagName, attributes, selfClosing );
     245                                                return;
     246                                        }
     247                                }
     248
     249                                processedHtml.push( makeTagOpenerHtml( tagName, attributes ) );
     250                        };
     251
     252                        parser.onText = function( text )
     253                        {
     254                                inProtection ? protectedHtml.push( text ) : processedHtml.push( text );
     255                        };
     256
     257                        parser.onComment = function( comment )
     258                        {
     259                                inProtection ? protectedHtml.push( '<!--' + comment + '-->' ) : processedHtml.push( '<!--' + comment + '-->' );
     260                        };
     261
     262                        parser.onTagClose = function( tagName )
     263                        {
     264                                if ( inProtection )
     265                                {
     266                                        if ( !emptyElements[ tagName ] )
     267                                                tagDepth--;
     268                                        protectedHtml.push( '</' + tagName + '>' );
     269                                        if ( tagDepth < 1 )
     270                                        {
     271                                                inProtection = false;
     272                                                processedHtml.push( encodeURIComponent( protectedHtml.join( '' ) ), '" />' );
     273                                                protectedHtml = [];
     274                                        }
     275                                }
     276                                else
     277                                        processedHtml.push( '</' + tagName + '>' );
     278                        };
     279
     280                        parser.parse( html );
     281                        return processedHtml.join( '' );
     282                },
     283                /**
     284                 * Updates HTML into a placeholder
     285                 * @param {CKEDITOR.dom.element} fakeImgElement The placeholder &lt;img&gt;.
     286                 * @param {CKEDITOR.dom.element} element Input DOM element.
     287                 * @returns {String} encoded HTML.
     288                 * @example
     289                 */
     290                updateFakeElement : function( fakeElement, realElement )
     291                {
     292                        var $ = realElement.$.cloneNode( true ),
     293                                doc = $.ownerDocument,
     294                                temp = doc.createElement( 'div' ),
     295                                html;
     296
     297                        // Get the object's HTML code.
     298                        temp.appendChild( $ );
     299                        html = temp.innerHTML;
     300                        fakeElement.setAttribute( '_cke_protected_html', encodeURIComponent( html ) );
     301                        return html;
     302                },
     303
     304                /**
     305                 * Restores placeholders in an HTML string back to their original elements.
     306                 * @param {String} html HTML with placeholders.
     307                 * @returns {String} Restored HTML.
     308                 * @example
     309                 */
     310                restoreHtml : function( html )
     311                {
     312                        var parser = new copyParser(),
     313                                innerParser = new copyParser();
     314
     315                        innerParser.onTagOpen = function( tagName, attributes, selfClosing )
     316                        {
     317                                if ( !this.done )
     318                                {
     319                                        var styles = attributes.style || '';
     320
     321                                        styles = styles.replace( cssWidthRegex, '' ).replace( cssHeightRegex, '' );
     322                                        if ( this.width )
     323                                                styles += 'width:' + this.width + ';';
     324                                        if ( this.height )
     325                                                styles += 'height:' + this.height + ';';
     326                                        attributes.style = styles;
     327
     328                                        this.done = true;
     329                                }
     330
     331                                return copyParser.prototype.onTagOpen.apply( this, arguments );
     332                        };
     333
     334                        parser.onTagOpen = function( tagName, attributes, selfClosing )
     335                        {
     336                                if ( tagName == 'img' && attributes._cke_protected_html !== undefined )
     337                                {
     338                                        var styles = attributes.style || '',
     339                                                protectedHtml = decodeURIComponent( attributes._cke_protected_html ),
     340                                                widthMatch = styles.match( cssWidthRegex ),
     341                                                heightMatch = styles.match( cssHeightRegex );
     342
     343                                        if ( widthMatch || heightMatch )
     344                                        {
     345                                                innerParser.width = widthMatch[1] + 'px';
     346                                                innerParser.height = heightMatch[1] + 'px';
     347                                                innerParser.parse( protectedHtml );
     348                                                protectedHtml = innerParser.output.join( '' );
     349                                        }
     350
     351                                        this.output.push( protectedHtml );
     352                                        return;
     353                                }
     354                                return copyParser.prototype.onTagOpen.apply( this, arguments );
     355                        };
     356
     357                        parser.parse( html );
     358                        return parser.output.join( '' );
     359                },
     360
     361                /**
     362                 * Adds an object type to be displayed by placeholders.
     363                 * @param {Function} matchFunc A predicate function to determine whether
     364                 * an object needs to be replaced by placeholders or not. The function
     365                 * should have the following signature:
     366                 * <blockquote>function( tagName, attributes )</blockquote>
     367                 * In which tagName is the object's tag name, and attributes is an object
     368                 * storing all the object's attributes.
     369                 * @param {String} cssClass The CSS class that should be added to the
     370                 * placeholder &lt;img&gt; for representing this type of object.
     371                 * @param {Number} priority (Optional) An integer representing the
     372                 * priority of this type of object. If an element matches the descriptions
     373                 * of two object types, the object type of <strong>lower</strong> priority
     374                 * takes precedance.
     375                 * @example
     376                 */
     377                addObjectType : function( matchFunc, cssClass, priority )
     378                {
     379                        if ( priority === undefined )
     380                                priority = 10;
     381
     382                        var obj = {
     383                                match : matchFunc,
     384                                cssClass : cssClass,
     385                                priority : priority
     386                        };
     387
     388                        for ( var i = this._.objectTypes.length - 1 ; i >= 0 ; i-- )
     389                        {
     390                                if ( this._.objectTypes[i].priority < priority )
     391                                {
     392                                        this._.objectTypes.splice( i + 1, 0, obj );
     393                                        return;
     394                                }
     395                        }
     396
     397                        this._.objectTypes.unshift( obj );
     398                }
     399        };
     400
     401        CKEDITOR.plugins.add( 'fakeobjects',
     402                {
     403                        init : function( editor, pluginPath )
     404                        {
     405                                editor.fakeobjects = new CKEDITOR.plugins.fakeobjects( editor );
     406                        }
     407                } );
     408})();
  • _source/plugins/fakeobjects/plugin.js

     
     1/*
     2Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
     3For licensing, see LICENSE.html or http://ckeditor.com/license
     4*/
     5
     6/**
     7 * @fileoverview The "fakeobjects" plugin. It handles placeholder DOM nodes
     8 *      in WYSIWYG mode.
     9 */
     10
     11(function()
     12{
     13        var flashExtensionRegex = /\.swf($|#|\?)/i,
     14                emptyElements = { base:1,col:1,meta:1,link:1,hr:1,br:1,param:1,img:1,area:1,input:1 },
     15                makeTagOpenerHtml = function( tagName, attributes, selfClosing )
     16                {
     17                        var attribStr = [], html = [ '<' + tagName ];
     18                        for ( var i in attributes )
     19                                attribStr.push( i + '="' + CKEDITOR.tools.htmlEncode( attributes[i] ) + '"');
     20                        if ( attribStr.length > 0 )
     21                                html.push( ' ', attribStr.join( ' ' ) );
     22                        if ( emptyElements[ tagName ] || selfClosing )
     23                                html.push( ' /' );
     24                        html.push( '>' );
     25                        return html.join( '' );
     26                },
     27                cssWidthRegex = /width\s*:\s*([0-9]+)\s*(?:[\w%]+)?\s*;?/i,
     28                cssHeightRegex = /height\s*:\s*([0-9]+)\s*(?:[\w%]+)?\s*;?/i;
     29
     30        var copyParser = function()
     31        {
     32                this._ = { html : null };
     33                this.output = [];
     34
     35                CKEDITOR.htmlParser.call( this );
     36        };
     37        copyParser.prototype = {
     38                onTagOpen : function( tagName, attributes, selfClosing )
     39                {
     40                        this.output.push( makeTagOpenerHtml( tagName, attributes, selfClosing ) );
     41                },
     42
     43                onTagClose : function( tagName )
     44                {
     45                        if ( !emptyElements[ tagName] )
     46                                this.output.push( '</' + tagName + '>' );
     47                },
     48
     49                onText : function( text )
     50                {
     51                        this.output.push( text );
     52                },
     53
     54                onComment : function( comment )
     55                {
     56                        this.output.push( '<!--' + comment + '-->' );
     57                },
     58
     59                parse : function( html )
     60                {
     61                        this._.html = html;
     62                        return CKEDITOR.htmlParser.prototype.parse.apply( this, arguments );
     63                }
     64        };
     65
     66        /**
     67         * Manages element placeholders in WYSIWYG area.
     68         * @constructor
     69         * @example
     70         */
     71        CKEDITOR.plugins.fakeobjects = function( editor )
     72        {
     73                this._ =
     74                {
     75                        editor : editor,
     76                        objectTypes : [
     77                                {
     78                                        match : function( nodeName, attributes )
     79                                        {
     80                                                return nodeName == 'embed' &&
     81                                                        ( attributes.type == 'application/x-shockwave-flash' || flashExtensionRegex.test( attributes.src || '' ) );
     82                                        },
     83                                        cssClass : 'flash',
     84                                        priority : 10
     85                                },
     86                                {
     87                                        match : function( nodeName, attributes )
     88                                        {
     89                                                return ( nodeName == 'a' && attributes.name != null && attributes.name != '' );
     90                                        },
     91                                        cssClass : 'anchor',
     92                                        priority : 10
     93                                },
     94                                {
     95                                        match : function( nodeName, attributes )
     96                                        {
     97                                                if ( nodeName == 'div' && attributes.style && attributes.style.pageBreakAfter == 'always' )
     98                                                        if ( attributes.firstChild )
     99                                                        {
     100                                                                var element = new CKEDITOR.dom.element( attributes.firstChild );
     101                                                                return ( element && element.getName() == 'span');
     102                                                        }
     103                                                return false;
     104                                        },
     105                                        cssClass : 'pagebreak',
     106                                        priority : 10
     107                                },
     108                                {
     109                                        match : function( nodeName, attributes )
     110                                        {
     111                                                return nodeName == 'embed' || nodeName == 'object';
     112                                        },
     113                                        cssClass : 'object',
     114                                        priority : 0x100000000
     115                                }
     116                        ]
     117                };
     118        };
     119        CKEDITOR.plugins.fakeobjects.prototype =
     120        {
     121                /**
     122                 * Converts an element into a placeholder &lt;img&gt; element, for adding
     123                 * into the WYSIWYG area.
     124                 * @param {CKEDITOR.dom.element} element Input DOM element.
     125                 * @returns {CKEDITOR.dom.element} The placeholder &lt;img&gt; element.
     126                 * @example
     127                 */
     128                protectElement : function( element )
     129                {
     130                        var $ = element.$.cloneNode( true ),
     131                                doc = $.ownerDocument,
     132                                temp = doc.createElement( 'div' ),
     133                                html;
     134
     135                        // Get the object's HTML code.
     136                        temp.appendChild( $ );
     137                        html = temp.innerHTML;
     138
     139                        // Get the fake element's CSS class.
     140                        var cssClass = 'unknown';
     141                        var realElementType = element.getName();
     142                        for ( var i = 0 ; i < this._.objectTypes.length ; i++ )
     143                        {
     144                                if ( this._.objectTypes[i].match( element.getName(), element.$ ) )
     145                                {
     146                                        cssClass = 'cke_fakeobject' + ' ' + this._.objectTypes[i].cssClass;
     147                                        realElementType = this._.objectTypes[i].cssClass;
     148                                        break;
     149                                }
     150                        }
     151
     152                        // Make the fake element.
     153                        var fakeRawElement = doc.createElement( 'img' ),
     154                                cssText = $.style.cssText,
     155                                widthMatch = cssText.match( cssWidthRegex ),
     156                                heightMatch = cssText.match( cssHeightRegex );
     157                        fakeRawElement.className = cssClass;
     158                        fakeRawElement.src = CKEDITOR.getUrl( 'images/spacer.gif' );
     159                        if ( widthMatch)
     160                                fakeRawElement.style.width = widthMatch[1] + 'px';
     161                        if ( heightMatch )
     162                                fakeRawElement.style.height = heightMatch[1] + 'px';
     163                        fakeRawElement.setAttribute( '_cke_protected_html', encodeURIComponent( html ) );
     164                        fakeRawElement.setAttribute( '_cke_real_element_type', realElementType );
     165                        return new CKEDITOR.dom.element( fakeRawElement );
     166                },
     167
     168                /**
     169                 * Converts a placeholder &lt;img&gt; element back to the real element.
     170                 * @param {CKEDITOR.dom.element} fakeImgElement The placeholder &lt;img&gt;.
     171                 * @returns {CKEDITOR.dom.element} The real element.
     172                 * @example
     173                 */
     174                restoreElement : function( fakeImgElement )
     175                {
     176                        var html = decodeURIComponent( fakeImgElement.getAttribute( '_cke_protected_html' ) ),
     177                                realElement = CKEDITOR.dom.element.createFromHtml( html, this._.editor.document );
     178
     179                        if ( fakeImgElement.$.style.width )
     180                                realElement.setStyle( 'width', fakeImgElement.$.style.width );
     181                        if ( fakeImgElement.$.style.height )
     182                                realElement.setStyle( 'height', fakeImgElement.$.style.height );
     183
     184                        return realElement;
     185                },
     186
     187                /**
     188                 * Converts protectable elements in an HTML string to placeholders.
     189                 * @param {String} html HTML with protectable elements.
     190                 * @returns {String} HTML with placeholders.
     191                 * @example
     192                 */
     193                protectHtml : function( html )
     194                {
     195                        var parser = new CKEDITOR.htmlParser(),
     196                                tagDepth = 0, processedHtml = [],
     197                                protectedHtml = [], inProtection = false,
     198                                objectTypes = this._.objectTypes;
     199
     200                        parser.onTagOpen = function( tagName, attributes, selfClosing )
     201                        {
     202                                if ( inProtection )
     203                                {
     204                                        protectedHtml.push( makeTagOpenerHtml( tagName, attributes, selfClosing ) );
     205                                        if ( !( emptyElements[ tagName ] || selfClosing ) )
     206                                                tagDepth++;
     207                                        if ( tagDepth < 1 )
     208                                        {
     209                                                inProtection = false;
     210                                                processedHtml.push( encodeURIComponent( protectedHtml.join( '' ) ), '" />' );
     211                                                protectedHtml = [];
     212                                        }
     213                                        return;
     214                                }
     215
     216                                for ( var i = 0 ; i < objectTypes.length ; i++ )
     217                                {
     218                                        if ( objectTypes[i].match( tagName, attributes ) )
     219                                        {
     220                                                inProtection = true;
     221                                                tagDepth = 0;
     222
     223                                                // Get the original object's width and height.
     224                                                var styles = attributes.style || '',
     225                                                        widthMatch = styles.match( cssWidthRegex ),
     226                                                        heightMatch = styles.match( cssHeightRegex );
     227
     228                                                // Create the fake <img> tag.
     229                                                processedHtml.push( '<img src="',
     230                                                        CKEDITOR.getUrl( 'images/spacer.gif' ),
     231                                                        '" ',
     232                                                        'class="cke_fakeobject ' + objectTypes[i].cssClass + '" ',
     233                                                        '_cke_real_element_type="' + objectTypes[i].cssClass + '"' );
     234
     235                                                if ( widthMatch || heightMatch )
     236                                                {
     237                                                        processedHtml.push( 'style="',
     238                                                                widthMatch ? 'width:' + widthMatch[1] + 'px;' : '',
     239                                                                heightMatch ? 'height:' + heightMatch[1] + 'px;' : '',
     240                                                                '" ' );
     241                                                }
     242
     243                                                processedHtml.push( '_cke_protected_html="' );
     244                                                arguments.callee.call( this, tagName, attributes, selfClosing );
     245                                                return;
     246                                        }
     247                                }
     248
     249                                processedHtml.push( makeTagOpenerHtml( tagName, attributes ) );
     250                        };
     251
     252                        parser.onText = function( text )
     253                        {
     254                                inProtection ? protectedHtml.push( text ) : processedHtml.push( text );
     255                        };
     256
     257                        parser.onComment = function( comment )
     258                        {
     259                                inProtection ? protectedHtml.push( '<!--' + comment + '-->' ) : processedHtml.push( '<!--' + comment + '-->' );
     260                        };
     261
     262                        parser.onTagClose = function( tagName )
     263                        {
     264                                if ( inProtection )
     265                                {
     266                                        if ( !emptyElements[ tagName ] )
     267                                                tagDepth--;
     268                                        protectedHtml.push( '</' + tagName + '>' );
     269                                        if ( tagDepth < 1 )
     270                                        {
     271                                                inProtection = false;
     272                                                processedHtml.push( encodeURIComponent( protectedHtml.join( '' ) ), '" />' );
     273                                                protectedHtml = [];
     274                                        }
     275                                }
     276                                else
     277                                        processedHtml.push( '</' + tagName + '>' );
     278                        };
     279
     280                        parser.parse( html );
     281                        return processedHtml.join( '' );
     282                },
     283                /**
     284                 * Updates HTML into a placeholder
     285                 * @param {CKEDITOR.dom.element} fakeImgElement The placeholder &lt;img&gt;.
     286                 * @param {CKEDITOR.dom.element} element Input DOM element.
     287                 * @returns {String} encoded HTML.
     288                 * @example
     289                 */
     290                updateFakeElement : function( fakeElement, realElement )
     291                {
     292                        var $ = realElement.$.cloneNode( true ),
     293                                doc = $.ownerDocument,
     294                                temp = doc.createElement( 'div' ),
     295                                html;
     296
     297                        // Get the object's HTML code.
     298                        temp.appendChild( $ );
     299                        html = temp.innerHTML;
     300                        fakeElement.setAttribute( '_cke_protected_html', encodeURIComponent( html ) );
     301                        return html;
     302                },
     303
     304                /**
     305                 * Restores placeholders in an HTML string back to their original elements.
     306                 * @param {String} html HTML with placeholders.
     307                 * @returns {String} Restored HTML.
     308                 * @example
     309                 */
     310                restoreHtml : function( html )
     311                {
     312                        var parser = new copyParser(),
     313                                innerParser = new copyParser();
     314
     315                        innerParser.onTagOpen = function( tagName, attributes, selfClosing )
     316                        {
     317                                if ( !this.done )
     318                                {
     319                                        var styles = attributes.style || '';
     320
     321                                        styles = styles.replace( cssWidthRegex, '' ).replace( cssHeightRegex, '' );
     322                                        if ( this.width )
     323                                                styles += 'width:' + this.width + ';';
     324                                        if ( this.height )
     325                                                styles += 'height:' + this.height + ';';
     326                                        attributes.style = styles;
     327
     328                                        this.done = true;
     329                                }
     330
     331                                return copyParser.prototype.onTagOpen.apply( this, arguments );
     332                        };
     333
     334                        parser.onTagOpen = function( tagName, attributes, selfClosing )
     335                        {
     336                                if ( tagName == 'img' && attributes._cke_protected_html !== undefined )
     337                                {
     338                                        var styles = attributes.style || '',
     339                                                protectedHtml = decodeURIComponent( attributes._cke_protected_html ),
     340                                                widthMatch = styles.match( cssWidthRegex ),
     341                                                heightMatch = styles.match( cssHeightRegex );
     342
     343                                        if ( widthMatch || heightMatch )
     344                                        {
     345                                                innerParser.width = widthMatch[1] + 'px';
     346                                                innerParser.height = heightMatch[1] + 'px';
     347                                                innerParser.parse( protectedHtml );
     348                                                protectedHtml = innerParser.output.join( '' );
     349                                        }
     350
     351                                        this.output.push( protectedHtml );
     352                                        return;
     353                                }
     354                                return copyParser.prototype.onTagOpen.apply( this, arguments );
     355                        };
     356
     357                        parser.parse( html );
     358                        return parser.output.join( '' );
     359                },
     360
     361                /**
     362                 * Adds an object type to be displayed by placeholders.
     363                 * @param {Function} matchFunc A predicate function to determine whether
     364                 * an object needs to be replaced by placeholders or not. The function
     365                 * should have the following signature:
     366                 * <blockquote>function( tagName, attributes )</blockquote>
     367                 * In which tagName is the object's tag name, and attributes is an object
     368                 * storing all the object's attributes.
     369                 * @param {String} cssClass The CSS class that should be added to the
     370                 * placeholder &lt;img&gt; for representing this type of object.
     371                 * @param {Number} priority (Optional) An integer representing the
     372                 * priority of this type of object. If an element matches the descriptions
     373                 * of two object types, the object type of <strong>lower</strong> priority
     374                 * takes precedance.
     375                 * @example
     376                 */
     377                addObjectType : function( matchFunc, cssClass, priority )
     378                {
     379                        if ( priority === undefined )
     380                                priority = 10;
     381
     382                        var obj = {
     383                                match : matchFunc,
     384                                cssClass : cssClass,
     385                                priority : priority
     386                        };
     387
     388                        for ( var i = this._.objectTypes.length - 1 ; i >= 0 ; i-- )
     389                        {
     390                                if ( this._.objectTypes[i].priority < priority )
     391                                {
     392                                        this._.objectTypes.splice( i + 1, 0, obj );
     393                                        return;
     394                                }
     395                        }
     396
     397                        this._.objectTypes.unshift( obj );
     398                }
     399        };
     400
     401        CKEDITOR.plugins.add( 'fakeobjects',
     402                {
     403                        init : function( editor, pluginPath )
     404                        {
     405                                editor.fakeobjects = new CKEDITOR.plugins.fakeobjects( editor );
     406                        }
     407                } );
     408})();
© 2003 – 2022, CKSource sp. z o.o. sp.k. All rights reserved. | Terms of use | Privacy policy