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 "CaptionUserPreferences.h" 31#include "Document.h" 32#include "ExceptionCode.h" 33#include "Frame.h" 34#include "FrameView.h" 35#include "Language.h" 36#include "LocaleToScriptMapping.h" 37#include "Page.h" 38#include "PageGroup.h" 39#include "RuntimeEnabledFeatures.h" 40#include "Settings.h" 41#include "Supplementable.h" 42#include "TextRun.h" 43 44#if ENABLE(INPUT_TYPE_COLOR) 45#include "ColorChooser.h" 46#endif 47 48#define InternalSettingsGuardForSettingsReturn(returnValue) \ 49 if (!settings()) { \ 50 ec = INVALID_ACCESS_ERR; \ 51 return returnValue; \ 52 } 53 54#define InternalSettingsGuardForSettings() \ 55 if (!settings()) { \ 56 ec = INVALID_ACCESS_ERR; \ 57 return; \ 58 } 59 60#define InternalSettingsGuardForPage() \ 61 if (!page()) { \ 62 ec = INVALID_ACCESS_ERR; \ 63 return; \ 64 } 65 66namespace WebCore { 67 68InternalSettings::Backup::Backup(Settings* settings) 69 : m_originalCSSExclusionsEnabled(RuntimeEnabledFeatures::cssExclusionsEnabled()) 70 , m_originalCSSShapesEnabled(RuntimeEnabledFeatures::cssShapesEnabled()) 71 , m_originalCSSVariablesEnabled(settings->cssVariablesEnabled()) 72#if ENABLE(SHADOW_DOM) 73 , m_originalShadowDOMEnabled(RuntimeEnabledFeatures::shadowDOMEnabled()) 74 , m_originalAuthorShadowDOMForAnyElementEnabled(RuntimeEnabledFeatures::authorShadowDOMForAnyElementEnabled()) 75#endif 76#if ENABLE(STYLE_SCOPED) 77 , m_originalStyleScoped(RuntimeEnabledFeatures::styleScopedEnabled()) 78#endif 79 , m_originalEditingBehavior(settings->editingBehaviorType()) 80#if ENABLE(TEXT_AUTOSIZING) 81 , m_originalTextAutosizingEnabled(settings->textAutosizingEnabled()) 82 , m_originalTextAutosizingWindowSizeOverride(settings->textAutosizingWindowSizeOverride()) 83 , m_originalTextAutosizingFontScaleFactor(settings->textAutosizingFontScaleFactor()) 84#endif 85 , m_originalMediaTypeOverride(settings->mediaTypeOverride()) 86#if ENABLE(DIALOG_ELEMENT) 87 , m_originalDialogElementEnabled(RuntimeEnabledFeatures::dialogElementEnabled()) 88#endif 89 , m_originalCanvasUsesAcceleratedDrawing(settings->canvasUsesAcceleratedDrawing()) 90 , m_originalMockScrollbarsEnabled(settings->mockScrollbarsEnabled()) 91 , m_langAttributeAwareFormControlUIEnabled(RuntimeEnabledFeatures::langAttributeAwareFormControlUIEnabled()) 92 , m_imagesEnabled(settings->areImagesEnabled()) 93 , m_minimumTimerInterval(settings->minDOMTimerInterval()) 94#if ENABLE(VIDEO_TRACK) 95 , m_shouldDisplaySubtitles(settings->shouldDisplaySubtitles()) 96 , m_shouldDisplayCaptions(settings->shouldDisplayCaptions()) 97 , m_shouldDisplayTextDescriptions(settings->shouldDisplayTextDescriptions()) 98#endif 99 , m_defaultVideoPosterURL(settings->defaultVideoPosterURL()) 100 , m_originalTimeWithoutMouseMovementBeforeHidingControls(settings->timeWithoutMouseMovementBeforeHidingControls()) 101 , m_useLegacyBackgroundSizeShorthandBehavior(settings->useLegacyBackgroundSizeShorthandBehavior()) 102{ 103} 104 105void InternalSettings::Backup::restoreTo(Settings* settings) 106{ 107 RuntimeEnabledFeatures::setCSSExclusionsEnabled(m_originalCSSExclusionsEnabled); 108 RuntimeEnabledFeatures::setCSSShapesEnabled(m_originalCSSShapesEnabled); 109 settings->setCSSVariablesEnabled(m_originalCSSVariablesEnabled); 110#if ENABLE(SHADOW_DOM) 111 RuntimeEnabledFeatures::setShadowDOMEnabled(m_originalShadowDOMEnabled); 112 RuntimeEnabledFeatures::setAuthorShadowDOMForAnyElementEnabled(m_originalAuthorShadowDOMForAnyElementEnabled); 113#endif 114#if ENABLE(STYLE_SCOPED) 115 RuntimeEnabledFeatures::setStyleScopedEnabled(m_originalStyleScoped); 116#endif 117 settings->setEditingBehaviorType(m_originalEditingBehavior); 118#if ENABLE(TEXT_AUTOSIZING) 119 settings->setTextAutosizingEnabled(m_originalTextAutosizingEnabled); 120 settings->setTextAutosizingWindowSizeOverride(m_originalTextAutosizingWindowSizeOverride); 121 settings->setTextAutosizingFontScaleFactor(m_originalTextAutosizingFontScaleFactor); 122#endif 123 settings->setMediaTypeOverride(m_originalMediaTypeOverride); 124#if ENABLE(DIALOG_ELEMENT) 125 RuntimeEnabledFeatures::setDialogElementEnabled(m_originalDialogElementEnabled); 126#endif 127 settings->setCanvasUsesAcceleratedDrawing(m_originalCanvasUsesAcceleratedDrawing); 128 settings->setMockScrollbarsEnabled(m_originalMockScrollbarsEnabled); 129 RuntimeEnabledFeatures::setLangAttributeAwareFormControlUIEnabled(m_langAttributeAwareFormControlUIEnabled); 130 settings->setImagesEnabled(m_imagesEnabled); 131 settings->setMinDOMTimerInterval(m_minimumTimerInterval); 132#if ENABLE(VIDEO_TRACK) 133 settings->setShouldDisplaySubtitles(m_shouldDisplaySubtitles); 134 settings->setShouldDisplayCaptions(m_shouldDisplayCaptions); 135 settings->setShouldDisplayTextDescriptions(m_shouldDisplayTextDescriptions); 136#endif 137 settings->setDefaultVideoPosterURL(m_defaultVideoPosterURL); 138 settings->setTimeWithoutMouseMovementBeforeHidingControls(m_originalTimeWithoutMouseMovementBeforeHidingControls); 139 settings->setUseLegacyBackgroundSizeShorthandBehavior(m_useLegacyBackgroundSizeShorthandBehavior); 140} 141 142// We can't use RefCountedSupplement because that would try to make InternalSettings RefCounted 143// and InternalSettings is already RefCounted via its base class, InternalSettingsGenerated. 144// Instead, we manually make InternalSettings supplement Page. 145class InternalSettingsWrapper : public Supplement<Page> { 146public: 147 explicit InternalSettingsWrapper(Page* page) 148 : m_internalSettings(InternalSettings::create(page)) { } 149 virtual ~InternalSettingsWrapper() { m_internalSettings->hostDestroyed(); } 150#if !ASSERT_DISABLED 151 virtual bool isRefCountedWrapper() const OVERRIDE { return true; } 152#endif 153 InternalSettings* internalSettings() const { return m_internalSettings.get(); } 154 155private: 156 RefPtr<InternalSettings> m_internalSettings; 157}; 158 159const char* InternalSettings::supplementName() 160{ 161 return "InternalSettings"; 162} 163 164InternalSettings* InternalSettings::from(Page* page) 165{ 166 if (!Supplement<Page>::from(page, supplementName())) 167 Supplement<Page>::provideTo(page, supplementName(), adoptPtr(new InternalSettingsWrapper(page))); 168 return static_cast<InternalSettingsWrapper*>(Supplement<Page>::from(page, supplementName()))->internalSettings(); 169} 170 171InternalSettings::~InternalSettings() 172{ 173} 174 175InternalSettings::InternalSettings(Page* page) 176 : InternalSettingsGenerated(page) 177 , m_page(page) 178 , m_backup(page->settings()) 179{ 180} 181 182void InternalSettings::resetToConsistentState() 183{ 184 page()->setPageScaleFactor(1, IntPoint(0, 0)); 185 page()->setCanStartMedia(true); 186 187 m_backup.restoreTo(settings()); 188 m_backup = Backup(settings()); 189 190 InternalSettingsGenerated::resetToConsistentState(); 191} 192 193Settings* InternalSettings::settings() const 194{ 195 if (!page()) 196 return 0; 197 return page()->settings(); 198} 199 200void InternalSettings::setMockScrollbarsEnabled(bool enabled, ExceptionCode& ec) 201{ 202 InternalSettingsGuardForSettings(); 203 settings()->setMockScrollbarsEnabled(enabled); 204} 205 206static bool urlIsWhitelistedForSetShadowDOMEnabled(const String& url) 207{ 208 // This check is just for preventing fuzzers from crashing because of unintended API calls. 209 // You can list your test if needed. 210 return notFound != url.find("fast/dom/shadow/content-shadow-unknown.html") 211 || notFound != url.find("fast/dom/shadow/insertion-points-with-shadow-disabled.html"); 212} 213 214void InternalSettings::setShadowDOMEnabled(bool enabled, ExceptionCode& ec) 215{ 216 if (!urlIsWhitelistedForSetShadowDOMEnabled(page()->mainFrame()->document()->url().string())) { 217 ec = INVALID_ACCESS_ERR; 218 return; 219 } 220 221#if ENABLE(SHADOW_DOM) 222 RuntimeEnabledFeatures::setShadowDOMEnabled(enabled); 223#else 224 // Even SHADOW_DOM is off, InternalSettings allows setShadowDOMEnabled(false) to 225 // have broader test coverage. But it cannot be setShadowDOMEnabled(true). 226 if (enabled) 227 ec = INVALID_ACCESS_ERR; 228#endif 229} 230 231void InternalSettings::setAuthorShadowDOMForAnyElementEnabled(bool isEnabled) 232{ 233#if ENABLE(SHADOW_DOM) 234 RuntimeEnabledFeatures::setAuthorShadowDOMForAnyElementEnabled(isEnabled); 235#else 236 UNUSED_PARAM(isEnabled); 237#endif 238} 239 240void InternalSettings::setStyleScopedEnabled(bool enabled) 241{ 242#if ENABLE(STYLE_SCOPED) 243 RuntimeEnabledFeatures::setStyleScopedEnabled(enabled); 244#else 245 UNUSED_PARAM(enabled); 246#endif 247} 248 249void InternalSettings::setTouchEventEmulationEnabled(bool enabled, ExceptionCode& ec) 250{ 251#if ENABLE(TOUCH_EVENTS) 252 InternalSettingsGuardForSettings(); 253 settings()->setTouchEventEmulationEnabled(enabled); 254#else 255 UNUSED_PARAM(enabled); 256 UNUSED_PARAM(ec); 257#endif 258} 259 260typedef void (Settings::*SetFontFamilyFunction)(const AtomicString&, UScriptCode); 261static void setFontFamily(Settings* settings, const String& family, const String& script, SetFontFamilyFunction setter) 262{ 263 UScriptCode code = scriptNameToCode(script); 264 if (code != USCRIPT_INVALID_CODE) 265 (settings->*setter)(family, code); 266} 267 268void InternalSettings::setStandardFontFamily(const String& family, const String& script, ExceptionCode& ec) 269{ 270 InternalSettingsGuardForSettings(); 271 setFontFamily(settings(), family, script, &Settings::setStandardFontFamily); 272} 273 274void InternalSettings::setSerifFontFamily(const String& family, const String& script, ExceptionCode& ec) 275{ 276 InternalSettingsGuardForSettings(); 277 setFontFamily(settings(), family, script, &Settings::setSerifFontFamily); 278} 279 280void InternalSettings::setSansSerifFontFamily(const String& family, const String& script, ExceptionCode& ec) 281{ 282 InternalSettingsGuardForSettings(); 283 setFontFamily(settings(), family, script, &Settings::setSansSerifFontFamily); 284} 285 286void InternalSettings::setFixedFontFamily(const String& family, const String& script, ExceptionCode& ec) 287{ 288 InternalSettingsGuardForSettings(); 289 setFontFamily(settings(), family, script, &Settings::setFixedFontFamily); 290} 291 292void InternalSettings::setCursiveFontFamily(const String& family, const String& script, ExceptionCode& ec) 293{ 294 InternalSettingsGuardForSettings(); 295 setFontFamily(settings(), family, script, &Settings::setCursiveFontFamily); 296} 297 298void InternalSettings::setFantasyFontFamily(const String& family, const String& script, ExceptionCode& ec) 299{ 300 InternalSettingsGuardForSettings(); 301 setFontFamily(settings(), family, script, &Settings::setFantasyFontFamily); 302} 303 304void InternalSettings::setPictographFontFamily(const String& family, const String& script, ExceptionCode& ec) 305{ 306 InternalSettingsGuardForSettings(); 307 setFontFamily(settings(), family, script, &Settings::setPictographFontFamily); 308} 309 310void InternalSettings::setTextAutosizingEnabled(bool enabled, ExceptionCode& ec) 311{ 312#if ENABLE(TEXT_AUTOSIZING) 313 InternalSettingsGuardForSettings(); 314 settings()->setTextAutosizingEnabled(enabled); 315#else 316 UNUSED_PARAM(enabled); 317 UNUSED_PARAM(ec); 318#endif 319} 320 321void InternalSettings::setTextAutosizingWindowSizeOverride(int width, int height, ExceptionCode& ec) 322{ 323#if ENABLE(TEXT_AUTOSIZING) 324 InternalSettingsGuardForSettings(); 325 settings()->setTextAutosizingWindowSizeOverride(IntSize(width, height)); 326#else 327 UNUSED_PARAM(width); 328 UNUSED_PARAM(height); 329 UNUSED_PARAM(ec); 330#endif 331} 332 333void InternalSettings::setMediaTypeOverride(const String& mediaType, ExceptionCode& ec) 334{ 335 InternalSettingsGuardForSettings(); 336 settings()->setMediaTypeOverride(mediaType); 337} 338 339void InternalSettings::setTextAutosizingFontScaleFactor(float fontScaleFactor, ExceptionCode& ec) 340{ 341#if ENABLE(TEXT_AUTOSIZING) 342 InternalSettingsGuardForSettings(); 343 settings()->setTextAutosizingFontScaleFactor(fontScaleFactor); 344#else 345 UNUSED_PARAM(fontScaleFactor); 346 UNUSED_PARAM(ec); 347#endif 348} 349 350void InternalSettings::setCSSExclusionsEnabled(bool enabled, ExceptionCode& ec) 351{ 352 UNUSED_PARAM(ec); 353 RuntimeEnabledFeatures::setCSSExclusionsEnabled(enabled); 354} 355 356void InternalSettings::setCSSShapesEnabled(bool enabled, ExceptionCode& ec) 357{ 358 UNUSED_PARAM(ec); 359 RuntimeEnabledFeatures::setCSSShapesEnabled(enabled); 360} 361 362void InternalSettings::setCSSVariablesEnabled(bool enabled, ExceptionCode& ec) 363{ 364 InternalSettingsGuardForSettings(); 365 settings()->setCSSVariablesEnabled(enabled); 366} 367 368bool InternalSettings::cssVariablesEnabled(ExceptionCode& ec) 369{ 370 InternalSettingsGuardForSettingsReturn(false); 371 return settings()->cssVariablesEnabled(); 372} 373 374void InternalSettings::setCanStartMedia(bool enabled, ExceptionCode& ec) 375{ 376 InternalSettingsGuardForSettings(); 377 m_page->setCanStartMedia(enabled); 378} 379 380void InternalSettings::setEditingBehavior(const String& editingBehavior, ExceptionCode& ec) 381{ 382 InternalSettingsGuardForSettings(); 383 if (equalIgnoringCase(editingBehavior, "win")) 384 settings()->setEditingBehaviorType(EditingWindowsBehavior); 385 else if (equalIgnoringCase(editingBehavior, "mac")) 386 settings()->setEditingBehaviorType(EditingMacBehavior); 387 else if (equalIgnoringCase(editingBehavior, "unix")) 388 settings()->setEditingBehaviorType(EditingUnixBehavior); 389 else 390 ec = SYNTAX_ERR; 391} 392 393void InternalSettings::setDialogElementEnabled(bool enabled, ExceptionCode& ec) 394{ 395 UNUSED_PARAM(ec); 396#if ENABLE(DIALOG_ELEMENT) 397 RuntimeEnabledFeatures::setDialogElementEnabled(enabled); 398#else 399 UNUSED_PARAM(enabled); 400#endif 401} 402 403void InternalSettings::setShouldDisplayTrackKind(const String& kind, bool enabled, ExceptionCode& ec) 404{ 405 InternalSettingsGuardForSettings(); 406 407#if ENABLE(VIDEO_TRACK) 408 if (!page()) 409 return; 410 CaptionUserPreferences* captionPreferences = page()->group().captionPreferences(); 411 412 if (equalIgnoringCase(kind, "Subtitles")) 413 captionPreferences->setUserPrefersSubtitles(enabled); 414 else if (equalIgnoringCase(kind, "Captions")) 415 captionPreferences->setUserPrefersCaptions(enabled); 416 else if (equalIgnoringCase(kind, "TextDescriptions")) 417 captionPreferences->setUserPrefersTextDescriptions(enabled); 418 else 419 ec = SYNTAX_ERR; 420#else 421 UNUSED_PARAM(kind); 422 UNUSED_PARAM(enabled); 423#endif 424} 425 426bool InternalSettings::shouldDisplayTrackKind(const String& kind, ExceptionCode& ec) 427{ 428 InternalSettingsGuardForSettingsReturn(false); 429 430#if ENABLE(VIDEO_TRACK) 431 if (!page()) 432 return false; 433 CaptionUserPreferences* captionPreferences = page()->group().captionPreferences(); 434 435 if (equalIgnoringCase(kind, "Subtitles")) 436 return captionPreferences->userPrefersSubtitles(); 437 if (equalIgnoringCase(kind, "Captions")) 438 return captionPreferences->userPrefersCaptions(); 439 if (equalIgnoringCase(kind, "TextDescriptions")) 440 return captionPreferences->userPrefersTextDescriptions(); 441 442 ec = SYNTAX_ERR; 443 return false; 444#else 445 UNUSED_PARAM(kind); 446 return false; 447#endif 448} 449 450void InternalSettings::setStorageBlockingPolicy(const String& mode, ExceptionCode& ec) 451{ 452 InternalSettingsGuardForSettings(); 453 454 if (mode == "AllowAll") 455 settings()->setStorageBlockingPolicy(SecurityOrigin::AllowAllStorage); 456 else if (mode == "BlockThirdParty") 457 settings()->setStorageBlockingPolicy(SecurityOrigin::BlockThirdPartyStorage); 458 else if (mode == "BlockAll") 459 settings()->setStorageBlockingPolicy(SecurityOrigin::BlockAllStorage); 460 else 461 ec = SYNTAX_ERR; 462} 463 464void InternalSettings::setLangAttributeAwareFormControlUIEnabled(bool enabled) 465{ 466 RuntimeEnabledFeatures::setLangAttributeAwareFormControlUIEnabled(enabled); 467} 468 469void InternalSettings::setImagesEnabled(bool enabled, ExceptionCode& ec) 470{ 471 InternalSettingsGuardForSettings(); 472 settings()->setImagesEnabled(enabled); 473} 474 475void InternalSettings::setMinimumTimerInterval(double intervalInSeconds, ExceptionCode& ec) 476{ 477 InternalSettingsGuardForSettings(); 478 settings()->setMinDOMTimerInterval(intervalInSeconds); 479} 480 481void InternalSettings::setDefaultVideoPosterURL(const String& url, ExceptionCode& ec) 482{ 483 InternalSettingsGuardForSettings(); 484 settings()->setDefaultVideoPosterURL(url); 485} 486 487void InternalSettings::setTimeWithoutMouseMovementBeforeHidingControls(double time, ExceptionCode& ec) 488{ 489 InternalSettingsGuardForSettings(); 490 settings()->setTimeWithoutMouseMovementBeforeHidingControls(time); 491} 492 493void InternalSettings::setUseLegacyBackgroundSizeShorthandBehavior(bool enabled, ExceptionCode& ec) 494{ 495 InternalSettingsGuardForSettings(); 496 settings()->setUseLegacyBackgroundSizeShorthandBehavior(enabled); 497} 498 499} 500