• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2012-2013 Intel Corporation. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1. Redistributions of source code must retain the above
9  *    copyright notice, this list of conditions and the following
10  *    disclaimer.
11  * 2. Redistributions in binary form must reproduce the above
12  *    copyright notice, this list of conditions and the following
13  *    disclaimer in the documentation and/or other materials
14  *    provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
21  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
25  * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
26  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29 
30 #include "config.h"
31 #include "core/css/resolver/ViewportStyleResolver.h"
32 
33 #include "CSSValueKeywords.h"
34 #include "core/css/CSSToLengthConversionData.h"
35 #include "core/css/StylePropertySet.h"
36 #include "core/css/StyleRule.h"
37 #include "core/dom/Document.h"
38 #include "core/dom/NodeRenderStyle.h"
39 #include "core/dom/ViewportDescription.h"
40 
41 namespace WebCore {
42 
ViewportStyleResolver(Document * document)43 ViewportStyleResolver::ViewportStyleResolver(Document* document)
44     : m_document(document),
45     m_hasAuthorStyle(false)
46 {
47     ASSERT(m_document);
48 }
49 
~ViewportStyleResolver()50 ViewportStyleResolver::~ViewportStyleResolver()
51 {
52 }
53 
collectViewportRules(RuleSet * rules,Origin origin)54 void ViewportStyleResolver::collectViewportRules(RuleSet* rules, Origin origin)
55 {
56     rules->compactRulesIfNeeded();
57 
58     const Vector<StyleRuleViewport*>& viewportRules = rules->viewportRules();
59     for (size_t i = 0; i < viewportRules.size(); ++i)
60         addViewportRule(viewportRules[i], origin);
61 }
62 
addViewportRule(StyleRuleViewport * viewportRule,Origin origin)63 void ViewportStyleResolver::addViewportRule(StyleRuleViewport* viewportRule, Origin origin)
64 {
65     StylePropertySet* propertySet = viewportRule->mutableProperties();
66 
67     unsigned propertyCount = propertySet->propertyCount();
68     if (!propertyCount)
69         return;
70 
71     if (origin == AuthorOrigin)
72         m_hasAuthorStyle = true;
73 
74     if (!m_propertySet) {
75         m_propertySet = propertySet->mutableCopy();
76         return;
77     }
78 
79     // We cannot use mergeAndOverrideOnConflict() here because it doesn't
80     // respect the !important declaration (but addParsedProperty() does).
81     for (unsigned i = 0; i < propertyCount; ++i)
82         m_propertySet->addParsedProperty(propertySet->propertyAt(i).toCSSProperty());
83 }
84 
clearDocument()85 void ViewportStyleResolver::clearDocument()
86 {
87     m_document = 0;
88 }
89 
resolve()90 void ViewportStyleResolver::resolve()
91 {
92     if (!m_document)
93         return;
94 
95     if (!m_propertySet || (!m_hasAuthorStyle && m_document->hasLegacyViewportTag())) {
96         ASSERT(!m_hasAuthorStyle);
97         m_propertySet = 0;
98         m_document->setViewportDescription(ViewportDescription());
99         return;
100     }
101 
102     ViewportDescription description(m_hasAuthorStyle ? ViewportDescription::AuthorStyleSheet : ViewportDescription::UserAgentStyleSheet);
103 
104     description.userZoom = viewportArgumentValue(CSSPropertyUserZoom);
105     description.zoom = viewportArgumentValue(CSSPropertyZoom);
106     description.minZoom = viewportArgumentValue(CSSPropertyMinZoom);
107     description.maxZoom = viewportArgumentValue(CSSPropertyMaxZoom);
108     description.minWidth = viewportLengthValue(CSSPropertyMinWidth);
109     description.maxWidth = viewportLengthValue(CSSPropertyMaxWidth);
110     description.minHeight = viewportLengthValue(CSSPropertyMinHeight);
111     description.maxHeight = viewportLengthValue(CSSPropertyMaxHeight);
112     description.orientation = viewportArgumentValue(CSSPropertyOrientation);
113 
114     m_document->setViewportDescription(description);
115 
116     m_propertySet = 0;
117     m_hasAuthorStyle = false;
118 }
119 
viewportArgumentValue(CSSPropertyID id) const120 float ViewportStyleResolver::viewportArgumentValue(CSSPropertyID id) const
121 {
122     float defaultValue = ViewportDescription::ValueAuto;
123 
124     // UserZoom default value is CSSValueZoom, which maps to true, meaning that
125     // yes, it is user scalable. When the value is set to CSSValueFixed, we
126     // return false.
127     if (id == CSSPropertyUserZoom)
128         defaultValue = 1;
129 
130     RefPtr<CSSValue> value = m_propertySet->getPropertyCSSValue(id);
131     if (!value || !value->isPrimitiveValue())
132         return defaultValue;
133 
134     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value.get());
135 
136     if (primitiveValue->isNumber() || primitiveValue->isPx())
137         return primitiveValue->getFloatValue();
138 
139     if (primitiveValue->isFontRelativeLength())
140         return primitiveValue->getFloatValue() * m_document->renderStyle()->fontDescription().computedSize();
141 
142     if (primitiveValue->isPercentage()) {
143         float percentValue = primitiveValue->getFloatValue() / 100.0f;
144         switch (id) {
145         case CSSPropertyMaxZoom:
146         case CSSPropertyMinZoom:
147         case CSSPropertyZoom:
148             return percentValue;
149         default:
150             ASSERT_NOT_REACHED();
151             break;
152         }
153     }
154 
155     switch (primitiveValue->getValueID()) {
156     case CSSValueAuto:
157         return defaultValue;
158     case CSSValueLandscape:
159         return ViewportDescription::ValueLandscape;
160     case CSSValuePortrait:
161         return ViewportDescription::ValuePortrait;
162     case CSSValueZoom:
163         return defaultValue;
164     case CSSValueInternalExtendToZoom:
165         return ViewportDescription::ValueExtendToZoom;
166     case CSSValueFixed:
167         return 0;
168     default:
169         return defaultValue;
170     }
171 }
172 
viewportLengthValue(CSSPropertyID id) const173 Length ViewportStyleResolver::viewportLengthValue(CSSPropertyID id) const
174 {
175     ASSERT(id == CSSPropertyMaxHeight
176         || id == CSSPropertyMinHeight
177         || id == CSSPropertyMaxWidth
178         || id == CSSPropertyMinWidth);
179 
180     RefPtr<CSSValue> value = m_propertySet->getPropertyCSSValue(id);
181     if (!value || !value->isPrimitiveValue())
182         return Length(); // auto
183 
184     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value.get());
185 
186     if (primitiveValue->isLength())
187         return primitiveValue->computeLength<Length>(CSSToLengthConversionData(m_document->renderStyle(), m_document->renderStyle(), 1.0f));
188 
189     if (primitiveValue->isViewportPercentageLength())
190         return primitiveValue->viewportPercentageLength();
191 
192     if (primitiveValue->isPercentage())
193         return Length(primitiveValue->getFloatValue(), Percent);
194 
195     switch (primitiveValue->getValueID()) {
196     case CSSValueInternalExtendToZoom:
197         return Length(ExtendToZoom);
198     case CSSValueAuto:
199         return Length();
200     default:
201         // Unrecognized keyword.
202         ASSERT_NOT_REACHED();
203         return Length(0, Fixed);
204     }
205 }
206 
207 } // namespace WebCore
208