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 30 matching lines...) Expand all Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |