2 * Copyright (C) 2012 Google Inc. All rights reserved.
3 * Copyright (C) 2013 Apple Inc. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
28 #include "core/testing/InternalSettings.h"
30 #include "bindings/core/v8/ExceptionState.h"
31 #include "core/css/PointerProperties.h"
32 #include "core/dom/ExceptionCode.h"
33 #include "core/frame/Settings.h"
34 #include "core/inspector/InspectorController.h"
35 #include "core/page/Page.h"
36 #include "platform/RuntimeEnabledFeatures.h"
37 #include "platform/Supplementable.h"
38 #include "platform/text/LocaleToScriptMapping.h"
40 #define InternalSettingsGuardForSettingsReturn(returnValue) \
42 exceptionState.throwDOMException(InvalidAccessError, "The settings object cannot be obtained."); \
46 #define InternalSettingsGuardForSettings() \
48 exceptionState.throwDOMException(InvalidAccessError, "The settings object cannot be obtained."); \
52 #define InternalSettingsGuardForPage() \
54 exceptionState.throwDOMException(InvalidAccessError, "The page object cannot be obtained."); \
60 InternalSettings::Backup::Backup(Settings* settings)
61 : m_originalAuthorShadowDOMForAnyElementEnabled(RuntimeEnabledFeatures::authorShadowDOMForAnyElementEnabled())
62 , m_originalCSP(RuntimeEnabledFeatures::experimentalContentSecurityPolicyFeaturesEnabled())
63 , m_originalLaxMixedContentCheckingEnabled(RuntimeEnabledFeatures::laxMixedContentCheckingEnabled())
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_originalMockGestureTapHighlightsEnabled(settings->mockGestureTapHighlightsEnabled())
72 , m_langAttributeAwareFormControlUIEnabled(RuntimeEnabledFeatures::langAttributeAwareFormControlUIEnabled())
73 , m_imagesEnabled(settings->imagesEnabled())
74 , m_defaultVideoPosterURL(settings->defaultVideoPosterURL())
75 , m_originalLayerSquashingEnabled(settings->layerSquashingEnabled())
76 , m_originalPseudoClassesInMatchingCriteriaInAuthorShadowTreesEnabled(RuntimeEnabledFeatures::pseudoClassesInMatchingCriteriaInAuthorShadowTreesEnabled())
80 void InternalSettings::Backup::restoreTo(Settings* settings)
82 RuntimeEnabledFeatures::setAuthorShadowDOMForAnyElementEnabled(m_originalAuthorShadowDOMForAnyElementEnabled);
83 RuntimeEnabledFeatures::setExperimentalContentSecurityPolicyFeaturesEnabled(m_originalCSP);
84 RuntimeEnabledFeatures::setLaxMixedContentCheckingEnabled(m_originalLaxMixedContentCheckingEnabled);
85 RuntimeEnabledFeatures::setOverlayScrollbarsEnabled(m_originalOverlayScrollbarsEnabled);
86 settings->setEditingBehaviorType(m_originalEditingBehavior);
87 settings->setTextAutosizingEnabled(m_originalTextAutosizingEnabled);
88 settings->setTextAutosizingWindowSizeOverride(m_originalTextAutosizingWindowSizeOverride);
89 settings->setAccessibilityFontScaleFactor(m_originalAccessibilityFontScaleFactor);
90 settings->setMediaTypeOverride(m_originalMediaTypeOverride);
91 settings->setMockScrollbarsEnabled(m_originalMockScrollbarsEnabled);
92 settings->setMockGestureTapHighlightsEnabled(m_originalMockGestureTapHighlightsEnabled);
93 RuntimeEnabledFeatures::setLangAttributeAwareFormControlUIEnabled(m_langAttributeAwareFormControlUIEnabled);
94 settings->setImagesEnabled(m_imagesEnabled);
95 settings->setDefaultVideoPosterURL(m_defaultVideoPosterURL);
96 settings->setLayerSquashingEnabled(m_originalLayerSquashingEnabled);
97 settings->genericFontFamilySettings().reset();
98 RuntimeEnabledFeatures::setPseudoClassesInMatchingCriteriaInAuthorShadowTreesEnabled(m_originalPseudoClassesInMatchingCriteriaInAuthorShadowTreesEnabled);
102 InternalSettings* InternalSettings::from(Page& page)
104 if (!HeapSupplement<Page>::from(page, supplementName()))
105 HeapSupplement<Page>::provideTo(page, supplementName(), new InternalSettings(page));
106 return static_cast<InternalSettings*>(HeapSupplement<Page>::from(page, supplementName()));
109 // We can't use RefCountedSupplement because that would try to make InternalSettings RefCounted
110 // and InternalSettings is already RefCounted via its base class, InternalSettingsGenerated.
111 // Instead, we manually make InternalSettings supplement Page.
112 class InternalSettingsWrapper : public Supplement<Page> {
114 explicit InternalSettingsWrapper(Page& page)
115 : m_internalSettings(InternalSettings::create(page)) { }
116 virtual ~InternalSettingsWrapper() { m_internalSettings->hostDestroyed(); }
118 virtual bool isRefCountedWrapper() const OVERRIDE { return true; }
120 InternalSettings* internalSettings() const { return m_internalSettings.get(); }
123 RefPtr<InternalSettings> m_internalSettings;
126 InternalSettings* InternalSettings::from(Page& page)
128 if (!Supplement<Page>::from(page, supplementName()))
129 Supplement<Page>::provideTo(page, supplementName(), adoptPtr(new InternalSettingsWrapper(page)));
130 return static_cast<InternalSettingsWrapper*>(Supplement<Page>::from(page, supplementName()))->internalSettings();
134 const char* InternalSettings::supplementName()
136 return "InternalSettings";
139 InternalSettings::~InternalSettings()
143 InternalSettings::InternalSettings(Page& page)
144 : InternalSettingsGenerated(&page)
146 , m_backup(&page.settings())
150 void InternalSettings::resetToConsistentState()
152 page()->setPageScaleFactor(1, IntPoint(0, 0));
154 m_backup.restoreTo(settings());
155 m_backup = Backup(settings());
156 m_backup.m_originalTextAutosizingEnabled = settings()->textAutosizingEnabled();
158 InternalSettingsGenerated::resetToConsistentState();
161 Settings* InternalSettings::settings() const
165 return &page()->settings();
168 void InternalSettings::setMockScrollbarsEnabled(bool enabled, ExceptionState& exceptionState)
170 InternalSettingsGuardForSettings();
171 settings()->setMockScrollbarsEnabled(enabled);
174 void InternalSettings::setMockGestureTapHighlightsEnabled(bool enabled, ExceptionState& exceptionState)
176 InternalSettingsGuardForSettings();
177 settings()->setMockGestureTapHighlightsEnabled(enabled);
180 void InternalSettings::setAuthorShadowDOMForAnyElementEnabled(bool isEnabled)
182 RuntimeEnabledFeatures::setAuthorShadowDOMForAnyElementEnabled(isEnabled);
185 void InternalSettings::setExperimentalContentSecurityPolicyFeaturesEnabled(bool enabled)
187 RuntimeEnabledFeatures::setExperimentalContentSecurityPolicyFeaturesEnabled(enabled);
190 void InternalSettings::setLaxMixedContentCheckingEnabled(bool enabled)
192 RuntimeEnabledFeatures::setLaxMixedContentCheckingEnabled(enabled);
195 void InternalSettings::setPseudoClassesInMatchingCriteriaInAuthorShadowTreesEnabled(bool enabled)
197 RuntimeEnabledFeatures::setPseudoClassesInMatchingCriteriaInAuthorShadowTreesEnabled(enabled);
200 void InternalSettings::setOverlayScrollbarsEnabled(bool enabled)
202 RuntimeEnabledFeatures::setOverlayScrollbarsEnabled(enabled);
205 void InternalSettings::setViewportEnabled(bool enabled, ExceptionState& exceptionState)
207 InternalSettingsGuardForSettings();
208 settings()->setViewportEnabled(enabled);
211 // FIXME: This is a temporary flag and should be removed once squashing is
212 // ready (crbug.com/261605).
213 void InternalSettings::setLayerSquashingEnabled(bool enabled, ExceptionState& exceptionState)
215 InternalSettingsGuardForSettings();
216 settings()->setLayerSquashingEnabled(enabled);
219 void InternalSettings::setStandardFontFamily(const AtomicString& family, const String& script, ExceptionState& exceptionState)
221 InternalSettingsGuardForSettings();
222 UScriptCode code = scriptNameToCode(script);
223 if (code == USCRIPT_INVALID_CODE)
225 if (settings()->genericFontFamilySettings().updateStandard(family, code))
226 settings()->notifyGenericFontFamilyChange();
229 void InternalSettings::setSerifFontFamily(const AtomicString& family, const String& script, ExceptionState& exceptionState)
231 InternalSettingsGuardForSettings();
232 UScriptCode code = scriptNameToCode(script);
233 if (code == USCRIPT_INVALID_CODE)
235 if (settings()->genericFontFamilySettings().updateSerif(family, code))
236 settings()->notifyGenericFontFamilyChange();
239 void InternalSettings::setSansSerifFontFamily(const AtomicString& family, const String& script, ExceptionState& exceptionState)
241 InternalSettingsGuardForSettings();
242 UScriptCode code = scriptNameToCode(script);
243 if (code == USCRIPT_INVALID_CODE)
245 if (settings()->genericFontFamilySettings().updateSansSerif(family, code))
246 settings()->notifyGenericFontFamilyChange();
249 void InternalSettings::setFixedFontFamily(const AtomicString& family, const String& script, ExceptionState& exceptionState)
251 InternalSettingsGuardForSettings();
252 UScriptCode code = scriptNameToCode(script);
253 if (code == USCRIPT_INVALID_CODE)
255 if (settings()->genericFontFamilySettings().updateFixed(family, code))
256 settings()->notifyGenericFontFamilyChange();
259 void InternalSettings::setCursiveFontFamily(const AtomicString& family, const String& script, ExceptionState& exceptionState)
261 InternalSettingsGuardForSettings();
262 UScriptCode code = scriptNameToCode(script);
263 if (code == USCRIPT_INVALID_CODE)
265 if (settings()->genericFontFamilySettings().updateCursive(family, code))
266 settings()->notifyGenericFontFamilyChange();
269 void InternalSettings::setFantasyFontFamily(const AtomicString& family, const String& script, ExceptionState& exceptionState)
271 InternalSettingsGuardForSettings();
272 UScriptCode code = scriptNameToCode(script);
273 if (code == USCRIPT_INVALID_CODE)
275 if (settings()->genericFontFamilySettings().updateFantasy(family, code))
276 settings()->notifyGenericFontFamilyChange();
279 void InternalSettings::setPictographFontFamily(const AtomicString& family, const String& script, ExceptionState& exceptionState)
281 InternalSettingsGuardForSettings();
282 UScriptCode code = scriptNameToCode(script);
283 if (code == USCRIPT_INVALID_CODE)
285 if (settings()->genericFontFamilySettings().updatePictograph(family, code))
286 settings()->notifyGenericFontFamilyChange();
289 void InternalSettings::setTextAutosizingEnabled(bool enabled, ExceptionState& exceptionState)
291 InternalSettingsGuardForSettings();
292 settings()->setTextAutosizingEnabled(enabled);
293 m_page->inspectorController().setTextAutosizingEnabled(enabled);
296 void InternalSettings::setTextAutosizingWindowSizeOverride(int width, int height, ExceptionState& exceptionState)
298 InternalSettingsGuardForSettings();
299 settings()->setTextAutosizingWindowSizeOverride(IntSize(width, height));
302 void InternalSettings::setMediaTypeOverride(const String& mediaType, ExceptionState& exceptionState)
304 InternalSettingsGuardForSettings();
305 settings()->setMediaTypeOverride(mediaType);
308 void InternalSettings::setAccessibilityFontScaleFactor(float fontScaleFactor, ExceptionState& exceptionState)
310 InternalSettingsGuardForSettings();
311 settings()->setAccessibilityFontScaleFactor(fontScaleFactor);
314 void InternalSettings::setEditingBehavior(const String& editingBehavior, ExceptionState& exceptionState)
316 InternalSettingsGuardForSettings();
317 if (equalIgnoringCase(editingBehavior, "win"))
318 settings()->setEditingBehaviorType(EditingWindowsBehavior);
319 else if (equalIgnoringCase(editingBehavior, "mac"))
320 settings()->setEditingBehaviorType(EditingMacBehavior);
321 else if (equalIgnoringCase(editingBehavior, "unix"))
322 settings()->setEditingBehaviorType(EditingUnixBehavior);
323 else if (equalIgnoringCase(editingBehavior, "android"))
324 settings()->setEditingBehaviorType(EditingAndroidBehavior);
326 exceptionState.throwDOMException(SyntaxError, "The editing behavior type provided ('" + editingBehavior + "') is invalid.");
329 void InternalSettings::setLangAttributeAwareFormControlUIEnabled(bool enabled)
331 RuntimeEnabledFeatures::setLangAttributeAwareFormControlUIEnabled(enabled);
334 void InternalSettings::setImagesEnabled(bool enabled, ExceptionState& exceptionState)
336 InternalSettingsGuardForSettings();
337 settings()->setImagesEnabled(enabled);
340 void InternalSettings::setDefaultVideoPosterURL(const String& url, ExceptionState& exceptionState)
342 InternalSettingsGuardForSettings();
343 settings()->setDefaultVideoPosterURL(url);
346 void InternalSettings::trace(Visitor* visitor)
348 visitor->trace(m_page);
349 InternalSettingsGenerated::trace(visitor);
351 HeapSupplement<Page>::trace(visitor);
355 void InternalSettings::setAvailablePointerTypes(const String& pointers, ExceptionState& exceptionState)
357 InternalSettingsGuardForSettings();
359 // Allow setting multiple pointer types by passing comma seperated list
361 Vector<String> tokens;
362 pointers.split(",", false, tokens);
364 int pointerTypes = 0;
365 for (size_t i = 0; i < tokens.size(); ++i) {
366 String token = tokens[i].stripWhiteSpace();
368 if (token == "coarse")
369 pointerTypes |= PointerTypeCoarse;
370 else if (token == "fine")
371 pointerTypes |= PointerTypeFine;
372 else if (token == "none")
373 pointerTypes |= PointerTypeNone;
375 exceptionState.throwDOMException(SyntaxError, "The pointer type token ('" + token + ")' is invalid.");
378 settings()->setAvailablePointerTypes(pointerTypes);
381 void InternalSettings::setPrimaryPointerType(const String& pointer, ExceptionState& exceptionState)
383 InternalSettingsGuardForSettings();
384 String token = pointer.stripWhiteSpace();
386 PointerType type = PointerTypeNone;
387 if (token == "coarse")
388 type = PointerTypeCoarse;
389 else if (token == "fine")
390 type = PointerTypeFine;
391 else if (token == "none")
392 type = PointerTypeNone;
394 exceptionState.throwDOMException(SyntaxError, "The pointer type token ('" + token + ")' is invalid.");
396 settings()->setPrimaryPointerType(type);
399 void InternalSettings::setAvailableHoverTypes(const String& types, ExceptionState& exceptionState)
401 InternalSettingsGuardForSettings();
403 // Allow setting multiple hover types by passing comma seperated list
404 // ("on-demand,none").
405 Vector<String> tokens;
406 types.split(",", false, tokens);
409 for (size_t i = 0; i < tokens.size(); ++i) {
410 String token = tokens[i].stripWhiteSpace();
413 hoverTypes |= HoverTypeNone;
414 else if (token == "on-demand")
415 hoverTypes |= HoverTypeOnDemand;
416 else if (token == "hover")
417 hoverTypes |= HoverTypeHover;
419 exceptionState.throwDOMException(SyntaxError, "The hover type token ('" + token + ")' is invalid.");
422 settings()->setAvailableHoverTypes(hoverTypes);
425 void InternalSettings::setPrimaryHoverType(const String& type, ExceptionState& exceptionState)
427 InternalSettingsGuardForSettings();
428 String token = type.stripWhiteSpace();
430 HoverType hoverType = HoverTypeNone;
432 hoverType = HoverTypeNone;
433 else if (token == "on-demand")
434 hoverType = HoverTypeOnDemand;
435 else if (token == "hover")
436 hoverType = HoverTypeHover;
438 exceptionState.throwDOMException(SyntaxError, "The hover type token ('" + token + ")' is invalid.");
440 settings()->setPrimaryHoverType(hoverType);