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