Ticket #2885: 2885_3.patch

File 2885_3.patch, 17.7 KB (added by garry.yao, 6 years ago)
  • _source/plugins/div/dialogs/div.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 
     6(function() 
     7{ 
     8         
     9        /** 
     10         * Add to collection with DUP examination. 
     11         * @param {Object} collection 
     12         * @param {Object} element 
     13         * @param {Object} database 
     14         */ 
     15        function addSafely( collection, element, database ) 
     16        { 
     17                // avoid duplicate 
     18                if ( !element.getCustomData( 'block_processed' ) ) 
     19                { 
     20                        CKEDITOR.dom.element.setMarker( database, element, 
     21                                'block_processed', true ); 
     22                        collection.push( element ); 
     23                } 
     24        } 
     25         
     26        /** 
     27         * Dialog reused by both 'creatediv' and 'editdiv' commands. 
     28         * @param {Object} editor 
     29         * @param {String} command      The command name which indicate what the current command is. 
     30         */ 
     31        function divDialog( editor, command ) { 
     32                 
     33                // Definition of elements at which div operation should stopped. 
     34                var divLimitDefiniton = (function(){ 
     35                         
     36                        // Customzie from specialize blockLimit elements 
     37                        var definition = CKEDITOR.tools.extend( {},  
     38                        CKEDITOR.dom.elementPath.pathBlockLimitElements ); 
     39                        // Exclude 'div' itself. 
     40                        delete definition.div; 
     41                        // Exclude 'td' and 'th' when 'wrapping table'  
     42                        if( editor.config.div_wrapTable) 
     43                        { 
     44                                delete definition.td; 
     45                                delete definition.th; 
     46                        } 
     47                        return definition; 
     48                })(); 
     49                 
     50                // DTD of 'div' element 
     51                var dtd = CKEDITOR.dtd.div; 
     52                 
     53                /** 
     54                 * Get the first div limit element on the element's path. 
     55                 * @param {Object} element 
     56                 */ 
     57                function getDivLimitElement( element ) 
     58                { 
     59                        var pathElements = new CKEDITOR.dom.elementPath( element ).elements; 
     60                        var i, l = pathElements.length, divLimit; 
     61                        for ( i = 0; i < l; i++ )  
     62                        { 
     63                                if ( pathElements[ i ].getName() in divLimitDefiniton )  
     64                                { 
     65                                        divLimit = pathElements[ i ]; 
     66                                        break; 
     67                                } 
     68                        } 
     69                        return divLimit; 
     70                } 
     71                 
     72                /** 
     73                 * Init all fields' setup/commit function. 
     74                 * @memberof divDialog 
     75                 */ 
     76                function setupFields() 
     77                { 
     78                        this.foreach( function( field ) 
     79                        { 
     80                                //Exclude layout container elements 
     81                                if( /^(?!vbox|hbox)/.test( field.type ))         
     82                                { 
     83                                        if ( !field.setup ) 
     84                                        { 
     85                                                // Read the dialog fields values from the specified 
     86                                                // element attributes. 
     87                                                field.setup = function( element ) 
     88                                                { 
     89                                                        field.setValue( element.getAttribute( field.id ) || '' ); 
     90                                                }; 
     91                                        } 
     92                                        if ( !field.commit ) 
     93                                        { 
     94                                                // Set element attributes assigned by the dialog 
     95                                                // fields. 
     96                                                field.commit = function( element ) 
     97                                                { 
     98                                                        var fieldValue = this.getValue(); 
     99                                                        // ignore default element attribute values 
     100                                                        if ( 'dir' == field.id 
     101                                                                && element.getComputedStyle( 'direction' ) == fieldValue ) 
     102                                                                return true; 
     103                                                        if ( fieldValue ) 
     104                                                                element.setAttribute( field.id, fieldValue ); 
     105                                                }; 
     106                                        } 
     107                                } 
     108                        } ); 
     109                } 
     110                 
     111                /** 
     112                 * Either create or detect the desired block containers among the selected ranges. 
     113                 * @param {Object} editor 
     114                 * @param {Object} containerTagName The tagName of the container. 
     115                 * @param {Object} isCreate Whether it's a creation process OR a detection process. 
     116                 */      
     117                function applyDiv( editor, isCreate ) 
     118                { 
     119                        // new adding containers OR detected pre-existed containers. 
     120                        var containers = [], 
     121                        // node markers store.  
     122                        database = {}, 
     123                        // All block level elements which contained by the ranges. 
     124                        containedBlocks = [], block; 
     125         
     126                        // Get all ranges from the selection. 
     127                        var selection = editor.document.getSelection(); 
     128                        var ranges = selection.getRanges(); 
     129                        var i, l = ranges.length, iterator; 
     130         
     131                        // collect all included elements from dom-iterator 
     132                        for( i = 0 ; i < l ; i++ ) 
     133                        { 
     134                                iterator = ranges[ i ].createIterator(); 
     135                                while( ( block = iterator.getNextParagraph() ) ) 
     136                                { 
     137                                        // include contents of blockLimit elements. 
     138                                        if( block.getName() in divLimitDefiniton ) 
     139                                        { 
     140                                                var j, childNodes = block.getChildren(), s = childNodes.count(); 
     141                                                for ( j = 0; j < s; j++) { 
     142                                                        addSafely( containedBlocks, childNodes.getItem( j ) , database ); 
     143                                                } 
     144                                        } 
     145                                        else 
     146                                        { 
     147                                                // Bypass dtd disallowed elements.       
     148                                                while( !dtd[ block.getName() ] && block.getName() != 'body' ) 
     149                                                { 
     150                                                        block = block.getParent(); 
     151                                                } 
     152                                                addSafely( containedBlocks, block, database ); 
     153                                        } 
     154                                } 
     155                        } 
     156                         
     157                        CKEDITOR.dom.element.clearAllMarkers(database); 
     158                         
     159                        var blockGroups = groupByDivLimit( containedBlocks ),  
     160                                l = blockGroups.length, ancestor, blockEl, divElement; 
     161                        for( i = 0 ; i < l ; i++ ) 
     162                        { 
     163                                var currentBlock = blockGroups[ i ][0]; 
     164                                 
     165                                // Calculate the common parent node of all contained elements. 
     166                                ancestor = currentBlock .getParent(); 
     167                                var j  = 1, s = blockGroups[ i ].length; 
     168                                for ( ; j < s; j++ ) 
     169                                        ancestor = ancestor.getCommonAncestor( blockGroups[ i ][ j ] ); 
     170                                 
     171                                if(isCreate) 
     172                                { 
     173                                        divElement = new CKEDITOR.dom.element( 'div' , 
     174                                                editor.document ); 
     175                                } 
     176                                 
     177                                var j, s = blockGroups[ i ].length, 
     178                                //Wrapped blocks counting 
     179                                childCount = 0; 
     180                                for( j = 0; j < s; j++ ) 
     181                                { 
     182                                        currentBlock = blockGroups[ i ][ j ]; 
     183         
     184                                        // Reconstruct the block list to only contain direct 
     185                                        // children of common ancestor. 
     186                                        while( !currentBlock.getParent().equals( ancestor ) ) 
     187                                                currentBlock = currentBlock.getParent(); 
     188         
     189                                        // Avoid DUP 
     190                                        if ( !currentBlock.getCustomData( 'block_processed' ) ) 
     191                                        { 
     192                                                CKEDITOR.dom.element.setMarker( database, currentBlock, 'block_processed', true ); 
     193                                                if( isCreate ) 
     194                                                { 
     195                                                        // Establish new container, wrapping all 
     196                                                        // elements in this group. 
     197                                                        if( j == 0 ) 
     198                                                                divElement.insertBefore( currentBlock ); 
     199                                                        divElement.append( currentBlock ); 
     200                                                } 
     201                                                else 
     202                                                        childCount++; 
     203                                        } 
     204                                } 
     205                                CKEDITOR.dom.element.clearAllMarkers( database ); 
     206         
     207                                if( isCreate ) 
     208                                { 
     209                                        // drop pre-existed container, since new container already 
     210                                        // established. 
     211                                        if ( command == 'editdiv' && 
     212                                                        ancestor.getName() == 'div' 
     213                                                        && 1 == ancestor.getNonEmptyChildren().length ) 
     214                                                        ancestor.remove( true ); 
     215                                        containers.push( divElement ); 
     216                                } 
     217                                else 
     218                                { 
     219                                        // discover existed container 
     220                                        if ( ancestor.getName() == 'div' 
     221                                                && childCount == ancestor.getNonEmptyChildren().length ) 
     222                                                containers.push( ancestor ); 
     223                                } 
     224                        } 
     225         
     226                        return containers; 
     227                } 
     228                 
     229                /** 
     230                 * Divide a set of nodes to different groups by their path's blocklimit element. 
     231                 * Note: the specified nodes should be in source order naturally, which mean they are supposed to producea by following class: 
     232                 *  * CKEDITOR.dom.range.Iterator 
     233                 *  * CKEDITOR.dom.domWalker 
     234                 *  @return {Array []} the grouped nodes 
     235                 */ 
     236                function groupByDivLimit( nodes ) 
     237                { 
     238                        var groups = [], 
     239                                lastDivLimit = null, 
     240                                path, block; 
     241                        for ( var i = 0 ; i < nodes.length ; i++ ) 
     242                        { 
     243                                block = nodes[i]; 
     244                                var limit = getDivLimitElement( block ); 
     245                                if ( !limit.equals( lastDivLimit ) ) 
     246                                { 
     247                                        lastDivLimit = limit ; 
     248                                        groups.push( [] ) ; 
     249                                } 
     250                                groups[ groups.length - 1 ].push( block ) ; 
     251                        } 
     252                        return groups; 
     253                } 
     254                 
     255                function compareNodes() 
     256                { 
     257                        return arguments[ 0 ].equals( arguments[ 1 ] ); 
     258                } 
     259                 
     260                /** 
     261                 * Hold a collection of created block container elements.   
     262                 */ 
     263                var containers = []; 
     264                /** 
     265                 * @type divDialog 
     266                 */  
     267                return { 
     268                        title : editor.lang.div.title, 
     269                        minWidth : 400, 
     270                        minHeight : 320, 
     271                        contents :  
     272                        [ 
     273                        { 
     274                                id :'info', 
     275                                label :editor.lang.common.generalTab, 
     276                                title :editor.lang.common.generalTab, 
     277                                elements :  
     278                                [ 
     279                                        { 
     280                                                type :'hbox', 
     281                                                widths : [ '50%', '50%' ], 
     282                                                children :  
     283                                                [ 
     284                                                        { 
     285                                                                id :'elementStyle', 
     286                                                                type :'select', 
     287                                                                style :'width: 100%;', 
     288                                                                label :editor.lang.div.styleSelectLabel, 
     289                                                                'default' :editor.config.div_defaultStyle, 
     290                                                                items : [], 
     291                                                                setup : function(){ 
     292                                                                        //TODO: Read 'elementStyle' field 
     293                                                                }, 
     294                                                                commit: function() 
     295                                                                { 
     296                                                                        //TODO: Commit 'elementStyle' field value 
     297                                                                } 
     298                                                        // TODO: Fill 'elementStyle' selection options. 
     299                                                        }, 
     300                                                        { 
     301                                                                id :'class', 
     302                                                                type :'text', 
     303                                                                label :editor.lang.common.cssClass, 
     304                                                                'default' :editor.config.div_defaultCssClass 
     305                                                        }  
     306                                                ] 
     307                                        }  
     308                                ] 
     309                        }, 
     310                        { 
     311                                        id :'advanced', 
     312                                        label :editor.lang.common.advancedTab, 
     313                                        title :editor.lang.common.advancedTab, 
     314                                        elements :  
     315                                        [ 
     316                                        { 
     317                                                type :'vbox', 
     318                                                padding :1, 
     319                                                children :  
     320                                                [ 
     321                                                        { 
     322                                                                type :'hbox', 
     323                                                                widths : [ '50%', '50%' ], 
     324                                                                children :  
     325                                                                [ 
     326                                                                        { 
     327                                                                                type :'text', 
     328                                                                                id :'id', 
     329                                                                                label :editor.lang.common.id, 
     330                                                                                'default' :editor.config.div_defaultId 
     331                                                                        }, 
     332                                                                        { 
     333                                                                                type :'text', 
     334                                                                                id :'lang', 
     335                                                                                label :editor.lang.link.langCode, 
     336                                                                                'default' :editor.config.div_defaultLanguageCode 
     337                                                                        }  
     338                                                                ] 
     339                                                        }, 
     340                                                        { 
     341                                                                type :'hbox', 
     342                                                                children :  
     343                                                                [ 
     344                                                                                { 
     345                                                                                        type :'text', 
     346                                                                                        id :'style', 
     347                                                                                        style :'width: 100%;', 
     348                                                                                        label :editor.lang.common.cssStyle, 
     349                                                                                        'default' :editor.config.div_defaultInlineStyle 
     350                                                                                }  
     351                                                                ] 
     352                                                        }, 
     353                                                        { 
     354                                                                type :'hbox', 
     355                                                                children :  
     356                                                                [ 
     357                                                                                { 
     358                                                                                        type :'text', 
     359                                                                                        id :'title', 
     360                                                                                        style :'width: 100%;', 
     361                                                                                        label :editor.lang.common.advisoryTitle, 
     362                                                                                        'default' :editor.config.div_defaultAdvisoryTitle 
     363                                                                                }  
     364                                                                ] 
     365                                                        }, 
     366                                                        { 
     367                                                                type :'select', 
     368                                                                id :'dir', 
     369                                                                style :'width: 100%;', 
     370                                                                label :editor.lang.common.langDir, 
     371                                                                'default' :editor.config.div_defaultLangDirLabel, 
     372                                                                items :  
     373                                                                [ 
     374                                                                        [ 
     375                                                                                editor.lang.common.langDirLtr, 
     376                                                                                'ltr'  
     377                                                                        ], 
     378                                                                        [ 
     379                                                                                editor.lang.common.langDirRtl, 
     380                                                                                'rtl'  
     381                                                                        ]  
     382                                                                ] 
     383                                                        }  
     384                                                ] 
     385                                        }  
     386                                        ] 
     387                                }  
     388                        ], 
     389                        onLoad : function() 
     390                        { 
     391                                setupFields.call(this); 
     392                        }, 
     393                        onShow : function() 
     394                        { 
     395                                containers = []; 
     396                                // Whether always create new container regardless of existed 
     397                                // ones. 
     398                                if ( command == 'editdiv' ) 
     399                                { 
     400                                        if( CKEDITOR.env.ie ) 
     401                                                this.restoreSelection(); 
     402                                                 
     403                                        // Try to discover the containers that already existed in 
     404                                        // ranges 
     405                                        containers = applyDiv( editor ); 
     406                                        if( containers.length ) 
     407                                        { 
     408                                                this._element = containers[ 0 ]; 
     409                                                // update dialog field values 
     410                                                this.setupContent( this._element ); 
     411                                        } 
     412                                } 
     413                        }, 
     414                        onOk : function() 
     415                        { 
     416                                if( CKEDITOR.env.ie ) 
     417                                        this.restoreSelection(); 
     418                                containers = applyDiv( editor, true ); 
     419                                 
     420                                // update elements attributes 
     421                                var i, l = containers.length; 
     422                                for( i = 0 ; i < l ; i++ ) 
     423                                { 
     424                                        this.commitContent( containers[ i ] ); 
     425                                } 
     426                                this.hide(); 
     427                        } 
     428                }; 
     429        } 
     430         
     431        CKEDITOR.dialog.add( 'creatediv', function( editor ) 
     432                { 
     433                        return divDialog( editor, 'creatediv' ); 
     434                } ); 
     435        CKEDITOR.dialog.add( 'editdiv', function( editor ) 
     436                { 
     437                        return divDialog( editor, 'editdiv' ); 
     438                } ); 
     439})(); 
     440 No newline at end of file 
  • _source/plugins/div/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 "div" plugin. It wraps the selected block level elements with a 'div' element with specified styles and attributes. 
     8 *  
     9 */ 
     10 
     11CKEDITOR.plugins.add( 'div',  
     12{ 
     13        requires : [ 'editingblock', 'domiterator', 'elementspath' ], 
     14 
     15        init : function( editor ){ 
     16         
     17                editor.addCommand( 'creatediv', new CKEDITOR.dialogCommand( 
     18                        'creatediv' ) ); 
     19                editor.addCommand( 'editdiv', new CKEDITOR.dialogCommand( 
     20                        'editdiv' ) ); 
     21                         
     22                editor.ui.addButton( 'CreateDiv', { 
     23                        label :editor.lang.div.toolbar, 
     24                        command :'creatediv' 
     25                } ); 
     26                // TODO: Adding 'editdiv' command button. 
     27                editor.ui.addButton( 'EditDiv', { 
     28                        label :editor.lang.div.toolbar, 
     29                        command :'editdiv' 
     30                } ); 
     31                 
     32                CKEDITOR.dialog.add( 'creatediv', 
     33                        this.path + 'dialogs/div.js' ); 
     34                CKEDITOR.dialog.add( 'editdiv', 
     35                        this.path + 'dialogs/div.js' ); 
     36        } 
     37} ); 
     38 
     39CKEDITOR.tools.extend(CKEDITOR.config,  
     40{ 
     41        /** 
     42         * Whether wrapping the whole table when created 'div' in table cell. 
     43         */ 
     44        div_wrapTable : false, 
     45        div_defaultCssClass :'', 
     46        div_defaultStyle :'', 
     47        div_defaultId :'', 
     48        div_defaultLanguageCode :'', 
     49        div_defaultInlineStyle :'', 
     50        div_defaultAdvisoryTitle :'', 
     51        div_defaultLangDir :'' 
     52}); 
  • _source/plugins/toolbar/plugin.js

     
    217217        ['Form', 'Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button', 'ImageButton', 'HiddenField'], 
    218218        '/', 
    219219        ['Bold','Italic','Underline','Strike','-','Subscript','Superscript'], 
    220         ['NumberedList','BulletedList','-','Outdent','Indent','Blockquote'], 
     220        ['NumberedList','BulletedList','-','Outdent','Indent','Blockquote','CreateDiv'], 
    221221        ['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'], 
    222222        ['Link','Unlink','Anchor'],     ['Image','Flash','Table','HorizontalRule','Smiley','SpecialChar','PageBreak'], 
    223223        '/', 
  • _source/lang/en.js

     
    453453                tag_h5 : 'Heading 5', 
    454454                tag_h6 : 'Heading 6', 
    455455                tag_div : 'Normal (DIV)' 
     456        }, 
     457         
     458        div : 
     459        { 
     460                title: 'Create Div Container', 
     461                toolbar: 'Create Div Container', 
     462                cssClassInputLabel : 'Stylesheet Classes', 
     463                styleSelectLabel : 'Style', 
     464                IdInputLabel: 'Id', 
     465                languageCodeInputLabel : ' Language Code', 
     466                inlineStyleInputLabel : 'Inline Style', 
     467                advisoryTitleInputLabel : 'Advisory Title', 
     468                langDirLabel : 'Language Direction', 
     469                langDirLTRLabel : 'Left to Right (LTR)', 
     470                langDirRTLLabel : 'Right to Left (RTL)' 
    456471        } 
    457472}; 
  • _source/skins/default/toolbar.css

     
    415415{ 
    416416        background-position: 0 -160px; 
    417417} 
     418 
     419.cke_skin_default a.cke_button_creatediv .cke_icon 
     420{ 
     421        background-position: 0 -1168px; 
     422} 
  • _source/core/config.js

     
    147147         * config.plugins = 'basicstyles,button,htmldataprocessor,toolbar,wysiwygarea'; 
    148148         */ 
    149149 
    150         plugins : 'basicstyles,blockquote,button,clipboard,elementspath,find,flash,format,forms,horizontalrule,htmldataprocessor,image,indent,justify,keystrokes,link,list,newpage,pagebreak,pastefromword,pastetext,preview,print,removeformat,smiley,showblocks,sourcearea,table,specialchar,tab,templates,toolbar,undo,wysiwygarea', 
     150        plugins : 'basicstyles,blockquote,button,clipboard,elementspath,find,flash,format,forms,horizontalrule,htmldataprocessor,image,indent,justify,keystrokes,link,list,div,newpage,pagebreak,pastefromword,pastetext,preview,print,removeformat,smiley,showblocks,sourcearea,table,specialchar,tab,templates,toolbar,undo,wysiwygarea', 
    151151 
    152152        /** 
    153153         * The theme to be used to build the UI. 
  • _source/core/dom/elementpath.js

     
    7474                this.blockLimit = blockLimit; 
    7575                this.elements = elements; 
    7676        }; 
     77        //Make bocklimit elements definition public visitable. 
     78        CKEDITOR.dom.elementPath.pathBlockLimitElements = pathBlockLimitElements; 
     79         
    7780})(); 
    7881 
    7982CKEDITOR.dom.elementPath.prototype = 
  • _source/core/dom/element.js

     
    409409                { 
    410410                        return new CKEDITOR.dom.nodeList( this.$.childNodes ); 
    411411                }, 
     412                 
     413                /** 
     414                 * Same as CKEDITOR.dom.element::getChildren except this method ignore 
     415                 * text nodes which contains only blank characters. 
     416                 * @return {Array}   
     417                 */ 
     418                getNonEmptyChildren : function() 
     419                { 
     420                        var resultsChilds = []; 
     421                        var children = this.getChildren(); 
     422                        var i, l = children.count(), child; 
     423                        for( i = 0 ; i < l ; i++ ) 
     424                        { 
     425                                child = children.getItem( i ); 
     426                                if( ! ( child.type === CKEDITOR.NODE_TEXT  
     427                                        && /^[ \t\n\r]+$/.test( child.getText() ) ) ) 
     428                                        resultsChilds.push( child ); 
     429                        } 
     430                        return resultsChilds; 
     431                }, 
    412432 
    413433                /** 
    414434                 * Gets the current computed value of one of the element CSS style 
© 2003 – 2012 CKSource – Frederico Knabben. All rights reserved. | Terms of use | Privacy policy