summaryrefslogtreecommitdiff
path: root/Source/WebCore/testing/Internals.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/testing/Internals.cpp')
-rw-r--r--Source/WebCore/testing/Internals.cpp3493
1 files changed, 2479 insertions, 1014 deletions
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