2 * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2012 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #include "AudioSession.h"
30 #include "BackForwardController.h"
31 #include "CachedResourceLoader.h"
32 #include "CookieStorage.h"
36 #include "FontCascade.h"
37 #include "FontGenericFamilies.h"
38 #include "FrameTree.h"
39 #include "FrameView.h"
40 #include "HTMLMediaElement.h"
41 #include "HistoryItem.h"
42 #include "InspectorInstrumentation.h"
43 #include "MainFrame.h"
45 #include "PageCache.h"
46 #include "StorageMap.h"
47 #include "TextAutosizer.h"
49 #include <wtf/NeverDestroyed.h>
50 #include <wtf/StdLibExtras.h>
54 static void setImageLoadingSettings(Page* page)
59 for (Frame* frame = &page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
60 frame->document()->cachedResourceLoader().setImagesEnabled(page->settings().areImagesEnabled());
61 frame->document()->cachedResourceLoader().setAutoLoadImages(page->settings().loadsImagesAutomatically());
65 static void invalidateAfterGenericFamilyChange(Page* page)
67 invalidateFontCascadeCache();
69 page->setNeedsRecalcStyleInAllFrames();
73 bool Settings::gAVFoundationEnabled = true;
77 bool Settings::gQTKitEnabled = false;
80 bool Settings::gMockScrollbarsEnabled = false;
81 bool Settings::gUsesOverlayScrollbars = false;
84 bool Settings::gShouldUseHighResolutionTimers = true;
87 bool Settings::gShouldRewriteConstAsVar = false;
88 bool Settings::gShouldRespectPriorityInCSSAttributeSetters = false;
89 bool Settings::gLowPowerVideoAudioBufferSizeEnabled = false;
92 bool Settings::gNetworkDataUsageTrackingEnabled = false;
93 bool Settings::gAVKitEnabled = false;
94 bool Settings::gShouldOptOutOfNetworkStateObservation = false;
95 bool Settings::gManageAudioSession = false;
99 // 1) EditingMacBehavior comprises Tiger, Leopard, SnowLeopard and iOS builds, as well as QtWebKit when built on Mac;
100 // 2) EditingWindowsBehavior comprises Win32 build;
101 // 3) EditingUnixBehavior comprises all unix-based systems, but Darwin/MacOS (and then abusing the terminology);
102 // 99) MacEditingBehavior is used as a fallback.
103 static EditingBehaviorType editingBehaviorTypeForPlatform()
111 EditingWindowsBehavior
122 static const bool defaultFixedPositionCreatesStackingContext = true;
123 static const bool defaultFixedBackgroundsPaintRelativeToDocument = true;
124 static const bool defaultAcceleratedCompositingForFixedPositionEnabled = true;
125 static const bool defaultAllowsInlineMediaPlayback = false;
126 static const bool defaultInlineMediaPlaybackRequiresPlaysInlineAttribute = true;
127 static const bool defaultRequiresUserGestureForMediaPlayback = true;
128 static const bool defaultAudioPlaybackRequiresUserGesture = true;
129 static const bool defaultMediaDataLoadsAutomatically = false;
130 static const bool defaultShouldRespectImageOrientation = true;
131 static const bool defaultImageSubsamplingEnabled = true;
132 static const bool defaultScrollingTreeIncludesFrames = true;
133 static const bool defaultMediaControlsScaleWithPageZoom = true;
135 static const bool defaultFixedPositionCreatesStackingContext = false;
136 static const bool defaultFixedBackgroundsPaintRelativeToDocument = false;
137 static const bool defaultAcceleratedCompositingForFixedPositionEnabled = false;
138 static const bool defaultAllowsInlineMediaPlayback = true;
139 static const bool defaultInlineMediaPlaybackRequiresPlaysInlineAttribute = false;
140 static const bool defaultRequiresUserGestureForMediaPlayback = false;
141 static const bool defaultAudioPlaybackRequiresUserGesture = false;
142 static const bool defaultMediaDataLoadsAutomatically = true;
143 static const bool defaultShouldRespectImageOrientation = false;
144 static const bool defaultImageSubsamplingEnabled = false;
145 static const bool defaultScrollingTreeIncludesFrames = false;
146 static const bool defaultMediaControlsScaleWithPageZoom = true;
149 static const bool defaultAllowsPictureInPictureMediaPlayback = true;
151 static const double defaultIncrementalRenderingSuppressionTimeoutInSeconds = 5;
152 #if USE(UNIFIED_TEXT_CHECKING)
153 static const bool defaultUnifiedTextCheckerEnabled = true;
155 static const bool defaultUnifiedTextCheckerEnabled = false;
157 static const bool defaultSmartInsertDeleteEnabled = true;
158 static const bool defaultSelectTrailingWhitespaceEnabled = false;
160 // This amount of time must have elapsed before we will even consider scheduling a layout without a delay.
161 // FIXME: For faster machines this value can really be lowered to 200. 250 is adequate, but a little high
163 static const auto layoutScheduleThreshold = std::chrono::milliseconds(250);
165 Settings::Settings(Page* page)
167 , m_mediaTypeOverride("screen")
168 , m_fontGenericFamilies(std::make_unique<FontGenericFamilies>())
169 , m_storageBlockingPolicy(SecurityOrigin::AllowAllStorage)
170 , m_layoutInterval(layoutScheduleThreshold)
171 , m_minimumDOMTimerInterval(DOMTimer::defaultMinimumInterval())
172 , m_domTimerAlignmentInterval(DOMTimer::defaultAlignmentInterval())
173 #if ENABLE(TEXT_AUTOSIZING)
174 , m_textAutosizingFontScaleFactor(1)
175 #if HACK_FORCE_TEXT_AUTOSIZING_ON_DESKTOP
176 , m_textAutosizingWindowSizeOverride(320, 480)
177 , m_textAutosizingEnabled(true)
179 , m_textAutosizingEnabled(false)
182 SETTINGS_INITIALIZER_LIST
183 , m_isJavaEnabled(false)
184 , m_isJavaEnabledForLocalFiles(true)
185 , m_loadsImagesAutomatically(false)
186 , m_areImagesEnabled(true)
187 , m_arePluginsEnabled(false)
188 , m_isScriptEnabled(false)
189 , m_needsAdobeFrameReloadingQuirk(false)
190 , m_usesPageCache(false)
191 , m_fontRenderingMode(0)
192 , m_antialiasedFontDilationEnabled(false)
193 , m_showTiledScrollingIndicator(false)
194 , m_backgroundShouldExtendBeyondPage(false)
195 , m_dnsPrefetchingEnabled(false)
196 #if ENABLE(TOUCH_EVENTS)
197 , m_touchEventEmulationEnabled(false)
199 , m_scrollingPerformanceLoggingEnabled(false)
200 , m_timeWithoutMouseMovementBeforeHidingControls(3)
201 , m_setImageLoadingSettingsTimer(*this, &Settings::imageLoadingSettingsTimerFired)
202 #if ENABLE(HIDDEN_PAGE_DOM_TIMER_THROTTLING)
203 , m_hiddenPageDOMTimerThrottlingEnabled(false)
205 , m_hiddenPageCSSAnimationSuspensionEnabled(false)
206 , m_fontFallbackPrefersPictographs(false)
207 , m_forcePendingWebGLPolicy(false)
209 // A Frame may not have been created yet, so we initialize the AtomicString
210 // hash before trying to use it.
211 AtomicString::init();
212 initializeDefaultFontFamilies();
213 m_page = page; // Page is not yet fully initialized when constructing Settings, so keeping m_page null over initializeDefaultFontFamilies() call.
216 Settings::~Settings()
220 Ref<Settings> Settings::create(Page* page)
222 return adoptRef(*new Settings(page));
225 SETTINGS_SETTER_BODIES
228 void Settings::initializeDefaultFontFamilies()
230 // Other platforms can set up fonts from a client, but on Mac, we want it in WebCore to share code between WebKit1 and WebKit2.
234 const AtomicString& Settings::standardFontFamily(UScriptCode script) const
236 return m_fontGenericFamilies->standardFontFamily(script);
239 void Settings::setStandardFontFamily(const AtomicString& family, UScriptCode script)
241 bool changes = m_fontGenericFamilies->setStandardFontFamily(family, script);
243 invalidateAfterGenericFamilyChange(m_page);
246 const AtomicString& Settings::fixedFontFamily(UScriptCode script) const
248 return m_fontGenericFamilies->fixedFontFamily(script);
251 void Settings::setFixedFontFamily(const AtomicString& family, UScriptCode script)
253 bool changes = m_fontGenericFamilies->setFixedFontFamily(family, script);
255 invalidateAfterGenericFamilyChange(m_page);
258 const AtomicString& Settings::serifFontFamily(UScriptCode script) const
260 return m_fontGenericFamilies->serifFontFamily(script);
263 void Settings::setSerifFontFamily(const AtomicString& family, UScriptCode script)
265 bool changes = m_fontGenericFamilies->setSerifFontFamily(family, script);
267 invalidateAfterGenericFamilyChange(m_page);
270 const AtomicString& Settings::sansSerifFontFamily(UScriptCode script) const
272 return m_fontGenericFamilies->sansSerifFontFamily(script);
275 void Settings::setSansSerifFontFamily(const AtomicString& family, UScriptCode script)
277 bool changes = m_fontGenericFamilies->setSansSerifFontFamily(family, script);
279 invalidateAfterGenericFamilyChange(m_page);
282 const AtomicString& Settings::cursiveFontFamily(UScriptCode script) const
284 return m_fontGenericFamilies->cursiveFontFamily(script);
287 void Settings::setCursiveFontFamily(const AtomicString& family, UScriptCode script)
289 bool changes = m_fontGenericFamilies->setCursiveFontFamily(family, script);
291 invalidateAfterGenericFamilyChange(m_page);
294 const AtomicString& Settings::fantasyFontFamily(UScriptCode script) const
296 return m_fontGenericFamilies->fantasyFontFamily(script);
299 void Settings::setFantasyFontFamily(const AtomicString& family, UScriptCode script)
301 bool changes = m_fontGenericFamilies->setFantasyFontFamily(family, script);
303 invalidateAfterGenericFamilyChange(m_page);
306 const AtomicString& Settings::pictographFontFamily(UScriptCode script) const
308 return m_fontGenericFamilies->pictographFontFamily(script);
311 void Settings::setPictographFontFamily(const AtomicString& family, UScriptCode script)
313 bool changes = m_fontGenericFamilies->setPictographFontFamily(family, script);
315 invalidateAfterGenericFamilyChange(m_page);
318 #if ENABLE(TEXT_AUTOSIZING)
319 void Settings::setTextAutosizingEnabled(bool textAutosizingEnabled)
321 if (m_textAutosizingEnabled == textAutosizingEnabled)
324 m_textAutosizingEnabled = textAutosizingEnabled;
326 m_page->setNeedsRecalcStyleInAllFrames();
329 void Settings::setTextAutosizingWindowSizeOverride(const IntSize& textAutosizingWindowSizeOverride)
331 if (m_textAutosizingWindowSizeOverride == textAutosizingWindowSizeOverride)
334 m_textAutosizingWindowSizeOverride = textAutosizingWindowSizeOverride;
336 m_page->setNeedsRecalcStyleInAllFrames();
339 void Settings::setTextAutosizingFontScaleFactor(float fontScaleFactor)
341 m_textAutosizingFontScaleFactor = fontScaleFactor;
346 // FIXME: I wonder if this needs to traverse frames like in WebViewImpl::resize, or whether there is only one document per Settings instance?
347 for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree().traverseNext())
348 frame->document()->textAutosizer()->recalculateMultipliers();
350 m_page->setNeedsRecalcStyleInAllFrames();
355 void Settings::setAntialiasedFontDilationEnabled(bool enabled)
357 // FIXME: It's wrong for a setting to toggle a global, but this code is temporary.
358 FontCascade::setAntialiasedFontDilationEnabled(enabled);
361 void Settings::setMediaTypeOverride(const String& mediaTypeOverride)
363 if (m_mediaTypeOverride == mediaTypeOverride)
366 m_mediaTypeOverride = mediaTypeOverride;
371 FrameView* view = m_page->mainFrame().view();
374 view->setMediaType(mediaTypeOverride);
375 m_page->setNeedsRecalcStyleInAllFrames();
378 void Settings::setLoadsImagesAutomatically(bool loadsImagesAutomatically)
380 m_loadsImagesAutomatically = loadsImagesAutomatically;
382 // Changing this setting to true might immediately start new loads for images that had previously had loading disabled.
383 // If this happens while a WebView is being dealloc'ed, and we don't know the WebView is being dealloc'ed, these new loads
384 // can cause crashes downstream when the WebView memory has actually been free'd.
385 // One example where this can happen is in Mac apps that subclass WebView then do work in their overridden dealloc methods.
386 // Starting these loads synchronously is not important. By putting it on a 0-delay, properly closing the Page cancels them
387 // before they have a chance to really start.
388 // See http://webkit.org/b/60572 for more discussion.
389 m_setImageLoadingSettingsTimer.startOneShot(0);
392 void Settings::imageLoadingSettingsTimerFired()
394 setImageLoadingSettings(m_page);
397 void Settings::setScriptEnabled(bool isScriptEnabled)
399 if (m_isScriptEnabled == isScriptEnabled)
402 m_isScriptEnabled = isScriptEnabled;
408 m_page->setNeedsRecalcStyleInAllFrames();
410 InspectorInstrumentation::scriptsEnabled(*m_page, m_isScriptEnabled);
413 void Settings::setJavaEnabled(bool isJavaEnabled)
415 m_isJavaEnabled = isJavaEnabled;
418 void Settings::setJavaEnabledForLocalFiles(bool isJavaEnabledForLocalFiles)
420 m_isJavaEnabledForLocalFiles = isJavaEnabledForLocalFiles;
423 void Settings::setImagesEnabled(bool areImagesEnabled)
425 m_areImagesEnabled = areImagesEnabled;
427 // See comment in setLoadsImagesAutomatically.
428 m_setImageLoadingSettingsTimer.startOneShot(0);
431 void Settings::setForcePendingWebGLPolicy(bool forced)
433 m_forcePendingWebGLPolicy = forced;
436 void Settings::setPluginsEnabled(bool arePluginsEnabled)
438 if (m_arePluginsEnabled == arePluginsEnabled)
441 m_arePluginsEnabled = arePluginsEnabled;
442 Page::refreshPlugins(false);
445 void Settings::setUserStyleSheetLocation(const URL& userStyleSheetLocation)
447 if (m_userStyleSheetLocation == userStyleSheetLocation)
450 m_userStyleSheetLocation = userStyleSheetLocation;
453 m_page->userStyleSheetLocationChanged();
456 // FIXME: This quirk is needed because of Radar 4674537 and 5211271. We need to phase it out once Adobe
457 // can fix the bug from their end.
458 void Settings::setNeedsAdobeFrameReloadingQuirk(bool shouldNotReloadIFramesForUnchangedSRC)
460 m_needsAdobeFrameReloadingQuirk = shouldNotReloadIFramesForUnchangedSRC;
463 void Settings::setMinimumDOMTimerInterval(double interval)
465 double oldTimerInterval = m_minimumDOMTimerInterval;
466 m_minimumDOMTimerInterval = interval;
471 for (Frame* frame = &m_page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
472 if (frame->document())
473 frame->document()->adjustMinimumTimerInterval(oldTimerInterval);
477 void Settings::setDOMTimerAlignmentInterval(double alignmentInterval)
479 m_domTimerAlignmentInterval = alignmentInterval;
482 void Settings::setLayoutInterval(std::chrono::milliseconds layoutInterval)
484 // FIXME: It seems weird that this function may disregard the specified layout interval.
485 // We should either expose layoutScheduleThreshold or better communicate this invariant.
486 m_layoutInterval = std::max(layoutInterval, layoutScheduleThreshold);
489 void Settings::setUsesPageCache(bool usesPageCache)
491 if (m_usesPageCache == usesPageCache)
494 m_usesPageCache = usesPageCache;
499 if (!m_usesPageCache)
500 PageCache::singleton().pruneToSizeNow(0, PruningReason::None);
503 void Settings::setFontRenderingMode(FontRenderingMode mode)
505 if (fontRenderingMode() == mode)
507 m_fontRenderingMode = static_cast<int>(mode);
509 m_page->setNeedsRecalcStyleInAllFrames();
512 FontRenderingMode Settings::fontRenderingMode() const
514 return static_cast<FontRenderingMode>(m_fontRenderingMode);
517 void Settings::setDNSPrefetchingEnabled(bool dnsPrefetchingEnabled)
519 if (m_dnsPrefetchingEnabled == dnsPrefetchingEnabled)
522 m_dnsPrefetchingEnabled = dnsPrefetchingEnabled;
524 m_page->dnsPrefetchingStateChanged();
527 void Settings::setShowTiledScrollingIndicator(bool enabled)
529 if (m_showTiledScrollingIndicator == enabled)
532 m_showTiledScrollingIndicator = enabled;
535 #if ENABLE(RESOURCE_USAGE_OVERLAY)
536 void Settings::setResourceUsageOverlayVisible(bool visible)
538 if (m_resourceUsageOverlayVisible == visible)
541 m_resourceUsageOverlayVisible = visible;
543 m_page->setResourceUsageOverlayVisible(visible);
548 void Settings::setShouldUseHighResolutionTimers(bool shouldUseHighResolutionTimers)
550 gShouldUseHighResolutionTimers = shouldUseHighResolutionTimers;
554 void Settings::setStorageBlockingPolicy(SecurityOrigin::StorageBlockingPolicy enabled)
556 if (m_storageBlockingPolicy == enabled)
559 m_storageBlockingPolicy = enabled;
561 m_page->storageBlockingStateChanged();
564 void Settings::setBackgroundShouldExtendBeyondPage(bool shouldExtend)
566 if (m_backgroundShouldExtendBeyondPage == shouldExtend)
569 m_backgroundShouldExtendBeyondPage = shouldExtend;
572 m_page->mainFrame().view()->updateExtendBackgroundIfNecessary();
575 #if USE(AVFOUNDATION)
576 void Settings::setAVFoundationEnabled(bool enabled)
578 if (gAVFoundationEnabled == enabled)
581 gAVFoundationEnabled = enabled;
582 HTMLMediaElement::resetMediaEngines();
587 void Settings::setQTKitEnabled(bool enabled)
589 if (gQTKitEnabled == enabled)
592 gQTKitEnabled = enabled;
593 HTMLMediaElement::resetMediaEngines();
597 void Settings::setScrollingPerformanceLoggingEnabled(bool enabled)
599 m_scrollingPerformanceLoggingEnabled = enabled;
601 if (m_page && m_page->mainFrame().view())
602 m_page->mainFrame().view()->setScrollingPerformanceLoggingEnabled(enabled);
605 void Settings::setMockScrollbarsEnabled(bool flag)
607 gMockScrollbarsEnabled = flag;
608 // FIXME: This should update scroll bars in existing pages.
611 bool Settings::mockScrollbarsEnabled()
613 return gMockScrollbarsEnabled;
616 void Settings::setUsesOverlayScrollbars(bool flag)
618 gUsesOverlayScrollbars = flag;
619 // FIXME: This should update scroll bars in existing pages.
622 bool Settings::usesOverlayScrollbars()
624 return gUsesOverlayScrollbars;
627 void Settings::setShouldRespectPriorityInCSSAttributeSetters(bool flag)
629 gShouldRespectPriorityInCSSAttributeSetters = flag;
632 bool Settings::shouldRespectPriorityInCSSAttributeSetters()
634 return gShouldRespectPriorityInCSSAttributeSetters;
637 #if ENABLE(HIDDEN_PAGE_DOM_TIMER_THROTTLING)
638 void Settings::setHiddenPageDOMTimerThrottlingEnabled(bool flag)
640 if (m_hiddenPageDOMTimerThrottlingEnabled == flag)
642 m_hiddenPageDOMTimerThrottlingEnabled = flag;
644 m_page->hiddenPageDOMTimerThrottlingStateChanged();
648 void Settings::setHiddenPageCSSAnimationSuspensionEnabled(bool flag)
650 if (m_hiddenPageCSSAnimationSuspensionEnabled == flag)
652 m_hiddenPageCSSAnimationSuspensionEnabled = flag;
654 m_page->hiddenPageCSSAnimationSuspensionStateChanged();
657 void Settings::setFontFallbackPrefersPictographs(bool preferPictographs)
659 if (m_fontFallbackPrefersPictographs == preferPictographs)
662 m_fontFallbackPrefersPictographs = preferPictographs;
664 m_page->setNeedsRecalcStyleInAllFrames();
667 void Settings::setLowPowerVideoAudioBufferSizeEnabled(bool flag)
669 gLowPowerVideoAudioBufferSizeEnabled = flag;
673 void Settings::setAudioSessionCategoryOverride(unsigned sessionCategory)
675 AudioSession::sharedSession().setCategoryOverride(static_cast<AudioSession::CategoryType>(sessionCategory));
678 unsigned Settings::audioSessionCategoryOverride()
680 return AudioSession::sharedSession().categoryOverride();
683 void Settings::setNetworkDataUsageTrackingEnabled(bool trackingEnabled)
685 gNetworkDataUsageTrackingEnabled = trackingEnabled;
688 bool Settings::networkDataUsageTrackingEnabled()
690 return gNetworkDataUsageTrackingEnabled;
693 static String& sharedNetworkInterfaceNameGlobal()
695 static NeverDestroyed<String> networkInterfaceName;
696 return networkInterfaceName;
699 void Settings::setNetworkInterfaceName(const String& networkInterfaceName)
701 sharedNetworkInterfaceNameGlobal() = networkInterfaceName;
704 const String& Settings::networkInterfaceName()
706 return sharedNetworkInterfaceNameGlobal();
710 } // namespace WebCore