OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |