summaryrefslogtreecommitdiff
path: root/Source/WebCore/testing
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/testing')
-rw-r--r--Source/WebCore/testing/GCObservation.cpp39
-rw-r--r--Source/WebCore/testing/GCObservation.h51
-rw-r--r--Source/WebCore/testing/GCObservation.idl38
-rw-r--r--Source/WebCore/testing/InternalSettings.cpp808
-rw-r--r--Source/WebCore/testing/InternalSettings.h188
-rw-r--r--Source/WebCore/testing/InternalSettings.idl107
-rw-r--r--Source/WebCore/testing/Internals.cpp3493
-rw-r--r--Source/WebCore/testing/Internals.h550
-rw-r--r--Source/WebCore/testing/Internals.idl502
-rw-r--r--Source/WebCore/testing/LegacyMockCDM.cpp144
-rw-r--r--Source/WebCore/testing/LegacyMockCDM.h57
-rw-r--r--Source/WebCore/testing/MallocStatistics.h8
-rw-r--r--Source/WebCore/testing/MallocStatistics.idl3
-rw-r--r--Source/WebCore/testing/MemoryInfo.h13
-rw-r--r--Source/WebCore/testing/MemoryInfo.idl3
-rw-r--r--Source/WebCore/testing/MockCDMFactory.cpp382
-rw-r--r--Source/WebCore/testing/MockCDMFactory.h148
-rw-r--r--Source/WebCore/testing/MockCDMFactory.idl42
-rw-r--r--Source/WebCore/testing/MockContentFilter.cpp158
-rw-r--r--Source/WebCore/testing/MockContentFilter.h59
-rw-r--r--Source/WebCore/testing/MockContentFilterSettings.cpp63
-rw-r--r--Source/WebCore/testing/MockContentFilterSettings.h92
-rw-r--r--Source/WebCore/testing/MockContentFilterSettings.idl49
-rw-r--r--Source/WebCore/testing/MockGamepad.cpp76
-rw-r--r--Source/WebCore/testing/MockGamepad.h52
-rw-r--r--Source/WebCore/testing/MockGamepadProvider.cpp155
-rw-r--r--Source/WebCore/testing/MockGamepadProvider.h69
-rw-r--r--Source/WebCore/testing/MockLibWebRTCPeerConnection.cpp401
-rw-r--r--Source/WebCore/testing/MockLibWebRTCPeerConnection.h229
-rw-r--r--Source/WebCore/testing/MockPageOverlay.cpp53
-rw-r--r--Source/WebCore/testing/MockPageOverlay.h48
-rw-r--r--Source/WebCore/testing/MockPageOverlay.idl31
-rw-r--r--Source/WebCore/testing/MockPageOverlayClient.cpp152
-rw-r--r--Source/WebCore/testing/MockPageOverlayClient.h65
-rw-r--r--Source/WebCore/testing/MockQuickLookHandleClient.cpp52
-rw-r--r--Source/WebCore/testing/MockQuickLookHandleClient.h53
-rw-r--r--Source/WebCore/testing/TypeConversions.h101
-rw-r--r--Source/WebCore/testing/TypeConversions.idl38
-rw-r--r--Source/WebCore/testing/WebCoreTestShimLibrary.cpp58
-rw-r--r--Source/WebCore/testing/js/WebCoreTestSupport.cpp130
-rw-r--r--Source/WebCore/testing/js/WebCoreTestSupport.h34
-rw-r--r--Source/WebCore/testing/js/WebCoreTestSupportPrefix.cpp26
-rw-r--r--Source/WebCore/testing/js/WebCoreTestSupportPrefix.h158
43 files changed, 7251 insertions, 1727 deletions
diff --git a/Source/WebCore/testing/GCObservation.cpp b/Source/WebCore/testing/GCObservation.cpp
new file mode 100644
index 000000000..03091921f
--- /dev/null
+++ b/Source/WebCore/testing/GCObservation.cpp
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "GCObservation.h"
+
+#include <heap/HeapInlines.h>
+#include <heap/WeakInlines.h>
+
+namespace WebCore {
+
+GCObservation::GCObservation(JSC::JSObject* object)
+ : m_observedValue(object, nullptr, nullptr)
+{
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/testing/GCObservation.h b/Source/WebCore/testing/GCObservation.h
new file mode 100644
index 000000000..116c54fe3
--- /dev/null
+++ b/Source/WebCore/testing/GCObservation.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <heap/Weak.h>
+#include <runtime/JSCJSValueInlines.h>
+#include <runtime/JSObject.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class GCObservation final : public RefCounted<GCObservation> {
+public:
+ template<typename... Args> static RefPtr<GCObservation> create(Args&&... args)
+ {
+ return adoptRef(new GCObservation(std::forward<Args>(args)...));
+ }
+
+ bool wasCollected() const { return !m_observedValue; }
+
+private:
+ explicit GCObservation(JSC::JSObject*);
+
+ mutable JSC::Weak<JSC::JSObject> m_observedValue;
+};
+
+} // namespace WebCore
diff --git a/Source/WebCore/testing/GCObservation.idl b/Source/WebCore/testing/GCObservation.idl
new file mode 100644
index 000000000..b6cb37802
--- /dev/null
+++ b/Source/WebCore/testing/GCObservation.idl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+[
+ NoInterfaceObject,
+ ImplementationLacksVTable,
+ ExportMacro=WEBCORE_TESTSUPPORT_EXPORT,
+] interface GCObservation {
+ readonly attribute boolean wasCollected;
+};
diff --git a/Source/WebCore/testing/InternalSettings.cpp b/Source/WebCore/testing/InternalSettings.cpp
index dc7da1e92..fadddbf56 100644
--- a/Source/WebCore/testing/InternalSettings.cpp
+++ b/Source/WebCore/testing/InternalSettings.cpp
@@ -45,129 +45,160 @@
#include "ColorChooser.h"
#endif
-#define InternalSettingsGuardForSettingsReturn(returnValue) \
- if (!settings()) { \
- ec = INVALID_ACCESS_ERR; \
- return returnValue; \
- }
-
-#define InternalSettingsGuardForSettings() \
- if (!settings()) { \
- ec = INVALID_ACCESS_ERR; \
- return; \
- }
-
-#define InternalSettingsGuardForPage() \
- if (!page()) { \
- ec = INVALID_ACCESS_ERR; \
- return; \
- }
+#if USE(SOUP)
+#include "SoupNetworkSession.h"
+#endif
namespace WebCore {
InternalSettings::Backup::Backup(Settings& settings)
- : m_originalCSSExclusionsEnabled(RuntimeEnabledFeatures::sharedFeatures().cssExclusionsEnabled())
- , m_originalCSSShapesEnabled(RuntimeEnabledFeatures::sharedFeatures().cssShapesEnabled())
-#if ENABLE(SHADOW_DOM)
- , m_originalShadowDOMEnabled(RuntimeEnabledFeatures::sharedFeatures().shadowDOMEnabled())
- , m_originalAuthorShadowDOMForAnyElementEnabled(RuntimeEnabledFeatures::sharedFeatures().authorShadowDOMForAnyElementEnabled())
-#endif
- , m_originalEditingBehavior(settings.editingBehaviorType())
+ : m_originalEditingBehavior(settings.editingBehaviorType())
#if ENABLE(TEXT_AUTOSIZING)
, m_originalTextAutosizingEnabled(settings.textAutosizingEnabled())
, m_originalTextAutosizingWindowSizeOverride(settings.textAutosizingWindowSizeOverride())
- , m_originalTextAutosizingFontScaleFactor(settings.textAutosizingFontScaleFactor())
#endif
, m_originalMediaTypeOverride(settings.mediaTypeOverride())
, m_originalCanvasUsesAcceleratedDrawing(settings.canvasUsesAcceleratedDrawing())
, m_originalMockScrollbarsEnabled(settings.mockScrollbarsEnabled())
- , m_langAttributeAwareFormControlUIEnabled(RuntimeEnabledFeatures::sharedFeatures().langAttributeAwareFormControlUIEnabled())
, m_imagesEnabled(settings.areImagesEnabled())
- , m_minimumTimerInterval(settings.minDOMTimerInterval())
+ , m_preferMIMETypeForImages(settings.preferMIMETypeForImages())
+ , m_minimumTimerInterval(settings.minimumDOMTimerInterval())
#if ENABLE(VIDEO_TRACK)
, m_shouldDisplaySubtitles(settings.shouldDisplaySubtitles())
, m_shouldDisplayCaptions(settings.shouldDisplayCaptions())
, m_shouldDisplayTextDescriptions(settings.shouldDisplayTextDescriptions())
#endif
, m_defaultVideoPosterURL(settings.defaultVideoPosterURL())
+ , m_forcePendingWebGLPolicy(settings.isForcePendingWebGLPolicy())
, m_originalTimeWithoutMouseMovementBeforeHidingControls(settings.timeWithoutMouseMovementBeforeHidingControls())
, m_useLegacyBackgroundSizeShorthandBehavior(settings.useLegacyBackgroundSizeShorthandBehavior())
, m_autoscrollForDragAndDropEnabled(settings.autoscrollForDragAndDropEnabled())
- , m_pluginReplacementEnabled(RuntimeEnabledFeatures::sharedFeatures().pluginReplacementEnabled())
+ , m_quickTimePluginReplacementEnabled(settings.quickTimePluginReplacementEnabled())
+ , m_youTubeFlashPluginReplacementEnabled(settings.youTubeFlashPluginReplacementEnabled())
+ , m_shouldConvertPositionStyleOnCopy(settings.shouldConvertPositionStyleOnCopy())
+ , m_fontFallbackPrefersPictographs(settings.fontFallbackPrefersPictographs())
+ , m_webFontsAlwaysFallBack(settings.webFontsAlwaysFallBack())
+ , m_backgroundShouldExtendBeyondPage(settings.backgroundShouldExtendBeyondPage())
+ , m_storageBlockingPolicy(settings.storageBlockingPolicy())
+ , m_scrollingTreeIncludesFrames(settings.scrollingTreeIncludesFrames())
+#if ENABLE(TOUCH_EVENTS)
+ , m_touchEventEmulationEnabled(settings.isTouchEventEmulationEnabled())
+#endif
+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+ , m_allowsAirPlayForMediaPlayback(settings.allowsAirPlayForMediaPlayback())
+#endif
+ , m_allowsInlineMediaPlayback(settings.allowsInlineMediaPlayback())
+ , m_allowsInlineMediaPlaybackAfterFullscreen(settings.allowsInlineMediaPlaybackAfterFullscreen())
+ , m_inlineMediaPlaybackRequiresPlaysInlineAttribute(settings.inlineMediaPlaybackRequiresPlaysInlineAttribute())
+ , m_deferredCSSParserEnabled(settings.deferredCSSParserEnabled())
+ , m_inputEventsEnabled(settings.inputEventsEnabled())
+ , m_userInterfaceDirectionPolicy(settings.userInterfaceDirectionPolicy())
+ , m_systemLayoutDirection(settings.systemLayoutDirection())
+ , m_pdfImageCachingPolicy(settings.pdfImageCachingPolicy())
+ , m_forcedColorsAreInvertedAccessibilityValue(settings.forcedColorsAreInvertedAccessibilityValue())
+ , m_forcedDisplayIsMonochromeAccessibilityValue(settings.forcedDisplayIsMonochromeAccessibilityValue())
+ , m_forcedPrefersReducedMotionAccessibilityValue(settings.forcedPrefersReducedMotionAccessibilityValue())
+#if ENABLE(INDEXED_DATABASE_IN_WORKERS)
+ , m_indexedDBWorkersEnabled(RuntimeEnabledFeatures::sharedFeatures().indexedDBWorkersEnabled())
+#endif
+ , m_cssGridLayoutEnabled(RuntimeEnabledFeatures::sharedFeatures().isCSSGridLayoutEnabled())
+#if ENABLE(WEBGL2)
+ , m_webGL2Enabled(RuntimeEnabledFeatures::sharedFeatures().webGL2Enabled())
+#endif
{
}
void InternalSettings::Backup::restoreTo(Settings& settings)
{
- RuntimeEnabledFeatures::sharedFeatures().setCSSExclusionsEnabled(m_originalCSSExclusionsEnabled);
- RuntimeEnabledFeatures::sharedFeatures().setCSSShapesEnabled(m_originalCSSShapesEnabled);
-#if ENABLE(SHADOW_DOM)
- RuntimeEnabledFeatures::sharedFeatures().setShadowDOMEnabled(m_originalShadowDOMEnabled);
- RuntimeEnabledFeatures::sharedFeatures().setAuthorShadowDOMForAnyElementEnabled(m_originalAuthorShadowDOMForAnyElementEnabled);
-#endif
settings.setEditingBehaviorType(m_originalEditingBehavior);
- for (auto iter = m_standardFontFamilies.begin(); iter != m_standardFontFamilies.end(); ++iter)
- settings.setStandardFontFamily(iter->value, static_cast<UScriptCode>(iter->key));
+ for (const auto& standardFont : m_standardFontFamilies)
+ settings.setStandardFontFamily(standardFont.value, static_cast<UScriptCode>(standardFont.key));
m_standardFontFamilies.clear();
- for (auto iter = m_fixedFontFamilies.begin(); iter != m_fixedFontFamilies.end(); ++iter)
- settings.setFixedFontFamily(iter->value, static_cast<UScriptCode>(iter->key));
+ for (const auto& fixedFont : m_fixedFontFamilies)
+ settings.setFixedFontFamily(fixedFont.value, static_cast<UScriptCode>(fixedFont.key));
m_fixedFontFamilies.clear();
- for (auto iter = m_serifFontFamilies.begin(); iter != m_serifFontFamilies.end(); ++iter)
- settings.setSerifFontFamily(iter->value, static_cast<UScriptCode>(iter->key));
+ for (const auto& serifFont : m_serifFontFamilies)
+ settings.setSerifFontFamily(serifFont.value, static_cast<UScriptCode>(serifFont.key));
m_serifFontFamilies.clear();
- for (auto iter = m_sansSerifFontFamilies.begin(); iter != m_sansSerifFontFamilies.end(); ++iter)
- settings.setSansSerifFontFamily(iter->value, static_cast<UScriptCode>(iter->key));
+ for (const auto& sansSerifFont : m_sansSerifFontFamilies)
+ settings.setSansSerifFontFamily(sansSerifFont.value, static_cast<UScriptCode>(sansSerifFont.key));
m_sansSerifFontFamilies.clear();
- for (auto iter = m_cursiveFontFamilies.begin(); iter != m_cursiveFontFamilies.end(); ++iter)
- settings.setCursiveFontFamily(iter->value, static_cast<UScriptCode>(iter->key));
+ for (const auto& cursiveFont : m_cursiveFontFamilies)
+ settings.setCursiveFontFamily(cursiveFont.value, static_cast<UScriptCode>(cursiveFont.key));
m_cursiveFontFamilies.clear();
- for (auto iter = m_fantasyFontFamilies.begin(); iter != m_fantasyFontFamilies.end(); ++iter)
- settings.setFantasyFontFamily(iter->value, static_cast<UScriptCode>(iter->key));
+ for (const auto& fantasyFont : m_fantasyFontFamilies)
+ settings.setFantasyFontFamily(fantasyFont.value, static_cast<UScriptCode>(fantasyFont.key));
m_fantasyFontFamilies.clear();
- for (auto iter = m_pictographFontFamilies.begin(); iter != m_pictographFontFamilies.end(); ++iter)
- settings.setPictographFontFamily(iter->value, static_cast<UScriptCode>(iter->key));
+ for (const auto& pictographFont : m_pictographFontFamilies)
+ settings.setPictographFontFamily(pictographFont.value, static_cast<UScriptCode>(pictographFont.key));
m_pictographFontFamilies.clear();
#if ENABLE(TEXT_AUTOSIZING)
settings.setTextAutosizingEnabled(m_originalTextAutosizingEnabled);
settings.setTextAutosizingWindowSizeOverride(m_originalTextAutosizingWindowSizeOverride);
- settings.setTextAutosizingFontScaleFactor(m_originalTextAutosizingFontScaleFactor);
#endif
settings.setMediaTypeOverride(m_originalMediaTypeOverride);
settings.setCanvasUsesAcceleratedDrawing(m_originalCanvasUsesAcceleratedDrawing);
- settings.setMockScrollbarsEnabled(m_originalMockScrollbarsEnabled);
- RuntimeEnabledFeatures::sharedFeatures().setLangAttributeAwareFormControlUIEnabled(m_langAttributeAwareFormControlUIEnabled);
settings.setImagesEnabled(m_imagesEnabled);
- settings.setMinDOMTimerInterval(m_minimumTimerInterval);
+ settings.setPreferMIMETypeForImages(m_preferMIMETypeForImages);
+ settings.setMinimumDOMTimerInterval(m_minimumTimerInterval);
#if ENABLE(VIDEO_TRACK)
settings.setShouldDisplaySubtitles(m_shouldDisplaySubtitles);
settings.setShouldDisplayCaptions(m_shouldDisplayCaptions);
settings.setShouldDisplayTextDescriptions(m_shouldDisplayTextDescriptions);
#endif
settings.setDefaultVideoPosterURL(m_defaultVideoPosterURL);
+ settings.setForcePendingWebGLPolicy(m_forcePendingWebGLPolicy);
settings.setTimeWithoutMouseMovementBeforeHidingControls(m_originalTimeWithoutMouseMovementBeforeHidingControls);
settings.setUseLegacyBackgroundSizeShorthandBehavior(m_useLegacyBackgroundSizeShorthandBehavior);
settings.setAutoscrollForDragAndDropEnabled(m_autoscrollForDragAndDropEnabled);
- RuntimeEnabledFeatures::sharedFeatures().setPluginReplacementEnabled(m_pluginReplacementEnabled);
+ settings.setShouldConvertPositionStyleOnCopy(m_shouldConvertPositionStyleOnCopy);
+ settings.setFontFallbackPrefersPictographs(m_fontFallbackPrefersPictographs);
+ settings.setWebFontsAlwaysFallBack(m_webFontsAlwaysFallBack);
+ settings.setBackgroundShouldExtendBeyondPage(m_backgroundShouldExtendBeyondPage);
+ settings.setStorageBlockingPolicy(m_storageBlockingPolicy);
+ settings.setScrollingTreeIncludesFrames(m_scrollingTreeIncludesFrames);
+#if ENABLE(TOUCH_EVENTS)
+ settings.setTouchEventEmulationEnabled(m_touchEventEmulationEnabled);
+#endif
+ settings.setAllowsInlineMediaPlayback(m_allowsInlineMediaPlayback);
+ settings.setAllowsInlineMediaPlaybackAfterFullscreen(m_allowsInlineMediaPlaybackAfterFullscreen);
+ settings.setInlineMediaPlaybackRequiresPlaysInlineAttribute(m_inlineMediaPlaybackRequiresPlaysInlineAttribute);
+ settings.setQuickTimePluginReplacementEnabled(m_quickTimePluginReplacementEnabled);
+ settings.setYouTubeFlashPluginReplacementEnabled(m_youTubeFlashPluginReplacementEnabled);
+ settings.setDeferredCSSParserEnabled(m_deferredCSSParserEnabled);
+ settings.setInputEventsEnabled(m_inputEventsEnabled);
+ settings.setUserInterfaceDirectionPolicy(m_userInterfaceDirectionPolicy);
+ settings.setSystemLayoutDirection(m_systemLayoutDirection);
+ settings.setPdfImageCachingPolicy(m_pdfImageCachingPolicy);
+ settings.setForcedColorsAreInvertedAccessibilityValue(m_forcedColorsAreInvertedAccessibilityValue);
+ settings.setForcedDisplayIsMonochromeAccessibilityValue(m_forcedDisplayIsMonochromeAccessibilityValue);
+ settings.setForcedPrefersReducedMotionAccessibilityValue(m_forcedPrefersReducedMotionAccessibilityValue);
+ Settings::setAllowsAnySSLCertificate(false);
+
+#if ENABLE(INDEXED_DATABASE_IN_WORKERS)
+ RuntimeEnabledFeatures::sharedFeatures().setIndexedDBWorkersEnabled(m_indexedDBWorkersEnabled);
+#endif
+ RuntimeEnabledFeatures::sharedFeatures().setCSSGridLayoutEnabled(m_cssGridLayoutEnabled);
+#if ENABLE(WEBGL2)
+ RuntimeEnabledFeatures::sharedFeatures().setWebGL2Enabled(m_webGL2Enabled);
+#endif
}
-// We can't use RefCountedSupplement because that would try to make InternalSettings RefCounted
-// and InternalSettings is already RefCounted via its base class, InternalSettingsGenerated.
-// Instead, we manually make InternalSettings supplement Page.
class InternalSettingsWrapper : public Supplement<Page> {
public:
explicit InternalSettingsWrapper(Page* page)
: m_internalSettings(InternalSettings::create(page)) { }
virtual ~InternalSettingsWrapper() { m_internalSettings->hostDestroyed(); }
#if !ASSERT_DISABLED
- virtual bool isRefCountedWrapper() const override { return true; }
+ bool isRefCountedWrapper() const override { return true; }
#endif
InternalSettings* internalSettings() const { return m_internalSettings.get(); }
@@ -183,12 +214,13 @@ const char* InternalSettings::supplementName()
InternalSettings* InternalSettings::from(Page* page)
{
if (!Supplement<Page>::from(page, supplementName()))
- Supplement<Page>::provideTo(page, supplementName(), adoptPtr(new InternalSettingsWrapper(page)));
+ Supplement<Page>::provideTo(page, supplementName(), std::make_unique<InternalSettingsWrapper>(page));
return static_cast<InternalSettingsWrapper*>(Supplement<Page>::from(page, supplementName()))->internalSettings();
}
-InternalSettings::~InternalSettings()
+void InternalSettings::hostDestroyed()
{
+ m_page = nullptr;
}
InternalSettings::InternalSettings(Page* page)
@@ -196,335 +228,613 @@ InternalSettings::InternalSettings(Page* page)
, m_page(page)
, m_backup(page->settings())
{
+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+ setAllowsAirPlayForMediaPlayback(false);
+#endif
+#if ENABLE(MEDIA_STREAM)
+ setMediaCaptureRequiresSecureConnection(false);
+#endif
}
-void InternalSettings::resetToConsistentState()
-{
- page()->setPageScaleFactor(1, IntPoint(0, 0));
- page()->setCanStartMedia(true);
-
- m_backup.restoreTo(*settings());
- m_backup = Backup(*settings());
-
- InternalSettingsGenerated::resetToConsistentState();
-}
-
-Settings* InternalSettings::settings() const
+Ref<InternalSettings> InternalSettings::create(Page* page)
{
- if (!page())
- return 0;
- return &page()->settings();
+ return adoptRef(*new InternalSettings(page));
}
-void InternalSettings::setMockScrollbarsEnabled(bool enabled, ExceptionCode& ec)
+void InternalSettings::resetToConsistentState()
{
- InternalSettingsGuardForSettings();
- settings()->setMockScrollbarsEnabled(enabled);
-}
+ m_page->setPageScaleFactor(1, { 0, 0 });
+ m_page->mainFrame().setPageAndTextZoomFactors(1, 1);
+ m_page->setCanStartMedia(true);
-static bool urlIsWhitelistedForSetShadowDOMEnabled(const String& url)
-{
- // This check is just for preventing fuzzers from crashing because of unintended API calls.
- // You can list your test if needed.
- return notFound != url.find("fast/dom/shadow/content-shadow-unknown.html")
- || notFound != url.find("fast/dom/shadow/insertion-points-with-shadow-disabled.html");
-}
+ settings().setForcePendingWebGLPolicy(false);
+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+ settings().setAllowsAirPlayForMediaPlayback(false);
+#endif
+#if ENABLE(MEDIA_STREAM)
+ setMediaCaptureRequiresSecureConnection(false);
+#endif
-void InternalSettings::setShadowDOMEnabled(bool enabled, ExceptionCode& ec)
-{
- if (!urlIsWhitelistedForSetShadowDOMEnabled(page()->mainFrame().document()->url().string())) {
- ec = INVALID_ACCESS_ERR;
- return;
- }
+ m_backup.restoreTo(settings());
+ m_backup = Backup { settings() };
-#if ENABLE(SHADOW_DOM)
- RuntimeEnabledFeatures::sharedFeatures().setShadowDOMEnabled(enabled);
-#else
- // Even SHADOW_DOM is off, InternalSettings allows setShadowDOMEnabled(false) to
- // have broader test coverage. But it cannot be setShadowDOMEnabled(true).
- if (enabled)
- ec = INVALID_ACCESS_ERR;
-#endif
+ InternalSettingsGenerated::resetToConsistentState();
}
-void InternalSettings::setAuthorShadowDOMForAnyElementEnabled(bool isEnabled)
+Settings& InternalSettings::settings() const
{
-#if ENABLE(SHADOW_DOM)
- RuntimeEnabledFeatures::sharedFeatures().setAuthorShadowDOMForAnyElementEnabled(isEnabled);
-#else
- UNUSED_PARAM(isEnabled);
-#endif
+ ASSERT(m_page);
+ return m_page->settings();
}
-void InternalSettings::setTouchEventEmulationEnabled(bool enabled, ExceptionCode& ec)
+ExceptionOr<void> InternalSettings::setTouchEventEmulationEnabled(bool enabled)
{
+ if (!m_page)
+ return Exception { INVALID_ACCESS_ERR };
#if ENABLE(TOUCH_EVENTS)
- InternalSettingsGuardForSettings();
- settings()->setTouchEventEmulationEnabled(enabled);
+ settings().setTouchEventEmulationEnabled(enabled);
#else
UNUSED_PARAM(enabled);
- UNUSED_PARAM(ec);
#endif
+ return { };
}
-void InternalSettings::setStandardFontFamily(const String& family, const String& script, ExceptionCode& ec)
+ExceptionOr<void> InternalSettings::setStandardFontFamily(const String& family, const String& script)
{
- InternalSettingsGuardForSettings();
+ if (!m_page)
+ return Exception { INVALID_ACCESS_ERR };
UScriptCode code = scriptNameToCode(script);
if (code == USCRIPT_INVALID_CODE)
- return;
- m_backup.m_standardFontFamilies.add(code, settings()->standardFontFamily(code));
- settings()->setStandardFontFamily(family, code);
+ return { };
+ m_backup.m_standardFontFamilies.add(code, settings().standardFontFamily(code));
+ settings().setStandardFontFamily(family, code);
+ return { };
}
-void InternalSettings::setSerifFontFamily(const String& family, const String& script, ExceptionCode& ec)
+ExceptionOr<void> InternalSettings::setSerifFontFamily(const String& family, const String& script)
{
- InternalSettingsGuardForSettings();
+ if (!m_page)
+ return Exception { INVALID_ACCESS_ERR };
UScriptCode code = scriptNameToCode(script);
if (code == USCRIPT_INVALID_CODE)
- return;
- m_backup.m_serifFontFamilies.add(code, settings()->serifFontFamily(code));
- settings()->setSerifFontFamily(family, code);
+ return { };
+ m_backup.m_serifFontFamilies.add(code, settings().serifFontFamily(code));
+ settings().setSerifFontFamily(family, code);
+ return { };
}
-void InternalSettings::setSansSerifFontFamily(const String& family, const String& script, ExceptionCode& ec)
+ExceptionOr<void> InternalSettings::setSansSerifFontFamily(const String& family, const String& script)
{
- InternalSettingsGuardForSettings();
+ if (!m_page)
+ return Exception { INVALID_ACCESS_ERR };
UScriptCode code = scriptNameToCode(script);
if (code == USCRIPT_INVALID_CODE)
- return;
- m_backup.m_sansSerifFontFamilies.add(code, settings()->sansSerifFontFamily(code));
- settings()->setSansSerifFontFamily(family, code);
+ return { };
+ m_backup.m_sansSerifFontFamilies.add(code, settings().sansSerifFontFamily(code));
+ settings().setSansSerifFontFamily(family, code);
+ return { };
}
-void InternalSettings::setFixedFontFamily(const String& family, const String& script, ExceptionCode& ec)
+ExceptionOr<void> InternalSettings::setFixedFontFamily(const String& family, const String& script)
{
- InternalSettingsGuardForSettings();
+ if (!m_page)
+ return Exception { INVALID_ACCESS_ERR };
UScriptCode code = scriptNameToCode(script);
if (code == USCRIPT_INVALID_CODE)
- return;
- m_backup.m_fixedFontFamilies.add(code, settings()->fixedFontFamily(code));
- settings()->setFixedFontFamily(family, code);
+ return { };
+ m_backup.m_fixedFontFamilies.add(code, settings().fixedFontFamily(code));
+ settings().setFixedFontFamily(family, code);
+ return { };
}
-void InternalSettings::setCursiveFontFamily(const String& family, const String& script, ExceptionCode& ec)
+ExceptionOr<void> InternalSettings::setCursiveFontFamily(const String& family, const String& script)
{
- InternalSettingsGuardForSettings();
+ if (!m_page)
+ return Exception { INVALID_ACCESS_ERR };
UScriptCode code = scriptNameToCode(script);
if (code == USCRIPT_INVALID_CODE)
- return;
- m_backup.m_cursiveFontFamilies.add(code, settings()->cursiveFontFamily(code));
- settings()->setCursiveFontFamily(family, code);
+ return { };
+ m_backup.m_cursiveFontFamilies.add(code, settings().cursiveFontFamily(code));
+ settings().setCursiveFontFamily(family, code);
+ return { };
}
-void InternalSettings::setFantasyFontFamily(const String& family, const String& script, ExceptionCode& ec)
+ExceptionOr<void> InternalSettings::setFantasyFontFamily(const String& family, const String& script)
{
- InternalSettingsGuardForSettings();
+ if (!m_page)
+ return Exception { INVALID_ACCESS_ERR };
UScriptCode code = scriptNameToCode(script);
if (code == USCRIPT_INVALID_CODE)
- return;
- m_backup.m_fantasyFontFamilies.add(code, settings()->fantasyFontFamily(code));
- settings()->setFantasyFontFamily(family, code);
+ return { };
+ m_backup.m_fantasyFontFamilies.add(code, settings().fantasyFontFamily(code));
+ settings().setFantasyFontFamily(family, code);
+ return { };
}
-void InternalSettings::setPictographFontFamily(const String& family, const String& script, ExceptionCode& ec)
+ExceptionOr<void> InternalSettings::setPictographFontFamily(const String& family, const String& script)
{
- InternalSettingsGuardForSettings();
+ if (!m_page)
+ return Exception { INVALID_ACCESS_ERR };
UScriptCode code = scriptNameToCode(script);
if (code == USCRIPT_INVALID_CODE)
- return;
- m_backup.m_pictographFontFamilies.add(code, settings()->pictographFontFamily(code));
- settings()->setPictographFontFamily(family, code);
+ return { };
+ m_backup.m_pictographFontFamilies.add(code, settings().pictographFontFamily(code));
+ settings().setPictographFontFamily(family, code);
+ return { };
}
-void InternalSettings::setTextAutosizingEnabled(bool enabled, ExceptionCode& ec)
+ExceptionOr<void> InternalSettings::setTextAutosizingEnabled(bool enabled)
{
+ if (!m_page)
+ return Exception { INVALID_ACCESS_ERR };
#if ENABLE(TEXT_AUTOSIZING)
- InternalSettingsGuardForSettings();
- settings()->setTextAutosizingEnabled(enabled);
+ settings().setTextAutosizingEnabled(enabled);
#else
UNUSED_PARAM(enabled);
- UNUSED_PARAM(ec);
#endif
+ return { };
}
-void InternalSettings::setTextAutosizingWindowSizeOverride(int width, int height, ExceptionCode& ec)
+ExceptionOr<void> InternalSettings::setTextAutosizingWindowSizeOverride(int width, int height)
{
+ if (!m_page)
+ return Exception { INVALID_ACCESS_ERR };
#if ENABLE(TEXT_AUTOSIZING)
- InternalSettingsGuardForSettings();
- settings()->setTextAutosizingWindowSizeOverride(IntSize(width, height));
+ settings().setTextAutosizingWindowSizeOverride(IntSize(width, height));
#else
UNUSED_PARAM(width);
UNUSED_PARAM(height);
- UNUSED_PARAM(ec);
#endif
+ return { };
}
-void InternalSettings::setMediaTypeOverride(const String& mediaType, ExceptionCode& ec)
-{
- InternalSettingsGuardForSettings();
- settings()->setMediaTypeOverride(mediaType);
-}
-
-void InternalSettings::setTextAutosizingFontScaleFactor(float fontScaleFactor, ExceptionCode& ec)
+ExceptionOr<void> InternalSettings::setMediaTypeOverride(const String& mediaType)
{
-#if ENABLE(TEXT_AUTOSIZING)
- InternalSettingsGuardForSettings();
- settings()->setTextAutosizingFontScaleFactor(fontScaleFactor);
-#else
- UNUSED_PARAM(fontScaleFactor);
- UNUSED_PARAM(ec);
-#endif
+ if (!m_page)
+ return Exception { INVALID_ACCESS_ERR };
+ settings().setMediaTypeOverride(mediaType);
+ return { };
}
-void InternalSettings::setCSSExclusionsEnabled(bool enabled, ExceptionCode& ec)
+ExceptionOr<void> InternalSettings::setCanStartMedia(bool enabled)
{
- UNUSED_PARAM(ec);
- RuntimeEnabledFeatures::sharedFeatures().setCSSExclusionsEnabled(enabled);
+ if (!m_page)
+ return Exception { INVALID_ACCESS_ERR };
+ m_page->setCanStartMedia(enabled);
+ return { };
}
-void InternalSettings::setCSSShapesEnabled(bool enabled, ExceptionCode& ec)
+ExceptionOr<void> InternalSettings::setAllowsAirPlayForMediaPlayback(bool allows)
{
- UNUSED_PARAM(ec);
- RuntimeEnabledFeatures::sharedFeatures().setCSSShapesEnabled(enabled);
+ if (!m_page)
+ return Exception { INVALID_ACCESS_ERR };
+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+ settings().setAllowsAirPlayForMediaPlayback(allows);
+#else
+ UNUSED_PARAM(allows);
+#endif
+ return { };
}
-void InternalSettings::setCanStartMedia(bool enabled, ExceptionCode& ec)
+ExceptionOr<void> InternalSettings::setMediaCaptureRequiresSecureConnection(bool requires)
{
- InternalSettingsGuardForSettings();
- m_page->setCanStartMedia(enabled);
+ if (!m_page)
+ return Exception { INVALID_ACCESS_ERR };
+#if ENABLE(MEDIA_STREAM)
+ settings().setMediaCaptureRequiresSecureConnection(requires);
+#else
+ UNUSED_PARAM(requires);
+#endif
+ return { };
}
-void InternalSettings::setEditingBehavior(const String& editingBehavior, ExceptionCode& ec)
+ExceptionOr<void> InternalSettings::setEditingBehavior(const String& editingBehavior)
{
- InternalSettingsGuardForSettings();
- if (equalIgnoringCase(editingBehavior, "win"))
- settings()->setEditingBehaviorType(EditingWindowsBehavior);
- else if (equalIgnoringCase(editingBehavior, "mac"))
- settings()->setEditingBehaviorType(EditingMacBehavior);
- else if (equalIgnoringCase(editingBehavior, "unix"))
- settings()->setEditingBehaviorType(EditingUnixBehavior);
+ if (!m_page)
+ return Exception { INVALID_ACCESS_ERR };
+ if (equalLettersIgnoringASCIICase(editingBehavior, "win"))
+ settings().setEditingBehaviorType(EditingWindowsBehavior);
+ else if (equalLettersIgnoringASCIICase(editingBehavior, "mac"))
+ settings().setEditingBehaviorType(EditingMacBehavior);
+ else if (equalLettersIgnoringASCIICase(editingBehavior, "unix"))
+ settings().setEditingBehaviorType(EditingUnixBehavior);
+ else if (equalLettersIgnoringASCIICase(editingBehavior, "ios"))
+ settings().setEditingBehaviorType(EditingIOSBehavior);
else
- ec = SYNTAX_ERR;
+ return Exception { SYNTAX_ERR };
+ return { };
}
-void InternalSettings::setShouldDisplayTrackKind(const String& kind, bool enabled, ExceptionCode& ec)
+ExceptionOr<void> InternalSettings::setShouldDisplayTrackKind(const String& kind, bool enabled)
{
- InternalSettingsGuardForSettings();
-
+ if (!m_page)
+ return Exception { INVALID_ACCESS_ERR };
#if ENABLE(VIDEO_TRACK)
- if (!page())
- return;
- CaptionUserPreferences* captionPreferences = page()->group().captionPreferences();
-
- if (equalIgnoringCase(kind, "Subtitles"))
- captionPreferences->setUserPrefersSubtitles(enabled);
- else if (equalIgnoringCase(kind, "Captions"))
- captionPreferences->setUserPrefersCaptions(enabled);
- else if (equalIgnoringCase(kind, "TextDescriptions"))
- captionPreferences->setUserPrefersTextDescriptions(enabled);
+ auto& captionPreferences = m_page->group().captionPreferences();
+ if (equalLettersIgnoringASCIICase(kind, "subtitles"))
+ captionPreferences.setUserPrefersSubtitles(enabled);
+ else if (equalLettersIgnoringASCIICase(kind, "captions"))
+ captionPreferences.setUserPrefersCaptions(enabled);
+ else if (equalLettersIgnoringASCIICase(kind, "textdescriptions"))
+ captionPreferences.setUserPrefersTextDescriptions(enabled);
else
- ec = SYNTAX_ERR;
+ return Exception { SYNTAX_ERR };
#else
UNUSED_PARAM(kind);
UNUSED_PARAM(enabled);
#endif
+ return { };
}
-bool InternalSettings::shouldDisplayTrackKind(const String& kind, ExceptionCode& ec)
+ExceptionOr<bool> InternalSettings::shouldDisplayTrackKind(const String& kind)
{
- InternalSettingsGuardForSettingsReturn(false);
-
+ if (!m_page)
+ return Exception { INVALID_ACCESS_ERR };
#if ENABLE(VIDEO_TRACK)
- if (!page())
- return false;
- CaptionUserPreferences* captionPreferences = page()->group().captionPreferences();
-
- if (equalIgnoringCase(kind, "Subtitles"))
- return captionPreferences->userPrefersSubtitles();
- if (equalIgnoringCase(kind, "Captions"))
- return captionPreferences->userPrefersCaptions();
- if (equalIgnoringCase(kind, "TextDescriptions"))
- return captionPreferences->userPrefersTextDescriptions();
-
- ec = SYNTAX_ERR;
- return false;
+ auto& captionPreferences = m_page->group().captionPreferences();
+ if (equalLettersIgnoringASCIICase(kind, "subtitles"))
+ return captionPreferences.userPrefersSubtitles();
+ if (equalLettersIgnoringASCIICase(kind, "captions"))
+ return captionPreferences.userPrefersCaptions();
+ if (equalLettersIgnoringASCIICase(kind, "textdescriptions"))
+ return captionPreferences.userPrefersTextDescriptions();
+
+ return Exception { SYNTAX_ERR };
#else
UNUSED_PARAM(kind);
return false;
#endif
}
-void InternalSettings::setStorageBlockingPolicy(const String& mode, ExceptionCode& ec)
+ExceptionOr<void> InternalSettings::setStorageBlockingPolicy(const String& mode)
{
- InternalSettingsGuardForSettings();
-
+ if (!m_page)
+ return Exception { INVALID_ACCESS_ERR };
if (mode == "AllowAll")
- settings()->setStorageBlockingPolicy(SecurityOrigin::AllowAllStorage);
+ settings().setStorageBlockingPolicy(SecurityOrigin::AllowAllStorage);
else if (mode == "BlockThirdParty")
- settings()->setStorageBlockingPolicy(SecurityOrigin::BlockThirdPartyStorage);
+ settings().setStorageBlockingPolicy(SecurityOrigin::BlockThirdPartyStorage);
else if (mode == "BlockAll")
- settings()->setStorageBlockingPolicy(SecurityOrigin::BlockAllStorage);
+ settings().setStorageBlockingPolicy(SecurityOrigin::BlockAllStorage);
+ else
+ return Exception { SYNTAX_ERR };
+ return { };
+}
+
+ExceptionOr<void> InternalSettings::setPreferMIMETypeForImages(bool preferMIMETypeForImages)
+{
+ if (!m_page)
+ return Exception { INVALID_ACCESS_ERR };
+ settings().setPreferMIMETypeForImages(preferMIMETypeForImages);
+ return { };
+}
+
+ExceptionOr<void> InternalSettings::setImagesEnabled(bool enabled)
+{
+ if (!m_page)
+ return Exception { INVALID_ACCESS_ERR };
+ settings().setImagesEnabled(enabled);
+ return { };
+}
+
+ExceptionOr<void> InternalSettings::setPDFImageCachingPolicy(const String& policy)
+{
+ if (!m_page)
+ return Exception { INVALID_ACCESS_ERR };
+ if (equalLettersIgnoringASCIICase(policy, "disabled"))
+ settings().setPdfImageCachingPolicy(PDFImageCachingDisabled);
+ else if (equalLettersIgnoringASCIICase(policy, "belowmemorylimit"))
+ settings().setPdfImageCachingPolicy(PDFImageCachingBelowMemoryLimit);
+ else if (equalLettersIgnoringASCIICase(policy, "clipboundsonly"))
+ settings().setPdfImageCachingPolicy(PDFImageCachingClipBoundsOnly);
+ else if (equalLettersIgnoringASCIICase(policy, "enabled"))
+ settings().setPdfImageCachingPolicy(PDFImageCachingEnabled);
else
- ec = SYNTAX_ERR;
+ return Exception { SYNTAX_ERR };
+ return { };
+}
+
+ExceptionOr<void> InternalSettings::setMinimumTimerInterval(double intervalInSeconds)
+{
+ if (!m_page)
+ return Exception { INVALID_ACCESS_ERR };
+ settings().setMinimumDOMTimerInterval(std::chrono::milliseconds((std::chrono::milliseconds::rep)(intervalInSeconds * 1000)));
+ return { };
+}
+
+ExceptionOr<void> InternalSettings::setDefaultVideoPosterURL(const String& url)
+{
+ if (!m_page)
+ return Exception { INVALID_ACCESS_ERR };
+ settings().setDefaultVideoPosterURL(url);
+ return { };
+}
+
+ExceptionOr<void> InternalSettings::setForcePendingWebGLPolicy(bool forced)
+{
+ if (!m_page)
+ return Exception { INVALID_ACCESS_ERR };
+ settings().setForcePendingWebGLPolicy(forced);
+ return { };
+}
+
+ExceptionOr<void> InternalSettings::setTimeWithoutMouseMovementBeforeHidingControls(double time)
+{
+ if (!m_page)
+ return Exception { INVALID_ACCESS_ERR };
+ settings().setTimeWithoutMouseMovementBeforeHidingControls(time);
+ return { };
}
-void InternalSettings::setLangAttributeAwareFormControlUIEnabled(bool enabled)
+ExceptionOr<void> InternalSettings::setUseLegacyBackgroundSizeShorthandBehavior(bool enabled)
{
- RuntimeEnabledFeatures::sharedFeatures().setLangAttributeAwareFormControlUIEnabled(enabled);
+ if (!m_page)
+ return Exception { INVALID_ACCESS_ERR };
+ settings().setUseLegacyBackgroundSizeShorthandBehavior(enabled);
+ return { };
}
-void InternalSettings::setImagesEnabled(bool enabled, ExceptionCode& ec)
+ExceptionOr<void> InternalSettings::setAutoscrollForDragAndDropEnabled(bool enabled)
{
- InternalSettingsGuardForSettings();
- settings()->setImagesEnabled(enabled);
+ if (!m_page)
+ return Exception { INVALID_ACCESS_ERR };
+ settings().setAutoscrollForDragAndDropEnabled(enabled);
+ return { };
}
-void InternalSettings::setMinimumTimerInterval(double intervalInSeconds, ExceptionCode& ec)
+ExceptionOr<void> InternalSettings::setFontFallbackPrefersPictographs(bool preferPictographs)
{
- InternalSettingsGuardForSettings();
- settings()->setMinDOMTimerInterval(intervalInSeconds);
+ if (!m_page)
+ return Exception { INVALID_ACCESS_ERR };
+ settings().setFontFallbackPrefersPictographs(preferPictographs);
+ return { };
}
-void InternalSettings::setDefaultVideoPosterURL(const String& url, ExceptionCode& ec)
+ExceptionOr<void> InternalSettings::setWebFontsAlwaysFallBack(bool enable)
{
- InternalSettingsGuardForSettings();
- settings()->setDefaultVideoPosterURL(url);
+ if (!m_page)
+ return Exception { INVALID_ACCESS_ERR };
+ settings().setWebFontsAlwaysFallBack(enable);
+ return { };
}
-void InternalSettings::setTimeWithoutMouseMovementBeforeHidingControls(double time, ExceptionCode& ec)
+ExceptionOr<void> InternalSettings::setQuickTimePluginReplacementEnabled(bool enabled)
{
- InternalSettingsGuardForSettings();
- settings()->setTimeWithoutMouseMovementBeforeHidingControls(time);
+ if (!m_page)
+ return Exception { INVALID_ACCESS_ERR };
+ settings().setQuickTimePluginReplacementEnabled(enabled);
+ return { };
}
-void InternalSettings::setUseLegacyBackgroundSizeShorthandBehavior(bool enabled, ExceptionCode& ec)
+ExceptionOr<void> InternalSettings::setYouTubeFlashPluginReplacementEnabled(bool enabled)
{
- InternalSettingsGuardForSettings();
- settings()->setUseLegacyBackgroundSizeShorthandBehavior(enabled);
+ if (!m_page)
+ return Exception { INVALID_ACCESS_ERR };
+ settings().setYouTubeFlashPluginReplacementEnabled(enabled);
+ return { };
}
-void InternalSettings::setAutoscrollForDragAndDropEnabled(bool enabled, ExceptionCode& ec)
+ExceptionOr<void> InternalSettings::setBackgroundShouldExtendBeyondPage(bool hasExtendedBackground)
{
- InternalSettingsGuardForSettings();
- settings()->setAutoscrollForDragAndDropEnabled(enabled);
+ if (!m_page)
+ return Exception { INVALID_ACCESS_ERR };
+ settings().setBackgroundShouldExtendBeyondPage(hasExtendedBackground);
+ return { };
}
-void InternalSettings::setFontFallbackPrefersPictographs(bool preferPictographs, ExceptionCode& ec)
+ExceptionOr<void> InternalSettings::setShouldConvertPositionStyleOnCopy(bool convert)
{
- InternalSettingsGuardForSettings();
- settings()->setFontFallbackPrefersPictographs(preferPictographs);
+ if (!m_page)
+ return Exception { INVALID_ACCESS_ERR };
+ settings().setShouldConvertPositionStyleOnCopy(convert);
+ return { };
}
-void InternalSettings::setPluginReplacementEnabled(bool enabled)
+ExceptionOr<void> InternalSettings::setScrollingTreeIncludesFrames(bool enabled)
{
- RuntimeEnabledFeatures::sharedFeatures().setPluginReplacementEnabled(enabled);
+ if (!m_page)
+ return Exception { INVALID_ACCESS_ERR };
+ settings().setScrollingTreeIncludesFrames(enabled);
+ return { };
}
-void InternalSettings::setBackgroundShouldExtendBeyondPage(bool hasExtendedBackground, ExceptionCode& ec)
+ExceptionOr<void> InternalSettings::setAllowUnclampedScrollPosition(bool allowUnclamped)
{
- InternalSettingsGuardForSettings();
- settings()->setBackgroundShouldExtendBeyondPage(hasExtendedBackground);
+ if (!m_page || !m_page->mainFrame().view())
+ return Exception { INVALID_ACCESS_ERR };
+
+ m_page->mainFrame().view()->setAllowsUnclampedScrollPositionForTesting(allowUnclamped);
+ return { };
}
+ExceptionOr<void> InternalSettings::setAllowsInlineMediaPlayback(bool allows)
+{
+ if (!m_page)
+ return Exception { INVALID_ACCESS_ERR };
+ settings().setAllowsInlineMediaPlayback(allows);
+ return { };
+}
+
+ExceptionOr<void> InternalSettings::setAllowsInlineMediaPlaybackAfterFullscreen(bool allows)
+{
+ if (!m_page)
+ return Exception { INVALID_ACCESS_ERR };
+ settings().setAllowsInlineMediaPlaybackAfterFullscreen(allows);
+ return { };
+}
+
+ExceptionOr<void> InternalSettings::setInlineMediaPlaybackRequiresPlaysInlineAttribute(bool requires)
+{
+ if (!m_page)
+ return Exception { INVALID_ACCESS_ERR };
+ settings().setInlineMediaPlaybackRequiresPlaysInlineAttribute(requires);
+ return { };
+}
+
+void InternalSettings::setIndexedDBWorkersEnabled(bool enabled)
+{
+#if ENABLE(INDEXED_DATABASE_IN_WORKERS)
+ RuntimeEnabledFeatures::sharedFeatures().setIndexedDBWorkersEnabled(enabled);
+#else
+ UNUSED_PARAM(enabled);
+#endif
+}
+
+void InternalSettings::setCSSGridLayoutEnabled(bool enabled)
+{
+ RuntimeEnabledFeatures::sharedFeatures().setCSSGridLayoutEnabled(enabled);
+}
+
+void InternalSettings::setWebGL2Enabled(bool enabled)
+{
+#if ENABLE(WEBGL2)
+ RuntimeEnabledFeatures::sharedFeatures().setWebGL2Enabled(enabled);
+#else
+ UNUSED_PARAM(enabled);
+#endif
+}
+
+ExceptionOr<String> InternalSettings::userInterfaceDirectionPolicy()
+{
+ if (!m_page)
+ return Exception { INVALID_ACCESS_ERR };
+ switch (settings().userInterfaceDirectionPolicy()) {
+ case UserInterfaceDirectionPolicy::Content:
+ return String { ASCIILiteral { "Content" } };
+ case UserInterfaceDirectionPolicy::System:
+ return String { ASCIILiteral { "View" } };
+ }
+ ASSERT_NOT_REACHED();
+ return Exception { INVALID_ACCESS_ERR };
+}
+
+ExceptionOr<void> InternalSettings::setUserInterfaceDirectionPolicy(const String& policy)
+{
+ if (!m_page)
+ return Exception { INVALID_ACCESS_ERR };
+ if (equalLettersIgnoringASCIICase(policy, "content")) {
+ settings().setUserInterfaceDirectionPolicy(UserInterfaceDirectionPolicy::Content);
+ return { };
+ }
+ if (equalLettersIgnoringASCIICase(policy, "view")) {
+ settings().setUserInterfaceDirectionPolicy(UserInterfaceDirectionPolicy::System);
+ return { };
+ }
+ return Exception { INVALID_ACCESS_ERR };
+}
+
+ExceptionOr<String> InternalSettings::systemLayoutDirection()
+{
+ if (!m_page)
+ return Exception { INVALID_ACCESS_ERR };
+ switch (settings().systemLayoutDirection()) {
+ case LTR:
+ return String { ASCIILiteral { "LTR" } };
+ case RTL:
+ return String { ASCIILiteral { "RTL" } };
+ }
+ ASSERT_NOT_REACHED();
+ return Exception { INVALID_ACCESS_ERR };
+}
+
+ExceptionOr<void> InternalSettings::setSystemLayoutDirection(const String& direction)
+{
+ if (!m_page)
+ return Exception { INVALID_ACCESS_ERR };
+ if (equalLettersIgnoringASCIICase(direction, "ltr")) {
+ settings().setSystemLayoutDirection(LTR);
+ return { };
+ }
+ if (equalLettersIgnoringASCIICase(direction, "rtl")) {
+ settings().setSystemLayoutDirection(RTL);
+ return { };
+ }
+ return Exception { INVALID_ACCESS_ERR };
+}
+
+void InternalSettings::setAllowsAnySSLCertificate(bool allowsAnyCertificate)
+{
+ Settings::setAllowsAnySSLCertificate(allowsAnyCertificate);
+#if USE(SOUP)
+ SoupNetworkSession::setShouldIgnoreTLSErrors(allowsAnyCertificate);
+#endif
+}
+
+ExceptionOr<bool> InternalSettings::deferredCSSParserEnabled()
+{
+ if (!m_page)
+ return Exception { INVALID_ACCESS_ERR };
+ return settings().deferredCSSParserEnabled();
+}
+
+ExceptionOr<void> InternalSettings::setDeferredCSSParserEnabled(bool enabled)
+{
+ if (!m_page)
+ return Exception { INVALID_ACCESS_ERR };
+ settings().setDeferredCSSParserEnabled(enabled);
+ return { };
+}
+
+static InternalSettings::ForcedAccessibilityValue settingsToInternalSettingsValue(Settings::ForcedAccessibilityValue value)
+{
+ switch (value) {
+ case Settings::ForcedAccessibilityValue::System:
+ return InternalSettings::ForcedAccessibilityValue::System;
+ case Settings::ForcedAccessibilityValue::On:
+ return InternalSettings::ForcedAccessibilityValue::On;
+ case Settings::ForcedAccessibilityValue::Off:
+ return InternalSettings::ForcedAccessibilityValue::Off;
+ }
+
+ ASSERT_NOT_REACHED();
+ return InternalSettings::ForcedAccessibilityValue::Off;
+}
+
+static Settings::ForcedAccessibilityValue internalSettingsToSettingsValue(InternalSettings::ForcedAccessibilityValue value)
+{
+ switch (value) {
+ case InternalSettings::ForcedAccessibilityValue::System:
+ return Settings::ForcedAccessibilityValue::System;
+ case InternalSettings::ForcedAccessibilityValue::On:
+ return Settings::ForcedAccessibilityValue::On;
+ case InternalSettings::ForcedAccessibilityValue::Off:
+ return Settings::ForcedAccessibilityValue::Off;
+ }
+
+ ASSERT_NOT_REACHED();
+ return Settings::ForcedAccessibilityValue::Off;
+}
+
+InternalSettings::ForcedAccessibilityValue InternalSettings::forcedColorsAreInvertedAccessibilityValue() const
+{
+ return settingsToInternalSettingsValue(settings().forcedColorsAreInvertedAccessibilityValue());
+}
+
+void InternalSettings::setForcedColorsAreInvertedAccessibilityValue(InternalSettings::ForcedAccessibilityValue value)
+{
+ settings().setForcedColorsAreInvertedAccessibilityValue(internalSettingsToSettingsValue(value));
+}
+
+InternalSettings::ForcedAccessibilityValue InternalSettings::forcedDisplayIsMonochromeAccessibilityValue() const
+{
+ return settingsToInternalSettingsValue(settings().forcedDisplayIsMonochromeAccessibilityValue());
+}
+
+void InternalSettings::setForcedDisplayIsMonochromeAccessibilityValue(InternalSettings::ForcedAccessibilityValue value)
+{
+ settings().setForcedDisplayIsMonochromeAccessibilityValue(internalSettingsToSettingsValue(value));
+}
+
+InternalSettings::ForcedAccessibilityValue InternalSettings::forcedPrefersReducedMotionAccessibilityValue() const
+{
+ return settingsToInternalSettingsValue(settings().forcedPrefersReducedMotionAccessibilityValue());
+}
+
+void InternalSettings::setForcedPrefersReducedMotionAccessibilityValue(InternalSettings::ForcedAccessibilityValue value)
+{
+ settings().setForcedPrefersReducedMotionAccessibilityValue(internalSettingsToSettingsValue(value));
+}
+
+// If you add to this class, make sure that you update the Backup class for test reproducability!
+
}
diff --git a/Source/WebCore/testing/InternalSettings.h b/Source/WebCore/testing/InternalSettings.h
index 768d5752b..8df919fa0 100644
--- a/Source/WebCore/testing/InternalSettings.h
+++ b/Source/WebCore/testing/InternalSettings.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2012 Google Inc. All rights reserved.
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -24,40 +24,107 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef InternalSettings_h
-#define InternalSettings_h
+#pragma once
// FIXME (121927): This include should not be needed.
#include <wtf/text/AtomicStringHash.h>
#include "EditingBehaviorTypes.h"
+#include "ExceptionOr.h"
#include "FontGenericFamilies.h"
#include "IntSize.h"
#include "InternalSettingsGenerated.h"
-#include <wtf/PassRefPtr.h>
+#include "SecurityOrigin.h"
+#include "Settings.h"
+#include "WritingMode.h"
namespace WebCore {
-typedef int ExceptionCode;
-
-class Frame;
-class Document;
class Page;
class Settings;
class InternalSettings : public InternalSettingsGenerated {
public:
+ static Ref<InternalSettings> create(Page*);
+ static InternalSettings* from(Page*);
+ void hostDestroyed();
+ void resetToConsistentState();
+
+ ExceptionOr<void> setUsesOverlayScrollbars(bool);
+ ExceptionOr<void> setTouchEventEmulationEnabled(bool);
+ ExceptionOr<void> setStandardFontFamily(const String& family, const String& script);
+ ExceptionOr<void> setSerifFontFamily(const String& family, const String& script);
+ ExceptionOr<void> setSansSerifFontFamily(const String& family, const String& script);
+ ExceptionOr<void> setFixedFontFamily(const String& family, const String& script);
+ ExceptionOr<void> setCursiveFontFamily(const String& family, const String& script);
+ ExceptionOr<void> setFantasyFontFamily(const String& family, const String& script);
+ ExceptionOr<void> setPictographFontFamily(const String& family, const String& script);
+ ExceptionOr<void> setTextAutosizingEnabled(bool);
+ ExceptionOr<void> setTextAutosizingWindowSizeOverride(int width, int height);
+ ExceptionOr<void> setTextAutosizingFontScaleFactor(float);
+ ExceptionOr<void> setMediaTypeOverride(const String&);
+ ExceptionOr<void> setCanStartMedia(bool);
+ ExceptionOr<void> setAllowsAirPlayForMediaPlayback(bool);
+ ExceptionOr<void> setMediaCaptureRequiresSecureConnection(bool);
+
+ ExceptionOr<void> setEditingBehavior(const String&);
+ ExceptionOr<void> setPreferMIMETypeForImages(bool);
+ ExceptionOr<void> setPDFImageCachingPolicy(const String&);
+ ExceptionOr<void> setShouldDisplayTrackKind(const String& kind, bool enabled);
+ ExceptionOr<bool> shouldDisplayTrackKind(const String& kind);
+ ExceptionOr<void> setStorageBlockingPolicy(const String&);
+ ExceptionOr<void> setImagesEnabled(bool);
+ ExceptionOr<void> setMinimumTimerInterval(double intervalInSeconds);
+ ExceptionOr<void> setDefaultVideoPosterURL(const String&);
+ ExceptionOr<void> setForcePendingWebGLPolicy(bool);
+ ExceptionOr<void> setTimeWithoutMouseMovementBeforeHidingControls(double);
+ ExceptionOr<void> setUseLegacyBackgroundSizeShorthandBehavior(bool);
+ ExceptionOr<void> setAutoscrollForDragAndDropEnabled(bool);
+ ExceptionOr<void> setFontFallbackPrefersPictographs(bool);
+ ExceptionOr<void> setWebFontsAlwaysFallBack(bool);
+ ExceptionOr<void> setQuickTimePluginReplacementEnabled(bool);
+ ExceptionOr<void> setYouTubeFlashPluginReplacementEnabled(bool);
+ ExceptionOr<void> setBackgroundShouldExtendBeyondPage(bool);
+ ExceptionOr<void> setShouldConvertPositionStyleOnCopy(bool);
+ ExceptionOr<void> setScrollingTreeIncludesFrames(bool);
+ ExceptionOr<void> setAllowUnclampedScrollPosition(bool);
+ ExceptionOr<void> setAllowsInlineMediaPlayback(bool);
+ ExceptionOr<void> setAllowsInlineMediaPlaybackAfterFullscreen(bool);
+ ExceptionOr<void> setInlineMediaPlaybackRequiresPlaysInlineAttribute(bool);
+ ExceptionOr<String> userInterfaceDirectionPolicy();
+ ExceptionOr<void> setUserInterfaceDirectionPolicy(const String&);
+ ExceptionOr<String> systemLayoutDirection();
+ ExceptionOr<void> setSystemLayoutDirection(const String&);
+
+ static void setAllowsAnySSLCertificate(bool);
+
+ ExceptionOr<bool> deferredCSSParserEnabled();
+ ExceptionOr<void> setDeferredCSSParserEnabled(bool);
+
+ enum class ForcedAccessibilityValue { System, On, Off };
+ ForcedAccessibilityValue forcedColorsAreInvertedAccessibilityValue() const;
+ void setForcedColorsAreInvertedAccessibilityValue(ForcedAccessibilityValue);
+ ForcedAccessibilityValue forcedDisplayIsMonochromeAccessibilityValue() const;
+ void setForcedDisplayIsMonochromeAccessibilityValue(ForcedAccessibilityValue);
+ ForcedAccessibilityValue forcedPrefersReducedMotionAccessibilityValue() const;
+ void setForcedPrefersReducedMotionAccessibilityValue(ForcedAccessibilityValue);
+
+ // RuntimeEnabledFeatures.
+ static void setIndexedDBWorkersEnabled(bool);
+ static void setCSSGridLayoutEnabled(bool);
+ static void setWebGL2Enabled(bool);
+
+private:
+ explicit InternalSettings(Page*);
+
+ Settings& settings() const;
+ static const char* supplementName();
+
class Backup {
public:
explicit Backup(Settings&);
void restoreTo(Settings&);
- bool m_originalCSSExclusionsEnabled;
- bool m_originalCSSShapesEnabled;
-#if ENABLE(SHADOW_DOM)
- bool m_originalShadowDOMEnabled;
- bool m_originalAuthorShadowDOMForAnyElementEnabled;
-#endif
EditingBehaviorType m_originalEditingBehavior;
// Initially empty, only used if changed by a test.
@@ -72,83 +139,60 @@ public:
#if ENABLE(TEXT_AUTOSIZING)
bool m_originalTextAutosizingEnabled;
IntSize m_originalTextAutosizingWindowSizeOverride;
- float m_originalTextAutosizingFontScaleFactor;
#endif
+
String m_originalMediaTypeOverride;
bool m_originalCanvasUsesAcceleratedDrawing;
bool m_originalMockScrollbarsEnabled;
bool m_originalUsesOverlayScrollbars;
- bool m_langAttributeAwareFormControlUIEnabled;
bool m_imagesEnabled;
- double m_minimumTimerInterval;
+ bool m_preferMIMETypeForImages;
+ std::chrono::milliseconds m_minimumTimerInterval;
#if ENABLE(VIDEO_TRACK)
bool m_shouldDisplaySubtitles;
bool m_shouldDisplayCaptions;
bool m_shouldDisplayTextDescriptions;
#endif
String m_defaultVideoPosterURL;
+ bool m_forcePendingWebGLPolicy;
bool m_originalTimeWithoutMouseMovementBeforeHidingControls;
bool m_useLegacyBackgroundSizeShorthandBehavior;
bool m_autoscrollForDragAndDropEnabled;
- bool m_pluginReplacementEnabled;
+ bool m_quickTimePluginReplacementEnabled;
+ bool m_youTubeFlashPluginReplacementEnabled;
+ bool m_shouldConvertPositionStyleOnCopy;
+ bool m_fontFallbackPrefersPictographs;
+ bool m_webFontsAlwaysFallBack;
+ bool m_backgroundShouldExtendBeyondPage;
+ SecurityOrigin::StorageBlockingPolicy m_storageBlockingPolicy;
+ bool m_scrollingTreeIncludesFrames;
+#if ENABLE(TOUCH_EVENTS)
+ bool m_touchEventEmulationEnabled;
+#endif
+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+ bool m_allowsAirPlayForMediaPlayback;
+#endif
+ bool m_allowsInlineMediaPlayback;
+ bool m_allowsInlineMediaPlaybackAfterFullscreen;
+ bool m_inlineMediaPlaybackRequiresPlaysInlineAttribute;
+ bool m_deferredCSSParserEnabled;
+ bool m_inputEventsEnabled;
+
+ UserInterfaceDirectionPolicy m_userInterfaceDirectionPolicy;
+ TextDirection m_systemLayoutDirection;
+ PDFImageCachingPolicy m_pdfImageCachingPolicy;
+ Settings::ForcedAccessibilityValue m_forcedColorsAreInvertedAccessibilityValue;
+ Settings::ForcedAccessibilityValue m_forcedDisplayIsMonochromeAccessibilityValue;
+ Settings::ForcedAccessibilityValue m_forcedPrefersReducedMotionAccessibilityValue;
+
+ // Runtime enabled settings.
+ bool m_indexedDBWorkersEnabled;
+ bool m_cssGridLayoutEnabled;
+ bool m_webGL2Enabled;
};
- static PassRefPtr<InternalSettings> create(Page* page)
- {
- return adoptRef(new InternalSettings(page));
- }
- static InternalSettings* from(Page*);
- void hostDestroyed() { m_page = 0; }
-
- virtual ~InternalSettings();
- void resetToConsistentState();
-
- void setMockScrollbarsEnabled(bool enabled, ExceptionCode&);
- void setUsesOverlayScrollbars(bool enabled, ExceptionCode&);
- void setTouchEventEmulationEnabled(bool enabled, ExceptionCode&);
- void setShadowDOMEnabled(bool enabled, ExceptionCode&);
- void setAuthorShadowDOMForAnyElementEnabled(bool);
- void setStandardFontFamily(const String& family, const String& script, ExceptionCode&);
- void setSerifFontFamily(const String& family, const String& script, ExceptionCode&);
- void setSansSerifFontFamily(const String& family, const String& script, ExceptionCode&);
- void setFixedFontFamily(const String& family, const String& script, ExceptionCode&);
- void setCursiveFontFamily(const String& family, const String& script, ExceptionCode&);
- void setFantasyFontFamily(const String& family, const String& script, ExceptionCode&);
- void setPictographFontFamily(const String& family, const String& script, ExceptionCode&);
- void setTextAutosizingEnabled(bool enabled, ExceptionCode&);
- void setTextAutosizingWindowSizeOverride(int width, int height, ExceptionCode&);
- void setTextAutosizingFontScaleFactor(float fontScaleFactor, ExceptionCode&);
- void setMediaTypeOverride(const String& mediaType, ExceptionCode&);
- void setCSSExclusionsEnabled(bool enabled, ExceptionCode&);
- void setCSSShapesEnabled(bool enabled, ExceptionCode&);
- void setCanStartMedia(bool, ExceptionCode&);
- void setEditingBehavior(const String&, ExceptionCode&);
- void setShouldDisplayTrackKind(const String& kind, bool enabled, ExceptionCode&);
- bool shouldDisplayTrackKind(const String& kind, ExceptionCode&);
- void setStorageBlockingPolicy(const String&, ExceptionCode&);
- void setLangAttributeAwareFormControlUIEnabled(bool);
- void setImagesEnabled(bool enabled, ExceptionCode&);
- void setMinimumTimerInterval(double intervalInSeconds, ExceptionCode&);
- void setDefaultVideoPosterURL(const String& url, ExceptionCode&);
- void setTimeWithoutMouseMovementBeforeHidingControls(double time, ExceptionCode&);
- void setUseLegacyBackgroundSizeShorthandBehavior(bool enabled, ExceptionCode&);
- void setAutoscrollForDragAndDropEnabled(bool enabled, ExceptionCode&);
- void setFontFallbackPrefersPictographs(bool preferPictographs, ExceptionCode&);
- void setPluginReplacementEnabled(bool);
- void setBackgroundShouldExtendBeyondPage(bool hasExtendedBackground, ExceptionCode&);
-
-
-private:
- explicit InternalSettings(Page*);
-
- Settings* settings() const;
- Page* page() const { return m_page; }
- static const char* supplementName();
-
Page* m_page;
Backup m_backup;
};
} // namespace WebCore
-
-#endif
diff --git a/Source/WebCore/testing/InternalSettings.idl b/Source/WebCore/testing/InternalSettings.idl
index f9fbfb107..d4811b79e 100644
--- a/Source/WebCore/testing/InternalSettings.idl
+++ b/Source/WebCore/testing/InternalSettings.idl
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2012 Google Inc. All rights reserved.
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -23,41 +24,79 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+enum ForcedAccessibilityValue { "system", "on", "off" };
+
[
NoInterfaceObject,
- JSGenerateToJSObject
+ JSGenerateToJSObject,
+ ExportMacro=WEBCORE_TESTSUPPORT_EXPORT,
] interface InternalSettings : InternalSettingsGenerated {
- [RaisesException] void setMockScrollbarsEnabled(boolean enabled);
- [RaisesException] void setTouchEventEmulationEnabled(boolean enabled);
- [RaisesException] void setShadowDOMEnabled(boolean enabled);
- void setAuthorShadowDOMForAnyElementEnabled(boolean isEnabled);
- [RaisesException] void setStandardFontFamily(DOMString family, DOMString script);
- [RaisesException] void setSerifFontFamily(DOMString family, DOMString script);
- [RaisesException] void setSansSerifFontFamily(DOMString family, DOMString script);
- [RaisesException] void setFixedFontFamily(DOMString family, DOMString script);
- [RaisesException] void setCursiveFontFamily(DOMString family, DOMString script);
- [RaisesException] void setFantasyFontFamily(DOMString family, DOMString script);
- [RaisesException] void setPictographFontFamily(DOMString family, DOMString script);
- [RaisesException] void setTextAutosizingEnabled(boolean enabled);
- [RaisesException] void setTextAutosizingWindowSizeOverride(long width, long height);
- [RaisesException] void setTextAutosizingFontScaleFactor(float fontScaleFactor);
- [RaisesException] void setMediaTypeOverride(DOMString mediaTypeOverride);
- [RaisesException] void setCSSExclusionsEnabled(boolean enabled);
- [RaisesException] void setCSSShapesEnabled(boolean enabled);
- [RaisesException] void setCanStartMedia(boolean enabled);
- [RaisesException] void setEditingBehavior(DOMString behavior);
- void setLangAttributeAwareFormControlUIEnabled(boolean enabled);
-
- [Conditional=VIDEO_TRACK, RaisesException] void setShouldDisplayTrackKind(DOMString kind, boolean enabled);
- [Conditional=VIDEO_TRACK, RaisesException] boolean shouldDisplayTrackKind(DOMString trackKind);
- [RaisesException] void setStorageBlockingPolicy(DOMString policy);
- [RaisesException] void setImagesEnabled(boolean enabled);
- [RaisesException] void setMinimumTimerInterval(double intervalInSeconds);
- [RaisesException] void setDefaultVideoPosterURL(DOMString poster);
- [RaisesException] void setTimeWithoutMouseMovementBeforeHidingControls(double time);
- [RaisesException] void setUseLegacyBackgroundSizeShorthandBehavior(boolean enabled);
- [RaisesException] void setAutoscrollForDragAndDropEnabled(boolean enabled);
- [RaisesException] void setFontFallbackPrefersPictographs(boolean preferPictographs);
- void setPluginReplacementEnabled(boolean enabled);
- [RaisesException] void setBackgroundShouldExtendBeyondPage(boolean hasExtendedBackground);
+ [MayThrowException] void setTouchEventEmulationEnabled(boolean enabled);
+
+ // Fonts, text
+ [MayThrowException] void setStandardFontFamily(DOMString family, DOMString script);
+ [MayThrowException] void setSerifFontFamily(DOMString family, DOMString script);
+ [MayThrowException] void setSansSerifFontFamily(DOMString family, DOMString script);
+ [MayThrowException] void setFixedFontFamily(DOMString family, DOMString script);
+ [MayThrowException] void setCursiveFontFamily(DOMString family, DOMString script);
+ [MayThrowException] void setFantasyFontFamily(DOMString family, DOMString script);
+ [MayThrowException] void setPictographFontFamily(DOMString family, DOMString script);
+ [MayThrowException] void setFontFallbackPrefersPictographs(boolean preferPictographs);
+ [MayThrowException] void setWebFontsAlwaysFallBack(boolean enable);
+
+ [MayThrowException] void setTextAutosizingEnabled(boolean enabled);
+ [MayThrowException] void setTextAutosizingWindowSizeOverride(long width, long height);
+
+ // Media
+ [MayThrowException] void setCanStartMedia(boolean enabled);
+ [Conditional=VIDEO_TRACK, MayThrowException] void setShouldDisplayTrackKind(DOMString kind, boolean enabled);
+ [Conditional=VIDEO_TRACK, MayThrowException] boolean shouldDisplayTrackKind(DOMString trackKind);
+ [MayThrowException] void setDefaultVideoPosterURL(DOMString poster);
+ [MayThrowException] void setTimeWithoutMouseMovementBeforeHidingControls(unrestricted double time);
+ [MayThrowException] void setMediaTypeOverride(DOMString mediaTypeOverride);
+ void setAllowsAirPlayForMediaPlayback(boolean available);
+ [Conditional=MEDIA_STREAM, MayThrowException] void setMediaCaptureRequiresSecureConnection(boolean enable);
+
+ [MayThrowException] void setForcePendingWebGLPolicy(boolean forced);
+
+ [MayThrowException] void setQuickTimePluginReplacementEnabled(boolean enabled);
+ [MayThrowException] void setYouTubeFlashPluginReplacementEnabled(boolean enabled);
+
+ // Editing, forms
+ [MayThrowException] void setEditingBehavior(DOMString behavior);
+ [MayThrowException] void setShouldConvertPositionStyleOnCopy(boolean convertPosition);
+ [MayThrowException] void setPreferMIMETypeForImages(boolean preferMimeTypeForImage);
+
+ // Other switches
+ [MayThrowException] void setStorageBlockingPolicy(DOMString policy);
+ [MayThrowException] void setImagesEnabled(boolean enabled);
+ [MayThrowException] void setPDFImageCachingPolicy(DOMString policy);
+ [MayThrowException] void setUseLegacyBackgroundSizeShorthandBehavior(boolean enabled);
+ [MayThrowException] void setAutoscrollForDragAndDropEnabled(boolean enabled);
+ [MayThrowException] void setBackgroundShouldExtendBeyondPage(boolean hasExtendedBackground);
+ [MayThrowException] void setScrollingTreeIncludesFrames(boolean enabled);
+ [MayThrowException] void setAllowUnclampedScrollPosition(boolean allowUnclamped);
+
+ [MayThrowException] void setMinimumTimerInterval(unrestricted double intervalInSeconds);
+ [MayThrowException] void setAllowsInlineMediaPlayback(boolean allows);
+ [MayThrowException] void setAllowsInlineMediaPlaybackAfterFullscreen(boolean allows);
+ [MayThrowException] void setInlineMediaPlaybackRequiresPlaysInlineAttribute(boolean requires);
+
+ // RuntimeEnabledFeatures.
+ void setIndexedDBWorkersEnabled(boolean enabled);
+ void setCSSGridLayoutEnabled(boolean enabled);
+ void setWebGL2Enabled(boolean enabled);
+
+ [MayThrowException] DOMString userInterfaceDirectionPolicy();
+ [MayThrowException] void setUserInterfaceDirectionPolicy(DOMString policy);
+ [MayThrowException] DOMString systemLayoutDirection();
+ [MayThrowException] void setSystemLayoutDirection(DOMString direction);
+
+ [MayThrowException] boolean deferredCSSParserEnabled();
+ [MayThrowException] void setDeferredCSSParserEnabled(boolean enabled);
+
+ attribute ForcedAccessibilityValue forcedColorsAreInvertedAccessibilityValue;
+ attribute ForcedAccessibilityValue forcedDisplayIsMonochromeAccessibilityValue;
+ attribute ForcedAccessibilityValue forcedPrefersReducedMotionAccessibilityValue;
};
+
diff --git a/Source/WebCore/testing/Internals.cpp b/Source/WebCore/testing/Internals.cpp
index 83fa07530..6d26d556e 100644
--- a/Source/WebCore/testing/Internals.cpp
+++ b/Source/WebCore/testing/Internals.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2012 Google Inc. All rights reserved.
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2017 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,18 +28,26 @@
#include "Internals.h"
#include "AXObjectCache.h"
-#include "AnimationController.h"
+#include "ActiveDOMCallbackMicrotask.h"
#include "ApplicationCacheStorage.h"
+#include "Autofill.h"
#include "BackForwardController.h"
+#include "BitmapImage.h"
+#include "CSSAnimationController.h"
+#include "CSSKeyframesRule.h"
+#include "CSSMediaRule.h"
+#include "CSSStyleRule.h"
+#include "CSSSupportsRule.h"
+#include "CachedImage.h"
#include "CachedResourceLoader.h"
-#include "Chrome.h"
-#include "ChromeClient.h"
#include "ClientRect.h"
#include "ClientRectList.h"
-#include "ContentDistributor.h"
+#include "ComposedTreeIterator.h"
#include "Cursor.h"
+#include "DOMPath.h"
#include "DOMStringList.h"
#include "DOMWindow.h"
+#include "DisplayList.h"
#include "Document.h"
#include "DocumentMarker.h"
#include "DocumentMarkerController.h"
@@ -47,76 +55,102 @@
#include "Element.h"
#include "EventHandler.h"
#include "ExceptionCode.h"
+#include "ExtensionStyleSheets.h"
+#include "File.h"
+#include "FontCache.h"
#include "FormController.h"
#include "FrameLoader.h"
#include "FrameView.h"
+#include "GCObservation.h"
+#include "HTMLCanvasElement.h"
#include "HTMLIFrameElement.h"
+#include "HTMLImageElement.h"
#include "HTMLInputElement.h"
+#include "HTMLLinkElement.h"
#include "HTMLNames.h"
+#include "HTMLPlugInElement.h"
+#include "HTMLPreloadScanner.h"
#include "HTMLSelectElement.h"
#include "HTMLTextAreaElement.h"
+#include "HTMLVideoElement.h"
#include "HistoryController.h"
#include "HistoryItem.h"
+#include "HitTestResult.h"
+#include "IconController.h"
#include "InspectorClient.h"
-#include "InspectorConsoleAgent.h"
#include "InspectorController.h"
-#include "InspectorCounters.h"
-#include "InspectorForwarding.h"
#include "InspectorFrontendClientLocal.h"
-#include "InspectorInstrumentation.h"
#include "InspectorOverlay.h"
#include "InstrumentingAgents.h"
-#include "InternalSettings.h"
#include "IntRect.h"
+#include "InternalSettings.h"
#include "Language.h"
+#include "LibWebRTCProvider.h"
#include "MainFrame.h"
#include "MallocStatistics.h"
#include "MediaPlayer.h"
-#include "MediaSessionManager.h"
+#include "MediaProducer.h"
#include "MemoryCache.h"
#include "MemoryInfo.h"
+#include "MemoryPressureHandler.h"
+#include "MockLibWebRTCPeerConnection.h"
+#include "MockPageOverlay.h"
+#include "MockPageOverlayClient.h"
#include "Page.h"
+#include "PageCache.h"
+#include "PageOverlay.h"
+#include "PathUtilities.h"
+#include "PlatformMediaSessionManager.h"
#include "PrintContext.h"
#include "PseudoElement.h"
#include "Range.h"
#include "RenderEmbeddedObject.h"
+#include "RenderLayerBacking.h"
+#include "RenderLayerCompositor.h"
#include "RenderMenuList.h"
#include "RenderTreeAsText.h"
#include "RenderView.h"
-#include "RuntimeEnabledFeatures.h"
+#include "RenderedDocumentMarker.h"
+#include "ResourceLoadObserver.h"
+#include "SVGDocumentExtensions.h"
+#include "SVGPathStringBuilder.h"
#include "SchemeRegistry.h"
+#include "ScriptedAnimationController.h"
#include "ScrollingCoordinator.h"
+#include "ScrollingMomentumCalculator.h"
#include "SerializedScriptValue.h"
#include "Settings.h"
#include "ShadowRoot.h"
+#include "SourceBuffer.h"
#include "SpellChecker.h"
#include "StaticNodeList.h"
+#include "StyleRule.h"
+#include "StyleScope.h"
#include "StyleSheetContents.h"
#include "TextIterator.h"
#include "TreeScope.h"
#include "TypeConversions.h"
+#include "UserGestureIndicator.h"
+#include "UserMediaController.h"
#include "ViewportArguments.h"
+#include "WebCoreJSClientData.h"
#include "WorkerThread.h"
+#include "WritingDirection.h"
+#include "XMLHttpRequest.h"
#include <bytecode/CodeBlock.h>
#include <inspector/InspectorAgentBase.h>
+#include <inspector/InspectorFrontendChannel.h>
#include <inspector/InspectorValues.h>
+#include <runtime/JSCInlines.h>
#include <runtime/JSCJSValue.h>
#include <wtf/text/CString.h>
#include <wtf/text/StringBuffer.h>
+#include <wtf/text/StringBuilder.h>
#if ENABLE(INPUT_TYPE_COLOR)
#include "ColorChooser.h"
#endif
-#if ENABLE(BATTERY_STATUS)
-#include "BatteryController.h"
-#endif
-
-#if ENABLE(NETWORK_INFO)
-#include "NetworkInfo.h"
-#include "NetworkInfoController.h"
-#endif
-
#if ENABLE(PROXIMITY_EVENTS)
#include "DeviceProximityController.h"
#endif
@@ -125,9 +159,13 @@
#include <wtf/dtoa.h>
#endif
-#if ENABLE(ENCRYPTED_MEDIA_V2)
-#include "CDM.h"
-#include "MockCDM.h"
+#if ENABLE(LEGACY_ENCRYPTED_MEDIA)
+#include "LegacyCDM.h"
+#include "LegacyMockCDM.h"
+#endif
+
+#if ENABLE(ENCRYPTED_MEDIA)
+#include "MockCDMFactory.h"
#endif
#if ENABLE(VIDEO_TRACK)
@@ -151,19 +189,59 @@
#endif
#if ENABLE(MEDIA_STREAM)
-#include "MockMediaStreamCenter.h"
+#include "MockRealtimeMediaSourceCenter.h"
+#endif
+
+#if ENABLE(WEB_RTC)
+#include "MockMediaEndpoint.h"
#include "RTCPeerConnection.h"
-#include "RTCPeerConnectionHandlerMock.h"
#endif
#if ENABLE(MEDIA_SOURCE)
#include "MockMediaPlayerMediaSource.h"
#endif
+#if PLATFORM(MAC)
+#include "DictionaryLookup.h"
+#endif
+
+#if ENABLE(CONTENT_FILTERING)
+#include "MockContentFilterSettings.h"
+#endif
+
+#if ENABLE(WEB_AUDIO)
+#include "AudioContext.h"
+#endif
+
+#if ENABLE(MEDIA_SESSION)
+#include "MediaSession.h"
+#include "MediaSessionManager.h"
+#endif
+
+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+#include "MediaPlaybackTargetContext.h"
+#endif
+
+#if ENABLE(POINTER_LOCK)
+#include "PointerLockController.h"
+#endif
+
+#if USE(QUICK_LOOK)
+#include "MockQuickLookHandleClient.h"
+#include "QuickLook.h"
+#endif
+
+using JSC::CallData;
+using JSC::CallType;
using JSC::CodeBlock;
using JSC::FunctionExecutable;
+using JSC::Identifier;
using JSC::JSFunction;
+using JSC::JSGlobalObject;
+using JSC::JSObject;
using JSC::JSValue;
+using JSC::MarkedArgumentBuffer;
+using JSC::PropertySlot;
using JSC::ScriptExecutable;
using JSC::StackVisitor;
@@ -173,77 +251,111 @@ namespace WebCore {
using namespace HTMLNames;
-#if ENABLE(INSPECTOR)
-class InspectorFrontendClientDummy : public InspectorFrontendClientLocal {
+class InspectorStubFrontend final : public InspectorFrontendClientLocal, public FrontendChannel {
public:
- InspectorFrontendClientDummy(InspectorController*, Page*);
- virtual ~InspectorFrontendClientDummy() { }
- virtual void attachWindow(DockSide) override { }
- virtual void detachWindow() override { }
+ InspectorStubFrontend(Page& inspectedPage, RefPtr<DOMWindow>&& frontendWindow);
+ virtual ~InspectorStubFrontend();
- virtual String localizedStringsURL() override { return String(); }
-
- virtual void bringToFront() override { }
- virtual void closeWindow() override { }
+private:
+ void attachWindow(DockSide) final { }
+ void detachWindow() final { }
+ void closeWindow() final;
+ void bringToFront() final { }
+ String localizedStringsURL() final { return String(); }
+ void inspectedURLChanged(const String&) final { }
+ void setAttachedWindowHeight(unsigned) final { }
+ void setAttachedWindowWidth(unsigned) final { }
+
+ void sendMessageToFrontend(const String& message) final;
+ ConnectionType connectionType() const final { return ConnectionType::Local; }
+
+ Page* frontendPage() const
+ {
+ if (!m_frontendWindow || !m_frontendWindow->document())
+ return nullptr;
- virtual void inspectedURLChanged(const String&) override { }
+ return m_frontendWindow->document()->page();
+ }
-protected:
- virtual void setAttachedWindowHeight(unsigned) override { }
- virtual void setAttachedWindowWidth(unsigned) override { }
- virtual void setToolbarHeight(unsigned) override { }
+ RefPtr<DOMWindow> m_frontendWindow;
+ InspectorController& m_frontendController;
};
-InspectorFrontendClientDummy::InspectorFrontendClientDummy(InspectorController* controller, Page* page)
- : InspectorFrontendClientLocal(controller, page, adoptPtr(new InspectorFrontendClientLocal::Settings()))
+InspectorStubFrontend::InspectorStubFrontend(Page& inspectedPage, RefPtr<DOMWindow>&& frontendWindow)
+ : InspectorFrontendClientLocal(&inspectedPage.inspectorController(), frontendWindow->document()->page(), std::make_unique<InspectorFrontendClientLocal::Settings>())
+ , m_frontendWindow(frontendWindow.copyRef())
+ , m_frontendController(frontendPage()->inspectorController())
{
-}
-
-class InspectorFrontendChannelDummy : public InspectorFrontendChannel {
-public:
- explicit InspectorFrontendChannelDummy(Page*);
- virtual ~InspectorFrontendChannelDummy() { }
- virtual bool sendMessageToFrontend(const String& message) override;
+ ASSERT_ARG(frontendWindow, frontendWindow);
-private:
- Page* m_frontendPage;
-};
+ m_frontendController.setInspectorFrontendClient(this);
+ inspectedPage.inspectorController().connectFrontend(this);
+}
-InspectorFrontendChannelDummy::InspectorFrontendChannelDummy(Page* page)
- : m_frontendPage(page)
+InspectorStubFrontend::~InspectorStubFrontend()
{
+ closeWindow();
}
-bool InspectorFrontendChannelDummy::sendMessageToFrontend(const String& message)
+void InspectorStubFrontend::closeWindow()
{
- return InspectorClient::doDispatchMessageOnFrontendPage(m_frontendPage, message);
+ if (!m_frontendWindow)
+ return;
+
+ m_frontendController.setInspectorFrontendClient(nullptr);
+ inspectedPage()->inspectorController().disconnectFrontend(this);
+
+ m_frontendWindow->close();
+ m_frontendWindow = nullptr;
+}
+
+void InspectorStubFrontend::sendMessageToFrontend(const String& message)
+{
+ ASSERT_ARG(message, !message.isEmpty());
+
+ InspectorClient::doDispatchMessageOnFrontendPage(frontendPage(), message);
+}
+
+static bool markerTypeFrom(const String& markerType, DocumentMarker::MarkerType& result)
+{
+ if (equalLettersIgnoringASCIICase(markerType, "spelling"))
+ result = DocumentMarker::Spelling;
+ else if (equalLettersIgnoringASCIICase(markerType, "grammar"))
+ result = DocumentMarker::Grammar;
+ else if (equalLettersIgnoringASCIICase(markerType, "textmatch"))
+ result = DocumentMarker::TextMatch;
+ else if (equalLettersIgnoringASCIICase(markerType, "replacement"))
+ result = DocumentMarker::Replacement;
+ else if (equalLettersIgnoringASCIICase(markerType, "correctionindicator"))
+ result = DocumentMarker::CorrectionIndicator;
+ else if (equalLettersIgnoringASCIICase(markerType, "rejectedcorrection"))
+ result = DocumentMarker::RejectedCorrection;
+ else if (equalLettersIgnoringASCIICase(markerType, "autocorrected"))
+ result = DocumentMarker::Autocorrected;
+ else if (equalLettersIgnoringASCIICase(markerType, "spellcheckingexemption"))
+ result = DocumentMarker::SpellCheckingExemption;
+ else if (equalLettersIgnoringASCIICase(markerType, "deletedautocorrection"))
+ result = DocumentMarker::DeletedAutocorrection;
+ else if (equalLettersIgnoringASCIICase(markerType, "dictationalternatives"))
+ result = DocumentMarker::DictationAlternatives;
+#if ENABLE(TELEPHONE_NUMBER_DETECTION)
+ else if (equalLettersIgnoringASCIICase(markerType, "telephonenumber"))
+ result = DocumentMarker::TelephoneNumber;
+#endif
+ else
+ return false;
+
+ return true;
}
-#endif // ENABLE(INSPECTOR)
static bool markerTypesFrom(const String& markerType, DocumentMarker::MarkerTypes& result)
{
- if (markerType.isEmpty() || equalIgnoringCase(markerType, "all"))
+ DocumentMarker::MarkerType singularResult;
+
+ if (markerType.isEmpty() || equalLettersIgnoringASCIICase(markerType, "all"))
result = DocumentMarker::AllMarkers();
- else if (equalIgnoringCase(markerType, "Spelling"))
- result = DocumentMarker::Spelling;
- else if (equalIgnoringCase(markerType, "Grammar"))
- result = DocumentMarker::Grammar;
- else if (equalIgnoringCase(markerType, "TextMatch"))
- result = DocumentMarker::TextMatch;
- else if (equalIgnoringCase(markerType, "Replacement"))
- result = DocumentMarker::Replacement;
- else if (equalIgnoringCase(markerType, "CorrectionIndicator"))
- result = DocumentMarker::CorrectionIndicator;
- else if (equalIgnoringCase(markerType, "RejectedCorrection"))
- result = DocumentMarker::RejectedCorrection;
- else if (equalIgnoringCase(markerType, "Autocorrected"))
- result = DocumentMarker::Autocorrected;
- else if (equalIgnoringCase(markerType, "SpellCheckingExemption"))
- result = DocumentMarker::SpellCheckingExemption;
- else if (equalIgnoringCase(markerType, "DeletedAutocorrection"))
- result = DocumentMarker::DeletedAutocorrection;
- else if (equalIgnoringCase(markerType, "DictationAlternatives"))
- result = DocumentMarker::DictationAlternatives;
+ else if (markerTypeFrom(markerType, singularResult))
+ result = singularResult;
else
return false;
@@ -252,75 +364,123 @@ static bool markerTypesFrom(const String& markerType, DocumentMarker::MarkerType
const char* Internals::internalsId = "internals";
-PassRefPtr<Internals> Internals::create(Document* document)
+Ref<Internals> Internals::create(Document& document)
{
- return adoptRef(new Internals(document));
+ return adoptRef(*new Internals(document));
}
Internals::~Internals()
{
}
-void Internals::resetToConsistentState(Page* page)
+void Internals::resetToConsistentState(Page& page)
{
- ASSERT(page);
+ page.setPageScaleFactor(1, IntPoint(0, 0));
+ page.setPagination(Pagination());
+ page.setPaginationLineGridEnabled(false);
- page->setPageScaleFactor(1, IntPoint(0, 0));
- page->setPagination(Pagination());
-
-#if USE(ACCELERATED_COMPOSITING)
- FrameView* mainFrameView = page->mainFrame().view();
+ page.setDefersLoading(false);
+
+ page.mainFrame().setTextZoomFactor(1.0f);
+
+ FrameView* mainFrameView = page.mainFrame().view();
if (mainFrameView) {
mainFrameView->setHeaderHeight(0);
mainFrameView->setFooterHeight(0);
- }
+ page.setTopContentInset(0);
+ mainFrameView->setUseFixedLayout(false);
+ mainFrameView->setFixedLayoutSize(IntSize());
+#if USE(COORDINATED_GRAPHICS)
+ mainFrameView->setFixedVisibleContentRect(IntRect());
#endif
- TextRun::setAllowsRoundingHacks(false);
+ if (auto* backing = mainFrameView->tiledBacking())
+ backing->setTileSizeUpdateDelayDisabledForTesting(false);
+ }
+
+ WebCore::clearDefaultPortForProtocolMapForTesting();
WebCore::overrideUserPreferredLanguages(Vector<String>());
WebCore::Settings::setUsesOverlayScrollbars(false);
-#if ENABLE(INSPECTOR)
- page->inspectorController().setProfilerEnabled(false);
-#endif
-#if ENABLE(VIDEO_TRACK) && !PLATFORM(WIN)
- page->group().captionPreferences()->setCaptionsStyleSheetOverride(emptyString());
- page->group().captionPreferences()->setTestingMode(false);
-#endif
- if (!page->mainFrame().editor().isContinuousSpellCheckingEnabled())
- page->mainFrame().editor().toggleContinuousSpellChecking();
- if (page->mainFrame().editor().isOverwriteModeEnabled())
- page->mainFrame().editor().toggleOverwriteModeEnabled();
- cacheStorage().setDefaultOriginQuota(ApplicationCacheStorage::noQuota());
+ WebCore::Settings::setUsesMockScrollAnimator(false);
+#if ENABLE(VIDEO_TRACK)
+ page.group().captionPreferences().setTestingMode(true);
+ page.group().captionPreferences().setCaptionsStyleSheetOverride(emptyString());
+ page.group().captionPreferences().setTestingMode(false);
+#endif
+ if (!page.mainFrame().editor().isContinuousSpellCheckingEnabled())
+ page.mainFrame().editor().toggleContinuousSpellChecking();
+ if (page.mainFrame().editor().isOverwriteModeEnabled())
+ page.mainFrame().editor().toggleOverwriteModeEnabled();
+ page.mainFrame().loader().clearTestingOverrides();
+ page.applicationCacheStorage().setDefaultOriginQuota(ApplicationCacheStorage::noQuota());
#if ENABLE(VIDEO)
- MediaSessionManager::sharedManager().resetRestrictions();
+ PlatformMediaSessionManager::sharedManager().resetRestrictions();
+ PlatformMediaSessionManager::sharedManager().setWillIgnoreSystemInterruptions(true);
#endif
#if HAVE(ACCESSIBILITY)
+ AXObjectCache::setEnhancedUserInterfaceAccessibility(false);
AXObjectCache::disableAccessibility();
#endif
+
+ MockPageOverlayClient::singleton().uninstallAllOverlays();
+
+#if ENABLE(CONTENT_FILTERING)
+ MockContentFilterSettings::reset();
+#endif
+
+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+ page.setMockMediaPlaybackTargetPickerEnabled(true);
+ page.setMockMediaPlaybackTargetPickerState(emptyString(), MediaPlaybackTargetContext::Unknown);
+#endif
+
+ page.setShowAllPlugins(false);
+
+#if USE(QUICK_LOOK)
+ MockQuickLookHandleClient::singleton().setPassword("");
+ QuickLookHandle::setClientForTesting(nullptr);
+#endif
}
-Internals::Internals(Document* document)
- : ContextDestructionObserver(document)
+Internals::Internals(Document& document)
+ : ContextDestructionObserver(&document)
{
-#if ENABLE(VIDEO_TRACK) && !PLATFORM(WIN)
- if (document && document->page())
- document->page()->group().captionPreferences()->setTestingMode(true);
+#if ENABLE(VIDEO_TRACK)
+ if (document.page())
+ document.page()->group().captionPreferences().setTestingMode(true);
#endif
#if ENABLE(MEDIA_STREAM)
- MockMediaStreamCenter::registerMockMediaStreamCenter();
- enableMockRTCPeerConnectionHandler();
+ setMockMediaCaptureDevicesEnabled(true);
+ WebCore::Settings::setMediaCaptureRequiresSecureConnection(false);
+#endif
+
+#if ENABLE(WEB_RTC)
+ enableMockMediaEndpoint();
+ useMockRTCPeerConnectionFactory(String());
+#endif
+
+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+ if (document.page())
+ document.page()->setMockMediaPlaybackTargetPickerEnabled(true);
#endif
+
+ if (contextDocument() && contextDocument()->frame()) {
+ setAutomaticSpellingCorrectionEnabled(true);
+ setAutomaticQuoteSubstitutionEnabled(false);
+ setAutomaticDashSubstitutionEnabled(false);
+ setAutomaticLinkDetectionEnabled(false);
+ setAutomaticTextReplacementEnabled(true);
+ }
}
Document* Internals::contextDocument() const
{
- return toDocument(scriptExecutionContext());
+ return downcast<Document>(scriptExecutionContext());
}
Frame* Internals::frame() const
{
if (!contextDocument())
- return 0;
+ return nullptr;
return contextDocument()->frame();
}
@@ -328,10 +488,10 @@ InternalSettings* Internals::settings() const
{
Document* document = contextDocument();
if (!document)
- return 0;
+ return nullptr;
Page* page = document->page();
if (!page)
- return 0;
+ return nullptr;
return InternalSettings::from(page);
}
@@ -340,55 +500,257 @@ unsigned Internals::workerThreadCount() const
return WorkerThread::workerThreadCount();
}
-String Internals::address(Node* node)
+bool Internals::areSVGAnimationsPaused() const
{
- char buf[32];
- sprintf(buf, "%p", node);
+ auto* document = contextDocument();
+ if (!document)
+ return false;
- return String(buf);
+ if (!document->svgExtensions())
+ return false;
+
+ return document->accessSVGExtensions().areAnimationsPaused();
+}
+
+String Internals::address(Node& node)
+{
+ return String::format("%p", &node);
+}
+
+bool Internals::nodeNeedsStyleRecalc(Node& node)
+{
+ return node.needsStyleRecalc();
+}
+
+static String styleValidityToToString(Style::Validity validity)
+{
+ switch (validity) {
+ case Style::Validity::Valid:
+ return "NoStyleChange";
+ case Style::Validity::ElementInvalid:
+ return "InlineStyleChange";
+ case Style::Validity::SubtreeInvalid:
+ return "FullStyleChange";
+ case Style::Validity::SubtreeAndRenderersInvalid:
+ return "ReconstructRenderTree";
+ }
+ ASSERT_NOT_REACHED();
+ return "";
+}
+
+String Internals::styleChangeType(Node& node)
+{
+ node.document().styleScope().flushPendingUpdate();
+
+ return styleValidityToToString(node.styleValidity());
+}
+
+String Internals::description(JSC::JSValue value)
+{
+ return toString(value);
}
bool Internals::isPreloaded(const String& url)
{
Document* document = contextDocument();
- return document->cachedResourceLoader()->isPreloaded(url);
+ return document->cachedResourceLoader().isPreloaded(url);
}
bool Internals::isLoadingFromMemoryCache(const String& url)
{
- if (!contextDocument())
+ if (!contextDocument() || !contextDocument()->page())
return false;
- CachedResource* resource = memoryCache()->resourceForURL(contextDocument()->completeURL(url));
+
+ ResourceRequest request(contextDocument()->completeURL(url));
+ request.setDomainForCachePartition(contextDocument()->topOrigin().domainForCachePartition());
+
+ CachedResource* resource = MemoryCache::singleton().resourceForRequest(request, contextDocument()->page()->sessionID());
return resource && resource->status() == CachedResource::Cached;
}
+String Internals::xhrResponseSource(XMLHttpRequest& request)
+{
+ if (request.resourceResponse().isNull())
+ return "Null response";
+ switch (request.resourceResponse().source()) {
+ case ResourceResponse::Source::Unknown:
+ return "Unknown";
+ case ResourceResponse::Source::Network:
+ return "Network";
+ case ResourceResponse::Source::DiskCache:
+ return "Disk cache";
+ case ResourceResponse::Source::DiskCacheAfterValidation:
+ return "Disk cache after validation";
+ case ResourceResponse::Source::MemoryCache:
+ return "Memory cache";
+ case ResourceResponse::Source::MemoryCacheAfterValidation:
+ return "Memory cache after validation";
+ }
+ ASSERT_NOT_REACHED();
+ return "Error";
+}
-Node* Internals::treeScopeRootNode(Node* node, ExceptionCode& ec)
+bool Internals::isSharingStyleSheetContents(HTMLLinkElement& a, HTMLLinkElement& b)
{
- if (!node) {
- ec = INVALID_ACCESS_ERR;
- return 0;
+ if (!a.sheet() || !b.sheet())
+ return false;
+ return &a.sheet()->contents() == &b.sheet()->contents();
+}
+
+bool Internals::isStyleSheetLoadingSubresources(HTMLLinkElement& link)
+{
+ return link.sheet() && link.sheet()->contents().isLoadingSubresources();
+}
+
+static ResourceRequestCachePolicy toResourceRequestCachePolicy(Internals::CachePolicy policy)
+{
+ switch (policy) {
+ case Internals::CachePolicy::UseProtocolCachePolicy:
+ return UseProtocolCachePolicy;
+ case Internals::CachePolicy::ReloadIgnoringCacheData:
+ return ReloadIgnoringCacheData;
+ case Internals::CachePolicy::ReturnCacheDataElseLoad:
+ return ReturnCacheDataElseLoad;
+ case Internals::CachePolicy::ReturnCacheDataDontLoad:
+ return ReturnCacheDataDontLoad;
}
+ ASSERT_NOT_REACHED();
+ return UseProtocolCachePolicy;
+}
- return node->treeScope().rootNode();
+void Internals::setOverrideCachePolicy(CachePolicy policy)
+{
+ frame()->loader().setOverrideCachePolicyForTesting(toResourceRequestCachePolicy(policy));
}
-Node* Internals::parentTreeScope(Node* node, ExceptionCode& ec)
+ExceptionOr<void> Internals::setCanShowModalDialogOverride(bool allow)
{
- if (!node) {
- ec = INVALID_ACCESS_ERR;
- return 0;
+ if (!contextDocument() || !contextDocument()->domWindow())
+ return Exception { INVALID_ACCESS_ERR };
+
+ contextDocument()->domWindow()->setCanShowModalDialogOverride(allow);
+ return { };
+}
+
+static ResourceLoadPriority toResourceLoadPriority(Internals::ResourceLoadPriority priority)
+{
+ switch (priority) {
+ case Internals::ResourceLoadPriority::ResourceLoadPriorityVeryLow:
+ return ResourceLoadPriority::VeryLow;
+ case Internals::ResourceLoadPriority::ResourceLoadPriorityLow:
+ return ResourceLoadPriority::Low;
+ case Internals::ResourceLoadPriority::ResourceLoadPriorityMedium:
+ return ResourceLoadPriority::Medium;
+ case Internals::ResourceLoadPriority::ResourceLoadPriorityHigh:
+ return ResourceLoadPriority::High;
+ case Internals::ResourceLoadPriority::ResourceLoadPriorityVeryHigh:
+ return ResourceLoadPriority::VeryHigh;
}
- const TreeScope* parentTreeScope = node->treeScope().parentTreeScope();
- return parentTreeScope ? parentTreeScope->rootNode() : 0;
+ ASSERT_NOT_REACHED();
+ return ResourceLoadPriority::Low;
+}
+
+void Internals::setOverrideResourceLoadPriority(ResourceLoadPriority priority)
+{
+ frame()->loader().setOverrideResourceLoadPriorityForTesting(toResourceLoadPriority(priority));
+}
+
+void Internals::setStrictRawResourceValidationPolicyDisabled(bool disabled)
+{
+ frame()->loader().setStrictRawResourceValidationPolicyDisabledForTesting(disabled);
+}
+
+void Internals::clearMemoryCache()
+{
+ MemoryCache::singleton().evictResources();
+}
+
+void Internals::pruneMemoryCacheToSize(unsigned size)
+{
+ MemoryCache::singleton().pruneDeadResourcesToSize(size);
+ MemoryCache::singleton().pruneLiveResourcesToSize(size, true);
+}
+
+unsigned Internals::memoryCacheSize() const
+{
+ return MemoryCache::singleton().size();
}
-unsigned Internals::lastSpatialNavigationCandidateCount(ExceptionCode& ec) const
+unsigned Internals::imageFrameIndex(HTMLImageElement& element)
{
- if (!contextDocument() || !contextDocument()->page()) {
- ec = INVALID_ACCESS_ERR;
+ auto* cachedImage = element.cachedImage();
+ if (!cachedImage)
return 0;
- }
+
+ auto* image = cachedImage->image();
+ return is<BitmapImage>(image) ? downcast<BitmapImage>(*image).currentFrame() : 0;
+}
+
+void Internals::setImageFrameDecodingDuration(HTMLImageElement& element, float duration)
+{
+ auto* cachedImage = element.cachedImage();
+ if (!cachedImage)
+ return;
+
+ auto* image = cachedImage->image();
+ if (!is<BitmapImage>(image))
+ return;
+
+ downcast<BitmapImage>(*image).setFrameDecodingDurationForTesting(duration);
+}
+
+void Internals::resetImageAnimation(HTMLImageElement& element)
+{
+ auto* cachedImage = element.cachedImage();
+ if (!cachedImage)
+ return;
+
+ auto* image = cachedImage->image();
+ if (!is<BitmapImage>(image))
+ return;
+
+ image->resetAnimation();
+}
+
+void Internals::clearPageCache()
+{
+ PageCache::singleton().pruneToSizeNow(0, PruningReason::None);
+}
+
+unsigned Internals::pageCacheSize() const
+{
+ return PageCache::singleton().pageCount();
+}
+
+void Internals::disableTileSizeUpdateDelay()
+{
+ Document* document = contextDocument();
+ if (!document || !document->frame())
+ return;
+
+ auto* view = document->frame()->view();
+ if (!view)
+ return;
+
+ if (auto* backing = view->tiledBacking())
+ backing->setTileSizeUpdateDelayDisabledForTesting(true);
+}
+
+Node* Internals::treeScopeRootNode(Node& node)
+{
+ return &node.treeScope().rootNode();
+}
+
+Node* Internals::parentTreeScope(Node& node)
+{
+ const TreeScope* parentTreeScope = node.treeScope().parentTreeScope();
+ return parentTreeScope ? &parentTreeScope->rootNode() : nullptr;
+}
+
+ExceptionOr<unsigned> Internals::lastSpatialNavigationCandidateCount() const
+{
+ if (!contextDocument() || !contextDocument()->page())
+ return Exception { INVALID_ACCESS_ERR };
return contextDocument()->page()->lastSpatialNavigationCandidateCount();
}
@@ -398,432 +760,591 @@ unsigned Internals::numberOfActiveAnimations() const
return frame()->animation().numberOfActiveAnimations(frame()->document());
}
-bool Internals::animationsAreSuspended(ExceptionCode& ec) const
+ExceptionOr<bool> Internals::animationsAreSuspended() const
{
Document* document = contextDocument();
- if (!document || !document->frame()) {
- ec = INVALID_ACCESS_ERR;
- return false;
- }
+ if (!document || !document->frame())
+ return Exception { INVALID_ACCESS_ERR };
- return document->frame()->animation().isSuspended();
+ return document->frame()->animation().animationsAreSuspendedForDocument(document);
}
-void Internals::suspendAnimations(ExceptionCode& ec) const
+ExceptionOr<void> Internals::suspendAnimations() const
{
Document* document = contextDocument();
- if (!document || !document->frame()) {
- ec = INVALID_ACCESS_ERR;
- return;
+ if (!document || !document->frame())
+ return Exception { INVALID_ACCESS_ERR };
+
+ document->frame()->animation().suspendAnimationsForDocument(document);
+
+ for (Frame* frame = document->frame(); frame; frame = frame->tree().traverseNext()) {
+ if (Document* document = frame->document())
+ frame->animation().suspendAnimationsForDocument(document);
}
- document->frame()->animation().suspendAnimations();
+ return { };
}
-void Internals::resumeAnimations(ExceptionCode& ec) const
+ExceptionOr<void> Internals::resumeAnimations() const
{
Document* document = contextDocument();
- if (!document || !document->frame()) {
- ec = INVALID_ACCESS_ERR;
- return;
+ if (!document || !document->frame())
+ return Exception { INVALID_ACCESS_ERR };
+
+ document->frame()->animation().resumeAnimationsForDocument(document);
+
+ for (Frame* frame = document->frame(); frame; frame = frame->tree().traverseNext()) {
+ if (Document* document = frame->document())
+ frame->animation().resumeAnimationsForDocument(document);
}
- document->frame()->animation().resumeAnimations();
+ return { };
}
-bool Internals::pauseAnimationAtTimeOnElement(const String& animationName, double pauseTime, Element* element, ExceptionCode& ec)
+ExceptionOr<bool> Internals::pauseAnimationAtTimeOnElement(const String& animationName, double pauseTime, Element& element)
{
- if (!element || pauseTime < 0) {
- ec = INVALID_ACCESS_ERR;
- return false;
- }
- return frame()->animation().pauseAnimationAtTime(element->renderer(), AtomicString(animationName), pauseTime);
+ if (pauseTime < 0)
+ return Exception { INVALID_ACCESS_ERR };
+ return frame()->animation().pauseAnimationAtTime(element.renderer(), AtomicString(animationName), pauseTime);
}
-bool Internals::pauseAnimationAtTimeOnPseudoElement(const String& animationName, double pauseTime, Element* element, const String& pseudoId, ExceptionCode& ec)
+ExceptionOr<bool> Internals::pauseAnimationAtTimeOnPseudoElement(const String& animationName, double pauseTime, Element& element, const String& pseudoId)
{
- if (!element || pauseTime < 0) {
- ec = INVALID_ACCESS_ERR;
- return false;
- }
+ if (pauseTime < 0)
+ return Exception { INVALID_ACCESS_ERR };
- if (pseudoId != "before" && pseudoId != "after") {
- ec = INVALID_ACCESS_ERR;
- return false;
- }
+ if (pseudoId != "before" && pseudoId != "after")
+ return Exception { INVALID_ACCESS_ERR };
- PseudoElement* pseudoElement = pseudoId == "before" ? element->beforePseudoElement() : element->afterPseudoElement();
- if (!pseudoElement) {
- ec = INVALID_ACCESS_ERR;
- return false;
- }
+ PseudoElement* pseudoElement = pseudoId == "before" ? element.beforePseudoElement() : element.afterPseudoElement();
+ if (!pseudoElement)
+ return Exception { INVALID_ACCESS_ERR };
return frame()->animation().pauseAnimationAtTime(pseudoElement->renderer(), AtomicString(animationName), pauseTime);
}
-bool Internals::pauseTransitionAtTimeOnElement(const String& propertyName, double pauseTime, Element* element, ExceptionCode& ec)
+ExceptionOr<bool> Internals::pauseTransitionAtTimeOnElement(const String& propertyName, double pauseTime, Element& element)
{
- if (!element || pauseTime < 0) {
- ec = INVALID_ACCESS_ERR;
- return false;
- }
- return frame()->animation().pauseTransitionAtTime(element->renderer(), propertyName, pauseTime);
+ if (pauseTime < 0)
+ return Exception { INVALID_ACCESS_ERR };
+ return frame()->animation().pauseTransitionAtTime(element.renderer(), propertyName, pauseTime);
}
-bool Internals::pauseTransitionAtTimeOnPseudoElement(const String& property, double pauseTime, Element* element, const String& pseudoId, ExceptionCode& ec)
+ExceptionOr<bool> Internals::pauseTransitionAtTimeOnPseudoElement(const String& property, double pauseTime, Element& element, const String& pseudoId)
{
- if (!element || pauseTime < 0) {
- ec = INVALID_ACCESS_ERR;
- return false;
- }
+ if (pauseTime < 0)
+ return Exception { INVALID_ACCESS_ERR };
- if (pseudoId != "before" && pseudoId != "after") {
- ec = INVALID_ACCESS_ERR;
- return false;
- }
+ if (pseudoId != "before" && pseudoId != "after")
+ return Exception { INVALID_ACCESS_ERR };
- PseudoElement* pseudoElement = pseudoId == "before" ? element->beforePseudoElement() : element->afterPseudoElement();
- if (!pseudoElement) {
- ec = INVALID_ACCESS_ERR;
- return false;
- }
+ PseudoElement* pseudoElement = pseudoId == "before" ? element.beforePseudoElement() : element.afterPseudoElement();
+ if (!pseudoElement)
+ return Exception { INVALID_ACCESS_ERR };
return frame()->animation().pauseTransitionAtTime(pseudoElement->renderer(), property, pauseTime);
}
-// FIXME: Remove.
-bool Internals::attached(Node* node, ExceptionCode& ec)
+ExceptionOr<String> Internals::elementRenderTreeAsText(Element& element)
{
- if (!node) {
- ec = INVALID_ACCESS_ERR;
- return false;
- }
+ element.document().updateStyleIfNeeded();
- return true;
+ String representation = externalRepresentation(&element);
+ if (representation.isEmpty())
+ return Exception { INVALID_ACCESS_ERR };
+
+ return WTFMove(representation);
}
-String Internals::elementRenderTreeAsText(Element* element, ExceptionCode& ec)
+bool Internals::hasPausedImageAnimations(Element& element)
{
- if (!element) {
- ec = INVALID_ACCESS_ERR;
- return String();
- }
+ return element.renderer() && element.renderer()->hasPausedImageAnimations();
+}
- element->document().updateStyleIfNeeded();
+Ref<CSSComputedStyleDeclaration> Internals::computedStyleIncludingVisitedInfo(Element& element) const
+{
+ bool allowVisitedStyle = true;
+ return CSSComputedStyleDeclaration::create(element, allowVisitedStyle);
+}
- String representation = externalRepresentation(element);
- if (representation.isEmpty()) {
- ec = INVALID_ACCESS_ERR;
- return String();
- }
+Node* Internals::ensureUserAgentShadowRoot(Element& host)
+{
+ return &host.ensureUserAgentShadowRoot();
+}
- return representation;
+Node* Internals::shadowRoot(Element& host)
+{
+ return host.shadowRoot();
}
-PassRefPtr<CSSComputedStyleDeclaration> Internals::computedStyleIncludingVisitedInfo(Node* node, ExceptionCode& ec) const
+ExceptionOr<String> Internals::shadowRootType(const Node& root) const
{
- if (!node) {
- ec = INVALID_ACCESS_ERR;
- return 0;
+ if (!is<ShadowRoot>(root))
+ return Exception { INVALID_ACCESS_ERR };
+
+ switch (downcast<ShadowRoot>(root).mode()) {
+ case ShadowRootMode::UserAgent:
+ return String("UserAgentShadowRoot");
+ case ShadowRootMode::Closed:
+ return String("ClosedShadowRoot");
+ case ShadowRootMode::Open:
+ return String("OpenShadowRoot");
+ default:
+ ASSERT_NOT_REACHED();
+ return String("Unknown");
}
+}
- bool allowVisitedStyle = true;
- return CSSComputedStyleDeclaration::create(node, allowVisitedStyle);
+String Internals::shadowPseudoId(Element& element)
+{
+ return element.shadowPseudoId().string();
}
-Internals::ShadowRootIfShadowDOMEnabledOrNode* Internals::ensureShadowRoot(Element* host, ExceptionCode& ec)
+void Internals::setShadowPseudoId(Element& element, const String& id)
{
- if (!host) {
- ec = INVALID_ACCESS_ERR;
- return 0;
+ return element.setPseudo(id);
+}
+
+static unsigned deferredStyleRulesCountForList(const Vector<RefPtr<StyleRuleBase>>& childRules)
+{
+ unsigned count = 0;
+ for (auto rule : childRules) {
+ if (is<StyleRule>(rule.get())) {
+ auto* cssRule = downcast<StyleRule>(rule.get());
+ if (!cssRule->propertiesWithoutDeferredParsing())
+ count++;
+ continue;
+ }
+
+ StyleRuleGroup* groupRule = nullptr;
+ if (is<StyleRuleMedia>(rule.get()))
+ groupRule = downcast<StyleRuleMedia>(rule.get());
+ else if (is<StyleRuleSupports>(rule.get()))
+ groupRule = downcast<StyleRuleSupports>(rule.get());
+ if (!groupRule)
+ continue;
+
+ auto* groupChildRules = groupRule->childRulesWithoutDeferredParsing();
+ if (!groupChildRules)
+ continue;
+
+ count += deferredStyleRulesCountForList(*groupChildRules);
}
- if (ShadowRoot* shadowRoot = host->shadowRoot())
- return shadowRoot;
+ return count;
+}
- return host->createShadowRoot(ec).get();
+unsigned Internals::deferredStyleRulesCount(StyleSheet& styleSheet)
+{
+ return deferredStyleRulesCountForList(downcast<CSSStyleSheet>(styleSheet).contents().childRules());
}
-Internals::ShadowRootIfShadowDOMEnabledOrNode* Internals::createShadowRoot(Element* host, ExceptionCode& ec)
+static unsigned deferredGroupRulesCountForList(const Vector<RefPtr<StyleRuleBase>>& childRules)
{
- if (!host) {
- ec = INVALID_ACCESS_ERR;
- return 0;
+ unsigned count = 0;
+ for (auto rule : childRules) {
+ StyleRuleGroup* groupRule = nullptr;
+ if (is<StyleRuleMedia>(rule.get()))
+ groupRule = downcast<StyleRuleMedia>(rule.get());
+ else if (is<StyleRuleSupports>(rule.get()))
+ groupRule = downcast<StyleRuleSupports>(rule.get());
+ if (!groupRule)
+ continue;
+
+ auto* groupChildRules = groupRule->childRulesWithoutDeferredParsing();
+ if (!groupChildRules)
+ count++;
+ else
+ count += deferredGroupRulesCountForList(*groupChildRules);
}
- return host->createShadowRoot(ec).get();
+ return count;
}
-Internals::ShadowRootIfShadowDOMEnabledOrNode* Internals::shadowRoot(Element* host, ExceptionCode& ec)
+unsigned Internals::deferredGroupRulesCount(StyleSheet& styleSheet)
{
- if (!host) {
- ec = INVALID_ACCESS_ERR;
- return 0;
- }
- return host->shadowRoot();
+ return deferredGroupRulesCountForList(downcast<CSSStyleSheet>(styleSheet).contents().childRules());
}
-String Internals::shadowRootType(const Node* root, ExceptionCode& ec) const
+static unsigned deferredKeyframesRulesCountForList(const Vector<RefPtr<StyleRuleBase>>& childRules)
{
- if (!root || !root->isShadowRoot()) {
- ec = INVALID_ACCESS_ERR;
- return String();
+ unsigned count = 0;
+ for (auto rule : childRules) {
+ if (is<StyleRuleKeyframes>(rule.get())) {
+ auto* cssRule = downcast<StyleRuleKeyframes>(rule.get());
+ if (!cssRule->keyframesWithoutDeferredParsing())
+ count++;
+ continue;
+ }
+
+ StyleRuleGroup* groupRule = nullptr;
+ if (is<StyleRuleMedia>(rule.get()))
+ groupRule = downcast<StyleRuleMedia>(rule.get());
+ else if (is<StyleRuleSupports>(rule.get()))
+ groupRule = downcast<StyleRuleSupports>(rule.get());
+ if (!groupRule)
+ continue;
+
+ auto* groupChildRules = groupRule->childRulesWithoutDeferredParsing();
+ if (!groupChildRules)
+ continue;
+
+ count += deferredKeyframesRulesCountForList(*groupChildRules);
}
+
+ return count;
+}
- switch (toShadowRoot(root)->type()) {
- case ShadowRoot::UserAgentShadowRoot:
- return String("UserAgentShadowRoot");
- case ShadowRoot::AuthorShadowRoot:
- return String("AuthorShadowRoot");
- default:
- ASSERT_NOT_REACHED();
- return String("Unknown");
- }
+unsigned Internals::deferredKeyframesRulesCount(StyleSheet& styleSheet)
+{
+ StyleSheetContents& contents = downcast<CSSStyleSheet>(styleSheet).contents();
+ return deferredKeyframesRulesCountForList(contents.childRules());
}
-Element* Internals::includerFor(Node*, ExceptionCode& ec)
+ExceptionOr<bool> Internals::isTimerThrottled(int timeoutId)
{
- ec = INVALID_ACCESS_ERR;
- return 0;
+ DOMTimer* timer = scriptExecutionContext()->findTimeout(timeoutId);
+ if (!timer)
+ return Exception { NOT_FOUND_ERR };
+ return timer->m_throttleState == DOMTimer::ShouldThrottle;
}
-String Internals::shadowPseudoId(Element* element, ExceptionCode& ec)
+bool Internals::isRequestAnimationFrameThrottled() const
{
- if (!element) {
- ec = INVALID_ACCESS_ERR;
- return String();
- }
+ auto* scriptedAnimationController = contextDocument()->scriptedAnimationController();
+ if (!scriptedAnimationController)
+ return false;
+ return scriptedAnimationController->isThrottled();
+}
- return element->shadowPseudoId().string();
+bool Internals::areTimersThrottled() const
+{
+ return contextDocument()->isTimerThrottlingEnabled();
}
-void Internals::setShadowPseudoId(Element* element, const String& id, ExceptionCode& ec)
+void Internals::setEventThrottlingBehaviorOverride(std::optional<EventThrottlingBehavior> value)
{
- if (!element) {
- ec = INVALID_ACCESS_ERR;
+ Document* document = contextDocument();
+ if (!document || !document->page())
+ return;
+
+ if (!value) {
+ document->page()->setEventThrottlingBehaviorOverride(std::nullopt);
return;
}
- return element->setPseudo(id);
+ switch (value.value()) {
+ case Internals::EventThrottlingBehavior::Responsive:
+ document->page()->setEventThrottlingBehaviorOverride(WebCore::EventThrottlingBehavior::Responsive);
+ break;
+ case Internals::EventThrottlingBehavior::Unresponsive:
+ document->page()->setEventThrottlingBehaviorOverride(WebCore::EventThrottlingBehavior::Unresponsive);
+ break;
+ }
+}
+
+std::optional<Internals::EventThrottlingBehavior> Internals::eventThrottlingBehaviorOverride() const
+{
+ Document* document = contextDocument();
+ if (!document || !document->page())
+ return std::nullopt;
+
+ auto behavior = document->page()->eventThrottlingBehaviorOverride();
+ if (!behavior)
+ return std::nullopt;
+
+ switch (behavior.value()) {
+ case WebCore::EventThrottlingBehavior::Responsive:
+ return Internals::EventThrottlingBehavior::Responsive;
+ case WebCore::EventThrottlingBehavior::Unresponsive:
+ return Internals::EventThrottlingBehavior::Unresponsive;
+ }
+
+ return std::nullopt;
}
-String Internals::visiblePlaceholder(Element* element)
+String Internals::visiblePlaceholder(Element& element)
{
- if (element && isHTMLTextFormControlElement(*element)) {
- if (toHTMLTextFormControlElement(*element).placeholderShouldBeVisible())
- return toHTMLTextFormControlElement(*element).placeholderElement()->textContent();
+ if (is<HTMLTextFormControlElement>(element)) {
+ const HTMLTextFormControlElement& textFormControlElement = downcast<HTMLTextFormControlElement>(element);
+ if (!textFormControlElement.isPlaceholderVisible())
+ return String();
+ if (HTMLElement* placeholderElement = textFormControlElement.placeholderElement())
+ return placeholderElement->textContent();
}
return String();
}
-#if ENABLE(INPUT_TYPE_COLOR)
-void Internals::selectColorInColorChooser(Element* element, const String& colorValue)
+void Internals::selectColorInColorChooser(HTMLInputElement& element, const String& colorValue)
{
- if (!isHTMLInputElement(element))
- return;
- HTMLInputElement* inputElement = element->toInputElement();
- if (!inputElement)
- return;
- inputElement->selectColorInColorChooser(Color(colorValue));
+ element.selectColor(Color(colorValue));
}
-#endif
-Vector<String> Internals::formControlStateOfPreviousHistoryItem(ExceptionCode& ec)
+ExceptionOr<Vector<String>> Internals::formControlStateOfPreviousHistoryItem()
{
HistoryItem* mainItem = frame()->loader().history().previousItem();
- if (!mainItem) {
- ec = INVALID_ACCESS_ERR;
- return Vector<String>();
- }
+ if (!mainItem)
+ return Exception { INVALID_ACCESS_ERR };
String uniqueName = frame()->tree().uniqueName();
- if (mainItem->target() != uniqueName && !mainItem->childItemWithTarget(uniqueName)) {
- ec = INVALID_ACCESS_ERR;
- return Vector<String>();
- }
- return mainItem->target() == uniqueName ? mainItem->documentState() : mainItem->childItemWithTarget(uniqueName)->documentState();
+ if (mainItem->target() != uniqueName && !mainItem->childItemWithTarget(uniqueName))
+ return Exception { INVALID_ACCESS_ERR };
+ return Vector<String> { mainItem->target() == uniqueName ? mainItem->documentState() : mainItem->childItemWithTarget(uniqueName)->documentState() };
}
-void Internals::setFormControlStateOfPreviousHistoryItem(const Vector<String>& state, ExceptionCode& ec)
+ExceptionOr<void> Internals::setFormControlStateOfPreviousHistoryItem(const Vector<String>& state)
{
HistoryItem* mainItem = frame()->loader().history().previousItem();
- if (!mainItem) {
- ec = INVALID_ACCESS_ERR;
- return;
- }
+ if (!mainItem)
+ return Exception { INVALID_ACCESS_ERR };
String uniqueName = frame()->tree().uniqueName();
if (mainItem->target() == uniqueName)
mainItem->setDocumentState(state);
else if (HistoryItem* subItem = mainItem->childItemWithTarget(uniqueName))
subItem->setDocumentState(state);
else
- ec = INVALID_ACCESS_ERR;
+ return Exception { INVALID_ACCESS_ERR };
+ return { };
}
#if ENABLE(SPEECH_SYNTHESIS)
+
void Internals::enableMockSpeechSynthesizer()
{
Document* document = contextDocument();
if (!document || !document->domWindow())
return;
- SpeechSynthesis* synthesis = DOMWindowSpeechSynthesis::speechSynthesis(document->domWindow());
+ SpeechSynthesis* synthesis = DOMWindowSpeechSynthesis::speechSynthesis(*document->domWindow());
if (!synthesis)
return;
- synthesis->setPlatformSynthesizer(PlatformSpeechSynthesizerMock::create(synthesis));
+ synthesis->setPlatformSynthesizer(std::make_unique<PlatformSpeechSynthesizerMock>(synthesis));
}
+
+#endif
+
+#if ENABLE(WEB_RTC)
+
+void Internals::enableMockMediaEndpoint()
+{
+ MediaEndpoint::create = MockMediaEndpoint::create;
+}
+
+void Internals::emulateRTCPeerConnectionPlatformEvent(RTCPeerConnection& connection, const String& action)
+{
+ connection.emulatePlatformEvent(action);
+}
+
+void Internals::useMockRTCPeerConnectionFactory(const String& testCase)
+{
+#if USE(LIBWEBRTC)
+ Document* document = contextDocument();
+ LibWebRTCProvider* provider = (document && document->page()) ? &document->page()->libWebRTCProvider() : nullptr;
+ WebCore::useMockRTCPeerConnectionFactory(provider, testCase);
+#else
+ UNUSED_PARAM(testCase);
+#endif
+}
+
#endif
#if ENABLE(MEDIA_STREAM)
-void Internals::enableMockRTCPeerConnectionHandler()
+
+void Internals::setMockMediaCaptureDevicesEnabled(bool enabled)
{
- RTCPeerConnectionHandler::create = RTCPeerConnectionHandlerMock::create;
+ WebCore::Settings::setMockCaptureDevicesEnabled(enabled);
}
+
#endif
-PassRefPtr<ClientRect> Internals::absoluteCaretBounds(ExceptionCode& ec)
+ExceptionOr<Ref<ClientRect>> Internals::absoluteCaretBounds()
{
Document* document = contextDocument();
- if (!document || !document->frame()) {
- ec = INVALID_ACCESS_ERR;
- return ClientRect::create();
- }
+ if (!document || !document->frame())
+ return Exception { INVALID_ACCESS_ERR };
return ClientRect::create(document->frame()->selection().absoluteCaretBounds());
}
-PassRefPtr<ClientRect> Internals::boundingBox(Element* element, ExceptionCode& ec)
+Ref<ClientRect> Internals::boundingBox(Element& element)
{
- if (!element) {
- ec = INVALID_ACCESS_ERR;
- return ClientRect::create();
- }
-
- element->document().updateLayoutIgnorePendingStylesheets();
- auto renderer = element->renderer();
+ element.document().updateLayoutIgnorePendingStylesheets();
+ auto renderer = element.renderer();
if (!renderer)
return ClientRect::create();
return ClientRect::create(renderer->absoluteBoundingBoxRectIgnoringTransforms());
}
-PassRefPtr<ClientRectList> Internals::inspectorHighlightRects(ExceptionCode& ec)
+ExceptionOr<Ref<ClientRectList>> Internals::inspectorHighlightRects()
{
-#if ENABLE(INSPECTOR)
Document* document = contextDocument();
- if (!document || !document->page()) {
- ec = INVALID_ACCESS_ERR;
- return ClientRectList::create();
- }
+ if (!document || !document->page())
+ return Exception { INVALID_ACCESS_ERR };
Highlight highlight;
- document->page()->inspectorController().getHighlight(&highlight);
+ document->page()->inspectorController().getHighlight(highlight, InspectorOverlay::CoordinateSystem::View);
return ClientRectList::create(highlight.quads);
-#else
- UNUSED_PARAM(ec);
- return ClientRectList::create();
-#endif
}
-String Internals::inspectorHighlightObject(ExceptionCode& ec)
+ExceptionOr<String> Internals::inspectorHighlightObject()
{
-#if ENABLE(INSPECTOR)
Document* document = contextDocument();
- if (!document || !document->page()) {
- ec = INVALID_ACCESS_ERR;
- return String();
- }
- RefPtr<InspectorObject> object = document->page()->inspectorController().buildObjectForHighlightedNode();
- return object ? object->toJSONString() : String();
-#else
- UNUSED_PARAM(ec);
- return String();
-#endif
+ if (!document || !document->page())
+ return Exception { INVALID_ACCESS_ERR };
+
+ return document->page()->inspectorController().buildObjectForHighlightedNodes()->toJSONString();
}
-unsigned Internals::markerCountForNode(Node* node, const String& markerType, ExceptionCode& ec)
+ExceptionOr<unsigned> Internals::markerCountForNode(Node& node, const String& markerType)
{
- if (!node) {
- ec = INVALID_ACCESS_ERR;
- return 0;
- }
-
DocumentMarker::MarkerTypes markerTypes = 0;
- if (!markerTypesFrom(markerType, markerTypes)) {
- ec = SYNTAX_ERR;
- return 0;
- }
+ if (!markerTypesFrom(markerType, markerTypes))
+ return Exception { SYNTAX_ERR };
- return node->document().markers().markersFor(node, markerTypes).size();
+ node.document().frame()->editor().updateEditorUINowIfScheduled();
+ return node.document().markers().markersFor(&node, markerTypes).size();
}
-DocumentMarker* Internals::markerAt(Node* node, const String& markerType, unsigned index, ExceptionCode& ec)
+ExceptionOr<RenderedDocumentMarker*> Internals::markerAt(Node& node, const String& markerType, unsigned index)
{
- node->document().updateLayoutIgnorePendingStylesheets();
- if (!node) {
- ec = INVALID_ACCESS_ERR;
- return 0;
- }
+ node.document().updateLayoutIgnorePendingStylesheets();
DocumentMarker::MarkerTypes markerTypes = 0;
- if (!markerTypesFrom(markerType, markerTypes)) {
- ec = SYNTAX_ERR;
- return 0;
- }
+ if (!markerTypesFrom(markerType, markerTypes))
+ return Exception { SYNTAX_ERR };
+
+ node.document().frame()->editor().updateEditorUINowIfScheduled();
- Vector<DocumentMarker*> markers = node->document().markers().markersFor(node, markerTypes);
+ Vector<RenderedDocumentMarker*> markers = node.document().markers().markersFor(&node, markerTypes);
if (markers.size() <= index)
- return 0;
+ return nullptr;
return markers[index];
}
-PassRefPtr<Range> Internals::markerRangeForNode(Node* node, const String& markerType, unsigned index, ExceptionCode& ec)
+ExceptionOr<RefPtr<Range>> Internals::markerRangeForNode(Node& node, const String& markerType, unsigned index)
{
- DocumentMarker* marker = markerAt(node, markerType, index, ec);
+ auto result = markerAt(node, markerType, index);
+ if (result.hasException())
+ return result.releaseException();
+ auto marker = result.releaseReturnValue();
if (!marker)
- return 0;
- return Range::create(node->document(), node, marker->startOffset(), node, marker->endOffset());
+ return nullptr;
+ return RefPtr<Range> { Range::create(node.document(), &node, marker->startOffset(), &node, marker->endOffset()) };
}
-String Internals::markerDescriptionForNode(Node* node, const String& markerType, unsigned index, ExceptionCode& ec)
+ExceptionOr<String> Internals::markerDescriptionForNode(Node& node, const String& markerType, unsigned index)
{
- DocumentMarker* marker = markerAt(node, markerType, index, ec);
+ auto result = markerAt(node, markerType, index);
+ if (result.hasException())
+ return result.releaseException();
+ auto marker = result.releaseReturnValue();
if (!marker)
return String();
- return marker->description();
+ return String { marker->description() };
}
-void Internals::addTextMatchMarker(const Range* range, bool isActive)
+ExceptionOr<String> Internals::dumpMarkerRects(const String& markerTypeString)
{
- range->ownerDocument().updateLayoutIgnorePendingStylesheets();
- range->ownerDocument().markers().addTextMatchMarker(range, isActive);
+ DocumentMarker::MarkerType markerType;
+ if (!markerTypeFrom(markerTypeString, markerType))
+ return Exception { SYNTAX_ERR };
+
+ contextDocument()->markers().updateRectsForInvalidatedMarkersOfType(markerType);
+ auto rects = contextDocument()->markers().renderedRectsForMarkers(markerType);
+
+ StringBuilder rectString;
+ rectString.appendLiteral("marker rects: ");
+ for (const auto& rect : rects) {
+ rectString.append('(');
+ rectString.appendNumber(rect.x());
+ rectString.appendLiteral(", ");
+ rectString.appendNumber(rect.y());
+ rectString.appendLiteral(", ");
+ rectString.appendNumber(rect.width());
+ rectString.appendLiteral(", ");
+ rectString.appendNumber(rect.height());
+ rectString.appendLiteral(") ");
+ }
+ return rectString.toString();
}
-void Internals::setScrollViewPosition(long x, long y, ExceptionCode& ec)
+void Internals::addTextMatchMarker(const Range& range, bool isActive)
+{
+ range.ownerDocument().updateLayoutIgnorePendingStylesheets();
+ range.ownerDocument().markers().addTextMatchMarker(&range, isActive);
+}
+
+ExceptionOr<void> Internals::setMarkedTextMatchesAreHighlighted(bool flag)
{
Document* document = contextDocument();
- if (!document || !document->view()) {
- ec = INVALID_ACCESS_ERR;
- return;
- }
+ if (!document || !document->frame())
+ return Exception { INVALID_ACCESS_ERR };
+ document->frame()->editor().setMarkedTextMatchesAreHighlighted(flag);
+ return { };
+}
+
+void Internals::invalidateFontCache()
+{
+ FontCache::singleton().invalidate();
+}
+
+ExceptionOr<void> Internals::setScrollViewPosition(int x, int y)
+{
+ Document* document = contextDocument();
+ if (!document || !document->view())
+ return Exception { INVALID_ACCESS_ERR };
+
+ auto& frameView = *document->view();
+ bool constrainsScrollingToContentEdgeOldValue = frameView.constrainsScrollingToContentEdge();
+ bool scrollbarsSuppressedOldValue = frameView.scrollbarsSuppressed();
- FrameView* frameView = document->view();
- bool constrainsScrollingToContentEdgeOldValue = frameView->constrainsScrollingToContentEdge();
- bool scrollbarsSuppressedOldValue = frameView->scrollbarsSuppressed();
+ frameView.setConstrainsScrollingToContentEdge(false);
+ frameView.setScrollbarsSuppressed(false);
+ frameView.setScrollOffsetFromInternals({ x, y });
+ frameView.setScrollbarsSuppressed(scrollbarsSuppressedOldValue);
+ frameView.setConstrainsScrollingToContentEdge(constrainsScrollingToContentEdgeOldValue);
- frameView->setConstrainsScrollingToContentEdge(false);
- frameView->setScrollbarsSuppressed(false);
- frameView->setScrollOffsetFromInternals(IntPoint(x, y));
- frameView->setScrollbarsSuppressed(scrollbarsSuppressedOldValue);
- frameView->setConstrainsScrollingToContentEdge(constrainsScrollingToContentEdgeOldValue);
+ return { };
}
-void Internals::setPagination(const String& mode, int gap, int pageLength, ExceptionCode& ec)
+ExceptionOr<Ref<ClientRect>> Internals::layoutViewportRect()
{
Document* document = contextDocument();
- if (!document || !document->page()) {
- ec = INVALID_ACCESS_ERR;
- return;
- }
- Page* page = document->page();
+ if (!document || !document->frame())
+ return Exception { INVALID_ACCESS_ERR };
+
+ document->updateLayoutIgnorePendingStylesheets();
+
+ auto& frameView = *document->view();
+ return ClientRect::create(frameView.layoutViewportRect());
+}
+
+ExceptionOr<Ref<ClientRect>> Internals::visualViewportRect()
+{
+ Document* document = contextDocument();
+ if (!document || !document->frame())
+ return Exception { INVALID_ACCESS_ERR };
+
+ document->updateLayoutIgnorePendingStylesheets();
+
+ auto& frameView = *document->view();
+ return ClientRect::create(frameView.visualViewportRect());
+}
+
+ExceptionOr<void> Internals::setViewBaseBackgroundColor(const String& colorValue)
+{
+ Document* document = contextDocument();
+ if (!document || !document->view())
+ return Exception { INVALID_ACCESS_ERR };
+
+ document->view()->setBaseBackgroundColor(Color(colorValue));
+ return { };
+}
+
+ExceptionOr<void> Internals::setPagination(const String& mode, int gap, int pageLength)
+{
+ Document* document = contextDocument();
+ if (!document || !document->page())
+ return Exception { INVALID_ACCESS_ERR };
Pagination pagination;
if (mode == "Unpaginated")
@@ -836,223 +1357,193 @@ void Internals::setPagination(const String& mode, int gap, int pageLength, Excep
pagination.mode = Pagination::TopToBottomPaginated;
else if (mode == "BottomToTopPaginated")
pagination.mode = Pagination::BottomToTopPaginated;
- else {
- ec = SYNTAX_ERR;
- return;
- }
+ else
+ return Exception { SYNTAX_ERR };
pagination.gap = gap;
pagination.pageLength = pageLength;
- page->setPagination(pagination);
+ document->page()->setPagination(pagination);
+
+ return { };
}
-String Internals::configurationForViewport(float devicePixelRatio, int deviceWidth, int deviceHeight, int availableWidth, int availableHeight, ExceptionCode& ec)
+ExceptionOr<void> Internals::setPaginationLineGridEnabled(bool enabled)
{
Document* document = contextDocument();
- if (!document || !document->page()) {
- ec = INVALID_ACCESS_ERR;
- return String();
- }
- Page* page = document->page();
+ if (!document || !document->page())
+ return Exception { INVALID_ACCESS_ERR };
+ document->page()->setPaginationLineGridEnabled(enabled);
+ return { };
+}
+
+ExceptionOr<String> Internals::configurationForViewport(float devicePixelRatio, int deviceWidth, int deviceHeight, int availableWidth, int availableHeight)
+{
+ Document* document = contextDocument();
+ if (!document || !document->page())
+ return Exception { INVALID_ACCESS_ERR };
const int defaultLayoutWidthForNonMobilePages = 980;
- ViewportArguments arguments = page->viewportArguments();
+ ViewportArguments arguments = document->page()->viewportArguments();
ViewportAttributes attributes = computeViewportAttributes(arguments, defaultLayoutWidthForNonMobilePages, deviceWidth, deviceHeight, devicePixelRatio, IntSize(availableWidth, availableHeight));
restrictMinimumScaleFactorToViewportSize(attributes, IntSize(availableWidth, availableHeight), devicePixelRatio);
restrictScaleFactorToInitialScaleIfNotUserScalable(attributes);
- return "viewport size " + String::number(attributes.layoutSize.width()) + "x" + String::number(attributes.layoutSize.height()) + " scale " + String::number(attributes.initialScale) + " with limits [" + String::number(attributes.minimumScale) + ", " + String::number(attributes.maximumScale) + "] and userScalable " + (attributes.userScalable ? "true" : "false");
+ return String { "viewport size " + String::number(attributes.layoutSize.width()) + "x" + String::number(attributes.layoutSize.height()) + " scale " + String::number(attributes.initialScale) + " with limits [" + String::number(attributes.minimumScale) + ", " + String::number(attributes.maximumScale) + "] and userScalable " + (attributes.userScalable ? "true" : "false") };
}
-bool Internals::wasLastChangeUserEdit(Element* textField, ExceptionCode& ec)
+ExceptionOr<bool> Internals::wasLastChangeUserEdit(Element& textField)
{
- if (!textField) {
- ec = INVALID_ACCESS_ERR;
- return false;
- }
-
- if (HTMLInputElement* inputElement = textField->toInputElement())
- return inputElement->lastChangeWasUserEdit();
+ if (is<HTMLInputElement>(textField))
+ return downcast<HTMLInputElement>(textField).lastChangeWasUserEdit();
- // FIXME: We should be using hasTagName instead but Windows port doesn't link QualifiedNames properly.
- if (textField->tagName() == "TEXTAREA")
- return toHTMLTextAreaElement(textField)->lastChangeWasUserEdit();
+ if (is<HTMLTextAreaElement>(textField))
+ return downcast<HTMLTextAreaElement>(textField).lastChangeWasUserEdit();
- ec = INVALID_NODE_TYPE_ERR;
- return false;
+ return Exception { INVALID_NODE_TYPE_ERR };
}
-bool Internals::elementShouldAutoComplete(Element* element, ExceptionCode& ec)
+bool Internals::elementShouldAutoComplete(HTMLInputElement& element)
{
- if (!element) {
- ec = INVALID_ACCESS_ERR;
- return false;
- }
-
- if (HTMLInputElement* inputElement = element->toInputElement())
- return inputElement->shouldAutocomplete();
-
- ec = INVALID_NODE_TYPE_ERR;
- return false;
+ return element.shouldAutocomplete();
}
-String Internals::suggestedValue(Element* element, ExceptionCode& ec)
+void Internals::setEditingValue(HTMLInputElement& element, const String& value)
{
- if (!element) {
- ec = INVALID_ACCESS_ERR;
- return String();
- }
-
- HTMLInputElement* inputElement = element->toInputElement();
- if (!inputElement) {
- ec = INVALID_NODE_TYPE_ERR;
- return String();
- }
-
- return inputElement->suggestedValue();
+ element.setEditingValue(value);
}
-void Internals::setSuggestedValue(Element* element, const String& value, ExceptionCode& ec)
+void Internals::setAutofilled(HTMLInputElement& element, bool enabled)
{
- if (!element) {
- ec = INVALID_ACCESS_ERR;
- return;
- }
-
- HTMLInputElement* inputElement = element->toInputElement();
- if (!inputElement) {
- ec = INVALID_NODE_TYPE_ERR;
- return;
- }
-
- inputElement->setSuggestedValue(value);
+ element.setAutoFilled(enabled);
}
-void Internals::setEditingValue(Element* element, const String& value, ExceptionCode& ec)
+static AutoFillButtonType toAutoFillButtonType(Internals::AutoFillButtonType type)
{
- if (!element) {
- ec = INVALID_ACCESS_ERR;
- return;
- }
-
- HTMLInputElement* inputElement = element->toInputElement();
- if (!inputElement) {
- ec = INVALID_NODE_TYPE_ERR;
- return;
+ switch (type) {
+ case Internals::AutoFillButtonType::AutoFillButtonTypeNone:
+ return AutoFillButtonType::None;
+ case Internals::AutoFillButtonType::AutoFillButtonTypeCredentials:
+ return AutoFillButtonType::Credentials;
+ case Internals::AutoFillButtonType::AutoFillButtonTypeContacts:
+ return AutoFillButtonType::Contacts;
}
-
- inputElement->setEditingValue(value);
+ ASSERT_NOT_REACHED();
+ return AutoFillButtonType::None;
}
-void Internals::setAutofilled(Element* element, bool enabled, ExceptionCode& ec)
+void Internals::setShowAutoFillButton(HTMLInputElement& element, AutoFillButtonType type)
{
- HTMLInputElement* inputElement = element->toInputElement();
- if (!inputElement) {
- ec = INVALID_ACCESS_ERR;
- return;
- }
- inputElement->setAutofilled(enabled);
+ element.setShowAutoFillButton(toAutoFillButtonType(type));
}
-void Internals::scrollElementToRect(Element* element, long x, long y, long w, long h, ExceptionCode& ec)
+ExceptionOr<void> Internals::scrollElementToRect(Element& element, int x, int y, int w, int h)
{
- if (!element || !element->document().view()) {
- ec = INVALID_ACCESS_ERR;
- return;
- }
- FrameView* frameView = element->document().view();
- frameView->scrollElementToRect(element, IntRect(x, y, w, h));
+ FrameView* frameView = element.document().view();
+ if (!frameView)
+ return Exception { INVALID_ACCESS_ERR };
+ frameView->scrollElementToRect(element, { x, y, w, h });
+ return { };
}
-void Internals::paintControlTints(ExceptionCode& ec)
+ExceptionOr<String> Internals::autofillFieldName(Element& element)
{
- Document* document = contextDocument();
- if (!document || !document->view()) {
- ec = INVALID_ACCESS_ERR;
- return;
- }
+ if (!is<HTMLFormControlElement>(element))
+ return Exception { INVALID_NODE_TYPE_ERR };
- FrameView* frameView = document->view();
- frameView->paintControlTints();
+ return String { downcast<HTMLFormControlElement>(element).autofillData().fieldName };
}
-PassRefPtr<Range> Internals::rangeFromLocationAndLength(Element* scope, int rangeLocation, int rangeLength, ExceptionCode& ec)
+ExceptionOr<void> Internals::paintControlTints()
{
- if (!scope) {
- ec = INVALID_ACCESS_ERR;
- return 0;
- }
+ Document* document = contextDocument();
+ if (!document || !document->view())
+ return Exception { INVALID_ACCESS_ERR };
- return TextIterator::rangeFromLocationAndLength(scope, rangeLocation, rangeLength);
+ document->view()->paintControlTints();
+ return { };
}
-unsigned Internals::locationFromRange(Element* scope, const Range* range, ExceptionCode& ec)
+RefPtr<Range> Internals::rangeFromLocationAndLength(Element& scope, int rangeLocation, int rangeLength)
{
- if (!scope || !range) {
- ec = INVALID_ACCESS_ERR;
- return 0;
- }
+ return TextIterator::rangeFromLocationAndLength(&scope, rangeLocation, rangeLength);
+}
+unsigned Internals::locationFromRange(Element& scope, const Range& range)
+{
size_t location = 0;
size_t unusedLength = 0;
- TextIterator::getLocationAndLengthFromRange(scope, range, location, unusedLength);
+ TextIterator::getLocationAndLengthFromRange(&scope, &range, location, unusedLength);
return location;
}
-unsigned Internals::lengthFromRange(Element* scope, const Range* range, ExceptionCode& ec)
+unsigned Internals::lengthFromRange(Element& scope, const Range& range)
{
- if (!scope || !range) {
- ec = INVALID_ACCESS_ERR;
- return 0;
- }
-
size_t unusedLocation = 0;
size_t length = 0;
- TextIterator::getLocationAndLengthFromRange(scope, range, unusedLocation, length);
+ TextIterator::getLocationAndLengthFromRange(&scope, &range, unusedLocation, length);
return length;
}
-String Internals::rangeAsText(const Range* range, ExceptionCode& ec)
+String Internals::rangeAsText(const Range& range)
{
- if (!range) {
- ec = INVALID_ACCESS_ERR;
- return String();
- }
+ return range.text();
+}
+
+Ref<Range> Internals::subrange(Range& range, int rangeLocation, int rangeLength)
+{
+ return TextIterator::subrange(&range, rangeLocation, rangeLength);
+}
+
+RefPtr<Range> Internals::rangeOfStringNearLocation(const Range& searchRange, const String& text, unsigned targetOffset)
+{
+ return findClosestPlainText(searchRange, text, 0, targetOffset);
+}
+
+ExceptionOr<RefPtr<Range>> Internals::rangeForDictionaryLookupAtLocation(int x, int y)
+{
+#if PLATFORM(MAC)
+ auto* document = contextDocument();
+ if (!document || !document->frame())
+ return Exception { INVALID_ACCESS_ERR };
- return range->text();
+ document->updateLayoutIgnorePendingStylesheets();
+
+ HitTestResult result = document->frame()->mainFrame().eventHandler().hitTestResultAtPoint(IntPoint(x, y));
+ NSDictionary *options = nullptr;
+ return DictionaryLookup::rangeAtHitTestResult(result, &options);
+#else
+ UNUSED_PARAM(x);
+ UNUSED_PARAM(y);
+ return Exception { INVALID_ACCESS_ERR };
+#endif
}
-void Internals::setDelegatesScrolling(bool enabled, ExceptionCode& ec)
+ExceptionOr<void> Internals::setDelegatesScrolling(bool enabled)
{
Document* document = contextDocument();
// Delegate scrolling is valid only on mainframe's view.
- if (!document || !document->view() || !document->page() || &document->page()->mainFrame() != document->frame()) {
- ec = INVALID_ACCESS_ERR;
- return;
- }
+ if (!document || !document->view() || !document->page() || &document->page()->mainFrame() != document->frame())
+ return Exception { INVALID_ACCESS_ERR };
document->view()->setDelegatesScrolling(enabled);
+ return { };
}
-int Internals::lastSpellCheckRequestSequence(ExceptionCode& ec)
+ExceptionOr<int> Internals::lastSpellCheckRequestSequence()
{
Document* document = contextDocument();
- if (!document || !document->frame()) {
- ec = INVALID_ACCESS_ERR;
- return -1;
- }
+ if (!document || !document->frame())
+ return Exception { INVALID_ACCESS_ERR };
return document->frame()->editor().spellChecker().lastRequestSequence();
}
-int Internals::lastSpellCheckProcessedSequence(ExceptionCode& ec)
+ExceptionOr<int> Internals::lastSpellCheckProcessedSequence()
{
Document* document = contextDocument();
- if (!document || !document->frame()) {
- ec = INVALID_ACCESS_ERR;
- return -1;
- }
+ if (!document || !document->frame())
+ return Exception { INVALID_ACCESS_ERR };
return document->frame()->editor().spellChecker().lastProcessedSequence();
}
@@ -1067,63 +1558,73 @@ void Internals::setUserPreferredLanguages(const Vector<String>& languages)
WebCore::overrideUserPreferredLanguages(languages);
}
-unsigned Internals::wheelEventHandlerCount(ExceptionCode& ec)
+Vector<String> Internals::userPreferredAudioCharacteristics() const
{
Document* document = contextDocument();
- if (!document) {
- ec = INVALID_ACCESS_ERR;
- return 0;
- }
+ if (!document || !document->page())
+ return Vector<String>();
+#if ENABLE(VIDEO_TRACK)
+ return document->page()->group().captionPreferences().preferredAudioCharacteristics();
+#else
+ return Vector<String>();
+#endif
+}
- return document->wheelEventHandlerCount();
+void Internals::setUserPreferredAudioCharacteristic(const String& characteristic)
+{
+ Document* document = contextDocument();
+ if (!document || !document->page())
+ return;
+#if ENABLE(VIDEO_TRACK)
+ document->page()->group().captionPreferences().setPreferredAudioCharacteristic(characteristic);
+#else
+ UNUSED_PARAM(characteristic);
+#endif
}
-unsigned Internals::touchEventHandlerCount(ExceptionCode& ec)
+ExceptionOr<unsigned> Internals::wheelEventHandlerCount()
{
Document* document = contextDocument();
- if (!document) {
- ec = INVALID_ACCESS_ERR;
- return 0;
- }
+ if (!document)
+ return Exception { INVALID_ACCESS_ERR };
- const TouchEventTargetSet* touchHandlers = document->touchEventTargets();
- if (!touchHandlers)
- return 0;
+ return document->wheelEventHandlerCount();
+}
- unsigned count = 0;
- for (TouchEventTargetSet::const_iterator iter = touchHandlers->begin(); iter != touchHandlers->end(); ++iter)
- count += iter->value;
- return count;
+ExceptionOr<unsigned> Internals::touchEventHandlerCount()
+{
+ Document* document = contextDocument();
+ if (!document)
+ return Exception { INVALID_ACCESS_ERR };
+
+ return document->touchEventHandlerCount();
}
// FIXME: Remove the document argument. It is almost always the same as
// contextDocument(), with the exception of a few tests that pass a
// different document, and could just make the call through another Internals
// instance instead.
-PassRefPtr<NodeList> Internals::nodesFromRect(Document* document, int centerX, int centerY, unsigned topPadding, unsigned rightPadding,
- unsigned bottomPadding, unsigned leftPadding, bool ignoreClipping, bool allowShadowContent, bool allowChildFrameContent, ExceptionCode& ec) const
+ExceptionOr<RefPtr<NodeList>> Internals::nodesFromRect(Document& document, int centerX, int centerY, unsigned topPadding, unsigned rightPadding, unsigned bottomPadding, unsigned leftPadding, bool ignoreClipping, bool allowShadowContent, bool allowChildFrameContent) const
{
- if (!document || !document->frame() || !document->frame()->view()) {
- ec = INVALID_ACCESS_ERR;
- return 0;
- }
+ if (!document.frame() || !document.frame()->view())
+ return Exception { INVALID_ACCESS_ERR };
- Frame* frame = document->frame();
- FrameView* frameView = document->view();
- RenderView* renderView = document->renderView();
+ Frame* frame = document.frame();
+ FrameView* frameView = document.view();
+ RenderView* renderView = document.renderView();
if (!renderView)
- return 0;
+ return nullptr;
- document->updateLayoutIgnorePendingStylesheets();
+ document.updateLayoutIgnorePendingStylesheets();
float zoomFactor = frame->pageZoomFactor();
- LayoutPoint point = roundedLayoutPoint(FloatPoint(centerX * zoomFactor + frameView->scrollX(), centerY * zoomFactor + frameView->scrollY()));
+ LayoutPoint point(centerX * zoomFactor + frameView->scrollX(), centerY * zoomFactor + frameView->scrollY());
HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active;
if (ignoreClipping)
hitType |= HitTestRequest::IgnoreClipping;
if (!allowShadowContent)
- hitType |= HitTestRequest::DisallowShadowContent;
+ hitType |= HitTestRequest::DisallowUserAgentShadowContent;
if (allowChildFrameContent)
hitType |= HitTestRequest::AllowChildFrameContent;
@@ -1131,7 +1632,7 @@ PassRefPtr<NodeList> Internals::nodesFromRect(Document* document, int centerX, i
// When ignoreClipping is false, this method returns null for coordinates outside of the viewport.
if (!request.ignoreClipping() && !frameView->visibleContentRect().intersects(HitTestLocation::rectForPoint(point, topPadding, rightPadding, bottomPadding, leftPadding)))
- return 0;
+ return nullptr;
Vector<Ref<Node>> matches;
@@ -1148,25 +1649,11 @@ PassRefPtr<NodeList> Internals::nodesFromRect(Document* document, int centerX, i
const HitTestResult::NodeSet& nodeSet = result.rectBasedTestResult();
matches.reserveInitialCapacity(nodeSet.size());
- for (auto it = nodeSet.begin(), end = nodeSet.end(); it != end; ++it)
- matches.uncheckedAppend(*it->get());
+ for (auto& node : nodeSet)
+ matches.uncheckedAppend(*node);
}
- return StaticNodeList::adopt(matches);
-}
-
-void Internals::emitInspectorDidBeginFrame()
-{
-#if ENABLE(INSPECTOR)
- contextDocument()->frame()->page()->inspectorController().didBeginFrame();
-#endif
-}
-
-void Internals::emitInspectorDidCancelFrame()
-{
-#if ENABLE(INSPECTOR)
- contextDocument()->frame()->page()->inspectorController().didCancelFrame();
-#endif
+ return RefPtr<NodeList> { StaticNodeList::create(WTFMove(matches)) };
}
class GetCallerCodeBlockFunctor {
@@ -1177,7 +1664,7 @@ public:
{
}
- StackVisitor::Status operator()(StackVisitor& visitor)
+ StackVisitor::Status operator()(StackVisitor& visitor) const
{
++m_iterations;
if (m_iterations < 2)
@@ -1190,29 +1677,28 @@ public:
CodeBlock* codeBlock() const { return m_codeBlock; }
private:
- int m_iterations;
- CodeBlock* m_codeBlock;
+ mutable int m_iterations;
+ mutable CodeBlock* m_codeBlock;
};
-String Internals::parserMetaData(Deprecated::ScriptValue value)
+String Internals::parserMetaData(JSC::JSValue code)
{
- JSC::VM* vm = contextDocument()->vm();
- JSC::ExecState* exec = vm->topCallFrame;
- JSC::JSValue code = value.jsValue();
+ JSC::VM& vm = contextDocument()->vm();
+ JSC::ExecState* exec = vm.topCallFrame;
ScriptExecutable* executable;
if (!code || code.isNull() || code.isUndefined()) {
GetCallerCodeBlockFunctor iter;
exec->iterate(iter);
CodeBlock* codeBlock = iter.codeBlock();
- executable = codeBlock->ownerExecutable();
+ executable = codeBlock->ownerScriptExecutable();
} else if (code.isFunction()) {
JSFunction* funcObj = JSC::jsCast<JSFunction*>(code.toObject(exec));
executable = funcObj->jsExecutable();
} else
return String();
- unsigned startLine = executable->lineNo();
+ unsigned startLine = executable->firstLine();
unsigned startColumn = executable->startColumn();
unsigned endLine = executable->lastLine();
unsigned endColumn = executable->endColumn();
@@ -1222,102 +1708,78 @@ String Internals::parserMetaData(Deprecated::ScriptValue value)
if (executable->isFunctionExecutable()) {
FunctionExecutable* funcExecutable = reinterpret_cast<FunctionExecutable*>(executable);
String inferredName = funcExecutable->inferredName().string();
- result.append("function \"");
+ result.appendLiteral("function \"");
result.append(inferredName);
- result.append("\"");
+ result.append('"');
} else if (executable->isEvalExecutable())
- result.append("eval");
- else {
- ASSERT(executable->isProgramExecutable());
- result.append("program");
- }
+ result.appendLiteral("eval");
+ else if (executable->isModuleProgramExecutable())
+ result.appendLiteral("module");
+ else if (executable->isProgramExecutable())
+ result.appendLiteral("program");
+ else
+ ASSERT_NOT_REACHED();
- result.append(" { ");
+ result.appendLiteral(" { ");
result.appendNumber(startLine);
- result.append(":");
+ result.append(':');
result.appendNumber(startColumn);
- result.append(" - ");
+ result.appendLiteral(" - ");
result.appendNumber(endLine);
- result.append(":");
+ result.append(':');
result.appendNumber(endColumn);
- result.append(" }");
+ result.appendLiteral(" }");
return result.toString();
}
-void Internals::setBatteryStatus(const String& eventType, bool charging, double chargingTime, double dischargingTime, double level, ExceptionCode& ec)
-{
- Document* document = contextDocument();
- if (!document || !document->page()) {
- ec = INVALID_ACCESS_ERR;
- return;
- }
-
-#if ENABLE(BATTERY_STATUS)
- BatteryController::from(document->page())->didChangeBatteryStatus(eventType, BatteryStatus::create(charging, chargingTime, dischargingTime, level));
-#else
- UNUSED_PARAM(eventType);
- UNUSED_PARAM(charging);
- UNUSED_PARAM(chargingTime);
- UNUSED_PARAM(dischargingTime);
- UNUSED_PARAM(level);
-#endif
-}
-
-void Internals::setNetworkInformation(const String& eventType, double bandwidth, bool metered, ExceptionCode& ec)
-{
- Document* document = contextDocument();
- if (!document || !document->page()) {
- ec = INVALID_ACCESS_ERR;
- return;
- }
-
-#if ENABLE(NETWORK_INFO)
- NetworkInfoController::from(document->page())->didChangeNetworkInformation(eventType, NetworkInfo::create(bandwidth, metered));
-#else
- UNUSED_PARAM(eventType);
- UNUSED_PARAM(bandwidth);
- UNUSED_PARAM(metered);
-#endif
-}
-
-void Internals::setDeviceProximity(const String& eventType, double value, double min, double max, ExceptionCode& ec)
+ExceptionOr<void> Internals::setDeviceProximity(const String&, double value, double min, double max)
{
Document* document = contextDocument();
- if (!document || !document->page()) {
- ec = INVALID_ACCESS_ERR;
- return;
- }
+ if (!document || !document->page())
+ return Exception { INVALID_ACCESS_ERR };
#if ENABLE(PROXIMITY_EVENTS)
DeviceProximityController::from(document->page())->didChangeDeviceProximity(value, min, max);
#else
- UNUSED_PARAM(eventType);
UNUSED_PARAM(value);
UNUSED_PARAM(min);
UNUSED_PARAM(max);
#endif
+ return { };
}
-bool Internals::hasSpellingMarker(int from, int length, ExceptionCode&)
+void Internals::updateEditorUINowIfScheduled()
+{
+ if (Document* document = contextDocument()) {
+ if (Frame* frame = document->frame())
+ frame->editor().updateEditorUINowIfScheduled();
+ }
+}
+
+bool Internals::hasSpellingMarker(int from, int length)
{
Document* document = contextDocument();
if (!document || !document->frame())
- return 0;
+ return false;
+
+ updateEditorUINowIfScheduled();
return document->frame()->editor().selectionStartHasMarkerFor(DocumentMarker::Spelling, from, length);
}
-bool Internals::hasAutocorrectedMarker(int from, int length, ExceptionCode&)
+bool Internals::hasAutocorrectedMarker(int from, int length)
{
Document* document = contextDocument();
if (!document || !document->frame())
- return 0;
-
+ return false;
+
+ updateEditorUINowIfScheduled();
+
return document->frame()->editor().selectionStartHasMarkerFor(DocumentMarker::Autocorrected, from, length);
}
-void Internals::setContinuousSpellCheckingEnabled(bool enabled, ExceptionCode&)
+void Internals::setContinuousSpellCheckingEnabled(bool enabled)
{
if (!contextDocument() || !contextDocument()->frame())
return;
@@ -1326,7 +1788,7 @@ void Internals::setContinuousSpellCheckingEnabled(bool enabled, ExceptionCode&)
contextDocument()->frame()->editor().toggleContinuousSpellChecking();
}
-void Internals::setAutomaticQuoteSubstitutionEnabled(bool enabled, ExceptionCode&)
+void Internals::setAutomaticQuoteSubstitutionEnabled(bool enabled)
{
if (!contextDocument() || !contextDocument()->frame())
return;
@@ -1339,7 +1801,7 @@ void Internals::setAutomaticQuoteSubstitutionEnabled(bool enabled, ExceptionCode
#endif
}
-void Internals::setAutomaticLinkDetectionEnabled(bool enabled, ExceptionCode&)
+void Internals::setAutomaticLinkDetectionEnabled(bool enabled)
{
if (!contextDocument() || !contextDocument()->frame())
return;
@@ -1352,7 +1814,7 @@ void Internals::setAutomaticLinkDetectionEnabled(bool enabled, ExceptionCode&)
#endif
}
-void Internals::setAutomaticDashSubstitutionEnabled(bool enabled, ExceptionCode&)
+void Internals::setAutomaticDashSubstitutionEnabled(bool enabled)
{
if (!contextDocument() || !contextDocument()->frame())
return;
@@ -1365,7 +1827,7 @@ void Internals::setAutomaticDashSubstitutionEnabled(bool enabled, ExceptionCode&
#endif
}
-void Internals::setAutomaticTextReplacementEnabled(bool enabled, ExceptionCode&)
+void Internals::setAutomaticTextReplacementEnabled(bool enabled)
{
if (!contextDocument() || !contextDocument()->frame())
return;
@@ -1378,7 +1840,7 @@ void Internals::setAutomaticTextReplacementEnabled(bool enabled, ExceptionCode&)
#endif
}
-void Internals::setAutomaticSpellingCorrectionEnabled(bool enabled, ExceptionCode&)
+void Internals::setAutomaticSpellingCorrectionEnabled(bool enabled)
{
if (!contextDocument() || !contextDocument()->frame())
return;
@@ -1391,16 +1853,29 @@ void Internals::setAutomaticSpellingCorrectionEnabled(bool enabled, ExceptionCod
#endif
}
-bool Internals::isOverwriteModeEnabled(ExceptionCode&)
+void Internals::handleAcceptedCandidate(const String& candidate, unsigned location, unsigned length)
+{
+ if (!contextDocument() || !contextDocument()->frame())
+ return;
+
+ TextCheckingResult result;
+ result.type = TextCheckingTypeNone;
+ result.location = location;
+ result.length = length;
+ result.replacement = candidate;
+ contextDocument()->frame()->editor().handleAcceptedCandidate(result);
+}
+
+bool Internals::isOverwriteModeEnabled()
{
Document* document = contextDocument();
if (!document || !document->frame())
- return 0;
+ return false;
return document->frame()->editor().isOverwriteModeEnabled();
}
-void Internals::toggleOverwriteModeEnabled(ExceptionCode&)
+void Internals::toggleOverwriteModeEnabled()
{
Document* document = contextDocument();
if (!document || !document->frame())
@@ -1409,107 +1884,125 @@ void Internals::toggleOverwriteModeEnabled(ExceptionCode&)
document->frame()->editor().toggleOverwriteModeEnabled();
}
-#if ENABLE(INSPECTOR)
-unsigned Internals::numberOfLiveNodes() const
-{
- return InspectorCounters::counterValue(InspectorCounters::NodeCounter);
-}
-
-unsigned Internals::numberOfLiveDocuments() const
-{
- return InspectorCounters::counterValue(InspectorCounters::DocumentCounter);
+static ExceptionOr<FindOptions> parseFindOptions(const Vector<String>& optionList)
+{
+ const struct {
+ const char* name;
+ FindOptionFlag value;
+ } flagList[] = {
+ {"CaseInsensitive", CaseInsensitive},
+ {"AtWordStarts", AtWordStarts},
+ {"TreatMedialCapitalAsWordStart", TreatMedialCapitalAsWordStart},
+ {"Backwards", Backwards},
+ {"WrapAround", WrapAround},
+ {"StartInSelection", StartInSelection},
+ {"DoNotRevealSelection", DoNotRevealSelection},
+ {"AtWordEnds", AtWordEnds},
+ {"DoNotTraverseFlatTree", DoNotTraverseFlatTree},
+ };
+ FindOptions result = 0;
+ for (auto& option : optionList) {
+ bool found = false;
+ for (auto& flag : flagList) {
+ if (flag.name == option) {
+ result |= flag.value;
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ return Exception { SYNTAX_ERR };
+ }
+ return result;
}
-Vector<String> Internals::consoleMessageArgumentCounts() const
+ExceptionOr<RefPtr<Range>> Internals::rangeOfString(const String& text, RefPtr<Range>&& referenceRange, const Vector<String>& findOptions)
{
Document* document = contextDocument();
- if (!document || !document->page())
- return Vector<String>();
+ if (!document || !document->frame())
+ return Exception { INVALID_ACCESS_ERR };
- InstrumentingAgents* instrumentingAgents = instrumentationForPage(document->page());
- if (!instrumentingAgents)
- return Vector<String>();
- InspectorConsoleAgent* consoleAgent = instrumentingAgents->inspectorConsoleAgent();
- if (!consoleAgent)
- return Vector<String>();
- Vector<unsigned> counts = consoleAgent->consoleMessageArgumentCounts();
- Vector<String> result(counts.size());
- for (size_t i = 0; i < counts.size(); i++)
- result[i] = String::number(counts[i]);
- return result;
+ auto parsedOptions = parseFindOptions(findOptions);
+ if (parsedOptions.hasException())
+ return parsedOptions.releaseException();
+
+ return document->frame()->editor().rangeOfString(text, referenceRange.get(), parsedOptions.releaseReturnValue());
}
-PassRefPtr<DOMWindow> Internals::openDummyInspectorFrontend(const String& url)
+ExceptionOr<unsigned> Internals::countMatchesForText(const String& text, const Vector<String>& findOptions, const String& markMatches)
{
- Page* page = contextDocument()->frame()->page();
- ASSERT(page);
-
- DOMWindow* window = page->mainFrame().document()->domWindow();
- ASSERT(window);
-
- m_frontendWindow = window->open(url, "", "", *window, *window);
- ASSERT(m_frontendWindow);
-
- Page* frontendPage = m_frontendWindow->document()->page();
- ASSERT(frontendPage);
+ Document* document = contextDocument();
+ if (!document || !document->frame())
+ return Exception { INVALID_ACCESS_ERR };
- auto frontendClient = std::make_unique<InspectorFrontendClientDummy>(&page->inspectorController(), frontendPage);
+ auto parsedOptions = parseFindOptions(findOptions);
+ if (parsedOptions.hasException())
+ return parsedOptions.releaseException();
- frontendPage->inspectorController().setInspectorFrontendClient(std::move(frontendClient));
+ bool mark = markMatches == "mark";
+ return document->frame()->editor().countMatchesForText(text, nullptr, parsedOptions.releaseReturnValue(), 1000, mark, nullptr);
+}
- m_frontendChannel = adoptPtr(new InspectorFrontendChannelDummy(frontendPage));
+ExceptionOr<unsigned> Internals::countFindMatches(const String& text, const Vector<String>& findOptions)
+{
+ Document* document = contextDocument();
+ if (!document || !document->page())
+ return Exception { INVALID_ACCESS_ERR };
- page->inspectorController().connectFrontend(m_frontendChannel.get());
+ auto parsedOptions = parseFindOptions(findOptions);
+ if (parsedOptions.hasException())
+ return parsedOptions.releaseException();
- return m_frontendWindow;
+ return document->page()->countFindMatches(text, parsedOptions.releaseReturnValue(), 1000);
}
-void Internals::closeDummyInspectorFrontend()
+unsigned Internals::numberOfLiveNodes() const
{
- Page* page = contextDocument()->frame()->page();
- ASSERT(page);
- ASSERT(m_frontendWindow);
-
- page->inspectorController().disconnectFrontend(InspectorDisconnectReason::InspectorDestroyed);
+ unsigned nodeCount = 0;
+ for (auto* document : Document::allDocuments())
+ nodeCount += document->referencingNodeCount();
+ return nodeCount;
+}
- m_frontendChannel.release();
+unsigned Internals::numberOfLiveDocuments() const
+{
+ return Document::allDocuments().size();
+}
- m_frontendWindow->close(m_frontendWindow->scriptExecutionContext());
- m_frontendWindow.release();
+RefPtr<DOMWindow> Internals::openDummyInspectorFrontend(const String& url)
+{
+ auto* inspectedPage = contextDocument()->frame()->page();
+ auto* window = inspectedPage->mainFrame().document()->domWindow();
+ auto frontendWindow = window->open(url, "", "", *window, *window);
+ m_inspectorFrontend = std::make_unique<InspectorStubFrontend>(*inspectedPage, frontendWindow.copyRef());
+ return frontendWindow;
}
-void Internals::setInspectorResourcesDataSizeLimits(int maximumResourcesContentSize, int maximumSingleResourceContentSize, ExceptionCode& ec)
+void Internals::closeDummyInspectorFrontend()
{
- Page* page = contextDocument()->frame()->page();
- if (!page) {
- ec = INVALID_ACCESS_ERR;
- return;
- }
- page->inspectorController().setResourcesDataSizeLimitsFromInternals(maximumResourcesContentSize, maximumSingleResourceContentSize);
+ m_inspectorFrontend = nullptr;
}
-void Internals::setJavaScriptProfilingEnabled(bool enabled, ExceptionCode& ec)
+ExceptionOr<void> Internals::setInspectorIsUnderTest(bool isUnderTest)
{
Page* page = contextDocument()->frame()->page();
- if (!page) {
- ec = INVALID_ACCESS_ERR;
- return;
- }
+ if (!page)
+ return Exception { INVALID_ACCESS_ERR };
- page->inspectorController().setProfilerEnabled(enabled);
+ page->inspectorController().setIsUnderTest(isUnderTest);
+ return { };
}
-#endif // ENABLE(INSPECTOR)
-bool Internals::hasGrammarMarker(int from, int length, ExceptionCode&)
+bool Internals::hasGrammarMarker(int from, int length)
{
Document* document = contextDocument();
if (!document || !document->frame())
- return 0;
+ return false;
return document->frame()->editor().selectionStartHasMarkerFor(DocumentMarker::Grammar, from, length);
}
-unsigned Internals::numberOfScrollableAreas(ExceptionCode&)
+unsigned Internals::numberOfScrollableAreas()
{
Document* document = contextDocument();
if (!document || !document->frame())
@@ -1528,66 +2021,60 @@ unsigned Internals::numberOfScrollableAreas(ExceptionCode&)
return count;
}
-bool Internals::isPageBoxVisible(int pageNumber, ExceptionCode& ec)
+ExceptionOr<bool> Internals::isPageBoxVisible(int pageNumber)
{
Document* document = contextDocument();
- if (!document) {
- ec = INVALID_ACCESS_ERR;
- return false;
- }
+ if (!document)
+ return Exception { INVALID_ACCESS_ERR };
return document->isPageBoxVisible(pageNumber);
}
-// FIXME: Remove the document argument. It is almost always the same as
-// contextDocument(), with the exception of a few tests that pass a
-// different document, and could just make the call through another Internals
-// instance instead.
-String Internals::layerTreeAsText(Document* document, ExceptionCode& ec) const
+static LayerTreeFlags toLayerTreeFlags(unsigned short flags)
{
- return layerTreeAsText(document, 0, ec);
-}
-
-String Internals::layerTreeAsText(Document* document, unsigned flags, ExceptionCode& ec) const
-{
- if (!document || !document->frame()) {
- ec = INVALID_ACCESS_ERR;
- return String();
- }
-
LayerTreeFlags layerTreeFlags = 0;
- if (flags & LAYER_TREE_INCLUDES_VISIBLE_RECTS)
+ if (flags & Internals::LAYER_TREE_INCLUDES_VISIBLE_RECTS)
layerTreeFlags |= LayerTreeFlagsIncludeVisibleRects;
- if (flags & LAYER_TREE_INCLUDES_TILE_CACHES)
+ if (flags & Internals::LAYER_TREE_INCLUDES_TILE_CACHES)
layerTreeFlags |= LayerTreeFlagsIncludeTileCaches;
- if (flags & LAYER_TREE_INCLUDES_REPAINT_RECTS)
+ if (flags & Internals::LAYER_TREE_INCLUDES_REPAINT_RECTS)
layerTreeFlags |= LayerTreeFlagsIncludeRepaintRects;
- if (flags & LAYER_TREE_INCLUDES_PAINTING_PHASES)
+ if (flags & Internals::LAYER_TREE_INCLUDES_PAINTING_PHASES)
layerTreeFlags |= LayerTreeFlagsIncludePaintingPhases;
- if (flags & LAYER_TREE_INCLUDES_CONTENT_LAYERS)
+ if (flags & Internals::LAYER_TREE_INCLUDES_CONTENT_LAYERS)
layerTreeFlags |= LayerTreeFlagsIncludeContentLayers;
+ if (flags & Internals::LAYER_TREE_INCLUDES_ACCELERATES_DRAWING)
+ layerTreeFlags |= LayerTreeFlagsIncludeAcceleratesDrawing;
- return document->frame()->layerTreeAsText(layerTreeFlags);
+ return layerTreeFlags;
}
-String Internals::repaintRectsAsText(ExceptionCode& ec) const
+// FIXME: Remove the document argument. It is almost always the same as
+// contextDocument(), with the exception of a few tests that pass a
+// different document, and could just make the call through another Internals
+// instance instead.
+ExceptionOr<String> Internals::layerTreeAsText(Document& document, unsigned short flags) const
+{
+ if (!document.frame())
+ return Exception { INVALID_ACCESS_ERR };
+
+ return document.frame()->layerTreeAsText(toLayerTreeFlags(flags));
+}
+
+ExceptionOr<String> Internals::repaintRectsAsText() const
{
Document* document = contextDocument();
- if (!document || !document->frame()) {
- ec = INVALID_ACCESS_ERR;
- return String();
- }
+ if (!document || !document->frame())
+ return Exception { INVALID_ACCESS_ERR };
return document->frame()->trackedRepaintRectsAsText();
}
-String Internals::scrollingStateTreeAsText(ExceptionCode& ec) const
+ExceptionOr<String> Internals::scrollingStateTreeAsText() const
{
Document* document = contextDocument();
- if (!document || !document->frame()) {
- ec = INVALID_ACCESS_ERR;
- return String();
- }
+ if (!document || !document->frame())
+ return Exception { INVALID_ACCESS_ERR };
Page* page = document->page();
if (!page)
@@ -1596,13 +2083,11 @@ String Internals::scrollingStateTreeAsText(ExceptionCode& ec) const
return page->scrollingStateTreeAsText();
}
-String Internals::mainThreadScrollingReasons(ExceptionCode& ec) const
+ExceptionOr<String> Internals::mainThreadScrollingReasons() const
{
Document* document = contextDocument();
- if (!document || !document->frame()) {
- ec = INVALID_ACCESS_ERR;
- return String();
- }
+ if (!document || !document->frame())
+ return Exception { INVALID_ACCESS_ERR };
Page* page = document->page();
if (!page)
@@ -1611,143 +2096,285 @@ String Internals::mainThreadScrollingReasons(ExceptionCode& ec) const
return page->synchronousScrollingReasonsAsText();
}
-PassRefPtr<ClientRectList> Internals::nonFastScrollableRects(ExceptionCode& ec) const
+ExceptionOr<RefPtr<ClientRectList>> Internals::nonFastScrollableRects() const
{
Document* document = contextDocument();
- if (!document || !document->frame()) {
- ec = INVALID_ACCESS_ERR;
- return 0;
- }
+ if (!document || !document->frame())
+ return Exception { INVALID_ACCESS_ERR };
Page* page = document->page();
if (!page)
- return 0;
+ return nullptr;
- return page->nonFastScrollableRects(document->frame());
+ return RefPtr<ClientRectList> { page->nonFastScrollableRects() };
}
-void Internals::garbageCollectDocumentResources(ExceptionCode& ec) const
+ExceptionOr<void> Internals::setElementUsesDisplayListDrawing(Element& element, bool usesDisplayListDrawing)
{
Document* document = contextDocument();
- if (!document) {
- ec = INVALID_ACCESS_ERR;
- return;
+ if (!document || !document->renderView())
+ return Exception { INVALID_ACCESS_ERR };
+
+ if (!element.renderer())
+ return Exception { INVALID_ACCESS_ERR };
+
+ if (is<HTMLCanvasElement>(element)) {
+ downcast<HTMLCanvasElement>(element).setUsesDisplayListDrawing(usesDisplayListDrawing);
+ return { };
}
- CachedResourceLoader* cachedResourceLoader = document->cachedResourceLoader();
- if (!cachedResourceLoader)
- return;
- cachedResourceLoader->garbageCollectDocumentResources();
+ if (!element.renderer()->hasLayer())
+ return Exception { INVALID_ACCESS_ERR };
+
+ RenderLayer* layer = downcast<RenderLayerModelObject>(element.renderer())->layer();
+ if (!layer->isComposited())
+ return Exception { INVALID_ACCESS_ERR };
+
+ layer->backing()->setUsesDisplayListDrawing(usesDisplayListDrawing);
+ return { };
}
-void Internals::allowRoundingHacks() const
+ExceptionOr<void> Internals::setElementTracksDisplayListReplay(Element& element, bool isTrackingReplay)
{
- TextRun::setAllowsRoundingHacks(true);
+ Document* document = contextDocument();
+ if (!document || !document->renderView())
+ return Exception { INVALID_ACCESS_ERR };
+
+ if (!element.renderer())
+ return Exception { INVALID_ACCESS_ERR };
+
+ if (is<HTMLCanvasElement>(element)) {
+ downcast<HTMLCanvasElement>(element).setTracksDisplayListReplay(isTrackingReplay);
+ return { };
+ }
+
+ if (!element.renderer()->hasLayer())
+ return Exception { INVALID_ACCESS_ERR };
+
+ RenderLayer* layer = downcast<RenderLayerModelObject>(element.renderer())->layer();
+ if (!layer->isComposited())
+ return Exception { INVALID_ACCESS_ERR };
+
+ layer->backing()->setIsTrackingDisplayListReplay(isTrackingReplay);
+ return { };
}
-void Internals::insertAuthorCSS(const String& css, ExceptionCode& ec) const
+ExceptionOr<String> Internals::displayListForElement(Element& element, unsigned short flags)
{
Document* document = contextDocument();
- if (!document) {
- ec = INVALID_ACCESS_ERR;
- return;
- }
+ if (!document || !document->renderView())
+ return Exception { INVALID_ACCESS_ERR };
+
+ if (!element.renderer())
+ return Exception { INVALID_ACCESS_ERR };
+
+ DisplayList::AsTextFlags displayListFlags = 0;
+ if (flags & DISPLAY_LIST_INCLUDES_PLATFORM_OPERATIONS)
+ displayListFlags |= DisplayList::AsTextFlag::IncludesPlatformOperations;
+
+ if (is<HTMLCanvasElement>(element))
+ return downcast<HTMLCanvasElement>(element).displayListAsText(displayListFlags);
+
+ if (!element.renderer()->hasLayer())
+ return Exception { INVALID_ACCESS_ERR };
+
+ RenderLayer* layer = downcast<RenderLayerModelObject>(element.renderer())->layer();
+ if (!layer->isComposited())
+ return Exception { INVALID_ACCESS_ERR };
+
+ return layer->backing()->displayListAsText(displayListFlags);
+}
+
+ExceptionOr<String> Internals::replayDisplayListForElement(Element& element, unsigned short flags)
+{
+ Document* document = contextDocument();
+ if (!document || !document->renderView())
+ return Exception { INVALID_ACCESS_ERR };
+
+ if (!element.renderer())
+ return Exception { INVALID_ACCESS_ERR };
+
+ DisplayList::AsTextFlags displayListFlags = 0;
+ if (flags & DISPLAY_LIST_INCLUDES_PLATFORM_OPERATIONS)
+ displayListFlags |= DisplayList::AsTextFlag::IncludesPlatformOperations;
+
+ if (is<HTMLCanvasElement>(element))
+ return downcast<HTMLCanvasElement>(element).replayDisplayListAsText(displayListFlags);
+
+ if (!element.renderer()->hasLayer())
+ return Exception { INVALID_ACCESS_ERR };
+
+ RenderLayer* layer = downcast<RenderLayerModelObject>(element.renderer())->layer();
+ if (!layer->isComposited())
+ return Exception { INVALID_ACCESS_ERR };
+
+ return layer->backing()->replayDisplayListAsText(displayListFlags);
+}
+
+ExceptionOr<void> Internals::garbageCollectDocumentResources() const
+{
+ Document* document = contextDocument();
+ if (!document)
+ return Exception { INVALID_ACCESS_ERR };
+ document->cachedResourceLoader().garbageCollectDocumentResources();
+ return { };
+}
+
+bool Internals::isUnderMemoryPressure()
+{
+ return MemoryPressureHandler::singleton().isUnderMemoryPressure();
+}
+
+void Internals::beginSimulatedMemoryPressure()
+{
+ MemoryPressureHandler::singleton().beginSimulatedMemoryPressure();
+}
+
+void Internals::endSimulatedMemoryPressure()
+{
+ MemoryPressureHandler::singleton().endSimulatedMemoryPressure();
+}
+
+ExceptionOr<void> Internals::insertAuthorCSS(const String& css) const
+{
+ Document* document = contextDocument();
+ if (!document)
+ return Exception { INVALID_ACCESS_ERR };
auto parsedSheet = StyleSheetContents::create(*document);
parsedSheet.get().setIsUserStyleSheet(false);
parsedSheet.get().parseString(css);
- document->styleSheetCollection().addAuthorSheet(std::move(parsedSheet));
+ document->extensionStyleSheets().addAuthorStyleSheetForTesting(WTFMove(parsedSheet));
+ return { };
}
-void Internals::insertUserCSS(const String& css, ExceptionCode& ec) const
+ExceptionOr<void> Internals::insertUserCSS(const String& css) const
{
Document* document = contextDocument();
- if (!document) {
- ec = INVALID_ACCESS_ERR;
- return;
- }
+ if (!document)
+ return Exception { INVALID_ACCESS_ERR };
auto parsedSheet = StyleSheetContents::create(*document);
parsedSheet.get().setIsUserStyleSheet(true);
parsedSheet.get().parseString(css);
- document->styleSheetCollection().addUserSheet(std::move(parsedSheet));
+ document->extensionStyleSheets().addUserStyleSheet(WTFMove(parsedSheet));
+ return { };
}
-String Internals::counterValue(Element* element)
+String Internals::counterValue(Element& element)
{
- if (!element)
- return String();
+ return counterValueForElement(&element);
+}
- return counterValueForElement(element);
+int Internals::pageNumber(Element& element, float pageWidth, float pageHeight)
+{
+ return PrintContext::pageNumberForElement(&element, { pageWidth, pageHeight });
}
-int Internals::pageNumber(Element* element, float pageWidth, float pageHeight)
+Vector<String> Internals::shortcutIconURLs() const
{
- if (!element)
- return 0;
+ Vector<String> vector;
- return PrintContext::pageNumberForElement(element, FloatSize(pageWidth, pageHeight));
+ if (!frame())
+ return vector;
+
+ auto string = frame()->loader().icon().url().string();
+ if (!string.isNull())
+ vector.append(string);
+ return vector;
}
-Vector<String> Internals::iconURLs(Document* document, int iconTypesMask) const
+int Internals::numberOfPages(float pageWidth, float pageHeight)
{
- Vector<IconURL> iconURLs = document->iconURLs(iconTypesMask);
- Vector<String> array;
+ if (!frame())
+ return -1;
+
+ return PrintContext::numberOfPages(*frame(), FloatSize(pageWidth, pageHeight));
+}
- Vector<IconURL>::const_iterator iter(iconURLs.begin());
- for (; iter != iconURLs.end(); ++iter)
- array.append(iter->m_iconURL.string());
+ExceptionOr<String> Internals::pageProperty(const String& propertyName, int pageNumber) const
+{
+ if (!frame())
+ return Exception { INVALID_ACCESS_ERR };
- return array;
+ return PrintContext::pageProperty(frame(), propertyName.utf8().data(), pageNumber);
}
-Vector<String> Internals::shortcutIconURLs() const
+ExceptionOr<String> Internals::pageSizeAndMarginsInPixels(int pageNumber, int width, int height, int marginTop, int marginRight, int marginBottom, int marginLeft) const
{
- return iconURLs(contextDocument(), Favicon);
+ if (!frame())
+ return Exception { INVALID_ACCESS_ERR };
+
+ return PrintContext::pageSizeAndMarginsInPixels(frame(), pageNumber, width, height, marginTop, marginRight, marginBottom, marginLeft);
}
-Vector<String> Internals::allIconURLs() const
+ExceptionOr<float> Internals::pageScaleFactor() const
{
- return iconURLs(contextDocument(), Favicon | TouchIcon | TouchPrecomposedIcon);
+ Document* document = contextDocument();
+ if (!document || !document->page())
+ return Exception { INVALID_ACCESS_ERR };
+
+ return document->page()->pageScaleFactor();
}
-int Internals::numberOfPages(float pageWidth, float pageHeight)
+ExceptionOr<void> Internals::setPageScaleFactor(float scaleFactor, int x, int y)
{
- if (!frame())
- return -1;
+ Document* document = contextDocument();
+ if (!document || !document->page())
+ return Exception { INVALID_ACCESS_ERR };
- return PrintContext::numberOfPages(frame(), FloatSize(pageWidth, pageHeight));
+ document->page()->setPageScaleFactor(scaleFactor, IntPoint(x, y));
+ return { };
}
-String Internals::pageProperty(String propertyName, int pageNumber, ExceptionCode& ec) const
+ExceptionOr<void> Internals::setPageZoomFactor(float zoomFactor)
{
- if (!frame()) {
- ec = INVALID_ACCESS_ERR;
- return String();
- }
+ Document* document = contextDocument();
+ if (!document || !document->frame())
+ return Exception { INVALID_ACCESS_ERR };
- return PrintContext::pageProperty(frame(), propertyName.utf8().data(), pageNumber);
+ document->frame()->setPageZoomFactor(zoomFactor);
+ return { };
}
-String Internals::pageSizeAndMarginsInPixels(int pageNumber, int width, int height, int marginTop, int marginRight, int marginBottom, int marginLeft, ExceptionCode& ec) const
+ExceptionOr<void> Internals::setTextZoomFactor(float zoomFactor)
{
- if (!frame()) {
- ec = INVALID_ACCESS_ERR;
- return String();
- }
+ Document* document = contextDocument();
+ if (!document || !document->frame())
+ return Exception { INVALID_ACCESS_ERR };
- return PrintContext::pageSizeAndMarginsInPixels(frame(), pageNumber, width, height, marginTop, marginRight, marginBottom, marginLeft);
+ document->frame()->setTextZoomFactor(zoomFactor);
+ return { };
}
-void Internals::setPageScaleFactor(float scaleFactor, int x, int y, ExceptionCode& ec)
+ExceptionOr<void> Internals::setUseFixedLayout(bool useFixedLayout)
{
Document* document = contextDocument();
- if (!document || !document->page()) {
- ec = INVALID_ACCESS_ERR;
- return;
- }
- Page* page = document->page();
- page->setPageScaleFactor(scaleFactor, IntPoint(x, y));
+ if (!document || !document->view())
+ return Exception { INVALID_ACCESS_ERR };
+
+ document->view()->setUseFixedLayout(useFixedLayout);
+ return { };
+}
+
+ExceptionOr<void> Internals::setFixedLayoutSize(int width, int height)
+{
+ Document* document = contextDocument();
+ if (!document || !document->view())
+ return Exception { INVALID_ACCESS_ERR };
+
+ document->view()->setFixedLayoutSize(IntSize(width, height));
+ return { };
+}
+
+ExceptionOr<void> Internals::setViewExposedRect(float x, float y, float width, float height)
+{
+ Document* document = contextDocument();
+ if (!document || !document->view())
+ return Exception { INVALID_ACCESS_ERR };
+
+ document->view()->setViewExposedRect(FloatRect(x, y, width, height));
+ return { };
}
void Internals::setHeaderHeight(float height)
@@ -1755,12 +2382,8 @@ void Internals::setHeaderHeight(float height)
Document* document = contextDocument();
if (!document || !document->view())
return;
-#if USE(ACCELERATED_COMPOSITING)
- FrameView* frameView = document->view();
- frameView->setHeaderHeight(height);
-#else
- UNUSED_PARAM(height);
-#endif
+
+ document->view()->setHeaderHeight(height);
}
void Internals::setFooterHeight(float height)
@@ -1768,52 +2391,61 @@ void Internals::setFooterHeight(float height)
Document* document = contextDocument();
if (!document || !document->view())
return;
-#if USE(ACCELERATED_COMPOSITING)
- FrameView* frameView = document->view();
- frameView->setFooterHeight(height);
-#endif
+
+ document->view()->setFooterHeight(height);
+}
+
+void Internals::setTopContentInset(float contentInset)
+{
+ Document* document = contextDocument();
+ if (!document || !document->page())
+ return;
+
+ document->page()->setTopContentInset(contentInset);
}
#if ENABLE(FULLSCREEN_API)
-void Internals::webkitWillEnterFullScreenForElement(Element* element)
+
+void Internals::webkitWillEnterFullScreenForElement(Element& element)
{
Document* document = contextDocument();
if (!document)
return;
- document->webkitWillEnterFullScreenForElement(element);
+ document->webkitWillEnterFullScreenForElement(&element);
}
-void Internals::webkitDidEnterFullScreenForElement(Element* element)
+void Internals::webkitDidEnterFullScreenForElement(Element& element)
{
Document* document = contextDocument();
if (!document)
return;
- document->webkitDidEnterFullScreenForElement(element);
+ document->webkitDidEnterFullScreenForElement(&element);
}
-void Internals::webkitWillExitFullScreenForElement(Element* element)
+void Internals::webkitWillExitFullScreenForElement(Element& element)
{
Document* document = contextDocument();
if (!document)
return;
- document->webkitWillExitFullScreenForElement(element);
+ document->webkitWillExitFullScreenForElement(&element);
}
-void Internals::webkitDidExitFullScreenForElement(Element* element)
+void Internals::webkitDidExitFullScreenForElement(Element& element)
{
Document* document = contextDocument();
if (!document)
return;
- document->webkitDidExitFullScreenForElement(element);
+ document->webkitDidExitFullScreenForElement(&element);
}
+
#endif
void Internals::setApplicationCacheOriginQuota(unsigned long long quota)
{
Document* document = contextDocument();
- if (!document)
+ if (!document || !document->page())
return;
- cacheStorage().storeUpdatedQuotaForOrigin(document->securityOrigin(), quota);
+ document->page()->applicationCacheStorage().storeUpdatedQuotaForOrigin(&document->securityOrigin(), quota);
}
void Internals::registerURLSchemeAsBypassingContentSecurityPolicy(const String& scheme)
@@ -1826,17 +2458,22 @@ void Internals::removeURLSchemeRegisteredAsBypassingContentSecurityPolicy(const
SchemeRegistry::removeURLSchemeRegisteredAsBypassingContentSecurityPolicy(scheme);
}
-PassRefPtr<MallocStatistics> Internals::mallocStatistics() const
+void Internals::registerDefaultPortForProtocol(unsigned short port, const String& protocol)
+{
+ registerDefaultPortForProtocolForTesting(port, protocol);
+}
+
+Ref<MallocStatistics> Internals::mallocStatistics() const
{
return MallocStatistics::create();
}
-PassRefPtr<TypeConversions> Internals::typeConversions() const
+Ref<TypeConversions> Internals::typeConversions() const
{
return TypeConversions::create();
}
-PassRefPtr<MemoryInfo> Internals::memoryInfo() const
+Ref<MemoryInfo> Internals::memoryInfo() const
{
return MemoryInfo::create();
}
@@ -1847,50 +2484,113 @@ Vector<String> Internals::getReferencedFilePaths() const
return FormController::getReferencedFilePaths(frame()->loader().history().currentItem()->documentState());
}
-void Internals::startTrackingRepaints(ExceptionCode& ec)
+ExceptionOr<void> Internals::startTrackingRepaints()
{
Document* document = contextDocument();
- if (!document || !document->view()) {
- ec = INVALID_ACCESS_ERR;
- return;
- }
+ if (!document || !document->view())
+ return Exception { INVALID_ACCESS_ERR };
- FrameView* frameView = document->view();
- frameView->setTracksRepaints(true);
+ document->view()->setTracksRepaints(true);
+ return { };
}
-void Internals::stopTrackingRepaints(ExceptionCode& ec)
+ExceptionOr<void> Internals::stopTrackingRepaints()
{
Document* document = contextDocument();
- if (!document || !document->view()) {
- ec = INVALID_ACCESS_ERR;
- return;
- }
+ if (!document || !document->view())
+ return Exception { INVALID_ACCESS_ERR };
+
+ document->view()->setTracksRepaints(false);
+ return { };
+}
+
+ExceptionOr<void> Internals::startTrackingLayerFlushes()
+{
+ Document* document = contextDocument();
+ if (!document || !document->renderView())
+ return Exception { INVALID_ACCESS_ERR };
+
+ document->renderView()->compositor().startTrackingLayerFlushes();
+ return { };
+}
- FrameView* frameView = document->view();
- frameView->setTracksRepaints(false);
+ExceptionOr<unsigned> Internals::layerFlushCount()
+{
+ Document* document = contextDocument();
+ if (!document || !document->renderView())
+ return Exception { INVALID_ACCESS_ERR };
+
+ return document->renderView()->compositor().layerFlushCount();
}
-void Internals::updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks(ExceptionCode& ec)
+ExceptionOr<void> Internals::startTrackingStyleRecalcs()
{
- updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks(nullptr, ec);
+ Document* document = contextDocument();
+ if (!document)
+ return Exception { INVALID_ACCESS_ERR };
+
+ document->startTrackingStyleRecalcs();
+ return { };
}
-void Internals::updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks(Node* node, ExceptionCode& ec)
+ExceptionOr<unsigned> Internals::styleRecalcCount()
+{
+ Document* document = contextDocument();
+ if (!document)
+ return Exception { INVALID_ACCESS_ERR };
+
+ return document->styleRecalcCount();
+}
+
+unsigned Internals::lastStyleUpdateSize() const
+{
+ Document* document = contextDocument();
+ if (!document)
+ return 0;
+ return document->lastStyleUpdateSizeForTesting();
+}
+
+ExceptionOr<void> Internals::startTrackingCompositingUpdates()
+{
+ Document* document = contextDocument();
+ if (!document || !document->renderView())
+ return Exception { INVALID_ACCESS_ERR };
+
+ document->renderView()->compositor().startTrackingCompositingUpdates();
+ return { };
+}
+
+ExceptionOr<unsigned> Internals::compositingUpdateCount()
+{
+ Document* document = contextDocument();
+ if (!document || !document->renderView())
+ return Exception { INVALID_ACCESS_ERR };
+
+ return document->renderView()->compositor().compositingUpdateCount();
+}
+
+ExceptionOr<void> Internals::updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks(Node* node)
{
Document* document;
if (!node)
document = contextDocument();
- else if (node->isDocumentNode())
- document = toDocument(node);
- else if (node->hasTagName(HTMLNames::iframeTag))
- document = toHTMLIFrameElement(node)->contentDocument();
- else {
- ec = TypeError;
- return;
- }
+ else if (is<Document>(*node))
+ document = downcast<Document>(node);
+ else if (is<HTMLIFrameElement>(*node))
+ document = downcast<HTMLIFrameElement>(*node).contentDocument();
+ else
+ return Exception { TypeError };
- document->updateLayoutIgnorePendingStylesheets(Document::RunPostLayoutTasksSynchronously);
+ document->updateLayoutIgnorePendingStylesheets(Document::RunPostLayoutTasks::Synchronously);
+ return { };
+}
+
+unsigned Internals::layoutCount() const
+{
+ Document* document = contextDocument();
+ if (!document || !document->view())
+ return 0;
+ return document->view()->layoutCount();
}
#if !PLATFORM(IOS)
@@ -1948,55 +2648,59 @@ static const char* cursorTypeToString(Cursor::Type cursorType)
}
#endif
-String Internals::getCurrentCursorInfo(ExceptionCode& ec)
+ExceptionOr<String> Internals::getCurrentCursorInfo()
{
Document* document = contextDocument();
- if (!document || !document->frame()) {
- ec = INVALID_ACCESS_ERR;
- return String();
- }
+ if (!document || !document->frame())
+ return Exception { INVALID_ACCESS_ERR };
#if !PLATFORM(IOS)
Cursor cursor = document->frame()->eventHandler().currentMouseCursor();
StringBuilder result;
- result.append("type=");
+ result.appendLiteral("type=");
result.append(cursorTypeToString(cursor.type()));
- result.append(" hotSpot=");
+ result.appendLiteral(" hotSpot=");
result.appendNumber(cursor.hotSpot().x());
- result.append(",");
+ result.append(',');
result.appendNumber(cursor.hotSpot().y());
if (cursor.image()) {
- IntSize size = cursor.image()->size();
- result.append(" image=");
+ FloatSize size = cursor.image()->size();
+ result.appendLiteral(" image=");
result.appendNumber(size.width());
- result.append("x");
+ result.append('x');
result.appendNumber(size.height());
}
#if ENABLE(MOUSE_CURSOR_SCALE)
if (cursor.imageScaleFactor() != 1) {
- result.append(" scale=");
+ result.appendLiteral(" scale=");
NumberToStringBuffer buffer;
result.append(numberToFixedPrecisionString(cursor.imageScaleFactor(), 8, buffer, true));
}
#endif
return result.toString();
#else
- return "FAIL: Cursor details not available on this platform.";
+ return String { "FAIL: Cursor details not available on this platform." };
#endif
}
-PassRefPtr<ArrayBuffer> Internals::serializeObject(PassRefPtr<SerializedScriptValue> value) const
+Ref<ArrayBuffer> Internals::serializeObject(const RefPtr<SerializedScriptValue>& value) const
{
- Vector<uint8_t> bytes = value->data();
+ auto& bytes = value->data();
return ArrayBuffer::create(bytes.data(), bytes.size());
}
-PassRefPtr<SerializedScriptValue> Internals::deserializeBuffer(PassRefPtr<ArrayBuffer> buffer) const
+Ref<SerializedScriptValue> Internals::deserializeBuffer(ArrayBuffer& buffer) const
{
Vector<uint8_t> bytes;
- bytes.append(static_cast<const uint8_t*>(buffer->data()), buffer->byteLength());
- return SerializedScriptValue::adopt(bytes);
+ bytes.append(static_cast<const uint8_t*>(buffer.data()), buffer.byteLength());
+ return SerializedScriptValue::adopt(WTFMove(bytes));
+}
+
+bool Internals::isFromCurrentWorld(JSC::JSValue value) const
+{
+ auto& state = *contextDocument()->vm().topCallFrame;
+ return !value.isObject() || &worldForDOMObject(asObject(value)) == &currentWorld(&state);
}
void Internals::setUsesOverlayScrollbars(bool enabled)
@@ -2004,247 +2708,1008 @@ void Internals::setUsesOverlayScrollbars(bool enabled)
WebCore::Settings::setUsesOverlayScrollbars(enabled);
}
+void Internals::setUsesMockScrollAnimator(bool enabled)
+{
+ WebCore::Settings::setUsesMockScrollAnimator(enabled);
+}
+
void Internals::forceReload(bool endToEnd)
{
frame()->loader().reload(endToEnd);
}
-#if ENABLE(ENCRYPTED_MEDIA_V2)
+void Internals::enableAutoSizeMode(bool enabled, int minimumWidth, int minimumHeight, int maximumWidth, int maximumHeight)
+{
+ auto* document = contextDocument();
+ if (!document || !document->view())
+ return;
+ document->view()->enableAutoSizeMode(enabled, IntSize(minimumWidth, minimumHeight), IntSize(maximumWidth, maximumHeight));
+}
+
+#if ENABLE(LEGACY_ENCRYPTED_MEDIA)
+
void Internals::initializeMockCDM()
{
- CDM::registerCDMFactory(MockCDM::create, MockCDM::supportsKeySystem, MockCDM::supportsKeySystemAndMimeType);
+ CDM::registerCDMFactory([] (CDM* cdm) { return std::make_unique<MockCDM>(cdm); },
+ MockCDM::supportsKeySystem, MockCDM::supportsKeySystemAndMimeType);
}
+
#endif
-String Internals::markerTextForListItem(Element* element, ExceptionCode& ec)
+#if ENABLE(ENCRYPTED_MEDIA)
+
+Ref<MockCDMFactory> Internals::registerMockCDM()
{
- if (!element) {
- ec = INVALID_ACCESS_ERR;
- return String();
- }
- return WebCore::markerTextForListItem(element);
+ return MockCDMFactory::create();
}
-String Internals::getImageSourceURL(Element* element, ExceptionCode& ec)
+#endif
+
+String Internals::markerTextForListItem(Element& element)
{
- if (!element) {
- ec = INVALID_ACCESS_ERR;
- return String();
- }
- return element->imageSourceURL();
+ return WebCore::markerTextForListItem(&element);
+}
+
+String Internals::toolTipFromElement(Element& element) const
+{
+ HitTestResult result;
+ result.setInnerNode(&element);
+ TextDirection direction;
+ return result.title(direction);
+}
+
+String Internals::getImageSourceURL(Element& element)
+{
+ return element.imageSourceURL();
}
#if ENABLE(VIDEO)
-void Internals::simulateAudioInterruption(Node* node)
+
+void Internals::simulateAudioInterruption(HTMLMediaElement& element)
{
#if USE(GSTREAMER)
- HTMLMediaElement* element = toHTMLMediaElement(node);
- element->player()->simulateAudioInterruption();
+ element.player()->simulateAudioInterruption();
#else
- UNUSED_PARAM(node);
+ UNUSED_PARAM(element);
#endif
}
-#endif
-bool Internals::isSelectPopupVisible(Node* node)
+ExceptionOr<bool> Internals::mediaElementHasCharacteristic(HTMLMediaElement& element, const String& characteristic)
{
- if (!isHTMLSelectElement(node))
- return false;
+ if (equalLettersIgnoringASCIICase(characteristic, "audible"))
+ return element.hasAudio();
+ if (equalLettersIgnoringASCIICase(characteristic, "visual"))
+ return element.hasVideo();
+ if (equalLettersIgnoringASCIICase(characteristic, "legible"))
+ return element.hasClosedCaptions();
+
+ return Exception { SYNTAX_ERR };
+}
- HTMLSelectElement* select = toHTMLSelectElement(node);
+#endif
- auto renderer = select->renderer();
- if (!renderer->isMenuList())
+bool Internals::isSelectPopupVisible(HTMLSelectElement& element)
+{
+ auto* renderer = element.renderer();
+ ASSERT(renderer);
+ if (!is<RenderMenuList>(*renderer))
return false;
#if !PLATFORM(IOS)
- RenderMenuList* menuList = toRenderMenuList(renderer);
- return menuList->popupIsVisible();
+ return downcast<RenderMenuList>(*renderer).popupIsVisible();
#else
return false;
-#endif // !PLATFORM(IOS)
+#endif
}
-String Internals::captionsStyleSheetOverride(ExceptionCode& ec)
+ExceptionOr<String> Internals::captionsStyleSheetOverride()
{
Document* document = contextDocument();
- if (!document || !document->page()) {
- ec = INVALID_ACCESS_ERR;
- return emptyString();
- }
+ if (!document || !document->page())
+ return Exception { INVALID_ACCESS_ERR };
-#if ENABLE(VIDEO_TRACK) && !PLATFORM(WIN)
- return document->page()->group().captionPreferences()->captionsStyleSheetOverride();
+#if ENABLE(VIDEO_TRACK)
+ return document->page()->group().captionPreferences().captionsStyleSheetOverride();
#else
- return emptyString();
+ return String { emptyString() };
#endif
}
-void Internals::setCaptionsStyleSheetOverride(const String& override, ExceptionCode& ec)
+ExceptionOr<void> Internals::setCaptionsStyleSheetOverride(const String& override)
{
Document* document = contextDocument();
- if (!document || !document->page()) {
- ec = INVALID_ACCESS_ERR;
- return;
- }
+ if (!document || !document->page())
+ return Exception { INVALID_ACCESS_ERR };
-#if ENABLE(VIDEO_TRACK) && !PLATFORM(WIN)
- document->page()->group().captionPreferences()->setCaptionsStyleSheetOverride(override);
+#if ENABLE(VIDEO_TRACK)
+ document->page()->group().captionPreferences().setCaptionsStyleSheetOverride(override);
#else
UNUSED_PARAM(override);
#endif
+ return { };
}
-void Internals::setPrimaryAudioTrackLanguageOverride(const String& language, ExceptionCode& ec)
+ExceptionOr<void> Internals::setPrimaryAudioTrackLanguageOverride(const String& language)
{
Document* document = contextDocument();
- if (!document || !document->page()) {
- ec = INVALID_ACCESS_ERR;
- return;
- }
+ if (!document || !document->page())
+ return Exception { INVALID_ACCESS_ERR };
-#if ENABLE(VIDEO_TRACK) && !PLATFORM(WIN)
- document->page()->group().captionPreferences()->setPrimaryAudioTrackLanguageOverride(language);
+#if ENABLE(VIDEO_TRACK)
+ document->page()->group().captionPreferences().setPrimaryAudioTrackLanguageOverride(language);
#else
UNUSED_PARAM(language);
#endif
+ return { };
}
-void Internals::setCaptionDisplayMode(const String& mode, ExceptionCode& ec)
+ExceptionOr<void> Internals::setCaptionDisplayMode(const String& mode)
{
Document* document = contextDocument();
- if (!document || !document->page()) {
- ec = INVALID_ACCESS_ERR;
- return;
- }
+ if (!document || !document->page())
+ return Exception { INVALID_ACCESS_ERR };
-#if ENABLE(VIDEO_TRACK) && !PLATFORM(WIN)
- CaptionUserPreferences* captionPreferences = document->page()->group().captionPreferences();
+#if ENABLE(VIDEO_TRACK)
+ auto& captionPreferences = document->page()->group().captionPreferences();
- if (equalIgnoringCase(mode, "Automatic"))
- captionPreferences->setCaptionDisplayMode(CaptionUserPreferences::Automatic);
- else if (equalIgnoringCase(mode, "ForcedOnly"))
- captionPreferences->setCaptionDisplayMode(CaptionUserPreferences::ForcedOnly);
- else if (equalIgnoringCase(mode, "AlwaysOn"))
- captionPreferences->setCaptionDisplayMode(CaptionUserPreferences::AlwaysOn);
+ if (equalLettersIgnoringASCIICase(mode, "automatic"))
+ captionPreferences.setCaptionDisplayMode(CaptionUserPreferences::Automatic);
+ else if (equalLettersIgnoringASCIICase(mode, "forcedonly"))
+ captionPreferences.setCaptionDisplayMode(CaptionUserPreferences::ForcedOnly);
+ else if (equalLettersIgnoringASCIICase(mode, "alwayson"))
+ captionPreferences.setCaptionDisplayMode(CaptionUserPreferences::AlwaysOn);
+ else if (equalLettersIgnoringASCIICase(mode, "manual"))
+ captionPreferences.setCaptionDisplayMode(CaptionUserPreferences::Manual);
else
- ec = SYNTAX_ERR;
+ return Exception { SYNTAX_ERR };
#else
UNUSED_PARAM(mode);
#endif
+ return { };
}
#if ENABLE(VIDEO)
-PassRefPtr<TimeRanges> Internals::createTimeRanges(Float32Array* startTimes, Float32Array* endTimes)
+
+Ref<TimeRanges> Internals::createTimeRanges(Float32Array& startTimes, Float32Array& endTimes)
{
- ASSERT(startTimes && endTimes);
- ASSERT(startTimes->length() == endTimes->length());
- RefPtr<TimeRanges> ranges = TimeRanges::create();
+ ASSERT(startTimes.length() == endTimes.length());
+ Ref<TimeRanges> ranges = TimeRanges::create();
- unsigned count = std::min(startTimes->length(), endTimes->length());
+ unsigned count = std::min(startTimes.length(), endTimes.length());
for (unsigned i = 0; i < count; ++i)
- ranges->add(startTimes->item(i), endTimes->item(i));
+ ranges->add(startTimes.item(i), endTimes.item(i));
return ranges;
}
-double Internals::closestTimeToTimeRanges(double time, TimeRanges* ranges)
+double Internals::closestTimeToTimeRanges(double time, TimeRanges& ranges)
{
- return ranges->nearest(time);
+ return ranges.nearest(time);
}
+
#endif
-PassRefPtr<ClientRect> Internals::selectionBounds(ExceptionCode& ec)
+ExceptionOr<Ref<ClientRect>> Internals::selectionBounds()
{
Document* document = contextDocument();
- if (!document || !document->frame()) {
- ec = INVALID_ACCESS_ERR;
- return ClientRect::create();
- }
+ if (!document || !document->frame())
+ return Exception { INVALID_ACCESS_ERR };
- return ClientRect::create(document->frame()->selection().bounds());
+ return ClientRect::create(document->frame()->selection().selectionBounds());
}
#if ENABLE(VIBRATION)
+
bool Internals::isVibrating()
{
- Page* page = contextDocument()->page();
- ASSERT(page);
-
- return Vibration::from(page)->isVibrating();
+ auto* document = contextDocument();
+ auto* page = document ? document->page() : nullptr;
+ return page && Vibration::from(page)->isVibrating();
}
+
#endif
-bool Internals::isPluginUnavailabilityIndicatorObscured(Element* element, ExceptionCode& ec)
+ExceptionOr<bool> Internals::isPluginUnavailabilityIndicatorObscured(Element& element)
{
- if (!element) {
- ec = INVALID_ACCESS_ERR;
- return false;
- }
-
- auto renderer = element->renderer();
- if (!renderer || !renderer->isEmbeddedObject()) {
- ec = INVALID_ACCESS_ERR;
- return false;
- }
+ auto* renderer = element.renderer();
+ if (!is<RenderEmbeddedObject>(renderer))
+ return Exception { INVALID_ACCESS_ERR };
- RenderEmbeddedObject* embed = toRenderEmbeddedObject(renderer);
- return embed->isReplacementObscured();
+ return downcast<RenderEmbeddedObject>(*renderer).isReplacementObscured();
}
-
+
+bool Internals::isPluginSnapshotted(Element& element)
+{
+ return is<HTMLPlugInElement>(element) && downcast<HTMLPlugInElement>(element).displayState() <= HTMLPlugInElement::DisplayingSnapshot;
+}
+
#if ENABLE(MEDIA_SOURCE)
+
void Internals::initializeMockMediaSource()
{
#if USE(AVFOUNDATION)
WebCore::Settings::setAVFoundationEnabled(false);
#endif
+#if USE(GSTREAMER)
+ WebCore::Settings::setGStreamerEnabled(false);
+#endif
MediaPlayerFactorySupport::callRegisterMediaEngine(MockMediaPlayerMediaSource::registerMediaEngine);
}
+
+Vector<String> Internals::bufferedSamplesForTrackID(SourceBuffer& buffer, const AtomicString& trackID)
+{
+ return buffer.bufferedSamplesForTrackID(trackID);
+}
+
+Vector<String> Internals::enqueuedSamplesForTrackID(SourceBuffer& buffer, const AtomicString& trackID)
+{
+ return buffer.enqueuedSamplesForTrackID(trackID);
+}
+
+void Internals::setShouldGenerateTimestamps(SourceBuffer& buffer, bool flag)
+{
+ buffer.setShouldGenerateTimestamps(flag);
+}
+
#endif
-void Internals::beginMediaSessionInterruption()
+#if ENABLE(VIDEO)
+
+ExceptionOr<void> Internals::beginMediaSessionInterruption(const String& interruptionString)
{
- MediaSessionManager::sharedManager().beginInterruption();
+ PlatformMediaSession::InterruptionType interruption = PlatformMediaSession::SystemInterruption;
+
+ if (equalLettersIgnoringASCIICase(interruptionString, "system"))
+ interruption = PlatformMediaSession::SystemInterruption;
+ else if (equalLettersIgnoringASCIICase(interruptionString, "systemsleep"))
+ interruption = PlatformMediaSession::SystemSleep;
+ else if (equalLettersIgnoringASCIICase(interruptionString, "enteringbackground"))
+ interruption = PlatformMediaSession::EnteringBackground;
+ else if (equalLettersIgnoringASCIICase(interruptionString, "suspendedunderlock"))
+ interruption = PlatformMediaSession::SuspendedUnderLock;
+ else
+ return Exception { INVALID_ACCESS_ERR };
+
+ PlatformMediaSessionManager::sharedManager().beginInterruption(interruption);
+ return { };
}
void Internals::endMediaSessionInterruption(const String& flagsString)
{
- MediaSession::EndInterruptionFlags flags = MediaSession::NoFlags;
+ PlatformMediaSession::EndInterruptionFlags flags = PlatformMediaSession::NoFlags;
- if (equalIgnoringCase(flagsString, "MayResumePlaying"))
- flags = MediaSession::MayResumePlaying;
+ if (equalLettersIgnoringASCIICase(flagsString, "mayresumeplaying"))
+ flags = PlatformMediaSession::MayResumePlaying;
- MediaSessionManager::sharedManager().endInterruption(flags);
+ PlatformMediaSessionManager::sharedManager().endInterruption(flags);
+}
+
+void Internals::applicationDidEnterForeground() const
+{
+ PlatformMediaSessionManager::sharedManager().applicationDidEnterForeground();
+}
+
+void Internals::applicationWillEnterBackground() const
+{
+ PlatformMediaSessionManager::sharedManager().applicationWillEnterBackground();
+}
+
+static PlatformMediaSession::MediaType mediaTypeFromString(const String& mediaTypeString)
+{
+ if (equalLettersIgnoringASCIICase(mediaTypeString, "video"))
+ return PlatformMediaSession::Video;
+ if (equalLettersIgnoringASCIICase(mediaTypeString, "audio"))
+ return PlatformMediaSession::Audio;
+ if (equalLettersIgnoringASCIICase(mediaTypeString, "videoaudio"))
+ return PlatformMediaSession::VideoAudio;
+ if (equalLettersIgnoringASCIICase(mediaTypeString, "webaudio"))
+ return PlatformMediaSession::WebAudio;
+
+ return PlatformMediaSession::None;
+}
+
+ExceptionOr<void> Internals::setMediaSessionRestrictions(const String& mediaTypeString, const String& restrictionsString)
+{
+ PlatformMediaSession::MediaType mediaType = mediaTypeFromString(mediaTypeString);
+ if (mediaType == PlatformMediaSession::None)
+ return Exception { INVALID_ACCESS_ERR };
+
+ PlatformMediaSessionManager::SessionRestrictions restrictions = PlatformMediaSessionManager::sharedManager().restrictions(mediaType);
+ PlatformMediaSessionManager::sharedManager().removeRestriction(mediaType, restrictions);
+
+ restrictions = PlatformMediaSessionManager::NoRestrictions;
+
+ Vector<String> restrictionsArray;
+ restrictionsString.split(',', false, restrictionsArray);
+ for (auto& restrictionString : restrictionsArray) {
+ if (equalLettersIgnoringASCIICase(restrictionString, "concurrentplaybacknotpermitted"))
+ restrictions |= PlatformMediaSessionManager::ConcurrentPlaybackNotPermitted;
+ if (equalLettersIgnoringASCIICase(restrictionString, "backgroundprocessplaybackrestricted"))
+ restrictions |= PlatformMediaSessionManager::BackgroundProcessPlaybackRestricted;
+ if (equalLettersIgnoringASCIICase(restrictionString, "backgroundtabplaybackrestricted"))
+ restrictions |= PlatformMediaSessionManager::BackgroundTabPlaybackRestricted;
+ if (equalLettersIgnoringASCIICase(restrictionString, "interruptedplaybacknotpermitted"))
+ restrictions |= PlatformMediaSessionManager::InterruptedPlaybackNotPermitted;
+ }
+ PlatformMediaSessionManager::sharedManager().addRestriction(mediaType, restrictions);
+ return { };
+}
+
+ExceptionOr<String> Internals::mediaSessionRestrictions(const String& mediaTypeString) const
+{
+ PlatformMediaSession::MediaType mediaType = mediaTypeFromString(mediaTypeString);
+ if (mediaType == PlatformMediaSession::None)
+ return Exception { INVALID_ACCESS_ERR };
+
+ PlatformMediaSessionManager::SessionRestrictions restrictions = PlatformMediaSessionManager::sharedManager().restrictions(mediaType);
+ if (restrictions == PlatformMediaSessionManager::NoRestrictions)
+ return String();
+
+ StringBuilder builder;
+ if (restrictions & PlatformMediaSessionManager::ConcurrentPlaybackNotPermitted)
+ builder.append("concurrentplaybacknotpermitted");
+ if (restrictions & PlatformMediaSessionManager::BackgroundProcessPlaybackRestricted) {
+ if (!builder.isEmpty())
+ builder.append(',');
+ builder.append("backgroundprocessplaybackrestricted");
+ }
+ if (restrictions & PlatformMediaSessionManager::BackgroundTabPlaybackRestricted) {
+ if (!builder.isEmpty())
+ builder.append(',');
+ builder.append("backgroundtabplaybackrestricted");
+ }
+ if (restrictions & PlatformMediaSessionManager::InterruptedPlaybackNotPermitted) {
+ if (!builder.isEmpty())
+ builder.append(',');
+ builder.append("interruptedplaybacknotpermitted");
+ }
+ return builder.toString();
+}
+
+void Internals::setMediaElementRestrictions(HTMLMediaElement& element, const String& restrictionsString)
+{
+ MediaElementSession::BehaviorRestrictions restrictions = element.mediaSession().behaviorRestrictions();
+ element.mediaSession().removeBehaviorRestriction(restrictions);
+
+ restrictions = MediaElementSession::NoRestrictions;
+
+ Vector<String> restrictionsArray;
+ restrictionsString.split(',', false, restrictionsArray);
+ for (auto& restrictionString : restrictionsArray) {
+ if (equalLettersIgnoringASCIICase(restrictionString, "norestrictions"))
+ restrictions |= MediaElementSession::NoRestrictions;
+ if (equalLettersIgnoringASCIICase(restrictionString, "requireusergestureforload"))
+ restrictions |= MediaElementSession::RequireUserGestureForLoad;
+ if (equalLettersIgnoringASCIICase(restrictionString, "requireusergestureforvideoratechange"))
+ restrictions |= MediaElementSession::RequireUserGestureForVideoRateChange;
+ if (equalLettersIgnoringASCIICase(restrictionString, "requireusergestureforfullscreen"))
+ restrictions |= MediaElementSession::RequireUserGestureForFullscreen;
+ if (equalLettersIgnoringASCIICase(restrictionString, "requirepageconsenttoloadmedia"))
+ restrictions |= MediaElementSession::RequirePageConsentToLoadMedia;
+ if (equalLettersIgnoringASCIICase(restrictionString, "requirepageconsenttoresumemedia"))
+ restrictions |= MediaElementSession::RequirePageConsentToResumeMedia;
+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+ if (equalLettersIgnoringASCIICase(restrictionString, "requireusergesturetoshowplaybacktargetpicker"))
+ restrictions |= MediaElementSession::RequireUserGestureToShowPlaybackTargetPicker;
+ if (equalLettersIgnoringASCIICase(restrictionString, "wirelessvideoplaybackdisabled"))
+ restrictions |= MediaElementSession::WirelessVideoPlaybackDisabled;
+#endif
+ if (equalLettersIgnoringASCIICase(restrictionString, "requireusergestureforaudioratechange"))
+ restrictions |= MediaElementSession::RequireUserGestureForAudioRateChange;
+ if (equalLettersIgnoringASCIICase(restrictionString, "metadatapreloadingnotpermitted"))
+ restrictions |= MediaElementSession::MetadataPreloadingNotPermitted;
+ if (equalLettersIgnoringASCIICase(restrictionString, "autopreloadingnotpermitted"))
+ restrictions |= MediaElementSession::AutoPreloadingNotPermitted;
+ if (equalLettersIgnoringASCIICase(restrictionString, "invisibleautoplaynotpermitted"))
+ restrictions |= MediaElementSession::InvisibleAutoplayNotPermitted;
+ if (equalLettersIgnoringASCIICase(restrictionString, "overrideusergesturerequirementformaincontent"))
+ restrictions |= MediaElementSession::OverrideUserGestureRequirementForMainContent;
+ }
+ element.mediaSession().addBehaviorRestriction(restrictions);
+}
+
+ExceptionOr<void> Internals::postRemoteControlCommand(const String& commandString, float argument)
+{
+ PlatformMediaSession::RemoteControlCommandType command;
+ PlatformMediaSession::RemoteCommandArgument parameter { argument };
+
+ if (equalLettersIgnoringASCIICase(commandString, "play"))
+ command = PlatformMediaSession::PlayCommand;
+ else if (equalLettersIgnoringASCIICase(commandString, "pause"))
+ command = PlatformMediaSession::PauseCommand;
+ else if (equalLettersIgnoringASCIICase(commandString, "stop"))
+ command = PlatformMediaSession::StopCommand;
+ else if (equalLettersIgnoringASCIICase(commandString, "toggleplaypause"))
+ command = PlatformMediaSession::TogglePlayPauseCommand;
+ else if (equalLettersIgnoringASCIICase(commandString, "beginseekingbackward"))
+ command = PlatformMediaSession::BeginSeekingBackwardCommand;
+ else if (equalLettersIgnoringASCIICase(commandString, "endseekingbackward"))
+ command = PlatformMediaSession::EndSeekingBackwardCommand;
+ else if (equalLettersIgnoringASCIICase(commandString, "beginseekingforward"))
+ command = PlatformMediaSession::BeginSeekingForwardCommand;
+ else if (equalLettersIgnoringASCIICase(commandString, "endseekingforward"))
+ command = PlatformMediaSession::EndSeekingForwardCommand;
+ else if (equalLettersIgnoringASCIICase(commandString, "seektoplaybackposition"))
+ command = PlatformMediaSession::SeekToPlaybackPositionCommand;
+ else
+ return Exception { INVALID_ACCESS_ERR };
+
+ PlatformMediaSessionManager::sharedManager().didReceiveRemoteControlCommand(command, &parameter);
+ return { };
+}
+
+bool Internals::elementIsBlockingDisplaySleep(HTMLMediaElement& element) const
+{
+ return element.isDisablingSleep();
+}
+
+#endif // ENABLE(VIDEO)
+
+#if ENABLE(MEDIA_SESSION)
+
+void Internals::sendMediaSessionStartOfInterruptionNotification(MediaSessionInterruptingCategory category)
+{
+ MediaSessionManager::singleton().didReceiveStartOfInterruptionNotification(category);
+}
+
+void Internals::sendMediaSessionEndOfInterruptionNotification(MediaSessionInterruptingCategory category)
+{
+ MediaSessionManager::singleton().didReceiveEndOfInterruptionNotification(category);
+}
+
+String Internals::mediaSessionCurrentState(MediaSession* session) const
+{
+ switch (session->currentState()) {
+ case MediaSession::State::Active:
+ return "active";
+ case MediaSession::State::Interrupted:
+ return "interrupted";
+ case MediaSession::State::Idle:
+ return "idle";
+ }
+}
+
+double Internals::mediaElementPlayerVolume(HTMLMediaElement* element) const
+{
+ ASSERT_ARG(element, element);
+ return element->playerVolume();
+}
+
+void Internals::sendMediaControlEvent(MediaControlEvent event)
+{
+ // FIXME: No good reason to use a single function with an argument instead of three functions.
+ switch (event) {
+ case MediControlEvent::PlayPause:
+ MediaSessionManager::singleton().togglePlayback();
+ break;
+ case MediControlEvent::NextTrack:
+ MediaSessionManager::singleton().skipToNextTrack();
+ break;
+ case MediControlEvent::PreviousTrack:
+ MediaSessionManager::singleton().skipToPreviousTrack();
+ break;
+ }
+}
+
+#endif // ENABLE(MEDIA_SESSION)
+
+#if ENABLE(WEB_AUDIO)
+
+void Internals::setAudioContextRestrictions(AudioContext& context, const String& restrictionsString)
+{
+ AudioContext::BehaviorRestrictions restrictions = context.behaviorRestrictions();
+ context.removeBehaviorRestriction(restrictions);
+
+ restrictions = AudioContext::NoRestrictions;
+
+ Vector<String> restrictionsArray;
+ restrictionsString.split(',', false, restrictionsArray);
+ for (auto& restrictionString : restrictionsArray) {
+ if (equalLettersIgnoringASCIICase(restrictionString, "norestrictions"))
+ restrictions |= AudioContext::NoRestrictions;
+ if (equalLettersIgnoringASCIICase(restrictionString, "requireusergestureforaudiostart"))
+ restrictions |= AudioContext::RequireUserGestureForAudioStartRestriction;
+ if (equalLettersIgnoringASCIICase(restrictionString, "requirepageconsentforaudiostart"))
+ restrictions |= AudioContext::RequirePageConsentForAudioStartRestriction;
+ }
+ context.addBehaviorRestriction(restrictions);
+}
+
+#endif
+
+void Internals::simulateSystemSleep() const
+{
+#if ENABLE(VIDEO)
+ PlatformMediaSessionManager::sharedManager().systemWillSleep();
+#endif
}
-void Internals::setMediaSessionRestrictions(const String& mediaTypeString, const String& restrictionsString, ExceptionCode& ec)
+void Internals::simulateSystemWake() const
{
- MediaSession::MediaType mediaType = MediaSession::None;
- if (equalIgnoringCase(mediaTypeString, "Video"))
- mediaType = MediaSession::Video;
- else if (equalIgnoringCase(mediaTypeString, "Audio"))
- mediaType = MediaSession::Audio;
- else if (equalIgnoringCase(mediaTypeString, "WebAudio"))
- mediaType = MediaSession::WebAudio;
- else {
- ec = INVALID_ACCESS_ERR;
+#if ENABLE(VIDEO)
+ PlatformMediaSessionManager::sharedManager().systemDidWake();
+#endif
+}
+
+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+
+void Internals::setMockMediaPlaybackTargetPickerEnabled(bool enabled)
+{
+ Page* page = contextDocument()->frame()->page();
+ ASSERT(page);
+
+ page->setMockMediaPlaybackTargetPickerEnabled(enabled);
+}
+
+ExceptionOr<void> Internals::setMockMediaPlaybackTargetPickerState(const String& deviceName, const String& deviceState)
+{
+ Page* page = contextDocument()->frame()->page();
+ ASSERT(page);
+
+ MediaPlaybackTargetContext::State state = MediaPlaybackTargetContext::Unknown;
+
+ if (equalLettersIgnoringASCIICase(deviceState, "deviceavailable"))
+ state = MediaPlaybackTargetContext::OutputDeviceAvailable;
+ else if (equalLettersIgnoringASCIICase(deviceState, "deviceunavailable"))
+ state = MediaPlaybackTargetContext::OutputDeviceUnavailable;
+ else if (equalLettersIgnoringASCIICase(deviceState, "unknown"))
+ state = MediaPlaybackTargetContext::Unknown;
+ else
+ return Exception { INVALID_ACCESS_ERR };
+
+ page->setMockMediaPlaybackTargetPickerState(deviceName, state);
+ return { };
+}
+
+#endif
+
+ExceptionOr<Ref<MockPageOverlay>> Internals::installMockPageOverlay(PageOverlayType type)
+{
+ Document* document = contextDocument();
+ if (!document || !document->frame())
+ return Exception { INVALID_ACCESS_ERR };
+
+ return MockPageOverlayClient::singleton().installOverlay(document->frame()->mainFrame(), type == PageOverlayType::View ? PageOverlay::OverlayType::View : PageOverlay::OverlayType::Document);
+}
+
+ExceptionOr<String> Internals::pageOverlayLayerTreeAsText(unsigned short flags) const
+{
+ Document* document = contextDocument();
+ if (!document || !document->frame())
+ return Exception { INVALID_ACCESS_ERR };
+
+ document->updateLayout();
+
+ return MockPageOverlayClient::singleton().layerTreeAsText(document->frame()->mainFrame(), toLayerTreeFlags(flags));
+}
+
+void Internals::setPageMuted(const String& states)
+{
+ Document* document = contextDocument();
+ if (!document)
+ return;
+
+ WebCore::MediaProducer::MutedStateFlags state = MediaProducer::NoneMuted;
+ Vector<String> stateString;
+ states.split(',', false, stateString);
+ for (auto& muteString : stateString) {
+ if (equalLettersIgnoringASCIICase(muteString, "audio"))
+ state |= MediaProducer::AudioIsMuted;
+ if (equalLettersIgnoringASCIICase(muteString, "capturedevices"))
+ state |= MediaProducer::CaptureDevicesAreMuted;
+ }
+
+ if (Page* page = document->page())
+ page->setMuted(state);
+}
+
+String Internals::pageMediaState()
+{
+ Document* document = contextDocument();
+ if (!document || !document->page())
+ return emptyString();
+
+ WebCore::MediaProducer::MediaStateFlags state = document->page()->mediaState();
+ StringBuilder string;
+ if (state & MediaProducer::IsPlayingAudio)
+ string.append("IsPlayingAudio,");
+ if (state & MediaProducer::IsPlayingVideo)
+ string.append("IsPlayingVideo,");
+ if (state & MediaProducer::IsPlayingToExternalDevice)
+ string.append("IsPlayingToExternalDevice,");
+ if (state & MediaProducer::RequiresPlaybackTargetMonitoring)
+ string.append("RequiresPlaybackTargetMonitoring,");
+ if (state & MediaProducer::ExternalDeviceAutoPlayCandidate)
+ string.append("ExternalDeviceAutoPlayCandidate,");
+ if (state & MediaProducer::DidPlayToEnd)
+ string.append("DidPlayToEnd,");
+ if (state & MediaProducer::IsSourceElementPlaying)
+ string.append("IsSourceElementPlaying,");
+
+ if (state & MediaProducer::IsNextTrackControlEnabled)
+ string.append("IsNextTrackControlEnabled,");
+ if (state & MediaProducer::IsPreviousTrackControlEnabled)
+ string.append("IsPreviousTrackControlEnabled,");
+
+ if (state & MediaProducer::HasPlaybackTargetAvailabilityListener)
+ string.append("HasPlaybackTargetAvailabilityListener,");
+ if (state & MediaProducer::HasAudioOrVideo)
+ string.append("HasAudioOrVideo,");
+ if (state & MediaProducer::HasActiveAudioCaptureDevice)
+ string.append("HasActiveAudioCaptureDevice,");
+ if (state & MediaProducer::HasActiveVideoCaptureDevice)
+ string.append("HasActiveVideoCaptureDevice,");
+
+ if (string.isEmpty())
+ string.append("IsNotPlaying");
+ else
+ string.resize(string.length() - 1);
+
+ return string.toString();
+}
+
+void Internals::setPageDefersLoading(bool defersLoading)
+{
+ Document* document = contextDocument();
+ if (!document)
+ return;
+ if (Page* page = document->page())
+ page->setDefersLoading(defersLoading);
+}
+
+RefPtr<File> Internals::createFile(const String& path)
+{
+ Document* document = contextDocument();
+ if (!document)
+ return nullptr;
+
+ URL url = document->completeURL(path);
+ if (!url.isLocalFile())
+ return nullptr;
+
+ return File::create(url.fileSystemPath());
+}
+
+void Internals::queueMicroTask(int testNumber)
+{
+ Document* document = contextDocument();
+ if (!document)
return;
+
+ auto microtask = std::make_unique<ActiveDOMCallbackMicrotask>(MicrotaskQueue::mainThreadQueue(), *document, [document, testNumber]() {
+ document->addConsoleMessage(MessageSource::JS, MessageLevel::Debug, makeString("MicroTask #", String::number(testNumber), " has run."));
+ });
+
+ MicrotaskQueue::mainThreadQueue().append(WTFMove(microtask));
+}
+
+#if ENABLE(CONTENT_FILTERING)
+
+MockContentFilterSettings& Internals::mockContentFilterSettings()
+{
+ return MockContentFilterSettings::singleton();
+}
+
+#endif
+
+#if ENABLE(CSS_SCROLL_SNAP)
+
+static void appendOffsets(StringBuilder& builder, const Vector<LayoutUnit>& snapOffsets)
+{
+ bool justStarting = true;
+
+ builder.appendLiteral("{ ");
+ for (auto& coordinate : snapOffsets) {
+ if (!justStarting)
+ builder.appendLiteral(", ");
+ else
+ justStarting = false;
+
+ builder.append(String::number(coordinate.toUnsigned()));
}
+ builder.appendLiteral(" }");
+}
+
+void Internals::setPlatformMomentumScrollingPredictionEnabled(bool enabled)
+{
+ ScrollingMomentumCalculator::setPlatformMomentumScrollingPredictionEnabled(enabled);
+}
- MediaSessionManager::SessionRestrictions restrictions = MediaSessionManager::sharedManager().restrictions(mediaType);
- MediaSessionManager::sharedManager().removeRestriction(mediaType, restrictions);
+ExceptionOr<String> Internals::scrollSnapOffsets(Element& element)
+{
+ if (!element.renderBox())
+ return String();
+
+ element.document().updateLayout();
- restrictions = MediaSessionManager::NoRestrictions;
+ RenderBox& box = *element.renderBox();
+ ScrollableArea* scrollableArea;
- if (equalIgnoringCase(restrictionsString, "ConcurrentPlaybackNotPermitted"))
- restrictions = MediaSessionManager::ConcurrentPlaybackNotPermitted;
- if (equalIgnoringCase(restrictionsString, "InlineVideoPlaybackRestricted"))
- restrictions += MediaSessionManager::InlineVideoPlaybackRestricted;
- if (equalIgnoringCase(restrictionsString, "MetadataPreloadingNotPermitted"))
- restrictions += MediaSessionManager::MetadataPreloadingNotPermitted;
- if (equalIgnoringCase(restrictionsString, "AutoPreloadingNotPermitted"))
- restrictions += MediaSessionManager::AutoPreloadingNotPermitted;
+ if (box.isBody()) {
+ FrameView* frameView = box.frame().mainFrame().view();
+ if (!frameView || !frameView->isScrollable())
+ return Exception { INVALID_ACCESS_ERR };
+ scrollableArea = frameView;
+
+ } else {
+ if (!box.canBeScrolledAndHasScrollableArea())
+ return Exception { INVALID_ACCESS_ERR };
+ scrollableArea = box.layer();
+ }
+
+ if (!scrollableArea)
+ return String();
+
+ StringBuilder result;
+
+ if (auto* offsets = scrollableArea->horizontalSnapOffsets()) {
+ if (offsets->size()) {
+ result.appendLiteral("horizontal = ");
+ appendOffsets(result, *offsets);
+ }
+ }
+
+ if (auto* offsets = scrollableArea->verticalSnapOffsets()) {
+ if (offsets->size()) {
+ if (result.length())
+ result.appendLiteral(", ");
+
+ result.appendLiteral("vertical = ");
+ appendOffsets(result, *offsets);
+ }
+ }
+
+ return result.toString();
+}
+
+#endif
+
+bool Internals::testPreloaderSettingViewport()
+{
+ return testPreloadScannerViewportSupport(contextDocument());
+}
+
+ExceptionOr<String> Internals::pathStringWithShrinkWrappedRects(const Vector<double>& rectComponents, double radius)
+{
+ if (rectComponents.size() % 4)
+ return Exception { INVALID_ACCESS_ERR };
+
+ Vector<FloatRect> rects;
+ for (unsigned i = 0; i < rectComponents.size(); i += 4)
+ rects.append(FloatRect(rectComponents[i], rectComponents[i + 1], rectComponents[i + 2], rectComponents[i + 3]));
+
+ SVGPathStringBuilder builder;
+ PathUtilities::pathWithShrinkWrappedRects(rects, radius).apply([&builder](const PathElement& element) {
+ switch (element.type) {
+ case PathElementMoveToPoint:
+ builder.moveTo(element.points[0], false, AbsoluteCoordinates);
+ return;
+ case PathElementAddLineToPoint:
+ builder.lineTo(element.points[0], AbsoluteCoordinates);
+ return;
+ case PathElementAddQuadCurveToPoint:
+ builder.curveToQuadratic(element.points[0], element.points[1], AbsoluteCoordinates);
+ return;
+ case PathElementAddCurveToPoint:
+ builder.curveToCubic(element.points[0], element.points[1], element.points[2], AbsoluteCoordinates);
+ return;
+ case PathElementCloseSubpath:
+ builder.closePath();
+ return;
+ }
+ ASSERT_NOT_REACHED();
+ });
+ return builder.result();
+}
+
+
+String Internals::getCurrentMediaControlsStatusForElement(HTMLMediaElement& mediaElement)
+{
+#if !ENABLE(MEDIA_CONTROLS_SCRIPT)
+ UNUSED_PARAM(mediaElement);
+ return String();
+#else
+ return mediaElement.getCurrentMediaControlsStatus();
+#endif
+}
+
+#if !PLATFORM(COCOA)
+
+String Internals::userVisibleString(const DOMURL&)
+{
+ // Cocoa-specific function. Could ASSERT_NOT_REACHED, but that's probably overkill.
+ return String();
+}
+
+#endif
+
+void Internals::setShowAllPlugins(bool show)
+{
+ Document* document = contextDocument();
+ if (!document)
+ return;
+
+ Page* page = document->page();
+ if (!page)
+ return;
+
+ page->setShowAllPlugins(show);
+}
+
+#if ENABLE(READABLE_STREAM_API)
+
+bool Internals::isReadableStreamDisturbed(JSC::ExecState& state, JSValue stream)
+{
+ JSGlobalObject* globalObject = state.vmEntryGlobalObject();
+ JSVMClientData* clientData = static_cast<JSVMClientData*>(state.vm().clientData);
+ const Identifier& privateName = clientData->builtinFunctions().readableStreamInternalsBuiltins().isReadableStreamDisturbedPrivateName();
+ JSValue value;
+ PropertySlot propertySlot(value, PropertySlot::InternalMethodType::Get);
+ globalObject->methodTable()->getOwnPropertySlot(globalObject, &state, privateName, propertySlot);
+ value = propertySlot.getValue(&state, privateName);
+ ASSERT(value.isFunction());
+
+ JSObject* function = value.getObject();
+ CallData callData;
+ CallType callType = JSC::getCallData(function, callData);
+ ASSERT(callType != JSC::CallType::None);
+ MarkedArgumentBuffer arguments;
+ arguments.append(stream);
+ JSValue returnedValue = JSC::call(&state, function, callType, callData, JSC::jsUndefined(), arguments);
+ ASSERT(returnedValue.isBoolean());
+
+ return returnedValue.asBoolean();
+}
+
+#endif
+
+String Internals::resourceLoadStatisticsForOrigin(const String& origin)
+{
+ return ResourceLoadObserver::sharedObserver().statisticsForOrigin(origin);
+}
- MediaSessionManager::sharedManager().addRestriction(mediaType, restrictions);
+void Internals::setResourceLoadStatisticsEnabled(bool enable)
+{
+ Settings::setResourceLoadStatisticsEnabled(enable);
+}
+
+String Internals::composedTreeAsText(Node& node)
+{
+ if (!is<ContainerNode>(node))
+ return emptyString();
+ return WebCore::composedTreeAsText(downcast<ContainerNode>(node));
}
+bool Internals::isProcessingUserGesture()
+{
+ return UserGestureIndicator::processingUserGesture();
}
+
+RefPtr<GCObservation> Internals::observeGC(JSC::JSValue value)
+{
+ if (!value.isObject())
+ return nullptr;
+ return GCObservation::create(asObject(value));
+}
+
+void Internals::setUserInterfaceLayoutDirection(UserInterfaceLayoutDirection userInterfaceLayoutDirection)
+{
+ Document* document = contextDocument();
+ if (!document)
+ return;
+
+ Page* page = document->page();
+ if (!page)
+ return;
+
+ page->setUserInterfaceLayoutDirection(userInterfaceLayoutDirection == UserInterfaceLayoutDirection::LTR ? WebCore::UserInterfaceLayoutDirection::LTR : WebCore::UserInterfaceLayoutDirection::RTL);
+}
+
+#if !PLATFORM(COCOA)
+
+bool Internals::userPrefersReducedMotion() const
+{
+ return false;
+}
+
+#endif
+
+void Internals::reportBacktrace()
+{
+ WTFReportBacktrace();
+}
+
+void Internals::setBaseWritingDirection(BaseWritingDirection direction)
+{
+ if (auto* document = contextDocument()) {
+ if (auto* frame = document->frame()) {
+ switch (direction) {
+ case BaseWritingDirection::Ltr:
+ frame->editor().setBaseWritingDirection(LeftToRightWritingDirection);
+ break;
+ case BaseWritingDirection::Rtl:
+ frame->editor().setBaseWritingDirection(RightToLeftWritingDirection);
+ break;
+ case BaseWritingDirection::Natural:
+ frame->editor().setBaseWritingDirection(NaturalWritingDirection);
+ break;
+ }
+ }
+ }
+}
+
+#if ENABLE(POINTER_LOCK)
+bool Internals::pageHasPendingPointerLock() const
+{
+ Document* document = contextDocument();
+ if (!document)
+ return false;
+
+ Page* page = document->page();
+ if (!page)
+ return false;
+
+ return page->pointerLockController().lockPending();
+}
+
+bool Internals::pageHasPointerLock() const
+{
+ Document* document = contextDocument();
+ if (!document)
+ return false;
+
+ Page* page = document->page();
+ if (!page)
+ return false;
+
+ auto& controller = page->pointerLockController();
+ return controller.element() && !controller.lockPending();
+}
+#endif
+
+Vector<String> Internals::accessKeyModifiers() const
+{
+ Vector<String> accessKeyModifierStrings;
+
+ for (auto modifier : EventHandler::accessKeyModifiers()) {
+ switch (modifier) {
+ case PlatformEvent::Modifier::AltKey:
+ accessKeyModifierStrings.append(ASCIILiteral("altKey"));
+ break;
+ case PlatformEvent::Modifier::CtrlKey:
+ accessKeyModifierStrings.append(ASCIILiteral("ctrlKey"));
+ break;
+ case PlatformEvent::Modifier::MetaKey:
+ accessKeyModifierStrings.append(ASCIILiteral("metaKey"));
+ break;
+ case PlatformEvent::Modifier::ShiftKey:
+ accessKeyModifierStrings.append(ASCIILiteral("shiftKey"));
+ break;
+ case PlatformEvent::Modifier::CapsLockKey:
+ accessKeyModifierStrings.append(ASCIILiteral("capsLockKey"));
+ break;
+ }
+ }
+
+ return accessKeyModifierStrings;
+}
+
+#if PLATFORM(IOS)
+void Internals::setQuickLookPassword(const String& password)
+{
+#if USE(QUICK_LOOK)
+ auto& quickLookHandleClient = MockQuickLookHandleClient::singleton();
+ QuickLookHandle::setClientForTesting(&quickLookHandleClient);
+ quickLookHandleClient.setPassword(password);
+#else
+ UNUSED_PARAM(password);
+#endif
+}
+#endif
+
+void Internals::setAsRunningUserScripts(Document& document)
+{
+ if (document.page())
+ document.page()->setAsRunningUserScripts();
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/testing/Internals.h b/Source/WebCore/testing/Internals.h
index 1b936332a..f5c08a87d 100644
--- a/Source/WebCore/testing/Internals.h
+++ b/Source/WebCore/testing/Internals.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2012 Google Inc. All rights reserved.
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2017 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -24,184 +24,237 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef Internals_h
-#define Internals_h
+#pragma once
#include "CSSComputedStyleDeclaration.h"
#include "ContextDestructionObserver.h"
-#include "ExceptionCodePlaceholder.h"
-#include "NodeList.h"
-#include <bindings/ScriptValue.h>
-#include <runtime/ArrayBuffer.h>
+#include "ExceptionOr.h"
+#include "PageConsoleClient.h"
#include <runtime/Float32Array.h>
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefCounted.h>
-#include <wtf/text/WTFString.h>
+
+#if ENABLE(MEDIA_SESSION)
+#include "MediaSessionInterruptionProvider.h"
+#endif
namespace WebCore {
+class AudioContext;
class ClientRect;
class ClientRectList;
-class DOMStringList;
+class DOMURL;
class DOMWindow;
class Document;
-class DocumentMarker;
class Element;
+class File;
class Frame;
-class InspectorFrontendChannelDummy;
+class GCObservation;
+class HTMLImageElement;
+class HTMLInputElement;
+class HTMLLinkElement;
+class HTMLMediaElement;
+class HTMLSelectElement;
+class InspectorStubFrontend;
class InternalSettings;
+class MallocStatistics;
+class MediaSession;
class MemoryInfo;
-class Node;
+class MockCDMFactory;
+class MockContentFilterSettings;
+class MockPageOverlay;
+class NodeList;
class Page;
class Range;
-class ScriptExecutionContext;
-class ShadowRoot;
-class MallocStatistics;
+class RenderedDocumentMarker;
+class RTCPeerConnection;
class SerializedScriptValue;
+class SourceBuffer;
+class StyleSheet;
class TimeRanges;
class TypeConversions;
+class XMLHttpRequest;
-typedef int ExceptionCode;
-
-class Internals : public RefCounted<Internals>
- , public ContextDestructionObserver {
+class Internals final : public RefCounted<Internals>, private ContextDestructionObserver {
public:
- static PassRefPtr<Internals> create(Document*);
+ static Ref<Internals> create(Document&);
virtual ~Internals();
- static void resetToConsistentState(Page*);
+ static void resetToConsistentState(Page&);
- String elementRenderTreeAsText(Element*, ExceptionCode&);
+ ExceptionOr<String> elementRenderTreeAsText(Element&);
+ bool hasPausedImageAnimations(Element&);
- String address(Node*);
+ String address(Node&);
+ bool nodeNeedsStyleRecalc(Node&);
+ String styleChangeType(Node&);
+ String description(JSC::JSValue);
bool isPreloaded(const String& url);
bool isLoadingFromMemoryCache(const String& url);
-
- PassRefPtr<CSSComputedStyleDeclaration> computedStyleIncludingVisitedInfo(Node*, ExceptionCode&) const;
-
-#if ENABLE(SHADOW_DOM)
- typedef ShadowRoot ShadowRootIfShadowDOMEnabledOrNode;
-#else
- typedef Node ShadowRootIfShadowDOMEnabledOrNode;
-#endif
- ShadowRootIfShadowDOMEnabledOrNode* ensureShadowRoot(Element* host, ExceptionCode&);
- ShadowRootIfShadowDOMEnabledOrNode* createShadowRoot(Element* host, ExceptionCode&);
- ShadowRootIfShadowDOMEnabledOrNode* shadowRoot(Element* host, ExceptionCode&);
- String shadowRootType(const Node*, ExceptionCode&) const;
- Element* includerFor(Node*, ExceptionCode&);
- String shadowPseudoId(Element*, ExceptionCode&);
- void setShadowPseudoId(Element*, const String&, ExceptionCode&);
+ String xhrResponseSource(XMLHttpRequest&);
+ bool isSharingStyleSheetContents(HTMLLinkElement&, HTMLLinkElement&);
+ bool isStyleSheetLoadingSubresources(HTMLLinkElement&);
+ enum class CachePolicy { UseProtocolCachePolicy, ReloadIgnoringCacheData, ReturnCacheDataElseLoad, ReturnCacheDataDontLoad };
+ void setOverrideCachePolicy(CachePolicy);
+ ExceptionOr<void> setCanShowModalDialogOverride(bool allow);
+ enum class ResourceLoadPriority { ResourceLoadPriorityVeryLow, ResourceLoadPriorityLow, ResourceLoadPriorityMedium, ResourceLoadPriorityHigh, ResourceLoadPriorityVeryHigh };
+ void setOverrideResourceLoadPriority(ResourceLoadPriority);
+ void setStrictRawResourceValidationPolicyDisabled(bool);
+
+ void clearMemoryCache();
+ void pruneMemoryCacheToSize(unsigned size);
+ unsigned memoryCacheSize() const;
+
+ unsigned imageFrameIndex(HTMLImageElement&);
+ void setImageFrameDecodingDuration(HTMLImageElement&, float duration);
+ void resetImageAnimation(HTMLImageElement&);
+
+ void clearPageCache();
+ unsigned pageCacheSize() const;
+
+ void disableTileSizeUpdateDelay();
+
+ Ref<CSSComputedStyleDeclaration> computedStyleIncludingVisitedInfo(Element&) const;
+
+ Node* ensureUserAgentShadowRoot(Element& host);
+ Node* shadowRoot(Element& host);
+ ExceptionOr<String> shadowRootType(const Node&) const;
+ String shadowPseudoId(Element&);
+ void setShadowPseudoId(Element&, const String&);
+
+ // CSS Deferred Parsing Testing
+ unsigned deferredStyleRulesCount(StyleSheet&);
+ unsigned deferredGroupRulesCount(StyleSheet&);
+ unsigned deferredKeyframesRulesCount(StyleSheet&);
+
+ // DOMTimers throttling testing.
+ ExceptionOr<bool> isTimerThrottled(int timeoutId);
+ bool isRequestAnimationFrameThrottled() const;
+ bool areTimersThrottled() const;
+
+ enum EventThrottlingBehavior { Responsive, Unresponsive };
+ void setEventThrottlingBehaviorOverride(std::optional<EventThrottlingBehavior>);
+ std::optional<EventThrottlingBehavior> eventThrottlingBehaviorOverride() const;
// Spatial Navigation testing.
- unsigned lastSpatialNavigationCandidateCount(ExceptionCode&) const;
+ ExceptionOr<unsigned> lastSpatialNavigationCandidateCount() const;
// CSS Animation testing.
unsigned numberOfActiveAnimations() const;
- bool animationsAreSuspended(ExceptionCode&) const;
- void suspendAnimations(ExceptionCode&) const;
- void resumeAnimations(ExceptionCode&) const;
- bool pauseAnimationAtTimeOnElement(const String& animationName, double pauseTime, Element*, ExceptionCode&);
- bool pauseAnimationAtTimeOnPseudoElement(const String& animationName, double pauseTime, Element*, const String& pseudoId, ExceptionCode&);
+ ExceptionOr<bool> animationsAreSuspended() const;
+ ExceptionOr<void> suspendAnimations() const;
+ ExceptionOr<void> resumeAnimations() const;
+ ExceptionOr<bool> pauseAnimationAtTimeOnElement(const String& animationName, double pauseTime, Element&);
+ ExceptionOr<bool> pauseAnimationAtTimeOnPseudoElement(const String& animationName, double pauseTime, Element&, const String& pseudoId);
// CSS Transition testing.
- bool pauseTransitionAtTimeOnElement(const String& propertyName, double pauseTime, Element*, ExceptionCode&);
- bool pauseTransitionAtTimeOnPseudoElement(const String& property, double pauseTime, Element*, const String& pseudoId, ExceptionCode&);
+ ExceptionOr<bool> pauseTransitionAtTimeOnElement(const String& propertyName, double pauseTime, Element&);
+ ExceptionOr<bool> pauseTransitionAtTimeOnPseudoElement(const String& property, double pauseTime, Element&, const String& pseudoId);
- Node* treeScopeRootNode(Node*, ExceptionCode&);
- Node* parentTreeScope(Node*, ExceptionCode&);
- bool hasSelectorForIdInShadow(Element* host, const String& idValue, ExceptionCode&);
- bool hasSelectorForClassInShadow(Element* host, const String& className, ExceptionCode&);
- bool hasSelectorForAttributeInShadow(Element* host, const String& attributeName, ExceptionCode&);
- bool hasSelectorForPseudoClassInShadow(Element* host, const String& pseudoClass, ExceptionCode&);
+ Node* treeScopeRootNode(Node&);
+ Node* parentTreeScope(Node&);
- bool attached(Node*, ExceptionCode&);
+ String visiblePlaceholder(Element&);
+ void selectColorInColorChooser(HTMLInputElement&, const String& colorValue);
+ ExceptionOr<Vector<String>> formControlStateOfPreviousHistoryItem();
+ ExceptionOr<void> setFormControlStateOfPreviousHistoryItem(const Vector<String>&);
- String visiblePlaceholder(Element*);
-#if ENABLE(INPUT_TYPE_COLOR)
- void selectColorInColorChooser(Element*, const String& colorValue);
-#endif
- Vector<String> formControlStateOfPreviousHistoryItem(ExceptionCode&);
- void setFormControlStateOfPreviousHistoryItem(const Vector<String>&, ExceptionCode&);
+ ExceptionOr<Ref<ClientRect>> absoluteCaretBounds();
+
+ Ref<ClientRect> boundingBox(Element&);
- PassRefPtr<ClientRect> absoluteCaretBounds(ExceptionCode&);
+ ExceptionOr<Ref<ClientRectList>> inspectorHighlightRects();
+ ExceptionOr<String> inspectorHighlightObject();
- PassRefPtr<ClientRect> boundingBox(Element*, ExceptionCode&);
+ ExceptionOr<unsigned> markerCountForNode(Node&, const String&);
+ ExceptionOr<RefPtr<Range>> markerRangeForNode(Node&, const String& markerType, unsigned index);
+ ExceptionOr<String> markerDescriptionForNode(Node&, const String& markerType, unsigned index);
+ ExceptionOr<String> dumpMarkerRects(const String& markerType);
+ void addTextMatchMarker(const Range&, bool isActive);
+ ExceptionOr<void> setMarkedTextMatchesAreHighlighted(bool);
- PassRefPtr<ClientRectList> inspectorHighlightRects(ExceptionCode&);
- String inspectorHighlightObject(ExceptionCode&);
+ void invalidateFontCache();
- unsigned markerCountForNode(Node*, const String&, ExceptionCode&);
- PassRefPtr<Range> markerRangeForNode(Node*, const String& markerType, unsigned index, ExceptionCode&);
- String markerDescriptionForNode(Node*, const String& markerType, unsigned index, ExceptionCode&);
- void addTextMatchMarker(const Range*, bool isActive);
+ ExceptionOr<void> setScrollViewPosition(int x, int y);
+
+ ExceptionOr<Ref<ClientRect>> layoutViewportRect();
+ ExceptionOr<Ref<ClientRect>> visualViewportRect();
+
+ ExceptionOr<void> setViewBaseBackgroundColor(const String& colorValue);
- void setScrollViewPosition(long x, long y, ExceptionCode&);
- void setPagination(const String& mode, int gap, ExceptionCode& ec) { setPagination(mode, gap, 0, ec); }
- void setPagination(const String& mode, int gap, int pageLength, ExceptionCode&);
- String configurationForViewport(float devicePixelRatio, int deviceWidth, int deviceHeight, int availableWidth, int availableHeight, ExceptionCode&);
+ ExceptionOr<void> setPagination(const String& mode, int gap, int pageLength);
+ ExceptionOr<void> setPaginationLineGridEnabled(bool);
+ ExceptionOr<String> configurationForViewport(float devicePixelRatio, int deviceWidth, int deviceHeight, int availableWidth, int availableHeight);
- bool wasLastChangeUserEdit(Element* textField, ExceptionCode&);
- bool elementShouldAutoComplete(Element* inputElement, ExceptionCode&);
- String suggestedValue(Element* inputElement, ExceptionCode&);
- void setSuggestedValue(Element* inputElement, const String&, ExceptionCode&);
- void setEditingValue(Element* inputElement, const String&, ExceptionCode&);
- void setAutofilled(Element*, bool enabled, ExceptionCode&);
- void scrollElementToRect(Element*, long x, long y, long w, long h, ExceptionCode&);
+ ExceptionOr<bool> wasLastChangeUserEdit(Element& textField);
+ bool elementShouldAutoComplete(HTMLInputElement&);
+ void setEditingValue(HTMLInputElement&, const String&);
+ void setAutofilled(HTMLInputElement&, bool enabled);
+ enum class AutoFillButtonType { AutoFillButtonTypeNone, AutoFillButtonTypeContacts, AutoFillButtonTypeCredentials };
+ void setShowAutoFillButton(HTMLInputElement&, AutoFillButtonType);
+ ExceptionOr<void> scrollElementToRect(Element&, int x, int y, int w, int h);
- void paintControlTints(ExceptionCode&);
+ ExceptionOr<String> autofillFieldName(Element&);
- PassRefPtr<Range> rangeFromLocationAndLength(Element* scope, int rangeLocation, int rangeLength, ExceptionCode&);
- unsigned locationFromRange(Element* scope, const Range*, ExceptionCode&);
- unsigned lengthFromRange(Element* scope, const Range*, ExceptionCode&);
- String rangeAsText(const Range*, ExceptionCode&);
+ ExceptionOr<void> paintControlTints();
- void setDelegatesScrolling(bool enabled, ExceptionCode&);
+ RefPtr<Range> rangeFromLocationAndLength(Element& scope, int rangeLocation, int rangeLength);
+ unsigned locationFromRange(Element& scope, const Range&);
+ unsigned lengthFromRange(Element& scope, const Range&);
+ String rangeAsText(const Range&);
+ Ref<Range> subrange(Range&, int rangeLocation, int rangeLength);
+ ExceptionOr<RefPtr<Range>> rangeForDictionaryLookupAtLocation(int x, int y);
+ RefPtr<Range> rangeOfStringNearLocation(const Range&, const String&, unsigned);
- int lastSpellCheckRequestSequence(ExceptionCode&);
- int lastSpellCheckProcessedSequence(ExceptionCode&);
+ ExceptionOr<void> setDelegatesScrolling(bool enabled);
+
+ ExceptionOr<int> lastSpellCheckRequestSequence();
+ ExceptionOr<int> lastSpellCheckProcessedSequence();
Vector<String> userPreferredLanguages() const;
void setUserPreferredLanguages(const Vector<String>&);
- unsigned wheelEventHandlerCount(ExceptionCode&);
- unsigned touchEventHandlerCount(ExceptionCode&);
+ Vector<String> userPreferredAudioCharacteristics() const;
+ void setUserPreferredAudioCharacteristic(const String&);
+
+ ExceptionOr<unsigned> wheelEventHandlerCount();
+ ExceptionOr<unsigned> touchEventHandlerCount();
+
+ ExceptionOr<RefPtr<NodeList>> nodesFromRect(Document&, int x, int y, unsigned topPadding, unsigned rightPadding, unsigned bottomPadding, unsigned leftPadding, bool ignoreClipping, bool allowShadowContent, bool allowChildFrameContent) const;
- PassRefPtr<NodeList> nodesFromRect(Document*, int x, int y, unsigned topPadding, unsigned rightPadding,
- unsigned bottomPadding, unsigned leftPadding, bool ignoreClipping, bool allowShadowContent, bool allowChildFrameContent, ExceptionCode&) const;
+ String parserMetaData(JSC::JSValue = JSC::JSValue::JSUndefined);
- void emitInspectorDidBeginFrame();
- void emitInspectorDidCancelFrame();
+ void updateEditorUINowIfScheduled();
- String parserMetaData(Deprecated::ScriptValue = Deprecated::ScriptValue());
+ bool hasSpellingMarker(int from, int length);
+ bool hasGrammarMarker(int from, int length);
+ bool hasAutocorrectedMarker(int from, int length);
+ void setContinuousSpellCheckingEnabled(bool);
+ void setAutomaticQuoteSubstitutionEnabled(bool);
+ void setAutomaticLinkDetectionEnabled(bool);
+ void setAutomaticDashSubstitutionEnabled(bool);
+ void setAutomaticTextReplacementEnabled(bool);
+ void setAutomaticSpellingCorrectionEnabled(bool);
- bool hasSpellingMarker(int from, int length, ExceptionCode&);
- bool hasGrammarMarker(int from, int length, ExceptionCode&);
- bool hasAutocorrectedMarker(int from, int length, ExceptionCode&);
- void setContinuousSpellCheckingEnabled(bool enabled, ExceptionCode&);
- void setAutomaticQuoteSubstitutionEnabled(bool enabled, ExceptionCode&);
- void setAutomaticLinkDetectionEnabled(bool enabled, ExceptionCode&);
- void setAutomaticDashSubstitutionEnabled(bool enabled, ExceptionCode&);
- void setAutomaticTextReplacementEnabled(bool enabled, ExceptionCode&);
- void setAutomaticSpellingCorrectionEnabled(bool enabled, ExceptionCode&);
+ void handleAcceptedCandidate(const String& candidate, unsigned location, unsigned length);
- bool isOverwriteModeEnabled(ExceptionCode&);
- void toggleOverwriteModeEnabled(ExceptionCode&);
+ bool isOverwriteModeEnabled();
+ void toggleOverwriteModeEnabled();
- unsigned numberOfScrollableAreas(ExceptionCode&);
+ ExceptionOr<RefPtr<Range>> rangeOfString(const String&, RefPtr<Range>&&, const Vector<String>& findOptions);
+ ExceptionOr<unsigned> countMatchesForText(const String&, const Vector<String>& findOptions, const String& markMatches);
+ ExceptionOr<unsigned> countFindMatches(const String&, const Vector<String>& findOptions);
- bool isPageBoxVisible(int pageNumber, ExceptionCode&);
+ unsigned numberOfScrollableAreas();
+
+ ExceptionOr<bool> isPageBoxVisible(int pageNumber);
static const char* internalsId;
InternalSettings* settings() const;
unsigned workerThreadCount() const;
+ bool areSVGAnimationsPaused() const;
- void setBatteryStatus(const String& eventType, bool charging, double chargingTime, double dischargingTime, double level, ExceptionCode&);
-
- void setNetworkInformation(const String& eventType, double bandwidth, bool metered, ExceptionCode&);
-
- void setDeviceProximity(const String& eventType, double value, double min, double max, ExceptionCode&);
+ ExceptionOr<void> setDeviceProximity(const String& eventType, double value, double min, double max);
enum {
// Values need to be kept in sync with Internals.idl.
@@ -209,140 +262,283 @@ public:
LAYER_TREE_INCLUDES_TILE_CACHES = 2,
LAYER_TREE_INCLUDES_REPAINT_RECTS = 4,
LAYER_TREE_INCLUDES_PAINTING_PHASES = 8,
- LAYER_TREE_INCLUDES_CONTENT_LAYERS = 16
+ LAYER_TREE_INCLUDES_CONTENT_LAYERS = 16,
+ LAYER_TREE_INCLUDES_ACCELERATES_DRAWING = 32,
+ };
+ ExceptionOr<String> layerTreeAsText(Document&, unsigned short flags) const;
+ ExceptionOr<String> repaintRectsAsText() const;
+ ExceptionOr<String> scrollingStateTreeAsText() const;
+ ExceptionOr<String> mainThreadScrollingReasons() const;
+ ExceptionOr<RefPtr<ClientRectList>> nonFastScrollableRects() const;
+
+ ExceptionOr<void> setElementUsesDisplayListDrawing(Element&, bool usesDisplayListDrawing);
+ ExceptionOr<void> setElementTracksDisplayListReplay(Element&, bool isTrackingReplay);
+
+ enum {
+ // Values need to be kept in sync with Internals.idl.
+ DISPLAY_LIST_INCLUDES_PLATFORM_OPERATIONS = 1,
};
- String layerTreeAsText(Document*, unsigned flags, ExceptionCode&) const;
- String layerTreeAsText(Document*, ExceptionCode&) const;
- String repaintRectsAsText(ExceptionCode&) const;
- String scrollingStateTreeAsText(ExceptionCode&) const;
- String mainThreadScrollingReasons(ExceptionCode&) const;
- PassRefPtr<ClientRectList> nonFastScrollableRects(ExceptionCode&) const;
+ ExceptionOr<String> displayListForElement(Element&, unsigned short flags);
+ ExceptionOr<String> replayDisplayListForElement(Element&, unsigned short flags);
- void garbageCollectDocumentResources(ExceptionCode&) const;
+ ExceptionOr<void> garbageCollectDocumentResources() const;
- void allowRoundingHacks() const;
+ void beginSimulatedMemoryPressure();
+ void endSimulatedMemoryPressure();
+ bool isUnderMemoryPressure();
- void insertAuthorCSS(const String&, ExceptionCode&) const;
- void insertUserCSS(const String&, ExceptionCode&) const;
+ ExceptionOr<void> insertAuthorCSS(const String&) const;
+ ExceptionOr<void> insertUserCSS(const String&) const;
-#if ENABLE(INSPECTOR)
unsigned numberOfLiveNodes() const;
unsigned numberOfLiveDocuments() const;
- Vector<String> consoleMessageArgumentCounts() const;
- PassRefPtr<DOMWindow> openDummyInspectorFrontend(const String& url);
+
+ RefPtr<DOMWindow> openDummyInspectorFrontend(const String& url);
void closeDummyInspectorFrontend();
- void setInspectorResourcesDataSizeLimits(int maximumResourcesContentSize, int maximumSingleResourceContentSize, ExceptionCode&);
- void setJavaScriptProfilingEnabled(bool enabled, ExceptionCode&);
-#endif
+ ExceptionOr<void> setInspectorIsUnderTest(bool);
- String counterValue(Element*);
+ String counterValue(Element&);
- int pageNumber(Element*, float pageWidth = 800, float pageHeight = 600);
+ int pageNumber(Element&, float pageWidth = 800, float pageHeight = 600);
Vector<String> shortcutIconURLs() const;
- Vector<String> allIconURLs() const;
int numberOfPages(float pageWidthInPixels = 800, float pageHeightInPixels = 600);
- String pageProperty(String, int, ExceptionCode& = ASSERT_NO_EXCEPTION) const;
- String pageSizeAndMarginsInPixels(int, int, int, int, int, int, int, ExceptionCode& = ASSERT_NO_EXCEPTION) const;
+ ExceptionOr<String> pageProperty(const String& propertyName, int pageNumber) const;
+ ExceptionOr<String> pageSizeAndMarginsInPixels(int pageNumber, int width, int height, int marginTop, int marginRight, int marginBottom, int marginLeft) const;
+
+ ExceptionOr<float> pageScaleFactor() const;
- void setPageScaleFactor(float scaleFactor, int x, int y, ExceptionCode&);
+ ExceptionOr<void> setPageScaleFactor(float scaleFactor, int x, int y);
+ ExceptionOr<void> setPageZoomFactor(float);
+ ExceptionOr<void> setTextZoomFactor(float);
+
+ ExceptionOr<void> setUseFixedLayout(bool);
+ ExceptionOr<void> setFixedLayoutSize(int width, int height);
+ ExceptionOr<void> setViewExposedRect(float left, float top, float width, float height);
void setHeaderHeight(float);
void setFooterHeight(float);
+ void setTopContentInset(float);
+
#if ENABLE(FULLSCREEN_API)
- void webkitWillEnterFullScreenForElement(Element*);
- void webkitDidEnterFullScreenForElement(Element*);
- void webkitWillExitFullScreenForElement(Element*);
- void webkitDidExitFullScreenForElement(Element*);
+ void webkitWillEnterFullScreenForElement(Element&);
+ void webkitDidEnterFullScreenForElement(Element&);
+ void webkitWillExitFullScreenForElement(Element&);
+ void webkitDidExitFullScreenForElement(Element&);
#endif
- void setApplicationCacheOriginQuota(unsigned long long);
+ WEBCORE_TESTSUPPORT_EXPORT void setApplicationCacheOriginQuota(unsigned long long);
void registerURLSchemeAsBypassingContentSecurityPolicy(const String& scheme);
void removeURLSchemeRegisteredAsBypassingContentSecurityPolicy(const String& scheme);
- PassRefPtr<MallocStatistics> mallocStatistics() const;
- PassRefPtr<TypeConversions> typeConversions() const;
- PassRefPtr<MemoryInfo> memoryInfo() const;
+ void registerDefaultPortForProtocol(unsigned short port, const String& protocol);
+
+ Ref<MallocStatistics> mallocStatistics() const;
+ Ref<TypeConversions> typeConversions() const;
+ Ref<MemoryInfo> memoryInfo() const;
Vector<String> getReferencedFilePaths() const;
- void startTrackingRepaints(ExceptionCode&);
- void stopTrackingRepaints(ExceptionCode&);
- void updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks(ExceptionCode&);
- void updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks(Node*, ExceptionCode&);
+ ExceptionOr<void> startTrackingRepaints();
+ ExceptionOr<void> stopTrackingRepaints();
+
+ ExceptionOr<void> startTrackingLayerFlushes();
+ ExceptionOr<unsigned> layerFlushCount();
+
+ ExceptionOr<void> startTrackingStyleRecalcs();
+ ExceptionOr<unsigned> styleRecalcCount();
+ unsigned lastStyleUpdateSize() const;
+
+ ExceptionOr<void> startTrackingCompositingUpdates();
+ ExceptionOr<unsigned> compositingUpdateCount();
- PassRefPtr<ArrayBuffer> serializeObject(PassRefPtr<SerializedScriptValue>) const;
- PassRefPtr<SerializedScriptValue> deserializeBuffer(PassRefPtr<ArrayBuffer>) const;
+ ExceptionOr<void> updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks(Node*);
+ unsigned layoutCount() const;
- void setUsesOverlayScrollbars(bool enabled);
+ Ref<ArrayBuffer> serializeObject(const RefPtr<SerializedScriptValue>&) const;
+ Ref<SerializedScriptValue> deserializeBuffer(ArrayBuffer&) const;
- String getCurrentCursorInfo(ExceptionCode&);
+ bool isFromCurrentWorld(JSC::JSValue) const;
- String markerTextForListItem(Element*, ExceptionCode&);
+ void setUsesOverlayScrollbars(bool);
+ void setUsesMockScrollAnimator(bool);
+
+ ExceptionOr<String> getCurrentCursorInfo();
+
+ String markerTextForListItem(Element&);
+
+ String toolTipFromElement(Element&) const;
void forceReload(bool endToEnd);
-#if ENABLE(ENCRYPTED_MEDIA_V2)
+ void enableAutoSizeMode(bool enabled, int minimumWidth, int minimumHeight, int maximumWidth, int maximumHeight);
+
+#if ENABLE(LEGACY_ENCRYPTED_MEDIA)
void initializeMockCDM();
#endif
+#if ENABLE(ENCRYPTED_MEDIA)
+ Ref<MockCDMFactory> registerMockCDM();
+#endif
+
#if ENABLE(SPEECH_SYNTHESIS)
void enableMockSpeechSynthesizer();
#endif
#if ENABLE(MEDIA_STREAM)
+ void setMockMediaCaptureDevicesEnabled(bool);
+#endif
+
+#if ENABLE(WEB_RTC)
+ void enableMockMediaEndpoint();
void enableMockRTCPeerConnectionHandler();
+ void emulateRTCPeerConnectionPlatformEvent(RTCPeerConnection&, const String& action);
+ void useMockRTCPeerConnectionFactory(const String&);
#endif
- String getImageSourceURL(Element*, ExceptionCode&);
+ String getImageSourceURL(Element&);
#if ENABLE(VIDEO)
- void simulateAudioInterruption(Node*);
+ void simulateAudioInterruption(HTMLMediaElement&);
+ ExceptionOr<bool> mediaElementHasCharacteristic(HTMLMediaElement&, const String&);
#endif
- bool isSelectPopupVisible(Node*);
+ bool isSelectPopupVisible(HTMLSelectElement&);
- String captionsStyleSheetOverride(ExceptionCode&);
- void setCaptionsStyleSheetOverride(const String&, ExceptionCode&);
- void setPrimaryAudioTrackLanguageOverride(const String&, ExceptionCode&);
- void setCaptionDisplayMode(const String&, ExceptionCode&);
+ ExceptionOr<String> captionsStyleSheetOverride();
+ ExceptionOr<void> setCaptionsStyleSheetOverride(const String&);
+ ExceptionOr<void> setPrimaryAudioTrackLanguageOverride(const String&);
+ ExceptionOr<void> setCaptionDisplayMode(const String&);
#if ENABLE(VIDEO)
- PassRefPtr<TimeRanges> createTimeRanges(Float32Array* startTimes, Float32Array* endTimes);
- double closestTimeToTimeRanges(double time, TimeRanges*);
+ Ref<TimeRanges> createTimeRanges(Float32Array& startTimes, Float32Array& endTimes);
+ double closestTimeToTimeRanges(double time, TimeRanges&);
#endif
- PassRefPtr<ClientRect> selectionBounds(ExceptionCode&);
+ ExceptionOr<Ref<ClientRect>> selectionBounds();
#if ENABLE(VIBRATION)
bool isVibrating();
#endif
- bool isPluginUnavailabilityIndicatorObscured(Element*, ExceptionCode&);
+ ExceptionOr<bool> isPluginUnavailabilityIndicatorObscured(Element&);
+ bool isPluginSnapshotted(Element&);
#if ENABLE(MEDIA_SOURCE)
- void initializeMockMediaSource();
+ WEBCORE_TESTSUPPORT_EXPORT void initializeMockMediaSource();
+ Vector<String> bufferedSamplesForTrackID(SourceBuffer&, const AtomicString&);
+ Vector<String> enqueuedSamplesForTrackID(SourceBuffer&, const AtomicString&);
+ void setShouldGenerateTimestamps(SourceBuffer&, bool);
#endif
- void beginMediaSessionInterruption();
+#if ENABLE(VIDEO)
+ ExceptionOr<void> beginMediaSessionInterruption(const String&);
void endMediaSessionInterruption(const String&);
- void setMediaSessionRestrictions(const String& mediaType, const String& restrictions, ExceptionCode& ec);
+ void applicationDidEnterForeground() const;
+ void applicationWillEnterBackground() const;
+ ExceptionOr<void> setMediaSessionRestrictions(const String& mediaType, const String& restrictions);
+ ExceptionOr<String> mediaSessionRestrictions(const String& mediaType) const;
+ void setMediaElementRestrictions(HTMLMediaElement&, const String& restrictions);
+ ExceptionOr<void> postRemoteControlCommand(const String&, float argument);
+ bool elementIsBlockingDisplaySleep(HTMLMediaElement&) const;
+#endif
+
+#if ENABLE(MEDIA_SESSION)
+ void sendMediaSessionStartOfInterruptionNotification(MediaSessionInterruptingCategory);
+ void sendMediaSessionEndOfInterruptionNotification(MediaSessionInterruptingCategory);
+ String mediaSessionCurrentState(MediaSession&) const;
+ double mediaElementPlayerVolume(HTMLMediaElement&) const;
+ enum class MediaControlEvent { PlayPause, NextTrack, PreviousTrack };
+ void sendMediaControlEvent(MediaControlEvent);
+#endif
+
+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+ void setMockMediaPlaybackTargetPickerEnabled(bool);
+ ExceptionOr<void> setMockMediaPlaybackTargetPickerState(const String& deviceName, const String& deviceState);
+#endif
+
+#if ENABLE(WEB_AUDIO)
+ void setAudioContextRestrictions(AudioContext&, const String& restrictions);
+#endif
+
+ void simulateSystemSleep() const;
+ void simulateSystemWake() const;
+
+ enum class PageOverlayType { View, Document };
+ ExceptionOr<Ref<MockPageOverlay>> installMockPageOverlay(PageOverlayType);
+ ExceptionOr<String> pageOverlayLayerTreeAsText(unsigned short flags) const;
+
+ void setPageMuted(const String&);
+ String pageMediaState();
+
+ void setPageDefersLoading(bool);
+
+ RefPtr<File> createFile(const String&);
+ void queueMicroTask(int);
+ bool testPreloaderSettingViewport();
+
+#if ENABLE(CONTENT_FILTERING)
+ MockContentFilterSettings& mockContentFilterSettings();
+#endif
+
+#if ENABLE(CSS_SCROLL_SNAP)
+ ExceptionOr<String> scrollSnapOffsets(Element&);
+ void setPlatformMomentumScrollingPredictionEnabled(bool);
+#endif
+
+ ExceptionOr<String> pathStringWithShrinkWrappedRects(const Vector<double>& rectComponents, double radius);
+
+ String getCurrentMediaControlsStatusForElement(HTMLMediaElement&);
+
+ String userVisibleString(const DOMURL&);
+ void setShowAllPlugins(bool);
+
+ String resourceLoadStatisticsForOrigin(const String& origin);
+ void setResourceLoadStatisticsEnabled(bool);
+
+#if ENABLE(READABLE_STREAM_API)
+ bool isReadableStreamDisturbed(JSC::ExecState&, JSC::JSValue);
+#endif
+
+ String composedTreeAsText(Node&);
+
+ bool isProcessingUserGesture();
+
+ RefPtr<GCObservation> observeGC(JSC::JSValue);
+
+ enum class UserInterfaceLayoutDirection { LTR, RTL };
+ void setUserInterfaceLayoutDirection(UserInterfaceLayoutDirection);
+
+ bool userPrefersReducedMotion() const;
+
+ void reportBacktrace();
+
+ enum class BaseWritingDirection { Natural, Ltr, Rtl };
+ void setBaseWritingDirection(BaseWritingDirection);
+
+#if ENABLE(POINTER_LOCK)
+ bool pageHasPendingPointerLock() const;
+ bool pageHasPointerLock() const;
+#endif
+
+ Vector<String> accessKeyModifiers() const;
+
+#if PLATFORM(IOS)
+ void setQuickLookPassword(const String&);
+#endif
+
+ void setAsRunningUserScripts(Document&);
private:
- explicit Internals(Document*);
+ explicit Internals(Document&);
Document* contextDocument() const;
Frame* frame() const;
- Vector<String> iconURLs(Document*, int iconTypesMask) const;
- DocumentMarker* markerAt(Node*, const String& markerType, unsigned index, ExceptionCode&);
-#if ENABLE(INSPECTOR)
- RefPtr<DOMWindow> m_frontendWindow;
- OwnPtr<InspectorFrontendChannelDummy> m_frontendChannel;
-#endif
+ ExceptionOr<RenderedDocumentMarker*> markerAt(Node&, const String& markerType, unsigned index);
+
+ std::unique_ptr<InspectorStubFrontend> m_inspectorFrontend;
};
} // namespace WebCore
-
-#endif
diff --git a/Source/WebCore/testing/Internals.idl b/Source/WebCore/testing/Internals.idl
index 6b0c22795..155b70b4a 100644
--- a/Source/WebCore/testing/Internals.idl
+++ b/Source/WebCore/testing/Internals.idl
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2012 Google Inc. All rights reserved.
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2017 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -24,189 +24,297 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+enum PageOverlayType {
+ "view",
+ "document"
+};
+
+// These map to ResourceRequestCachePolicy.
+enum CachePolicy {
+ "UseProtocolCachePolicy",
+ "ReloadIgnoringCacheData",
+ "ReturnCacheDataElseLoad",
+ "ReturnCacheDataDontLoad"
+};
+
+// FIXME: Strings in an enum should not have the name of the enum as a prefix.
+enum ResourceLoadPriority {
+ "ResourceLoadPriorityVeryLow",
+ "ResourceLoadPriorityLow",
+ "ResourceLoadPriorityMedium",
+ "ResourceLoadPriorityHigh",
+ "ResourceLoadPriorityVeryHigh"
+};
+
+[Conditional=MEDIA_SESSION] enum MediaSessionInterruptingCategory {
+ "content",
+ "transient",
+ "transient-solo"
+};
+
+[Conditional=MEDIA_SESSION] enum MediaControlEvent {
+ "play-pause",
+ "next-track",
+ "previous-track"
+};
+
+// FIXME: Strings in an enum should not have the name of the enum as a prefix.
+enum AutoFillButtonType {
+ "AutoFillButtonTypeNone",
+ "AutoFillButtonTypeContacts",
+ "AutoFillButtonTypeCredentials"
+};
+
+enum UserInterfaceLayoutDirection {
+ "LTR",
+ "RTL"
+};
+
+enum BaseWritingDirection {
+ "Natural",
+ "Ltr",
+ "Rtl"
+};
+
+enum EventThrottlingBehavior {
+ "responsive",
+ "unresponsive"
+};
+
[
+ ExportMacro=WEBCORE_TESTSUPPORT_EXPORT,
NoInterfaceObject,
] interface Internals {
DOMString address(Node node);
+ boolean nodeNeedsStyleRecalc(Node node);
+ DOMString styleChangeType(Node node);
+ DOMString description(any value);
+
+ // Animated image pausing testing.
+ boolean hasPausedImageAnimations(Element element);
- [RaisesException] DOMString elementRenderTreeAsText(Element element);
+ [MayThrowException] DOMString elementRenderTreeAsText(Element element);
boolean isPreloaded(DOMString url);
boolean isLoadingFromMemoryCache(DOMString url);
-
- [RaisesException] CSSStyleDeclaration computedStyleIncludingVisitedInfo(Node node);
-
-#if defined(ENABLE_SHADOW_DOM) && ENABLE_SHADOW_DOM
- [RaisesException] ShadowRoot ensureShadowRoot(Element host);
- [RaisesException] ShadowRoot createShadowRoot(Element host);
- [RaisesException] ShadowRoot shadowRoot(Element host);
-#else
- [RaisesException] Node ensureShadowRoot(Element host);
- [RaisesException] Node createShadowRoot(Element host);
- [RaisesException] Node shadowRoot(Element host);
-#endif
- [RaisesException] DOMString shadowRootType(Node root);
- [RaisesException] Element includerFor(Node node);
- [RaisesException] DOMString shadowPseudoId(Element element);
- [RaisesException] void setShadowPseudoId(Element element, DOMString id);
- [RaisesException] Node treeScopeRootNode(Node node);
- [RaisesException] Node parentTreeScope(Node node);
+ DOMString xhrResponseSource(XMLHttpRequest xhr);
+ boolean isSharingStyleSheetContents(HTMLLinkElement a, HTMLLinkElement b);
+ boolean isStyleSheetLoadingSubresources(HTMLLinkElement link);
+ void clearMemoryCache();
+ void pruneMemoryCacheToSize(long size);
+ long memoryCacheSize();
+ void setOverrideCachePolicy(CachePolicy policy);
+ void setOverrideResourceLoadPriority(ResourceLoadPriority priority);
+ void setStrictRawResourceValidationPolicyDisabled(boolean disabled);
+
+ void clearPageCache();
+ unsigned long pageCacheSize();
+
+ CSSStyleDeclaration computedStyleIncludingVisitedInfo(Element element);
+
+ Node ensureUserAgentShadowRoot(Element host);
+ Node shadowRoot(Element host);
+
+ // CSS Deferred Parsing Testing.
+ long deferredStyleRulesCount(StyleSheet sheet);
+ long deferredGroupRulesCount(StyleSheet sheet);
+ long deferredKeyframesRulesCount(StyleSheet sheet);
+
+ [MayThrowException] DOMString shadowRootType(Node root);
+ DOMString shadowPseudoId(Element element);
+ void setShadowPseudoId(Element element, DOMString id);
+ Node treeScopeRootNode(Node node);
+ Node parentTreeScope(Node node);
// Spatial Navigation testing
- [RaisesException] unsigned long lastSpatialNavigationCandidateCount();
+ [MayThrowException] unsigned long lastSpatialNavigationCandidateCount();
// CSS Animation testing.
unsigned long numberOfActiveAnimations();
- [RaisesException] void suspendAnimations();
- [RaisesException] void resumeAnimations();
- [RaisesException] boolean animationsAreSuspended();
- [RaisesException] boolean pauseAnimationAtTimeOnElement(DOMString animationName, double pauseTime, Element element);
- [RaisesException] boolean pauseAnimationAtTimeOnPseudoElement(DOMString animationName, double pauseTime, Element element, DOMString pseudoId);
+ [MayThrowException] void suspendAnimations();
+ [MayThrowException] void resumeAnimations();
+ [MayThrowException] boolean animationsAreSuspended();
+ [MayThrowException] boolean pauseAnimationAtTimeOnElement(DOMString animationName, unrestricted double pauseTime, Element element);
+ [MayThrowException] boolean pauseAnimationAtTimeOnPseudoElement(DOMString animationName, unrestricted double pauseTime, Element element, DOMString pseudoId);
// CSS Transition testing.
- [RaisesException] boolean pauseTransitionAtTimeOnElement(DOMString propertyName, double pauseTime, Element element);
- [RaisesException] boolean pauseTransitionAtTimeOnPseudoElement(DOMString property, double pauseTime, Element element, DOMString pseudoId);
-
- [RaisesException] boolean attached(Node node);
+ [MayThrowException] boolean pauseTransitionAtTimeOnElement(DOMString propertyName, unrestricted double pauseTime, Element element);
+ [MayThrowException] boolean pauseTransitionAtTimeOnPseudoElement(DOMString property, unrestricted double pauseTime, Element element, DOMString pseudoId);
DOMString visiblePlaceholder(Element element);
-#if defined(ENABLE_INPUT_TYPE_COLOR) && ENABLE_INPUT_TYPE_COLOR
- void selectColorInColorChooser(Element element, DOMString colorValue);
-#endif
- [RaisesException] DOMString[] formControlStateOfPreviousHistoryItem();
- [RaisesException] void setFormControlStateOfPreviousHistoryItem(sequence<DOMString> values);
+ void selectColorInColorChooser(HTMLInputElement element, DOMString colorValue);
+ [MayThrowException] sequence<DOMString> formControlStateOfPreviousHistoryItem();
+ [MayThrowException] void setFormControlStateOfPreviousHistoryItem(sequence<DOMString> values);
- [RaisesException] ClientRect absoluteCaretBounds();
+ [MayThrowException] ClientRect absoluteCaretBounds();
- [RaisesException] ClientRect boundingBox(Element element);
+ ClientRect boundingBox(Element element);
- [RaisesException] ClientRectList inspectorHighlightRects();
- [RaisesException] DOMString inspectorHighlightObject();
+ [MayThrowException] ClientRectList inspectorHighlightRects();
+ [MayThrowException] DOMString inspectorHighlightObject();
- [RaisesException] unsigned long markerCountForNode(Node node, DOMString markerType);
- [RaisesException] Range markerRangeForNode(Node node, DOMString markerType, unsigned long index);
- [RaisesException] DOMString markerDescriptionForNode(Node node, DOMString markerType, unsigned long index);
+ [MayThrowException] unsigned long markerCountForNode(Node node, DOMString markerType);
+ [MayThrowException] Range? markerRangeForNode(Node node, DOMString markerType, unsigned long index);
+ [MayThrowException] DOMString markerDescriptionForNode(Node node, DOMString markerType, unsigned long index);
+ [MayThrowException] DOMString dumpMarkerRects(DOMString markerType);
void addTextMatchMarker(Range range, boolean isActive);
+ [MayThrowException] void setMarkedTextMatchesAreHighlighted(boolean flag);
+
+ void invalidateFontCache();
+
+ [MayThrowException] void setScrollViewPosition(long x, long y);
+
+ [MayThrowException] ClientRect layoutViewportRect();
+ [MayThrowException] ClientRect visualViewportRect();
+
+ [MayThrowException] void setViewBaseBackgroundColor(DOMString colorValue);
- [RaisesException] void setScrollViewPosition(long x, long y);
+ [MayThrowException] void setPagination(DOMString mode, long gap, optional long pageLength = 0);
+ [MayThrowException] void setPaginationLineGridEnabled(boolean enabled);
- [RaisesException] void setPagination(DOMString mode, long gap, optional long pageLength);
+ [MayThrowException] DOMString configurationForViewport(unrestricted float devicePixelRatio, long deviceWidth, long deviceHeight, long availableWidth, long availableHeight);
- [RaisesException] DOMString configurationForViewport(float devicePixelRatio,
- long deviceWidth,
- long deviceHeight,
- long availableWidth,
- long availableHeight);
+ [MayThrowException] boolean wasLastChangeUserEdit(Element textField);
+ boolean elementShouldAutoComplete(HTMLInputElement inputElement);
+ void setEditingValue(HTMLInputElement inputElement, DOMString value);
+ void setAutofilled(HTMLInputElement inputElement, boolean enabled);
+ void setShowAutoFillButton(HTMLInputElement inputElement, AutoFillButtonType autoFillButtonType);
- [RaisesException] boolean wasLastChangeUserEdit(Element textField);
- [RaisesException] boolean elementShouldAutoComplete(Element inputElement);
- [RaisesException] DOMString suggestedValue(Element inputElement);
- [RaisesException] void setSuggestedValue(Element inputElement, DOMString value);
- [RaisesException] void setEditingValue(Element inputElement, DOMString value);
- [RaisesException] void setAutofilled(Element inputElement, boolean enabled);
+ [MayThrowException] Range? rangeOfString(DOMString text, Range? referenceRange, sequence<DOMString> findOptions);
+ [MayThrowException] unsigned long countMatchesForText(DOMString text, sequence<DOMString> findOptions, DOMString markMatches);
+ [MayThrowException] unsigned long countFindMatches(DOMString text, sequence<DOMString> findOptions);
- [RaisesException] void paintControlTints();
+ [MayThrowException] DOMString autofillFieldName(Element formControlElement);
- [RaisesException] void scrollElementToRect(Element element, long x, long y, long w, long h);
+ [MayThrowException] void paintControlTints();
- [RaisesException] Range rangeFromLocationAndLength(Element scope, long rangeLocation, long rangeLength);
- [RaisesException] unsigned long locationFromRange(Element scope, Range range);
- [RaisesException] unsigned long lengthFromRange(Element scope, Range range);
- [RaisesException] DOMString rangeAsText(Range range);
+ [MayThrowException] void scrollElementToRect(Element element, long x, long y, long w, long h);
- [RaisesException] void setDelegatesScrolling(boolean enabled);
+ Range? rangeFromLocationAndLength(Element scope, long rangeLocation, long rangeLength);
+ unsigned long locationFromRange(Element scope, Range range);
+ unsigned long lengthFromRange(Element scope, Range range);
+ DOMString rangeAsText(Range range);
+ Range subrange(Range range, long rangeLocation, long rangeLength);
+ [MayThrowException] Range? rangeForDictionaryLookupAtLocation(long x, long y);
+ Range? rangeOfStringNearLocation(Range range, DOMString text, long targetOffset);
- [RaisesException] long lastSpellCheckRequestSequence();
- [RaisesException] long lastSpellCheckProcessedSequence();
+ [MayThrowException] void setDelegatesScrolling(boolean enabled);
+
+ [MayThrowException] long lastSpellCheckRequestSequence();
+ [MayThrowException] long lastSpellCheckProcessedSequence();
sequence<DOMString> userPreferredLanguages();
void setUserPreferredLanguages(sequence<DOMString> languages);
- [RaisesException] unsigned long wheelEventHandlerCount();
- [RaisesException] unsigned long touchEventHandlerCount();
+ sequence<DOMString> userPreferredAudioCharacteristics();
+ void setUserPreferredAudioCharacteristic(DOMString characteristic);
+
+ [MayThrowException] unsigned long wheelEventHandlerCount();
+ [MayThrowException] unsigned long touchEventHandlerCount();
- [RaisesException] NodeList nodesFromRect(Document document, long x, long y,
+ [MayThrowException] NodeList? nodesFromRect(Document document, long x, long y,
unsigned long topPadding, unsigned long rightPadding, unsigned long bottomPadding, unsigned long leftPadding,
boolean ignoreClipping, boolean allowShadowContent, boolean allowChildFrameContent);
- void emitInspectorDidBeginFrame();
- void emitInspectorDidCancelFrame();
-
// Calling parserMetaData() with no arguments gets the metadata for the script of the current scope.
DOMString parserMetaData(optional any func);
- [RaisesException] boolean hasSpellingMarker(long from, long length);
- [RaisesException] boolean hasGrammarMarker(long from, long length);
- [RaisesException] boolean hasAutocorrectedMarker(long from, long length);
- [RaisesException] void setContinuousSpellCheckingEnabled(boolean enabled);
- [RaisesException] void setAutomaticQuoteSubstitutionEnabled(boolean enabled);
- [RaisesException] void setAutomaticLinkDetectionEnabled(boolean enabled);
- [RaisesException] void setAutomaticDashSubstitutionEnabled(boolean enabled);
- [RaisesException] void setAutomaticTextReplacementEnabled(boolean enabled);
- [RaisesException] void setAutomaticSpellingCorrectionEnabled(boolean enabled);
+ void updateEditorUINowIfScheduled();
+
+ boolean hasSpellingMarker(long from, long length);
+ boolean hasGrammarMarker(long from, long length);
+ boolean hasAutocorrectedMarker(long from, long length);
+ void setContinuousSpellCheckingEnabled(boolean enabled);
+ void setAutomaticQuoteSubstitutionEnabled(boolean enabled);
+ void setAutomaticLinkDetectionEnabled(boolean enabled);
+ void setAutomaticDashSubstitutionEnabled(boolean enabled);
+ void setAutomaticTextReplacementEnabled(boolean enabled);
+ void setAutomaticSpellingCorrectionEnabled(boolean enabled);
+
+ void handleAcceptedCandidate(DOMString candidate, unsigned long location, unsigned long length);
- [RaisesException] boolean isOverwriteModeEnabled();
- [RaisesException] void toggleOverwriteModeEnabled();
+ boolean isOverwriteModeEnabled();
+ void toggleOverwriteModeEnabled();
- [RaisesException] unsigned long numberOfScrollableAreas();
+ unsigned long numberOfScrollableAreas();
- [RaisesException] boolean isPageBoxVisible(long pageNumber);
+ [MayThrowException] boolean isPageBoxVisible(long pageNumber);
+
+ unsigned long imageFrameIndex(HTMLImageElement element);
+ void setImageFrameDecodingDuration(HTMLImageElement element, unrestricted float duration);
+ void resetImageAnimation(HTMLImageElement element);
readonly attribute InternalSettings settings;
readonly attribute unsigned long workerThreadCount;
+ readonly attribute boolean areSVGAnimationsPaused;
+
// Flags for layerTreeAsText.
const unsigned short LAYER_TREE_INCLUDES_VISIBLE_RECTS = 1;
const unsigned short LAYER_TREE_INCLUDES_TILE_CACHES = 2;
const unsigned short LAYER_TREE_INCLUDES_REPAINT_RECTS = 4;
const unsigned short LAYER_TREE_INCLUDES_PAINTING_PHASES = 8;
const unsigned short LAYER_TREE_INCLUDES_CONTENT_LAYERS = 16;
- [RaisesException] DOMString layerTreeAsText(Document document, optional unsigned short flags);
+ const unsigned short LAYER_TREE_INCLUDES_ACCELERATES_DRAWING = 32;
+ [MayThrowException] DOMString layerTreeAsText(Document document, optional unsigned short flags = 0);
- [RaisesException] DOMString scrollingStateTreeAsText();
- [RaisesException] DOMString mainThreadScrollingReasons(); // FIXME: rename to synchronousScrollingReasons().
- [RaisesException] ClientRectList nonFastScrollableRects();
+ [MayThrowException] DOMString scrollingStateTreeAsText();
+ [MayThrowException] DOMString mainThreadScrollingReasons(); // FIXME: rename to synchronousScrollingReasons().
+ [MayThrowException] ClientRectList? nonFastScrollableRects();
- [RaisesException] DOMString repaintRectsAsText();
+ [MayThrowException] DOMString repaintRectsAsText();
- [RaisesException] void garbageCollectDocumentResources();
+ // These throw if the element does not have a compositing layer.
+ [MayThrowException] void setElementUsesDisplayListDrawing(Element element, boolean usesDisplayListDrawing);
+ [MayThrowException] void setElementTracksDisplayListReplay(Element element, boolean trackReplay);
- void allowRoundingHacks();
+ // Flags for displayListForElement.
+ const unsigned short DISPLAY_LIST_INCLUDES_PLATFORM_OPERATIONS = 1;
+ // Returns the recorded display list.
+ [MayThrowException] DOMString displayListForElement(Element element, optional unsigned short flags = 0);
+ // Returns the display list that was actually painted.
+ [MayThrowException] DOMString replayDisplayListForElement(Element element, optional unsigned short flags = 0);
- [RaisesException] void insertAuthorCSS(DOMString css);
- [RaisesException] void insertUserCSS(DOMString css);
+ [MayThrowException] void garbageCollectDocumentResources();
-#if defined(ENABLE_BATTERY_STATUS) && ENABLE_BATTERY_STATUS
- [RaisesException] void setBatteryStatus(DOMString eventType, boolean charging, double chargingTime, double dischargingTime, double level);
-#endif
+ [MayThrowException] void insertAuthorCSS(DOMString css);
+ [MayThrowException] void insertUserCSS(DOMString css);
-#if defined(ENABLE_NETWORK_INFO) && ENABLE_NETWORK_INFO
- [RaisesException] void setNetworkInformation(DOMString eventType, double bandwidth, boolean metered);
-#endif
+ readonly attribute boolean isUnderMemoryPressure;
+ void beginSimulatedMemoryPressure();
+ void endSimulatedMemoryPressure();
#if defined(ENABLE_PROXIMITY_EVENTS) && ENABLE_PROXIMITY_EVENTS
- [RaisesException] void setDeviceProximity(DOMString eventType, double value, double min, double max);
+ [MayThrowException] void setDeviceProximity(DOMString eventType, unrestricted double value, unrestricted double min, unrestricted double max);
#endif
- [Conditional=INSPECTOR] unsigned long numberOfLiveNodes();
- [Conditional=INSPECTOR] unsigned long numberOfLiveDocuments();
- [Conditional=INSPECTOR] sequence<DOMString> consoleMessageArgumentCounts();
- [Conditional=INSPECTOR] DOMWindow openDummyInspectorFrontend(DOMString url);
- [Conditional=INSPECTOR] void closeDummyInspectorFrontend();
- [Conditional=INSPECTOR, RaisesException] void setInspectorResourcesDataSizeLimits(long maximumResourcesContentSize, long maximumSingleResourceContentSize);
- [Conditional=INSPECTOR, RaisesException] void setJavaScriptProfilingEnabled(boolean creates);
+ unsigned long numberOfLiveNodes();
+ unsigned long numberOfLiveDocuments();
+ DOMWindow? openDummyInspectorFrontend(DOMString url);
+ void closeDummyInspectorFrontend();
+ [MayThrowException] void setInspectorIsUnderTest(boolean isUnderTest);
DOMString counterValue(Element element);
- long pageNumber(Element element, optional float pageWidth, optional float pageHeight);
- DOMString[] shortcutIconURLs();
- DOMString[] allIconURLs();
- long numberOfPages(optional double pageWidthInPixels, optional double pageHeightInPixels);
- [RaisesException] DOMString pageProperty(DOMString propertyName, long pageNumber);
- [RaisesException] DOMString pageSizeAndMarginsInPixels(long pageIndex, long width, long height, long marginTop, long marginRight, long marginBottom, long marginLeft);
+ long pageNumber(Element element, optional unrestricted float pageWidth = 800, optional unrestricted float pageHeight = 600);
+ sequence<DOMString> shortcutIconURLs();
+ long numberOfPages(optional unrestricted double pageWidthInPixels = 800, optional unrestricted double pageHeightInPixels = 600);
+ [MayThrowException] DOMString pageProperty(DOMString propertyName, long pageNumber);
+ [MayThrowException] DOMString pageSizeAndMarginsInPixels(long pageIndex, long width, long height, long marginTop, long marginRight, long marginBottom, long marginLeft);
- [RaisesException] void setPageScaleFactor(float scaleFactor, long x, long y);
+ [MayThrowException] void setPageScaleFactor(unrestricted float scaleFactor, long x, long y);
+ [MayThrowException] float pageScaleFactor();
- void setHeaderHeight(float height);
- void setFooterHeight(float height);
+ [MayThrowException] void setPageZoomFactor(unrestricted float zoomFactor);
+ [MayThrowException] void setTextZoomFactor(unrestricted float zoomFactor);
+
+ [MayThrowException] void setUseFixedLayout(boolean useFixedLayout);
+ [MayThrowException] void setFixedLayoutSize(long width, long height);
+
+ [MayThrowException] void setViewExposedRect(unrestricted float x, unrestricted float y, unrestricted float width, unrestricted float height);
+
+ void setHeaderHeight(unrestricted float height);
+ void setFooterHeight(unrestricted float height);
+
+ void setTopContentInset(unrestricted float contentInset);
#if defined(ENABLE_FULLSCREEN_API) && ENABLE_FULLSCREEN_API
void webkitWillEnterFullScreenForElement(Element element);
@@ -220,64 +328,180 @@
void registerURLSchemeAsBypassingContentSecurityPolicy(DOMString scheme);
void removeURLSchemeRegisteredAsBypassingContentSecurityPolicy(DOMString scheme);
+ void registerDefaultPortForProtocol(unsigned short port, DOMString scheme);
+
MallocStatistics mallocStatistics();
TypeConversions typeConversions();
MemoryInfo memoryInfo();
- DOMString[] getReferencedFilePaths();
+ sequence<DOMString> getReferencedFilePaths();
- // These functions both reset the tracked repaint rects. They are inteded to be used in the following order:
+ // These functions both reset the tracked repaint rects. They are intended to be used in the following order:
// startTrackingRepaints, repaintRectsAsText, stopTrackingRepaints.
- [RaisesException] void startTrackingRepaints();
- [RaisesException] void stopTrackingRepaints();
+ [MayThrowException] void startTrackingRepaints();
+ [MayThrowException] void stopTrackingRepaints();
+
+ [MayThrowException] void startTrackingLayerFlushes();
+ [MayThrowException] unsigned long layerFlushCount();
+
+ // Query if a timer is currently throttled, to debug timer throttling.
+ [MayThrowException] boolean isTimerThrottled(long timerHandle);
+
+ boolean isRequestAnimationFrameThrottled();
+ boolean areTimersThrottled();
+
+ // Override the behavior of WebPage::eventThrottlingDelay(), which only affects iOS.
+ attribute EventThrottlingBehavior? eventThrottlingBehaviorOverride;
+
+ [MayThrowException] void startTrackingStyleRecalcs();
+ [MayThrowException] unsigned long styleRecalcCount();
+ readonly attribute unsigned long lastStyleUpdateSize;
+
+ [MayThrowException] void startTrackingCompositingUpdates();
+ [MayThrowException] unsigned long compositingUpdateCount();
// |node| should be Document, HTMLIFrameElement, or unspecified.
// If |node| is an HTMLIFrameElement, it assumes node.contentDocument is
- // specified without security checks. Unspecified means this document.
- [RaisesException] void updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks(optional Node node);
+ // specified without security checks. Unspecified or null means this document.
+ [MayThrowException] void updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks(optional Node? node = null);
+
+ readonly attribute unsigned long layoutCount;
// Returns a string with information about the mouse cursor used at the specified client location.
- [RaisesException] DOMString getCurrentCursorInfo();
+ [MayThrowException] DOMString getCurrentCursorInfo();
- [RaisesException] DOMString markerTextForListItem(Element element);
+ DOMString markerTextForListItem(Element element);
+
+ DOMString toolTipFromElement(Element element);
SerializedScriptValue deserializeBuffer(ArrayBuffer buffer);
- ArrayBuffer serializeObject(SerializedScriptValue obj);
+ ArrayBuffer serializeObject(SerializedScriptValue object);
+
+ boolean isFromCurrentWorld(any obj);
void setUsesOverlayScrollbars(boolean enabled);
+ void setUsesMockScrollAnimator(boolean enabled);
void forceReload(boolean endToEnd);
- [Conditional=VIDEO] void simulateAudioInterruption(Node node);
+ void enableAutoSizeMode(boolean enabled, long minimumWidth, long minimumHeight, long maximumWidth, long maximumHeight);
- [Conditional=ENCRYPTED_MEDIA_V2] void initializeMockCDM();
+ [Conditional=VIDEO] void simulateAudioInterruption(HTMLMediaElement element);
+ [Conditional=VIDEO, MayThrowException] boolean mediaElementHasCharacteristic(HTMLMediaElement element, DOMString characteristic);
+
+ [Conditional=LEGACY_ENCRYPTED_MEDIA] void initializeMockCDM();
+ [Conditional=ENCRYPTED_MEDIA] MockCDMFactory registerMockCDM();
[Conditional=SPEECH_SYNTHESIS] void enableMockSpeechSynthesizer();
- [RaisesException] DOMString getImageSourceURL(Element element);
+ DOMString getImageSourceURL(Element element);
- [Conditional=VIDEO_TRACK, RaisesException] DOMString captionsStyleSheetOverride();
- [Conditional=VIDEO_TRACK, RaisesException] void setCaptionsStyleSheetOverride(DOMString override);
- [Conditional=VIDEO_TRACK, RaisesException] void setPrimaryAudioTrackLanguageOverride(DOMString language);
- [Conditional=VIDEO_TRACK, RaisesException] void setCaptionDisplayMode(DOMString mode);
+ [Conditional=VIDEO_TRACK, MayThrowException] DOMString captionsStyleSheetOverride();
+ [Conditional=VIDEO_TRACK, MayThrowException] void setCaptionsStyleSheetOverride(DOMString override);
+ [Conditional=VIDEO_TRACK, MayThrowException] void setPrimaryAudioTrackLanguageOverride(DOMString language);
+ [Conditional=VIDEO_TRACK, MayThrowException] void setCaptionDisplayMode(DOMString mode);
[Conditional=VIDEO] TimeRanges createTimeRanges(Float32Array startTimes, Float32Array
endTimes);
- [Conditional=VIDEO] double closestTimeToTimeRanges(double time, TimeRanges ranges);
+ [Conditional=VIDEO] unrestricted double closestTimeToTimeRanges(unrestricted double time, TimeRanges ranges);
- boolean isSelectPopupVisible(Node node);
+ boolean isSelectPopupVisible(HTMLSelectElement element);
#if defined(ENABLE_VIBRATION) && ENABLE_VIBRATION
boolean isVibrating();
#endif
- [RaisesException] boolean isPluginUnavailabilityIndicatorObscured(Element element);
+ [MayThrowException] boolean isPluginUnavailabilityIndicatorObscured(Element element);
+ boolean isPluginSnapshotted(Element element);
+
+ [MayThrowException] ClientRect selectionBounds();
- [RaisesException] ClientRect selectionBounds();
-
[Conditional=MEDIA_SOURCE] void initializeMockMediaSource();
+ [Conditional=MEDIA_SOURCE] sequence<DOMString> bufferedSamplesForTrackID(SourceBuffer buffer, DOMString trackID);
+ [Conditional=MEDIA_SOURCE] sequence<DOMString> enqueuedSamplesForTrackID(SourceBuffer buffer, DOMString trackID);
+ [Conditional=MEDIA_SOURCE] void setShouldGenerateTimestamps(SourceBuffer buffer, boolean flag);
+
+ [Conditional=VIDEO, MayThrowException] void beginMediaSessionInterruption(DOMString interruptionType);
+ [Conditional=VIDEO] void endMediaSessionInterruption(DOMString flags);
+ [Conditional=MEDIA_SESSION] void sendMediaSessionStartOfInterruptionNotification(MediaSessionInterruptingCategory category);
+ [Conditional=MEDIA_SESSION] void sendMediaSessionEndOfInterruptionNotification(MediaSessionInterruptingCategory category);
+ [Conditional=MEDIA_SESSION] DOMString mediaSessionCurrentState(MediaSession session);
+ [Conditional=MEDIA_SESSION] double mediaElementPlayerVolume(HTMLMediaElement element);
+ [Conditional=MEDIA_SESSION] void sendMediaControlEvent(MediaControlEvent event);
+ [Conditional=VIDEO] void applicationDidEnterForeground();
+ [Conditional=VIDEO] void applicationWillEnterBackground();
+ [Conditional=VIDEO, MayThrowException] void setMediaSessionRestrictions(DOMString mediaType, DOMString restrictions);
+ [Conditional=VIDEO, MayThrowException] DOMString mediaSessionRestrictions(DOMString mediaType);
+ [Conditional=VIDEO] void setMediaElementRestrictions(HTMLMediaElement element, DOMString restrictions);
+ [Conditional=WEB_AUDIO] void setAudioContextRestrictions(AudioContext context, DOMString restrictions);
+ [Conditional=VIDEO, MayThrowException] void postRemoteControlCommand(DOMString command, optional unrestricted float argument = 0);
+ [Conditional=WIRELESS_PLAYBACK_TARGET] void setMockMediaPlaybackTargetPickerEnabled(boolean enabled);
+ [Conditional=WIRELESS_PLAYBACK_TARGET, MayThrowException] void setMockMediaPlaybackTargetPickerState(DOMString deviceName, DOMString deviceState);
+ [Conditional=MEDIA_STREAM] void setMockMediaCaptureDevicesEnabled(boolean enabled);
+ [Conditional=WEB_RTC] void emulateRTCPeerConnectionPlatformEvent(RTCPeerConnection connection, DOMString action);
+ [Conditional=WEB_RTC] void useMockRTCPeerConnectionFactory(DOMString testCase);
+
+ [Conditional=VIDEO] void simulateSystemSleep();
+ [Conditional=VIDEO] void simulateSystemWake();
+ [Conditional=VIDEO] boolean elementIsBlockingDisplaySleep(HTMLMediaElement element);
+
+ [MayThrowException] MockPageOverlay installMockPageOverlay(PageOverlayType type);
+ [MayThrowException] DOMString pageOverlayLayerTreeAsText(optional unsigned short flags = 0);
+
+ void setPageMuted(DOMString mutedState);
+ DOMString pageMediaState();
+
+ void setPageDefersLoading(boolean defersLoading);
+
+ File? createFile(DOMString url);
+ void queueMicroTask(long testNumber);
+ boolean testPreloaderSettingViewport();
+
+ [Conditional=CONTENT_FILTERING] readonly attribute MockContentFilterSettings mockContentFilterSettings;
+
+#if defined(ENABLE_CSS_SCROLL_SNAP) && ENABLE_CSS_SCROLL_SNAP
+ [MayThrowException] DOMString scrollSnapOffsets(Element element);
+ void setPlatformMomentumScrollingPredictionEnabled(boolean enabled);
+#endif
+
+ [MayThrowException] DOMString pathStringWithShrinkWrappedRects(sequence<double> rectComponents, double radius);
+
+ [Conditional=VIDEO] DOMString getCurrentMediaControlsStatusForElement(HTMLMediaElement element);
+
+ DOMString userVisibleString(DOMURL url);
+
+ void setShowAllPlugins(boolean showAll);
+
+ [Conditional=READABLE_STREAM_API, CallWith=ScriptState] boolean isReadableStreamDisturbed(any stream);
+
+ DOMString resourceLoadStatisticsForOrigin(DOMString domain);
+ void setResourceLoadStatisticsEnabled(boolean enable);
+
+ [MayThrowException] void setCanShowModalDialogOverride(boolean allow);
+
+ DOMString composedTreeAsText(Node parent);
+
+ boolean isProcessingUserGesture();
+
+ GCObservation? observeGC(any observed);
+
+ void setUserInterfaceLayoutDirection(UserInterfaceLayoutDirection userInterfaceLayoutDirection);
+ void setBaseWritingDirection(BaseWritingDirection direction);
+
+ boolean userPrefersReducedMotion();
+
+ void reportBacktrace();
+
+ [Conditional=POINTER_LOCK] boolean pageHasPendingPointerLock();
+ [Conditional=POINTER_LOCK] boolean pageHasPointerLock();
+
+ sequence<DOMString> accessKeyModifiers();
+
+#if defined(WTF_PLATFORM_IOS) && WTF_PLATFORM_IOS
+ void setQuickLookPassword(DOMString password);
+#endif
+
+ [CallWith=Document] void setAsRunningUserScripts();
- void beginMediaSessionInterruption();
- void endMediaSessionInterruption(DOMString flags);
- [RaisesException] void setMediaSessionRestrictions(DOMString mediaType, DOMString restrictions);
+ void disableTileSizeUpdateDelay();
};
diff --git a/Source/WebCore/testing/LegacyMockCDM.cpp b/Source/WebCore/testing/LegacyMockCDM.cpp
new file mode 100644
index 000000000..b1a56aa21
--- /dev/null
+++ b/Source/WebCore/testing/LegacyMockCDM.cpp
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "LegacyMockCDM.h"
+
+#if ENABLE(LEGACY_ENCRYPTED_MEDIA)
+
+#include "LegacyCDM.h"
+#include "LegacyCDMSession.h"
+#include "WebKitMediaKeyError.h"
+#include <runtime/JSCInlines.h>
+#include <runtime/TypedArrayInlines.h>
+#include <runtime/Uint8Array.h>
+
+namespace WebCore {
+
+class MockCDMSession : public CDMSession {
+public:
+ MockCDMSession(CDMSessionClient*);
+ virtual ~MockCDMSession() { }
+
+ void setClient(CDMSessionClient* client) override { m_client = client; }
+ const String& sessionId() const override { return m_sessionId; }
+ RefPtr<Uint8Array> generateKeyRequest(const String& mimeType, Uint8Array* initData, String& destinationURL, unsigned short& errorCode, uint32_t& systemCode) override;
+ void releaseKeys() override;
+ bool update(Uint8Array*, RefPtr<Uint8Array>& nextMessage, unsigned short& errorCode, uint32_t& systemCode) override;
+
+protected:
+ CDMSessionClient* m_client;
+ String m_sessionId;
+};
+
+bool MockCDM::supportsKeySystem(const String& keySystem)
+{
+ return equalLettersIgnoringASCIICase(keySystem, "com.webcore.mock");
+}
+
+bool MockCDM::supportsKeySystemAndMimeType(const String& keySystem, const String& mimeType)
+{
+ if (!supportsKeySystem(keySystem))
+ return false;
+
+ return equalLettersIgnoringASCIICase(mimeType, "video/mock");
+}
+
+bool MockCDM::supportsMIMEType(const String& mimeType)
+{
+ return equalLettersIgnoringASCIICase(mimeType, "video/mock");
+}
+
+std::unique_ptr<CDMSession> MockCDM::createSession(CDMSessionClient* client)
+{
+ return std::make_unique<MockCDMSession>(client);
+}
+
+static Uint8Array* initDataPrefix()
+{
+ const unsigned char prefixData[] = { 'm', 'o', 'c', 'k' };
+ static Uint8Array* prefix = Uint8Array::create(prefixData, WTF_ARRAY_LENGTH(prefixData)).leakRef();
+
+ return prefix;
+}
+
+static Uint8Array* keyPrefix()
+{
+ static const unsigned char prefixData[] = {'k', 'e', 'y'};
+ static Uint8Array* prefix = Uint8Array::create(prefixData, WTF_ARRAY_LENGTH(prefixData)).leakRef();
+
+ return prefix;
+}
+
+static Uint8Array* keyRequest()
+{
+ static const unsigned char requestData[] = {'r', 'e', 'q', 'u', 'e', 's', 't'};
+ static Uint8Array* request = Uint8Array::create(requestData, WTF_ARRAY_LENGTH(requestData)).leakRef();
+
+ return request;
+}
+
+static String generateSessionId()
+{
+ static int monotonicallyIncreasingSessionId = 0;
+ return String::number(monotonicallyIncreasingSessionId++);
+}
+
+MockCDMSession::MockCDMSession(CDMSessionClient* client)
+ : m_client(client)
+ , m_sessionId(generateSessionId())
+{
+}
+
+RefPtr<Uint8Array> MockCDMSession::generateKeyRequest(const String&, Uint8Array* initData, String&, unsigned short& errorCode, uint32_t&)
+{
+ for (unsigned i = 0; i < initDataPrefix()->length(); ++i) {
+ if (!initData || i >= initData->length() || initData->item(i) != initDataPrefix()->item(i)) {
+ errorCode = WebKitMediaKeyError::MEDIA_KEYERR_UNKNOWN;
+ return nullptr;
+ }
+ }
+ return keyRequest();
+}
+
+void MockCDMSession::releaseKeys()
+{
+ // no-op
+}
+
+bool MockCDMSession::update(Uint8Array* key, RefPtr<Uint8Array>&, unsigned short& errorCode, uint32_t&)
+{
+ for (unsigned i = 0; i < keyPrefix()->length(); ++i) {
+ if (i >= key->length() || key->item(i) != keyPrefix()->item(i)) {
+ errorCode = WebKitMediaKeyError::MEDIA_KEYERR_CLIENT;
+ return false;
+ }
+ }
+ return true;
+}
+
+}
+
+#endif // ENABLE(LEGACY_ENCRYPTED_MEDIA)
diff --git a/Source/WebCore/testing/LegacyMockCDM.h b/Source/WebCore/testing/LegacyMockCDM.h
new file mode 100644
index 000000000..0161ad3d8
--- /dev/null
+++ b/Source/WebCore/testing/LegacyMockCDM.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(LEGACY_ENCRYPTED_MEDIA)
+
+#include "LegacyCDMPrivate.h"
+
+namespace WebCore {
+
+class CDM;
+
+class MockCDM : public CDMPrivateInterface {
+public:
+ explicit MockCDM(CDM* cdm)
+ : m_cdm(cdm)
+ { }
+
+ // CDMFactory support:
+ static bool supportsKeySystem(const String&);
+ static bool supportsKeySystemAndMimeType(const String& keySystem, const String& mimeType);
+
+ virtual ~MockCDM() { }
+
+ bool supportsMIMEType(const String& mimeType) override;
+ std::unique_ptr<CDMSession> createSession(CDMSessionClient*) override;
+
+protected:
+ CDM* m_cdm;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(LEGACY_ENCRYPTED_MEDIA)
diff --git a/Source/WebCore/testing/MallocStatistics.h b/Source/WebCore/testing/MallocStatistics.h
index 3f07bbd9f..f08c4e212 100644
--- a/Source/WebCore/testing/MallocStatistics.h
+++ b/Source/WebCore/testing/MallocStatistics.h
@@ -23,18 +23,16 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef MallocStatistics_h
-#define MallocStatistics_h
+#pragma once
#include <wtf/FastMalloc.h>
-#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
namespace WebCore {
class MallocStatistics : public RefCounted<MallocStatistics> {
public:
- static PassRefPtr<MallocStatistics> create() { return adoptRef(new MallocStatistics()); }
+ static Ref<MallocStatistics> create() { return adoptRef(*new MallocStatistics); }
size_t reservedVMBytes() const { return m_stats.reservedVMBytes; }
size_t committedVMBytes() const { return m_stats.committedVMBytes; }
@@ -50,5 +48,3 @@ private:
};
} // namespace WebCore
-
-#endif
diff --git a/Source/WebCore/testing/MallocStatistics.idl b/Source/WebCore/testing/MallocStatistics.idl
index d9c817b91..c6e471e0b 100644
--- a/Source/WebCore/testing/MallocStatistics.idl
+++ b/Source/WebCore/testing/MallocStatistics.idl
@@ -25,7 +25,8 @@
[
NoInterfaceObject,
- ImplementationLacksVTable
+ ImplementationLacksVTable,
+ ExportMacro=WEBCORE_TESTSUPPORT_EXPORT,
] interface MallocStatistics {
readonly attribute unsigned long reservedVMBytes;
readonly attribute unsigned long committedVMBytes;
diff --git a/Source/WebCore/testing/MemoryInfo.h b/Source/WebCore/testing/MemoryInfo.h
index d4d298443..06084a83f 100644
--- a/Source/WebCore/testing/MemoryInfo.h
+++ b/Source/WebCore/testing/MemoryInfo.h
@@ -28,26 +28,25 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef MemoryInfo_h
-#define MemoryInfo_h
+#pragma once
+#include "CommonVM.h"
#include "JSDOMWindow.h"
-#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
namespace WebCore {
class MemoryInfo : public RefCounted<MemoryInfo> {
public:
- static PassRefPtr<MemoryInfo> create() { return adoptRef(new MemoryInfo); }
+ static Ref<MemoryInfo> create() { return adoptRef(*new MemoryInfo); }
size_t usedJSHeapSize() const { return m_usedJSHeapSize; }
size_t totalJSHeapSize() const { return m_totalJSHeapSize; }
private:
MemoryInfo()
- : m_usedJSHeapSize(JSDOMWindow::commonVM()->heap.size())
- , m_totalJSHeapSize(JSDOMWindow::commonVM()->heap.capacity())
+ : m_usedJSHeapSize(commonVM().heap.size())
+ , m_totalJSHeapSize(commonVM().heap.capacity())
{
}
@@ -56,5 +55,3 @@ private:
};
} // namespace WebCore
-
-#endif // MemoryInfo_h
diff --git a/Source/WebCore/testing/MemoryInfo.idl b/Source/WebCore/testing/MemoryInfo.idl
index 6eb998721..54c7cff21 100644
--- a/Source/WebCore/testing/MemoryInfo.idl
+++ b/Source/WebCore/testing/MemoryInfo.idl
@@ -30,7 +30,8 @@
[
NoInterfaceObject,
- ImplementationLacksVTable
+ ImplementationLacksVTable,
+ ExportMacro=WEBCORE_TESTSUPPORT_EXPORT,
] interface MemoryInfo {
readonly attribute unsigned long usedJSHeapSize;
readonly attribute unsigned long totalJSHeapSize;
diff --git a/Source/WebCore/testing/MockCDMFactory.cpp b/Source/WebCore/testing/MockCDMFactory.cpp
new file mode 100644
index 000000000..f3b4a47e6
--- /dev/null
+++ b/Source/WebCore/testing/MockCDMFactory.cpp
@@ -0,0 +1,382 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "MockCDMFactory.h"
+
+#if ENABLE(ENCRYPTED_MEDIA)
+
+#include "InitDataRegistry.h"
+#include "UUID.h"
+#include <runtime/ArrayBuffer.h>
+#include <wtf/text/StringHash.h>
+#include <wtf/text/StringView.h>
+
+namespace WebCore {
+
+MockCDMFactory::MockCDMFactory()
+ : m_supportedSessionTypes({ MediaKeySessionType::Temporary, MediaKeySessionType::PersistentUsageRecord, MediaKeySessionType::PersistentLicense })
+ , m_weakPtrFactory(this)
+{
+ CDM::registerCDMFactory(*this);
+}
+
+MockCDMFactory::~MockCDMFactory()
+{
+ unregister();
+}
+
+void MockCDMFactory::unregister()
+{
+ if (m_registered) {
+ CDM::unregisterCDMFactory(*this);
+ m_registered = false;
+ }
+}
+
+bool MockCDMFactory::supportsKeySystem(const String& keySystem)
+{
+ return equalIgnoringASCIICase(keySystem, "org.webkit.mock");
+}
+
+void MockCDMFactory::addKeysToSessionWithID(const String& id, Vector<Ref<SharedBuffer>>&& keys)
+{
+ auto addResult = m_sessions.add(id, WTFMove(keys));
+ if (addResult.isNewEntry)
+ return;
+
+ auto& value = addResult.iterator->value;
+ for (auto& key : keys)
+ value.append(WTFMove(key));
+}
+
+Vector<Ref<SharedBuffer>> MockCDMFactory::removeKeysFromSessionWithID(const String& id)
+{
+ auto it = m_sessions.find(id);
+ if (it == m_sessions.end())
+ return { };
+
+ return WTFMove(it->value);
+}
+
+std::optional<const Vector<Ref<SharedBuffer>>&> MockCDMFactory::keysForSessionWithID(const String& id) const
+{
+ auto it = m_sessions.find(id);
+ if (it == m_sessions.end())
+ return std::nullopt;
+ return it->value;
+}
+
+void MockCDMFactory::setSupportedDataTypes(Vector<String>&& types)
+{
+ m_supportedDataTypes.clear();
+ for (auto& type : types)
+ m_supportedDataTypes.append(type);
+}
+
+std::unique_ptr<CDMPrivate> MockCDMFactory::createCDM(CDM&)
+{
+ return std::make_unique<MockCDM>(m_weakPtrFactory.createWeakPtr());
+}
+
+MockCDM::MockCDM(WeakPtr<MockCDMFactory> factory)
+ : m_factory(WTFMove(factory))
+ , m_weakPtrFactory(this)
+{
+}
+
+bool MockCDM::supportsInitDataType(const AtomicString& initDataType) const
+{
+ if (m_factory)
+ return m_factory->supportedDataTypes().contains(initDataType);
+ return false;
+}
+
+bool MockCDM::supportsConfiguration(const MediaKeySystemConfiguration&) const
+{
+ // NOTE: Implement;
+ return true;
+
+}
+
+bool MockCDM::supportsConfigurationWithRestrictions(const MediaKeySystemConfiguration&, const MediaKeysRestrictions&) const
+{
+ // NOTE: Implement;
+ return true;
+}
+
+bool MockCDM::supportsSessionTypeWithConfiguration(MediaKeySessionType& sessionType, const MediaKeySystemConfiguration&) const
+{
+ if (!m_factory || !m_factory->supportedSessionTypes().contains(sessionType))
+ return false;
+
+ // NOTE: Implement configuration checking;
+ return true;
+}
+
+bool MockCDM::supportsRobustness(const String& robustness) const
+{
+ if (m_factory)
+ return m_factory->supportedRobustness().contains(robustness);
+ return false;
+}
+
+MediaKeysRequirement MockCDM::distinctiveIdentifiersRequirement(const MediaKeySystemConfiguration&, const MediaKeysRestrictions&) const
+{
+ if (m_factory)
+ return m_factory->distinctiveIdentifiersRequirement();
+ return MediaKeysRequirement::Optional;
+}
+
+MediaKeysRequirement MockCDM::persistentStateRequirement(const MediaKeySystemConfiguration&, const MediaKeysRestrictions&) const
+{
+ if (m_factory)
+ return m_factory->persistentStateRequirement();
+ return MediaKeysRequirement::Optional;
+}
+
+bool MockCDM::distinctiveIdentifiersAreUniquePerOriginAndClearable(const MediaKeySystemConfiguration&) const
+{
+ // NOTE: Implement;
+ return true;
+}
+
+RefPtr<CDMInstance> MockCDM::createInstance()
+{
+ if (m_factory && !m_factory->canCreateInstances())
+ return nullptr;
+ return adoptRef(new MockCDMInstance(m_weakPtrFactory.createWeakPtr()));
+}
+
+void MockCDM::loadAndInitialize()
+{
+ // No-op.
+}
+
+bool MockCDM::supportsServerCertificates() const
+{
+ return m_factory && m_factory->supportsServerCertificates();
+}
+
+bool MockCDM::supportsSessions() const
+{
+ return m_factory && m_factory->supportsSessions();
+}
+
+bool MockCDM::supportsInitData(const AtomicString& initDataType, const SharedBuffer& initData) const
+{
+ if (!supportsInitDataType(initDataType))
+ return false;
+
+ UNUSED_PARAM(initData);
+ return true;
+}
+
+RefPtr<SharedBuffer> MockCDM::sanitizeResponse(const SharedBuffer& response) const
+{
+ if (!charactersAreAllASCII(reinterpret_cast<const LChar*>(response.data()), response.size()))
+ return nullptr;
+
+ Vector<String> responseArray;
+ String(response.data(), response.size()).split(ASCIILiteral(" "), responseArray);
+
+ if (!responseArray.contains(String(ASCIILiteral("valid-response"))))
+ return nullptr;
+
+ return response.copy();
+}
+
+std::optional<String> MockCDM::sanitizeSessionId(const String& sessionId) const
+{
+ if (equalLettersIgnoringASCIICase(sessionId, "valid-loaded-session"))
+ return sessionId;
+ return std::nullopt;
+}
+
+MockCDMInstance::MockCDMInstance(WeakPtr<MockCDM> cdm)
+ : m_cdm(cdm)
+{
+}
+
+CDMInstance::SuccessValue MockCDMInstance::initializeWithConfiguration(const MediaKeySystemConfiguration& configuration)
+{
+ if (!m_cdm || !m_cdm->supportsConfiguration(configuration))
+ return Failed;
+
+ return Succeeded;
+}
+
+CDMInstance::SuccessValue MockCDMInstance::setDistinctiveIdentifiersAllowed(bool distinctiveIdentifiersAllowed)
+{
+ if (m_distinctiveIdentifiersAllowed == distinctiveIdentifiersAllowed)
+ return Succeeded;
+
+ auto* factory = m_cdm ? m_cdm->factory() : nullptr;
+
+ if (!factory || (!distinctiveIdentifiersAllowed && factory->distinctiveIdentifiersRequirement() == MediaKeysRequirement::Required))
+ return Failed;
+
+ m_distinctiveIdentifiersAllowed = distinctiveIdentifiersAllowed;
+ return Succeeded;
+}
+
+CDMInstance::SuccessValue MockCDMInstance::setPersistentStateAllowed(bool persistentStateAllowed)
+{
+ if (m_persistentStateAllowed == persistentStateAllowed)
+ return Succeeded;
+
+ MockCDMFactory* factory = m_cdm ? m_cdm->factory() : nullptr;
+
+ if (!factory || (!persistentStateAllowed && factory->persistentStateRequirement() == MediaKeysRequirement::Required))
+ return Failed;
+
+ m_persistentStateAllowed = persistentStateAllowed;
+ return Succeeded;
+}
+
+CDMInstance::SuccessValue MockCDMInstance::setServerCertificate(Ref<SharedBuffer>&& certificate)
+{
+ StringView certificateStringView(reinterpret_cast<const LChar*>(certificate->data()), certificate->size());
+
+ if (equalIgnoringASCIICase(certificateStringView, "valid"))
+ return Succeeded;
+ return Failed;
+}
+
+void MockCDMInstance::requestLicense(LicenseType licenseType, const AtomicString& initDataType, Ref<SharedBuffer>&& initData, LicenseCallback callback)
+{
+ MockCDMFactory* factory = m_cdm ? m_cdm->factory() : nullptr;
+ if (!factory) {
+ callback(SharedBuffer::create(), emptyAtom, false, SuccessValue::Failed);
+ return;
+ }
+
+ if (!factory->supportedSessionTypes().contains(licenseType) || !factory->supportedDataTypes().contains(initDataType)) {
+ callback(SharedBuffer::create(), emptyString(), false, SuccessValue::Failed);
+ return;
+ }
+
+ auto keyIDs = InitDataRegistry::shared().extractKeyIDs(initDataType, initData);
+ if (keyIDs.isEmpty()) {
+ callback(SharedBuffer::create(), emptyString(), false, SuccessValue::Failed);
+ return;
+ }
+
+ String sessionID = createCanonicalUUIDString();
+ factory->addKeysToSessionWithID(sessionID, WTFMove(keyIDs));
+
+ CString license { "license" };
+ callback(SharedBuffer::create(license.data(), license.length()), sessionID, false, SuccessValue::Succeeded);
+}
+
+void MockCDMInstance::updateLicense(const String& sessionID, LicenseType, const SharedBuffer& response, LicenseUpdateCallback callback)
+{
+ MockCDMFactory* factory = m_cdm ? m_cdm->factory() : nullptr;
+ if (!factory) {
+ callback(false, std::nullopt, std::nullopt, std::nullopt, SuccessValue::Failed);
+ return;
+ }
+
+ Vector<String> responseVector;
+ String(response.data(), response.size()).split(ASCIILiteral(" "), responseVector);
+
+ if (responseVector.contains(String(ASCIILiteral("invalid-format")))) {
+ callback(false, std::nullopt, std::nullopt, std::nullopt, SuccessValue::Failed);
+ return;
+ }
+
+ std::optional<KeyStatusVector> changedKeys;
+ if (responseVector.contains(String(ASCIILiteral("keys-changed")))) {
+ std::optional<const Vector<Ref<SharedBuffer>>&> keys = factory->keysForSessionWithID(sessionID);
+ if (keys) {
+ KeyStatusVector keyStatusVector;
+ keyStatusVector.reserveInitialCapacity(keys->size());
+ for (auto& key : *keys)
+ keyStatusVector.uncheckedAppend({ key.copyRef(), KeyStatus::Usable });
+
+ changedKeys = WTFMove(keyStatusVector);
+ }
+ }
+
+ // FIXME: Session closure, expiration and message handling should be implemented
+ // once the relevant algorithms are supported.
+
+ callback(false, WTFMove(changedKeys), std::nullopt, std::nullopt, SuccessValue::Succeeded);
+}
+
+void MockCDMInstance::loadSession(LicenseType, const String&, const String&, LoadSessionCallback callback)
+{
+ MockCDMFactory* factory = m_cdm ? m_cdm->factory() : nullptr;
+ if (!factory) {
+ callback(std::nullopt, std::nullopt, std::nullopt, SuccessValue::Failed, SessionLoadFailure::Other);
+ return;
+ }
+
+ // FIXME: Key status and expiration handling should be implemented once the relevant algorithms are supported.
+
+ CString messageData { "session loaded" };
+ Message message { MessageType::LicenseRenewal, SharedBuffer::create(messageData.data(), messageData.length()) };
+
+ callback(std::nullopt, std::nullopt, WTFMove(message), SuccessValue::Succeeded, SessionLoadFailure::None);
+}
+
+void MockCDMInstance::closeSession(const String& sessionID, CloseSessionCallback callback)
+{
+ MockCDMFactory* factory = m_cdm ? m_cdm->factory() : nullptr;
+ if (!factory) {
+ callback();
+ return;
+ }
+
+ factory->removeSessionWithID(sessionID);
+ callback();
+}
+
+void MockCDMInstance::removeSessionData(const String& id, LicenseType, RemoveSessionDataCallback callback)
+{
+ MockCDMFactory* factory = m_cdm ? m_cdm->factory() : nullptr;
+ if (!factory) {
+ callback({ }, std::nullopt, SuccessValue::Failed);
+ return;
+ }
+
+ auto keys = factory->removeKeysFromSessionWithID(id);
+ KeyStatusVector keyStatusVector;
+ keyStatusVector.reserveInitialCapacity(keys.size());
+ for (auto& key : keys)
+ keyStatusVector.uncheckedAppend({ WTFMove(key), KeyStatus::Released });
+
+ CString message { "remove-message" };
+ callback(WTFMove(keyStatusVector), SharedBuffer::create(message.data(), message.length()), SuccessValue::Succeeded);
+}
+
+void MockCDMInstance::storeRecordOfKeyUsage(const String&)
+{
+ // FIXME: This should be implemented along with the support for persistent-usage-record sessions.
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/testing/MockCDMFactory.h b/Source/WebCore/testing/MockCDMFactory.h
new file mode 100644
index 000000000..9e36a881b
--- /dev/null
+++ b/Source/WebCore/testing/MockCDMFactory.h
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(ENCRYPTED_MEDIA)
+
+#include "CDM.h"
+#include "CDMInstance.h"
+#include "CDMPrivate.h"
+#include "MediaKeysRequirement.h"
+#include <wtf/HashMap.h>
+#include <wtf/RefCounted.h>
+#include <wtf/Vector.h>
+#include <wtf/WeakPtr.h>
+
+namespace WebCore {
+
+class MockCDMFactory : public RefCounted<MockCDMFactory>, private CDMFactory {
+public:
+ static Ref<MockCDMFactory> create() { return adoptRef(*new MockCDMFactory); }
+ ~MockCDMFactory();
+
+ const Vector<AtomicString>& supportedDataTypes() const { return m_supportedDataTypes; }
+ void setSupportedDataTypes(Vector<String>&&);
+
+ const Vector<MediaKeySessionType>& supportedSessionTypes() const { return m_supportedSessionTypes; }
+ void setSupportedSessionTypes(Vector<MediaKeySessionType>&& types) { m_supportedSessionTypes = WTFMove(types); }
+
+ const Vector<String>& supportedRobustness() const { return m_supportedRobustness; }
+ void setSupportedRobustness(Vector<String>&& robustness) { m_supportedRobustness = WTFMove(robustness); }
+
+ MediaKeysRequirement distinctiveIdentifiersRequirement() const { return m_distinctiveIdentifiersRequirement; }
+ void setDistinctiveIdentifiersRequirement(MediaKeysRequirement requirement) { m_distinctiveIdentifiersRequirement = requirement; }
+
+ MediaKeysRequirement persistentStateRequirement() const { return m_persistentStateRequirement; }
+ void setPersistentStateRequirement(MediaKeysRequirement requirement) { m_persistentStateRequirement = requirement; }
+
+ bool canCreateInstances() const { return m_canCreateInstances; }
+ void setCanCreateInstances(bool flag) { m_canCreateInstances = flag; }
+
+ bool supportsServerCertificates() const { return m_supportsServerCertificates; }
+ void setSupportsServerCertificates(bool flag) { m_supportsServerCertificates = flag; }
+
+ bool supportsSessions() const { return m_supportsSessions; }
+ void setSupportsSessions(bool flag) { m_supportsSessions = flag; }
+
+ void unregister();
+
+ bool hasSessionWithID(const String& id) { return m_sessions.contains(id); }
+ void removeSessionWithID(const String& id) { m_sessions.remove(id); }
+ void addKeysToSessionWithID(const String& id, Vector<Ref<SharedBuffer>>&&);
+ std::optional<const Vector<Ref<SharedBuffer>>&> keysForSessionWithID(const String& id) const;
+ Vector<Ref<SharedBuffer>> removeKeysFromSessionWithID(const String& id);
+
+private:
+ MockCDMFactory();
+ std::unique_ptr<CDMPrivate> createCDM(CDM&) final;
+ bool supportsKeySystem(const String&) final;
+
+ MediaKeysRequirement m_distinctiveIdentifiersRequirement { MediaKeysRequirement::Optional };
+ MediaKeysRequirement m_persistentStateRequirement { MediaKeysRequirement::Optional };
+ Vector<AtomicString> m_supportedDataTypes;
+ Vector<MediaKeySessionType> m_supportedSessionTypes;
+ Vector<String> m_supportedRobustness;
+ bool m_registered { true };
+ bool m_canCreateInstances { true };
+ bool m_supportsServerCertificates { true };
+ bool m_supportsSessions { true };
+ WeakPtrFactory<MockCDMFactory> m_weakPtrFactory;
+ HashMap<String, Vector<Ref<SharedBuffer>>> m_sessions;
+};
+
+class MockCDM : public CDMPrivate {
+public:
+ MockCDM(WeakPtr<MockCDMFactory>);
+
+ MockCDMFactory* factory() { return m_factory.get(); }
+
+private:
+ friend class MockCDMInstance;
+
+ bool supportsInitDataType(const AtomicString&) const final;
+ bool supportsConfiguration(const MediaKeySystemConfiguration&) const final;
+ bool supportsConfigurationWithRestrictions(const MediaKeySystemConfiguration&, const MediaKeysRestrictions&) const final;
+ bool supportsSessionTypeWithConfiguration(MediaKeySessionType&, const MediaKeySystemConfiguration&) const final;
+ bool supportsRobustness(const String&) const final;
+ MediaKeysRequirement distinctiveIdentifiersRequirement(const MediaKeySystemConfiguration&, const MediaKeysRestrictions&) const final;
+ MediaKeysRequirement persistentStateRequirement(const MediaKeySystemConfiguration&, const MediaKeysRestrictions&) const final;
+ bool distinctiveIdentifiersAreUniquePerOriginAndClearable(const MediaKeySystemConfiguration&) const final;
+ RefPtr<CDMInstance> createInstance() final;
+ void loadAndInitialize() final;
+ bool supportsServerCertificates() const final;
+ bool supportsSessions() const final;
+ bool supportsInitData(const AtomicString&, const SharedBuffer&) const final;
+ RefPtr<SharedBuffer> sanitizeResponse(const SharedBuffer&) const final;
+ std::optional<String> sanitizeSessionId(const String&) const final;
+
+ WeakPtr<MockCDMFactory> m_factory;
+ WeakPtrFactory<MockCDM> m_weakPtrFactory;
+};
+
+class MockCDMInstance : public CDMInstance {
+public:
+ MockCDMInstance(WeakPtr<MockCDM>);
+
+private:
+ SuccessValue initializeWithConfiguration(const MediaKeySystemConfiguration&) final;
+ SuccessValue setDistinctiveIdentifiersAllowed(bool) final;
+ SuccessValue setPersistentStateAllowed(bool) final;
+ SuccessValue setServerCertificate(Ref<SharedBuffer>&&) final;
+ void requestLicense(LicenseType, const AtomicString& initDataType, Ref<SharedBuffer>&& initData, LicenseCallback) final;
+ void updateLicense(const String&, LicenseType, const SharedBuffer&, LicenseUpdateCallback) final;
+ void loadSession(LicenseType, const String&, const String&, LoadSessionCallback) final;
+ void closeSession(const String&, CloseSessionCallback) final;
+ void removeSessionData(const String&, LicenseType, RemoveSessionDataCallback) final;
+ void storeRecordOfKeyUsage(const String&) final;
+
+ WeakPtr<MockCDM> m_cdm;
+ bool m_distinctiveIdentifiersAllowed { true };
+ bool m_persistentStateAllowed { true };
+};
+
+}
+
+#endif
diff --git a/Source/WebCore/testing/MockCDMFactory.idl b/Source/WebCore/testing/MockCDMFactory.idl
new file mode 100644
index 000000000..90d382ec6
--- /dev/null
+++ b/Source/WebCore/testing/MockCDMFactory.idl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+[
+ Conditional=ENCRYPTED_MEDIA,
+ NoInterfaceObject,
+ ExportMacro=WEBCORE_TESTSUPPORT_EXPORT,
+] interface MockCDMFactory {
+ attribute sequence<DOMString> supportedDataTypes;
+ attribute sequence<DOMString> supportedRobustness;
+ attribute sequence<MediaKeySessionType> supportedSessionTypes;
+ attribute MediaKeysRequirement distinctiveIdentifiersRequirement;
+ attribute MediaKeysRequirement persistentStateRequirement;
+ attribute boolean canCreateInstances;
+ attribute boolean supportsServerCertificates;
+ attribute boolean supportsSessions;
+
+ void unregister();
+};
+
diff --git a/Source/WebCore/testing/MockContentFilter.cpp b/Source/WebCore/testing/MockContentFilter.cpp
new file mode 100644
index 000000000..d773f472d
--- /dev/null
+++ b/Source/WebCore/testing/MockContentFilter.cpp
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "MockContentFilter.h"
+
+#if ENABLE(CONTENT_FILTERING)
+
+#include "ContentFilter.h"
+#include "ContentFilterUnblockHandler.h"
+#include "Logging.h"
+#include "ResourceRequest.h"
+#include "ResourceResponse.h"
+#include "SharedBuffer.h"
+#include <mutex>
+#include <wtf/text/CString.h>
+
+namespace WebCore {
+
+using Decision = MockContentFilterSettings::Decision;
+using DecisionPoint = MockContentFilterSettings::DecisionPoint;
+
+void MockContentFilter::ensureInstalled()
+{
+ static std::once_flag onceFlag;
+ std::call_once(onceFlag, []{
+ ContentFilter::addType<MockContentFilter>();
+ });
+}
+
+static inline MockContentFilterSettings& settings()
+{
+ return MockContentFilterSettings::singleton();
+}
+
+bool MockContentFilter::enabled()
+{
+ bool enabled = settings().enabled();
+ LOG(ContentFiltering, "MockContentFilter is %s.\n", enabled ? "enabled" : "not enabled");
+ return enabled;
+}
+
+std::unique_ptr<MockContentFilter> MockContentFilter::create()
+{
+ return std::make_unique<MockContentFilter>();
+}
+
+void MockContentFilter::willSendRequest(ResourceRequest& request, const ResourceResponse& redirectResponse)
+{
+ if (!enabled()) {
+ m_state = State::Allowed;
+ return;
+ }
+
+ if (redirectResponse.isNull())
+ maybeDetermineStatus(DecisionPoint::AfterWillSendRequest);
+ else
+ maybeDetermineStatus(DecisionPoint::AfterRedirect);
+
+ if (m_state == State::Filtering)
+ return;
+
+ String modifiedRequestURLString { settings().modifiedRequestURL() };
+ if (modifiedRequestURLString.isEmpty())
+ return;
+
+ URL modifiedRequestURL { request.url(), modifiedRequestURLString };
+ if (!modifiedRequestURL.isValid()) {
+ LOG(ContentFiltering, "MockContentFilter failed to convert %s to a WebCore::URL.\n", modifiedRequestURL.string().ascii().data());
+ return;
+ }
+
+ request.setURL(modifiedRequestURL);
+}
+
+void MockContentFilter::responseReceived(const ResourceResponse&)
+{
+ maybeDetermineStatus(DecisionPoint::AfterResponse);
+}
+
+void MockContentFilter::addData(const char*, int)
+{
+ maybeDetermineStatus(DecisionPoint::AfterAddData);
+}
+
+void MockContentFilter::finishedAddingData()
+{
+ maybeDetermineStatus(DecisionPoint::AfterFinishedAddingData);
+}
+
+Ref<SharedBuffer> MockContentFilter::replacementData() const
+{
+ ASSERT(didBlockData());
+ return SharedBuffer::create(m_replacementData.data(), m_replacementData.size());
+}
+
+ContentFilterUnblockHandler MockContentFilter::unblockHandler() const
+{
+ ASSERT(didBlockData());
+ using DecisionHandlerFunction = ContentFilterUnblockHandler::DecisionHandlerFunction;
+
+ return ContentFilterUnblockHandler {
+ MockContentFilterSettings::unblockURLHost(), [](DecisionHandlerFunction decisionHandler) {
+ bool shouldAllow { settings().unblockRequestDecision() == Decision::Allow };
+ if (shouldAllow)
+ settings().setDecision(Decision::Allow);
+ LOG(ContentFiltering, "MockContentFilter %s the unblock request.\n", shouldAllow ? "allowed" : "did not allow");
+ decisionHandler(shouldAllow);
+ }
+ };
+}
+
+String MockContentFilter::unblockRequestDeniedScript() const
+{
+ return ASCIILiteral("unblockRequestDenied()");
+}
+
+void MockContentFilter::maybeDetermineStatus(DecisionPoint decisionPoint)
+{
+ if (m_state != State::Filtering || decisionPoint != settings().decisionPoint())
+ return;
+
+ LOG(ContentFiltering, "MockContentFilter stopped buffering with state %u at decision point %u.\n", m_state, decisionPoint);
+
+ m_state = settings().decision() == Decision::Allow ? State::Allowed : State::Blocked;
+ if (m_state != State::Blocked)
+ return;
+
+ m_replacementData.clear();
+ const CString utf8BlockedString = settings().blockedString().utf8();
+ m_replacementData.append(utf8BlockedString.data(), utf8BlockedString.length());
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(CONTENT_FILTERING)
diff --git a/Source/WebCore/testing/MockContentFilter.h b/Source/WebCore/testing/MockContentFilter.h
new file mode 100644
index 000000000..c99d2aeb9
--- /dev/null
+++ b/Source/WebCore/testing/MockContentFilter.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "MockContentFilterSettings.h"
+#include "PlatformContentFilter.h"
+
+namespace WebCore {
+
+class MockContentFilter final : public PlatformContentFilter {
+ friend std::unique_ptr<MockContentFilter> std::make_unique<MockContentFilter>();
+
+public:
+ static void ensureInstalled();
+ static std::unique_ptr<MockContentFilter> create();
+
+ void willSendRequest(ResourceRequest&, const ResourceResponse&) override;
+ void responseReceived(const ResourceResponse&) override;
+ void addData(const char* data, int length) override;
+ void finishedAddingData() override;
+ Ref<SharedBuffer> replacementData() const override;
+#if ENABLE(CONTENT_FILTERING)
+ ContentFilterUnblockHandler unblockHandler() const override;
+#endif
+ String unblockRequestDeniedScript() const override;
+
+private:
+ static bool enabled();
+
+ MockContentFilter() = default;
+ void maybeDetermineStatus(MockContentFilterSettings::DecisionPoint);
+
+ Vector<char> m_replacementData;
+};
+
+} // namespace WebCore
diff --git a/Source/WebCore/testing/MockContentFilterSettings.cpp b/Source/WebCore/testing/MockContentFilterSettings.cpp
new file mode 100644
index 000000000..a6d8f6dbb
--- /dev/null
+++ b/Source/WebCore/testing/MockContentFilterSettings.cpp
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "MockContentFilterSettings.h"
+
+#if ENABLE(CONTENT_FILTERING)
+
+#include "ContentFilter.h"
+#include "ContentFilterUnblockHandler.h"
+#include "MockContentFilter.h"
+#include <wtf/NeverDestroyed.h>
+
+namespace WebCore {
+
+MockContentFilterSettings& MockContentFilterSettings::singleton()
+{
+ static NeverDestroyed<MockContentFilterSettings> settings;
+ return settings;
+}
+
+void MockContentFilterSettings::reset()
+{
+ singleton() = MockContentFilterSettings();
+}
+
+void MockContentFilterSettings::setEnabled(bool enabled)
+{
+ MockContentFilter::ensureInstalled();
+ m_enabled = enabled;
+}
+
+const String& MockContentFilterSettings::unblockRequestURL() const
+{
+ static NeverDestroyed<String> unblockRequestURL = makeString(ContentFilter::urlScheme(), "://", unblockURLHost());
+ return unblockRequestURL;
+}
+
+}; // namespace WebCore
+
+#endif // ENABLE(CONTENT_FILTERING)
diff --git a/Source/WebCore/testing/MockContentFilterSettings.h b/Source/WebCore/testing/MockContentFilterSettings.h
new file mode 100644
index 000000000..5e8afdf83
--- /dev/null
+++ b/Source/WebCore/testing/MockContentFilterSettings.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <wtf/NeverDestroyed.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+class MockContentFilterSettings {
+ friend class NeverDestroyed<MockContentFilterSettings>;
+
+public:
+ enum class DecisionPoint {
+ AfterWillSendRequest,
+ AfterRedirect,
+ AfterResponse,
+ AfterAddData,
+ AfterFinishedAddingData,
+ Never
+ };
+
+ enum class Decision {
+ Allow,
+ Block
+ };
+
+ WTF_EXPORT_PRIVATE static MockContentFilterSettings& singleton();
+ static void reset();
+ static const char* unblockURLHost() { return "mock-unblock"; }
+
+ // Trick the generated bindings into thinking we're RefCounted.
+ void ref() { }
+ void deref() { }
+
+ bool enabled() const { return m_enabled; }
+ WTF_EXPORT_PRIVATE void setEnabled(bool);
+
+ const String& blockedString() const { return m_blockedString; }
+ void setBlockedString(const String& blockedString) { m_blockedString = blockedString; }
+
+ DecisionPoint decisionPoint() const { return m_decisionPoint; }
+ void setDecisionPoint(DecisionPoint decisionPoint) { m_decisionPoint = decisionPoint; }
+
+ Decision decision() const { return m_decision; }
+ void setDecision(Decision decision) { m_decision = decision; }
+
+ Decision unblockRequestDecision() const { return m_unblockRequestDecision; }
+ void setUnblockRequestDecision(Decision unblockRequestDecision) { m_unblockRequestDecision = unblockRequestDecision; }
+
+ const String& unblockRequestURL() const;
+
+ const String& modifiedRequestURL() const { return m_modifiedRequestURL; }
+ void setModifiedRequestURL(const String& modifiedRequestURL) { m_modifiedRequestURL = modifiedRequestURL; }
+
+private:
+ MockContentFilterSettings() = default;
+ MockContentFilterSettings(const MockContentFilterSettings&) = delete;
+ MockContentFilterSettings& operator=(const MockContentFilterSettings&) = default;
+
+ bool m_enabled { false };
+ DecisionPoint m_decisionPoint { DecisionPoint::AfterResponse };
+ Decision m_decision { Decision::Allow };
+ Decision m_unblockRequestDecision { Decision::Block };
+ String m_blockedString;
+ String m_modifiedRequestURL;
+};
+
+} // namespace WebCore
diff --git a/Source/WebCore/testing/MockContentFilterSettings.idl b/Source/WebCore/testing/MockContentFilterSettings.idl
new file mode 100644
index 000000000..d401ae901
--- /dev/null
+++ b/Source/WebCore/testing/MockContentFilterSettings.idl
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+[
+ Conditional=CONTENT_FILTERING,
+ NoInterfaceObject,
+ ImplementationLacksVTable
+] interface MockContentFilterSettings {
+ attribute boolean enabled;
+ attribute DOMString blockedString;
+ attribute DOMString modifiedRequestURL;
+
+ const octet DECISION_POINT_AFTER_WILL_SEND_REQUEST = 0;
+ const octet DECISION_POINT_AFTER_REDIRECT = 1;
+ const octet DECISION_POINT_AFTER_RESPONSE = 2;
+ const octet DECISION_POINT_AFTER_ADD_DATA = 3;
+ const octet DECISION_POINT_AFTER_FINISHED_ADDING_DATA = 4;
+ const octet DECISION_POINT_NEVER = 5;
+ [Custom] attribute octet decisionPoint;
+
+ const octet DECISION_ALLOW = 0;
+ const octet DECISION_BLOCK = 1;
+ [Custom] attribute octet decision;
+ [Custom] attribute octet unblockRequestDecision;
+
+ readonly attribute DOMString unblockRequestURL;
+};
diff --git a/Source/WebCore/testing/MockGamepad.cpp b/Source/WebCore/testing/MockGamepad.cpp
new file mode 100644
index 000000000..a49af87b3
--- /dev/null
+++ b/Source/WebCore/testing/MockGamepad.cpp
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "MockGamepad.h"
+
+#if ENABLE(GAMEPAD)
+
+#include <wtf/CurrentTime.h>
+
+namespace WebCore {
+
+MockGamepad::MockGamepad(unsigned index, const String& gamepadID, unsigned axisCount, unsigned buttonCount)
+ : PlatformGamepad(index)
+{
+ m_connectTime = m_lastUpdateTime = monotonicallyIncreasingTime();
+ updateDetails(gamepadID, axisCount, buttonCount);
+}
+
+void MockGamepad::updateDetails(const String& gamepadID, unsigned axisCount, unsigned buttonCount)
+{
+ m_id = gamepadID;
+ m_axisValues = Vector<double>(axisCount, 0.0);
+ m_buttonValues = Vector<double>(buttonCount, 0.0);
+ m_lastUpdateTime = monotonicallyIncreasingTime();
+}
+
+bool MockGamepad::setAxisValue(unsigned index, double value)
+{
+ if (index >= m_axisValues.size()) {
+ LOG_ERROR("MockGamepad (%u): Attempt to set value on axis %u which doesn't exist", m_index, index);
+ return false;
+ }
+
+ m_axisValues[index] = value;
+ m_lastUpdateTime = monotonicallyIncreasingTime();
+ return true;
+}
+
+bool MockGamepad::setButtonValue(unsigned index, double value)
+{
+ if (index >= m_buttonValues.size()) {
+ LOG_ERROR("MockGamepad (%u): Attempt to set value on button %u which doesn't exist", m_index, index);
+ return false;
+ }
+
+ m_buttonValues[index] = value;
+ m_lastUpdateTime = monotonicallyIncreasingTime();
+ return true;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(GAMEPAD)
diff --git a/Source/WebCore/testing/MockGamepad.h b/Source/WebCore/testing/MockGamepad.h
new file mode 100644
index 000000000..728f7d21c
--- /dev/null
+++ b/Source/WebCore/testing/MockGamepad.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(GAMEPAD)
+
+#include "PlatformGamepad.h"
+
+namespace WebCore {
+
+class MockGamepad : public PlatformGamepad {
+public:
+ MockGamepad(unsigned index, const String& gamepadID, unsigned axisCount, unsigned buttonCount);
+
+ const Vector<double>& axisValues() const final { return m_axisValues; }
+ const Vector<double>& buttonValues() const final { return m_buttonValues; }
+
+ void updateDetails(const String& gamepadID, unsigned axisCount, unsigned buttonCount);
+ bool setAxisValue(unsigned index, double value);
+ bool setButtonValue(unsigned index, double value);
+
+private:
+ Vector<double> m_axisValues;
+ Vector<double> m_buttonValues;
+};
+
+}
+
+#endif // ENABLE(GAMEPAD)
diff --git a/Source/WebCore/testing/MockGamepadProvider.cpp b/Source/WebCore/testing/MockGamepadProvider.cpp
new file mode 100644
index 000000000..ef21e5096
--- /dev/null
+++ b/Source/WebCore/testing/MockGamepadProvider.cpp
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "MockGamepadProvider.h"
+
+#if ENABLE(GAMEPAD)
+
+#include "GamepadProviderClient.h"
+#include "MockGamepad.h"
+#include <wtf/MainThread.h>
+
+namespace WebCore {
+
+MockGamepadProvider& MockGamepadProvider::singleton()
+{
+ static NeverDestroyed<MockGamepadProvider> sharedProvider;
+ return sharedProvider;
+}
+
+MockGamepadProvider::MockGamepadProvider()
+{
+}
+
+void MockGamepadProvider::startMonitoringGamepads(GamepadProviderClient& client)
+{
+ ASSERT(!m_clients.contains(&client));
+ m_clients.add(&client);
+}
+
+void MockGamepadProvider::stopMonitoringGamepads(GamepadProviderClient& client)
+{
+ ASSERT(m_clients.contains(&client));
+ m_clients.remove(&client);
+}
+
+void MockGamepadProvider::setMockGamepadDetails(unsigned index, const String& gamepadID, unsigned axisCount, unsigned buttonCount)
+{
+ if (index >= m_mockGamepadVector.size())
+ m_mockGamepadVector.resize(index + 1);
+
+ if (m_mockGamepadVector[index])
+ m_mockGamepadVector[index]->updateDetails(gamepadID, axisCount, buttonCount);
+ else
+ m_mockGamepadVector[index] = std::make_unique<MockGamepad>(index, gamepadID, axisCount, buttonCount);
+}
+
+bool MockGamepadProvider::connectMockGamepad(unsigned index)
+{
+ if (index < m_connectedGamepadVector.size() && m_connectedGamepadVector[index]) {
+ LOG_ERROR("MockGamepadProvider: Attempt to connect a fake gamepad that is already connected (%u)", index);
+ return false;
+ }
+
+ if (index >= m_mockGamepadVector.size() || !m_mockGamepadVector[index]) {
+ LOG_ERROR("MockGamepadProvider: Attempt to connect a fake gamepad that doesn't have details set(%u)", index);
+ return false;
+ }
+
+ if (m_connectedGamepadVector.size() <= index)
+ m_connectedGamepadVector.reserveCapacity(index + 1);
+
+ while (m_connectedGamepadVector.size() <= index)
+ m_connectedGamepadVector.uncheckedAppend(nullptr);
+
+ m_connectedGamepadVector[index] = m_mockGamepadVector[index].get();
+
+ for (auto& client : m_clients)
+ client->platformGamepadConnected(*m_connectedGamepadVector[index]);
+
+ return true;
+}
+
+bool MockGamepadProvider::disconnectMockGamepad(unsigned index)
+{
+ if (index >= m_connectedGamepadVector.size() || !m_connectedGamepadVector[index]) {
+ LOG_ERROR("MockGamepadProvider: Attempt to disconnect a fake gamepad that is not connected (%u)", index);
+ return false;
+ }
+ if (m_connectedGamepadVector[index] != m_mockGamepadVector[index].get()) {
+ LOG_ERROR("MockGamepadProvider: Vectors of fake gamepads and connected gamepads have gotten out of sync");
+ return false;
+ }
+
+ m_connectedGamepadVector[index] = nullptr;
+
+ for (auto& client : m_clients)
+ client->platformGamepadDisconnected(*m_mockGamepadVector[index]);
+
+ return true;
+}
+
+bool MockGamepadProvider::setMockGamepadAxisValue(unsigned index, unsigned axisIndex, double value)
+{
+ if (index >= m_mockGamepadVector.size() || !m_mockGamepadVector[index]) {
+ LOG_ERROR("MockGamepadProvider: Attempt to set axis value on a fake gamepad that doesn't exist (%u)", index);
+ return false;
+ }
+
+ m_mockGamepadVector[index]->setAxisValue(axisIndex, value);
+ gamepadInputActivity();
+ return true;
+}
+
+bool MockGamepadProvider::setMockGamepadButtonValue(unsigned index, unsigned buttonIndex, double value)
+{
+ if (index >= m_mockGamepadVector.size() || !m_mockGamepadVector[index]) {
+ LOG_ERROR("MockGamepadProvider: Attempt to set button value on a fake gamepad that doesn't exist (%u)", index);
+ return false;
+ }
+
+ m_mockGamepadVector[index]->setButtonValue(buttonIndex, value);
+ setShouldMakeGamepadsVisibile();
+ gamepadInputActivity();
+ return true;
+}
+
+void MockGamepadProvider::gamepadInputActivity()
+{
+ if (!m_shouldScheduleActivityCallback)
+ return;
+
+ m_shouldScheduleActivityCallback = false;
+ callOnMainThread([this]() {
+ dispatchPlatformGamepadInputActivity();
+
+ m_shouldScheduleActivityCallback = true;
+ });
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(GAMEPAD)
diff --git a/Source/WebCore/testing/MockGamepadProvider.h b/Source/WebCore/testing/MockGamepadProvider.h
new file mode 100644
index 000000000..9dd31e5fb
--- /dev/null
+++ b/Source/WebCore/testing/MockGamepadProvider.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(GAMEPAD)
+
+#include "GamepadProvider.h"
+#include "MockGamepad.h"
+#include <wtf/NeverDestroyed.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+class MockGamepadProvider : public GamepadProvider {
+ WTF_MAKE_NONCOPYABLE(MockGamepadProvider);
+ friend class NeverDestroyed<MockGamepadProvider>;
+public:
+ WEBCORE_EXPORT static MockGamepadProvider& singleton();
+
+ virtual ~MockGamepadProvider() { }
+
+ WEBCORE_EXPORT void startMonitoringGamepads(GamepadProviderClient&) final;
+ WEBCORE_EXPORT void stopMonitoringGamepads(GamepadProviderClient&) final;
+ WEBCORE_EXPORT const Vector<PlatformGamepad*>& platformGamepads() final { return m_connectedGamepadVector; }
+ bool isMockGamepadProvider() const final { return true; }
+
+ void setMockGamepadDetails(unsigned index, const String& gamepadID, unsigned axisCount, unsigned buttonCount);
+ bool setMockGamepadAxisValue(unsigned index, unsigned axisIndex, double value);
+ bool setMockGamepadButtonValue(unsigned index, unsigned buttonIndex, double value);
+ bool connectMockGamepad(unsigned index);
+ bool disconnectMockGamepad(unsigned index);
+
+private:
+ MockGamepadProvider();
+
+ void gamepadInputActivity();
+
+ Vector<PlatformGamepad*> m_connectedGamepadVector;
+ Vector<std::unique_ptr<MockGamepad>> m_mockGamepadVector;
+
+ bool m_shouldScheduleActivityCallback { true };
+};
+
+}
+
+#endif // ENABLE(GAMEPAD)
diff --git a/Source/WebCore/testing/MockLibWebRTCPeerConnection.cpp b/Source/WebCore/testing/MockLibWebRTCPeerConnection.cpp
new file mode 100644
index 000000000..963493125
--- /dev/null
+++ b/Source/WebCore/testing/MockLibWebRTCPeerConnection.cpp
@@ -0,0 +1,401 @@
+/*
+ * Copyright (C) 2017 Apple Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "MockLibWebRTCPeerConnection.h"
+
+#if USE(LIBWEBRTC)
+
+#include "LibWebRTCProvider.h"
+#include <sstream>
+#include <webrtc/api/mediastream.h>
+#include <wtf/Function.h>
+#include <wtf/MainThread.h>
+#include <wtf/NeverDestroyed.h>
+
+namespace WebCore {
+
+static inline rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface>& getRealPeerConnectionFactory()
+{
+ static NeverDestroyed<rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface>> realPeerConnectionFactory;
+ return realPeerConnectionFactory;
+}
+
+static inline webrtc::PeerConnectionFactoryInterface* realPeerConnectionFactory()
+{
+ return getRealPeerConnectionFactory().get();
+}
+
+void useMockRTCPeerConnectionFactory(LibWebRTCProvider* provider, const String& testCase)
+{
+ if (provider && !realPeerConnectionFactory()) {
+ auto& factory = getRealPeerConnectionFactory();
+ factory = &provider->factory();
+ }
+
+ LibWebRTCProvider::setPeerConnectionFactory(MockLibWebRTCPeerConnectionFactory::create(String(testCase)));
+}
+
+class MockLibWebRTCPeerConnectionForIceCandidates : public MockLibWebRTCPeerConnection {
+public:
+ explicit MockLibWebRTCPeerConnectionForIceCandidates(webrtc::PeerConnectionObserver& observer) : MockLibWebRTCPeerConnection(observer) { }
+ virtual ~MockLibWebRTCPeerConnectionForIceCandidates() = default;
+private:
+ void gotLocalDescription() final;
+};
+
+void MockLibWebRTCPeerConnectionForIceCandidates::gotLocalDescription()
+{
+ // Let's gather candidates
+ LibWebRTCProvider::callOnWebRTCSignalingThread([this]() {
+ MockLibWebRTCIceCandidate candidate("2013266431 1 udp 2013266432 192.168.0.100 38838 typ host generation 0", "1");
+ m_observer.OnIceCandidate(&candidate);
+ });
+ LibWebRTCProvider::callOnWebRTCSignalingThread([this]() {
+ MockLibWebRTCIceCandidate candidate("1019216383 1 tcp 1019216384 192.168.0.100 9 typ host tcptype passive generation 0", "1");
+ m_observer.OnIceCandidate(&candidate);
+ });
+ LibWebRTCProvider::callOnWebRTCSignalingThread([this]() {
+ MockLibWebRTCIceCandidate candidate("1677722111 1 tcp 1677722112 172.18.0.1 47989 typ srflx raddr 192.168.0.100 rport 47989 generation 0", "1");
+ m_observer.OnIceCandidate(&candidate);
+ });
+ LibWebRTCProvider::callOnWebRTCSignalingThread([this]() {
+ m_observer.OnIceGatheringChange(webrtc::PeerConnectionInterface::kIceGatheringComplete);
+ });
+}
+
+class MockLibWebRTCPeerConnectionForIceConnectionState : public MockLibWebRTCPeerConnection {
+public:
+ explicit MockLibWebRTCPeerConnectionForIceConnectionState(webrtc::PeerConnectionObserver& observer) : MockLibWebRTCPeerConnection(observer) { }
+ virtual ~MockLibWebRTCPeerConnectionForIceConnectionState() = default;
+
+private:
+ void gotLocalDescription() final;
+};
+
+void MockLibWebRTCPeerConnectionForIceConnectionState::gotLocalDescription()
+{
+ m_observer.OnIceConnectionChange(kIceConnectionChecking);
+ m_observer.OnIceConnectionChange(kIceConnectionConnected);
+ m_observer.OnIceConnectionChange(kIceConnectionCompleted);
+ m_observer.OnIceConnectionChange(kIceConnectionFailed);
+ m_observer.OnIceConnectionChange(kIceConnectionDisconnected);
+ m_observer.OnIceConnectionChange(kIceConnectionNew);
+}
+
+template<typename U> static inline void releaseInNetworkThread(MockLibWebRTCPeerConnection& mock, U& observer)
+{
+ mock.AddRef();
+ observer.AddRef();
+ callOnMainThread([&mock, &observer] {
+ LibWebRTCProvider::callOnWebRTCNetworkThread([&mock, &observer]() {
+ observer.Release();
+ mock.Release();
+ });
+ });
+}
+
+class MockLibWebRTCPeerConnectionReleasedInNetworkThreadWhileCreatingOffer : public MockLibWebRTCPeerConnection {
+public:
+ explicit MockLibWebRTCPeerConnectionReleasedInNetworkThreadWhileCreatingOffer(webrtc::PeerConnectionObserver& observer) : MockLibWebRTCPeerConnection(observer) { }
+ virtual ~MockLibWebRTCPeerConnectionReleasedInNetworkThreadWhileCreatingOffer() = default;
+
+private:
+ void CreateOffer(webrtc::CreateSessionDescriptionObserver* observer, const webrtc::MediaConstraintsInterface*) final { releaseInNetworkThread(*this, *observer); }
+};
+
+class MockLibWebRTCPeerConnectionReleasedInNetworkThreadWhileGettingStats : public MockLibWebRTCPeerConnection {
+public:
+ explicit MockLibWebRTCPeerConnectionReleasedInNetworkThreadWhileGettingStats(webrtc::PeerConnectionObserver& observer) : MockLibWebRTCPeerConnection(observer) { }
+ virtual ~MockLibWebRTCPeerConnectionReleasedInNetworkThreadWhileGettingStats() = default;
+
+private:
+ bool GetStats(webrtc::StatsObserver*, webrtc::MediaStreamTrackInterface*, StatsOutputLevel) final;
+};
+
+bool MockLibWebRTCPeerConnectionReleasedInNetworkThreadWhileGettingStats::GetStats(webrtc::StatsObserver* observer, webrtc::MediaStreamTrackInterface*, StatsOutputLevel)
+{
+ releaseInNetworkThread(*this, *observer);
+ return true;
+}
+
+class MockLibWebRTCPeerConnectionReleasedInNetworkThreadWhileSettingDescription : public MockLibWebRTCPeerConnection {
+public:
+ explicit MockLibWebRTCPeerConnectionReleasedInNetworkThreadWhileSettingDescription(webrtc::PeerConnectionObserver& observer) : MockLibWebRTCPeerConnection(observer) { }
+ virtual ~MockLibWebRTCPeerConnectionReleasedInNetworkThreadWhileSettingDescription() = default;
+
+private:
+ void SetLocalDescription(webrtc::SetSessionDescriptionObserver* observer, webrtc::SessionDescriptionInterface*) final { releaseInNetworkThread(*this, *observer); }
+};
+
+MockLibWebRTCPeerConnectionFactory::MockLibWebRTCPeerConnectionFactory(String&& testCase)
+ : m_testCase(WTFMove(testCase))
+{
+ if (m_testCase == "TwoRealPeerConnections") {
+ m_numberOfRealPeerConnections = 2;
+ return;
+ }
+ if (m_testCase == "OneRealPeerConnection")
+ m_numberOfRealPeerConnections = 1;
+}
+
+rtc::scoped_refptr<webrtc::PeerConnectionInterface> MockLibWebRTCPeerConnectionFactory::CreatePeerConnection(const webrtc::PeerConnectionInterface::RTCConfiguration& configuration, std::unique_ptr<cricket::PortAllocator> portAllocator, std::unique_ptr<rtc::RTCCertificateGeneratorInterface> generator, webrtc::PeerConnectionObserver* observer)
+{
+ if (m_numberOfRealPeerConnections) {
+ auto connection = realPeerConnectionFactory()->CreatePeerConnection(configuration, WTFMove(portAllocator), WTFMove(generator), observer);
+ --m_numberOfRealPeerConnections;
+ return connection;
+ }
+
+ if (m_testCase == "ICECandidates")
+ return new rtc::RefCountedObject<MockLibWebRTCPeerConnectionForIceCandidates>(*observer);
+
+ if (m_testCase == "ICEConnectionState")
+ return new rtc::RefCountedObject<MockLibWebRTCPeerConnectionForIceConnectionState>(*observer);
+
+ if (m_testCase == "LibWebRTCReleasingWhileCreatingOffer")
+ return new rtc::RefCountedObject<MockLibWebRTCPeerConnectionReleasedInNetworkThreadWhileCreatingOffer>(*observer);
+
+ if (m_testCase == "LibWebRTCReleasingWhileGettingStats")
+ return new rtc::RefCountedObject<MockLibWebRTCPeerConnectionReleasedInNetworkThreadWhileGettingStats>(*observer);
+
+ if (m_testCase == "LibWebRTCReleasingWhileSettingDescription")
+ return new rtc::RefCountedObject<MockLibWebRTCPeerConnectionReleasedInNetworkThreadWhileSettingDescription>(*observer);
+
+ return new rtc::RefCountedObject<MockLibWebRTCPeerConnection>(*observer);
+}
+
+rtc::scoped_refptr<webrtc::MediaStreamInterface> MockLibWebRTCPeerConnectionFactory::CreateLocalMediaStream(const std::string& label)
+{
+ return new rtc::RefCountedObject<webrtc::MediaStream>(label);
+}
+
+void MockLibWebRTCPeerConnection::SetLocalDescription(webrtc::SetSessionDescriptionObserver* observer, webrtc::SessionDescriptionInterface*)
+{
+ LibWebRTCProvider::callOnWebRTCSignalingThread([this, observer] {
+ observer->OnSuccess();
+ gotLocalDescription();
+ });
+}
+
+void MockLibWebRTCPeerConnection::SetRemoteDescription(webrtc::SetSessionDescriptionObserver* observer, webrtc::SessionDescriptionInterface* sessionDescription)
+{
+ LibWebRTCProvider::callOnWebRTCSignalingThread([observer] {
+ observer->OnSuccess();
+ });
+ ASSERT(sessionDescription);
+ if (sessionDescription->type() == "offer") {
+ std::string sdp;
+ sessionDescription->ToString(&sdp);
+
+ m_isInitiator = false;
+ m_isReceivingAudio = sdp.find("m=audio") != std::string::npos;
+ m_isReceivingVideo = sdp.find("m=video") != std::string::npos;
+ }
+}
+
+rtc::scoped_refptr<webrtc::DataChannelInterface> MockLibWebRTCPeerConnection::CreateDataChannel(const std::string& label, const webrtc::DataChannelInit* init)
+{
+ webrtc::DataChannelInit parameters;
+ if (init)
+ parameters = *init;
+ return new rtc::RefCountedObject<MockLibWebRTCDataChannel>(std::string(label), parameters.ordered, parameters.reliable, parameters.id);
+}
+
+bool MockLibWebRTCPeerConnection::AddStream(webrtc::MediaStreamInterface* stream)
+{
+ m_stream = stream;
+ LibWebRTCProvider::callOnWebRTCSignalingThread([observer = &m_observer] {
+ observer->OnRenegotiationNeeded();
+ });
+ return true;
+}
+
+void MockLibWebRTCPeerConnection::RemoveStream(webrtc::MediaStreamInterface*)
+{
+ LibWebRTCProvider::callOnWebRTCSignalingThread([observer = &m_observer] {
+ observer->OnRenegotiationNeeded();
+ });
+ m_stream = nullptr;
+}
+
+void MockLibWebRTCPeerConnection::CreateOffer(webrtc::CreateSessionDescriptionObserver* observer, const webrtc::MediaConstraintsInterface*)
+{
+ LibWebRTCProvider::callOnWebRTCSignalingThread([this, observer] {
+ std::ostringstream sdp;
+ sdp <<
+ "v=0\r\n"
+ "o=- 5667094644266930845 " << m_counter++ << " IN IP4 127.0.0.1\r\n"
+ "s=-\r\n"
+ "t=0 0\r\n";
+ if (m_stream) {
+ unsigned partCounter = 1;
+ sdp << "a=msid-semantic:WMS " << m_stream->label() << "\r\n";
+ for (auto& audioTrack : m_stream->GetAudioTracks()) {
+ sdp <<
+ "m=audio 9 UDP/TLS/RTP/SAVPF 111 8 0\r\n"
+ "c=IN IP4 0.0.0.0\r\n"
+ "a=rtcp-mux\r\n"
+ "a=sendrecv\r\n"
+ "a=mid:part" << partCounter++ << "\r\n"
+ "a=rtpmap:111 OPUS/48000/2\r\n"
+ "a=rtpmap:8 PCMA/8000\r\n"
+ "a=rtpmap:0 PCMU/8000\r\n"
+ "a=ssrc:3409173717 cname:/chKzCS9K6KOgL0n\r\n"
+ "a=msid:" << m_stream->label() << " " << audioTrack->id() << "\r\n"
+ "a=ice-ufrag:e/B1\r\n"
+ "a=ice-pwd:Yotk3Im3mnyi+1Q38p51MDub\r\n"
+ "a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B\r\n"
+ "a=setup:actpass\r\n";
+ }
+ for (auto& videoTrack : m_stream->GetVideoTracks()) {
+ sdp <<
+ "m=video 9 UDP/TLS/RTP/SAVPF 103 100 120\r\n"
+ "c=IN IP4 0.0.0.0\r\n"
+ "a=rtcp-mux\r\n"
+ "a=sendrecv\r\n"
+ "a=mid:part" << partCounter++ << "\r\n"
+ "a=rtpmap:103 H264/90000\r\n"
+ "a=rtpmap:100 VP8/90000\r\n"
+ "a=rtpmap:120 RTX/90000\r\n"
+ "a=fmtp:103 packetization-mode=1\r\n"
+ "a=fmtp:120 apt=100;rtx-time=200\r\n"
+ "a=rtcp-fb:100 nack\r\n"
+ "a=rtcp-fb:103 nack pli\r\n"
+ "a=rtcp-fb:100 nack pli\r\n"
+ "a=rtcp-fb:103 ccm fir\r\n"
+ "a=rtcp-fb:100 ccm fir\r\n"
+ "a=ssrc:3409173718 cname:/chKzCS9K6KOgL0n\r\n"
+ "a=msid:" << m_stream->label() << " " << videoTrack->id() << "\r\n"
+ "a=ice-ufrag:e/B1\r\n"
+ "a=ice-pwd:Yotk3Im3mnyi+1Q38p51MDub\r\n"
+ "a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B\r\n"
+ "a=setup:actpass\r\n";
+ }
+ }
+ MockLibWebRTCSessionDescription description(sdp.str());
+ observer->OnSuccess(&description);
+ });
+}
+
+void MockLibWebRTCPeerConnection::CreateAnswer(webrtc::CreateSessionDescriptionObserver* observer, const webrtc::MediaConstraintsInterface*)
+{
+ LibWebRTCProvider::callOnWebRTCSignalingThread([this, observer] {
+ std::ostringstream sdp;
+ sdp <<
+ "v=0\r\n"
+ "o=- 5667094644266930846 " << m_counter++ << " IN IP4 127.0.0.1\r\n"
+ "s=-\r\n"
+ "t=0 0\r\n";
+ if (m_stream) {
+ for (auto& audioTrack : m_stream->GetAudioTracks()) {
+ ASSERT_UNUSED(audioTrack, !!audioTrack);
+ sdp <<
+ "m=audio 9 UDP/TLS/RTP/SAVPF 111 8 0\r\n"
+ "c=IN IP4 0.0.0.0\r\n"
+ "a=rtcp-mux\r\n"
+ "a=recvonly\r\n"
+ "a=mid:part1\r\n"
+ "a=rtpmap:111 OPUS/48000/2\r\n"
+ "a=rtpmap:8 PCMA/8000\r\n"
+ "a=rtpmap:0 PCMU/8000\r\n"
+ "a=ssrc:3409173717 cname:/chKzCS9K6KOgL0m\r\n"
+ "a=ice-ufrag:e/B1\r\n"
+ "a=ice-pwd:Yotk3Im3mnyi+1Q38p51MDub\r\n"
+ "a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B\r\n"
+ "a=setup:active\r\n";
+ }
+ for (auto& videoTrack : m_stream->GetVideoTracks()) {
+ ASSERT_UNUSED(videoTrack, !!videoTrack);
+ sdp <<
+ "m=video 9 UDP/TLS/RTP/SAVPF 103 100 120\r\n"
+ "c=IN IP4 0.0.0.0\r\n"
+ "a=rtcp-mux\r\n"
+ "a=recvonly\r\n"
+ "a=mid:part2\r\n"
+ "a=rtpmap:103 H264/90000\r\n"
+ "a=rtpmap:100 VP8/90000\r\n"
+ "a=rtpmap:120 RTX/90000\r\n"
+ "a=fmtp:103 packetization-mode=1\r\n"
+ "a=fmtp:120 apt=100;rtx-time=200\r\n"
+ "a=rtcp-fb:100 nack\r\n"
+ "a=rtcp-fb:103 nack pli\r\n"
+ "a=rtcp-fb:100 nack pli\r\n"
+ "a=rtcp-fb:103 ccm fir\r\n"
+ "a=rtcp-fb:100 ccm fir\r\n"
+ "a=ssrc:3409173718 cname:/chKzCS9K6KOgL0n\r\n"
+ "a=ice-ufrag:e/B1\r\n"
+ "a=ice-pwd:Yotk3Im3mnyi+1Q38p51MDub\r\n"
+ "a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B\r\n"
+ "a=setup:active\r\n";
+ }
+ } else if (!m_isInitiator) {
+ if (m_isReceivingAudio) {
+ sdp <<
+ "m=audio 9 UDP/TLS/RTP/SAVPF 111 8 0\r\n"
+ "c=IN IP4 0.0.0.0\r\n"
+ "a=rtcp-mux\r\n"
+ "a=recvonly\r\n"
+ "a=mid:part1\r\n"
+ "a=rtpmap:111 OPUS/48000/2\r\n"
+ "a=rtpmap:8 PCMA/8000\r\n"
+ "a=rtpmap:0 PCMU/8000\r\n"
+ "a=ssrc:3409173717 cname:/chKzCS9K6KOgL0m\r\n"
+ "a=ice-ufrag:e/B1\r\n"
+ "a=ice-pwd:Yotk3Im3mnyi+1Q38p51MDub\r\n"
+ "a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B\r\n"
+ "a=setup:active\r\n";
+ }
+ if (m_isReceivingVideo) {
+ sdp <<
+ "m=video 9 UDP/TLS/RTP/SAVPF 103 100 120\r\n"
+ "c=IN IP4 0.0.0.0\r\n"
+ "a=rtcp-mux\r\n"
+ "a=recvonly\r\n"
+ "a=mid:part2\r\n"
+ "a=rtpmap:103 H264/90000\r\n"
+ "a=rtpmap:100 VP8/90000\r\n"
+ "a=rtpmap:120 RTX/90000\r\n"
+ "a=fmtp:103 packetization-mode=1\r\n"
+ "a=fmtp:120 apt=100;rtx-time=200\r\n"
+ "a=rtcp-fb:100 nack\r\n"
+ "a=rtcp-fb:103 nack pli\r\n"
+ "a=rtcp-fb:100 nack pli\r\n"
+ "a=rtcp-fb:103 ccm fir\r\n"
+ "a=rtcp-fb:100 ccm fir\r\n"
+ "a=ssrc:3409173718 cname:/chKzCS9K6KOgL0n\r\n"
+ "a=ice-ufrag:e/B1\r\n"
+ "a=ice-pwd:Yotk3Im3mnyi+1Q38p51MDub\r\n"
+ "a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B\r\n"
+ "a=setup:active\r\n";
+ }
+ }
+ MockLibWebRTCSessionDescription description(sdp.str());
+ observer->OnSuccess(&description);
+ });
+}
+
+} // namespace WebCore
+
+#endif // USE(LIBWEBRTC)
diff --git a/Source/WebCore/testing/MockLibWebRTCPeerConnection.h b/Source/WebCore/testing/MockLibWebRTCPeerConnection.h
new file mode 100644
index 000000000..a050897d0
--- /dev/null
+++ b/Source/WebCore/testing/MockLibWebRTCPeerConnection.h
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2017 Apple Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if USE(LIBWEBRTC)
+
+#include "LibWebRTCMacros.h"
+#include <webrtc/api/mediastreaminterface.h>
+#include <webrtc/api/peerconnectioninterface.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+class LibWebRTCProvider;
+
+void useMockRTCPeerConnectionFactory(LibWebRTCProvider*, const String&);
+
+class MockLibWebRTCPeerConnection : public webrtc::PeerConnectionInterface {
+public:
+ virtual ~MockLibWebRTCPeerConnection() { }
+
+protected:
+ explicit MockLibWebRTCPeerConnection(webrtc::PeerConnectionObserver& observer) : m_observer(observer) { }
+
+private:
+ rtc::scoped_refptr<webrtc::StreamCollectionInterface> local_streams() override { return nullptr; }
+ rtc::scoped_refptr<webrtc::StreamCollectionInterface> remote_streams() override { return nullptr; }
+ rtc::scoped_refptr<webrtc::DtmfSenderInterface> CreateDtmfSender(webrtc::AudioTrackInterface*) override { return nullptr; }
+ const webrtc::SessionDescriptionInterface* local_description() const override { return nullptr; }
+ const webrtc::SessionDescriptionInterface* remote_description() const override { return nullptr; }
+ bool AddIceCandidate(const webrtc::IceCandidateInterface*) override { return true; }
+ void RegisterUMAObserver(webrtc::UMAObserver*) override { }
+ SignalingState signaling_state() override { return kStable; }
+ IceConnectionState ice_connection_state() override { return kIceConnectionNew; }
+ IceGatheringState ice_gathering_state() override { return kIceGatheringNew; }
+ void StopRtcEventLog() override { }
+ void Close() override { }
+
+protected:
+ void SetRemoteDescription(webrtc::SetSessionDescriptionObserver*, webrtc::SessionDescriptionInterface*) final;
+ void CreateAnswer(webrtc::CreateSessionDescriptionObserver*, const webrtc::MediaConstraintsInterface*) final;
+ rtc::scoped_refptr<webrtc::DataChannelInterface> CreateDataChannel(const std::string&, const webrtc::DataChannelInit*) final;
+ bool AddStream(webrtc::MediaStreamInterface*) final;
+ void RemoveStream(webrtc::MediaStreamInterface*) final;
+
+ void SetLocalDescription(webrtc::SetSessionDescriptionObserver*, webrtc::SessionDescriptionInterface*) override;
+ bool GetStats(webrtc::StatsObserver*, webrtc::MediaStreamTrackInterface*, StatsOutputLevel) override { return false; }
+ void CreateOffer(webrtc::CreateSessionDescriptionObserver*, const webrtc::MediaConstraintsInterface*) override;
+
+ virtual void gotLocalDescription() { }
+
+ webrtc::PeerConnectionObserver& m_observer;
+ unsigned m_counter { 0 };
+ rtc::scoped_refptr<webrtc::MediaStreamInterface> m_stream;
+ bool m_isInitiator { true };
+ bool m_isReceivingAudio { false };
+ bool m_isReceivingVideo { false };
+};
+
+class MockLibWebRTCSessionDescription: public webrtc::SessionDescriptionInterface {
+public:
+ explicit MockLibWebRTCSessionDescription(std::string&& sdp) : m_sdp(WTFMove(sdp)) { }
+
+private:
+ bool ToString(std::string* out) const final { *out = m_sdp; return true; }
+
+ cricket::SessionDescription* description() final { return nullptr; }
+ const cricket::SessionDescription* description() const final { return nullptr; }
+ std::string session_id() const final { return ""; }
+ std::string session_version() const final { return ""; }
+ std::string type() const final { return ""; }
+ bool AddCandidate(const webrtc::IceCandidateInterface*) final { return true; }
+ size_t number_of_mediasections() const final { return 0; }
+ const webrtc::IceCandidateCollection* candidates(size_t) const final { return nullptr; }
+
+ std::string m_sdp;
+};
+
+class MockLibWebRTCIceCandidate : public webrtc::IceCandidateInterface {
+public:
+ MockLibWebRTCIceCandidate(const char* sdp, const char* sdpMid)
+ : m_sdp(sdp)
+ , m_sdpMid(sdpMid) { }
+
+private:
+ std::string sdp_mid() const final { return m_sdpMid; }
+ int sdp_mline_index() const final { return 0; }
+ const cricket::Candidate& candidate() const final { return m_candidate; }
+ bool ToString(std::string* out) const final { *out = m_sdp; return true; }
+
+protected:
+ const char* m_sdp;
+ const char* m_sdpMid;
+ cricket::Candidate m_candidate;
+};
+
+class MockLibWebRTCAudioTrack : public webrtc::AudioTrackInterface {
+public:
+ explicit MockLibWebRTCAudioTrack(const std::string& id, webrtc::AudioSourceInterface* source)
+ : m_id(id)
+ , m_source(source) { }
+
+private:
+ webrtc::AudioSourceInterface* GetSource() const final { return m_source; }
+ void AddSink(webrtc::AudioTrackSinkInterface*) final { }
+ void RemoveSink(webrtc::AudioTrackSinkInterface*) final { }
+ void RegisterObserver(webrtc::ObserverInterface*) final { }
+ void UnregisterObserver(webrtc::ObserverInterface*) final { }
+
+ std::string kind() const final { return "audio"; }
+ std::string id() const final { return m_id; }
+ bool enabled() const final { return m_enabled; }
+ TrackState state() const final { return kLive; }
+ bool set_enabled(bool enabled) final { m_enabled = enabled; return true; }
+
+ bool m_enabled;
+ std::string m_id;
+ webrtc::AudioSourceInterface* m_source { nullptr };
+};
+
+class MockLibWebRTCVideoTrack : public webrtc::VideoTrackInterface {
+public:
+ explicit MockLibWebRTCVideoTrack(const std::string& id, webrtc::VideoTrackSourceInterface* source)
+ : m_id(id)
+ , m_source(source) { }
+
+private:
+ webrtc::VideoTrackSourceInterface* GetSource() const final { return m_source; }
+ void RegisterObserver(webrtc::ObserverInterface*) final { }
+ void UnregisterObserver(webrtc::ObserverInterface*) final { }
+
+ std::string kind() const final { return "video"; }
+ std::string id() const final { return m_id; }
+ bool enabled() const final { return m_enabled; }
+ TrackState state() const final { return kLive; }
+ bool set_enabled(bool enabled) final { m_enabled = enabled; return true; }
+
+ bool m_enabled;
+ std::string m_id;
+ webrtc::VideoTrackSourceInterface* m_source { nullptr };
+};
+
+class MockLibWebRTCDataChannel : public webrtc::DataChannelInterface {
+public:
+ MockLibWebRTCDataChannel(std::string&& label, bool ordered, bool reliable, int id)
+ : m_label(WTFMove(label))
+ , m_ordered(ordered)
+ , m_reliable(reliable)
+ , m_id(id) { }
+
+private:
+ void RegisterObserver(webrtc::DataChannelObserver*) final { }
+ void UnregisterObserver() final { }
+ std::string label() const final { return m_label; }
+ bool reliable() const final { return m_reliable; }
+ bool ordered() const final { return m_ordered; }
+
+ int id() const final { return m_id; }
+ DataState state() const final { return kConnecting; }
+ uint64_t buffered_amount() const final { return 0; }
+ void Close() final { }
+ bool Send(const webrtc::DataBuffer&) final { return true; }
+
+ std::string m_label;
+ bool m_ordered { true };
+ bool m_reliable { false };
+ int m_id { -1 };
+};
+
+class MockLibWebRTCPeerConnectionFactory : public webrtc::PeerConnectionFactoryInterface {
+public:
+ static rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> create(String&& testCase) { return new rtc::RefCountedObject<MockLibWebRTCPeerConnectionFactory>(WTFMove(testCase)); }
+
+protected:
+ MockLibWebRTCPeerConnectionFactory(String&&);
+
+private:
+ rtc::scoped_refptr<webrtc::PeerConnectionInterface> CreatePeerConnection(const webrtc::PeerConnectionInterface::RTCConfiguration&, const webrtc::MediaConstraintsInterface*, std::unique_ptr<cricket::PortAllocator>, std::unique_ptr<rtc::RTCCertificateGeneratorInterface>, webrtc::PeerConnectionObserver*) final { return nullptr; }
+
+ rtc::scoped_refptr<webrtc::PeerConnectionInterface> CreatePeerConnection(const webrtc::PeerConnectionInterface::RTCConfiguration&, std::unique_ptr<cricket::PortAllocator>, std::unique_ptr<rtc::RTCCertificateGeneratorInterface>, webrtc::PeerConnectionObserver*) final;
+
+ rtc::scoped_refptr<webrtc::MediaStreamInterface> CreateLocalMediaStream(const std::string&) final;
+
+ void SetOptions(const Options&) final { }
+ rtc::scoped_refptr<webrtc::AudioSourceInterface> CreateAudioSource(const cricket::AudioOptions&) final { return nullptr; }
+ rtc::scoped_refptr<webrtc::AudioSourceInterface> CreateAudioSource(const webrtc::MediaConstraintsInterface*) final { return nullptr; }
+
+ rtc::scoped_refptr<webrtc::VideoTrackSourceInterface> CreateVideoSource(cricket::VideoCapturer*) final { return nullptr; }
+ rtc::scoped_refptr<webrtc::VideoTrackSourceInterface> CreateVideoSource(cricket::VideoCapturer*, const webrtc::MediaConstraintsInterface*) final { return nullptr; }
+
+ rtc::scoped_refptr<webrtc::VideoTrackInterface> CreateVideoTrack(const std::string& id, webrtc::VideoTrackSourceInterface* source) final { return new rtc::RefCountedObject<MockLibWebRTCVideoTrack>(id, source); }
+ rtc::scoped_refptr<webrtc::AudioTrackInterface> CreateAudioTrack(const std::string& id, webrtc::AudioSourceInterface* source) final { return new rtc::RefCountedObject<MockLibWebRTCAudioTrack>(id, source); }
+ bool StartAecDump(rtc::PlatformFile, int64_t) final { return false; }
+ void StopAecDump() final { }
+
+ bool StartRtcEventLog(rtc::PlatformFile, int64_t) final { return false; }
+ bool StartRtcEventLog(rtc::PlatformFile) final { return false; }
+ void StopRtcEventLog() final { }
+
+private:
+ String m_testCase;
+ unsigned m_numberOfRealPeerConnections { 0 };
+};
+
+} // namespace WebCore
+
+#endif // USE(LIBWEBRTC)
diff --git a/Source/WebCore/testing/MockPageOverlay.cpp b/Source/WebCore/testing/MockPageOverlay.cpp
new file mode 100644
index 000000000..3bfa6d9a7
--- /dev/null
+++ b/Source/WebCore/testing/MockPageOverlay.cpp
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "MockPageOverlay.h"
+
+#include "Document.h"
+#include "GraphicsContext.h"
+#include "GraphicsLayer.h"
+#include "MainFrame.h"
+#include "PageOverlayController.h"
+#include "PlatformMouseEvent.h"
+
+namespace WebCore {
+
+Ref<MockPageOverlay> MockPageOverlay::create(PageOverlay* overlay)
+{
+ return adoptRef(*new MockPageOverlay(overlay));
+}
+
+MockPageOverlay::MockPageOverlay(PageOverlay* overlay)
+ : m_overlay(overlay)
+{
+}
+
+void MockPageOverlay::setFrame(double x, double y, double width, double height)
+{
+ m_overlay->setFrame(IntRect(x, y, width, height));
+}
+
+}
diff --git a/Source/WebCore/testing/MockPageOverlay.h b/Source/WebCore/testing/MockPageOverlay.h
new file mode 100644
index 000000000..21956e038
--- /dev/null
+++ b/Source/WebCore/testing/MockPageOverlay.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "PageOverlay.h"
+
+namespace WebCore {
+
+class MainFrame;
+
+class MockPageOverlay : public RefCounted<MockPageOverlay> {
+public:
+ static Ref<MockPageOverlay> create(PageOverlay*);
+
+ void setFrame(double x, double y, double width, double height);
+
+ PageOverlay* overlay() const { return m_overlay.get(); }
+
+private:
+ explicit MockPageOverlay(PageOverlay*);
+
+ RefPtr<PageOverlay> m_overlay;
+};
+
+} // namespace WebCore
diff --git a/Source/WebCore/testing/MockPageOverlay.idl b/Source/WebCore/testing/MockPageOverlay.idl
new file mode 100644
index 000000000..7a5a4a81b
--- /dev/null
+++ b/Source/WebCore/testing/MockPageOverlay.idl
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+[
+ NoInterfaceObject,
+ ImplementationLacksVTable
+] interface MockPageOverlay {
+ void setFrame(double x, double y, double width, double height);
+};
diff --git a/Source/WebCore/testing/MockPageOverlayClient.cpp b/Source/WebCore/testing/MockPageOverlayClient.cpp
new file mode 100644
index 000000000..d0b4bab4c
--- /dev/null
+++ b/Source/WebCore/testing/MockPageOverlayClient.cpp
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "MockPageOverlayClient.h"
+
+#include "Document.h"
+#include "GraphicsContext.h"
+#include "GraphicsLayer.h"
+#include "MainFrame.h"
+#include "Page.h"
+#include "PageOverlayController.h"
+#include "PlatformMouseEvent.h"
+#include <wtf/NeverDestroyed.h>
+#include <wtf/text/StringBuilder.h>
+
+namespace WebCore {
+
+MockPageOverlayClient& MockPageOverlayClient::singleton()
+{
+ static NeverDestroyed<MockPageOverlayClient> sharedClient;
+ return sharedClient.get();
+}
+
+MockPageOverlayClient::MockPageOverlayClient()
+{
+}
+
+Ref<MockPageOverlay> MockPageOverlayClient::installOverlay(MainFrame& mainFrame, PageOverlay::OverlayType overlayType)
+{
+ auto overlay = PageOverlay::create(*this, overlayType);
+ mainFrame.pageOverlayController().installPageOverlay(overlay, PageOverlay::FadeMode::DoNotFade);
+
+ auto mockOverlay = MockPageOverlay::create(overlay.ptr());
+ m_overlays.add(mockOverlay.ptr());
+
+ return mockOverlay;
+}
+
+void MockPageOverlayClient::uninstallAllOverlays()
+{
+ while (!m_overlays.isEmpty()) {
+ RefPtr<MockPageOverlay> mockOverlay = m_overlays.takeAny();
+ PageOverlayController* overlayController = mockOverlay->overlay()->controller();
+ ASSERT(overlayController);
+ overlayController->uninstallPageOverlay(*mockOverlay->overlay(), PageOverlay::FadeMode::DoNotFade);
+ }
+}
+
+String MockPageOverlayClient::layerTreeAsText(MainFrame& mainFrame, LayerTreeFlags flags)
+{
+ GraphicsLayer* viewOverlayRoot = mainFrame.pageOverlayController().viewOverlayRootLayer();
+ GraphicsLayer* documentOverlayRoot = mainFrame.pageOverlayController().documentOverlayRootLayer();
+
+ return "View-relative:\n" + (viewOverlayRoot ? viewOverlayRoot->layerTreeAsText(flags | LayerTreeAsTextIncludePageOverlayLayers) : "(no view-relative overlay root)")
+ + "\n\nDocument-relative:\n" + (documentOverlayRoot ? documentOverlayRoot->layerTreeAsText(flags | LayerTreeAsTextIncludePageOverlayLayers) : "(no document-relative overlay root)");
+}
+
+void MockPageOverlayClient::willMoveToPage(PageOverlay&, Page*)
+{
+}
+
+void MockPageOverlayClient::didMoveToPage(PageOverlay& overlay, Page* page)
+{
+ if (page)
+ overlay.setNeedsDisplay();
+}
+
+void MockPageOverlayClient::drawRect(PageOverlay& overlay, GraphicsContext& context, const IntRect& dirtyRect)
+{
+ StringBuilder message;
+ message.appendLiteral("MockPageOverlayClient::drawRect dirtyRect (");
+ message.appendNumber(dirtyRect.x());
+ message.appendLiteral(", ");
+ message.appendNumber(dirtyRect.y());
+ message.appendLiteral(", ");
+ message.appendNumber(dirtyRect.width());
+ message.appendLiteral(", ");
+ message.appendNumber(dirtyRect.height());
+ message.appendLiteral(")");
+ overlay.page()->mainFrame().document()->addConsoleMessage(MessageSource::Other, MessageLevel::Debug, message.toString());
+
+ GraphicsContextStateSaver stateSaver(context);
+
+ FloatRect insetRect = overlay.bounds();
+
+ if (overlay.overlayType() == PageOverlay::OverlayType::Document) {
+ context.setStrokeColor(Color(0, 255, 0));
+ insetRect.inflate(-50);
+ } else {
+ context.setStrokeColor(Color(0, 0, 255));
+ insetRect.inflate(-20);
+ }
+
+ context.strokeRect(insetRect, 20);
+}
+
+bool MockPageOverlayClient::mouseEvent(PageOverlay& overlay, const PlatformMouseEvent& event)
+{
+ StringBuilder message;
+ message.appendLiteral("MockPageOverlayClient::mouseEvent location (");
+ message.appendNumber(event.position().x());
+ message.appendLiteral(", ");
+ message.appendNumber(event.position().y());
+ message.appendLiteral(")");
+ overlay.page()->mainFrame().document()->addConsoleMessage(MessageSource::Other, MessageLevel::Debug, message.toString());
+
+ return false;
+}
+
+void MockPageOverlayClient::didScrollFrame(PageOverlay&, Frame&)
+{
+}
+
+bool MockPageOverlayClient::copyAccessibilityAttributeStringValueForPoint(PageOverlay&, String /* attribute */, FloatPoint, String&)
+{
+ return false;
+}
+
+bool MockPageOverlayClient::copyAccessibilityAttributeBoolValueForPoint(PageOverlay&, String /* attribute */, FloatPoint, bool&)
+{
+ return false;
+}
+
+Vector<String> MockPageOverlayClient::copyAccessibilityAttributeNames(PageOverlay&, bool /* parameterizedNames */)
+{
+ return Vector<String>();
+}
+
+}
diff --git a/Source/WebCore/testing/MockPageOverlayClient.h b/Source/WebCore/testing/MockPageOverlayClient.h
new file mode 100644
index 000000000..377d7ab04
--- /dev/null
+++ b/Source/WebCore/testing/MockPageOverlayClient.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "Frame.h"
+#include "MockPageOverlay.h"
+#include "PageOverlay.h"
+#include <wtf/HashSet.h>
+
+namespace WebCore {
+
+class MainFrame;
+
+class MockPageOverlayClient final : public PageOverlay::Client {
+ friend class NeverDestroyed<MockPageOverlayClient>;
+public:
+ static MockPageOverlayClient& singleton();
+
+ explicit MockPageOverlayClient();
+
+ Ref<MockPageOverlay> installOverlay(MainFrame&, PageOverlay::OverlayType);
+ void uninstallAllOverlays();
+
+ String layerTreeAsText(MainFrame&, LayerTreeFlags);
+
+ virtual ~MockPageOverlayClient() { }
+
+private:
+ void willMoveToPage(PageOverlay&, Page*) override;
+ void didMoveToPage(PageOverlay&, Page*) override;
+ void drawRect(PageOverlay&, GraphicsContext&, const IntRect& dirtyRect) override;
+ bool mouseEvent(PageOverlay&, const PlatformMouseEvent&) override;
+ void didScrollFrame(PageOverlay&, Frame&) override;
+
+ bool copyAccessibilityAttributeStringValueForPoint(PageOverlay&, String /* attribute */, FloatPoint, String&) override;
+ bool copyAccessibilityAttributeBoolValueForPoint(PageOverlay&, String /* attribute */, FloatPoint, bool&) override;
+ Vector<String> copyAccessibilityAttributeNames(PageOverlay&, bool /* parameterizedNames */) override;
+
+ HashSet<RefPtr<MockPageOverlay>> m_overlays;
+};
+
+} // namespace WebCore
diff --git a/Source/WebCore/testing/MockQuickLookHandleClient.cpp b/Source/WebCore/testing/MockQuickLookHandleClient.cpp
new file mode 100644
index 000000000..ca8197e10
--- /dev/null
+++ b/Source/WebCore/testing/MockQuickLookHandleClient.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "MockQuickLookHandleClient.h"
+
+#if USE(QUICK_LOOK)
+
+#include <wtf/MainThread.h>
+#include <wtf/RunLoop.h>
+
+namespace WebCore {
+
+MockQuickLookHandleClient& MockQuickLookHandleClient::singleton()
+{
+ static NeverDestroyed<MockQuickLookHandleClient> sharedClient;
+ return sharedClient.get();
+}
+
+void MockQuickLookHandleClient::didRequestPassword(Function<void(const String&)>&& completionHandler)
+{
+ ASSERT(isMainThread());
+ RunLoop::current().dispatch([completionHandler = WTFMove(completionHandler), password = m_password] {
+ completionHandler(password);
+ });
+}
+
+} // namespace WebCore
+
+#endif // USE(QUICK_LOOK)
diff --git a/Source/WebCore/testing/MockQuickLookHandleClient.h b/Source/WebCore/testing/MockQuickLookHandleClient.h
new file mode 100644
index 000000000..39cef17b9
--- /dev/null
+++ b/Source/WebCore/testing/MockQuickLookHandleClient.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if USE(QUICK_LOOK)
+
+#include "QuickLookHandleClient.h"
+#include <wtf/NeverDestroyed.h>
+
+namespace WebCore {
+
+class MockQuickLookHandleClient final : public QuickLookHandleClient {
+public:
+ static MockQuickLookHandleClient& singleton();
+
+ void setPassword(const String& password) { m_password = password; }
+
+ bool supportsPasswordEntry() const override { return true; }
+ void didRequestPassword(Function<void(const String&)>&&) override;
+
+private:
+ friend class NeverDestroyed<MockQuickLookHandleClient>;
+ MockQuickLookHandleClient() = default;
+
+ String m_password;
+};
+
+} // namespace WebCore
+
+#endif // USE(QUICK_LOOK)
diff --git a/Source/WebCore/testing/TypeConversions.h b/Source/WebCore/testing/TypeConversions.h
index 826387502..b352b17d1 100644
--- a/Source/WebCore/testing/TypeConversions.h
+++ b/Source/WebCore/testing/TypeConversions.h
@@ -23,18 +23,41 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef TypeConversions_h
-#define TypeConversions_h
+#pragma once
+#include "Node.h"
#include <wtf/FastMalloc.h>
-#include <wtf/PassRefPtr.h>
+#include <wtf/HashMap.h>
#include <wtf/RefCounted.h>
+#include <wtf/Variant.h>
+#include <wtf/Vector.h>
+#include <wtf/text/WTFString.h>
namespace WebCore {
class TypeConversions : public RefCounted<TypeConversions> {
public:
- static PassRefPtr<TypeConversions> create() { return adoptRef(new TypeConversions()); }
+ static Ref<TypeConversions> create() { return adoptRef(*new TypeConversions()); }
+
+ enum class UnionType {
+ Node,
+ Sequence,
+ Dictionary
+ };
+
+ struct OtherDictionary {
+ int longValue;
+ String stringValue;
+ };
+
+ using DictionaryUnion = Variant<RefPtr<Node>, Vector<String>, OtherDictionary>;
+
+ struct Dictionary {
+ int longValue;
+ String stringValue;
+ Vector<String> sequenceValue;
+ DictionaryUnion unionValue;
+ };
long testLong() { return m_long; }
void setTestLong(long value) { m_long = value; }
@@ -71,21 +94,71 @@ public:
void setTestUnsignedShort(uint16_t value) { m_UnsignedShort = value; }
uint16_t testEnforceRangeUnsignedShort() { return m_UnsignedShort; }
void setTestEnforceRangeUnsignedShort(uint16_t value) { m_UnsignedShort = value; }
+
+ const String& testString() const { return m_string; }
+ void setTestString(const String& string) { m_string = string; }
+ const String& testUSVString() const { return m_usvstring; }
+ void setTestUSVString(const String& usvstring) { m_usvstring = usvstring; }
+ const String& testByteString() const { return m_byteString; }
+ void setTestByteString(const String& byteString) { m_byteString = byteString; }
+
+ const Vector<WTF::KeyValuePair<String, int>>& testLongRecord() const { return m_longRecord; }
+ void setTestLongRecord(const Vector<WTF::KeyValuePair<String, int>>& value) { m_longRecord = value; }
+ const Vector<WTF::KeyValuePair<String, RefPtr<Node>>>& testNodeRecord() const { return m_nodeRecord; }
+ void setTestNodeRecord(const Vector<WTF::KeyValuePair<String, RefPtr<Node>>>& value) { m_nodeRecord = value; }
+ const Vector<WTF::KeyValuePair<String, Vector<String>>>& testSequenceRecord() const { return m_sequenceRecord; }
+ void setTestSequenceRecord(const Vector<WTF::KeyValuePair<String, Vector<String>>>& value) { m_sequenceRecord = value; }
+
+ using TestUnion = Variant<String, int, bool, RefPtr<Node>, Vector<int>>;
+ const TestUnion& testUnion() const { return m_union; }
+ void setTestUnion(const TestUnion& value) { m_union = value; }
+
+ void setTypeConversionsDictionary(Dictionary&& dictionary)
+ {
+ m_typeConversionsDictionaryLongValue = dictionary.longValue;
+ m_typeConversionsDictionaryStringValue = WTFMove(dictionary.stringValue);
+ m_typeConversionsDictionarySequenceValue = WTFMove(dictionary.sequenceValue);
+ m_typeConversionsDictionaryUnionValue = WTFMove(dictionary.unionValue);
+ }
+
+ int typeConversionsDictionaryLongValue() { return m_typeConversionsDictionaryLongValue; }
+ String typeConversionsDictionaryStringValue() { return m_typeConversionsDictionaryStringValue; }
+ const Vector<String>& typeConversionsDictionarySequenceValue() { return m_typeConversionsDictionarySequenceValue; }
+ const DictionaryUnion& typeConversionsDictionaryUnionValue() { return m_typeConversionsDictionaryUnionValue; }
+ UnionType typeConversionsDictionaryUnionType()
+ {
+ return WTF::switchOn(m_typeConversionsDictionaryUnionValue,
+ [](const RefPtr<Node>&) -> UnionType { return UnionType::Node; },
+ [](const Vector<String>&) -> UnionType { return UnionType::Sequence; },
+ [](const OtherDictionary&) -> UnionType { return UnionType::Dictionary; }
+ );
+ }
+
private:
TypeConversions()
{
}
- long m_long;
- unsigned long m_unsignedLong;
- long long m_longLong;
- unsigned long long m_unsignedLongLong;
- int8_t m_byte;
- uint8_t m_octet;
- int16_t m_short;
- uint16_t m_UnsignedShort;
+ long m_long { 0 };
+ unsigned long m_unsignedLong { 0 };
+ long long m_longLong { 0 };
+ unsigned long long m_unsignedLongLong { 0 };
+ int8_t m_byte { 0 };
+ uint8_t m_octet { 0 };
+ int16_t m_short { 0 };
+ uint16_t m_UnsignedShort { 0 };
+ String m_string;
+ String m_usvstring;
+ String m_byteString;
+ Vector<WTF::KeyValuePair<String, int>> m_longRecord;
+ Vector<WTF::KeyValuePair<String, RefPtr<Node>>> m_nodeRecord;
+ Vector<WTF::KeyValuePair<String, Vector<String>>> m_sequenceRecord;
+ TestUnion m_union;
+
+ int m_typeConversionsDictionaryLongValue { 0 };
+ String m_typeConversionsDictionaryStringValue;
+ Vector<String> m_typeConversionsDictionarySequenceValue;
+ DictionaryUnion m_typeConversionsDictionaryUnionValue;
};
} // namespace WebCore
-
-#endif
diff --git a/Source/WebCore/testing/TypeConversions.idl b/Source/WebCore/testing/TypeConversions.idl
index f02d73c70..5a5908941 100644
--- a/Source/WebCore/testing/TypeConversions.idl
+++ b/Source/WebCore/testing/TypeConversions.idl
@@ -23,9 +23,12 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+enum UnionType { "node", "sequence", "dictionary" };
+
[
NoInterfaceObject,
- ImplementationLacksVTable
+ ImplementationLacksVTable,
+ ExportMacro=WEBCORE_TESTSUPPORT_EXPORT,
] interface TypeConversions {
attribute long testLong;
[EnforceRange] attribute long testEnforceRangeLong;
@@ -46,4 +49,37 @@
[EnforceRange] attribute short testEnforceRangeShort;
attribute unsigned short testUnsignedShort;
[EnforceRange] attribute unsigned short testEnforceRangeUnsignedShort;
+
+ attribute DOMString testString;
+ attribute ByteString testByteString;
+ attribute USVString testUSVString;
+
+ void setTestLongRecord(record<DOMString, long> record);
+ record<DOMString, long> testLongRecord();
+
+ void setTestNodeRecord(record<USVString, Node> record);
+ record<USVString, Node> testNodeRecord();
+
+ void setTestSequenceRecord(record<ByteString, sequence<DOMString>> record);
+ record<ByteString, sequence<DOMString>> testSequenceRecord();
+
+ attribute (DOMString or long or boolean or Node or sequence<long>) testUnion;
+
+ void setTypeConversionsDictionary(TypeConversionsDictionary d);
+ readonly attribute long typeConversionsDictionaryLongValue;
+ readonly attribute DOMString typeConversionsDictionaryStringValue;
+ readonly attribute sequence<DOMString> typeConversionsDictionarySequenceValue;
+ readonly attribute UnionType typeConversionsDictionaryUnionType;
+};
+
+dictionary TypeConversionsOtherDictionary {
+ long longValue = 0;
+ DOMString stringValue = "";
+};
+
+dictionary TypeConversionsDictionary {
+ long longValue = 0;
+ DOMString stringValue = "";
+ sequence<DOMString> sequenceValue = [];
+ (Node or sequence<DOMString> or TypeConversionsOtherDictionary) unionValue = null;
};
diff --git a/Source/WebCore/testing/WebCoreTestShimLibrary.cpp b/Source/WebCore/testing/WebCoreTestShimLibrary.cpp
new file mode 100644
index 000000000..edf3d388c
--- /dev/null
+++ b/Source/WebCore/testing/WebCoreTestShimLibrary.cpp
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <TargetConditionals.h>
+
+#if !defined(TARGET_OS_IPHONE) || !TARGET_OS_IPHONE
+
+#include "DynamicLinkerInterposing.h"
+#include <Carbon/Carbon.h>
+
+static int sSecureInputEnableCount;
+
+static OSStatus shimEnableSecureEventInput()
+{
+ ++sSecureInputEnableCount;
+ return noErr;
+}
+
+static OSStatus shimDisableSecureEventInput()
+{
+ if (!sSecureInputEnableCount)
+ return paramErr;
+ --sSecureInputEnableCount;
+ return noErr;
+}
+
+static Boolean shimIsSecureEventInputEnabled()
+{
+ return sSecureInputEnableCount;
+}
+
+DYLD_INTERPOSE(shimEnableSecureEventInput, EnableSecureEventInput)
+DYLD_INTERPOSE(shimDisableSecureEventInput, DisableSecureEventInput)
+DYLD_INTERPOSE(shimIsSecureEventInputEnabled, IsSecureEventInputEnabled)
+
+#endif // !defined(TARGET_OS_IPHONE) || !TARGET_OS_IPHONE
diff --git a/Source/WebCore/testing/js/WebCoreTestSupport.cpp b/Source/WebCore/testing/js/WebCoreTestSupport.cpp
index 92623793c..faffd0c4a 100644
--- a/Source/WebCore/testing/js/WebCoreTestSupport.cpp
+++ b/Source/WebCore/testing/js/WebCoreTestSupport.cpp
@@ -1,5 +1,6 @@
/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
+ * Copyright (C) 2011, 2015 Google Inc. All rights reserved.
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -31,8 +32,15 @@
#include "Internals.h"
#include "JSDocument.h"
#include "JSInternals.h"
+#include "LogInitialization.h"
+#include "MockGamepadProvider.h"
+#include "Page.h"
+#include "URLParser.h"
+#include "WheelEventTestTrigger.h"
#include <JavaScriptCore/APICast.h>
+#include <JavaScriptCore/JSValueRef.h>
#include <interpreter/CallFrame.h>
+#include <runtime/IdentifierInlines.h>
using namespace JSC;
using namespace WebCore;
@@ -45,8 +53,8 @@ void injectInternalsObject(JSContextRef context)
JSLockHolder lock(exec);
JSDOMGlobalObject* globalObject = jsCast<JSDOMGlobalObject*>(exec->lexicalGlobalObject());
ScriptExecutionContext* scriptContext = globalObject->scriptExecutionContext();
- if (scriptContext->isDocument())
- globalObject->putDirect(exec->vm(), Identifier(exec, Internals::internalsId), toJS(exec, globalObject, Internals::create(toDocument(scriptContext))));
+ if (is<Document>(*scriptContext))
+ globalObject->putDirect(exec->vm(), Identifier::fromString(exec, Internals::internalsId), toJS(exec, globalObject, Internals::create(downcast<Document>(*scriptContext))));
}
void resetInternalsObject(JSContextRef context)
@@ -55,9 +63,121 @@ void resetInternalsObject(JSContextRef context)
JSLockHolder lock(exec);
JSDOMGlobalObject* globalObject = jsCast<JSDOMGlobalObject*>(exec->lexicalGlobalObject());
ScriptExecutionContext* scriptContext = globalObject->scriptExecutionContext();
- Page* page = toDocument(scriptContext)->frame()->page();
- Internals::resetToConsistentState(page);
+ Page* page = downcast<Document>(scriptContext)->frame()->page();
+ Internals::resetToConsistentState(*page);
InternalSettings::from(page)->resetToConsistentState();
}
+void monitorWheelEvents(WebCore::Frame& frame)
+{
+ Page* page = frame.page();
+ if (!page)
+ return;
+
+ page->ensureTestTrigger();
+}
+
+void setTestCallbackAndStartNotificationTimer(WebCore::Frame& frame, JSContextRef context, JSObjectRef jsCallbackFunction)
+{
+ Page* page = frame.page();
+ if (!page || !page->expectsWheelEventTriggers())
+ return;
+
+ JSValueProtect(context, jsCallbackFunction);
+
+ page->ensureTestTrigger().setTestCallbackAndStartNotificationTimer([=](void) {
+ JSObjectCallAsFunction(context, jsCallbackFunction, nullptr, 0, nullptr, nullptr);
+ JSValueUnprotect(context, jsCallbackFunction);
+ });
+}
+
+void clearWheelEventTestTrigger(WebCore::Frame& frame)
+{
+ Page* page = frame.page();
+ if (!page)
+ return;
+
+ page->clearTrigger();
+}
+
+void setLogChannelToAccumulate(const String& name)
+{
+#if !LOG_DISABLED
+ WebCore::setLogChannelToAccumulate(name);
+#else
+ UNUSED_PARAM(name);
+#endif
+}
+
+void initializeLogChannelsIfNecessary()
+{
+#if !LOG_DISABLED || !RELEASE_LOG_DISABLED
+ WebCore::initializeLogChannelsIfNecessary();
+#endif
+}
+
+void setAllowsAnySSLCertificate(bool allowAnySSLCertificate)
+{
+ InternalSettings::setAllowsAnySSLCertificate(allowAnySSLCertificate);
+}
+
+void installMockGamepadProvider()
+{
+#if ENABLE(GAMEPAD)
+ GamepadProvider::setSharedProvider(MockGamepadProvider::singleton());
+#endif
+}
+
+void connectMockGamepad(unsigned gamepadIndex)
+{
+#if ENABLE(GAMEPAD)
+ MockGamepadProvider::singleton().connectMockGamepad(gamepadIndex);
+#else
+ UNUSED_PARAM(gamepadIndex);
+#endif
+}
+
+void disconnectMockGamepad(unsigned gamepadIndex)
+{
+#if ENABLE(GAMEPAD)
+ MockGamepadProvider::singleton().disconnectMockGamepad(gamepadIndex);
+#else
+ UNUSED_PARAM(gamepadIndex);
+#endif
+}
+
+void setMockGamepadDetails(unsigned gamepadIndex, const WTF::String& gamepadID, unsigned axisCount, unsigned buttonCount)
+{
+#if ENABLE(GAMEPAD)
+ MockGamepadProvider::singleton().setMockGamepadDetails(gamepadIndex, gamepadID, axisCount, buttonCount);
+#else
+ UNUSED_PARAM(gamepadIndex);
+ UNUSED_PARAM(gamepadID);
+ UNUSED_PARAM(axisCount);
+ UNUSED_PARAM(buttonCount);
+#endif
+}
+
+void setMockGamepadAxisValue(unsigned gamepadIndex, unsigned axisIndex, double axisValue)
+{
+#if ENABLE(GAMEPAD)
+ MockGamepadProvider::singleton().setMockGamepadAxisValue(gamepadIndex, axisIndex, axisValue);
+#else
+ UNUSED_PARAM(gamepadIndex);
+ UNUSED_PARAM(axisIndex);
+ UNUSED_PARAM(axisValue);
+#endif
+}
+
+void setMockGamepadButtonValue(unsigned gamepadIndex, unsigned buttonIndex, double buttonValue)
+{
+#if ENABLE(GAMEPAD)
+ MockGamepadProvider::singleton().setMockGamepadButtonValue(gamepadIndex, buttonIndex, buttonValue);
+#else
+ UNUSED_PARAM(gamepadIndex);
+ UNUSED_PARAM(buttonIndex);
+ UNUSED_PARAM(buttonValue);
+#endif
+}
+
}
diff --git a/Source/WebCore/testing/js/WebCoreTestSupport.h b/Source/WebCore/testing/js/WebCoreTestSupport.h
index de7fc747f..564094a52 100644
--- a/Source/WebCore/testing/js/WebCoreTestSupport.h
+++ b/Source/WebCore/testing/js/WebCoreTestSupport.h
@@ -1,5 +1,6 @@
/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
+ * Copyright (C) 2011, 2015 Google Inc. All rights reserved.
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -23,22 +24,43 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef WebCoreTestSupport_h
-#define WebCoreTestSupport_h
+#pragma once
typedef const struct OpaqueJSContext* JSContextRef;
+typedef struct OpaqueJSString* JSStringRef;
+typedef struct OpaqueJSValue* JSObjectRef;
-#if PLATFORM(MAC)
+#if PLATFORM(COCOA)
#define TEST_SUPPORT_EXPORT WTF_EXPORT_PRIVATE
#else
#define TEST_SUPPORT_EXPORT
#endif
+namespace WTF {
+class String;
+}
+
+namespace WebCore {
+class Frame;
+}
+
namespace WebCoreTestSupport {
void injectInternalsObject(JSContextRef) TEST_SUPPORT_EXPORT;
void resetInternalsObject(JSContextRef) TEST_SUPPORT_EXPORT;
+void monitorWheelEvents(WebCore::Frame&) TEST_SUPPORT_EXPORT;
+void setTestCallbackAndStartNotificationTimer(WebCore::Frame&, JSContextRef, JSObjectRef) TEST_SUPPORT_EXPORT;
+void clearWheelEventTestTrigger(WebCore::Frame&) TEST_SUPPORT_EXPORT;
-} // namespace WebCore
+void setLogChannelToAccumulate(const WTF::String& name) TEST_SUPPORT_EXPORT;
+void initializeLogChannelsIfNecessary() TEST_SUPPORT_EXPORT;
+void setAllowsAnySSLCertificate(bool) TEST_SUPPORT_EXPORT;
-#endif
+void installMockGamepadProvider() TEST_SUPPORT_EXPORT;
+void connectMockGamepad(unsigned index) TEST_SUPPORT_EXPORT;
+void disconnectMockGamepad(unsigned index) TEST_SUPPORT_EXPORT;
+void setMockGamepadDetails(unsigned index, const WTF::String& gamepadID, unsigned axisCount, unsigned buttonCount) TEST_SUPPORT_EXPORT;
+void setMockGamepadAxisValue(unsigned index, unsigned axisIndex, double value) TEST_SUPPORT_EXPORT;
+void setMockGamepadButtonValue(unsigned index, unsigned buttonIndex, double value) TEST_SUPPORT_EXPORT;
+
+} // namespace WebCoreTestSupport
diff --git a/Source/WebCore/testing/js/WebCoreTestSupportPrefix.cpp b/Source/WebCore/testing/js/WebCoreTestSupportPrefix.cpp
new file mode 100644
index 000000000..30eaa33c4
--- /dev/null
+++ b/Source/WebCore/testing/js/WebCoreTestSupportPrefix.cpp
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "WebCoreTestSupportPrefix.h"
diff --git a/Source/WebCore/testing/js/WebCoreTestSupportPrefix.h b/Source/WebCore/testing/js/WebCoreTestSupportPrefix.h
new file mode 100644
index 000000000..da9b0fce9
--- /dev/null
+++ b/Source/WebCore/testing/js/WebCoreTestSupportPrefix.h
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2015 Apple Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+/* This prefix file should contain only:
+ * 1) files to precompile for faster builds
+ * 2) in one case at least: OS-X-specific performance bug workarounds
+ * 3) the special trick to catch us using new or delete without including "config.h"
+ * The project should be able to build without this header, although we rarely test that.
+ */
+
+/* Things that need to be defined globally should go into "config.h". */
+
+#if defined(HAVE_CONFIG_H) && HAVE_CONFIG_H && defined(BUILDING_WITH_CMAKE)
+#include "cmakeconfig.h"
+#endif
+
+#include <wtf/Platform.h>
+
+#if defined(__APPLE__)
+#ifdef __cplusplus
+#define NULL __null
+#else
+#define NULL ((void *)0)
+#endif
+#endif
+
+#if OS(WINDOWS)
+
+#ifndef _WIN32_WINNT
+#define _WIN32_WINNT 0x601
+#endif
+
+#ifndef WINVER
+#define WINVER 0x0601
+#endif
+
+#if !USE(CURL)
+#ifndef _WINSOCKAPI_
+#define _WINSOCKAPI_ // Prevent inclusion of winsock.h in windows.h
+#endif
+#endif
+
+#undef WEBCORE_EXPORT
+#define WEBCORE_EXPORT WTF_IMPORT_DECLARATION
+#define WEBCORE_TESTSUPPORT_EXPORT WTF_EXPORT_DECLARATION
+
+#else
+
+#include <pthread.h>
+
+#define WEBCORE_TESTSUPPORT_EXPORT WEBCORE_EXPORT
+
+#endif // OS(WINDOWS)
+
+#include <fcntl.h>
+#include <sys/types.h>
+#if defined(__APPLE__)
+#include <regex.h>
+#endif
+
+#include <setjmp.h>
+
+#include <signal.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#if defined(__APPLE__)
+#include <unistd.h>
+#endif
+
+#ifdef __cplusplus
+#include <algorithm>
+#include <cstddef>
+#include <new>
+#endif
+
+#if defined(__APPLE__)
+#include <sys/param.h>
+#endif
+#include <sys/stat.h>
+#if defined(__APPLE__)
+#include <sys/resource.h>
+#include <sys/time.h>
+#endif
+
+#include <CoreFoundation/CoreFoundation.h>
+#if PLATFORM(WIN_CAIRO)
+#include <ConditionalMacros.h>
+#include <windows.h>
+#else
+
+#if OS(WINDOWS)
+#if USE(CG)
+
+// FIXME <rdar://problem/8208868> Remove support for obsolete ColorSync API, CoreServices header in CoreGraphics
+// We can remove this once the new ColorSync APIs are available in an internal Safari SDK.
+#include <ColorSync/ColorSync.h>
+#ifdef __COLORSYNCDEPRECATED__
+#define COREGRAPHICS_INCLUDES_CORESERVICES_HEADER
+#define OBSOLETE_COLORSYNC_API
+#endif
+#endif
+#if USE(CFURLCONNECTION)
+#include <CFNetwork/CFNetwork.h>
+// On Windows, dispatch.h needs to be included before certain CFNetwork headers.
+#include <dispatch/dispatch.h>
+#endif
+#include <windows.h>
+#else
+#if !PLATFORM(IOS)
+#include <CoreServices/CoreServices.h>
+#endif // !PLATFORM(IOS)
+#endif // OS(WINDOWS)
+
+#endif
+
+#ifdef __OBJC__
+#if PLATFORM(IOS)
+#import <Foundation/Foundation.h>
+#else
+#import <Cocoa/Cocoa.h>
+#endif // PLATFORM(IOS)
+#endif
+
+#ifdef __cplusplus
+#define new ("if you use new/delete make sure to include config.h at the top of the file"())
+#define delete ("if you use new/delete make sure to include config.h at the top of the file"())
+#endif
+
+/* When C++ exceptions are disabled, the C++ library defines |try| and |catch|
+ * to allow C++ code that expects exceptions to build. These definitions
+ * interfere with Objective-C++ uses of Objective-C exception handlers, which
+ * use |@try| and |@catch|. As a workaround, undefine these macros. */
+#ifdef __OBJC__
+#undef try
+#undef catch
+#endif
+