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