Ticket #2885: 2885.patch

File 2885.patch, 16.3 KB (added by Garry Yao, 15 years ago)

This patch file requires 2871_4.patch

  • _source/plugins/toolbar/plugin.js

     
    211211                'Bold', 'Italic', 'Underline', 'Strike', '-',
    212212                'Subscript', 'Superscript', '-',
    213213                'SelectAll', 'RemoveFormat', '-',
    214                 'Smiley', 'HorizontalRule', 'SpecialChar', 'PageBreak'
     214                'Smiley', 'HorizontalRule', 'SpecialChar', 'PageBreak', '-',
     215                'CreateDiv'
    215216        ]
    216217];
  • _source/plugins/newcontainer/dialogs/newcontainer.js

     
     1/*
     2 * Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
     3 * For licensing, see LICENSE.html or http://ckeditor.com/license
     4 */
     5
     6CKEDITOR.dialog.add('newcontainer', function(editor) {
     7       
     8        /**
     9         * Set element attributes assigned by the dialog fields.
     10         */
     11        function receiveAttributesFromDialog( element )
     12        {
     13                var attributes = {}, fileldValue;
     14                this.foreach( function( field )
     15                {
     16                        //Ignore layout container
     17                        if( /^(?!vbox|hbox)/.test( field.type )
     18                                //Ignore empty value
     19                                && ( fileldValue = field.getValue() )
     20                                && !CKEDITOR.tools.isEmpty( fileldValue )
     21                                //TODO: Process 'elementStyle'
     22                                && 'elementStyle' !== field.id )       
     23                        {
     24                                // ignore default element attribute values
     25                                if( 'dir' === field.id
     26                                        && element.getComputedStyle( 'direction' ) === fileldValue )
     27                                        return true;
     28                                attributes[ field.id ] = fileldValue;
     29                        }
     30                } )     ;
     31                element.setAttributes( attributes );
     32        }
     33       
     34        /**
     35         * Read the dialog fields values from the specified element attributes.
     36         * @param {CKEDITOR.dom.element} element
     37         */
     38        function populateAttributesToDialog( element )
     39        {
     40                this.foreach( function( field )
     41                {
     42                        //Ignore layout container
     43                        if( /^(?!vbox|hbox)/.test( field.type )
     44                                //TODO: Process 'elementStyle'
     45                                && 'elementStyle' !== field.id )       
     46                        {
     47                                field.setValue( element.getAttribute( field.id ) || '' );
     48                        }
     49                } );
     50        }
     51       
     52        /**
     53         * Either create or detect the desired block containers among the selected ranges.
     54         * @param {Object} editor
     55         * @param {Object} containerTagName The tagName of the container.
     56         * @param {Object} isCreate Whether it's a creation process OR a detection process.
     57         */     
     58        function applyContainer(editor, containerTagName, isCreate)
     59        {
     60                // new adding containers OR detected pre-existed containers.
     61                var containers = [],
     62
     63                // All block level elements which contained by the ranges.
     64                containedBlocks = [], block;
     65
     66                // Get all ranges from the selection.
     67                var selection = editor.document.getSelection();
     68                var ranges = selection.getRanges();
     69                var i, l = ranges.length, iterator;
     70
     71                // Get the DTD definition for the element.
     72                var dtd = CKEDITOR.dtd[ containerTagName ];
     73                // collect all included block level elements
     74                for( i = 0 ; i < l ; i++ )
     75                {
     76                        iterator = ranges[ i ].createIterator();
     77                        while( ( block = iterator.getNextParagraph() ) )
     78                        {
     79                                // bypass dtd disallowed elements.
     80                                while( !dtd[ block.getName() ] )
     81                                        block = block.getParent();
     82                                // avoid duplicate
     83                                if( CKEDITOR.tools.indexOf( containedBlocks, block,
     84                                        compareNodes ) === -1 )
     85                                        containedBlocks.push( block );
     86                        }
     87                }
     88
     89                var blockGroups = groupByBlockLimit( containedBlocks ), l = blockGroups.length, ancestor, blockEl, containerEl;
     90                containedBlocks = [];
     91                for( i = 0 ; i < l ; i++ )
     92                {
     93                        ancestor = getNodesDeepMostAncestor( blockGroups[ i ] );
     94                       
     95                        if(isCreate)
     96                        {
     97                                containerEl = new CKEDITOR.dom.element( containerTagName ,
     98                                        editor.document );
     99                        }
     100                       
     101                        var j, s = blockGroups[ i ].length,
     102                        //Wrapped blocks counting
     103                        childCount = 0;
     104                        for( j = 0 ; j < s ; j++ )
     105                        {
     106                                blockEl = blockGroups[ i ][ j ];
     107
     108                                // Reconstruct the block list to only contain direct
     109                                // children of common ancestor.
     110                                while( !blockEl.getParent().equals( ancestor ) )
     111                                        blockEl = blockEl.getParent();
     112
     113                                // avoid duplicate
     114                                if( CKEDITOR.tools.indexOf( containedBlocks, blockEl,
     115                                        compareNodes ) === -1 )
     116                                {
     117                                        if( isCreate )
     118                                        {
     119                                                // Establish new container, wrapping all
     120                                                // elements in this group.
     121                                                if( j == 0 )
     122                                                        containerEl.insertBefore( blockEl );
     123                                                containerEl.append( blockEl );
     124                                                containedBlocks.push( blockEl );
     125                                        }
     126                                        else
     127                                                childCount++;
     128                                }
     129                        }
     130
     131                        if( isCreate )
     132                        {
     133                                // drop pre-existed container, since new container already established.
     134                                if( ancestor.getName() === containerTagName
     135                                        && 1 === ancestor.getNonEmptyChildren().length )
     136                                        ancestor.remove( true );
     137                                containers.push( containerEl );
     138                        }
     139                        else
     140                        {
     141                                // discover existed container
     142                                if( ancestor.getName() === containerTagName
     143                                        && childCount === ancestor.getNonEmptyChildren().length )
     144                                        containers.push( ancestor );
     145                        }
     146                }
     147
     148                return containers;
     149        }
     150       
     151        /**
     152         * Divide a set of nodes to different groups by their path's blocklimit element.
     153         * Note: the specified nodes should be in source order naturally, which mean they are supposed to producea by following class:
     154         *  * CKEDITOR.dom.range.Iterator
     155         *  * CKEDITOR.dom.domWalker
     156         *  @return {Array []} the grouped nodes
     157         */
     158        function groupByBlockLimit(nodes)
     159        {
     160                var groups = [],
     161                        lastBlockLimit = null,
     162                        path;
     163                for ( var i = 0 ; i < nodes.length ; i++ )
     164                {
     165                        block = nodes[i] ;
     166                        path = new CKEDITOR.dom.elementPath( block ) ;
     167                        if ( !path.blockLimit.equals(lastBlockLimit ) )
     168                        {
     169                                groups.push( [] ) ;
     170                                lastBlockLimit = path.blockLimit ;
     171                        }
     172                        groups[groups.length - 1].push( block ) ;
     173                }
     174                return groups;
     175        }
     176       
     177        /**
     178         * Find the deep-most common ancestor of a set of dom nodes.
     179         * Note: This method will report 'body' node as result if nothing satisfied.
     180         * @param {Array<CKEDITOR.dom.node>} nodes a set of dom nodes
     181         * @return {CKEDITOR.dom.node} The DCA result
     182         */
     183        function getNodesDeepMostAncestor( nodes )
     184        {
     185                var range , currentDCA;
     186                if(nodes.length === 1)
     187                        return nodes[0].getParent();
     188               
     189                nodes = CKEDITOR.tools.cloneArray( nodes);
     190                while ( nodes.length > 1 )
     191                {
     192                        range = new CKEDITOR.dom.range();
     193                        range.startContainer = nodes[ 0 ];
     194                        range.endContainer = nodes[ 1 ];
     195                        currentDCA = range.getCommonAncestor( false );
     196                        if ( currentDCA.getName() === 'body' )
     197                                return currentDCA;
     198                        else
     199                                nodes.splice( 0 , 2 , currentDCA );
     200                }
     201                return nodes[ 0 ];
     202        }
     203       
     204        function compareNodes()
     205        {
     206                return arguments[0].equals(arguments[1]);
     207        }
     208       
     209        /**
     210         * Hold a collection of created block container elements. 
     211         */
     212        var containers = [];
     213       
     214        return {
     215                title : editor.lang.newcontainer.title,
     216                minWidth : 400,
     217                minHeight : 320,
     218                contents : [{
     219                        id : 'info',
     220                        label : editor.lang.newcontainer.generalTabLabel,
     221                        title : editor.lang.newcontainer.generalTabLabel,
     222                        elements : [{
     223                                type : 'hbox',
     224                                widths : ['50%', '50%'],
     225                                children : [{
     226                                                        id : 'elementStyle',
     227                                                        type : 'select',
     228                                                        style : 'width: 100%;',
     229                                                        label : editor.lang.newcontainer.styleSelectLabel,
     230                                                        'default' : editor.config.newcontainer.defaultValues.style,
     231                                                        items : []      //      TODO: Fill 'elementStyle' selection options.
     232                                                },{
     233                                                        id : 'class',
     234                                                        type : 'text',
     235                                                        label : editor.lang.newcontainer.cssClassInputLabel,
     236                                                        'default' : editor.config.newcontainer.defaultValues.cssClass
     237                                                }]
     238                        }]
     239                }, {
     240                        id : 'advanced',
     241                        label : editor.lang.newcontainer.advancedTabLabel,
     242                        title : editor.lang.newcontainer.advancedTabLabel,
     243                        elements : [{
     244                                type : 'vbox',
     245                                padding : 1,
     246                                children : [{
     247                                        type : 'hbox',
     248                                        widths : ['50%', '50%'],
     249                                        children : [{
     250                                                                type : 'text',
     251                                                                id : 'id',
     252                                                                label : editor.lang.newcontainer.IdInputLabel,
     253                                                                'default' : editor.config.newcontainer.defaultValues.Id
     254                                                        }, {
     255                                                                type : 'text',
     256                                                                id : 'lang',
     257                                                                label : editor.lang.newcontainer.languageCodeInputLabel,
     258                                                                'default' : editor.config.newcontainer.defaultValues.languageCode
     259                                                        }]
     260                                }, {
     261                                        type : 'hbox',
     262                                        children : [{
     263                                                                type : 'text',
     264                                                                id : 'style',
     265                                                                style : 'width: 100%;',
     266                                                                label : editor.lang.newcontainer.inlineStyleInputLabel,
     267                                                                'default' : editor.config.newcontainer.defaultValues.inlineStyle
     268                                                        }]
     269                                }, {
     270                                        type : 'hbox',
     271                                        children : [{
     272                                                type : 'text',
     273                                                id : 'title',
     274                                                style : 'width: 100%;',
     275                                                label : editor.lang.newcontainer.advisoryTitleInputLabel,
     276                                                'default' : editor.config.newcontainer.defaultValues.advisoryTitle
     277                                        }]
     278                                }, {
     279                                        type : 'select',
     280                                        id : 'dir',
     281                                        style : 'width: 100%;',
     282                                        label : editor.lang.newcontainer.langDirLabel,
     283                                        'default' : editor.config.newcontainer.defaultValues.langDirLabel,
     284                                        items : [ [ editor.lang.newcontainer.langDirOptions.langDirLTRLabel, 'ltr' ],
     285                                                        [ editor.lang.newcontainer.langDirOptions.langDirRTLLabel, 'rtl'] ]
     286                                }]
     287                        }]
     288                }],
     289                onShow : function()
     290                {
     291                        containers = [];
     292                        // Whether always create new container regardless of existed
     293                        // ones.
     294                        if( !editor.config.newcontainer.alwaysCreate )
     295                        {
     296                                if( CKEDITOR.env.ie )
     297                                        this.restoreSelection();
     298                                // Try to collect the containers that already existed in
     299                                // ranges
     300                                containers = applyContainer( editor, 'div' );
     301                                if( containers.length )
     302                                {
     303                                        // update dialog field values
     304                                        populateAttributesToDialog.call( this, containers[ 0 ] );
     305                                }
     306                        }
     307                },
     308                onOk : function()
     309                {
     310                        if( CKEDITOR.env.ie )
     311                                this.restoreSelection();
     312                        containers = applyContainer( editor, 'div', true );
     313                       
     314                        // update elements attributes
     315                        var i, l = containers.length;
     316                        for( i = 0 ; i < l ; i++ )
     317                        {
     318                                receiveAttributesFromDialog.call( this, containers[ i ] );
     319                        }
     320                       
     321                        this.hide();
     322                }
     323        };
     324});
  • _source/plugins/newcontainer/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 "newcontainer" plugin. It wraps the selected block level elements with a 'div' element with specified styles and attributes.
     8 *
     9 */
     10
     11( function()
     12{
     13        CKEDITOR.plugins.add( 'newcontainer', {
     14                requires : [ 'editingblock', 'domiterator', 'elementspath' ],
     15
     16                init : function( editor )
     17                {
     18
     19                        editor.addCommand( 'creatediv',
     20                                new CKEDITOR.dialogCommand( 'newcontainer' ) );
     21                        editor.ui.addButton( 'CreateDiv', {
     22                                label :editor.lang.newcontainer.toolbar,
     23                                command :'creatediv'
     24                        } );
     25                        CKEDITOR.dialog.add( 'newcontainer',
     26                                this.path + 'dialogs/newcontainer.js' );
     27                }
     28        } );
     29
     30} )();
     31
     32CKEDITOR.config.newcontainer = {
     33       
     34        /**
     35         * Whether ignore the pre-existed containers
     36         */
     37        alwaysCreate :false,
     38        defaultValues : {
     39                title :'',
     40                cssClass :'',
     41                style :'',
     42                Id :'',
     43                languageCode :'',
     44                inlineStyle :'',
     45                advisoryTitleInput :'',
     46                langDir :'ltr'
     47        }
     48};
  • _source/core/dom/element.js

     
    360360                {
    361361                        return new CKEDITOR.dom.nodeList( this.$.childNodes );
    362362                },
     363               
     364                /**
     365                 * Same as CKEDITOR.dom.element::getChildren except this method ignore
     366                 * text nodes which contains only blank characters.
     367                 * @return {Array} 
     368                 */
     369                getNonEmptyChildren : function()
     370                {
     371                        var resultsChilds = [];
     372                        var children = this.getChildren();
     373                        var i, l = children.count(), child;
     374                        for( i = 0 ; i < l ; i++ )
     375                        {
     376                                child = children.getItem( i );
     377                                if( ! ( child.type === CKEDITOR.NODE_TEXT
     378                                        && /[ \t\n\r]+/.test( child.getText() ) ) )
     379                                        resultsChilds.push( child );
     380                        }
     381                        return resultsChilds;
     382                },
    363383
    364384                /**
    365385                 * Gets the current computed value of one of the element CSS style
  • _source/core/tools.js

     
    296296         * Returns the index of an element in an array.
    297297         * @param {Array} array The array to be searched.
    298298         * @param {Object} entry The element to be found.
     299         * @param {Function} equalFunc The comparator function.
    299300         * @returns {Number} The (zero based) index of the first entry that matches
    300301         *              the entry, or -1 if not found.
    301302         * @example
     
    302303         * var letters = [ 'a', 'b', 'c' ];
    303304         * alert( CKEDITOR.tools.indexOf( letters, 'b' ) );  "1"
    304305         */
    305         indexOf : function( array, entry )
     306        indexOf : function( array, entry , equalFunc)
    306307        {
    307308                for ( var i = 0, len = array.length ; i < len ; i++ )
    308309                {
    309                         if ( array[ i ] == entry )
     310                        if ( equalFunc? equalFunc(array[ i ], entry) : array[ i ] == entry )
    310311                                return i;
    311312                }
    312313                return -1;
     314        },
     315       
     316        /**
     317         * Examine if the object is meaningless, which yield a falsy value but except number '0' and boolean 'false'.
     318         * @param {Object} object
     319         */
     320        isEmpty : function( object )
     321        {
     322                return object === null ||( typeof object === 'undefined' ) || object === '';
     323        },
     324       
     325        /**
     326         * Shallow copy all items inside an Array.
     327         * @param {Array} array
     328         */
     329        cloneArray: function( array ) {
     330                return [].concat( array );
    313331        }
     332       
    314333};
    315334
    316335// PACKAGER_RENAME( CKEDITOR.tools )
  • _source/core/config.js

     
    146146         * @example
    147147         * config.plugins = 'basicstyles,button,htmldataprocessor,toolbar,wysiwygarea';
    148148         */
    149         plugins : 'basicstyles,button,elementspath,horizontalrule,htmldataprocessor,keystrokes,newpage,pagebreak,removeformat,smiley,sourcearea,specialchar,tab,toolbar,wysiwygarea',
     149        plugins : 'basicstyles,button,elementspath,horizontalrule,htmldataprocessor,keystrokes,newpage,pagebreak,removeformat,smiley,sourcearea,specialchar,tab,toolbar,wysiwygarea,newcontainer',
    150150
    151151        /**
    152152         * The theme to be used to build the UI.
  • _source/lang/en.js

     
    99 */
    1010
    1111/**#@+
    12    @type String
    13    @example
     12@type String
     13@example
    1414*/
    1515
    1616/**
     
    329329                chkLoop         : 'Loop',
    330330                chkMenu         : 'Enable Flash Menu',
    331331                chkFull         : 'Allow Fullscreen',
    332                 scale           : 'Scale',
     332                scale           : 'Scale',
    333333                scaleAll                : 'Show all',
    334334                scaleNoBorder   : 'No Border',
    335335                scaleFit                : 'Exact Fit',
     
    366366        elementsPath :
    367367        {
    368368                eleTitle : '%1 element'
     369        },
     370       
     371        newcontainer :
     372        {
     373                title: 'Create Div Container',
     374                toolbar: 'Create Div Container',
     375                generalTabLabel : 'General',
     376                advancedTabLabel: 'Advanced',
     377                cssClassInputLabel : 'Stylesheet Classes',
     378                styleSelectLabel : 'Style',
     379                IdInputLabel: 'Id',
     380                languageCodeInputLabel : ' Language Code',
     381                inlineStyleInputLabel : 'Inline Style',
     382                advisoryTitleInputLabel : 'Advisory Title',
     383                langDirLabel : 'Language Direction',
     384                langDirOptions : {
     385                        langDirLTRLabel : 'Left to Right (LTR)',
     386                        langDirRTLLabel : 'Right to Left (RTL)'
     387                }
    369388        }
    370389};
  • _source/skins/default/toolbar.css

     
    305305{
    306306        background-position: 0 -880px;
    307307}
     308.cke_skin_default a.cke_button_creatediv .cke_icon
     309{
     310        background-position: 0 -1168px;
     311}
© 2003 – 2022, CKSource sp. z o.o. sp.k. All rights reserved. | Terms of use | Privacy policy