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. 95 inline bool editingIgnoresContent(const Node* node) 96 { 97 return !node->canContainRangeEndPoint(); 98 } 99 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 142 inline Position firstPositionInOrBeforeNode(Node* node) 143 { 144 if (!node) 145 return Position(); 146 return editingIgnoresContent(node) ? positionBeforeNode(node) : firstPositionInNode(node); 147 } 148 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 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. 263 inline bool isCollapsibleWhitespace(UChar c) 264 { 265 return c == ' ' || c == '\n'; 266 } 267 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