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 "InternalSettings.h" 29 30 #include "RuntimeEnabledFeatures.h" 31 #include "bindings/v8/ExceptionState.h" 32 #include "core/dom/ExceptionCode.h" 33 #include "core/page/Page.h" 34 #include "core/frame/Settings.h" 35 #include "platform/ColorChooser.h" 36 #include "platform/Supplementable.h" 37 #include "platform/text/LocaleToScriptMapping.h" 38 39 #define InternalSettingsGuardForSettingsReturn(returnValue) \ 40 if (!settings()) { \ 41 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError); \ 42 return returnValue; \ 43 } 44 45 #define InternalSettingsGuardForSettings() \ 46 if (!settings()) { \ 47 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError); \ 48 return; \ 49 } 50 51 #define InternalSettingsGuardForPage() \ 52 if (!page()) { \ 53 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError); \ 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_originalExperimentalWebSocketEnabled(settings->experimentalWebSocketEnabled()) 63 , m_originalStyleScoped(RuntimeEnabledFeatures::styleScopedEnabled()) 64 , m_originalOverlayScrollbarsEnabled(RuntimeEnabledFeatures::overlayScrollbarsEnabled()) 65 , m_originalEditingBehavior(settings->editingBehaviorType()) 66 , m_originalTextAutosizingEnabled(settings->textAutosizingEnabled()) 67 , m_originalTextAutosizingWindowSizeOverride(settings->textAutosizingWindowSizeOverride()) 68 , m_originalAccessibilityFontScaleFactor(settings->accessibilityFontScaleFactor()) 69 , m_originalMediaTypeOverride(settings->mediaTypeOverride()) 70 , m_originalMockScrollbarsEnabled(settings->mockScrollbarsEnabled()) 71 , m_langAttributeAwareFormControlUIEnabled(RuntimeEnabledFeatures::langAttributeAwareFormControlUIEnabled()) 72 , m_imagesEnabled(settings->imagesEnabled()) 73 , m_shouldDisplaySubtitles(settings->shouldDisplaySubtitles()) 74 , m_shouldDisplayCaptions(settings->shouldDisplayCaptions()) 75 , m_shouldDisplayTextDescriptions(settings->shouldDisplayTextDescriptions()) 76 , m_defaultVideoPosterURL(settings->defaultVideoPosterURL()) 77 , m_originalCompositorDrivenAcceleratedScrollEnabled(settings->compositorDrivenAcceleratedScrollingEnabled()) 78 , m_originalLayerSquashingEnabled(settings->layerSquashingEnabled()) 79 , m_originalPasswordGenerationDecorationEnabled(settings->passwordGenerationDecorationEnabled()) 80 { 81 } 82 83 void InternalSettings::Backup::restoreTo(Settings* settings) 84 { 85 RuntimeEnabledFeatures::setCSSExclusionsEnabled(m_originalCSSExclusionsEnabled); 86 RuntimeEnabledFeatures::setAuthorShadowDOMForAnyElementEnabled(m_originalAuthorShadowDOMForAnyElementEnabled); 87 settings->setExperimentalWebSocketEnabled(m_originalExperimentalWebSocketEnabled); 88 RuntimeEnabledFeatures::setStyleScopedEnabled(m_originalStyleScoped); 89 RuntimeEnabledFeatures::setOverlayScrollbarsEnabled(m_originalOverlayScrollbarsEnabled); 90 settings->setEditingBehaviorType(m_originalEditingBehavior); 91 settings->setTextAutosizingEnabled(m_originalTextAutosizingEnabled); 92 settings->setTextAutosizingWindowSizeOverride(m_originalTextAutosizingWindowSizeOverride); 93 settings->setAccessibilityFontScaleFactor(m_originalAccessibilityFontScaleFactor); 94 settings->setMediaTypeOverride(m_originalMediaTypeOverride); 95 settings->setMockScrollbarsEnabled(m_originalMockScrollbarsEnabled); 96 RuntimeEnabledFeatures::setLangAttributeAwareFormControlUIEnabled(m_langAttributeAwareFormControlUIEnabled); 97 settings->setImagesEnabled(m_imagesEnabled); 98 settings->setShouldDisplaySubtitles(m_shouldDisplaySubtitles); 99 settings->setShouldDisplayCaptions(m_shouldDisplayCaptions); 100 settings->setShouldDisplayTextDescriptions(m_shouldDisplayTextDescriptions); 101 settings->setDefaultVideoPosterURL(m_defaultVideoPosterURL); 102 settings->setCompositorDrivenAcceleratedScrollingEnabled(m_originalCompositorDrivenAcceleratedScrollEnabled); 103 settings->setLayerSquashingEnabled(m_originalLayerSquashingEnabled); 104 settings->setPasswordGenerationDecorationEnabled(m_originalPasswordGenerationDecorationEnabled); 105 settings->genericFontFamilySettings().reset(); 106 } 107 108 // We can't use RefCountedSupplement because that would try to make InternalSettings RefCounted 109 // and InternalSettings is already RefCounted via its base class, InternalSettingsGenerated. 110 // Instead, we manually make InternalSettings supplement Page. 111 class InternalSettingsWrapper : public Supplement<Page> { 112 public: 113 explicit InternalSettingsWrapper(Page* page) 114 : m_internalSettings(InternalSettings::create(page)) { } 115 virtual ~InternalSettingsWrapper() { m_internalSettings->hostDestroyed(); } 116 #if !ASSERT_DISABLED 117 virtual bool isRefCountedWrapper() const OVERRIDE { return true; } 118 #endif 119 InternalSettings* internalSettings() const { return m_internalSettings.get(); } 120 121 private: 122 RefPtr<InternalSettings> m_internalSettings; 123 }; 124 125 const char* InternalSettings::supplementName() 126 { 127 return "InternalSettings"; 128 } 129 130 InternalSettings* InternalSettings::from(Page* page) 131 { 132 if (!Supplement<Page>::from(page, supplementName())) 133 Supplement<Page>::provideTo(page, supplementName(), adoptPtr(new InternalSettingsWrapper(page))); 134 return static_cast<InternalSettingsWrapper*>(Supplement<Page>::from(page, supplementName()))->internalSettings(); 135 } 136 137 InternalSettings::~InternalSettings() 138 { 139 } 140 141 InternalSettings::InternalSettings(Page* page) 142 : InternalSettingsGenerated(page) 143 , m_page(page) 144 , m_backup(&page->settings()) 145 { 146 } 147 148 void InternalSettings::resetToConsistentState() 149 { 150 page()->setPageScaleFactor(1, IntPoint(0, 0)); 151 152 m_backup.restoreTo(settings()); 153 m_backup = Backup(settings()); 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::setExperimentalWebSocketEnabled(bool isEnabled) 177 { 178 settings()->setExperimentalWebSocketEnabled(isEnabled); 179 } 180 181 void InternalSettings::setStyleScopedEnabled(bool enabled) 182 { 183 RuntimeEnabledFeatures::setStyleScopedEnabled(enabled); 184 } 185 186 void InternalSettings::setOverlayScrollbarsEnabled(bool enabled) 187 { 188 RuntimeEnabledFeatures::setOverlayScrollbarsEnabled(enabled); 189 } 190 191 void InternalSettings::setTouchEventEmulationEnabled(bool enabled, ExceptionState& exceptionState) 192 { 193 InternalSettingsGuardForSettings(); 194 settings()->setTouchEventEmulationEnabled(enabled); 195 } 196 197 void InternalSettings::setViewportEnabled(bool enabled, ExceptionState& exceptionState) 198 { 199 InternalSettingsGuardForSettings(); 200 settings()->setViewportEnabled(enabled); 201 } 202 203 // FIXME: This is a temporary flag and should be removed once accelerated 204 // overflow scroll is ready (crbug.com/254111). 205 void InternalSettings::setCompositorDrivenAcceleratedScrollingEnabled(bool enabled, ExceptionState& exceptionState) 206 { 207 InternalSettingsGuardForSettings(); 208 settings()->setCompositorDrivenAcceleratedScrollingEnabled(enabled); 209 } 210 211 // FIXME: This is a temporary flag and should be removed once squashing is 212 // ready (crbug.com/261605). 213 void InternalSettings::setLayerSquashingEnabled(bool enabled, ExceptionState& exceptionState) 214 { 215 InternalSettingsGuardForSettings(); 216 settings()->setLayerSquashingEnabled(enabled); 217 } 218 219 void InternalSettings::setStandardFontFamily(const String& family, const String& script, ExceptionState& exceptionState) 220 { 221 InternalSettingsGuardForSettings(); 222 UScriptCode code = scriptNameToCode(script); 223 if (code == USCRIPT_INVALID_CODE) 224 return; 225 settings()->genericFontFamilySettings().setStandard(family, code); 226 m_page->setNeedsRecalcStyleInAllFrames(); 227 } 228 229 void InternalSettings::setSerifFontFamily(const String& family, const String& script, ExceptionState& exceptionState) 230 { 231 InternalSettingsGuardForSettings(); 232 UScriptCode code = scriptNameToCode(script); 233 if (code == USCRIPT_INVALID_CODE) 234 return; 235 settings()->genericFontFamilySettings().setSerif(family, code); 236 m_page->setNeedsRecalcStyleInAllFrames(); 237 } 238 239 void InternalSettings::setSansSerifFontFamily(const String& family, const String& script, ExceptionState& exceptionState) 240 { 241 InternalSettingsGuardForSettings(); 242 UScriptCode code = scriptNameToCode(script); 243 if (code == USCRIPT_INVALID_CODE) 244 return; 245 settings()->genericFontFamilySettings().setSansSerif(family, code); 246 m_page->setNeedsRecalcStyleInAllFrames(); 247 } 248 249 void InternalSettings::setFixedFontFamily(const String& family, const String& script, ExceptionState& exceptionState) 250 { 251 InternalSettingsGuardForSettings(); 252 UScriptCode code = scriptNameToCode(script); 253 if (code == USCRIPT_INVALID_CODE) 254 return; 255 settings()->genericFontFamilySettings().setFixed(family, code); 256 m_page->setNeedsRecalcStyleInAllFrames(); 257 } 258 259 void InternalSettings::setCursiveFontFamily(const String& family, const String& script, ExceptionState& exceptionState) 260 { 261 InternalSettingsGuardForSettings(); 262 UScriptCode code = scriptNameToCode(script); 263 if (code == USCRIPT_INVALID_CODE) 264 return; 265 settings()->genericFontFamilySettings().setCursive(family, code); 266 m_page->setNeedsRecalcStyleInAllFrames(); 267 } 268 269 void InternalSettings::setFantasyFontFamily(const String& family, const String& script, ExceptionState& exceptionState) 270 { 271 InternalSettingsGuardForSettings(); 272 UScriptCode code = scriptNameToCode(script); 273 if (code == USCRIPT_INVALID_CODE) 274 return; 275 settings()->genericFontFamilySettings().setFantasy(family, code); 276 m_page->setNeedsRecalcStyleInAllFrames(); 277 } 278 279 void InternalSettings::setPictographFontFamily(const String& family, const String& script, ExceptionState& exceptionState) 280 { 281 InternalSettingsGuardForSettings(); 282 UScriptCode code = scriptNameToCode(script); 283 if (code == USCRIPT_INVALID_CODE) 284 return; 285 settings()->genericFontFamilySettings().setPictograph(family, code); 286 m_page->setNeedsRecalcStyleInAllFrames(); 287 } 288 289 void InternalSettings::setTextAutosizingEnabled(bool enabled, ExceptionState& exceptionState) 290 { 291 InternalSettingsGuardForSettings(); 292 settings()->setTextAutosizingEnabled(enabled); 293 } 294 295 void InternalSettings::setTextAutosizingWindowSizeOverride(int width, int height, ExceptionState& exceptionState) 296 { 297 InternalSettingsGuardForSettings(); 298 settings()->setTextAutosizingWindowSizeOverride(IntSize(width, height)); 299 } 300 301 void InternalSettings::setMediaTypeOverride(const String& mediaType, ExceptionState& exceptionState) 302 { 303 InternalSettingsGuardForSettings(); 304 settings()->setMediaTypeOverride(mediaType); 305 } 306 307 void InternalSettings::setAccessibilityFontScaleFactor(float fontScaleFactor, ExceptionState& exceptionState) 308 { 309 InternalSettingsGuardForSettings(); 310 settings()->setAccessibilityFontScaleFactor(fontScaleFactor); 311 } 312 313 void InternalSettings::setCSSExclusionsEnabled(bool enabled) 314 { 315 RuntimeEnabledFeatures::setCSSExclusionsEnabled(enabled); 316 } 317 318 void InternalSettings::setEditingBehavior(const String& editingBehavior, ExceptionState& exceptionState) 319 { 320 InternalSettingsGuardForSettings(); 321 if (equalIgnoringCase(editingBehavior, "win")) 322 settings()->setEditingBehaviorType(EditingWindowsBehavior); 323 else if (equalIgnoringCase(editingBehavior, "mac")) 324 settings()->setEditingBehaviorType(EditingMacBehavior); 325 else if (equalIgnoringCase(editingBehavior, "unix")) 326 settings()->setEditingBehaviorType(EditingUnixBehavior); 327 else if (equalIgnoringCase(editingBehavior, "android")) 328 settings()->setEditingBehaviorType(EditingAndroidBehavior); 329 else 330 exceptionState.throwUninformativeAndGenericDOMException(SyntaxError); 331 } 332 333 void InternalSettings::setLangAttributeAwareFormControlUIEnabled(bool enabled) 334 { 335 RuntimeEnabledFeatures::setLangAttributeAwareFormControlUIEnabled(enabled); 336 } 337 338 void InternalSettings::setImagesEnabled(bool enabled, ExceptionState& exceptionState) 339 { 340 InternalSettingsGuardForSettings(); 341 settings()->setImagesEnabled(enabled); 342 } 343 344 void InternalSettings::setDefaultVideoPosterURL(const String& url, ExceptionState& exceptionState) 345 { 346 InternalSettingsGuardForSettings(); 347 settings()->setDefaultVideoPosterURL(url); 348 } 349 350 void InternalSettings::setPasswordGenerationDecorationEnabled(bool enabled, ExceptionState& exceptionState) 351 { 352 InternalSettingsGuardForSettings(); 353 settings()->setPasswordGenerationDecorationEnabled(enabled); 354 } 355 356 } 357