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

Side by Side Diff: third_party/WebKit/Source/core/inspector/InspectorCSSAgent.cpp

Issue 2882193002: [devtools] Add DOMSnapshot domain for dom+layout+style snapshots. (Closed)
Patch Set: back to DOMSnapshot domain, with custom node types + traversal. Created 3 years, 6 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) 2010, Google Inc. All rights reserved. 2 * Copyright (C) 2010, Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 #include "core/css/StylePropertySet.h" 47 #include "core/css/StylePropertySet.h"
48 #include "core/css/StyleRule.h" 48 #include "core/css/StyleRule.h"
49 #include "core/css/StyleSheet.h" 49 #include "core/css/StyleSheet.h"
50 #include "core/css/StyleSheetContents.h" 50 #include "core/css/StyleSheetContents.h"
51 #include "core/css/StyleSheetList.h" 51 #include "core/css/StyleSheetList.h"
52 #include "core/css/parser/CSSParser.h" 52 #include "core/css/parser/CSSParser.h"
53 #include "core/css/parser/CSSParserContext.h" 53 #include "core/css/parser/CSSParserContext.h"
54 #include "core/css/resolver/StyleResolver.h" 54 #include "core/css/resolver/StyleResolver.h"
55 #include "core/css/resolver/StyleRuleUsageTracker.h" 55 #include "core/css/resolver/StyleRuleUsageTracker.h"
56 #include "core/dom/DOMException.h" 56 #include "core/dom/DOMException.h"
57 #include "core/dom/DOMNodeIds.h"
58 #include "core/dom/Node.h" 57 #include "core/dom/Node.h"
59 #include "core/dom/StyleChangeReason.h" 58 #include "core/dom/StyleChangeReason.h"
60 #include "core/dom/StyleEngine.h" 59 #include "core/dom/StyleEngine.h"
61 #include "core/dom/Text.h" 60 #include "core/dom/Text.h"
62 #include "core/dom/shadow/ElementShadow.h"
63 #include "core/frame/LocalFrame.h" 61 #include "core/frame/LocalFrame.h"
64 #include "core/frame/LocalFrameView.h" 62 #include "core/frame/LocalFrameView.h"
65 #include "core/html/HTMLFrameOwnerElement.h" 63 #include "core/html/HTMLFrameOwnerElement.h"
66 #include "core/html/HTMLHeadElement.h" 64 #include "core/html/HTMLHeadElement.h"
67 #include "core/html/VoidCallback.h" 65 #include "core/html/VoidCallback.h"
68 #include "core/inspector/IdentifiersFactory.h" 66 #include "core/inspector/IdentifiersFactory.h"
69 #include "core/inspector/InspectedFrames.h" 67 #include "core/inspector/InspectedFrames.h"
70 #include "core/inspector/InspectorHistory.h" 68 #include "core/inspector/InspectorHistory.h"
71 #include "core/inspector/InspectorNetworkAgent.h" 69 #include "core/inspector/InspectorNetworkAgent.h"
72 #include "core/inspector/InspectorResourceContainer.h" 70 #include "core/inspector/InspectorResourceContainer.h"
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 bool contains = found_top_element || element->BoundingBox().Contains(rect); 284 bool contains = found_top_element || element->BoundingBox().Contains(rect);
287 if (!contains && found_non_transparent_color) { 285 if (!contains && found_non_transparent_color) {
288 // Only return colors if some opaque element covers up this one. 286 // Only return colors if some opaque element covers up this one.
289 colors.clear(); 287 colors.clear();
290 found_opaque_color = false; 288 found_opaque_color = false;
291 } 289 }
292 } 290 }
293 return found_opaque_color; 291 return found_opaque_color;
294 } 292 }
295 293
296 std::unique_ptr<protocol::DOM::Rect> BuildRectForFloatRect(
297 const FloatRect& rect) {
298 return protocol::DOM::Rect::create()
299 .setX(rect.X())
300 .setY(rect.Y())
301 .setWidth(rect.Width())
302 .setHeight(rect.Height())
303 .build();
304 }
305
306 } // namespace 294 } // namespace
307 295
308 namespace CSSAgentState { 296 namespace CSSAgentState {
309 static const char kCssAgentEnabled[] = "cssAgentEnabled"; 297 static const char kCssAgentEnabled[] = "cssAgentEnabled";
310 static const char kRuleRecordingEnabled[] = "ruleRecordingEnabled"; 298 static const char kRuleRecordingEnabled[] = "ruleRecordingEnabled";
311 } 299 }
312 300
313 typedef blink::protocol::CSS::Backend::EnableCallback EnableCallback; 301 typedef blink::protocol::CSS::Backend::EnableCallback EnableCallback;
314 302
315 enum ForcePseudoClassFlags { 303 enum ForcePseudoClassFlags {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
353 WTF_MAKE_NONCOPYABLE(StyleSheetAction); 341 WTF_MAKE_NONCOPYABLE(StyleSheetAction);
354 342
355 public: 343 public:
356 StyleSheetAction(const String& name) : InspectorHistory::Action(name) {} 344 StyleSheetAction(const String& name) : InspectorHistory::Action(name) {}
357 345
358 virtual std::unique_ptr<protocol::CSS::CSSStyle> TakeSerializedStyle() { 346 virtual std::unique_ptr<protocol::CSS::CSSStyle> TakeSerializedStyle() {
359 return nullptr; 347 return nullptr;
360 } 348 }
361 }; 349 };
362 350
363 struct InspectorCSSAgent::VectorStringHashTraits
364 : public WTF::GenericHashTraits<Vector<String>> {
365 static unsigned GetHash(const Vector<String>& vec) {
366 unsigned h = DefaultHash<size_t>::Hash::GetHash(vec.size());
367 for (size_t i = 0; i < vec.size(); i++) {
368 h = WTF::HashInts(h, DefaultHash<String>::Hash::GetHash(vec[i]));
369 }
370 return h;
371 }
372
373 static bool Equal(const Vector<String>& a, const Vector<String>& b) {
374 if (a.size() != b.size())
375 return false;
376 for (size_t i = 0; i < a.size(); i++) {
377 if (a[i] != b[i])
378 return false;
379 }
380 return true;
381 }
382
383 static void ConstructDeletedValue(Vector<String>& vec, bool) {
384 vec.clear();
385 vec.push_back(String(WTF::kHashTableDeletedValue));
386 }
387
388 static bool IsDeletedValue(const Vector<String>& vec) {
389 return !vec.IsEmpty() && vec[0].IsHashTableDeletedValue();
390 }
391
392 static bool IsEmptyValue(const Vector<String>& vec) { return vec.IsEmpty(); }
393
394 static const bool kEmptyValueIsZero = false;
395 static const bool safe_to_compare_to_empty_or_deleted = false;
396 static const bool kHasIsEmptyValueFunction = true;
397 };
398
399 class InspectorCSSAgent::SetStyleSheetTextAction final 351 class InspectorCSSAgent::SetStyleSheetTextAction final
400 : public InspectorCSSAgent::StyleSheetAction { 352 : public InspectorCSSAgent::StyleSheetAction {
401 WTF_MAKE_NONCOPYABLE(SetStyleSheetTextAction); 353 WTF_MAKE_NONCOPYABLE(SetStyleSheetTextAction);
402 354
403 public: 355 public:
404 SetStyleSheetTextAction(InspectorStyleSheetBase* style_sheet, 356 SetStyleSheetTextAction(InspectorStyleSheetBase* style_sheet,
405 const String& text) 357 const String& text)
406 : InspectorCSSAgent::StyleSheetAction("SetStyleSheetText"), 358 : InspectorCSSAgent::StyleSheetAction("SetStyleSheetText"),
407 style_sheet_(style_sheet), 359 style_sheet_(style_sheet),
408 text_(text) {} 360 text_(text) {}
(...skipping 1912 matching lines...) Expand 10 before | Expand all | Expand 10 after
2321 text_bounds, owner_element->GetDocument(), nullptr, colors); 2273 text_bounds, owner_element->GetDocument(), nullptr, colors);
2322 } 2274 }
2323 } 2275 }
2324 2276
2325 *result = protocol::Array<String>::create(); 2277 *result = protocol::Array<String>::create();
2326 for (auto color : colors) 2278 for (auto color : colors)
2327 result->fromJust()->addItem(color.SerializedAsCSSComponentValue()); 2279 result->fromJust()->addItem(color.SerializedAsCSSComponentValue());
2328 return Response::OK(); 2280 return Response::OK();
2329 } 2281 }
2330 2282
2331 Response InspectorCSSAgent::getLayoutTreeAndStyles(
2332 std::unique_ptr<protocol::Array<String>> style_whitelist,
2333 std::unique_ptr<protocol::Array<protocol::CSS::LayoutTreeNode>>*
2334 layout_tree_nodes,
2335 std::unique_ptr<protocol::Array<protocol::CSS::ComputedStyle>>*
2336 computed_styles) {
2337 dom_agent_->GetDocument()->UpdateStyleAndLayoutTree();
2338
2339 // Look up the CSSPropertyIDs for each entry in |styleWhitelist|.
2340 Vector<std::pair<String, CSSPropertyID>> css_property_whitelist;
2341 for (size_t i = 0; i < style_whitelist->length(); i++) {
2342 CSSPropertyID property_id = cssPropertyID(style_whitelist->get(i));
2343 if (property_id == CSSPropertyInvalid)
2344 continue;
2345 css_property_whitelist.push_back(
2346 std::make_pair(style_whitelist->get(i), property_id));
2347 }
2348
2349 *layout_tree_nodes = protocol::Array<protocol::CSS::LayoutTreeNode>::create();
2350 *computed_styles = protocol::Array<protocol::CSS::ComputedStyle>::create();
2351
2352 ComputedStylesMap style_to_index_map;
2353 VisitLayoutTreeNodes(dom_agent_->GetDocument(), *layout_tree_nodes->get(),
2354 css_property_whitelist, style_to_index_map,
2355 *computed_styles->get());
2356 return Response::OK();
2357 }
2358
2359 int InspectorCSSAgent::GetStyleIndexForNode(
2360 Node* node,
2361 const Vector<std::pair<String, CSSPropertyID>>& css_property_whitelist,
2362 ComputedStylesMap& style_to_index_map,
2363 protocol::Array<protocol::CSS::ComputedStyle>& computed_styles) {
2364 CSSComputedStyleDeclaration* computed_style_info =
2365 CSSComputedStyleDeclaration::Create(node, true);
2366
2367 Vector<String> style;
2368 bool all_properties_empty = true;
2369 for (const auto& pair : css_property_whitelist) {
2370 String value = computed_style_info->GetPropertyValue(pair.second);
2371 if (!value.IsEmpty())
2372 all_properties_empty = false;
2373 style.push_back(value);
2374 }
2375
2376 // -1 means an empty style.
2377 if (all_properties_empty)
2378 return -1;
2379
2380 ComputedStylesMap::iterator it = style_to_index_map.find(style);
2381 if (it != style_to_index_map.end())
2382 return it->value;
2383
2384 // It's a distinct style, so append to |computedStyles|.
2385 std::unique_ptr<protocol::Array<protocol::CSS::CSSComputedStyleProperty>>
2386 style_properties =
2387 protocol::Array<protocol::CSS::CSSComputedStyleProperty>::create();
2388
2389 for (size_t i = 0; i < style.size(); i++) {
2390 if (style[i].IsEmpty())
2391 continue;
2392 style_properties->addItem(protocol::CSS::CSSComputedStyleProperty::create()
2393 .setName(css_property_whitelist[i].first)
2394 .setValue(style[i])
2395 .build());
2396 }
2397 computed_styles.addItem(protocol::CSS::ComputedStyle::create()
2398 .setProperties(std::move(style_properties))
2399 .build());
2400
2401 size_t index = style_to_index_map.size();
2402 style_to_index_map.insert(std::move(style), index);
2403 return index;
2404 }
2405
2406 void InspectorCSSAgent::VisitLayoutTreeNodes(
2407 Node* node,
2408 protocol::Array<protocol::CSS::LayoutTreeNode>& layout_tree_nodes,
2409 const Vector<std::pair<String, CSSPropertyID>>& css_property_whitelist,
2410 ComputedStylesMap& style_to_index_map,
2411 protocol::Array<protocol::CSS::ComputedStyle>& computed_styles) {
2412 for (; node; node = NodeTraversal::Next(*node)) {
2413 // Visit shadow dom nodes.
2414 if (node->IsElementNode()) {
2415 const Element* element = ToElement(node);
2416 ElementShadow* element_shadow = element->Shadow();
2417 if (element_shadow) {
2418 VisitLayoutTreeNodes(&element_shadow->YoungestShadowRoot(),
2419 layout_tree_nodes, css_property_whitelist,
2420 style_to_index_map, computed_styles);
2421 }
2422 }
2423
2424 // Pierce iframe boundaries.
2425 if (node->IsFrameOwnerElement()) {
2426 Document* content_document =
2427 ToHTMLFrameOwnerElement(node)->contentDocument();
2428 if (content_document) {
2429 content_document->UpdateStyleAndLayoutTree();
2430 VisitLayoutTreeNodes(content_document->documentElement(),
2431 layout_tree_nodes, css_property_whitelist,
2432 style_to_index_map, computed_styles);
2433 }
2434 }
2435
2436 LayoutObject* layout_object = node->GetLayoutObject();
2437 if (!layout_object)
2438 continue;
2439
2440 int node_id = dom_agent_->BoundNodeId(node);
2441 if (!node_id)
2442 continue;
2443
2444 std::unique_ptr<protocol::CSS::LayoutTreeNode> layout_tree_node =
2445 protocol::CSS::LayoutTreeNode::create()
2446 .setNodeId(node_id)
2447 .setBoundingBox(BuildRectForFloatRect(
2448 node->IsElementNode()
2449 ? FloatRect(ToElement(node)->BoundsInViewport())
2450 : layout_object->AbsoluteBoundingBoxRect()))
2451 .build();
2452 int style_index = GetStyleIndexForNode(node, css_property_whitelist,
2453 style_to_index_map, computed_styles);
2454 if (style_index != -1)
2455 layout_tree_node->setStyleIndex(style_index);
2456
2457 if (layout_object->IsText()) {
2458 LayoutText* layout_text = ToLayoutText(layout_object);
2459 layout_tree_node->setLayoutText(layout_text->GetText());
2460 if (layout_text->HasTextBoxes()) {
2461 std::unique_ptr<protocol::Array<protocol::CSS::InlineTextBox>>
2462 inline_text_nodes =
2463 protocol::Array<protocol::CSS::InlineTextBox>::create();
2464 for (const InlineTextBox* text_box = layout_text->FirstTextBox();
2465 text_box; text_box = text_box->NextTextBox()) {
2466 FloatRect local_coords_text_box_rect(text_box->FrameRect());
2467 FloatRect absolute_coords_text_box_rect =
2468 layout_object->LocalToAbsoluteQuad(local_coords_text_box_rect)
2469 .BoundingBox();
2470 inline_text_nodes->addItem(
2471 protocol::CSS::InlineTextBox::create()
2472 .setStartCharacterIndex(text_box->Start())
2473 .setNumCharacters(text_box->Len())
2474 .setBoundingBox(
2475 BuildRectForFloatRect(absolute_coords_text_box_rect))
2476 .build());
2477 }
2478 layout_tree_node->setInlineTextNodes(std::move(inline_text_nodes));
2479 }
2480 }
2481
2482 layout_tree_nodes.addItem(std::move(layout_tree_node));
2483 }
2484 }
2485
2486 void InspectorCSSAgent::SetCoverageEnabled(bool enabled) { 2283 void InspectorCSSAgent::SetCoverageEnabled(bool enabled) {
2487 if (enabled == !!tracker_) 2284 if (enabled == !!tracker_)
2488 return; 2285 return;
2489 tracker_ = enabled ? new StyleRuleUsageTracker() : nullptr; 2286 tracker_ = enabled ? new StyleRuleUsageTracker() : nullptr;
2490 2287
2491 for (Document* document : dom_agent_->Documents()) 2288 for (Document* document : dom_agent_->Documents())
2492 document->GetStyleEngine().SetRuleUsageTracker(tracker_); 2289 document->GetStyleEngine().SetRuleUsageTracker(tracker_);
2493 } 2290 }
2494 2291
2495 Response InspectorCSSAgent::startRuleUsageTracking() { 2292 Response InspectorCSSAgent::startRuleUsageTracking() {
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
2562 visitor->Trace(css_style_sheet_to_inspector_style_sheet_); 2359 visitor->Trace(css_style_sheet_to_inspector_style_sheet_);
2563 visitor->Trace(document_to_css_style_sheets_); 2360 visitor->Trace(document_to_css_style_sheets_);
2564 visitor->Trace(invalidated_documents_); 2361 visitor->Trace(invalidated_documents_);
2565 visitor->Trace(node_to_inspector_style_sheet_); 2362 visitor->Trace(node_to_inspector_style_sheet_);
2566 visitor->Trace(inspector_user_agent_style_sheet_); 2363 visitor->Trace(inspector_user_agent_style_sheet_);
2567 visitor->Trace(tracker_); 2364 visitor->Trace(tracker_);
2568 InspectorBaseAgent::Trace(visitor); 2365 InspectorBaseAgent::Trace(visitor);
2569 } 2366 }
2570 2367
2571 } // namespace blink 2368 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698