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