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 isTableElement(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 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(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