Ticket #7131: 7131_6.patch

File 7131_6.patch, 19.3 KB (added by Garry Yao, 13 years ago)
  • _source/plugins/pastefromword/filter/default.js

     
    118118                return result;
    119119        };
    120120
     121        // 1. move list item styles up to list root if they're consistent.
     122        // 2. clear out verbose list item numbering.
     123        function postProcessList( list )
     124        {
     125                var children = list.children,
     126                        child,
     127                        attrs,
     128                        count = list.children.length,
     129                        match,
     130                        mergeStyle,
     131                        styleTypeRegexp = /list-style-type:(.*?)(?:;|$)/,
     132                        stylesFilter = CKEDITOR.plugins.pastefromword.filters.stylesFilter;
     133
     134                attrs = list.attributes;
     135                if ( styleTypeRegexp.exec( attrs.style ) )
     136                        return;
     137
     138                for ( var i = 0; i < count; i++ )
     139                {
     140                        child = children[ i ];
     141                        if ( child.attributes.value && Number( child.attributes.value ) == i + 1 )
     142                                delete child.attributes.value;
     143
     144                        match = styleTypeRegexp.exec( child.attributes.style );
     145
     146                        if ( match )
     147                        {
     148                                if ( match[ 1 ] == mergeStyle || !mergeStyle )
     149                                        mergeStyle = match[ 1 ];
     150                                else
     151                                {
     152                                        mergeStyle = null;
     153                                        break;
     154                                }
     155                        }
     156                }
     157
     158                if ( mergeStyle )
     159                {
     160                        for ( i = 0; i < count; i++ )
     161                        {
     162                                attrs = children[ i ].attributes;
     163                                attrs.style && ( attrs.style = stylesFilter( [ [ 'list-style-type'] ] )( attrs.style ) || '' );
     164                        }
     165
     166                        list.addStyle( 'list-style-type', mergeStyle );
     167                }
     168        }
     169
    121170        var cssLengthRelativeUnit = /^([.\d]*)+(em|ex|px|gd|rem|vw|vh|vm|ch|mm|cm|in|pt|pc|deg|rad|ms|s|hz|khz){1}?/i;
    122171        var emptyMarginRegex = /^(?:\b0[^\s]*\s*){1,4}$/;               // e.g. 0px 0pt 0px
    123172        var romanLiternalPattern = '^m{0,4}(cm|cd|d?c{0,3})(xc|xl|l?x{0,3})(ix|iv|v?i{0,3})$',
    124173                lowerRomanLiteralRegex = new RegExp( romanLiternalPattern ),
    125174                upperRomanLiteralRegex = new RegExp( romanLiternalPattern.toUpperCase() );
    126175
    127         var listBaseIndent = 0,
    128                  previousListItemMargin;
     176        var orderedPatterns = { 'decimal' : /\d+/, 'lower-roman': lowerRomanLiteralRegex, 'upper-roman': upperRomanLiteralRegex, 'lower-alpha' : /^[a-z]+$/, 'upper-alpha': /^[A-Z]+$/ },
     177                unorderedPatterns = { 'disc' : /[l\u00B7\u2002]/, 'circle' : /[\u006F\u00D8]/,'square' : /[\u006E\u25C6]/},
     178                listMarkerPatterns = { 'ol' : orderedPatterns, 'ul' : unorderedPatterns },
     179                romans = [ [1000, 'M'], [900, 'CM'], [500, 'D'], [400, 'CD'], [100, 'C'], [90, 'XC'], [50, 'L'], [40, 'XL'], [10, 'X'], [9, 'IX'], [5, 'V'], [4, 'IV'], [1, 'I'] ],
     180                alpahbets = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    129181
    130         CKEDITOR.plugins.pastefromword =
    131         {
    132                 utils :
    133                 {
    134                         // Create a <cke:listbullet> which indicate an list item type.
    135                         createListBulletMarker : function ( bulletStyle, bulletText )
    136                         {
    137                                 var marker = new CKEDITOR.htmlParser.element( 'cke:listbullet' ),
    138                                         listType;
     182        // Convert roman numbering back to decimal.
     183        function fromRoman( str )
     184         {
     185                 str = str.toUpperCase();
     186                 var l = romans.length, retVal = 0;
     187                 for ( var i = 0; i < l; ++i )
     188                 {
     189                         for ( var j = romans[i], k = j[1].length; str.substr( 0, k ) == j[1]; str = str.substr( k ) )
     190                                 retVal += j[ 0 ];
     191                 }
     192                 return retVal;
     193         }
    139194
    140                                 // TODO: Support more list style type from MS-Word.
    141                                 if ( !bulletStyle )
    142                                 {
    143                                         bulletStyle = 'decimal';
    144                                         listType = 'ol';
    145                                 }
    146                                 else if ( bulletStyle[ 2 ] )
    147                                 {
    148                                         if ( !isNaN( bulletStyle[ 1 ] ) )
    149                                                 bulletStyle = 'decimal';
    150                                         else if ( lowerRomanLiteralRegex.test( bulletStyle[ 1 ] ) )
    151                                                 bulletStyle = 'lower-roman';
    152                                         else if ( upperRomanLiteralRegex.test( bulletStyle[ 1 ] ) )
    153                                                 bulletStyle = 'upper-roman';
    154                                         else if ( /^[a-z]+$/.test( bulletStyle[ 1 ] ) )
    155                                                 bulletStyle = 'lower-alpha';
    156                                         else if ( /^[A-Z]+$/.test( bulletStyle[ 1 ] ) )
    157                                                 bulletStyle = 'upper-alpha';
    158                                         // Simply use decimal for the rest forms of unrepresentable
    159                                         // numerals, e.g. Chinese...
    160                                         else
    161                                                 bulletStyle = 'decimal';
    162 
    163                                         listType = 'ol';
    164                                 }
    165                                 else
    166                                 {
    167                                         if ( /[l\u00B7\u2002]/.test( bulletStyle[ 1 ] ) )
    168                                                 bulletStyle = 'disc';
    169                                         else if ( /[\u006F\u00D8]/.test( bulletStyle[ 1 ] ) )
    170                                                 bulletStyle = 'circle';
    171                                         else if ( /[\u006E\u25C6]/.test( bulletStyle[ 1 ] ) )
    172                                                 bulletStyle = 'square';
    173                                         else
    174                                                 bulletStyle = 'disc';
    175 
    176                                         listType = 'ul';
    177                                 }
     195        // Convert alphabet numbering back to decimal.
     196        function fromAlphabet( str )
     197        {
     198                str = str.toUpperCase();
     199                var l = alpahbets.length, retVal = 1;
     200                for ( var x = 1; str.length > 0; x *= l )
     201                {
     202                        retVal += alpahbets.indexOf( str.charAt( str.length - 1 ) ) * x;
     203                        str = str.substr( 0, str.length - 1 );
     204                }
     205                return retVal;
     206        }
    178207
    179                                 // Represent list type as CSS style.
    180                                 marker.attributes =
    181                                 {
    182                                         'cke:listtype' : listType,
    183                                         'style' : 'list-style-type:' + bulletStyle + ';'
    184                                 };
     208        var listBaseIndent = 0,
     209                previousListItemMargin = null,
     210                previousListId;
     211
     212        var plugin = ( CKEDITOR.plugins.pastefromword =
     213        {
     214                utils :
     215                {
     216                        // Create a <cke:listbullet> which indicate an list item type.
     217                        createListBulletMarker : function ( bullet, bulletText )
     218                        {
     219                                var marker = new CKEDITOR.htmlParser.element( 'cke:listbullet' );
     220                                marker.attributes = { 'cke:listsymbol' : bullet[ 0 ] };
    185221                                marker.add( new CKEDITOR.htmlParser.text( bulletText ) );
    186222                                return marker;
    187223                        },
     
    207243                                        listMarker;
    208244
    209245                                if ( ( listMarker = element.removeAnyChildWithName( 'cke:listbullet' ) )
    210                                           && listMarker.length
    211                                           && ( listMarker = listMarker[ 0 ] ) )
     246                                                && listMarker.length
     247                                                && ( listMarker = listMarker[ 0 ] ) )
    212248                                {
    213249                                        element.name = 'cke:li';
    214250
    215251                                        if ( attrs.style )
    216252                                        {
    217                                                 attrs.style = CKEDITOR.plugins.pastefromword.filters.stylesFilter(
     253                                                attrs.style = plugin.filters.stylesFilter(
    218254                                                                [
    219255                                                                        // Text-indent is not representing list item level any more.
    220256                                                                        [ 'text-indent' ],
    221257                                                                        [ 'line-height' ],
    222                                                                         // Resolve indent level from 'margin-left' value.
     258                                                                        // First attempt is to resolve indent level from on a constant margin increment.
    223259                                                                        [ ( /^margin(:?-left)?$/ ), null, function( margin )
    224260                                                                        {
    225                                                                                 // Be able to deal with component/short-hand form style.
     261                                                                                // Deal with component/short-hand form.
    226262                                                                                var values = margin.split( ' ' );
    227                                                                                 margin = CKEDITOR.plugins.pastefromword.utils.convertToPx( values[ 3 ] || values[ 1 ] || values [ 0 ] );
     263                                                                                margin = plugin.utils.convertToPx( values[ 3 ] || values[ 1 ] || values [ 0 ] );
    228264                                                                                margin = parseInt( margin, 10 );
    229265
    230                                                                                 // Figure out the indent unit by looking at the first increament.
    231                                                                                 if ( !listBaseIndent && previousListItemMargin != undefined && margin > previousListItemMargin )
     266                                                                                // Figure out the indent unit by checking the first time of incrementation.
     267                                                                                if ( !listBaseIndent && previousListItemMargin != null && margin > previousListItemMargin )
    232268                                                                                        listBaseIndent = margin - previousListItemMargin;
    233269
    234                                                                                 attrs[ 'cke:margin' ] = previousListItemMargin = margin;
     270                                                                                previousListItemMargin = margin;
     271
     272                                                                                attrs[ 'cke:indent' ] = listBaseIndent && ( Math.ceil( margin / listBaseIndent ) + 1 ) || 1;
     273                                                                        } ],
     274                                                                        // The best situation: "mso-list:l0 level1 lfo2" tells the belonged list root, list item indentation, etc.
     275                                                                        [ ( /^mso-list$/ ), null, function( val )
     276                                                                        {
     277                                                                                val = val.split( ' ' );
     278                                                                                var listId = Number( val[ 0 ].match( /\d+/ ) ),
     279                                                                                        indent = Number( val[ 1 ].match( /\d+/ ) );
     280
     281                                                                                listId !== previousListId && ( attrs[ 'cke:reset' ] = 1 );
     282                                                                                previousListId = listId;
     283                                                                                attrs[ 'cke:indent' ] = indent;
    235284                                                                        } ]
    236                                                         ] )( attrs.style, element ) || '' ;
     285                                                                ] )( attrs.style, element ) || '';
    237286                                        }
    238287
    239                                         // First level list item are always presented without a margin.
    240                                         !attrs[ 'cke:margin' ] && ( attrs[ 'cke:margin' ] = previousListItemMargin = 0 );
     288                                        // First level list item might be presented without a margin.
    241289
    242                                         // Inherit list-type-style from bullet.
    243                                         var listBulletAttrs = listMarker.attributes,
    244                                                 listBulletStyle = listBulletAttrs.style;
    245290
    246                                         element.addStyle( listBulletStyle );
    247                                         CKEDITOR.tools.extend( attrs, listBulletAttrs );
     291                                        // In case all above doesn't apply.
     292                                        if ( !attrs[ 'cke:indent' ] )
     293                                        {
     294                                                previousListItemMargin = 0;
     295                                                attrs[ 'cke:indent' ] = 1;
     296                                        }
     297
     298                                        // Inherit attributes from bullet.
     299                                        CKEDITOR.tools.extend( attrs, listMarker.attributes );
    248300                                        return true;
    249301                                }
     302                                // Current list disconnected.
     303                                else
     304                                        previousListId = previousListItemMargin = listBaseIndent = null;
    250305
    251306                                return false;
    252307                        },
     
    312367                                        // Resolve how many level nested.
    313368                                        while ( parent )
    314369                                        {
    315                                                 parent.attributes && parent.attributes[ 'cke:list'] && indentLevel++;
     370                                                parent.attributes && parent.attributes[ 'cke:list' ] && indentLevel++;
    316371                                                parent = parent.parent;
    317372                                        }
    318373
     
    351406                                                        }
    352407
    353408                                                        child.name = 'cke:li';
     409
     410                                                        // Inherit numbering from list root on the first list item.
     411                                                        attrs.start && !i && ( attributes.value = attrs.start );
     412
     413                                                        plugin.filters.stylesFilter(
     414                                                                [
     415                                                                    [ 'tab-stops', null, function( val )
     416                                                                        {
     417                                                                                var margin = val.split( ' ' )[ 1 ].match( cssLengthRelativeUnit );
     418                                                                                margin && ( previousListItemMargin = parseInt( plugin.utils.convertToPx( margin[ 0 ] ), 10 ) );
     419                                                                        } ],
     420                                                                        [ 'mso-list', null, function( val )
     421                                                                        {
     422                                                                                val = val.split( ' ' );
     423                                                                                var listId = Number( val[ 0 ].match( /\d+/ ) );
     424                                                                                listId !== previousListId && ( attributes[ 'cke:reset' ] = 1 );
     425                                                                                previousListId = listId;
     426                                                                        } ]
     427                                                                ] )( attributes.style );
     428
    354429                                                        attributes[ 'cke:indent' ] = indentLevel;
    355                                                         previousListItemMargin = 0;
    356430                                                        attributes[ 'cke:listtype' ] = element.name;
    357                                                         listStyleType && child.addStyle( 'list-style-type', listStyleType, true );
     431                                                        attributes[ 'cke:list-style-type' ] = listStyleType;
    358432                                                }
    359433                                        }
    360434
     
    374448                                        var children = element.children, child,
    375449                                                        listItem,   // The current processing cke:li element.
    376450                                                        listItemAttrs,
    377                                                         listType,   // Determine the root type of the list.
    378451                                                        listItemIndent, // Indent level of current list item.
     452                                                        lastIndent,
    379453                                                        lastListItem, // The previous one just been added to the list.
    380                                                         list, parentList, // Current staging list and it's parent list if any.
    381                                                         indent;
     454                                                        list, // Current staging list and it's parent list if any.
     455                                                        openedLists = [],
     456                                                        previousListStyleType,
     457                                                        previousListType;
    382458
     459                                        // Properties of the list item are to be resolved from the list bullet.
     460                                        var bullet,
     461                                                listType,
     462                                                listStyleType,
     463                                                itemNumeric;
     464
    383465                                        for ( var i = 0; i < children.length; i++ )
    384466                                        {
    385467                                                child = children[ i ];
     
    389471                                                        child.name = 'li';
    390472                                                        listItem = child;
    391473                                                        listItemAttrs = listItem.attributes;
    392                                                         listType = listItem.attributes[ 'cke:listtype' ];
     474                                                        bullet = listItemAttrs[ 'cke:listsymbol' ];
     475                                                        bullet = bullet && bullet.match( /^(?:[(]?)([^\s]+?)([.)]?)$/ );
     476                                                        listType = listStyleType = itemNumeric = null;
    393477
     478                                                        if ( listItemAttrs[ 'cke:ignored' ] )
     479                                                        {
     480                                                                children.splice( i--, 1 );
     481                                                                continue;
     482                                                        }
     483
     484
     485                                                        // This's from a new list root.
     486                                                        listItemAttrs[ 'cke:reset' ] && ( list = lastIndent = lastListItem = null );
     487
    394488                                                        // List item indent level might come from a real list indentation or
    395489                                                        // been resolved from a pseudo list item's margin value, even get
    396490                                                        // no indentation at all.
    397                                                         listItemIndent = parseInt( listItemAttrs[ 'cke:indent' ], 10 )
    398                                                                                                         || listBaseIndent && ( Math.ceil( listItemAttrs[ 'cke:margin' ] / listBaseIndent ) + 1 )
    399                                                                                                         || 1;
     491                                                        listItemIndent = Number( listItemAttrs[ 'cke:indent' ] );
    400492
    401                                                         // Ignore the 'list-style-type' attribute if it's matched with
    402                                                         // the list root element's default style type.
    403                                                         listItemAttrs.style && ( listItemAttrs.style =
    404                                                                 CKEDITOR.plugins.pastefromword.filters.stylesFilter(
    405                                                                         [
    406                                                                                 [ 'list-style-type', listType == 'ol' ? 'decimal' : 'disc' ]
    407                                                                         ] )( listItemAttrs.style )
    408                                                                         || '' );
     493                                                        // We're moving out of the current list, cleaning up.
     494                                                        if ( listItemIndent != lastIndent )
     495                                                                previousListType = previousListStyleType = null;
    409496
     497                                                        // List type and item style are already resolved.
     498                                                        if ( !bullet )
     499                                                        {
     500                                                                listType = listItemAttrs[ 'cke:listtype' ] || 'ol';
     501                                                                listStyleType = listItemAttrs[ 'cke:list-style-type' ] || 'decimal';
     502                                                        }
     503                                                        else
     504                                                        {
     505                                                                // Probably share the same list style type with previous list item,
     506                                                                // give it priority to avoid ambiguous between C(Alpha) and C.(Roman).
     507                                                                if ( previousListType && listMarkerPatterns[ previousListType ] [ previousListStyleType ].test( bullet[ 1 ] ) )
     508                                                                {
     509                                                                        listType = previousListType;
     510                                                                        listStyleType = previousListStyleType;
     511                                                                }
     512                                                                else
     513                                                                {
     514                                                                        for ( var type in listMarkerPatterns )
     515                                                                        {
     516                                                                                for ( var style in listMarkerPatterns[ type ] )
     517                                                                                {
     518                                                                                        if ( listMarkerPatterns[ type ][ style ].test( bullet[ 1 ] ) )
     519                                                                                        {
     520                                                                                                // Small numbering has higher priority, when dealing with ambiguous
     521                                                                                                // between C(Alpha) and C.(Roman).
     522                                                                                                if ( type == 'ol' && /alpha|roman/.test( style ) )
     523                                                                                                {
     524                                                                                                        var num = /roman/.test( style ) ? fromRoman( bullet[ 1 ] ) : fromAlphabet( bullet[ 1 ] );
     525                                                                                                        if ( !itemNumeric || num < itemNumeric )
     526                                                                                                        {
     527                                                                                                                itemNumeric = num;
     528                                                                                                                listType = type;
     529                                                                                                                listStyleType = style;
     530                                                                                                        }
     531                                                                                                }
     532                                                                                                else
     533                                                                                                {
     534                                                                                                        listType = type;
     535                                                                                                        listStyleType = style;
     536                                                                                                        break;
     537                                                                                                }
     538                                                                                        }
     539                                                                                }
     540                                                                        }
     541                                                                }
     542
     543                                                                // Simply use decimal/disc for the rest forms of unrepresentable
     544                                                                // numerals, e.g. Chinese..., but as long as there a second part
     545                                                                // included, it has a bigger chance of being a order list ;)
     546                                                                !listType && ( listType = bullet[ 2 ] ? 'ol' : 'ul' );
     547                                                        }
     548
     549                                                        previousListType = listType;
     550                                                        previousListStyleType = listStyleType || ( listType == 'ol' ? 'decimal' : 'disc' );
     551                                                        if ( listStyleType && listStyleType != ( listType == 'ol' ? 'decimal' : 'disc' ) )
     552                                                                listItem.addStyle( 'list-style-type', listStyleType );
     553
     554                                                        // Figure out start numbering.
     555                                                        if ( listType == 'ol' && bullet )
     556                                                        {
     557                                                                switch ( listStyleType )
     558                                                                {
     559                                                                        case 'decimal' :
     560                                                                                itemNumeric = Number( bullet[ 1 ] );
     561                                                                                break;
     562                                                                        case 'lower-roman':
     563                                                                        case 'upper-roman':
     564                                                                                itemNumeric = fromRoman( bullet[ 1 ] );
     565                                                                                break;
     566                                                                        case 'lower-alpha':
     567                                                                        case 'upper-alpha':
     568                                                                                itemNumeric = fromAlphabet( bullet[ 1 ] );
     569                                                                                break;
     570                                                                }
     571
     572                                                                // Always create the numbering, swipe out unnecessary ones later.
     573                                                                listItem.attributes.value = itemNumeric;
     574                                                        }
     575
     576                                                        // Start the list construction.
    410577                                                        if ( !list )
    411578                                                        {
    412                                                                 list = new CKEDITOR.htmlParser.element( listType );
     579                                                                openedLists.push( list = new CKEDITOR.htmlParser.element( listType ) );
    413580                                                                list.add( listItem );
    414581                                                                children[ i ] = list;
    415582                                                        }
    416583                                                        else
    417584                                                        {
    418                                                                 if ( listItemIndent > indent )
     585                                                                if ( listItemIndent > lastIndent )
    419586                                                                {
    420                                                                         list = new CKEDITOR.htmlParser.element( listType );
     587                                                                        openedLists.push( list = new CKEDITOR.htmlParser.element( listType ) );
    421588                                                                        list.add( listItem );
    422589                                                                        lastListItem.add( list );
    423590                                                                }
    424                                                                 else if ( listItemIndent < indent )
     591                                                                else if ( listItemIndent < lastIndent )
    425592                                                                {
    426593                                                                        // There might be a negative gap between two list levels. (#4944)
    427                                                                         var diff = indent - listItemIndent,
    428                                                                                 parent;
     594                                                                        var diff = lastIndent - listItemIndent,
     595                                                                                        parent;
    429596                                                                        while ( diff-- && ( parent = list.parent ) )
    430597                                                                                list = parent.parent;
    431598
     
    438605                                                        }
    439606
    440607                                                        lastListItem = listItem;
    441                                                         indent = listItemIndent;
     608                                                        lastIndent = listItemIndent;
    442609                                                }
    443                                                 else
    444                                                         list = null;
     610                                                else if ( list )
     611                                                        list = lastIndent = lastListItem = null;
    445612                                        }
    446613
    447                                         listBaseIndent = 0;
     614                                        for ( i = 0; i < openedLists.length; i++ )
     615                                                postProcessList( openedLists[ i ] );
     616
     617                                        list = lastIndent = lastListItem = previousListId = previousListItemMargin = listBaseIndent = null;
    448618                                },
    449619
    450620                                /**
     
    8941064                                                        });
    8951065
    8961066                                                        var listSymbol =  listSymbolNode && ( listSymbolNode.value || 'l.' ),
    897                                                                 listType = listSymbol.match( /^([^\s]+?)([.)]?)$/ );
    898                                                         return createListBulletMarker( listType, listSymbol );
    899                                                 }
     1067                                                                listType = listSymbol.match( /^(?:[(]?)([^\s]+?)([.)]?)$/ );
     1068
     1069                                                        if ( listType )
     1070                                                        {
     1071                                                                var marker = createListBulletMarker( listType, listSymbol );
     1072                                                                // Some non-existed list items might be carried by an inconsequential list, indicate by "mso-hide:all/display:none",
     1073                                                                // those are to be removed later, now mark it with "cke:ignored".
     1074                                                                var ancestor = element.getAncestor( 'span' );
     1075                                                                if ( ancestor && /mso-hide:\s*all|display:\s*none/.test( ancestor.attributes.style ) )
     1076                                                                        marker.attributes[ 'cke:ignored' ] = 1;
     1077                                                                return marker;
     1078                                                        }
     1079                                                }
    9001080
    9011081                                                // Update the src attribute of image element with href.
    9021082                                                var children = element.children,
     
    9411121                                        {
    9421122                                                if ( element.getAncestor( /h\d/ ) && !config.pasteFromWordNumberedHeadingToList )
    9431123                                                        delete element.name;
    944                                                 }
     1124                                        }
    9451125                                },
    9461126
    9471127                                attributeNames :
     
    9631143                                        // Provide a white-list of styles that we preserve, those should
    9641144                                        // be the ones that could later be altered with editor tools.
    9651145                                        [
     1146                                                // Leave list-style-type
     1147                                                [ /^list-style-type$/, null ],
     1148
    9661149                                                // Preserve margin-left/right which used as default indent style in the editor.
    9671150                                                [ ( /^margin$|^margin-(?!bottom|top)/ ), null, function( value, element, name )
    9681151                                                        {
     
    10691252                                                        {
    10701253                                                                // Bullet symbol could be either text or an image.
    10711254                                                                var listSymbol = listInfo[ 1 ] || ( imageInfo && 'l.' ),
    1072                                                                         listType = listSymbol && listSymbol.match( />([^\s]+?)([.)]?)</ );
     1255                                                                        listType = listSymbol && listSymbol.match( />(?:[(]?)([^\s]+?)([.)]?)</ );
    10731256                                                                return createListBulletMarker( listType, listSymbol );
    10741257                                                        }
    10751258
     
    10921275                                        : falsyFilter
    10931276                        };
    10941277                }
    1095         };
     1278        });
    10961279
    10971280        // The paste processor here is just a reduced copy of html data processor.
    10981281        var pasteProcessor = function()
© 2003 – 2022, CKSource sp. z o.o. sp.k. All rights reserved. | Terms of use | Privacy policy