Ticket #3709: 3709.patch

File 3709.patch, 12.7 KB (added by Garry Yao, 12 years ago)
  • _source/core/config.js

     
    149149         * @example
    150150         * config.plugins = 'basicstyles,button,htmldataprocessor,toolbar,wysiwygarea';
    151151         */
    152         plugins : 'about,basicstyles,blockquote,button,clipboard,colorbutton,contextmenu,elementspath,enterkey,entities,filebrowser,find,flash,font,format,forms,horizontalrule,htmldataprocessor,image,indent,justify,keystrokes,link,list,maximize,newpage,pagebreak,pastefromword,pastetext,popup,preview,print,removeformat,resize,save,scayt,smiley,showblocks,sourcearea,stylescombo,table,tabletools,specialchar,tab,templates,toolbar,undo,wysiwygarea,wsc',
     152        plugins : 'about,basicstyles,blockquote,button,clipboard,colorbutton,contextmenu,elementspath,enterkey,entities,filebrowser,find,flash,font,format,forms,horizontalrule,htmldataprocessor,image,indent,justify,keystrokes,link,list,maximize,newpage,pagebreak,pastefromword,pastetext,popup,preview,print,removeformat,resize,save,scayt,smiley,showblocks,sourcearea,stylescombo,table,tabletools,specialchar,tab,templates,textselection,toolbar,undo,wysiwygarea,wsc',
    153153
    154154        /**
    155155         * List of additional plugins to be loaded. This is a tool setting which
  • _source/core/dom/node.js

     
    3030
    3131                        case CKEDITOR.NODE_TEXT :
    3232                                return new CKEDITOR.dom.text( domNode );
     33
     34                        case CKEDITOR.NODE_COMMENT :
     35                                return new CKEDITOR.dom.comment( domNode );
    3336                }
    3437
    3538                // Call the base constructor.
  • ckeditor.pack

     
    9595                                        '_source/core/dom/document.js',
    9696                                        '_source/core/dom/node.js',
    9797                                        '_source/core/dom/nodelist.js',
     98                                        '_source/core/dom/comment.js',
    9899                                        '_source/core/dom/element.js',
    99100                                        '_source/core/command.js',
    100101                                        '_source/core/config.js',
  • _source/plugins/textselection/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(function()
     7{
     8        /**
     9         * Represent plain text selection range.
     10         */
     11        CKEDITOR.plugins.add( 'textselection',
     12        {
     13                init : function( editor )
     14                {
     15                        var sourceBookmark, wysiwygBookmark,
     16                                textRange;  // Corresponding text range of wysiwyg bookmark.
     17
     18                        // Auto sync text selection with 'WYSIWYG' mode selection range.
     19                        if( editor.config.syncSelection
     20                                && CKEDITOR.plugins.sourcearea )
     21                        {
     22                                editor.on( 'beforeModeUnload', function( evt ){
     23                                        if ( editor.mode == 'source' )
     24                                        {
     25                                                var range = editor.getTextSelection();
     26                                                // Fly the range when create bookmark.
     27                                                delete range.element;
     28                                                range.createBookmark();
     29                                                sourceBookmark = true;
     30                                                evt.data = range.content;
     31                                        }
     32                                } );
     33                                editor.on( 'mode', function( evt ){
     34                                        if ( editor.mode == 'wysiwyg' && sourceBookmark )
     35                                        {
     36                                                editor.focus();
     37                                                var doc = editor.document,
     38                                                        range = new CKEDITOR.dom.range( editor.document ),
     39                                                        walker,
     40                                                        startNode,
     41                                                        endNode;
     42                                                range.setStartAt( doc.getBody(), CKEDITOR.POSITION_AFTER_START );
     43                                                range.setEndAt( doc.getBody(), CKEDITOR.POSITION_BEFORE_END );
     44                                                walker = new CKEDITOR.dom.walker( range );
     45                                                walker.type = CKEDITOR.NODE_COMMENT;
     46                                                walker.evaluator = function( comment ){
     47
     48                                                        var match = /cke_bookmark_\d+(\w)/.exec(  comment.$.nodeValue );
     49                                                        if ( match )
     50                                                        {
     51                                                                if ( match[ 1 ] == 'S' )
     52                                                                        startNode = comment;
     53                                                                else ( match[ 1 ] == 'E' )
     54                                                                {
     55                                                                        endNode = comment;
     56                                                                        return false;
     57                                                                }
     58                                                        }
     59
     60                                                };
     61                                                walker.lastForward();
     62                                                range.setStartAfter( startNode );
     63                                                range.setEndBefore( endNode );
     64                                                range.select();
     65                                                // Scroll into view for non-IE.
     66                                                if( !CKEDITOR.env.ie )
     67                                                                editor.getSelection().getStartElement().scrollIntoView( true );
     68                                                // Remove the comments node which are out of range.
     69                                                startNode.remove();
     70                                                endNode.remove();
     71                                        }
     72                                }, null, null, 10 );
     73
     74                                editor.on( 'beforeGetModeData', function( evt ){
     75                                        if ( editor.mode == 'wysiwyg' )
     76                                        {
     77                                                var sel = editor.getSelection(), range;
     78                                                if ( sel && ( range = sel.getRanges()[ 0 ] ) )
     79                                                        wysiwygBookmark = range.createBookmark( true );
     80                                        }
     81                                } );
     82                                // Build text range right after wysiwyg has unloaded.
     83                                editor.on( 'afterModeUnload', function( evt ){
     84                                        if ( editor.mode == 'wysiwyg' && wysiwygBookmark )
     85                                        {
     86                                                textRange = new CKEDITOR.dom.textRange( evt.data );
     87                                                textRange.moveToBookmark( wysiwygBookmark );
     88                                                evt.data = textRange.content;
     89                                        }
     90                                } );
     91                                editor.on( 'mode', function( evt ){
     92                                        if ( editor.mode == 'source' && textRange )
     93                                        {
     94                                                textRange.element = editor.textarea;
     95                                                textRange.select();
     96                                        }
     97                                } );
     98
     99
     100                        }
     101                }
     102        });
     103
     104        /**
     105         * Gets the current text selection from the editing area when in Source mode.
     106         * @returns {CKEDITOR.dom.textRange} Text range represent the caret positoins.
     107         * @example
     108         * var textSelection = CKEDITOR.instances.editor1.<b>getTextSelection()</b>;
     109         * alert( textSelection.startOffset );
     110         * alert( textSelection.endOffset );
     111         */
     112        CKEDITOR.editor.prototype.getTextSelection = function()
     113        {
     114                return this.textarea && getTextSelection( this.textarea.$ ) || null;
     115        };
     116
     117        /**
     118         * Returns the caret position of the specified textfield/textarea.
     119         * @param {HTMLTextArea|HTMLTextInput} element
     120         */
     121        function getTextSelection( element ) {
     122
     123                var startOffset, endOffset;
     124
     125                if ( !CKEDITOR.env.ie )
     126                {
     127                        startOffset = element.selectionStart;
     128                        endOffset = element.selectionEnd;
     129                }
     130                else
     131                {
     132                        element.focus();
     133
     134                        // The current selection
     135                        var range = document.selection.createRange(),
     136                                textLength = range.text.length;
     137
     138                        // Create a 'measuring' range to help calculate the start offset by
     139                        // stretching it from start to current position.
     140                        var measureRange = range.duplicate();
     141                        measureRange.moveToElementText( element );
     142                        measureRange.setEndPoint( 'EndToEnd', range );
     143
     144                        endOffset = measureRange.text.length;
     145                        startOffset = endOffset - textLength;
     146                }
     147                return new CKEDITOR.dom.textRange(
     148                        new CKEDITOR.dom.element( element ), startOffset, endOffset );
     149        }
     150
     151        /**
     152         * Represent the selection range within a html textfield/textarea element,
     153         * or even a flyweight string content represent the text content.
     154         * @constructor
     155         * @param {CKEDITOR.dom.element|String} element
     156         * @param {Number} start
     157         * @param {Number} end
     158         */
     159        CKEDITOR.dom.textRange = function( element, start, end )
     160        {
     161                if( element instanceof CKEDITOR.dom.element
     162                        && ( element.is( 'textarea' )
     163                        || element.is( 'input' ) && element.getAttribute( 'type' ) == 'text' ) )
     164                {
     165                        this.element = element;
     166                        this.content = element.$.value;
     167                }
     168                else if( typeof element == 'string' )
     169                        this.content = element;
     170                else
     171                        throw 'Unkown "element" type.';
     172                this.startOffset = start || 0;
     173                this.endOffset = end || 0;
     174        }
     175
     176        CKEDITOR.dom.textRange.prototype =
     177        {
     178                /**
     179                 * Sets the text selection of the specified textfield/textarea.
     180                 * @param {HTMLTextArea|HTMLTextInput} element
     181                 * @param {CKEDITOR.dom.textRange} range
     182                 */
     183                select : function() {
     184
     185                        var startOffset = this.startOffset,
     186                                endOffset = this.endOffset,
     187                                element = this.element.$;
     188
     189                        if ( !CKEDITOR.env.ie )
     190                        {
     191                                element.selectionStart = startOffset;
     192                                element.selectionEnd = endOffset;
     193                        }
     194                        else
     195                        {
     196                                element.focus();
     197                                // Create empty selection this
     198                                var textRange = document.selection.createRange();
     199                                textRange.collapse();
     200                                textRange.moveStart('character', startOffset );
     201                                textRange.moveEnd('character', endOffset - startOffset );
     202                                textRange.select();
     203                        }
     204                },
     205
     206                /**
     207                 * Select the range included within the bookmark text with the bookmark
     208                 * text removed.
     209                 * @param {Object} bookmark Exactly the one created by CKEDITOR.dom.range.createBookmark( true ).
     210                 */
     211                moveToBookmark : function( bookmark ) {
     212                        var content = this.content;
     213                        function removeBookmarkText( bookmarkId )
     214                        {
     215
     216                                var bookmarkRegex = new RegExp( '<span.*?' + bookmarkId + '.*?/span>' ),
     217                                        offset;
     218                                content = content.replace( bookmarkRegex, function( str, index ){
     219                                        offset = index;
     220                                        return '';
     221                                });
     222                                return offset;
     223                        }
     224
     225                        this.startOffset = removeBookmarkText( bookmark.startNode );
     226                        this.endOffset = removeBookmarkText( bookmark.endNode );
     227                        this.content = content;
     228                        this.updateElement();
     229                },
     230
     231
     232
     233                /**
     234                 * If startOffset/endOffset anchor inside element tag, start the range before/after the element
     235                 */
     236                enlarge : function()
     237                {
     238                        var htmlTagRegexp = /<[^>]+>/g;
     239                        var content = this.content,
     240                                start = this.startOffset,
     241                                end = this.endOffset,
     242                                match,
     243                                tagStartIndex,
     244                                tagEndIndex;
     245
     246                        // Adjust offset position on parsing result.
     247                        while( match = htmlTagRegexp.exec( content ) )
     248                        {
     249                                tagStartIndex = match.index;
     250                                tagEndIndex = tagStartIndex + match[ 0 ].length;
     251                                if ( start > tagStartIndex && start < tagEndIndex )
     252                                        start = tagStartIndex;
     253                                if ( end > tagStartIndex && end < tagEndIndex )
     254                                {
     255                                        end = tagEndIndex;
     256                                        break;
     257                                }
     258                        }
     259
     260                        this.startOffset = start;
     261                        this.endOffset = end;
     262                },
     263
     264                createBookmark : function()
     265                {
     266                        // Enlarge the range to avoid tag partial selection.
     267                        this.enlarge();
     268                        var content = this.content,
     269                                start = this.startOffset,
     270                                end = this.endOffset,
     271                                id = CKEDITOR.tools.getNextNumber(),
     272                                bookmarkTemplate = '<!--cke_bookmark_%1-->';
     273
     274                        content = content.substring( 0, start ) + bookmarkTemplate.replace( '%1', id + 'S' )
     275                                  + content.substring( start, end ) + bookmarkTemplate.replace( '%1', id + 'E' )
     276                                          + content.substring( end );
     277
     278                        this.content = content;
     279                        this.updateElement();
     280                },
     281
     282                updateElement : function()
     283                {
     284                        if ( this.element )
     285                                this.element.$.value = this.content;
     286                }
     287
     288        };
     289
     290} )();
     291
     292// Seamless selection range across different modes.
     293CKEDITOR.config.syncSelection = true;
  • _source/plugins/editingblock/plugin.js

     
    170170                                return;
    171171
    172172                        var currentMode = getMode( this );
     173                        this.fire( 'beforeGetModeData' );
    173174                        data = currentMode.getData();
     175                        data = this.fire( 'beforeModeUnload', data );
    174176                        currentMode.unload( holderElement );
     177                        data = this.fire( 'afterModeUnload', data );
    175178                        this.mode = '';
    176179                }
    177180
  • _source/core/loader.js

     
    3131                        'core/command'                  : [],
    3232                        'core/config'                   : [ 'core/ckeditor_base' ],
    3333                        'core/dom'                              : [],
     34                        'core/dom/comment'              : [ 'core/dom/node' ],
    3435                        'core/dom/document'             : [ 'core/dom', 'core/dom/domobject', 'core/dom/window' ],
    3536                        'core/dom/documentfragment'     : [ 'core/dom/element' ],
    3637                        'core/dom/element'              : [ 'core/dom', 'core/dom/document', 'core/dom/domobject', 'core/dom/node', 'core/dom/nodelist', 'core/tools' ],
     
    4243                        'core/dom/domwalker'    : [ 'core/dom/node', 'core/dom/element', 'core/dom/document' ],
    4344                        'core/dom/range'                : [ 'core/dom/document', 'core/dom/documentfragment', 'core/dom/element', 'core/dom/domwalker', 'core/dom/walker' ],
    4445                        'core/dom/text'                 : [ 'core/dom/node', 'core/dom/domobject' ],
    45                         'core/dom/walker'               : [ 'core/dom/node' ],
     46                        'core/dom/walker'               : [ 'core/dom/node', 'core/dom/comment' ],
    4647                        'core/dom/window'               : [ 'core/dom/domobject' ],
    4748                        'core/dtd'                              : [ 'core/tools' ],
    4849                        'core/editor'                   : [ 'core/command', 'core/config', 'core/editor_basic', 'core/focusmanager', 'core/lang', 'core/plugins', 'core/skins', 'core/themes', 'core/tools', 'core/ui' ],
© 2003 – 2020 CKSource – Frederico Knabben. All rights reserved. | Terms of use | Privacy policy