Chromium Code Reviews| Index: Source/core/editing/DOMSelection.cpp |
| diff --git a/Source/core/editing/DOMSelection.cpp b/Source/core/editing/DOMSelection.cpp |
| index 25703e256911f5e5673ad5af24a39089b115e0d4..68c179e483e99cb44546c3f902c536b73c489cd6 100644 |
| --- a/Source/core/editing/DOMSelection.cpp |
| +++ b/Source/core/editing/DOMSelection.cpp |
| @@ -48,18 +48,6 @@ |
| namespace blink { |
| -static Node* selectionShadowAncestor(LocalFrame* frame) |
| -{ |
| - Node* node = frame->selection().selection().base().anchorNode(); |
| - if (!node) |
| - return 0; |
| - |
| - if (!node->isInShadowTree()) |
| - return 0; |
| - |
| - return frame->document()->ancestorInThisScope(node); |
| -} |
| - |
| DOMSelection::DOMSelection(const TreeScope* treeScope) |
| : DOMWindowProperty(treeScope->rootNode().document().frame()) |
| , m_treeScope(treeScope) |
| @@ -77,6 +65,17 @@ const VisibleSelection& DOMSelection::visibleSelection() const |
| return m_frame->selection().selection(); |
| } |
| +bool DOMSelection::isInShadowTree() const |
| +{ |
| + ASSERT(m_frame); |
| + const VisibleSelection& selection = visibleSelection(); |
| + if (selection.start().anchorNode() && selection.start().anchorNode()->isInShadowTree()) { |
| + ASSERT(selection.end().anchorNode() && selection.end().anchorNode()->isInShadowTree()); |
| + return true; |
| + } |
| + return false; |
| +} |
| + |
| static Position anchorPosition(const VisibleSelection& selection) |
| { |
| Position anchor = selection.isBaseFirst() ? selection.start() : selection.end(); |
| @@ -165,9 +164,22 @@ int DOMSelection::extentOffset() const |
| bool DOMSelection::isCollapsed() const |
| { |
| - if (!m_frame || selectionShadowAncestor(m_frame)) |
| + if (!m_frame) |
| + return false; |
| + |
| + 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.
|
| + if (selection.isNone()) |
| return true; |
| - return !m_frame->selection().isRange(); |
| + |
| + if (isInShadowTree()) { |
| + Position anchor = anchorPosition(selection.selection()); |
| + ASSERT(anchor.anchorNode() && anchor.anchorNode()->isInShadowTree()); |
| + Position focus = focusPosition(selection.selection()); |
| + ASSERT(focus.anchorNode() && focus.anchorNode()->isInShadowTree()); |
| + return shadowAdjustedPosition(anchor) == shadowAdjustedPosition(focus); |
| + } |
| + |
| + return !selection.isRange(); |
| } |
| String DOMSelection::type() const |
| @@ -369,11 +381,12 @@ PassRefPtrWillBeRawPtr<Range> DOMSelection::getRangeAt(int index, ExceptionState |
| // If you're hitting this, you've added broken multi-range selection support |
| ASSERT(rangeCount() == 1); |
| - if (Node* shadowAncestor = selectionShadowAncestor(m_frame)) { |
| - ASSERT(!shadowAncestor->isShadowRoot()); |
| - ContainerNode* container = shadowAncestor->parentOrShadowHostNode(); |
| - int offset = shadowAncestor->nodeIndex(); |
| - return Range::create(shadowAncestor->document(), container, offset, container, offset); |
| + 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.
|
| + ASSERT(anchor.anchorNode()); |
| + if (anchor.anchorNode()->isInShadowTree()) { |
| + Position focus = focusPosition(visibleSelection()); |
| + ASSERT(focus.anchorNode() && focus.anchorNode()->isInShadowTree()); |
| + return Range::create(*anchor.document(), shadowAdjustedPosition(anchor), shadowAdjustedPosition(focus)); |
| } |
| return m_frame->selection().firstRange(); |
| @@ -510,6 +523,24 @@ String DOMSelection::toString() |
| return emptyString(); |
| } |
| +Position DOMSelection::shadowAdjustedPosition(const Position& position) const |
| +{ |
| + if (position.isNull()) |
| + return position; |
| + |
| + Node* containerNode = position.containerNode(); |
| + Node* adjustedNode = m_treeScope->ancestorInThisScope(containerNode); |
| + |
| + if (!adjustedNode) |
| + return Position(); |
| + |
| + if (containerNode == adjustedNode) |
| + return Position(containerNode, position.computeOffsetInContainerNode(), Position::PositionIsOffsetInAnchor); |
| + |
| + ASSERT(!adjustedNode->isShadowRoot()); |
| + return Position(adjustedNode->parentOrShadowHostNode(), adjustedNode->nodeIndex(), Position::PositionIsOffsetInAnchor); |
| +} |
| + |
| Node* DOMSelection::shadowAdjustedNode(const Position& position) const |
| { |
| if (position.isNull()) |