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 41namespace WebCore { 42 43ViewportStyleResolver::ViewportStyleResolver(Document* document) 44 : m_document(document), 45 m_hasAuthorStyle(false) 46{ 47 ASSERT(m_document); 48} 49 50ViewportStyleResolver::~ViewportStyleResolver() 51{ 52} 53 54void 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 63void 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 85void ViewportStyleResolver::clearDocument() 86{ 87 m_document = 0; 88} 89 90void 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 120float 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 173Length 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