Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / css / resolver / ViewportStyleResolver.cpp
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/CSSPrimitiveValueMappings.h"
35 #include "core/css/CSSToLengthConversionData.h"
36 #include "core/css/StylePropertySet.h"
37 #include "core/css/StyleRule.h"
38 #include "core/dom/Document.h"
39 #include "core/dom/NodeRenderStyle.h"
40 #include "core/dom/ViewportDescription.h"
41 #include "core/frame/FrameView.h"
42
43 namespace WebCore {
44
45 DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(ViewportStyleResolver);
46
47 ViewportStyleResolver::ViewportStyleResolver(Document* document)
48     : m_document(document)
49     , m_hasAuthorStyle(false)
50 {
51     ASSERT(m_document);
52 }
53
54 void ViewportStyleResolver::collectViewportRules(RuleSet* rules, Origin origin)
55 {
56     rules->compactRulesIfNeeded();
57
58     const WillBeHeapVector<RawPtrWillBeMember<StyleRuleViewport> >& viewportRules = rules->viewportRules();
59     for (size_t i = 0; i < viewportRules.size(); ++i)
60         addViewportRule(viewportRules[i], origin);
61 }
62
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
85 void ViewportStyleResolver::resolve()
86 {
87     if (!m_document)
88         return;
89
90     if (!m_propertySet) {
91         m_document->setViewportDescription(ViewportDescription(ViewportDescription::UserAgentStyleSheet));
92         return;
93     }
94
95     ViewportDescription description(m_hasAuthorStyle ? ViewportDescription::AuthorStyleSheet : ViewportDescription::UserAgentStyleSheet);
96
97     description.userZoom = viewportArgumentValue(CSSPropertyUserZoom);
98     description.zoom = viewportArgumentValue(CSSPropertyZoom);
99     description.minZoom = viewportArgumentValue(CSSPropertyMinZoom);
100     description.maxZoom = viewportArgumentValue(CSSPropertyMaxZoom);
101     description.minWidth = viewportLengthValue(CSSPropertyMinWidth);
102     description.maxWidth = viewportLengthValue(CSSPropertyMaxWidth);
103     description.minHeight = viewportLengthValue(CSSPropertyMinHeight);
104     description.maxHeight = viewportLengthValue(CSSPropertyMaxHeight);
105     description.orientation = viewportArgumentValue(CSSPropertyOrientation);
106
107     m_document->setViewportDescription(description);
108
109     m_propertySet = nullptr;
110     m_hasAuthorStyle = false;
111 }
112
113 float ViewportStyleResolver::viewportArgumentValue(CSSPropertyID id) const
114 {
115     float defaultValue = ViewportDescription::ValueAuto;
116
117     // UserZoom default value is CSSValueZoom, which maps to true, meaning that
118     // yes, it is user scalable. When the value is set to CSSValueFixed, we
119     // return false.
120     if (id == CSSPropertyUserZoom)
121         defaultValue = 1;
122
123     RefPtrWillBeRawPtr<CSSValue> value = m_propertySet->getPropertyCSSValue(id);
124     if (!value || !value->isPrimitiveValue())
125         return defaultValue;
126
127     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value.get());
128
129     if (primitiveValue->isNumber() || primitiveValue->isPx())
130         return primitiveValue->getFloatValue();
131
132     if (primitiveValue->isFontRelativeLength())
133         return primitiveValue->getFloatValue() * m_document->renderStyle()->fontDescription().computedSize();
134
135     if (primitiveValue->isPercentage()) {
136         float percentValue = primitiveValue->getFloatValue() / 100.0f;
137         switch (id) {
138         case CSSPropertyMaxZoom:
139         case CSSPropertyMinZoom:
140         case CSSPropertyZoom:
141             return percentValue;
142         default:
143             ASSERT_NOT_REACHED();
144             break;
145         }
146     }
147
148     switch (primitiveValue->getValueID()) {
149     case CSSValueAuto:
150         return defaultValue;
151     case CSSValueLandscape:
152         return ViewportDescription::ValueLandscape;
153     case CSSValuePortrait:
154         return ViewportDescription::ValuePortrait;
155     case CSSValueZoom:
156         return defaultValue;
157     case CSSValueInternalExtendToZoom:
158         return ViewportDescription::ValueExtendToZoom;
159     case CSSValueFixed:
160         return 0;
161     default:
162         return defaultValue;
163     }
164 }
165
166 Length ViewportStyleResolver::viewportLengthValue(CSSPropertyID id) const
167 {
168     ASSERT(id == CSSPropertyMaxHeight
169         || id == CSSPropertyMinHeight
170         || id == CSSPropertyMaxWidth
171         || id == CSSPropertyMinWidth);
172
173     RefPtrWillBeRawPtr<CSSValue> value = m_propertySet->getPropertyCSSValue(id);
174     if (!value || !value->isPrimitiveValue())
175         return Length(); // auto
176
177     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value.get());
178
179     if (primitiveValue->getValueID() == CSSValueInternalExtendToZoom)
180         return Length(ExtendToZoom);
181
182     RenderStyle* documentStyle = m_document->renderStyle();
183
184     // If we have viewport units the conversion will mark the document style as having viewport units.
185     bool documentStyleHasViewportUnits = documentStyle->hasViewportUnits();
186     documentStyle->setHasViewportUnits(false);
187
188     FrameView* view = m_document->view();
189     float width = view ? view->width() : 0;
190     float height = view ? view->height() : 0;
191
192     Length result = primitiveValue->convertToLength<AnyConversion>(CSSToLengthConversionData(documentStyle, documentStyle, width, height, 1.0f));
193     if (documentStyle->hasViewportUnits())
194         m_document->setHasViewportUnits();
195     documentStyle->setHasViewportUnits(documentStyleHasViewportUnits);
196
197     return result;
198 }
199
200 void ViewportStyleResolver::trace(Visitor* visitor)
201 {
202     visitor->trace(m_propertySet);
203 }
204
205 } // namespace WebCore