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

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

Issue 800633004: ShadowRoot's getSelection().getRangeAt(0) returns an incorrect Range object (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 5 years, 11 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 30 matching lines...) Expand all
41 #include "core/dom/TreeScope.h" 41 #include "core/dom/TreeScope.h"
42 #include "core/editing/FrameSelection.h" 42 #include "core/editing/FrameSelection.h"
43 #include "core/editing/TextIterator.h" 43 #include "core/editing/TextIterator.h"
44 #include "core/editing/htmlediting.h" 44 #include "core/editing/htmlediting.h"
45 #include "core/frame/LocalFrame.h" 45 #include "core/frame/LocalFrame.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 Node* selectionShadowAncestor(LocalFrame* frame)
52 {
53 Node* node = frame->selection().selection().base().anchorNode();
54 if (!node)
55 return 0;
56
57 if (!node->isInShadowTree())
58 return 0;
59
60 return frame->document()->ancestorInThisScope(node);
61 }
62
63 DOMSelection::DOMSelection(const TreeScope* treeScope) 51 DOMSelection::DOMSelection(const TreeScope* treeScope)
64 : DOMWindowProperty(treeScope->rootNode().document().frame()) 52 : DOMWindowProperty(treeScope->rootNode().document().frame())
65 , m_treeScope(treeScope) 53 , m_treeScope(treeScope)
66 { 54 {
67 } 55 }
68 56
69 void DOMSelection::clearTreeScope() 57 void DOMSelection::clearTreeScope()
70 { 58 {
71 m_treeScope = nullptr; 59 m_treeScope = nullptr;
72 } 60 }
73 61
74 const VisibleSelection& DOMSelection::visibleSelection() const 62 const VisibleSelection& DOMSelection::visibleSelection() const
75 { 63 {
76 ASSERT(m_frame); 64 ASSERT(m_frame);
77 return m_frame->selection().selection(); 65 return m_frame->selection().selection();
78 } 66 }
79 67
68 bool DOMSelection::isInShadowTree() const
69 {
70 ASSERT(m_frame);
71 const VisibleSelection& selection = visibleSelection();
72 if (selection.start().anchorNode() && selection.start().anchorNode()->isInSh adowTree()) {
73 ASSERT(selection.end().anchorNode() && selection.end().anchorNode()->isI nShadowTree());
74 return true;
75 }
76 return false;
77 }
78
80 static Position anchorPosition(const VisibleSelection& selection) 79 static Position anchorPosition(const VisibleSelection& selection)
81 { 80 {
82 Position anchor = selection.isBaseFirst() ? selection.start() : selection.en d(); 81 Position anchor = selection.isBaseFirst() ? selection.start() : selection.en d();
83 return anchor.parentAnchoredEquivalent(); 82 return anchor.parentAnchoredEquivalent();
84 } 83 }
85 84
86 static Position focusPosition(const VisibleSelection& selection) 85 static Position focusPosition(const VisibleSelection& selection)
87 { 86 {
88 Position focus = selection.isBaseFirst() ? selection.end() : selection.start (); 87 Position focus = selection.isBaseFirst() ? selection.end() : selection.start ();
89 return focus.parentAnchoredEquivalent(); 88 return focus.parentAnchoredEquivalent();
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 int DOMSelection::extentOffset() const 157 int DOMSelection::extentOffset() const
159 { 158 {
160 if (!m_frame) 159 if (!m_frame)
161 return 0; 160 return 0;
162 161
163 return shadowAdjustedOffset(extentPosition(visibleSelection())); 162 return shadowAdjustedOffset(extentPosition(visibleSelection()));
164 } 163 }
165 164
166 bool DOMSelection::isCollapsed() const 165 bool DOMSelection::isCollapsed() const
167 { 166 {
168 if (!m_frame || selectionShadowAncestor(m_frame)) 167 if (!m_frame)
168 return false;
169
170 FrameSelection& selection = m_frame->selection();
yosin_UTC9 2015/01/06 08:39:37 I think |isCollapsed()| should be |return anchorNo
kojii 2015/01/07 06:53:52 Done.
171 if (selection.isNone())
169 return true; 172 return true;
170 return !m_frame->selection().isRange(); 173
174 if (isInShadowTree()) {
175 Position anchor = anchorPosition(selection.selection());
176 ASSERT(anchor.anchorNode() && anchor.anchorNode()->isInShadowTree());
177 Position focus = focusPosition(selection.selection());
178 ASSERT(focus.anchorNode() && focus.anchorNode()->isInShadowTree());
179 return shadowAdjustedPosition(anchor) == shadowAdjustedPosition(focus);
180 }
181
182 return !selection.isRange();
171 } 183 }
172 184
173 String DOMSelection::type() const 185 String DOMSelection::type() const
174 { 186 {
175 if (!m_frame) 187 if (!m_frame)
176 return String(); 188 return String();
177 189
178 FrameSelection& selection = m_frame->selection(); 190 FrameSelection& selection = m_frame->selection();
179 191
180 // This is a WebKit DOM extension, incompatible with an IE extension 192 // This is a WebKit DOM extension, incompatible with an IE extension
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
362 return nullptr; 374 return nullptr;
363 375
364 if (index < 0 || index >= rangeCount()) { 376 if (index < 0 || index >= rangeCount()) {
365 exceptionState.throwDOMException(IndexSizeError, String::number(index) + " is not a valid index."); 377 exceptionState.throwDOMException(IndexSizeError, String::number(index) + " is not a valid index.");
366 return nullptr; 378 return nullptr;
367 } 379 }
368 380
369 // If you're hitting this, you've added broken multi-range selection support 381 // If you're hitting this, you've added broken multi-range selection support
370 ASSERT(rangeCount() == 1); 382 ASSERT(rangeCount() == 1);
371 383
372 if (Node* shadowAncestor = selectionShadowAncestor(m_frame)) { 384 Position anchor = anchorPosition(visibleSelection());
yosin_UTC9 2015/01/06 08:39:37 I think we can implement as below: if (!isShadowRo
kojii 2015/01/07 06:53:52 Done.
373 ASSERT(!shadowAncestor->isShadowRoot()); 385 ASSERT(anchor.anchorNode());
374 ContainerNode* container = shadowAncestor->parentOrShadowHostNode(); 386 if (anchor.anchorNode()->isInShadowTree()) {
375 int offset = shadowAncestor->nodeIndex(); 387 Position focus = focusPosition(visibleSelection());
376 return Range::create(shadowAncestor->document(), container, offset, cont ainer, offset); 388 ASSERT(focus.anchorNode() && focus.anchorNode()->isInShadowTree());
389 return Range::create(*anchor.document(), shadowAdjustedPosition(anchor), shadowAdjustedPosition(focus));
377 } 390 }
378 391
379 return m_frame->selection().firstRange(); 392 return m_frame->selection().firstRange();
380 } 393 }
381 394
382 void DOMSelection::removeAllRanges() 395 void DOMSelection::removeAllRanges()
383 { 396 {
384 if (!m_frame) 397 if (!m_frame)
385 return; 398 return;
386 m_frame->selection().clear(); 399 m_frame->selection().clear();
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
503 { 516 {
504 if (!m_frame) 517 if (!m_frame)
505 return String(); 518 return String();
506 519
507 Position start, end; 520 Position start, end;
508 if (m_frame->selection().selection().toNormalizedPositions(start, end)) 521 if (m_frame->selection().selection().toNormalizedPositions(start, end))
509 return plainText(start, end); 522 return plainText(start, end);
510 return emptyString(); 523 return emptyString();
511 } 524 }
512 525
526 Position DOMSelection::shadowAdjustedPosition(const Position& position) const
527 {
528 if (position.isNull())
529 return position;
530
531 Node* containerNode = position.containerNode();
532 Node* adjustedNode = m_treeScope->ancestorInThisScope(containerNode);
533
534 if (!adjustedNode)
535 return Position();
536
537 if (containerNode == adjustedNode)
538 return Position(containerNode, position.computeOffsetInContainerNode(), Position::PositionIsOffsetInAnchor);
539
540 ASSERT(!adjustedNode->isShadowRoot());
541 return Position(adjustedNode->parentOrShadowHostNode(), adjustedNode->nodeIn dex(), Position::PositionIsOffsetInAnchor);
542 }
543
513 Node* DOMSelection::shadowAdjustedNode(const Position& position) const 544 Node* DOMSelection::shadowAdjustedNode(const Position& position) const
514 { 545 {
515 if (position.isNull()) 546 if (position.isNull())
516 return 0; 547 return 0;
517 548
518 Node* containerNode = position.containerNode(); 549 Node* containerNode = position.containerNode();
519 Node* adjustedNode = m_treeScope->ancestorInThisScope(containerNode); 550 Node* adjustedNode = m_treeScope->ancestorInThisScope(containerNode);
520 551
521 if (!adjustedNode) 552 if (!adjustedNode)
522 return 0; 553 return 0;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
559 m_treeScope->document().addConsoleMessage(ConsoleMessage::create(JSMessa geSource, ErrorMessageLevel, message)); 590 m_treeScope->document().addConsoleMessage(ConsoleMessage::create(JSMessa geSource, ErrorMessageLevel, message));
560 } 591 }
561 592
562 void DOMSelection::trace(Visitor* visitor) 593 void DOMSelection::trace(Visitor* visitor)
563 { 594 {
564 visitor->trace(m_treeScope); 595 visitor->trace(m_treeScope);
565 DOMWindowProperty::trace(visitor); 596 DOMWindowProperty::trace(visitor);
566 } 597 }
567 598
568 } // namespace blink 599 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698