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 "RuntimeEnabledFeatures.h"
31 #include "bindings/v8/ExceptionState.h"
32 #include "core/dom/ExceptionCode.h"
33 #include "core/page/Page.h"
34 #include "core/frame/Settings.h"
35 #include "platform/ColorChooser.h"
36 #include "platform/Supplementable.h"
37 #include "platform/text/LocaleToScriptMapping.h"
38
39 #define InternalSettingsGuardForSettingsReturn(returnValue) \
40 if (!settings()) { \
41 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError); \
42 return returnValue; \
43 }
44
45 #define InternalSettingsGuardForSettings() \
46 if (!settings()) { \
47 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError); \
48 return; \
49 }
50
51 #define InternalSettingsGuardForPage() \
52 if (!page()) { \
53 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError); \
54 return; \
55 }
56
57 namespace WebCore {
58
Backup(Settings * settings)59 InternalSettings::Backup::Backup(Settings* settings)
60 : m_originalCSSExclusionsEnabled(RuntimeEnabledFeatures::cssExclusionsEnabled())
61 , m_originalAuthorShadowDOMForAnyElementEnabled(RuntimeEnabledFeatures::authorShadowDOMForAnyElementEnabled())
62 , m_originalExperimentalWebSocketEnabled(settings->experimentalWebSocketEnabled())
63 , m_originalStyleScoped(RuntimeEnabledFeatures::styleScopedEnabled())
64 , m_originalOverlayScrollbarsEnabled(RuntimeEnabledFeatures::overlayScrollbarsEnabled())
65 , m_originalEditingBehavior(settings->editingBehaviorType())
66 , m_originalTextAutosizingEnabled(settings->textAutosizingEnabled())
67 , m_originalTextAutosizingWindowSizeOverride(settings->textAutosizingWindowSizeOverride())
68 , m_originalAccessibilityFontScaleFactor(settings->accessibilityFontScaleFactor())
69 , m_originalMediaTypeOverride(settings->mediaTypeOverride())
70 , m_originalMockScrollbarsEnabled(settings->mockScrollbarsEnabled())
71 , m_langAttributeAwareFormControlUIEnabled(RuntimeEnabledFeatures::langAttributeAwareFormControlUIEnabled())
72 , m_imagesEnabled(settings->imagesEnabled())
73 , m_shouldDisplaySubtitles(settings->shouldDisplaySubtitles())
74 , m_shouldDisplayCaptions(settings->shouldDisplayCaptions())
75 , m_shouldDisplayTextDescriptions(settings->shouldDisplayTextDescriptions())
76 , m_defaultVideoPosterURL(settings->defaultVideoPosterURL())
77 , m_originalCompositorDrivenAcceleratedScrollEnabled(settings->compositorDrivenAcceleratedScrollingEnabled())
78 , m_originalLayerSquashingEnabled(settings->layerSquashingEnabled())
79 , m_originalPasswordGenerationDecorationEnabled(settings->passwordGenerationDecorationEnabled())
80 {
81 }
82
restoreTo(Settings * settings)83 void InternalSettings::Backup::restoreTo(Settings* settings)
84 {
85 RuntimeEnabledFeatures::setCSSExclusionsEnabled(m_originalCSSExclusionsEnabled);
86 RuntimeEnabledFeatures::setAuthorShadowDOMForAnyElementEnabled(m_originalAuthorShadowDOMForAnyElementEnabled);
87 settings->setExperimentalWebSocketEnabled(m_originalExperimentalWebSocketEnabled);
88 RuntimeEnabledFeatures::setStyleScopedEnabled(m_originalStyleScoped);
89 RuntimeEnabledFeatures::setOverlayScrollbarsEnabled(m_originalOverlayScrollbarsEnabled);
90 settings->setEditingBehaviorType(m_originalEditingBehavior);
91 settings->setTextAutosizingEnabled(m_originalTextAutosizingEnabled);
92 settings->setTextAutosizingWindowSizeOverride(m_originalTextAutosizingWindowSizeOverride);
93 settings->setAccessibilityFontScaleFactor(m_originalAccessibilityFontScaleFactor);
94 settings->setMediaTypeOverride(m_originalMediaTypeOverride);
95 settings->setMockScrollbarsEnabled(m_originalMockScrollbarsEnabled);
96 RuntimeEnabledFeatures::setLangAttributeAwareFormControlUIEnabled(m_langAttributeAwareFormControlUIEnabled);
97 settings->setImagesEnabled(m_imagesEnabled);
98 settings->setShouldDisplaySubtitles(m_shouldDisplaySubtitles);
99 settings->setShouldDisplayCaptions(m_shouldDisplayCaptions);
100 settings->setShouldDisplayTextDescriptions(m_shouldDisplayTextDescriptions);
101 settings->setDefaultVideoPosterURL(m_defaultVideoPosterURL);
102 settings->setCompositorDrivenAcceleratedScrollingEnabled(m_originalCompositorDrivenAcceleratedScrollEnabled);
103 settings->setLayerSquashingEnabled(m_originalLayerSquashingEnabled);
104 settings->setPasswordGenerationDecorationEnabled(m_originalPasswordGenerationDecorationEnabled);
105 settings->genericFontFamilySettings().reset();
106 }
107
108 // We can't use RefCountedSupplement because that would try to make InternalSettings RefCounted
109 // and InternalSettings is already RefCounted via its base class, InternalSettingsGenerated.
110 // Instead, we manually make InternalSettings supplement Page.
111 class InternalSettingsWrapper : public Supplement<Page> {
112 public:
InternalSettingsWrapper(Page * page)113 explicit InternalSettingsWrapper(Page* page)
114 : m_internalSettings(InternalSettings::create(page)) { }
~InternalSettingsWrapper()115 virtual ~InternalSettingsWrapper() { m_internalSettings->hostDestroyed(); }
116 #if !ASSERT_DISABLED
isRefCountedWrapper() const117 virtual bool isRefCountedWrapper() const OVERRIDE { return true; }
118 #endif
internalSettings() const119 InternalSettings* internalSettings() const { return m_internalSettings.get(); }
120
121 private:
122 RefPtr<InternalSettings> m_internalSettings;
123 };
124
supplementName()125 const char* InternalSettings::supplementName()
126 {
127 return "InternalSettings";
128 }
129
from(Page * page)130 InternalSettings* InternalSettings::from(Page* page)
131 {
132 if (!Supplement<Page>::from(page, supplementName()))
133 Supplement<Page>::provideTo(page, supplementName(), adoptPtr(new InternalSettingsWrapper(page)));
134 return static_cast<InternalSettingsWrapper*>(Supplement<Page>::from(page, supplementName()))->internalSettings();
135 }
136
~InternalSettings()137 InternalSettings::~InternalSettings()
138 {
139 }
140
InternalSettings(Page * page)141 InternalSettings::InternalSettings(Page* page)
142 : InternalSettingsGenerated(page)
143 , m_page(page)
144 , m_backup(&page->settings())
145 {
146 }
147
resetToConsistentState()148 void InternalSettings::resetToConsistentState()
149 {
150 page()->setPageScaleFactor(1, IntPoint(0, 0));
151
152 m_backup.restoreTo(settings());
153 m_backup = Backup(settings());
154
155 InternalSettingsGenerated::resetToConsistentState();
156 }
157
settings() const158 Settings* InternalSettings::settings() const
159 {
160 if (!page())
161 return 0;
162 return &page()->settings();
163 }
164
setMockScrollbarsEnabled(bool enabled,ExceptionState & exceptionState)165 void InternalSettings::setMockScrollbarsEnabled(bool enabled, ExceptionState& exceptionState)
166 {
167 InternalSettingsGuardForSettings();
168 settings()->setMockScrollbarsEnabled(enabled);
169 }
170
setAuthorShadowDOMForAnyElementEnabled(bool isEnabled)171 void InternalSettings::setAuthorShadowDOMForAnyElementEnabled(bool isEnabled)
172 {
173 RuntimeEnabledFeatures::setAuthorShadowDOMForAnyElementEnabled(isEnabled);
174 }
175
setExperimentalWebSocketEnabled(bool isEnabled)176 void InternalSettings::setExperimentalWebSocketEnabled(bool isEnabled)
177 {
178 settings()->setExperimentalWebSocketEnabled(isEnabled);
179 }
180
setStyleScopedEnabled(bool enabled)181 void InternalSettings::setStyleScopedEnabled(bool enabled)
182 {
183 RuntimeEnabledFeatures::setStyleScopedEnabled(enabled);
184 }
185
setOverlayScrollbarsEnabled(bool enabled)186 void InternalSettings::setOverlayScrollbarsEnabled(bool enabled)
187 {
188 RuntimeEnabledFeatures::setOverlayScrollbarsEnabled(enabled);
189 }
190
setTouchEventEmulationEnabled(bool enabled,ExceptionState & exceptionState)191 void InternalSettings::setTouchEventEmulationEnabled(bool enabled, ExceptionState& exceptionState)
192 {
193 InternalSettingsGuardForSettings();
194 settings()->setTouchEventEmulationEnabled(enabled);
195 }
196
setViewportEnabled(bool enabled,ExceptionState & exceptionState)197 void InternalSettings::setViewportEnabled(bool enabled, ExceptionState& exceptionState)
198 {
199 InternalSettingsGuardForSettings();
200 settings()->setViewportEnabled(enabled);
201 }
202
203 // FIXME: This is a temporary flag and should be removed once accelerated
204 // overflow scroll is ready (crbug.com/254111).
setCompositorDrivenAcceleratedScrollingEnabled(bool enabled,ExceptionState & exceptionState)205 void InternalSettings::setCompositorDrivenAcceleratedScrollingEnabled(bool enabled, ExceptionState& exceptionState)
206 {
207 InternalSettingsGuardForSettings();
208 settings()->setCompositorDrivenAcceleratedScrollingEnabled(enabled);
209 }
210
211 // FIXME: This is a temporary flag and should be removed once squashing is
212 // ready (crbug.com/261605).
setLayerSquashingEnabled(bool enabled,ExceptionState & exceptionState)213 void InternalSettings::setLayerSquashingEnabled(bool enabled, ExceptionState& exceptionState)
214 {
215 InternalSettingsGuardForSettings();
216 settings()->setLayerSquashingEnabled(enabled);
217 }
218
setStandardFontFamily(const String & family,const String & script,ExceptionState & exceptionState)219 void InternalSettings::setStandardFontFamily(const String& family, const String& script, ExceptionState& exceptionState)
220 {
221 InternalSettingsGuardForSettings();
222 UScriptCode code = scriptNameToCode(script);
223 if (code == USCRIPT_INVALID_CODE)
224 return;
225 settings()->genericFontFamilySettings().setStandard(family, code);
226 m_page->setNeedsRecalcStyleInAllFrames();
227 }
228
setSerifFontFamily(const String & family,const String & script,ExceptionState & exceptionState)229 void InternalSettings::setSerifFontFamily(const String& family, const String& script, ExceptionState& exceptionState)
230 {
231 InternalSettingsGuardForSettings();
232 UScriptCode code = scriptNameToCode(script);
233 if (code == USCRIPT_INVALID_CODE)
234 return;
235 settings()->genericFontFamilySettings().setSerif(family, code);
236 m_page->setNeedsRecalcStyleInAllFrames();
237 }
238
setSansSerifFontFamily(const String & family,const String & script,ExceptionState & exceptionState)239 void InternalSettings::setSansSerifFontFamily(const String& family, const String& script, ExceptionState& exceptionState)
240 {
241 InternalSettingsGuardForSettings();
242 UScriptCode code = scriptNameToCode(script);
243 if (code == USCRIPT_INVALID_CODE)
244 return;
245 settings()->genericFontFamilySettings().setSansSerif(family, code);
246 m_page->setNeedsRecalcStyleInAllFrames();
247 }
248
setFixedFontFamily(const String & family,const String & script,ExceptionState & exceptionState)249 void InternalSettings::setFixedFontFamily(const String& family, const String& script, ExceptionState& exceptionState)
250 {
251 InternalSettingsGuardForSettings();
252 UScriptCode code = scriptNameToCode(script);
253 if (code == USCRIPT_INVALID_CODE)
254 return;
255 settings()->genericFontFamilySettings().setFixed(family, code);
256 m_page->setNeedsRecalcStyleInAllFrames();
257 }
258
setCursiveFontFamily(const String & family,const String & script,ExceptionState & exceptionState)259 void InternalSettings::setCursiveFontFamily(const String& family, const String& script, ExceptionState& exceptionState)
260 {
261 InternalSettingsGuardForSettings();
262 UScriptCode code = scriptNameToCode(script);
263 if (code == USCRIPT_INVALID_CODE)
264 return;
265 settings()->genericFontFamilySettings().setCursive(family, code);
266 m_page->setNeedsRecalcStyleInAllFrames();
267 }
268
setFantasyFontFamily(const String & family,const String & script,ExceptionState & exceptionState)269 void InternalSettings::setFantasyFontFamily(const String& family, const String& script, ExceptionState& exceptionState)
270 {
271 InternalSettingsGuardForSettings();
272 UScriptCode code = scriptNameToCode(script);
273 if (code == USCRIPT_INVALID_CODE)
274 return;
275 settings()->genericFontFamilySettings().setFantasy(family, code);
276 m_page->setNeedsRecalcStyleInAllFrames();
277 }
278
setPictographFontFamily(const String & family,const String & script,ExceptionState & exceptionState)279 void InternalSettings::setPictographFontFamily(const String& family, const String& script, ExceptionState& exceptionState)
280 {
281 InternalSettingsGuardForSettings();
282 UScriptCode code = scriptNameToCode(script);
283 if (code == USCRIPT_INVALID_CODE)
284 return;
285 settings()->genericFontFamilySettings().setPictograph(family, code);
286 m_page->setNeedsRecalcStyleInAllFrames();
287 }
288
setTextAutosizingEnabled(bool enabled,ExceptionState & exceptionState)289 void InternalSettings::setTextAutosizingEnabled(bool enabled, ExceptionState& exceptionState)
290 {
291 InternalSettingsGuardForSettings();
292 settings()->setTextAutosizingEnabled(enabled);
293 }
294
setTextAutosizingWindowSizeOverride(int width,int height,ExceptionState & exceptionState)295 void InternalSettings::setTextAutosizingWindowSizeOverride(int width, int height, ExceptionState& exceptionState)
296 {
297 InternalSettingsGuardForSettings();
298 settings()->setTextAutosizingWindowSizeOverride(IntSize(width, height));
299 }
300
setMediaTypeOverride(const String & mediaType,ExceptionState & exceptionState)301 void InternalSettings::setMediaTypeOverride(const String& mediaType, ExceptionState& exceptionState)
302 {
303 InternalSettingsGuardForSettings();
304 settings()->setMediaTypeOverride(mediaType);
305 }
306
setAccessibilityFontScaleFactor(float fontScaleFactor,ExceptionState & exceptionState)307 void InternalSettings::setAccessibilityFontScaleFactor(float fontScaleFactor, ExceptionState& exceptionState)
308 {
309 InternalSettingsGuardForSettings();
310 settings()->setAccessibilityFontScaleFactor(fontScaleFactor);
311 }
312
setCSSExclusionsEnabled(bool enabled)313 void InternalSettings::setCSSExclusionsEnabled(bool enabled)
314 {
315 RuntimeEnabledFeatures::setCSSExclusionsEnabled(enabled);
316 }
317
setEditingBehavior(const String & editingBehavior,ExceptionState & exceptionState)318 void InternalSettings::setEditingBehavior(const String& editingBehavior, ExceptionState& exceptionState)
319 {
320 InternalSettingsGuardForSettings();
321 if (equalIgnoringCase(editingBehavior, "win"))
322 settings()->setEditingBehaviorType(EditingWindowsBehavior);
323 else if (equalIgnoringCase(editingBehavior, "mac"))
324 settings()->setEditingBehaviorType(EditingMacBehavior);
325 else if (equalIgnoringCase(editingBehavior, "unix"))
326 settings()->setEditingBehaviorType(EditingUnixBehavior);
327 else if (equalIgnoringCase(editingBehavior, "android"))
328 settings()->setEditingBehaviorType(EditingAndroidBehavior);
329 else
330 exceptionState.throwUninformativeAndGenericDOMException(SyntaxError);
331 }
332
setLangAttributeAwareFormControlUIEnabled(bool enabled)333 void InternalSettings::setLangAttributeAwareFormControlUIEnabled(bool enabled)
334 {
335 RuntimeEnabledFeatures::setLangAttributeAwareFormControlUIEnabled(enabled);
336 }
337
setImagesEnabled(bool enabled,ExceptionState & exceptionState)338 void InternalSettings::setImagesEnabled(bool enabled, ExceptionState& exceptionState)
339 {
340 InternalSettingsGuardForSettings();
341 settings()->setImagesEnabled(enabled);
342 }
343
setDefaultVideoPosterURL(const String & url,ExceptionState & exceptionState)344 void InternalSettings::setDefaultVideoPosterURL(const String& url, ExceptionState& exceptionState)
345 {
346 InternalSettingsGuardForSettings();
347 settings()->setDefaultVideoPosterURL(url);
348 }
349
setPasswordGenerationDecorationEnabled(bool enabled,ExceptionState & exceptionState)350 void InternalSettings::setPasswordGenerationDecorationEnabled(bool enabled, ExceptionState& exceptionState)
351 {
352 InternalSettingsGuardForSettings();
353 settings()->setPasswordGenerationDecorationEnabled(enabled);
354 }
355
356 }
357