1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
6 #include "core/editing/EditingStrategy.h"
8 #include "core/editing/EditingUtilities.h"
9 #include "core/layout/LayoutObject.h"
13 // If a node can contain candidates for VisiblePositions, return the offset of
14 // the last candidate, otherwise return the number of children for container
15 // nodes and the length for unrendered text nodes.
16 template <typename Traversal
>
17 int EditingAlgorithm
<Traversal
>::caretMaxOffset(const Node
& node
)
19 // For rendered text nodes, return the last position that a caret could
21 if (node
.isTextNode() && node
.layoutObject())
22 return node
.layoutObject()->caretMaxOffset();
23 // For containers return the number of children. For others do the same as
25 return lastOffsetForEditing(&node
);
28 template <typename Traversal
>
29 bool EditingAlgorithm
<Traversal
>::isEmptyNonEditableNodeInEditable(const Node
* node
)
31 // Editability is defined the DOM tree rather than the composed tree. For example:
33 // <host><span>unedittable</span><shadowroot><div ce><content /></div></shadowroot></host>
35 // <host><div ce><span1>unedittable</span></div></host>
36 // e.g. editing/shadow/breaking-editing-boundaries.html
37 return !Traversal::hasChildren(*node
) && !node
->hasEditableStyle() && node
->parentNode() && node
->parentNode()->hasEditableStyle();
40 template <typename Traversal
>
41 bool EditingAlgorithm
<Traversal
>::editingIgnoresContent(const Node
* node
)
43 return !node
->canContainRangeEndPoint() || isEmptyNonEditableNodeInEditable(node
);
46 template <typename Traversal
>
47 int EditingAlgorithm
<Traversal
>::lastOffsetForEditing(const Node
* node
)
52 if (node
->offsetInCharacters())
53 return node
->maxCharacterOffset();
55 if (Traversal::hasChildren(*node
))
56 return Traversal::countChildren(*node
);
58 // FIXME: Try return 0 here.
60 if (!editingIgnoresContent(node
))
63 // editingIgnoresContent uses the same logic in
64 // isEmptyNonEditableNodeInEditable (EditingUtilities.cpp). We don't
65 // understand why this function returns 1 even when the node doesn't have
70 template <typename Strategy
>
71 Node
* EditingAlgorithm
<Strategy
>::rootUserSelectAllForNode(Node
* node
)
73 if (!node
|| !nodeIsUserSelectAll(node
))
75 Node
* parent
= Strategy::parent(*node
);
79 Node
* candidateRoot
= node
;
81 if (!parent
->layoutObject()) {
82 parent
= Strategy::parent(*parent
);
85 if (!nodeIsUserSelectAll(parent
))
87 candidateRoot
= parent
;
88 parent
= Strategy::parent(*candidateRoot
);
93 template class CORE_TEMPLATE_EXPORT EditingAlgorithm
<NodeTraversal
>;
94 template class CORE_TEMPLATE_EXPORT EditingAlgorithm
<ComposedTreeTraversal
>;