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 |