Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2009 Apple Inc. All rights reserved. | 2 * Copyright (C) 2009 Apple Inc. All rights reserved. |
| 3 * Copyright (C) 2011 Google Inc. All rights reserved. | 3 * Copyright (C) 2011 Google Inc. All rights reserved. |
| 4 * Copyright (C) 2009 Joseph Pecoraro | 4 * Copyright (C) 2009 Joseph Pecoraro |
| 5 * | 5 * |
| 6 * Redistribution and use in source and binary forms, with or without | 6 * Redistribution and use in source and binary forms, with or without |
| 7 * modification, are permitted provided that the following conditions | 7 * modification, are permitted provided that the following conditions |
| 8 * are met: | 8 * are met: |
| 9 * | 9 * |
| 10 * 1. Redistributions of source code must retain the above copyright | 10 * 1. Redistributions of source code must retain the above copyright |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
| 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 29 */ | 29 */ |
| 30 | 30 |
| 31 #include "core/inspector/InspectorDOMAgent.h" | 31 #include "core/inspector/InspectorDOMAgent.h" |
| 32 | 32 |
| 33 #include "bindings/core/v8/BindingSecurity.h" | 33 #include "bindings/core/v8/BindingSecurity.h" |
| 34 #include "bindings/core/v8/ExceptionState.h" | 34 #include "bindings/core/v8/ExceptionState.h" |
| 35 #include "bindings/core/v8/V8Node.h" | 35 #include "bindings/core/v8/V8Node.h" |
| 36 #include "core/InputTypeNames.h" | 36 #include "core/InputTypeNames.h" |
| 37 #include "core/css/CSSComputedStyleDeclaration.h" | |
| 38 #include "core/css/CSSVariableData.h" | |
| 37 #include "core/dom/Attr.h" | 39 #include "core/dom/Attr.h" |
| 38 #include "core/dom/CharacterData.h" | 40 #include "core/dom/CharacterData.h" |
| 39 #include "core/dom/ContainerNode.h" | 41 #include "core/dom/ContainerNode.h" |
| 40 #include "core/dom/DOMException.h" | 42 #include "core/dom/DOMException.h" |
| 41 #include "core/dom/DOMNodeIds.h" | 43 #include "core/dom/DOMNodeIds.h" |
| 42 #include "core/dom/Document.h" | 44 #include "core/dom/Document.h" |
| 43 #include "core/dom/DocumentFragment.h" | 45 #include "core/dom/DocumentFragment.h" |
| 44 #include "core/dom/DocumentType.h" | 46 #include "core/dom/DocumentType.h" |
| 45 #include "core/dom/Element.h" | 47 #include "core/dom/Element.h" |
| 46 #include "core/dom/Node.h" | 48 #include "core/dom/Node.h" |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 77 #include "core/xml/XPathResult.h" | 79 #include "core/xml/XPathResult.h" |
| 78 #include "platform/PlatformGestureEvent.h" | 80 #include "platform/PlatformGestureEvent.h" |
| 79 #include "platform/PlatformMouseEvent.h" | 81 #include "platform/PlatformMouseEvent.h" |
| 80 #include "platform/PlatformTouchEvent.h" | 82 #include "platform/PlatformTouchEvent.h" |
| 81 #include "wtf/ListHashSet.h" | 83 #include "wtf/ListHashSet.h" |
| 82 #include "wtf/PtrUtil.h" | 84 #include "wtf/PtrUtil.h" |
| 83 #include "wtf/text/CString.h" | 85 #include "wtf/text/CString.h" |
| 84 #include "wtf/text/WTFString.h" | 86 #include "wtf/text/WTFString.h" |
| 85 #include <memory> | 87 #include <memory> |
| 86 | 88 |
| 89 namespace std { | |
| 90 | |
| 91 using ComputedStyleArray = | |
| 92 std::vector<std::unique_ptr<blink::protocol::DOM::ComputedStyleProperty>>; | |
| 93 | |
| 94 template <> | |
| 95 struct equal_to<ComputedStyleArray> { | |
| 96 bool operator()(const ComputedStyleArray& a, | |
| 97 const ComputedStyleArray& b) const { | |
| 98 if (a.size() != b.size()) | |
| 99 return false; | |
| 100 for (size_t i = 0; i < a.size(); i++) { | |
| 101 if (a[i]->getName() != b[i]->getName() || | |
| 102 a[i]->getValue() != b[i]->getValue()) { | |
| 103 return false; | |
| 104 } | |
| 105 } | |
| 106 return true; | |
| 107 } | |
| 108 }; | |
| 109 | |
| 110 template <> | |
| 111 struct hash<ComputedStyleArray> { | |
| 112 using argument_type = ComputedStyleArray; | |
| 113 using result_type = size_t; | |
| 114 | |
| 115 static size_t computeHash( | |
| 116 const blink::protocol::DOM::ComputedStyleProperty* property) { | |
| 117 size_t h1 = DefaultHash<String>::Hash::hash(property->getName()); | |
| 118 size_t h2 = DefaultHash<String>::Hash::hash(property->getValue()); | |
| 119 return h1 ^ (h2 << 1); | |
| 120 } | |
| 121 | |
| 122 size_t operator()(const ComputedStyleArray& array) const { | |
| 123 if (array.size() == 0) | |
| 124 return 0; | |
| 125 size_t h = computeHash(array[0].get()); | |
| 126 for (size_t i = 1; i < array.size(); i++) { | |
| 127 size_t h2 = computeHash(array[i].get()); | |
| 128 h ^= (h2 << 1); | |
| 129 } | |
| 130 return h; | |
| 131 } | |
| 132 }; | |
| 133 } // namespace std | |
| 134 | |
| 87 namespace blink { | 135 namespace blink { |
| 88 | 136 |
| 89 using namespace HTMLNames; | 137 using namespace HTMLNames; |
| 90 | 138 |
| 91 namespace DOMAgentState { | 139 namespace DOMAgentState { |
| 92 static const char domAgentEnabled[] = "domAgentEnabled"; | 140 static const char domAgentEnabled[] = "domAgentEnabled"; |
| 93 }; | 141 }; |
| 94 | 142 |
| 95 namespace { | 143 namespace { |
| 96 | 144 |
| (...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 527 *errorString = "Document is not available"; | 575 *errorString = "Document is not available"; |
| 528 return; | 576 return; |
| 529 } | 577 } |
| 530 | 578 |
| 531 discardFrontendBindings(); | 579 discardFrontendBindings(); |
| 532 | 580 |
| 533 *root = buildObjectForNode(m_document.get(), 2, m_documentNodeToIdMap.get()); | 581 *root = buildObjectForNode(m_document.get(), 2, m_documentNodeToIdMap.get()); |
| 534 } | 582 } |
| 535 | 583 |
| 536 void InspectorDOMAgent::getLayoutTreeNodes( | 584 void InspectorDOMAgent::getLayoutTreeNodes( |
| 537 ErrorString* errorString, | 585 ErrorString* error_string, |
| 586 std::unique_ptr<protocol::Array<String>> style_whitelist, | |
| 538 std::unique_ptr<protocol::Array<protocol::DOM::LayoutTreeNode>>* | 587 std::unique_ptr<protocol::Array<protocol::DOM::LayoutTreeNode>>* |
| 539 layoutTreeNodes) { | 588 layout_tree_nodes, |
| 540 layoutTreeNodes->reset(new protocol::Array<protocol::DOM::LayoutTreeNode>); | 589 std::unique_ptr<protocol::Array<protocol::DOM::ComputedStyle>>* |
| 541 visitLayoutTreeNodes(m_document.get(), *layoutTreeNodes->get()); | 590 computed_styles) { |
| 591 m_document->updateStyleAndLayoutTree(); | |
| 592 | |
| 593 layout_tree_nodes->reset(new protocol::Array<protocol::DOM::LayoutTreeNode>); | |
| 594 ComputedStylesMap style_to_index_map; | |
| 595 visitLayoutTreeNodes(m_document.get(), *layout_tree_nodes->get(), | |
| 596 style_whitelist.get(), style_to_index_map); | |
| 597 | |
| 598 std::vector<std::unique_ptr<protocol::DOM::ComputedStyle>> styles( | |
| 599 style_to_index_map.size()); | |
| 600 for (ComputedStylesMap::value_type& pair : style_to_index_map) { | |
| 601 ComputedStyleArray& style = *const_cast<ComputedStyleArray*>(&pair.first); | |
| 602 using ProtocolStyleArray = | |
| 603 protocol::Array<blink::protocol::DOM::ComputedStyleProperty>; | |
| 604 styles[pair.second] = | |
| 605 protocol::DOM::ComputedStyle::create() | |
| 606 .setProperties(std::unique_ptr<ProtocolStyleArray>( | |
| 607 new ProtocolStyleArray(std::move(style)))) | |
| 608 .build(); | |
| 609 } | |
| 610 | |
| 611 computed_styles->reset( | |
| 612 new protocol::Array<protocol::DOM::ComputedStyle>(std::move(styles))); | |
|
dgozman
2016/10/12 21:00:40
Can just use addItem above, directly constructing
alex clarke (OOO till 29th)
2016/10/13 20:25:10
The problem with that is:
for (ComputedStylesMap::
| |
| 613 } | |
| 614 | |
| 615 int InspectorDOMAgent::getStyleIndexForNode( | |
| 616 Node* node, | |
| 617 protocol::Array<String>* style_whitelist, | |
| 618 ComputedStylesMap& style_to_index_map) { | |
| 619 CSSComputedStyleDeclaration* computed_style_info = | |
| 620 CSSComputedStyleDeclaration::create(node, true); | |
| 621 ComputedStyleArray style; | |
| 622 for (size_t i = 0; i < style_whitelist->length(); i++) { | |
| 623 CSSPropertyID property_id = cssPropertyID(style_whitelist->get(i)); | |
| 624 if (property_id == CSSPropertyInvalid) | |
| 625 continue; | |
| 626 style.push_back( | |
|
dgozman
2016/10/12 21:00:40
Since all the keys in all ComputedStyleArray insta
alex clarke (OOO till 29th)
2016/10/13 20:25:10
Right, in the spirit of that it seems simplest to
| |
| 627 protocol::DOM::ComputedStyleProperty::create() | |
| 628 .setName(style_whitelist->get(i)) | |
| 629 .setValue(computed_style_info->getPropertyValue(property_id)) | |
| 630 .build()); | |
| 631 } | |
| 632 | |
| 633 ComputedStylesMap::iterator it = style_to_index_map.find(style); | |
| 634 if (it != style_to_index_map.end()) | |
| 635 return it->second; | |
| 636 size_t index = style_to_index_map.size(); | |
| 637 style_to_index_map.insert(std::make_pair(std::move(style), index)); | |
| 638 return index; | |
| 542 } | 639 } |
| 543 | 640 |
| 544 void InspectorDOMAgent::visitLayoutTreeNodes( | 641 void InspectorDOMAgent::visitLayoutTreeNodes( |
| 545 Node* node, | 642 Node* node, |
| 546 protocol::Array<protocol::DOM::LayoutTreeNode>& layoutTreeNodes) { | 643 protocol::Array<protocol::DOM::LayoutTreeNode>& layout_tree_nodes, |
| 644 protocol::Array<String>* style_whitelist, | |
| 645 ComputedStylesMap& style_to_index_map) { | |
| 547 for (; node; node = NodeTraversal::next(*node)) { | 646 for (; node; node = NodeTraversal::next(*node)) { |
| 548 // Visit shadow dom nodes. | 647 // Visit shadow dom nodes. |
| 549 if (node->isElementNode()) { | 648 if (node->isElementNode()) { |
| 550 const Element* element = toElement(node); | 649 const Element* element = toElement(node); |
| 551 ElementShadow* elementShadow = element->shadow(); | 650 ElementShadow* elementShadow = element->shadow(); |
| 552 if (elementShadow) { | 651 if (elementShadow) { |
| 553 visitLayoutTreeNodes(&elementShadow->youngestShadowRoot(), | 652 visitLayoutTreeNodes(&elementShadow->youngestShadowRoot(), |
| 554 layoutTreeNodes); | 653 layout_tree_nodes, style_whitelist, |
| 654 style_to_index_map); | |
| 555 } | 655 } |
| 556 } | 656 } |
| 557 | 657 |
| 558 // Pierce iframe boundaries. | 658 // Pierce iframe boundaries. |
| 559 if (node->isFrameOwnerElement()) { | 659 if (node->isFrameOwnerElement()) { |
| 560 visitLayoutTreeNodes( | 660 Document* content_document = |
| 561 toHTMLFrameOwnerElement(node)->contentDocument()->documentElement(), | 661 toHTMLFrameOwnerElement(node)->contentDocument(); |
| 562 layoutTreeNodes); | 662 content_document->updateStyleAndLayoutTree(); |
| 663 visitLayoutTreeNodes(content_document->documentElement(), | |
| 664 layout_tree_nodes, style_whitelist, | |
| 665 style_to_index_map); | |
| 563 } | 666 } |
| 564 | 667 |
| 565 LayoutObject* layoutObject = node->layoutObject(); | 668 LayoutObject* layoutObject = node->layoutObject(); |
| 566 if (!layoutObject) | 669 if (!layoutObject) |
| 567 continue; | 670 continue; |
| 568 | 671 |
| 569 int backendNodeId = DOMNodeIds::idForNode(node); | 672 int backendNodeId = DOMNodeIds::idForNode(node); |
| 570 std::unique_ptr<protocol::DOM::LayoutTreeNode> layoutTreeNode = | 673 std::unique_ptr<protocol::DOM::LayoutTreeNode> layoutTreeNode = |
| 571 protocol::DOM::LayoutTreeNode::create() | 674 protocol::DOM::LayoutTreeNode::create() |
| 572 .setBackendNodeId(backendNodeId) | 675 .setBackendNodeId(backendNodeId) |
| 676 .setStyleIndex( | |
| 677 getStyleIndexForNode(node, style_whitelist, style_to_index_map)) | |
| 573 .setBoundingBox(buildRectForFloatRect( | 678 .setBoundingBox(buildRectForFloatRect( |
| 574 node->isElementNode() | 679 node->isElementNode() |
| 575 ? FloatRect(toElement(node)->boundsInViewport()) | 680 ? FloatRect(toElement(node)->boundsInViewport()) |
| 576 : layoutObject->absoluteBoundingBoxRect())) | 681 : layoutObject->absoluteBoundingBoxRect())) |
| 577 .build(); | 682 .build(); |
| 578 | 683 |
| 579 if (layoutObject->isText()) { | 684 if (layoutObject->isText()) { |
| 580 LayoutText* layoutText = toLayoutText(layoutObject); | 685 LayoutText* layoutText = toLayoutText(layoutObject); |
| 581 layoutTreeNode->setLayoutText(layoutText->text()); | 686 layoutTreeNode->setLayoutText(layoutText->text()); |
| 582 if (layoutText->hasTextBoxes()) { | 687 if (layoutText->hasTextBoxes()) { |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 593 .setStartCharacterIndex(textBox->start()) | 698 .setStartCharacterIndex(textBox->start()) |
| 594 .setNumCharacters(textBox->len()) | 699 .setNumCharacters(textBox->len()) |
| 595 .setBoundingBox(buildRectForFloatRect( | 700 .setBoundingBox(buildRectForFloatRect( |
| 596 absoluteCoordsTextBoxRect)) | 701 absoluteCoordsTextBoxRect)) |
| 597 .build()); | 702 .build()); |
| 598 } | 703 } |
| 599 layoutTreeNode->setInlineTextNodes(std::move(inlineTextNodes)); | 704 layoutTreeNode->setInlineTextNodes(std::move(inlineTextNodes)); |
| 600 } | 705 } |
| 601 } | 706 } |
| 602 | 707 |
| 603 layoutTreeNodes.addItem(std::move(layoutTreeNode)); | 708 layout_tree_nodes.addItem(std::move(layoutTreeNode)); |
| 604 } | 709 } |
| 605 } | 710 } |
| 606 | 711 |
| 607 void InspectorDOMAgent::pushChildNodesToFrontend(int nodeId, int depth) { | 712 void InspectorDOMAgent::pushChildNodesToFrontend(int nodeId, int depth) { |
| 608 Node* node = nodeForId(nodeId); | 713 Node* node = nodeForId(nodeId); |
| 609 if (!node || (!node->isElementNode() && !node->isDocumentNode() && | 714 if (!node || (!node->isElementNode() && !node->isDocumentNode() && |
| 610 !node->isDocumentFragment())) | 715 !node->isDocumentFragment())) |
| 611 return; | 716 return; |
| 612 | 717 |
| 613 NodeToIdMap* nodeMap = m_idToNodesMap.get(nodeId); | 718 NodeToIdMap* nodeMap = m_idToNodesMap.get(nodeId); |
| (...skipping 1752 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2366 visitor->trace(m_idToNodesMap); | 2471 visitor->trace(m_idToNodesMap); |
| 2367 visitor->trace(m_document); | 2472 visitor->trace(m_document); |
| 2368 visitor->trace(m_revalidateTask); | 2473 visitor->trace(m_revalidateTask); |
| 2369 visitor->trace(m_searchResults); | 2474 visitor->trace(m_searchResults); |
| 2370 visitor->trace(m_history); | 2475 visitor->trace(m_history); |
| 2371 visitor->trace(m_domEditor); | 2476 visitor->trace(m_domEditor); |
| 2372 InspectorBaseAgent::trace(visitor); | 2477 InspectorBaseAgent::trace(visitor); |
| 2373 } | 2478 } |
| 2374 | 2479 |
| 2375 } // namespace blink | 2480 } // namespace blink |
| OLD | NEW |