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 "core/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* highestAncestor(Node*); 57 Node* highestEditableRoot(const Position&, EditableType = ContentIsEditable); 58 59 Node* highestEnclosingNodeOfType(const Position&, bool (*nodeIsOfType)(const Node*), 60 EditingBoundaryCrossingRule = CannotCrossEditingBoundary, Node* stayWithin = 0); 61 Node* highestNodeToRemoveInPruning(Node*, Node* excludeNode = 0); 62 Node* lowestEditableAncestor(Node*); 63 64 Element* enclosingBlock(Node*, EditingBoundaryCrossingRule = CannotCrossEditingBoundary); 65 Node* enclosingTableCell(const Position&); 66 Node* enclosingEmptyListItem(const VisiblePosition&); 67 Element* enclosingAnchorElement(const Position&); 68 Node* enclosingNodeWithTag(const Position&, const QualifiedName&); 69 Node* enclosingNodeOfType(const Position&, bool (*nodeIsOfType)(const Node*), EditingBoundaryCrossingRule = CannotCrossEditingBoundary); 70 71 Node* tabSpanNode(const Node*); 72 Node* isLastPositionBeforeTable(const VisiblePosition&); 73 Node* isFirstPositionAfterTable(const VisiblePosition&); 74 75 // offset functions on Node 76 77 int lastOffsetForEditing(const Node*); 78 int caretMinOffset(const Node*); 79 int caretMaxOffset(const Node*); 80 81 // boolean functions on Node 82 83 // FIXME: editingIgnoresContent, canHaveChildrenForEditing, and isAtomicNode 84 // should be renamed to reflect its usage. 85 86 // Returns true for nodes that either have no content, or have content that is ignored (skipped over) while editing. 87 // There are no VisiblePositions inside these nodes. 88 inline bool editingIgnoresContent(const Node* node) 89 { 90 return !node->canContainRangeEndPoint(); 91 } 92 93 inline bool canHaveChildrenForEditing(const Node* node) 94 { 95 return !node->isTextNode() && node->canContainRangeEndPoint(); 96 } 97 98 bool isAtomicNode(const Node*); 99 bool isBlock(const Node*); 100 bool isInline(const Node*); 101 bool isSpecialElement(const Node*); 102 bool isTabSpanNode(const Node*); 103 bool isTabSpanTextNode(const Node*); 104 bool isMailBlockquote(const Node*); 105 bool isTableElement(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 positionOutsideTabSpan(const Position&); 131 Position positionBeforeContainingSpecialElement(const Position&, Node** containingSpecialElement = 0); 132 Position positionAfterContainingSpecialElement(const Position&, Node** containingSpecialElement = 0); 133 134 inline Position firstPositionInOrBeforeNode(Node* node) 135 { 136 if (!node) 137 return Position(); 138 return editingIgnoresContent(node) ? positionBeforeNode(node) : firstPositionInNode(node); 139 } 140 141 inline Position lastPositionInOrAfterNode(Node* node) 142 { 143 if (!node) 144 return Position(); 145 return editingIgnoresContent(node) ? positionAfterNode(node) : lastPositionInNode(node); 146 } 147 148 // comparision functions on Position 149 150 int comparePositions(const Position&, const Position&); 151 int comparePositions(const PositionWithAffinity&, const PositionWithAffinity&); 152 153 // boolean functions on Position 154 155 enum EUpdateStyle { UpdateStyle, DoNotUpdateStyle }; 156 bool isEditablePosition(const Position&, EditableType = ContentIsEditable, EUpdateStyle = UpdateStyle); 157 bool isRichlyEditablePosition(const Position&, EditableType = ContentIsEditable); 158 bool lineBreakExistsAtPosition(const Position&); 159 bool isVisiblyAdjacent(const Position& first, const Position& second); 160 bool isAtUnsplittableElement(const Position&); 161 162 // miscellaneous functions on Position 163 164 unsigned numEnclosingMailBlockquotes(const Position&); 165 void updatePositionForNodeRemoval(Position&, Node*); 166 167 // ------------------------------------------------------------------------- 168 // VisiblePosition 169 // ------------------------------------------------------------------------- 170 171 // Functions returning VisiblePosition 172 173 VisiblePosition firstEditablePositionAfterPositionInRoot(const Position&, Node*); 174 VisiblePosition lastEditablePositionBeforePositionInRoot(const Position&, Node*); 175 VisiblePosition visiblePositionBeforeNode(Node*); 176 VisiblePosition visiblePositionAfterNode(Node*); 177 178 bool lineBreakExistsAtVisiblePosition(const VisiblePosition&); 179 180 int comparePositions(const VisiblePosition&, const VisiblePosition&); 181 182 int indexForVisiblePosition(const VisiblePosition&, RefPtr<ContainerNode>& scope); 183 VisiblePosition visiblePositionForIndex(int index, ContainerNode* scope); 184 185 // ------------------------------------------------------------------------- 186 // Range 187 // ------------------------------------------------------------------------- 188 189 // Functions returning Range 190 191 PassRefPtr<Range> createRange(PassRefPtr<Document>, const VisiblePosition& start, const VisiblePosition& end, ExceptionState&); 192 193 // ------------------------------------------------------------------------- 194 // HTMLElement 195 // ------------------------------------------------------------------------- 196 197 // Functions returning HTMLElement 198 199 PassRefPtr<HTMLElement> createDefaultParagraphElement(Document*); 200 PassRefPtr<HTMLElement> createBreakElement(Document*); 201 PassRefPtr<HTMLElement> createOrderedListElement(Document*); 202 PassRefPtr<HTMLElement> createUnorderedListElement(Document*); 203 PassRefPtr<HTMLElement> createListItemElement(Document*); 204 PassRefPtr<HTMLElement> createHTMLElement(Document*, const QualifiedName&); 205 PassRefPtr<HTMLElement> createHTMLElement(Document*, const AtomicString&); 206 207 HTMLElement* enclosingList(Node*); 208 HTMLElement* outermostEnclosingList(Node*, Node* rootList = 0); 209 Node* enclosingListChild(Node*); 210 211 // ------------------------------------------------------------------------- 212 // Element 213 // ------------------------------------------------------------------------- 214 215 // Functions returning Element 216 217 PassRefPtr<Element> createTabSpanElement(Document*); 218 PassRefPtr<Element> createTabSpanElement(Document*, PassRefPtr<Node> tabTextNode); 219 PassRefPtr<Element> createTabSpanElement(Document*, const String& tabText); 220 PassRefPtr<Element> createBlockPlaceholderElement(Document*); 221 222 Element* editableRootForPosition(const Position&, EditableType = ContentIsEditable); 223 Element* unsplittableElementForPosition(const Position&); 224 225 // Boolean functions on Element 226 227 bool canMergeLists(Element* firstList, Element* secondList); 228 229 // ------------------------------------------------------------------------- 230 // VisibleSelection 231 // ------------------------------------------------------------------------- 232 233 // Functions returning VisibleSelection 234 VisibleSelection selectionForParagraphIteration(const VisibleSelection&); 235 236 Position adjustedSelectionStartForStyleComputation(const VisibleSelection&); 237 238 239 // Miscellaneous functions on Text 240 inline bool isWhitespace(UChar c) 241 { 242 return c == noBreakSpace || c == ' ' || c == '\n' || c == '\t'; 243 } 244 245 inline bool isAmbiguousBoundaryCharacter(UChar character) 246 { 247 // These are characters that can behave as word boundaries, but can appear within words. 248 // 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. 249 // FIXME: this is required until 6853027 is fixed and text checking can do this for us. 250 return character == '\'' || character == rightSingleQuotationMark || character == hebrewPunctuationGershayim; 251 } 252 253 String stringWithRebalancedWhitespace(const String&, bool startIsStartOfParagraph, bool endIsEndOfParagraph); 254 const String& nonBreakingSpaceString(); 255 256 } 257 258 #endif 259