Web Replay: add page-level setting to bypass the MemoryCache
[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 "FrameView.h"
34 #include "Language.h"
35 #include "LocaleToScriptMapping.h"
36 #include "MainFrame.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::sharedFeatures().cssExclusionsEnabled())
70     , m_originalCSSShapesEnabled(RuntimeEnabledFeatures::sharedFeatures().cssShapesEnabled())
71     , m_originalEditingBehavior(settings.editingBehaviorType())
72 #if ENABLE(TEXT_AUTOSIZING)
73     , m_originalTextAutosizingEnabled(settings.textAutosizingEnabled())
74     , m_originalTextAutosizingWindowSizeOverride(settings.textAutosizingWindowSizeOverride())
75     , m_originalTextAutosizingFontScaleFactor(settings.textAutosizingFontScaleFactor())
76 #endif
77     , m_originalMediaTypeOverride(settings.mediaTypeOverride())
78     , m_originalCanvasUsesAcceleratedDrawing(settings.canvasUsesAcceleratedDrawing())
79     , m_originalMockScrollbarsEnabled(settings.mockScrollbarsEnabled())
80     , m_langAttributeAwareFormControlUIEnabled(RuntimeEnabledFeatures::sharedFeatures().langAttributeAwareFormControlUIEnabled())
81     , m_imagesEnabled(settings.areImagesEnabled())
82     , m_minimumTimerInterval(settings.minDOMTimerInterval())
83 #if ENABLE(VIDEO_TRACK)
84     , m_shouldDisplaySubtitles(settings.shouldDisplaySubtitles())
85     , m_shouldDisplayCaptions(settings.shouldDisplayCaptions())
86     , m_shouldDisplayTextDescriptions(settings.shouldDisplayTextDescriptions())
87 #endif
88     , m_defaultVideoPosterURL(settings.defaultVideoPosterURL())
89     , m_originalTimeWithoutMouseMovementBeforeHidingControls(settings.timeWithoutMouseMovementBeforeHidingControls())
90     , m_useLegacyBackgroundSizeShorthandBehavior(settings.useLegacyBackgroundSizeShorthandBehavior())
91     , m_autoscrollForDragAndDropEnabled(settings.autoscrollForDragAndDropEnabled())
92     , m_pluginReplacementEnabled(RuntimeEnabledFeatures::sharedFeatures().pluginReplacementEnabled())
93     , m_shouldConvertPositionStyleOnCopy(settings.shouldConvertPositionStyleOnCopy())
94     , m_usesMemoryCache(settings.usesMemoryCache())
95 {
96 }
97
98 void InternalSettings::Backup::restoreTo(Settings& settings)
99 {
100     RuntimeEnabledFeatures::sharedFeatures().setCSSExclusionsEnabled(m_originalCSSExclusionsEnabled);
101     RuntimeEnabledFeatures::sharedFeatures().setCSSShapesEnabled(m_originalCSSShapesEnabled);
102     settings.setEditingBehaviorType(m_originalEditingBehavior);
103
104     for (const auto& standardFont : m_standardFontFamilies)
105         settings.setStandardFontFamily(standardFont.value, static_cast<UScriptCode>(standardFont.key));
106     m_standardFontFamilies.clear();
107
108     for (const auto& fixedFont : m_fixedFontFamilies)
109         settings.setFixedFontFamily(fixedFont.value, static_cast<UScriptCode>(fixedFont.key));
110     m_fixedFontFamilies.clear();
111
112     for (const auto& serifFont : m_serifFontFamilies)
113         settings.setSerifFontFamily(serifFont.value, static_cast<UScriptCode>(serifFont.key));
114     m_serifFontFamilies.clear();
115
116     for (const auto& sansSerifFont : m_sansSerifFontFamilies)
117         settings.setSansSerifFontFamily(sansSerifFont.value, static_cast<UScriptCode>(sansSerifFont.key));
118     m_sansSerifFontFamilies.clear();
119
120     for (const auto& cursiveFont : m_cursiveFontFamilies)
121         settings.setCursiveFontFamily(cursiveFont.value, static_cast<UScriptCode>(cursiveFont.key));
122     m_cursiveFontFamilies.clear();
123
124     for (const auto& fantasyFont : m_fantasyFontFamilies)
125         settings.setFantasyFontFamily(fantasyFont.value, static_cast<UScriptCode>(fantasyFont.key));
126     m_fantasyFontFamilies.clear();
127
128     for (const auto& pictographFont : m_pictographFontFamilies)
129         settings.setPictographFontFamily(pictographFont.value, static_cast<UScriptCode>(pictographFont.key));
130     m_pictographFontFamilies.clear();
131
132 #if ENABLE(TEXT_AUTOSIZING)
133     settings.setTextAutosizingEnabled(m_originalTextAutosizingEnabled);
134     settings.setTextAutosizingWindowSizeOverride(m_originalTextAutosizingWindowSizeOverride);
135     settings.setTextAutosizingFontScaleFactor(m_originalTextAutosizingFontScaleFactor);
136 #endif
137     settings.setMediaTypeOverride(m_originalMediaTypeOverride);
138     settings.setCanvasUsesAcceleratedDrawing(m_originalCanvasUsesAcceleratedDrawing);
139     settings.setMockScrollbarsEnabled(m_originalMockScrollbarsEnabled);
140     RuntimeEnabledFeatures::sharedFeatures().setLangAttributeAwareFormControlUIEnabled(m_langAttributeAwareFormControlUIEnabled);
141     settings.setImagesEnabled(m_imagesEnabled);
142     settings.setMinDOMTimerInterval(m_minimumTimerInterval);
143 #if ENABLE(VIDEO_TRACK)
144     settings.setShouldDisplaySubtitles(m_shouldDisplaySubtitles);
145     settings.setShouldDisplayCaptions(m_shouldDisplayCaptions);
146     settings.setShouldDisplayTextDescriptions(m_shouldDisplayTextDescriptions);
147 #endif
148     settings.setDefaultVideoPosterURL(m_defaultVideoPosterURL);
149     settings.setTimeWithoutMouseMovementBeforeHidingControls(m_originalTimeWithoutMouseMovementBeforeHidingControls);
150     settings.setUseLegacyBackgroundSizeShorthandBehavior(m_useLegacyBackgroundSizeShorthandBehavior);
151     settings.setAutoscrollForDragAndDropEnabled(m_autoscrollForDragAndDropEnabled);
152     settings.setShouldConvertPositionStyleOnCopy(m_shouldConvertPositionStyleOnCopy);
153     settings.setUsesMemoryCache(m_usesMemoryCache);
154     RuntimeEnabledFeatures::sharedFeatures().setPluginReplacementEnabled(m_pluginReplacementEnabled);
155 }
156
157 // We can't use RefCountedSupplement because that would try to make InternalSettings RefCounted
158 // and InternalSettings is already RefCounted via its base class, InternalSettingsGenerated.
159 // Instead, we manually make InternalSettings supplement Page.
160 class InternalSettingsWrapper : public Supplement<Page> {
161 public:
162     explicit InternalSettingsWrapper(Page* page)
163         : m_internalSettings(InternalSettings::create(page)) { }
164     virtual ~InternalSettingsWrapper() { m_internalSettings->hostDestroyed(); }
165 #if !ASSERT_DISABLED
166     virtual bool isRefCountedWrapper() const override { return true; }
167 #endif
168     InternalSettings* internalSettings() const { return m_internalSettings.get(); }
169
170 private:
171     RefPtr<InternalSettings> m_internalSettings;
172 };
173
174 const char* InternalSettings::supplementName()
175 {
176     return "InternalSettings";
177 }
178
179 InternalSettings* InternalSettings::from(Page* page)
180 {
181     if (!Supplement<Page>::from(page, supplementName()))
182         Supplement<Page>::provideTo(page, supplementName(), adoptPtr(new InternalSettingsWrapper(page)));
183     return static_cast<InternalSettingsWrapper*>(Supplement<Page>::from(page, supplementName()))->internalSettings();
184 }
185
186 InternalSettings::~InternalSettings()
187 {
188 }
189
190 InternalSettings::InternalSettings(Page* page)
191     : InternalSettingsGenerated(page)
192     , m_page(page)
193     , m_backup(page->settings())
194 {
195 }
196
197 void InternalSettings::resetToConsistentState()
198 {
199     page()->setPageScaleFactor(1, IntPoint(0, 0));
200     page()->setCanStartMedia(true);
201
202     m_backup.restoreTo(*settings());
203     m_backup = Backup(*settings());
204
205     InternalSettingsGenerated::resetToConsistentState();
206 }
207
208 Settings* InternalSettings::settings() const
209 {
210     if (!page())
211         return 0;
212     return &page()->settings();
213 }
214
215 void InternalSettings::setMockScrollbarsEnabled(bool enabled, ExceptionCode& ec)
216 {
217     InternalSettingsGuardForSettings();
218     settings()->setMockScrollbarsEnabled(enabled);
219 }
220
221 void InternalSettings::setTouchEventEmulationEnabled(bool enabled, ExceptionCode& ec)
222 {
223 #if ENABLE(TOUCH_EVENTS)
224     InternalSettingsGuardForSettings();
225     settings()->setTouchEventEmulationEnabled(enabled);
226 #else
227     UNUSED_PARAM(enabled);
228     UNUSED_PARAM(ec);
229 #endif
230 }
231
232 void InternalSettings::setStandardFontFamily(const String& family, const String& script, ExceptionCode& ec)
233 {
234     InternalSettingsGuardForSettings();
235     UScriptCode code = scriptNameToCode(script);
236     if (code == USCRIPT_INVALID_CODE)
237         return;
238     m_backup.m_standardFontFamilies.add(code, settings()->standardFontFamily(code));
239     settings()->setStandardFontFamily(family, code);
240 }
241
242 void InternalSettings::setSerifFontFamily(const String& family, const String& script, ExceptionCode& ec)
243 {
244     InternalSettingsGuardForSettings();
245     UScriptCode code = scriptNameToCode(script);
246     if (code == USCRIPT_INVALID_CODE)
247         return;
248     m_backup.m_serifFontFamilies.add(code, settings()->serifFontFamily(code));
249     settings()->setSerifFontFamily(family, code);
250 }
251
252 void InternalSettings::setSansSerifFontFamily(const String& family, const String& script, ExceptionCode& ec)
253 {
254     InternalSettingsGuardForSettings();
255     UScriptCode code = scriptNameToCode(script);
256     if (code == USCRIPT_INVALID_CODE)
257         return;
258     m_backup.m_sansSerifFontFamilies.add(code, settings()->sansSerifFontFamily(code));
259     settings()->setSansSerifFontFamily(family, code);
260 }
261
262 void InternalSettings::setFixedFontFamily(const String& family, const String& script, ExceptionCode& ec)
263 {
264     InternalSettingsGuardForSettings();
265     UScriptCode code = scriptNameToCode(script);
266     if (code == USCRIPT_INVALID_CODE)
267         return;
268     m_backup.m_fixedFontFamilies.add(code, settings()->fixedFontFamily(code));
269     settings()->setFixedFontFamily(family, code);
270 }
271
272 void InternalSettings::setCursiveFontFamily(const String& family, const String& script, ExceptionCode& ec)
273 {
274     InternalSettingsGuardForSettings();
275     UScriptCode code = scriptNameToCode(script);
276     if (code == USCRIPT_INVALID_CODE)
277         return;
278     m_backup.m_cursiveFontFamilies.add(code, settings()->cursiveFontFamily(code));
279     settings()->setCursiveFontFamily(family, code);
280 }
281
282 void InternalSettings::setFantasyFontFamily(const String& family, const String& script, ExceptionCode& ec)
283 {
284     InternalSettingsGuardForSettings();
285     UScriptCode code = scriptNameToCode(script);
286     if (code == USCRIPT_INVALID_CODE)
287         return;
288     m_backup.m_fantasyFontFamilies.add(code, settings()->fantasyFontFamily(code));
289     settings()->setFantasyFontFamily(family, code);
290 }
291
292 void InternalSettings::setPictographFontFamily(const String& family, const String& script, ExceptionCode& ec)
293 {
294     InternalSettingsGuardForSettings();
295     UScriptCode code = scriptNameToCode(script);
296     if (code == USCRIPT_INVALID_CODE)
297         return;
298     m_backup.m_pictographFontFamilies.add(code, settings()->pictographFontFamily(code));
299     settings()->setPictographFontFamily(family, code);
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::setMediaTypeOverride(const String& mediaType, ExceptionCode& ec)
326 {
327     InternalSettingsGuardForSettings();
328     settings()->setMediaTypeOverride(mediaType);
329 }
330
331 void InternalSettings::setTextAutosizingFontScaleFactor(float fontScaleFactor, ExceptionCode& ec)
332 {
333 #if ENABLE(TEXT_AUTOSIZING)
334     InternalSettingsGuardForSettings();
335     settings()->setTextAutosizingFontScaleFactor(fontScaleFactor);
336 #else
337     UNUSED_PARAM(fontScaleFactor);
338     UNUSED_PARAM(ec);
339 #endif
340 }
341
342 void InternalSettings::setCSSExclusionsEnabled(bool enabled, ExceptionCode& ec)
343 {
344     UNUSED_PARAM(ec);
345     RuntimeEnabledFeatures::sharedFeatures().setCSSExclusionsEnabled(enabled);
346 }
347
348 void InternalSettings::setCSSShapesEnabled(bool enabled, ExceptionCode& ec)
349 {
350     UNUSED_PARAM(ec);
351     RuntimeEnabledFeatures::sharedFeatures().setCSSShapesEnabled(enabled);
352 }
353
354 void InternalSettings::setCanStartMedia(bool enabled, ExceptionCode& ec)
355 {
356     InternalSettingsGuardForSettings();
357     m_page->setCanStartMedia(enabled);
358 }
359
360 void InternalSettings::setEditingBehavior(const String& editingBehavior, ExceptionCode& ec)
361 {
362     InternalSettingsGuardForSettings();
363     if (equalIgnoringCase(editingBehavior, "win"))
364         settings()->setEditingBehaviorType(EditingWindowsBehavior);
365     else if (equalIgnoringCase(editingBehavior, "mac"))
366         settings()->setEditingBehaviorType(EditingMacBehavior);
367     else if (equalIgnoringCase(editingBehavior, "unix"))
368         settings()->setEditingBehaviorType(EditingUnixBehavior);
369     else
370         ec = SYNTAX_ERR;
371 }
372
373 void InternalSettings::setShouldDisplayTrackKind(const String& kind, bool enabled, ExceptionCode& ec)
374 {
375     InternalSettingsGuardForSettings();
376
377 #if ENABLE(VIDEO_TRACK)
378     if (!page())
379         return;
380     CaptionUserPreferences* captionPreferences = page()->group().captionPreferences();
381
382     if (equalIgnoringCase(kind, "Subtitles"))
383         captionPreferences->setUserPrefersSubtitles(enabled);
384     else if (equalIgnoringCase(kind, "Captions"))
385         captionPreferences->setUserPrefersCaptions(enabled);
386     else if (equalIgnoringCase(kind, "TextDescriptions"))
387         captionPreferences->setUserPrefersTextDescriptions(enabled);
388     else
389         ec = SYNTAX_ERR;
390 #else
391     UNUSED_PARAM(kind);
392     UNUSED_PARAM(enabled);
393 #endif
394 }
395
396 bool InternalSettings::shouldDisplayTrackKind(const String& kind, ExceptionCode& ec)
397 {
398     InternalSettingsGuardForSettingsReturn(false);
399
400 #if ENABLE(VIDEO_TRACK)
401     if (!page())
402         return false;
403     CaptionUserPreferences* captionPreferences = page()->group().captionPreferences();
404
405     if (equalIgnoringCase(kind, "Subtitles"))
406         return captionPreferences->userPrefersSubtitles();
407     if (equalIgnoringCase(kind, "Captions"))
408         return captionPreferences->userPrefersCaptions();
409     if (equalIgnoringCase(kind, "TextDescriptions"))
410         return captionPreferences->userPrefersTextDescriptions();
411
412     ec = SYNTAX_ERR;
413     return false;
414 #else
415     UNUSED_PARAM(kind);
416     return false;
417 #endif
418 }
419
420 void InternalSettings::setStorageBlockingPolicy(const String& mode, ExceptionCode& ec)
421 {
422     InternalSettingsGuardForSettings();
423
424     if (mode == "AllowAll")
425         settings()->setStorageBlockingPolicy(SecurityOrigin::AllowAllStorage);
426     else if (mode == "BlockThirdParty")
427         settings()->setStorageBlockingPolicy(SecurityOrigin::BlockThirdPartyStorage);
428     else if (mode == "BlockAll")
429         settings()->setStorageBlockingPolicy(SecurityOrigin::BlockAllStorage);
430     else
431         ec = SYNTAX_ERR;
432 }
433
434 void InternalSettings::setLangAttributeAwareFormControlUIEnabled(bool enabled)
435 {
436     RuntimeEnabledFeatures::sharedFeatures().setLangAttributeAwareFormControlUIEnabled(enabled);
437 }
438
439 void InternalSettings::setImagesEnabled(bool enabled, ExceptionCode& ec)
440 {
441     InternalSettingsGuardForSettings();
442     settings()->setImagesEnabled(enabled);
443 }
444
445 void InternalSettings::setMinimumTimerInterval(double intervalInSeconds, ExceptionCode& ec)
446 {
447     InternalSettingsGuardForSettings();
448     settings()->setMinDOMTimerInterval(intervalInSeconds);
449 }
450
451 void InternalSettings::setDefaultVideoPosterURL(const String& url, ExceptionCode& ec)
452 {
453     InternalSettingsGuardForSettings();
454     settings()->setDefaultVideoPosterURL(url);
455 }
456
457 void InternalSettings::setTimeWithoutMouseMovementBeforeHidingControls(double time, ExceptionCode& ec)
458 {
459     InternalSettingsGuardForSettings();
460     settings()->setTimeWithoutMouseMovementBeforeHidingControls(time);
461 }
462
463 void InternalSettings::setUseLegacyBackgroundSizeShorthandBehavior(bool enabled, ExceptionCode& ec)
464 {
465     InternalSettingsGuardForSettings();
466     settings()->setUseLegacyBackgroundSizeShorthandBehavior(enabled);
467 }
468
469 void InternalSettings::setAutoscrollForDragAndDropEnabled(bool enabled, ExceptionCode& ec)
470 {
471     InternalSettingsGuardForSettings();
472     settings()->setAutoscrollForDragAndDropEnabled(enabled);
473 }
474
475 void InternalSettings::setFontFallbackPrefersPictographs(bool preferPictographs, ExceptionCode& ec)
476 {
477     InternalSettingsGuardForSettings();
478     settings()->setFontFallbackPrefersPictographs(preferPictographs);
479 }
480
481 void InternalSettings::setPluginReplacementEnabled(bool enabled)
482 {
483     RuntimeEnabledFeatures::sharedFeatures().setPluginReplacementEnabled(enabled);
484 }
485
486 void InternalSettings::setBackgroundShouldExtendBeyondPage(bool hasExtendedBackground, ExceptionCode& ec)
487 {
488     InternalSettingsGuardForSettings();
489     settings()->setBackgroundShouldExtendBeyondPage(hasExtendedBackground);
490 }
491
492 void InternalSettings::setShouldConvertPositionStyleOnCopy(bool convert, ExceptionCode& ec)
493 {
494     InternalSettingsGuardForSettings();
495     settings()->setShouldConvertPositionStyleOnCopy(convert);
496 }
497
498 void InternalSettings::setUsesMemoryCache(bool usesMemoryCache, ExceptionCode& ec)
499 {
500     InternalSettingsGuardForSettings();
501     settings()->setUsesMemoryCache(usesMemoryCache);
502 }
503
504 }