Chromium Code Reviews| 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 30 matching lines...) Expand all Loading... | |
| 41 #include "core/css/CSSStyleSheet.h" | 41 #include "core/css/CSSStyleSheet.h" |
| 42 #include "core/css/MediaList.h" | 42 #include "core/css/MediaList.h" |
| 43 #include "core/css/StylePropertySet.h" | 43 #include "core/css/StylePropertySet.h" |
| 44 #include "core/css/StyleRule.h" | 44 #include "core/css/StyleRule.h" |
| 45 #include "core/css/StyleSheet.h" | 45 #include "core/css/StyleSheet.h" |
| 46 #include "core/css/StyleSheetContents.h" | 46 #include "core/css/StyleSheetContents.h" |
| 47 #include "core/css/StyleSheetList.h" | 47 #include "core/css/StyleSheetList.h" |
| 48 #include "core/css/resolver/StyleResolver.h" | 48 #include "core/css/resolver/StyleResolver.h" |
| 49 #include "core/dom/Node.h" | 49 #include "core/dom/Node.h" |
| 50 #include "core/dom/NodeList.h" | 50 #include "core/dom/NodeList.h" |
| 51 #include "core/dom/VisitedLinkState.h" | |
| 51 #include "core/fetch/CSSStyleSheetResource.h" | 52 #include "core/fetch/CSSStyleSheetResource.h" |
| 52 #include "core/fetch/ResourceClient.h" | 53 #include "core/fetch/ResourceClient.h" |
| 53 #include "core/fetch/ResourceFetcher.h" | 54 #include "core/fetch/ResourceFetcher.h" |
| 54 #include "core/fetch/StyleSheetResourceClient.h" | 55 #include "core/fetch/StyleSheetResourceClient.h" |
| 55 #include "core/frame/LocalFrame.h" | 56 #include "core/frame/LocalFrame.h" |
| 56 #include "core/html/HTMLHeadElement.h" | 57 #include "core/html/HTMLHeadElement.h" |
| 57 #include "core/inspector/InspectorHistory.h" | 58 #include "core/inspector/InspectorHistory.h" |
| 58 #include "core/inspector/InspectorPageAgent.h" | 59 #include "core/inspector/InspectorPageAgent.h" |
| 59 #include "core/inspector/InspectorResourceAgent.h" | 60 #include "core/inspector/InspectorResourceAgent.h" |
| 60 #include "core/inspector/InspectorState.h" | 61 #include "core/inspector/InspectorState.h" |
| 61 #include "core/inspector/InstrumentingAgents.h" | 62 #include "core/inspector/InstrumentingAgents.h" |
| 62 #include "core/loader/DocumentLoader.h" | 63 #include "core/loader/DocumentLoader.h" |
| 63 #include "core/page/Page.h" | 64 #include "core/page/Page.h" |
| 64 #include "core/rendering/InlineTextBox.h" | 65 #include "core/rendering/InlineTextBox.h" |
| 65 #include "core/rendering/RenderObject.h" | 66 #include "core/rendering/RenderObject.h" |
| 66 #include "core/rendering/RenderText.h" | 67 #include "core/rendering/RenderText.h" |
| 67 #include "core/rendering/RenderTextFragment.h" | 68 #include "core/rendering/RenderTextFragment.h" |
| 69 #include "core/rendering/style/RenderStyleConstants.h" | |
| 68 #include "platform/fonts/Font.h" | 70 #include "platform/fonts/Font.h" |
| 69 #include "platform/fonts/GlyphBuffer.h" | 71 #include "platform/fonts/GlyphBuffer.h" |
| 70 #include "platform/fonts/WidthIterator.h" | 72 #include "platform/fonts/WidthIterator.h" |
| 71 #include "platform/text/TextRun.h" | 73 #include "platform/text/TextRun.h" |
| 72 #include "wtf/CurrentTime.h" | 74 #include "wtf/CurrentTime.h" |
| 73 #include "wtf/text/CString.h" | 75 #include "wtf/text/CString.h" |
| 74 #include "wtf/text/StringConcatenate.h" | 76 #include "wtf/text/StringConcatenate.h" |
| 75 | 77 |
| 76 namespace CSSAgentState { | 78 namespace CSSAgentState { |
| 77 static const char cssAgentEnabled[] = "cssAgentEnabled"; | 79 static const char cssAgentEnabled[] = "cssAgentEnabled"; |
| (...skipping 582 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 660 return; | 662 return; |
| 661 | 663 |
| 662 // FIXME: It's really gross for the inspector to reach in and access StyleRe solver | 664 // FIXME: It's really gross for the inspector to reach in and access StyleRe solver |
| 663 // directly here. We need to provide the Inspector better APIs to get this i nformation | 665 // directly here. We need to provide the Inspector better APIs to get this i nformation |
| 664 // without grabbing at internal style classes! | 666 // without grabbing at internal style classes! |
| 665 | 667 |
| 666 // Matched rules. | 668 // Matched rules. |
| 667 StyleResolver& styleResolver = ownerDocument->ensureStyleResolver(); | 669 StyleResolver& styleResolver = ownerDocument->ensureStyleResolver(); |
| 668 | 670 |
| 669 RefPtrWillBeRawPtr<CSSRuleList> matchedRules = styleResolver.pseudoCSSRulesF orElement(element, elementPseudoId, StyleResolver::AllCSSRules); | 671 RefPtrWillBeRawPtr<CSSRuleList> matchedRules = styleResolver.pseudoCSSRulesF orElement(element, elementPseudoId, StyleResolver::AllCSSRules); |
| 670 matchedCSSRules = buildArrayForMatchedRuleList(matchedRules.get(), originalE lement); | 672 matchedCSSRules = buildArrayForMatchedRuleList(matchedRules.get(), originalE lement, true); |
| 671 | 673 |
| 672 // Pseudo elements. | 674 // Pseudo elements. |
| 673 if (!elementPseudoId && (!includePseudo || *includePseudo)) { | 675 if (!elementPseudoId && (!includePseudo || *includePseudo)) { |
| 674 RefPtr<TypeBuilder::Array<TypeBuilder::CSS::PseudoIdMatches> > pseudoEle ments = TypeBuilder::Array<TypeBuilder::CSS::PseudoIdMatches>::create(); | 676 RefPtr<TypeBuilder::Array<TypeBuilder::CSS::PseudoIdMatches> > pseudoEle ments = TypeBuilder::Array<TypeBuilder::CSS::PseudoIdMatches>::create(); |
| 675 for (PseudoId pseudoId = FIRST_PUBLIC_PSEUDOID; pseudoId < AFTER_LAST_IN TERNAL_PSEUDOID; pseudoId = static_cast<PseudoId>(pseudoId + 1)) { | 677 for (PseudoId pseudoId = FIRST_PUBLIC_PSEUDOID; pseudoId < AFTER_LAST_IN TERNAL_PSEUDOID; pseudoId = static_cast<PseudoId>(pseudoId + 1)) { |
| 676 RefPtrWillBeRawPtr<CSSRuleList> matchedRules = styleResolver.pseudoC SSRulesForElement(element, pseudoId, StyleResolver::AllCSSRules); | 678 RefPtrWillBeRawPtr<CSSRuleList> matchedRules = styleResolver.pseudoC SSRulesForElement(element, pseudoId, StyleResolver::AllCSSRules); |
| 677 if (matchedRules && matchedRules->length()) { | 679 if (matchedRules && matchedRules->length()) { |
| 678 RefPtr<TypeBuilder::CSS::PseudoIdMatches> matches = TypeBuilder: :CSS::PseudoIdMatches::create() | 680 RefPtr<TypeBuilder::CSS::PseudoIdMatches> matches = TypeBuilder: :CSS::PseudoIdMatches::create() |
| 679 .setPseudoId(static_cast<int>(pseudoId)) | 681 .setPseudoId(static_cast<int>(pseudoId)) |
| 680 .setMatches(buildArrayForMatchedRuleList(matchedRules.get(), element)); | 682 .setMatches(buildArrayForMatchedRuleList(matchedRules.get(), element, false)); |
| 681 pseudoElements->addItem(matches.release()); | 683 pseudoElements->addItem(matches.release()); |
| 682 } | 684 } |
| 683 } | 685 } |
| 684 | 686 |
| 685 pseudoIdMatches = pseudoElements.release(); | 687 pseudoIdMatches = pseudoElements.release(); |
| 686 } | 688 } |
| 687 | 689 |
| 688 // Inherited styles. | 690 // Inherited styles. |
| 689 if (!elementPseudoId && (!includeInherited || *includeInherited)) { | 691 if (!elementPseudoId && (!includeInherited || *includeInherited)) { |
| 690 RefPtr<TypeBuilder::Array<TypeBuilder::CSS::InheritedStyleEntry> > entri es = TypeBuilder::Array<TypeBuilder::CSS::InheritedStyleEntry>::create(); | 692 RefPtr<TypeBuilder::Array<TypeBuilder::CSS::InheritedStyleEntry> > entri es = TypeBuilder::Array<TypeBuilder::CSS::InheritedStyleEntry>::create(); |
| 691 Element* parentElement = element->parentElement(); | 693 Element* parentElement = element->parentElement(); |
| 692 while (parentElement) { | 694 while (parentElement) { |
| 693 StyleResolver& parentStyleResolver = parentElement->ownerDocument()- >ensureStyleResolver(); | 695 StyleResolver& parentStyleResolver = parentElement->ownerDocument()- >ensureStyleResolver(); |
| 694 RefPtrWillBeRawPtr<CSSRuleList> parentMatchedRules = parentStyleReso lver.cssRulesForElement(parentElement, StyleResolver::AllCSSRules); | 696 RefPtrWillBeRawPtr<CSSRuleList> parentMatchedRules = parentStyleReso lver.cssRulesForElement(parentElement, StyleResolver::AllCSSRules); |
| 695 RefPtr<TypeBuilder::CSS::InheritedStyleEntry> entry = TypeBuilder::C SS::InheritedStyleEntry::create() | 697 RefPtr<TypeBuilder::CSS::InheritedStyleEntry> entry = TypeBuilder::C SS::InheritedStyleEntry::create() |
| 696 .setMatchedCSSRules(buildArrayForMatchedRuleList(parentMatchedRu les.get(), parentElement)); | 698 .setMatchedCSSRules(buildArrayForMatchedRuleList(parentMatchedRu les.get(), parentElement, true)); |
| 697 if (parentElement->style() && parentElement->style()->length()) { | 699 if (parentElement->style() && parentElement->style()->length()) { |
| 698 InspectorStyleSheetForInlineStyle* styleSheet = asInspectorStyle Sheet(parentElement); | 700 InspectorStyleSheetForInlineStyle* styleSheet = asInspectorStyle Sheet(parentElement); |
| 699 if (styleSheet) | 701 if (styleSheet) |
| 700 entry->setInlineStyle(styleSheet->buildObjectForStyle(styleS heet->styleForId(InspectorCSSId(styleSheet->id(), 0)))); | 702 entry->setInlineStyle(styleSheet->buildObjectForStyle(styleS heet->styleForId(InspectorCSSId(styleSheet->id(), 0)))); |
| 701 } | 703 } |
| 702 | 704 |
| 703 entries->addItem(entry.release()); | 705 entries->addItem(entry.release()); |
| 704 parentElement = parentElement->parentElement(); | 706 parentElement = parentElement->parentElement(); |
| 705 } | 707 } |
| 706 | 708 |
| (...skipping 561 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1268 // According to http://www.w3.org/TR/css3-selectors/#pseudo-elements, "Only one pseudo-element may appear per selector." | 1270 // According to http://www.w3.org/TR/css3-selectors/#pseudo-elements, "Only one pseudo-element may appear per selector." |
| 1269 // As such, check the last selector in the tag history. | 1271 // As such, check the last selector in the tag history. |
| 1270 for (; !selector->isLastInTagHistory(); ++selector) { } | 1272 for (; !selector->isLastInTagHistory(); ++selector) { } |
| 1271 PseudoId selectorPseudoId = selector->matchesPseudoElement() ? CSSSelector:: pseudoId(selector->pseudoType()) : NOPSEUDO; | 1273 PseudoId selectorPseudoId = selector->matchesPseudoElement() ? CSSSelector:: pseudoId(selector->pseudoType()) : NOPSEUDO; |
| 1272 | 1274 |
| 1273 // FIXME: This only covers the case of matching pseudo-element selectors aga inst PseudoElements. | 1275 // FIXME: This only covers the case of matching pseudo-element selectors aga inst PseudoElements. |
| 1274 // We should come up with a solution for matching pseudo-element selectors a gainst ordinary Elements, too. | 1276 // We should come up with a solution for matching pseudo-element selectors a gainst ordinary Elements, too. |
| 1275 return selectorPseudoId == elementPseudoId; | 1277 return selectorPseudoId == elementPseudoId; |
| 1276 } | 1278 } |
| 1277 | 1279 |
| 1278 PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::RuleMatch> > InspectorCSSAgent:: buildArrayForMatchedRuleList(CSSRuleList* ruleList, Element* element) | 1280 static inline bool matchesElement(const CSSSelector& selector, Element& element) |
| 1281 { | |
| 1282 if (selector.pseudoType() != CSSSelector::PseudoVisited && selector.pseudoTy pe() != CSSSelector::PseudoLink) | |
| 1283 return true; | |
| 1284 SelectorChecker selectorChecker(element.document(), SelectorChecker::Queryin gRules); | |
| 1285 SelectorChecker::SelectorCheckingContext selectorCheckingContext(selector, & element, SelectorChecker::VisitedMatchEnabled); | |
| 1286 selectorCheckingContext.behaviorAtBoundary = SelectorChecker::StaysWithinTre eScope; | |
| 1287 selectorCheckingContext.scope = !element.isDocumentNode() ? &element : 0; | |
| 1288 return selectorChecker.match(selectorCheckingContext, DOMSiblingTraversalStr ategy()) == SelectorChecker::SelectorMatches; | |
| 1289 } | |
| 1290 | |
| 1291 EInsideLink InspectorCSSAgent::linkStateForElement(Element* element) | |
| 1292 { | |
| 1293 EInsideLink linkState = NotInsideLink; | |
| 1294 if (element->isLink()) { | |
|
apavlov
2014/05/26 14:03:40
Early bailout:
if (!element->isLink())
return
| |
| 1295 VisitedLinkState& visitedLinkState = element->ownerDocument()->visitedLi nkState(); | |
| 1296 linkState = visitedLinkState.determineLinkState(*element); | |
| 1297 bool forceVisited = forcePseudoState(element, CSSSelector::PseudoVisited ); | |
| 1298 if (forceVisited) | |
| 1299 linkState = InsideVisitedLink; | |
| 1300 } | |
| 1301 return linkState; | |
| 1302 } | |
| 1303 | |
| 1304 PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::RuleMatch> > InspectorCSSAgent:: buildArrayForMatchedRuleList(CSSRuleList* ruleList, Element* element, bool skipR ulesWithoutMatchedSelectors) | |
| 1279 { | 1305 { |
| 1280 RefPtr<TypeBuilder::Array<TypeBuilder::CSS::RuleMatch> > result = TypeBuilde r::Array<TypeBuilder::CSS::RuleMatch>::create(); | 1306 RefPtr<TypeBuilder::Array<TypeBuilder::CSS::RuleMatch> > result = TypeBuilde r::Array<TypeBuilder::CSS::RuleMatch>::create(); |
| 1281 if (!ruleList) | 1307 if (!ruleList) |
| 1282 return result.release(); | 1308 return result.release(); |
| 1283 | 1309 |
| 1310 EInsideLink linkState = linkStateForElement(element); | |
| 1284 for (unsigned i = 0, size = ruleList->length(); i < size; ++i) { | 1311 for (unsigned i = 0, size = ruleList->length(); i < size; ++i) { |
| 1285 CSSStyleRule* rule = asCSSStyleRule(ruleList->item(i)); | 1312 CSSStyleRule* rule = asCSSStyleRule(ruleList->item(i)); |
| 1286 RefPtr<TypeBuilder::CSS::CSSRule> ruleObject = buildObjectForRule(rule); | 1313 RefPtr<TypeBuilder::CSS::CSSRule> ruleObject = buildObjectForRule(rule); |
| 1287 if (!ruleObject) | 1314 if (!ruleObject) |
| 1288 continue; | 1315 continue; |
| 1289 RefPtr<TypeBuilder::Array<int> > matchingSelectors = TypeBuilder::Array< int>::create(); | 1316 RefPtr<TypeBuilder::Array<int> > matchingSelectors = TypeBuilder::Array< int>::create(); |
| 1290 const CSSSelectorList& selectorList = rule->styleRule()->selectorList(); | 1317 const CSSSelectorList& selectorList = rule->styleRule()->selectorList(); |
| 1291 long index = 0; | 1318 long index = 0; |
| 1292 PseudoId elementPseudoId = element->pseudoId(); | 1319 PseudoId elementPseudoId = element->pseudoId(); |
| 1320 bool hasMatchingSelectors = false; | |
| 1293 for (const CSSSelector* selector = selectorList.first(); selector; selec tor = CSSSelectorList::next(*selector)) { | 1321 for (const CSSSelector* selector = selectorList.first(); selector; selec tor = CSSSelectorList::next(*selector)) { |
| 1294 const CSSSelector* firstTagHistorySelector = selector; | 1322 const CSSSelector* firstTagHistorySelector = selector; |
| 1295 bool matched = false; | 1323 bool matchedPseudo = false; |
| 1296 if (elementPseudoId) | 1324 if (elementPseudoId) |
| 1297 matched = matchesPseudoElement(selector, elementPseudoId); // Mo difies |selector|. | 1325 matchedPseudo = matchesPseudoElement(selector, elementPseudoId); // Modifies |selector|. |
| 1298 matched |= element->matches(firstTagHistorySelector->selectorText(), IGNORE_EXCEPTION); | 1326 |
| 1299 if (matched) | 1327 bool matchedElement = matchesElement(*firstTagHistorySelector, *elem ent); |
| 1328 if (matchedElement) { | |
| 1329 unsigned linkMatchType = SelectorChecker::determineLinkMatchType (*firstTagHistorySelector); | |
| 1330 if (linkState == InsideUnvisitedLink) | |
| 1331 matchedElement = linkMatchType & SelectorChecker::MatchLink; | |
| 1332 else if (linkState == InsideVisitedLink) | |
| 1333 matchedElement = linkMatchType & SelectorChecker::MatchVisit ed; | |
| 1334 } | |
| 1335 | |
| 1336 if (matchedPseudo || matchedElement) { | |
| 1300 matchingSelectors->addItem(index); | 1337 matchingSelectors->addItem(index); |
| 1338 hasMatchingSelectors = true; | |
| 1339 } | |
| 1301 ++index; | 1340 ++index; |
| 1302 } | 1341 } |
| 1342 if (skipRulesWithoutMatchedSelectors && !hasMatchingSelectors) | |
| 1343 continue; | |
| 1303 RefPtr<TypeBuilder::CSS::RuleMatch> match = TypeBuilder::CSS::RuleMatch: :create() | 1344 RefPtr<TypeBuilder::CSS::RuleMatch> match = TypeBuilder::CSS::RuleMatch: :create() |
| 1304 .setRule(ruleObject.release()) | 1345 .setRule(ruleObject.release()) |
| 1305 .setMatchingSelectors(matchingSelectors.release()); | 1346 .setMatchingSelectors(matchingSelectors.release()); |
| 1306 result->addItem(match); | 1347 result->addItem(match); |
| 1307 } | 1348 } |
| 1308 | 1349 |
| 1309 return result; | 1350 return result; |
| 1310 } | 1351 } |
| 1311 | 1352 |
| 1312 PassRefPtr<TypeBuilder::CSS::CSSStyle> InspectorCSSAgent::buildObjectForAttribut esStyle(Element* element) | 1353 PassRefPtr<TypeBuilder::CSS::CSSStyle> InspectorCSSAgent::buildObjectForAttribut esStyle(Element* element) |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1387 documentsToChange.add(element->ownerDocument()); | 1428 documentsToChange.add(element->ownerDocument()); |
| 1388 } | 1429 } |
| 1389 | 1430 |
| 1390 m_nodeIdToForcedPseudoState.clear(); | 1431 m_nodeIdToForcedPseudoState.clear(); |
| 1391 for (HashSet<Document*>::iterator it = documentsToChange.begin(), end = docu mentsToChange.end(); it != end; ++it) | 1432 for (HashSet<Document*>::iterator it = documentsToChange.begin(), end = docu mentsToChange.end(); it != end; ++it) |
| 1392 (*it)->setNeedsStyleRecalc(SubtreeStyleChange); | 1433 (*it)->setNeedsStyleRecalc(SubtreeStyleChange); |
| 1393 } | 1434 } |
| 1394 | 1435 |
| 1395 } // namespace WebCore | 1436 } // namespace WebCore |
| 1396 | 1437 |
| OLD | NEW |