151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/* 251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * Copyright (C) 2006, 2007 Apple, Inc. All rights reserved. 351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * Copyright (C) 2012 Google, Inc. All rights reserved. 451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * 551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * Redistribution and use in source and binary forms, with or without 651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * modification, are permitted provided that the following conditions 751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * are met: 851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * 1. Redistributions of source code must retain the above copyright 951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * notice, this list of conditions and the following disclaimer. 1051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright 1151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * notice, this list of conditions and the following disclaimer in the 1251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * documentation and/or other materials provided with the distribution. 1351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * 1451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 1551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 1751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 1851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 1951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 2051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 2151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 2251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) */ 2651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) 2751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "config.h" 285d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "core/editing/UndoStack.h" 2951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) 3051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "core/dom/ContainerNode.h" 3151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "core/editing/UndoStep.h" 32e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)#include "platform/EventDispatchForbiddenScope.h" 3351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "wtf/TemporaryChange.h" 3451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) 35c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink { 3651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) 3751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)// Arbitrary depth limit for the undo stack, to keep it from using 3851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)// unbounded memory. This is the maximum number of distinct undoable 3951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)// actions -- unbroken stretches of typed characters are coalesced 4051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)// into a single action. 4151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)static const size_t maximumUndoStackDepth = 1000; 4251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) 4351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)UndoStack::UndoStack() 4451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) : m_inRedo(false) 4551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){ 4651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)} 4751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) 485d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(UndoStack) 4951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) 505d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)PassOwnPtrWillBeRawPtr<UndoStack> UndoStack::create() 5151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){ 525d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return adoptPtrWillBeNoop(new UndoStack()); 5351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)} 5451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) 55f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)void UndoStack::registerUndoStep(PassRefPtrWillBeRawPtr<UndoStep> step) 5651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){ 5751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) if (m_undoStack.size() == maximumUndoStackDepth) 5851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) m_undoStack.removeFirst(); // drop oldest item off the far end 5951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) if (!m_inRedo) 6051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) m_redoStack.clear(); 6151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) m_undoStack.append(step); 6251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)} 6351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) 64f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)void UndoStack::registerRedoStep(PassRefPtrWillBeRawPtr<UndoStep> step) 6551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){ 6651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) m_redoStack.append(step); 6751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)} 6851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) 69d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void UndoStack::didUnloadFrame(const LocalFrame& frame) 7051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){ 71e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) EventDispatchForbiddenScope assertNoEventDispatch; 72a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) filterOutUndoSteps(m_undoStack, frame); 73a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) filterOutUndoSteps(m_redoStack, frame); 74a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)} 75a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) 765d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)void UndoStack::filterOutUndoSteps(UndoStepStack& stack, const LocalFrame& frame) 77a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles){ 78a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) UndoStepStack newStack; 79a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) while (!stack.isEmpty()) { 80a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) UndoStep* step = stack.first().get(); 81a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) if (!step->belongsTo(frame)) 82a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) newStack.append(step); 83a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) stack.removeFirst(); 84a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) } 85a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) stack.swap(newStack); 8651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)} 8751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) 8851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)bool UndoStack::canUndo() const 8951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){ 9051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) return !m_undoStack.isEmpty(); 9151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)} 9251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) 9351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)bool UndoStack::canRedo() const 9451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){ 9551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) return !m_redoStack.isEmpty(); 9651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)} 9751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) 9851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void UndoStack::undo() 9951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){ 10051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) if (canUndo()) { 101a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) UndoStepStack::iterator back = --m_undoStack.end(); 102f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) RefPtrWillBeRawPtr<UndoStep> step(back->get()); 10351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) m_undoStack.remove(back); 10451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) step->unapply(); 10551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) // unapply will call us back to push this command onto the redo stack. 10651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) } 10751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)} 10851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) 10951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void UndoStack::redo() 11051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){ 11151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) if (canRedo()) { 112a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) UndoStepStack::iterator back = --m_redoStack.end(); 113f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) RefPtrWillBeRawPtr<UndoStep> step(back->get()); 11451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) m_redoStack.remove(back); 11551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) 11651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) ASSERT(!m_inRedo); 11751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) TemporaryChange<bool> redoScope(m_inRedo, true); 11851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) step->reapply(); 11951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) // reapply will call us back to push this command onto the undo stack. 12051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) } 12151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)} 12251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) 1235d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)void UndoStack::trace(Visitor* visitor) 1245d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles){ 1255d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) visitor->trace(m_undoStack); 1265d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) visitor->trace(m_redoStack); 1275d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)} 1285d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 129c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink 130