blob: a8c3be72ed1cefeb5bf16f9274c1d16a30472612 [file] [log] [blame]
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001/*
Ben Murdoch7757ec22013-07-23 11:17:36 +01002 * Copyright (C) 2012-2013 Intel Corporation. All rights reserved.
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01003 *
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"
Torne (Richard Coles)81a51572013-05-13 16:52:28 +010031#include "core/css/resolver/ViewportStyleResolver.h"
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010032
Torne (Richard Coles)5d92fed2014-06-20 14:52:37 +010033#include "core/CSSValueKeywords.h"
Torne (Richard Coles)09380292014-02-21 12:17:33 +000034#include "core/css/CSSPrimitiveValueMappings.h"
Torne (Richard Coles)a854de02013-12-18 16:25:25 +000035#include "core/css/CSSToLengthConversionData.h"
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010036#include "core/css/StylePropertySet.h"
37#include "core/css/StyleRule.h"
38#include "core/dom/Document.h"
Torne (Richard Coles)521d96e2013-06-19 11:58:24 +010039#include "core/dom/NodeRenderStyle.h"
Torne (Richard Coles)1e202182013-10-18 15:46:42 +010040#include "core/dom/ViewportDescription.h"
Torne (Richard Coles)09380292014-02-21 12:17:33 +000041#include "core/frame/FrameView.h"
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010042
43namespace WebCore {
44
Torne (Richard Coles)43e75022014-03-21 14:26:12 +000045DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(ViewportStyleResolver);
46
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010047ViewportStyleResolver::ViewportStyleResolver(Document* document)
Ben Murdochaafa69c2014-04-03 12:30:15 +010048 : m_document(document)
49 , m_hasAuthorStyle(false)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010050{
51 ASSERT(m_document);
52}
53
Torne (Richard Coles)1e202182013-10-18 15:46:42 +010054void ViewportStyleResolver::collectViewportRules(RuleSet* rules, Origin origin)
55{
56 rules->compactRulesIfNeeded();
57
Torne (Richard Coles)d5428f32014-03-18 10:21:16 +000058 const WillBeHeapVector<RawPtrWillBeMember<StyleRuleViewport> >& viewportRules = rules->viewportRules();
Torne (Richard Coles)1e202182013-10-18 15:46:42 +010059 for (size_t i = 0; i < viewportRules.size(); ++i)
60 addViewportRule(viewportRules[i], origin);
61}
62
63void ViewportStyleResolver::addViewportRule(StyleRuleViewport* viewportRule, Origin origin)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010064{
Torne (Richard Coles)d5428f32014-03-18 10:21:16 +000065 StylePropertySet& propertySet = viewportRule->mutableProperties();
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010066
Torne (Richard Coles)d5428f32014-03-18 10:21:16 +000067 unsigned propertyCount = propertySet.propertyCount();
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010068 if (!propertyCount)
69 return;
70
Torne (Richard Coles)1e202182013-10-18 15:46:42 +010071 if (origin == AuthorOrigin)
72 m_hasAuthorStyle = true;
73
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010074 if (!m_propertySet) {
Torne (Richard Coles)d5428f32014-03-18 10:21:16 +000075 m_propertySet = propertySet.mutableCopy();
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010076 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)
Torne (Richard Coles)d5428f32014-03-18 10:21:16 +000082 m_propertySet->addParsedProperty(propertySet.propertyAt(i).toCSSProperty());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010083}
84
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010085void ViewportStyleResolver::resolve()
86{
Torne (Richard Coles)c0e19a62013-08-30 15:15:11 +010087 if (!m_document)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010088 return;
89
Ben Murdochaafa69c2014-04-03 12:30:15 +010090 if (!m_propertySet) {
91 m_document->setViewportDescription(ViewportDescription(ViewportDescription::UserAgentStyleSheet));
Torne (Richard Coles)c0e19a62013-08-30 15:15:11 +010092 return;
93 }
94
Torne (Richard Coles)1e202182013-10-18 15:46:42 +010095 ViewportDescription description(m_hasAuthorStyle ? ViewportDescription::AuthorStyleSheet : ViewportDescription::UserAgentStyleSheet);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010096
Torne (Richard Coles)1e202182013-10-18 15:46:42 +010097 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);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100106
Torne (Richard Coles)1e202182013-10-18 15:46:42 +0100107 m_document->setViewportDescription(description);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100108
Torne (Richard Coles)d5428f32014-03-18 10:21:16 +0000109 m_propertySet = nullptr;
Torne (Richard Coles)8abfc582013-09-12 12:10:38 +0100110 m_hasAuthorStyle = false;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100111}
112
Torne (Richard Coles)8abfc582013-09-12 12:10:38 +0100113float ViewportStyleResolver::viewportArgumentValue(CSSPropertyID id) const
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100114{
Torne (Richard Coles)1e202182013-10-18 15:46:42 +0100115 float defaultValue = ViewportDescription::ValueAuto;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100116
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
Torne (Richard Coles)d5428f32014-03-18 10:21:16 +0000123 RefPtrWillBeRawPtr<CSSValue> value = m_propertySet->getPropertyCSSValue(id);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100124 if (!value || !value->isPrimitiveValue())
125 return defaultValue;
126
Torne (Richard Coles)e5249552013-05-15 11:35:13 +0100127 CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value.get());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100128
129 if (primitiveValue->isNumber() || primitiveValue->isPx())
130 return primitiveValue->getFloatValue();
131
132 if (primitiveValue->isFontRelativeLength())
Ben Murdoche69819b2013-07-17 14:56:49 +0100133 return primitiveValue->getFloatValue() * m_document->renderStyle()->fontDescription().computedSize();
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100134
135 if (primitiveValue->isPercentage()) {
136 float percentValue = primitiveValue->getFloatValue() / 100.0f;
137 switch (id) {
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100138 case CSSPropertyMaxZoom:
139 case CSSPropertyMinZoom:
140 case CSSPropertyZoom:
141 return percentValue;
142 default:
143 ASSERT_NOT_REACHED();
144 break;
145 }
146 }
147
Torne (Richard Coles)521d96e2013-06-19 11:58:24 +0100148 switch (primitiveValue->getValueID()) {
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100149 case CSSValueAuto:
150 return defaultValue;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100151 case CSSValueLandscape:
Torne (Richard Coles)1e202182013-10-18 15:46:42 +0100152 return ViewportDescription::ValueLandscape;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100153 case CSSValuePortrait:
Torne (Richard Coles)1e202182013-10-18 15:46:42 +0100154 return ViewportDescription::ValuePortrait;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100155 case CSSValueZoom:
156 return defaultValue;
Ben Murdoch7757ec22013-07-23 11:17:36 +0100157 case CSSValueInternalExtendToZoom:
Torne (Richard Coles)1e202182013-10-18 15:46:42 +0100158 return ViewportDescription::ValueExtendToZoom;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100159 case CSSValueFixed:
160 return 0;
161 default:
162 return defaultValue;
163 }
164}
165
Torne (Richard Coles)8abfc582013-09-12 12:10:38 +0100166Length ViewportStyleResolver::viewportLengthValue(CSSPropertyID id) const
167{
168 ASSERT(id == CSSPropertyMaxHeight
169 || id == CSSPropertyMinHeight
170 || id == CSSPropertyMaxWidth
171 || id == CSSPropertyMinWidth);
172
Torne (Richard Coles)d5428f32014-03-18 10:21:16 +0000173 RefPtrWillBeRawPtr<CSSValue> value = m_propertySet->getPropertyCSSValue(id);
Torne (Richard Coles)8abfc582013-09-12 12:10:38 +0100174 if (!value || !value->isPrimitiveValue())
175 return Length(); // auto
176
177 CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value.get());
178
Torne (Richard Coles)09380292014-02-21 12:17:33 +0000179 if (primitiveValue->getValueID() == CSSValueInternalExtendToZoom)
Torne (Richard Coles)8abfc582013-09-12 12:10:38 +0100180 return Length(ExtendToZoom);
Torne (Richard Coles)09380292014-02-21 12:17:33 +0000181
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;
Torne (Richard Coles)8abfc582013-09-12 12:10:38 +0100198}
199
Torne (Richard Coles)43e75022014-03-21 14:26:12 +0000200void ViewportStyleResolver::trace(Visitor* visitor)
201{
202 visitor->trace(m_propertySet);
203}
204
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100205} // namespace WebCore