Commit 21a95df4 authored by yosin@chromium.org's avatar yosin@chromium.org

Move {next,previous}PositionOf() to EditingUtilities.{cpp,h} from Position.{cpp,h}

This patch moves |{next,previous}PositionOf()| to "EditingUtilities.{cpp,h}"
from "Position.{cpp,h}" to simplify "Position.{cpp,h}" for improving code
health since |{next,previous}PositionOf()| don't depend of implementation of
|PositionAlgorithm| template class.

BUG=518738
TEST=n/a; no behavior changes

Review URL: https://codereview.chromium.org/1310533002

git-svn-id: svn://svn.chromium.org/blink/trunk@201033 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 4e0fed2e
......@@ -506,6 +506,113 @@ PositionInComposedTree lastEditablePositionBeforePositionInRoot(const PositionIn
return lastEditablePositionBeforePositionInRootAlgorithm<PositionInComposedTree>(position, highestRoot);
}
int uncheckedPreviousOffset(const Node* n, int current)
{
return n->layoutObject() ? n->layoutObject()->previousOffset(current) : current - 1;
}
static int uncheckedPreviousOffsetForBackwardDeletion(const Node* n, int current)
{
return n->layoutObject() ? n->layoutObject()->previousOffsetForBackwardDeletion(current) : current - 1;
}
int uncheckedNextOffset(const Node* n, int current)
{
return n->layoutObject() ? n->layoutObject()->nextOffset(current) : current + 1;
}
template <typename Strategy>
PositionAlgorithm<Strategy> previousPositionOfAlgorithm(const PositionAlgorithm<Strategy>& position, PositionMoveType moveType)
{
Node* const node = position.anchorNode();
if (!node)
return position;
const int offset = position.computeEditingOffset();
if (offset > 0) {
if (editingIgnoresContent(node))
return PositionAlgorithm<Strategy>::beforeNode(node);
if (Node* child = Strategy::childAt(*node, offset - 1))
return PositionAlgorithm<Strategy>::lastPositionInOrAfterNode(child);
// There are two reasons child might be 0:
// 1) The node is node like a text node that is not an element, and
// therefore has no children. Going backward one character at a
// time is correct.
// 2) The old offset was a bogus offset like (<br>, 1), and there is
// no child. Going from 1 to 0 is correct.
switch (moveType) {
case PositionMoveType::CodePoint:
return PositionAlgorithm<Strategy>(node, offset - 1);
case PositionMoveType::Character:
return PositionAlgorithm<Strategy>(node, uncheckedPreviousOffset(node, offset));
case PositionMoveType::BackwardDeletion:
return PositionAlgorithm<Strategy>(node, uncheckedPreviousOffsetForBackwardDeletion(node, offset));
}
}
if (ContainerNode* parent = Strategy::parent(*node)) {
if (editingIgnoresContent(parent))
return PositionAlgorithm<Strategy>::beforeNode(parent);
// TODO(yosin) We should use |Strategy::index(Node&)| instead of
// |Node::nodeIndex()|.
return PositionAlgorithm<Strategy>(parent, node->nodeIndex());
}
return position;
}
Position previousPositionOf(const Position& position, PositionMoveType moveType)
{
return previousPositionOfAlgorithm<EditingStrategy>(position, moveType);
}
PositionInComposedTree previousPositionOf(const PositionInComposedTree& position, PositionMoveType moveType)
{
return previousPositionOfAlgorithm<EditingInComposedTreeStrategy>(position, moveType);
}
template <typename Strategy>
PositionAlgorithm<Strategy> nextPositionOfAlgorithm(const PositionAlgorithm<Strategy>& position, PositionMoveType moveType)
{
ASSERT(moveType != PositionMoveType::BackwardDeletion);
Node* node = position.anchorNode();
if (!node)
return position;
const int offset = position.computeEditingOffset();
if (Node* child = Strategy::childAt(*node, offset))
return PositionAlgorithm<Strategy>::firstPositionInOrBeforeNode(child);
// TODO(yosin) We should use |Strategy::lastOffsetForEditing()| instead of
// DOM tree version.
if (!Strategy::hasChildren(*node) && offset < EditingStrategy::lastOffsetForEditing(node)) {
// There are two reasons child might be 0:
// 1) The node is node like a text node that is not an element, and
// therefore has no children. Going forward one character at a time
// is correct.
// 2) The new offset is a bogus offset like (<br>, 1), and there is no
// child. Going from 0 to 1 is correct.
return PositionAlgorithm<Strategy>::editingPositionOf(node, (moveType == PositionMoveType::Character) ? uncheckedNextOffset(node, offset) : offset + 1);
}
if (ContainerNode* parent = Strategy::parent(*node))
return PositionAlgorithm<Strategy>::editingPositionOf(parent, Strategy::index(*node) + 1);
return position;
}
Position nextPositionOf(const Position& position, PositionMoveType moveType)
{
return nextPositionOfAlgorithm<EditingStrategy>(position, moveType);
}
PositionInComposedTree nextPositionOf(const PositionInComposedTree& position, PositionMoveType moveType)
{
return nextPositionOfAlgorithm<EditingInComposedTreeStrategy>(position, moveType);
}
// FIXME: The method name, comment, and code say three different things here!
// Whether or not content before and after this node will collapse onto the same line as it.
bool isBlock(const Node* node)
......
......@@ -36,6 +36,12 @@
namespace blink {
enum class PositionMoveType {
CodePoint, // Move by a single code point.
Character, // Move to the next Unicode character break.
BackwardDeletion // Subject to platform conventions.
};
class Document;
class Element;
class HTMLBRElement;
......@@ -48,7 +54,6 @@ class Range;
class VisiblePosition;
class VisibleSelection;
// This file contains a set of helper functions used by the editing commands
// -------------------------------------------------------------------------
......@@ -177,6 +182,18 @@ inline Position lastPositionInOrAfterNode(Node* node)
Position lastEditablePositionBeforePositionInRoot(const Position&, Node*);
PositionInComposedTree lastEditablePositionBeforePositionInRoot(const PositionInComposedTree&, Node*);
// Move up or down the DOM by one position.
// Offsets are computed using layout text for nodes that have layoutObjects -
// but note that even when using composed characters, the result may be inside
// a single user-visible character if a ligature is formed.
CORE_EXPORT Position previousPositionOf(const Position&, PositionMoveType);
CORE_EXPORT Position nextPositionOf(const Position&, PositionMoveType);
CORE_EXPORT PositionInComposedTree previousPositionOf(const PositionInComposedTree&, PositionMoveType);
CORE_EXPORT PositionInComposedTree nextPositionOf(const PositionInComposedTree&, PositionMoveType);
CORE_EXPORT int uncheckedPreviousOffset(const Node*, int current);
CORE_EXPORT int uncheckedNextOffset(const Node*, int current);
// comparision functions on Position
// |disconnected| is optional output parameter having true if specified
......
......@@ -29,8 +29,6 @@
#include "core/dom/shadow/ElementShadow.h"
#include "core/editing/EditingUtilities.h"
#include "core/editing/TextAffinity.h"
#include "core/editing/VisibleUnits.h"
#include "core/layout/LayoutObject.h"
#include "wtf/text/CString.h"
#include <stdio.h>
......@@ -299,119 +297,6 @@ int PositionAlgorithm<Strategy>::compareTo(const PositionAlgorithm<Strategy>& ot
return comparePositions(*this, other);
}
// TODO(yosin) We should move |uncheckedPreviousOffsetForBackwardDeletion()|
// to "EditingUtilities.cpp" with |previousPositionOf()|.
// TODO(yosin) To avoid forward declaration, we should move implementation of
// |uncheckedPreviousOffsetForBackwardDeletion()| here.
static int uncheckedPreviousOffsetForBackwardDeletion(const Node*, int current);
template <typename Strategy>
PositionAlgorithm<Strategy> previousPositionOfAlgorithm(const PositionAlgorithm<Strategy>& position, PositionMoveType moveType)
{
Node* const node = position.anchorNode();
if (!node)
return position;
const int offset = position.computeEditingOffset();
if (offset > 0) {
if (editingIgnoresContent(node))
return PositionAlgorithm<Strategy>::beforeNode(node);
if (Node* child = Strategy::childAt(*node, offset - 1))
return PositionAlgorithm<Strategy>::lastPositionInOrAfterNode(child);
// There are two reasons child might be 0:
// 1) The node is node like a text node that is not an element, and
// therefore has no children. Going backward one character at a
// time is correct.
// 2) The old offset was a bogus offset like (<br>, 1), and there is
// no child. Going from 1 to 0 is correct.
switch (moveType) {
case PositionMoveType::CodePoint:
return PositionAlgorithm<Strategy>(node, offset - 1);
case PositionMoveType::Character:
return PositionAlgorithm<Strategy>(node, uncheckedPreviousOffset(node, offset));
case PositionMoveType::BackwardDeletion:
return PositionAlgorithm<Strategy>(node, uncheckedPreviousOffsetForBackwardDeletion(node, offset));
}
}
if (ContainerNode* parent = Strategy::parent(*node)) {
if (editingIgnoresContent(parent))
return PositionAlgorithm<Strategy>::beforeNode(parent);
// TODO(yosin) We should use |Strategy::index(Node&)| instead of
// |Node::nodeIndex()|.
return PositionAlgorithm<Strategy>(parent, node->nodeIndex());
}
return position;
}
Position previousPositionOf(const Position& position, PositionMoveType moveType)
{
return previousPositionOfAlgorithm<EditingStrategy>(position, moveType);
}
PositionInComposedTree previousPositionOf(const PositionInComposedTree& position, PositionMoveType moveType)
{
return previousPositionOfAlgorithm<EditingInComposedTreeStrategy>(position, moveType);
}
template <typename Strategy>
PositionAlgorithm<Strategy> nextPositionOfAlgorithm(const PositionAlgorithm<Strategy>& position, PositionMoveType moveType)
{
ASSERT(moveType != PositionMoveType::BackwardDeletion);
Node* node = position.anchorNode();
if (!node)
return position;
const int offset = position.computeEditingOffset();
if (Node* child = Strategy::childAt(*node, offset))
return PositionAlgorithm<Strategy>::firstPositionInOrBeforeNode(child);
// TODO(yosin) We should use |Strategy::lastOffsetForEditing()| instead of
// DOM tree version.
if (!Strategy::hasChildren(*node) && offset < EditingStrategy::lastOffsetForEditing(node)) {
// There are two reasons child might be 0:
// 1) The node is node like a text node that is not an element, and
// therefore has no children. Going forward one character at a time
// is correct.
// 2) The new offset is a bogus offset like (<br>, 1), and there is no
// child. Going from 0 to 1 is correct.
return PositionAlgorithm<Strategy>::editingPositionOf(node, (moveType == PositionMoveType::Character) ? uncheckedNextOffset(node, offset) : offset + 1);
}
if (ContainerNode* parent = Strategy::parent(*node))
return PositionAlgorithm<Strategy>::editingPositionOf(parent, Strategy::index(*node) + 1);
return position;
}
Position nextPositionOf(const Position& position, PositionMoveType moveType)
{
return nextPositionOfAlgorithm<EditingStrategy>(position, moveType);
}
PositionInComposedTree nextPositionOf(const PositionInComposedTree& position, PositionMoveType moveType)
{
return nextPositionOfAlgorithm<EditingInComposedTreeStrategy>(position, moveType);
}
int uncheckedPreviousOffset(const Node* n, int current)
{
return n->layoutObject() ? n->layoutObject()->previousOffset(current) : current - 1;
}
static int uncheckedPreviousOffsetForBackwardDeletion(const Node* n, int current)
{
return n->layoutObject() ? n->layoutObject()->previousOffsetForBackwardDeletion(current) : current - 1;
}
int uncheckedNextOffset(const Node* n, int current)
{
return n->layoutObject() ? n->layoutObject()->nextOffset(current) : current + 1;
}
template <typename Strategy>
bool PositionAlgorithm<Strategy>::atFirstEditingPositionForNode() const
{
......
......@@ -45,12 +45,6 @@ class Text;
enum class TextAffinity;
class TreeScope;
enum class PositionMoveType {
CodePoint, // Move by a single code point.
Character, // Move to the next Unicode character break.
BackwardDeletion // Subject to platform conventions.
};
enum class PositionAnchorType : unsigned {
OffsetInAnchor,
BeforeAnchor,
......@@ -396,21 +390,6 @@ inline PositionInComposedTree fromPositionInDOMTree<EditingInComposedTreeStrateg
return toPositionInComposedTree(position);
}
// TODO(yosin) We should move |previousPositionOf()| and |nextPositionOf()|
// to "EditingUtilities.h" with |uncheckedPreviousOffset()| and
// |uncheckedNextOffset()|.
// Move up or down the DOM by one position.
// Offsets are computed using layout text for nodes that have layoutObjects -
// but note that even when using composed characters, the result may be inside
// a single user-visible character if a ligature is formed.
CORE_EXPORT Position previousPositionOf(const Position&, PositionMoveType);
CORE_EXPORT Position nextPositionOf(const Position&, PositionMoveType);
CORE_EXPORT PositionInComposedTree previousPositionOf(const PositionInComposedTree&, PositionMoveType);
CORE_EXPORT PositionInComposedTree nextPositionOf(const PositionInComposedTree&, PositionMoveType);
CORE_EXPORT int uncheckedPreviousOffset(const Node*, int current);
CORE_EXPORT int uncheckedNextOffset(const Node*, int current);
} // namespace blink
#ifndef NDEBUG
......
......@@ -22,6 +22,7 @@
#include "core/layout/PendingSelection.h"
#include "core/dom/Document.h"
#include "core/editing/EditingUtilities.h"
#include "core/editing/FrameSelection.h"
#include "core/editing/VisiblePosition.h"
#include "core/editing/VisibleUnits.h"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment