Changeset 106953 in webkit


Ignore:
Timestamp:
Feb 7, 2012 9:00:32 AM (12 years ago)
Author:
pfeldman@chromium.org
Message:

Web Inspector: add generic support for undo-ing DOM edits.
https://bugs.webkit.org/show_bug.cgi?id=77875

Reviewed by Yury Semikhatsky.

Source/WebCore:

This change introduces InspectorHistory::Action that encapsulates all DOM modifications
initiated by the inspector. There is a way to undo these actions up until the undoable
state marker.

Tests: inspector/elements/undo-dom-edits-2.html

inspector/elements/undo-dom-edits.html
inspector/styles/undo-add-property.html
inspector/styles/undo-change-property.html
inspector/styles/undo-property-toggle.html

  • CMakeLists.txt:
  • GNUmakefile.list.am:
  • Target.pri:
  • WebCore.gypi:
  • WebCore.vcproj/WebCore.vcproj:
  • WebCore.xcodeproj/project.pbxproj:
  • inspector/Inspector.json:
  • inspector/InspectorAllInOne.cpp:
  • inspector/InspectorCSSAgent.cpp:

(InspectorCSSAgent::StyleSheetAction):
(WebCore::InspectorCSSAgent::StyleSheetAction::StyleSheetAction):
(WebCore::InspectorCSSAgent::StyleSheetAction::perform):
(WebCore::InspectorCSSAgent::StyleSheetAction::undo):
(WebCore):
(InspectorCSSAgent::SetStyleSheetTextAction):
(WebCore::InspectorCSSAgent::SetStyleSheetTextAction::SetStyleSheetTextAction):
(WebCore::InspectorCSSAgent::SetStyleSheetTextAction::perform):
(WebCore::InspectorCSSAgent::SetStyleSheetTextAction::undo):
(InspectorCSSAgent::SetPropertyTextAction):
(WebCore::InspectorCSSAgent::SetPropertyTextAction::SetPropertyTextAction):
(WebCore::InspectorCSSAgent::SetPropertyTextAction::toString):
(WebCore::InspectorCSSAgent::SetPropertyTextAction::perform):
(WebCore::InspectorCSSAgent::SetPropertyTextAction::undo):
(WebCore::InspectorCSSAgent::SetPropertyTextAction::mergeId):
(WebCore::InspectorCSSAgent::SetPropertyTextAction::merge):
(InspectorCSSAgent::TogglePropertyAction):
(WebCore::InspectorCSSAgent::TogglePropertyAction::TogglePropertyAction):
(WebCore::InspectorCSSAgent::TogglePropertyAction::perform):
(WebCore::InspectorCSSAgent::TogglePropertyAction::undo):
(WebCore::InspectorCSSAgent::getStyleSheetText):
(WebCore::InspectorCSSAgent::setStyleSheetText):
(WebCore::InspectorCSSAgent::setPropertyText):
(WebCore::InspectorCSSAgent::toggleProperty):

  • inspector/InspectorCSSAgent.h:

(InspectorCSSAgent):

  • inspector/InspectorDOMAgent.cpp:

(InspectorDOMAgent::DOMAction):
(WebCore::InspectorDOMAgent::DOMAction::DOMAction):
(WebCore::InspectorDOMAgent::DOMAction::perform):
(WebCore::InspectorDOMAgent::DOMAction::undo):
(WebCore):
(InspectorDOMAgent::RemoveChildAction):
(WebCore::InspectorDOMAgent::RemoveChildAction::RemoveChildAction):
(WebCore::InspectorDOMAgent::RemoveChildAction::perform):
(WebCore::InspectorDOMAgent::RemoveChildAction::undo):
(InspectorDOMAgent::InsertBeforeAction):
(WebCore::InspectorDOMAgent::InsertBeforeAction::InsertBeforeAction):
(WebCore::InspectorDOMAgent::InsertBeforeAction::perform):
(WebCore::InspectorDOMAgent::InsertBeforeAction::undo):
(InspectorDOMAgent::RemoveAttributeAction):
(WebCore::InspectorDOMAgent::RemoveAttributeAction::RemoveAttributeAction):
(WebCore::InspectorDOMAgent::RemoveAttributeAction::perform):
(WebCore::InspectorDOMAgent::RemoveAttributeAction::undo):
(InspectorDOMAgent::SetAttributeAction):
(WebCore::InspectorDOMAgent::SetAttributeAction::SetAttributeAction):
(WebCore::InspectorDOMAgent::SetAttributeAction::perform):
(WebCore::InspectorDOMAgent::SetAttributeAction::undo):
(InspectorDOMAgent::SetOuterHTMLAction):
(WebCore::InspectorDOMAgent::SetOuterHTMLAction::SetOuterHTMLAction):
(WebCore::InspectorDOMAgent::SetOuterHTMLAction::perform):
(WebCore::InspectorDOMAgent::SetOuterHTMLAction::undo):
(WebCore::InspectorDOMAgent::SetOuterHTMLAction::newNode):
(InspectorDOMAgent::ReplaceWholeTextAction):
(WebCore::InspectorDOMAgent::ReplaceWholeTextAction::ReplaceWholeTextAction):
(WebCore::InspectorDOMAgent::ReplaceWholeTextAction::perform):
(WebCore::InspectorDOMAgent::ReplaceWholeTextAction::undo):
(WebCore::InspectorDOMAgent::InspectorDOMAgent):
(WebCore::InspectorDOMAgent::reset):
(WebCore::InspectorDOMAgent::setAttributeValue):
(WebCore::InspectorDOMAgent::setAttributesAsText):
(WebCore::InspectorDOMAgent::removeAttribute):
(WebCore::InspectorDOMAgent::removeNode):
(WebCore::InspectorDOMAgent::setNodeName):
(WebCore::InspectorDOMAgent::setOuterHTML):
(WebCore::InspectorDOMAgent::setNodeValue):
(WebCore::InspectorDOMAgent::moveTo):
(WebCore::InspectorDOMAgent::undo):
(WebCore::InspectorDOMAgent::markUndoableState):

  • inspector/InspectorDOMAgent.h:

(InspectorDOMAgent):
(WebCore::InspectorDOMAgent::history):

  • inspector/InspectorHistory.cpp: Added.

(WebCore::InspectorHistory::Action::Action):
(WebCore):
(WebCore::InspectorHistory::Action::~Action):
(WebCore::InspectorHistory::Action::toString):
(WebCore::InspectorHistory::Action::isUndoableStateMark):
(WebCore::InspectorHistory::Action::mergeId):
(WebCore::InspectorHistory::Action::merge):
(WebCore::InspectorHistory::InspectorHistory):
(WebCore::InspectorHistory::~InspectorHistory):
(WebCore::InspectorHistory::perform):
(WebCore::InspectorHistory::markUndoableState):
(WebCore::InspectorHistory::undo):
(WebCore::InspectorHistory::reset):

  • inspector/InspectorHistory.h: Added.

(WebCore):
(InspectorHistory):
(Action):

  • inspector/InspectorStyleSheet.cpp:

(WebCore::InspectorStyle::setPropertyText):
(WebCore::InspectorStyle::styleText):
(WebCore::InspectorStyleSheet::addRule):
(WebCore::InspectorStyleSheet::buildObjectForStyleSheet):
(WebCore::InspectorStyleSheet::buildObjectForStyle):
(WebCore::InspectorStyleSheet::setPropertyText):
(WebCore::InspectorStyleSheet::getText):
(WebCore::InspectorStyleSheetForInlineStyle::getText):

  • inspector/InspectorStyleSheet.h:

(InspectorStyle):
(InspectorStyleSheet):
(InspectorStyleSheetForInlineStyle):

  • inspector/front-end/CSSStyleModel.js:

(WebInspector.CSSProperty.prototype.setText):

  • inspector/front-end/ElementsPanel.js:

(WebInspector.ElementsPanel.prototype._selectedNodeChanged):
(WebInspector.ElementsPanel.prototype._updateSidebars):
(WebInspector.ElementsPanel.prototype.handleShortcut):

  • inspector/front-end/StylesSidebarPane.js:

(WebInspector.StylePropertiesSection.prototype.onpopulate):
(WebInspector.StylePropertiesSection.prototype.addNewBlankProperty):
(WebInspector.ComputedStylePropertiesSection.prototype.onpopulate):
(WebInspector.StylePropertyTreeElement):
(WebInspector.StylePropertyTreeElement.prototype):

LayoutTests:

  • http/tests/inspector/elements-test.js:

(initialize_ElementTest.InspectorTest.rangeText):
(initialize_ElementTest.InspectorTest.generateUndoTest):

  • inspector/elements/undo-dom-edits-2-expected.txt: Added.
  • inspector/elements/undo-dom-edits-2.html: Added.
  • inspector/elements/undo-dom-edits-expected.txt: Added.
  • inspector/elements/undo-dom-edits.html: Added.
  • inspector/styles/undo-add-property-expected.txt: Added.
  • inspector/styles/undo-add-property.html: Added.
  • inspector/styles/undo-change-property-expected.txt: Added.
  • inspector/styles/undo-change-property.html: Added.
  • inspector/styles/undo-property-toggle-expected.txt: Added.
  • inspector/styles/undo-property-toggle.html: Added.
Location:
trunk
Files:
12 added
20 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r106952 r106953  
     12012-02-07  Pavel Feldman  <pfeldman@google.com>
     2
     3        Web Inspector: add generic support for undo-ing DOM edits.
     4        https://bugs.webkit.org/show_bug.cgi?id=77875
     5
     6        Reviewed by Yury Semikhatsky.
     7
     8        * http/tests/inspector/elements-test.js:
     9        (initialize_ElementTest.InspectorTest.rangeText):
     10        (initialize_ElementTest.InspectorTest.generateUndoTest):
     11        * inspector/elements/undo-dom-edits-2-expected.txt: Added.
     12        * inspector/elements/undo-dom-edits-2.html: Added.
     13        * inspector/elements/undo-dom-edits-expected.txt: Added.
     14        * inspector/elements/undo-dom-edits.html: Added.
     15        * inspector/styles/undo-add-property-expected.txt: Added.
     16        * inspector/styles/undo-add-property.html: Added.
     17        * inspector/styles/undo-change-property-expected.txt: Added.
     18        * inspector/styles/undo-change-property.html: Added.
     19        * inspector/styles/undo-property-toggle-expected.txt: Added.
     20        * inspector/styles/undo-property-toggle.html: Added.
     21
    1222012-02-07  Tony Gentilcore  <tonyg@chromium.org>
    223
  • trunk/LayoutTests/http/tests/inspector/elements-test.js

    r106947 r106953  
    382382        return "[undefined-undefined]";
    383383    return "[" + range.start + "-" + range.end + "]";
    384 };
    385 
    386 };
     384}
     385
     386InspectorTest.generateUndoTest = function(testBody)
     387{
     388    function result(next)
     389    {
     390        var testNode = InspectorTest.expandedNodeWithId(/function\s([^(]*)/.exec(testBody)[1]);
     391        InspectorTest.addResult("Initial:");
     392        InspectorTest.dumpElementsTree(testNode);
     393
     394        testBody(step1);
     395
     396        function step1()
     397        {
     398            InspectorTest.addResult("Post-action:");
     399            InspectorTest.dumpElementsTree(testNode);
     400            DOMAgent.undo(step2);
     401        }
     402
     403        function step2()
     404        {
     405            InspectorTest.addResult("Post-undo (initial):");
     406            InspectorTest.dumpElementsTree(testNode);
     407            next();
     408        }
     409    }
     410    result.toString = function()
     411    {
     412        return testBody.toString();
     413    }
     414    return result;
     415}
     416
     417};
  • trunk/Source/WebCore/CMakeLists.txt

    r106947 r106953  
    902902    inspector/InspectorFrontendClientLocal.cpp
    903903    inspector/InspectorFrontendHost.cpp
     904    inspector/InspectorHistory.cpp
    904905    inspector/InspectorIndexedDBAgent.cpp
    905906    inspector/InspectorInstrumentation.cpp
  • trunk/Source/WebCore/ChangeLog

    r106951 r106953  
     12012-02-07  Pavel Feldman  <pfeldman@google.com>
     2
     3        Web Inspector: add generic support for undo-ing DOM edits.
     4        https://bugs.webkit.org/show_bug.cgi?id=77875
     5
     6        Reviewed by Yury Semikhatsky.
     7
     8        This change introduces InspectorHistory::Action that encapsulates all DOM modifications
     9        initiated by the inspector. There is a way to undo these actions up until the undoable
     10        state marker.
     11
     12        Tests: inspector/elements/undo-dom-edits-2.html
     13               inspector/elements/undo-dom-edits.html
     14               inspector/styles/undo-add-property.html
     15               inspector/styles/undo-change-property.html
     16               inspector/styles/undo-property-toggle.html
     17
     18        * CMakeLists.txt:
     19        * GNUmakefile.list.am:
     20        * Target.pri:
     21        * WebCore.gypi:
     22        * WebCore.vcproj/WebCore.vcproj:
     23        * WebCore.xcodeproj/project.pbxproj:
     24        * inspector/Inspector.json:
     25        * inspector/InspectorAllInOne.cpp:
     26        * inspector/InspectorCSSAgent.cpp:
     27        (InspectorCSSAgent::StyleSheetAction):
     28        (WebCore::InspectorCSSAgent::StyleSheetAction::StyleSheetAction):
     29        (WebCore::InspectorCSSAgent::StyleSheetAction::perform):
     30        (WebCore::InspectorCSSAgent::StyleSheetAction::undo):
     31        (WebCore):
     32        (InspectorCSSAgent::SetStyleSheetTextAction):
     33        (WebCore::InspectorCSSAgent::SetStyleSheetTextAction::SetStyleSheetTextAction):
     34        (WebCore::InspectorCSSAgent::SetStyleSheetTextAction::perform):
     35        (WebCore::InspectorCSSAgent::SetStyleSheetTextAction::undo):
     36        (InspectorCSSAgent::SetPropertyTextAction):
     37        (WebCore::InspectorCSSAgent::SetPropertyTextAction::SetPropertyTextAction):
     38        (WebCore::InspectorCSSAgent::SetPropertyTextAction::toString):
     39        (WebCore::InspectorCSSAgent::SetPropertyTextAction::perform):
     40        (WebCore::InspectorCSSAgent::SetPropertyTextAction::undo):
     41        (WebCore::InspectorCSSAgent::SetPropertyTextAction::mergeId):
     42        (WebCore::InspectorCSSAgent::SetPropertyTextAction::merge):
     43        (InspectorCSSAgent::TogglePropertyAction):
     44        (WebCore::InspectorCSSAgent::TogglePropertyAction::TogglePropertyAction):
     45        (WebCore::InspectorCSSAgent::TogglePropertyAction::perform):
     46        (WebCore::InspectorCSSAgent::TogglePropertyAction::undo):
     47        (WebCore::InspectorCSSAgent::getStyleSheetText):
     48        (WebCore::InspectorCSSAgent::setStyleSheetText):
     49        (WebCore::InspectorCSSAgent::setPropertyText):
     50        (WebCore::InspectorCSSAgent::toggleProperty):
     51        * inspector/InspectorCSSAgent.h:
     52        (InspectorCSSAgent):
     53        * inspector/InspectorDOMAgent.cpp:
     54        (InspectorDOMAgent::DOMAction):
     55        (WebCore::InspectorDOMAgent::DOMAction::DOMAction):
     56        (WebCore::InspectorDOMAgent::DOMAction::perform):
     57        (WebCore::InspectorDOMAgent::DOMAction::undo):
     58        (WebCore):
     59        (InspectorDOMAgent::RemoveChildAction):
     60        (WebCore::InspectorDOMAgent::RemoveChildAction::RemoveChildAction):
     61        (WebCore::InspectorDOMAgent::RemoveChildAction::perform):
     62        (WebCore::InspectorDOMAgent::RemoveChildAction::undo):
     63        (InspectorDOMAgent::InsertBeforeAction):
     64        (WebCore::InspectorDOMAgent::InsertBeforeAction::InsertBeforeAction):
     65        (WebCore::InspectorDOMAgent::InsertBeforeAction::perform):
     66        (WebCore::InspectorDOMAgent::InsertBeforeAction::undo):
     67        (InspectorDOMAgent::RemoveAttributeAction):
     68        (WebCore::InspectorDOMAgent::RemoveAttributeAction::RemoveAttributeAction):
     69        (WebCore::InspectorDOMAgent::RemoveAttributeAction::perform):
     70        (WebCore::InspectorDOMAgent::RemoveAttributeAction::undo):
     71        (InspectorDOMAgent::SetAttributeAction):
     72        (WebCore::InspectorDOMAgent::SetAttributeAction::SetAttributeAction):
     73        (WebCore::InspectorDOMAgent::SetAttributeAction::perform):
     74        (WebCore::InspectorDOMAgent::SetAttributeAction::undo):
     75        (InspectorDOMAgent::SetOuterHTMLAction):
     76        (WebCore::InspectorDOMAgent::SetOuterHTMLAction::SetOuterHTMLAction):
     77        (WebCore::InspectorDOMAgent::SetOuterHTMLAction::perform):
     78        (WebCore::InspectorDOMAgent::SetOuterHTMLAction::undo):
     79        (WebCore::InspectorDOMAgent::SetOuterHTMLAction::newNode):
     80        (InspectorDOMAgent::ReplaceWholeTextAction):
     81        (WebCore::InspectorDOMAgent::ReplaceWholeTextAction::ReplaceWholeTextAction):
     82        (WebCore::InspectorDOMAgent::ReplaceWholeTextAction::perform):
     83        (WebCore::InspectorDOMAgent::ReplaceWholeTextAction::undo):
     84        (WebCore::InspectorDOMAgent::InspectorDOMAgent):
     85        (WebCore::InspectorDOMAgent::reset):
     86        (WebCore::InspectorDOMAgent::setAttributeValue):
     87        (WebCore::InspectorDOMAgent::setAttributesAsText):
     88        (WebCore::InspectorDOMAgent::removeAttribute):
     89        (WebCore::InspectorDOMAgent::removeNode):
     90        (WebCore::InspectorDOMAgent::setNodeName):
     91        (WebCore::InspectorDOMAgent::setOuterHTML):
     92        (WebCore::InspectorDOMAgent::setNodeValue):
     93        (WebCore::InspectorDOMAgent::moveTo):
     94        (WebCore::InspectorDOMAgent::undo):
     95        (WebCore::InspectorDOMAgent::markUndoableState):
     96        * inspector/InspectorDOMAgent.h:
     97        (InspectorDOMAgent):
     98        (WebCore::InspectorDOMAgent::history):
     99        * inspector/InspectorHistory.cpp: Added.
     100        (WebCore::InspectorHistory::Action::Action):
     101        (WebCore):
     102        (WebCore::InspectorHistory::Action::~Action):
     103        (WebCore::InspectorHistory::Action::toString):
     104        (WebCore::InspectorHistory::Action::isUndoableStateMark):
     105        (WebCore::InspectorHistory::Action::mergeId):
     106        (WebCore::InspectorHistory::Action::merge):
     107        (WebCore::InspectorHistory::InspectorHistory):
     108        (WebCore::InspectorHistory::~InspectorHistory):
     109        (WebCore::InspectorHistory::perform):
     110        (WebCore::InspectorHistory::markUndoableState):
     111        (WebCore::InspectorHistory::undo):
     112        (WebCore::InspectorHistory::reset):
     113        * inspector/InspectorHistory.h: Added.
     114        (WebCore):
     115        (InspectorHistory):
     116        (Action):
     117        * inspector/InspectorStyleSheet.cpp:
     118        (WebCore::InspectorStyle::setPropertyText):
     119        (WebCore::InspectorStyle::styleText):
     120        (WebCore::InspectorStyleSheet::addRule):
     121        (WebCore::InspectorStyleSheet::buildObjectForStyleSheet):
     122        (WebCore::InspectorStyleSheet::buildObjectForStyle):
     123        (WebCore::InspectorStyleSheet::setPropertyText):
     124        (WebCore::InspectorStyleSheet::getText):
     125        (WebCore::InspectorStyleSheetForInlineStyle::getText):
     126        * inspector/InspectorStyleSheet.h:
     127        (InspectorStyle):
     128        (InspectorStyleSheet):
     129        (InspectorStyleSheetForInlineStyle):
     130        * inspector/front-end/CSSStyleModel.js:
     131        (WebInspector.CSSProperty.prototype.setText):
     132        * inspector/front-end/ElementsPanel.js:
     133        (WebInspector.ElementsPanel.prototype._selectedNodeChanged):
     134        (WebInspector.ElementsPanel.prototype._updateSidebars):
     135        (WebInspector.ElementsPanel.prototype.handleShortcut):
     136        * inspector/front-end/StylesSidebarPane.js:
     137        (WebInspector.StylePropertiesSection.prototype.onpopulate):
     138        (WebInspector.StylePropertiesSection.prototype.addNewBlankProperty):
     139        (WebInspector.ComputedStylePropertiesSection.prototype.onpopulate):
     140        (WebInspector.StylePropertyTreeElement):
     141        (WebInspector.StylePropertyTreeElement.prototype):
     142
    11432012-02-07  Sheriff Bot  <webkit.review.bot@gmail.com>
    2144
  • trunk/Source/WebCore/GNUmakefile.list.am

    r106947 r106953  
    23912391        Source/WebCore/inspector/InspectorFrontendHost.cpp \
    23922392        Source/WebCore/inspector/InspectorFrontendHost.h \
     2393        Source/WebCore/inspector/InspectorHistory.cpp \
     2394        Source/WebCore/inspector/InspectorHistory.h \
    23932395        Source/WebCore/inspector/InspectorIndexedDBAgent.h \
    23942396        Source/WebCore/inspector/InspectorIndexedDBAgent.cpp \
  • trunk/Source/WebCore/Target.pri

    r106947 r106953  
    878878    inspector/InspectorFrontendClientLocal.cpp \
    879879    inspector/InspectorFrontendHost.cpp \
     880    inspector/InspectorHistory.cpp \
    880881    inspector/InspectorInstrumentation.cpp \
    881882    inspector/InspectorMemoryAgent.cpp \
     
    19441945    inspector/InspectorFrontendClientLocal.h \
    19451946    inspector/InspectorFrontendHost.h \
     1947    inspector/InspectorHistory.h \
    19461948    inspector/InspectorInstrumentation.h \
    19471949    inspector/InspectorMemoryAgent.h \
  • trunk/Source/WebCore/WebCore.gypi

    r106947 r106953  
    23872387            'inspector/InspectorFrontendHost.cpp',
    23882388            'inspector/InspectorFrontendHost.h',
     2389            'inspector/InspectorHistory.cpp',
     2390            'inspector/InspectorHistory.h',
    23892391            'inspector/InspectorIndexedDBAgent.cpp',
    23902392            'inspector/InspectorIndexedDBAgent.h',
  • trunk/Source/WebCore/WebCore.vcproj/WebCore.vcproj

    r106947 r106953  
    7165971659                        </File>
    7166071660                        <File
     71661                                RelativePath="..\inspector\InspectorHistory.cpp"
     71662                                >
     71663                                <FileConfiguration
     71664                                        Name="Release|Win32"
     71665                                        ExcludedFromBuild="true"
     71666                                        >
     71667                                        <Tool
     71668                                                Name="VCCLCompilerTool"
     71669                                        />
     71670                                </FileConfiguration>
     71671                                <FileConfiguration
     71672                                        Name="Production|Win32"
     71673                                        ExcludedFromBuild="true"
     71674                                        >
     71675                                        <Tool
     71676                                                Name="VCCLCompilerTool"
     71677                                        />
     71678                                </FileConfiguration>
     71679                        </File>
     71680                        <File
     71681                                RelativePath="..\inspector\InspectorHistory.h"
     71682                                >
     71683                        </File>
     71684                        <File
    7166171685                                RelativePath="..\inspector\InspectorIndexedDBAgent.cpp"
    7166271686                                >
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r106947 r106953  
    18881888                7A24587B1021EAF4000A00AA /* InspectorDOMAgent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7A2458791021EAF4000A00AA /* InspectorDOMAgent.cpp */; };
    18891889                7A24587C1021EAF4000A00AA /* InspectorDOMAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A24587A1021EAF4000A00AA /* InspectorDOMAgent.h */; settings = {ATTRIBUTES = (Private, ); }; };
     1890                7A54857F14E02D51006AE05A /* InspectorHistory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7A54857D14E02D51006AE05A /* InspectorHistory.cpp */; };
     1891                7A54858014E02D51006AE05A /* InspectorHistory.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A54857E14E02D51006AE05A /* InspectorHistory.h */; };
    18901892                7A674BDB0F9EBF4E006CF099 /* PageGroupLoadDeferrer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7A674BD90F9EBF4E006CF099 /* PageGroupLoadDeferrer.cpp */; };
    18911893                7A674BDC0F9EBF4E006CF099 /* PageGroupLoadDeferrer.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A674BDA0F9EBF4E006CF099 /* PageGroupLoadDeferrer.h */; };
     
    87698771                7A2458791021EAF4000A00AA /* InspectorDOMAgent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorDOMAgent.cpp; sourceTree = "<group>"; };
    87708772                7A24587A1021EAF4000A00AA /* InspectorDOMAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorDOMAgent.h; sourceTree = "<group>"; };
     8773                7A54857D14E02D51006AE05A /* InspectorHistory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorHistory.cpp; sourceTree = "<group>"; };
     8774                7A54857E14E02D51006AE05A /* InspectorHistory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorHistory.h; sourceTree = "<group>"; };
    87718775                7A563E5412DE32B000F4536D /* InjectedScriptSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InjectedScriptSource.h; sourceTree = "<group>"; };
    87728776                7A563F9512DF5C9100F4536D /* InjectedScriptSource.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = InjectedScriptSource.js; sourceTree = "<group>"; };
     
    1405814062                                7A0E770C10C00A8800A0276E /* InspectorFrontendHost.h */,
    1405914063                                7A0E770D10C00A8800A0276E /* InspectorFrontendHost.idl */,
     14064                                7A54857D14E02D51006AE05A /* InspectorHistory.cpp */,
     14065                                7A54857E14E02D51006AE05A /* InspectorHistory.h */,
    1406014066                                7ACD88D114C08BD60084EDD2 /* InspectorIndexedDBAgent.cpp */,
    1406114067                                7ACD88D214C08BD60084EDD2 /* InspectorIndexedDBAgent.h */,
     
    2414924155                                1AAADDE414DC8C8F00AF64B3 /* ScrollingTreeNode.h in Headers */,
    2415024156                                1AAADDE914DC8DF800AF64B3 /* ScrollingTreeNodeMac.h in Headers */,
     24157                                7A54858014E02D51006AE05A /* InspectorHistory.h in Headers */,
    2415124158                        );
    2415224159                        runOnlyForDeploymentPostprocessing = 0;
     
    2708527092                                1AAADDE314DC8C8F00AF64B3 /* ScrollingTreeNode.cpp in Sources */,
    2708627093                                1AAADDE814DC8DF800AF64B3 /* ScrollingTreeNodeMac.mm in Sources */,
     27094                                7A54857F14E02D51006AE05A /* InspectorHistory.cpp in Sources */,
    2708727095                        );
    2708827096                        runOnlyForDeploymentPostprocessing = 0;
  • trunk/Source/WebCore/inspector/Inspector.json

    r106947 r106953  
    15171517                "description": "Toggles mouse event-based touch event emulation.",
    15181518                "hidden": true
     1519            },
     1520            {
     1521                "name": "undo",
     1522                "description": "Undoes the last performed action.",
     1523                "hidden": true
     1524            },
     1525            {
     1526                "name": "markUndoableState",
     1527                "description": "Marks last undoable state.",
     1528                "hidden": true
    15191529            }
    15201530        ],
  • trunk/Source/WebCore/inspector/InspectorAllInOne.cpp

    r106947 r106953  
    4343#include "InspectorFrontendClientLocal.cpp"
    4444#include "InspectorFrontendHost.cpp"
     45#include "InspectorHistory.cpp"
    4546#include "InspectorIndexedDBAgent.cpp"
    4647#include "InspectorInstrumentation.cpp"
  • trunk/Source/WebCore/inspector/InspectorCSSAgent.cpp

    r106947 r106953  
    4040#include "HTMLHeadElement.h"
    4141#include "InspectorDOMAgent.h"
     42#include "InspectorHistory.h"
    4243#include "InspectorState.h"
    4344#include "InspectorValues.h"
     
    218219}
    219220
     221class InspectorCSSAgent::StyleSheetAction : public InspectorHistory::Action {
     222    WTF_MAKE_NONCOPYABLE(StyleSheetAction);
     223public:
     224    StyleSheetAction(const String& name, InspectorCSSAgent* cssAgent, const String& styleSheetId)
     225        : InspectorHistory::Action(name)
     226        , m_cssAgent(cssAgent)
     227        , m_styleSheetId(styleSheetId)
     228    {
     229    }
     230
     231    virtual bool perform(ErrorString* errorString)
     232    {
     233        InspectorStyleSheet* styleSheet = m_cssAgent->assertStyleSheetForId(errorString, m_styleSheetId);
     234        if (!styleSheet)
     235            return false;
     236        return perform(styleSheet, errorString);
     237    }
     238
     239    virtual bool undo(ErrorString* errorString)
     240    {
     241        InspectorStyleSheet* styleSheet = m_cssAgent->assertStyleSheetForId(errorString, m_styleSheetId);
     242        if (!styleSheet)
     243            return false;
     244        return undo(styleSheet, errorString);
     245    }
     246
     247    virtual bool perform(InspectorStyleSheet*, ErrorString*) = 0;
     248
     249    virtual bool undo(InspectorStyleSheet*, ErrorString*) = 0;
     250
     251protected:
     252    InspectorCSSAgent* m_cssAgent;
     253    String m_styleSheetId;
     254};
     255
     256class InspectorCSSAgent::SetStyleSheetTextAction : public InspectorCSSAgent::StyleSheetAction {
     257    WTF_MAKE_NONCOPYABLE(SetStyleSheetTextAction);
     258public:
     259    SetStyleSheetTextAction(InspectorCSSAgent* cssAgent, const String& styleSheetId, const String& text)
     260        : InspectorCSSAgent::StyleSheetAction("SetStyleSheetText", cssAgent, styleSheetId)
     261        , m_text(text)
     262    {
     263    }
     264
     265    virtual bool perform(InspectorStyleSheet* inspectorStyleSheet, ErrorString*)
     266    {
     267        if (!inspectorStyleSheet->getText(&m_oldText))
     268            return false;
     269
     270        if (inspectorStyleSheet->setText(m_text)) {
     271            inspectorStyleSheet->reparseStyleSheet(m_text);
     272            return true;
     273        }
     274        return false;
     275    }
     276
     277    virtual bool undo(InspectorStyleSheet* inspectorStyleSheet, ErrorString*)
     278    {
     279        if (inspectorStyleSheet->setText(m_oldText)) {
     280            inspectorStyleSheet->reparseStyleSheet(m_oldText);
     281            return true;
     282        }
     283        return false;
     284    }
     285
     286private:
     287    String m_text;
     288    String m_oldText;
     289};
     290
     291class InspectorCSSAgent::SetPropertyTextAction : public InspectorCSSAgent::StyleSheetAction {
     292    WTF_MAKE_NONCOPYABLE(SetPropertyTextAction);
     293public:
     294    SetPropertyTextAction(InspectorCSSAgent* cssAgent, const String& styleSheetId, const InspectorCSSId& cssId, unsigned propertyIndex, const String& text, bool overwrite)
     295        : InspectorCSSAgent::StyleSheetAction("SetPropertyText", cssAgent, styleSheetId)
     296        , m_cssId(cssId)
     297        , m_propertyIndex(propertyIndex)
     298        , m_text(text)
     299        , m_overwrite(overwrite)
     300    {
     301    }
     302
     303    virtual String toString()
     304    {
     305        return mergeId() + ": " + m_oldText + " -> " + m_text;
     306    }
     307
     308    virtual bool perform(InspectorStyleSheet* inspectorStyleSheet, ErrorString* errorString)
     309    {
     310        String oldText;
     311        bool result = inspectorStyleSheet->setPropertyText(errorString, m_cssId, m_propertyIndex, m_text, m_overwrite, &oldText);
     312        m_oldText = oldText.stripWhiteSpace();
     313        // FIXME: remove this once the model handles this case.
     314        if (!m_oldText.endsWith(";"))
     315            m_oldText += ";";
     316        return result;
     317    }
     318
     319    virtual bool undo(InspectorStyleSheet* inspectorStyleSheet, ErrorString* errorString)
     320    {
     321        String placeholder;
     322        return inspectorStyleSheet->setPropertyText(errorString, m_cssId, m_propertyIndex, m_overwrite ? m_oldText : "", true, &placeholder);
     323    }
     324
     325    virtual String mergeId()
     326    {
     327        return String::format("SetPropertyText %s:%u:%s", m_styleSheetId.utf8().data(), m_propertyIndex, m_overwrite ? "true" : "false");
     328    }
     329
     330    virtual void merge(PassOwnPtr<Action> action)
     331    {
     332        ASSERT(action->mergeId() == mergeId());
     333
     334        SetPropertyTextAction* other = static_cast<SetPropertyTextAction*>(action.get());
     335        m_text = other->m_text;
     336    }
     337
     338private:
     339    InspectorCSSId m_cssId;
     340    unsigned m_propertyIndex;
     341    String m_text;
     342    String m_oldText;
     343    bool m_overwrite;
     344};
     345
     346class InspectorCSSAgent::TogglePropertyAction : public InspectorCSSAgent::StyleSheetAction {
     347    WTF_MAKE_NONCOPYABLE(TogglePropertyAction);
     348public:
     349    TogglePropertyAction(InspectorCSSAgent* cssAgent, const String& styleSheetId, const InspectorCSSId& cssId, unsigned propertyIndex, bool disable)
     350        : InspectorCSSAgent::StyleSheetAction("ToggleProperty", cssAgent, styleSheetId)
     351        , m_cssId(cssId)
     352        , m_propertyIndex(propertyIndex)
     353        , m_disable(disable)
     354    {
     355    }
     356
     357    virtual bool perform(InspectorStyleSheet* inspectorStyleSheet, ErrorString* errorString)
     358    {
     359        return inspectorStyleSheet->toggleProperty(errorString, m_cssId, m_propertyIndex, m_disable);
     360    }
     361
     362    virtual bool undo(InspectorStyleSheet* inspectorStyleSheet, ErrorString* errorString)
     363    {
     364      return inspectorStyleSheet->toggleProperty(errorString, m_cssId, m_propertyIndex, !m_disable);
     365    }
     366
     367private:
     368    InspectorCSSId m_cssId;
     369    unsigned m_propertyIndex;
     370    bool m_disable;
     371};
     372
    220373// static
    221374CSSStyleRule* InspectorCSSAgent::asCSSStyleRule(CSSRule* rule)
     
    439592        return;
    440593
    441     inspectorStyleSheet->text(result);
     594    inspectorStyleSheet->getText(result);
    442595}
    443596
    444597void InspectorCSSAgent::setStyleSheetText(ErrorString* errorString, const String& styleSheetId, const String& text)
    445598{
    446     InspectorStyleSheet* inspectorStyleSheet = assertStyleSheetForId(errorString, styleSheetId);
    447     if (!inspectorStyleSheet)
    448         return;
    449 
    450     if (inspectorStyleSheet->setText(text))
    451         inspectorStyleSheet->reparseStyleSheet(text);
    452     else
    453         *errorString = "Internal error setting style sheet text";
     599    m_domAgent->history()->perform(adoptPtr(new SetStyleSheetTextAction(this, styleSheetId, text)), errorString);
     600    m_domAgent->history()->markUndoableState();
    454601}
    455602
     
    463610        return;
    464611
    465     bool success = inspectorStyleSheet->setPropertyText(errorString, compoundId, propertyIndex, text, overwrite);
     612    bool success = m_domAgent->history()->perform(adoptPtr(new SetPropertyTextAction(this, compoundId.styleSheetId(), compoundId, propertyIndex, text, overwrite)), errorString);
    466613    if (success)
    467614        result = inspectorStyleSheet->buildObjectForStyle(inspectorStyleSheet->styleForId(compoundId));
     
    477624        return;
    478625
    479     bool success = inspectorStyleSheet->toggleProperty(errorString, compoundId, propertyIndex, disable);
     626    bool success = m_domAgent->history()->perform(adoptPtr(new TogglePropertyAction(this, compoundId.styleSheetId(), compoundId, propertyIndex, disable)), errorString);
    480627    if (success)
    481628        result = inspectorStyleSheet->buildObjectForStyle(inspectorStyleSheet->styleForId(compoundId));
     629    m_domAgent->history()->markUndoableState();
    482630}
    483631
  • trunk/Source/WebCore/inspector/InspectorCSSAgent.h

    r106947 r106953  
    9999
    100100private:
     101    class StyleSheetAction;
     102    class SetStyleSheetTextAction;
     103    class SetPropertyTextAction;
     104    class TogglePropertyAction;
     105
    101106    InspectorCSSAgent(InstrumentingAgents*, InspectorState*, InspectorDOMAgent*);
    102107
  • trunk/Source/WebCore/inspector/InspectorDOMAgent.cpp

    r106947 r106953  
    178178}
    179179
     180class InspectorDOMAgent::DOMAction : public InspectorHistory::Action {
     181public:
     182    DOMAction(const String& name) : InspectorHistory::Action(name) { }
     183
     184    virtual bool perform(ErrorString* errorString)
     185    {
     186        ExceptionCode ec = 0;
     187        bool result = perform(ec);
     188        if (ec) {
     189            ExceptionCodeDescription description(ec);
     190            *errorString = description.name;
     191        }
     192        return result && !ec;
     193    }
     194
     195    virtual bool undo(ErrorString* errorString)
     196    {
     197        ExceptionCode ec = 0;
     198        bool result = undo(ec);
     199        if (ec) {
     200            ExceptionCodeDescription description(ec);
     201            *errorString = description.name;
     202        }
     203        return result && !ec;
     204    }
     205
     206    virtual bool perform(ExceptionCode&) = 0;
     207
     208    virtual bool undo(ExceptionCode&) = 0;
     209
     210private:
     211    RefPtr<Node> m_parentNode;
     212    RefPtr<Node> m_node;
     213    RefPtr<Node> m_anchorNode;
     214};
     215
     216class InspectorDOMAgent::RemoveChildAction : public InspectorDOMAgent::DOMAction {
     217    WTF_MAKE_NONCOPYABLE(RemoveChildAction);
     218public:
     219    RemoveChildAction(Node* parentNode, Node* node)
     220        : InspectorDOMAgent::DOMAction("RemoveChild")
     221        , m_parentNode(parentNode)
     222        , m_node(node)
     223    {
     224    }
     225
     226    virtual bool perform(ExceptionCode& ec)
     227    {
     228        m_anchorNode = m_node->nextSibling();
     229        return m_parentNode->removeChild(m_node.get(), ec);
     230    }
     231
     232    virtual bool undo(ExceptionCode& ec)
     233    {
     234        return m_parentNode->insertBefore(m_node.get(), m_anchorNode.get(), ec);
     235    }
     236
     237private:
     238    RefPtr<Node> m_parentNode;
     239    RefPtr<Node> m_node;
     240    RefPtr<Node> m_anchorNode;
     241};
     242
     243class InspectorDOMAgent::InsertBeforeAction : public InspectorDOMAgent::DOMAction {
     244    WTF_MAKE_NONCOPYABLE(InsertBeforeAction);
     245public:
     246    InsertBeforeAction(Node* parentNode, Node* node, Node* anchorNode)
     247        : InspectorDOMAgent::DOMAction("InsertBefore")
     248        , m_parentNode(parentNode)
     249        , m_node(node)
     250        , m_anchorNode(anchorNode)
     251    {
     252    }
     253
     254    virtual bool perform(ExceptionCode& ec)
     255    {
     256        if (m_node->parentNode()) {
     257            m_removeChildAction = adoptPtr(new RemoveChildAction(m_node->parentNode(), m_node.get()));
     258            if (!m_removeChildAction->perform(ec))
     259                return false;
     260        }
     261        return m_parentNode->insertBefore(m_node.get(), m_anchorNode.get(), ec);
     262    }
     263
     264    virtual bool undo(ExceptionCode& ec)
     265    {
     266        if (m_removeChildAction)
     267            return m_removeChildAction->undo(ec);
     268
     269        return m_parentNode->removeChild(m_node.get(), ec);
     270    }
     271
     272private:
     273    RefPtr<Node> m_parentNode;
     274    RefPtr<Node> m_node;
     275    RefPtr<Node> m_anchorNode;
     276    OwnPtr<RemoveChildAction> m_removeChildAction;
     277};
     278
     279class InspectorDOMAgent::RemoveAttributeAction : public InspectorDOMAgent::DOMAction {
     280    WTF_MAKE_NONCOPYABLE(RemoveAttributeAction);
     281public:
     282    RemoveAttributeAction(Element* element, const String& name)
     283        : InspectorDOMAgent::DOMAction("RemoveAttribute")
     284        , m_element(element)
     285        , m_name(name)
     286    {
     287    }
     288
     289    virtual bool perform(ExceptionCode&)
     290    {
     291        m_value = m_element->getAttribute(m_name);
     292        m_element->removeAttribute(m_name);
     293        return true;
     294    }
     295
     296    virtual bool undo(ExceptionCode& ec)
     297    {
     298        m_element->setAttribute(m_name, m_value, ec);
     299        return true;
     300    }
     301
     302private:
     303    RefPtr<Element> m_element;
     304    String m_name;
     305    String m_value;
     306};
     307
     308class InspectorDOMAgent::SetAttributeAction : public InspectorDOMAgent::DOMAction {
     309    WTF_MAKE_NONCOPYABLE(SetAttributeAction);
     310public:
     311    SetAttributeAction(Element* element, const String& name, const String& value)
     312        : InspectorDOMAgent::DOMAction("SetAttribute")
     313        , m_element(element)
     314        , m_name(name)
     315        , m_value(value)
     316        , m_hadAttribute(false)
     317    {
     318    }
     319
     320    virtual bool perform(ExceptionCode& ec)
     321    {
     322        m_hadAttribute = m_element->hasAttribute(m_name);
     323        if (m_hadAttribute)
     324            m_oldValue = m_element->getAttribute(m_name);
     325        m_element->setAttribute(m_name, m_value, ec);
     326        return !ec;
     327    }
     328
     329    virtual bool undo(ExceptionCode& ec)
     330    {
     331        if (m_hadAttribute)
     332            m_element->setAttribute(m_name, m_oldValue, ec);
     333        else
     334            m_element->removeAttribute(m_name);
     335        return true;
     336    }
     337
     338private:
     339    RefPtr<Element> m_element;
     340    String m_name;
     341    String m_value;
     342    bool m_hadAttribute;
     343    String m_oldValue;
     344};
     345
     346class InspectorDOMAgent::SetOuterHTMLAction : public InspectorDOMAgent::DOMAction {
     347    WTF_MAKE_NONCOPYABLE(SetOuterHTMLAction);
     348public:
     349    SetOuterHTMLAction(Node* node, const String& html)
     350        : InspectorDOMAgent::DOMAction("SetOuterHTML")
     351        , m_node(node)
     352        , m_html(html)
     353        , m_newNode(0)
     354    {
     355    }
     356
     357    virtual bool perform(ExceptionCode& ec)
     358    {
     359        m_oldHTML = createMarkup(m_node.get());
     360        DOMEditor domEditor(m_node->ownerDocument());
     361        m_newNode = domEditor.patchNode(m_node.get(), m_html, ec);
     362        return !ec;
     363    }
     364
     365    virtual bool undo(ExceptionCode& ec)
     366    {
     367        DOMEditor domEditor(m_node->ownerDocument());
     368        domEditor.patchNode(m_node.get(), m_oldHTML, ec);
     369        return !ec;
     370    }
     371
     372    Node* newNode()
     373    {
     374        return m_newNode;
     375    }
     376
     377private:
     378    RefPtr<Node> m_node;
     379    String m_html;
     380    String m_oldHTML;
     381    Node* m_newNode;
     382};
     383
     384class InspectorDOMAgent::ReplaceWholeTextAction : public InspectorDOMAgent::DOMAction {
     385    WTF_MAKE_NONCOPYABLE(ReplaceWholeTextAction);
     386public:
     387    ReplaceWholeTextAction(Text* textNode, const String& text)
     388        : DOMAction("ReplaceWholeText")
     389        , m_textNode(textNode)
     390        , m_text(text)
     391    {
     392    }
     393
     394    virtual bool perform(ExceptionCode& ec)
     395    {
     396        m_oldText = m_textNode->wholeText();
     397        m_textNode->replaceWholeText(m_text, ec);
     398        return true;
     399    }
     400
     401    virtual bool undo(ExceptionCode& ec)
     402    {
     403        m_textNode->replaceWholeText(m_oldText, ec);
     404        return true;
     405    }
     406
     407private:
     408    RefPtr<Text> m_textNode;
     409    String m_text;
     410    String m_oldText;
     411};
     412
    180413InspectorDOMAgent::InspectorDOMAgent(InstrumentingAgents* instrumentingAgents, InspectorPageAgent* pageAgent, InspectorClient* client, InspectorState* inspectorState, InjectedScriptManager* injectedScriptManager)
    181414    : InspectorBaseAgent<InspectorDOMAgent>("DOM", instrumentingAgents, inspectorState)
     
    187420    , m_lastNodeId(1)
    188421    , m_searchingForNode(false)
     422    , m_history(adoptPtr(new InspectorHistory()))
    189423{
    190424}
     
    254488void InspectorDOMAgent::reset()
    255489{
    256     ErrorString error;
     490    m_history->reset();
    257491    m_searchResults.clear();
    258492    discardBindings();
     
    519753        return;
    520754
    521     ExceptionCode ec = 0;
    522     element->setAttribute(name, value, ec);
    523     if (ec)
    524         *errorString = "Internal error: could not set attribute value";
     755    m_history->perform(adoptPtr(new SetAttributeAction(element, name, value)), errorString);
     756    m_history->markUndoableState();
    525757}
    526758
     
    552784    Element* childElement = toElement(child);
    553785    if (!childElement->hasAttributes() && name) {
    554         element->removeAttribute(*name);
     786        m_history->perform(adoptPtr(new RemoveAttributeAction(element, *name)), errorString);
    555787        return;
    556788    }
     
    562794        const Attribute* attribute = childElement->attributeItem(i);
    563795        foundOriginalAttribute = foundOriginalAttribute || (name && attribute->name().toString() == *name);
    564         element->setAttribute(attribute->name(), attribute->value());
    565     }
    566 
    567     if (!foundOriginalAttribute && name) {
    568         element->removeAttribute(*name);
    569         return;
    570     }
     796        if (!m_history->perform(adoptPtr(new SetAttributeAction(element, attribute->name().toString(), attribute->value())), errorString))
     797            return;
     798    }
     799
     800    if (!foundOriginalAttribute && name && !name->stripWhiteSpace().isEmpty())
     801        m_history->perform(adoptPtr(new RemoveAttributeAction(element, *name)), errorString);
     802
     803    m_history->markUndoableState();
    571804}
    572805
     
    574807{
    575808    Element* element = assertElement(errorString, elementId);
    576     if (element)
    577         element->removeAttribute(name);
     809    if (!element)
     810        return;
     811
     812    m_history->perform(adoptPtr(new RemoveAttributeAction(element, name)), errorString);
     813    m_history->markUndoableState();
    578814}
    579815
     
    590826    }
    591827
    592     ExceptionCode ec = 0;
    593     parentNode->removeChild(node, ec);
    594     if (ec)
    595         *errorString = "Could not remove node due to DOM exception";
    596 }
    597 
    598 void InspectorDOMAgent::setNodeName(ErrorString*, int nodeId, const String& tagName, int* newId)
     828    m_history->perform(adoptPtr(new RemoveChildAction(parentNode, node)), errorString);
     829    m_history->markUndoableState();
     830}
     831
     832void InspectorDOMAgent::setNodeName(ErrorString* errorString, int nodeId, const String& tagName, int* newId)
    599833{
    600834    *newId = 0;
     
    614848    // Copy over the original node's children.
    615849    Node* child;
    616     while ((child = oldNode->firstChild()))
    617         newElem->appendChild(child, ec);
     850    while ((child = oldNode->firstChild())) {
     851        if (!m_history->perform(adoptPtr(new InsertBeforeAction(newElem.get(), child, 0)), errorString))
     852            return;
     853    }
    618854
    619855    // Replace the old node with the new node
    620856    ContainerNode* parent = oldNode->parentNode();
    621     parent->insertBefore(newElem, oldNode->nextSibling(), ec);
    622     parent->removeChild(oldNode, ec);
    623 
    624     if (ec)
    625         return;
     857    if (!m_history->perform(adoptPtr(new InsertBeforeAction(parent, newElem.get(), oldNode->nextSibling())), errorString))
     858        return;
     859    if (!m_history->perform(adoptPtr(new RemoveChildAction(parent, oldNode)), errorString))
     860        return;
     861    m_history->markUndoableState();
    626862
    627863    *newId = pushNodePathToFrontend(newElem.get());
     
    659895    DOMEditor domEditor(document);
    660896
    661     ExceptionCode ec = 0;
    662     Node* newNode = domEditor.patchNode(node, outerHTML, ec);
    663     if (ec) {
    664         ExceptionCodeDescription description(ec);
    665         *errorString = description.name;
    666         return;
    667     }
     897    OwnPtr<SetOuterHTMLAction> action = adoptPtr(new SetOuterHTMLAction(node, outerHTML));
     898    SetOuterHTMLAction* rawAction = action.get();
     899    Node* newNode = 0;
     900    if (!m_history->perform(action.release(), errorString))
     901        return;
     902    m_history->markUndoableState();
     903
     904    newNode = rawAction->newNode();
    668905
    669906    if (!newNode) {
     
    690927    }
    691928
    692     Text* textNode = static_cast<Text*>(node);
    693     ExceptionCode ec = 0;
    694     textNode->replaceWholeText(value, ec);
    695     if (ec)
    696         *errorString = "DOM Error while setting the node value";
     929    m_history->perform(adoptPtr(new ReplaceWholeTextAction(static_cast<Text*>(node), value)), errorString);
    697930}
    698931
     
    10311264}
    10321265
    1033 void InspectorDOMAgent::moveTo(ErrorString* error, int nodeId, int targetElementId, const int* const anchorNodeId, int* newNodeId)
    1034 {
    1035     Node* node = assertNode(error, nodeId);
     1266void InspectorDOMAgent::moveTo(ErrorString* errorString, int nodeId, int targetElementId, const int* const anchorNodeId, int* newNodeId)
     1267{
     1268    Node* node = assertNode(errorString, nodeId);
    10361269    if (!node)
    10371270        return;
    10381271
    1039     Element* targetElement = assertElement(error, targetElementId);
     1272    Element* targetElement = assertElement(errorString, targetElementId);
    10401273    if (!targetElement)
    10411274        return;
     
    10431276    Node* anchorNode = 0;
    10441277    if (anchorNodeId && *anchorNodeId) {
    1045         anchorNode = assertNode(error, *anchorNodeId);
     1278        anchorNode = assertNode(errorString, *anchorNodeId);
    10461279        if (!anchorNode)
    10471280            return;
    10481281        if (anchorNode->parentNode() != targetElement) {
    1049             *error = "Anchor node must be child of the target element";
     1282            *errorString = "Anchor node must be child of the target element";
    10501283            return;
    10511284        }
    10521285    }
    10531286
    1054     ExceptionCode ec = 0;
    1055     bool success = targetElement->insertBefore(node, anchorNode, ec);
    1056     if (ec || !success) {
    1057         *error = "Could not drop node";
    1058         return;
    1059     }
     1287    if (!m_history->perform(adoptPtr(new InsertBeforeAction(targetElement, node, anchorNode)), errorString))
     1288        return;
     1289    m_history->markUndoableState();
     1290
    10601291    *newNodeId = pushNodePathToFrontend(node);
    10611292}
     
    10721303    UNUSED_PARAM(enabled);
    10731304#endif
     1305}
     1306
     1307void InspectorDOMAgent::undo(ErrorString* errorString)
     1308{
     1309    m_history->undo(errorString);
     1310}
     1311
     1312void InspectorDOMAgent::markUndoableState(ErrorString*)
     1313{
     1314    m_history->markUndoableState();
    10741315}
    10751316
  • trunk/Source/WebCore/inspector/InspectorDOMAgent.h

    r106947 r106953  
    3636#include "InspectorBaseAgent.h"
    3737#include "InspectorFrontend.h"
     38#include "InspectorHistory.h"
    3839#include "InspectorValues.h"
    3940#include "Timer.h"
     
    144145    virtual void moveTo(ErrorString*, int nodeId, int targetNodeId, const int* anchorNodeId, int* newNodeId);
    145146    virtual void setTouchEmulationEnabled(ErrorString*, bool);
     147    virtual void undo(ErrorString*);
     148    virtual void markUndoableState(ErrorString*);
    146149
    147150    Node* highlightedNode() const;
     
    176179    void drawHighlight(GraphicsContext&) const;
    177180    void getHighlight(Highlight*) const;
     181
     182    InspectorHistory* history() { return m_history.get(); }
    178183
    179184    // We represent embedded doms as a part of the same hierarchy. Hence we treat children of frame owners differently.
     
    189194
    190195private:
     196    class DOMAction;
     197    class RemoveChildAction;
     198    class InsertBeforeAction;
     199    class RemoveAttributeAction;
     200    class SetAttributeAction;
     201    class SetOuterHTMLAction;
     202    class ReplaceWholeTextAction;
     203
    191204    InspectorDOMAgent(InstrumentingAgents*, InspectorPageAgent*, InspectorClient*, InspectorState*, InjectedScriptManager*);
    192205
     
    241254    RefPtr<Node> m_nodeToFocus;
    242255    bool m_searchingForNode;
     256    OwnPtr<InspectorHistory> m_history;
    243257};
    244258
  • trunk/Source/WebCore/inspector/InspectorStyleSheet.cpp

    r106947 r106953  
    281281// The propertyText (if not empty) is checked to be a valid style declaration (containing at least one property). If not,
    282282// the method returns false (denoting an error).
    283 bool InspectorStyle::setPropertyText(ErrorString* errorString, unsigned index, const String& propertyText, bool overwrite)
     283bool InspectorStyle::setPropertyText(ErrorString* errorString, unsigned index, const String& propertyText, bool overwrite, String* oldText)
    284284{
    285285    ASSERT(m_parentStyleSheet);
     
    329329
    330330    InspectorStyleTextEditor editor(&allProperties, &m_disabledProperties, text, newLineAndWhitespaceDelimiters());
    331     if (overwrite)
     331    if (overwrite) {
     332        *oldText = allProperties.at(index).rawText;
    332333        editor.replaceProperty(index, propertyText);
    333     else
     334    } else
    334335        editor.insertProperty(index, propertyText, sourceData->styleSourceData->styleBodyRange.length());
    335336
     
    386387
    387388    String styleSheetText;
    388     bool success = m_parentStyleSheet->text(&styleSheetText);
     389    bool success = m_parentStyleSheet->getText(&styleSheetText);
    389390    if (!success)
    390391        return false;
     
    730731{
    731732    String styleSheetText;
    732     bool success = text(&styleSheetText);
     733    bool success = getText(&styleSheetText);
    733734    if (!success)
    734735        return 0;
     
    778779
    779780    String styleSheetText;
    780     bool success = text(&styleSheetText);
     781    bool success = getText(&styleSheetText);
    781782    if (success)
    782783        result->setString("text", styleSheetText);
     
    858859    if (sourceData) {
    859860        String sheetText;
    860         bool success = text(&sheetText);
     861        bool success = getText(&sheetText);
    861862        if (success) {
    862863            const SourceRange& bodyRange = sourceData->styleSourceData->styleBodyRange;
     
    868869}
    869870
    870 bool InspectorStyleSheet::setPropertyText(ErrorString* errorString, const InspectorCSSId& id, unsigned propertyIndex, const String& text, bool overwrite)
     871bool InspectorStyleSheet::setPropertyText(ErrorString* errorString, const InspectorCSSId& id, unsigned propertyIndex, const String& text, bool overwrite, String* oldText)
    871872{
    872873    RefPtr<InspectorStyle> inspectorStyle = inspectorStyleForId(id);
     
    876877    }
    877878
    878     return inspectorStyle->setPropertyText(errorString, propertyIndex, text, overwrite);
     879    return inspectorStyle->setPropertyText(errorString, propertyIndex, text, overwrite, oldText);
    879880}
    880881
     
    897898}
    898899
    899 bool InspectorStyleSheet::text(String* result) const
     900bool InspectorStyleSheet::getText(String* result) const
    900901{
    901902    if (!ensureText())
     
    12421243}
    12431244
    1244 bool InspectorStyleSheetForInlineStyle::text(String* result) const
     1245bool InspectorStyleSheetForInlineStyle::getText(String* result) const
    12451246{
    12461247    if (!m_isStyleTextValid) {
  • trunk/Source/WebCore/inspector/InspectorStyleSheet.h

    r106947 r106953  
    132132    PassRefPtr<InspectorArray> buildArrayForComputedStyle() const;
    133133    bool hasDisabledProperties() const { return !m_disabledProperties.isEmpty(); }
    134     bool setPropertyText(ErrorString*, unsigned index, const String& text, bool overwrite);
     134    bool setPropertyText(ErrorString*, unsigned index, const String& text, bool overwrite, String* oldText);
    135135    bool toggleProperty(ErrorString*, unsigned index, bool disable);
    136136
     
    175175    PassRefPtr<InspectorObject> buildObjectForRule(CSSStyleRule*);
    176176    PassRefPtr<InspectorObject> buildObjectForStyle(CSSStyleDeclaration*);
    177     bool setPropertyText(ErrorString*, const InspectorCSSId&, unsigned propertyIndex, const String& text, bool overwrite);
     177    bool setPropertyText(ErrorString*, const InspectorCSSId&, unsigned propertyIndex, const String& text, bool overwrite, String* oldPropertyText);
    178178    bool toggleProperty(ErrorString*, const InspectorCSSId&, unsigned propertyIndex, bool disable);
    179179
    180     virtual bool text(String* result) const;
     180    virtual bool getText(String* result) const;
    181181    virtual CSSStyleDeclaration* styleForId(const InspectorCSSId&) const;
    182182
     
    229229
    230230    void didModifyElementAttribute();
    231     virtual bool text(String* result) const;
     231    virtual bool getText(String* result) const;
    232232    virtual CSSStyleDeclaration* styleForId(const InspectorCSSId& id) const { ASSERT_UNUSED(id, !id.ordinal()); return inlineStyle(); }
    233233
  • trunk/Source/WebCore/inspector/front-end/CSSStyleModel.js

    r106947 r106953  
    644644        // An index past all the properties adds a new property to the style.
    645645        CSSAgent.setPropertyText(this.ownerStyle.id, this.index, propertyText, this.index < this.ownerStyle.pastLastSourcePropertyIndex(), callback.bind(this));
     646        if (majorChange)
     647            DOMAgent.markUndoableState();
    646648    },
    647649
  • trunk/Source/WebCore/inspector/front-end/ElementsPanel.js

    r106947 r106953  
    168168        this.updateBreadcrumb(false);
    169169
     170        this._updateSidebars();
     171
     172        if (selectedNode) {
     173            ConsoleAgent.addInspectedNode(selectedNode.id);
     174            this._lastValidSelectedNode = selectedNode;
     175        }
     176    },
     177
     178    _updateSidebars: function()
     179    {
    170180        for (var pane in this.sidebarPanes)
    171181           this.sidebarPanes[pane].needsUpdate = true;
     
    175185        this.updateProperties();
    176186        this.updateEventListeners();
    177 
    178         if (selectedNode) {
    179             ConsoleAgent.addInspectedNode(selectedNode.id);
    180             this._lastValidSelectedNode = selectedNode;
    181         }
    182187    },
    183188
     
    908913        // Cmd/Control + Shift + C should be a shortcut to clicking the Node Search Button.
    909914        // This shortcut matches Firebug.
    910         if (event.keyIdentifier === "U+0043") {     // C key
     915        if (event.keyIdentifier === "U+0043") { // C key
    911916            if (WebInspector.isMac())
    912917                var isNodeSearchKey = event.metaKey && !event.ctrlKey && !event.altKey && event.shiftKey;
     
    919924                return;
    920925            }
    921         }
     926            return;
     927        }
     928        if (WebInspector.KeyboardShortcut.eventHasCtrlOrMeta(event) && event.keyIdentifier === "U+005A")  // Z key
     929            DOMAgent.undo(this._updateSidebars.bind(this));
    922930    },
    923931
  • trunk/Source/WebCore/inspector/front-end/StylesSidebarPane.js

    r106947 r106953  
    10691069            var overloaded = this.isPropertyOverloaded(property.name, isShorthand);
    10701070
    1071             var item = new WebInspector.StylePropertyTreeElement(this._parentPane, this.styleRule, style, property, isShorthand, inherited, overloaded);
     1071            var item = new WebInspector.StylePropertyTreeElement(this, this._parentPane, this.styleRule, style, property, isShorthand, inherited, overloaded);
    10721072            this.propertiesTreeOutline.appendChild(item);
    10731073            handledProperties[property.name] = property;
     
    10931093        var style = this.styleRule.style;
    10941094        var property = style.newBlankProperty();
    1095         var item = new WebInspector.StylePropertyTreeElement(this._parentPane, this.styleRule, style, property, false, false, false);
     1095        var item = new WebInspector.StylePropertyTreeElement(this, this._parentPane, this.styleRule, style, property, false, false, false);
    10961096        this.propertiesTreeOutline.appendChild(item);
    10971097        item.listItemElement.textContent = "";
     
    12991299            var property = uniqueProperties[i];
    13001300            var inherited = this._isPropertyInherited(property.name);
    1301             var item = new WebInspector.StylePropertyTreeElement(null, this.styleRule, style, property, false, inherited, false);
     1301            var item = new WebInspector.StylePropertyTreeElement(this, null, this.styleRule, style, property, false, inherited, false);
    13021302            this.propertiesTreeOutline.appendChild(item);
    13031303            this._propertyTreeElements[property.name] = item;
     
    14251425 * @param {?WebInspector.StylesSidebarPane} parentPane
    14261426 */
    1427 WebInspector.StylePropertyTreeElement = function(parentPane, styleRule, style, property, shorthand, inherited, overloaded)
     1427WebInspector.StylePropertyTreeElement = function(section, parentPane, styleRule, style, property, shorthand, inherited, overloaded)
    14281428{
     1429    this.section = section;
    14291430    this._parentPane = parentPane;
    14301431    this._styleRule = styleRule;
     
    18201821
    18211822            var liveProperty = this.style.getLiveProperty(name);
    1822             var item = new WebInspector.StylePropertyTreeElement(this._parentPane, this._styleRule, this.style, liveProperty, false, inherited, overloaded);
     1823            var item = new WebInspector.StylePropertyTreeElement(this, this._parentPane, this._styleRule, this.style, liveProperty, false, inherited, overloaded);
    18231824            this.appendChild(item);
    18241825        }
Note: See TracChangeset for help on using the changeset viewer.