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 "core/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 43namespace blink { 44 45DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(ViewportStyleResolver); 46 47ViewportStyleResolver::ViewportStyleResolver(Document* document) 48 : m_document(document) 49 , m_hasAuthorStyle(false) 50{ 51 ASSERT(m_document); 52} 53 54void 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 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::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 113float 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 166Length 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 200void ViewportStyleResolver::trace(Visitor* visitor) 201{ 202 visitor->trace(m_propertySet); 203 visitor->trace(m_document); 204} 205 206} // namespace blink 207