Ticket #2763: 2763_6.patch

File 2763_6.patch, 14.4 KB (added by Frederico Caldeira Knabben, 11 years ago)
  • _source/core/command.js

     
    99
    1010        this.exec = function()
    1111        {
    12                 commandDefinition.exec.call( this, editor );
     12                if ( this.state == CKEDITOR.TRISTATE_DISABLED )
     13                        return false;
     14
     15                return ( commandDefinition.exec.call( this, editor ) !== false );
    1316        };
    1417
    1518        CKEDITOR.tools.extend( this, commandDefinition );
  • _source/core/commanddefinition.js

     
    2424 * @function
    2525 * @param {CKEDITOR.editor} editor The editor within which run the command.
    2626 * @param {Object} [data] Additional data to be used to execute the command.
     27 * @returns {Boolean} Whether the command has been successfully executed.
     28 *              Defaults to "true", if nothing is returned.
    2729 * @example
    2830 * editorInstance.addCommand( 'sample',
    2931 * {
     
    3335 *     }
    3436 * });
    3537 */
     38
     39/**
     40 * Whether the command need to be hooked into the redo/undo system.
     41 * @name  CKEDITOR.commandDefinition.canUndo
     42 * @type {Boolean} If not defined or 'true' both hook into undo system, set it
     43 *              to 'false' explicitly  keep it out.
     44 * @field
     45 * @example
     46 * editorInstance.addCommand( 'alertName',
     47 * {
     48 *     exec : function( editor )
     49 *     {
     50 *         alert( editor.name );
     51 *     },
     52 *     canUndo : false    // No support for undo/redo
     53 * });
     54 */
  • _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,preview,removeformat,smiley,indent,link,list,sourcearea,table,specialchar,tab,toolbar,undo,wysiwygarea',
    149150
    150         plugins : 'basicstyles,button,elementspath,horizontalrule,htmldataprocessor,keystrokes,newpage,pagebreak,preview,removeformat,smiley,indent,link,list,sourcearea,table,specialchar,tab,toolbar,wysiwygarea',
    151 
    152151        /**
    153152         * The theme to be used to build the UI.
    154153         * @type String
  • _source/core/editor.js

     
    346346                 */
    347347                addCommand : function( commandName, commandDefinition )
    348348                {
    349                         this._.commands[ commandName ] = new CKEDITOR.command( this, commandDefinition );
     349                        return this._.commands[ commandName ] = new CKEDITOR.command( this, commandDefinition );
    350350                },
    351351
    352352                addCss : function( css )
     
    386386                execCommand : function( commandName, data )
    387387                {
    388388                        var command = this.getCommand( commandName );
     389
     390                        var eventData =
     391                        {
     392                                name: commandName,
     393                                commandData: data,
     394                                command: command
     395                        };
     396
    389397                        if ( command && command.state != CKEDITOR.TRISTATE_DISABLED )
    390                                 return command.exec( this, data );
     398                        {
     399                                if ( this.fire( 'beforeCommandExec', eventData ) !== false )
     400                                {
     401                                        eventData.returnValue = command.exec( this, eventData.commandData );
    391402
     403                                        if ( this.fire( 'afterCommandExec', eventData ) !== false )
     404                                                return eventData.returnValue;
     405                                }
     406                        }
     407
    392408                        // throw 'Unknown command name "' + commandName + '"';
    393409                        return false;
    394410                },
     
    454470                        return data;
    455471                },
    456472
     473                loadSnapshot : function( snapshot )
     474                {
     475                        this.fire( 'loadSnapshot', snapshot );
     476                },
     477
    457478                /**
    458479                 * Sets the editor data. The data must be provided in raw format.
    459480                 * @param {String} data HTML code to replace the curent content in the editor.
  • _source/core/tools.js

     
    1515 */
    1616CKEDITOR.tools =
    1717{
     18        arrayCompare : function( arrayA, arrayB )
     19        {
     20                if ( !arrayA && !arrayB )
     21                        return true;
     22
     23                if ( !arrayA || !arrayB || arrayA.length != arrayB.length )
     24                        return false;
     25
     26                for ( var i = 0 ; i < arrayA.length ; i++ )
     27                {
     28                        if ( arrayA[ i ] != arrayB[ i ] )
     29                                return false;
     30                }
     31
     32                return true;
     33        },
     34
    1835        /**
    1936         * Copy the properties from one object to another. By default, properties
    2037         * already present in the target object <strong>are not</strong> overwritten.
  • _source/lang/en.js

     
    4343        horizontalrule  : 'Insert Horizontal Line',
    4444        pagebreak               : 'Insert Page Break',
    4545        unlink                  : 'Unlink',
     46        undo                    : 'Undo',
     47        redo                    : 'Redo',
    4648
    4749        // Common messages and labels.
    4850        common :
  • _source/plugins/editingblock/plugin.js

     
    7070                                        if ( editor.mode )
    7171                                                event.data = getMode( editor ).getSnapshotData();
    7272                                });
     73
     74                        editor.on( 'loadSnapshot', function( event )
     75                                {
     76                                        if ( editor.mode )
     77                                                getMode( editor ).loadSnapshotData( event.data );
     78                                });
    7379                }
    7480        });
    7581
  • _source/plugins/selection/plugin.js

     
    633633                        return retval;
    634634                },
    635635
     636                createBookmarks2 : function()
     637                {
     638                        var bookmarks = [],
     639                                ranges = this.getRanges();
     640
     641                        for ( var i = 0 ; i < ranges.length ; i++ )
     642                                bookmarks.push( ranges[i].createBookmark2() );
     643                       
     644                        return bookmarks;
     645                },
     646
    636647                selectBookmarks : function( bookmarks )
    637648                {
    638649                        var ranges = [];
  • _source/plugins/toolbar/plugin.js

     
    212212                'NumberedList', 'BulletedList', '-',
    213213                'Outdent', 'Indent', '-',
    214214                'Subscript', 'Superscript', '-',
     215                'Undo', 'Redo', '-',
    215216                'SelectAll', 'RemoveFormat', '-',
    216217                'Link', 'Unlink', 'Anchor', '-',
    217218                'Table', 'Smiley', 'HorizontalRule', 'SpecialChar', 'PageBreak'
  • _source/plugins/undo/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 Undo/Redo system for saving shapshot for document modification
     8 *              and other recordable changes.
     9 */
     10
     11(function()
     12{
     13        CKEDITOR.plugins.add( 'undo',
     14        {
     15                requires : [ 'selection', 'wysiwygarea' ],
     16
     17                init : function( editor )
     18                {
     19                        var undoManager = new UndoManager( editor );
     20
     21                        var undoCommand = editor.addCommand( 'undo',
     22                                {
     23                                        exec : function()
     24                                        {
     25                                                if ( undoManager.undo() )
     26                                                {
     27                                                        editor.selectionChange();
     28                                                        this.fire( 'afterUndo' );
     29                                                }
     30                                        },
     31                                        state : CKEDITOR.TRISTATE_DISABLED,
     32                                        canUndo : false
     33                                });
     34
     35                        var redoCommand = editor.addCommand( 'redo',
     36                                {
     37                                        exec : function()
     38                                        {
     39                                                if ( undoManager.redo() )
     40                                                {
     41                                                        editor.selectionChange();
     42                                                        this.fire( 'afterRedo' );
     43                                                }
     44                                        },
     45                                        state : CKEDITOR.TRISTATE_DISABLED,
     46                                        canUndo : false
     47                                });
     48
     49                        undoManager.onChange = function()
     50                        {
     51                                undoCommand.setState( undoManager.undoable() ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED );
     52                                redoCommand.setState( undoManager.redoable() ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED );
     53                        };
     54
     55                        function recordCommand( event )
     56                        {
     57                                // If the command hasn't been marked to not support undo.
     58                                if ( undoManager.enabled && event.data.command.canUndo !== false )
     59                                        undoManager.save( event.name == 'afterCommandExec' ? 'R' : 'U' );
     60                        }
     61
     62                        // We'll save snapshots before and after executing a command.
     63                        editor.on( 'beforeCommandExec', recordCommand );
     64                        editor.on( 'afterCommandExec', recordCommand );
     65
     66                        // Make the undo manager available only in wysiwyg mode.
     67                        editor.on( 'mode', function()
     68                                {
     69                                        if ( !undoManager.enabled && editor.mode == 'wysiwyg' )
     70                                        {
     71                                                undoManager.enabled = true;
     72
     73                                                editor.document.on( 'keydown', function()
     74                                                        {
     75                                                                undoManager.type();
     76                                                        });
     77
     78                                                // Being this the first call, let's get an undo snapshot.
     79                                                if ( undoManager.index == -1 )
     80                                                        undoManager.save();
     81                                        }
     82
     83                                        undoManager.onChange();
     84                                });
     85
     86                        editor.ui.addButton( 'Undo',
     87                                {
     88                                        label : editor.lang.undo,
     89                                        command : 'undo'
     90                                });
     91
     92                        editor.ui.addButton( 'Redo',
     93                                {
     94                                        label : editor.lang.redo,
     95                                        command : 'redo'
     96                                });
     97                }
     98        });
     99
     100        // Gets a snapshot image which represent the current document status.
     101        function Image( editor )
     102        {
     103                this.contents   = editor.getSnapshot();
     104                this.bookmarks  = editor.getSelection().createBookmarks2();
     105        }
     106
     107        Image.prototype =
     108        {
     109                equals : function( otherImage, contentOnly )
     110                {
     111                        if ( this.contents != otherImage.contents )
     112                                return false;
     113
     114                        if ( contentOnly )
     115                                return true;
     116
     117                        var bookmarksA = this.bookmarks,
     118                                bookmarksB = otherImage.bookmarks;
     119
     120                        if ( bookmarksA.length != bookmarksB.length )
     121                                return false;
     122
     123                        for ( var i = 0 ; i < bookmarksA.length ; i++ )
     124                        {
     125                                var bookmarkA = bookmarksA[ i ],
     126                                        bookmarkB = bookmarksB[ i ];
     127
     128                                if (
     129                                        bookmarkA.startOffset != bookmarkB.startOffset ||
     130                                        bookmarkA.endOffset != bookmarkB.endOffset ||
     131                                        !CKEDITOR.tools.arrayCompare( bookmarkA.start, bookmarkB.start ) ||
     132                                        !CKEDITOR.tools.arrayCompare( bookmarkA.end, bookmarkB.end ) )
     133                                {
     134                                        return false;
     135                                }
     136                        }
     137
     138                        return true;
     139                }
     140        };
     141
     142        /**
     143         * @constructor Main logic for Redo/Undo feature.
     144         */
     145        function UndoManager( editor )
     146        {
     147                /**
     148                 * Indicates that the Undo/Redo features are avaialable and effective.
     149                 */
     150                this.enabled = false;
     151
     152                this.typing = false;
     153                this.typesCount = 0;
     154
     155                this.editor = editor;
     156
     157                /**
     158                 * Stack for all the undo and redo snapshots, they're always created/removed
     159                 * in consistency.
     160                 */
     161                this.snapshots = [];
     162
     163                /**
     164                 * Current snapshot history index.
     165                 */
     166                this.index = -1;
     167
     168                this.limit = editor.config.maxUndoLevels;
     169        }
     170
     171        UndoManager.prototype =
     172        {
     173                type : function()
     174                {
     175                        if ( !this.typing )
     176                        {
     177                                this.save( 'U' );
     178                                this.typing = true;
     179                        }
     180
     181                        this.typesCount++;
     182
     183                        if ( this.typesCount > 25 )
     184                        {
     185                                this.typesCount = 0;
     186                                this.save();
     187                        }
     188                },
     189
     190                /**
     191                 * Save a snapshot of document image for later retrieve.
     192                 */
     193                save : function( type, onContentOnly )
     194                {
     195                        var snapshots = this.snapshots;
     196
     197                        // Get a content image.
     198                        var image = new Image( this.editor );
     199
     200                        // Check if this is a duplicate. In such case, do nothing.
     201                        if ( this.index > -1 && image.equals( snapshots[ this.index ], onContentOnly ) )
     202                                return;
     203
     204                        image.type = type || 'UR';
     205
     206                        // Drop future snapshots.
     207                        snapshots.splice( this.index + 1, snapshots.length - this.index - 1 );
     208
     209                        // If we have reached the limit, remove the oldest one.
     210                        if ( snapshots.length == this.limit )
     211                                snapshots.shift();
     212
     213                        // Add the new image, updating the current index.
     214                        this.index = snapshots.push( image ) - 1;
     215
     216                        this.onChange();
     217                },
     218
     219                restoreImage : function( index )
     220                {
     221                        var image = this.snapshots[ index ];
     222
     223                        this.editor.loadSnapshot( image.contents );
     224                        this.editor.getSelection().selectBookmarks( image.bookmarks );
     225
     226                        this.index = index;
     227
     228                        this.onChange();
     229                },
     230
     231                /**
     232                 * Check the current redo state.
     233                 * @return {Boolean} Whether the document has previous state to
     234                 *              retrieve.
     235                 */
     236                redoable : function()
     237                {
     238                        return this.enabled && ( this.index < this.snapshots.length - 1 );
     239                },
     240
     241                /**
     242                 * Check the current undo state.
     243                 * @return {Boolean} Whether the document has future state to restore.
     244                 */
     245                undoable : function()
     246                {
     247                        return this.enabled && ( this.index > 0 );
     248                },
     249
     250                /**
     251                 * Perform undo on current index.
     252                 */
     253                undo : function()
     254                {
     255                        if ( this.undoable() )
     256                        {
     257                                this.save( 'UR', true );
     258
     259                                var index = this.index;
     260
     261                                while ( --index >= 0 )
     262                                {
     263                                        var image = this.snapshots[ index ];
     264                                        if ( image.type == 'U' || image.type == 'UR' )
     265                                                return this.restoreImage( index ), true;
     266                                }
     267                        }
     268
     269                        return false;
     270                },
     271
     272                /**
     273                 * Perform redo on current index.
     274                 */
     275                redo : function()
     276                {
     277                        if ( this.redoable() )
     278                        {
     279                                // Try to save. If no changes have been made, the redo stack
     280                                // will not change, so it will still be redoable.
     281                                this.save( 'UR', true );
     282
     283                                // If instead we had changes, we can't redo anymore.
     284                                if ( this.redoable() )
     285                                {
     286                                        var index = this.index;
     287
     288                                        while ( ++index < this.snapshots.length )
     289                                        {
     290                                                var image = this.snapshots[ index ];
     291                                                if ( image.type == 'R' || image.type == 'UR' )
     292                                                        return this.restoreImage( index ), true;
     293                                        }
     294                                }
     295                        }
     296
     297                        return false;
     298                }
     299        };
     300})();
     301
     302CKEDITOR.config.maxUndoLevels = 20;
     303 No newline at end of file
  • _source/skins/default/toolbar.css

     
    310310{
    311311        background-position: 0 -880px;
    312312}
    313 
     313.cke_skin_default a.cke_button_undo .cke_icon
     314{
     315        background-position: 0 -208px;
     316}
     317.cke_skin_default a.cke_button_redo .cke_icon
     318{
     319        background-position: 0 -224px;
     320}
    314321.cke_skin_default a.cke_button_numberedlist .cke_icon
    315322{
    316323        background-position: 0 -400px;
© 2003 – 2019 CKSource – Frederico Knabben. All rights reserved. | Terms of use | Privacy policy