Home | History | Annotate | Download | only in page
      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