PageRuleCollector.cpp [plain text]
#include "config.h"
#include "PageRuleCollector.h"
#include "CSSDefaultStyleSheets.h"
#include "StyleProperties.h"
#include "StyleRule.h"
namespace WebCore {
static inline bool comparePageRules(const StyleRulePage* r1, const StyleRulePage* r2)
{
return r1->selector()->specificityForPage() < r2->selector()->specificityForPage();
}
bool PageRuleCollector::isLeftPage(int pageIndex) const
{
bool isFirstPageLeft = false;
if (!m_state.rootElementStyle()->isLeftToRightDirection())
isFirstPageLeft = true;
return (pageIndex + (isFirstPageLeft ? 1 : 0)) % 2;
}
bool PageRuleCollector::isFirstPage(int pageIndex) const
{
return (!pageIndex);
}
String PageRuleCollector::pageName(int ) const
{
return "";
}
void PageRuleCollector::matchAllPageRules(int pageIndex)
{
const bool isLeft = isLeftPage(pageIndex);
const bool isFirst = isFirstPage(pageIndex);
const String page = pageName(pageIndex);
matchPageRules(CSSDefaultStyleSheets::defaultPrintStyle, isLeft, isFirst, page);
matchPageRules(m_ruleSets.userStyle(), isLeft, isFirst, page);
matchPageRules(m_ruleSets.authorStyle(), isLeft, isFirst, page);
}
void PageRuleCollector::matchPageRules(RuleSet* rules, bool isLeftPage, bool isFirstPage, const String& pageName)
{
if (!rules)
return;
Vector<StyleRulePage*> matchedPageRules;
matchPageRulesForList(matchedPageRules, rules->pageRules(), isLeftPage, isFirstPage, pageName);
if (matchedPageRules.isEmpty())
return;
std::stable_sort(matchedPageRules.begin(), matchedPageRules.end(), comparePageRules);
for (unsigned i = 0; i < matchedPageRules.size(); i++)
m_result.addMatchedProperties(matchedPageRules[i]->properties());
}
static bool checkPageSelectorComponents(const CSSSelector* selector, bool isLeftPage, bool isFirstPage, const String& pageName)
{
for (const CSSSelector* component = selector; component; component = component->tagHistory()) {
if (component->match() == CSSSelector::Tag) {
const AtomicString& localName = component->tagQName().localName();
if (localName != starAtom && localName != pageName)
return false;
} else if (component->match() == CSSSelector::PagePseudoClass) {
CSSSelector::PagePseudoClassType pseudoType = component->pagePseudoClassType();
if ((pseudoType == CSSSelector::PagePseudoClassLeft && !isLeftPage)
|| (pseudoType == CSSSelector::PagePseudoClassRight && isLeftPage)
|| (pseudoType == CSSSelector::PagePseudoClassFirst && !isFirstPage))
{
return false;
}
}
}
return true;
}
void PageRuleCollector::matchPageRulesForList(Vector<StyleRulePage*>& matchedRules, const Vector<StyleRulePage*>& rules, bool isLeftPage, bool isFirstPage, const String& pageName)
{
for (unsigned i = 0; i < rules.size(); ++i) {
StyleRulePage* rule = rules[i];
if (!checkPageSelectorComponents(rule->selector(), isLeftPage, isFirstPage, pageName))
continue;
const StyleProperties& properties = rule->properties();
if (properties.isEmpty())
continue;
matchedRules.append(rule);
}
}
}