• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2004, 2006, 2008 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 COMPUTER, 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 COMPUTER, 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 #ifndef htmlediting_h
27 #define htmlediting_h
28 
29 #include "core/dom/Position.h"
30 #include "core/editing/EditingBoundary.h"
31 #include "platform/text/TextDirection.h"
32 #include "wtf/Forward.h"
33 #include "wtf/unicode/CharacterNames.h"
34 
35 namespace blink {
36 
37 class Document;
38 class Element;
39 class ExceptionState;
40 class HTMLBRElement;
41 class HTMLElement;
42 class HTMLLIElement;
43 class HTMLOListElement;
44 class HTMLSpanElement;
45 class HTMLUListElement;
46 class Node;
47 class Position;
48 class PositionWithAffinity;
49 class Range;
50 class VisiblePosition;
51 class VisibleSelection;
52 
53 
54 // This file contains a set of helper functions used by the editing commands
55 
56 // -------------------------------------------------------------------------
57 // Node
58 // -------------------------------------------------------------------------
59 
60 // Functions returning Node
61 
62 ContainerNode* highestEditableRoot(const Position&, EditableType = ContentIsEditable);
63 
64 Node* highestEnclosingNodeOfType(const Position&, bool (*nodeIsOfType)(const Node*),
65     EditingBoundaryCrossingRule = CannotCrossEditingBoundary, Node* stayWithin = 0);
66 Node* highestNodeToRemoveInPruning(Node*, Node* excludeNode = 0);
67 Element* lowestEditableAncestor(Node*);
68 
69 Element* enclosingBlock(Node*, EditingBoundaryCrossingRule = CannotCrossEditingBoundary);
70 Element* enclosingBlockFlowElement(Node&); // Deprecated, use enclosingBlock instead.
71 bool inSameContainingBlockFlowElement(Node*, Node*);
72 Element* enclosingTableCell(const Position&);
73 Node* enclosingEmptyListItem(const VisiblePosition&);
74 Element* enclosingAnchorElement(const Position&);
75 Element* enclosingElementWithTag(const Position&, const QualifiedName&);
76 Node* enclosingNodeOfType(const Position&, bool (*nodeIsOfType)(const Node*), EditingBoundaryCrossingRule = CannotCrossEditingBoundary);
77 
78 HTMLSpanElement* tabSpanElement(const Node*);
79 Element* isLastPositionBeforeTable(const VisiblePosition&);
80 Element* isFirstPositionAfterTable(const VisiblePosition&);
81 
82 // offset functions on Node
83 
84 int lastOffsetForEditing(const Node*);
85 int caretMinOffset(const Node*);
86 int caretMaxOffset(const Node*);
87 
88 // boolean functions on Node
89 
90 // FIXME: editingIgnoresContent, canHaveChildrenForEditing, and isAtomicNode
91 // should be renamed to reflect its usage.
92 
93 // Returns true for nodes that either have no content, or have content that is ignored (skipped over) while editing.
94 // There are no VisiblePositions inside these nodes.
editingIgnoresContent(const Node * node)95 inline bool editingIgnoresContent(const Node* node)
96 {
97     return !node->canContainRangeEndPoint();
98 }
99 
canHaveChildrenForEditing(const Node * node)100 inline bool canHaveChildrenForEditing(const Node* node)
101 {
102     return !node->isTextNode() && node->canContainRangeEndPoint();
103 }
104 
105 bool isAtomicNode(const Node*);
106 bool isBlock(const Node*);
107 bool isInline(const Node*);
108 bool isSpecialHTMLElement(const Node*);
109 bool isTabHTMLSpanElement(const Node*);
110 bool isTabHTMLSpanElementTextNode(const Node*);
111 bool isMailHTMLBlockquoteElement(const Node*);
112 bool isRenderedTableElement(const Node*);
113 bool isRenderedHTMLTableElement(const Node*);
114 bool isTableCell(const Node*);
115 bool isEmptyTableCell(const Node*);
116 bool isTableStructureNode(const Node*);
117 bool isHTMLListElement(Node*);
118 bool isListItem(const Node*);
119 bool isNodeRendered(const Node*);
120 bool isNodeVisiblyContainedWithin(Node&, const Range&);
121 bool isRenderedAsNonInlineTableImageOrHR(const Node*);
122 bool areIdenticalElements(const Node*, const Node*);
123 bool isNonTableCellHTMLBlockElement(const Node*);
124 bool isBlockFlowElement(const Node&);
125 TextDirection directionOfEnclosingBlock(const Position&);
126 
127 // -------------------------------------------------------------------------
128 // Position
129 // -------------------------------------------------------------------------
130 
131 // Functions returning Position
132 
133 Position nextCandidate(const Position&);
134 Position previousCandidate(const Position&);
135 
136 Position nextVisuallyDistinctCandidate(const Position&);
137 Position previousVisuallyDistinctCandidate(const Position&);
138 
139 Position positionBeforeContainingSpecialElement(const Position&, HTMLElement** containingSpecialElement = 0);
140 Position positionAfterContainingSpecialElement(const Position&, HTMLElement** containingSpecialElement = 0);
141 
firstPositionInOrBeforeNode(Node * node)142 inline Position firstPositionInOrBeforeNode(Node* node)
143 {
144     if (!node)
145         return Position();
146     return editingIgnoresContent(node) ? positionBeforeNode(node) : firstPositionInNode(node);
147 }
148 
lastPositionInOrAfterNode(Node * node)149 inline Position lastPositionInOrAfterNode(Node* node)
150 {
151     if (!node)
152         return Position();
153     return editingIgnoresContent(node) ? positionAfterNode(node) : lastPositionInNode(node);
154 }
155 
156 Position lastEditablePositionBeforePositionInRoot(const Position&, Node*);
157 
158 // comparision functions on Position
159 
160 int comparePositions(const Position&, const Position&);
161 int comparePositions(const PositionWithAffinity&, const PositionWithAffinity&);
162 
163 // boolean functions on Position
164 
165 enum EUpdateStyle { UpdateStyle, DoNotUpdateStyle };
166 // FIXME: Both isEditablePosition and isRichlyEditablePosition rely on up-to-date
167 // style to give proper results. They shouldn't update style by default, but
168 // should make it clear that that is the contract.
169 // FIXME: isRichlyEditablePosition should also take EUpdateStyle.
170 bool isEditablePosition(const Position&, EditableType = ContentIsEditable, EUpdateStyle = UpdateStyle);
171 bool isRichlyEditablePosition(const Position&, EditableType = ContentIsEditable);
172 bool lineBreakExistsAtPosition(const Position&);
173 bool isVisiblyAdjacent(const Position& first, const Position& second);
174 bool isAtUnsplittableElement(const Position&);
175 
176 // miscellaneous functions on Position
177 
178 enum WhitespacePositionOption { NotConsiderNonCollapsibleWhitespace, ConsiderNonCollapsibleWhitespace };
179 Position leadingWhitespacePosition(const Position&, EAffinity, WhitespacePositionOption = NotConsiderNonCollapsibleWhitespace);
180 Position trailingWhitespacePosition(const Position&, EAffinity, WhitespacePositionOption = NotConsiderNonCollapsibleWhitespace);
181 unsigned numEnclosingMailBlockquotes(const Position&);
182 void updatePositionForNodeRemoval(Position&, Node&);
183 
184 // -------------------------------------------------------------------------
185 // VisiblePosition
186 // -------------------------------------------------------------------------
187 
188 // Functions returning VisiblePosition
189 
190 VisiblePosition firstEditableVisiblePositionAfterPositionInRoot(const Position&, ContainerNode*);
191 VisiblePosition lastEditableVisiblePositionBeforePositionInRoot(const Position&, ContainerNode*);
192 VisiblePosition visiblePositionBeforeNode(Node&);
193 VisiblePosition visiblePositionAfterNode(Node&);
194 
195 bool lineBreakExistsAtVisiblePosition(const VisiblePosition&);
196 
197 int comparePositions(const VisiblePosition&, const VisiblePosition&);
198 
199 int indexForVisiblePosition(const VisiblePosition&, RefPtrWillBeRawPtr<ContainerNode>& scope);
200 VisiblePosition visiblePositionForIndex(int index, ContainerNode* scope);
201 
202 // -------------------------------------------------------------------------
203 // Range
204 // -------------------------------------------------------------------------
205 
206 // Functions returning Range
207 
208 PassRefPtrWillBeRawPtr<Range> createRange(Document&, const VisiblePosition& start, const VisiblePosition& end, ExceptionState&);
209 
210 // -------------------------------------------------------------------------
211 // HTMLElement
212 // -------------------------------------------------------------------------
213 
214 // Functions returning HTMLElement
215 
216 PassRefPtrWillBeRawPtr<HTMLElement> createDefaultParagraphElement(Document&);
217 PassRefPtrWillBeRawPtr<HTMLBRElement> createBreakElement(Document&);
218 PassRefPtrWillBeRawPtr<HTMLOListElement> createOrderedListElement(Document&);
219 PassRefPtrWillBeRawPtr<HTMLUListElement> createUnorderedListElement(Document&);
220 PassRefPtrWillBeRawPtr<HTMLLIElement> createListItemElement(Document&);
221 PassRefPtrWillBeRawPtr<HTMLElement> createHTMLElement(Document&, const QualifiedName&);
222 PassRefPtrWillBeRawPtr<HTMLElement> createHTMLElement(Document&, const AtomicString&);
223 
224 HTMLElement* enclosingList(Node*);
225 HTMLElement* outermostEnclosingList(Node*, HTMLElement* rootList = 0);
226 Node* enclosingListChild(Node*);
227 
228 // -------------------------------------------------------------------------
229 // Element
230 // -------------------------------------------------------------------------
231 
232 // Functions returning Element
233 
234 PassRefPtrWillBeRawPtr<HTMLSpanElement> createTabSpanElement(Document&);
235 PassRefPtrWillBeRawPtr<HTMLSpanElement> createTabSpanElement(Document&, PassRefPtrWillBeRawPtr<Text> tabTextNode);
236 PassRefPtrWillBeRawPtr<HTMLSpanElement> createTabSpanElement(Document&, const String& tabText);
237 PassRefPtrWillBeRawPtr<HTMLBRElement> createBlockPlaceholderElement(Document&);
238 
239 Element* editableRootForPosition(const Position&, EditableType = ContentIsEditable);
240 Element* unsplittableElementForPosition(const Position&);
241 
242 // Boolean functions on Element
243 
244 bool canMergeLists(Element* firstList, Element* secondList);
245 
246 // -------------------------------------------------------------------------
247 // VisibleSelection
248 // -------------------------------------------------------------------------
249 
250 // Functions returning VisibleSelection
251 VisibleSelection selectionForParagraphIteration(const VisibleSelection&);
252 
253 Position adjustedSelectionStartForStyleComputation(const VisibleSelection&);
254 
255 
256 // Miscellaneous functions on Text
isWhitespace(UChar c)257 inline bool isWhitespace(UChar c)
258 {
259     return c == noBreakSpace || c == ' ' || c == '\n' || c == '\t';
260 }
261 
262 // FIXME: Can't really answer this question correctly without knowing the white-space mode.
isCollapsibleWhitespace(UChar c)263 inline bool isCollapsibleWhitespace(UChar c)
264 {
265     return c == ' ' || c == '\n';
266 }
267 
isAmbiguousBoundaryCharacter(UChar character)268 inline bool isAmbiguousBoundaryCharacter(UChar character)
269 {
270     // These are characters that can behave as word boundaries, but can appear within words.
271     // If they are just typed, i.e. if they are immediately followed by a caret, we want to delay text checking until the next character has been typed.
272     // FIXME: this is required until 6853027 is fixed and text checking can do this for us.
273     return character == '\'' || character == rightSingleQuotationMark || character == hebrewPunctuationGershayim;
274 }
275 
276 String stringWithRebalancedWhitespace(const String&, bool startIsStartOfParagraph, bool endIsEndOfParagraph);
277 const String& nonBreakingSpaceString();
278 
279 }
280 
281 #endif
282