|
Lines 59-65
a/Source/WebCore/css/StyleResolver.cpp_sec1
|
| 59 |
#include "CounterContent.h" |
59 |
#include "CounterContent.h" |
| 60 |
#include "CursorList.h" |
60 |
#include "CursorList.h" |
| 61 |
#include "DocumentStyleSheetCollection.h" |
61 |
#include "DocumentStyleSheetCollection.h" |
| 62 |
#include "ElementRuleCollector.h" |
|
|
| 63 |
#include "ElementShadow.h" |
62 |
#include "ElementShadow.h" |
| 64 |
#include "FontFeatureValue.h" |
63 |
#include "FontFeatureValue.h" |
| 65 |
#include "FontValue.h" |
64 |
#include "FontValue.h" |
|
Lines 87-93
a/Source/WebCore/css/StyleResolver.cpp_sec2
|
| 87 |
#include "NodeRenderStyle.h" |
86 |
#include "NodeRenderStyle.h" |
| 88 |
#include "NodeRenderingContext.h" |
87 |
#include "NodeRenderingContext.h" |
| 89 |
#include "Page.h" |
88 |
#include "Page.h" |
| 90 |
#include "PageRuleCollector.h" |
|
|
| 91 |
#include "Pair.h" |
89 |
#include "Pair.h" |
| 92 |
#include "PerspectiveTransformOperation.h" |
90 |
#include "PerspectiveTransformOperation.h" |
| 93 |
#include "QuotesData.h" |
91 |
#include "QuotesData.h" |
|
Lines 109-114
a/Source/WebCore/css/StyleResolver.cpp_sec3
|
| 109 |
#include "ShadowData.h" |
107 |
#include "ShadowData.h" |
| 110 |
#include "ShadowRoot.h" |
108 |
#include "ShadowRoot.h" |
| 111 |
#include "ShadowValue.h" |
109 |
#include "ShadowValue.h" |
|
|
110 |
#include "SiblingTraversalStrategies.h" |
| 112 |
#include "SkewTransformOperation.h" |
111 |
#include "SkewTransformOperation.h" |
| 113 |
#include "StyleBuilder.h" |
112 |
#include "StyleBuilder.h" |
| 114 |
#include "StyleCachedImage.h" |
113 |
#include "StyleCachedImage.h" |
|
Lines 211-216
if (isInitial) { \
a/Source/WebCore/css/StyleResolver.cpp_sec4
|
| 211 |
|
210 |
|
| 212 |
RenderStyle* StyleResolver::s_styleNotYetAvailable; |
211 |
RenderStyle* StyleResolver::s_styleNotYetAvailable; |
| 213 |
|
212 |
|
|
|
213 |
static StylePropertySet* leftToRightDeclaration() |
| 214 |
{ |
| 215 |
DEFINE_STATIC_LOCAL(RefPtr<StylePropertySet>, leftToRightDecl, (StylePropertySet::create())); |
| 216 |
if (leftToRightDecl->isEmpty()) |
| 217 |
leftToRightDecl->setProperty(CSSPropertyDirection, CSSValueLtr); |
| 218 |
return leftToRightDecl.get(); |
| 219 |
} |
| 220 |
|
| 221 |
static StylePropertySet* rightToLeftDeclaration() |
| 222 |
{ |
| 223 |
DEFINE_STATIC_LOCAL(RefPtr<StylePropertySet>, rightToLeftDecl, (StylePropertySet::create())); |
| 224 |
if (rightToLeftDecl->isEmpty()) |
| 225 |
rightToLeftDecl->setProperty(CSSPropertyDirection, CSSValueRtl); |
| 226 |
return rightToLeftDecl.get(); |
| 227 |
} |
| 228 |
|
| 229 |
|
| 230 |
inline StaticCSSRuleList* StyleResolver::State::ensureRuleList() |
| 231 |
{ |
| 232 |
if (!m_ruleList) |
| 233 |
m_ruleList = StaticCSSRuleList::create(); |
| 234 |
return m_ruleList.get(); |
| 235 |
} |
| 236 |
|
| 214 |
inline void StyleResolver::State::cacheBorderAndBackground() |
237 |
inline void StyleResolver::State::cacheBorderAndBackground() |
| 215 |
{ |
238 |
{ |
| 216 |
m_hasUAAppearance = m_style->hasAppearance(); |
239 |
m_hasUAAppearance = m_style->hasAppearance(); |
|
Lines 228-233
inline void StyleResolver::State::clear()
a/Source/WebCore/css/StyleResolver.cpp_sec5
|
| 228 |
m_parentStyle = 0; |
251 |
m_parentStyle = 0; |
| 229 |
m_parentNode = 0; |
252 |
m_parentNode = 0; |
| 230 |
m_regionForStyling = 0; |
253 |
m_regionForStyling = 0; |
|
|
254 |
m_ruleList = 0; |
| 255 |
m_matchedRules.clear(); |
| 231 |
m_pendingImageProperties.clear(); |
256 |
m_pendingImageProperties.clear(); |
| 232 |
#if ENABLE(CSS_SHADERS) |
257 |
#if ENABLE(CSS_SHADERS) |
| 233 |
m_hasPendingShaders = false; |
258 |
m_hasPendingShaders = false; |
|
Lines 237-252
inline void StyleResolver::State::clear()
a/Source/WebCore/css/StyleResolver.cpp_sec6
|
| 237 |
#endif |
262 |
#endif |
| 238 |
} |
263 |
} |
| 239 |
|
264 |
|
| 240 |
void StyleResolver::MatchResult::addMatchedProperties(const StylePropertySet* properties, StyleRule* rule, unsigned linkMatchType, PropertyWhitelistType propertyWhitelistType) |
|
|
| 241 |
{ |
| 242 |
matchedProperties.grow(matchedProperties.size() + 1); |
| 243 |
StyleResolver::MatchedProperties& newProperties = matchedProperties.last(); |
| 244 |
newProperties.properties = const_cast<StylePropertySet*>(properties); |
| 245 |
newProperties.linkMatchType = linkMatchType; |
| 246 |
newProperties.whitelistType = propertyWhitelistType; |
| 247 |
matchedRules.append(rule); |
| 248 |
} |
| 249 |
|
| 250 |
StyleResolver::StyleResolver(Document* document, bool matchAuthorAndUserStyles) |
265 |
StyleResolver::StyleResolver(Document* document, bool matchAuthorAndUserStyles) |
| 251 |
: m_matchedPropertiesCacheAdditionsSinceLastSweep(0) |
266 |
: m_matchedPropertiesCacheAdditionsSinceLastSweep(0) |
| 252 |
, m_matchedPropertiesCacheSweepTimer(this, &StyleResolver::sweepMatchedPropertiesCache) |
267 |
, m_matchedPropertiesCacheSweepTimer(this, &StyleResolver::sweepMatchedPropertiesCache) |
|
Lines 390-395
void StyleResolver::sweepMatchedPropertiesCache(Timer<StyleResolver>*)
a/Source/WebCore/css/StyleResolver.cpp_sec7
|
| 390 |
m_matchedPropertiesCacheAdditionsSinceLastSweep = 0; |
405 |
m_matchedPropertiesCacheAdditionsSinceLastSweep = 0; |
| 391 |
} |
406 |
} |
| 392 |
|
407 |
|
|
|
408 |
void StyleResolver::addMatchedProperties(MatchResult& matchResult, const StylePropertySet* properties, StyleRule* rule, unsigned linkMatchType, PropertyWhitelistType propertyWhitelistType) |
| 409 |
{ |
| 410 |
matchResult.matchedProperties.grow(matchResult.matchedProperties.size() + 1); |
| 411 |
MatchedProperties& newProperties = matchResult.matchedProperties.last(); |
| 412 |
newProperties.properties = const_cast<StylePropertySet*>(properties); |
| 413 |
newProperties.linkMatchType = linkMatchType; |
| 414 |
newProperties.whitelistType = propertyWhitelistType; |
| 415 |
matchResult.matchedRules.append(rule); |
| 416 |
} |
| 417 |
|
| 418 |
inline void StyleResolver::addElementStyleProperties(MatchResult& result, const StylePropertySet* propertySet, bool isCacheable) |
| 419 |
{ |
| 420 |
if (!propertySet) |
| 421 |
return; |
| 422 |
result.ranges.lastAuthorRule = result.matchedProperties.size(); |
| 423 |
if (result.ranges.firstAuthorRule == -1) |
| 424 |
result.ranges.firstAuthorRule = result.ranges.lastAuthorRule; |
| 425 |
addMatchedProperties(result, propertySet); |
| 426 |
if (!isCacheable) |
| 427 |
result.isCacheable = false; |
| 428 |
} |
| 429 |
|
| 430 |
class MatchingUARulesScope { |
| 431 |
public: |
| 432 |
MatchingUARulesScope(); |
| 433 |
~MatchingUARulesScope(); |
| 434 |
|
| 435 |
static bool isMatchingUARules(); |
| 436 |
|
| 437 |
private: |
| 438 |
static bool m_matchingUARules; |
| 439 |
}; |
| 440 |
|
| 441 |
MatchingUARulesScope::MatchingUARulesScope() |
| 442 |
{ |
| 443 |
ASSERT(!m_matchingUARules); |
| 444 |
m_matchingUARules = true; |
| 445 |
} |
| 446 |
|
| 447 |
MatchingUARulesScope::~MatchingUARulesScope() |
| 448 |
{ |
| 449 |
m_matchingUARules = false; |
| 450 |
} |
| 451 |
|
| 452 |
inline bool MatchingUARulesScope::isMatchingUARules() |
| 453 |
{ |
| 454 |
return m_matchingUARules; |
| 455 |
} |
| 456 |
|
| 457 |
bool MatchingUARulesScope::m_matchingUARules = false; |
| 458 |
|
| 459 |
void StyleResolver::collectMatchingRules(const MatchRequest& matchRequest, RuleRange& ruleRange) |
| 460 |
{ |
| 461 |
ASSERT(matchRequest.ruleSet); |
| 462 |
ASSERT(m_state.element()); |
| 463 |
|
| 464 |
State& state = m_state; |
| 465 |
Element* element = state.element(); |
| 466 |
const StyledElement* styledElement = state.styledElement(); |
| 467 |
const AtomicString& pseudoId = element->shadowPseudoId(); |
| 468 |
if (!pseudoId.isEmpty()) { |
| 469 |
ASSERT(styledElement); |
| 470 |
collectMatchingRulesForList(matchRequest.ruleSet->shadowPseudoElementRules(pseudoId.impl()), matchRequest, ruleRange); |
| 471 |
} |
| 472 |
|
| 473 |
#if ENABLE(VIDEO_TRACK) |
| 474 |
if (element->isWebVTTElement()) |
| 475 |
collectMatchingRulesForList(matchRequest.ruleSet->cuePseudoRules(), matchRequest, ruleRange); |
| 476 |
#endif |
| 477 |
// Check whether other types of rules are applicable in the current tree scope. Criteria for this: |
| 478 |
// a) it's a UA rule |
| 479 |
// b) the tree scope allows author rules |
| 480 |
// c) the rules comes from a scoped style sheet within the same tree scope |
| 481 |
TreeScope* treeScope = element->treeScope(); |
| 482 |
if (!MatchingUARulesScope::isMatchingUARules() |
| 483 |
&& !treeScope->applyAuthorStyles() |
| 484 |
&& (!matchRequest.scope || matchRequest.scope->treeScope() != treeScope) |
| 485 |
&& matchRequest.behaviorAtBoundary == SelectorChecker::DoesNotCrossBoundary) |
| 486 |
return; |
| 487 |
|
| 488 |
// We need to collect the rules for id, class, tag, and everything else into a buffer and |
| 489 |
// then sort the buffer. |
| 490 |
if (element->hasID()) |
| 491 |
collectMatchingRulesForList(matchRequest.ruleSet->idRules(element->idForStyleResolution().impl()), matchRequest, ruleRange); |
| 492 |
if (styledElement && styledElement->hasClass()) { |
| 493 |
for (size_t i = 0; i < styledElement->classNames().size(); ++i) |
| 494 |
collectMatchingRulesForList(matchRequest.ruleSet->classRules(styledElement->classNames()[i].impl()), matchRequest, ruleRange); |
| 495 |
} |
| 496 |
|
| 497 |
if (element->isLink()) |
| 498 |
collectMatchingRulesForList(matchRequest.ruleSet->linkPseudoClassRules(), matchRequest, ruleRange); |
| 499 |
if (SelectorChecker::matchesFocusPseudoClass(element)) |
| 500 |
collectMatchingRulesForList(matchRequest.ruleSet->focusPseudoClassRules(), matchRequest, ruleRange); |
| 501 |
collectMatchingRulesForList(matchRequest.ruleSet->tagRules(element->localName().impl()), matchRequest, ruleRange); |
| 502 |
collectMatchingRulesForList(matchRequest.ruleSet->universalRules(), matchRequest, ruleRange); |
| 503 |
} |
| 504 |
|
| 505 |
void StyleResolver::collectMatchingRulesForRegion(const MatchRequest& matchRequest, RuleRange& ruleRange) |
| 506 |
{ |
| 507 |
if (!m_state.regionForStyling()) |
| 508 |
return; |
| 509 |
|
| 510 |
unsigned size = matchRequest.ruleSet->m_regionSelectorsAndRuleSets.size(); |
| 511 |
for (unsigned i = 0; i < size; ++i) { |
| 512 |
const CSSSelector* regionSelector = matchRequest.ruleSet->m_regionSelectorsAndRuleSets.at(i).selector; |
| 513 |
if (checkRegionSelector(regionSelector, static_cast<Element*>(m_state.regionForStyling()->node()))) { |
| 514 |
RuleSet* regionRules = matchRequest.ruleSet->m_regionSelectorsAndRuleSets.at(i).ruleSet.get(); |
| 515 |
ASSERT(regionRules); |
| 516 |
collectMatchingRules(MatchRequest(regionRules, matchRequest.includeEmptyRules, matchRequest.scope), ruleRange); |
| 517 |
} |
| 518 |
} |
| 519 |
} |
| 520 |
|
| 521 |
void StyleResolver::sortAndTransferMatchedRules(MatchResult& result) |
| 522 |
{ |
| 523 |
State& state = m_state; |
| 524 |
Vector<const RuleData*, 32>& matchedRules = state.matchedRules(); |
| 525 |
if (matchedRules.isEmpty()) |
| 526 |
return; |
| 527 |
|
| 528 |
sortMatchedRules(); |
| 529 |
|
| 530 |
if (state.mode() == SelectorChecker::CollectingRules) { |
| 531 |
for (unsigned i = 0; i < matchedRules.size(); ++i) |
| 532 |
state.ensureRuleList()->rules().append(matchedRules[i]->rule()->createCSSOMWrapper()); |
| 533 |
return; |
| 534 |
} |
| 535 |
|
| 536 |
// Now transfer the set of matched rules over to our list of declarations. |
| 537 |
for (unsigned i = 0; i < matchedRules.size(); i++) { |
| 538 |
if (state.style() && matchedRules[i]->containsUncommonAttributeSelector()) |
| 539 |
state.style()->setUnique(); |
| 540 |
addMatchedProperties(result, matchedRules[i]->rule()->properties(), matchedRules[i]->rule(), matchedRules[i]->linkMatchType(), matchedRules[i]->propertyWhitelistType()); |
| 541 |
} |
| 542 |
} |
| 543 |
|
| 544 |
void StyleResolver::matchScopedAuthorRules(MatchResult& result, bool includeEmptyRules) |
| 545 |
{ |
| 546 |
#if ENABLE(STYLE_SCOPED) || ENABLE(SHADOW_DOM) |
| 547 |
if (!m_scopeResolver) |
| 548 |
return; |
| 549 |
|
| 550 |
// Match scoped author rules by traversing the scoped element stack (rebuild it if it got inconsistent). |
| 551 |
if (m_scopeResolver->hasScopedStyles() && m_scopeResolver->ensureStackConsistency(m_state.element())) { |
| 552 |
bool applyAuthorStyles = m_state.element()->treeScope()->applyAuthorStyles(); |
| 553 |
bool documentScope = true; |
| 554 |
unsigned scopeSize = m_scopeResolver->stackSize(); |
| 555 |
for (unsigned i = 0; i < scopeSize; ++i) { |
| 556 |
m_state.matchedRules().clear(); |
| 557 |
result.ranges.lastAuthorRule = result.matchedProperties.size() - 1; |
| 558 |
|
| 559 |
const StyleScopeResolver::StackFrame& frame = m_scopeResolver->stackFrameAt(i); |
| 560 |
documentScope = documentScope && !frame.m_scope->isInShadowTree(); |
| 561 |
if (documentScope) { |
| 562 |
if (!applyAuthorStyles) |
| 563 |
continue; |
| 564 |
} else { |
| 565 |
if (!m_scopeResolver->matchesStyleBounds(frame)) |
| 566 |
continue; |
| 567 |
} |
| 568 |
|
| 569 |
MatchRequest matchRequest(frame.m_ruleSet, includeEmptyRules, frame.m_scope); |
| 570 |
RuleRange ruleRange = result.ranges.authorRuleRange(); |
| 571 |
collectMatchingRules(matchRequest, ruleRange); |
| 572 |
collectMatchingRulesForRegion(matchRequest, ruleRange); |
| 573 |
sortAndTransferMatchedRules(result); |
| 574 |
} |
| 575 |
} |
| 576 |
|
| 577 |
matchHostRules(result, includeEmptyRules); |
| 578 |
#else |
| 579 |
UNUSED_PARAM(result); |
| 580 |
UNUSED_PARAM(includeEmptyRules); |
| 581 |
#endif |
| 582 |
} |
| 583 |
|
| 393 |
inline bool StyleResolver::styleSharingCandidateMatchesHostRules() |
584 |
inline bool StyleResolver::styleSharingCandidateMatchesHostRules() |
| 394 |
{ |
585 |
{ |
| 395 |
#if ENABLE(SHADOW_DOM) |
586 |
#if ENABLE(SHADOW_DOM) |
|
Lines 399-404
inline bool StyleResolver::styleSharingCandidateMatchesHostRules()
a/Source/WebCore/css/StyleResolver.cpp_sec8
|
| 399 |
#endif |
590 |
#endif |
| 400 |
} |
591 |
} |
| 401 |
|
592 |
|
|
|
593 |
void StyleResolver::matchHostRules(MatchResult& result, bool includeEmptyRules) |
| 594 |
{ |
| 595 |
#if ENABLE(SHADOW_DOM) |
| 596 |
ASSERT(m_scopeResolver); |
| 597 |
|
| 598 |
m_state.matchedRules().clear(); |
| 599 |
result.ranges.lastAuthorRule = result.matchedProperties.size() - 1; |
| 600 |
|
| 601 |
Vector<RuleSet*> matchedRules; |
| 602 |
m_scopeResolver->matchHostRules(m_state.element(), matchedRules); |
| 603 |
if (matchedRules.isEmpty()) |
| 604 |
return; |
| 605 |
|
| 606 |
for (unsigned i = matchedRules.size(); i > 0; --i) { |
| 607 |
RuleRange ruleRange = result.ranges.authorRuleRange(); |
| 608 |
collectMatchingRules(MatchRequest(matchedRules.at(i-1), includeEmptyRules, m_state.element()), ruleRange); |
| 609 |
} |
| 610 |
sortAndTransferMatchedRules(result); |
| 611 |
#else |
| 612 |
UNUSED_PARAM(result); |
| 613 |
UNUSED_PARAM(includeEmptyRules); |
| 614 |
#endif |
| 615 |
} |
| 616 |
|
| 617 |
void StyleResolver::matchAuthorRules(MatchResult& result, bool includeEmptyRules) |
| 618 |
{ |
| 619 |
m_state.matchedRules().clear(); |
| 620 |
result.ranges.lastAuthorRule = result.matchedProperties.size() - 1; |
| 621 |
|
| 622 |
if (!m_state.element()) |
| 623 |
return; |
| 624 |
|
| 625 |
// Match global author rules. |
| 626 |
MatchRequest matchRequest(m_ruleSets.authorStyle(), includeEmptyRules); |
| 627 |
RuleRange ruleRange = result.ranges.authorRuleRange(); |
| 628 |
collectMatchingRules(matchRequest, ruleRange); |
| 629 |
collectMatchingRulesForRegion(matchRequest, ruleRange); |
| 630 |
#if ENABLE(SHADOW_DOM) |
| 631 |
Vector<MatchRequest> matchRequests; |
| 632 |
m_ruleSets.shadowDistributedRules().collectMatchRequests(includeEmptyRules, matchRequests); |
| 633 |
for (size_t i = 0; i < matchRequests.size(); ++i) |
| 634 |
collectMatchingRules(matchRequests[i], ruleRange); |
| 635 |
#endif |
| 636 |
|
| 637 |
sortAndTransferMatchedRules(result); |
| 638 |
|
| 639 |
matchScopedAuthorRules(result, includeEmptyRules); |
| 640 |
} |
| 641 |
|
| 642 |
void StyleResolver::matchUserRules(MatchResult& result, bool includeEmptyRules) |
| 643 |
{ |
| 644 |
if (!m_ruleSets.userStyle()) |
| 645 |
return; |
| 646 |
|
| 647 |
m_state.matchedRules().clear(); |
| 648 |
|
| 649 |
result.ranges.lastUserRule = result.matchedProperties.size() - 1; |
| 650 |
MatchRequest matchRequest(m_ruleSets.userStyle(), includeEmptyRules); |
| 651 |
RuleRange ruleRange = result.ranges.userRuleRange(); |
| 652 |
collectMatchingRules(matchRequest, ruleRange); |
| 653 |
collectMatchingRulesForRegion(matchRequest, ruleRange); |
| 654 |
|
| 655 |
sortAndTransferMatchedRules(result); |
| 656 |
} |
| 657 |
|
| 658 |
void StyleResolver::matchUARules(MatchResult& result, RuleSet* rules) |
| 659 |
{ |
| 660 |
m_state.matchedRules().clear(); |
| 661 |
|
| 662 |
result.ranges.lastUARule = result.matchedProperties.size() - 1; |
| 663 |
RuleRange ruleRange = result.ranges.UARuleRange(); |
| 664 |
collectMatchingRules(MatchRequest(rules), ruleRange); |
| 665 |
|
| 666 |
sortAndTransferMatchedRules(result); |
| 667 |
} |
| 668 |
|
| 669 |
void StyleResolver::collectMatchingRulesForList(const Vector<RuleData>* rules, const MatchRequest& matchRequest, RuleRange& ruleRange) |
| 670 |
{ |
| 671 |
if (!rules) |
| 672 |
return; |
| 673 |
|
| 674 |
State& state = m_state; |
| 675 |
// In some cases we may end up looking up style for random elements in the middle of a recursive tree resolve. |
| 676 |
// Ancestor identifier filter won't be up-to-date in that case and we can't use the fast path. |
| 677 |
bool canUseFastReject = m_selectorFilter.parentStackIsConsistent(state.parentNode()) && matchRequest.behaviorAtBoundary == SelectorChecker::DoesNotCrossBoundary; |
| 678 |
|
| 679 |
unsigned size = rules->size(); |
| 680 |
for (unsigned i = 0; i < size; ++i) { |
| 681 |
const RuleData& ruleData = rules->at(i); |
| 682 |
if (canUseFastReject && m_selectorFilter.fastRejectSelector<RuleData::maximumIdentifierCount>(ruleData.descendantSelectorIdentifierHashes())) |
| 683 |
continue; |
| 684 |
|
| 685 |
StyleRule* rule = ruleData.rule(); |
| 686 |
InspectorInstrumentationCookie cookie = InspectorInstrumentation::willMatchRule(document(), rule, this); |
| 687 |
PseudoId dynamicPseudo = NOPSEUDO; |
| 688 |
if (ruleMatches(ruleData, matchRequest.scope, dynamicPseudo, matchRequest.behaviorAtBoundary)) { |
| 689 |
// If the rule has no properties to apply, then ignore it in the non-debug mode. |
| 690 |
const StylePropertySet* properties = rule->properties(); |
| 691 |
if (!properties || (properties->isEmpty() && !matchRequest.includeEmptyRules)) { |
| 692 |
InspectorInstrumentation::didMatchRule(cookie, false); |
| 693 |
continue; |
| 694 |
} |
| 695 |
// FIXME: Exposing the non-standard getMatchedCSSRules API to web is the only reason this is needed. |
| 696 |
if (state.isSameOriginOnly() && !ruleData.hasDocumentSecurityOrigin()) { |
| 697 |
InspectorInstrumentation::didMatchRule(cookie, false); |
| 698 |
continue; |
| 699 |
} |
| 700 |
// If we're matching normal rules, set a pseudo bit if |
| 701 |
// we really just matched a pseudo-element. |
| 702 |
if (dynamicPseudo != NOPSEUDO && state.pseudoStyleRequest().pseudoId == NOPSEUDO) { |
| 703 |
if (state.mode() == SelectorChecker::CollectingRules) { |
| 704 |
InspectorInstrumentation::didMatchRule(cookie, false); |
| 705 |
continue; |
| 706 |
} |
| 707 |
if (dynamicPseudo < FIRST_INTERNAL_PSEUDOID) |
| 708 |
state.style()->setHasPseudoStyle(dynamicPseudo); |
| 709 |
} else { |
| 710 |
// Update our first/last rule indices in the matched rules array. |
| 711 |
++ruleRange.lastRuleIndex; |
| 712 |
if (ruleRange.firstRuleIndex == -1) |
| 713 |
ruleRange.firstRuleIndex = ruleRange.lastRuleIndex; |
| 714 |
|
| 715 |
// Add this rule to our list of matched rules. |
| 716 |
m_state.addMatchedRule(&ruleData); |
| 717 |
InspectorInstrumentation::didMatchRule(cookie, true); |
| 718 |
continue; |
| 719 |
} |
| 720 |
} |
| 721 |
InspectorInstrumentation::didMatchRule(cookie, false); |
| 722 |
} |
| 723 |
} |
| 724 |
|
| 725 |
static inline bool compareRules(const RuleData* r1, const RuleData* r2) |
| 726 |
{ |
| 727 |
unsigned specificity1 = r1->specificity(); |
| 728 |
unsigned specificity2 = r2->specificity(); |
| 729 |
return (specificity1 == specificity2) ? r1->position() < r2->position() : specificity1 < specificity2; |
| 730 |
} |
| 731 |
|
| 732 |
void StyleResolver::sortMatchedRules() |
| 733 |
{ |
| 734 |
std::sort(m_state.matchedRules().begin(), m_state.matchedRules().end(), compareRules); |
| 735 |
} |
| 736 |
|
| 737 |
void StyleResolver::matchAllRules(MatchResult& result, bool includeSMILProperties) |
| 738 |
{ |
| 739 |
matchUARules(result); |
| 740 |
|
| 741 |
// Now we check user sheet rules. |
| 742 |
if (m_matchAuthorAndUserStyles) |
| 743 |
matchUserRules(result, false); |
| 744 |
|
| 745 |
// Now check author rules, beginning first with presentational attributes mapped from HTML. |
| 746 |
if (m_state.styledElement()) { |
| 747 |
addElementStyleProperties(result, m_state.styledElement()->presentationAttributeStyle()); |
| 748 |
|
| 749 |
// Now we check additional mapped declarations. |
| 750 |
// Tables and table cells share an additional mapped rule that must be applied |
| 751 |
// after all attributes, since their mapped style depends on the values of multiple attributes. |
| 752 |
addElementStyleProperties(result, m_state.styledElement()->additionalPresentationAttributeStyle()); |
| 753 |
|
| 754 |
if (m_state.styledElement()->isHTMLElement()) { |
| 755 |
bool isAuto; |
| 756 |
TextDirection textDirection = toHTMLElement(m_state.styledElement())->directionalityIfhasDirAutoAttribute(isAuto); |
| 757 |
if (isAuto) |
| 758 |
addMatchedProperties(result, textDirection == LTR ? leftToRightDeclaration() : rightToLeftDeclaration()); |
| 759 |
} |
| 760 |
} |
| 761 |
|
| 762 |
// Check the rules in author sheets next. |
| 763 |
if (m_matchAuthorAndUserStyles) |
| 764 |
matchAuthorRules(result, false); |
| 765 |
|
| 766 |
// Now check our inline style attribute. |
| 767 |
if (m_matchAuthorAndUserStyles && m_state.styledElement() && m_state.styledElement()->inlineStyle()) { |
| 768 |
// Inline style is immutable as long as there is no CSSOM wrapper. |
| 769 |
// FIXME: Media control shadow trees seem to have problems with caching. |
| 770 |
bool isInlineStyleCacheable = !m_state.styledElement()->inlineStyle()->isMutable() && !m_state.styledElement()->isInShadowTree(); |
| 771 |
// FIXME: Constify. |
| 772 |
addElementStyleProperties(result, m_state.styledElement()->inlineStyle(), isInlineStyleCacheable); |
| 773 |
} |
| 774 |
|
| 775 |
#if ENABLE(SVG) |
| 776 |
// Now check SMIL animation override style. |
| 777 |
if (includeSMILProperties && m_matchAuthorAndUserStyles && m_state.styledElement() && m_state.styledElement()->isSVGElement()) |
| 778 |
addElementStyleProperties(result, static_cast<SVGElement*>(m_state.styledElement())->animatedSMILStyleProperties(), false /* isCacheable */); |
| 779 |
#else |
| 780 |
UNUSED_PARAM(includeSMILProperties); |
| 781 |
#endif |
| 782 |
} |
| 783 |
|
| 402 |
bool StyleResolver::classNamesAffectedByRules(const SpaceSplitString& classNames) const |
784 |
bool StyleResolver::classNamesAffectedByRules(const SpaceSplitString& classNames) const |
| 403 |
{ |
785 |
{ |
| 404 |
for (unsigned i = 0; i < classNames.size(); ++i) { |
786 |
for (unsigned i = 0; i < classNames.size(); ++i) { |
|
Lines 426-433
inline void StyleResolver::initElement(Element* e)
a/Source/WebCore/css/StyleResolver.cpp_sec9
|
| 426 |
} |
808 |
} |
| 427 |
} |
809 |
} |
| 428 |
|
810 |
|
| 429 |
inline void StyleResolver::State::initForStyleResolve(Document* document, Element* e, RenderStyle* parentStyle, RenderRegion* regionForStyling) |
811 |
inline void StyleResolver::State::initForStyleResolve(Document* document, Element* e, RenderStyle* parentStyle, const PseudoStyleRequest& pseudoStyleRequest, RenderRegion* regionForStyling) |
| 430 |
{ |
812 |
{ |
|
|
813 |
m_pseudoStyleRequest = pseudoStyleRequest; |
| 431 |
m_regionForStyling = regionForStyling; |
814 |
m_regionForStyling = regionForStyling; |
| 432 |
|
815 |
|
| 433 |
if (e) { |
816 |
if (e) { |
|
Lines 449-454
inline void StyleResolver::State::initForStyleResolve(Document* document, Elemen
a/Source/WebCore/css/StyleResolver.cpp_sec10
|
| 449 |
|
832 |
|
| 450 |
m_style = 0; |
833 |
m_style = 0; |
| 451 |
m_pendingImageProperties.clear(); |
834 |
m_pendingImageProperties.clear(); |
|
|
835 |
m_ruleList = 0; |
| 452 |
m_fontDirty = false; |
836 |
m_fontDirty = false; |
| 453 |
} |
837 |
} |
| 454 |
|
838 |
|
|
Lines 516-524
bool StyleResolver::styleSharingCandidateMatchesRuleSet(RuleSet* ruleSet)
a/Source/WebCore/css/StyleResolver.cpp_sec11
|
| 516 |
{ |
900 |
{ |
| 517 |
if (!ruleSet) |
901 |
if (!ruleSet) |
| 518 |
return false; |
902 |
return false; |
| 519 |
|
903 |
m_state.matchedRules().clear(); |
| 520 |
ElementRuleCollector collector(this, m_state); |
904 |
|
| 521 |
return collector.hasAnyMatchingRules(ruleSet); |
905 |
m_state.setMode(SelectorChecker::SharingRules); |
|
|
906 |
int firstRuleIndex = -1, lastRuleIndex = -1; |
| 907 |
RuleRange ruleRange(firstRuleIndex, lastRuleIndex); |
| 908 |
collectMatchingRules(MatchRequest(ruleSet), ruleRange); |
| 909 |
m_state.setMode(SelectorChecker::ResolvingStyle); |
| 910 |
if (m_state.matchedRules().isEmpty()) |
| 911 |
return false; |
| 912 |
m_state.matchedRules().clear(); |
| 913 |
return true; |
| 522 |
} |
914 |
} |
| 523 |
|
915 |
|
| 524 |
bool StyleResolver::canShareStyleWithControl(StyledElement* element) const |
916 |
bool StyleResolver::canShareStyleWithControl(StyledElement* element) const |
|
Lines 786-791
RenderStyle* StyleResolver::locateSharedStyle()
a/Source/WebCore/css/StyleResolver.cpp_sec12
|
| 786 |
return shareElement->renderStyle(); |
1178 |
return shareElement->renderStyle(); |
| 787 |
} |
1179 |
} |
| 788 |
|
1180 |
|
|
|
1181 |
void StyleResolver::matchUARules(MatchResult& result) |
| 1182 |
{ |
| 1183 |
MatchingUARulesScope scope; |
| 1184 |
|
| 1185 |
// First we match rules from the user agent sheet. |
| 1186 |
if (CSSDefaultStyleSheets::simpleDefaultStyleSheet) |
| 1187 |
result.isCacheable = false; |
| 1188 |
RuleSet* userAgentStyleSheet = m_medium->mediaTypeMatchSpecific("print") |
| 1189 |
? CSSDefaultStyleSheets::defaultPrintStyle : CSSDefaultStyleSheets::defaultStyle; |
| 1190 |
matchUARules(result, userAgentStyleSheet); |
| 1191 |
|
| 1192 |
// In quirks mode, we match rules from the quirks user agent sheet. |
| 1193 |
if (document()->inQuirksMode()) |
| 1194 |
matchUARules(result, CSSDefaultStyleSheets::defaultQuirksStyle); |
| 1195 |
|
| 1196 |
// If document uses view source styles (in view source mode or in xml viewer mode), then we match rules from the view source style sheet. |
| 1197 |
if (document()->isViewSource()) |
| 1198 |
matchUARules(result, CSSDefaultStyleSheets::viewSourceStyle()); |
| 1199 |
} |
| 1200 |
|
| 789 |
static void setStylesForPaginationMode(Pagination::Mode paginationMode, RenderStyle* style) |
1201 |
static void setStylesForPaginationMode(Pagination::Mode paginationMode, RenderStyle* style) |
| 790 |
{ |
1202 |
{ |
| 791 |
if (paginationMode == Pagination::Unpaginated) |
1203 |
if (paginationMode == Pagination::Unpaginated) |
|
Lines 983-989
PassRefPtr<RenderStyle> StyleResolver::styleForElement(Element* element, RenderS
a/Source/WebCore/css/StyleResolver.cpp_sec13
|
| 983 |
|
1395 |
|
| 984 |
State& state = m_state; |
1396 |
State& state = m_state; |
| 985 |
initElement(element); |
1397 |
initElement(element); |
| 986 |
state.initForStyleResolve(document(), element, defaultParent, regionForStyling); |
1398 |
state.initForStyleResolve(document(), element, defaultParent, NOPSEUDO, regionForStyling); |
| 987 |
if (sharingBehavior == AllowStyleSharing && !state.distributedToInsertionPoint()) { |
1399 |
if (sharingBehavior == AllowStyleSharing && !state.distributedToInsertionPoint()) { |
| 988 |
RenderStyle* sharedStyle = locateSharedStyle(); |
1400 |
RenderStyle* sharedStyle = locateSharedStyle(); |
| 989 |
if (sharedStyle) |
1401 |
if (sharedStyle) |
|
Lines 1025-1040
PassRefPtr<RenderStyle> StyleResolver::styleForElement(Element* element, RenderS
a/Source/WebCore/css/StyleResolver.cpp_sec14
|
| 1025 |
if (needsCollection) |
1437 |
if (needsCollection) |
| 1026 |
m_ruleSets.collectFeatures(document()->isViewSource(), m_scopeResolver.get()); |
1438 |
m_ruleSets.collectFeatures(document()->isViewSource(), m_scopeResolver.get()); |
| 1027 |
|
1439 |
|
| 1028 |
ElementRuleCollector collector(this, state); |
1440 |
MatchResult matchResult; |
| 1029 |
collector.setRegionForStyling(regionForStyling); |
|
|
| 1030 |
collector.setMedium(m_medium.get()); |
| 1031 |
|
| 1032 |
if (matchingBehavior == MatchOnlyUserAgentRules) |
1441 |
if (matchingBehavior == MatchOnlyUserAgentRules) |
| 1033 |
collector.matchUARules(); |
1442 |
matchUARules(matchResult); |
| 1034 |
else |
1443 |
else |
| 1035 |
collector.matchAllRules(m_matchAuthorAndUserStyles, matchingBehavior != MatchAllRulesExcludingSMIL); |
1444 |
matchAllRules(matchResult, matchingBehavior != MatchAllRulesExcludingSMIL); |
| 1036 |
|
1445 |
|
| 1037 |
applyMatchedProperties(collector.matchedResult(), element); |
1446 |
applyMatchedProperties(matchResult, element); |
| 1038 |
|
1447 |
|
| 1039 |
// Clean up our style object's display and text decorations (among other fixups). |
1448 |
// Clean up our style object's display and text decorations (among other fixups). |
| 1040 |
adjustRenderStyle(state.style(), state.parentStyle(), element); |
1449 |
adjustRenderStyle(state.style(), state.parentStyle(), element); |
|
Lines 1051-1057
PassRefPtr<RenderStyle> StyleResolver::styleForKeyframe(const RenderStyle* eleme
a/Source/WebCore/css/StyleResolver.cpp_sec15
|
| 1051 |
{ |
1460 |
{ |
| 1052 |
MatchResult result; |
1461 |
MatchResult result; |
| 1053 |
if (keyframe->properties()) |
1462 |
if (keyframe->properties()) |
| 1054 |
result.addMatchedProperties(keyframe->properties()); |
1463 |
addMatchedProperties(result, keyframe->properties()); |
| 1055 |
|
1464 |
|
| 1056 |
ASSERT(!m_state.style()); |
1465 |
ASSERT(!m_state.style()); |
| 1057 |
|
1466 |
|
|
Lines 1175-1181
PassRefPtr<RenderStyle> StyleResolver::pseudoStyleForElement(Element* e, const P
a/Source/WebCore/css/StyleResolver.cpp_sec16
|
| 1175 |
|
1584 |
|
| 1176 |
initElement(e); |
1585 |
initElement(e); |
| 1177 |
|
1586 |
|
| 1178 |
state.initForStyleResolve(document(), e, parentStyle); |
1587 |
state.initForStyleResolve(document(), e, parentStyle, pseudoStyleRequest); |
| 1179 |
state.setStyle(RenderStyle::create()); |
1588 |
state.setStyle(RenderStyle::create()); |
| 1180 |
state.style()->inheritFrom(m_state.parentStyle()); |
1589 |
state.style()->inheritFrom(m_state.parentStyle()); |
| 1181 |
|
1590 |
|
|
Lines 1183-1204
PassRefPtr<RenderStyle> StyleResolver::pseudoStyleForElement(Element* e, const P
a/Source/WebCore/css/StyleResolver.cpp_sec17
|
| 1183 |
// those rules. |
1592 |
// those rules. |
| 1184 |
|
1593 |
|
| 1185 |
// Check UA, user and author rules. |
1594 |
// Check UA, user and author rules. |
| 1186 |
ElementRuleCollector collector(this, state); |
1595 |
MatchResult matchResult; |
| 1187 |
collector.setPseudoStyleRequest(pseudoStyleRequest); |
1596 |
matchUARules(matchResult); |
| 1188 |
collector.setMedium(m_medium.get()); |
|
|
| 1189 |
collector.matchUARules(); |
| 1190 |
|
1597 |
|
| 1191 |
if (m_matchAuthorAndUserStyles) { |
1598 |
if (m_matchAuthorAndUserStyles) { |
| 1192 |
collector.matchUserRules(false); |
1599 |
matchUserRules(matchResult, false); |
| 1193 |
collector.matchAuthorRules(false); |
1600 |
matchAuthorRules(matchResult, false); |
| 1194 |
} |
1601 |
} |
| 1195 |
|
1602 |
|
| 1196 |
if (collector.matchedResult().matchedProperties.isEmpty()) |
1603 |
if (matchResult.matchedProperties.isEmpty()) |
| 1197 |
return 0; |
1604 |
return 0; |
| 1198 |
|
1605 |
|
| 1199 |
state.style()->setStyleType(pseudoStyleRequest.pseudoId); |
1606 |
state.style()->setStyleType(pseudoStyleRequest.pseudoId); |
| 1200 |
|
1607 |
|
| 1201 |
applyMatchedProperties(collector.matchedResult(), e); |
1608 |
applyMatchedProperties(matchResult, e); |
| 1202 |
|
1609 |
|
| 1203 |
// Clean up our style object's display and text decorations (among other fixups). |
1610 |
// Clean up our style object's display and text decorations (among other fixups). |
| 1204 |
adjustRenderStyle(state.style(), m_state.parentStyle(), 0); |
1611 |
adjustRenderStyle(state.style(), m_state.parentStyle(), 0); |
|
Lines 1219-1230
PassRefPtr<RenderStyle> StyleResolver::styleForPage(int pageIndex)
a/Source/WebCore/css/StyleResolver.cpp_sec18
|
| 1219 |
m_state.setStyle(RenderStyle::create()); |
1626 |
m_state.setStyle(RenderStyle::create()); |
| 1220 |
m_state.style()->inheritFrom(m_state.rootElementStyle()); |
1627 |
m_state.style()->inheritFrom(m_state.rootElementStyle()); |
| 1221 |
|
1628 |
|
| 1222 |
PageRuleCollector collector(m_state, m_ruleSets); |
1629 |
const bool isLeft = isLeftPage(pageIndex); |
| 1223 |
collector.matchAllPageRules(pageIndex); |
1630 |
const bool isFirst = isFirstPage(pageIndex); |
|
|
1631 |
const String page = pageName(pageIndex); |
| 1632 |
|
| 1633 |
MatchResult result; |
| 1634 |
matchPageRules(result, CSSDefaultStyleSheets::defaultPrintStyle, isLeft, isFirst, page); |
| 1635 |
matchPageRules(result, m_ruleSets.userStyle(), isLeft, isFirst, page); |
| 1636 |
// Only consider the global author RuleSet for @page rules, as per the HTML5 spec. |
| 1637 |
matchPageRules(result, m_ruleSets.authorStyle(), isLeft, isFirst, page); |
| 1224 |
m_state.setLineHeightValue(0); |
1638 |
m_state.setLineHeightValue(0); |
| 1225 |
bool inheritedOnly = false; |
1639 |
bool inheritedOnly = false; |
| 1226 |
|
|
|
| 1227 |
MatchResult& result = collector.matchedResult(); |
| 1228 |
#if ENABLE(CSS_VARIABLES) |
1640 |
#if ENABLE(CSS_VARIABLES) |
| 1229 |
applyMatchedProperties<VariableDefinitions>(result, false, 0, result.matchedProperties.size() - 1, inheritedOnly); |
1641 |
applyMatchedProperties<VariableDefinitions>(result, false, 0, result.matchedProperties.size() - 1, inheritedOnly); |
| 1230 |
#endif |
1642 |
#endif |
|
Lines 1651-1681
PassRefPtr<CSSRuleList> StyleResolver::pseudoStyleRulesForElement(Element* e, Ps
a/Source/WebCore/css/StyleResolver.cpp_sec19
|
| 1651 |
if (!e || !e->document()->haveStylesheetsLoaded()) |
2063 |
if (!e || !e->document()->haveStylesheetsLoaded()) |
| 1652 |
return 0; |
2064 |
return 0; |
| 1653 |
|
2065 |
|
| 1654 |
initElement(e); |
2066 |
m_state.setMode(SelectorChecker::CollectingRules); |
| 1655 |
m_state.initForStyleResolve(document(), e, 0); |
|
|
| 1656 |
|
2067 |
|
| 1657 |
ElementRuleCollector collector(this, m_state); |
2068 |
initElement(e); |
| 1658 |
collector.setMode(SelectorChecker::CollectingRules); |
2069 |
m_state.initForStyleResolve(document(), e, 0, pseudoId); |
| 1659 |
collector.setPseudoStyleRequest(PseudoStyleRequest(pseudoId)); |
|
|
| 1660 |
collector.setMedium(m_medium.get()); |
| 1661 |
|
2070 |
|
|
|
2071 |
MatchResult dummy; |
| 1662 |
if (rulesToInclude & UAAndUserCSSRules) { |
2072 |
if (rulesToInclude & UAAndUserCSSRules) { |
| 1663 |
// First we match rules from the user agent sheet. |
2073 |
// First we match rules from the user agent sheet. |
| 1664 |
collector.matchUARules(); |
2074 |
matchUARules(dummy); |
| 1665 |
|
2075 |
|
| 1666 |
// Now we check user sheet rules. |
2076 |
// Now we check user sheet rules. |
| 1667 |
if (m_matchAuthorAndUserStyles) |
2077 |
if (m_matchAuthorAndUserStyles) |
| 1668 |
collector.matchUserRules(rulesToInclude & EmptyCSSRules); |
2078 |
matchUserRules(dummy, rulesToInclude & EmptyCSSRules); |
| 1669 |
} |
2079 |
} |
| 1670 |
|
2080 |
|
| 1671 |
if (m_matchAuthorAndUserStyles && (rulesToInclude & AuthorCSSRules)) { |
2081 |
if (m_matchAuthorAndUserStyles && (rulesToInclude & AuthorCSSRules)) { |
| 1672 |
collector.setSameOriginOnly(!(rulesToInclude & CrossOriginCSSRules)); |
2082 |
m_state.setSameOriginOnly(!(rulesToInclude & CrossOriginCSSRules)); |
| 1673 |
|
2083 |
|
| 1674 |
// Check the rules in author sheets. |
2084 |
// Check the rules in author sheets. |
| 1675 |
collector.matchAuthorRules(rulesToInclude & EmptyCSSRules); |
2085 |
matchAuthorRules(dummy, rulesToInclude & EmptyCSSRules); |
|
|
2086 |
|
| 2087 |
m_state.setSameOriginOnly(false); |
| 2088 |
} |
| 2089 |
|
| 2090 |
m_state.setMode(SelectorChecker::ResolvingStyle); |
| 2091 |
|
| 2092 |
return m_state.takeRuleList(); |
| 2093 |
} |
| 2094 |
|
| 2095 |
inline bool StyleResolver::ruleMatches(const RuleData& ruleData, const ContainerNode* scope, PseudoId& dynamicPseudo, SelectorChecker::BehaviorAtBoundary behaviorAtBoundary) |
| 2096 |
{ |
| 2097 |
State& state = m_state; |
| 2098 |
|
| 2099 |
if (ruleData.hasFastCheckableSelector()) { |
| 2100 |
// We know this selector does not include any pseudo elements. |
| 2101 |
if (state.pseudoStyleRequest().pseudoId != NOPSEUDO) |
| 2102 |
return false; |
| 2103 |
// We know a sufficiently simple single part selector matches simply because we found it from the rule hash. |
| 2104 |
// This is limited to HTML only so we don't need to check the namespace. |
| 2105 |
if (ruleData.hasRightmostSelectorMatchingHTMLBasedOnRuleHash() && state.element()->isHTMLElement()) { |
| 2106 |
if (!ruleData.hasMultipartSelector()) |
| 2107 |
return true; |
| 2108 |
} |
| 2109 |
if (ruleData.selector()->m_match == CSSSelector::Tag && !SelectorChecker::tagMatches(state.element(), ruleData.selector()->tagQName())) |
| 2110 |
return false; |
| 2111 |
SelectorCheckerFastPath selectorCheckerFastPath(ruleData.selector(), state.element()); |
| 2112 |
if (!selectorCheckerFastPath.matchesRightmostAttributeSelector()) |
| 2113 |
return false; |
| 2114 |
|
| 2115 |
return selectorCheckerFastPath.matches(); |
| 1676 |
} |
2116 |
} |
| 1677 |
|
2117 |
|
| 1678 |
return collector.matchedRuleList(); |
2118 |
// Slow path. |
|
|
2119 |
SelectorChecker selectorChecker(document(), state.mode()); |
| 2120 |
SelectorChecker::SelectorCheckingContext context(ruleData.selector(), state.element(), SelectorChecker::VisitedMatchEnabled); |
| 2121 |
context.elementStyle = state.style(); |
| 2122 |
context.scope = scope; |
| 2123 |
context.pseudoId = state.pseudoStyleRequest().pseudoId; |
| 2124 |
context.scrollbar = state.pseudoStyleRequest().scrollbar; |
| 2125 |
context.scrollbarPart = state.pseudoStyleRequest().scrollbarPart; |
| 2126 |
context.behaviorAtBoundary = behaviorAtBoundary; |
| 2127 |
SelectorChecker::Match match = selectorChecker.match(context, dynamicPseudo, DOMSiblingTraversalStrategy()); |
| 2128 |
if (match != SelectorChecker::SelectorMatches) |
| 2129 |
return false; |
| 2130 |
if (state.pseudoStyleRequest().pseudoId != NOPSEUDO && state.pseudoStyleRequest().pseudoId != dynamicPseudo) |
| 2131 |
return false; |
| 2132 |
return true; |
| 2133 |
} |
| 2134 |
|
| 2135 |
bool StyleResolver::checkRegionSelector(const CSSSelector* regionSelector, Element* regionElement) |
| 2136 |
{ |
| 2137 |
if (!regionSelector || !regionElement) |
| 2138 |
return false; |
| 2139 |
|
| 2140 |
SelectorChecker selectorChecker(document(), m_state.mode()); |
| 2141 |
for (const CSSSelector* s = regionSelector; s; s = CSSSelectorList::next(s)) { |
| 2142 |
SelectorChecker::SelectorCheckingContext selectorCheckingContext(s, regionElement, SelectorChecker::VisitedMatchDisabled); |
| 2143 |
PseudoId ignoreDynamicPseudo = NOPSEUDO; |
| 2144 |
if (selectorChecker.match(selectorCheckingContext, ignoreDynamicPseudo, DOMSiblingTraversalStrategy()) == SelectorChecker::SelectorMatches) |
| 2145 |
return true; |
| 2146 |
} |
| 2147 |
|
| 2148 |
return false; |
| 1679 |
} |
2149 |
} |
| 1680 |
|
2150 |
|
| 1681 |
// ------------------------------------------------------------------------------------- |
2151 |
// ------------------------------------------------------------------------------------- |
|
Lines 1954-1959
void StyleResolver::applyMatchedProperties(const MatchResult& matchResult, const
a/Source/WebCore/css/StyleResolver.cpp_sec20
|
| 1954 |
addToMatchedPropertiesCache(state.style(), state.parentStyle(), cacheHash, matchResult); |
2424 |
addToMatchedPropertiesCache(state.style(), state.parentStyle(), cacheHash, matchResult); |
| 1955 |
} |
2425 |
} |
| 1956 |
|
2426 |
|
|
|
2427 |
static inline bool comparePageRules(const StyleRulePage* r1, const StyleRulePage* r2) |
| 2428 |
{ |
| 2429 |
return r1->selector()->specificity() < r2->selector()->specificity(); |
| 2430 |
} |
| 2431 |
|
| 2432 |
void StyleResolver::matchPageRules(MatchResult& result, RuleSet* rules, bool isLeftPage, bool isFirstPage, const String& pageName) |
| 2433 |
{ |
| 2434 |
if (!rules) |
| 2435 |
return; |
| 2436 |
|
| 2437 |
Vector<StyleRulePage*> matchedPageRules; |
| 2438 |
matchPageRulesForList(matchedPageRules, rules->pageRules(), isLeftPage, isFirstPage, pageName); |
| 2439 |
if (matchedPageRules.isEmpty()) |
| 2440 |
return; |
| 2441 |
|
| 2442 |
std::stable_sort(matchedPageRules.begin(), matchedPageRules.end(), comparePageRules); |
| 2443 |
|
| 2444 |
for (unsigned i = 0; i < matchedPageRules.size(); i++) |
| 2445 |
addMatchedProperties(result, matchedPageRules[i]->properties()); |
| 2446 |
} |
| 2447 |
|
| 2448 |
static bool checkPageSelectorComponents(const CSSSelector* selector, bool isLeftPage, bool isFirstPage, const String& pageName) |
| 2449 |
{ |
| 2450 |
for (const CSSSelector* component = selector; component; component = component->tagHistory()) { |
| 2451 |
if (component->m_match == CSSSelector::Tag) { |
| 2452 |
const AtomicString& localName = component->tagQName().localName(); |
| 2453 |
if (localName != starAtom && localName != pageName) |
| 2454 |
return false; |
| 2455 |
} |
| 2456 |
|
| 2457 |
CSSSelector::PseudoType pseudoType = component->pseudoType(); |
| 2458 |
if ((pseudoType == CSSSelector::PseudoLeftPage && !isLeftPage) |
| 2459 |
|| (pseudoType == CSSSelector::PseudoRightPage && isLeftPage) |
| 2460 |
|| (pseudoType == CSSSelector::PseudoFirstPage && !isFirstPage)) |
| 2461 |
{ |
| 2462 |
return false; |
| 2463 |
} |
| 2464 |
} |
| 2465 |
return true; |
| 2466 |
} |
| 2467 |
|
| 2468 |
void StyleResolver::matchPageRulesForList(Vector<StyleRulePage*>& matchedRules, const Vector<StyleRulePage*>& rules, bool isLeftPage, bool isFirstPage, const String& pageName) |
| 2469 |
{ |
| 2470 |
for (unsigned i = 0; i < rules.size(); ++i) { |
| 2471 |
StyleRulePage* rule = rules[i]; |
| 2472 |
|
| 2473 |
if (!checkPageSelectorComponents(rule->selector(), isLeftPage, isFirstPage, pageName)) |
| 2474 |
continue; |
| 2475 |
|
| 2476 |
// If the rule has no properties to apply, then ignore it. |
| 2477 |
const StylePropertySet* properties = rule->properties(); |
| 2478 |
if (!properties || properties->isEmpty()) |
| 2479 |
continue; |
| 2480 |
|
| 2481 |
// Add this rule to our list of matched rules. |
| 2482 |
matchedRules.append(rule); |
| 2483 |
} |
| 2484 |
} |
| 2485 |
|
| 2486 |
bool StyleResolver::isLeftPage(int pageIndex) const |
| 2487 |
{ |
| 2488 |
bool isFirstPageLeft = false; |
| 2489 |
if (!m_state.rootElementStyle()->isLeftToRightDirection()) |
| 2490 |
isFirstPageLeft = true; |
| 2491 |
|
| 2492 |
return (pageIndex + (isFirstPageLeft ? 1 : 0)) % 2; |
| 2493 |
} |
| 2494 |
|
| 2495 |
bool StyleResolver::isFirstPage(int pageIndex) const |
| 2496 |
{ |
| 2497 |
// FIXME: In case of forced left/right page, page at index 1 (not 0) can be the first page. |
| 2498 |
return (!pageIndex); |
| 2499 |
} |
| 2500 |
|
| 2501 |
String StyleResolver::pageName(int /* pageIndex */) const |
| 2502 |
{ |
| 2503 |
// FIXME: Implement page index to page name mapping. |
| 2504 |
return ""; |
| 2505 |
} |
| 2506 |
|
| 1957 |
void StyleResolver::applyPropertyToStyle(CSSPropertyID id, CSSValue* value, RenderStyle* style) |
2507 |
void StyleResolver::applyPropertyToStyle(CSSPropertyID id, CSSValue* value, RenderStyle* style) |
| 1958 |
{ |
2508 |
{ |
| 1959 |
initElement(0); |
2509 |
initElement(0); |