| 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 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 65 #include "core/inspector/DOMEditor.h" | 65 #include "core/inspector/DOMEditor.h" |
| 66 #include "core/inspector/DOMPatchSupport.h" | 66 #include "core/inspector/DOMPatchSupport.h" |
| 67 #include "core/inspector/EventListenerInfo.h" | 67 #include "core/inspector/EventListenerInfo.h" |
| 68 #include "core/inspector/IdentifiersFactory.h" | 68 #include "core/inspector/IdentifiersFactory.h" |
| 69 #include "core/inspector/InjectedScriptHost.h" | 69 #include "core/inspector/InjectedScriptHost.h" |
| 70 #include "core/inspector/InjectedScriptManager.h" | 70 #include "core/inspector/InjectedScriptManager.h" |
| 71 #include "core/inspector/InspectorHighlight.h" | 71 #include "core/inspector/InspectorHighlight.h" |
| 72 #include "core/inspector/InspectorHistory.h" | 72 #include "core/inspector/InspectorHistory.h" |
| 73 #include "core/inspector/InspectorIdentifiers.h" | 73 #include "core/inspector/InspectorIdentifiers.h" |
| 74 #include "core/inspector/InspectorOverlay.h" | 74 #include "core/inspector/InspectorOverlay.h" |
| 75 #include "core/inspector/InspectorResolver.h" | 75 #include "core/inspector/InspectorPageAgent.h" |
| 76 #include "core/inspector/InspectorState.h" | 76 #include "core/inspector/InspectorState.h" |
| 77 #include "core/inspector/InstrumentingAgents.h" | 77 #include "core/inspector/InstrumentingAgents.h" |
| 78 #include "core/layout/HitTestResult.h" | 78 #include "core/layout/HitTestResult.h" |
| 79 #include "core/layout/LayoutView.h" | 79 #include "core/layout/LayoutView.h" |
| 80 #include "core/loader/DocumentLoader.h" | 80 #include "core/loader/DocumentLoader.h" |
| 81 #include "core/page/FrameTree.h" | 81 #include "core/page/FrameTree.h" |
| 82 #include "core/page/Page.h" | 82 #include "core/page/Page.h" |
| 83 #include "core/xml/DocumentXPathEvaluator.h" | 83 #include "core/xml/DocumentXPathEvaluator.h" |
| 84 #include "core/xml/XPathResult.h" | 84 #include "core/xml/XPathResult.h" |
| 85 #include "platform/PlatformGestureEvent.h" | 85 #include "platform/PlatformGestureEvent.h" |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 285 *type = TypeBuilder::DOM::PseudoType::Resizer; | 285 *type = TypeBuilder::DOM::PseudoType::Resizer; |
| 286 return true; | 286 return true; |
| 287 case INPUT_LIST_BUTTON: | 287 case INPUT_LIST_BUTTON: |
| 288 *type = TypeBuilder::DOM::PseudoType::Input_list_button; | 288 *type = TypeBuilder::DOM::PseudoType::Input_list_button; |
| 289 return true; | 289 return true; |
| 290 default: | 290 default: |
| 291 return false; | 291 return false; |
| 292 } | 292 } |
| 293 } | 293 } |
| 294 | 294 |
| 295 InspectorDOMAgent::InspectorDOMAgent(LocalFrame* inspectedFrame, InjectedScriptM
anager* injectedScriptManager, InspectorOverlay* overlay) | 295 InspectorDOMAgent::InspectorDOMAgent(InspectorPageAgent* pageAgent, InjectedScri
ptManager* injectedScriptManager, InspectorOverlay* overlay) |
| 296 : InspectorBaseAgent<InspectorDOMAgent, InspectorFrontend::DOM>("DOM") | 296 : InspectorBaseAgent<InspectorDOMAgent, InspectorFrontend::DOM>("DOM") |
| 297 , m_inspectedFrame(inspectedFrame) | 297 , m_pageAgent(pageAgent) |
| 298 , m_injectedScriptManager(injectedScriptManager) | 298 , m_injectedScriptManager(injectedScriptManager) |
| 299 , m_overlay(overlay) | 299 , m_overlay(overlay) |
| 300 , m_domListener(nullptr) | 300 , m_domListener(nullptr) |
| 301 , m_documentNodeToIdMap(adoptPtrWillBeNoop(new NodeToIdMap())) | 301 , m_documentNodeToIdMap(adoptPtrWillBeNoop(new NodeToIdMap())) |
| 302 , m_lastNodeId(1) | 302 , m_lastNodeId(1) |
| 303 , m_searchingForNode(NotSearching) | 303 , m_searchingForNode(NotSearching) |
| 304 , m_suppressAttributeModifiedEvent(false) | 304 , m_suppressAttributeModifiedEvent(false) |
| 305 , m_listener(nullptr) | 305 , m_listener(nullptr) |
| 306 , m_backendNodeIdToInspect(0) | 306 , m_backendNodeIdToInspect(0) |
| 307 { | 307 { |
| (...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 530 } | 530 } |
| 531 | 531 |
| 532 return element; | 532 return element; |
| 533 } | 533 } |
| 534 | 534 |
| 535 void InspectorDOMAgent::innerEnable() | 535 void InspectorDOMAgent::innerEnable() |
| 536 { | 536 { |
| 537 m_state->setBoolean(DOMAgentState::domAgentEnabled, true); | 537 m_state->setBoolean(DOMAgentState::domAgentEnabled, true); |
| 538 m_history = adoptPtrWillBeNoop(new InspectorHistory()); | 538 m_history = adoptPtrWillBeNoop(new InspectorHistory()); |
| 539 m_domEditor = adoptPtrWillBeNoop(new DOMEditor(m_history.get())); | 539 m_domEditor = adoptPtrWillBeNoop(new DOMEditor(m_history.get())); |
| 540 m_document = m_inspectedFrame->document(); | 540 m_document = m_pageAgent->inspectedFrame()->document(); |
| 541 m_instrumentingAgents->setInspectorDOMAgent(this); | 541 m_instrumentingAgents->setInspectorDOMAgent(this); |
| 542 if (m_listener) | 542 if (m_listener) |
| 543 m_listener->domAgentWasEnabled(); | 543 m_listener->domAgentWasEnabled(); |
| 544 if (m_backendNodeIdToInspect) | 544 if (m_backendNodeIdToInspect) |
| 545 frontend()->inspectNodeRequested(m_backendNodeIdToInspect); | 545 frontend()->inspectNodeRequested(m_backendNodeIdToInspect); |
| 546 m_backendNodeIdToInspect = 0; | 546 m_backendNodeIdToInspect = 0; |
| 547 } | 547 } |
| 548 | 548 |
| 549 void InspectorDOMAgent::enable(ErrorString*) | 549 void InspectorDOMAgent::enable(ErrorString*) |
| 550 { | 550 { |
| (...skipping 754 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1305 highlightConfig->contentOutline = parseColor(outlineColor); | 1305 highlightConfig->contentOutline = parseColor(outlineColor); |
| 1306 m_overlay->highlightQuad(quad, *highlightConfig); | 1306 m_overlay->highlightQuad(quad, *highlightConfig); |
| 1307 } | 1307 } |
| 1308 | 1308 |
| 1309 void InspectorDOMAgent::highlightNode(ErrorString* errorString, const RefPtr<JSO
NObject>& highlightInspectorObject, const int* nodeId, const int* backendNodeId,
const String* objectId) | 1309 void InspectorDOMAgent::highlightNode(ErrorString* errorString, const RefPtr<JSO
NObject>& highlightInspectorObject, const int* nodeId, const int* backendNodeId,
const String* objectId) |
| 1310 { | 1310 { |
| 1311 Node* node = nullptr; | 1311 Node* node = nullptr; |
| 1312 if (nodeId) { | 1312 if (nodeId) { |
| 1313 node = assertNode(errorString, *nodeId); | 1313 node = assertNode(errorString, *nodeId); |
| 1314 } else if (backendNodeId) { | 1314 } else if (backendNodeId) { |
| 1315 node = InspectorResolver::resolveNode(m_inspectedFrame, *backendNodeId); | 1315 node = DOMNodeIds::nodeForId(*backendNodeId); |
| 1316 } else if (objectId) { | 1316 } else if (objectId) { |
| 1317 InjectedScript injectedScript = m_injectedScriptManager->injectedScriptF
orObjectId(*objectId); | 1317 InjectedScript injectedScript = m_injectedScriptManager->injectedScriptF
orObjectId(*objectId); |
| 1318 node = injectedScript.nodeForObjectId(*objectId); | 1318 node = injectedScript.nodeForObjectId(*objectId); |
| 1319 if (!node) | 1319 if (!node) |
| 1320 *errorString = "Node for given objectId not found"; | 1320 *errorString = "Node for given objectId not found"; |
| 1321 } else | 1321 } else |
| 1322 *errorString = "Either nodeId or objectId must be specified"; | 1322 *errorString = "Either nodeId or objectId must be specified"; |
| 1323 | 1323 |
| 1324 if (!node) | 1324 if (!node) |
| 1325 return; | 1325 return; |
| 1326 | 1326 |
| 1327 OwnPtr<InspectorHighlightConfig> highlightConfig = highlightConfigFromInspec
torObject(errorString, highlightInspectorObject.get()); | 1327 OwnPtr<InspectorHighlightConfig> highlightConfig = highlightConfigFromInspec
torObject(errorString, highlightInspectorObject.get()); |
| 1328 if (!highlightConfig) | 1328 if (!highlightConfig) |
| 1329 return; | 1329 return; |
| 1330 | 1330 |
| 1331 m_overlay->highlightNode(node, 0 /* eventTarget */, *highlightConfig, false)
; | 1331 m_overlay->highlightNode(node, 0 /* eventTarget */, *highlightConfig, false)
; |
| 1332 } | 1332 } |
| 1333 | 1333 |
| 1334 void InspectorDOMAgent::highlightFrame( | 1334 void InspectorDOMAgent::highlightFrame( |
| 1335 ErrorString* errorString, | 1335 ErrorString*, |
| 1336 const String& frameId, | 1336 const String& frameId, |
| 1337 const RefPtr<JSONObject>* color, | 1337 const RefPtr<JSONObject>* color, |
| 1338 const RefPtr<JSONObject>* outlineColor) | 1338 const RefPtr<JSONObject>* outlineColor) |
| 1339 { | 1339 { |
| 1340 LocalFrame* frame = InspectorResolver::resolveFrame(m_inspectedFrame, frameI
d); | 1340 LocalFrame* frame = m_pageAgent->frameForId(frameId); |
| 1341 if (!frame) { | 1341 // FIXME: Inspector doesn't currently work cross process. |
| 1342 *errorString = "No frame for given id found"; | 1342 if (frame && frame->deprecatedLocalOwner()) { |
| 1343 return; | 1343 OwnPtr<InspectorHighlightConfig> highlightConfig = adoptPtr(new Inspecto
rHighlightConfig()); |
| 1344 highlightConfig->showInfo = true; // Always show tooltips for frames. |
| 1345 highlightConfig->content = parseColor(color); |
| 1346 highlightConfig->contentOutline = parseColor(outlineColor); |
| 1347 m_overlay->highlightNode(frame->deprecatedLocalOwner(), 0 /* eventTarget
*/, *highlightConfig, false); |
| 1344 } | 1348 } |
| 1345 FrameOwner* owner = frame->owner(); | |
| 1346 // FIXME: Inspector doesn't currently work cross process. | |
| 1347 if (!owner || !owner->isLocal()) | |
| 1348 return; | |
| 1349 HTMLFrameOwnerElement* ownerElement = toHTMLFrameOwnerElement(owner); | |
| 1350 OwnPtr<InspectorHighlightConfig> highlightConfig = adoptPtr(new InspectorHig
hlightConfig()); | |
| 1351 highlightConfig->showInfo = true; // Always show tooltips for frames. | |
| 1352 highlightConfig->content = parseColor(color); | |
| 1353 highlightConfig->contentOutline = parseColor(outlineColor); | |
| 1354 m_overlay->highlightNode(ownerElement, 0 /* eventTarget */, *highlightConfig
, false); | |
| 1355 } | 1349 } |
| 1356 | 1350 |
| 1357 void InspectorDOMAgent::hideHighlight(ErrorString*) | 1351 void InspectorDOMAgent::hideHighlight(ErrorString*) |
| 1358 { | 1352 { |
| 1359 m_overlay->hideHighlight(); | 1353 m_overlay->hideHighlight(); |
| 1360 } | 1354 } |
| 1361 | 1355 |
| 1362 void InspectorDOMAgent::copyTo(ErrorString* errorString, int nodeId, int targetE
lementId, const int* const anchorNodeId, int* newNodeId) | 1356 void InspectorDOMAgent::copyTo(ErrorString* errorString, int nodeId, int targetE
lementId, const int* const anchorNodeId, int* newNodeId) |
| 1363 { | 1357 { |
| 1364 Node* node = assertEditableNode(errorString, nodeId); | 1358 Node* node = assertEditableNode(errorString, nodeId); |
| (...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1815 } | 1809 } |
| 1816 | 1810 |
| 1817 bool InspectorDOMAgent::isWhitespace(Node* node) | 1811 bool InspectorDOMAgent::isWhitespace(Node* node) |
| 1818 { | 1812 { |
| 1819 //TODO: pull ignoreWhitespace setting from the frontend and use here. | 1813 //TODO: pull ignoreWhitespace setting from the frontend and use here. |
| 1820 return node && node->nodeType() == Node::TEXT_NODE && node->nodeValue().stri
pWhiteSpace().length() == 0; | 1814 return node && node->nodeType() == Node::TEXT_NODE && node->nodeValue().stri
pWhiteSpace().length() == 0; |
| 1821 } | 1815 } |
| 1822 | 1816 |
| 1823 void InspectorDOMAgent::domContentLoadedEventFired(LocalFrame* frame) | 1817 void InspectorDOMAgent::domContentLoadedEventFired(LocalFrame* frame) |
| 1824 { | 1818 { |
| 1825 if (frame != m_inspectedFrame) | 1819 if (frame != m_pageAgent->inspectedFrame()) |
| 1826 return; | 1820 return; |
| 1827 | 1821 |
| 1828 // Re-push document once it is loaded. | 1822 // Re-push document once it is loaded. |
| 1829 discardFrontendBindings(); | 1823 discardFrontendBindings(); |
| 1830 if (enabled()) | 1824 if (enabled()) |
| 1831 frontend()->documentUpdated(); | 1825 frontend()->documentUpdated(); |
| 1832 } | 1826 } |
| 1833 | 1827 |
| 1834 void InspectorDOMAgent::invalidateFrameOwnerElement(LocalFrame* frame) | 1828 void InspectorDOMAgent::invalidateFrameOwnerElement(LocalFrame* frame) |
| 1835 { | 1829 { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1847 unbind(frameOwner, m_documentNodeToIdMap.get()); | 1841 unbind(frameOwner, m_documentNodeToIdMap.get()); |
| 1848 | 1842 |
| 1849 RefPtr<TypeBuilder::DOM::Node> value = buildObjectForNode(frameOwner, 0, m_d
ocumentNodeToIdMap.get()); | 1843 RefPtr<TypeBuilder::DOM::Node> value = buildObjectForNode(frameOwner, 0, m_d
ocumentNodeToIdMap.get()); |
| 1850 Node* previousSibling = innerPreviousSibling(frameOwner); | 1844 Node* previousSibling = innerPreviousSibling(frameOwner); |
| 1851 int prevId = previousSibling ? m_documentNodeToIdMap->get(previousSibling) :
0; | 1845 int prevId = previousSibling ? m_documentNodeToIdMap->get(previousSibling) :
0; |
| 1852 frontend()->childNodeInserted(parentId, prevId, value.release()); | 1846 frontend()->childNodeInserted(parentId, prevId, value.release()); |
| 1853 } | 1847 } |
| 1854 | 1848 |
| 1855 void InspectorDOMAgent::didCommitLoad(LocalFrame*, DocumentLoader* loader) | 1849 void InspectorDOMAgent::didCommitLoad(LocalFrame*, DocumentLoader* loader) |
| 1856 { | 1850 { |
| 1857 if (loader->frame() != m_inspectedFrame) { | 1851 LocalFrame* inspectedFrame = m_pageAgent->inspectedFrame(); |
| 1852 if (loader->frame() != inspectedFrame) { |
| 1858 invalidateFrameOwnerElement(loader->frame()); | 1853 invalidateFrameOwnerElement(loader->frame()); |
| 1859 return; | 1854 return; |
| 1860 } | 1855 } |
| 1861 | 1856 |
| 1862 setDocument(m_inspectedFrame->document()); | 1857 setDocument(inspectedFrame->document()); |
| 1863 } | 1858 } |
| 1864 | 1859 |
| 1865 void InspectorDOMAgent::didInsertDOMNode(Node* node) | 1860 void InspectorDOMAgent::didInsertDOMNode(Node* node) |
| 1866 { | 1861 { |
| 1867 if (isWhitespace(node)) | 1862 if (isWhitespace(node)) |
| 1868 return; | 1863 return; |
| 1869 | 1864 |
| 1870 // We could be attaching existing subtree. Forget the bindings. | 1865 // We could be attaching existing subtree. Forget the bindings. |
| 1871 unbind(node, m_documentNodeToIdMap.get()); | 1866 unbind(node, m_documentNodeToIdMap.get()); |
| 1872 | 1867 |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2037 } | 2032 } |
| 2038 } | 2033 } |
| 2039 } | 2034 } |
| 2040 | 2035 |
| 2041 void InspectorDOMAgent::frameDocumentUpdated(LocalFrame* frame) | 2036 void InspectorDOMAgent::frameDocumentUpdated(LocalFrame* frame) |
| 2042 { | 2037 { |
| 2043 Document* document = frame->document(); | 2038 Document* document = frame->document(); |
| 2044 if (!document) | 2039 if (!document) |
| 2045 return; | 2040 return; |
| 2046 | 2041 |
| 2047 if (frame != m_inspectedFrame) | 2042 if (frame != m_pageAgent->inspectedFrame()) |
| 2048 return; | 2043 return; |
| 2049 | 2044 |
| 2050 // Only update the main frame document, nested frame document updates are no
t required | 2045 // Only update the main frame document, nested frame document updates are no
t required |
| 2051 // (will be handled by invalidateFrameOwnerElement()). | 2046 // (will be handled by invalidateFrameOwnerElement()). |
| 2052 setDocument(document); | 2047 setDocument(document); |
| 2053 } | 2048 } |
| 2054 | 2049 |
| 2055 void InspectorDOMAgent::pseudoElementCreated(PseudoElement* pseudoElement) | 2050 void InspectorDOMAgent::pseudoElementCreated(PseudoElement* pseudoElement) |
| 2056 { | 2051 { |
| 2057 Element* parent = pseudoElement->parentOrShadowHostElement(); | 2052 Element* parent = pseudoElement->parentOrShadowHostElement(); |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2142 { | 2137 { |
| 2143 result = TypeBuilder::Array<int>::create(); | 2138 result = TypeBuilder::Array<int>::create(); |
| 2144 for (const auto& backendNode : *backendNodeIds) { | 2139 for (const auto& backendNode : *backendNodeIds) { |
| 2145 int backendNodeId; | 2140 int backendNodeId; |
| 2146 | 2141 |
| 2147 if (!(backendNode)->asNumber(&backendNodeId)) { | 2142 if (!(backendNode)->asNumber(&backendNodeId)) { |
| 2148 *errorString = "Invalid argument type"; | 2143 *errorString = "Invalid argument type"; |
| 2149 return; | 2144 return; |
| 2150 } | 2145 } |
| 2151 | 2146 |
| 2152 if (Node* node = InspectorResolver::resolveNode(m_inspectedFrame, backen
dNodeId)) | 2147 Node* node = DOMNodeIds::nodeForId(backendNodeId); |
| 2148 if (node && node->document().frame() && node->document().frame()->instru
mentingAgents() == m_pageAgent->inspectedFrame()->instrumentingAgents()) |
| 2153 result->addItem(pushNodePathToFrontend(node)); | 2149 result->addItem(pushNodePathToFrontend(node)); |
| 2154 else | 2150 else |
| 2155 result->addItem(0); | 2151 result->addItem(0); |
| 2156 } | 2152 } |
| 2157 } | 2153 } |
| 2158 | 2154 |
| 2159 class InspectableNode final : public InjectedScriptHost::InspectableObject { | 2155 class InspectableNode final : public InjectedScriptHost::InspectableObject { |
| 2160 public: | 2156 public: |
| 2161 explicit InspectableNode(Node* node) : m_node(node) { } | 2157 explicit InspectableNode(Node* node) : m_node(node) { } |
| 2162 virtual ScriptValue get(ScriptState* state) override | 2158 virtual ScriptValue get(ScriptState* state) override |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2220 RefPtr<TypeBuilder::DOM::Node> root; | 2216 RefPtr<TypeBuilder::DOM::Node> root; |
| 2221 getDocument(errorString, root); | 2217 getDocument(errorString, root); |
| 2222 return errorString->isEmpty(); | 2218 return errorString->isEmpty(); |
| 2223 } | 2219 } |
| 2224 return true; | 2220 return true; |
| 2225 } | 2221 } |
| 2226 | 2222 |
| 2227 DEFINE_TRACE(InspectorDOMAgent) | 2223 DEFINE_TRACE(InspectorDOMAgent) |
| 2228 { | 2224 { |
| 2229 visitor->trace(m_domListener); | 2225 visitor->trace(m_domListener); |
| 2230 visitor->trace(m_inspectedFrame); | 2226 visitor->trace(m_pageAgent); |
| 2231 visitor->trace(m_injectedScriptManager); | 2227 visitor->trace(m_injectedScriptManager); |
| 2232 visitor->trace(m_overlay); | 2228 visitor->trace(m_overlay); |
| 2233 #if ENABLE(OILPAN) | 2229 #if ENABLE(OILPAN) |
| 2234 visitor->trace(m_documentNodeToIdMap); | 2230 visitor->trace(m_documentNodeToIdMap); |
| 2235 visitor->trace(m_danglingNodeToIdMaps); | 2231 visitor->trace(m_danglingNodeToIdMaps); |
| 2236 visitor->trace(m_idToNode); | 2232 visitor->trace(m_idToNode); |
| 2237 visitor->trace(m_idToNodesMap); | 2233 visitor->trace(m_idToNodesMap); |
| 2238 visitor->trace(m_document); | 2234 visitor->trace(m_document); |
| 2239 visitor->trace(m_revalidateTask); | 2235 visitor->trace(m_revalidateTask); |
| 2240 visitor->trace(m_searchResults); | 2236 visitor->trace(m_searchResults); |
| 2241 #endif | 2237 #endif |
| 2242 visitor->trace(m_hoveredNodeForInspectMode); | 2238 visitor->trace(m_hoveredNodeForInspectMode); |
| 2243 visitor->trace(m_history); | 2239 visitor->trace(m_history); |
| 2244 visitor->trace(m_domEditor); | 2240 visitor->trace(m_domEditor); |
| 2245 visitor->trace(m_listener); | 2241 visitor->trace(m_listener); |
| 2246 InspectorBaseAgent::trace(visitor); | 2242 InspectorBaseAgent::trace(visitor); |
| 2247 } | 2243 } |
| 2248 | 2244 |
| 2249 } // namespace blink | 2245 } // namespace blink |
| OLD | NEW |