Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / testing / InternalSettings.cpp
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 "core/testing/InternalSettings.h"
29
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"
39
40 #define InternalSettingsGuardForSettingsReturn(returnValue) \
41     if (!settings()) { \
42         exceptionState.throwDOMException(InvalidAccessError, "The settings object cannot be obtained."); \
43         return returnValue; \
44     }
45
46 #define InternalSettingsGuardForSettings()  \
47     if (!settings()) { \
48         exceptionState.throwDOMException(InvalidAccessError, "The settings object cannot be obtained."); \
49         return; \
50     }
51
52 #define InternalSettingsGuardForPage() \
53     if (!page()) { \
54         exceptionState.throwDOMException(InvalidAccessError, "The page object cannot be obtained."); \
55         return; \
56     }
57
58 namespace blink {
59
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())
77 {
78 }
79
80 void InternalSettings::Backup::restoreTo(Settings* settings)
81 {
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);
99 }
100
101 #if ENABLE(OILPAN)
102 InternalSettings* InternalSettings::from(Page& page)
103 {
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()));
107 }
108 #else
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> {
113 public:
114     explicit InternalSettingsWrapper(Page& page)
115         : m_internalSettings(InternalSettings::create(page)) { }
116     virtual ~InternalSettingsWrapper() { m_internalSettings->hostDestroyed(); }
117 #if ENABLE(ASSERT)
118     virtual bool isRefCountedWrapper() const OVERRIDE { return true; }
119 #endif
120     InternalSettings* internalSettings() const { return m_internalSettings.get(); }
121
122 private:
123     RefPtr<InternalSettings> m_internalSettings;
124 };
125
126 InternalSettings* InternalSettings::from(Page& page)
127 {
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();
131 }
132 #endif
133
134 const char* InternalSettings::supplementName()
135 {
136     return "InternalSettings";
137 }
138
139 InternalSettings::~InternalSettings()
140 {
141 }
142
143 InternalSettings::InternalSettings(Page& page)
144     : InternalSettingsGenerated(&page)
145     , m_page(&page)
146     , m_backup(&page.settings())
147 {
148 }
149
150 void InternalSettings::resetToConsistentState()
151 {
152     page()->setPageScaleFactor(1, IntPoint(0, 0));
153
154     m_backup.restoreTo(settings());
155     m_backup = Backup(settings());
156     m_backup.m_originalTextAutosizingEnabled = settings()->textAutosizingEnabled();
157
158     InternalSettingsGenerated::resetToConsistentState();
159 }
160
161 Settings* InternalSettings::settings() const
162 {
163     if (!page())
164         return 0;
165     return &page()->settings();
166 }
167
168 void InternalSettings::setMockScrollbarsEnabled(bool enabled, ExceptionState& exceptionState)
169 {
170     InternalSettingsGuardForSettings();
171     settings()->setMockScrollbarsEnabled(enabled);
172 }
173
174 void InternalSettings::setMockGestureTapHighlightsEnabled(bool enabled, ExceptionState& exceptionState)
175 {
176     InternalSettingsGuardForSettings();
177     settings()->setMockGestureTapHighlightsEnabled(enabled);
178 }
179
180 void InternalSettings::setAuthorShadowDOMForAnyElementEnabled(bool isEnabled)
181 {
182     RuntimeEnabledFeatures::setAuthorShadowDOMForAnyElementEnabled(isEnabled);
183 }
184
185 void InternalSettings::setExperimentalContentSecurityPolicyFeaturesEnabled(bool enabled)
186 {
187     RuntimeEnabledFeatures::setExperimentalContentSecurityPolicyFeaturesEnabled(enabled);
188 }
189
190 void InternalSettings::setLaxMixedContentCheckingEnabled(bool enabled)
191 {
192     RuntimeEnabledFeatures::setLaxMixedContentCheckingEnabled(enabled);
193 }
194
195 void InternalSettings::setPseudoClassesInMatchingCriteriaInAuthorShadowTreesEnabled(bool enabled)
196 {
197     RuntimeEnabledFeatures::setPseudoClassesInMatchingCriteriaInAuthorShadowTreesEnabled(enabled);
198 }
199
200 void InternalSettings::setOverlayScrollbarsEnabled(bool enabled)
201 {
202     RuntimeEnabledFeatures::setOverlayScrollbarsEnabled(enabled);
203 }
204
205 void InternalSettings::setViewportEnabled(bool enabled, ExceptionState& exceptionState)
206 {
207     InternalSettingsGuardForSettings();
208     settings()->setViewportEnabled(enabled);
209 }
210
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)
214 {
215     InternalSettingsGuardForSettings();
216     settings()->setLayerSquashingEnabled(enabled);
217 }
218
219 void InternalSettings::setStandardFontFamily(const AtomicString& family, const String& script, ExceptionState& exceptionState)
220 {
221     InternalSettingsGuardForSettings();
222     UScriptCode code = scriptNameToCode(script);
223     if (code == USCRIPT_INVALID_CODE)
224         return;
225     if (settings()->genericFontFamilySettings().updateStandard(family, code))
226         settings()->notifyGenericFontFamilyChange();
227 }
228
229 void InternalSettings::setSerifFontFamily(const AtomicString& family, const String& script, ExceptionState& exceptionState)
230 {
231     InternalSettingsGuardForSettings();
232     UScriptCode code = scriptNameToCode(script);
233     if (code == USCRIPT_INVALID_CODE)
234         return;
235     if (settings()->genericFontFamilySettings().updateSerif(family, code))
236         settings()->notifyGenericFontFamilyChange();
237 }
238
239 void InternalSettings::setSansSerifFontFamily(const AtomicString& family, const String& script, ExceptionState& exceptionState)
240 {
241     InternalSettingsGuardForSettings();
242     UScriptCode code = scriptNameToCode(script);
243     if (code == USCRIPT_INVALID_CODE)
244         return;
245     if (settings()->genericFontFamilySettings().updateSansSerif(family, code))
246         settings()->notifyGenericFontFamilyChange();
247 }
248
249 void InternalSettings::setFixedFontFamily(const AtomicString& family, const String& script, ExceptionState& exceptionState)
250 {
251     InternalSettingsGuardForSettings();
252     UScriptCode code = scriptNameToCode(script);
253     if (code == USCRIPT_INVALID_CODE)
254         return;
255     if (settings()->genericFontFamilySettings().updateFixed(family, code))
256         settings()->notifyGenericFontFamilyChange();
257 }
258
259 void InternalSettings::setCursiveFontFamily(const AtomicString& family, const String& script, ExceptionState& exceptionState)
260 {
261     InternalSettingsGuardForSettings();
262     UScriptCode code = scriptNameToCode(script);
263     if (code == USCRIPT_INVALID_CODE)
264         return;
265     if (settings()->genericFontFamilySettings().updateCursive(family, code))
266         settings()->notifyGenericFontFamilyChange();
267 }
268
269 void InternalSettings::setFantasyFontFamily(const AtomicString& family, const String& script, ExceptionState& exceptionState)
270 {
271     InternalSettingsGuardForSettings();
272     UScriptCode code = scriptNameToCode(script);
273     if (code == USCRIPT_INVALID_CODE)
274         return;
275     if (settings()->genericFontFamilySettings().updateFantasy(family, code))
276         settings()->notifyGenericFontFamilyChange();
277 }
278
279 void InternalSettings::setPictographFontFamily(const AtomicString& family, const String& script, ExceptionState& exceptionState)
280 {
281     InternalSettingsGuardForSettings();
282     UScriptCode code = scriptNameToCode(script);
283     if (code == USCRIPT_INVALID_CODE)
284         return;
285     if (settings()->genericFontFamilySettings().updatePictograph(family, code))
286         settings()->notifyGenericFontFamilyChange();
287 }
288
289 void InternalSettings::setTextAutosizingEnabled(bool enabled, ExceptionState& exceptionState)
290 {
291     InternalSettingsGuardForSettings();
292     settings()->setTextAutosizingEnabled(enabled);
293     m_page->inspectorController().setTextAutosizingEnabled(enabled);
294 }
295
296 void InternalSettings::setTextAutosizingWindowSizeOverride(int width, int height, ExceptionState& exceptionState)
297 {
298     InternalSettingsGuardForSettings();
299     settings()->setTextAutosizingWindowSizeOverride(IntSize(width, height));
300 }
301
302 void InternalSettings::setMediaTypeOverride(const String& mediaType, ExceptionState& exceptionState)
303 {
304     InternalSettingsGuardForSettings();
305     settings()->setMediaTypeOverride(mediaType);
306 }
307
308 void InternalSettings::setAccessibilityFontScaleFactor(float fontScaleFactor, ExceptionState& exceptionState)
309 {
310     InternalSettingsGuardForSettings();
311     settings()->setAccessibilityFontScaleFactor(fontScaleFactor);
312 }
313
314 void InternalSettings::setEditingBehavior(const String& editingBehavior, ExceptionState& exceptionState)
315 {
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);
325     else
326         exceptionState.throwDOMException(SyntaxError, "The editing behavior type provided ('" + editingBehavior + "') is invalid.");
327 }
328
329 void InternalSettings::setLangAttributeAwareFormControlUIEnabled(bool enabled)
330 {
331     RuntimeEnabledFeatures::setLangAttributeAwareFormControlUIEnabled(enabled);
332 }
333
334 void InternalSettings::setImagesEnabled(bool enabled, ExceptionState& exceptionState)
335 {
336     InternalSettingsGuardForSettings();
337     settings()->setImagesEnabled(enabled);
338 }
339
340 void InternalSettings::setDefaultVideoPosterURL(const String& url, ExceptionState& exceptionState)
341 {
342     InternalSettingsGuardForSettings();
343     settings()->setDefaultVideoPosterURL(url);
344 }
345
346 void InternalSettings::trace(Visitor* visitor)
347 {
348     visitor->trace(m_page);
349     InternalSettingsGenerated::trace(visitor);
350 #if ENABLE(OILPAN)
351     HeapSupplement<Page>::trace(visitor);
352 #endif
353 }
354
355 void InternalSettings::setAvailablePointerTypes(const String& pointers, ExceptionState& exceptionState)
356 {
357     InternalSettingsGuardForSettings();
358
359     // Allow setting multiple pointer types by passing comma seperated list
360     // ("coarse,fine").
361     Vector<String> tokens;
362     pointers.split(",", false, tokens);
363
364     int pointerTypes = 0;
365     for (size_t i = 0; i < tokens.size(); ++i) {
366         String token = tokens[i].stripWhiteSpace();
367
368         if (token == "coarse")
369             pointerTypes |= PointerTypeCoarse;
370         else if (token == "fine")
371             pointerTypes |= PointerTypeFine;
372         else if (token == "none")
373             pointerTypes |= PointerTypeNone;
374         else
375             exceptionState.throwDOMException(SyntaxError, "The pointer type token ('" + token + ")' is invalid.");
376     }
377
378     settings()->setAvailablePointerTypes(pointerTypes);
379 }
380
381 void InternalSettings::setPrimaryPointerType(const String& pointer, ExceptionState& exceptionState)
382 {
383     InternalSettingsGuardForSettings();
384     String token = pointer.stripWhiteSpace();
385
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;
393     else
394         exceptionState.throwDOMException(SyntaxError, "The pointer type token ('" + token + ")' is invalid.");
395
396     settings()->setPrimaryPointerType(type);
397 }
398
399 void InternalSettings::setAvailableHoverTypes(const String& types, ExceptionState& exceptionState)
400 {
401     InternalSettingsGuardForSettings();
402
403     // Allow setting multiple hover types by passing comma seperated list
404     // ("on-demand,none").
405     Vector<String> tokens;
406     types.split(",", false, tokens);
407
408     int hoverTypes = 0;
409     for (size_t i = 0; i < tokens.size(); ++i) {
410         String token = tokens[i].stripWhiteSpace();
411
412         if (token == "none")
413             hoverTypes |= HoverTypeNone;
414         else if (token == "on-demand")
415             hoverTypes |= HoverTypeOnDemand;
416         else if (token == "hover")
417             hoverTypes |= HoverTypeHover;
418         else
419             exceptionState.throwDOMException(SyntaxError, "The hover type token ('" + token + ")' is invalid.");
420     }
421
422     settings()->setAvailableHoverTypes(hoverTypes);
423 }
424
425 void InternalSettings::setPrimaryHoverType(const String& type, ExceptionState& exceptionState)
426 {
427     InternalSettingsGuardForSettings();
428     String token = type.stripWhiteSpace();
429
430     HoverType hoverType = HoverTypeNone;
431     if (token == "none")
432         hoverType = HoverTypeNone;
433     else if (token == "on-demand")
434         hoverType = HoverTypeOnDemand;
435     else if (token == "hover")
436         hoverType = HoverTypeHover;
437     else
438         exceptionState.throwDOMException(SyntaxError, "The hover type token ('" + token + ")' is invalid.");
439
440     settings()->setPrimaryHoverType(hoverType);
441 }
442
443 }