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/page/Settings.h" 35 #include "core/platform/ColorChooser.h" 36 #include "core/platform/Supplementable.h" 37 #include "core/platform/text/LocaleToScriptMapping.h" 38 39 #define InternalSettingsGuardForSettingsReturn(returnValue) \ 40 if (!settings()) { \ 41 es.throwDOMException(InvalidAccessError); \ 42 return returnValue; \ 43 } 44 45 #define InternalSettingsGuardForSettings() \ 46 if (!settings()) { \ 47 es.throwDOMException(InvalidAccessError); \ 48 return; \ 49 } 50 51 #define InternalSettingsGuardForPage() \ 52 if (!page()) { \ 53 es.throwDOMException(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_originalEditingBehavior(settings->editingBehaviorType()) 65 , m_originalTextAutosizingEnabled(settings->textAutosizingEnabled()) 66 , m_originalTextAutosizingWindowSizeOverride(settings->textAutosizingWindowSizeOverride()) 67 , m_originalTextAutosizingFontScaleFactor(settings->textAutosizingFontScaleFactor()) 68 , m_originalMediaTypeOverride(settings->mediaTypeOverride()) 69 , m_originalLazyLayoutEnabled(RuntimeEnabledFeatures::lazyLayoutEnabled()) 70 , m_originalMockScrollbarsEnabled(settings->mockScrollbarsEnabled()) 71 , m_langAttributeAwareFormControlUIEnabled(RuntimeEnabledFeatures::langAttributeAwareFormControlUIEnabled()) 72 , m_imagesEnabled(settings->areImagesEnabled()) 73 , m_shouldDisplaySubtitles(settings->shouldDisplaySubtitles()) 74 , m_shouldDisplayCaptions(settings->shouldDisplayCaptions()) 75 , m_shouldDisplayTextDescriptions(settings->shouldDisplayTextDescriptions()) 76 , m_defaultVideoPosterURL(settings->defaultVideoPosterURL()) 77 { 78 } 79 80 void InternalSettings::Backup::restoreTo(Settings* settings) 81 { 82 RuntimeEnabledFeatures::setCSSExclusionsEnabled(m_originalCSSExclusionsEnabled); 83 RuntimeEnabledFeatures::setAuthorShadowDOMForAnyElementEnabled(m_originalAuthorShadowDOMForAnyElementEnabled); 84 settings->setExperimentalWebSocketEnabled(m_originalExperimentalWebSocketEnabled); 85 RuntimeEnabledFeatures::setStyleScopedEnabled(m_originalStyleScoped); 86 settings->setEditingBehaviorType(m_originalEditingBehavior); 87 settings->setTextAutosizingEnabled(m_originalTextAutosizingEnabled); 88 settings->setTextAutosizingWindowSizeOverride(m_originalTextAutosizingWindowSizeOverride); 89 settings->setTextAutosizingFontScaleFactor(m_originalTextAutosizingFontScaleFactor); 90 settings->setMediaTypeOverride(m_originalMediaTypeOverride); 91 RuntimeEnabledFeatures::setLazyLayoutEnabled(m_originalLazyLayoutEnabled); 92 settings->setMockScrollbarsEnabled(m_originalMockScrollbarsEnabled); 93 RuntimeEnabledFeatures::setLangAttributeAwareFormControlUIEnabled(m_langAttributeAwareFormControlUIEnabled); 94 settings->setImagesEnabled(m_imagesEnabled); 95 settings->setShouldDisplaySubtitles(m_shouldDisplaySubtitles); 96 settings->setShouldDisplayCaptions(m_shouldDisplayCaptions); 97 settings->setShouldDisplayTextDescriptions(m_shouldDisplayTextDescriptions); 98 settings->setDefaultVideoPosterURL(m_defaultVideoPosterURL); 99 } 100 101 // We can't use RefCountedSupplement because that would try to make InternalSettings RefCounted 102 // and InternalSettings is already RefCounted via its base class, InternalSettingsGenerated. 103 // Instead, we manually make InternalSettings supplement Page. 104 class InternalSettingsWrapper : public Supplement<Page> { 105 public: 106 explicit InternalSettingsWrapper(Page* page) 107 : m_internalSettings(InternalSettings::create(page)) { } 108 virtual ~InternalSettingsWrapper() { m_internalSettings->hostDestroyed(); } 109 #if !ASSERT_DISABLED 110 virtual bool isRefCountedWrapper() const OVERRIDE { return true; } 111 #endif 112 InternalSettings* internalSettings() const { return m_internalSettings.get(); } 113 114 private: 115 RefPtr<InternalSettings> m_internalSettings; 116 }; 117 118 const char* InternalSettings::supplementName() 119 { 120 return "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 130 InternalSettings::~InternalSettings() 131 { 132 } 133 134 InternalSettings::InternalSettings(Page* page) 135 : InternalSettingsGenerated(page) 136 , m_page(page) 137 , m_backup(page->settings()) 138 { 139 } 140 141 void InternalSettings::resetToConsistentState() 142 { 143 page()->setPageScaleFactor(1, IntPoint(0, 0)); 144 145 m_backup.restoreTo(settings()); 146 m_backup = Backup(settings()); 147 148 InternalSettingsGenerated::resetToConsistentState(); 149 } 150 151 Settings* InternalSettings::settings() const 152 { 153 if (!page()) 154 return 0; 155 return page()->settings(); 156 } 157 158 void InternalSettings::setMockScrollbarsEnabled(bool enabled, ExceptionState& es) 159 { 160 InternalSettingsGuardForSettings(); 161 settings()->setMockScrollbarsEnabled(enabled); 162 } 163 164 void InternalSettings::setAuthorShadowDOMForAnyElementEnabled(bool isEnabled) 165 { 166 RuntimeEnabledFeatures::setAuthorShadowDOMForAnyElementEnabled(isEnabled); 167 } 168 169 void InternalSettings::setExperimentalWebSocketEnabled(bool isEnabled) 170 { 171 settings()->setExperimentalWebSocketEnabled(isEnabled); 172 } 173 174 void InternalSettings::setStyleScopedEnabled(bool enabled) 175 { 176 RuntimeEnabledFeatures::setStyleScopedEnabled(enabled); 177 } 178 179 void InternalSettings::setTouchEventEmulationEnabled(bool enabled, ExceptionState& es) 180 { 181 InternalSettingsGuardForSettings(); 182 settings()->setTouchEventEmulationEnabled(enabled); 183 } 184 185 // FIXME: This is a temporary flag and should be removed once accelerated 186 // overflow scroll is ready (crbug.com/254111). 187 void InternalSettings::setCompositorDrivenAcceleratedScrollingEnabled(bool enabled, ExceptionState& es) 188 { 189 InternalSettingsGuardForSettings(); 190 settings()->setCompositorDrivenAcceleratedScrollingEnabled(enabled); 191 } 192 193 typedef void (Settings::*SetFontFamilyFunction)(const AtomicString&, UScriptCode); 194 static void setFontFamily(Settings* settings, const String& family, const String& script, SetFontFamilyFunction setter) 195 { 196 UScriptCode code = scriptNameToCode(script); 197 if (code != USCRIPT_INVALID_CODE) 198 (settings->*setter)(family, code); 199 } 200 201 void InternalSettings::setStandardFontFamily(const String& family, const String& script, ExceptionState& es) 202 { 203 InternalSettingsGuardForSettings(); 204 setFontFamily(settings(), family, script, &Settings::setStandardFontFamily); 205 } 206 207 void InternalSettings::setSerifFontFamily(const String& family, const String& script, ExceptionState& es) 208 { 209 InternalSettingsGuardForSettings(); 210 setFontFamily(settings(), family, script, &Settings::setSerifFontFamily); 211 } 212 213 void InternalSettings::setSansSerifFontFamily(const String& family, const String& script, ExceptionState& es) 214 { 215 InternalSettingsGuardForSettings(); 216 setFontFamily(settings(), family, script, &Settings::setSansSerifFontFamily); 217 } 218 219 void InternalSettings::setFixedFontFamily(const String& family, const String& script, ExceptionState& es) 220 { 221 InternalSettingsGuardForSettings(); 222 setFontFamily(settings(), family, script, &Settings::setFixedFontFamily); 223 } 224 225 void InternalSettings::setCursiveFontFamily(const String& family, const String& script, ExceptionState& es) 226 { 227 InternalSettingsGuardForSettings(); 228 setFontFamily(settings(), family, script, &Settings::setCursiveFontFamily); 229 } 230 231 void InternalSettings::setFantasyFontFamily(const String& family, const String& script, ExceptionState& es) 232 { 233 InternalSettingsGuardForSettings(); 234 setFontFamily(settings(), family, script, &Settings::setFantasyFontFamily); 235 } 236 237 void InternalSettings::setPictographFontFamily(const String& family, const String& script, ExceptionState& es) 238 { 239 InternalSettingsGuardForSettings(); 240 setFontFamily(settings(), family, script, &Settings::setPictographFontFamily); 241 } 242 243 void InternalSettings::setTextAutosizingEnabled(bool enabled, ExceptionState& es) 244 { 245 InternalSettingsGuardForSettings(); 246 settings()->setTextAutosizingEnabled(enabled); 247 } 248 249 void InternalSettings::setTextAutosizingWindowSizeOverride(int width, int height, ExceptionState& es) 250 { 251 InternalSettingsGuardForSettings(); 252 settings()->setTextAutosizingWindowSizeOverride(IntSize(width, height)); 253 } 254 255 void InternalSettings::setMediaTypeOverride(const String& mediaType, ExceptionState& es) 256 { 257 InternalSettingsGuardForSettings(); 258 settings()->setMediaTypeOverride(mediaType); 259 } 260 261 void InternalSettings::setTextAutosizingFontScaleFactor(float fontScaleFactor, ExceptionState& es) 262 { 263 InternalSettingsGuardForSettings(); 264 settings()->setTextAutosizingFontScaleFactor(fontScaleFactor); 265 } 266 267 void InternalSettings::setCSSExclusionsEnabled(bool enabled) 268 { 269 RuntimeEnabledFeatures::setCSSExclusionsEnabled(enabled); 270 } 271 272 void InternalSettings::setEditingBehavior(const String& editingBehavior, ExceptionState& es) 273 { 274 InternalSettingsGuardForSettings(); 275 if (equalIgnoringCase(editingBehavior, "win")) 276 settings()->setEditingBehaviorType(EditingWindowsBehavior); 277 else if (equalIgnoringCase(editingBehavior, "mac")) 278 settings()->setEditingBehaviorType(EditingMacBehavior); 279 else if (equalIgnoringCase(editingBehavior, "unix")) 280 settings()->setEditingBehaviorType(EditingUnixBehavior); 281 else if (equalIgnoringCase(editingBehavior, "android")) 282 settings()->setEditingBehaviorType(EditingAndroidBehavior); 283 else 284 es.throwDOMException(SyntaxError); 285 } 286 287 void InternalSettings::setLazyLayoutEnabled(bool enabled) 288 { 289 RuntimeEnabledFeatures::setLazyLayoutEnabled(enabled); 290 } 291 292 void InternalSettings::setLangAttributeAwareFormControlUIEnabled(bool enabled) 293 { 294 RuntimeEnabledFeatures::setLangAttributeAwareFormControlUIEnabled(enabled); 295 } 296 297 void InternalSettings::setImagesEnabled(bool enabled, ExceptionState& es) 298 { 299 InternalSettingsGuardForSettings(); 300 settings()->setImagesEnabled(enabled); 301 } 302 303 void InternalSettings::setDefaultVideoPosterURL(const String& url, ExceptionState& es) 304 { 305 InternalSettingsGuardForSettings(); 306 settings()->setDefaultVideoPosterURL(url); 307 } 308 309 } 310