1 | /* |
2 | * Copyright (C) 2004, 2006, 2008, 2016 Apple 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 |
6 | * are met: |
7 | * 1. Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. |
9 | * 2. Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. |
12 | * |
13 | * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY |
14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
15 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
16 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR |
17 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
18 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
19 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
20 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
21 | * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
23 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
24 | */ |
25 | |
26 | #pragma once |
27 | |
28 | #include "Position.h" |
29 | #include <wtf/Forward.h> |
30 | #include <wtf/unicode/CharacterNames.h> |
31 | |
32 | namespace WebCore { |
33 | |
34 | class Document; |
35 | class HTMLElement; |
36 | class HTMLSpanElement; |
37 | class HTMLTextFormControlElement; |
38 | class RenderBlock; |
39 | class VisiblePosition; |
40 | class VisibleSelection; |
41 | |
42 | // ------------------------------------------------------------------------- |
43 | // Node |
44 | // ------------------------------------------------------------------------- |
45 | |
46 | ContainerNode* highestEditableRoot(const Position&, EditableType = ContentIsEditable); |
47 | |
48 | Node* highestEnclosingNodeOfType(const Position&, bool (*nodeIsOfType)(const Node*), EditingBoundaryCrossingRule = CannotCrossEditingBoundary, Node* stayWithin = nullptr); |
49 | Node* highestNodeToRemoveInPruning(Node*); |
50 | Element* lowestEditableAncestor(Node*); |
51 | |
52 | Element* deprecatedEnclosingBlockFlowElement(Node*); // Use enclosingBlock instead. |
53 | Element* enclosingBlock(Node*, EditingBoundaryCrossingRule = CannotCrossEditingBoundary); |
54 | Element* enclosingTableCell(const Position&); |
55 | Node* enclosingEmptyListItem(const VisiblePosition&); |
56 | Element* enclosingAnchorElement(const Position&); |
57 | Element* enclosingElementWithTag(const Position&, const QualifiedName&); |
58 | Node* enclosingNodeOfType(const Position&, bool (*nodeIsOfType)(const Node*), EditingBoundaryCrossingRule = CannotCrossEditingBoundary); |
59 | HTMLSpanElement* tabSpanNode(const Node*); |
60 | Element* isLastPositionBeforeTable(const VisiblePosition&); // FIXME: Strange to name this isXXX, but return an element. |
61 | Element* isFirstPositionAfterTable(const VisiblePosition&); // FIXME: Strange to name this isXXX, but return an element. |
62 | |
63 | // These two deliver leaf nodes as if the whole DOM tree were a linear chain of its leaf nodes. |
64 | Node* nextLeafNode(const Node*); |
65 | Node* previousLeafNode(const Node*); |
66 | |
67 | WEBCORE_EXPORT int lastOffsetForEditing(const Node&); |
68 | int caretMinOffset(const Node&); |
69 | int caretMaxOffset(const Node&); |
70 | |
71 | bool hasEditableStyle(const Node&, EditableType); |
72 | bool isEditableNode(const Node&); |
73 | |
74 | // FIXME: editingIgnoresContent, canHaveChildrenForEditing, and isAtomicNode should be named to clarify how they differ. |
75 | |
76 | // Returns true for nodes that either have no content, or have content that is ignored (skipped over) while editing. |
77 | // There are no VisiblePositions inside these nodes. |
78 | bool editingIgnoresContent(const Node&); |
79 | |
80 | bool canHaveChildrenForEditing(const Node&); |
81 | bool isAtomicNode(const Node*); |
82 | |
83 | bool isBlock(const Node*); |
84 | bool isBlockFlowElement(const Node&); |
85 | bool isInline(const Node*); |
86 | bool isTabSpanNode(const Node*); |
87 | bool isTabSpanTextNode(const Node*); |
88 | bool isMailBlockquote(const Node*); |
89 | bool isRenderedTable(const Node*); |
90 | bool isTableCell(const Node*); |
91 | bool isEmptyTableCell(const Node*); |
92 | bool isTableStructureNode(const Node*); |
93 | bool isListHTMLElement(Node*); |
94 | bool isListItem(const Node*); |
95 | bool isNodeRendered(const Node&); |
96 | bool isRenderedAsNonInlineTableImageOrHR(const Node*); |
97 | bool isNonTableCellHTMLBlockElement(const Node*); |
98 | |
99 | bool isNodeVisiblyContainedWithin(Node&, const Range&); |
100 | |
101 | bool areIdenticalElements(const Node&, const Node&); |
102 | |
103 | bool positionBeforeOrAfterNodeIsCandidate(Node&); |
104 | |
105 | // ------------------------------------------------------------------------- |
106 | // Position |
107 | // ------------------------------------------------------------------------- |
108 | |
109 | Position nextCandidate(const Position&); |
110 | Position previousCandidate(const Position&); |
111 | |
112 | Position nextVisuallyDistinctCandidate(const Position&); |
113 | Position previousVisuallyDistinctCandidate(const Position&); |
114 | |
115 | Position positionBeforeContainingSpecialElement(const Position&, HTMLElement** containingSpecialElement = nullptr); |
116 | Position positionAfterContainingSpecialElement(const Position&, HTMLElement** containingSpecialElement = nullptr); |
117 | |
118 | Position firstPositionInOrBeforeNode(Node*); |
119 | Position lastPositionInOrAfterNode(Node*); |
120 | |
121 | Position firstEditablePositionAfterPositionInRoot(const Position&, ContainerNode* root); |
122 | Position lastEditablePositionBeforePositionInRoot(const Position&, ContainerNode* root); |
123 | |
124 | WEBCORE_EXPORT int comparePositions(const Position&, const Position&); |
125 | |
126 | WEBCORE_EXPORT bool isEditablePosition(const Position&, EditableType = ContentIsEditable); |
127 | bool isRichlyEditablePosition(const Position&); |
128 | bool lineBreakExistsAtPosition(const Position&); |
129 | bool isAtUnsplittableElement(const Position&); |
130 | |
131 | unsigned numEnclosingMailBlockquotes(const Position&); |
132 | void updatePositionForNodeRemoval(Position&, Node&); |
133 | |
134 | WEBCORE_EXPORT TextDirection directionOfEnclosingBlock(const Position&); |
135 | |
136 | // ------------------------------------------------------------------------- |
137 | // VisiblePosition |
138 | // ------------------------------------------------------------------------- |
139 | |
140 | VisiblePosition visiblePositionBeforeNode(Node&); |
141 | VisiblePosition visiblePositionAfterNode(Node&); |
142 | |
143 | bool lineBreakExistsAtVisiblePosition(const VisiblePosition&); |
144 | |
145 | WEBCORE_EXPORT int comparePositions(const VisiblePosition&, const VisiblePosition&); |
146 | |
147 | WEBCORE_EXPORT int indexForVisiblePosition(const VisiblePosition&, RefPtr<ContainerNode>& scope); |
148 | int indexForVisiblePosition(Node&, const VisiblePosition&, bool forSelectionPreservation); |
149 | WEBCORE_EXPORT VisiblePosition visiblePositionForPositionWithOffset(const VisiblePosition&, int offset); |
150 | WEBCORE_EXPORT VisiblePosition visiblePositionForIndex(int index, ContainerNode* scope); |
151 | VisiblePosition visiblePositionForIndexUsingCharacterIterator(Node&, int index); // FIXME: Why do we need this version? |
152 | |
153 | // ------------------------------------------------------------------------- |
154 | // HTMLElement |
155 | // ------------------------------------------------------------------------- |
156 | |
157 | WEBCORE_EXPORT Ref<HTMLElement> createDefaultParagraphElement(Document&); |
158 | Ref<HTMLElement> createHTMLElement(Document&, const QualifiedName&); |
159 | Ref<HTMLElement> createHTMLElement(Document&, const AtomString&); |
160 | |
161 | WEBCORE_EXPORT HTMLElement* enclosingList(Node*); |
162 | HTMLElement* outermostEnclosingList(Node*, Node* rootList = nullptr); |
163 | Node* enclosingListChild(Node*); |
164 | |
165 | // ------------------------------------------------------------------------- |
166 | // Element |
167 | // ------------------------------------------------------------------------- |
168 | |
169 | Ref<Element> createTabSpanElement(Document&); |
170 | Ref<Element> createTabSpanElement(Document&, const String& tabText); |
171 | Ref<Element> createBlockPlaceholderElement(Document&); |
172 | |
173 | Element* editableRootForPosition(const Position&, EditableType = ContentIsEditable); |
174 | Element* unsplittableElementForPosition(const Position&); |
175 | |
176 | bool canMergeLists(Element* firstList, Element* secondList); |
177 | |
178 | // ------------------------------------------------------------------------- |
179 | // VisibleSelection |
180 | // ------------------------------------------------------------------------- |
181 | |
182 | VisibleSelection selectionForParagraphIteration(const VisibleSelection&); |
183 | Position adjustedSelectionStartForStyleComputation(const VisibleSelection&); |
184 | |
185 | // ------------------------------------------------------------------------- |
186 | |
187 | // FIXME: This is only one of many definitions of whitespace. Possibly never the right one to use. |
188 | bool deprecatedIsEditingWhitespace(UChar); |
189 | |
190 | // FIXME: Can't answer this question correctly without being passed the white-space mode. |
191 | bool deprecatedIsCollapsibleWhitespace(UChar); |
192 | |
193 | bool isAmbiguousBoundaryCharacter(UChar); |
194 | |
195 | String stringWithRebalancedWhitespace(const String&, bool startIsStartOfParagraph, bool endIsEndOfParagraph); |
196 | const String& nonBreakingSpaceString(); |
197 | |
198 | // Miscellaneous functions for caret rendering. |
199 | |
200 | RenderBlock* rendererForCaretPainting(Node*); |
201 | LayoutRect localCaretRectInRendererForCaretPainting(const VisiblePosition&, RenderBlock*&); |
202 | LayoutRect localCaretRectInRendererForRect(LayoutRect&, Node*, RenderObject*, RenderBlock*&); |
203 | IntRect absoluteBoundsForLocalCaretRect(RenderBlock* rendererForCaretPainting, const LayoutRect&, bool* insideFixed = nullptr); |
204 | |
205 | // ------------------------------------------------------------------------- |
206 | |
207 | inline bool deprecatedIsEditingWhitespace(UChar c) |
208 | { |
209 | return c == noBreakSpace || c == ' ' || c == '\n' || c == '\t'; |
210 | } |
211 | |
212 | // FIXME: Can't really answer this question correctly without knowing the white-space mode. |
213 | inline bool deprecatedIsCollapsibleWhitespace(UChar c) |
214 | { |
215 | return c == ' ' || c == '\n'; |
216 | } |
217 | |
218 | bool isAmbiguousBoundaryCharacter(UChar); |
219 | |
220 | inline bool editingIgnoresContent(const Node& node) |
221 | { |
222 | return !node.canContainRangeEndPoint(); |
223 | } |
224 | |
225 | inline bool positionBeforeOrAfterNodeIsCandidate(Node& node) |
226 | { |
227 | return isRenderedTable(&node) || editingIgnoresContent(node); |
228 | } |
229 | |
230 | inline Position firstPositionInOrBeforeNode(Node* node) |
231 | { |
232 | if (!node) |
233 | return { }; |
234 | return editingIgnoresContent(*node) ? positionBeforeNode(node) : firstPositionInNode(node); |
235 | } |
236 | |
237 | inline Position lastPositionInOrAfterNode(Node* node) |
238 | { |
239 | if (!node) |
240 | return { }; |
241 | return editingIgnoresContent(*node) ? positionAfterNode(node) : lastPositionInNode(node); |
242 | } |
243 | |
244 | } |
245 | |