Changeset 143005 in webkit


Ignore:
Timestamp:
Feb 15, 2013 8:53:55 AM (11 years ago)
Author:
vsevik@chromium.org
Message:

Web Inspector: Several consecutive Backspace or Delete strikes should not be marked as undoable state.
https://bugs.webkit.org/show_bug.cgi?id=109915

Reviewed by Pavel Feldman.

Source/WebCore:

Extracted _isEditRangeUndoBoundary() and _isEditRangeAdjacentToLastCommand() in TextEditorModel
to detect if markUndoableState() call is needed before and after editRange.

  • inspector/front-end/TextEditorModel.js:

(WebInspector.TextRange.prototype.immediatelyPrecedes):
(WebInspector.TextRange.prototype.immediatelyFollows):
(WebInspector.TextEditorModel.endsWithBracketRegex.):

LayoutTests:

  • inspector/editor/text-editor-undo-redo-expected.txt:
  • inspector/editor/text-editor-undo-redo.html:
Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r143002 r143005  
     12013-02-15  Vsevolod Vlasov  <vsevik@chromium.org>
     2
     3        Web Inspector: Several consecutive Backspace or Delete strikes should not be marked as undoable state.
     4        https://bugs.webkit.org/show_bug.cgi?id=109915
     5
     6        Reviewed by Pavel Feldman.
     7
     8        * inspector/editor/text-editor-undo-redo-expected.txt:
     9        * inspector/editor/text-editor-undo-redo.html:
     10
    1112013-02-15  Sudarsana Nagineni  <sudarsana.nagineni@intel.com>
    212
  • trunk/LayoutTests/inspector/editor/text-editor-undo-redo-expected.txt

    r142998 r143005  
    135135
    136136
     137Running: testDelete
     138Text before edit:
     139function foo()
     140{
     141
     142}
     143
     144Text after edit:
     145function foo()
     146{
     147    bar();
     148    baz();
     149    foo();|
     150}
     151
     152Text after deletes:
     153function foo()
     154{
     155|
     156}
     157
     158Text after first undo:
     159function foo()
     160{
     161|    bar();
     162    baz();
     163    foo();
     164}
     165
     166Text after second undo:
     167function foo()
     168{
     169    bar();
     170    baz();|
     171}
     172
     173Text after first redo:
     174function foo()
     175{
     176    bar();
     177    baz();
     178    foo();|
     179}
     180
     181Text after second redo:
     182function foo()
     183{
     184|
     185}
     186
     187
     188Running: testBackspace
     189Text before edit:
     190function foo()
     191{
     192
     193}
     194
     195Text after edit:
     196function foo()
     197{
     198    bar();
     199    baz();
     200    foo();|
     201}
     202
     203Text after backspaces:
     204function foo()
     205{
     206|
     207}
     208
     209Text after first undo:
     210function foo()
     211{
     212    bar();
     213    baz();
     214    foo();|
     215}
     216
     217Text after second undo:
     218function foo()
     219{
     220    bar();
     221    baz();|
     222}
     223
     224Text after first redo:
     225function foo()
     226{
     227    bar();
     228    baz();
     229    foo();|
     230}
     231
     232Text after second redo:
     233function foo()
     234{
     235|
     236}
     237
     238
     239Running: testBackspaceAndDeleteInDifferentLines
     240Text before edit:
     241function foo()
     242{
     243
     244}
     245
     246Text after edit:
     247function foo()
     248{
     249    bar();
     250    baz();
     251    foo();|
     252}
     253
     254Text after backspace:
     255function foo()
     256{
     257    bar();
     258    baz();
     259    foo()|
     260}
     261
     262Text after delete:
     263function foo()
     264{
     265|   bar();
     266    baz();
     267    foo()
     268}
     269
     270Text after first undo:
     271function foo()
     272{
     273|    bar();
     274    baz();
     275    foo()
     276}
     277
     278Text after second undo:
     279function foo()
     280{
     281    bar();
     282    baz();
     283    foo();|
     284}
     285
     286Text after third undo:
     287function foo()
     288{
     289    bar();
     290    baz();|
     291}
     292
     293Text after first redo:
     294function foo()
     295{
     296    bar();
     297    baz();
     298    foo();|
     299}
     300
     301Text after second redo:
     302function foo()
     303{
     304    bar();
     305    baz();
     306    foo()|
     307}
     308
     309Text after third redo:
     310function foo()
     311{
     312|   bar();
     313    baz();
     314    foo()
     315}
     316
     317
     318Running: testPasteSeveralTimes
     319Text before edit:
     320function foo()
     321{
     322
     323}
     324
     325Text after edit:
     326function foo()
     327{
     328    bar();
     329    baz();
     330    foo();|
     331}
     332
     333Text after first paste:
     334function foo()
     335{
     336    bar();
     337    baz();
     338    foo();42|
     339}
     340
     341Text after second paste:
     342function foo()
     343{
     344    bar();
     345    baz();
     346    foo();4242|
     347}
     348
     349Text after first undo:
     350function foo()
     351{
     352    bar();
     353    baz();
     354    foo();42|
     355}
     356
     357Text after second undo:
     358function foo()
     359{
     360    bar();
     361    baz();
     362    foo();|
     363}
     364
     365Text after third undo:
     366function foo()
     367{
     368    bar();
     369    baz();|
     370}
     371
     372Text after first redo:
     373function foo()
     374{
     375    bar();
     376    baz();
     377    foo();|
     378}
     379
     380Text after second redo:
     381function foo()
     382{
     383    bar();
     384    baz();
     385    foo();42|
     386}
     387
     388Text after third redo:
     389function foo()
     390{
     391    bar();
     392    baz();
     393    foo();4242|
     394}
     395
     396
    137397Running: testSelectionAfterUndoRedo
    138398Text before edit:
  • trunk/LayoutTests/inspector/editor/text-editor-undo-redo.html

    r142998 r143005  
    2020    }
    2121
     22    function typeDelete(textModel, startRange, count)
     23    {
     24        var count = count || 1;
     25        var range = startRange;
     26        for (var i = 0; i < count; ++i) {
     27            var deleteRange = range.isEmpty() ? textModel.growRangeRight(range) : range;
     28            range = textModel.editRange(deleteRange, "", range).collapseToEnd();
     29        }
     30        return range;
     31    }
     32
    2233    function typeBackspace(textModel, startRange, count)
    2334    {
     
    8697            range = textModel.redo();
    8798            dumpTextModel("Text after second redo:\n", textModel, range);
     99            next();
     100        },
     101
     102        function testDelete(next)
     103        {
     104            var textModel = new WebInspector.TextEditorModel();
     105            var functionText = "    bar();\n    baz();\n    foo();";
     106            textModel.setText("function foo()\n{\n\n}\n");
     107            dumpTextModel("Text before edit:\n", textModel);
     108            var range = typeText(textModel, new WebInspector.TextRange(2, 0, 2, 0), "    bar();\n    baz();\n    foo();");
     109            dumpTextModel("Text after edit:\n", textModel, range);
     110            range = typeDelete(textModel, new WebInspector.TextRange(2, 0, 2, 0), functionText.length);
     111            dumpTextModel("Text after deletes:\n", textModel, range);
     112            range = textModel.undo();
     113            dumpTextModel("Text after first undo:\n", textModel, range);
     114            range = textModel.undo();
     115            dumpTextModel("Text after second undo:\n", textModel, range);
     116            range = textModel.redo();
     117            dumpTextModel("Text after first redo:\n", textModel, range);
     118            range = textModel.redo();
     119            dumpTextModel("Text after second redo:\n", textModel, range);
     120            next();
     121        },
     122
     123        function testBackspace(next)
     124        {
     125            var textModel = new WebInspector.TextEditorModel();
     126            var functionText = "    bar();\n    baz();\n    foo();";
     127            textModel.setText("function foo()\n{\n\n}\n");
     128            dumpTextModel("Text before edit:\n", textModel);
     129            var range = typeText(textModel, new WebInspector.TextRange(2, 0, 2, 0), "    bar();\n    baz();\n    foo();");
     130            dumpTextModel("Text after edit:\n", textModel, range);
     131            range = typeBackspace(textModel, range, functionText.length);
     132            dumpTextModel("Text after backspaces:\n", textModel, range);
     133            range = textModel.undo();
     134            dumpTextModel("Text after first undo:\n", textModel, range);
     135            range = textModel.undo();
     136            dumpTextModel("Text after second undo:\n", textModel, range);
     137            range = textModel.redo();
     138            dumpTextModel("Text after first redo:\n", textModel, range);
     139            range = textModel.redo();
     140            dumpTextModel("Text after second redo:\n", textModel, range);
     141            next();
     142        },
     143
     144        function testBackspaceAndDeleteInDifferentLines(next)
     145        {
     146            var textModel = new WebInspector.TextEditorModel();
     147            var functionText = "    bar();\n    baz();\n    foo();";
     148            textModel.setText("function foo()\n{\n\n}\n");
     149            dumpTextModel("Text before edit:\n", textModel);
     150            var range = typeText(textModel, new WebInspector.TextRange(2, 0, 2, 0), "    bar();\n    baz();\n    foo();");
     151            dumpTextModel("Text after edit:\n", textModel, range);
     152            range = typeBackspace(textModel, range);
     153            dumpTextModel("Text after backspace:\n", textModel, range);
     154            range = typeDelete(textModel, new WebInspector.TextRange(2, 0, 2, 0));
     155            dumpTextModel("Text after delete:\n", textModel, range);
     156            range = textModel.undo();
     157            dumpTextModel("Text after first undo:\n", textModel, range);
     158            range = textModel.undo();
     159            dumpTextModel("Text after second undo:\n", textModel, range);
     160            range = textModel.undo();
     161            dumpTextModel("Text after third undo:\n", textModel, range);
     162            range = textModel.redo();
     163            dumpTextModel("Text after first redo:\n", textModel, range);
     164            range = textModel.redo();
     165            dumpTextModel("Text after second redo:\n", textModel, range);
     166            range = textModel.redo();
     167            dumpTextModel("Text after third redo:\n", textModel, range);
     168            next();
     169        },
     170
     171        function testPasteSeveralTimes(next)
     172        {
     173            var textModel = new WebInspector.TextEditorModel();
     174            var functionText = "    bar();\n    baz();\n    foo();";
     175            textModel.setText("function foo()\n{\n\n}\n");
     176            dumpTextModel("Text before edit:\n", textModel);
     177            var range = typeText(textModel, new WebInspector.TextRange(2, 0, 2, 0), "    bar();\n    baz();\n    foo();");
     178            dumpTextModel("Text after edit:\n", textModel, range);
     179            range = textModel.editRange(range, "42").collapseToEnd();
     180            dumpTextModel("Text after first paste:\n", textModel, range);
     181            range = textModel.editRange(range, "42").collapseToEnd();
     182            dumpTextModel("Text after second paste:\n", textModel, range);
     183            range = textModel.undo();
     184            dumpTextModel("Text after first undo:\n", textModel, range);
     185            range = textModel.undo();
     186            dumpTextModel("Text after second undo:\n", textModel, range);
     187            range = textModel.undo();
     188            dumpTextModel("Text after third undo:\n", textModel, range);
     189            range = textModel.redo();
     190            dumpTextModel("Text after first redo:\n", textModel, range);
     191            range = textModel.redo();
     192            dumpTextModel("Text after second redo:\n", textModel, range);
     193            range = textModel.redo();
     194            dumpTextModel("Text after third redo:\n", textModel, range);
    88195            next();
    89196        },
  • trunk/Source/WebCore/ChangeLog

    r143003 r143005  
     12013-02-15  Vsevolod Vlasov  <vsevik@chromium.org>
     2
     3        Web Inspector: Several consecutive Backspace or Delete strikes should not be marked as undoable state.
     4        https://bugs.webkit.org/show_bug.cgi?id=109915
     5
     6        Reviewed by Pavel Feldman.
     7
     8        Extracted _isEditRangeUndoBoundary() and _isEditRangeAdjacentToLastCommand() in TextEditorModel
     9        to detect if markUndoableState() call is needed before and after editRange.
     10
     11        * inspector/front-end/TextEditorModel.js:
     12        (WebInspector.TextRange.prototype.immediatelyPrecedes):
     13        (WebInspector.TextRange.prototype.immediatelyFollows):
     14        (WebInspector.TextEditorModel.endsWithBracketRegex.):
     15
    1162013-02-15  Andrey Adaikin  <aandrey@chromium.org>
    217
  • trunk/Source/WebCore/inspector/front-end/TextEditorModel.js

    r142998 r143005  
    6868
    6969    /**
     70     * @param {WebInspector.TextRange} range
     71     * @return {boolean}
     72     */
     73    immediatelyPrecedes: function(range)
     74    {
     75        if (!range)
     76            return false;
     77        return this.endLine === range.startLine && this.endColumn === range.startColumn;
     78    },
     79
     80    /**
     81     * @param {WebInspector.TextRange} range
     82     * @return {boolean}
     83     */
     84    immediatelyFollows: function(range)
     85    {
     86        if (!range)
     87            return false;
     88        return range.immediatelyPrecedes(this);
     89    },
     90
     91    /**
    7092     * @return {number}
    7193     */
     
    252274    /**
    253275     * @param {WebInspector.TextRange} range
     276     * @return {boolean}
     277     */
     278    _rangeHasOneCharacter: function(range)
     279    {
     280        if (range.startLine === range.endLine && range.endColumn - range.startColumn === 1)
     281            return true;
     282        if (range.endLine - range.startLine === 1 && range.endColumn === 0 && range.startColumn === this.lineLength(range.startLine))
     283            return true;
     284        return false;
     285    },
     286
     287    /**
     288     * @param {WebInspector.TextRange} range
    254289     * @param {string} text
    255290     * @param {WebInspector.TextRange=} originalSelection
    256      * @return {WebInspector.TextRange}
    257      */
    258     editRange: function(range, text, originalSelection)
    259     {   
    260         if (this._lastEditedRange && (!text || text.indexOf("\n") !== -1 || this._lastEditedRange.endLine !== range.startLine || this._lastEditedRange.endColumn !== range.startColumn))
    261             this._markUndoableState();
    262         return this._innerEditRange(range, text, originalSelection);
     291     * @return {boolean}
     292     */
     293    _isEditRangeUndoBoundary: function(range, text, originalSelection)
     294    {
     295        if (originalSelection && !originalSelection.isEmpty())
     296            return true;
     297        if (text)
     298            return text.length > 1 || !range.isEmpty();
     299        return !this._rangeHasOneCharacter(range);
     300    },
     301
     302    /**
     303     * @param {WebInspector.TextRange} range
     304     * @param {string} text
     305     * @return {boolean}
     306     */
     307    _isEditRangeAdjacentToLastCommand: function(range, text)
     308    {
     309        if (!this._lastCommand)
     310            return true;
     311        if (!text) {
     312            // FIXME: Distinguish backspace and delete in lastCommand.
     313            return this._lastCommand.newRange.immediatelyPrecedes(range) || this._lastCommand.newRange.immediatelyFollows(range);
     314        }
     315        return text.indexOf("\n") === -1 && this._lastCommand.newRange.immediatelyPrecedes(range);
    263316    },
    264317
     
    269322     * @return {WebInspector.TextRange}
    270323     */
     324    editRange: function(range, text, originalSelection)
     325    {
     326        var undoBoundary = this._isEditRangeUndoBoundary(range, text, originalSelection);
     327        if (undoBoundary || !this._isEditRangeAdjacentToLastCommand(range, text))
     328            this._markUndoableState();
     329        var newRange = this._innerEditRange(range, text, originalSelection);
     330        if (undoBoundary)
     331            this._markUndoableState();
     332        return newRange;
     333    },
     334
     335    /**
     336     * @param {WebInspector.TextRange} range
     337     * @param {string} text
     338     * @param {WebInspector.TextRange=} originalSelection
     339     * @return {WebInspector.TextRange}
     340     */
    271341    _innerEditRange: function(range, text, originalSelection)
    272342    {
    273343        var originalText = this.copyRange(range);
    274344        var newRange = this._innerSetText(range, text);
    275         this._lastEditedRange = newRange;
    276         this._pushUndoableCommand(newRange, originalText, originalSelection || range);
     345        this._lastCommand = this._pushUndoableCommand(newRange, originalText, originalSelection || range);
    277346        this.dispatchEventToListeners(WebInspector.TextEditorModel.Events.TextChanged, { oldRange: range, newRange: newRange, editRange: true });
    278347        return newRange;
Note: See TracChangeset for help on using the changeset viewer.