1 | /* |
2 | * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
3 | * (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com) |
4 | * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com) |
5 | * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved. |
6 | * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org> |
7 | * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org> |
8 | * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/) |
9 | * Copyright (c) 2011, Code Aurora Forum. All rights reserved. |
10 | * Copyright (C) Research In Motion Limited 2011. All rights reserved. |
11 | * Copyright (C) 2012 Google Inc. All rights reserved. |
12 | * |
13 | * This library is free software; you can redistribute it and/or |
14 | * modify it under the terms of the GNU Library General Public |
15 | * License as published by the Free Software Foundation; either |
16 | * version 2 of the License, or (at your option) any later version. |
17 | * |
18 | * This library is distributed in the hope that it will be useful, |
19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
21 | * Library General Public License for more details. |
22 | * |
23 | * You should have received a copy of the GNU Library General Public License |
24 | * along with this library; see the file COPYING.LIB. If not, write to |
25 | * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
26 | * Boston, MA 02110-1301, USA. |
27 | */ |
28 | |
29 | #include "config.h" |
30 | #include "PageRuleCollector.h" |
31 | |
32 | #include "CSSDefaultStyleSheets.h" |
33 | #include "StyleProperties.h" |
34 | #include "StyleRule.h" |
35 | |
36 | namespace WebCore { |
37 | |
38 | static inline bool (const StyleRulePage* r1, const StyleRulePage* r2) |
39 | { |
40 | return r1->selector()->specificityForPage() < r2->selector()->specificityForPage(); |
41 | } |
42 | |
43 | bool PageRuleCollector::(int pageIndex) const |
44 | { |
45 | bool isFirstPageLeft = false; |
46 | if (!m_state.rootElementStyle()->isLeftToRightDirection()) |
47 | isFirstPageLeft = true; |
48 | |
49 | return (pageIndex + (isFirstPageLeft ? 1 : 0)) % 2; |
50 | } |
51 | |
52 | bool PageRuleCollector::(int pageIndex) const |
53 | { |
54 | // FIXME: In case of forced left/right page, page at index 1 (not 0) can be the first page. |
55 | return (!pageIndex); |
56 | } |
57 | |
58 | String PageRuleCollector::(int /* pageIndex */) const |
59 | { |
60 | // FIXME: Implement page index to page name mapping. |
61 | return emptyString(); |
62 | } |
63 | |
64 | void PageRuleCollector::(int pageIndex) |
65 | { |
66 | const bool isLeft = isLeftPage(pageIndex); |
67 | const bool isFirst = isFirstPage(pageIndex); |
68 | const String page = pageName(pageIndex); |
69 | |
70 | matchPageRules(CSSDefaultStyleSheets::defaultPrintStyle, isLeft, isFirst, page); |
71 | matchPageRules(m_ruleSets.userStyle(), isLeft, isFirst, page); |
72 | // Only consider the global author RuleSet for @page rules, as per the HTML5 spec. |
73 | if (m_ruleSets.isAuthorStyleDefined()) |
74 | matchPageRules(&m_ruleSets.authorStyle(), isLeft, isFirst, page); |
75 | } |
76 | |
77 | void PageRuleCollector::(RuleSet* rules, bool isLeftPage, bool isFirstPage, const String& pageName) |
78 | { |
79 | if (!rules) |
80 | return; |
81 | |
82 | Vector<StyleRulePage*> ; |
83 | matchPageRulesForList(matchedPageRules, rules->pageRules(), isLeftPage, isFirstPage, pageName); |
84 | if (matchedPageRules.isEmpty()) |
85 | return; |
86 | |
87 | std::stable_sort(matchedPageRules.begin(), matchedPageRules.end(), comparePageRules); |
88 | |
89 | for (unsigned i = 0; i < matchedPageRules.size(); i++) |
90 | m_result.addMatchedProperties(matchedPageRules[i]->properties()); |
91 | } |
92 | |
93 | static bool checkPageSelectorComponents(const CSSSelector* selector, bool isLeftPage, bool isFirstPage, const String& pageName) |
94 | { |
95 | for (const CSSSelector* component = selector; component; component = component->tagHistory()) { |
96 | if (component->match() == CSSSelector::Tag) { |
97 | const AtomicString& localName = component->tagQName().localName(); |
98 | if (localName != starAtom() && localName != pageName) |
99 | return false; |
100 | } else if (component->match() == CSSSelector::PagePseudoClass) { |
101 | CSSSelector::PagePseudoClassType pseudoType = component->pagePseudoClassType(); |
102 | if ((pseudoType == CSSSelector::PagePseudoClassLeft && !isLeftPage) |
103 | || (pseudoType == CSSSelector::PagePseudoClassRight && isLeftPage) |
104 | || (pseudoType == CSSSelector::PagePseudoClassFirst && !isFirstPage)) |
105 | { |
106 | return false; |
107 | } |
108 | } |
109 | } |
110 | return true; |
111 | } |
112 | |
113 | void PageRuleCollector::(Vector<StyleRulePage*>& matchedRules, const Vector<StyleRulePage*>& rules, bool isLeftPage, bool isFirstPage, const String& pageName) |
114 | { |
115 | for (unsigned i = 0; i < rules.size(); ++i) { |
116 | StyleRulePage* rule = rules[i]; |
117 | |
118 | if (!checkPageSelectorComponents(rule->selector(), isLeftPage, isFirstPage, pageName)) |
119 | continue; |
120 | |
121 | // If the rule has no properties to apply, then ignore it. |
122 | const StyleProperties& properties = rule->properties(); |
123 | if (properties.isEmpty()) |
124 | continue; |
125 | |
126 | // Add this rule to our list of matched rules. |
127 | matchedRules.append(rule); |
128 | } |
129 | } |
130 | |
131 | } // namespace WebCore |
132 | |