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