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