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

Side by Side Diff: third_party/WebKit/Source/core/editing/DOMSelection.cpp

Issue 2694043004: Selection API: anchorNode, anchorOffset, focusNode, focusOffset, isCollapsed, and type should be ba… (Closed)
Patch Set: . 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 * 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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698