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 40 using namespace std; 41 42 namespace WebCore { 43 44 static 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. 53 static 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 69 static 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 79 bool Settings::gMockScrollbarsEnabled = false; 80 bool 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. 88 static 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 106 static const bool defaultUnifiedTextCheckerEnabled = false; 107 #if OS(DARWIN) 108 static const bool defaultSmartInsertDeleteEnabled = true; 109 #else 110 static const bool defaultSmartInsertDeleteEnabled = false; 111 #endif 112 #if OS(WINDOWS) 113 static const bool defaultSelectTrailingWhitespaceEnabled = true; 114 #else 115 static const bool defaultSelectTrailingWhitespaceEnabled = false; 116 #endif 117 118 Settings::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 145 PassOwnPtr<Settings> Settings::create(Page* page) 146 { 147 return adoptPtr(new Settings(page)); 148 } 149 150 SETTINGS_SETTER_BODIES 151 152 const AtomicString& Settings::standardFontFamily(UScriptCode script) const 153 { 154 return getGenericFontFamilyForScript(m_standardFontFamilyMap, script); 155 } 156 157 void Settings::setStandardFontFamily(const AtomicString& family, UScriptCode script) 158 { 159 setGenericFontFamilyMap(m_standardFontFamilyMap, family, script, m_page); 160 } 161 162 const AtomicString& Settings::fixedFontFamily(UScriptCode script) const 163 { 164 return getGenericFontFamilyForScript(m_fixedFontFamilyMap, script); 165 } 166 167 void Settings::setFixedFontFamily(const AtomicString& family, UScriptCode script) 168 { 169 setGenericFontFamilyMap(m_fixedFontFamilyMap, family, script, m_page); 170 } 171 172 const AtomicString& Settings::serifFontFamily(UScriptCode script) const 173 { 174 return getGenericFontFamilyForScript(m_serifFontFamilyMap, script); 175 } 176 177 void Settings::setSerifFontFamily(const AtomicString& family, UScriptCode script) 178 { 179 setGenericFontFamilyMap(m_serifFontFamilyMap, family, script, m_page); 180 } 181 182 const AtomicString& Settings::sansSerifFontFamily(UScriptCode script) const 183 { 184 return getGenericFontFamilyForScript(m_sansSerifFontFamilyMap, script); 185 } 186 187 void Settings::setSansSerifFontFamily(const AtomicString& family, UScriptCode script) 188 { 189 setGenericFontFamilyMap(m_sansSerifFontFamilyMap, family, script, m_page); 190 } 191 192 const AtomicString& Settings::cursiveFontFamily(UScriptCode script) const 193 { 194 return getGenericFontFamilyForScript(m_cursiveFontFamilyMap, script); 195 } 196 197 void Settings::setCursiveFontFamily(const AtomicString& family, UScriptCode script) 198 { 199 setGenericFontFamilyMap(m_cursiveFontFamilyMap, family, script, m_page); 200 } 201 202 const AtomicString& Settings::fantasyFontFamily(UScriptCode script) const 203 { 204 return getGenericFontFamilyForScript(m_fantasyFontFamilyMap, script); 205 } 206 207 void Settings::setFantasyFontFamily(const AtomicString& family, UScriptCode script) 208 { 209 setGenericFontFamilyMap(m_fantasyFontFamilyMap, family, script, m_page); 210 } 211 212 const AtomicString& Settings::pictographFontFamily(UScriptCode script) const 213 { 214 return getGenericFontFamilyForScript(m_pictographFontFamilyMap, script); 215 } 216 217 void Settings::setPictographFontFamily(const AtomicString& family, UScriptCode script) 218 { 219 setGenericFontFamilyMap(m_pictographFontFamilyMap, family, script, m_page); 220 } 221 222 void Settings::setTextAutosizingEnabled(bool textAutosizingEnabled) 223 { 224 if (m_textAutosizingEnabled == textAutosizingEnabled) 225 return; 226 227 m_textAutosizingEnabled = textAutosizingEnabled; 228 m_page->setNeedsRecalcStyleInAllFrames(); 229 } 230 231 void Settings::setTextAutosizingWindowSizeOverride(const IntSize& textAutosizingWindowSizeOverride) 232 { 233 if (m_textAutosizingWindowSizeOverride == textAutosizingWindowSizeOverride) 234 return; 235 236 m_textAutosizingWindowSizeOverride = textAutosizingWindowSizeOverride; 237 m_page->setNeedsRecalcStyleInAllFrames(); 238 } 239 240 void 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 250 void 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 260 void 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 271 void 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 287 void 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 301 void Settings::imageLoadingSettingsTimerFired(Timer<Settings>*) 302 { 303 setImageLoadingSettings(m_page); 304 } 305 306 void Settings::setScriptEnabled(bool isScriptEnabled) 307 { 308 m_isScriptEnabled = isScriptEnabled; 309 InspectorInstrumentation::scriptsEnabled(m_page, m_isScriptEnabled); 310 } 311 312 void Settings::setJavaEnabled(bool isJavaEnabled) 313 { 314 m_isJavaEnabled = isJavaEnabled; 315 } 316 317 void Settings::setImagesEnabled(bool areImagesEnabled) 318 { 319 m_areImagesEnabled = areImagesEnabled; 320 321 // See comment in setLoadsImagesAutomatically. 322 m_setImageLoadingSettingsTimer.startOneShot(0); 323 } 324 325 void Settings::setPluginsEnabled(bool arePluginsEnabled) 326 { 327 m_arePluginsEnabled = arePluginsEnabled; 328 } 329 330 void 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 340 void Settings::setDNSPrefetchingEnabled(bool dnsPrefetchingEnabled) 341 { 342 if (m_dnsPrefetchingEnabled == dnsPrefetchingEnabled) 343 return; 344 345 m_dnsPrefetchingEnabled = dnsPrefetchingEnabled; 346 m_page->dnsPrefetchingStateChanged(); 347 } 348 349 void Settings::setMockScrollbarsEnabled(bool flag) 350 { 351 gMockScrollbarsEnabled = flag; 352 } 353 354 bool Settings::mockScrollbarsEnabled() 355 { 356 return gMockScrollbarsEnabled; 357 } 358 359 void Settings::setUsesOverlayScrollbars(bool flag) 360 { 361 gUsesOverlayScrollbars = flag; 362 } 363 364 bool Settings::usesOverlayScrollbars() 365 { 366 return gUsesOverlayScrollbars; 367 } 368 369 void Settings::setOpenGLMultisamplingEnabled(bool flag) 370 { 371 if (m_openGLMultisamplingEnabled == flag) 372 return; 373 374 m_openGLMultisamplingEnabled = flag; 375 m_page->multisamplingChanged(); 376 } 377 378 bool Settings::openGLMultisamplingEnabled() 379 { 380 return m_openGLMultisamplingEnabled; 381 } 382 383 } // namespace WebCore 384