Home | History | Annotate | Download | only in inspector
      1 /*
      2  * Copyright (C) 2012 Google Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions are
      6  * met:
      7  *
      8  *     * Redistributions of source code must retain the above copyright
      9  * notice, this list of conditions and the following disclaimer.
     10  *     * Redistributions in binary form must reproduce the above
     11  * copyright notice, this list of conditions and the following disclaimer
     12  * in the documentation and/or other materials provided with the
     13  * distribution.
     14  *     * Neither the name of Google Inc. nor the names of its
     15  * contributors may be used to endorse or promote products derived from
     16  * this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 
     31 #include "config.h"
     32 #include "core/inspector/InspectorHistory.h"
     33 
     34 #include "bindings/v8/ExceptionState.h"
     35 #include "bindings/v8/ExceptionStatePlaceholder.h"
     36 #include "core/dom/Node.h"
     37 
     38 namespace WebCore {
     39 
     40 namespace {
     41 
     42 class UndoableStateMark : public InspectorHistory::Action {
     43 public:
     44     UndoableStateMark() : InspectorHistory::Action("[UndoableState]") { }
     45 
     46     virtual bool perform(ExceptionState&) { return true; }
     47 
     48     virtual bool undo(ExceptionState&) { return true; }
     49 
     50     virtual bool redo(ExceptionState&) { return true; }
     51 
     52     virtual bool isUndoableStateMark() { return true; }
     53 };
     54 
     55 }
     56 
     57 InspectorHistory::Action::Action(const String& name) : m_name(name)
     58 {
     59 }
     60 
     61 InspectorHistory::Action::~Action()
     62 {
     63 }
     64 
     65 String InspectorHistory::Action::toString()
     66 {
     67     return m_name;
     68 }
     69 
     70 bool InspectorHistory::Action::isUndoableStateMark()
     71 {
     72     return false;
     73 }
     74 
     75 String InspectorHistory::Action::mergeId()
     76 {
     77     return "";
     78 }
     79 
     80 void InspectorHistory::Action::merge(PassOwnPtr<Action>)
     81 {
     82 }
     83 
     84 InspectorHistory::InspectorHistory() : m_afterLastActionIndex(0) { }
     85 
     86 InspectorHistory::~InspectorHistory() { }
     87 
     88 bool InspectorHistory::perform(PassOwnPtr<Action> action, ExceptionState& es)
     89 {
     90     if (!action->perform(es))
     91         return false;
     92 
     93     if (!action->mergeId().isEmpty() && m_afterLastActionIndex > 0 && action->mergeId() == m_history[m_afterLastActionIndex - 1]->mergeId())
     94         m_history[m_afterLastActionIndex - 1]->merge(action);
     95     else {
     96         m_history.resize(m_afterLastActionIndex);
     97         m_history.append(action);
     98         ++m_afterLastActionIndex;
     99     }
    100     return true;
    101 }
    102 
    103 void InspectorHistory::markUndoableState()
    104 {
    105     perform(adoptPtr(new UndoableStateMark()), IGNORE_EXCEPTION);
    106 }
    107 
    108 bool InspectorHistory::undo(ExceptionState& es)
    109 {
    110     while (m_afterLastActionIndex > 0 && m_history[m_afterLastActionIndex - 1]->isUndoableStateMark())
    111         --m_afterLastActionIndex;
    112 
    113     while (m_afterLastActionIndex > 0) {
    114         Action* action = m_history[m_afterLastActionIndex - 1].get();
    115         if (!action->undo(es)) {
    116             reset();
    117             return false;
    118         }
    119         --m_afterLastActionIndex;
    120         if (action->isUndoableStateMark())
    121             break;
    122     }
    123 
    124     return true;
    125 }
    126 
    127 bool InspectorHistory::redo(ExceptionState& es)
    128 {
    129     while (m_afterLastActionIndex < m_history.size() && m_history[m_afterLastActionIndex]->isUndoableStateMark())
    130         ++m_afterLastActionIndex;
    131 
    132     while (m_afterLastActionIndex < m_history.size()) {
    133         Action* action = m_history[m_afterLastActionIndex].get();
    134         if (!action->redo(es)) {
    135             reset();
    136             return false;
    137         }
    138         ++m_afterLastActionIndex;
    139         if (action->isUndoableStateMark())
    140             break;
    141     }
    142     return true;
    143 }
    144 
    145 void InspectorHistory::reset()
    146 {
    147     m_afterLastActionIndex = 0;
    148     m_history.clear();
    149 }
    150 
    151 } // namespace WebCore
    152 
    153