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