Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2007, 2009 Apple Inc. All rights reserved. | 2 * Copyright (C) 2007, 2009 Apple Inc. All rights reserved. |
| 3 * Copyright (C) 2012 Google Inc. All rights reserved. | 3 * Copyright (C) 2012 Google Inc. All rights reserved. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
| 7 * are met: | 7 * are met: |
| 8 * | 8 * |
| 9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
| 10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 43 #include "core/editing/iterators/TextIterator.h" | 43 #include "core/editing/iterators/TextIterator.h" |
| 44 #include "core/frame/LocalFrame.h" | 44 #include "core/frame/LocalFrame.h" |
| 45 #include "core/frame/UseCounter.h" | 45 #include "core/frame/UseCounter.h" |
| 46 #include "core/inspector/ConsoleMessage.h" | 46 #include "core/inspector/ConsoleMessage.h" |
| 47 #include "wtf/text/WTFString.h" | 47 #include "wtf/text/WTFString.h" |
| 48 | 48 |
| 49 namespace blink { | 49 namespace blink { |
| 50 | 50 |
| 51 static Position createPosition(Node* node, int offset) | 51 static Position createPosition(Node* node, int offset) |
| 52 { | 52 { |
| 53 ASSERT(offset >= 0); | 53 DCHECK_GE(offset, 0); |
| 54 if (!node) | 54 if (!node) |
| 55 return Position(); | 55 return Position(); |
| 56 return Position(node, offset); | 56 return Position(node, offset); |
| 57 } | 57 } |
| 58 | 58 |
| 59 static Node* selectionShadowAncestor(LocalFrame* frame) | 59 static Node* selectionShadowAncestor(LocalFrame* frame) |
| 60 { | 60 { |
| 61 Node* node = frame->selection().selection().base().anchorNode(); | 61 Node* node = frame->selection().selection().base().anchorNode(); |
| 62 if (!node) | 62 if (!node) |
| 63 return 0; | 63 return 0; |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 74 { | 74 { |
| 75 } | 75 } |
| 76 | 76 |
| 77 void DOMSelection::clearTreeScope() | 77 void DOMSelection::clearTreeScope() |
| 78 { | 78 { |
| 79 m_treeScope = nullptr; | 79 m_treeScope = nullptr; |
| 80 } | 80 } |
| 81 | 81 |
| 82 const VisibleSelection& DOMSelection::visibleSelection() const | 82 const VisibleSelection& DOMSelection::visibleSelection() const |
| 83 { | 83 { |
| 84 ASSERT(m_frame); | 84 DCHECK(m_frame); |
| 85 return m_frame->selection().selection(); | 85 return m_frame->selection().selection(); |
| 86 } | 86 } |
| 87 | 87 |
| 88 static Position anchorPosition(const VisibleSelection& selection) | 88 static Position anchorPosition(const VisibleSelection& selection) |
| 89 { | 89 { |
| 90 Position anchor = selection.isBaseFirst() ? selection.start() : selection.en d(); | 90 Position anchor = selection.isBaseFirst() ? selection.start() : selection.en d(); |
| 91 return anchor.parentAnchoredEquivalent(); | 91 return anchor.parentAnchoredEquivalent(); |
| 92 } | 92 } |
| 93 | 93 |
| 94 static Position focusPosition(const VisibleSelection& selection) | 94 static Position focusPosition(const VisibleSelection& selection) |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 339 else if (equalIgnoringCase(granularityString, "documentboundary")) | 339 else if (equalIgnoringCase(granularityString, "documentboundary")) |
| 340 granularity = DocumentBoundary; | 340 granularity = DocumentBoundary; |
| 341 else | 341 else |
| 342 return; | 342 return; |
| 343 | 343 |
| 344 m_frame->selection().modify(alter, direction, granularity); | 344 m_frame->selection().modify(alter, direction, granularity); |
| 345 } | 345 } |
| 346 | 346 |
| 347 void DOMSelection::extend(Node* node, int offset, ExceptionState& exceptionState ) | 347 void DOMSelection::extend(Node* node, int offset, ExceptionState& exceptionState ) |
| 348 { | 348 { |
| 349 ASSERT(node); | 349 DCHECK(node); |
| 350 | 350 |
| 351 if (!m_frame) | 351 if (!m_frame) |
| 352 return; | 352 return; |
| 353 | 353 |
| 354 if (offset < 0) { | 354 if (offset < 0) { |
| 355 exceptionState.throwDOMException(IndexSizeError, String::number(offset) + " is not a valid offset."); | 355 exceptionState.throwDOMException(IndexSizeError, String::number(offset) + " is not a valid offset."); |
| 356 return; | 356 return; |
| 357 } | 357 } |
| 358 if (static_cast<unsigned>(offset) > node->lengthOfContents()) { | 358 if (static_cast<unsigned>(offset) > node->lengthOfContents()) { |
| 359 exceptionState.throwDOMException(IndexSizeError, String::number(offset) + " is larger than the given node's length."); | 359 exceptionState.throwDOMException(IndexSizeError, String::number(offset) + " is larger than the given node's length."); |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 370 { | 370 { |
| 371 if (!m_frame) | 371 if (!m_frame) |
| 372 return nullptr; | 372 return nullptr; |
| 373 | 373 |
| 374 if (index < 0 || index >= rangeCount()) { | 374 if (index < 0 || index >= rangeCount()) { |
| 375 exceptionState.throwDOMException(IndexSizeError, String::number(index) + " is not a valid index."); | 375 exceptionState.throwDOMException(IndexSizeError, String::number(index) + " is not a valid index."); |
| 376 return nullptr; | 376 return nullptr; |
| 377 } | 377 } |
| 378 | 378 |
| 379 // If you're hitting this, you've added broken multi-range selection support | 379 // If you're hitting this, you've added broken multi-range selection support |
| 380 ASSERT(rangeCount() == 1); | 380 DCHECK_EQ(rangeCount(), 1); |
| 381 | 381 |
| 382 Position anchor = anchorPosition(visibleSelection()); | 382 Position anchor = anchorPosition(visibleSelection()); |
| 383 if (!anchor.anchorNode()->isInShadowTree()) | 383 if (!anchor.anchorNode()->isInShadowTree()) |
| 384 return m_frame->selection().firstRange(); | 384 return m_frame->selection().firstRange(); |
| 385 | 385 |
| 386 Node* node = shadowAdjustedNode(anchor); | 386 Node* node = shadowAdjustedNode(anchor); |
| 387 if (!node) // crbug.com/595100 | 387 if (!node) // crbug.com/595100 |
| 388 return nullptr; | 388 return nullptr; |
| 389 if (!visibleSelection().isBaseFirst()) | 389 if (!visibleSelection().isBaseFirst()) |
| 390 return Range::create(*anchor.document(), focusNode(), focusOffset(), nod e, anchorOffset()); | 390 return Range::create(*anchor.document(), focusNode(), focusOffset(), nod e, anchorOffset()); |
| 391 return Range::create(*anchor.document(), node, anchorOffset(), focusNode(), focusOffset()); | 391 return Range::create(*anchor.document(), node, anchorOffset(), focusNode(), focusOffset()); |
| 392 } | 392 } |
| 393 | 393 |
| 394 void DOMSelection::removeAllRanges() | 394 void DOMSelection::removeAllRanges() |
| 395 { | 395 { |
| 396 if (!m_frame) | 396 if (!m_frame) |
| 397 return; | 397 return; |
| 398 m_frame->selection().clear(); | 398 m_frame->selection().clear(); |
| 399 } | 399 } |
| 400 | 400 |
| 401 void DOMSelection::addRange(Range* newRange) | 401 void DOMSelection::addRange(Range* newRange) |
| 402 { | 402 { |
| 403 ASSERT(newRange); | 403 DCHECK(newRange); |
| 404 | 404 |
| 405 if (!m_frame) | 405 if (!m_frame) |
| 406 return; | 406 return; |
| 407 | 407 |
| 408 if (!newRange->inShadowIncludingDocument()) { | 408 if (!newRange->inShadowIncludingDocument()) { |
| 409 addConsoleError("The given range isn't in document."); | 409 addConsoleError("The given range isn't in document."); |
| 410 return; | 410 return; |
| 411 } | 411 } |
| 412 | 412 |
| 413 FrameSelection& selection = m_frame->selection(); | 413 FrameSelection& selection = m_frame->selection(); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 460 if (!selectedRange) | 460 if (!selectedRange) |
| 461 return; | 461 return; |
| 462 | 462 |
| 463 selectedRange->deleteContents(ASSERT_NO_EXCEPTION); | 463 selectedRange->deleteContents(ASSERT_NO_EXCEPTION); |
| 464 | 464 |
| 465 setBaseAndExtent(selectedRange->startContainer(), selectedRange->startOffset (), selectedRange->startContainer(), selectedRange->startOffset(), ASSERT_NO_EXC EPTION); | 465 setBaseAndExtent(selectedRange->startContainer(), selectedRange->startOffset (), selectedRange->startContainer(), selectedRange->startOffset(), ASSERT_NO_EXC EPTION); |
| 466 } | 466 } |
| 467 | 467 |
| 468 bool DOMSelection::containsNode(const Node* n, bool allowPartial) const | 468 bool DOMSelection::containsNode(const Node* n, bool allowPartial) const |
| 469 { | 469 { |
| 470 ASSERT(n); | 470 DCHECK(n); |
| 471 | 471 |
| 472 if (!m_frame) | 472 if (!m_frame) |
| 473 return false; | 473 return false; |
| 474 | 474 |
| 475 FrameSelection& selection = m_frame->selection(); | 475 FrameSelection& selection = m_frame->selection(); |
| 476 | 476 |
| 477 if (m_frame->document() != n->document() || selection.isNone()) | 477 if (m_frame->document() != n->document() || selection.isNone()) |
| 478 return false; | 478 return false; |
| 479 | 479 |
| 480 unsigned nodeIndex = n->nodeIndex(); | 480 unsigned nodeIndex = n->nodeIndex(); |
| 481 const EphemeralRange selectedRange = selection.selection().toNormalizedEphem eralRange(); | 481 const EphemeralRange selectedRange = selection.selection().toNormalizedEphem eralRange(); |
| 482 | 482 |
| 483 ContainerNode* parentNode = n->parentNode(); | 483 ContainerNode* parentNode = n->parentNode(); |
| 484 if (!parentNode) | 484 if (!parentNode) |
| 485 return false; | 485 return false; |
| 486 | 486 |
| 487 const Position startPosition = selectedRange.startPosition().toOffsetInAncho r(); | 487 const Position startPosition = selectedRange.startPosition().toOffsetInAncho r(); |
| 488 const Position endPosition = selectedRange.endPosition().toOffsetInAnchor(); | 488 const Position endPosition = selectedRange.endPosition().toOffsetInAnchor(); |
| 489 TrackExceptionState exceptionState; | 489 TrackExceptionState exceptionState; |
| 490 bool nodeFullySelected = Range::compareBoundaryPoints(parentNode, nodeIndex, startPosition.computeContainerNode(), startPosition.offsetInContainerNode(), ex ceptionState) >= 0 && !exceptionState.hadException() | 490 bool nodeFullySelected = Range::compareBoundaryPoints(parentNode, nodeIndex, startPosition.computeContainerNode(), startPosition.offsetInContainerNode(), ex ceptionState) >= 0 && !exceptionState.hadException() |
| 491 && Range::compareBoundaryPoints(parentNode, nodeIndex + 1, endPosition.c omputeContainerNode(), endPosition.offsetInContainerNode(), exceptionState) <= 0 && !exceptionState.hadException(); | 491 && Range::compareBoundaryPoints(parentNode, nodeIndex + 1, endPosition.c omputeContainerNode(), endPosition.offsetInContainerNode(), exceptionState) <= 0 && !exceptionState.hadException(); |
| 492 if (exceptionState.hadException()) | 492 if (exceptionState.hadException()) |
| 493 return false; | 493 return false; |
| 494 if (nodeFullySelected) | 494 if (nodeFullySelected) |
| 495 return true; | 495 return true; |
| 496 | 496 |
| 497 bool nodeFullyUnselected = (Range::compareBoundaryPoints(parentNode, nodeInd ex, endPosition.computeContainerNode(), endPosition.offsetInContainerNode(), exc eptionState) > 0 && !exceptionState.hadException()) | 497 bool nodeFullyUnselected = (Range::compareBoundaryPoints(parentNode, nodeInd ex, endPosition.computeContainerNode(), endPosition.offsetInContainerNode(), exc eptionState) > 0 && !exceptionState.hadException()) |
| 498 || (Range::compareBoundaryPoints(parentNode, nodeIndex + 1, startPositio n.computeContainerNode(), startPosition.offsetInContainerNode(), exceptionState) < 0 && !exceptionState.hadException()); | 498 || (Range::compareBoundaryPoints(parentNode, nodeIndex + 1, startPositio n.computeContainerNode(), startPosition.offsetInContainerNode(), exceptionState) < 0 && !exceptionState.hadException()); |
| 499 ASSERT(!exceptionState.hadException()); | 499 DCHECK(!exceptionState.hadException()); |
| 500 if (nodeFullyUnselected) | 500 if (nodeFullyUnselected) |
| 501 return false; | 501 return false; |
| 502 | 502 |
| 503 return allowPartial || n->isTextNode(); | 503 return allowPartial || n->isTextNode(); |
| 504 } | 504 } |
| 505 | 505 |
| 506 void DOMSelection::selectAllChildren(Node* n, ExceptionState& exceptionState) | 506 void DOMSelection::selectAllChildren(Node* n, ExceptionState& exceptionState) |
| 507 { | 507 { |
| 508 ASSERT(n); | 508 DCHECK(n); |
| 509 | 509 |
| 510 // This doesn't (and shouldn't) select text node characters. | 510 // This doesn't (and shouldn't) select text node characters. |
| 511 setBaseAndExtent(n, 0, n, n->countChildren(), exceptionState); | 511 setBaseAndExtent(n, 0, n, n->countChildren(), exceptionState); |
| 512 } | 512 } |
| 513 | 513 |
| 514 String DOMSelection::toString() | 514 String DOMSelection::toString() |
| 515 { | 515 { |
| 516 if (!m_frame) | 516 if (!m_frame) |
| 517 return String(); | 517 return String(); |
| 518 | 518 |
| 519 const EphemeralRange range = m_frame->selection().selection().toNormalizedEp hemeralRange(); | 519 const EphemeralRange range = m_frame->selection().selection().toNormalizedEp hemeralRange(); |
| 520 return plainText(range, TextIteratorForSelectionToString); | 520 return plainText(range, TextIteratorForSelectionToString); |
| 521 } | 521 } |
| 522 | 522 |
| 523 Node* DOMSelection::shadowAdjustedNode(const Position& position) const | 523 Node* DOMSelection::shadowAdjustedNode(const Position& position) const |
| 524 { | 524 { |
| 525 if (position.isNull()) | 525 if (position.isNull()) |
| 526 return 0; | 526 return 0; |
| 527 | 527 |
| 528 Node* containerNode = position.computeContainerNode(); | 528 Node* containerNode = position.computeContainerNode(); |
| 529 Node* adjustedNode = m_treeScope->ancestorInThisScope(containerNode); | 529 Node* adjustedNode = m_treeScope->ancestorInThisScope(containerNode); |
| 530 | 530 |
| 531 if (!adjustedNode) | 531 if (!adjustedNode) |
| 532 return 0; | 532 return 0; |
| 533 | 533 |
| 534 if (containerNode == adjustedNode) | 534 if (containerNode == adjustedNode) |
| 535 return containerNode; | 535 return containerNode; |
| 536 | 536 |
| 537 ASSERT(!adjustedNode->isShadowRoot()); | 537 DCHECK(!adjustedNode->isShadowRoot()); |
|
yosin_UTC9
2016/04/14 04:34:59
How about adding |adjustedNode|?
| |
| 538 return adjustedNode->parentOrShadowHostNode(); | 538 return adjustedNode->parentOrShadowHostNode(); |
| 539 } | 539 } |
| 540 | 540 |
| 541 int DOMSelection::shadowAdjustedOffset(const Position& position) const | 541 int DOMSelection::shadowAdjustedOffset(const Position& position) const |
| 542 { | 542 { |
| 543 if (position.isNull()) | 543 if (position.isNull()) |
| 544 return 0; | 544 return 0; |
| 545 | 545 |
| 546 Node* containerNode = position.computeContainerNode(); | 546 Node* containerNode = position.computeContainerNode(); |
| 547 Node* adjustedNode = m_treeScope->ancestorInThisScope(containerNode); | 547 Node* adjustedNode = m_treeScope->ancestorInThisScope(containerNode); |
| 548 | 548 |
| 549 if (!adjustedNode) | 549 if (!adjustedNode) |
| 550 return 0; | 550 return 0; |
| 551 | 551 |
| 552 if (containerNode == adjustedNode) | 552 if (containerNode == adjustedNode) |
| 553 return position.computeOffsetInContainerNode(); | 553 return position.computeOffsetInContainerNode(); |
| 554 | 554 |
| 555 return adjustedNode->nodeIndex(); | 555 return adjustedNode->nodeIndex(); |
| 556 } | 556 } |
| 557 | 557 |
| 558 bool DOMSelection::isValidForPosition(Node* node) const | 558 bool DOMSelection::isValidForPosition(Node* node) const |
| 559 { | 559 { |
| 560 ASSERT(m_frame); | 560 DCHECK(m_frame); |
| 561 if (!node) | 561 if (!node) |
| 562 return true; | 562 return true; |
| 563 return node->document() == m_frame->document(); | 563 return node->document() == m_frame->document(); |
| 564 } | 564 } |
| 565 | 565 |
| 566 void DOMSelection::addConsoleError(const String& message) | 566 void DOMSelection::addConsoleError(const String& message) |
| 567 { | 567 { |
| 568 if (m_treeScope) | 568 if (m_treeScope) |
| 569 m_treeScope->document().addConsoleMessage(ConsoleMessage::create(JSMessa geSource, ErrorMessageLevel, message)); | 569 m_treeScope->document().addConsoleMessage(ConsoleMessage::create(JSMessa geSource, ErrorMessageLevel, message)); |
| 570 } | 570 } |
| 571 | 571 |
| 572 DEFINE_TRACE(DOMSelection) | 572 DEFINE_TRACE(DOMSelection) |
| 573 { | 573 { |
| 574 visitor->trace(m_treeScope); | 574 visitor->trace(m_treeScope); |
| 575 DOMWindowProperty::trace(visitor); | 575 DOMWindowProperty::trace(visitor); |
| 576 } | 576 } |
| 577 | 577 |
| 578 } // namespace blink | 578 } // namespace blink |
| OLD | NEW |