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 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 88 | 88 |
| 89 static Position basePosition(const VisibleSelection& selection) { | 89 static Position basePosition(const VisibleSelection& selection) { |
| 90 return selection.base().parentAnchoredEquivalent(); | 90 return selection.base().parentAnchoredEquivalent(); |
| 91 } | 91 } |
| 92 | 92 |
| 93 static Position extentPosition(const VisibleSelection& selection) { | 93 static Position extentPosition(const VisibleSelection& selection) { |
| 94 return selection.extent().parentAnchoredEquivalent(); | 94 return selection.extent().parentAnchoredEquivalent(); |
| 95 } | 95 } |
| 96 | 96 |
| 97 Node* DOMSelection::anchorNode() const { | 97 Node* DOMSelection::anchorNode() const { |
| 98 if (!isAvailable()) | 98 if (Range* range = primaryRangeOrNull()) { |
| 99 return 0; | 99 if (!frame() || visibleSelection().isBaseFirst()) |
| 100 | 100 return range->startContainer(); |
| 101 return shadowAdjustedNode(anchorPosition(visibleSelection())); | 101 return range->endContainer(); |
| 102 } | |
| 103 return nullptr; | |
| 102 } | 104 } |
| 103 | 105 |
| 104 int DOMSelection::anchorOffset() const { | 106 int DOMSelection::anchorOffset() const { |
| 105 if (!isAvailable()) | 107 if (Range* range = primaryRangeOrNull()) { |
| 106 return 0; | 108 if (!frame() || visibleSelection().isBaseFirst()) |
| 107 | 109 return range->startOffset(); |
| 108 return shadowAdjustedOffset(anchorPosition(visibleSelection())); | 110 return range->endOffset(); |
| 111 } | |
| 112 return 0; | |
| 109 } | 113 } |
| 110 | 114 |
| 111 Node* DOMSelection::focusNode() const { | 115 Node* DOMSelection::focusNode() const { |
| 112 if (!isAvailable()) | 116 if (Range* range = primaryRangeOrNull()) { |
| 113 return 0; | 117 if (!frame() || visibleSelection().isBaseFirst()) |
| 114 | 118 return range->endContainer(); |
| 115 return shadowAdjustedNode(focusPosition(visibleSelection())); | 119 return range->startContainer(); |
| 120 } | |
| 121 return nullptr; | |
| 116 } | 122 } |
| 117 | 123 |
| 118 int DOMSelection::focusOffset() const { | 124 int DOMSelection::focusOffset() const { |
| 119 if (!isAvailable()) | 125 if (Range* range = primaryRangeOrNull()) { |
| 120 return 0; | 126 if (!frame() || visibleSelection().isBaseFirst()) |
| 121 | 127 return range->endOffset(); |
| 122 return shadowAdjustedOffset(focusPosition(visibleSelection())); | 128 return range->startOffset(); |
| 129 } | |
| 130 return 0; | |
| 123 } | 131 } |
| 124 | 132 |
| 125 Node* DOMSelection::baseNode() const { | 133 Node* DOMSelection::baseNode() const { |
| 126 if (!isAvailable()) | 134 if (!isAvailable()) |
| 127 return 0; | 135 return 0; |
| 128 | 136 |
| 129 return shadowAdjustedNode(basePosition(visibleSelection())); | 137 return shadowAdjustedNode(basePosition(visibleSelection())); |
| 130 } | 138 } |
| 131 | 139 |
| 132 int DOMSelection::baseOffset() const { | 140 int DOMSelection::baseOffset() const { |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 146 int DOMSelection::extentOffset() const { | 154 int DOMSelection::extentOffset() const { |
| 147 if (!isAvailable()) | 155 if (!isAvailable()) |
| 148 return 0; | 156 return 0; |
| 149 | 157 |
| 150 return shadowAdjustedOffset(extentPosition(visibleSelection())); | 158 return shadowAdjustedOffset(extentPosition(visibleSelection())); |
| 151 } | 159 } |
| 152 | 160 |
| 153 bool DOMSelection::isCollapsed() const { | 161 bool DOMSelection::isCollapsed() const { |
| 154 if (!isAvailable() || selectionShadowAncestor(frame())) | 162 if (!isAvailable() || selectionShadowAncestor(frame())) |
| 155 return true; | 163 return true; |
| 156 return !frame()->selection().isRange(); | 164 if (Range* range = primaryRangeOrNull()) |
| 165 return range->collapsed(); | |
| 166 return true; | |
| 157 } | 167 } |
| 158 | 168 |
| 159 String DOMSelection::type() const { | 169 String DOMSelection::type() const { |
| 160 if (!isAvailable()) | 170 if (!isAvailable()) |
| 161 return String(); | 171 return String(); |
| 162 | |
| 163 FrameSelection& selection = frame()->selection(); | |
| 164 | |
| 165 // This is a WebKit DOM extension, incompatible with an IE extension | 172 // This is a WebKit DOM extension, incompatible with an IE extension |
| 166 // IE has this same attribute, but returns "none", "text" and "control" | 173 // IE has this same attribute, but returns "none", "text" and "control" |
| 167 // http://msdn.microsoft.com/en-us/library/ms534692(VS.85).aspx | 174 // http://msdn.microsoft.com/en-us/library/ms534692(VS.85).aspx |
| 168 if (selection.isNone()) | 175 if (rangeCount() == 0) |
| 169 return "None"; | 176 return "None"; |
| 170 if (selection.isCaret()) | 177 if (isCollapsed()) |
| 171 return "Caret"; | 178 return "Caret"; |
| 172 return "Range"; | 179 return "Range"; |
| 173 } | 180 } |
| 174 | 181 |
| 175 int DOMSelection::rangeCount() const { | 182 int DOMSelection::rangeCount() const { |
| 176 if (!isAvailable()) | 183 if (!isAvailable()) |
| 177 return 0; | 184 return 0; |
| 178 if (documentCachedRange()) | 185 if (documentCachedRange()) |
| 179 return 1; | 186 return 1; |
| 180 return frame()->selection().isNone() ? 0 : 1; | 187 return frame()->selection().isNone() ? 0 : 1; |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 407 .build()); | 414 .build()); |
| 408 return; | 415 return; |
| 409 } | 416 } |
| 410 frame()->selection().setSelection(SelectionInDOMTree::Builder() | 417 frame()->selection().setSelection(SelectionInDOMTree::Builder() |
| 411 .collapse(base) | 418 .collapse(base) |
| 412 .extend(Position(node, offset)) | 419 .extend(Position(node, offset)) |
| 413 .setIsDirectional(true) | 420 .setIsDirectional(true) |
| 414 .build()); | 421 .build()); |
| 415 } | 422 } |
| 416 | 423 |
| 417 Range* DOMSelection::getRangeAt(int index, ExceptionState& exceptionState) { | 424 Range* DOMSelection::getRangeAt(int index, |
| 425 ExceptionState& exceptionState) const { | |
| 418 if (!isAvailable()) | 426 if (!isAvailable()) |
| 419 return nullptr; | 427 return nullptr; |
| 420 | 428 |
| 421 if (index < 0 || index >= rangeCount()) { | 429 if (index < 0 || index >= rangeCount()) { |
| 422 exceptionState.throwDOMException( | 430 exceptionState.throwDOMException( |
| 423 IndexSizeError, String::number(index) + " is not a valid index."); | 431 IndexSizeError, String::number(index) + " is not a valid index."); |
| 424 return nullptr; | 432 return nullptr; |
| 425 } | 433 } |
| 426 | 434 |
| 427 // If you're hitting this, you've added broken multi-range selection support | 435 // If you're hitting this, you've added broken multi-range selection support |
| 428 DCHECK_EQ(rangeCount(), 1); | 436 DCHECK_EQ(rangeCount(), 1); |
| 429 | 437 |
| 430 if (Range* cachedRange = documentCachedRange()) | 438 if (Range* cachedRange = documentCachedRange()) |
| 431 return cachedRange; | 439 return cachedRange; |
| 432 | 440 |
| 433 Range* range = createRangeFromSelectionEditor(); | 441 Range* range = createRangeFromSelectionEditor(); |
| 434 cacheRangeIfSelectionOfDocument(range); | 442 cacheRangeIfSelectionOfDocument(range); |
| 435 return range; | 443 return range; |
| 436 } | 444 } |
| 437 | 445 |
| 438 Range* DOMSelection::createRangeFromSelectionEditor() { | 446 Range* DOMSelection::primaryRangeOrNull() const { |
|
yosin_UTC9
2017/02/14 04:52:21
Thanks for better name! (^_^)b
| |
| 447 return rangeCount() > 0 ? getRangeAt(0, ASSERT_NO_EXCEPTION) : nullptr; | |
| 448 } | |
| 449 | |
| 450 Range* DOMSelection::createRangeFromSelectionEditor() const { | |
| 439 Position anchor = anchorPosition(visibleSelection()); | 451 Position anchor = anchorPosition(visibleSelection()); |
| 440 if (!anchor.anchorNode()->isInShadowTree()) | 452 if (isSelectionOfDocument() && !anchor.anchorNode()->isInShadowTree()) |
| 441 return frame()->selection().firstRange(); | 453 return frame()->selection().firstRange(); |
| 442 | 454 |
| 443 Node* node = shadowAdjustedNode(anchor); | 455 Node* node = shadowAdjustedNode(anchor); |
| 444 if (!node) // crbug.com/595100 | 456 if (!node) // crbug.com/595100 |
| 445 return nullptr; | 457 return nullptr; |
| 446 if (!visibleSelection().isBaseFirst()) | 458 Position focus = focusPosition(visibleSelection()); |
|
yosin_UTC9
2017/02/14 04:52:21
nit: s/Position/const Position&/
| |
| 447 return Range::create(*anchor.document(), focusNode(), focusOffset(), node, | 459 if (!visibleSelection().isBaseFirst()) { |
| 448 anchorOffset()); | 460 return Range::create(*anchor.document(), shadowAdjustedNode(focus), |
| 449 return Range::create(*anchor.document(), node, anchorOffset(), focusNode(), | 461 shadowAdjustedOffset(focus), node, |
| 450 focusOffset()); | 462 shadowAdjustedOffset(anchor)); |
| 463 } | |
| 464 return Range::create(*anchor.document(), node, shadowAdjustedOffset(anchor), | |
| 465 shadowAdjustedNode(focus), shadowAdjustedOffset(focus)); | |
| 451 } | 466 } |
| 452 | 467 |
| 453 bool DOMSelection::isSelectionOfDocument() const { | 468 bool DOMSelection::isSelectionOfDocument() const { |
| 454 return m_treeScope == m_treeScope->document(); | 469 return m_treeScope == m_treeScope->document(); |
| 455 } | 470 } |
| 456 | 471 |
| 457 void DOMSelection::cacheRangeIfSelectionOfDocument(Range* range) { | 472 void DOMSelection::cacheRangeIfSelectionOfDocument(Range* range) const { |
| 458 if (!isSelectionOfDocument()) | 473 if (!isSelectionOfDocument()) |
| 459 return; | 474 return; |
| 460 frame()->selection().cacheRangeOfDocument(range); | 475 frame()->selection().cacheRangeOfDocument(range); |
| 461 } | 476 } |
| 462 | 477 |
| 463 Range* DOMSelection::documentCachedRange() const { | 478 Range* DOMSelection::documentCachedRange() const { |
| 464 if (!isSelectionOfDocument()) | 479 if (!isSelectionOfDocument()) |
| 465 return nullptr; | 480 return nullptr; |
| 466 return frame()->selection().documentCachedRange(); | 481 return frame()->selection().documentCachedRange(); |
| 467 } | 482 } |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 715 m_treeScope->document().addConsoleMessage( | 730 m_treeScope->document().addConsoleMessage( |
| 716 ConsoleMessage::create(JSMessageSource, ErrorMessageLevel, message)); | 731 ConsoleMessage::create(JSMessageSource, ErrorMessageLevel, message)); |
| 717 } | 732 } |
| 718 | 733 |
| 719 DEFINE_TRACE(DOMSelection) { | 734 DEFINE_TRACE(DOMSelection) { |
| 720 visitor->trace(m_treeScope); | 735 visitor->trace(m_treeScope); |
| 721 ContextClient::trace(visitor); | 736 ContextClient::trace(visitor); |
| 722 } | 737 } |
| 723 | 738 |
| 724 } // namespace blink | 739 } // namespace blink |
| OLD | NEW |