mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
123 lines
3.8 KiB
C++
123 lines
3.8 KiB
C++
/*
|
|
* Copyright (C) 2006, 2007 Apple, Inc. All rights reserved.
|
|
* Copyright (C) 2012 Google, Inc. All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
|
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
|
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
|
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#include "sky/engine/core/editing/UndoStack.h"
|
|
|
|
#include "sky/engine/core/dom/ContainerNode.h"
|
|
#include "sky/engine/core/editing/UndoStep.h"
|
|
#include "sky/engine/platform/EventDispatchForbiddenScope.h"
|
|
#include "sky/engine/wtf/TemporaryChange.h"
|
|
|
|
namespace blink {
|
|
|
|
// Arbitrary depth limit for the undo stack, to keep it from using
|
|
// unbounded memory. This is the maximum number of distinct undoable
|
|
// actions -- unbroken stretches of typed characters are coalesced
|
|
// into a single action.
|
|
static const size_t maximumUndoStackDepth = 1000;
|
|
|
|
UndoStack::UndoStack()
|
|
: m_inRedo(false)
|
|
{
|
|
}
|
|
|
|
DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(UndoStack)
|
|
|
|
PassOwnPtr<UndoStack> UndoStack::create()
|
|
{
|
|
return adoptPtr(new UndoStack());
|
|
}
|
|
|
|
void UndoStack::registerUndoStep(PassRefPtr<UndoStep> step)
|
|
{
|
|
if (m_undoStack.size() == maximumUndoStackDepth)
|
|
m_undoStack.removeFirst(); // drop oldest item off the far end
|
|
if (!m_inRedo)
|
|
m_redoStack.clear();
|
|
m_undoStack.append(step);
|
|
}
|
|
|
|
void UndoStack::registerRedoStep(PassRefPtr<UndoStep> step)
|
|
{
|
|
m_redoStack.append(step);
|
|
}
|
|
|
|
void UndoStack::didUnloadFrame(const LocalFrame& frame)
|
|
{
|
|
EventDispatchForbiddenScope assertNoEventDispatch;
|
|
filterOutUndoSteps(m_undoStack, frame);
|
|
filterOutUndoSteps(m_redoStack, frame);
|
|
}
|
|
|
|
void UndoStack::filterOutUndoSteps(UndoStepStack& stack, const LocalFrame& frame)
|
|
{
|
|
UndoStepStack newStack;
|
|
while (!stack.isEmpty()) {
|
|
UndoStep* step = stack.first().get();
|
|
if (!step->belongsTo(frame))
|
|
newStack.append(step);
|
|
stack.removeFirst();
|
|
}
|
|
stack.swap(newStack);
|
|
}
|
|
|
|
bool UndoStack::canUndo() const
|
|
{
|
|
return !m_undoStack.isEmpty();
|
|
}
|
|
|
|
bool UndoStack::canRedo() const
|
|
{
|
|
return !m_redoStack.isEmpty();
|
|
}
|
|
|
|
void UndoStack::undo()
|
|
{
|
|
if (canUndo()) {
|
|
UndoStepStack::iterator back = --m_undoStack.end();
|
|
RefPtr<UndoStep> step(back->get());
|
|
m_undoStack.remove(back);
|
|
step->unapply();
|
|
// unapply will call us back to push this command onto the redo stack.
|
|
}
|
|
}
|
|
|
|
void UndoStack::redo()
|
|
{
|
|
if (canRedo()) {
|
|
UndoStepStack::iterator back = --m_redoStack.end();
|
|
RefPtr<UndoStep> step(back->get());
|
|
m_redoStack.remove(back);
|
|
|
|
ASSERT(!m_inRedo);
|
|
TemporaryChange<bool> redoScope(m_inRedo, true);
|
|
step->reapply();
|
|
// reapply will call us back to push this command onto the undo stack.
|
|
}
|
|
}
|
|
|
|
} // namespace blink
|