Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(182)

Side by Side Diff: third_party/WebKit/Source/core/dom/Range.cpp

Issue 2701413003: Range: node offsets should be unsigned. (Closed)
Patch Set: Resolve std::numeric_limits<int>::max() leftover Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * (C) 1999 Lars Knoll (knoll@kde.org) 2 * (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 2000 Gunnstein Lye (gunnstein@netcom.no) 3 * (C) 2000 Gunnstein Lye (gunnstein@netcom.no)
4 * (C) 2000 Frederik Holljen (frederik.holljen@hig.no) 4 * (C) 2000 Frederik Holljen (frederik.holljen@hig.no)
5 * (C) 2001 Peter Kelly (pmk@post.com) 5 * (C) 2001 Peter Kelly (pmk@post.com)
6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All
7 * rights reserved. 7 * rights reserved.
8 * Copyright (C) 2011 Motorola Mobility. All rights reserved. 8 * Copyright (C) 2011 Motorola Mobility. All rights reserved.
9 * 9 *
10 * This library is free software; you can redistribute it and/or 10 * This library is free software; you can redistribute it and/or
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 m_end(m_ownerDocument) { 63 m_end(m_ownerDocument) {
64 m_ownerDocument->attachRange(this); 64 m_ownerDocument->attachRange(this);
65 } 65 }
66 66
67 Range* Range::create(Document& ownerDocument) { 67 Range* Range::create(Document& ownerDocument) {
68 return new Range(ownerDocument); 68 return new Range(ownerDocument);
69 } 69 }
70 70
71 inline Range::Range(Document& ownerDocument, 71 inline Range::Range(Document& ownerDocument,
72 Node* startContainer, 72 Node* startContainer,
73 int startOffset, 73 unsigned startOffset,
74 Node* endContainer, 74 Node* endContainer,
75 int endOffset) 75 unsigned endOffset)
76 : m_ownerDocument(&ownerDocument), 76 : m_ownerDocument(&ownerDocument),
77 m_start(m_ownerDocument), 77 m_start(m_ownerDocument),
78 m_end(m_ownerDocument) { 78 m_end(m_ownerDocument) {
79 m_ownerDocument->attachRange(this); 79 m_ownerDocument->attachRange(this);
80 80
81 // Simply setting the containers and offsets directly would not do any of the 81 // Simply setting the containers and offsets directly would not do any of the
82 // checking that setStart and setEnd do, so we call those functions. 82 // checking that setStart and setEnd do, so we call those functions.
83 setStart(startContainer, startOffset); 83 setStart(startContainer, startOffset);
84 setEnd(endContainer, endOffset); 84 setEnd(endContainer, endOffset);
85 } 85 }
86 86
87 Range* Range::create(Document& ownerDocument, 87 Range* Range::create(Document& ownerDocument,
88 Node* startContainer, 88 Node* startContainer,
89 int startOffset, 89 unsigned startOffset,
90 Node* endContainer, 90 Node* endContainer,
91 int endOffset) { 91 unsigned endOffset) {
92 return new Range(ownerDocument, startContainer, startOffset, endContainer, 92 return new Range(ownerDocument, startContainer, startOffset, endContainer,
93 endOffset); 93 endOffset);
94 } 94 }
95 95
96 Range* Range::create(Document& ownerDocument, 96 Range* Range::create(Document& ownerDocument,
97 const Position& start, 97 const Position& start,
98 const Position& end) { 98 const Position& end) {
99 return new Range(ownerDocument, start.computeContainerNode(), 99 return new Range(ownerDocument, start.computeContainerNode(),
100 start.computeOffsetInContainerNode(), 100 start.computeOffsetInContainerNode(),
101 end.computeContainerNode(), 101 end.computeContainerNode(),
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 endRootContainer = endRootContainer->parentNode(); 156 endRootContainer = endRootContainer->parentNode();
157 Node* startRootContainer = start.container(); 157 Node* startRootContainer = start.container();
158 while (startRootContainer->parentNode()) 158 while (startRootContainer->parentNode())
159 startRootContainer = startRootContainer->parentNode(); 159 startRootContainer = startRootContainer->parentNode();
160 160
161 return startRootContainer != endRootContainer || 161 return startRootContainer != endRootContainer ||
162 (Range::compareBoundaryPoints(start, end, ASSERT_NO_EXCEPTION) > 0); 162 (Range::compareBoundaryPoints(start, end, ASSERT_NO_EXCEPTION) > 0);
163 } 163 }
164 164
165 void Range::setStart(Node* refNode, 165 void Range::setStart(Node* refNode,
166 int offset, 166 unsigned offset,
167 ExceptionState& exceptionState) { 167 ExceptionState& exceptionState) {
168 if (!refNode) { 168 if (!refNode) {
169 // FIXME: Generated bindings code never calls with null, and neither should 169 // FIXME: Generated bindings code never calls with null, and neither should
170 // other callers! 170 // other callers!
171 exceptionState.throwTypeError("The node provided is null."); 171 exceptionState.throwTypeError("The node provided is null.");
172 return; 172 return;
173 } 173 }
174 174
175 Document& oldDocument = ownerDocument(); 175 Document& oldDocument = ownerDocument();
176 bool didMoveDocument = false; 176 bool didMoveDocument = false;
177 if (refNode->document() != m_ownerDocument) { 177 if (refNode->document() != m_ownerDocument) {
178 setDocument(refNode->document()); 178 setDocument(refNode->document());
179 didMoveDocument = true; 179 didMoveDocument = true;
180 } 180 }
181 181
182 Node* childNode = checkNodeWOffset(refNode, offset, exceptionState); 182 Node* childNode = checkNodeWOffset(refNode, offset, exceptionState);
183 if (exceptionState.hadException()) 183 if (exceptionState.hadException())
184 return; 184 return;
185 185
186 m_start.set(refNode, offset, childNode); 186 m_start.set(refNode, offset, childNode);
187 187
188 if (didMoveDocument || checkForDifferentRootContainer(m_start, m_end)) { 188 if (didMoveDocument || checkForDifferentRootContainer(m_start, m_end)) {
189 removeFromSelectionIfInDifferentRoot(oldDocument); 189 removeFromSelectionIfInDifferentRoot(oldDocument);
190 collapse(true); 190 collapse(true);
191 return; 191 return;
192 } 192 }
193 updateSelectionIfAddedToSelection(); 193 updateSelectionIfAddedToSelection();
194 } 194 }
195 195
196 void Range::setEnd(Node* refNode, int offset, ExceptionState& exceptionState) { 196 void Range::setEnd(Node* refNode,
197 unsigned offset,
198 ExceptionState& exceptionState) {
197 if (!refNode) { 199 if (!refNode) {
198 // FIXME: Generated bindings code never calls with null, and neither should 200 // FIXME: Generated bindings code never calls with null, and neither should
199 // other callers! 201 // other callers!
200 exceptionState.throwTypeError("The node provided is null."); 202 exceptionState.throwTypeError("The node provided is null.");
201 return; 203 return;
202 } 204 }
203 205
204 bool didMoveDocument = false; 206 bool didMoveDocument = false;
205 Document& oldDocument = ownerDocument(); 207 Document& oldDocument = ownerDocument();
206 if (refNode->document() != m_ownerDocument) { 208 if (refNode->document() != m_ownerDocument) {
(...skipping 30 matching lines...) Expand all
237 void Range::collapse(bool toStart) { 239 void Range::collapse(bool toStart) {
238 if (toStart) 240 if (toStart)
239 m_end = m_start; 241 m_end = m_start;
240 else 242 else
241 m_start = m_end; 243 m_start = m_end;
242 updateSelectionIfAddedToSelection(); 244 updateSelectionIfAddedToSelection();
243 } 245 }
244 246
245 bool Range::isNodeFullyContained(Node& node) const { 247 bool Range::isNodeFullyContained(Node& node) const {
246 ContainerNode* parentNode = node.parentNode(); 248 ContainerNode* parentNode = node.parentNode();
247 int nodeIndex = node.nodeIndex(); 249 unsigned nodeIndex = node.nodeIndex();
248 return isPointInRange( 250 return isPointInRange(
249 parentNode, nodeIndex, 251 parentNode, nodeIndex,
250 IGNORE_EXCEPTION_FOR_TESTING) // starts in the middle of this 252 IGNORE_EXCEPTION_FOR_TESTING) // starts in the middle of this
251 // range, or on the boundary points. 253 // range, or on the boundary points.
252 && isPointInRange( 254 && isPointInRange(
253 parentNode, nodeIndex + 1, 255 parentNode, nodeIndex + 1,
254 IGNORE_EXCEPTION_FOR_TESTING); // ends in the middle of this 256 IGNORE_EXCEPTION_FOR_TESTING); // ends in the middle of this
255 // range, or on the boundary 257 // range, or on the boundary
256 // points. 258 // points.
257 } 259 }
258 260
259 bool Range::hasSameRoot(const Node& node) const { 261 bool Range::hasSameRoot(const Node& node) const {
260 if (node.document() != m_ownerDocument) 262 if (node.document() != m_ownerDocument)
261 return false; 263 return false;
262 // commonAncestorContainer() is O(depth). We should avoid to call it in common 264 // commonAncestorContainer() is O(depth). We should avoid to call it in common
263 // cases. 265 // cases.
264 if (node.isInTreeScope() && m_start.container()->isInTreeScope() && 266 if (node.isInTreeScope() && m_start.container()->isInTreeScope() &&
265 &node.treeScope() == &m_start.container()->treeScope()) 267 &node.treeScope() == &m_start.container()->treeScope())
266 return true; 268 return true;
267 return node.commonAncestor(*m_start.container(), NodeTraversal::parent); 269 return node.commonAncestor(*m_start.container(), NodeTraversal::parent);
268 } 270 }
269 271
270 bool Range::isPointInRange(Node* refNode, 272 bool Range::isPointInRange(Node* refNode,
271 int offset, 273 unsigned offset,
272 ExceptionState& exceptionState) const { 274 ExceptionState& exceptionState) const {
273 if (!refNode) { 275 if (!refNode) {
274 // FIXME: Generated bindings code never calls with null, and neither should 276 // FIXME: Generated bindings code never calls with null, and neither should
275 // other callers! 277 // other callers!
276 exceptionState.throwTypeError("The node provided is null."); 278 exceptionState.throwTypeError("The node provided is null.");
277 return false; 279 return false;
278 } 280 }
279 if (!hasSameRoot(*refNode)) 281 if (!hasSameRoot(*refNode))
280 return false; 282 return false;
281 283
282 checkNodeWOffset(refNode, offset, exceptionState); 284 checkNodeWOffset(refNode, offset, exceptionState);
283 if (exceptionState.hadException()) 285 if (exceptionState.hadException())
284 return false; 286 return false;
285 287
286 return compareBoundaryPoints(refNode, offset, m_start.container(), 288 return compareBoundaryPoints(refNode, offset, m_start.container(),
287 m_start.offset(), exceptionState) >= 0 && 289 m_start.offset(), exceptionState) >= 0 &&
288 !exceptionState.hadException() && 290 !exceptionState.hadException() &&
289 compareBoundaryPoints(refNode, offset, m_end.container(), 291 compareBoundaryPoints(refNode, offset, m_end.container(),
290 m_end.offset(), exceptionState) <= 0 && 292 m_end.offset(), exceptionState) <= 0 &&
291 !exceptionState.hadException(); 293 !exceptionState.hadException();
292 } 294 }
293 295
294 short Range::comparePoint(Node* refNode, 296 short Range::comparePoint(Node* refNode,
295 int offset, 297 unsigned offset,
296 ExceptionState& exceptionState) const { 298 ExceptionState& exceptionState) const {
297 // http://developer.mozilla.org/en/docs/DOM:range.comparePoint 299 // http://developer.mozilla.org/en/docs/DOM:range.comparePoint
298 // This method returns -1, 0 or 1 depending on if the point described by the 300 // This method returns -1, 0 or 1 depending on if the point described by the
299 // refNode node and an offset within the node is before, same as, or after the 301 // refNode node and an offset within the node is before, same as, or after the
300 // range respectively. 302 // range respectively.
301 303
302 if (!hasSameRoot(*refNode)) { 304 if (!hasSameRoot(*refNode)) {
303 exceptionState.throwDOMException( 305 exceptionState.throwDOMException(
304 WrongDocumentError, 306 WrongDocumentError,
305 "The node provided and the Range are not in the same tree."); 307 "The node provided and the Range are not in the same tree.");
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 return compareBoundaryPoints(m_end, sourceRange->m_end, exceptionState); 374 return compareBoundaryPoints(m_end, sourceRange->m_end, exceptionState);
373 case kEndToStart: 375 case kEndToStart:
374 return compareBoundaryPoints(m_start, sourceRange->m_end, exceptionState); 376 return compareBoundaryPoints(m_start, sourceRange->m_end, exceptionState);
375 } 377 }
376 378
377 NOTREACHED(); 379 NOTREACHED();
378 return 0; 380 return 0;
379 } 381 }
380 382
381 short Range::compareBoundaryPoints(Node* containerA, 383 short Range::compareBoundaryPoints(Node* containerA,
382 int offsetA, 384 unsigned offsetA,
383 Node* containerB, 385 Node* containerB,
384 int offsetB, 386 unsigned offsetB,
385 ExceptionState& exceptionState) { 387 ExceptionState& exceptionState) {
386 bool disconnected = false; 388 bool disconnected = false;
387 short result = comparePositionsInDOMTree(containerA, offsetA, containerB, 389 short result = comparePositionsInDOMTree(containerA, offsetA, containerB,
388 offsetB, &disconnected); 390 offsetB, &disconnected);
389 if (disconnected) { 391 if (disconnected) {
390 exceptionState.throwDOMException( 392 exceptionState.throwDOMException(
391 WrongDocumentError, "The two ranges are in separate documents."); 393 WrongDocumentError, "The two ranges are in separate documents.");
392 return 0; 394 return 0;
393 } 395 }
394 return result; 396 return result;
(...skipping 555 matching lines...) Expand 10 before | Expand all | Expand 10 after
950 } 952 }
951 953
952 String Range::toString() const { 954 String Range::toString() const {
953 StringBuilder builder; 955 StringBuilder builder;
954 956
955 Node* pastLast = pastLastNode(); 957 Node* pastLast = pastLastNode();
956 for (Node* n = firstNode(); n != pastLast; n = NodeTraversal::next(*n)) { 958 for (Node* n = firstNode(); n != pastLast; n = NodeTraversal::next(*n)) {
957 Node::NodeType type = n->getNodeType(); 959 Node::NodeType type = n->getNodeType();
958 if (type == Node::kTextNode || type == Node::kCdataSectionNode) { 960 if (type == Node::kTextNode || type == Node::kCdataSectionNode) {
959 String data = toCharacterData(n)->data(); 961 String data = toCharacterData(n)->data();
960 int length = data.length(); 962 unsigned length = data.length();
961 int start = (n == m_start.container()) 963 unsigned start =
962 ? std::min(std::max(0, m_start.offset()), length) 964 (n == m_start.container()) ? std::min(m_start.offset(), length) : 0;
963 : 0; 965 unsigned end = (n == m_end.container())
964 int end = (n == m_end.container()) 966 ? std::min(std::max(start, m_end.offset()), length)
965 ? std::min(std::max(start, m_end.offset()), length) 967 : length;
966 : length;
967 builder.append(data, start, end - start); 968 builder.append(data, start, end - start);
968 } 969 }
969 } 970 }
970 971
971 return builder.toString(); 972 return builder.toString();
972 } 973 }
973 974
974 String Range::text() const { 975 String Range::text() const {
975 DCHECK(!m_ownerDocument->needsLayoutTreeUpdate()); 976 DCHECK(!m_ownerDocument->needsLayoutTreeUpdate());
976 return plainText(EphemeralRange(this), 977 return plainText(EphemeralRange(this),
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1018 return blink::createContextualFragment( 1019 return blink::createContextualFragment(
1019 markup, element, AllowScriptingContentAndDoNotMarkAlreadyStarted, 1020 markup, element, AllowScriptingContentAndDoNotMarkAlreadyStarted,
1020 exceptionState); 1021 exceptionState);
1021 } 1022 }
1022 1023
1023 void Range::detach() { 1024 void Range::detach() {
1024 // This is now a no-op as per the DOM specification. 1025 // This is now a no-op as per the DOM specification.
1025 } 1026 }
1026 1027
1027 Node* Range::checkNodeWOffset(Node* n, 1028 Node* Range::checkNodeWOffset(Node* n,
1028 int offset, 1029 unsigned offset,
1029 ExceptionState& exceptionState) { 1030 ExceptionState& exceptionState) {
1030 switch (n->getNodeType()) { 1031 switch (n->getNodeType()) {
1031 case Node::kDocumentTypeNode: 1032 case Node::kDocumentTypeNode:
1032 exceptionState.throwDOMException( 1033 exceptionState.throwDOMException(
1033 InvalidNodeTypeError, 1034 InvalidNodeTypeError,
1034 "The node provided is of type '" + n->nodeName() + "'."); 1035 "The node provided is of type '" + n->nodeName() + "'.");
1035 return nullptr; 1036 return nullptr;
1036 case Node::kCdataSectionNode: 1037 case Node::kCdataSectionNode:
1037 case Node::kCommentNode: 1038 case Node::kCommentNode:
1038 case Node::kTextNode: 1039 case Node::kTextNode:
1039 if (static_cast<unsigned>(offset) > toCharacterData(n)->length()) 1040 if (offset > toCharacterData(n)->length()) {
1041 exceptionState.throwDOMException(
1042 IndexSizeError, "The offset " + String::number(offset) +
1043 " is larger than the node's length (" +
1044 String::number(toCharacterData(n)->length()) +
1045 ").");
1046 }
1047 return nullptr;
1048 case Node::kProcessingInstructionNode:
1049 if (offset > toProcessingInstruction(n)->data().length()) {
1040 exceptionState.throwDOMException( 1050 exceptionState.throwDOMException(
1041 IndexSizeError, 1051 IndexSizeError,
1042 "The offset " + String::number(offset) + 1052 "The offset " + String::number(offset) +
1043 " is larger than or equal to the node's length (" + 1053 " is larger than the node's length (" +
1044 String::number(toCharacterData(n)->length()) + ").");
1045 return nullptr;
1046 case Node::kProcessingInstructionNode:
1047 if (static_cast<unsigned>(offset) >
1048 toProcessingInstruction(n)->data().length())
1049 exceptionState.throwDOMException(
1050 IndexSizeError,
1051 "The offset " + String::number(offset) +
1052 " is larger than or equal to than the node's length (" +
1053 String::number(toProcessingInstruction(n)->data().length()) + 1054 String::number(toProcessingInstruction(n)->data().length()) +
1054 ")."); 1055 ").");
1056 }
1055 return nullptr; 1057 return nullptr;
1056 case Node::kAttributeNode: 1058 case Node::kAttributeNode:
1057 case Node::kDocumentFragmentNode: 1059 case Node::kDocumentFragmentNode:
1058 case Node::kDocumentNode: 1060 case Node::kDocumentNode:
1059 case Node::kElementNode: { 1061 case Node::kElementNode: {
1060 if (!offset) 1062 if (!offset)
1061 return nullptr; 1063 return nullptr;
1062 Node* childBefore = NodeTraversal::childAt(*n, offset - 1); 1064 Node* childBefore = NodeTraversal::childAt(*n, offset - 1);
1063 if (!childBefore) 1065 if (!childBefore) {
1064 exceptionState.throwDOMException( 1066 exceptionState.throwDOMException(
1065 IndexSizeError, 1067 IndexSizeError,
1066 "There is no child at offset " + String::number(offset) + "."); 1068 "There is no child at offset " + String::number(offset) + ".");
1069 }
1067 return childBefore; 1070 return childBefore;
1068 } 1071 }
1069 } 1072 }
1070 NOTREACHED(); 1073 NOTREACHED();
1071 return nullptr; 1074 return nullptr;
1072 } 1075 }
1073 1076
1074 void Range::checkNodeBA(Node* n, ExceptionState& exceptionState) const { 1077 void Range::checkNodeBA(Node* n, ExceptionState& exceptionState) const {
1075 if (!n) { 1078 if (!n) {
1076 // FIXME: Generated bindings code never calls with null, and neither should 1079 // FIXME: Generated bindings code never calls with null, and neither should
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after
1417 Node* endContainer = m_end.container(); 1420 Node* endContainer = m_end.container();
1418 DCHECK(endContainer); 1421 DCHECK(endContainer);
1419 1422
1420 Node* stopNode = pastLastNode(); 1423 Node* stopNode = pastLastNode();
1421 for (Node* node = firstNode(); node != stopNode; 1424 for (Node* node = firstNode(); node != stopNode;
1422 node = NodeTraversal::next(*node)) { 1425 node = NodeTraversal::next(*node)) {
1423 LayoutObject* r = node->layoutObject(); 1426 LayoutObject* r = node->layoutObject();
1424 if (!r || !r->isText()) 1427 if (!r || !r->isText())
1425 continue; 1428 continue;
1426 LayoutText* layoutText = toLayoutText(r); 1429 LayoutText* layoutText = toLayoutText(r);
1427 int startOffset = node == startContainer ? m_start.offset() : 0; 1430 unsigned startOffset = node == startContainer ? m_start.offset() : 0;
1428 int endOffset = 1431 unsigned endOffset = node == endContainer
1429 node == endContainer ? m_end.offset() : std::numeric_limits<int>::max(); 1432 ? m_end.offset()
1433 : std::numeric_limits<unsigned>::max();
1430 layoutText->absoluteRectsForRange(rects, startOffset, endOffset, 1434 layoutText->absoluteRectsForRange(rects, startOffset, endOffset,
1431 useSelectionHeight); 1435 useSelectionHeight);
1432 } 1436 }
1433 } 1437 }
1434 1438
1435 void Range::textQuads(Vector<FloatQuad>& quads, bool useSelectionHeight) const { 1439 void Range::textQuads(Vector<FloatQuad>& quads, bool useSelectionHeight) const {
1436 Node* startContainer = m_start.container(); 1440 Node* startContainer = m_start.container();
1437 DCHECK(startContainer); 1441 DCHECK(startContainer);
1438 Node* endContainer = m_end.container(); 1442 Node* endContainer = m_end.container();
1439 DCHECK(endContainer); 1443 DCHECK(endContainer);
1440 1444
1441 Node* stopNode = pastLastNode(); 1445 Node* stopNode = pastLastNode();
1442 for (Node* node = firstNode(); node != stopNode; 1446 for (Node* node = firstNode(); node != stopNode;
1443 node = NodeTraversal::next(*node)) { 1447 node = NodeTraversal::next(*node)) {
1444 LayoutObject* r = node->layoutObject(); 1448 LayoutObject* r = node->layoutObject();
1445 if (!r || !r->isText()) 1449 if (!r || !r->isText())
1446 continue; 1450 continue;
1447 LayoutText* layoutText = toLayoutText(r); 1451 LayoutText* layoutText = toLayoutText(r);
1448 int startOffset = node == startContainer ? m_start.offset() : 0; 1452 unsigned startOffset = node == startContainer ? m_start.offset() : 0;
1449 int endOffset = 1453 unsigned endOffset = node == endContainer
1450 node == endContainer ? m_end.offset() : std::numeric_limits<int>::max(); 1454 ? m_end.offset()
1455 : std::numeric_limits<unsigned>::max();
1451 layoutText->absoluteQuadsForRange(quads, startOffset, endOffset, 1456 layoutText->absoluteQuadsForRange(quads, startOffset, endOffset,
1452 useSelectionHeight); 1457 useSelectionHeight);
1453 } 1458 }
1454 } 1459 }
1455 1460
1456 bool areRangesEqual(const Range* a, const Range* b) { 1461 bool areRangesEqual(const Range* a, const Range* b) {
1457 if (a == b) 1462 if (a == b)
1458 return true; 1463 return true;
1459 if (!a || !b) 1464 if (!a || !b)
1460 return false; 1465 return false;
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
1557 boundaryTextRemoved(m_end, text, offset, length); 1562 boundaryTextRemoved(m_end, text, offset, length);
1558 } 1563 }
1559 1564
1560 static inline void boundaryTextNodesMerged(RangeBoundaryPoint& boundary, 1565 static inline void boundaryTextNodesMerged(RangeBoundaryPoint& boundary,
1561 const NodeWithIndex& oldNode, 1566 const NodeWithIndex& oldNode,
1562 unsigned offset) { 1567 unsigned offset) {
1563 if (boundary.container() == oldNode.node()) 1568 if (boundary.container() == oldNode.node())
1564 boundary.set(oldNode.node().previousSibling(), boundary.offset() + offset, 1569 boundary.set(oldNode.node().previousSibling(), boundary.offset() + offset,
1565 0); 1570 0);
1566 else if (boundary.container() == oldNode.node().parentNode() && 1571 else if (boundary.container() == oldNode.node().parentNode() &&
1567 boundary.offset() == oldNode.index()) 1572 boundary.offset() == static_cast<unsigned>(oldNode.index()))
1568 boundary.set(oldNode.node().previousSibling(), offset, 0); 1573 boundary.set(oldNode.node().previousSibling(), offset, 0);
1569 } 1574 }
1570 1575
1571 void Range::didMergeTextNodes(const NodeWithIndex& oldNode, unsigned offset) { 1576 void Range::didMergeTextNodes(const NodeWithIndex& oldNode, unsigned offset) {
1572 DCHECK_EQ(oldNode.node().document(), m_ownerDocument); 1577 DCHECK_EQ(oldNode.node().document(), m_ownerDocument);
1573 DCHECK(oldNode.node().parentNode()); 1578 DCHECK(oldNode.node().parentNode());
1574 DCHECK(oldNode.node().isTextNode()); 1579 DCHECK(oldNode.node().isTextNode());
1575 DCHECK(oldNode.node().previousSibling()); 1580 DCHECK(oldNode.node().previousSibling());
1576 DCHECK(oldNode.node().previousSibling()->isTextNode()); 1581 DCHECK(oldNode.node().previousSibling()->isTextNode());
1577 boundaryTextNodesMerged(m_start, oldNode, offset); 1582 boundaryTextNodesMerged(m_start, oldNode, offset);
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
1675 Vector<FloatQuad> elementQuads; 1680 Vector<FloatQuad> elementQuads;
1676 layoutObject->absoluteQuads(elementQuads); 1681 layoutObject->absoluteQuads(elementQuads);
1677 m_ownerDocument->adjustFloatQuadsForScrollAndAbsoluteZoom( 1682 m_ownerDocument->adjustFloatQuadsForScrollAndAbsoluteZoom(
1678 elementQuads, *layoutObject); 1683 elementQuads, *layoutObject);
1679 1684
1680 quads.appendVector(elementQuads); 1685 quads.appendVector(elementQuads);
1681 } 1686 }
1682 } 1687 }
1683 } else if (node->isTextNode()) { 1688 } else if (node->isTextNode()) {
1684 if (LayoutText* layoutText = toText(node)->layoutObject()) { 1689 if (LayoutText* layoutText = toText(node)->layoutObject()) {
1685 int startOffset = (node == startContainer) ? m_start.offset() : 0; 1690 unsigned startOffset = (node == startContainer) ? m_start.offset() : 0;
1686 int endOffset = (node == endContainer) ? m_end.offset() : INT_MAX; 1691 unsigned endOffset = (node == endContainer)
1692 ? m_end.offset()
1693 : std::numeric_limits<unsigned>::max();
1687 1694
1688 Vector<FloatQuad> textQuads; 1695 Vector<FloatQuad> textQuads;
1689 layoutText->absoluteQuadsForRange(textQuads, startOffset, endOffset); 1696 layoutText->absoluteQuadsForRange(textQuads, startOffset, endOffset);
1690 m_ownerDocument->adjustFloatQuadsForScrollAndAbsoluteZoom(textQuads, 1697 m_ownerDocument->adjustFloatQuadsForScrollAndAbsoluteZoom(textQuads,
1691 *layoutText); 1698 *layoutText);
1692 1699
1693 quads.appendVector(textQuads); 1700 quads.appendVector(textQuads);
1694 } 1701 }
1695 } 1702 }
1696 } 1703 }
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1760 .data() 1767 .data()
1761 << "start offset: " << range->startOffset() 1768 << "start offset: " << range->startOffset()
1762 << ", end offset: " << range->endOffset(); 1769 << ", end offset: " << range->endOffset();
1763 } else { 1770 } else {
1764 LOG(INFO) << "Cannot show tree if range is null, or if boundary points are " 1771 LOG(INFO) << "Cannot show tree if range is null, or if boundary points are "
1765 "invalid."; 1772 "invalid.";
1766 } 1773 }
1767 } 1774 }
1768 1775
1769 #endif 1776 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698