1 /* 2 * (C) 1999 Lars Knoll (knoll@kde.org) 3 * (C) 2000 Gunnstein Lye (gunnstein@netcom.no) 4 * (C) 2000 Frederik Holljen (frederik.holljen@hig.no) 5 * (C) 2001 Peter Kelly (pmk@post.com) 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. 7 * 8 * This library is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Library General Public 10 * License as published by the Free Software Foundation; either 11 * version 2 of the License, or (at your option) any later version. 12 * 13 * This library is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Library General Public License for more details. 17 * 18 * You should have received a copy of the GNU Library General Public License 19 * along with this library; see the file COPYING.LIB. If not, write to 20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 21 * Boston, MA 02110-1301, USA. 22 * 23 */ 24 25 #ifndef Range_h 26 #define Range_h 27 28 #include "FloatQuad.h" 29 #include "RangeBoundaryPoint.h" 30 #include <wtf/Forward.h> 31 #include <wtf/RefCounted.h> 32 #include <wtf/Vector.h> 33 34 namespace WebCore { 35 36 class ClientRect; 37 class ClientRectList; 38 class DocumentFragment; 39 class NodeWithIndex; 40 class Text; 41 42 class Range : public RefCounted<Range> { 43 public: 44 static PassRefPtr<Range> create(PassRefPtr<Document>); 45 static PassRefPtr<Range> create(PassRefPtr<Document>, PassRefPtr<Node> startContainer, int startOffset, PassRefPtr<Node> endContainer, int endOffset); 46 static PassRefPtr<Range> create(PassRefPtr<Document>, const Position&, const Position&); 47 ~Range(); 48 ownerDocument()49 Document* ownerDocument() const { return m_ownerDocument.get(); } startContainer()50 Node* startContainer() const { return m_start.container(); } startOffset()51 int startOffset() const { return m_start.offset(); } endContainer()52 Node* endContainer() const { return m_end.container(); } endOffset()53 int endOffset() const { return m_end.offset(); } 54 55 Node* startContainer(ExceptionCode&) const; 56 int startOffset(ExceptionCode&) const; 57 Node* endContainer(ExceptionCode&) const; 58 int endOffset(ExceptionCode&) const; 59 bool collapsed(ExceptionCode&) const; 60 61 Node* commonAncestorContainer(ExceptionCode&) const; 62 static Node* commonAncestorContainer(Node* containerA, Node* containerB); 63 void setStart(PassRefPtr<Node> container, int offset, ExceptionCode&); 64 void setEnd(PassRefPtr<Node> container, int offset, ExceptionCode&); 65 void collapse(bool toStart, ExceptionCode&); 66 bool isPointInRange(Node* refNode, int offset, ExceptionCode&); 67 short comparePoint(Node* refNode, int offset, ExceptionCode&) const; 68 enum CompareResults { NODE_BEFORE, NODE_AFTER, NODE_BEFORE_AND_AFTER, NODE_INSIDE }; 69 CompareResults compareNode(Node* refNode, ExceptionCode&) const; 70 enum CompareHow { START_TO_START, START_TO_END, END_TO_END, END_TO_START }; 71 short compareBoundaryPoints(CompareHow, const Range* sourceRange, ExceptionCode&) const; 72 static short compareBoundaryPoints(Node* containerA, int offsetA, Node* containerB, int offsetB, ExceptionCode&); 73 static short compareBoundaryPoints(const RangeBoundaryPoint& boundaryA, const RangeBoundaryPoint& boundaryB, ExceptionCode&); 74 bool boundaryPointsValid() const; 75 bool intersectsNode(Node* refNode, ExceptionCode&); 76 void deleteContents(ExceptionCode&); 77 PassRefPtr<DocumentFragment> extractContents(ExceptionCode&); 78 PassRefPtr<DocumentFragment> cloneContents(ExceptionCode&); 79 void insertNode(PassRefPtr<Node>, ExceptionCode&); 80 String toString(ExceptionCode&) const; 81 82 String toHTML() const; 83 String text() const; 84 85 PassRefPtr<DocumentFragment> createContextualFragment(const String& html, ExceptionCode&) const; 86 87 void detach(ExceptionCode&); 88 PassRefPtr<Range> cloneRange(ExceptionCode&) const; 89 90 void setStartAfter(Node*, ExceptionCode&); 91 void setEndBefore(Node*, ExceptionCode&); 92 void setEndAfter(Node*, ExceptionCode&); 93 void selectNode(Node*, ExceptionCode&); 94 void selectNodeContents(Node*, ExceptionCode&); 95 void surroundContents(PassRefPtr<Node>, ExceptionCode&); 96 void setStartBefore(Node*, ExceptionCode&); 97 startPosition()98 const Position startPosition() const { return m_start.toPosition(); } endPosition()99 const Position endPosition() const { return m_end.toPosition(); } 100 101 Node* firstNode() const; 102 Node* pastLastNode() const; 103 104 Position editingStartPosition() const; 105 106 Node* shadowTreeRootNode() const; 107 108 IntRect boundingBox(); 109 // Not transform-friendly 110 void textRects(Vector<IntRect>&, bool useSelectionHeight = false); 111 // Transform-friendly 112 void textQuads(Vector<FloatQuad>&, bool useSelectionHeight = false) const; 113 void getBorderAndTextQuads(Vector<FloatQuad>&) const; 114 FloatRect boundingRect() const; 115 116 void nodeChildrenChanged(ContainerNode*); 117 void nodeChildrenWillBeRemoved(ContainerNode*); 118 void nodeWillBeRemoved(Node*); 119 120 void textInserted(Node*, unsigned offset, unsigned length); 121 void textRemoved(Node*, unsigned offset, unsigned length); 122 void textNodesMerged(NodeWithIndex& oldNode, unsigned offset); 123 void textNodeSplit(Text* oldNode); 124 125 // Expand range to a unit (word or sentence or block or document) boundary. 126 // Please refer to https://bugs.webkit.org/show_bug.cgi?id=27632 comment #5 127 // for details. 128 void expand(const String&, ExceptionCode&); 129 130 PassRefPtr<ClientRectList> getClientRects() const; 131 PassRefPtr<ClientRect> getBoundingClientRect() const; 132 133 #ifndef NDEBUG 134 void formatForDebugger(char* buffer, unsigned length) const; 135 #endif 136 137 private: 138 Range(PassRefPtr<Document>); 139 Range(PassRefPtr<Document>, PassRefPtr<Node> startContainer, int startOffset, PassRefPtr<Node> endContainer, int endOffset); 140 141 void setDocument(Document*); 142 143 Node* checkNodeWOffset(Node*, int offset, ExceptionCode&) const; 144 void checkNodeBA(Node*, ExceptionCode&) const; 145 void checkDeleteExtract(ExceptionCode&); 146 bool containedByReadOnly() const; 147 int maxStartOffset() const; 148 int maxEndOffset() const; 149 150 enum ActionType { DELETE_CONTENTS, EXTRACT_CONTENTS, CLONE_CONTENTS }; 151 PassRefPtr<DocumentFragment> processContents(ActionType, ExceptionCode&); 152 static PassRefPtr<Node> processContentsBetweenOffsets(ActionType, PassRefPtr<DocumentFragment>, Node*, unsigned startOffset, unsigned endOffset, ExceptionCode&); 153 static void processNodes(ActionType, Vector<RefPtr<Node> >&, PassRefPtr<Node> oldContainer, PassRefPtr<Node> newContainer, ExceptionCode&); 154 enum ContentsProcessDirection { ProcessContentsForward, ProcessContentsBackward }; 155 static PassRefPtr<Node> processAncestorsAndTheirSiblings(ActionType, Node* container, ContentsProcessDirection, PassRefPtr<Node> clonedContainer, Node* commonRoot, ExceptionCode&); 156 157 RefPtr<Document> m_ownerDocument; 158 RangeBoundaryPoint m_start; 159 RangeBoundaryPoint m_end; 160 }; 161 162 PassRefPtr<Range> rangeOfContents(Node*); 163 164 bool areRangesEqual(const Range*, const Range*); 165 166 } // namespace 167 168 #ifndef NDEBUG 169 // Outside the WebCore namespace for ease of invocation from gdb. 170 void showTree(const WebCore::Range*); 171 #endif 172 173 #endif 174