1/* 2 * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2012 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 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. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, 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 COMPUTER, 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. 24 */ 25 26#include "config.h" 27#include "core/page/Settings.h" 28 29#include <limits> 30#include "core/dom/Document.h" 31#include "core/inspector/InspectorInstrumentation.h" 32#include "core/loader/cache/ResourceFetcher.h" 33#include "core/page/Chrome.h" 34#include "core/page/Frame.h" 35#include "core/page/FrameTree.h" 36#include "core/page/FrameView.h" 37#include "core/page/Page.h" 38#include "core/rendering/TextAutosizer.h" 39 40using namespace std; 41 42namespace WebCore { 43 44static void setImageLoadingSettings(Page* page) 45{ 46 for (Frame* frame = page->mainFrame(); frame; frame = frame->tree()->traverseNext()) { 47 frame->document()->fetcher()->setImagesEnabled(page->settings()->areImagesEnabled()); 48 frame->document()->fetcher()->setAutoLoadImages(page->settings()->loadsImagesAutomatically()); 49 } 50} 51 52// Sets the entry in the font map for the given script. If family is the empty string, removes the entry instead. 53static inline void setGenericFontFamilyMap(ScriptFontFamilyMap& fontMap, const AtomicString& family, UScriptCode script, Page* page) 54{ 55 ScriptFontFamilyMap::iterator it = fontMap.find(static_cast<int>(script)); 56 if (family.isEmpty()) { 57 if (it == fontMap.end()) 58 return; 59 fontMap.remove(it); 60 } else if (it != fontMap.end() && it->value == family) 61 return; 62 else 63 fontMap.set(static_cast<int>(script), family); 64 65 if (page) 66 page->setNeedsRecalcStyleInAllFrames(); 67} 68 69static inline const AtomicString& getGenericFontFamilyForScript(const ScriptFontFamilyMap& fontMap, UScriptCode script) 70{ 71 ScriptFontFamilyMap::const_iterator it = fontMap.find(static_cast<int>(script)); 72 if (it != fontMap.end()) 73 return it->value; 74 if (script != USCRIPT_COMMON) 75 return getGenericFontFamilyForScript(fontMap, USCRIPT_COMMON); 76 return emptyAtom; 77} 78 79bool Settings::gMockScrollbarsEnabled = false; 80bool Settings::gUsesOverlayScrollbars = false; 81 82// NOTEs 83// 1) EditingMacBehavior comprises builds on Mac; 84// 2) EditingWindowsBehavior comprises builds on Windows; 85// 3) EditingUnixBehavior comprises all unix-based systems, but Darwin/MacOS/Android (and then abusing the terminology); 86// 4) EditingAndroidBehavior comprises Android builds. 87// 99) MacEditingBehavior is used a fallback. 88static EditingBehaviorType editingBehaviorTypeForPlatform() 89{ 90 return 91#if OS(DARWIN) 92 EditingMacBehavior 93#elif OS(WINDOWS) 94 EditingWindowsBehavior 95#elif OS(ANDROID) 96 EditingAndroidBehavior 97#elif OS(UNIX) 98 EditingUnixBehavior 99#else 100 // Fallback 101 EditingMacBehavior 102#endif 103 ; 104} 105 106static const bool defaultUnifiedTextCheckerEnabled = false; 107#if OS(DARWIN) 108static const bool defaultSmartInsertDeleteEnabled = true; 109#else 110static const bool defaultSmartInsertDeleteEnabled = false; 111#endif 112#if OS(WINDOWS) 113static const bool defaultSelectTrailingWhitespaceEnabled = true; 114#else 115static const bool defaultSelectTrailingWhitespaceEnabled = false; 116#endif 117 118Settings::Settings(Page* page) 119 : m_page(0) 120 , m_mediaTypeOverride("screen") 121 , m_textAutosizingFontScaleFactor(1) 122#if HACK_FORCE_TEXT_AUTOSIZING_ON_DESKTOP 123 , m_textAutosizingWindowSizeOverride(320, 480) 124 , m_textAutosizingEnabled(true) 125#else 126 , m_textAutosizingEnabled(false) 127#endif 128 , m_useWideViewport(true) 129 , m_loadWithOverviewMode(true) 130 SETTINGS_INITIALIZER_LIST 131 , m_isJavaEnabled(false) 132 , m_loadsImagesAutomatically(false) 133 , m_areImagesEnabled(true) 134 , m_arePluginsEnabled(false) 135 , m_isScriptEnabled(false) 136 , m_isCSSCustomFilterEnabled(false) 137 , m_cssStickyPositionEnabled(true) 138 , m_dnsPrefetchingEnabled(false) 139 , m_touchEventEmulationEnabled(false) 140 , m_setImageLoadingSettingsTimer(this, &Settings::imageLoadingSettingsTimerFired) 141{ 142 m_page = page; // Page is not yet fully initialized wen constructing Settings, so keeping m_page null over initializeDefaultFontFamilies() call. 143} 144 145PassOwnPtr<Settings> Settings::create(Page* page) 146{ 147 return adoptPtr(new Settings(page)); 148} 149 150SETTINGS_SETTER_BODIES 151 152const AtomicString& Settings::standardFontFamily(UScriptCode script) const 153{ 154 return getGenericFontFamilyForScript(m_standardFontFamilyMap, script); 155} 156 157void Settings::setStandardFontFamily(const AtomicString& family, UScriptCode script) 158{ 159 setGenericFontFamilyMap(m_standardFontFamilyMap, family, script, m_page); 160} 161 162const AtomicString& Settings::fixedFontFamily(UScriptCode script) const 163{ 164 return getGenericFontFamilyForScript(m_fixedFontFamilyMap, script); 165} 166 167void Settings::setFixedFontFamily(const AtomicString& family, UScriptCode script) 168{ 169 setGenericFontFamilyMap(m_fixedFontFamilyMap, family, script, m_page); 170} 171 172const AtomicString& Settings::serifFontFamily(UScriptCode script) const 173{ 174 return getGenericFontFamilyForScript(m_serifFontFamilyMap, script); 175} 176 177void Settings::setSerifFontFamily(const AtomicString& family, UScriptCode script) 178{ 179 setGenericFontFamilyMap(m_serifFontFamilyMap, family, script, m_page); 180} 181 182const AtomicString& Settings::sansSerifFontFamily(UScriptCode script) const 183{ 184 return getGenericFontFamilyForScript(m_sansSerifFontFamilyMap, script); 185} 186 187void Settings::setSansSerifFontFamily(const AtomicString& family, UScriptCode script) 188{ 189 setGenericFontFamilyMap(m_sansSerifFontFamilyMap, family, script, m_page); 190} 191 192const AtomicString& Settings::cursiveFontFamily(UScriptCode script) const 193{ 194 return getGenericFontFamilyForScript(m_cursiveFontFamilyMap, script); 195} 196 197void Settings::setCursiveFontFamily(const AtomicString& family, UScriptCode script) 198{ 199 setGenericFontFamilyMap(m_cursiveFontFamilyMap, family, script, m_page); 200} 201 202const AtomicString& Settings::fantasyFontFamily(UScriptCode script) const 203{ 204 return getGenericFontFamilyForScript(m_fantasyFontFamilyMap, script); 205} 206 207void Settings::setFantasyFontFamily(const AtomicString& family, UScriptCode script) 208{ 209 setGenericFontFamilyMap(m_fantasyFontFamilyMap, family, script, m_page); 210} 211 212const AtomicString& Settings::pictographFontFamily(UScriptCode script) const 213{ 214 return getGenericFontFamilyForScript(m_pictographFontFamilyMap, script); 215} 216 217void Settings::setPictographFontFamily(const AtomicString& family, UScriptCode script) 218{ 219 setGenericFontFamilyMap(m_pictographFontFamilyMap, family, script, m_page); 220} 221 222void Settings::setTextAutosizingEnabled(bool textAutosizingEnabled) 223{ 224 if (m_textAutosizingEnabled == textAutosizingEnabled) 225 return; 226 227 m_textAutosizingEnabled = textAutosizingEnabled; 228 m_page->setNeedsRecalcStyleInAllFrames(); 229} 230 231void Settings::setTextAutosizingWindowSizeOverride(const IntSize& textAutosizingWindowSizeOverride) 232{ 233 if (m_textAutosizingWindowSizeOverride == textAutosizingWindowSizeOverride) 234 return; 235 236 m_textAutosizingWindowSizeOverride = textAutosizingWindowSizeOverride; 237 m_page->setNeedsRecalcStyleInAllFrames(); 238} 239 240void Settings::setUseWideViewport(bool useWideViewport) 241{ 242 if (m_useWideViewport == useWideViewport) 243 return; 244 245 m_useWideViewport = useWideViewport; 246 if (m_page->mainFrame()) 247 m_page->chrome().dispatchViewportPropertiesDidChange(m_page->mainFrame()->document()->viewportArguments()); 248} 249 250void Settings::setLoadWithOverviewMode(bool loadWithOverviewMode) 251{ 252 if (m_loadWithOverviewMode == loadWithOverviewMode) 253 return; 254 255 m_loadWithOverviewMode = loadWithOverviewMode; 256 if (m_page->mainFrame()) 257 m_page->chrome().dispatchViewportPropertiesDidChange(m_page->mainFrame()->document()->viewportArguments()); 258} 259 260void Settings::setTextAutosizingFontScaleFactor(float fontScaleFactor) 261{ 262 m_textAutosizingFontScaleFactor = fontScaleFactor; 263 264 // FIXME: I wonder if this needs to traverse frames like in WebViewImpl::resize, or whether there is only one document per Settings instance? 265 for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree()->traverseNext()) 266 frame->document()->textAutosizer()->recalculateMultipliers(); 267 268 m_page->setNeedsRecalcStyleInAllFrames(); 269} 270 271void Settings::setMediaTypeOverride(const String& mediaTypeOverride) 272{ 273 if (m_mediaTypeOverride == mediaTypeOverride) 274 return; 275 276 m_mediaTypeOverride = mediaTypeOverride; 277 278 Frame* mainFrame = m_page->mainFrame(); 279 ASSERT(mainFrame); 280 FrameView* view = mainFrame->view(); 281 ASSERT(view); 282 283 view->setMediaType(mediaTypeOverride); 284 m_page->setNeedsRecalcStyleInAllFrames(); 285} 286 287void Settings::setLoadsImagesAutomatically(bool loadsImagesAutomatically) 288{ 289 m_loadsImagesAutomatically = loadsImagesAutomatically; 290 291 // Changing this setting to true might immediately start new loads for images that had previously had loading disabled. 292 // If this happens while a WebView is being dealloc'ed, and we don't know the WebView is being dealloc'ed, these new loads 293 // can cause crashes downstream when the WebView memory has actually been free'd. 294 // One example where this can happen is in Mac apps that subclass WebView then do work in their overridden dealloc methods. 295 // Starting these loads synchronously is not important. By putting it on a 0-delay, properly closing the Page cancels them 296 // before they have a chance to really start. 297 // See http://webkit.org/b/60572 for more discussion. 298 m_setImageLoadingSettingsTimer.startOneShot(0); 299} 300 301void Settings::imageLoadingSettingsTimerFired(Timer<Settings>*) 302{ 303 setImageLoadingSettings(m_page); 304} 305 306void Settings::setScriptEnabled(bool isScriptEnabled) 307{ 308 m_isScriptEnabled = isScriptEnabled; 309 InspectorInstrumentation::scriptsEnabled(m_page, m_isScriptEnabled); 310} 311 312void Settings::setJavaEnabled(bool isJavaEnabled) 313{ 314 m_isJavaEnabled = isJavaEnabled; 315} 316 317void Settings::setImagesEnabled(bool areImagesEnabled) 318{ 319 m_areImagesEnabled = areImagesEnabled; 320 321 // See comment in setLoadsImagesAutomatically. 322 m_setImageLoadingSettingsTimer.startOneShot(0); 323} 324 325void Settings::setPluginsEnabled(bool arePluginsEnabled) 326{ 327 m_arePluginsEnabled = arePluginsEnabled; 328} 329 330void Settings::setUserStyleSheetLocation(const KURL& userStyleSheetLocation) 331{ 332 if (m_userStyleSheetLocation == userStyleSheetLocation) 333 return; 334 335 m_userStyleSheetLocation = userStyleSheetLocation; 336 337 m_page->userStyleSheetLocationChanged(); 338} 339 340void Settings::setDNSPrefetchingEnabled(bool dnsPrefetchingEnabled) 341{ 342 if (m_dnsPrefetchingEnabled == dnsPrefetchingEnabled) 343 return; 344 345 m_dnsPrefetchingEnabled = dnsPrefetchingEnabled; 346 m_page->dnsPrefetchingStateChanged(); 347} 348 349void Settings::setMockScrollbarsEnabled(bool flag) 350{ 351 gMockScrollbarsEnabled = flag; 352} 353 354bool Settings::mockScrollbarsEnabled() 355{ 356 return gMockScrollbarsEnabled; 357} 358 359void Settings::setUsesOverlayScrollbars(bool flag) 360{ 361 gUsesOverlayScrollbars = flag; 362} 363 364bool Settings::usesOverlayScrollbars() 365{ 366 return gUsesOverlayScrollbars; 367} 368 369void Settings::setOpenGLMultisamplingEnabled(bool flag) 370{ 371 if (m_openGLMultisamplingEnabled == flag) 372 return; 373 374 m_openGLMultisamplingEnabled = flag; 375 m_page->multisamplingChanged(); 376} 377 378bool Settings::openGLMultisamplingEnabled() 379{ 380 return m_openGLMultisamplingEnabled; 381} 382 383} // namespace WebCore 384