[Internals] setShadowDOMEnabled() shouldn't be used except a few tests.
[WebKit-https.git] / Source / WebCore / 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 "InternalSettings.h"
29
30 #include "Document.h"
31 #include "ExceptionCode.h"
32 #include "Frame.h"
33 #include "FrameView.h"
34 #include "Language.h"
35 #include "LocaleToScriptMapping.h"
36 #include "Page.h"
37 #include "RuntimeEnabledFeatures.h"
38 #include "Settings.h"
39 #include "Supplementable.h"
40 #include "TextRun.h"
41
42 #if ENABLE(INPUT_TYPE_COLOR)
43 #include "ColorChooser.h"
44 #endif
45
46 #define InternalSettingsGuardForSettingsReturn(returnValue) \
47     if (!settings()) { \
48         ec = INVALID_ACCESS_ERR; \
49         return returnValue; \
50     }
51
52 #define InternalSettingsGuardForSettings()  \
53     if (!settings()) { \
54         ec = INVALID_ACCESS_ERR; \
55         return; \
56     }
57
58 #define InternalSettingsGuardForPage() \
59     if (!page()) { \
60         ec = INVALID_ACCESS_ERR; \
61         return; \
62     }
63
64 namespace WebCore {
65
66 InternalSettings::Backup::Backup(Settings* settings)
67     : m_originalCSSExclusionsEnabled(RuntimeEnabledFeatures::cssExclusionsEnabled())
68     , m_originalCSSVariablesEnabled(settings->cssVariablesEnabled())
69 #if ENABLE(SHADOW_DOM)
70     , m_originalShadowDOMEnabled(RuntimeEnabledFeatures::shadowDOMEnabled())
71     , m_originalAuthorShadowDOMForAnyElementEnabled(RuntimeEnabledFeatures::authorShadowDOMForAnyElementEnabled())
72 #endif
73 #if ENABLE(STYLE_SCOPED)
74     , m_originalStyleScoped(RuntimeEnabledFeatures::styleScopedEnabled())
75 #endif
76     , m_originalEditingBehavior(settings->editingBehaviorType())
77 #if ENABLE(TEXT_AUTOSIZING)
78     , m_originalTextAutosizingEnabled(settings->textAutosizingEnabled())
79     , m_originalTextAutosizingWindowSizeOverride(settings->textAutosizingWindowSizeOverride())
80     , m_originalTextAutosizingFontScaleFactor(settings->textAutosizingFontScaleFactor())
81 #endif
82     , m_originalResolutionOverride(settings->resolutionOverride())
83     , m_originalMediaTypeOverride(settings->mediaTypeOverride())
84 #if ENABLE(DIALOG_ELEMENT)
85     , m_originalDialogElementEnabled(RuntimeEnabledFeatures::dialogElementEnabled())
86 #endif
87     , m_originalCanvasUsesAcceleratedDrawing(settings->canvasUsesAcceleratedDrawing())
88     , m_originalMockScrollbarsEnabled(settings->mockScrollbarsEnabled())
89     , m_langAttributeAwareFormControlUIEnabled(RuntimeEnabledFeatures::langAttributeAwareFormControlUIEnabled())
90     , m_imagesEnabled(settings->areImagesEnabled())
91     , m_minimumTimerInterval(settings->minDOMTimerInterval())
92 #if ENABLE(VIDEO_TRACK)
93     , m_shouldDisplaySubtitles(settings->shouldDisplaySubtitles())
94     , m_shouldDisplayCaptions(settings->shouldDisplayCaptions())
95     , m_shouldDisplayTextDescriptions(settings->shouldDisplayTextDescriptions())
96 #endif
97 {
98 }
99
100 void InternalSettings::Backup::restoreTo(Settings* settings)
101 {
102     RuntimeEnabledFeatures::setCSSExclusionsEnabled(m_originalCSSExclusionsEnabled);
103     settings->setCSSVariablesEnabled(m_originalCSSVariablesEnabled);
104 #if ENABLE(SHADOW_DOM)
105     RuntimeEnabledFeatures::setShadowDOMEnabled(m_originalShadowDOMEnabled);
106     RuntimeEnabledFeatures::setAuthorShadowDOMForAnyElementEnabled(m_originalAuthorShadowDOMForAnyElementEnabled);
107 #endif
108 #if ENABLE(STYLE_SCOPED)
109     RuntimeEnabledFeatures::setStyleScopedEnabled(m_originalStyleScoped);
110 #endif
111     settings->setEditingBehaviorType(m_originalEditingBehavior);
112 #if ENABLE(TEXT_AUTOSIZING)
113     settings->setTextAutosizingEnabled(m_originalTextAutosizingEnabled);
114     settings->setTextAutosizingWindowSizeOverride(m_originalTextAutosizingWindowSizeOverride);
115     settings->setTextAutosizingFontScaleFactor(m_originalTextAutosizingFontScaleFactor);
116 #endif
117     settings->setResolutionOverride(m_originalResolutionOverride);
118     settings->setMediaTypeOverride(m_originalMediaTypeOverride);
119 #if ENABLE(DIALOG_ELEMENT)
120     RuntimeEnabledFeatures::setDialogElementEnabled(m_originalDialogElementEnabled);
121 #endif
122     settings->setCanvasUsesAcceleratedDrawing(m_originalCanvasUsesAcceleratedDrawing);
123     settings->setMockScrollbarsEnabled(m_originalMockScrollbarsEnabled);
124     RuntimeEnabledFeatures::setLangAttributeAwareFormControlUIEnabled(m_langAttributeAwareFormControlUIEnabled);
125     settings->setImagesEnabled(m_imagesEnabled);
126     settings->setMinDOMTimerInterval(m_minimumTimerInterval);
127 #if ENABLE(VIDEO_TRACK)
128     settings->setShouldDisplaySubtitles(m_shouldDisplaySubtitles);
129     settings->setShouldDisplayCaptions(m_shouldDisplayCaptions);
130     settings->setShouldDisplayTextDescriptions(m_shouldDisplayTextDescriptions);
131 #endif
132 }
133
134 // We can't use RefCountedSupplement because that would try to make InternalSettings RefCounted
135 // and InternalSettings is already RefCounted via its base class, InternalSettingsGenerated.
136 // Instead, we manually make InternalSettings supplement Page.
137 class InternalSettingsWrapper : public Supplement<Page> {
138 public:
139     explicit InternalSettingsWrapper(Page* page)
140         : m_internalSettings(InternalSettings::create(page)) { }
141     virtual ~InternalSettingsWrapper() { m_internalSettings->hostDestroyed(); }
142 #if !ASSERT_DISABLED
143     virtual bool isRefCountedWrapper() const OVERRIDE { return true; }
144 #endif
145     InternalSettings* internalSettings() const { return m_internalSettings.get(); }
146
147 private:
148     RefPtr<InternalSettings> m_internalSettings;
149 };
150
151 const char* InternalSettings::supplementName()
152 {
153     return "InternalSettings";
154 }
155
156 InternalSettings* InternalSettings::from(Page* page)
157 {
158     if (!Supplement<Page>::from(page, supplementName()))
159         Supplement<Page>::provideTo(page, supplementName(), adoptPtr(new InternalSettingsWrapper(page)));
160     return static_cast<InternalSettingsWrapper*>(Supplement<Page>::from(page, supplementName()))->internalSettings();
161 }
162
163 InternalSettings::~InternalSettings()
164 {
165 }
166
167 InternalSettings::InternalSettings(Page* page)
168     : InternalSettingsGenerated(page)
169     , m_page(page)
170     , m_backup(page->settings())
171 {
172 }
173
174 void InternalSettings::resetToConsistentState()
175 {
176     page()->setPageScaleFactor(1, IntPoint(0, 0));
177     page()->setCanStartMedia(true);
178
179     m_backup.restoreTo(settings());
180     m_backup = Backup(settings());
181
182     InternalSettingsGenerated::resetToConsistentState();
183 }
184
185 Settings* InternalSettings::settings() const
186 {
187     if (!page())
188         return 0;
189     return page()->settings();
190 }
191
192 void InternalSettings::setMockScrollbarsEnabled(bool enabled, ExceptionCode& ec)
193 {
194     InternalSettingsGuardForSettings();
195     settings()->setMockScrollbarsEnabled(enabled);
196 }
197
198 static bool urlIsWhitelistedForSetShadowDOMEnabled(const String& url)
199 {
200     // This check is just for preventing fuzzers from crashing because of unintended API calls.
201     // You can list your test if needed.
202     return notFound != url.find("fast/dom/shadow/content-shadow-unknown.html")
203         || notFound != url.find("fast/dom/shadow/insertion-points-with-shadow-disabled.html");
204 }
205
206 void InternalSettings::setShadowDOMEnabled(bool enabled, ExceptionCode& ec)
207 {
208     if (!urlIsWhitelistedForSetShadowDOMEnabled(page()->mainFrame()->document()->url().string())) {
209         ec = INVALID_ACCESS_ERR;
210         return;
211     }
212
213 #if ENABLE(SHADOW_DOM)
214     RuntimeEnabledFeatures::setShadowDOMEnabled(enabled);
215 #else
216     // Even SHADOW_DOM is off, InternalSettings allows setShadowDOMEnabled(false) to
217     // have broader test coverage. But it cannot be setShadowDOMEnabled(true).
218     if (enabled)
219         ec = INVALID_ACCESS_ERR;
220 #endif
221 }
222
223 void InternalSettings::setAuthorShadowDOMForAnyElementEnabled(bool isEnabled)
224 {
225 #if ENABLE(SHADOW_DOM)
226     RuntimeEnabledFeatures::setAuthorShadowDOMForAnyElementEnabled(isEnabled);
227 #else
228     UNUSED_PARAM(isEnabled);
229 #endif
230 }
231
232 void InternalSettings::setStyleScopedEnabled(bool enabled)
233 {
234 #if ENABLE(STYLE_SCOPED)
235     RuntimeEnabledFeatures::setStyleScopedEnabled(enabled);
236 #else
237     UNUSED_PARAM(enabled);
238 #endif
239 }
240
241 void InternalSettings::setTouchEventEmulationEnabled(bool enabled, ExceptionCode& ec)
242 {
243 #if ENABLE(TOUCH_EVENTS)
244     InternalSettingsGuardForSettings();
245     settings()->setTouchEventEmulationEnabled(enabled);
246 #else
247     UNUSED_PARAM(enabled);
248     UNUSED_PARAM(ec);
249 #endif
250 }
251
252 typedef void (Settings::*SetFontFamilyFunction)(const AtomicString&, UScriptCode);
253 static void setFontFamily(Settings* settings, const String& family, const String& script, SetFontFamilyFunction setter)
254 {
255     UScriptCode code = scriptNameToCode(script);
256     if (code != USCRIPT_INVALID_CODE)
257         (settings->*setter)(family, code);
258 }
259
260 void InternalSettings::setStandardFontFamily(const String& family, const String& script, ExceptionCode& ec)
261 {
262     InternalSettingsGuardForSettings();
263     setFontFamily(settings(), family, script, &Settings::setStandardFontFamily);
264 }
265
266 void InternalSettings::setSerifFontFamily(const String& family, const String& script, ExceptionCode& ec)
267 {
268     InternalSettingsGuardForSettings();
269     setFontFamily(settings(), family, script, &Settings::setSerifFontFamily);
270 }
271
272 void InternalSettings::setSansSerifFontFamily(const String& family, const String& script, ExceptionCode& ec)
273 {
274     InternalSettingsGuardForSettings();
275     setFontFamily(settings(), family, script, &Settings::setSansSerifFontFamily);
276 }
277
278 void InternalSettings::setFixedFontFamily(const String& family, const String& script, ExceptionCode& ec)
279 {
280     InternalSettingsGuardForSettings();
281     setFontFamily(settings(), family, script, &Settings::setFixedFontFamily);
282 }
283
284 void InternalSettings::setCursiveFontFamily(const String& family, const String& script, ExceptionCode& ec)
285 {
286     InternalSettingsGuardForSettings();
287     setFontFamily(settings(), family, script, &Settings::setCursiveFontFamily);
288 }
289
290 void InternalSettings::setFantasyFontFamily(const String& family, const String& script, ExceptionCode& ec)
291 {
292     InternalSettingsGuardForSettings();
293     setFontFamily(settings(), family, script, &Settings::setFantasyFontFamily);
294 }
295
296 void InternalSettings::setPictographFontFamily(const String& family, const String& script, ExceptionCode& ec)
297 {
298     InternalSettingsGuardForSettings();
299     setFontFamily(settings(), family, script, &Settings::setPictographFontFamily);
300 }
301
302 void InternalSettings::setTextAutosizingEnabled(bool enabled, ExceptionCode& ec)
303 {
304 #if ENABLE(TEXT_AUTOSIZING)
305     InternalSettingsGuardForSettings();
306     settings()->setTextAutosizingEnabled(enabled);
307 #else
308     UNUSED_PARAM(enabled);
309     UNUSED_PARAM(ec);
310 #endif
311 }
312
313 void InternalSettings::setTextAutosizingWindowSizeOverride(int width, int height, ExceptionCode& ec)
314 {
315 #if ENABLE(TEXT_AUTOSIZING)
316     InternalSettingsGuardForSettings();
317     settings()->setTextAutosizingWindowSizeOverride(IntSize(width, height));
318 #else
319     UNUSED_PARAM(width);
320     UNUSED_PARAM(height);
321     UNUSED_PARAM(ec);
322 #endif
323 }
324
325 void InternalSettings::setResolutionOverride(int dotsPerCSSInchHorizontally, int dotsPerCSSInchVertically, ExceptionCode& ec)
326 {
327     InternalSettingsGuardForSettings();
328     // An empty size resets the override.
329     settings()->setResolutionOverride(IntSize(dotsPerCSSInchHorizontally, dotsPerCSSInchVertically));
330 }
331
332 void InternalSettings::setMediaTypeOverride(const String& mediaType, ExceptionCode& ec)
333 {
334     InternalSettingsGuardForSettings();
335     settings()->setMediaTypeOverride(mediaType);
336 }
337
338 void InternalSettings::setTextAutosizingFontScaleFactor(float fontScaleFactor, ExceptionCode& ec)
339 {
340 #if ENABLE(TEXT_AUTOSIZING)
341     InternalSettingsGuardForSettings();
342     settings()->setTextAutosizingFontScaleFactor(fontScaleFactor);
343 #else
344     UNUSED_PARAM(fontScaleFactor);
345     UNUSED_PARAM(ec);
346 #endif
347 }
348
349 void InternalSettings::setEnableScrollAnimator(bool enabled, ExceptionCode& ec)
350 {
351 #if ENABLE(SMOOTH_SCROLLING)
352     InternalSettingsGuardForSettings();
353     settings()->setEnableScrollAnimator(enabled);
354 #else
355     UNUSED_PARAM(enabled);
356     UNUSED_PARAM(ec);
357 #endif
358 }
359
360 bool InternalSettings::scrollAnimatorEnabled(ExceptionCode& ec)
361 {
362 #if ENABLE(SMOOTH_SCROLLING)
363     InternalSettingsGuardForSettingsReturn(false);
364     return settings()->scrollAnimatorEnabled();
365 #else
366     UNUSED_PARAM(ec);
367     return false;
368 #endif
369 }
370
371 void InternalSettings::setCSSExclusionsEnabled(bool enabled, ExceptionCode& ec)
372 {
373     UNUSED_PARAM(ec);
374     RuntimeEnabledFeatures::setCSSExclusionsEnabled(enabled);
375 }
376
377 void InternalSettings::setCSSVariablesEnabled(bool enabled, ExceptionCode& ec)
378 {
379     InternalSettingsGuardForSettings();
380     settings()->setCSSVariablesEnabled(enabled);
381 }
382
383 bool InternalSettings::cssVariablesEnabled(ExceptionCode& ec)
384 {
385     InternalSettingsGuardForSettingsReturn(false);
386     return settings()->cssVariablesEnabled();
387 }
388
389 void InternalSettings::setCanStartMedia(bool enabled, ExceptionCode& ec)
390 {
391     InternalSettingsGuardForSettings();
392     m_page->setCanStartMedia(enabled);
393 }
394
395 void InternalSettings::setEditingBehavior(const String& editingBehavior, ExceptionCode& ec)
396 {
397     InternalSettingsGuardForSettings();
398     if (equalIgnoringCase(editingBehavior, "win"))
399         settings()->setEditingBehaviorType(EditingWindowsBehavior);
400     else if (equalIgnoringCase(editingBehavior, "mac"))
401         settings()->setEditingBehaviorType(EditingMacBehavior);
402     else if (equalIgnoringCase(editingBehavior, "unix"))
403         settings()->setEditingBehaviorType(EditingUnixBehavior);
404     else if (equalIgnoringCase(editingBehavior, "android"))
405         settings()->setEditingBehaviorType(EditingAndroidBehavior);
406     else
407         ec = SYNTAX_ERR;
408 }
409
410 void InternalSettings::setDialogElementEnabled(bool enabled, ExceptionCode& ec)
411 {
412     UNUSED_PARAM(ec);
413 #if ENABLE(DIALOG_ELEMENT)
414     RuntimeEnabledFeatures::setDialogElementEnabled(enabled);
415 #else
416     UNUSED_PARAM(enabled);
417 #endif
418 }
419
420 void InternalSettings::setShouldDisplayTrackKind(const String& kind, bool enabled, ExceptionCode& ec)
421 {
422     InternalSettingsGuardForSettings();
423
424 #if ENABLE(VIDEO_TRACK)
425     if (equalIgnoringCase(kind, "Subtitles"))
426         settings()->setShouldDisplaySubtitles(enabled);
427     else if (equalIgnoringCase(kind, "Captions"))
428         settings()->setShouldDisplayCaptions(enabled);
429     else if (equalIgnoringCase(kind, "TextDescriptions"))
430         settings()->setShouldDisplayTextDescriptions(enabled);
431     else
432         ec = SYNTAX_ERR;
433 #else
434     UNUSED_PARAM(kind);
435     UNUSED_PARAM(enabled);
436 #endif
437 }
438
439 bool InternalSettings::shouldDisplayTrackKind(const String& kind, ExceptionCode& ec)
440 {
441     InternalSettingsGuardForSettingsReturn(false);
442
443 #if ENABLE(VIDEO_TRACK)
444     if (equalIgnoringCase(kind, "Subtitles"))
445         return settings()->shouldDisplaySubtitles();
446     if (equalIgnoringCase(kind, "Captions"))
447         return settings()->shouldDisplayCaptions();
448     if (equalIgnoringCase(kind, "TextDescriptions"))
449         return settings()->shouldDisplayTextDescriptions();
450
451     ec = SYNTAX_ERR;
452     return false;
453 #else
454     UNUSED_PARAM(kind);
455     return false;
456 #endif
457 }
458
459 void InternalSettings::setStorageBlockingPolicy(const String& mode, ExceptionCode& ec)
460 {
461     InternalSettingsGuardForSettings();
462
463     if (mode == "AllowAll")
464         settings()->setStorageBlockingPolicy(SecurityOrigin::AllowAllStorage);
465     else if (mode == "BlockThirdParty")
466         settings()->setStorageBlockingPolicy(SecurityOrigin::BlockThirdPartyStorage);
467     else if (mode == "BlockAll")
468         settings()->setStorageBlockingPolicy(SecurityOrigin::BlockAllStorage);
469     else
470         ec = SYNTAX_ERR;
471 }
472
473 void InternalSettings::setLangAttributeAwareFormControlUIEnabled(bool enabled)
474 {
475     RuntimeEnabledFeatures::setLangAttributeAwareFormControlUIEnabled(enabled);
476 }
477
478 void InternalSettings::setImagesEnabled(bool enabled, ExceptionCode& ec)
479 {
480     InternalSettingsGuardForSettings();
481     settings()->setImagesEnabled(enabled);
482 }
483
484 void InternalSettings::setMinimumTimerInterval(double intervalInSeconds, ExceptionCode& ec)
485 {
486     InternalSettingsGuardForSettings();
487     settings()->setMinDOMTimerInterval(intervalInSeconds);
488 }
489
490 }