1/*
2 * Copyright (C) 2012 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 "ViewportStyleResolver.h"
32
33#if ENABLE(CSS_DEVICE_ADAPTATION)
34
35#include "CSSValueKeywords.h"
36#include "Document.h"
37#include "NodeRenderStyle.h"
38#include "StyleProperties.h"
39#include "StyleRule.h"
40#include "ViewportArguments.h"
41
42namespace WebCore {
43
44ViewportStyleResolver::ViewportStyleResolver(Document* document)
45 : m_document(document ? makeWeakPtr(*document) : nullptr)
46{
47 ASSERT(m_document);
48}
49
50ViewportStyleResolver::~ViewportStyleResolver() = default;
51
52void ViewportStyleResolver::addViewportRule(StyleRuleViewport* viewportRule)
53{
54 StyleProperties& propertySet = viewportRule->mutableProperties();
55
56 unsigned propertyCount = propertySet.propertyCount();
57 if (!propertyCount)
58 return;
59
60 if (!m_propertySet) {
61 m_propertySet = propertySet.mutableCopy();
62 return;
63 }
64
65 m_propertySet->mergeAndOverrideOnConflict(propertySet);
66}
67
68void ViewportStyleResolver::clearDocument()
69{
70 m_document = nullptr;
71}
72
73void ViewportStyleResolver::resolve()
74{
75 if (!m_document || !m_propertySet)
76 return;
77
78 ViewportArguments arguments(ViewportArguments::CSSDeviceAdaptation);
79
80 arguments.userZoom = getViewportArgumentValue(CSSPropertyUserZoom);
81 arguments.zoom = getViewportArgumentValue(CSSPropertyZoom);
82 arguments.minZoom = getViewportArgumentValue(CSSPropertyMinZoom);
83 arguments.maxZoom = getViewportArgumentValue(CSSPropertyMaxZoom);
84 arguments.minWidth = getViewportArgumentValue(CSSPropertyMinWidth);
85 arguments.maxWidth = getViewportArgumentValue(CSSPropertyMaxWidth);
86 arguments.minHeight = getViewportArgumentValue(CSSPropertyMinHeight);
87 arguments.maxHeight = getViewportArgumentValue(CSSPropertyMaxHeight);
88 arguments.orientation = getViewportArgumentValue(CSSPropertyOrientation);
89
90 m_document->setViewportArguments(arguments);
91 m_document->updateViewportArguments();
92
93 m_propertySet = nullptr;
94}
95
96float ViewportStyleResolver::getViewportArgumentValue(CSSPropertyID id) const
97{
98 float defaultValue = ViewportArguments::ValueAuto;
99
100 // UserZoom default value is CSSValueZoom, which maps to true, meaning that
101 // yes, it is user scalable. When the value is set to CSSValueFixed, we
102 // return false.
103 if (id == CSSPropertyUserZoom)
104 defaultValue = 1;
105
106 RefPtr<CSSValue> value = m_propertySet->getPropertyCSSValue(id);
107 if (!is<CSSPrimitiveValue>(value))
108 return defaultValue;
109
110 CSSPrimitiveValue& primitiveValue = downcast<CSSPrimitiveValue>(*value);
111
112 if (primitiveValue.isNumber() || primitiveValue.isPx())
113 return primitiveValue.floatValue();
114
115 if (primitiveValue.isFontRelativeLength())
116 return primitiveValue.floatValue() * m_document->documentElement()->renderStyle()->fontDescription().computedSize();
117
118 if (primitiveValue.isPercentage()) {
119 float percentValue = primitiveValue.floatValue() / 100.0f;
120 switch (id) {
121 case CSSPropertyMaxHeight:
122 case CSSPropertyMinHeight:
123 ASSERT(m_document->initialViewportSize().height() > 0);
124 return percentValue * m_document->initialViewportSize().height();
125 case CSSPropertyMaxWidth:
126 case CSSPropertyMinWidth:
127 ASSERT(m_document->initialViewportSize().width() > 0);
128 return percentValue * m_document->initialViewportSize().width();
129 case CSSPropertyMaxZoom:
130 case CSSPropertyMinZoom:
131 case CSSPropertyZoom:
132 return percentValue;
133 default:
134 ASSERT_NOT_REACHED();
135 break;
136 }
137 }
138
139 switch (primitiveValue.valueID()) {
140 case CSSValueAuto:
141 return defaultValue;
142 case CSSValueDeviceHeight:
143 return ViewportArguments::ValueDeviceHeight;
144 case CSSValueDeviceWidth:
145 return ViewportArguments::ValueDeviceWidth;
146 case CSSValueLandscape:
147 return ViewportArguments::ValueLandscape;
148 case CSSValuePortrait:
149 return ViewportArguments::ValuePortrait;
150 case CSSValueZoom:
151 return defaultValue;
152 case CSSValueFixed:
153 return 0;
154 default:
155 return defaultValue;
156 }
157}
158
159} // namespace WebCore
160
161#endif // ENABLE(CSS_DEVICE_ADAPTATION)
162