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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
42 #include "core/css/MediaList.h" | 42 #include "core/css/MediaList.h" |
43 #include "core/css/MediaQuery.h" | 43 #include "core/css/MediaQuery.h" |
44 #include "core/css/StylePropertySet.h" | 44 #include "core/css/StylePropertySet.h" |
45 #include "core/css/StyleRule.h" | 45 #include "core/css/StyleRule.h" |
46 #include "core/css/StyleSheet.h" | 46 #include "core/css/StyleSheet.h" |
47 #include "core/css/StyleSheetContents.h" | 47 #include "core/css/StyleSheetContents.h" |
48 #include "core/css/StyleSheetList.h" | 48 #include "core/css/StyleSheetList.h" |
49 #include "core/css/resolver/StyleResolver.h" | 49 #include "core/css/resolver/StyleResolver.h" |
50 #include "core/dom/Node.h" | 50 #include "core/dom/Node.h" |
51 #include "core/dom/NodeList.h" | 51 #include "core/dom/NodeList.h" |
52 #include "core/dom/VisitedLinkState.h" | |
53 #include "core/fetch/CSSStyleSheetResource.h" | 52 #include "core/fetch/CSSStyleSheetResource.h" |
54 #include "core/fetch/ResourceClient.h" | 53 #include "core/fetch/ResourceClient.h" |
55 #include "core/fetch/ResourceFetcher.h" | 54 #include "core/fetch/ResourceFetcher.h" |
56 #include "core/fetch/StyleSheetResourceClient.h" | 55 #include "core/fetch/StyleSheetResourceClient.h" |
57 #include "core/frame/LocalFrame.h" | 56 #include "core/frame/LocalFrame.h" |
58 #include "core/html/HTMLHeadElement.h" | 57 #include "core/html/HTMLHeadElement.h" |
59 #include "core/inspector/InspectorHistory.h" | 58 #include "core/inspector/InspectorHistory.h" |
60 #include "core/inspector/InspectorPageAgent.h" | 59 #include "core/inspector/InspectorPageAgent.h" |
61 #include "core/inspector/InspectorResourceAgent.h" | 60 #include "core/inspector/InspectorResourceAgent.h" |
62 #include "core/inspector/InspectorState.h" | 61 #include "core/inspector/InspectorState.h" |
63 #include "core/inspector/InstrumentingAgents.h" | 62 #include "core/inspector/InstrumentingAgents.h" |
64 #include "core/loader/DocumentLoader.h" | 63 #include "core/loader/DocumentLoader.h" |
65 #include "core/page/Page.h" | 64 #include "core/page/Page.h" |
66 #include "core/rendering/InlineTextBox.h" | 65 #include "core/rendering/InlineTextBox.h" |
67 #include "core/rendering/RenderObject.h" | 66 #include "core/rendering/RenderObject.h" |
68 #include "core/rendering/RenderText.h" | 67 #include "core/rendering/RenderText.h" |
69 #include "core/rendering/RenderTextFragment.h" | 68 #include "core/rendering/RenderTextFragment.h" |
70 #include "core/rendering/style/RenderStyleConstants.h" | |
71 #include "platform/fonts/Font.h" | 69 #include "platform/fonts/Font.h" |
72 #include "platform/fonts/GlyphBuffer.h" | 70 #include "platform/fonts/GlyphBuffer.h" |
73 #include "platform/fonts/WidthIterator.h" | 71 #include "platform/fonts/WidthIterator.h" |
74 #include "platform/text/TextRun.h" | 72 #include "platform/text/TextRun.h" |
75 #include "wtf/CurrentTime.h" | 73 #include "wtf/CurrentTime.h" |
76 #include "wtf/text/CString.h" | 74 #include "wtf/text/CString.h" |
77 #include "wtf/text/StringConcatenate.h" | 75 #include "wtf/text/StringConcatenate.h" |
78 | 76 |
79 namespace CSSAgentState { | 77 namespace CSSAgentState { |
80 static const char cssAgentEnabled[] = "cssAgentEnabled"; | 78 static const char cssAgentEnabled[] = "cssAgentEnabled"; |
(...skipping 597 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
678 return; | 676 return; |
679 | 677 |
680 // FIXME: It's really gross for the inspector to reach in and access StyleRe
solver | 678 // FIXME: It's really gross for the inspector to reach in and access StyleRe
solver |
681 // directly here. We need to provide the Inspector better APIs to get this i
nformation | 679 // directly here. We need to provide the Inspector better APIs to get this i
nformation |
682 // without grabbing at internal style classes! | 680 // without grabbing at internal style classes! |
683 | 681 |
684 // Matched rules. | 682 // Matched rules. |
685 StyleResolver& styleResolver = ownerDocument->ensureStyleResolver(); | 683 StyleResolver& styleResolver = ownerDocument->ensureStyleResolver(); |
686 | 684 |
687 RefPtrWillBeRawPtr<CSSRuleList> matchedRules = styleResolver.pseudoCSSRulesF
orElement(element, elementPseudoId, StyleResolver::AllCSSRules); | 685 RefPtrWillBeRawPtr<CSSRuleList> matchedRules = styleResolver.pseudoCSSRulesF
orElement(element, elementPseudoId, StyleResolver::AllCSSRules); |
688 matchedCSSRules = buildArrayForMatchedRuleList(matchedRules.get(), originalE
lement, true); | 686 matchedCSSRules = buildArrayForMatchedRuleList(matchedRules.get(), originalE
lement); |
689 | 687 |
690 // Pseudo elements. | 688 // Pseudo elements. |
691 if (!elementPseudoId && (!includePseudo || *includePseudo)) { | 689 if (!elementPseudoId && (!includePseudo || *includePseudo)) { |
692 RefPtr<TypeBuilder::Array<TypeBuilder::CSS::PseudoIdMatches> > pseudoEle
ments = TypeBuilder::Array<TypeBuilder::CSS::PseudoIdMatches>::create(); | 690 RefPtr<TypeBuilder::Array<TypeBuilder::CSS::PseudoIdMatches> > pseudoEle
ments = TypeBuilder::Array<TypeBuilder::CSS::PseudoIdMatches>::create(); |
693 for (PseudoId pseudoId = FIRST_PUBLIC_PSEUDOID; pseudoId < AFTER_LAST_IN
TERNAL_PSEUDOID; pseudoId = static_cast<PseudoId>(pseudoId + 1)) { | 691 for (PseudoId pseudoId = FIRST_PUBLIC_PSEUDOID; pseudoId < AFTER_LAST_IN
TERNAL_PSEUDOID; pseudoId = static_cast<PseudoId>(pseudoId + 1)) { |
694 RefPtrWillBeRawPtr<CSSRuleList> matchedRules = styleResolver.pseudoC
SSRulesForElement(element, pseudoId, StyleResolver::AllCSSRules); | 692 RefPtrWillBeRawPtr<CSSRuleList> matchedRules = styleResolver.pseudoC
SSRulesForElement(element, pseudoId, StyleResolver::AllCSSRules); |
695 if (matchedRules && matchedRules->length()) { | 693 if (matchedRules && matchedRules->length()) { |
696 RefPtr<TypeBuilder::CSS::PseudoIdMatches> matches = TypeBuilder:
:CSS::PseudoIdMatches::create() | 694 RefPtr<TypeBuilder::CSS::PseudoIdMatches> matches = TypeBuilder:
:CSS::PseudoIdMatches::create() |
697 .setPseudoId(static_cast<int>(pseudoId)) | 695 .setPseudoId(static_cast<int>(pseudoId)) |
698 .setMatches(buildArrayForMatchedRuleList(matchedRules.get(),
element, false)); | 696 .setMatches(buildArrayForMatchedRuleList(matchedRules.get(),
element)); |
699 pseudoElements->addItem(matches.release()); | 697 pseudoElements->addItem(matches.release()); |
700 } | 698 } |
701 } | 699 } |
702 | 700 |
703 pseudoIdMatches = pseudoElements.release(); | 701 pseudoIdMatches = pseudoElements.release(); |
704 } | 702 } |
705 | 703 |
706 // Inherited styles. | 704 // Inherited styles. |
707 if (!elementPseudoId && (!includeInherited || *includeInherited)) { | 705 if (!elementPseudoId && (!includeInherited || *includeInherited)) { |
708 RefPtr<TypeBuilder::Array<TypeBuilder::CSS::InheritedStyleEntry> > entri
es = TypeBuilder::Array<TypeBuilder::CSS::InheritedStyleEntry>::create(); | 706 RefPtr<TypeBuilder::Array<TypeBuilder::CSS::InheritedStyleEntry> > entri
es = TypeBuilder::Array<TypeBuilder::CSS::InheritedStyleEntry>::create(); |
709 Element* parentElement = element->parentElement(); | 707 Element* parentElement = element->parentElement(); |
710 while (parentElement) { | 708 while (parentElement) { |
711 StyleResolver& parentStyleResolver = parentElement->ownerDocument()-
>ensureStyleResolver(); | 709 StyleResolver& parentStyleResolver = parentElement->ownerDocument()-
>ensureStyleResolver(); |
712 RefPtrWillBeRawPtr<CSSRuleList> parentMatchedRules = parentStyleReso
lver.cssRulesForElement(parentElement, StyleResolver::AllCSSRules); | 710 RefPtrWillBeRawPtr<CSSRuleList> parentMatchedRules = parentStyleReso
lver.cssRulesForElement(parentElement, StyleResolver::AllCSSRules); |
713 RefPtr<TypeBuilder::CSS::InheritedStyleEntry> entry = TypeBuilder::C
SS::InheritedStyleEntry::create() | 711 RefPtr<TypeBuilder::CSS::InheritedStyleEntry> entry = TypeBuilder::C
SS::InheritedStyleEntry::create() |
714 .setMatchedCSSRules(buildArrayForMatchedRuleList(parentMatchedRu
les.get(), parentElement, true)); | 712 .setMatchedCSSRules(buildArrayForMatchedRuleList(parentMatchedRu
les.get(), parentElement)); |
715 if (parentElement->style() && parentElement->style()->length()) { | 713 if (parentElement->style() && parentElement->style()->length()) { |
716 InspectorStyleSheetForInlineStyle* styleSheet = asInspectorStyle
Sheet(parentElement); | 714 InspectorStyleSheetForInlineStyle* styleSheet = asInspectorStyle
Sheet(parentElement); |
717 if (styleSheet) | 715 if (styleSheet) |
718 entry->setInlineStyle(styleSheet->buildObjectForStyle(styleS
heet->styleForId(InspectorCSSId(styleSheet->id(), 0)))); | 716 entry->setInlineStyle(styleSheet->buildObjectForStyle(styleS
heet->styleForId(InspectorCSSId(styleSheet->id(), 0)))); |
719 } | 717 } |
720 | 718 |
721 entries->addItem(entry.release()); | 719 entries->addItem(entry.release()); |
722 parentElement = parentElement->parentElement(); | 720 parentElement = parentElement->parentElement(); |
723 } | 721 } |
724 | 722 |
(...skipping 606 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1331 // According to http://www.w3.org/TR/css3-selectors/#pseudo-elements, "Only
one pseudo-element may appear per selector." | 1329 // According to http://www.w3.org/TR/css3-selectors/#pseudo-elements, "Only
one pseudo-element may appear per selector." |
1332 // As such, check the last selector in the tag history. | 1330 // As such, check the last selector in the tag history. |
1333 for (; !selector->isLastInTagHistory(); ++selector) { } | 1331 for (; !selector->isLastInTagHistory(); ++selector) { } |
1334 PseudoId selectorPseudoId = selector->matchesPseudoElement() ? CSSSelector::
pseudoId(selector->pseudoType()) : NOPSEUDO; | 1332 PseudoId selectorPseudoId = selector->matchesPseudoElement() ? CSSSelector::
pseudoId(selector->pseudoType()) : NOPSEUDO; |
1335 | 1333 |
1336 // FIXME: This only covers the case of matching pseudo-element selectors aga
inst PseudoElements. | 1334 // FIXME: This only covers the case of matching pseudo-element selectors aga
inst PseudoElements. |
1337 // We should come up with a solution for matching pseudo-element selectors a
gainst ordinary Elements, too. | 1335 // We should come up with a solution for matching pseudo-element selectors a
gainst ordinary Elements, too. |
1338 return selectorPseudoId == elementPseudoId; | 1336 return selectorPseudoId == elementPseudoId; |
1339 } | 1337 } |
1340 | 1338 |
1341 static inline bool matchesElement(const CSSSelector& selector, Element& element) | 1339 PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::RuleMatch> > InspectorCSSAgent::
buildArrayForMatchedRuleList(CSSRuleList* ruleList, Element* element) |
1342 { | |
1343 SelectorChecker selectorChecker(element.document(), SelectorChecker::Queryin
gRules); | |
1344 SelectorChecker::SelectorCheckingContext selectorCheckingContext(selector, &
element, SelectorChecker::VisitedMatchEnabled); | |
1345 selectorCheckingContext.behaviorAtBoundary = SelectorChecker::StaysWithinTre
eScope; | |
1346 selectorCheckingContext.scope = !element.isDocumentNode() ? &element : 0; | |
1347 | |
1348 if (selectorChecker.match(selectorCheckingContext, DOMSiblingTraversalStrate
gy()) == SelectorChecker::SelectorMatches) | |
1349 return true; | |
1350 | |
1351 SelectorChecker::SelectorCheckingContext shadowDOMContext(selector, &element
, SelectorChecker::VisitedMatchEnabled); | |
1352 shadowDOMContext.behaviorAtBoundary = SelectorChecker::ScopeIsShadowHost; | |
1353 shadowDOMContext.scope = !element.isDocumentNode() ? &element : 0; | |
1354 return selectorChecker.match(shadowDOMContext, DOMSiblingTraversalStrategy()
) == SelectorChecker::SelectorMatches; | |
1355 } | |
1356 | |
1357 EInsideLink InspectorCSSAgent::linkStateForElement(Element* element) | |
1358 { | |
1359 if (!element->isLink()) | |
1360 return NotInsideLink; | |
1361 | |
1362 VisitedLinkState& visitedLinkState = element->ownerDocument()->visitedLinkSt
ate(); | |
1363 EInsideLink linkState = visitedLinkState.determineLinkState(*element); | |
1364 bool forceVisited = forcePseudoState(element, CSSSelector::PseudoVisited); | |
1365 if (forceVisited) | |
1366 linkState = InsideVisitedLink; | |
1367 | |
1368 return linkState; | |
1369 } | |
1370 | |
1371 PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::RuleMatch> > InspectorCSSAgent::
buildArrayForMatchedRuleList(CSSRuleList* ruleList, Element* element, bool skipR
ulesWithoutMatchedSelectors) | |
1372 { | 1340 { |
1373 RefPtr<TypeBuilder::Array<TypeBuilder::CSS::RuleMatch> > result = TypeBuilde
r::Array<TypeBuilder::CSS::RuleMatch>::create(); | 1341 RefPtr<TypeBuilder::Array<TypeBuilder::CSS::RuleMatch> > result = TypeBuilde
r::Array<TypeBuilder::CSS::RuleMatch>::create(); |
1374 if (!ruleList) | 1342 if (!ruleList) |
1375 return result.release(); | 1343 return result.release(); |
1376 | 1344 |
1377 EInsideLink linkState = linkStateForElement(element); | |
1378 for (unsigned i = 0, size = ruleList->length(); i < size; ++i) { | 1345 for (unsigned i = 0, size = ruleList->length(); i < size; ++i) { |
1379 CSSStyleRule* rule = asCSSStyleRule(ruleList->item(i)); | 1346 CSSStyleRule* rule = asCSSStyleRule(ruleList->item(i)); |
1380 RefPtr<TypeBuilder::CSS::CSSRule> ruleObject = buildObjectForRule(rule); | 1347 RefPtr<TypeBuilder::CSS::CSSRule> ruleObject = buildObjectForRule(rule); |
1381 if (!ruleObject) | 1348 if (!ruleObject) |
1382 continue; | 1349 continue; |
1383 RefPtr<TypeBuilder::Array<int> > matchingSelectors = TypeBuilder::Array<
int>::create(); | 1350 RefPtr<TypeBuilder::Array<int> > matchingSelectors = TypeBuilder::Array<
int>::create(); |
1384 const CSSSelectorList& selectorList = rule->styleRule()->selectorList(); | 1351 const CSSSelectorList& selectorList = rule->styleRule()->selectorList(); |
1385 long index = 0; | 1352 long index = 0; |
1386 PseudoId elementPseudoId = element->pseudoId(); | 1353 PseudoId elementPseudoId = element->pseudoId(); |
1387 bool hasMatchingSelectors = false; | |
1388 for (const CSSSelector* selector = selectorList.first(); selector; selec
tor = CSSSelectorList::next(*selector)) { | 1354 for (const CSSSelector* selector = selectorList.first(); selector; selec
tor = CSSSelectorList::next(*selector)) { |
1389 const CSSSelector* firstTagHistorySelector = selector; | 1355 const CSSSelector* firstTagHistorySelector = selector; |
1390 bool matchedPseudo = false; | 1356 bool matched = false; |
1391 if (elementPseudoId) | 1357 if (elementPseudoId) |
1392 matchedPseudo = matchesPseudoElement(selector, elementPseudoId);
// Modifies |selector|. | 1358 matched = matchesPseudoElement(selector, elementPseudoId); // Mo
difies |selector|. |
1393 | 1359 matched |= element->matches(firstTagHistorySelector->selectorText(),
IGNORE_EXCEPTION); |
1394 bool matchedElement = matchesElement(*firstTagHistorySelector, *elem
ent); | 1360 if (matched) |
1395 if (matchedElement) { | |
1396 unsigned linkMatchType = SelectorChecker::determineLinkMatchType
(*firstTagHistorySelector); | |
1397 if (linkState == InsideUnvisitedLink) | |
1398 matchedElement = linkMatchType & SelectorChecker::MatchLink; | |
1399 else if (linkState == InsideVisitedLink) | |
1400 matchedElement = linkMatchType & SelectorChecker::MatchVisit
ed; | |
1401 } | |
1402 | |
1403 if (matchedPseudo || matchedElement) { | |
1404 matchingSelectors->addItem(index); | 1361 matchingSelectors->addItem(index); |
1405 hasMatchingSelectors = true; | |
1406 } | |
1407 ++index; | 1362 ++index; |
1408 } | 1363 } |
1409 if (skipRulesWithoutMatchedSelectors && !hasMatchingSelectors) | |
1410 continue; | |
1411 RefPtr<TypeBuilder::CSS::RuleMatch> match = TypeBuilder::CSS::RuleMatch:
:create() | 1364 RefPtr<TypeBuilder::CSS::RuleMatch> match = TypeBuilder::CSS::RuleMatch:
:create() |
1412 .setRule(ruleObject.release()) | 1365 .setRule(ruleObject.release()) |
1413 .setMatchingSelectors(matchingSelectors.release()); | 1366 .setMatchingSelectors(matchingSelectors.release()); |
1414 result->addItem(match); | 1367 result->addItem(match); |
1415 } | 1368 } |
1416 | 1369 |
1417 return result; | 1370 return result; |
1418 } | 1371 } |
1419 | 1372 |
1420 PassRefPtr<TypeBuilder::CSS::CSSStyle> InspectorCSSAgent::buildObjectForAttribut
esStyle(Element* element) | 1373 PassRefPtr<TypeBuilder::CSS::CSSStyle> InspectorCSSAgent::buildObjectForAttribut
esStyle(Element* element) |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1495 documentsToChange.add(element->ownerDocument()); | 1448 documentsToChange.add(element->ownerDocument()); |
1496 } | 1449 } |
1497 | 1450 |
1498 m_nodeIdToForcedPseudoState.clear(); | 1451 m_nodeIdToForcedPseudoState.clear(); |
1499 for (HashSet<Document*>::iterator it = documentsToChange.begin(), end = docu
mentsToChange.end(); it != end; ++it) | 1452 for (HashSet<Document*>::iterator it = documentsToChange.begin(), end = docu
mentsToChange.end(); it != end; ++it) |
1500 (*it)->setNeedsStyleRecalc(SubtreeStyleChange); | 1453 (*it)->setNeedsStyleRecalc(SubtreeStyleChange); |
1501 } | 1454 } |
1502 | 1455 |
1503 } // namespace WebCore | 1456 } // namespace WebCore |
1504 | 1457 |
OLD | NEW |