Home | History | Annotate | Download | only in resolver
      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