Home | History | Annotate | Download | only in testing
      1 /*
      2  * Copyright (C) 2012 Google Inc. All rights reserved.
      3  * Copyright (C) 2013 Apple Inc. All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  *
      9  * 1.  Redistributions of source code must retain the above copyright
     10  *     notice, this list of conditions and the following disclaimer.
     11  * 2.  Redistributions in binary form must reproduce the above copyright
     12  *     notice, this list of conditions and the following disclaimer in the
     13  *     documentation and/or other materials provided with the distribution.
     14  *
     15  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
     16  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     18  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
     19  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     20  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     21  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     22  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     25  */
     26 
     27 #include "config.h"
     28 #include "core/testing/InternalSettings.h"
     29 
     30 #include "bindings/v8/ExceptionState.h"
     31 #include "core/dom/ExceptionCode.h"
     32 #include "core/frame/Settings.h"
     33 #include "core/inspector/InspectorController.h"
     34 #include "core/page/Page.h"
     35 #include "platform/RuntimeEnabledFeatures.h"
     36 #include "platform/Supplementable.h"
     37 #include "platform/text/LocaleToScriptMapping.h"
     38 
     39 #define InternalSettingsGuardForSettingsReturn(returnValue) \
     40     if (!settings()) { \
     41         exceptionState.throwDOMException(InvalidAccessError, "The settings object cannot be obtained."); \
     42         return returnValue; \
     43     }
     44 
     45 #define InternalSettingsGuardForSettings()  \
     46     if (!settings()) { \
     47         exceptionState.throwDOMException(InvalidAccessError, "The settings object cannot be obtained."); \
     48         return; \
     49     }
     50 
     51 #define InternalSettingsGuardForPage() \
     52     if (!page()) { \
     53         exceptionState.throwDOMException(InvalidAccessError, "The page object cannot be obtained."); \
     54         return; \
     55     }
     56 
     57 namespace WebCore {
     58 
     59 InternalSettings::Backup::Backup(Settings* settings)
     60     : m_originalCSSExclusionsEnabled(RuntimeEnabledFeatures::cssExclusionsEnabled())
     61     , m_originalAuthorShadowDOMForAnyElementEnabled(RuntimeEnabledFeatures::authorShadowDOMForAnyElementEnabled())
     62     , m_originalCSP(RuntimeEnabledFeatures::experimentalContentSecurityPolicyFeaturesEnabled())
     63     , m_originalOverlayScrollbarsEnabled(RuntimeEnabledFeatures::overlayScrollbarsEnabled())
     64     , m_originalEditingBehavior(settings->editingBehaviorType())
     65     , m_originalTextAutosizingEnabled(settings->textAutosizingEnabled())
     66     , m_originalTextAutosizingWindowSizeOverride(settings->textAutosizingWindowSizeOverride())
     67     , m_originalAccessibilityFontScaleFactor(settings->accessibilityFontScaleFactor())
     68     , m_originalMediaTypeOverride(settings->mediaTypeOverride())
     69     , m_originalMockScrollbarsEnabled(settings->mockScrollbarsEnabled())
     70     , m_langAttributeAwareFormControlUIEnabled(RuntimeEnabledFeatures::langAttributeAwareFormControlUIEnabled())
     71     , m_imagesEnabled(settings->imagesEnabled())
     72     , m_defaultVideoPosterURL(settings->defaultVideoPosterURL())
     73     , m_originalLayerSquashingEnabled(settings->layerSquashingEnabled())
     74     , m_originalPseudoClassesInMatchingCriteriaInAuthorShadowTreesEnabled(RuntimeEnabledFeatures::pseudoClassesInMatchingCriteriaInAuthorShadowTreesEnabled())
     75 {
     76 }
     77 
     78 void InternalSettings::Backup::restoreTo(Settings* settings)
     79 {
     80     RuntimeEnabledFeatures::setCSSExclusionsEnabled(m_originalCSSExclusionsEnabled);
     81     RuntimeEnabledFeatures::setAuthorShadowDOMForAnyElementEnabled(m_originalAuthorShadowDOMForAnyElementEnabled);
     82     RuntimeEnabledFeatures::setExperimentalContentSecurityPolicyFeaturesEnabled(m_originalCSP);
     83     RuntimeEnabledFeatures::setOverlayScrollbarsEnabled(m_originalOverlayScrollbarsEnabled);
     84     settings->setEditingBehaviorType(m_originalEditingBehavior);
     85     settings->setTextAutosizingEnabled(m_originalTextAutosizingEnabled);
     86     settings->setTextAutosizingWindowSizeOverride(m_originalTextAutosizingWindowSizeOverride);
     87     settings->setAccessibilityFontScaleFactor(m_originalAccessibilityFontScaleFactor);
     88     settings->setMediaTypeOverride(m_originalMediaTypeOverride);
     89     settings->setMockScrollbarsEnabled(m_originalMockScrollbarsEnabled);
     90     RuntimeEnabledFeatures::setLangAttributeAwareFormControlUIEnabled(m_langAttributeAwareFormControlUIEnabled);
     91     settings->setImagesEnabled(m_imagesEnabled);
     92     settings->setDefaultVideoPosterURL(m_defaultVideoPosterURL);
     93     settings->setLayerSquashingEnabled(m_originalLayerSquashingEnabled);
     94     settings->genericFontFamilySettings().reset();
     95     RuntimeEnabledFeatures::setPseudoClassesInMatchingCriteriaInAuthorShadowTreesEnabled(m_originalPseudoClassesInMatchingCriteriaInAuthorShadowTreesEnabled);
     96 }
     97 
     98 #if ENABLE(OILPAN)
     99 InternalSettings* InternalSettings::from(Page& page)
    100 {
    101     if (!HeapSupplement<Page>::from(page, supplementName()))
    102         HeapSupplement<Page>::provideTo(page, supplementName(), new InternalSettings(page));
    103     return static_cast<InternalSettings*>(HeapSupplement<Page>::from(page, supplementName()));
    104 }
    105 #else
    106 // We can't use RefCountedSupplement because that would try to make InternalSettings RefCounted
    107 // and InternalSettings is already RefCounted via its base class, InternalSettingsGenerated.
    108 // Instead, we manually make InternalSettings supplement Page.
    109 class InternalSettingsWrapper : public Supplement<Page> {
    110 public:
    111     explicit InternalSettingsWrapper(Page& page)
    112         : m_internalSettings(InternalSettings::create(page)) { }
    113     virtual ~InternalSettingsWrapper() { m_internalSettings->hostDestroyed(); }
    114 #if ASSERT_ENABLED
    115     virtual bool isRefCountedWrapper() const OVERRIDE { return true; }
    116 #endif
    117     InternalSettings* internalSettings() const { return m_internalSettings.get(); }
    118 
    119 private:
    120     RefPtr<InternalSettings> m_internalSettings;
    121 };
    122 
    123 InternalSettings* InternalSettings::from(Page& page)
    124 {
    125     if (!Supplement<Page>::from(page, supplementName()))
    126         Supplement<Page>::provideTo(page, supplementName(), adoptPtr(new InternalSettingsWrapper(page)));
    127     return static_cast<InternalSettingsWrapper*>(Supplement<Page>::from(page, supplementName()))->internalSettings();
    128 }
    129 #endif
    130 
    131 const char* InternalSettings::supplementName()
    132 {
    133     return "InternalSettings";
    134 }
    135 
    136 InternalSettings::~InternalSettings()
    137 {
    138 }
    139 
    140 InternalSettings::InternalSettings(Page& page)
    141     : InternalSettingsGenerated(&page)
    142     , m_page(&page)
    143     , m_backup(&page.settings())
    144 {
    145 }
    146 
    147 void InternalSettings::resetToConsistentState()
    148 {
    149     page()->setPageScaleFactor(1, IntPoint(0, 0));
    150 
    151     m_backup.restoreTo(settings());
    152     m_backup = Backup(settings());
    153     m_backup.m_originalTextAutosizingEnabled = settings()->textAutosizingEnabled();
    154 
    155     InternalSettingsGenerated::resetToConsistentState();
    156 }
    157 
    158 Settings* InternalSettings::settings() const
    159 {
    160     if (!page())
    161         return 0;
    162     return &page()->settings();
    163 }
    164 
    165 void InternalSettings::setMockScrollbarsEnabled(bool enabled, ExceptionState& exceptionState)
    166 {
    167     InternalSettingsGuardForSettings();
    168     settings()->setMockScrollbarsEnabled(enabled);
    169 }
    170 
    171 void InternalSettings::setAuthorShadowDOMForAnyElementEnabled(bool isEnabled)
    172 {
    173     RuntimeEnabledFeatures::setAuthorShadowDOMForAnyElementEnabled(isEnabled);
    174 }
    175 
    176 void InternalSettings::setExperimentalContentSecurityPolicyFeaturesEnabled(bool enabled)
    177 {
    178     RuntimeEnabledFeatures::setExperimentalContentSecurityPolicyFeaturesEnabled(enabled);
    179 }
    180 
    181 void InternalSettings::setPseudoClassesInMatchingCriteriaInAuthorShadowTreesEnabled(bool enabled)
    182 {
    183     RuntimeEnabledFeatures::setPseudoClassesInMatchingCriteriaInAuthorShadowTreesEnabled(enabled);
    184 }
    185 
    186 void InternalSettings::setOverlayScrollbarsEnabled(bool enabled)
    187 {
    188     RuntimeEnabledFeatures::setOverlayScrollbarsEnabled(enabled);
    189 }
    190 
    191 void InternalSettings::setViewportEnabled(bool enabled, ExceptionState& exceptionState)
    192 {
    193     InternalSettingsGuardForSettings();
    194     settings()->setViewportEnabled(enabled);
    195 }
    196 
    197 // FIXME: This is a temporary flag and should be removed once squashing is
    198 // ready (crbug.com/261605).
    199 void InternalSettings::setLayerSquashingEnabled(bool enabled, ExceptionState& exceptionState)
    200 {
    201     InternalSettingsGuardForSettings();
    202     settings()->setLayerSquashingEnabled(enabled);
    203 }
    204 
    205 void InternalSettings::setStandardFontFamily(const AtomicString& family, const String& script, ExceptionState& exceptionState)
    206 {
    207     InternalSettingsGuardForSettings();
    208     UScriptCode code = scriptNameToCode(script);
    209     if (code == USCRIPT_INVALID_CODE)
    210         return;
    211     settings()->genericFontFamilySettings().setStandard(family, code);
    212     settings()->notifyGenericFontFamilyChange();
    213 }
    214 
    215 void InternalSettings::setSerifFontFamily(const AtomicString& family, const String& script, ExceptionState& exceptionState)
    216 {
    217     InternalSettingsGuardForSettings();
    218     UScriptCode code = scriptNameToCode(script);
    219     if (code == USCRIPT_INVALID_CODE)
    220         return;
    221     settings()->genericFontFamilySettings().setSerif(family, code);
    222     settings()->notifyGenericFontFamilyChange();
    223 }
    224 
    225 void InternalSettings::setSansSerifFontFamily(const AtomicString& family, const String& script, ExceptionState& exceptionState)
    226 {
    227     InternalSettingsGuardForSettings();
    228     UScriptCode code = scriptNameToCode(script);
    229     if (code == USCRIPT_INVALID_CODE)
    230         return;
    231     settings()->genericFontFamilySettings().setSansSerif(family, code);
    232     settings()->notifyGenericFontFamilyChange();
    233 }
    234 
    235 void InternalSettings::setFixedFontFamily(const AtomicString& family, const String& script, ExceptionState& exceptionState)
    236 {
    237     InternalSettingsGuardForSettings();
    238     UScriptCode code = scriptNameToCode(script);
    239     if (code == USCRIPT_INVALID_CODE)
    240         return;
    241     settings()->genericFontFamilySettings().setFixed(family, code);
    242     settings()->notifyGenericFontFamilyChange();
    243 }
    244 
    245 void InternalSettings::setCursiveFontFamily(const AtomicString& family, const String& script, ExceptionState& exceptionState)
    246 {
    247     InternalSettingsGuardForSettings();
    248     UScriptCode code = scriptNameToCode(script);
    249     if (code == USCRIPT_INVALID_CODE)
    250         return;
    251     settings()->genericFontFamilySettings().setCursive(family, code);
    252     settings()->notifyGenericFontFamilyChange();
    253 }
    254 
    255 void InternalSettings::setFantasyFontFamily(const AtomicString& family, const String& script, ExceptionState& exceptionState)
    256 {
    257     InternalSettingsGuardForSettings();
    258     UScriptCode code = scriptNameToCode(script);
    259     if (code == USCRIPT_INVALID_CODE)
    260         return;
    261     settings()->genericFontFamilySettings().setFantasy(family, code);
    262     settings()->notifyGenericFontFamilyChange();
    263 }
    264 
    265 void InternalSettings::setPictographFontFamily(const AtomicString& family, const String& script, ExceptionState& exceptionState)
    266 {
    267     InternalSettingsGuardForSettings();
    268     UScriptCode code = scriptNameToCode(script);
    269     if (code == USCRIPT_INVALID_CODE)
    270         return;
    271     settings()->genericFontFamilySettings().setPictograph(family, code);
    272     settings()->notifyGenericFontFamilyChange();
    273 }
    274 
    275 void InternalSettings::setTextAutosizingEnabled(bool enabled, ExceptionState& exceptionState)
    276 {
    277     InternalSettingsGuardForSettings();
    278     settings()->setTextAutosizingEnabled(enabled);
    279     m_page->inspectorController().setTextAutosizingEnabled(enabled);
    280 }
    281 
    282 void InternalSettings::setTextAutosizingWindowSizeOverride(int width, int height, ExceptionState& exceptionState)
    283 {
    284     InternalSettingsGuardForSettings();
    285     settings()->setTextAutosizingWindowSizeOverride(IntSize(width, height));
    286 }
    287 
    288 void InternalSettings::setMediaTypeOverride(const String& mediaType, ExceptionState& exceptionState)
    289 {
    290     InternalSettingsGuardForSettings();
    291     settings()->setMediaTypeOverride(mediaType);
    292 }
    293 
    294 void InternalSettings::setAccessibilityFontScaleFactor(float fontScaleFactor, ExceptionState& exceptionState)
    295 {
    296     InternalSettingsGuardForSettings();
    297     settings()->setAccessibilityFontScaleFactor(fontScaleFactor);
    298 }
    299 
    300 void InternalSettings::setCSSExclusionsEnabled(bool enabled)
    301 {
    302     RuntimeEnabledFeatures::setCSSExclusionsEnabled(enabled);
    303 }
    304 
    305 void InternalSettings::setEditingBehavior(const String& editingBehavior, ExceptionState& exceptionState)
    306 {
    307     InternalSettingsGuardForSettings();
    308     if (equalIgnoringCase(editingBehavior, "win"))
    309         settings()->setEditingBehaviorType(EditingWindowsBehavior);
    310     else if (equalIgnoringCase(editingBehavior, "mac"))
    311         settings()->setEditingBehaviorType(EditingMacBehavior);
    312     else if (equalIgnoringCase(editingBehavior, "unix"))
    313         settings()->setEditingBehaviorType(EditingUnixBehavior);
    314     else if (equalIgnoringCase(editingBehavior, "android"))
    315         settings()->setEditingBehaviorType(EditingAndroidBehavior);
    316     else
    317         exceptionState.throwDOMException(SyntaxError, "The editing behavior type provided ('" + editingBehavior + "') is invalid.");
    318 }
    319 
    320 void InternalSettings::setLangAttributeAwareFormControlUIEnabled(bool enabled)
    321 {
    322     RuntimeEnabledFeatures::setLangAttributeAwareFormControlUIEnabled(enabled);
    323 }
    324 
    325 void InternalSettings::setImagesEnabled(bool enabled, ExceptionState& exceptionState)
    326 {
    327     InternalSettingsGuardForSettings();
    328     settings()->setImagesEnabled(enabled);
    329 }
    330 
    331 void InternalSettings::setDefaultVideoPosterURL(const String& url, ExceptionState& exceptionState)
    332 {
    333     InternalSettingsGuardForSettings();
    334     settings()->setDefaultVideoPosterURL(url);
    335 }
    336 
    337 void InternalSettings::trace(Visitor* visitor)
    338 {
    339     visitor->trace(m_page);
    340     InternalSettingsGenerated::trace(visitor);
    341 #if ENABLE(OILPAN)
    342     HeapSupplement<Page>::trace(visitor);
    343 #endif
    344 }
    345 
    346 }
    347