Files
AI/참고/playwright-main/browser_patches/webkit/patches/bootstrap.diff
2026-05-12 19:40:31 +09:00

20039 lines
905 KiB
Diff

diff --git a/Source/JavaScriptCore/CMakeLists.txt b/Source/JavaScriptCore/CMakeLists.txt
index c257f6a5a523ce12f67857e0d344aadffea6601a..f8c46e22eb4fa79c6b9f56846828391c3bf4de21 100644
--- a/Source/JavaScriptCore/CMakeLists.txt
+++ b/Source/JavaScriptCore/CMakeLists.txt
@@ -1615,21 +1615,26 @@ set(JavaScriptCore_INSPECTOR_DOMAINS
${JAVASCRIPTCORE_DIR}/inspector/protocol/CSS.json
${JAVASCRIPTCORE_DIR}/inspector/protocol/Canvas.json
${JAVASCRIPTCORE_DIR}/inspector/protocol/Console.json
+ ${JAVASCRIPTCORE_DIR}/inspector/protocol/Dialog.json
${JAVASCRIPTCORE_DIR}/inspector/protocol/DOM.json
${JAVASCRIPTCORE_DIR}/inspector/protocol/DOMDebugger.json
${JAVASCRIPTCORE_DIR}/inspector/protocol/DOMStorage.json
${JAVASCRIPTCORE_DIR}/inspector/protocol/Debugger.json
+ ${JAVASCRIPTCORE_DIR}/inspector/protocol/Emulation.json
${JAVASCRIPTCORE_DIR}/inspector/protocol/GenericTypes.json
${JAVASCRIPTCORE_DIR}/inspector/protocol/Heap.json
${JAVASCRIPTCORE_DIR}/inspector/protocol/IndexedDB.json
+ ${JAVASCRIPTCORE_DIR}/inspector/protocol/Input.json
${JAVASCRIPTCORE_DIR}/inspector/protocol/Inspector.json
${JAVASCRIPTCORE_DIR}/inspector/protocol/LayerTree.json
${JAVASCRIPTCORE_DIR}/inspector/protocol/Memory.json
${JAVASCRIPTCORE_DIR}/inspector/protocol/Network.json
${JAVASCRIPTCORE_DIR}/inspector/protocol/Page.json
+ ${JAVASCRIPTCORE_DIR}/inspector/protocol/Playwright.json
${JAVASCRIPTCORE_DIR}/inspector/protocol/Recording.json
${JAVASCRIPTCORE_DIR}/inspector/protocol/Runtime.json
${JAVASCRIPTCORE_DIR}/inspector/protocol/ScriptProfiler.json
+ ${JAVASCRIPTCORE_DIR}/inspector/protocol/Screencast.json
${JAVASCRIPTCORE_DIR}/inspector/protocol/Security.json
${JAVASCRIPTCORE_DIR}/inspector/protocol/ServiceWorker.json
${JAVASCRIPTCORE_DIR}/inspector/protocol/Target.json
diff --git a/Source/JavaScriptCore/DerivedSources-input.xcfilelist b/Source/JavaScriptCore/DerivedSources-input.xcfilelist
index 55eacb0d378fddea15ece56db612655ac5d64061..cb6cfa7c542e82671f68984ff9373e1bf58da2b8 100644
--- a/Source/JavaScriptCore/DerivedSources-input.xcfilelist
+++ b/Source/JavaScriptCore/DerivedSources-input.xcfilelist
@@ -101,20 +101,25 @@ $(PROJECT_DIR)/inspector/protocol/CPUProfiler.json
$(PROJECT_DIR)/inspector/protocol/CSS.json
$(PROJECT_DIR)/inspector/protocol/Canvas.json
$(PROJECT_DIR)/inspector/protocol/Console.json
+$(PROJECT_DIR)/inspector/protocol/Dialog.json
$(PROJECT_DIR)/inspector/protocol/DOM.json
$(PROJECT_DIR)/inspector/protocol/DOMDebugger.json
$(PROJECT_DIR)/inspector/protocol/DOMStorage.json
$(PROJECT_DIR)/inspector/protocol/Debugger.json
+$(PROJECT_DIR)/inspector/protocol/Emulation.json
$(PROJECT_DIR)/inspector/protocol/GenericTypes.json
$(PROJECT_DIR)/inspector/protocol/Heap.json
$(PROJECT_DIR)/inspector/protocol/IndexedDB.json
+$(PROJECT_DIR)/inspector/protocol/Input.json
$(PROJECT_DIR)/inspector/protocol/Inspector.json
$(PROJECT_DIR)/inspector/protocol/LayerTree.json
$(PROJECT_DIR)/inspector/protocol/Memory.json
$(PROJECT_DIR)/inspector/protocol/Network.json
$(PROJECT_DIR)/inspector/protocol/Page.json
+$(PROJECT_DIR)/inspector/protocol/Playwright.json
$(PROJECT_DIR)/inspector/protocol/Recording.json
$(PROJECT_DIR)/inspector/protocol/Runtime.json
+$(PROJECT_DIR)/inspector/protocol/Screencast.json
$(PROJECT_DIR)/inspector/protocol/ScriptProfiler.json
$(PROJECT_DIR)/inspector/protocol/Security.json
$(PROJECT_DIR)/inspector/protocol/ServiceWorker.json
diff --git a/Source/JavaScriptCore/DerivedSources.make b/Source/JavaScriptCore/DerivedSources.make
index 7eb4f1c1e0cd3abdf61203d33cd2f53d77d4264d..01adf210b42055612dc02aba0ed52e6f6ed1d10f 100644
--- a/Source/JavaScriptCore/DerivedSources.make
+++ b/Source/JavaScriptCore/DerivedSources.make
@@ -298,21 +298,26 @@ INSPECTOR_DOMAINS := \
$(JavaScriptCore)/inspector/protocol/CSS.json \
$(JavaScriptCore)/inspector/protocol/Canvas.json \
$(JavaScriptCore)/inspector/protocol/Console.json \
+ $(JavaScriptCore)/inspector/protocol/Dialog.json \
$(JavaScriptCore)/inspector/protocol/DOM.json \
$(JavaScriptCore)/inspector/protocol/DOMDebugger.json \
$(JavaScriptCore)/inspector/protocol/DOMStorage.json \
$(JavaScriptCore)/inspector/protocol/Debugger.json \
+ $(JavaScriptCore)/inspector/protocol/Emulation.json \
$(JavaScriptCore)/inspector/protocol/GenericTypes.json \
$(JavaScriptCore)/inspector/protocol/Heap.json \
$(JavaScriptCore)/inspector/protocol/IndexedDB.json \
+ $(JavaScriptCore)/inspector/protocol/Input.json \
$(JavaScriptCore)/inspector/protocol/Inspector.json \
$(JavaScriptCore)/inspector/protocol/LayerTree.json \
$(JavaScriptCore)/inspector/protocol/Memory.json \
$(JavaScriptCore)/inspector/protocol/Network.json \
$(JavaScriptCore)/inspector/protocol/Page.json \
+ $(JavaScriptCore)/inspector/protocol/Playwright.json \
$(JavaScriptCore)/inspector/protocol/Recording.json \
$(JavaScriptCore)/inspector/protocol/Runtime.json \
$(JavaScriptCore)/inspector/protocol/ScriptProfiler.json \
+ $(JavaScriptCore)/inspector/protocol/Screencast.json \
$(JavaScriptCore)/inspector/protocol/Security.json \
$(JavaScriptCore)/inspector/protocol/ServiceWorker.json \
$(JavaScriptCore)/inspector/protocol/Target.json \
diff --git a/Source/JavaScriptCore/inspector/IdentifiersFactory.cpp b/Source/JavaScriptCore/inspector/IdentifiersFactory.cpp
index 9bc5d1fd8e2a7e576be046b3c6ae1266696cf552..610f810db1dd6865c500c0796386a8284f4178e9 100644
--- a/Source/JavaScriptCore/inspector/IdentifiersFactory.cpp
+++ b/Source/JavaScriptCore/inspector/IdentifiersFactory.cpp
@@ -32,14 +32,21 @@
namespace Inspector {
namespace {
+static uint64_t s_processID = 0;
static unsigned long s_lastUsedIdentifier = 0;
}
static String addPrefixToIdentifier(unsigned long identifier)
{
- return makeString("0."_s, identifier);
+ return makeString(s_processID, '.', identifier);
}
+void IdentifiersFactory::initializeWithProcessID(uint64_t processID) {
+ ASSERT(!s_processID);
+ s_processID = processID;
+}
+
+
String IdentifiersFactory::createIdentifier()
{
return addPrefixToIdentifier(++s_lastUsedIdentifier);
diff --git a/Source/JavaScriptCore/inspector/IdentifiersFactory.h b/Source/JavaScriptCore/inspector/IdentifiersFactory.h
index e145f18eff043f6d718f38d14159415327a0b43b..747c06864110ef4488d8e4b0f6fd74a1d9badadd 100644
--- a/Source/JavaScriptCore/inspector/IdentifiersFactory.h
+++ b/Source/JavaScriptCore/inspector/IdentifiersFactory.h
@@ -32,6 +32,7 @@ namespace Inspector {
class IdentifiersFactory {
public:
+ JS_EXPORT_PRIVATE static void initializeWithProcessID(uint64_t);
JS_EXPORT_PRIVATE static String createIdentifier();
JS_EXPORT_PRIVATE static String requestId(unsigned long identifier);
};
diff --git a/Source/JavaScriptCore/inspector/InjectedScriptBase.cpp b/Source/JavaScriptCore/inspector/InjectedScriptBase.cpp
index 4d9152423abf35dfbdf338435b567a822b2f6904..4e6b551494e1d124655c8cc54f121ac4843c3298 100644
--- a/Source/JavaScriptCore/inspector/InjectedScriptBase.cpp
+++ b/Source/JavaScriptCore/inspector/InjectedScriptBase.cpp
@@ -85,7 +85,10 @@ static RefPtr<JSON::Value> jsToInspectorValue(JSC::JSGlobalObject* globalObject,
JSC::PropertyNameArrayBuilder propertyNames(vm, JSC::PropertyNameMode::Strings, JSC::PrivateSymbolMode::Exclude);
object.methodTable()->getOwnPropertyNames(&object, globalObject, propertyNames, JSC::DontEnumPropertiesMode::Exclude);
for (auto& name : propertyNames) {
- auto inspectorValue = jsToInspectorValue(globalObject, object.get(globalObject, name), maxDepth);
+ JSC::JSValue childValue = object.get(globalObject, name);
+ if (childValue.isUndefined())
+ continue;
+ auto inspectorValue = jsToInspectorValue(globalObject, childValue, maxDepth);
if (!inspectorValue)
return nullptr;
inspectorObject->setValue(name.string(), inspectorValue.releaseNonNull());
diff --git a/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.cpp b/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.cpp
index 449ff9c805107a41f783eaf72b9901d0df6a3e72..a56a086892caa03e171616bd90db8cbf94905b0d 100644
--- a/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.cpp
+++ b/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.cpp
@@ -103,7 +103,7 @@ void BackendDispatcher::registerDispatcherForDomain(const String& domain, Supple
m_dispatchers.set(domain, dispatcher);
}
-void BackendDispatcher::dispatch(const String& message)
+void BackendDispatcher::dispatch(const String& message, Interceptor&& interceptor)
{
Ref<BackendDispatcher> protect(*this);
@@ -148,6 +148,9 @@ void BackendDispatcher::dispatch(const String& message)
requestId = *requestIdInt;
}
+ if (interceptor && interceptor(messageObject) == InterceptionResult::Intercepted)
+ return;
+
{
// We could be called re-entrantly from a nested run loop, so restore the previous id.
SetForScope scopedRequestId(m_currentRequestId, requestId);
diff --git a/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.h b/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.h
index ed0cb419967759a258d3d250fd42d2b86ca32561..0788de297278f875d18dd9da22df53a72f34d52b 100644
--- a/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.h
+++ b/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.h
@@ -97,8 +97,11 @@ public:
ServerError
};
+ enum class InterceptionResult { Intercepted, Continue };
+ using Interceptor = WTF::Function<InterceptionResult(const RefPtr<JSON::Object>&)>;
+
JS_EXPORT_PRIVATE void registerDispatcherForDomain(const String& domain, SupplementalBackendDispatcher*);
- JS_EXPORT_PRIVATE void dispatch(const String& message);
+ JS_EXPORT_PRIVATE void dispatch(const String& message, Interceptor&& interceptor = Interceptor());
// Note that 'unused' is a workaround so the compiler can pick the right sendResponse based on arity.
// When <http://webkit.org/b/179847> is fixed or this class is renamed for the JSON::Object case,
diff --git a/Source/JavaScriptCore/inspector/InspectorFrontendRouter.cpp b/Source/JavaScriptCore/inspector/InspectorFrontendRouter.cpp
index 13207d2da597e3b96cc9e83d0bee83fa859cdcf0..c4f9f4714578652cb71f106bb0bfdb69440ed238 100644
--- a/Source/JavaScriptCore/inspector/InspectorFrontendRouter.cpp
+++ b/Source/JavaScriptCore/inspector/InspectorFrontendRouter.cpp
@@ -52,7 +52,7 @@ void FrontendRouter::connectFrontend(FrontendChannel& connection)
void FrontendRouter::disconnectFrontend(FrontendChannel& connection)
{
if (!m_connections.contains(&connection)) {
- ASSERT_NOT_REACHED();
+ ASSERT(m_connections.isEmpty());
return;
}
diff --git a/Source/JavaScriptCore/inspector/InspectorTarget.cpp b/Source/JavaScriptCore/inspector/InspectorTarget.cpp
index b68a7eb5e8d26ea7631b451f629734c886896684..92dba414b7e9c3587ae40c4cb7bb6e4f10895a70 100644
--- a/Source/JavaScriptCore/inspector/InspectorTarget.cpp
+++ b/Source/JavaScriptCore/inspector/InspectorTarget.cpp
@@ -48,6 +48,8 @@ void InspectorTarget::resume()
ASSERT(m_isPaused);
m_isPaused = false;
+ willResume();
+
if (m_resumeCallback) {
m_resumeCallback();
m_resumeCallback = nullptr;
@@ -56,7 +58,6 @@ void InspectorTarget::resume()
void InspectorTarget::setResumeCallback(WTF::Function<void()>&& callback)
{
- ASSERT(!m_resumeCallback);
m_resumeCallback = WTF::move(callback);
}
diff --git a/Source/JavaScriptCore/inspector/InspectorTarget.h b/Source/JavaScriptCore/inspector/InspectorTarget.h
index 421d62c0071a43b7fb111a4e2b120e28c5ba96af..de764f8519c3df6a9325d3eb87e7fe907c5b5b6a 100644
--- a/Source/JavaScriptCore/inspector/InspectorTarget.h
+++ b/Source/JavaScriptCore/inspector/InspectorTarget.h
@@ -61,8 +61,12 @@ public:
virtual void connect(FrontendChannel::ConnectionType) = 0;
virtual void disconnect() = 0;
virtual void sendMessageToTargetBackend(const String&) = 0;
+ virtual void activate(String& error) { error = "Target cannot be activated"_s; }
+ virtual void close(String& error, bool /* runBeforeUnload */) { error = "Target cannot be closed"_s; }
private:
+ virtual void willResume() { }
+
WTF::Function<void()> m_resumeCallback;
bool m_isPaused { false };
};
diff --git a/Source/JavaScriptCore/inspector/JSGlobalObjectConsoleClient.cpp b/Source/JavaScriptCore/inspector/JSGlobalObjectConsoleClient.cpp
index ddd58da62382291979c72d62700c61c137f5b965..ab114ba249ec6901c78da7703b5e8140d7cebcca 100644
--- a/Source/JavaScriptCore/inspector/JSGlobalObjectConsoleClient.cpp
+++ b/Source/JavaScriptCore/inspector/JSGlobalObjectConsoleClient.cpp
@@ -232,6 +232,14 @@ void JSGlobalObjectConsoleClient::screenshot(JSGlobalObject*, Ref<ScriptArgument
warnUnimplemented("console.screenshot"_s);
}
+void JSGlobalObjectConsoleClient::bindingCalled(JSGlobalObject*, const String&, const String&)
+{
+ if (!m_consoleAgent->developerExtrasEnabled())
+ return;
+
+ warnUnimplemented("console.bindingCalled"_s);
+}
+
void JSGlobalObjectConsoleClient::warnUnimplemented(const String& method)
{
auto message = makeString(method, " is currently ignored in JavaScript context inspection."_s);
diff --git a/Source/JavaScriptCore/inspector/JSGlobalObjectConsoleClient.h b/Source/JavaScriptCore/inspector/JSGlobalObjectConsoleClient.h
index ed7dbb3ee1de5183f1c1868310b332f52d2e8cd6..90dd8331ba5cf87a32407a01cfe9d218b4822f1c 100644
--- a/Source/JavaScriptCore/inspector/JSGlobalObjectConsoleClient.h
+++ b/Source/JavaScriptCore/inspector/JSGlobalObjectConsoleClient.h
@@ -68,6 +68,7 @@ private:
void record(JSC::JSGlobalObject*, Ref<ScriptArguments>&&) final;
void recordEnd(JSC::JSGlobalObject*, Ref<ScriptArguments>&&) final;
void screenshot(JSC::JSGlobalObject*, Ref<ScriptArguments>&&) final;
+ void bindingCalled(JSC::JSGlobalObject*, const String&, const String&) final;
void warnUnimplemented(const String& method);
void internalAddMessage(MessageType, MessageLevel, JSC::JSGlobalObject*, Ref<ScriptArguments>&&);
diff --git a/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.cpp b/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.cpp
index bd5258cf60b70750c52277007f657fbfaeaeec68..8ad812f65d8f2f6112d2456789a82520e215633b 100644
--- a/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.cpp
+++ b/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.cpp
@@ -219,6 +219,11 @@ void InspectorRuntimeAgent::callFunctionOn(InjectedScript& injectedScript, const
unmuteConsole();
}
+Protocol::ErrorStringOr<void> InspectorRuntimeAgent::addBinding(const String&)
+{
+ return makeUnexpected("Not implemented in this type of agent."_s);
+}
+
Protocol::ErrorStringOr<Ref<Protocol::Runtime::ObjectPreview>> InspectorRuntimeAgent::getPreview(const Protocol::Runtime::RemoteObjectId& objectId)
{
Protocol::ErrorString errorString;
diff --git a/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.h b/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.h
index f7ed41f0b3aaa9bb0eb388c4edbef2645e9b1dd4..511ff1799f7480c85fb46beda36fb52f3d489099 100644
--- a/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.h
+++ b/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.h
@@ -65,6 +65,7 @@ public:
Protocol::ErrorStringOr<std::tuple<Ref<Protocol::Runtime::RemoteObject>, std::optional<bool> /* wasThrown */, std::optional<int> /* savedResultIndex */>> evaluate(const String& expression, const String& objectGroup, std::optional<bool>&& includeCommandLineAPI, std::optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, std::optional<Protocol::Runtime::ExecutionContextId>&&, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& saveResult, std::optional<bool>&& emulateUserGesture) override;
void awaitPromise(const Protocol::Runtime::RemoteObjectId&, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& saveResult, Ref<AwaitPromiseCallback>&&) final;
void callFunctionOn(const Protocol::Runtime::RemoteObjectId&, const String& functionDeclaration, RefPtr<JSON::Array>&& arguments, std::optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& emulateUserGesture, std::optional<bool>&& awaitPromise, Ref<CallFunctionOnCallback>&&) override;
+ Protocol::ErrorStringOr<void> addBinding(const String& name) override;
Protocol::ErrorStringOr<void> releaseObject(const Protocol::Runtime::RemoteObjectId&) final;
Protocol::ErrorStringOr<Ref<Protocol::Runtime::ObjectPreview>> getPreview(const Protocol::Runtime::RemoteObjectId&) final;
Protocol::ErrorStringOr<std::tuple<Ref<JSON::ArrayOf<Protocol::Runtime::PropertyDescriptor>>, RefPtr<JSON::ArrayOf<Protocol::Runtime::InternalPropertyDescriptor>>>> getProperties(const Protocol::Runtime::RemoteObjectId&, std::optional<bool>&& ownProperties, std::optional<int>&& fetchStart, std::optional<int>&& fetchCount, std::optional<bool>&& generatePreview) final;
diff --git a/Source/JavaScriptCore/inspector/agents/InspectorTargetAgent.cpp b/Source/JavaScriptCore/inspector/agents/InspectorTargetAgent.cpp
index 38d8aa7a256deab40470631c8f2231d9d34613e1..6c7f776c0b7f2ab7a1a3870ebaa42a3da5ad794c 100644
--- a/Source/JavaScriptCore/inspector/agents/InspectorTargetAgent.cpp
+++ b/Source/JavaScriptCore/inspector/agents/InspectorTargetAgent.cpp
@@ -90,6 +90,34 @@ Protocol::ErrorStringOr<void> InspectorTargetAgent::sendMessageToTarget(const St
return { };
}
+Protocol::ErrorStringOr<void> InspectorTargetAgent::activate(const String& targetId)
+{
+ InspectorTarget* target = m_targets.get(targetId);
+ if (!target)
+ return makeUnexpected("Missing target for given targetId"_s);
+
+ String errorString;
+ target->activate(errorString);
+ if (!errorString.isEmpty())
+ return makeUnexpected(errorString);
+
+ return { };
+}
+
+Protocol::ErrorStringOr<void> InspectorTargetAgent::close(const String& targetId, std::optional<bool>&& runBeforeUnload)
+{
+ InspectorTarget* target = m_targets.get(targetId);
+ if (!target)
+ return makeUnexpected("Missing target for given targetId"_s);
+
+ String errorString;
+ target->close(errorString, runBeforeUnload && *runBeforeUnload);
+ if (!errorString.isEmpty())
+ return makeUnexpected(errorString);
+
+ return { };
+}
+
void InspectorTargetAgent::sendMessageFromTargetToFrontend(const String& targetId, const String& message)
{
m_frontendDispatcher->dispatchMessageFromTarget(targetId, message);
@@ -147,7 +175,17 @@ void InspectorTargetAgent::targetDestroyed(InspectorTarget& target)
if (!m_isConnected)
return;
- m_frontendDispatcher->targetDestroyed(target.identifier());
+ m_frontendDispatcher->targetDestroyed(target.identifier(), false);
+}
+
+void InspectorTargetAgent::targetCrashed(InspectorTarget& target)
+{
+ m_targets.remove(target.identifier());
+
+ if (!m_isConnected)
+ return;
+
+ m_frontendDispatcher->targetDestroyed(target.identifier(), true);
}
void InspectorTargetAgent::didCommitProvisionalTarget(const String& oldTargetID, const String& committedTargetID)
diff --git a/Source/JavaScriptCore/inspector/agents/InspectorTargetAgent.h b/Source/JavaScriptCore/inspector/agents/InspectorTargetAgent.h
index 0b7d732f036fce96b01bd06f4c47f5d471a0ab38..a9efea4bec66aa68966c99d9e77f8a36f7f7205a 100644
--- a/Source/JavaScriptCore/inspector/agents/InspectorTargetAgent.h
+++ b/Source/JavaScriptCore/inspector/agents/InspectorTargetAgent.h
@@ -53,8 +53,11 @@ public:
Protocol::ErrorStringOr<void> setPauseOnStart(bool) final;
Protocol::ErrorStringOr<void> resume(const String& targetId) final;
Protocol::ErrorStringOr<void> sendMessageToTarget(const String& targetId, const String& message) final;
+ Protocol::ErrorStringOr<void> activate(const String& targetId) override;
+ Protocol::ErrorStringOr<void> close(const String& targetId, std::optional<bool>&& runBeforeUnload) override;
// Target lifecycle.
+ void targetCrashed(InspectorTarget&);
void targetCreated(InspectorTarget&);
void targetDestroyed(InspectorTarget&);
void didCommitProvisionalTarget(const String& oldTargetID, const String& committedTargetID);
@@ -62,6 +65,9 @@ public:
// Target messages.
void sendMessageFromTargetToFrontend(const String& targetId, const String& message);
+ bool shouldPauseOnStart() const { return m_shouldPauseOnStart; }
+ bool isConnected() { return m_isConnected; }
+
private:
// FrontendChannel
FrontendChannel::ConnectionType connectionType() const;
diff --git a/Source/JavaScriptCore/inspector/protocol/DOM.json b/Source/JavaScriptCore/inspector/protocol/DOM.json
index 0b41f31605a2407fd068e28eaec60dbeabefd4d8..80fc7f1351949447c1f988641a26bcf695d589f2 100644
--- a/Source/JavaScriptCore/inspector/protocol/DOM.json
+++ b/Source/JavaScriptCore/inspector/protocol/DOM.json
@@ -80,6 +80,16 @@
{ "name": "value", "type": "string", "description": "The value that is resolved to with this data binding relationship." }
]
},
+ {
+ "id": "Rect",
+ "type": "object",
+ "properties": [
+ { "name": "x", "type": "integer", "description": "X coordinate" },
+ { "name": "y", "type": "integer", "description": "Y coordinate" },
+ { "name": "width", "type": "integer", "description": "Rectangle width" },
+ { "name": "height", "type": "integer", "description": "Rectangle height" }
+ ]
+ },
{
"id": "EventListener",
"type": "object",
@@ -740,7 +750,10 @@
"description": "Resolves JavaScript node object for given node id.",
"targetTypes": ["page"],
"parameters": [
- { "name": "nodeId", "$ref": "NodeId", "description": "Id of the node to resolve." },
+ { "name": "nodeId", "$ref": "NodeId", "optional": true, "description": "Id of the node to resolve." },
+ { "name": "objectId", "$ref": "Runtime.RemoteObjectId", "optional": true, "description": "Source element handle." },
+ { "name": "frameId", "$ref": "Network.FrameId", "optional": true, "description": "Id of the frame to resolve the owner element." },
+ { "name": "executionContextId", "$ref": "Runtime.ExecutionContextId", "optional": true, "description": "Specifies in which execution context to adopt to." },
{ "name": "objectGroup", "type": "string", "optional": true, "description": "Symbolic group name that can be used to release multiple objects." }
],
"returns": [
@@ -817,6 +830,46 @@
"returns": [
{ "name": "mediaStats", "$ref": "MediaStats", "description": "An interleaved array of node attribute names and values." }
]
+ },
+ {
+ "name": "describeNode",
+ "description": "Returns node description.",
+ "parameters": [
+ { "name": "objectId", "$ref": "Runtime.RemoteObjectId", "description": "JavaScript object id of the node wrapper." }
+ ],
+ "returns": [
+ { "name": "contentFrameId", "$ref": "Network.FrameId", "optional": true, "description": "Frame ID for frame owner elements." },
+ { "name": "ownerFrameId", "$ref": "Network.FrameId", "optional": true, "description": "ID of the owning frame element." }
+ ]
+ },
+ {
+ "name": "scrollIntoViewIfNeeded",
+ "description": "Scrolls the given rect into view if not already in the viewport.",
+ "parameters": [
+ { "name": "objectId", "$ref": "Runtime.RemoteObjectId", "description": "JavaScript object id of the node wrapper." },
+ { "name": "rect", "$ref": "Rect", "optional": true, "description": "Rect relative to the node's border box, in CSS pixels." }
+ ]
+ },
+ {
+ "name": "getContentQuads",
+ "description": "Returns quads that describe node position on the page. This method\nmight return multiple quads for inline nodes.",
+ "parameters": [
+ { "name": "objectId", "$ref": "Runtime.RemoteObjectId", "description": "JavaScript object id of the node wrapper." }
+ ],
+ "returns": [
+ {
+ "name": "quads", "type": "array", "items": { "$ref": "Quad" }, "description": "Quads that describe node layout relative to viewport."
+ }
+ ]
+ },
+ {
+ "name": "setInputFiles",
+ "description": "Sets input files for given <input type=file>",
+ "parameters": [
+ { "name": "objectId", "$ref": "Runtime.RemoteObjectId", "description": "Input element handle." },
+ { "name": "paths", "type": "array", "items": { "type": "string" }, "description": "File paths to set" }
+ ],
+ "async": true
}
],
"events": [
diff --git a/Source/JavaScriptCore/inspector/protocol/Dialog.json b/Source/JavaScriptCore/inspector/protocol/Dialog.json
new file mode 100644
index 0000000000000000000000000000000000000000..79edea03fed4e9be5da96e1275e182a479cb7a0a
--- /dev/null
+++ b/Source/JavaScriptCore/inspector/protocol/Dialog.json
@@ -0,0 +1,36 @@
+{
+ "domain": "Dialog",
+ "description": "Actions and events related to alert boxes.",
+ "availability": ["web"],
+ "types": [
+ ],
+ "commands": [
+ {
+ "name": "enable",
+ "description": "Enables dialog domain notifications."
+ },
+ {
+ "name": "disable",
+ "description": "Disables dialog domain notifications."
+ },
+ {
+ "name": "handleJavaScriptDialog",
+ "description": "Accepts or dismisses a JavaScript initiated dialog (alert, confirm, prompt, or onbeforeunload).",
+ "parameters": [
+ { "name": "accept", "type": "boolean", "description": "Whether to accept or dismiss the dialog."},
+ { "name": "promptText", "optional": true, "type": "string", "description": "The text to enter into the dialog prompt before accepting. Used only if this is a prompt dialog."}
+ ]
+ }
+ ],
+ "events": [
+ {
+ "name": "javascriptDialogOpening",
+ "description": "Fired when a JavaScript initiated dialog (alert, confirm, prompt, or onbeforeunload) is about to open.",
+ "parameters": [
+ { "name": "type", "type": "string", "description": "Dialog type."},
+ { "name": "message", "type": "string", "description": "Message that will be displayed by the dialog."},
+ { "name": "defaultPrompt", "optional": true, "type": "string", "description": "Default dialog prompt."}
+ ]
+ }
+ ]
+}
diff --git a/Source/JavaScriptCore/inspector/protocol/Emulation.json b/Source/JavaScriptCore/inspector/protocol/Emulation.json
new file mode 100644
index 0000000000000000000000000000000000000000..8377901cb3ad75c29532a1f0f547efb53558a327
--- /dev/null
+++ b/Source/JavaScriptCore/inspector/protocol/Emulation.json
@@ -0,0 +1,59 @@
+{
+ "domain": "Emulation",
+ "availability": ["web"],
+ "commands": [
+ {
+ "name": "setDeviceMetricsOverride",
+ "description": "Overrides device metrics with provided values.",
+ "async": true,
+ "parameters": [
+ { "name": "width", "type": "integer" },
+ { "name": "height", "type": "integer" },
+ { "name": "fixedLayout", "type": "boolean" },
+ { "name": "deviceScaleFactor", "type": "number", "optional": true }
+ ]
+ },
+ {
+ "name": "setJavaScriptEnabled",
+ "description": "Allows to disable script execution for the page.",
+ "parameters": [
+ { "name": "enabled", "type": "boolean" }
+ ]
+ },
+ {
+ "name": "setAuthCredentials",
+ "description": "Credentials to use during HTTP authentication.",
+ "parameters": [
+ { "name": "username", "type": "string", "optional": true },
+ { "name": "password", "type": "string", "optional": true },
+ { "name": "origin", "type": "string", "optional": true }
+ ]
+ },
+ {
+ "name": "setActiveAndFocused",
+ "description": "Makes page focused for test.",
+ "parameters": [
+ { "name": "active", "type": "boolean", "optional": true }
+ ]
+ },
+ {
+ "name": "grantPermissions",
+ "parameters": [
+ { "name": "origin", "type": "string" },
+ { "name": "permissions", "type": "array", "items": { "type": "string" } }
+ ],
+ "description": "Overrides the permissions."
+ },
+ {
+ "name": "resetPermissions",
+ "description": "Clears permission overrides."
+ },
+ {
+ "name": "setOrientationOverride",
+ "description": "Overrides window.orientation with provided value.",
+ "parameters": [
+ { "name": "angle", "type": "integer", "optional": true }
+ ]
+ }
+ ]
+}
diff --git a/Source/JavaScriptCore/inspector/protocol/Input.json b/Source/JavaScriptCore/inspector/protocol/Input.json
new file mode 100644
index 0000000000000000000000000000000000000000..1c43b476603325fa412bcfded9163e7a00aebbfa
--- /dev/null
+++ b/Source/JavaScriptCore/inspector/protocol/Input.json
@@ -0,0 +1,264 @@
+{
+ "domain": "Input",
+ "availability": ["web"],
+ "types": [
+ {
+ "id": "TimeSinceEpoch",
+ "description": "UTC time in seconds, counted from January 1, 1970.",
+ "type": "number"
+ },
+ {
+ "id": "TouchPoint",
+ "type": "object",
+ "description": "Touch point.",
+ "properties": [
+ { "name": "x", "type": "integer", "description": "X coordinate of the event relative to the main frame's viewport in CSS pixels." },
+ { "name": "y", "type": "integer", "description": "Y coordinate of the event relative to the main frame's viewport in CSS pixels." },
+ { "name": "id", "type": "integer", "description": "Identifier used to track touch sources between events, must be unique within an event." }
+ ]
+ }
+ ],
+ "commands": [
+ {
+ "name": "dispatchKeyEvent",
+ "description": "Dispatches a key event to the page.",
+ "async": true,
+ "parameters": [
+ {
+ "name": "type",
+ "description": "Type of the key event.",
+ "type": "string",
+ "enum": [
+ "keyDown",
+ "keyUp"
+ ]
+ },
+ {
+ "name": "modifiers",
+ "description": "Bit field representing pressed modifier keys. (default: 0).",
+ "optional": true,
+ "type": "integer"
+ },
+ {
+ "name": "text",
+ "description": "Text as generated by processing a virtual key code with a keyboard layout. Not needed for\nfor `keyUp` and `rawKeyDown` events (default: \"\")",
+ "optional": true,
+ "type": "string"
+ },
+ {
+ "name": "unmodifiedText",
+ "description": "Text that would have been generated by the keyboard if no modifiers were pressed (except for\nshift). Useful for shortcut (accelerator) key handling (default: \"\").",
+ "optional": true,
+ "type": "string"
+ },
+ {
+ "name": "code",
+ "description": "Unique DOM defined string value for each physical key (e.g., 'KeyA') (default: \"\").",
+ "optional": true,
+ "type": "string"
+ },
+ {
+ "name": "key",
+ "description": "Unique DOM defined string value describing the meaning of the key in the context of active\nmodifiers, keyboard layout, etc (e.g., 'AltGr') (default: \"\").",
+ "optional": true,
+ "type": "string"
+ },
+ {
+ "name": "windowsVirtualKeyCode",
+ "description": "Windows virtual key code (default: 0).",
+ "optional": true,
+ "type": "integer"
+ },
+ {
+ "name": "nativeVirtualKeyCode",
+ "description": "Native virtual key code (default: 0).",
+ "optional": true,
+ "type": "integer"
+ },
+ {
+ "name": "autoRepeat",
+ "description": "Whether the event was generated from auto repeat (default: false).",
+ "optional": true,
+ "type": "boolean"
+ },
+ {
+ "name": "isKeypad",
+ "description": "Whether the event was generated from the keypad (default: false).",
+ "optional": true,
+ "type": "boolean"
+ },
+ {
+ "name": "isSystemKey",
+ "description": "Whether the event was a system key event (default: false).",
+ "optional": true,
+ "type": "boolean"
+ },
+ {
+ "name": "macCommands",
+ "description": "Mac editing commands associated with this key",
+ "type": "array",
+ "optional": true,
+ "items": {
+ "type": "string"
+ }
+ }
+ ]
+ },
+ {
+ "name": "dispatchMouseEvent",
+ "description": "Dispatches a mouse event to the page.",
+ "async": true,
+ "parameters": [
+ {
+ "name": "type",
+ "description": "Type of the mouse event.",
+ "type": "string",
+ "enum": [ "move", "down", "up", "wheel"]
+ },
+ {
+ "name": "x",
+ "description": "X coordinate of the event relative to the main frame's viewport in CSS pixels.",
+ "type": "integer"
+ },
+ {
+ "name": "y",
+ "description": "Y coordinate of the event relative to the main frame's viewport in CSS pixels. 0 refers to\nthe top of the viewport and Y increases as it proceeds towards the bottom of the viewport.",
+ "type": "integer"
+ },
+ {
+ "name": "modifiers",
+ "description": "Bit field representing pressed modifier keys. Alt=1, Ctrl=2, Meta/Command=4, Shift=8\n(default: 0).",
+ "optional": true,
+ "type": "integer"
+ },
+ {
+ "name": "button",
+ "description": "Mouse button (default: \"none\").",
+ "optional": true,
+ "type": "string",
+ "enum": [
+ "none",
+ "left",
+ "middle",
+ "right",
+ "back",
+ "forward"
+ ]
+ },
+ {
+ "name": "buttons",
+ "description": "A number indicating which buttons are pressed on the mouse when a mouse event is triggered.\nLeft=1, Right=2, Middle=4, Back=8, Forward=16, None=0.",
+ "optional": true,
+ "type": "integer"
+ },
+ {
+ "name": "clickCount",
+ "description": "Number of times the mouse button was clicked (default: 0).",
+ "optional": true,
+ "type": "integer"
+ },
+ {
+ "name": "deltaX",
+ "description": "X delta in CSS pixels for mouse wheel event (default: 0).",
+ "optional": true,
+ "type": "integer"
+ },
+ {
+ "name": "deltaY",
+ "description": "Y delta in CSS pixels for mouse wheel event (default: 0).",
+ "optional": true,
+ "type": "integer"
+ }
+ ]
+ },
+ {
+ "name": "dispatchWheelEvent",
+ "description": "Dispatches a wheel event to the page.",
+ "async": true,
+ "parameters": [
+ {
+ "name": "x",
+ "description": "X coordinate of the event relative to the main frame's viewport in CSS pixels.",
+ "type": "integer"
+ },
+ {
+ "name": "y",
+ "description": "Y coordinate of the event relative to the main frame's viewport in CSS pixels. 0 refers to\nthe top of the viewport and Y increases as it proceeds towards the bottom of the viewport.",
+ "type": "integer"
+ },
+ {
+ "name": "modifiers",
+ "description": "Bit field representing pressed modifier keys. Alt=1, Ctrl=2, Meta/Command=4, Shift=8\n(default: 0).",
+ "optional": true,
+ "type": "integer"
+ },
+ {
+ "name": "deltaX",
+ "description": "X delta in CSS pixels for mouse wheel event (default: 0).",
+ "optional": true,
+ "type": "integer"
+ },
+ {
+ "name": "deltaY",
+ "description": "Y delta in CSS pixels for mouse wheel event (default: 0).",
+ "optional": true,
+ "type": "integer"
+ }
+ ]
+ },
+ {
+ "name": "dispatchTapEvent",
+ "description": "Dispatches a tap event to the page.",
+ "async": true,
+ "parameters": [
+ {
+ "name": "x",
+ "description": "X coordinate of the event relative to the main frame's viewport in CSS pixels.",
+ "type": "integer"
+ },
+ {
+ "name": "y",
+ "description": "Y coordinate of the event relative to the main frame's viewport in CSS pixels. 0 refers to\nthe top of the viewport and Y increases as it proceeds towards the bottom of the viewport.",
+ "type": "integer"
+ },
+ {
+ "name": "modifiers",
+ "description": "Bit field representing pressed modifier keys. Alt=1, Ctrl=2, Meta/Command=4, Shift=8\n(default: 0).",
+ "optional": true,
+ "type": "integer"
+ }
+ ]
+ },
+ {
+ "name": "dispatchTouchEvent",
+ "description": "Dispatches a touch event to the page.",
+ "async": true,
+ "parameters": [
+ {
+ "name": "type",
+ "description": "Type of the touch event.",
+ "type": "string",
+ "enum": [
+ "touchStart",
+ "touchMove",
+ "touchEnd",
+ "touchCancel"
+ ]
+ },
+ {
+ "name": "modifiers",
+ "description": "Bit field representing pressed modifier keys. Alt=1, Ctrl=2, Meta/Command=4, Shift=8\n(default: 0).",
+ "optional": true,
+ "type": "integer"
+ },
+ {
+ "name": "touchPoints",
+ "description": "List of touch points",
+ "type": "array",
+ "optional": true,
+ "items": { "$ref": "TouchPoint" }
+ }
+ ]
+ }
+ ]
+}
diff --git a/Source/JavaScriptCore/inspector/protocol/Network.json b/Source/JavaScriptCore/inspector/protocol/Network.json
index 29a3ef3294dcdf9e9559b665e9f1bb9a5727cf4b..b6b90f356dd6b7de7752ab4296069c8f07b4de38 100644
--- a/Source/JavaScriptCore/inspector/protocol/Network.json
+++ b/Source/JavaScriptCore/inspector/protocol/Network.json
@@ -360,6 +360,13 @@
"parameters": [
{ "name": "bytesPerSecondLimit", "type": "integer", "optional": true, "description": "Limits the bytes per second of requests if positive. Removes any limits if zero or not provided." }
]
+ },
+ {
+ "name": "setEmulateOfflineState",
+ "description": "Emulate offline state overriding the actual state.",
+ "parameters": [
+ { "name": "offline", "type": "boolean", "description": "True to emulate offline." }
+ ]
}
],
"events": [
diff --git a/Source/JavaScriptCore/inspector/protocol/Page.json b/Source/JavaScriptCore/inspector/protocol/Page.json
index 374b26c3ee9acf39aeb23fb60821b39d0afd971c..8843241e3e669c2d7537adb11e83325f216febba 100644
--- a/Source/JavaScriptCore/inspector/protocol/Page.json
+++ b/Source/JavaScriptCore/inspector/protocol/Page.json
@@ -20,7 +20,15 @@
"ScriptEnabled",
"ShowDebugBorders",
"ShowRepaintCounter",
- "WebSecurityEnabled"
+ "WebSecurityEnabled",
+ "DeviceOrientationEventEnabled",
+ "SpeechRecognitionEnabled",
+ "PointerLockEnabled",
+ "NotificationsEnabled",
+ "FullScreenEnabled",
+ "InputTypeMonthEnabled",
+ "InputTypeWeekEnabled",
+ "FixedBackgroundsPaintRelativeToDocument"
]
},
{
@@ -62,6 +70,12 @@
"enum": ["None", "Lax", "Strict"],
"description": "Same-Site policy of a cookie."
},
+ {
+ "id": "ForcedColors",
+ "type": "string",
+ "enum": ["Active", "None"],
+ "description": "Page forced-colors media query override."
+ },
{
"id": "Frame",
"type": "object",
@@ -126,6 +140,16 @@
{ "name": "sameSite", "$ref": "CookieSameSitePolicy", "description": "Cookie Same-Site policy." },
{ "name": "partitionKey", "type": "string", "optional": true, "description": "Cookie partition key. If null and partitioned property is true, then key must be computed." }
]
+ },
+ {
+ "id": "Insets",
+ "type": "object",
+ "properties": [
+ { "name": "top", "type": "number" },
+ { "name": "right", "type": "number" },
+ { "name": "bottom", "type": "number" },
+ { "name": "left", "type": "number" }
+ ]
}
],
"commands": [
@@ -145,6 +169,14 @@
{ "name": "revalidateAllResources", "type": "boolean", "optional": true, "description": "If true, all cached subresources will be revalidated when the main resource loads. Otherwise, only expired cached subresources will be revalidated (the default behavior for most WebKit clients)." }
]
},
+ {
+ "name": "goBack",
+ "description": "Goes back in the history."
+ },
+ {
+ "name": "goForward",
+ "description": "Goes forward in the history."
+ },
{
"name": "overrideUserAgent",
"description": "Override's the user agent of the inspected page",
@@ -153,6 +185,14 @@
{ "name": "value", "type": "string", "optional": true, "description": "Value to override the user agent with. If this value is not provided, the override is removed. Overrides are removed when Web Inspector closes/disconnects." }
]
},
+ {
+ "name": "overridePlatform",
+ "description": "Override's the navigator.platform of the inspected page",
+ "targetTypes": ["page"],
+ "parameters": [
+ { "name": "value", "type": "string", "optional": true, "description": "Value to override the platform with. If this value is not provided, the override is removed. Overrides are removed when Web Inspector closes/disconnects." }
+ ]
+ },
{
"name": "overrideSetting",
"description": "Allows the frontend to override the inspected page's settings.",
@@ -277,6 +317,28 @@
{ "name": "media", "type": "string", "description": "Media type to emulate. Empty string disables the override." }
]
},
+ {
+ "name": "setForcedColors",
+ "description": "Forces the forced-colors media query for the page.",
+ "targetTypes": ["page"],
+ "parameters": [
+ { "name": "forcedColors", "$ref": "ForcedColors", "optional": true }
+ ]
+ },
+ {
+ "name": "setTimeZone",
+ "description": "Enables time zone emulation.",
+ "parameters": [
+ { "name": "timeZone", "type": "string", "optional": true }
+ ]
+ },
+ {
+ "name": "setTouchEmulationEnabled",
+ "description": "Enables touch events on platforms that lack them.",
+ "parameters": [
+ {"name": "enabled", "type": "boolean", "description": "Whether touch should be enabled."}
+ ]
+ },
{
"name": "snapshotNode",
"description": "Capture a snapshot of the specified node that does not include unrelated layers.",
@@ -297,7 +359,8 @@
{ "name": "y", "type": "integer", "description": "Y coordinate" },
{ "name": "width", "type": "integer", "description": "Rectangle width" },
{ "name": "height", "type": "integer", "description": "Rectangle height" },
- { "name": "coordinateSystem", "$ref": "CoordinateSystem", "description": "Indicates the coordinate system of the supplied rectangle." }
+ { "name": "coordinateSystem", "$ref": "CoordinateSystem", "description": "Indicates the coordinate system of the supplied rectangle." },
+ { "name": "omitDeviceScaleFactor", "type": "boolean", "optional": true, "description": "By default, screenshot is inflated by device scale factor to avoid blurry image. This flag disables it." }
],
"returns": [
{ "name": "dataURL", "type": "string", "description": "Base64-encoded image data (PNG)." }
@@ -315,12 +378,54 @@
{
"name": "setScreenSizeOverride",
"description": "Overrides screen size exposed to DOM and used in media queries for testing with provided values.",
- "condition": "!(defined(WTF_PLATFORM_COCOA) && WTF_PLATFORM_COCOA)",
"targetTypes": ["page"],
"parameters": [
{ "name": "width", "type": "integer", "description": "Screen width", "optional": true },
{ "name": "height", "type": "integer", "description": "Screen height", "optional": true }
]
+ },
+ {
+ "name": "insertText",
+ "description": "Insert text into the current selection of the page.",
+ "parameters": [
+ { "name": "text", "type": "string", "description": "Text to insert." }
+ ]
+ },
+ {
+ "name": "setInterceptFileChooserDialog",
+ "description": "Intercepts file chooser dialog",
+ "parameters": [
+ { "name": "enabled", "type": "boolean", "description": "True to enable." }
+ ]
+ },
+ {
+ "name": "setDefaultBackgroundColorOverride",
+ "description": "Sets or clears an override of the default background color of the frame. This override is used if the content does not specify one.",
+ "parameters": [
+ { "name": "color", "$ref": "DOM.RGBAColor", "optional": true, "description": "RGBA of the default background color. If not specified, any existing override will be cleared." }
+ ]
+ },
+ {
+ "name": "createUserWorld",
+ "description": "Creates an user world for every loaded frame.",
+ "parameters": [
+ { "name": "name", "type": "string", "description": "Isolated world name, will be used as an execution context name." }
+ ]
+ },
+ {
+ "name": "setBypassCSP",
+ "description": "Enable page Content Security Policy by-passing.",
+ "parameters": [
+ { "name": "enabled", "type": "boolean", "description": "Whether to bypass page CSP." }
+ ]
+ },
+ {
+ "name": "crash",
+ "description": "Crashes the page process"
+ },
+ {
+ "name": "updateScrollingState",
+ "description": "Ensures that the scroll regions are up to date."
}
],
"events": [
@@ -328,14 +433,16 @@
"name": "domContentEventFired",
"targetTypes": ["page"],
"parameters": [
- { "name": "timestamp", "type": "number" }
+ { "name": "timestamp", "type": "number" },
+ { "name": "frameId", "$ref": "Network.FrameId", "description": "Id of the frame that has fired DOMContentLoaded event." }
]
},
{
"name": "loadEventFired",
"targetTypes": ["page"],
"parameters": [
- { "name": "timestamp", "type": "number" }
+ { "name": "timestamp", "type": "number" },
+ { "name": "frameId", "$ref": "Network.FrameId", "description": "Id of the frame that has fired load event." }
]
},
{
@@ -345,6 +452,14 @@
{ "name": "frame", "$ref": "Frame", "description": "Frame object." }
]
},
+ {
+ "name": "frameAttached",
+ "description": "Fired when frame has been attached to its parent.",
+ "parameters": [
+ { "name": "frameId", "$ref": "Network.FrameId", "description": "Id of the frame that has been detached." },
+ { "name": "parentFrameId", "$ref": "Network.FrameId", "optional": true, "description": "Parent frame id if non-root." }
+ ]
+ },
{
"name": "frameDetached",
"description": "Fired when frame has been detached from its parent.",
@@ -353,6 +468,22 @@
{ "name": "frameId", "$ref": "Network.FrameId", "description": "Id of the frame that has been detached." }
]
},
+ {
+ "name": "navigatedWithinDocument",
+ "description": "Fired when same-document navigation happens, e.g. due to history API usage or anchor navigation.",
+ "parameters": [
+ {
+ "name": "frameId",
+ "description": "Id of the frame.",
+ "$ref": "Network.FrameId"
+ },
+ {
+ "name": "url",
+ "description": "Frame's new url.",
+ "type": "string"
+ }
+ ]
+ },
{
"name": "defaultUserPreferencesDidChange",
"description": "Fired when the default value of a user preference changes at the system level.",
@@ -360,6 +491,42 @@
"parameters": [
{ "name": "preferences", "type": "array", "items": { "$ref": "UserPreference" }, "description": "List of user preferences that can be overriden and their new system (default) values." }
]
+ },
+ {
+ "name": "willCheckNavigationPolicy",
+ "description": "Fired when page is about to check policy for newly triggered navigation.",
+ "parameters": [
+ {
+ "name": "frameId",
+ "description": "Id of the frame.",
+ "$ref": "Network.FrameId"
+ }
+ ]
+ },
+ {
+ "name": "didCheckNavigationPolicy",
+ "description": "Fired when page has received navigation policy decision.",
+ "parameters": [
+ {
+ "name": "frameId",
+ "description": "Id of the frame.",
+ "$ref": "Network.FrameId"
+ },
+ {
+ "name": "cancel",
+ "description": "True if the navigation will not continue in this frame.",
+ "type": "boolean",
+ "optional": true
+ }
+ ]
+ },
+ {
+ "name": "fileChooserOpened",
+ "description": "Fired when the page shows file chooser for it's <input type=file>.",
+ "parameters": [
+ { "name": "frameId", "$ref": "Network.FrameId", "description": "Frame where file chooser is opened." },
+ { "name": "element", "$ref": "Runtime.RemoteObject", "description": "Input element." }
+ ]
}
]
}
diff --git a/Source/JavaScriptCore/inspector/protocol/Playwright.json b/Source/JavaScriptCore/inspector/protocol/Playwright.json
new file mode 100644
index 0000000000000000000000000000000000000000..ade3e257b614f210ba5dcc024df81642425f8d51
--- /dev/null
+++ b/Source/JavaScriptCore/inspector/protocol/Playwright.json
@@ -0,0 +1,310 @@
+{
+ "domain": "Playwright",
+ "availability": ["web"],
+ "types": [
+ {
+ "id": "ContextID",
+ "type": "string",
+ "description": "Id of Browser context."
+ },
+ {
+ "id": "PageProxyID",
+ "type": "string",
+ "description": "Id of WebPageProxy."
+ },
+ {
+ "id": "CookieSameSitePolicy",
+ "type": "string",
+ "enum": ["None", "Lax", "Strict"],
+ "description": "Same-Site policy of a cookie."
+ },
+ {
+ "id": "Cookie",
+ "type": "object",
+ "description": "Cookie object",
+ "properties": [
+ { "name": "name", "type": "string", "description": "Cookie name." },
+ { "name": "value", "type": "string", "description": "Cookie value." },
+ { "name": "domain", "type": "string", "description": "Cookie domain." },
+ { "name": "path", "type": "string", "description": "Cookie path." },
+ { "name": "expires", "type": "number", "description": "Cookie expires." },
+ { "name": "httpOnly", "type": "boolean", "description": "True if cookie is http-only." },
+ { "name": "secure", "type": "boolean", "description": "True if cookie is secure." },
+ { "name": "session", "type": "boolean", "description": "True if cookie is session cookie." },
+ { "name": "sameSite", "$ref": "CookieSameSitePolicy", "description": "Cookie Same-Site policy." }
+ ]
+ },
+ {
+ "id": "SetCookieParam",
+ "type": "object",
+ "description": "Cookie object",
+ "properties": [
+ { "name": "name", "type": "string", "description": "Cookie name." },
+ { "name": "value", "type": "string", "description": "Cookie value." },
+ { "name": "domain", "type": "string", "description": "Cookie domain." },
+ { "name": "path", "type": "string", "description": "Cookie path." },
+ { "name": "expires", "type": "number", "optional": true, "description": "Cookie expires." },
+ { "name": "httpOnly", "type": "boolean", "optional": true, "description": "True if cookie is http-only." },
+ { "name": "secure", "type": "boolean", "optional": true, "description": "True if cookie is secure." },
+ { "name": "session", "type": "boolean", "optional": true, "description": "True if cookie is session cookie." },
+ { "name": "sameSite", "$ref": "CookieSameSitePolicy", "optional": true, "description": "Cookie Same-Site policy." }
+ ]
+ },
+ {
+ "id": "NameValue",
+ "type": "object",
+ "description": "Name-value pair",
+ "properties": [
+ { "name": "name", "type": "string" },
+ { "name": "value", "type": "string" }
+ ]
+ },
+ {
+ "id": "OriginStorage",
+ "type": "object",
+ "description": "Origin object",
+ "properties": [
+ { "name": "origin", "type": "string", "description": "Origin." },
+ { "name": "items", "type": "array", "items": { "$ref": "NameValue" }, "description": "Storage entries." }
+ ]
+ },
+ {
+ "id": "Geolocation",
+ "type": "object",
+ "description": "Geolocation",
+ "properties": [
+ { "name": "timestamp", "type": "number", "description": "Mock latitude" },
+ { "name": "latitude", "type": "number", "description": "Mock latitude" },
+ { "name": "longitude", "type": "number", "description": "Mock longitude" },
+ { "name": "accuracy", "type": "number", "description": "Mock accuracy" }
+ ]
+ }
+ ],
+ "commands": [
+ {
+ "name": "enable"
+ },
+ {
+ "name": "disable"
+ },
+ {
+ "name": "getInfo",
+ "returns": [
+ { "name": "os", "type": "string", "description": "Name of the operating system where the browser is running (macOS, Linux or Windows)." }
+ ]
+ },
+ {
+ "name": "close",
+ "async": true,
+ "description": "Close browser."
+ },
+ {
+ "name": "createContext",
+ "description": "Creates new ephemeral browser context.",
+ "parameters": [
+ { "name": "proxyServer", "type": "string", "optional": true, "description": "Proxy server, similar to the one passed to --proxy-server" },
+ { "name": "proxyBypassList", "type": "string", "optional": true, "description": "Proxy bypass list, similar to the one passed to --proxy-bypass-list" },
+ { "name": "enableStoragePartitioning", "type": "boolean", "optional": true, "description": "Wether to use storage partitioning. Be default Playwright disables the partitioning." }
+ ],
+ "returns": [
+ { "name": "browserContextId", "$ref": "ContextID", "description": "Unique identifier of the context." }
+ ]
+ },
+ {
+ "name": "deleteContext",
+ "async": true,
+ "description": "Deletes browser context previously created with createContect. The command will automatically close all pages that use the context.",
+ "parameters": [
+ { "name": "browserContextId", "$ref": "ContextID", "description": "Identifier of the context to delete." }
+ ]
+ },
+ {
+ "name": "createPage",
+ "parameters": [
+ { "name": "browserContextId", "$ref": "ContextID", "optional": true, "description": "JSON Inspector Protocol message (command) to be dispatched on the backend." }
+ ],
+ "returns": [
+ { "name": "pageProxyId", "$ref": "PageProxyID", "description": "Unique identifier of the page proxy." }
+ ]
+ },
+ {
+ "name": "navigate",
+ "async": true,
+ "description": "Navigates current page to the given URL.",
+ "parameters": [
+ { "name": "url", "type": "string", "description": "URL to navigate the page to." },
+ { "name": "pageProxyId", "$ref": "PageProxyID", "description": "Unique identifier of the page proxy." },
+ { "name": "frameId", "$ref": "Network.FrameId", "optional": true, "description": "Id of the frame to navigate."},
+ { "name": "referrer", "type": "string", "optional": true, "description": "Referrer URL." }
+ ],
+ "returns": [
+ { "name": "loaderId", "$ref": "Network.LoaderId", "optional": true, "description": "Identifier of the loader associated with the navigation." }
+ ]
+ },
+ {
+ "name": "grantFileReadAccess",
+ "description": "Grants read access for the specified files to the web process of the page.",
+ "parameters": [
+ { "name": "pageProxyId", "$ref": "PageProxyID", "description": "Unique identifier of the page proxy." },
+ { "name": "paths", "type": "array", "items": { "type": "string" }, "description": "Id of the frame to navigate."}
+ ]
+ },
+ {
+ "name": "takePageScreenshot",
+ "description": "Capture a snapshot of the page.",
+ "async": true,
+ "parameters": [
+ { "name": "pageProxyId", "$ref": "PageProxyID", "description": "Unique identifier of the page proxy." },
+ { "name": "x", "type": "integer", "description": "X coordinate" },
+ { "name": "y", "type": "integer", "description": "Y coordinate" },
+ { "name": "width", "type": "integer", "description": "Rectangle width" },
+ { "name": "height", "type": "integer", "description": "Rectangle height" },
+ { "name": "omitDeviceScaleFactor", "type": "boolean", "optional": true, "description": "By default, screenshot is inflated by device scale factor to avoid blurry image. This flag disables it." }
+ ],
+ "returns": [
+ { "name": "dataURL", "type": "string", "description": "Base64-encoded image data (PNG)." }
+ ]
+ },
+ {
+ "name": "setIgnoreCertificateErrors",
+ "description": "Change whether all certificate errors should be ignored.",
+ "parameters": [
+ { "name": "browserContextId", "$ref": "ContextID", "optional": true, "description": "Browser context id." },
+ { "name": "ignore", "type": "boolean" }
+ ]
+ },
+ {
+ "name": "setPageZoomFactor",
+ "description": "Changes page zoom factor.",
+ "parameters": [
+ { "name": "pageProxyId", "$ref": "PageProxyID", "description": "Unique identifier of the page proxy." },
+ { "name": "zoomFactor", "type": "number" }
+ ]
+ },
+ {
+ "name": "getAllCookies",
+ "description": "Returns all cookies in the given browser context.",
+ "async": true,
+ "parameters": [
+ { "name": "browserContextId", "$ref": "ContextID", "optional": true, "description": "Browser context id." }
+ ],
+ "returns": [
+ { "name": "cookies", "type": "array", "items": { "$ref": "Cookie" }, "description": "Cookies." }
+ ]
+ },
+ {
+ "name": "setCookies",
+ "description": "Sets cookies in the given browser context.",
+ "async": true,
+ "parameters": [
+ { "name": "browserContextId", "$ref": "ContextID", "optional": true, "description": "Browser context id." },
+ { "name": "cookies", "type": "array", "items": { "$ref": "SetCookieParam" }, "description": "Cookies." }
+ ]
+ },
+ {
+ "name": "deleteAllCookies",
+ "description": "Deletes cookies in the given browser context.",
+ "async": true,
+ "parameters": [
+ { "name": "browserContextId", "$ref": "ContextID", "optional": true, "description": "Browser context id." }
+ ]
+ },
+ {
+ "name": "setGeolocationOverride",
+ "parameters": [
+ { "name": "browserContextId", "$ref": "ContextID", "optional": true, "description": "Browser context id." },
+ { "name": "geolocation", "$ref": "Geolocation", "optional": true, "description": "Geolocation to set, if missing emulates position unavailable." }
+ ],
+ "description": "Overrides the geolocation position or error."
+ },
+ {
+ "name": "setLanguages",
+ "description": "Allows to set locale language for context.",
+ "parameters": [
+ { "name": "languages", "type": "array", "items": { "type": "string" } },
+ { "name": "browserContextId", "$ref": "ContextID", "optional": true, "description": "Browser context id." }
+ ]
+ },
+ {
+ "name": "setDownloadBehavior",
+ "description": "Allows to override download behavior.",
+ "parameters": [
+ { "name": "behavior", "optional": true, "type": "string", "enum": ["allow", "deny"] },
+ { "name": "downloadPath", "optional": true, "type": "string" },
+ { "name": "browserContextId", "$ref": "ContextID", "optional": true, "description": "Browser context id." }
+ ]
+ },
+ {
+ "name": "cancelDownload",
+ "parameters": [
+ { "name": "uuid", "type": "string" }
+ ],
+ "description": "Cancels a current running download."
+ },
+ {
+ "name": "clearMemoryCache",
+ "description": "Clears browser memory cache.",
+ "async": true,
+ "parameters": [
+ { "name": "browserContextId", "$ref": "ContextID", "optional": true, "description": "Browser context id." }
+ ]
+ }
+ ],
+ "events": [
+ {
+ "name": "pageProxyCreated",
+ "parameters": [
+ { "name": "browserContextId", "$ref": "ContextID", "description": "Unique identifier of the context." },
+ { "name": "pageProxyId", "$ref": "PageProxyID" },
+ { "name": "openerId", "$ref": "PageProxyID", "optional": true, "description": "Unique identifier of the opening page. Only set for pages created by window.open()." }
+ ]
+ },
+ {
+ "name": "pageProxyDestroyed",
+ "parameters": [
+ { "name": "pageProxyId", "$ref": "PageProxyID" }
+ ]
+ },
+ {
+ "name": "provisionalLoadFailed",
+ "description": "Fired when provisional load fails.",
+ "parameters": [
+ { "name": "pageProxyId", "$ref": "PageProxyID", "description": "Unique identifier of the page proxy." },
+ { "name": "loaderId", "$ref": "Network.LoaderId", "description": "Identifier of the loader associated with the navigation." },
+ { "name": "error", "type": "string", "description": "Localized error string." }
+ ]
+ },
+ {
+ "name": "windowOpen",
+ "description": "Fired when page opens a new window.",
+ "parameters": [
+ { "name": "pageProxyId", "$ref": "PageProxyID", "description": "Unique identifier of the page proxy." },
+ { "name": "url", "type": "string" },
+ { "name": "windowFeatures", "type": "array", "items": { "type": "string" } }
+ ]
+ },
+ {
+ "name": "downloadCreated",
+ "parameters": [
+ { "name": "pageProxyId", "$ref": "PageProxyID", "description": "Unique identifier of the page proxy." },
+ { "name": "frameId", "$ref": "Network.FrameId", "description": "Unique identifier of the originating frame." },
+ { "name": "uuid", "type": "string" },
+ { "name": "url", "type": "string" }
+ ]
+ },
+ {
+ "name": "downloadFilenameSuggested",
+ "parameters": [
+ { "name": "uuid", "type": "string" },
+ { "name": "suggestedFilename", "type": "string" }
+ ]
+ },
+ {
+ "name": "downloadFinished",
+ "parameters": [
+ { "name": "uuid", "type": "string" },
+ { "name": "error", "type": "string" }
+ ]
+ }
+ ]
+}
diff --git a/Source/JavaScriptCore/inspector/protocol/Runtime.json b/Source/JavaScriptCore/inspector/protocol/Runtime.json
index b8c2c5b7c4a4411affc4d928521f809bc468673c..b0134b3d794df05a6386ed012715bb47519248f2 100644
--- a/Source/JavaScriptCore/inspector/protocol/Runtime.json
+++ b/Source/JavaScriptCore/inspector/protocol/Runtime.json
@@ -272,6 +272,13 @@
],
"async": true
},
+ {
+ "name": "addBinding",
+ "description": "Adds binding with the given name on the global objects of all inspected contexts. Each binding function call produces Runtime.bindingCalled event.",
+ "parameters": [
+ { "name": "name", "type": "string", "description": "Name of the bound function." }
+ ]
+ },
{
"name": "getPreview",
"description": "Returns a preview for the given object.",
@@ -408,6 +415,15 @@
"parameters": [
{ "name": "context", "$ref": "ExecutionContextDescription", "description": "A newly created execution context." }
]
- }
+ },
+ {
+ "name": "bindingCalled",
+ "description": "Issued when new execution context is created.",
+ "parameters": [
+ { "name": "contextId", "$ref": "ExecutionContextId", "description": "Id of the execution context where the binding was called." },
+ { "name": "name", "type": "string", "description": "Name of the bound function." },
+ { "name": "argument", "type": "string", "description": "String argument passed to the function." }
+ ]
+ }
]
}
diff --git a/Source/JavaScriptCore/inspector/protocol/Screencast.json b/Source/JavaScriptCore/inspector/protocol/Screencast.json
new file mode 100644
index 0000000000000000000000000000000000000000..8546676698ddb1e0606068dd99f66cc8cca6357f
--- /dev/null
+++ b/Source/JavaScriptCore/inspector/protocol/Screencast.json
@@ -0,0 +1,47 @@
+{
+ "domain": "Screencast",
+ "availability": ["web"],
+ "types": [
+ {
+ "id": "ScreencastId",
+ "type": "string",
+ "description": "Unique identifier of the screencast."
+ }
+ ],
+ "commands": [
+ {
+ "name": "startScreencast",
+ "description": "Starts screencast.",
+ "parameters": [
+ { "name": "width", "type": "integer" },
+ { "name": "height", "type": "integer" },
+ { "name": "toolbarHeight", "type": "integer" },
+ { "name": "quality", "type": "integer" }
+ ],
+ "returns": [
+ { "name": "generation", "type": "integer", "description": "Screencast session generation." }
+ ]
+ },
+ {
+ "name": "stopScreencast",
+ "description": "Stops screencast."
+ },
+ {
+ "name": "screencastFrameAck",
+ "parameters": [
+ { "name": "generation", "type": "integer", "description": "Screencast session generation" }
+ ]
+ }
+ ],
+ "events": [
+ {
+ "name": "screencastFrame",
+ "parameters": [
+ { "name": "data", "type": "string", "description": "Base64 data" },
+ { "name": "timestamp", "type": "number" },
+ { "name": "deviceWidth", "type": "integer" },
+ { "name": "deviceHeight", "type": "integer" }
+ ]
+ }
+ ]
+}
diff --git a/Source/JavaScriptCore/inspector/protocol/Target.json b/Source/JavaScriptCore/inspector/protocol/Target.json
index a861a83b87e4e7752e547b7070ec1ef26e1cc3e5..16d6ec26034758e127dcb599f5cb170823182470 100644
--- a/Source/JavaScriptCore/inspector/protocol/Target.json
+++ b/Source/JavaScriptCore/inspector/protocol/Target.json
@@ -10,7 +10,7 @@
"properties": [
{ "name": "targetId", "type": "string", "description": "Unique identifier for the target." },
{ "name": "type", "type": "string", "enum": ["page", "frame", "service-worker", "worker"] },
- { "name": "isProvisional", "type": "boolean", "optional": true, "description": "Whether this is a provisional page target." },
+ { "name": "isProvisional", "type": "boolean", "optional": true, "description": "True value indicates that this is a provisional page target i.e. Such target may be created when current page starts cross-origin navigation. Eventually each provisional target is either committed and swaps with the current target or gets destroyed, e.g. in case of load request failure." },
{ "name": "isPaused", "type": "boolean", "optional": true, "description": "Whether the target is paused on start and has to be explicitely resumed by inspector." }
]
}
@@ -37,6 +37,21 @@
{ "name": "targetId", "type": "string" },
{ "name": "message", "type": "string", "description": "JSON Inspector Protocol message (command) to be dispatched on the backend." }
]
+ },
+ {
+ "name": "activate",
+ "description": "Reveals the target on screen.",
+ "parameters": [
+ { "name": "targetId", "type": "string" }
+ ]
+ },
+ {
+ "name": "close",
+ "description": "Closes the target.",
+ "parameters": [
+ { "name": "targetId", "type": "string" },
+ { "name": "runBeforeUnload", "type": "boolean", "optional": true }
+ ]
}
],
"events": [
@@ -49,7 +64,8 @@
{
"name": "targetDestroyed",
"parameters": [
- { "name": "targetId", "type": "string" }
+ { "name": "targetId", "type": "string" },
+ { "name": "crashed", "type": "boolean" }
]
},
{
diff --git a/Source/JavaScriptCore/runtime/ConsoleClient.h b/Source/JavaScriptCore/runtime/ConsoleClient.h
index 6af957ee69490bad4443e90161adc2230c329105..1270e77b913578ba8965fdd30c4bd44687d891ab 100644
--- a/Source/JavaScriptCore/runtime/ConsoleClient.h
+++ b/Source/JavaScriptCore/runtime/ConsoleClient.h
@@ -74,6 +74,7 @@ public:
virtual void record(JSGlobalObject*, Ref<Inspector::ScriptArguments>&&) = 0;
virtual void recordEnd(JSGlobalObject*, Ref<Inspector::ScriptArguments>&&) = 0;
virtual void screenshot(JSGlobalObject*, Ref<Inspector::ScriptArguments>&&) = 0;
+ virtual void bindingCalled(JSGlobalObject*, const String& name, const String& arg) = 0;
private:
enum class ArgumentRequirement { No, Yes };
diff --git a/Source/ThirdParty/skia/CMakeLists.txt b/Source/ThirdParty/skia/CMakeLists.txt
index 607a4b0f761b0aadd3ca8b83e080519ad6f97715..609f5b23e6ebd2629a1313673d9d8ea5d6fc57b7 100644
--- a/Source/ThirdParty/skia/CMakeLists.txt
+++ b/Source/ThirdParty/skia/CMakeLists.txt
@@ -10,6 +10,8 @@ if (USE_SKIA_ENCODERS)
find_package(WebP REQUIRED COMPONENTS mux)
endif ()
+find_package(Threads REQUIRED)
+
if (ANDROID)
find_package(EXPAT REQUIRED)
endif ()
@@ -970,6 +972,7 @@ endif ()
target_link_libraries(Skia PRIVATE
JPEG::JPEG
PNG::PNG
+ Threads::Threads
)
WEBKIT_ADD_TARGET_CXX_FLAGS(Skia
diff --git a/Source/WTF/Scripts/Preferences/UnifiedWebPreferences.yaml b/Source/WTF/Scripts/Preferences/UnifiedWebPreferences.yaml
index 991cbe56d742a6cdd31d5a142754675272d4abd8..ce7e004a533d87765976b46e1d538799d2226af5 100644
--- a/Source/WTF/Scripts/Preferences/UnifiedWebPreferences.yaml
+++ b/Source/WTF/Scripts/Preferences/UnifiedWebPreferences.yaml
@@ -605,6 +605,7 @@ ApplePayEnabled:
richJavaScript: true
# FIXME: This is on by default in WebKit2 PLATFORM(COCOA). Perhaps we should consider turning it on for WebKitLegacy as well.
+# Playwright: enable on all platforms to align with Safari.
AsyncClipboardAPIEnabled:
type: bool
status: mature
@@ -615,7 +616,7 @@ AsyncClipboardAPIEnabled:
default: false
WebKit:
"PLATFORM(COCOA) || PLATFORM(GTK) || PLATFORM(WPE)" : true
- default: false
+ default: true
WebCore:
default: false
@@ -871,13 +872,10 @@ BlobFileAccessEnforcementEnabled:
sharedPreferenceForWebProcess: true
defaultValue:
WebKitLegacy:
- "PLATFORM(COCOA)": true
default: false
WebKit:
- "PLATFORM(COCOA)": true
default: false
WebCore:
- "PLATFORM(COCOA)": true
default: false
BlockIOKitInWebContentSandbox:
@@ -2073,6 +2071,7 @@ CrossOriginEmbedderPolicyEnabled:
WebCore:
default: false
+# Playwright: disable setting.
CrossOriginOpenerPolicyEnabled:
type: bool
status: stable
@@ -2146,6 +2145,7 @@ DOMAudioSessionFullEnabled:
WebCore:
default: false
+# Playwright: enable on all platforms to align with Safari.
DOMPasteAccessRequestsEnabled:
type: bool
status: internal
@@ -2157,7 +2157,7 @@ DOMPasteAccessRequestsEnabled:
default: false
WebKit:
"PLATFORM(IOS) || PLATFORM(MAC) || PLATFORM(GTK) || PLATFORM(WPE) || PLATFORM(VISION)": true
- default: false
+ default: true
WebCore:
default: false
@@ -2223,10 +2223,10 @@ DataListElementEnabled:
WebKitLegacy:
default: false
WebKit:
- "(PLATFORM(COCOA) && !PLATFORM(WATCHOS)) || PLATFORM(GTK)": true
+ "(PLATFORM(COCOA) && !PLATFORM(WATCHOS)) || PLATFORM(GTK) || PLATFORM(WPE) || PLATFORM(WIN)": true
default: false
WebCore:
- "(PLATFORM(COCOA) && !PLATFORM(WATCHOS)) || PLATFORM(GTK)": true
+ "(PLATFORM(COCOA) && !PLATFORM(WATCHOS)) || PLATFORM(GTK) || PLATFORM(WPE) || PLATFORM(WIN)": true
default: false
sharedPreferenceForWebProcess: true
@@ -2239,7 +2239,7 @@ DataTransferItemsEnabled:
WebKitLegacy:
default: true
WebKit:
- "PLATFORM(COCOA) || PLATFORM(GTK) || PLATFORM(WPE)": true
+ "PLATFORM(COCOA) || PLATFORM(GTK) || PLATFORM(WPE) || PLATFORM(WIN)": true
default: false
WebCore:
default: false
@@ -2482,7 +2482,7 @@ DirectoryUploadEnabled:
WebKitLegacy:
default: false
WebKit:
- "PLATFORM(COCOA) || PLATFORM(GTK) || PLATFORM(WPE)": true
+ "PLATFORM(COCOA) || PLATFORM(GTK) || PLATFORM(WPE) || PLATFORM(WIN)": true
default: false
WebCore:
default: false
@@ -3188,10 +3188,10 @@ FullScreenEnabled:
WebKitLegacy:
default: false
WebKit:
- "PLATFORM(GTK) || PLATFORM(WPE)": true
+ "PLATFORM(WIN) || PLATFORM(GTK) || PLATFORM(WPE)": true
default: false
WebCore:
- "PLATFORM(GTK) || PLATFORM(WPE)": true
+ "PLATFORM(WIN) || PLATFORM(GTK) || PLATFORM(WPE)": true
default: false
sharedPreferenceForWebProcess: true
@@ -3503,7 +3503,7 @@ HardwareAccelerationEnabled:
status: internal
humanReadableName: "Hardware acceleration"
humanReadableDescription: "Enable hardware acceleration"
- condition: PLATFORM(GTK) || ENABLE(WPE_PLATFORM)
+ condition: PLATFORM(GTK) || PLATFORM(WPE)
defaultValue:
WebKitLegacy:
default: true
@@ -3910,7 +3910,7 @@ InputTypeColorEnabled:
WebKitLegacy:
default: false
WebKit:
- "PLATFORM(COCOA) && !PLATFORM(WATCHOS) || PLATFORM(GTK)": true
+ "PLATFORM(COCOA) && !PLATFORM(WATCHOS) || PLATFORM(GTK) || PLATFORM(WPE)": true
default: false
WebCore:
default: false
@@ -3943,7 +3943,7 @@ InputTypeDateEnabled:
"PLATFORM(IOS_FAMILY)": true
default: false
WebKit:
- "PLATFORM(COCOA) || PLATFORM(GTK)": true
+ "PLATFORM(COCOA) || PLATFORM(GTK) || PLATFORM(WPE)": true
default: false
WebCore:
default: false
@@ -3959,7 +3959,7 @@ InputTypeDateTimeLocalEnabled:
"PLATFORM(IOS_FAMILY)": true
default: false
WebKit:
- "PLATFORM(COCOA) || PLATFORM(GTK)": true
+ "PLATFORM(COCOA) || PLATFORM(GTK) || PLATFORM(WPE)": true
default: false
WebCore:
default: false
@@ -3991,7 +3991,7 @@ InputTypeTimeEnabled:
"PLATFORM(IOS_FAMILY)": true
default: false
WebKit:
- "PLATFORM(COCOA) || PLATFORM(GTK)": true
+ "PLATFORM(COCOA) || PLATFORM(GTK) || PLATFORM(WPE)": true
default: false
WebCore:
default: false
@@ -4052,6 +4052,7 @@ InspectorMaximumResourcesContentSize:
"PLATFORM(WPE)": 50
default: 200
+# Playwright: disable setting.
InspectorStartsAttached:
type: bool
status: embedder
@@ -4059,7 +4060,7 @@ InspectorStartsAttached:
exposed: [ WebKit ]
defaultValue:
WebKit:
- default: true
+ default: false
InspectorSupportsShowingCertificate:
type: bool
@@ -6266,7 +6267,7 @@ PointerLockEnabled:
"PLATFORM(IOS_FAMILY)": false
default: true
WebCore:
- default: false
+ default: true
PopoverAttributeEnabled:
type: bool
@@ -6896,7 +6897,7 @@ ScreenOrientationAPIEnabled:
WebKitLegacy:
default: false
WebKit:
- default: WebKit::defaultShouldEnableScreenOrientationAPI()
+ default: true
WebCore:
default: false
sharedPreferenceForWebProcess: true
diff --git a/Source/WTF/wtf/PlatformEnable.h b/Source/WTF/wtf/PlatformEnable.h
index 7219e25002712fb773a8dd1c7c601e60b63c5d14..3d3054fbce6dda47761e0a1c1533a51764bf79ba 100644
--- a/Source/WTF/wtf/PlatformEnable.h
+++ b/Source/WTF/wtf/PlatformEnable.h
@@ -455,7 +455,7 @@
// ORIENTATION_EVENTS should never get enabled on Desktop, only Mobile.
#if !defined(ENABLE_ORIENTATION_EVENTS)
-#define ENABLE_ORIENTATION_EVENTS 0
+#define ENABLE_ORIENTATION_EVENTS 1
#endif
#if OS(WINDOWS)
@@ -568,7 +568,7 @@
#endif
#if !defined(ENABLE_TOUCH_EVENTS)
-#define ENABLE_TOUCH_EVENTS 0
+#define ENABLE_TOUCH_EVENTS 1
#endif
#if !defined(ENABLE_CSS_TAP_HIGHLIGHT_COLOR) && ENABLE(TOUCH_EVENTS)
diff --git a/Source/WTF/wtf/PlatformEnableCocoa.h b/Source/WTF/wtf/PlatformEnableCocoa.h
index cfa2003ccb9464bbf804c4aa37a283110ac0fbfd..3db834d1a46023ed7a3cdffd64b012ab882aa8c9 100644
--- a/Source/WTF/wtf/PlatformEnableCocoa.h
+++ b/Source/WTF/wtf/PlatformEnableCocoa.h
@@ -822,7 +822,7 @@
#endif
#if !defined(ENABLE_SEC_ITEM_SHIM)
-#define ENABLE_SEC_ITEM_SHIM 1
+#define ENABLE_SEC_ITEM_SHIM 0
#endif
#if !defined(ENABLE_SERVER_PRECONNECT)
diff --git a/Source/WTF/wtf/StdLibExtras.h b/Source/WTF/wtf/StdLibExtras.h
index ebdcb2707223f582f378d83ccbf31aa115724047..cc2d26b056618c847d6e184f73fff1701d5b921d 100644
--- a/Source/WTF/wtf/StdLibExtras.h
+++ b/Source/WTF/wtf/StdLibExtras.h
@@ -1607,6 +1607,39 @@ template<typename T, typename U> constexpr auto forward_like(U&& value) -> detai
template<typename T, typename U> constexpr auto forward_like_preserving_const(U&& value) -> detail::forward_like_preserving_const_impl<T, U> { return static_cast<detail::forward_like_preserving_const_impl<T, U>>(value); }
} // namespace WTF
+#if defined(__GLIBCXX__) && !defined(__cpp_lib_ranges_zip)
+#include <wtf/ZippedRange.h>
+
+namespace std::ranges {
+
+struct _Zip {
+ template<typename... _Ts>
+ requires (sizeof...(_Ts) <= 2)
+ constexpr auto
+ operator() [[nodiscard]] (_Ts&&... __ts) const {
+ if constexpr (!sizeof...(_Ts)) {
+ return views::empty<tuple<>>;
+ } else if constexpr (sizeof...(_Ts) == 1) {
+ return [](auto&& arg1, auto&&...) {
+ return std::forward<decltype(arg1)>(arg1);
+ }(std::forward<_Ts>(__ts)...);
+ } else {
+ return [](auto&& arg1, auto&& arg2, auto&&...) {
+ return zippedRange(std::forward<decltype(arg1)>(arg1), std::forward<decltype(arg2)>(arg2));
+ }(std::forward<_Ts>(__ts)...);
+ }
+ }
+};
+
+namespace views {
+ inline constexpr _Zip zip;
+}
+
+using WTF::zippedRange;
+
+} // namespace std::ranges
+#endif // defined(__GLIBCXX__) && !defined(__cpp_lib_ranges_zip)
+
using WTF::GB;
using WTF::KB;
using WTF::MB;
diff --git a/Source/WTF/wtf/unicode/UTF8Conversion.h b/Source/WTF/wtf/unicode/UTF8Conversion.h
index 8f551b2abcca06a623c432ac52db75de16849e8e..92bbd90bd032b9a9290ec741e7b38f9e9438f97e 100644
--- a/Source/WTF/wtf/unicode/UTF8Conversion.h
+++ b/Source/WTF/wtf/unicode/UTF8Conversion.h
@@ -30,6 +30,11 @@
#include <wtf/ExportMacros.h>
#include <wtf/text/Latin1Character.h>
+// Can be probably removed when we drop Debian 11.
+#ifdef Success
+#undef Success
+#endif
+
namespace WTF {
namespace Unicode {
diff --git a/Source/WebCore/DerivedSources.make b/Source/WebCore/DerivedSources.make
index e98fccbdefe93270040e91cb9fef8e28879c7dec..5187df2924731e17a779a23e5fd51eafadd8bb0e 100644
--- a/Source/WebCore/DerivedSources.make
+++ b/Source/WebCore/DerivedSources.make
@@ -1257,6 +1257,10 @@ JS_BINDING_IDLS := \
$(WebCore)/dom/SubscriberCallback.idl \
$(WebCore)/dom/SubscriptionObserver.idl \
$(WebCore)/dom/SubscriptionObserverCallback.idl \
+ $(WebCore)/dom/Document+Touch.idl \
+ $(WebCore)/dom/Touch.idl \
+ $(WebCore)/dom/TouchEvent.idl \
+ $(WebCore)/dom/TouchList.idl \
$(WebCore)/dom/Text.idl \
$(WebCore)/dom/TextDecoder.idl \
$(WebCore)/dom/TextDecoderStream.idl \
@@ -1881,9 +1885,6 @@ JS_BINDING_IDLS := \
ADDITIONAL_BINDING_IDLS = \
DocumentTouch.idl \
GestureEvent.idl \
- Touch.idl \
- TouchEvent.idl \
- TouchList.idl \
#
vpath %.in $(WEBKITADDITIONS_HEADER_SEARCH_PATHS)
diff --git a/Source/WebCore/Modules/geolocation/Geolocation.cpp b/Source/WebCore/Modules/geolocation/Geolocation.cpp
index f468a12c6cae3ecc22fd9d7eacccb55c199f4dab..7fdb15208f24e4c91267c7d9fb776b774e5dfdda 100644
--- a/Source/WebCore/Modules/geolocation/Geolocation.cpp
+++ b/Source/WebCore/Modules/geolocation/Geolocation.cpp
@@ -365,8 +365,9 @@ bool Geolocation::shouldBlockGeolocationRequests()
bool isSecure = SecurityOrigin::isSecure(document->url()) || document->isSecureContext();
bool isLocalOrigin = securityOrigin()->isLocal();
+ bool isPotentiallyTrustworthy = securityOrigin()->isPotentiallyTrustworthy();
if (document->canAccessResource(ScriptExecutionContext::ResourceType::Geolocation) != ScriptExecutionContext::HasResourceAccess::No) {
- if (isLocalOrigin || isSecure)
+ if (isLocalOrigin || isSecure || isPotentiallyTrustworthy)
return false;
}
diff --git a/Source/WebCore/Modules/speech/cocoa/WebSpeechRecognizerTask.mm b/Source/WebCore/Modules/speech/cocoa/WebSpeechRecognizerTask.mm
index de8ce576a7e7156460680e5ea11f10a84cda83ec..3b502fa4663dc528cb892d28e5217c4ec8bb7ea4 100644
--- a/Source/WebCore/Modules/speech/cocoa/WebSpeechRecognizerTask.mm
+++ b/Source/WebCore/Modules/speech/cocoa/WebSpeechRecognizerTask.mm
@@ -198,6 +198,7 @@ - (void)sendEndIfNeeded
- (void)speechRecognizer:(SFSpeechRecognizer *)speechRecognizer availabilityDidChange:(BOOL)available
{
+ UNUSED_PARAM(speechRecognizer);
ASSERT(isMainThread());
if (available || !_task)
@@ -211,6 +212,7 @@ - (void)speechRecognizer:(SFSpeechRecognizer *)speechRecognizer availabilityDidC
- (void)speechRecognitionTask:(SFSpeechRecognitionTask *)task didHypothesizeTranscription:(SFTranscription *)transcription
{
+ UNUSED_PARAM(task);
ASSERT(isMainThread());
[self sendSpeechStartIfNeeded];
@@ -219,6 +221,7 @@ - (void)speechRecognitionTask:(SFSpeechRecognitionTask *)task didHypothesizeTran
- (void)speechRecognitionTask:(SFSpeechRecognitionTask *)task didFinishRecognition:(SFSpeechRecognitionResult *)recognitionResult
{
+ UNUSED_PARAM(task);
ASSERT(isMainThread());
if (task.state == SFSpeechRecognitionTaskStateCanceling || (!_doMultipleRecognitions && task.state == SFSpeechRecognitionTaskStateCompleted))
@@ -232,6 +235,7 @@ - (void)speechRecognitionTask:(SFSpeechRecognitionTask *)task didFinishRecogniti
- (void)speechRecognitionTaskWasCancelled:(SFSpeechRecognitionTask *)task
{
+ UNUSED_PARAM(task);
ASSERT(isMainThread());
[self sendSpeechEndIfNeeded];
diff --git a/Source/WebCore/PlatformWin.cmake b/Source/WebCore/PlatformWin.cmake
index 72b2846f2c82818fc9a64fd90b7cba0c0601e15f..22277ab6c3233f040852d9daf9becf7ba81d12ca 100644
--- a/Source/WebCore/PlatformWin.cmake
+++ b/Source/WebCore/PlatformWin.cmake
@@ -217,6 +217,7 @@ if (USE_CAIRO)
platform/graphics/win/cairo/MediaPlayerPrivateMediaFoundationCairo.cpp
platform/win/cairo/DragImageWinCairo.cpp
+ platform/win/DragImageWin.cpp
)
elseif (USE_SKIA)
list(APPEND WebCore_SOURCES
diff --git a/Source/WebCore/SourcesCocoa.txt b/Source/WebCore/SourcesCocoa.txt
index 0630227f46780e9af2a5442c8f6807f2e889b011..acb032704a3b778b9c184afb02f7cb70450de1b0 100644
--- a/Source/WebCore/SourcesCocoa.txt
+++ b/Source/WebCore/SourcesCocoa.txt
@@ -746,3 +746,9 @@ testing/cocoa/WebViewVisualIdentificationOverlay.mm @nonARC
platform/graphics/angle/GraphicsContextGLANGLE.cpp @no-unify
platform/graphics/cocoa/GraphicsContextGLCocoa.mm @nonARC @no-unify
platform/graphics/cv/GraphicsContextGLCVCocoa.mm @nonARC @no-unify
+
+// Playwright begin
+JSTouch.cpp
+JSTouchEvent.cpp
+JSTouchList.cpp
+// Playwright end
diff --git a/Source/WebCore/SourcesGTK.txt b/Source/WebCore/SourcesGTK.txt
index 8c4a4c5e75fc792adb0c0801b3e81fd220df777c..99da4150c59018176142f34ebfccd4053c55fc49 100644
--- a/Source/WebCore/SourcesGTK.txt
+++ b/Source/WebCore/SourcesGTK.txt
@@ -107,3 +107,10 @@ platform/unix/LoggingUnix.cpp
platform/unix/SharedMemoryUnix.cpp
platform/xdg/MIMETypeRegistryXdg.cpp
+
+// Playwright: begin.
+JSSpeechSynthesisErrorCode.cpp
+JSSpeechSynthesisErrorEvent.cpp
+JSSpeechSynthesisErrorEventInit.cpp
+JSSpeechSynthesisEventInit.cpp
+// Playwright: end.
diff --git a/Source/WebCore/SourcesWPE.txt b/Source/WebCore/SourcesWPE.txt
index eb48da502311408b4772385e51b4143da28fc5d0..0cbc5941fa1c659f5a76f77cc4b22ee5842e77af 100644
--- a/Source/WebCore/SourcesWPE.txt
+++ b/Source/WebCore/SourcesWPE.txt
@@ -114,3 +114,8 @@ platform/wpe/PasteboardWPE.cpp
platform/wpe/PlatformScreenWPE.cpp
platform/xdg/MIMETypeRegistryXdg.cpp
+
+JSSpeechSynthesisErrorCode.cpp
+JSSpeechSynthesisErrorEvent.cpp
+JSSpeechSynthesisErrorEventInit.cpp
+JSSpeechSynthesisEventInit.cpp
diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj
index 308d7803e73db4277cd404ddb1314d29d3dba836..9526210649e3d9f55ec524547be40f3087aaa9dd 100644
--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj
+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj
@@ -6992,6 +6992,13 @@
EE6C530F2F8831FF00C7B706 /* RenderTreeOrder.h in Headers */ = {isa = PBXBuildFile; fileRef = EE6C530D2F8830BD00C7B706 /* RenderTreeOrder.h */; settings = {ATTRIBUTES = (Private, ); }; };
EEE349082DE0061C00A7D4BB /* StyleScopeIdentifier.h in Headers */ = {isa = PBXBuildFile; fileRef = EEE349072DE005FC00A7D4BB /* StyleScopeIdentifier.h */; settings = {ATTRIBUTES = (Private, ); }; };
EFCC6C8F20FE914400A2321B /* CanvasActivityRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = EFCC6C8D20FE914000A2321B /* CanvasActivityRecord.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ F050E16823AC9C080011CE47 /* PlatformTouchEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = F050E16623AC9C070011CE47 /* PlatformTouchEvent.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ F050E16A23AD660C0011CE47 /* Touch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F050E16923AD660C0011CE47 /* Touch.cpp */; };
+ F050E16D23AD66630011CE47 /* TouchList.h in Headers */ = {isa = PBXBuildFile; fileRef = F050E16B23AD66620011CE47 /* TouchList.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ F050E16E23AD66630011CE47 /* TouchList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F050E16C23AD66630011CE47 /* TouchList.cpp */; };
+ F050E17123AD669F0011CE47 /* TouchEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F050E16F23AD669E0011CE47 /* TouchEvent.cpp */; };
+ F050E17423AD6A800011CE47 /* DocumentTouch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F050E17323AD6A800011CE47 /* DocumentTouch.cpp */; };
+ F050E17823AD70C50011CE47 /* PlatformTouchPoint.h in Headers */ = {isa = PBXBuildFile; fileRef = F050E17623AD70C40011CE47 /* PlatformTouchPoint.h */; settings = {ATTRIBUTES = (Private, ); }; };
F12171F616A8CF0B000053CA /* WebVTTElement.h in Headers */ = {isa = PBXBuildFile; fileRef = F12171F416A8BC63000053CA /* WebVTTElement.h */; };
F30EE46B2E721BA800935B60 /* FrameInspectorController.h in Headers */ = {isa = PBXBuildFile; fileRef = F30EE46A2E721B9D00935B60 /* FrameInspectorController.h */; settings = {ATTRIBUTES = (Private, ); }; };
F32BDCD92363AACA0073B6AE /* UserGestureEmulationScope.h in Headers */ = {isa = PBXBuildFile; fileRef = F32BDCD72363AACA0073B6AE /* UserGestureEmulationScope.h */; };
@@ -22710,6 +22717,14 @@
EFCC6C8D20FE914000A2321B /* CanvasActivityRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CanvasActivityRecord.h; sourceTree = "<group>"; };
F088343F2E721B29001B2348 /* AXLocalFrame.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AXLocalFrame.h; sourceTree = "<group>"; };
F08834402E721B33001B2348 /* AXLocalFrame.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AXLocalFrame.cpp; sourceTree = "<group>"; };
+ F050E16623AC9C070011CE47 /* PlatformTouchEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlatformTouchEvent.h; sourceTree = "<group>"; };
+ F050E16923AD660C0011CE47 /* Touch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Touch.cpp; path = dom/Touch.cpp; sourceTree = SOURCE_ROOT; };
+ F050E16B23AD66620011CE47 /* TouchList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TouchList.h; path = dom/TouchList.h; sourceTree = SOURCE_ROOT; };
+ F050E16C23AD66630011CE47 /* TouchList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TouchList.cpp; path = dom/TouchList.cpp; sourceTree = SOURCE_ROOT; };
+ F050E16F23AD669E0011CE47 /* TouchEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TouchEvent.cpp; path = dom/TouchEvent.cpp; sourceTree = SOURCE_ROOT; };
+ F050E17023AD669F0011CE47 /* TouchEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TouchEvent.h; path = dom/TouchEvent.h; sourceTree = SOURCE_ROOT; };
+ F050E17323AD6A800011CE47 /* DocumentTouch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DocumentTouch.cpp; sourceTree = "<group>"; };
+ F050E17623AD70C40011CE47 /* PlatformTouchPoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlatformTouchPoint.h; sourceTree = "<group>"; };
F12171F316A8BC63000053CA /* WebVTTElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebVTTElement.cpp; sourceTree = "<group>"; };
F12171F416A8BC63000053CA /* WebVTTElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebVTTElement.h; sourceTree = "<group>"; };
F30EE46A2E721B9D00935B60 /* FrameInspectorController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FrameInspectorController.h; sourceTree = "<group>"; };
@@ -30743,6 +30758,11 @@
BC4A5324256055590028C592 /* TextDirectionSubmenuInclusionBehavior.h */,
2D4F96F11A1ECC240098BF88 /* TextIndicator.cpp */,
2D4F96F21A1ECC240098BF88 /* TextIndicator.h */,
+ F050E16923AD660C0011CE47 /* Touch.cpp */,
+ F050E16F23AD669E0011CE47 /* TouchEvent.cpp */,
+ F050E17023AD669F0011CE47 /* TouchEvent.h */,
+ F050E16C23AD66630011CE47 /* TouchList.cpp */,
+ F050E16B23AD66620011CE47 /* TouchList.h */,
F48570A42644C76D00C05F71 /* TranslationContextMenuInfo.h */,
D640B24C2E3058C800EB6C49 /* UADataValues.h */,
D640B24E2E3058C800EB6C49 /* UADataValues.idl */,
@@ -38753,6 +38773,8 @@
29E4D8DF16B0940F00C84704 /* PlatformSpeechSynthesizer.h */,
1AD8F81A11CAB9E900E93E54 /* PlatformStrategies.cpp */,
1AD8F81911CAB9E900E93E54 /* PlatformStrategies.h */,
+ F050E16623AC9C070011CE47 /* PlatformTouchEvent.h */,
+ F050E17623AD70C40011CE47 /* PlatformTouchPoint.h */,
FE3DC9932D0C063C0021B6FC /* PlatformTZoneImpls.cpp */,
0FD7C21D23CE41E30096D102 /* PlatformWheelEvent.cpp */,
935C476A09AC4D4F00A6AAB4 /* PlatformWheelEvent.h */,
@@ -41766,6 +41788,7 @@
AD6E71AB1668899D00320C13 /* DocumentSharedObjectPool.h */,
6BDB5DC1227BD3B800919770 /* DocumentStorageAccess.cpp */,
6BDB5DC0227BD3B800919770 /* DocumentStorageAccess.h */,
+ F050E17323AD6A800011CE47 /* DocumentTouch.cpp */,
7CE7FA5B1EF882300060C9D6 /* DocumentTouch.cpp */,
7CE7FA591EF882300060C9D6 /* DocumentTouch.h */,
A8185F3209765765005826D9 /* DocumentType.cpp */,
@@ -46955,6 +46978,8 @@
F4E90A3C2B52038E002DA469 /* PlatformTextAlternatives.h in Headers */,
0F7D07331884C56C00B4AF86 /* PlatformTextTrack.h in Headers */,
074E82BB18A69F0E007EF54C /* PlatformTimeRanges.h in Headers */,
+ F050E16823AC9C080011CE47 /* PlatformTouchEvent.h in Headers */,
+ F050E17823AD70C50011CE47 /* PlatformTouchPoint.h in Headers */,
CDD08ABD277E542600EA3755 /* PlatformTrackConfiguration.h in Headers */,
CD1F9B022700323D00617EB6 /* PlatformVideoColorPrimaries.h in Headers */,
CD1F9B01270020B700617EB6 /* PlatformVideoColorSpace.h in Headers */,
@@ -48629,6 +48654,7 @@
0F54DD081881D5F5003EEDBB /* Touch.h in Headers */,
71B7EE0D21B5C6870031C1EF /* TouchAction.h in Headers */,
0F54DD091881D5F5003EEDBB /* TouchEvent.h in Headers */,
+ F050E16D23AD66630011CE47 /* TouchList.h in Headers */,
0F54DD0A1881D5F5003EEDBB /* TouchList.h in Headers */,
070334D71459FFD5008D8D45 /* TrackBase.h in Headers */,
513C7B6E2E7C2E7A00079881 /* TrackInfo.h in Headers */,
@@ -49903,7 +49929,9 @@
2D22830323A8470700364B7E /* CursorMac.mm in Sources */,
5CBD59592280E926002B22AA /* CustomHeaderFields.cpp in Sources */,
07E4BDBF2A3A5FAB000D5509 /* DictationCaretAnimator.cpp in Sources */,
+ F050E17423AD6A800011CE47 /* DocumentTouch.cpp in Sources */,
0749E9512E275A23009B912B /* EditingHTMLConverter.mm in Sources */,
+ 329C0C2528BD96EB00F187D2 /* ElementName.cpp in Sources */,
7CE6CBFD187F394900D46BF5 /* FormatConverter.cpp in Sources */,
4667EA3E2968D9DA00BAB1E2 /* GameControllerHapticEffect.mm in Sources */,
46FE73D32968E52000B8064C /* GameControllerHapticEngines.mm in Sources */,
@@ -50000,6 +50028,9 @@
072F696F2E755BFA00281FC5 /* TextListParser.cpp in Sources */,
BE39137129B267F500FA5D4F /* TextTransformCocoa.cpp in Sources */,
51DF6D800B92A18E00C2DC85 /* ThreadCheck.mm in Sources */,
+ F050E16A23AD660C0011CE47 /* Touch.cpp in Sources */,
+ F050E17123AD669F0011CE47 /* TouchEvent.cpp in Sources */,
+ F050E16E23AD66630011CE47 /* TouchList.cpp in Sources */,
0D0B4DA32EBD20E30053FB12 /* UnifiedSource1-ARC.mm in Sources */,
538EC8031F96AF81004D22A8 /* UnifiedSource1-nonARC.mm in Sources */,
538EC8021F96AF81004D22A8 /* UnifiedSource1.cpp in Sources */,
diff --git a/Source/WebCore/css/query/MediaQueryFeatures.cpp b/Source/WebCore/css/query/MediaQueryFeatures.cpp
index ab1b8b7d0e7baff7d7564609736a6145472c2e3a..00921097a9f2b5d96937785e62f5a3533afafe55 100644
--- a/Source/WebCore/css/query/MediaQueryFeatures.cpp
+++ b/Source/WebCore/css/query/MediaQueryFeatures.cpp
@@ -404,7 +404,11 @@ static const IdentifierSchema& forcedColorsFeatureSchema()
"forced-colors"_s,
FixedVector { CSSValueNone, CSSValueActive },
OptionSet<MediaQueryDynamicDependency>(),
- [](auto&) {
+ [](auto& context) {
+ auto* page = context.document->frame()->page();
+ std::optional<bool> forcedColorsOverride = page->useForcedColorsOverride();
+ if (forcedColorsOverride)
+ return forcedColorsOverride.value() ? MatchingIdentifiers { CSSValueActive } : MatchingIdentifiers { CSSValueNone };
return MatchingIdentifiers { CSSValueNone };
}
};
@@ -592,6 +596,9 @@ static const IdentifierSchema& prefersReducedMotionFeatureSchema()
[](auto& context) {
bool userPrefersReducedMotion = [&] {
Ref frame = *context.document->frame();
+ std::optional<bool> reducedMotionOverride = frame->page()->useReducedMotionOverride();
+ if (reducedMotionOverride)
+ return reducedMotionOverride.value();
switch (frame->settings().forcedPrefersReducedMotionAccessibilityValue()) {
case ForcedAccessibilityValue::On:
return true;
diff --git a/Source/WebCore/dom/DataTransfer.cpp b/Source/WebCore/dom/DataTransfer.cpp
index 6fac2c209afa640cf7a305c9c322791c0cce2435..a609e0272959a42dec0e44cfd943ab6a8d78865a 100644
--- a/Source/WebCore/dom/DataTransfer.cpp
+++ b/Source/WebCore/dom/DataTransfer.cpp
@@ -531,6 +531,14 @@ Ref<DataTransfer> DataTransfer::createForDrag(const Document& document)
return adoptRef(*new DataTransfer(StoreMode::ReadWrite, Pasteboard::createForDragAndDrop(PagePasteboardContext::create(document.pageID())), Type::DragAndDropData));
}
+#if PLATFORM(MAC)
+Ref<DataTransfer> DataTransfer::createForDrag(const Document& document, const String& pasteboardName)
+{
+ return adoptRef(*new DataTransfer(StoreMode::ReadWrite, makeUnique<Pasteboard>(PagePasteboardContext::create(document.pageID()), pasteboardName), Type::DragAndDropData));
+}
+#endif
+
+
Ref<DataTransfer> DataTransfer::createForDragStartEvent(const Document& document)
{
auto dataTransfer = adoptRef(*new DataTransfer(StoreMode::ReadWrite, makeUnique<StaticPasteboard>(), Type::DragAndDropData));
diff --git a/Source/WebCore/dom/DataTransfer.h b/Source/WebCore/dom/DataTransfer.h
index 64a53ff58bf7bcd9e56ccc8b74cea8c9c75bf89e..10d52432373f02622328f32d3f665ed0fdd8bc24 100644
--- a/Source/WebCore/dom/DataTransfer.h
+++ b/Source/WebCore/dom/DataTransfer.h
@@ -92,6 +92,9 @@ public:
#if ENABLE(DRAG_SUPPORT)
static Ref<DataTransfer> createForDrag(const Document&);
+#if PLATFORM(MAC)
+ static Ref<DataTransfer> createForDrag(const Document&, const String& pasteboardName);
+#endif
static Ref<DataTransfer> createForDragStartEvent(const Document&);
static Ref<DataTransfer> createForDrop(const Document&, std::unique_ptr<Pasteboard>&&, OptionSet<DragOperation>, bool draggingFiles);
static Ref<DataTransfer> createForUpdatingDropTarget(const Document&, std::unique_ptr<Pasteboard>&&, OptionSet<DragOperation>, bool draggingFiles);
diff --git a/Source/WebCore/dom/DeviceMotionEvent.idl b/Source/WebCore/dom/DeviceMotionEvent.idl
index a2e91e304c473d6c2de246e51539fac8e265e216..eb3f2a61f74a7d533fcdc5aedecb723be75ba105 100644
--- a/Source/WebCore/dom/DeviceMotionEvent.idl
+++ b/Source/WebCore/dom/DeviceMotionEvent.idl
@@ -20,12 +20,13 @@
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// https://w3c.github.io/deviceorientation/#devicemotionevent
[
Conditional=DEVICE_ORIENTATION,
+ EnabledBySetting=DeviceOrientationEventEnabled,
Exposed=Window,
SecureContext
] interface DeviceMotionEvent : Event {
diff --git a/Source/WebCore/dom/DeviceOrientationEvent.idl b/Source/WebCore/dom/DeviceOrientationEvent.idl
index 2feeeac677ee3f36cb13c2bac1afbc57fbe70e12..6ed92e45b7659c48b3bb1e24f7f0075117178332 100644
--- a/Source/WebCore/dom/DeviceOrientationEvent.idl
+++ b/Source/WebCore/dom/DeviceOrientationEvent.idl
@@ -25,6 +25,7 @@
[
Conditional=DEVICE_ORIENTATION,
+ EnabledBySetting=DeviceOrientationEventEnabled,
Exposed=Window,
SecureContext
] interface DeviceOrientationEvent : Event {
diff --git a/Source/WebCore/dom/PointerEvent.cpp b/Source/WebCore/dom/PointerEvent.cpp
index dd8c59fe17c70a72f03df3c884b5a92f8f655e61..9c2b847b15f4361ad8199729c2b808a0253b77c2 100644
--- a/Source/WebCore/dom/PointerEvent.cpp
+++ b/Source/WebCore/dom/PointerEvent.cpp
@@ -20,7 +20,7 @@
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
@@ -28,7 +28,9 @@
#include "EventNames.h"
#include "MouseEventTypes.h"
+#include "MouseEvent.h"
#include "Node.h"
+#include "PlatformTouchEvent.h"
#include "PointerEventTypeNames.h"
#include <numbers>
#include <wtf/TZoneMallocInlines.h>
@@ -380,4 +382,59 @@ double PointerEvent::offsetY()
return adjustedCoordinateForType(offsetLocation().y());
}
+#if ENABLE(TOUCH_EVENTS) && !PLATFORM(IOS_FAMILY) && !PLATFORM(WPE) && !PLATFORM(GTK)
+
+static const AtomString& pointerEventType(PlatformTouchPoint::State state)
+{
+ switch (state) {
+ case PlatformTouchPoint::State::TouchPressed:
+ return eventNames().pointerdownEvent;
+ case PlatformTouchPoint::State::TouchMoved:
+ return eventNames().pointermoveEvent;
+ case PlatformTouchPoint::State::TouchStationary:
+ return eventNames().pointermoveEvent;
+ case PlatformTouchPoint::State::TouchReleased:
+ return eventNames().pointerupEvent;
+ case PlatformTouchPoint::State::TouchCancelled:
+ return eventNames().pointercancelEvent;
+ case PlatformTouchPoint::State::TouchStateEnd:
+ break;
+ }
+ ASSERT_NOT_REACHED();
+ return nullAtom();
+}
+
+Ref<PointerEvent> PointerEvent::create(const PlatformTouchEvent& event, const Vector<Ref<PointerEvent>>& coalescedEvents, const Vector<Ref<PointerEvent>>& predictedEvents, unsigned touchIndex, bool isPrimary, Ref<WindowProxy>&& view, const DoublePoint& touchDelta)
+{
+ const auto& type = pointerEventType(event.touchPoints().at(touchIndex).state());
+ return adoptRef(*new PointerEvent(type, event, coalescedEvents, predictedEvents, typeCanBubble(type), typeIsCancelable(type), touchIndex, isPrimary, WTF::move(view), touchDelta));
+}
+
+Ref<PointerEvent> PointerEvent::create(const PlatformTouchEvent& event, const Vector<Ref<PointerEvent>>& coalescedEvents, const Vector<Ref<PointerEvent>>& predictedEvents, CanBubble canBubble, IsCancelable isCancelable, unsigned touchIndex, bool isPrimary, Ref<WindowProxy>&& view, const DoublePoint& touchDelta)
+{
+ const auto& type = pointerEventType(event.touchPoints().at(touchIndex).state());
+ return adoptRef(*new PointerEvent(type, event, coalescedEvents, predictedEvents, canBubble, isCancelable, touchIndex, isPrimary, WTF::move(view), touchDelta));
+}
+
+Ref<PointerEvent> PointerEvent::create(const AtomString& type, const PlatformTouchEvent& event, const Vector<Ref<PointerEvent>>& coalescedEvents, const Vector<Ref<PointerEvent>>& predictedEvents, unsigned touchIndex, bool isPrimary, Ref<WindowProxy>&& view, const DoublePoint& touchDelta)
+{
+ return adoptRef(*new PointerEvent(type, event, coalescedEvents, predictedEvents, typeCanBubble(type), typeIsCancelable(type), touchIndex, isPrimary, WTF::move(view), touchDelta));
+}
+
+PointerEvent::PointerEvent(const AtomString& type, const PlatformTouchEvent& event, const Vector<Ref<PointerEvent>>& coalescedEvents, const Vector<Ref<PointerEvent>>& predictedEvents, CanBubble canBubble, IsCancelable isCancelable, unsigned touchIndex, bool isPrimary, Ref<WindowProxy>&& view, const DoublePoint& touchDelta)
+ : MouseEvent(EventInterfaceType::PointerEvent, type, canBubble, isCancelable, typeIsComposed(type), event.timestamp().approximateMonotonicTime(), WTF::move(view), 0,
+ event.touchPoints().at(touchIndex).pos(), event.touchPoints().at(touchIndex).pos(), touchDelta.x(), touchDelta.y(), event.modifiers(), buttonForType(type), buttonsForType(type), nullptr, 0, SyntheticClickType::NoTap, { }, { }, std::nullopt, IsSimulated::No, IsTrusted::Yes)
+ , m_pointerId(event.touchPoints().at(touchIndex).id())
+ , m_width(2 * event.touchPoints().at(touchIndex).radius().width())
+ , m_height(2 * event.touchPoints().at(touchIndex).radius().height())
+ , m_pressure(event.touchPoints().at(touchIndex).force())
+ , m_pointerType(touchPointerEventType())
+ , m_isPrimary(isPrimary)
+ , m_coalescedEvents(coalescedEvents)
+ , m_predictedEvents(predictedEvents)
+{
+}
+
+#endif // ENABLE(TOUCH_EVENTS) && !PLATFORM(IOS_FAMILY) && !PLATFORM(WPE) && !PLATFORM(GTK)
+
} // namespace WebCore
diff --git a/Source/WebCore/dom/PointerEvent.h b/Source/WebCore/dom/PointerEvent.h
index a9ad0f77eedb629a360c8ec77257e84e59418dbf..3486cfaa73edb83300e597ab3fc8ab115e96ee54 100644
--- a/Source/WebCore/dom/PointerEvent.h
+++ b/Source/WebCore/dom/PointerEvent.h
@@ -41,8 +41,8 @@
#pragma clang diagnostic pop
#endif
-#if ENABLE(TOUCH_EVENTS) && (PLATFORM(WPE) || PLATFORM(GTK))
-#include "PlatformTouchEvent.h"
+#if ENABLE(TOUCH_EVENTS) && !PLATFORM(IOS_FAMILY)
+#include <WebCore/PlatformTouchEvent.h>
#endif
namespace WebCore {
@@ -99,14 +99,18 @@ public:
static Ref<PointerEvent> create(const AtomString& type, MouseButton, const MouseEvent&, PointerID, const String& pointerType, CanBubble, IsCancelable);
static Ref<PointerEvent> create(const AtomString& type, PointerID, const String& pointerType, IsPrimary = IsPrimary::No);
-#if ENABLE(TOUCH_EVENTS) && (PLATFORM(IOS_FAMILY) || PLATFORM(WPE) || PLATFORM(GTK))
+#if ENABLE(TOUCH_EVENTS)
static Ref<PointerEvent> create(const PlatformTouchEvent&, const Vector<Ref<PointerEvent>>& coalescedEvents, const Vector<Ref<PointerEvent>>& predictedEvents, unsigned touchIndex, bool isPrimary, Ref<WindowProxy>&&, const DoublePoint& touchDelta = { });
static Ref<PointerEvent> create(const PlatformTouchEvent&, const Vector<Ref<PointerEvent>>& coalescedEvents, const Vector<Ref<PointerEvent>>& predictedEvents, CanBubble, IsCancelable, unsigned touchIndex, bool isPrimary, Ref<WindowProxy>&& view, const DoublePoint& touchDelta = { });
static Ref<PointerEvent> create(const AtomString& type, const PlatformTouchEvent&, const Vector<Ref<PointerEvent>>& coalescedEvents, const Vector<Ref<PointerEvent>>& predictedEvents, unsigned touchIndex, bool isPrimary, Ref<WindowProxy>&&, const DoublePoint& touchDelta = { });
#endif
-#if ENABLE(TOUCH_EVENTS) && (PLATFORM(WPE) || PLATFORM(GTK))
+#if ENABLE(TOUCH_EVENTS)
+#if PLATFORM(WPE) || PLATFORM(GTK)
static unsigned pointerIdForTouchPoint(const PlatformTouchPoint&);
+#elif !ENABLE(IOS_TOUCH_EVENTS)
+ static unsigned pointerIdForTouchPoint(const PlatformTouchPoint& point) { return point.id(); }
+#endif
#endif
virtual ~PointerEvent();
@@ -194,7 +198,7 @@ private:
PointerEvent();
PointerEvent(const AtomString&, Init&&, IsTrusted);
PointerEvent(const AtomString& type, PointerID, const String& pointerType, IsPrimary);
-#if ENABLE(TOUCH_EVENTS) && (PLATFORM(IOS_FAMILY) || PLATFORM(WPE) || PLATFORM(GTK))
+#if ENABLE(TOUCH_EVENTS)
PointerEvent(const AtomString& type, const PlatformTouchEvent&, const Vector<Ref<PointerEvent>>& coalescedEvents, const Vector<Ref<PointerEvent>>& predictedEvents, CanBubble canBubble, IsCancelable isCancelable, unsigned touchIndex, bool isPrimary, Ref<WindowProxy>&&, const DoublePoint& touchDelta = { });
#endif
diff --git a/Source/WebCore/dom/TouchList.h b/Source/WebCore/dom/TouchList.h
index 25546b5bdf24a88141f2a968c07e9d424d61f7e1..980a173d056b6dd4f89ae394dee01b510def691e 100644
--- a/Source/WebCore/dom/TouchList.h
+++ b/Source/WebCore/dom/TouchList.h
@@ -28,8 +28,8 @@
#include <WebKitAdditions/TouchListIOS.h>
#elif ENABLE(TOUCH_EVENTS)
-#include "Node.h"
-#include "Touch.h"
+#include <WebCore/Node.h>
+#include <WebCore/Touch.h>
#include <wtf/FixedVector.h>
#include <wtf/Ref.h>
#include <wtf/RefCounted.h>
diff --git a/Source/WebCore/editing/libwpe/EditorLibWPE.cpp b/Source/WebCore/editing/libwpe/EditorLibWPE.cpp
index d0a3d5c048647b07772e1581c76c4eb60ecf41b0..bec324636991079264e620c0dfdaf9842ff585cd 100644
--- a/Source/WebCore/editing/libwpe/EditorLibWPE.cpp
+++ b/Source/WebCore/editing/libwpe/EditorLibWPE.cpp
@@ -35,6 +35,7 @@
#include "Pasteboard.h"
#include "Settings.h"
#include "SimpleRange.h"
+#include "WebContentReader.h"
#include "markup.h"
namespace WebCore {
@@ -100,6 +101,14 @@ void Editor::platformPasteFont()
{
}
+RefPtr<DocumentFragment> Editor::webContentFromPasteboard(Pasteboard& pasteboard, const SimpleRange& context, bool allowPlainText, bool& chosePlainText)
+{
+ WebContentReader reader(*document().frame(), context, allowPlainText);
+ pasteboard.read(reader);
+ chosePlainText = reader.madeFragmentFromPlainText();
+ return reader.takeFragment();
+}
+
} // namespace WebCore
#endif // USE(LIBWPE)
diff --git a/Source/WebCore/html/FileInputType.cpp b/Source/WebCore/html/FileInputType.cpp
index 70293a7486130c23eda9198e399f4fc7a998c2b3..1ff1dc564dbe7f2ed2d35000d82bac6e2fb2cad0 100644
--- a/Source/WebCore/html/FileInputType.cpp
+++ b/Source/WebCore/html/FileInputType.cpp
@@ -39,6 +39,7 @@
#include "HTMLNames.h"
#include "Icon.h"
#include "InputTypeNames.h"
+#include "InspectorInstrumentation.h"
#include "LocalFrame.h"
#include "LocalizedStrings.h"
#include "MIMETypeRegistry.h"
@@ -162,6 +163,11 @@ void FileInputType::handleDOMActivateEvent(Event& event)
if (element()->isDisabledFormControl())
return;
+ bool intercept = false;
+ InspectorInstrumentation::runOpenPanel(element()->document().frame(), element(), &intercept);
+ if (intercept)
+ return;
+
if (!UserGestureIndicator::processingUserGesture())
return;
diff --git a/Source/WebCore/inspector/FrameInspectorController.cpp b/Source/WebCore/inspector/FrameInspectorController.cpp
index 12650ec508ee1acef286c9b862e37a73f652409f..5721af8def5099347a80e7ad31c7551dbc0be0d5 100644
--- a/Source/WebCore/inspector/FrameInspectorController.cpp
+++ b/Source/WebCore/inspector/FrameInspectorController.cpp
@@ -170,6 +170,12 @@ void FrameInspectorController::connectFrontend(Inspector::FrontendChannel& front
UNUSED_PARAM(isAutomaticInspection);
UNUSED_PARAM(immediatelyPause);
+ // Playwright begin
+ // Child frames copy parent's frontend connection.
+ if (!m_frame->isMainFrame() && m_frontendRouter->hasFrontends())
+ return;
+ // Playwright end
+
if (auto* page = m_frame->page())
page->settings().setDeveloperExtrasEnabled(true);
@@ -184,6 +190,19 @@ void FrameInspectorController::connectFrontend(Inspector::FrontendChannel& front
m_injectedScriptManager->addClient();
m_agents.didCreateFrontendAndBackend();
}
+
+ // Playwright begin
+ // Auto attach/enable agents for subframes.
+ if (!m_frame->isMainFrame()) {
+ LocalFrame* localMainFrame = m_frame->page()->localMainFrame();
+ if (localMainFrame) {
+ Ref mainFrameController = localMainFrame->inspectorController();
+ auto* mainFrameConsoleAgent = mainFrameController->m_instrumentingAgents->webConsoleAgent();
+ if (mainFrameConsoleAgent && mainFrameConsoleAgent->enabled())
+ m_instrumentingAgents->webConsoleAgent()->enable();
+ }
+ }
+ // Playwright end
}
void FrameInspectorController::disconnectFrontend(Inspector::FrontendChannel& frontendChannel)
diff --git a/Source/WebCore/inspector/InspectorIdentifierRegistry.cpp b/Source/WebCore/inspector/InspectorIdentifierRegistry.cpp
index 1585d249dafdc13f4258ff1dde95268eeb329f93..24d21908c7a79e744aadf37a6d8ba0918f2dd7b7 100644
--- a/Source/WebCore/inspector/InspectorIdentifierRegistry.cpp
+++ b/Source/WebCore/inspector/InspectorIdentifierRegistry.cpp
@@ -48,20 +48,22 @@ Protocol::Network::FrameId LegacyIdentifierRegistry::frameId(const WebCore::Fram
{
if (!frame)
return emptyString();
- return m_frameToIdentifier.ensure(*frame, [this, frame] {
- auto identifier = IdentifiersFactory::createIdentifier();
- m_identifierToFrame.set(identifier, frame);
- return identifier;
- }).iterator->value;
+
+ auto identifier = String::number(frame->frameID().toUInt64());
+ m_identifierToFrame.set(identifier, frame);
+ return identifier;
}
Protocol::Network::LoaderId LegacyIdentifierRegistry::loaderId(WebCore::DocumentLoader* loader)
{
if (!loader)
return emptyString();
- return m_loaderToIdentifier.ensure(loader, [] {
- return IdentifiersFactory::createIdentifier();
- }).iterator->value;
+
+ auto navigationID = loader->navigationID();
+ if (!navigationID)
+ return emptyString();
+
+ return String::number(navigationID->toUInt64());
}
WebCore::LocalFrame* LegacyIdentifierRegistry::assertFrame(Protocol::ErrorString& errorString, const Protocol::Network::FrameId& frameId)
@@ -74,15 +76,19 @@ WebCore::LocalFrame* LegacyIdentifierRegistry::assertFrame(Protocol::ErrorString
Protocol::Network::FrameId LegacyIdentifierRegistry::takeFrame(const WebCore::Frame& frame)
{
- auto identifier = m_frameToIdentifier.take(frame);
- if (!identifier.isNull())
- m_identifierToFrame.remove(identifier);
+ auto identifier = String::number(frame.frameID().toUInt64());
+ if (!m_identifierToFrame.take(identifier))
+ return {};
return identifier;
}
Protocol::Network::LoaderId LegacyIdentifierRegistry::takeLoader(WebCore::DocumentLoader& loader)
{
- return m_loaderToIdentifier.take(&loader);
+ auto navigationID = loader.navigationID();
+ if (!navigationID)
+ return {};
+
+ return String::number(navigationID->toUInt64());
}
} // namespace Inspector
diff --git a/Source/WebCore/inspector/InspectorInstrumentation.cpp b/Source/WebCore/inspector/InspectorInstrumentation.cpp
index 68b5996d7ae96ce0c3f5eda869e353b448823da7..5227faf95b488a3f67e2e63e30089ba9b9cd0d5c 100644
--- a/Source/WebCore/inspector/InspectorInstrumentation.cpp
+++ b/Source/WebCore/inspector/InspectorInstrumentation.cpp
@@ -617,6 +617,12 @@ void InspectorInstrumentation::applyUserAgentOverrideImpl(InstrumentingAgents& i
pageAgent->applyUserAgentOverride(userAgent);
}
+void InspectorInstrumentation::applyPlatformOverrideImpl(InstrumentingAgents& instrumentingAgents, String& platform)
+{
+ if (auto* pageAgent = instrumentingAgents.enabledPageAgent())
+ pageAgent->applyPlatformOverride(platform);
+}
+
void InspectorInstrumentation::applyEmulatedMediaImpl(InstrumentingAgents& instrumentingAgents, AtomString& media)
{
if (CheckedPtr pageAgent = instrumentingAgents.enabledPageAgent())
@@ -700,6 +706,12 @@ void InspectorInstrumentation::didFailLoadingImpl(InstrumentingAgents& instrumen
consoleAgent->didFailLoading(identifier, error); // This should come AFTER resource notification, front-end relies on this.
}
+void InspectorInstrumentation::didReceiveMainResourceErrorImpl(InstrumentingAgents& instrumentingAgents, LocalFrame& frame, const ResourceError&)
+{
+ if (auto* pageRuntimeAgent = instrumentingAgents.enabledPageRuntimeAgent())
+ pageRuntimeAgent->didReceiveMainResourceError(frame);
+}
+
void InspectorInstrumentation::willLoadXHRSynchronouslyImpl(InstrumentingAgents& instrumentingAgents)
{
if (auto* networkAgent = instrumentingAgents.enabledNetworkAgent())
@@ -732,20 +744,17 @@ void InspectorInstrumentation::didReceiveScriptResponseImpl(InstrumentingAgents&
void InspectorInstrumentation::domContentLoadedEventFiredImpl(InstrumentingAgents& instrumentingAgents, LocalFrame& frame)
{
- if (!frame.isMainFrame())
- return;
-
if (CheckedPtr pageAgent = instrumentingAgents.enabledPageAgent())
- pageAgent->domContentEventFired();
+ pageAgent->domContentEventFired(frame);
}
void InspectorInstrumentation::loadEventFiredImpl(InstrumentingAgents& instrumentingAgents, LocalFrame* frame)
{
- if (!frame || !frame->isMainFrame())
+ if (!frame)
return;
if (CheckedPtr pageAgent = instrumentingAgents.enabledPageAgent())
- pageAgent->loadEventFired();
+ pageAgent->loadEventFired(*frame);
}
void InspectorInstrumentation::frameDetachedFromParentImpl(InstrumentingAgents& instrumentingAgents, LocalFrame& frame)
@@ -825,12 +834,6 @@ void InspectorInstrumentation::frameDocumentUpdatedImpl(InstrumentingAgents& ins
pageDOMDebuggerAgent->frameDocumentUpdated(frame);
}
-void InspectorInstrumentation::loaderDetachedFromFrameImpl(InstrumentingAgents& instrumentingAgents, DocumentLoader& loader)
-{
- if (CheckedPtr inspectorPageAgent = instrumentingAgents.enabledPageAgent())
- inspectorPageAgent->loaderDetachedFromFrame(loader);
-}
-
void InspectorInstrumentation::frameStartedLoadingImpl(InstrumentingAgents& instrumentingAgents, LocalFrame& frame)
{
if (frame.isMainFrame()) {
@@ -861,6 +864,12 @@ void InspectorInstrumentation::accessibilitySettingsDidChangeImpl(InstrumentingA
inspectorPageAgent->accessibilitySettingsDidChange();
}
+void InspectorInstrumentation::didNavigateWithinPageImpl(InstrumentingAgents& instrumentingAgents, LocalFrame& frame)
+{
+ if (InspectorPageAgent* inspectorPageAgent = instrumentingAgents.enabledPageAgent())
+ inspectorPageAgent->didNavigateWithinPage(frame);
+}
+
#if ENABLE(DARK_MODE_CSS)
void InspectorInstrumentation::defaultAppearanceDidChangeImpl(InstrumentingAgents& instrumentingAgents)
{
@@ -913,6 +922,12 @@ void InspectorInstrumentation::interceptResponseImpl(InstrumentingAgents& instru
networkAgent->interceptResponse(response, identifier, WTF::move(handler));
}
+void InspectorInstrumentation::setStoppingLoadingDueToProcessSwapImpl(InstrumentingAgents& instrumentingAgents, bool value)
+{
+ if (auto* networkAgent = instrumentingAgents.enabledNetworkAgent())
+ networkAgent->setStoppingLoadingDueToProcessSwap(value);
+}
+
// JavaScriptCore InspectorDebuggerAgent should know Console MessageTypes.
static bool NODELETE isConsoleAssertMessage(MessageSource source, MessageType type)
{
@@ -1050,6 +1065,12 @@ void InspectorInstrumentation::consoleStopRecordingCanvasImpl(InstrumentingAgent
canvasAgent->consoleStopRecordingCanvas(context);
}
+void InspectorInstrumentation::bindingCalledImpl(InstrumentingAgents& instrumentingAgents, JSC::JSGlobalObject* globalObject, const String& name, const String& arg)
+{
+ if (auto* pageRuntimeAgent = instrumentingAgents.enabledPageRuntimeAgent())
+ pageRuntimeAgent->bindingCalled(globalObject, name, arg);
+}
+
void InspectorInstrumentation::didDispatchDOMStorageEventImpl(InstrumentingAgents& instrumentingAgents, const String& key, const String& oldValue, const String& newValue, StorageType storageType, const SecurityOrigin& securityOrigin)
{
if (auto* domStorageAgent = instrumentingAgents.enabledDOMStorageAgent())
@@ -1347,6 +1368,36 @@ void InspectorInstrumentation::renderLayerDestroyedImpl(InstrumentingAgents& ins
layerTreeAgent->renderLayerDestroyed(renderLayer);
}
+void InspectorInstrumentation::runOpenPanelImpl(InstrumentingAgents& instrumentingAgents, HTMLInputElement* element, bool* intercept)
+{
+ if (InspectorPageAgent* pageAgent = instrumentingAgents.enabledPageAgent())
+ pageAgent->runOpenPanel(element, intercept);
+}
+
+void InspectorInstrumentation::frameAttachedImpl(InstrumentingAgents& instrumentingAgents, LocalFrame& frame) {
+ if (InspectorPageAgent* pageAgent = instrumentingAgents.enabledPageAgent())
+ pageAgent->frameAttached(frame);
+}
+
+bool InspectorInstrumentation::shouldBypassCSPImpl(InstrumentingAgents& instrumentingAgents)
+{
+ if (InspectorPageAgent* pageAgent = instrumentingAgents.enabledPageAgent())
+ return pageAgent->shouldBypassCSP();
+ return false;
+}
+
+void InspectorInstrumentation::willCheckNavigationPolicyImpl(InstrumentingAgents& instrumentingAgents, LocalFrame& frame)
+{
+ if (InspectorPageAgent* pageAgent = instrumentingAgents.enabledPageAgent())
+ pageAgent->willCheckNavigationPolicy(frame);
+}
+
+void InspectorInstrumentation::didCheckNavigationPolicyImpl(InstrumentingAgents& instrumentingAgents, LocalFrame& frame, bool cancel)
+{
+ if (InspectorPageAgent* pageAgent = instrumentingAgents.enabledPageAgent())
+ pageAgent->didCheckNavigationPolicy(frame, cancel);
+}
+
InstrumentingAgents& InspectorInstrumentation::instrumentingAgents(WorkerOrWorkletGlobalScope& globalScope)
{
return globalScope.inspectorController().m_instrumentingAgents;
diff --git a/Source/WebCore/inspector/InspectorInstrumentation.h b/Source/WebCore/inspector/InspectorInstrumentation.h
index d3c1a73fd1eaa95dad8e582f8e52ed894a53a8be..24791c5f62638513dd507ff0886ae4d593523919 100644
--- a/Source/WebCore/inspector/InspectorInstrumentation.h
+++ b/Source/WebCore/inspector/InspectorInstrumentation.h
@@ -45,6 +45,7 @@
#include "LocalFrame.h"
#include "NodeDocument.h"
#include "Page.h"
+#include "ResourceError.h"
#include "ResourceLoader.h"
#include "ResourceLoaderIdentifier.h"
#include "StorageArea.h"
@@ -79,6 +80,7 @@ class Document;
class DocumentLoader;
class DocumentThreadableLoader;
class EventListener;
+class HTMLInputElement;
class HTTPHeaderMap;
class InspectorTimelineAgent;
class InstrumentingAgents;
@@ -203,6 +205,7 @@ public:
static void didRecalculateStyle(Document&);
static void didScheduleStyleRecalculation(Document&);
static void applyUserAgentOverride(LocalFrame&, String&);
+ static void applyPlatformOverride(LocalFrame&, String&);
static void applyEmulatedMedia(LocalFrame&, AtomString&);
static void flexibleBoxRendererBeganLayout(const RenderObject&);
@@ -215,6 +218,7 @@ public:
static void didReceiveData(LocalFrame*, ResourceLoaderIdentifier, const SharedBuffer*, int encodedDataLength);
static void didFinishLoading(LocalFrame*, DocumentLoader*, ResourceLoaderIdentifier, const NetworkLoadMetrics&, ResourceLoader*);
static void didFailLoading(LocalFrame*, DocumentLoader*, ResourceLoaderIdentifier, const ResourceError&);
+ static void didReceiveMainResourceError(LocalFrame&, const ResourceError&);
static void willSendRequest(ServiceWorkerGlobalScope&, ResourceLoaderIdentifier, ResourceRequest&);
static void didReceiveResourceResponse(ServiceWorkerGlobalScope&, ResourceLoaderIdentifier, const ResourceResponse&);
@@ -241,11 +245,11 @@ public:
static void frameDetachedFromParent(LocalFrame&);
static void didCommitLoad(LocalFrame&, DocumentLoader*);
static void frameDocumentUpdated(LocalFrame&);
- static void loaderDetachedFromFrame(LocalFrame&, DocumentLoader&);
static void frameStartedLoading(LocalFrame&);
static void frameStoppedLoading(LocalFrame&);
static void didCompleteRenderingFrame(LocalFrame&);
static void accessibilitySettingsDidChange(Page&);
+ static void didNavigateWithinPage(LocalFrame&);
#if ENABLE(DARK_MODE_CSS)
static void defaultAppearanceDidChange(Page&);
#endif
@@ -256,6 +260,7 @@ public:
static bool shouldInterceptResponse(const LocalFrame&, const ResourceResponse&);
static void interceptRequest(ResourceLoader&, Function<void(const ResourceRequest&)>&&);
static void interceptResponse(const LocalFrame&, const ResourceResponse&, ResourceLoaderIdentifier, CompletionHandler<void(const ResourceResponse&, RefPtr<FragmentedSharedBuffer>)>&&);
+ static void setStoppingLoadingDueToProcessSwap(Page*, bool);
static void addMessageToConsole(LocalFrame&, std::unique_ptr<Inspector::ConsoleMessage>);
static void addMessageToConsole(WorkerOrWorkletGlobalScope&, std::unique_ptr<Inspector::ConsoleMessage>);
@@ -281,6 +286,7 @@ public:
static void stopProfiling(WorkerOrWorkletGlobalScope&, const String& title);
static void consoleStartRecordingCanvas(CanvasRenderingContext&, JSC::JSGlobalObject&, JSC::JSObject* options);
static void consoleStopRecordingCanvas(CanvasRenderingContext&);
+ static void bindingCalled(Page& , JSC::JSGlobalObject*, const String& name, const String& arg);
static void performanceMark(ScriptExecutionContext&, const String&, std::optional<MonotonicTime>);
@@ -337,6 +343,12 @@ public:
static void layerTreeDidChange(Page*);
static void renderLayerDestroyed(Page*, const RenderLayer&);
+ static void runOpenPanel(LocalFrame*, HTMLInputElement*, bool*);
+ static void frameAttached(LocalFrame*);
+ static bool shouldBypassCSP(ScriptExecutionContext*);
+ static void willCheckNavigationPolicy(LocalFrame&);
+ static void didCheckNavigationPolicy(LocalFrame&, bool cancel);
+
static void frontendCreated();
static void frontendDeleted();
static bool hasFrontends() { return InspectorInstrumentationPublic::hasFrontends(); }
@@ -434,6 +446,7 @@ private:
static void didRecalculateStyleImpl(InstrumentingAgents&);
static void didScheduleStyleRecalculationImpl(InstrumentingAgents&, Document&);
static void applyUserAgentOverrideImpl(InstrumentingAgents&, String&);
+ static void applyPlatformOverrideImpl(InstrumentingAgents&, String&);
static void applyEmulatedMediaImpl(InstrumentingAgents&, AtomString&);
static void flexibleBoxRendererBeganLayoutImpl(InstrumentingAgents&, const RenderObject&);
@@ -448,6 +461,7 @@ private:
static void didReceiveDataImpl(InstrumentingAgents&, ResourceLoaderIdentifier, const SharedBuffer*, int encodedDataLength);
static void didFinishLoadingImpl(InstrumentingAgents&, ResourceLoaderIdentifier, DocumentLoader*, const NetworkLoadMetrics&, ResourceLoader*);
static void didFailLoadingImpl(InstrumentingAgents&, ResourceLoaderIdentifier, DocumentLoader*, const ResourceError&);
+ static void didReceiveMainResourceErrorImpl(InstrumentingAgents&, LocalFrame&, const ResourceError&);
static void willLoadXHRSynchronouslyImpl(InstrumentingAgents&);
static void didLoadXHRSynchronouslyImpl(InstrumentingAgents&);
static void scriptImportedImpl(InstrumentingAgents&, ResourceLoaderIdentifier, const String& sourceString);
@@ -458,11 +472,11 @@ private:
static void frameDetachedFromParentImpl(InstrumentingAgents&, LocalFrame&);
static void didCommitLoadImpl(InstrumentingAgents&, LocalFrame&, DocumentLoader*);
static void frameDocumentUpdatedImpl(InstrumentingAgents&, LocalFrame&);
- static void loaderDetachedFromFrameImpl(InstrumentingAgents&, DocumentLoader&);
static void frameStartedLoadingImpl(InstrumentingAgents&, LocalFrame&);
static void didCompleteRenderingFrameImpl(InstrumentingAgents&);
static void frameStoppedLoadingImpl(InstrumentingAgents&, LocalFrame&);
static void accessibilitySettingsDidChangeImpl(InstrumentingAgents&);
+ static void didNavigateWithinPageImpl(InstrumentingAgents&, LocalFrame&);
#if ENABLE(DARK_MODE_CSS)
static void defaultAppearanceDidChangeImpl(InstrumentingAgents&);
#endif
@@ -473,6 +487,7 @@ private:
static bool shouldInterceptResponseImpl(InstrumentingAgents&, const ResourceResponse&);
static void interceptRequestImpl(InstrumentingAgents&, ResourceLoader&, Function<void(const ResourceRequest&)>&&);
static void interceptResponseImpl(InstrumentingAgents&, const ResourceResponse&, ResourceLoaderIdentifier, CompletionHandler<void(const ResourceResponse&, RefPtr<FragmentedSharedBuffer>)>&&);
+ static void setStoppingLoadingDueToProcessSwapImpl(InstrumentingAgents&, bool);
static void addMessageToConsoleImpl(InstrumentingAgents&, std::unique_ptr<Inspector::ConsoleMessage>);
@@ -487,6 +502,7 @@ private:
static void stopProfilingImpl(InstrumentingAgents&, const String& title);
static void consoleStartRecordingCanvasImpl(InstrumentingAgents&, CanvasRenderingContext&, JSC::JSGlobalObject&, JSC::JSObject* options);
static void consoleStopRecordingCanvasImpl(InstrumentingAgents&, CanvasRenderingContext&);
+ static void bindingCalledImpl(InstrumentingAgents&, JSC::JSGlobalObject*, const String& name, const String& arg);
static void performanceMarkImpl(InstrumentingAgents&, const String& label, std::optional<MonotonicTime>);
static void didEnqueueFirstContentfulPaintImpl(InstrumentingAgents&);
@@ -542,6 +558,12 @@ private:
static void layerTreeDidChangeImpl(InstrumentingAgents&);
static void renderLayerDestroyedImpl(InstrumentingAgents&, const RenderLayer&);
+ static void runOpenPanelImpl(InstrumentingAgents&, HTMLInputElement*, bool*);
+ static void frameAttachedImpl(InstrumentingAgents&, LocalFrame&);
+ static bool shouldBypassCSPImpl(InstrumentingAgents&);
+ static void willCheckNavigationPolicyImpl(InstrumentingAgents&, LocalFrame&);
+ static void didCheckNavigationPolicyImpl(InstrumentingAgents&, LocalFrame&, bool cancel);
+
static InstrumentingAgents& NODELETE instrumentingAgents(Page&);
static InstrumentingAgents& NODELETE instrumentingAgents(const LocalFrame&);
static InstrumentingAgents& NODELETE instrumentingAgents(const LocalFrameView&);
@@ -1078,6 +1100,12 @@ inline void InspectorInstrumentation::applyUserAgentOverride(LocalFrame& frame,
applyUserAgentOverrideImpl(instrumentingAgents(frame), userAgent);
}
+inline void InspectorInstrumentation::applyPlatformOverride(LocalFrame& frame, String& platform)
+{
+ FAST_RETURN_IF_NO_FRONTENDS(void());
+ applyPlatformOverrideImpl(instrumentingAgents(frame), platform);
+}
+
inline void InspectorInstrumentation::applyEmulatedMedia(LocalFrame& frame, AtomString& media)
{
FAST_RETURN_IF_NO_FRONTENDS(void());
@@ -1176,6 +1204,12 @@ inline void InspectorInstrumentation::didFailLoading(ServiceWorkerGlobalScope& g
didFailLoadingImpl(instrumentingAgents(globalScope), identifier, nullptr, error);
}
+inline void InspectorInstrumentation::didReceiveMainResourceError(LocalFrame& frame, const ResourceError& error)
+{
+ FAST_RETURN_IF_NO_FRONTENDS(void());
+ didReceiveMainResourceErrorImpl(instrumentingAgents(frame), frame, error);
+}
+
inline void InspectorInstrumentation::continueAfterXFrameOptionsDenied(LocalFrame& frame, ResourceLoaderIdentifier identifier, DocumentLoader& loader, const ResourceResponse& response)
{
// Treat the same as didReceiveResponse.
@@ -1259,12 +1293,6 @@ inline void InspectorInstrumentation::frameDocumentUpdated(LocalFrame& frame)
frameDocumentUpdatedImpl(instrumentingAgents(frame), frame);
}
-inline void InspectorInstrumentation::loaderDetachedFromFrame(LocalFrame& frame, DocumentLoader& loader)
-{
- FAST_RETURN_IF_NO_FRONTENDS(void());
- loaderDetachedFromFrameImpl(instrumentingAgents(frame), loader);
-}
-
inline void InspectorInstrumentation::frameStartedLoading(LocalFrame& frame)
{
FAST_RETURN_IF_NO_FRONTENDS(void());
@@ -1289,6 +1317,12 @@ inline void InspectorInstrumentation::accessibilitySettingsDidChange(Page& page)
accessibilitySettingsDidChangeImpl(instrumentingAgents(page));
}
+inline void InspectorInstrumentation::didNavigateWithinPage(LocalFrame& frame)
+{
+ FAST_RETURN_IF_NO_FRONTENDS(void());
+ didNavigateWithinPageImpl(instrumentingAgents(frame), frame);
+}
+
#if ENABLE(DARK_MODE_CSS)
inline void InspectorInstrumentation::defaultAppearanceDidChange(Page& page)
{
@@ -1338,6 +1372,13 @@ inline void InspectorInstrumentation::interceptResponse(const LocalFrame& frame,
interceptResponseImpl(instrumentingAgents(frame), response, identifier, WTF::move(handler));
}
+inline void InspectorInstrumentation::setStoppingLoadingDueToProcessSwap(Page* page, bool value)
+{
+ ASSERT(InspectorInstrumentationPublic::hasFrontends());
+ if (auto* agents = instrumentingAgents(page))
+ setStoppingLoadingDueToProcessSwapImpl(*agents, value);
+}
+
inline void InspectorInstrumentation::didDispatchDOMStorageEvent(Page& page, const String& key, const String& oldValue, const String& newValue, StorageType storageType, const SecurityOrigin& securityOrigin)
{
FAST_RETURN_IF_NO_FRONTENDS(void());
@@ -1681,6 +1722,11 @@ inline void InspectorInstrumentation::didEnqueueLargestContentfulPaint(ScriptExe
didEnqueueLargestContentfulPaintImpl(*agents, entry);
}
+inline void InspectorInstrumentation::bindingCalled(Page& page, JSC::JSGlobalObject* globalObject, const String& name, const String& arg)
+{
+ bindingCalledImpl(instrumentingAgents(page), globalObject, name, arg);
+}
+
inline void InspectorInstrumentation::didRequestAnimationFrame(ScriptExecutionContext& scriptExecutionContext, int callbackId)
{
FAST_RETURN_IF_NO_FRONTENDS(void());
@@ -1737,6 +1783,39 @@ inline void InspectorInstrumentation::renderLayerDestroyed(Page* page, const Ren
renderLayerDestroyedImpl(*agents, renderLayer);
}
+inline void InspectorInstrumentation::runOpenPanel(LocalFrame* frame, HTMLInputElement* element, bool* intercept)
+{
+ FAST_RETURN_IF_NO_FRONTENDS(void());
+ runOpenPanelImpl(instrumentingAgents(*frame), element, intercept);
+}
+
+inline void InspectorInstrumentation::frameAttached(LocalFrame* frame)
+{
+ FAST_RETURN_IF_NO_FRONTENDS(void());
+ if (auto* agents = instrumentingAgents(frame))
+ frameAttachedImpl(*agents, *frame);
+}
+
+inline bool InspectorInstrumentation::shouldBypassCSP(ScriptExecutionContext* context)
+{
+ FAST_RETURN_IF_NO_FRONTENDS(false);
+ if (auto* agents = instrumentingAgents(context))
+ return shouldBypassCSPImpl(*agents);
+ return false;
+}
+
+inline void InspectorInstrumentation::willCheckNavigationPolicy(LocalFrame& frame)
+{
+ FAST_RETURN_IF_NO_FRONTENDS(void());
+ willCheckNavigationPolicyImpl(instrumentingAgents(frame), frame);
+}
+
+inline void InspectorInstrumentation::didCheckNavigationPolicy(LocalFrame& frame, bool cancel)
+{
+ FAST_RETURN_IF_NO_FRONTENDS(void());
+ didCheckNavigationPolicyImpl(instrumentingAgents(frame), frame, cancel);
+}
+
inline InstrumentingAgents* InspectorInstrumentation::instrumentingAgents(ScriptExecutionContext* context)
{
return context ? instrumentingAgents(*context) : nullptr;
diff --git a/Source/WebCore/inspector/InspectorInstrumentationWebKit.cpp b/Source/WebCore/inspector/InspectorInstrumentationWebKit.cpp
index f866893f2d6d9748b5f58ad28db0bb06398c6f48..294f450025f595b44a3e130c738291e6b45de740 100644
--- a/Source/WebCore/inspector/InspectorInstrumentationWebKit.cpp
+++ b/Source/WebCore/inspector/InspectorInstrumentationWebKit.cpp
@@ -50,4 +50,9 @@ void InspectorInstrumentationWebKit::interceptResponseInternal(const LocalFrame&
InspectorInstrumentation::interceptResponse(frame, response, identifier, WTF::move(handler));
}
+void InspectorInstrumentationWebKit::setStoppingLoadingDueToProcessSwapInternal(Page* page, bool value)
+{
+ InspectorInstrumentation::setStoppingLoadingDueToProcessSwap(page, value);
+}
+
} // namespace WebCore
diff --git a/Source/WebCore/inspector/InspectorInstrumentationWebKit.h b/Source/WebCore/inspector/InspectorInstrumentationWebKit.h
index 01ad196099f09a89717830cd70dded3b495cf5f5..c9d2e97c6f5f5e6b0a8f70c31af947ef2e72af8a 100644
--- a/Source/WebCore/inspector/InspectorInstrumentationWebKit.h
+++ b/Source/WebCore/inspector/InspectorInstrumentationWebKit.h
@@ -33,6 +33,7 @@
namespace WebCore {
class LocalFrame;
+class Page;
class ResourceLoader;
class ResourceRequest;
class ResourceResponse;
@@ -44,12 +45,14 @@ public:
static bool shouldInterceptResponse(const LocalFrame*, const ResourceResponse&);
static void interceptRequest(ResourceLoader&, Function<void(const ResourceRequest&)>&&);
static void interceptResponse(const LocalFrame*, const ResourceResponse&, ResourceLoaderIdentifier, CompletionHandler<void(const ResourceResponse&, RefPtr<FragmentedSharedBuffer>)>&&);
+ static void setStoppingLoadingDueToProcessSwap(Page*, bool);
private:
static bool shouldInterceptRequestInternal(const ResourceLoader&);
static bool shouldInterceptResponseInternal(const LocalFrame&, const ResourceResponse&);
static void interceptRequestInternal(ResourceLoader&, Function<void(const ResourceRequest&)>&&);
static void interceptResponseInternal(const LocalFrame&, const ResourceResponse&, ResourceLoaderIdentifier, CompletionHandler<void(const ResourceResponse&, RefPtr<FragmentedSharedBuffer>)>&&);
+ static void setStoppingLoadingDueToProcessSwapInternal(Page*, bool);
};
inline bool InspectorInstrumentationWebKit::shouldInterceptRequest(const ResourceLoader& loader)
@@ -79,4 +82,10 @@ inline void InspectorInstrumentationWebKit::interceptResponse(const LocalFrame*
interceptResponseInternal(*frame, response, identifier, WTF::move(handler));
}
+inline void InspectorInstrumentationWebKit::setStoppingLoadingDueToProcessSwap(Page* page, bool value)
+{
+ FAST_RETURN_IF_NO_FRONTENDS(void());
+ setStoppingLoadingDueToProcessSwapInternal(page, value);
+}
+
}
diff --git a/Source/WebCore/inspector/PageInspectorController.cpp b/Source/WebCore/inspector/PageInspectorController.cpp
index 4fa92ae7d7c2f6e501eecb90691c3dca65e4482e..21dbf683927dec650570a540f0fcd5be6538afa5 100644
--- a/Source/WebCore/inspector/PageInspectorController.cpp
+++ b/Source/WebCore/inspector/PageInspectorController.cpp
@@ -291,6 +291,8 @@ void PageInspectorController::disconnectFrontend(FrontendChannel& frontendChanne
// Unplug all instrumentations since they aren't needed now.
InspectorInstrumentation::unregisterInstrumentingAgents(m_instrumentingAgents.get());
+
+ m_pauseOnStart = PauseCondition::DONT_PAUSE;
}
m_inspectorBackendClient->frontendCountChanged(m_frontendRouter->frontendCount());
@@ -305,6 +307,8 @@ void PageInspectorController::disconnectAllFrontends()
// The frontend should call setInspectorFrontendClient(nullptr) under closeWindow().
ASSERT(!m_inspectorFrontendClient);
+ m_pauseOnStart = PauseCondition::DONT_PAUSE;
+
if (!m_frontendRouter->hasFrontends())
return;
@@ -384,8 +388,8 @@ void PageInspectorController::inspect(Node* node)
if (!enabled())
return;
- if (!hasRemoteFrontend())
- show();
+ // HACK: Always attempt to show inspector even if there is a remote connection.
+ show();
CheckedRef { ensureDOMAgent() }->inspect(node);
}
@@ -523,4 +527,34 @@ void PageInspectorController::didComposite(LocalFrame& frame)
InspectorInstrumentation::didComposite(frame);
}
+void PageInspectorController::pauseOnStart(PauseCondition condition)
+{
+ m_pauseOnStart = condition;
+}
+
+void PageInspectorController::resumeIfPausedInNewWindow()
+{
+ m_pauseOnStart = PauseCondition::DONT_PAUSE;
+}
+
+void PageInspectorController::didFinishPageCreation()
+{
+ if (m_pauseOnStart == PauseCondition::WHEN_CREATION_FINISHED)
+ runLoopWhilePaused();
+}
+
+void PageInspectorController::didShowPage()
+{
+ if (m_pauseOnStart == PauseCondition::WHEN_SHOWN)
+ runLoopWhilePaused();
+}
+
+void PageInspectorController::runLoopWhilePaused()
+{
+ while (m_pauseOnStart != PauseCondition::DONT_PAUSE) {
+ if (RunLoop::cycle() == RunLoop::CycleResult::Stop)
+ break;
+ }
+}
+
} // namespace WebCore
diff --git a/Source/WebCore/inspector/PageInspectorController.h b/Source/WebCore/inspector/PageInspectorController.h
index 1418886b19d5310d76deef334ae994ff8afd0562..6217b778b6c0bd73d7da6f9b8ef1454dda156806 100644
--- a/Source/WebCore/inspector/PageInspectorController.h
+++ b/Source/WebCore/inspector/PageInspectorController.h
@@ -117,6 +117,12 @@ public:
WEBCORE_EXPORT void willComposite(LocalFrame&);
WEBCORE_EXPORT void didComposite(LocalFrame&);
+ enum class PauseCondition { DONT_PAUSE, WHEN_SHOWN, WHEN_CREATION_FINISHED };
+ WEBCORE_EXPORT void pauseOnStart(PauseCondition);
+ WEBCORE_EXPORT void resumeIfPausedInNewWindow();
+ WEBCORE_EXPORT void didShowPage();
+ WEBCORE_EXPORT void didFinishPageCreation();
+
// Testing support.
bool isUnderTest() const { return m_isUnderTest; }
void setIsUnderTest(bool isUnderTest) { m_isUnderTest = isUnderTest; }
@@ -153,6 +159,7 @@ private:
PageAgentContext pageAgentContext();
void createLazyAgents();
+ void runLoopWhilePaused();
WeakRef<Page> m_page;
const Ref<InstrumentingAgents> m_instrumentingAgents;
@@ -177,6 +184,7 @@ private:
bool m_isAutomaticInspection { false };
bool m_pauseAfterInitialization = { false };
bool m_didCreateLazyAgents { false };
+ PauseCondition m_pauseOnStart { PauseCondition::DONT_PAUSE };
};
} // namespace WebCore
diff --git a/Source/WebCore/inspector/agents/InspectorDOMAgent.cpp b/Source/WebCore/inspector/agents/InspectorDOMAgent.cpp
index aee336fcc014831222e12d1806ffc0052e0daed3..88d87a57acf14678214918c5c7a44063951f8b8f 100644
--- a/Source/WebCore/inspector/agents/InspectorDOMAgent.cpp
+++ b/Source/WebCore/inspector/agents/InspectorDOMAgent.cpp
@@ -54,6 +54,7 @@
#include "Cookie.h"
#include "CookieJar.h"
#include "CustomElementRegistry.h"
+#include "DirectoryFileListCreator.h"
#include "DOMEditor.h"
#include "DOMException.h"
#include "DOMPatchSupport.h"
@@ -66,10 +67,15 @@
#include "Event.h"
#include "EventListener.h"
#include "EventNames.h"
+#include <FileChooser.h>
+#include "File.h"
+#include "FileList.h"
+#include "FloatQuad.h"
#include "FrameInlines.h"
#include "FrameTree.h"
#include "HTMLElement.h"
#include "HTMLFrameOwnerElement.h"
+#include "HTMLInputElement.h"
#include "HTMLMediaElement.h"
#include "HTMLNames.h"
#include "HTMLScriptElement.h"
@@ -107,12 +113,14 @@
#include "Pasteboard.h"
#include "PseudoElement.h"
#include "RenderGrid.h"
+#include "RenderLayer.h"
#include "RenderObject.h"
#include "RenderStyle.h"
#include "RenderStyleConstants.h"
#include "ScriptController.h"
#include "SelectorChecker.h"
#include "ShadowRoot.h"
+#include "SharedBuffer.h"
#include "StaticNodeList.h"
#include "StyleProperties.h"
#include "StyleResolver.h"
@@ -156,7 +164,8 @@ using namespace HTMLNames;
static const size_t maxTextSize = 10000;
static const char16_t horizontalEllipsisUTF16[] = { horizontalEllipsis, 0 };
-static std::optional<Color> parseColor(RefPtr<JSON::Object>&& colorObject)
+// static
+std::optional<Color> InspectorDOMAgent::parseColor(RefPtr<JSON::Object>&& colorObject)
{
if (!colorObject)
return std::nullopt;
@@ -175,7 +184,7 @@ static std::optional<Color> parseColor(RefPtr<JSON::Object>&& colorObject)
static std::optional<Color> parseRequiredConfigColor(const String& fieldName, JSON::Object& configObject)
{
- return parseColor(configObject.getObject(fieldName));
+ return InspectorDOMAgent::parseColor(configObject.getObject(fieldName));
}
static Color parseOptionalConfigColor(const String& fieldName, JSON::Object& configObject)
@@ -202,6 +211,20 @@ static bool parseQuad(Ref<JSON::Array>&& quadArray, FloatQuad* quad)
return true;
}
+static void CollectQuads(Node* node, Vector<FloatQuad>& quads)
+{
+ Element* element = dynamicDowncast<Element>(node);
+ if (element && element->hasDisplayContents()) {
+ // display:contents elements do not render themselves, so we look into children.
+ for (auto& child : composedTreeChildren(*element))
+ CollectQuads(&child, quads);
+ return;
+ }
+ RenderObject* renderer = node->renderer();
+ if (renderer)
+ renderer->absoluteQuads(quads);
+}
+
class RevalidateStyleAttributeTask final : public CanMakeCheckedPtr<RevalidateStyleAttributeTask> {
WTF_MAKE_TZONE_ALLOCATED(RevalidateStyleAttributeTask);
WTF_OVERRIDE_DELETE_FOR_CHECKED_PTR(RevalidateStyleAttributeTask);
@@ -485,6 +508,20 @@ Node* InspectorDOMAgent::assertNode(Inspector::Protocol::ErrorString& errorStrin
return node.unsafeGet();
}
+Node* InspectorDOMAgent::assertNode(Inspector::Protocol::ErrorString& errorString, std::optional<Inspector::Protocol::DOM::NodeId>&& nodeId, const String& objectId)
+{
+ Node* node = nullptr;
+ if (nodeId) {
+ node = assertNode(errorString, *nodeId);
+ } else if (!!objectId) {
+ node = nodeForObjectId(objectId);
+ if (!node)
+ errorString = "Missing node for given objectId"_s;
+ } else
+ errorString = "Either nodeId or objectId must be specified"_s;
+ return node;
+}
+
Document* InspectorDOMAgent::assertDocument(Inspector::Protocol::ErrorString& errorString, Inspector::Protocol::DOM::NodeId nodeId)
{
RefPtr node = assertNode(errorString, nodeId);
@@ -1602,15 +1639,7 @@ Inspector::Protocol::ErrorStringOr<void> InspectorDOMAgent::highlightNode(std::o
{
Inspector::Protocol::ErrorString errorString;
- RefPtr<Node> node;
- if (nodeId)
- node = assertNode(errorString, *nodeId);
- else if (!!objectId) {
- node = nodeForObjectId(objectId);
- errorString = "Missing node for given objectId"_s;
- } else
- errorString = "Either nodeId or objectId must be specified"_s;
-
+ RefPtr<Node> node = assertNode(errorString, WTF::move(nodeId), objectId);
if (!node)
return makeUnexpected(errorString);
@@ -1861,15 +1890,159 @@ Inspector::Protocol::ErrorStringOr<void> InspectorDOMAgent::setInspectedNode(Ins
return { };
}
-Inspector::Protocol::ErrorStringOr<Ref<Inspector::Protocol::Runtime::RemoteObject>> InspectorDOMAgent::resolveNode(Inspector::Protocol::DOM::NodeId nodeId, const String& objectGroup)
+static FloatPoint contentsToRootView(LocalFrameView& containingView, const FloatPoint& point)
+{
+ return containingView.convertToRootView(point - toFloatSize(containingView.documentScrollPositionRelativeToViewOrigin()));
+}
+
+static void frameQuadToViewport(LocalFrameView& containingView, FloatQuad& quad, Page& inspectedPage)
+{
+ float pageScaleFactor = inspectedPage.pageScaleFactor();
+ auto mainFrame = inspectedPage.localMainFrame();
+ float scale = pageScaleFactor * mainFrame->pageZoomFactor();
+
+ // Return css (not dip) coordinates by scaling back.
+ quad.setP1(contentsToRootView(containingView, quad.p1()).scaled(1 / scale));
+ quad.setP2(contentsToRootView(containingView, quad.p2()).scaled(1 / scale));
+ quad.setP3(contentsToRootView(containingView, quad.p3()).scaled(1 / scale));
+ quad.setP4(contentsToRootView(containingView, quad.p4()).scaled(1 / scale));
+}
+
+static Ref<Inspector::Protocol::DOM::Quad> buildObjectForQuad(const FloatQuad& quad)
+{
+ auto result = Inspector::Protocol::DOM::Quad::create();
+ result->addItem(quad.p1().x());
+ result->addItem(quad.p1().y());
+ result->addItem(quad.p2().x());
+ result->addItem(quad.p2().y());
+ result->addItem(quad.p3().x());
+ result->addItem(quad.p3().y());
+ result->addItem(quad.p4().x());
+ result->addItem(quad.p4().y());
+ return result;
+}
+
+static Ref<JSON::ArrayOf<Inspector::Protocol::DOM::Quad>> buildArrayOfQuads(const Vector<FloatQuad>& quads)
+{
+ auto result = JSON::ArrayOf<Inspector::Protocol::DOM::Quad>::create();
+ for (const auto& quad : quads)
+ result->addItem(buildObjectForQuad(quad));
+ return result;
+}
+
+Inspector::Protocol::ErrorStringOr<std::tuple<String /* contentFrameId */, String /* ownerFrameId */>> InspectorDOMAgent::describeNode(const String& objectId)
+{
+ Node* node = nodeForObjectId(objectId);
+ if (!node)
+ return makeUnexpected("Node not found"_s);
+
+ auto* pageAgent = m_instrumentingAgents->enabledPageAgent();
+ if (!pageAgent)
+ return makeUnexpected("Page agent must be enabled"_s);
+
+ String ownerFrameId;
+ String frameId = pageAgent->frameId(node->document().frame());
+ if (!frameId.isEmpty())
+ ownerFrameId = frameId;
+
+ String contentFrameId;
+ if (is<HTMLFrameOwnerElement>(*node)) {
+ const auto& frameOwner = downcast<HTMLFrameOwnerElement>(*node);
+ // TODO(playwright): Unnecessary downcast to LocalFrame?
+ String frameId = pageAgent->frameId(dynamicDowncast<LocalFrame>(frameOwner.contentFrame()));
+ if (!frameId.isEmpty())
+ contentFrameId = frameId;
+ }
+
+ return { { contentFrameId, ownerFrameId } };
+}
+
+Inspector::Protocol::ErrorStringOr<void> InspectorDOMAgent::scrollIntoViewIfNeeded(const String& objectId, RefPtr<JSON::Object>&& rect)
+{
+ Node* node = nodeForObjectId(objectId);
+ if (!node)
+ return makeUnexpected("Node not found"_s);
+
+ m_inspectedPage->isolatedUpdateRendering();
+ if (!node->isConnected())
+ return makeUnexpected("Node is detached from document"_s);
+
+ RenderObject* renderer = node->renderer();
+ auto* containerNode = dynamicDowncast<ContainerNode>(*node);
+ if (!renderer && containerNode) {
+ // Find the first descendant with a renderer, to account for
+ // containers without a renderer like display:contents elements.
+ for (auto& descendant : composedTreeDescendants(*containerNode)) {
+ renderer = descendant.renderer();
+ if (renderer)
+ break;
+ }
+ }
+ if (!renderer)
+ return makeUnexpected("Node does not have a layout object"_s);
+
+ bool insideFixed = false;
+ LayoutRect absoluteBounds = renderer->absoluteBoundingBoxRect(true, &insideFixed);
+ if (rect) {
+ std::optional<double> x = rect->getDouble("x"_s);
+ std::optional<double> y = rect->getDouble("y"_s);
+ std::optional<double> width = rect->getDouble("width"_s);
+ std::optional<double> height = rect->getDouble("height"_s);
+ if (!x || !y || !width || !height)
+ return makeUnexpected("Malformed rect"_s);
+
+ absoluteBounds.setX(absoluteBounds.x() + LayoutUnit(*x));
+ absoluteBounds.setY(absoluteBounds.y() + LayoutUnit(*y));
+ absoluteBounds.setWidth(LayoutUnit(std::max(*width, 1.0)));
+ absoluteBounds.setHeight(LayoutUnit(std::max(*height, 1.0)));
+ }
+ ScrollAlignment alignment = ScrollAlignment::alignCenterIfNeeded;
+ alignment.m_enableLegacyHorizontalVisibilityThreshold = false; // Disable RenderLayer minium horizontal scroll threshold.
+ LocalFrameView::scrollRectToVisible(absoluteBounds, *renderer, insideFixed, { SelectionRevealMode::Reveal, alignment, alignment, ShouldAllowCrossOriginScrolling::Yes, ScrollBehavior::Instant });
+ return { };
+}
+
+Inspector::Protocol::ErrorStringOr<Ref<JSON::ArrayOf<Inspector::Protocol::DOM::Quad>>> InspectorDOMAgent::getContentQuads(const String& objectId)
+{
+ Node* node = nodeForObjectId(objectId);
+ if (!node)
+ return makeUnexpected("Node not found"_s);
+
+ // Ensure quads are up to date.
+ m_inspectedPage->isolatedUpdateRendering();
+
+ LocalFrameView* containingView = node->document().view();
+ if (!containingView)
+ return makeUnexpected("Internal error: no containing view"_s);
+
+ Vector<FloatQuad> quads;
+ CollectQuads(node, quads);
+ for (auto& quad : quads)
+ frameQuadToViewport(*containingView, quad, m_inspectedPage.get());
+ return buildArrayOfQuads(quads);
+}
+
+Inspector::Protocol::ErrorStringOr<Ref<Inspector::Protocol::Runtime::RemoteObject>> InspectorDOMAgent::resolveNode(std::optional<Inspector::Protocol::DOM::NodeId>&& nodeId, const String& objectId, const Inspector::Protocol::Network::FrameId& frameId, std::optional<int>&& contextId, const String& objectGroup)
{
Inspector::Protocol::ErrorString errorString;
+ RefPtr<Node> node = nullptr;
+ if (!!frameId) {
+ auto* pageAgent = m_instrumentingAgents->enabledPageAgent();
+ if (!pageAgent)
+ return makeUnexpected("Page domain must be enabled"_s);
- RefPtr node = assertNode(errorString, nodeId);
+ auto* frame = pageAgent->assertFrame(errorString, frameId);
+ if (!frame)
+ return makeUnexpected(errorString);
+
+ node = frame->ownerElement();
+ } else {
+ node = assertNode(errorString, WTF::move(nodeId), objectId);
+ }
if (!node)
return makeUnexpected(errorString);
- auto object = resolveNode(node.get(), objectGroup);
+ auto object = resolveNode(node.get(), objectGroup, WTF::move(contextId));
if (!object)
return makeUnexpected("Missing injected script for given nodeId"_s);
@@ -3133,7 +3306,7 @@ Inspector::Protocol::ErrorStringOr<Inspector::Protocol::DOM::NodeId> InspectorDO
return makeUnexpected("Missing node for given path"_s);
}
-RefPtr<Inspector::Protocol::Runtime::RemoteObject> InspectorDOMAgent::resolveNode(Node* node, const String& objectGroup)
+RefPtr<Inspector::Protocol::Runtime::RemoteObject> InspectorDOMAgent::resolveNode(Node* node, const String& objectGroup, std::optional<int>&& contextId)
{
RefPtr document = &node->document();
if (auto* templateHost = document->templateDocumentHost())
@@ -3142,12 +3315,18 @@ RefPtr<Inspector::Protocol::Runtime::RemoteObject> InspectorDOMAgent::resolveNod
if (!frame)
return nullptr;
- auto& globalObject = mainWorldGlobalObject(*frame);
- auto injectedScript = m_injectedScriptManager->injectedScriptFor(&globalObject);
+ InjectedScript injectedScript;
+ if (contextId) {
+ injectedScript = m_injectedScriptManager->injectedScriptForId(*contextId);
+ } else {
+ auto& globalObject = mainWorldGlobalObject(*frame);
+ injectedScript = m_injectedScriptManager->injectedScriptFor(&globalObject);
+ }
+
if (injectedScript.hasNoValue())
return nullptr;
- return injectedScript.wrapObject(nodeAsScriptValue(globalObject, node), objectGroup);
+ return injectedScript.wrapObject(nodeAsScriptValue(*injectedScript.globalObject(), node), objectGroup);
}
Node* InspectorDOMAgent::scriptValueAsNode(JSC::JSValue value)
@@ -3301,4 +3480,53 @@ Inspector::Protocol::ErrorStringOr<Ref<Inspector::Protocol::DOM::MediaStats>> In
#endif
}
+void InspectorDOMAgent::setInputFiles(const String& objectId, Ref<JSON::Array>&& paths, Ref<SetInputFilesCallback>&& callback) {
+ InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(objectId);
+ if (injectedScript.hasNoValue()) {
+ callback->sendFailure("Can not find element's context for given id"_s);
+ return;
+ }
+
+ Node* node = scriptValueAsNode(injectedScript.findObjectById(objectId));
+ if (!node) {
+ callback->sendFailure("Can not find element for given id"_s);
+ return;
+ }
+
+ if (node->nodeType() != NodeType::Element || node->nodeName() != "INPUT"_s) {
+ callback->sendFailure("Not an input node"_s);
+ return;
+ }
+
+ HTMLInputElement* element = static_cast<HTMLInputElement*>(node);
+ Vector<Ref<File>> fileObjects;
+ if (element->hasAttributeWithoutSynchronization(webkitdirectoryAttr)) {
+ auto directoryFileListCreator = DirectoryFileListCreator::create([element = RefPtr { element }, callback = WTF::move(callback)](Ref<FileList>&& fileList) mutable {
+ ASSERT(isMainThread());
+ element->setFiles(WTF::move(fileList));
+ callback->sendSuccess();
+ });
+ Vector<FileChooserFileInfo> fileChooserFiles;
+ for (size_t i = 0; i < paths->length(); ++i) {
+ fileChooserFiles.append(FileChooserFileInfo { paths->get(i)->asString(), nullString(), { } });
+ }
+ directoryFileListCreator->start(m_document.get(), fileChooserFiles);
+ } else {
+ for (unsigned i = 0; i < paths->length(); ++i) {
+ RefPtr<JSON::Value> item = paths->get(i);
+ String path = item->asString();
+ if (path.isEmpty()) {
+ callback->sendFailure("Invalid file path"_s);
+ return;
+ }
+
+ ScriptExecutionContext* context = element->scriptExecutionContext();
+ fileObjects.append(File::create(context, path));
+ }
+ RefPtr<FileList> fileList = FileList::create(WTF::move(fileObjects));
+ element->setFiles(WTF::move(fileList));
+ callback->sendSuccess();
+ }
+}
+
} // namespace WebCore
diff --git a/Source/WebCore/inspector/agents/InspectorDOMAgent.h b/Source/WebCore/inspector/agents/InspectorDOMAgent.h
index 8f83cc5eaca550bbcea167c98b944f704d9a9cb1..2f655b6534f1428a23907e1cada99c244a9a2c98 100644
--- a/Source/WebCore/inspector/agents/InspectorDOMAgent.h
+++ b/Source/WebCore/inspector/agents/InspectorDOMAgent.h
@@ -62,6 +62,7 @@ namespace WebCore {
class AXCoreObject;
class CharacterData;
+class Color;
class DOMEditor;
class Document;
class Element;
@@ -98,6 +99,7 @@ public:
static String toErrorString(Exception&&);
static String documentURLString(Document*);
+ static std::optional<Color> parseColor(RefPtr<JSON::Object>&&);
// We represent embedded doms as a part of the same hierarchy. Hence we treat children of frame owners differently.
// We also skip whitespace text nodes conditionally. Following methods encapsulate these specifics.
@@ -143,7 +145,7 @@ public:
Inspector::Protocol::ErrorStringOr<std::tuple<String /* searchId */, int /* resultCount */>> performSearch(const String& query, RefPtr<JSON::Array>&& nodeIds, std::optional<bool>&& caseSensitive);
Inspector::Protocol::ErrorStringOr<Ref<JSON::ArrayOf<Inspector::Protocol::DOM::NodeId>>> getSearchResults(const String& searchId, int fromIndex, int toIndex);
Inspector::Protocol::ErrorStringOr<void> discardSearchResults(const String& searchId);
- Inspector::Protocol::ErrorStringOr<Ref<Inspector::Protocol::Runtime::RemoteObject>> resolveNode(Inspector::Protocol::DOM::NodeId, const String& objectGroup);
+ Inspector::Protocol::ErrorStringOr<Ref<Inspector::Protocol::Runtime::RemoteObject>> resolveNode(std::optional<Inspector::Protocol::DOM::NodeId>&& nodeId, const String& objectId, const Inspector::Protocol::Network::FrameId& frameId, std::optional<int>&& contextId, const String& objectGroup);
Inspector::Protocol::ErrorStringOr<Ref<JSON::ArrayOf<String>>> getAttributes(Inspector::Protocol::DOM::NodeId);
#if PLATFORM(IOS_FAMILY)
Inspector::Protocol::ErrorStringOr<void> setInspectModeEnabled(bool, RefPtr<JSON::Object>&& highlightConfig, RefPtr<JSON::Object>&& gridOverlayConfig, RefPtr<JSON::Object>&& flexOverlayConfig);
@@ -180,6 +182,10 @@ public:
Inspector::Protocol::ErrorStringOr<void> setInspectedNode(Inspector::Protocol::DOM::NodeId);
Inspector::Protocol::ErrorStringOr<void> setAllowEditingUserAgentShadowTrees(bool);
Inspector::Protocol::ErrorStringOr<Ref<Inspector::Protocol::DOM::MediaStats>> getMediaStats(Inspector::Protocol::DOM::NodeId);
+ Inspector::Protocol::ErrorStringOr<std::tuple<String /* contentFrameId */, String /* ownerFrameId */>> describeNode(const String& objectId);
+ Inspector::Protocol::ErrorStringOr<void> scrollIntoViewIfNeeded(const String& objectId, RefPtr<JSON::Object>&& rect);
+ Inspector::Protocol::ErrorStringOr<Ref<JSON::ArrayOf<Inspector::Protocol::DOM::Quad>>> getContentQuads(const String& objectId);
+ void setInputFiles(const String& objectId, Ref<JSON::Array>&& paths, Ref<SetInputFilesCallback>&& callback);
// InspectorInstrumentation
Inspector::Protocol::DOM::NodeId identifierForNode(Node&);
@@ -221,7 +227,7 @@ public:
Node* nodeForId(Inspector::Protocol::DOM::NodeId);
Inspector::Protocol::DOM::NodeId boundNodeId(const Node*);
- RefPtr<Inspector::Protocol::Runtime::RemoteObject> resolveNode(Node*, const String& objectGroup);
+ RefPtr<Inspector::Protocol::Runtime::RemoteObject> resolveNode(Node*, const String& objectGroup, std::optional<int>&& contextId);
bool handleMousePress();
void mouseDidMoveOverElement(const HitTestResult&, OptionSet<PlatformEventModifier>);
void inspect(Node*);
@@ -233,12 +239,15 @@ public:
void reset();
Node* assertNode(Inspector::Protocol::ErrorString&, Inspector::Protocol::DOM::NodeId);
+ Node* assertNode(Inspector::Protocol::ErrorString&, std::optional<Inspector::Protocol::DOM::NodeId>&& nodeId, const String& objectId);
Element* assertElement(Inspector::Protocol::ErrorString&, Inspector::Protocol::DOM::NodeId);
Document* assertDocument(Inspector::Protocol::ErrorString&, Inspector::Protocol::DOM::NodeId);
RefPtr<JSC::Breakpoint> breakpointForEventListener(EventTarget&, const AtomString& eventType, EventListener&, bool capture);
Inspector::Protocol::DOM::EventListenerId idForEventListener(EventTarget&, const AtomString& eventType, EventListener&, bool capture);
+ Node* nodeForObjectId(const Inspector::Protocol::Runtime::RemoteObjectId&);
+
private:
#if ENABLE(VIDEO)
void mediaMetricsTimerFired();
@@ -268,7 +277,6 @@ private:
void processAccessibilityChildren(AXCoreObject&, JSON::ArrayOf<Inspector::Protocol::DOM::NodeId>&);
RefPtr<Node> nodeForPath(const String& path);
- Node* nodeForObjectId(const Inspector::Protocol::Runtime::RemoteObjectId&);
void discardBindings();
diff --git a/Source/WebCore/inspector/agents/InspectorNetworkAgent.cpp b/Source/WebCore/inspector/agents/InspectorNetworkAgent.cpp
index dd164a0c7161396ee21bc3e1e4f7889f5ddbb770..58a528c6ac0efea4b383688d5369606013282075 100644
--- a/Source/WebCore/inspector/agents/InspectorNetworkAgent.cpp
+++ b/Source/WebCore/inspector/agents/InspectorNetworkAgent.cpp
@@ -62,6 +62,7 @@
#include "LocalFrame.h"
#include "MIMETypeRegistry.h"
#include "MemoryCache.h"
+#include "NetworkStateNotifier.h"
#include "Page.h"
#include "PlatformStrategies.h"
#include "ProgressTracker.h"
@@ -275,8 +276,8 @@ static Ref<Inspector::Protocol::Network::Request> buildObjectForResourceRequest(
.release();
if (request.httpBody() && !request.httpBody()->isEmpty()) {
- auto bytes = request.httpBody()->flatten();
- requestObject->setPostData(String::fromUTF8WithLatin1Fallback(bytes.span()));
+ Vector<uint8_t> bytes = request.httpBody()->flatten();
+ requestObject->setPostData(base64EncodeToString(bytes));
}
if (resourceLoader) {
@@ -328,6 +329,8 @@ RefPtr<Inspector::Protocol::Network::Response> InspectorNetworkAgent::buildObjec
.setSource(responseSource(response.source()))
.release();
+ responseObject->setRequestHeaders(buildObjectForHeaders(response.m_httpRequestHeaderFields));
+
if (resourceLoader) {
auto* metrics = response.deprecatedNetworkLoadMetricsOrNull();
responseObject->setTiming(buildObjectForTiming(metrics ? *metrics : NetworkLoadMetrics::emptyMetrics(), *resourceLoader));
@@ -522,7 +525,7 @@ void InspectorNetworkAgent::didReceiveResponse(ResourceLoaderIdentifier identifi
// 'Raw' is used for loading worker scripts, and those should stay as 'Script' and not change to 'XHR' type.
if (type != newType && newType != ResourceType::XHR && newType != ResourceType::Other)
type = newType;
-
+
// FIXME: <webkit.org/b/216125> 304 Not Modified responses for XHR/Fetch do not have all their information from the cache.
if (isNotModified && (type == ResourceType::XHR || type == ResourceType::Fetch) && (!cachedResource || !cachedResource->encodedSize())) {
if (auto previousResourceData = m_resourcesData->dataForURL(response.url().string())) {
@@ -533,12 +536,12 @@ void InspectorNetworkAgent::didReceiveResponse(ResourceLoaderIdentifier identifi
m_resourcesData->maybeAddResourceData(requestId, buffer);
});
}
-
+
resourceResponse->setString("mimeType"_s, previousResourceData->mimeType());
-
+
resourceResponse->setInteger("status"_s, previousResourceData->httpStatusCode());
resourceResponse->setString("statusText"_s, previousResourceData->httpStatusText());
-
+
resourceResponse->setString("source"_s, Inspector::Protocol::Helpers::getEnumConstantValue(Inspector::Protocol::Network::Response::Source::DiskCache));
}
}
@@ -617,6 +620,9 @@ void InspectorNetworkAgent::didFailLoading(ResourceLoaderIdentifier identifier,
String requestId = IdentifiersFactory::requestId(identifier.toUInt64());
if (loader && m_resourcesData->resourceType(requestId) == ResourceType::Document) {
+ if (m_stoppingLoadingDueToProcessSwap)
+ return;
+
auto* frame = loader->frame();
if (frame && frame->loader().documentLoader() && frame->document()) {
m_resourcesData->addResourceSharedBuffer(requestId,
@@ -846,6 +852,7 @@ Inspector::Protocol::ErrorStringOr<void> InspectorNetworkAgent::disable()
Ref { m_instrumentingAgents.get() }->setEnabledNetworkAgent(nullptr);
m_resourcesData->clear();
m_extraRequestHeaders.clear();
+ m_stoppingLoadingDueToProcessSwap = false;
continuePendingRequests();
continuePendingResponses();
@@ -904,6 +911,7 @@ void InspectorNetworkAgent::continuePendingResponses()
Inspector::Protocol::ErrorStringOr<void> InspectorNetworkAgent::setExtraHTTPHeaders(Ref<JSON::Object>&& headers)
{
+ m_extraRequestHeaders.clear();
for (auto& entry : headers.get()) {
auto stringValue = entry.value->asString();
if (!!stringValue)
@@ -1158,6 +1166,11 @@ void InspectorNetworkAgent::interceptResponse(const ResourceResponse& response,
m_frontendDispatcher->responseIntercepted(requestId, resourceResponse.releaseNonNull());
}
+void InspectorNetworkAgent::setStoppingLoadingDueToProcessSwap(bool stopping)
+{
+ m_stoppingLoadingDueToProcessSwap = stopping;
+}
+
Inspector::Protocol::ErrorStringOr<void> InspectorNetworkAgent::interceptContinue(const Inspector::Protocol::Network::RequestId& requestId, Inspector::Protocol::Network::NetworkStage networkStage)
{
switch (networkStage) {
@@ -1187,6 +1200,9 @@ Inspector::Protocol::ErrorStringOr<void> InspectorNetworkAgent::interceptWithReq
return makeUnexpected("Missing pending intercept request for given requestId"_s);
auto& loader = *pendingRequest->m_loader;
+ if (loader.reachedTerminalState())
+ return makeUnexpected("Unable to intercept request, it has already been processed"_s);
+
ResourceRequest request = loader.request();
if (!!url)
request.setURL(URL({ }, url));
@@ -1282,13 +1298,22 @@ Inspector::Protocol::ErrorStringOr<void> InspectorNetworkAgent::interceptRequest
response.setHTTPStatusCode(status);
response.setHTTPStatusText(String { statusText });
HTTPHeaderMap explicitHeaders;
+ String setCookieValue;
for (auto& header : headers.get()) {
auto headerValue = header.value->asString();
- if (!!headerValue)
+ if (equalIgnoringASCIICase(header.key, "Set-Cookie"_s))
+ setCookieValue = headerValue;
+ else if (!!headerValue)
explicitHeaders.add(header.key, headerValue);
+
}
response.setHTTPHeaderFields(WTF::move(explicitHeaders));
response.setHTTPHeaderField(HTTPHeaderName::ContentType, response.mimeType());
+
+ auto* frame = loader->frame();
+ if (!setCookieValue.isEmpty() && frame && frame->page())
+ frame->page()->cookieJar().setCookieFromResponse(*loader.get(), setCookieValue);
+
loader->didReceiveResponse(WTF::move(response), [loader, buffer = data.releaseNonNull()]() {
if (loader->reachedTerminalState())
return;
@@ -1352,6 +1377,12 @@ Inspector::Protocol::ErrorStringOr<void> InspectorNetworkAgent::setEmulatedCondi
#endif // ENABLE(INSPECTOR_NETWORK_THROTTLING)
+Inspector::Protocol::ErrorStringOr<void> InspectorNetworkAgent::setEmulateOfflineState(bool offline)
+{
+ platformStrategies()->loaderStrategy()->setEmulateOfflineState(offline);
+ return { };
+}
+
static Ref<Inspector::Protocol::Page::SearchResult> buildObjectForSearchResult(const Inspector::Protocol::Network::RequestId& requestId, const Inspector::Protocol::Network::FrameId& frameId, const String& url, int matchesCount)
{
auto searchResult = Inspector::Protocol::Page::SearchResult::create()
diff --git a/Source/WebCore/inspector/agents/InspectorNetworkAgent.h b/Source/WebCore/inspector/agents/InspectorNetworkAgent.h
index 5875ac43836d8cbd9b40e82ebf964a34eb65254f..175bd8649c496232fed546ccbb12102722d8608b 100644
--- a/Source/WebCore/inspector/agents/InspectorNetworkAgent.h
+++ b/Source/WebCore/inspector/agents/InspectorNetworkAgent.h
@@ -35,6 +35,8 @@
#include "InspectorPageAgent.h"
#include "InspectorWebAgentBase.h"
#include "NetworkResourcesData.h"
+#include "ResourceError.h"
+#include "SharedBuffer.h"
#include "WebSocket.h"
#include <JavaScriptCore/ContentSearchUtilities.h>
#include <JavaScriptCore/InspectorBackendDispatchers.h>
@@ -105,6 +107,7 @@ public:
#if ENABLE(INSPECTOR_NETWORK_THROTTLING)
Inspector::Protocol::ErrorStringOr<void> setEmulatedConditions(std::optional<int>&& bytesPerSecondLimit) final;
#endif
+ Inspector::Protocol::ErrorStringOr<void> setEmulateOfflineState(bool offline) final;
// InspectorInstrumentation
void NODELETE willRecalculateStyle();
@@ -136,6 +139,7 @@ public:
bool shouldInterceptResponse(const ResourceResponse&);
void interceptResponse(const ResourceResponse&, ResourceLoaderIdentifier, CompletionHandler<void(const ResourceResponse&, RefPtr<FragmentedSharedBuffer>)>&&);
void interceptRequest(ResourceLoader&, Function<void(const ResourceRequest&)>&&);
+ void setStoppingLoadingDueToProcessSwap(bool);
void searchOtherRequests(const JSC::Yarr::RegularExpression&, Ref<JSON::ArrayOf<Inspector::Protocol::Page::SearchResult>>&);
void searchInRequest(Inspector::Protocol::ErrorString&, const Inspector::Protocol::Network::RequestId&, const String& query, bool caseSensitive, bool isRegex, RefPtr<JSON::ArrayOf<Inspector::Protocol::GenericTypes::SearchMatch>>&);
@@ -192,6 +196,7 @@ private:
bool m_loadingXHRSynchronously { false };
bool m_interceptionEnabled { false };
bool m_clearResourceDataOnNavigate { true };
+ bool m_stoppingLoadingDueToProcessSwap { false };
};
} // namespace WebCore
diff --git a/Source/WebCore/inspector/agents/InspectorPageAgent.cpp b/Source/WebCore/inspector/agents/InspectorPageAgent.cpp
index 6bb8dd192ae2fedac06e2b35bb9c6711950d5b23..5fb689a1a62b8fd687b73c590236ac11d5e1fb03 100644
--- a/Source/WebCore/inspector/agents/InspectorPageAgent.cpp
+++ b/Source/WebCore/inspector/agents/InspectorPageAgent.cpp
@@ -32,6 +32,7 @@
#include "config.h"
#include "InspectorPageAgent.h"
+#include "BackForwardController.h"
#include "CachedResource.h"
#include "Cookie.h"
#include "CookieJar.h"
@@ -39,14 +40,17 @@
#include "DocumentLoader.h"
#include "DocumentResourceLoader.h"
#include "DocumentView.h"
+#include "Editor.h"
#include "ElementInlines.h"
#include "EventTargetInlines.h"
+#include "FocusController.h"
#include "ForcedAccessibilityValue.h"
#include "FrameInlines.h"
#include "FrameLoadRequest.h"
#include "FrameLoader.h"
#include "FrameSnapshotting.h"
#include "HTMLFrameOwnerElement.h"
+#include "HTMLInputElement.h"
#include "HTMLNames.h"
#include "ImageBuffer.h"
#include "ImageUtilities.h"
@@ -57,30 +61,38 @@
#include "InspectorOverlay.h"
#include "InspectorResourceUtilities.h"
#include "InstrumentingAgents.h"
+#include "JSDOMWindowCustom.h"
#include "LocalFrame.h"
#include "LocalFrameView.h"
#include "MIMETypeRegistry.h"
#include "MemoryCache.h"
#include "Page.h"
#include "PageInspectorController.h"
+#include "PlatformScreen.h"
#include "RenderObjectInlines.h"
#include "RenderTheme.h"
#include "ScriptController.h"
#include "ScriptSourceCode.h"
+#include "ScrollingCoordinator.h"
#include "SecurityOrigin.h"
#include "Settings.h"
#include "ShouldPartitionCookie.h"
#include "StyleScope.h"
#include "Theme.h"
+#include "TypingCommand.h"
#include <pal/text/TextEncoding.h>
#include "UserGestureIndicator.h"
#include <JavaScriptCore/ContentSearchUtilities.h>
#include <JavaScriptCore/IdentifiersFactory.h>
+#include <JavaScriptCore/InjectedScriptManager.h>
#include <JavaScriptCore/RegularExpression.h>
+#include <wtf/DateMath.h>
#include <wtf/ListHashSet.h>
+#include <wtf/NeverDestroyed.h>
#include <wtf/Stopwatch.h>
#include <wtf/TZoneMallocInlines.h>
#include <wtf/text/Base64.h>
+#include <wtf/text/MakeString.h>
#include <wtf/text/StringBuilder.h>
#if ENABLE(APPLICATION_MANIFEST)
@@ -102,6 +114,11 @@ using namespace Inspector;
WTF_MAKE_TZONE_ALLOCATED_IMPL(InspectorPageAgent);
+static UncheckedKeyHashMap<String, Ref<DOMWrapperWorld>>& createdUserWorlds() {
+ static NeverDestroyed<UncheckedKeyHashMap<String, Ref<DOMWrapperWorld>>> nameToWorld;
+ return nameToWorld;
+}
+
InspectorOverlay& InspectorPageAgent::overlay() const
{
return m_overlay.get();
@@ -112,6 +129,7 @@ InspectorPageAgent::InspectorPageAgent(PageAgentContext& context, InspectorBacke
, m_frontendDispatcher(makeUniqueRef<Inspector::PageFrontendDispatcher>(context.frontendRouter))
, m_backendDispatcher(Inspector::PageBackendDispatcher::create(context.backendDispatcher, this))
, m_inspectedPage(context.inspectedPage)
+ , m_injectedScriptManager(context.injectedScriptManager)
, m_client(client)
, m_overlay(overlay)
{
@@ -142,12 +160,20 @@ Inspector::Protocol::ErrorStringOr<void> InspectorPageAgent::enable()
defaultUserPreferencesDidChange();
+ if (!createdUserWorlds().isEmpty()) {
+ Vector<DOMWrapperWorld*> worlds;
+ for (const auto& world : createdUserWorlds().values())
+ worlds.append(world.ptr());
+ ensureUserWorldsExistInAllFrames(worlds);
+ }
return { };
}
Inspector::Protocol::ErrorStringOr<void> InspectorPageAgent::disable()
{
Ref { m_instrumentingAgents.get() }->setEnabledPageAgent(nullptr);
+ m_interceptFileChooserDialog = false;
+ m_bypassCSP = false;
std::ignore = setShowPaintRects(false);
#if !PLATFORM(IOS_FAMILY)
@@ -200,6 +226,22 @@ Inspector::Protocol::ErrorStringOr<void> InspectorPageAgent::reload(std::optiona
return { };
}
+Inspector::Protocol::ErrorStringOr<void> InspectorPageAgent::goBack()
+{
+ if (!m_inspectedPage->backForward().goBack())
+ return makeUnexpected("Failed to go back"_s);
+
+ return { };
+}
+
+Inspector::Protocol::ErrorStringOr<void> InspectorPageAgent::goForward()
+{
+ if (!m_inspectedPage->backForward().goForward())
+ return makeUnexpected("Failed to go forward"_s);
+
+ return { };
+}
+
Inspector::Protocol::ErrorStringOr<void> InspectorPageAgent::overrideUserAgent(const String& value)
{
m_userAgentOverride = value;
@@ -207,6 +249,13 @@ Inspector::Protocol::ErrorStringOr<void> InspectorPageAgent::overrideUserAgent(c
return { };
}
+Inspector::Protocol::ErrorStringOr<void> InspectorPageAgent::overridePlatform(const String& value)
+{
+ m_platformOverride = value;
+
+ return { };
+}
+
Inspector::Protocol::ErrorStringOr<void> InspectorPageAgent::overrideSetting(Inspector::Protocol::Page::Setting setting, std::optional<bool>&& value)
{
auto& inspectedPageSettings = m_inspectedPage->settings();
@@ -220,6 +269,12 @@ Inspector::Protocol::ErrorStringOr<void> InspectorPageAgent::overrideSetting(Ins
inspectedPageSettings.setAuthorAndUserStylesEnabledInspectorOverride(value);
return { };
+#if ENABLE(DEVICE_ORIENTATION)
+ case Inspector::Protocol::Page::Setting::DeviceOrientationEventEnabled:
+ inspectedPageSettings.setDeviceOrientationEventEnabled(value.value_or(false));
+ return { };
+#endif
+
case Inspector::Protocol::Page::Setting::ICECandidateFilteringEnabled:
inspectedPageSettings.setICECandidateFilteringEnabledInspectorOverride(value);
return { };
@@ -246,6 +301,39 @@ Inspector::Protocol::ErrorStringOr<void> InspectorPageAgent::overrideSetting(Ins
m_client->setDeveloperPreferenceOverride(InspectorBackendClient::DeveloperPreference::NeedsSiteSpecificQuirks, value);
return { };
+#if ENABLE(NOTIFICATIONS)
+ case Inspector::Protocol::Page::Setting::NotificationsEnabled:
+ inspectedPageSettings.setNotificationsEnabled(value.value_or(false));
+ return { };
+#endif
+
+#if ENABLE(FULLSCREEN_API)
+ case Inspector::Protocol::Page::Setting::FullScreenEnabled:
+ inspectedPageSettings.setFullScreenEnabled(value.value_or(false));
+ return { };
+#endif
+
+ case Inspector::Protocol::Page::Setting::InputTypeMonthEnabled:
+ inspectedPageSettings.setInputTypeMonthEnabled(value.value_or(false));
+ return { };
+
+ case Inspector::Protocol::Page::Setting::InputTypeWeekEnabled:
+ inspectedPageSettings.setInputTypeWeekEnabled(value.value_or(false));
+ return { };
+
+ case Inspector::Protocol::Page::Setting::FixedBackgroundsPaintRelativeToDocument:
+ // Enable this setting similar to iOS to ensure scrolling works with
+ // `background-attachment: fixed`.
+ // See https://github.com/microsoft/playwright/issues/31551.
+ inspectedPageSettings.setFixedBackgroundsPaintRelativeToDocument(value.value_or(false));
+ return { };
+
+#if ENABLE(POINTER_LOCK)
+ case Inspector::Protocol::Page::Setting::PointerLockEnabled:
+ inspectedPageSettings.setPointerLockEnabled(value.value_or(false));
+ return { };
+#endif
+
case Inspector::Protocol::Page::Setting::ScriptEnabled:
inspectedPageSettings.setScriptEnabledInspectorOverride(value);
return { };
@@ -258,6 +346,12 @@ Inspector::Protocol::ErrorStringOr<void> InspectorPageAgent::overrideSetting(Ins
inspectedPageSettings.setShowRepaintCounterInspectorOverride(value);
return { };
+#if ENABLE(MEDIA_STREAM)
+ case Inspector::Protocol::Page::Setting::SpeechRecognitionEnabled:
+ inspectedPageSettings.setSpeechRecognitionEnabled(value.value_or(false));
+ return { };
+#endif
+
case Inspector::Protocol::Page::Setting::WebSecurityEnabled:
inspectedPageSettings.setWebSecurityEnabledInspectorOverride(value);
return { };
@@ -670,15 +764,16 @@ Inspector::Protocol::ErrorStringOr<void> InspectorPageAgent::setShowPaintRects(b
return { };
}
-void InspectorPageAgent::domContentEventFired()
+void InspectorPageAgent::domContentEventFired(LocalFrame& frame)
{
- m_isFirstLayoutAfterOnLoad = true;
- m_frontendDispatcher->domContentEventFired(timestamp());
+ if (frame.isMainFrame())
+ m_isFirstLayoutAfterOnLoad = true;
+ m_frontendDispatcher->domContentEventFired(timestamp(), frameId(&frame));
}
-void InspectorPageAgent::loadEventFired()
+void InspectorPageAgent::loadEventFired(LocalFrame& frame)
{
- m_frontendDispatcher->loadEventFired(timestamp());
+ m_frontendDispatcher->loadEventFired(timestamp(), frameId(&frame));
}
void InspectorPageAgent::frameNavigated(LocalFrame& frame)
@@ -686,6 +781,22 @@ void InspectorPageAgent::frameNavigated(LocalFrame& frame)
m_frontendDispatcher->frameNavigated(buildObjectForFrame(&frame));
}
+String InspectorPageAgent::serializeFrameID(FrameIdentifier frameID)
+{
+ return makeString(frameID.toUInt64());
+}
+
+std::optional<FrameIdentifier> InspectorPageAgent::parseFrameID(String frameID)
+{
+ if (!frameID.containsOnlyASCII())
+ return std::nullopt;
+
+WTF_ALLOW_UNSAFE_BUFFER_USAGE_BEGIN
+ uint64_t frameIDNumber = strtoull(frameID.ascii().data(), 0, 10);
+WTF_ALLOW_UNSAFE_BUFFER_USAGE_END
+ return WebCore::FrameIdentifier(frameIDNumber);
+}
+
void InspectorPageAgent::frameDetached(LocalFrame& frame)
{
auto identifier = m_inspectedPage->inspectorController().identifierRegistry().takeFrame(frame);
@@ -758,6 +869,12 @@ void InspectorPageAgent::defaultUserPreferencesDidChange()
m_frontendDispatcher->defaultUserPreferencesDidChange(WTF::move(defaultUserPreferences));
}
+void InspectorPageAgent::didNavigateWithinPage(LocalFrame& frame)
+{
+ String url = frame.document()->url().string();
+ m_frontendDispatcher->navigatedWithinDocument(frameId(&frame), url);
+}
+
#if ENABLE(DARK_MODE_CSS)
void InspectorPageAgent::defaultAppearanceDidChange()
{
@@ -771,6 +888,9 @@ void InspectorPageAgent::didClearWindowObjectInWorld(LocalFrame& frame, DOMWrapp
return;
if (m_bootstrapScript.isEmpty())
+ return;
+
+ if (m_ignoreDidClearWindowObject)
return;
frame.script().evaluateIgnoringException(ScriptSourceCode(m_bootstrapScript, JSC::SourceTaintedOrigin::Untainted, URL { "web-inspector://bootstrap.js"_str }));
@@ -818,6 +938,51 @@ void InspectorPageAgent::didRecalculateStyle()
protect(overlay())->update();
}
+void InspectorPageAgent::runOpenPanel(HTMLInputElement* element, bool* intercept)
+{
+ if (m_interceptFileChooserDialog) {
+ *intercept = true;
+ } else {
+ return;
+ }
+ Document& document = element->document();
+ auto* frame = document.frame();
+ if (!frame)
+ return;
+
+ auto& globalObject = mainWorldGlobalObject(*frame);
+ auto injectedScript = m_injectedScriptManager.injectedScriptFor(&globalObject);
+ if (injectedScript.hasNoValue())
+ return;
+
+ auto object = injectedScript.wrapObject(InspectorDOMAgent::nodeAsScriptValue(globalObject, element), WTF::String());
+ if (!object)
+ return;
+
+ m_frontendDispatcher->fileChooserOpened(frameId(frame), object.releaseNonNull());
+}
+
+void InspectorPageAgent::frameAttached(LocalFrame& frame)
+{
+ String parentFrameId = frameId(dynamicDowncast<LocalFrame>(frame.tree().parent()));
+ m_frontendDispatcher->frameAttached(frameId(&frame), parentFrameId);
+}
+
+bool InspectorPageAgent::shouldBypassCSP()
+{
+ return m_bypassCSP;
+}
+
+void InspectorPageAgent::willCheckNavigationPolicy(LocalFrame& frame)
+{
+ m_frontendDispatcher->willCheckNavigationPolicy(frameId(&frame));
+}
+
+void InspectorPageAgent::didCheckNavigationPolicy(LocalFrame& frame, bool cancel)
+{
+ m_frontendDispatcher->didCheckNavigationPolicy(frameId(&frame), cancel);
+}
+
Ref<Inspector::Protocol::Page::Frame> InspectorPageAgent::buildObjectForFrame(LocalFrame* frame)
{
ASSERT_ARG(frame, frame);
@@ -911,6 +1076,12 @@ void InspectorPageAgent::applyUserAgentOverride(String& userAgent)
userAgent = m_userAgentOverride;
}
+void InspectorPageAgent::applyPlatformOverride(String& platform)
+{
+ if (!m_platformOverride.isEmpty())
+ platform = m_platformOverride;
+}
+
void InspectorPageAgent::applyEmulatedMedia(AtomString& media)
{
if (!m_emulatedMedia.isEmpty())
@@ -926,7 +1097,7 @@ Inspector::Protocol::ErrorStringOr<String> InspectorPageAgent::snapshotNode(Insp
RefPtr node = domAgent->assertNode(errorString, nodeId);
if (!node)
return makeUnexpected(errorString);
-
+
RefPtr localMainFrame = m_inspectedPage->localMainFrame();
if (!localMainFrame)
return makeUnexpected("Main frame isn't local"_s);
@@ -937,11 +1108,13 @@ Inspector::Protocol::ErrorStringOr<String> InspectorPageAgent::snapshotNode(Insp
return encodeDataURL(WTF::move(snapshot), "image/png"_s);
}
-Inspector::Protocol::ErrorStringOr<String> InspectorPageAgent::snapshotRect(int x, int y, int width, int height, Inspector::Protocol::Page::CoordinateSystem coordinateSystem)
+Inspector::Protocol::ErrorStringOr<String> InspectorPageAgent::snapshotRect(int x, int y, int width, int height, Inspector::Protocol::Page::CoordinateSystem coordinateSystem, std::optional<bool>&& omitDeviceScaleFactor)
{
SnapshotOptions options { { }, PixelFormat::BGRA8, DestinationColorSpace::SRGB() };
if (coordinateSystem == Inspector::Protocol::Page::CoordinateSystem::Viewport)
options.flags.add(SnapshotFlags::InViewCoordinates);
+ if (omitDeviceScaleFactor.has_value() && *omitDeviceScaleFactor)
+ options.flags.add(SnapshotFlags::OmitDeviceScaleFactor);
IntRect rectangle(x, y, width, height);
RefPtr localMainFrame = m_inspectedPage->localMainFrame();
@@ -954,6 +1127,43 @@ Inspector::Protocol::ErrorStringOr<String> InspectorPageAgent::snapshotRect(int
return encodeDataURL(WTF::move(snapshot), "image/png"_s);
}
+Inspector::Protocol::ErrorStringOr<void> InspectorPageAgent::setForcedColors(std::optional<Inspector::Protocol::Page::ForcedColors>&& forcedColors)
+{
+ if (!forcedColors) {
+ m_inspectedPage->setUseForcedColorsOverride(std::nullopt);
+ return { };
+ }
+
+ switch (*forcedColors) {
+ case Inspector::Protocol::Page::ForcedColors::Active:
+ m_inspectedPage->setUseForcedColorsOverride(true);
+ return { };
+ case Inspector::Protocol::Page::ForcedColors::None:
+ m_inspectedPage->setUseForcedColorsOverride(false);
+ return { };
+ }
+
+ ASSERT_NOT_REACHED();
+ return { };
+}
+
+Inspector::Protocol::ErrorStringOr<void> InspectorPageAgent::setTimeZone(const String& timeZone)
+{
+ bool success = WTF::setTimeZoneOverride(timeZone);
+ if (!success)
+ return makeUnexpected(makeString("Invalid time zone "_s, timeZone));
+
+ return { };
+}
+
+Inspector::Protocol::ErrorStringOr<void> InspectorPageAgent::setTouchEmulationEnabled(bool enabled)
+{
+ setScreenHasTouchDeviceOverride(enabled);
+ m_inspectedPage->settings().setTouchEventDOMAttributesEnabled(enabled);
+ return { };
+}
+
+
#if ENABLE(WEB_ARCHIVE) && USE(CF)
Inspector::Protocol::ErrorStringOr<String> InspectorPageAgent::archive()
{
@@ -970,7 +1180,6 @@ Inspector::Protocol::ErrorStringOr<String> InspectorPageAgent::archive()
}
#endif
-#if !PLATFORM(COCOA)
Inspector::Protocol::ErrorStringOr<void> InspectorPageAgent::setScreenSizeOverride(std::optional<int>&& width, std::optional<int>&& height)
{
if (width.has_value() != height.has_value())
@@ -988,6 +1197,86 @@ Inspector::Protocol::ErrorStringOr<void> InspectorPageAgent::setScreenSizeOverri
localMainFrame->setOverrideScreenSize(FloatSize(width.value_or(0), height.value_or(0)));
return { };
}
-#endif
+
+Inspector::Protocol::ErrorStringOr<void> InspectorPageAgent::insertText(const String& text)
+{
+ UserGestureIndicator indicator { IsProcessingUserGesture::Yes };
+ RefPtr frame = m_inspectedPage->focusController().focusedOrMainFrame();
+ if (!frame)
+ return { };
+
+ if (frame->editor().hasComposition()) {
+ frame->editor().confirmComposition(text);
+ } else {
+ Document* focusedDocument = frame->document();
+ TypingCommand::insertText(*focusedDocument, text, nullptr, { });
+ }
+ return { };
+}
+
+Inspector::Protocol::ErrorStringOr<void> InspectorPageAgent::setInterceptFileChooserDialog(bool enabled)
+{
+ m_interceptFileChooserDialog = enabled;
+ return { };
+}
+
+Inspector::Protocol::ErrorStringOr<void> InspectorPageAgent::setDefaultBackgroundColorOverride(RefPtr<JSON::Object>&& color)
+{
+ auto* localFrame = dynamicDowncast<LocalFrame>(m_inspectedPage->mainFrame());
+ LocalFrameView* view = localFrame ? localFrame->view() : nullptr;
+ if (!view)
+ return makeUnexpected("Internal error: No frame view to set color two"_s);
+
+ if (!color) {
+ view->updateBackgroundRecursively(std::optional<Color>());
+ return { };
+ }
+
+ view->updateBackgroundRecursively(InspectorDOMAgent::parseColor(WTF::move(color)));
+ return { };
+}
+
+Inspector::Protocol::ErrorStringOr<void> InspectorPageAgent::createUserWorld(const String& name)
+{
+ if (createdUserWorlds().contains(name))
+ return makeUnexpected("World with the given name already exists"_s);
+
+ Ref<DOMWrapperWorld> world = ScriptController::createWorld(name, ScriptController::WorldType::User);
+ ensureUserWorldsExistInAllFrames({world.ptr()});
+ createdUserWorlds().set(name, WTF::move(world));
+ return { };
+}
+
+void InspectorPageAgent::ensureUserWorldsExistInAllFrames(const Vector<DOMWrapperWorld*>& worlds)
+{
+ for (Frame* frame = &m_inspectedPage->mainFrame(); frame; frame = frame->tree().traverseNext()) {
+ auto* localFrame = dynamicDowncast<LocalFrame>(frame);
+ if (!localFrame)
+ continue;
+ for (auto* world : worlds)
+ localFrame->windowProxy().jsWindowProxy(*world)->window();
+ }
+}
+
+Inspector::Protocol::ErrorStringOr<void> InspectorPageAgent::setBypassCSP(bool enabled)
+{
+ m_bypassCSP = enabled;
+ return { };
+}
+
+Inspector::Protocol::ErrorStringOr<void> InspectorPageAgent::crash()
+{
+ WTFCrash();
+ return { };
+}
+
+Inspector::Protocol::ErrorStringOr<void> InspectorPageAgent::updateScrollingState()
+{
+ auto* scrollingCoordinator = m_inspectedPage->scrollingCoordinator();
+ if (!scrollingCoordinator)
+ return {};
+ scrollingCoordinator->commitTreeStateIfNeeded();
+ return {};
+}
} // namespace WebCore
diff --git a/Source/WebCore/inspector/agents/InspectorPageAgent.h b/Source/WebCore/inspector/agents/InspectorPageAgent.h
index 97c3cf09961f5c5ea7ede70d35755639fc66a3df..d5aabfbb3062f6037415bb3e136d3d7cebdfbbfd 100644
--- a/Source/WebCore/inspector/agents/InspectorPageAgent.h
+++ b/Source/WebCore/inspector/agents/InspectorPageAgent.h
@@ -43,10 +43,12 @@
#include <wtf/Seconds.h>
#include <wtf/TZoneMalloc.h>
#include <wtf/WeakRef.h>
+#include <wtf/Vector.h>
#include <wtf/text/WTFString.h>
namespace Inspector {
enum class ResourceType;
+class InjectedScriptManager;
}
namespace WebCore {
@@ -54,6 +56,7 @@ namespace WebCore {
class DOMWrapperWorld;
class DocumentLoader;
class Frame;
+class HTMLInputElement;
class InspectorOverlay;
class LocalFrame;
class Page;
@@ -68,6 +71,9 @@ public:
InspectorPageAgent(PageAgentContext&, InspectorBackendClient*, InspectorOverlay&);
~InspectorPageAgent();
+ WEBCORE_EXPORT static String serializeFrameID(FrameIdentifier frameID);
+ WEBCORE_EXPORT static std::optional<FrameIdentifier> parseFrameID(String frameID);
+
// InspectorAgentBase
void didCreateFrontendAndBackend();
void willDestroyFrontendAndBackend(Inspector::DisconnectReason);
@@ -76,7 +82,10 @@ public:
Inspector::Protocol::ErrorStringOr<void> enable();
Inspector::Protocol::ErrorStringOr<void> disable();
Inspector::Protocol::ErrorStringOr<void> reload(std::optional<bool>&& ignoreCache, std::optional<bool>&& revalidateAllResources);
+ Inspector::Protocol::ErrorStringOr<void> goBack();
+ Inspector::Protocol::ErrorStringOr<void> goForward();
Inspector::Protocol::ErrorStringOr<void> overrideUserAgent(const String&);
+ Inspector::Protocol::ErrorStringOr<void> overridePlatform(const String&);
Inspector::Protocol::ErrorStringOr<void> overrideSetting(Inspector::Protocol::Page::Setting, std::optional<bool>&& value);
Inspector::Protocol::ErrorStringOr<void> overrideUserPreference(Inspector::Protocol::Page::UserPreferenceName, std::optional<Inspector::Protocol::Page::UserPreferenceValue>&&);
Inspector::Protocol::ErrorStringOr<Ref<JSON::ArrayOf<Inspector::Protocol::Page::Cookie>>> getCookies();
@@ -92,41 +101,60 @@ public:
#endif
Inspector::Protocol::ErrorStringOr<void> setShowPaintRects(bool);
Inspector::Protocol::ErrorStringOr<void> setEmulatedMedia(const String&);
+ Inspector::Protocol::ErrorStringOr<void> setForcedColors(std::optional<Inspector::Protocol::Page::ForcedColors>&&);
+ Inspector::Protocol::ErrorStringOr<void> setTimeZone(const String&);
+ Inspector::Protocol::ErrorStringOr<void> setTouchEmulationEnabled(bool);
Inspector::Protocol::ErrorStringOr<String> snapshotNode(Inspector::Protocol::DOM::NodeId);
- Inspector::Protocol::ErrorStringOr<String> snapshotRect(int x, int y, int width, int height, Inspector::Protocol::Page::CoordinateSystem);
+ Inspector::Protocol::ErrorStringOr<String> snapshotRect(int x, int y, int width, int height, Inspector::Protocol::Page::CoordinateSystem, std::optional<bool>&& omitDeviceScaleFactor);
#if ENABLE(WEB_ARCHIVE) && USE(CF)
Inspector::Protocol::ErrorStringOr<String> archive();
#endif
-#if !PLATFORM(COCOA)
Inspector::Protocol::ErrorStringOr<void> setScreenSizeOverride(std::optional<int>&& width, std::optional<int>&& height);
-#endif
+
+ Inspector::Protocol::ErrorStringOr<void> insertText(const String& text);
+ Inspector::Protocol::ErrorStringOr<void> setInterceptFileChooserDialog(bool enabled);
+ Inspector::Protocol::ErrorStringOr<void> setDefaultBackgroundColorOverride(RefPtr<JSON::Object>&&);
+ Inspector::Protocol::ErrorStringOr<void> createUserWorld(const String&);
+ Inspector::Protocol::ErrorStringOr<void> setBypassCSP(bool);
+ Inspector::Protocol::ErrorStringOr<void> crash();
+ Inspector::Protocol::ErrorStringOr<void> updateScrollingState();
// InspectorInstrumentation
- void domContentEventFired();
- void loadEventFired();
+ void domContentEventFired(LocalFrame&);
+ void loadEventFired(LocalFrame&);
void frameNavigated(LocalFrame&);
void frameDetached(LocalFrame&);
void loaderDetachedFromFrame(DocumentLoader&);
void accessibilitySettingsDidChange();
void defaultUserPreferencesDidChange();
+ void didNavigateWithinPage(LocalFrame&);
#if ENABLE(DARK_MODE_CSS)
void defaultAppearanceDidChange();
#endif
void applyUserAgentOverride(String&);
+ void applyPlatformOverride(String&);
void applyEmulatedMedia(AtomString&);
void didClearWindowObjectInWorld(LocalFrame&, DOMWrapperWorld&);
void didPaint(RenderObject&, const LayoutRect&);
void didLayout();
void didScroll();
void didRecalculateStyle();
+ void runOpenPanel(HTMLInputElement* element, bool* intercept);
+ void frameAttached(LocalFrame&);
+ bool shouldBypassCSP();
+ void willCheckNavigationPolicy(LocalFrame&);
+ void didCheckNavigationPolicy(LocalFrame&, bool cancel);
Frame* frameForId(const Inspector::Protocol::Network::FrameId&);
WEBCORE_EXPORT String frameId(Frame*);
String loaderId(DocumentLoader*);
LocalFrame* assertFrame(Inspector::Protocol::ErrorString&, const Inspector::Protocol::Network::FrameId&);
+ void setIgnoreDidClearWindowObject(bool ignore) { m_ignoreDidClearWindowObject = ignore; }
+ bool ignoreDidClearWindowObject() const { return m_ignoreDidClearWindowObject; }
private:
double timestamp();
+ void ensureUserWorldsExistInAllFrames(const Vector<DOMWrapperWorld*>&);
InspectorOverlay& NODELETE overlay() const;
@@ -141,14 +169,19 @@ private:
const Ref<Inspector::PageBackendDispatcher> m_backendDispatcher;
WeakRef<Page> m_inspectedPage;
+ Inspector::InjectedScriptManager& m_injectedScriptManager;
InspectorBackendClient* m_client { nullptr };
WeakRef<InspectorOverlay> m_overlay;
String m_userAgentOverride;
+ String m_platformOverride;
AtomString m_emulatedMedia;
String m_bootstrapScript;
bool m_isFirstLayoutAfterOnLoad { false };
bool m_showPaintRects { false };
+ bool m_interceptFileChooserDialog { false };
+ bool m_bypassCSP { false };
+ bool m_ignoreDidClearWindowObject { false };
};
} // namespace WebCore
diff --git a/Source/WebCore/inspector/agents/page/PageRuntimeAgent.cpp b/Source/WebCore/inspector/agents/page/PageRuntimeAgent.cpp
index e93e93df33a77cf1995340ff1375488efee0a9df..002c160eec98597f97d547f6f2722b7edb58be72 100644
--- a/Source/WebCore/inspector/agents/page/PageRuntimeAgent.cpp
+++ b/Source/WebCore/inspector/agents/page/PageRuntimeAgent.cpp
@@ -35,7 +35,9 @@
#include "DOMWrapperWorld.h"
#include "Document.h"
#include "FrameConsoleClient.h"
+#include "FrameLoader.h"
#include "InspectorIdentifierRegistry.h"
+#include "InspectorPageAgent.h"
#include "InstrumentingAgents.h"
#include "JSDOMWindowCustom.h"
#include "JSExecState.h"
@@ -43,6 +45,7 @@
#include "Page.h"
#include "PageInspectorController.h"
#include "ScriptController.h"
+#include "ScriptSourceCode.h"
#include "SecurityOrigin.h"
#include "UserGestureEmulationScope.h"
#include <JavaScriptCore/InjectedScript.h>
@@ -90,13 +93,74 @@ Inspector::Protocol::ErrorStringOr<void> PageRuntimeAgent::disable()
{
Ref { m_instrumentingAgents.get() }->setEnabledPageRuntimeAgent(nullptr);
+ m_bindingNames.clear();
+
return InspectorRuntimeAgent::disable();
}
void PageRuntimeAgent::frameNavigated(LocalFrame& frame)
{
+ auto* pageAgent = Ref { m_instrumentingAgents.get() }->enabledPageAgent();
+ if (pageAgent)
+ pageAgent->setIgnoreDidClearWindowObject(true);
// Ensure execution context is created for the frame even if it doesn't have scripts.
mainWorldGlobalObject(frame);
+ if (pageAgent)
+ pageAgent->setIgnoreDidClearWindowObject(false);
+}
+
+static JSC_DECLARE_HOST_FUNCTION(bindingCallback);
+
+JSC_DEFINE_HOST_FUNCTION(bindingCallback, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
+{
+ auto result = JSC::JSValue::encode(JSC::jsUndefined());
+ if (!callFrame->jsCallee())
+ return result;
+ String bindingName;
+ if (auto* function = dynamicDowncast<JSC::JSFunction>(callFrame->jsCallee()))
+ bindingName = function->name(globalObject->vm());
+ auto client = globalObject->consoleClient();
+ if (!client)
+ return result;
+ if (callFrame->argumentCount() < 1)
+ return result;
+ auto value = callFrame->argument(0);
+ if (value.isUndefined())
+ return result;
+ String stringArg = value.toWTFString(globalObject);
+ client->bindingCalled(globalObject, bindingName, stringArg);
+ return result;
+}
+
+static void addBindingToFrame(LocalFrame& frame, const String& name)
+{
+ JSC::JSGlobalObject* globalObject = frame.script().globalObject(mainThreadNormalWorldSingleton());
+ auto& vm = globalObject->vm();
+ JSC::JSLockHolder lock(vm);
+ globalObject->putDirectNativeFunction(vm, globalObject, JSC::Identifier::fromString(vm, name), 1, bindingCallback, JSC::ImplementationVisibility::Public, JSC::NoIntrinsic, JSC::attributesForStructure(static_cast<unsigned>(JSC::PropertyAttribute::Function)));
+}
+
+Inspector::Protocol::ErrorStringOr<void> PageRuntimeAgent::addBinding(const String& name)
+{
+ if (!m_bindingNames.add(name).isNewEntry)
+ return {};
+
+ m_inspectedPage->forEachLocalFrame([&](LocalFrame& frame) {
+ if (!frame.script().canExecuteScripts(ReasonForCallingCanExecuteScripts::NotAboutToExecuteScript))
+ return;
+
+ addBindingToFrame(frame, name);
+ });
+
+ return {};
+}
+
+void PageRuntimeAgent::bindingCalled(JSC::JSGlobalObject* globalObject, const String& name, const String& arg)
+{
+ auto injectedScript = injectedScriptManager().injectedScriptFor(globalObject);
+ if (injectedScript.hasNoValue())
+ return;
+ m_frontendDispatcher->bindingCalled(injectedScriptManager().injectedScriptIdFor(globalObject), name, arg);
}
void PageRuntimeAgent::didClearWindowObjectInWorld(LocalFrame& frame, DOMWrapperWorld& world)
@@ -105,7 +169,29 @@ void PageRuntimeAgent::didClearWindowObjectInWorld(LocalFrame& frame, DOMWrapper
if (frameId.isEmpty())
return;
+ auto* pageAgent = Ref { m_instrumentingAgents.get() }->enabledPageAgent();
+ if (pageAgent && pageAgent->ignoreDidClearWindowObject())
+ return;
+
+ if (world.isNormal()) {
+ for (const auto& name : m_bindingNames)
+ addBindingToFrame(frame, name);
+ }
+
+ if (pageAgent)
+ pageAgent->setIgnoreDidClearWindowObject(true);
notifyContextCreated(frameId, frame.script().globalObject(world), world);
+ if (pageAgent)
+ pageAgent->setIgnoreDidClearWindowObject(false);
+}
+
+void PageRuntimeAgent::didReceiveMainResourceError(LocalFrame& frame)
+{
+ if (frame.loader().stateMachine().isDisplayingInitialEmptyDocument()) {
+ // Ensure execution context is created for the empty docment to make
+ // it usable in case loading failed.
+ mainWorldGlobalObject(frame);
+ }
}
InjectedScript PageRuntimeAgent::injectedScriptForEval(Inspector::Protocol::ErrorString& errorString, std::optional<Inspector::Protocol::Runtime::ExecutionContextId>&& executionContextId)
@@ -142,9 +228,6 @@ void PageRuntimeAgent::reportExecutionContextCreation()
Ref identifierRegistry = m_inspectedPage->inspectorController().identifierRegistry();
m_inspectedPage->forEachLocalFrame([&](LocalFrame& frame) {
- if (!frame.script().canExecuteScripts(ReasonForCallingCanExecuteScripts::NotAboutToExecuteScript))
- return;
-
auto frameId = identifierRegistry->frameId(&frame);
// Always send the main world first.
diff --git a/Source/WebCore/inspector/agents/page/PageRuntimeAgent.h b/Source/WebCore/inspector/agents/page/PageRuntimeAgent.h
index db4e1b7cd5ba1c46f962c07fa6e23cb13092832c..f7fb1503fc42b4b5fd21f76a893c84030e8af8c2 100644
--- a/Source/WebCore/inspector/agents/page/PageRuntimeAgent.h
+++ b/Source/WebCore/inspector/agents/page/PageRuntimeAgent.h
@@ -39,6 +39,7 @@
namespace JSC {
class CallFrame;
+class JSGlobalObject;
}
namespace WebCore {
@@ -60,10 +61,13 @@ public:
Inspector::Protocol::ErrorStringOr<void> disable();
Inspector::Protocol::ErrorStringOr<std::tuple<Ref<Inspector::Protocol::Runtime::RemoteObject>, std::optional<bool> /* wasThrown */, std::optional<int> /* savedResultIndex */>> evaluate(const String& expression, const String& objectGroup, std::optional<bool>&& includeCommandLineAPI, std::optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, std::optional<Inspector::Protocol::Runtime::ExecutionContextId>&&, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& saveResult, std::optional<bool>&& emulateUserGesture);
void callFunctionOn(const Inspector::Protocol::Runtime::RemoteObjectId&, const String& functionDeclaration, RefPtr<JSON::Array>&& arguments, std::optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& emulateUserGesture, std::optional<bool>&& awaitPromise, Ref<CallFunctionOnCallback>&&);
+ Inspector::Protocol::ErrorStringOr<void> addBinding(const String& name);
// InspectorInstrumentation
void frameNavigated(LocalFrame&);
void didClearWindowObjectInWorld(LocalFrame&, DOMWrapperWorld&);
+ void didReceiveMainResourceError(LocalFrame&);
+ void bindingCalled(JSC::JSGlobalObject* globalObject, const String& name, const String& arg);
private:
Inspector::InjectedScript injectedScriptForEval(Inspector::Protocol::ErrorString&, std::optional<Inspector::Protocol::Runtime::ExecutionContextId>&&);
@@ -78,6 +82,7 @@ private:
WeakRef<InstrumentingAgents> m_instrumentingAgents;
WeakRef<Page> m_inspectedPage;
+ HashSet<String> m_bindingNames;
};
} // namespace WebCore
diff --git a/Source/WebCore/loader/CookieJar.h b/Source/WebCore/loader/CookieJar.h
index c2f9d5d90ff590154ef39132453194c162be0cc5..ff36e34f9e5963f1deaa41341174a7fd312ae25f 100644
--- a/Source/WebCore/loader/CookieJar.h
+++ b/Source/WebCore/loader/CookieJar.h
@@ -48,6 +48,7 @@ class NetworkStorageSession;
class StorageSessionProvider;
struct SameSiteInfo;
enum class ShouldPartitionCookie : bool;
+class ResourceLoader;
class WEBCORE_EXPORT CookieJar : public RefCountedAndCanMakeWeakPtr<CookieJar> {
public:
@@ -82,6 +83,9 @@ public:
virtual void clearCache() { }
virtual void clearCacheForHost(const String&) { }
+ // Playwright.
+ virtual void setCookieFromResponse(ResourceLoader&, const String&) { }
+
virtual ~CookieJar();
protected:
static SameSiteInfo sameSiteInfo(const Document&, IsForDOMCookieAccess = IsForDOMCookieAccess::No);
diff --git a/Source/WebCore/loader/DocumentLoader.cpp b/Source/WebCore/loader/DocumentLoader.cpp
index a060ef80b1c658b388324d5c3f724097fb5c3787..70a1c51d4e2b6e396afd5e5dbf9ad00cf88d42e8 100644
--- a/Source/WebCore/loader/DocumentLoader.cpp
+++ b/Source/WebCore/loader/DocumentLoader.cpp
@@ -787,8 +787,10 @@ void DocumentLoader::willSendRequest(ResourceRequest&& newRequest, const Resourc
if (!didReceiveRedirectResponse)
return completionHandler(WTF::move(newRequest));
+ InspectorInstrumentation::willCheckNavigationPolicy(*frame);
auto navigationPolicyCompletionHandler = [this, protectedThis = Ref { *this }, frame, completionHandler = WTF::move(completionHandler)] (ResourceRequest&& request, WeakPtr<FormSubmission>&&, NavigationPolicyDecision navigationPolicyDecision) mutable {
m_waitingForNavigationPolicy = false;
+ InspectorInstrumentation::didCheckNavigationPolicy(*frame, navigationPolicyDecision != NavigationPolicyDecision::ContinueLoad);
switch (navigationPolicyDecision) {
case NavigationPolicyDecision::IgnoreLoad:
case NavigationPolicyDecision::LoadWillContinueInAnotherProcess:
@@ -1590,11 +1592,17 @@ void DocumentLoader::detachFromFrame(LoadWillContinueInAnotherProcess loadWillCo
if (auto navigationID = std::exchange(m_navigationID, { }))
frame->loader().client().documentLoaderDetached(*navigationID, loadWillContinueInAnotherProcess);
- InspectorInstrumentation::loaderDetachedFromFrame(*frame, *this);
-
observeFrame(nullptr);
}
+void DocumentLoader::replacedByFragmentNavigation(LocalFrame& frame)
+{
+ ASSERT(!this->frame());
+ // Notify WebPageProxy that the navigation has been converted into same page navigation.
+ if (auto navigationID = std::exchange(m_navigationID, { }))
+ frame.loader().client().documentLoaderDetached(*navigationID, LoadWillContinueInAnotherProcess::No);
+}
+
void DocumentLoader::setNavigationID(NavigationIdentifier navigationID)
{
m_navigationID = navigationID;
diff --git a/Source/WebCore/loader/DocumentLoader.h b/Source/WebCore/loader/DocumentLoader.h
index ffebadc8882ffd9a519fdaec8d42ac2909c5fe65..145e7ee21440d14da048d59f7c177c8d334e0ee3 100644
--- a/Source/WebCore/loader/DocumentLoader.h
+++ b/Source/WebCore/loader/DocumentLoader.h
@@ -209,6 +209,8 @@ public:
WEBCORE_EXPORT virtual void detachFromFrame(LoadWillContinueInAnotherProcess);
+ void replacedByFragmentNavigation(LocalFrame&);
+
WEBCORE_EXPORT FrameLoader* NODELETE frameLoader() const;
WEBCORE_EXPORT SubresourceLoader* NODELETE mainResourceLoader() const;
WEBCORE_EXPORT RefPtr<FragmentedSharedBuffer> mainResourceData() const;
diff --git a/Source/WebCore/loader/FrameLoader.cpp b/Source/WebCore/loader/FrameLoader.cpp
index 994f22fa6190e271f9f9927caa6a331c355cc43e..3f469ef6abebeea6f7df6b9406c8c0e9cd5fe386 100644
--- a/Source/WebCore/loader/FrameLoader.cpp
+++ b/Source/WebCore/loader/FrameLoader.cpp
@@ -1385,6 +1385,7 @@ void FrameLoader::loadInSameDocument(URL url, RefPtr<SerializedScriptValue> stat
}
m_client->dispatchDidNavigateWithinPage();
+ InspectorInstrumentation::didNavigateWithinPage(m_frame);
document->statePopped(stateObject ? stateObject.releaseNonNull() : SerializedScriptValue::nullValue());
m_client->dispatchDidPopStateWithinPage();
@@ -1938,6 +1939,7 @@ void FrameLoader::loadWithDocumentLoader(DocumentLoader* loader, FrameLoadType t
const String& httpMethod = loader->request().httpMethod();
if (shouldPerformFragmentNavigation(isFormSubmission, httpMethod, policyChecker().loadType(), newURL) && !loader->substituteData().isValid()) {
+ loader->replacedByFragmentNavigation(m_frame);
RefPtr oldDocumentLoader = m_documentLoader;
NavigationAction action { protect(frame->document()).releaseNonNull(), loader->request(), InitiatedByMainFrame::Unknown, loader->isRequestFromClientOrUserInput(), policyChecker().loadType(), isFormSubmission };
@@ -1977,7 +1979,9 @@ void FrameLoader::loadWithDocumentLoader(DocumentLoader* loader, FrameLoadType t
auto policyDecisionMode = loader->triggeringAction().isFromNavigationAPI() ? PolicyDecisionMode::Synchronous : PolicyDecisionMode::Asynchronous;
RELEASE_ASSERT(!isBackForwardLoadType(policyChecker().loadType()) || history().provisionalItem());
+ InspectorInstrumentation::willCheckNavigationPolicy(m_frame);
policyChecker().checkNavigationPolicy(ResourceRequest(loader->request()), ResourceResponse { } /* redirectResponse */, loader, WTF::move(formSubmission), [this, protectedThis = Ref { *this }, allowNavigationToInvalidURL, completionHandler = completionHandlerCaller.release()] (const ResourceRequest& request, WeakPtr<const FormSubmission>&& weakFormSubmission, NavigationPolicyDecision navigationPolicyDecision) mutable {
+ InspectorInstrumentation::didCheckNavigationPolicy(m_frame, navigationPolicyDecision != NavigationPolicyDecision::ContinueLoad);
continueLoadAfterNavigationPolicy(request, RefPtr { weakFormSubmission.get() }.get(), navigationPolicyDecision, allowNavigationToInvalidURL);
completionHandler();
}, policyDecisionMode, determineNavigationType(type, NavigationHistoryBehavior::Auto));
@@ -3324,10 +3328,15 @@ String FrameLoader::userAgent(const URL& url) const
String FrameLoader::navigatorPlatform() const
{
+ String platform;
+
auto customNavigatorPlatform = protect(m_frame->mainFrame())->customNavigatorPlatform();
if (!customNavigatorPlatform.isEmpty())
- return customNavigatorPlatform;
- return String();
+ platform = customNavigatorPlatform;
+
+ InspectorInstrumentation::applyPlatformOverride(m_frame, platform);
+
+ return platform;
}
void FrameLoader::dispatchOnloadEvents()
@@ -3785,6 +3794,8 @@ void FrameLoader::receivedMainResourceError(const ResourceError& error, LoadWill
}
if (frame->page())
checkLoadComplete(loadWillContinueInAnotherProcess);
+
+ InspectorInstrumentation::didReceiveMainResourceError(m_frame, error);
}
void FrameLoader::continueFragmentScrollAfterNavigationPolicy(const ResourceRequest& request, const SecurityOrigin* requesterOrigin, bool shouldContinue, NavigationHistoryBehavior historyHandling)
@@ -4789,9 +4800,6 @@ String FrameLoader::referrer() const
void FrameLoader::dispatchDidClearWindowObjectsInAllWorlds()
{
- if (!protect(m_frame->script())->canExecuteScripts(ReasonForCallingCanExecuteScripts::NotAboutToExecuteScript))
- return;
-
Vector<Ref<DOMWrapperWorld>> worlds;
ScriptController::getAllWorlds(worlds);
for (auto& world : worlds)
@@ -4801,13 +4809,12 @@ void FrameLoader::dispatchDidClearWindowObjectsInAllWorlds()
void FrameLoader::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld& world)
{
Ref frame = m_frame.get();
- if (!protect(frame->script())->canExecuteScripts(ReasonForCallingCanExecuteScripts::NotAboutToExecuteScript) || !protect(frame->windowProxy())->existingJSWindowProxy(world))
- return;
-
- m_client->dispatchDidClearWindowObjectInWorld(world);
-
- if (RefPtr page = frame->page())
- page->inspectorController().didClearWindowObjectInWorld(frame, world);
+ if (frame->windowProxy().existingJSWindowProxy(world)) {
+ if (protect(frame->script())->canExecuteScripts(ReasonForCallingCanExecuteScripts::NotAboutToExecuteScript))
+ m_client->dispatchDidClearWindowObjectInWorld(world);
+ if (RefPtr page = frame->page())
+ page->inspectorController().didClearWindowObjectInWorld(m_frame, world);
+ }
InspectorInstrumentation::didClearWindowObjectInWorld(frame, world);
}
diff --git a/Source/WebCore/loader/LoaderStrategy.h b/Source/WebCore/loader/LoaderStrategy.h
index 9a5561ea2fa43baab02c7f8d43d29cf4a5543411..4b1c8dfd6be705aa3560685bb2453dd4e309372f 100644
--- a/Source/WebCore/loader/LoaderStrategy.h
+++ b/Source/WebCore/loader/LoaderStrategy.h
@@ -89,6 +89,7 @@ public:
virtual bool isOnLine() const = 0;
virtual void addOnlineStateChangeListener(Function<void(bool)>&&) = 0;
+ virtual void setEmulateOfflineState(bool) {};
virtual bool shouldPerformSecurityChecks() const { return false; }
virtual bool havePerformedSecurityChecks(const ResourceResponse&) const { return false; }
diff --git a/Source/WebCore/loader/ProgressTracker.cpp b/Source/WebCore/loader/ProgressTracker.cpp
index 3acb026789c46395be3f8cd6b837ebf207e215f7..a4e3c1e69fbbb108badd23f32e879423c0ec72e6 100644
--- a/Source/WebCore/loader/ProgressTracker.cpp
+++ b/Source/WebCore/loader/ProgressTracker.cpp
@@ -158,6 +158,8 @@ void ProgressTracker::progressCompleted(LocalFrame& frame)
if (!m_numProgressTrackedFrames || originatingProgressFrame == &frame)
finalProgressComplete();
+ InspectorInstrumentation::frameStoppedLoading(frame);
+
m_client->didChangeEstimatedProgress();
}
@@ -184,8 +186,6 @@ void ProgressTracker::finalProgressComplete()
m_client->progressFinished(*frame);
protect(m_page)->progressFinished(*frame);
frame->loader().loadProgressingStatusChanged();
-
- InspectorInstrumentation::frameStoppedLoading(*frame);
}
}
diff --git a/Source/WebCore/loader/cache/CachedResourceLoader.cpp b/Source/WebCore/loader/cache/CachedResourceLoader.cpp
index 01466dae0f43c53e7e50dad34c73731fbc8240d6..f37b4130add559d50a869ab494a3f7fb99b275d1 100644
--- a/Source/WebCore/loader/cache/CachedResourceLoader.cpp
+++ b/Source/WebCore/loader/cache/CachedResourceLoader.cpp
@@ -1159,8 +1159,11 @@ ResourceErrorOr<Ref<CachedResource>> CachedResourceLoader::requestResource(Cache
request.updateReferrerPolicy(document ? document->referrerPolicy() : ReferrerPolicy::Default);
- if (InspectorInstrumentation::willIntercept(frame.ptr(), request.resourceRequest()))
- request.setCachingPolicy(CachingPolicy::DisallowCaching);
+ if (InspectorInstrumentation::willIntercept(frame.ptr(), request.resourceRequest())) {
+ // Playwright: we don't disable such caching in other browsers and it breaks css resource downloads,
+ // see https://github.com/microsoft/playwright/issues/19158
+ // request.setCachingPolicy(CachingPolicy::DisallowCaching);
+ }
if (RefPtr documentLoader = m_documentLoader) {
bool madeHTTPS { request.resourceRequest().wasSchemeOptimisticallyUpgraded() };
@@ -1817,8 +1820,9 @@ Vector<Ref<SVGImage>> CachedResourceLoader::allCachedSVGImages() const
ResourceErrorOr<Ref<CachedResource>> CachedResourceLoader::preload(CachedResource::Type type, CachedResourceRequest&& request)
{
- if (InspectorInstrumentation::willIntercept(protect(frame()).get(), request.resourceRequest()))
- return makeUnexpected(ResourceError { errorDomainWebKitInternal, 0, request.resourceRequest().url(), "Inspector intercept"_s });
+ // Playwright: <link rel=preload ... /> requests are intercepted (see https://github.com/microsoft/playwright/issues/16745)
+ // if (InspectorInstrumentation::willIntercept(protect(frame()).get(), request.resourceRequest()))
+ // return makeUnexpected(ResourceError { errorDomainWebKitInternal, 0, request.resourceRequest().url(), "Inspector intercept"_s });
RefPtr document = m_document;
ASSERT(document);
diff --git a/Source/WebCore/page/ChromeClient.h b/Source/WebCore/page/ChromeClient.h
index 1a4fae919b725be107c91cde64f8ccfa30b1e839..2687ebc237823715ebfa06440d54e9dd6dbddd8e 100644
--- a/Source/WebCore/page/ChromeClient.h
+++ b/Source/WebCore/page/ChromeClient.h
@@ -408,7 +408,7 @@ public:
#endif
#if ENABLE(ORIENTATION_EVENTS)
- virtual IntDegrees deviceOrientation() const = 0;
+ virtual IntDegrees deviceOrientation() const { return 0; }
#endif
virtual RefPtr<ColorChooser> createColorChooser(ColorChooserClient&, const Color&) = 0;
diff --git a/Source/WebCore/page/EventHandler.cpp b/Source/WebCore/page/EventHandler.cpp
index d425f52413eba85996fc0a1fae3a0af0974a1d5d..4fa3846cd38402a61676be5330e354ed7d96f92b 100644
--- a/Source/WebCore/page/EventHandler.cpp
+++ b/Source/WebCore/page/EventHandler.cpp
@@ -4823,6 +4823,12 @@ bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event, CheckDr
if (!document)
return false;
+#if PLATFORM(MAC)
+ auto* page = m_frame->page();
+ if (page && !page->overrideDragPasteboardName().isEmpty())
+ dragState().dataTransfer = DataTransfer::createForDrag(*document, page->overrideDragPasteboardName());
+ else
+#endif
dragState().dataTransfer = DataTransfer::createForDrag(*document);
auto hasNonDefaultPasteboardData = HasNonDefaultPasteboardData::No;
@@ -5427,6 +5433,7 @@ static HitTestResult hitTestResultInFrame(LocalFrame* frame, const LayoutPoint&
return result;
}
+WTF_ALLOW_UNSAFE_BUFFER_USAGE_BEGIN
Expected<bool, RemoteFrameGeometryTransformer> EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
{
Ref frame = m_frame.get();
@@ -5558,7 +5565,7 @@ Expected<bool, RemoteFrameGeometryTransformer> EventHandler::handleTouchEvent(co
if (!targetFrame)
continue;
-#if PLATFORM(WPE) || PLATFORM(GTK)
+#if !ENABLE(IOS_TOUCH_EVENTS)
RefPtr<EventTarget> pointerTarget = touchTarget;
if (pointState != PlatformTouchPoint::TouchPressed) {
@@ -5654,6 +5661,7 @@ Expected<bool, RemoteFrameGeometryTransformer> EventHandler::handleTouchEvent(co
return swallowedEvent;
}
+WTF_ALLOW_UNSAFE_BUFFER_USAGE_BEGIN
#endif // ENABLE(TOUCH_EVENTS) && !ENABLE(IOS_TOUCH_EVENTS)
#if ENABLE(TOUCH_EVENTS)
diff --git a/Source/WebCore/page/FocusController.cpp b/Source/WebCore/page/FocusController.cpp
index 1862c8160a30a39f04c64819ab4be917fba219ca..b1877c40f4111f02d448ed9d5df2a2c5723f3a5b 100644
--- a/Source/WebCore/page/FocusController.cpp
+++ b/Source/WebCore/page/FocusController.cpp
@@ -708,13 +708,14 @@ bool FocusController::relinquishFocusToChrome(FocusDirection direction)
return false;
Ref page = m_page.get();
- if (!page->chrome().canTakeFocus(direction) || page->isControlledByAutomation())
+ if (!page->chrome().canTakeFocus(direction))
return false;
clearSelectionIfNeeded(frame.get(), nullptr, nullptr);
document->setFocusedElement(nullptr);
setFocusedFrame(nullptr);
- page->chrome().takeFocus(direction);
+ if (!page->isControlledByAutomation())
+ page->chrome().takeFocus(direction);
return true;
}
diff --git a/Source/WebCore/page/FrameConsoleClient.cpp b/Source/WebCore/page/FrameConsoleClient.cpp
index 23e6d8380ec1e3488bc746887ea06be8eed79fb9..7a1b91c923530472bf1bd613a237dd5a8739b88f 100644
--- a/Source/WebCore/page/FrameConsoleClient.cpp
+++ b/Source/WebCore/page/FrameConsoleClient.cpp
@@ -478,4 +478,12 @@ void FrameConsoleClient::screenshot(JSC::JSGlobalObject* lexicalGlobalObject, Re
addMessage(makeUnique<Inspector::ConsoleMessage>(MessageSource::ConsoleAPI, MessageType::Image, MessageLevel::Log, dataURL, ScriptArguments::create(lexicalGlobalObject, WTF::move(adjustedArguments)), lexicalGlobalObject, /* requestIdentifier */ 0, timestamp));
}
+void FrameConsoleClient::bindingCalled(JSC::JSGlobalObject* globalObject, const String& name, const String& arg)
+{
+ RefPtr frame = m_frame.get();
+ if (!frame)
+ return;
+ InspectorInstrumentation::bindingCalled(*frame->page(), globalObject, name, arg);
+}
+
} // namespace WebCore
diff --git a/Source/WebCore/page/FrameConsoleClient.h b/Source/WebCore/page/FrameConsoleClient.h
index 7a6671ff0da0bbec833318a1c37e6280ad9f4255..5a16fa04c515f0c3842d1187eeacc487a7491080 100644
--- a/Source/WebCore/page/FrameConsoleClient.h
+++ b/Source/WebCore/page/FrameConsoleClient.h
@@ -92,6 +92,7 @@ private:
void record(JSC::JSGlobalObject*, Ref<Inspector::ScriptArguments>&&) override;
void recordEnd(JSC::JSGlobalObject*, Ref<Inspector::ScriptArguments>&&) override;
void screenshot(JSC::JSGlobalObject*, Ref<Inspector::ScriptArguments>&&) override;
+ void bindingCalled(JSC::JSGlobalObject*, const String& name, const String& arg) override;
WeakRef<LocalFrame> m_frame;
};
diff --git a/Source/WebCore/page/FrameSnapshotting.cpp b/Source/WebCore/page/FrameSnapshotting.cpp
index dd21eb7cd8958c99a153769d26e03a8eb5bed0fb..a94d8b5d2eced11e03f963d3848159914d554ae3 100644
--- a/Source/WebCore/page/FrameSnapshotting.cpp
+++ b/Source/WebCore/page/FrameSnapshotting.cpp
@@ -121,7 +121,7 @@ RefPtr<ImageBuffer> snapshotFrameRectWithClip(LocalFrame& frame, const IntRect&
// Other paint behaviors are set by paintContentsForSnapshot.
frame.view()->setPaintBehavior(paintBehavior);
- float scaleFactor = frame.page()->deviceScaleFactor();
+ float scaleFactor = options.flags.contains(SnapshotFlags::OmitDeviceScaleFactor) ? 1 : frame.page()->deviceScaleFactor();
if (options.flags.contains(SnapshotFlags::PaintWith3xBaseScale))
scaleFactor = 3;
@@ -140,6 +140,8 @@ RefPtr<ImageBuffer> snapshotFrameRectWithClip(LocalFrame& frame, const IntRect&
return nullptr;
buffer->context().translate(-imageRect.location());
+ if (coordinateSpace != LocalFrameView::ViewCoordinates)
+ buffer->context().scale(1 / frame.page()->pageScaleFactor());
if (!clipRects.isEmpty()) {
Path clipPath;
@@ -148,7 +150,10 @@ RefPtr<ImageBuffer> snapshotFrameRectWithClip(LocalFrame& frame, const IntRect&
buffer->context().clipPath(clipPath);
}
- frame.view()->paintContentsForSnapshot(buffer->context(), imageRect, shouldIncludeSelection, coordinateSpace);
+ FloatRect fr = imageRect;
+ if (coordinateSpace != LocalFrameView::ViewCoordinates)
+ fr.scale(frame.page()->pageScaleFactor());
+ frame.view()->paintContentsForSnapshot(buffer->context(), enclosingIntRect(fr), shouldIncludeSelection, coordinateSpace);
return buffer;
}
diff --git a/Source/WebCore/page/FrameSnapshotting.h b/Source/WebCore/page/FrameSnapshotting.h
index c34982712f798dff6c484e4a4b6b6a9b23905d4a..52da92d68344cd4d734db4565f174bbd05e26ad9 100644
--- a/Source/WebCore/page/FrameSnapshotting.h
+++ b/Source/WebCore/page/FrameSnapshotting.h
@@ -60,6 +60,7 @@ enum class SnapshotFlags : uint16_t {
FixedAndStickyLayersOnly = 1 << 12,
DraggableElement = 1 << 13,
IncludeDocumentMarkers = 1 << 14,
+ OmitDeviceScaleFactor = 1 << 15,
};
struct SnapshotOptions {
diff --git a/Source/WebCore/page/History.cpp b/Source/WebCore/page/History.cpp
index 6cde8d25af42de8e96f6aa23dbeedb5abaa7feab..bef6092300de6f6d33c5a9e2a9354e00c200d9ef 100644
--- a/Source/WebCore/page/History.cpp
+++ b/Source/WebCore/page/History.cpp
@@ -35,6 +35,7 @@
#include "FrameLoader.h"
#include "HistoryController.h"
#include "HistoryItem.h"
+#include "InspectorInstrumentation.h"
#include "LocalFrame.h"
#include "LocalFrameInlines.h"
#include "LocalFrameLoaderClient.h"
@@ -97,7 +98,7 @@ ExceptionOr<History::ScrollRestoration> History::scrollRestoration() const
RefPtr historyItem = frame->loader().history().currentItem();
if (!historyItem)
return ScrollRestoration::Auto;
-
+
return historyItem->shouldRestoreScrollPosition() ? ScrollRestoration::Auto : ScrollRestoration::Manual;
}
@@ -315,6 +316,8 @@ ExceptionOr<void> History::stateObjectAdded(RefPtr<SerializedScriptValue>&& data
}
frame->loader().updateURLAndHistory(fullURL, WTF::move(data), historyBehavior);
+ InspectorInstrumentation::didNavigateWithinPage(*frame);
+
return { };
}
diff --git a/Source/WebCore/page/LocalFrame.cpp b/Source/WebCore/page/LocalFrame.cpp
index 50342738fed8b72c737e834caa6517b3a642687f..3bf5c788d2a2091c521ae83a211de701d57bce4d 100644
--- a/Source/WebCore/page/LocalFrame.cpp
+++ b/Source/WebCore/page/LocalFrame.cpp
@@ -41,6 +41,7 @@
#include "CachedCSSStyleSheet.h"
#include "Chrome.h"
#include "ChromeClient.h"
+#include "ComposedTreeIterator.h"
#include "DiagnosticLoggingClient.h"
#include "DiagnosticLoggingKeys.h"
#include "DocumentLoader.h"
@@ -92,6 +93,7 @@
#include "MixedContentChecker.h"
#include "Navigator.h"
#include "NodeList.h"
+#include "NodeRenderStyle.h"
#include "NodeTraversal.h"
#include "Page.h"
#include "PaymentSession.h"
@@ -226,6 +228,7 @@ LocalFrame::LocalFrame(Page& page, ClientCreator&& clientCreator, FrameIdentifie
void LocalFrame::init()
{
+ InspectorInstrumentation::frameAttached(this);
loader().init();
}
@@ -462,7 +465,7 @@ void LocalFrame::orientationChanged()
IntDegrees LocalFrame::orientation() const
{
if (RefPtr page = this->page())
- return page->chrome().client().deviceOrientation();
+ return page->orientation();
return 0;
}
#endif // ENABLE(ORIENTATION_EVENTS)
@@ -1672,7 +1675,6 @@ String LocalFrame::frameURLProtocol() const
return ""_s;
}
-#if PLATFORM(COCOA)
static bool nodeIsMouseFocusable(Node& node)
{
@@ -1908,7 +1910,7 @@ RefPtr<Node> LocalFrame::nodeRespondingToDoubleClickEvent(const FloatPoint& view
for (; node && node != terminationNode; node = node->parentInComposedTree()) {
if (!node->hasEventListeners(eventNames().dblclickEvent))
continue;
-#if ENABLE(TOUCH_EVENTS)
+#if ENABLE(TWO_PHASE_CLICKS)
if (!node->allowsDoubleTapGesture())
continue;
#endif
@@ -1922,7 +1924,6 @@ RefPtr<Node> LocalFrame::nodeRespondingToDoubleClickEvent(const FloatPoint& view
return qualifyingNodeAtViewportLocation(viewportLocation, adjustedViewportLocation, WTF::move(ancestorRespondingToDoubleClickEvent), ShouldApproximate::Yes);
}
-#endif // PLATFORM(COCOA)
} // namespace WebCore
diff --git a/Source/WebCore/page/LocalFrame.h b/Source/WebCore/page/LocalFrame.h
index 8f81b0ea3fc343e6c214ad566ab4a6d9b95f5c3b..53ac6ea36a6fb13debd0f029f78c4dc4037d24f2 100644
--- a/Source/WebCore/page/LocalFrame.h
+++ b/Source/WebCore/page/LocalFrame.h
@@ -29,6 +29,7 @@
#include <WebCore/DOMPasteAccess.h>
#include <WebCore/Frame.h>
+#include <WebCore/IntDegrees.h>
#include <WebCore/HitTestRequest.h>
#include <WebCore/ScrollbarMode.h>
#include <wtf/CheckedRef.h>
@@ -129,9 +130,7 @@ enum {
enum OverflowScrollAction { DoNotPerformOverflowScroll, PerformOverflowScroll };
#endif
-#if PLATFORM(COCOA)
using NodeQualifier = Function<RefPtr<Node> (const HitTestResult&, Node* terminationNode, IntRect* nodeBounds)>;
-#endif
class LocalFrame final : public Frame {
public:
@@ -232,7 +231,6 @@ public:
WEBCORE_EXPORT DataDetectionResultsStorage& dataDetectionResults() LIFETIME_BOUND;
#endif
-#if PLATFORM(COCOA)
RefPtr<Node> betterApproximateNode(const IntPoint& testPoint, const NodeQualifier&, Node* best, Node* failedNode, IntPoint& bestPoint, IntRect& bestRect, const IntRect& testRect);
WEBCORE_EXPORT RefPtr<Node> nodeRespondingToInteraction(const FloatPoint& viewportLocation, FloatPoint& adjustedViewportLocation);
@@ -246,7 +244,6 @@ public:
WEBCORE_EXPORT RefPtr<Node> nodeRespondingToDoubleClickEvent(const FloatPoint& viewportLocation, FloatPoint& adjustedViewportLocation);
static bool nodeWillRespondToMouseEvents(Node&);
-#endif // PLATFORM(COCOA)
#if PLATFORM(IOS_FAMILY)
const ViewportArguments& viewportArguments() const LIFETIME_BOUND;
@@ -324,6 +321,7 @@ public:
WEBCORE_EXPORT FloatSize screenSize() const;
void setOverrideScreenSize(FloatSize&&);
+ bool hasScreenSizeOverride() const { return !!m_overrideScreenSize; }
void NODELETE selfOnlyRef();
void selfOnlyDeref();
diff --git a/Source/WebCore/page/Page.cpp b/Source/WebCore/page/Page.cpp
index 52c005d8cf66917c42f05c5cd478b3d2e2b1cac3..13ba48bae2d135b620fd80a642c060a906e3b38c 100644
--- a/Source/WebCore/page/Page.cpp
+++ b/Source/WebCore/page/Page.cpp
@@ -697,6 +697,44 @@ void Page::setOverrideViewportArguments(const std::optional<ViewportArguments>&
localTopDocument->updateViewportArguments();
}
+FloatSize Page::screenSize()
+{
+ RefPtr localMainFrame = this->localMainFrame();
+ RefPtr frameView = localMainFrame ? localMainFrame->view() : nullptr;
+ if (!frameView)
+ return { };
+ return m_overrideScreenSize.value_or(screenRect(frameView.get()).size());
+}
+
+void Page::setOverrideScreenSize(std::optional<FloatSize> size)
+{
+ if (size == m_overrideScreenSize)
+ return;
+
+ m_overrideScreenSize = size;
+ RefPtr localMainFrame = this->localMainFrame();
+ if (auto* document = localMainFrame ? localMainFrame->document() : nullptr)
+ document->updateViewportArguments();
+}
+
+#if ENABLE(ORIENTATION_EVENTS)
+int Page::orientation() const
+{
+ return m_overrideOrientation.value_or(chrome().client().deviceOrientation());
+}
+
+void Page::setOverrideOrientation(std::optional<int> orientation)
+{
+ if (orientation == m_overrideOrientation)
+ return;
+
+ m_overrideOrientation = orientation;
+
+ if (RefPtr localMainFrame = this->localMainFrame())
+ localMainFrame->orientationChanged();
+}
+#endif
+
ScrollingCoordinator* Page::scrollingCoordinator()
{
if (!m_scrollingCoordinator && m_settings->scrollingCoordinatorEnabled()) {
@@ -4417,6 +4455,26 @@ void Page::setUseDarkAppearanceOverride(std::optional<bool> valueOverride)
appearanceDidChange();
}
+void Page::setUseReducedMotionOverride(std::optional<bool> valueOverride)
+{
+ if (valueOverride == m_useReducedMotionOverride)
+ return;
+
+ m_useReducedMotionOverride = valueOverride;
+
+ appearanceDidChange();
+}
+
+void Page::setUseForcedColorsOverride(std::optional<bool> valueOverride)
+{
+ if (valueOverride == m_useForcedColorsOverride)
+ return;
+
+ m_useForcedColorsOverride = valueOverride;
+
+ appearanceDidChange();
+}
+
void Page::setFullscreenInsets(const FloatBoxExtent& insets)
{
if (insets == m_fullscreenInsets)
diff --git a/Source/WebCore/page/Page.h b/Source/WebCore/page/Page.h
index 5bfae7e81b70cbd14f12e307bebd5b551f10c18b..ef95a268fd4aeb4ff5a325517386716ab17f257c 100644
--- a/Source/WebCore/page/Page.h
+++ b/Source/WebCore/page/Page.h
@@ -413,6 +413,9 @@ public:
const ViewportArguments* overrideViewportArguments() const LIFETIME_BOUND { return m_overrideViewportArguments.get(); }
WEBCORE_EXPORT void setOverrideViewportArguments(const std::optional<ViewportArguments>&);
+ WEBCORE_EXPORT FloatSize screenSize();
+ void setOverrideScreenSize(std::optional<FloatSize> size);
+
static void refreshPlugins(bool reload);
WEBCORE_EXPORT PluginData& pluginData();
void clearPluginData();
@@ -498,6 +501,10 @@ public:
#if ENABLE(DRAG_SUPPORT)
DragController& dragController() LIFETIME_BOUND { return m_dragController.get(); }
const DragController& dragController() const LIFETIME_BOUND { return m_dragController.get(); }
+#if PLATFORM(MAC)
+ void setDragPasteboardName(const String& pasteboardName) { m_overrideDragPasteboardName = pasteboardName; }
+ const String& overrideDragPasteboardName() { return m_overrideDragPasteboardName; }
+#endif
#endif
FocusController& focusController() const { return m_focusController; }
#if ENABLE(CONTEXT_MENUS)
@@ -687,6 +694,10 @@ public:
WEBCORE_EXPORT void setUseColorAppearance(bool useDarkAppearance, bool useElevatedUserInterfaceLevel);
bool defaultUseDarkAppearance() const { return m_useDarkAppearance; }
void setUseDarkAppearanceOverride(std::optional<bool>);
+ std::optional<bool> useReducedMotionOverride() const { return m_useReducedMotionOverride; }
+ void setUseReducedMotionOverride(std::optional<bool>);
+ std::optional<bool> useForcedColorsOverride() const { return m_useForcedColorsOverride; }
+ void setUseForcedColorsOverride(std::optional<bool>);
#if ENABLE(TEXT_AUTOSIZING)
float textAutosizingWidth() const { return m_textAutosizingWidth; }
@@ -1150,6 +1161,11 @@ public:
WEBCORE_EXPORT void setInteractionRegionsEnabled(bool);
#endif
+#if ENABLE(ORIENTATION_EVENTS)
+ int orientation() const;
+ WEBCORE_EXPORT void setOverrideOrientation(std::optional<int>);
+#endif
+
#if ENABLE(DEVICE_ORIENTATION) && PLATFORM(IOS_FAMILY)
DeviceOrientationUpdateProvider* deviceOrientationUpdateProvider() const { return m_deviceOrientationUpdateProvider.get(); }
#endif
@@ -1484,6 +1500,9 @@ private:
#if ENABLE(DRAG_SUPPORT)
const UniqueRef<DragController> m_dragController;
+#if PLATFORM(MAC)
+ String m_overrideDragPasteboardName;
+#endif
#endif
const UniqueRef<FocusController> m_focusController;
#if ENABLE(CONTEXT_MENUS)
@@ -1562,6 +1581,8 @@ private:
bool m_useElevatedUserInterfaceLevel { false };
bool m_useDarkAppearance { false };
std::optional<bool> m_useDarkAppearanceOverride;
+ std::optional<bool> m_useReducedMotionOverride;
+ std::optional<bool> m_useForcedColorsOverride;
#if ENABLE(TEXT_AUTOSIZING)
float m_textAutosizingWidth { 0 };
@@ -1739,6 +1760,11 @@ private:
#endif
std::unique_ptr<ViewportArguments> m_overrideViewportArguments;
+ std::optional<FloatSize> m_overrideScreenSize;
+
+#if ENABLE(ORIENTATION_EVENTS)
+ std::optional<int> m_overrideOrientation;
+#endif
#if ENABLE(DEVICE_ORIENTATION) && PLATFORM(IOS_FAMILY)
RefPtr<DeviceOrientationUpdateProvider> m_deviceOrientationUpdateProvider;
diff --git a/Source/WebCore/page/PointerCaptureController.cpp b/Source/WebCore/page/PointerCaptureController.cpp
index e9fa28ab43ecb4f3139791eca2bbb7bd82cfd6e0..8bbb8c76d913c37b60472972eb1647c58622c5a7 100644
--- a/Source/WebCore/page/PointerCaptureController.cpp
+++ b/Source/WebCore/page/PointerCaptureController.cpp
@@ -213,7 +213,7 @@ bool PointerCaptureController::preventsCompatibilityMouseEventsForIdentifier(Poi
return capturingData && capturingData->preventsCompatibilityMouseEvents;
}
-#if ENABLE(TOUCH_EVENTS) && (PLATFORM(IOS_FAMILY) || PLATFORM(WPE) || PLATFORM(GTK))
+#if ENABLE(TOUCH_EVENTS)
static bool hierarchyHasCapturingEventListeners(Element* target, const AtomString& eventName)
{
for (RefPtr<ContainerNode> currentNode = target; currentNode; currentNode = currentNode->parentInComposedTree()) {
@@ -574,7 +574,7 @@ void PointerCaptureController::cancelPointer(PointerID pointerId, const IntPoint
capturingData->pendingTargetOverride = nullptr;
capturingData->state = CapturingData::State::Cancelled;
-#if ENABLE(TOUCH_EVENTS) && (PLATFORM(IOS_FAMILY) || PLATFORM(WPE) || PLATFORM(GTK))
+#if ENABLE(TOUCH_EVENTS)
capturingData->previousTarget = nullptr;
#endif
diff --git a/Source/WebCore/page/PointerCaptureController.h b/Source/WebCore/page/PointerCaptureController.h
index bafa2e9995a142e1bc07d506204ff5f14cbeab9c..d06922b691b02699ca89483c6e4e5c43bb49303c 100644
--- a/Source/WebCore/page/PointerCaptureController.h
+++ b/Source/WebCore/page/PointerCaptureController.h
@@ -63,7 +63,7 @@ public:
RefPtr<PointerEvent> pointerEventForMouseEvent(const MouseEvent&, PointerID, const String& pointerType);
-#if ENABLE(TOUCH_EVENTS) && (PLATFORM(IOS_FAMILY) || PLATFORM(WPE) || PLATFORM(GTK))
+#if ENABLE(TOUCH_EVENTS)
void dispatchEventForTouchAtIndex(EventTarget&, const PlatformTouchEvent&, unsigned, bool isPrimary, WindowProxy&, const DoublePoint&);
#endif
@@ -91,12 +91,12 @@ private:
WeakPtr<Document, WeakPtrImplWithEventTargetData> activeDocument;
RefPtr<Element> pendingTargetOverride;
RefPtr<Element> targetOverride;
-#if ENABLE(TOUCH_EVENTS) && (PLATFORM(IOS_FAMILY) || PLATFORM(WPE) || PLATFORM(GTK))
+#if ENABLE(TOUCH_EVENTS)
RefPtr<Element> previousTarget;
#endif
bool hasAnyElement() const {
return pendingTargetOverride || targetOverride
-#if ENABLE(TOUCH_EVENTS) && (PLATFORM(IOS_FAMILY) || PLATFORM(WPE) || PLATFORM(GTK))
+#if ENABLE(TOUCH_EVENTS)
|| previousTarget
#endif
;
diff --git a/Source/WebCore/page/Screen.cpp b/Source/WebCore/page/Screen.cpp
index cd1f3ce09ba0ab6e414bfcb12f38918404946700..f78cd1f89fb32ce4b9109c80f1f7c303c351b4fc 100644
--- a/Source/WebCore/page/Screen.cpp
+++ b/Source/WebCore/page/Screen.cpp
@@ -125,6 +125,9 @@ int Screen::availLeft() const
if (shouldApplyScreenFingerprintingProtections(*frame))
return 0;
+ if (frame->hasScreenSizeOverride())
+ return 0;
+
return static_cast<int>(screenAvailableRect(protect(frame->view()).get()).x());
}
@@ -140,6 +143,9 @@ int Screen::availTop() const
if (shouldApplyScreenFingerprintingProtections(*frame))
return 0;
+ if (frame->hasScreenSizeOverride())
+ return 0;
+
return static_cast<int>(screenAvailableRect(protect(frame->view()).get()).y());
}
@@ -155,6 +161,9 @@ int Screen::availHeight() const
if (shouldApplyScreenFingerprintingProtections(*frame))
return static_cast<int>(frame->screenSize().height());
+ if (frame->hasScreenSizeOverride())
+ return static_cast<int>(frame->screenSize().height());
+
return static_cast<int>(screenAvailableRect(protect(frame->view()).get()).height());
}
@@ -170,6 +179,9 @@ int Screen::availWidth() const
if (shouldApplyScreenFingerprintingProtections(*frame))
return static_cast<int>(frame->screenSize().width());
+ if (frame->hasScreenSizeOverride())
+ return static_cast<int>(frame->screenSize().width());
+
return static_cast<int>(screenAvailableRect(protect(frame->view()).get()).width());
}
diff --git a/Source/WebCore/page/csp/ContentSecurityPolicy.cpp b/Source/WebCore/page/csp/ContentSecurityPolicy.cpp
index cb4f081221a783cb05b6f65dba5cf338600148d5..88c4adcd84270f24bc4394125d44f34d7b2011c6 100644
--- a/Source/WebCore/page/csp/ContentSecurityPolicy.cpp
+++ b/Source/WebCore/page/csp/ContentSecurityPolicy.cpp
@@ -352,6 +352,8 @@ template<typename Predicate, typename... Args>
bool ContentSecurityPolicy::allPoliciesWithDispositionAllow(Disposition disposition, Predicate&& predicate, Args&&... args) const
requires (!std::is_convertible_v<Predicate, ContentSecurityPolicy::ViolatedDirectiveCallback>)
{
+ if (InspectorInstrumentation::shouldBypassCSP(m_scriptExecutionContext.get()))
+ return true;
bool isReportOnly = disposition == ContentSecurityPolicy::Disposition::ReportOnly;
for (auto& policy : m_policies) {
if (policy->isReportOnly() != isReportOnly)
@@ -365,6 +367,8 @@ bool ContentSecurityPolicy::allPoliciesWithDispositionAllow(Disposition disposit
template<typename Predicate, typename... Args>
bool ContentSecurityPolicy::allPoliciesWithDispositionAllow(Disposition disposition, ViolatedDirectiveCallback&& callback, Predicate&& predicate, Args&&... args) const
{
+ if (InspectorInstrumentation::shouldBypassCSP(m_scriptExecutionContext.get()))
+ return true;
bool isReportOnly = disposition == ContentSecurityPolicy::Disposition::ReportOnly;
bool isAllowed = true;
for (auto& policy : m_policies) {
@@ -381,6 +385,8 @@ bool ContentSecurityPolicy::allPoliciesWithDispositionAllow(Disposition disposit
template<typename Predicate, typename... Args>
bool ContentSecurityPolicy::allPoliciesAllow(NOESCAPE const ViolatedDirectiveCallback& callback, Predicate&& predicate, Args&&... args) const
{
+ if (InspectorInstrumentation::shouldBypassCSP(m_scriptExecutionContext.get()))
+ return true;
bool isAllowed = true;
for (auto& policy : m_policies) {
if (const ContentSecurityPolicyDirective* violatedDirective = (policy.get()->*predicate)(args...)) {
diff --git a/Source/WebCore/page/wpe/DragControllerWPE.cpp b/Source/WebCore/page/wpe/DragControllerWPE.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7bea08826a16de4774a55c81ccba0d81f7d72472
--- /dev/null
+++ b/Source/WebCore/page/wpe/DragControllerWPE.cpp
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2007-20 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "DragController.h"
+
+#include "DataTransfer.h"
+#include "Document.h"
+#include "DragData.h"
+#include "Editor.h"
+#include "Element.h"
+#include "Frame.h"
+#include "FrameDestructionObserverInlines.h"
+#include "LocalFrameInlines.h"
+#include "NodeInlines.h"
+#include "Pasteboard.h"
+#include "markup.h"
+
+namespace WebCore {
+
+// FIXME: These values are straight out of DragControllerMac, so probably have
+// little correlation with Gdk standards...
+const int DragController::MaxOriginalImageArea = 1500 * 1500;
+const int DragController::DragIconRightInset = 7;
+const int DragController::DragIconBottomInset = 3;
+
+const float DragController::DragImageAlpha = 0.75f;
+
+bool DragController::isCopyKeyDown(const DragData& dragData)
+{
+ return dragData.flags().contains(DragApplicationFlags::IsCopyKeyDown);
+}
+
+std::optional<DragOperation> DragController::dragOperation(const DragData& dragData)
+{
+ // FIXME: This logic is incomplete
+ if (dragData.containsURL())
+ return DragOperation::Copy;
+
+ return std::nullopt;
+}
+
+const IntSize& DragController::maxDragImageSize()
+{
+ static const IntSize maxDragImageSize(200, 200);
+ return maxDragImageSize;
+}
+
+void DragController::cleanupAfterSystemDrag()
+{
+}
+
+void DragController::declareAndWriteDragImage(DataTransfer& dataTransfer, Element& element, const URL& url, const String& label)
+{
+ auto* frame = element.document().frame();
+ ASSERT(frame);
+ frame->editor().writeImageToPasteboard(dataTransfer.pasteboard(), element, url, label);
+}
+
+}
diff --git a/Source/WebCore/platform/DragData.h b/Source/WebCore/platform/DragData.h
index 9e2964b6e5f27f3a9c9f39e95b37de574cd52b1b..20e211ebc0217e6f4e66118fd98a7eb42f0edc5d 100644
--- a/Source/WebCore/platform/DragData.h
+++ b/Source/WebCore/platform/DragData.h
@@ -93,8 +93,8 @@ public:
// is initialized by the decoder and not in the constructor.
DragData() = default;
#if PLATFORM(WIN)
- WEBCORE_EXPORT DragData(const DragDataMap&, const IntPoint& clientPosition, const IntPoint& globalPosition, OptionSet<DragOperation> sourceOperationMask, OptionSet<DragApplicationFlags> = { }, std::optional<PageIdentifier> pageID = std::nullopt);
- const DragDataMap& dragDataMap();
+ WEBCORE_EXPORT DragData(const DragDataMap&, const IntPoint& clientPosition, const IntPoint& globalPosition, OptionSet<DragOperation> sourceOperationMask, OptionSet<DragApplicationFlags> = { }, OptionSet<DragDestinationAction> = anyDragDestinationAction(), std::optional<PageIdentifier> pageID = std::nullopt);
+ WEBCORE_EXPORT const DragDataMap& dragDataMap() const;
void getDragFileDescriptorData(int& size, String& pathname);
void getDragFileContentData(int size, void* dataBlob);
#endif
@@ -147,7 +147,7 @@ private:
String m_pasteboardName;
#endif
#if PLATFORM(WIN)
- DragDataMap m_dragDataMap;
+ mutable DragDataMap m_dragDataMap;
#endif
bool m_disallowFileAccess { false };
};
diff --git a/Source/WebCore/platform/Pasteboard.h b/Source/WebCore/platform/Pasteboard.h
index 18569a97050f6711699829d52a3177a4a48e3cca..7e7c7d74edb2f7b9c5769ffd15bf7eb97a7cd396 100644
--- a/Source/WebCore/platform/Pasteboard.h
+++ b/Source/WebCore/platform/Pasteboard.h
@@ -322,6 +322,7 @@ public:
COMPtr<IDataObject> dataObject() const { return m_dataObject; }
WEBCORE_EXPORT void setExternalDataObject(IDataObject*);
const DragDataMap& dragDataMap() const LIFETIME_BOUND { return m_dragDataMap; }
+ WEBCORE_EXPORT DragDataMap createDragDataMap();
void writeURLToWritableDataObject(const URL&, const String&);
COMPtr<WCDataObject> writableDataObject() const { return m_writableDataObject; }
void writeImageToDataObject(Element&, const URL&); // FIXME: Layering violation.
@@ -393,6 +394,7 @@ private:
COMPtr<IDataObject> m_dataObject;
COMPtr<WCDataObject> m_writableDataObject;
DragDataMap m_dragDataMap;
+ bool m_forDrag = false;
#endif
};
diff --git a/Source/WebCore/platform/PlatformKeyboardEvent.h b/Source/WebCore/platform/PlatformKeyboardEvent.h
index 071f9fa0e6cfaa84d9b077e39a64bec9361ead9a..fdd0ec667cc7e2f59bd2d21c5c381ae54dde06d9 100644
--- a/Source/WebCore/platform/PlatformKeyboardEvent.h
+++ b/Source/WebCore/platform/PlatformKeyboardEvent.h
@@ -134,6 +134,7 @@ namespace WebCore {
static String keyCodeForHardwareKeyCode(unsigned);
static String keyIdentifierForWPEKeyCode(unsigned);
static int windowsKeyCodeForWPEKeyCode(unsigned);
+ static unsigned WPEKeyCodeForWindowsKeyCode(int);
static String singleCharacterString(unsigned);
#endif
diff --git a/Source/WebCore/platform/PlatformScreen.cpp b/Source/WebCore/platform/PlatformScreen.cpp
index eac5bf40c150dba990c13775db0ae9e10f883574..563106c0d9fb259c2171aedd5d57efbf81049cc9 100644
--- a/Source/WebCore/platform/PlatformScreen.cpp
+++ b/Source/WebCore/platform/PlatformScreen.cpp
@@ -85,3 +85,24 @@ OptionSet<ContentsFormat> screenContentsFormatsForTesting()
} // namespace WebCore
#endif // PLATFORM(COCOA) || PLATFORM(GTK) || (PLATFORM(WPE) && ENABLE(WPE_PLATFORM))
+
+#if ENABLE(TOUCH_EVENTS)
+namespace WebCore {
+
+static std::optional<bool> _screenHasTouchDeviceOverride = std::nullopt;
+
+void setScreenHasTouchDeviceOverride(bool value) {
+ _screenHasTouchDeviceOverride = value;
+}
+std::optional<bool> screenHasTouchDeviceOverride() {
+ return _screenHasTouchDeviceOverride;
+}
+
+bool screenHasTouchDevice() {
+ if (screenHasTouchDeviceOverride())
+ return screenHasTouchDeviceOverride().value();
+ return platformScreenHasTouchDevice();
+}
+
+} // namespace WebCore
+#endif
diff --git a/Source/WebCore/platform/PlatformScreen.h b/Source/WebCore/platform/PlatformScreen.h
index 2a80049e6065880ac2e9d1a42784fc69659f889d..a804d1251cccef36547551344e9ebf838aec1e18 100644
--- a/Source/WebCore/platform/PlatformScreen.h
+++ b/Source/WebCore/platform/PlatformScreen.h
@@ -162,10 +162,14 @@ WEBCORE_EXPORT float screenScaleFactor(UIScreen * = nullptr);
#endif
#if ENABLE(TOUCH_EVENTS)
-#if PLATFORM(GTK)
+WEBCORE_EXPORT void setScreenHasTouchDeviceOverride(bool);
+WEBCORE_EXPORT std::optional<bool> screenHasTouchDeviceOverride();
+
WEBCORE_EXPORT bool screenHasTouchDevice();
+#if PLATFORM(GTK)
+bool platformScreenHasTouchDevice();
#else
-constexpr bool screenHasTouchDevice() { return true; }
+constexpr bool platformScreenHasTouchDevice() { return true; }
#endif
#endif
diff --git a/Source/WebCore/platform/PlatformTouchEvent.h b/Source/WebCore/platform/PlatformTouchEvent.h
index 8de9b7ed5c5c92eb9700105e5ae186755b13423a..91a007843f7539a2c61121217d393048877a8dc3 100644
--- a/Source/WebCore/platform/PlatformTouchEvent.h
+++ b/Source/WebCore/platform/PlatformTouchEvent.h
@@ -20,8 +20,8 @@
#ifndef PlatformTouchEvent_h
#define PlatformTouchEvent_h
-#include "PlatformEvent.h"
-#include "PlatformTouchPoint.h"
+#include <WebCore/PlatformEvent.h>
+#include <WebCore/PlatformTouchPoint.h>
#include <wtf/Vector.h>
#if ENABLE(TOUCH_EVENTS)
@@ -42,7 +42,7 @@ public:
const Vector<PlatformTouchEvent>& predictedEvents() const LIFETIME_BOUND { return m_predictedEvents; }
-#if PLATFORM(WPE)
+#if !ENABLE(IOS_TOUCH_EVENTS)
// FIXME: since WPE currently does not send touch stationary events, we need to be able to set
// TouchCancelled touchPoints subsequently
void setTouchPoints(Vector<PlatformTouchPoint>& touchPoints) { m_touchPoints = touchPoints; }
diff --git a/Source/WebCore/platform/adwaita/AdwaitaScrollbarPainter.h b/Source/WebCore/platform/adwaita/AdwaitaScrollbarPainter.h
index a251b8f6a5e05997594a2962e7fcb3fab49a27b2..fd95b909650098869d44c8860a525051fc6996f8 100644
--- a/Source/WebCore/platform/adwaita/AdwaitaScrollbarPainter.h
+++ b/Source/WebCore/platform/adwaita/AdwaitaScrollbarPainter.h
@@ -36,7 +36,7 @@ class GraphicsContext;
namespace AdwaitaScrollbarPainter {
-static const unsigned scrollbarSize = 21;
+static const unsigned scrollbarSize = 0;
static const unsigned scrollbarBorderSize = 1;
static const unsigned thumbBorderSize = 1;
static const unsigned overlayThumbSize = 3;
diff --git a/Source/WebCore/platform/graphics/ImageUtilities.h b/Source/WebCore/platform/graphics/ImageUtilities.h
index 2848aea78c6f4e7c75b2896428e4d5f6d32f4273..c1add6e2c65f702c056380a3744cc2af0ab05d7a 100644
--- a/Source/WebCore/platform/graphics/ImageUtilities.h
+++ b/Source/WebCore/platform/graphics/ImageUtilities.h
@@ -81,7 +81,7 @@ WEBCORE_EXPORT void createBitmapsFromImageData(std::span<const uint8_t> data, st
WEBCORE_EXPORT RefPtr<SharedBuffer> createIconDataFromBitmaps(Vector<Ref<ShareableBitmap>>&&);
WEBCORE_EXPORT void decodeImageWithSize(std::span<const uint8_t> data, std::optional<FloatSize>, CompletionHandler<void(RefPtr<ShareableBitmap>&&)>&&);
-Vector<uint8_t> encodeData(CGImageRef, const String& mimeType, std::optional<double> quality = std::nullopt);
+WEBCORE_EXPORT Vector<uint8_t> encodeData(CGImageRef, const String& mimeType, std::optional<double> quality = std::nullopt);
WEBCORE_EXPORT String encodeDataURL(CGImageRef, const String& mimeType, std::optional<double> quality = std::nullopt);
WEBCORE_EXPORT uint8_t NODELETE verifyImageBufferIsBigEnough(std::span<const uint8_t> buffer);
RetainPtr<CFStringRef> utiFromImageBufferMIMEType(const String& mimeType);
diff --git a/Source/WebCore/platform/graphics/filters/software/FEComponentTransferSoftwareApplier.h b/Source/WebCore/platform/graphics/filters/software/FEComponentTransferSoftwareApplier.h
index 515ddea3cd42796efa9f41ad74be07a7447c337e..36db42e2a0822d5609b39046191f05a1f8d2b54b 100644
--- a/Source/WebCore/platform/graphics/filters/software/FEComponentTransferSoftwareApplier.h
+++ b/Source/WebCore/platform/graphics/filters/software/FEComponentTransferSoftwareApplier.h
@@ -23,6 +23,7 @@
#pragma once
#include "FilterEffectApplier.h"
+#include "PixelBuffer.h"
#include <wtf/TZoneMalloc.h>
namespace WebCore {
diff --git a/Source/WebCore/platform/graphics/win/ComplexTextControllerUniscribe.cpp b/Source/WebCore/platform/graphics/win/ComplexTextControllerUniscribe.cpp
index 775df102268b397e6c96e8b93296a7dbe6afcd26..cdbb7b79bde8ba30bc2b0f6bb579b44de72d7fc7 100644
--- a/Source/WebCore/platform/graphics/win/ComplexTextControllerUniscribe.cpp
+++ b/Source/WebCore/platform/graphics/win/ComplexTextControllerUniscribe.cpp
@@ -168,6 +168,33 @@ static Vector<unsigned> stringIndicesFromClusters(const Vector<WORD>& clusters,
return stringIndices;
}
+static int compactScriptItemsIfNeeded(std::span<const UChar> cp, Vector<SCRIPT_ITEM>& items, int numItems, const Font* font)
+{
+ // https://bugs.webkit.org/show_bug.cgi?id=201214
+ // Uniscribe is overly aggressive in separating the runs. It'll split "3d_rotation" into "3", "d", "_" and "rotation" and we
+ // will ScriptShape them separately. As a result, a ligature for "3d_rotation" in the Material icon set
+ // (https://www.materialui.co/icon/3d-rotation) will not be used. A quick and dirty hack is to glue them back here, only making
+ // this apply to the readable characters, digits and _.
+
+ if (!numItems)
+ return numItems;
+
+ if (font->platformData().hasVariations())
+ return numItems;
+
+ bool allGoodCharacters = true;
+ for (unsigned i = 0; allGoodCharacters && i < cp.size(); ++i) {
+ const UChar c = cp[i];
+ allGoodCharacters = (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c == '_';
+ }
+ if (!allGoodCharacters)
+ return numItems;
+
+ // Consume entire string into a single run. |items| is at least numItems + 1 long.
+ items[1] = items[numItems];
+ return 1;
+}
+
void ComplexTextController::collectComplexTextRunsForCharacters(std::span<const char16_t> cp, unsigned stringLocation, const Font* font)
{
if (!font) {
@@ -197,6 +224,8 @@ void ComplexTextController::collectComplexTextRunsForCharacters(std::span<const
}
items.resize(numItems + 1);
+ numItems = compactScriptItemsIfNeeded(cp, items, numItems, font);
+
for (int i = 0; i < numItems; i++) {
// Determine the string for this item.
const char16_t* str = cp.data() + items[i].iCharPos;
diff --git a/Source/WebCore/platform/gtk/PlatformScreenGtk.cpp b/Source/WebCore/platform/gtk/PlatformScreenGtk.cpp
index 98d93889a1b97450fde21cee53e45111b622dca7..9362518e8351eb8fe5b30a2d7875417bb3da770d 100644
--- a/Source/WebCore/platform/gtk/PlatformScreenGtk.cpp
+++ b/Source/WebCore/platform/gtk/PlatformScreenGtk.cpp
@@ -121,7 +121,7 @@ bool screenSupportsExtendedColor(Widget*)
}
#if ENABLE(TOUCH_EVENTS)
-bool screenHasTouchDevice()
+bool platformScreenHasTouchDevice()
{
return getScreenProperties().screenHasTouchDevice;
}
diff --git a/Source/WebCore/platform/libwpe/PlatformKeyboardEventLibWPE.cpp b/Source/WebCore/platform/libwpe/PlatformKeyboardEventLibWPE.cpp
index ee7238303b628d0be016c80e391fe8edb9de1439..dc3b000902cd7d8344ed3a16f49f57766864dd47 100644
--- a/Source/WebCore/platform/libwpe/PlatformKeyboardEventLibWPE.cpp
+++ b/Source/WebCore/platform/libwpe/PlatformKeyboardEventLibWPE.cpp
@@ -29,9 +29,11 @@
#if USE(LIBWPE)
#include "WindowsKeyboardCodes.h"
#include <wpe/wpe.h>
+#include <wtf/HashMap.h>
#include <wtf/HexNumber.h>
#include <wtf/text/MakeString.h>
#include <wtf/text/StringBuilder.h>
+#include <mutex>
#endif
namespace WebCore {
@@ -1304,6 +1306,246 @@ int PlatformKeyboardEvent::windowsKeyCodeForWPEKeyCode(unsigned keycode)
return 0;
}
+static const UncheckedKeyHashMap<int, unsigned>& WPEToWindowsKeyCodeMap()
+{
+ static UncheckedKeyHashMap<int, unsigned>* result;
+ static std::once_flag once;
+ std::call_once(
+ once,
+ [] {
+ const unsigned WPEKeyCodes[] = {
+ WPE_KEY_Cancel,
+ // FIXME: non-keypad keys should take precedence, so we skip WPE_KEY_KP_*
+ // WPE_KEY_KP_0,
+ // WPE_KEY_KP_1,
+ // WPE_KEY_KP_2,
+ // WPE_KEY_KP_3,
+ // WPE_KEY_KP_4,
+ // WPE_KEY_KP_5,
+ // WPE_KEY_KP_6,
+ // WPE_KEY_KP_7,
+ // WPE_KEY_KP_8,
+ // WPE_KEY_KP_9,
+ // WPE_KEY_KP_Multiply,
+ // WPE_KEY_KP_Add,
+ // WPE_KEY_KP_Subtract,
+ // WPE_KEY_KP_Decimal,
+ // WPE_KEY_KP_Divide,
+ // WPE_KEY_KP_Page_Up,
+ // WPE_KEY_KP_Page_Down,
+ // WPE_KEY_KP_End,
+ // WPE_KEY_KP_Home,
+ // WPE_KEY_KP_Left,
+ // WPE_KEY_KP_Up,
+ // WPE_KEY_KP_Right,
+ // WPE_KEY_KP_Down,
+ WPE_KEY_BackSpace,
+ // WPE_KEY_ISO_Left_Tab,
+ // WPE_KEY_3270_BackTab,
+ WPE_KEY_Tab,
+ WPE_KEY_Clear,
+ // WPE_KEY_ISO_Enter,
+ // WPE_KEY_KP_Enter,
+ WPE_KEY_Return,
+ WPE_KEY_Menu,
+ WPE_KEY_Pause,
+ WPE_KEY_AudioPause,
+ WPE_KEY_Caps_Lock,
+ WPE_KEY_Kana_Lock,
+ WPE_KEY_Kana_Shift,
+ WPE_KEY_Hangul,
+ WPE_KEY_Hangul_Hanja,
+ WPE_KEY_Kanji,
+ WPE_KEY_Escape,
+ WPE_KEY_space,
+ WPE_KEY_Page_Up,
+ WPE_KEY_Page_Down,
+ WPE_KEY_End,
+ WPE_KEY_Home,
+ WPE_KEY_Left,
+ WPE_KEY_Up,
+ WPE_KEY_Right,
+ WPE_KEY_Down,
+ WPE_KEY_Select,
+ WPE_KEY_Print,
+ WPE_KEY_Execute,
+ WPE_KEY_Insert,
+ WPE_KEY_KP_Insert,
+ WPE_KEY_Delete,
+ WPE_KEY_KP_Delete,
+ WPE_KEY_Help,
+ WPE_KEY_0,
+ WPE_KEY_parenright,
+ WPE_KEY_1,
+ WPE_KEY_exclam,
+ WPE_KEY_2,
+ WPE_KEY_at,
+ WPE_KEY_3,
+ WPE_KEY_numbersign,
+ WPE_KEY_4,
+ WPE_KEY_dollar,
+ WPE_KEY_5,
+ WPE_KEY_percent,
+ WPE_KEY_6,
+ WPE_KEY_asciicircum,
+ WPE_KEY_7,
+ WPE_KEY_ampersand,
+ WPE_KEY_8,
+ WPE_KEY_asterisk,
+ WPE_KEY_9,
+ WPE_KEY_parenleft,
+ WPE_KEY_a,
+ WPE_KEY_A,
+ WPE_KEY_b,
+ WPE_KEY_B,
+ WPE_KEY_c,
+ WPE_KEY_C,
+ WPE_KEY_d,
+ WPE_KEY_D,
+ WPE_KEY_e,
+ WPE_KEY_E,
+ WPE_KEY_f,
+ WPE_KEY_F,
+ WPE_KEY_g,
+ WPE_KEY_G,
+ WPE_KEY_h,
+ WPE_KEY_H,
+ WPE_KEY_i,
+ WPE_KEY_I,
+ WPE_KEY_j,
+ WPE_KEY_J,
+ WPE_KEY_k,
+ WPE_KEY_K,
+ WPE_KEY_l,
+ WPE_KEY_L,
+ WPE_KEY_m,
+ WPE_KEY_M,
+ WPE_KEY_n,
+ WPE_KEY_N,
+ WPE_KEY_o,
+ WPE_KEY_O,
+ WPE_KEY_p,
+ WPE_KEY_P,
+ WPE_KEY_q,
+ WPE_KEY_Q,
+ WPE_KEY_r,
+ WPE_KEY_R,
+ WPE_KEY_s,
+ WPE_KEY_S,
+ WPE_KEY_t,
+ WPE_KEY_T,
+ WPE_KEY_u,
+ WPE_KEY_U,
+ WPE_KEY_v,
+ WPE_KEY_V,
+ WPE_KEY_w,
+ WPE_KEY_W,
+ WPE_KEY_x,
+ WPE_KEY_X,
+ WPE_KEY_y,
+ WPE_KEY_Y,
+ WPE_KEY_z,
+ WPE_KEY_Z,
+ WPE_KEY_Meta_L,
+ WPE_KEY_Meta_R,
+ WPE_KEY_Sleep,
+ WPE_KEY_Num_Lock,
+ WPE_KEY_Scroll_Lock,
+ WPE_KEY_Shift_L,
+ WPE_KEY_Shift_R,
+ WPE_KEY_Control_L,
+ WPE_KEY_Control_R,
+ WPE_KEY_Alt_L,
+ WPE_KEY_Alt_R,
+ WPE_KEY_Back,
+ WPE_KEY_Forward,
+ WPE_KEY_Refresh,
+ WPE_KEY_Stop,
+ WPE_KEY_Search,
+ WPE_KEY_Favorites,
+ WPE_KEY_HomePage,
+ WPE_KEY_AudioMute,
+ WPE_KEY_AudioLowerVolume,
+ WPE_KEY_AudioRaiseVolume,
+ WPE_KEY_AudioNext,
+ WPE_KEY_AudioPrev,
+ WPE_KEY_AudioStop,
+ WPE_KEY_AudioMedia,
+ WPE_KEY_semicolon,
+ WPE_KEY_colon,
+ WPE_KEY_plus,
+ WPE_KEY_equal,
+ WPE_KEY_comma,
+ WPE_KEY_less,
+ WPE_KEY_minus,
+ WPE_KEY_underscore,
+ WPE_KEY_period,
+ WPE_KEY_greater,
+ WPE_KEY_slash,
+ WPE_KEY_question,
+ WPE_KEY_asciitilde,
+ WPE_KEY_quoteleft,
+ WPE_KEY_bracketleft,
+ WPE_KEY_braceleft,
+ WPE_KEY_backslash,
+ WPE_KEY_bar,
+ WPE_KEY_bracketright,
+ WPE_KEY_braceright,
+ WPE_KEY_quoteright,
+ WPE_KEY_quotedbl,
+ WPE_KEY_AudioRewind,
+ WPE_KEY_AudioForward,
+ WPE_KEY_AudioPlay,
+ WPE_KEY_F1,
+ WPE_KEY_F2,
+ WPE_KEY_F3,
+ WPE_KEY_F4,
+ WPE_KEY_F5,
+ WPE_KEY_F6,
+ WPE_KEY_F7,
+ WPE_KEY_F8,
+ WPE_KEY_F9,
+ WPE_KEY_F10,
+ WPE_KEY_F11,
+ WPE_KEY_F12,
+ WPE_KEY_F13,
+ WPE_KEY_F14,
+ WPE_KEY_F15,
+ WPE_KEY_F16,
+ WPE_KEY_F17,
+ WPE_KEY_F18,
+ WPE_KEY_F19,
+ WPE_KEY_F20,
+ WPE_KEY_F21,
+ WPE_KEY_F22,
+ WPE_KEY_F23,
+ WPE_KEY_F24,
+ WPE_KEY_VoidSymbol,
+ WPE_KEY_Red,
+ WPE_KEY_Green,
+ WPE_KEY_Yellow,
+ WPE_KEY_Blue,
+ WPE_KEY_PowerOff,
+ WPE_KEY_AudioRecord,
+ WPE_KEY_Display,
+ WPE_KEY_Subtitle,
+ WPE_KEY_Video
+ };
+ result = new UncheckedKeyHashMap<int, unsigned>();
+ for (unsigned WPEKeyCode : WPEKeyCodes) {
+ int winKeyCode = PlatformKeyboardEvent::windowsKeyCodeForWPEKeyCode(WPEKeyCode);
+ // If several gdk key codes map to the same win key code first one is used.
+ result->add(winKeyCode, WPEKeyCode);
+ }
+ });
+ return *result;
+}
+
+unsigned PlatformKeyboardEvent::WPEKeyCodeForWindowsKeyCode(int keycode)
+{
+ return WPEToWindowsKeyCodeMap().get(keycode);
+}
+
String PlatformKeyboardEvent::singleCharacterString(unsigned val)
{
switch (val) {
diff --git a/Source/WebCore/platform/libwpe/PlatformPasteboardLibWPE.cpp b/Source/WebCore/platform/libwpe/PlatformPasteboardLibWPE.cpp
index e47f5bade7c0a27e8a27f8dc95b51174f025b4a6..016efe9bc0898bb648a33973e771b49ed4be5624 100644
--- a/Source/WebCore/platform/libwpe/PlatformPasteboardLibWPE.cpp
+++ b/Source/WebCore/platform/libwpe/PlatformPasteboardLibWPE.cpp
@@ -31,10 +31,18 @@
#include "Pasteboard.h"
#include <wpe/wpe.h>
#include <wtf/Assertions.h>
+#include <wtf/HashMap.h>
+#include <wtf/NeverDestroyed.h>
#include <wtf/text/WTFString.h>
namespace WebCore {
+static UncheckedKeyHashMap<String, String>& sharedPasteboard()
+{
+ static NeverDestroyed<UncheckedKeyHashMap<String, String>> pasteboard;
+ return pasteboard.get();
+}
+
PlatformPasteboard::PlatformPasteboard(const String&)
: m_pasteboard(wpe_pasteboard_get_singleton())
{
@@ -59,76 +67,26 @@ int64_t PlatformPasteboard::changeCount() const
void PlatformPasteboard::getTypes(Vector<String>& types) const
{
- struct wpe_pasteboard_string_vector pasteboardTypes = { nullptr, 0 };
- wpe_pasteboard_get_types(m_pasteboard, &pasteboardTypes);
- for (auto& typeString : unsafeMakeSpan(pasteboardTypes.strings, pasteboardTypes.length)) {
- const auto length = std::min(static_cast<size_t>(typeString.length), std::numeric_limits<size_t>::max());
- types.append(String(unsafeMakeSpan(typeString.data, length)));
- }
-
- wpe_pasteboard_string_vector_free(&pasteboardTypes);
+ for (const auto& type : sharedPasteboard().keys())
+ types.append(type);
}
String PlatformPasteboard::readString(size_t, const String& type) const
{
- struct wpe_pasteboard_string string = { nullptr, 0 };
- wpe_pasteboard_get_string(m_pasteboard, type.utf8().data(), &string);
- if (!string.length)
- return String();
-
- const auto length = std::min(static_cast<size_t>(string.length), std::numeric_limits<size_t>::max());
- String returnValue(unsafeMakeSpan(string.data, length));
-
- wpe_pasteboard_string_free(&string);
- return returnValue;
+ return sharedPasteboard().get(type);
}
void PlatformPasteboard::write(const PasteboardWebContent& content)
{
- static constexpr auto plainText = "text/plain;charset=utf-8"_s;
- static constexpr auto htmlText = "text/html"_s;
-
- CString textString = content.text.utf8();
- CString markupString = content.markup.utf8();
-
- IGNORE_CLANG_WARNINGS_BEGIN("unsafe-buffer-usage-in-libc-call")
- std::array<struct wpe_pasteboard_string_pair, 2> pairs = { {
- { { nullptr, 0 }, { nullptr, 0 } },
- { { nullptr, 0 }, { nullptr, 0 } },
- } };
- wpe_pasteboard_string_initialize(&pairs[0].type, plainText, strlen(plainText));
- wpe_pasteboard_string_initialize(&pairs[0].string, textString.data(), textString.length());
- wpe_pasteboard_string_initialize(&pairs[1].type, htmlText, strlen(htmlText));
- wpe_pasteboard_string_initialize(&pairs[1].string, markupString.data(), markupString.length());
- struct wpe_pasteboard_string_map map = { pairs.data(), pairs.size() };
- IGNORE_CLANG_WARNINGS_END
-
- wpe_pasteboard_write(m_pasteboard, &map);
- m_changeCount++;
-
- wpe_pasteboard_string_free(&pairs[0].type);
- wpe_pasteboard_string_free(&pairs[0].string);
- wpe_pasteboard_string_free(&pairs[1].type);
- wpe_pasteboard_string_free(&pairs[1].string);
+ String plainText = "text/plain;charset=utf-8"_s;
+ String htmlText = "text/html;charset=utf-8"_s;
+ sharedPasteboard().set(plainText, content.text);
+ sharedPasteboard().set(htmlText, content.markup);
}
void PlatformPasteboard::write(const String& type, const String& string)
{
- struct wpe_pasteboard_string_pair pairs[] = {
- { { nullptr, 0 }, { nullptr, 0 } },
- };
-
- auto typeUTF8 = type.utf8();
- auto stringUTF8 = string.utf8();
- wpe_pasteboard_string_initialize(&pairs[0].type, typeUTF8.data(), typeUTF8.length());
- wpe_pasteboard_string_initialize(&pairs[0].string, stringUTF8.data(), stringUTF8.length());
- struct wpe_pasteboard_string_map map = { pairs, 1 };
-
- wpe_pasteboard_write(m_pasteboard, &map);
- m_changeCount++;
-
- wpe_pasteboard_string_free(&pairs[0].type);
- wpe_pasteboard_string_free(&pairs[0].string);
+ sharedPasteboard().set(type, string);
}
Vector<String> PlatformPasteboard::typesSafeForDOMToReadAndWrite(const String&) const
diff --git a/Source/WebCore/platform/mediastream/libwebrtc/gstreamer/GStreamerVideoDecoderFactory.cpp b/Source/WebCore/platform/mediastream/libwebrtc/gstreamer/GStreamerVideoDecoderFactory.cpp
index 6a5b3325d2aae3c4769332fa7488e2ca7dd55ef5..3065482616cb5fbc61913f71822262bcbbbd43cf 100644
--- a/Source/WebCore/platform/mediastream/libwebrtc/gstreamer/GStreamerVideoDecoderFactory.cpp
+++ b/Source/WebCore/platform/mediastream/libwebrtc/gstreamer/GStreamerVideoDecoderFactory.cpp
@@ -35,6 +35,7 @@
#include <gst/video/video.h>
#include <wtf/TZoneMallocInlines.h>
#include <wtf/glib/GUniquePtr.h>
+#include <wtf/text/ASCIILiteral.h>
#include <wtf/text/MakeString.h>
#include <wtf/text/WTFString.h>
diff --git a/Source/WebCore/platform/network/HTTPHeaderMap.cpp b/Source/WebCore/platform/network/HTTPHeaderMap.cpp
index df27a094a0b2239892c96b4f5835826bcf8d7540..3bbea5c96110c0ae70d944b7f6fb018e438cf8c4 100644
--- a/Source/WebCore/platform/network/HTTPHeaderMap.cpp
+++ b/Source/WebCore/platform/network/HTTPHeaderMap.cpp
@@ -237,8 +237,11 @@ void HTTPHeaderMap::add(HTTPHeaderName name, const String& value)
auto index = m_commonHeaders.findIf([&](auto& header) {
return header.key == name;
});
+ // Align with Chromium and Firefox, but just for SetCookies where it is critical:
+ // https://bit.ly/2HCa0iq
+ String separator = name == HTTPHeaderName::SetCookie ? "playwright-set-cookie-separator"_s : ", "_s;
if (index != notFound)
- m_commonHeaders[index].value = makeString(m_commonHeaders[index].value, ", "_s, value);
+ m_commonHeaders[index].value = makeString(m_commonHeaders[index].value, separator, value);
else
m_commonHeaders.append(CommonHeader { name, value });
}
diff --git a/Source/WebCore/platform/network/NetworkStorageSession.h b/Source/WebCore/platform/network/NetworkStorageSession.h
index 0640345cf5f133b7f84d3e32b272871d9beff519..320dce768def18327ee25e889109cd6d75ba4cac 100644
--- a/Source/WebCore/platform/network/NetworkStorageSession.h
+++ b/Source/WebCore/platform/network/NetworkStorageSession.h
@@ -201,6 +201,7 @@ public:
NetworkingContext* context() const;
#endif
+ WEBCORE_EXPORT void setCookiesFromResponse(const URL& firstParty, const SameSiteInfo&, const URL&, const String& setCookieValue);
WEBCORE_EXPORT HTTPCookieAcceptPolicy cookieAcceptPolicy() const;
WEBCORE_EXPORT void setCookie(const Cookie&);
diff --git a/Source/WebCore/platform/network/ResourceResponseBase.cpp b/Source/WebCore/platform/network/ResourceResponseBase.cpp
index e413db463376bcf31da4cd0f8e2f869f4b6a0a95..6d43a62553f3e82968964a89608a121a72bc3d74 100644
--- a/Source/WebCore/platform/network/ResourceResponseBase.cpp
+++ b/Source/WebCore/platform/network/ResourceResponseBase.cpp
@@ -21,7 +21,7 @@
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
@@ -77,6 +77,7 @@ ResourceResponseBase::ResourceResponseBase(std::optional<ResourceResponseData>&&
, m_httpStatusText(data ? WTF::move(data->httpStatusText) : String { })
, m_httpVersion(data ? WTF::move(data->httpVersion) : String { })
, m_httpHeaderFields(data ? WTF::move(data->httpHeaderFields) : HTTPHeaderMap { })
+ , m_httpRequestHeaderFields(data ? data->httpRequestHeaderFields : HTTPHeaderMap { })
, m_networkLoadMetrics(data && data->networkLoadMetrics ? Box<NetworkLoadMetrics>::create(WTF::move(*data->networkLoadMetrics)) : Box<NetworkLoadMetrics> { })
, m_certificateInfo(data ? WTF::move(data->certificateInfo) : std::nullopt)
, m_httpStatusCode(data ? data->httpStatusCode : 0)
@@ -277,7 +278,7 @@ const String& ResourceResponseBase::mimeType() const
{
lazyInit(CommonFieldsOnly);
- return m_mimeType;
+ return m_mimeType;
}
void ResourceResponseBase::setMimeType(String&& mimeType)
@@ -291,7 +292,7 @@ void ResourceResponseBase::setMimeType(String&& mimeType)
// FIXME: Should invalidate or update platform response if present.
}
-long long ResourceResponseBase::expectedContentLength() const
+long long ResourceResponseBase::expectedContentLength() const
{
lazyInit(CommonFieldsOnly);
@@ -304,7 +305,7 @@ void ResourceResponseBase::setExpectedContentLength(long long expectedContentLen
m_isNull = false;
// FIXME: Content length is determined by HTTP Content-Length header. We should update the header, so that it doesn't disagree with m_expectedContentLength.
- m_expectedContentLength = expectedContentLength;
+ m_expectedContentLength = expectedContentLength;
// FIXME: Should invalidate or update platform response if present.
}
@@ -395,7 +396,7 @@ const String& ResourceResponseBase::httpStatusText() const
{
lazyInit(AllFields);
- return m_httpStatusText;
+ return m_httpStatusText;
}
void ResourceResponseBase::setHTTPStatusText(String&& statusText)
@@ -410,16 +411,16 @@ void ResourceResponseBase::setHTTPStatusText(String&& statusText)
const String& ResourceResponseBase::httpVersion() const
{
lazyInit(AllFields);
-
+
return m_httpVersion;
}
void ResourceResponseBase::setHTTPVersion(String&& versionText)
{
lazyInit(AllFields);
-
+
m_httpVersion = versionText;
-
+
// FIXME: Should invalidate or update platform response if present.
}
@@ -557,12 +558,12 @@ String ResourceResponseBase::httpHeaderField(StringView name) const
// If we already have the header, just return it instead of consuming memory by grabing all headers.
String value = m_httpHeaderFields.get(name);
- if (!value.isEmpty())
+ if (!value.isEmpty())
return value;
lazyInit(AllFields);
- return m_httpHeaderFields.get(name);
+ return m_httpHeaderFields.get(name);
}
String ResourceResponseBase::httpHeaderField(HTTPHeaderName name) const
@@ -576,7 +577,7 @@ String ResourceResponseBase::httpHeaderField(HTTPHeaderName name) const
lazyInit(AllFields);
- return m_httpHeaderFields.get(name);
+ return m_httpHeaderFields.get(name);
}
void ResourceResponseBase::updateHeaderParsedState(HTTPHeaderName name)
@@ -686,7 +687,7 @@ void ResourceResponseBase::parseCacheControlDirectives() const
m_cacheControlDirectives = WebCore::parseCacheControlDirectives(m_httpHeaderFields);
m_haveParsedCacheControlHeader = true;
}
-
+
bool ResourceResponseBase::cacheControlContainsNoCache() const
{
if (!m_haveParsedCacheControlHeader)
@@ -707,7 +708,7 @@ bool ResourceResponseBase::cacheControlContainsMustRevalidate() const
parseCacheControlDirectives();
return m_cacheControlDirectives.mustRevalidate;
}
-
+
bool ResourceResponseBase::cacheControlContainsImmutable() const
{
if (!m_haveParsedCacheControlHeader)
@@ -862,7 +863,7 @@ void ResourceResponseBase::lazyInit(InitLevel initLevel) const
bool ResourceResponseBase::equalForWebKitLegacyChallengeComparison(const ResourceResponse& a, const ResourceResponse& b)
{
if (a.isNull() != b.isNull())
- return false;
+ return false;
if (a.url() != b.url())
return false;
if (a.mimeType() != b.mimeType())
@@ -896,7 +897,7 @@ std::optional<ResourceResponseData> ResourceResponseBase::getResponseData() cons
if (m_isNull)
return std::nullopt;
lazyInit(AllFields);
-
+
return { ResourceResponseData {
URL { m_url },
String { m_mimeType },
@@ -906,6 +907,7 @@ std::optional<ResourceResponseData> ResourceResponseBase::getResponseData() cons
String { m_httpStatusText },
String { m_httpVersion },
HTTPHeaderMap { m_httpHeaderFields },
+ HTTPHeaderMap { m_httpRequestHeaderFields },
m_networkLoadMetrics ? std::optional(*m_networkLoadMetrics) : std::nullopt,
m_source,
m_type,
@@ -982,6 +984,11 @@ std::optional<WebCore::ResourceResponseData> Coder<WebCore::ResourceResponseData
if (!httpHeaderFields)
return std::nullopt;
+ std::optional<WebCore::HTTPHeaderMap> httpRequestHeaderFields;
+ decoder >> httpRequestHeaderFields;
+ if (!httpRequestHeaderFields)
+ return std::nullopt;
+
std::optional<short> httpStatusCode;
decoder >> httpStatusCode;
if (!httpStatusCode)
@@ -1041,6 +1048,7 @@ std::optional<WebCore::ResourceResponseData> Coder<WebCore::ResourceResponseData
WTF::move(*httpStatusText),
WTF::move(*httpVersion),
WTF::move(*httpHeaderFields),
+ WTF::move(*httpRequestHeaderFields),
std::nullopt,
*source,
*type,
diff --git a/Source/WebCore/platform/network/ResourceResponseBase.h b/Source/WebCore/platform/network/ResourceResponseBase.h
index ef0c552143191b48c1a52a0702c7596da349eff4..b69149fef86c536d95dd01c39da64f719b86e89d 100644
--- a/Source/WebCore/platform/network/ResourceResponseBase.h
+++ b/Source/WebCore/platform/network/ResourceResponseBase.h
@@ -21,7 +21,7 @@
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
@@ -228,9 +228,9 @@ public:
WEBCORE_EXPORT bool containsInvalidHTTPHeaders() const;
WEBCORE_EXPORT static ResourceResponse dataURLResponse(const URL&, const DataURLDecoder::Result&);
-
+
WEBCORE_EXPORT ResourceResponseBase(std::optional<ResourceResponseData>&&);
-
+
WEBCORE_EXPORT std::optional<ResourceResponseData> getResponseData() const;
protected:
@@ -265,6 +265,11 @@ protected:
String m_httpStatusText;
String m_httpVersion;
HTTPHeaderMap m_httpHeaderFields;
+
+public:
+ HTTPHeaderMap m_httpRequestHeaderFields;
+
+protected:
Box<NetworkLoadMetrics> m_networkLoadMetrics;
mutable std::optional<CertificateInfo> m_certificateInfo;
@@ -308,7 +313,7 @@ struct ResourceResponseData {
ResourceResponseData() = default;
ResourceResponseData(ResourceResponseData&&) = default;
ResourceResponseData& operator=(ResourceResponseData&&) = default;
- ResourceResponseData(URL&& url, String&& mimeType, long long expectedContentLength, String&& textEncodingName, int httpStatusCode, String&& httpStatusText, String&& httpVersion, HTTPHeaderMap&& httpHeaderFields, std::optional<NetworkLoadMetrics>&& networkLoadMetrics, ResourceResponseSource source, ResourceResponseBaseType type, ResourceResponseBaseTainting tainting, bool isRedirected, UsedLegacyTLS usedLegacyTLS, WasPrivateRelayed wasPrivateRelayed, String&& proxyName, bool isRangeRequested, std::optional<CertificateInfo> certificateInfo, IPAddressSpace ipAddressSpace)
+ ResourceResponseData(URL&& url, String&& mimeType, long long expectedContentLength, String&& textEncodingName, int httpStatusCode, String&& httpStatusText, String&& httpVersion, HTTPHeaderMap&& httpHeaderFields, HTTPHeaderMap&& httpRequestHeaderFields, std::optional<NetworkLoadMetrics>&& networkLoadMetrics, ResourceResponseSource source, ResourceResponseBaseType type, ResourceResponseBaseTainting tainting, bool isRedirected, UsedLegacyTLS usedLegacyTLS, WasPrivateRelayed wasPrivateRelayed, String&& proxyName, bool isRangeRequested, std::optional<CertificateInfo> certificateInfo, IPAddressSpace ipAddressSpace)
: url(WTF::move(url))
, mimeType(WTF::move(mimeType))
, expectedContentLength(expectedContentLength)
@@ -317,6 +322,7 @@ struct ResourceResponseData {
, httpStatusText(WTF::move(httpStatusText))
, httpVersion(WTF::move(httpVersion))
, httpHeaderFields(WTF::move(httpHeaderFields))
+ , httpRequestHeaderFields(WTF::move(httpRequestHeaderFields))
, networkLoadMetrics(WTF::move(networkLoadMetrics))
, source(source)
, type(type)
@@ -341,6 +347,7 @@ struct ResourceResponseData {
String httpStatusText;
String httpVersion;
HTTPHeaderMap httpHeaderFields;
+ HTTPHeaderMap httpRequestHeaderFields;
std::optional<NetworkLoadMetrics> networkLoadMetrics;
ResourceResponseBase::Source source;
ResourceResponseBase::Type type;
diff --git a/Source/WebCore/platform/network/cocoa/NetworkStorageSessionCocoa.mm b/Source/WebCore/platform/network/cocoa/NetworkStorageSessionCocoa.mm
index 3ed98966972014b88f2a4ca24ea615717a9a812c..7b75b20a84474ac8f227666d2d8305a60c1923f5 100644
--- a/Source/WebCore/platform/network/cocoa/NetworkStorageSessionCocoa.mm
+++ b/Source/WebCore/platform/network/cocoa/NetworkStorageSessionCocoa.mm
@@ -582,6 +582,27 @@ bool NetworkStorageSession::setCookieFromDOM(const URL& firstParty, const SameSi
return false;
}
+void NetworkStorageSession::setCookiesFromResponse(const URL& firstParty, const SameSiteInfo& sameSiteInfo, const URL& url, const String& setCookieValue)
+{
+ auto thirdPartyCookieBlockingDecision = ThirdPartyCookieBlockingDecision::None;
+ Vector<String> cookieValues = setCookieValue.split('\n');
+ size_t count = cookieValues.size();
+ auto* cookies = [NSMutableArray arrayWithCapacity:count];
+ for (const auto& cookieValue : cookieValues) {
+ NSString* cookieString = cookieValue.createNSString().autorelease();
+ NSString* cookieKey = @"Set-Cookie";
+ NSDictionary* headers = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObject:cookieString] forKeys:[NSArray arrayWithObject:cookieKey]];
+ NSArray<NSHTTPCookie*>* parsedCookies = [NSHTTPCookie cookiesWithResponseHeaderFields:headers forURL:url.createNSURL().get()];
+ [cookies addObject:parsedCookies[0]];
+ }
+#if ENABLE(OPT_IN_PARTITIONED_COOKIES) && defined(CFN_COOKIE_ACCEPTS_POLICY_PARTITION) && CFN_COOKIE_ACCEPTS_POLICY_PARTITION
+ String partitionKey = isOptInCookiePartitioningEnabled() ? cookiePartitionIdentifier(firstParty) : String { };
+#else
+ String partitionKey;
+#endif
+ setHTTPCookiesForURL(cookieStorage().get(), cookies, url.createNSURL().get(), firstParty.createNSURL().get(), nsStringNilIfEmpty(partitionKey).get(), sameSiteInfo, thirdPartyCookieBlockingDecision);
+}
+
static NSHTTPCookieAcceptPolicy httpCookieAcceptPolicy(CFHTTPCookieStorageRef cookieStorage)
{
ASSERT(hasProcessPrivilege(ProcessPrivilege::CanAccessRawCookies));
diff --git a/Source/WebCore/platform/network/curl/CookieJarDB.h b/Source/WebCore/platform/network/curl/CookieJarDB.h
index 96e0a63b347c170c963bc7e851f383b91665c5c8..2f0afc26bcc87e9440e201728778892b3fe35543 100644
--- a/Source/WebCore/platform/network/curl/CookieJarDB.h
+++ b/Source/WebCore/platform/network/curl/CookieJarDB.h
@@ -73,7 +73,7 @@ public:
WEBCORE_EXPORT ~CookieJarDB();
private:
- CookieAcceptPolicy m_acceptPolicy { CookieAcceptPolicy::Always };
+ CookieAcceptPolicy m_acceptPolicy { CookieAcceptPolicy::OnlyFromMainDocumentDomain };
String m_databasePath;
bool m_detectedDatabaseCorruption { false };
diff --git a/Source/WebCore/platform/network/curl/NetworkStorageSessionCurl.cpp b/Source/WebCore/platform/network/curl/NetworkStorageSessionCurl.cpp
index 5a78d6c775542cd62d3b192dc60972fdbea92270..5dab0edfef83cc1672012d94bcb4d6390b91bc97 100644
--- a/Source/WebCore/platform/network/curl/NetworkStorageSessionCurl.cpp
+++ b/Source/WebCore/platform/network/curl/NetworkStorageSessionCurl.cpp
@@ -136,6 +136,12 @@ void NetworkStorageSession::setCookieAcceptPolicy(CookieAcceptPolicy policy) con
cookieDatabase().setAcceptPolicy(policy);
}
+void NetworkStorageSession::setCookiesFromResponse(const URL& firstParty, const SameSiteInfo&, const URL& url, const String& setCookieValue)
+{
+ for (auto& cookieString : setCookieValue.split('\n'))
+ cookieDatabase().setCookie(firstParty, url, cookieString, CookieJarDB::Source::Network);
+}
+
HTTPCookieAcceptPolicy NetworkStorageSession::cookieAcceptPolicy() const
{
switch (cookieDatabase().acceptPolicy()) {
diff --git a/Source/WebCore/platform/network/soup/NetworkStorageSessionSoup.cpp b/Source/WebCore/platform/network/soup/NetworkStorageSessionSoup.cpp
index f3c07eb9e056bf031d37b1d2d30a2ebcbe4ba42e..c6b732f75b4e3e823d8c3ebc0b825e389e1d175a 100644
--- a/Source/WebCore/platform/network/soup/NetworkStorageSessionSoup.cpp
+++ b/Source/WebCore/platform/network/soup/NetworkStorageSessionSoup.cpp
@@ -531,6 +531,26 @@ void NetworkStorageSession::replaceCookies(const Vector<Cookie>& cookies)
g_signal_emit(jar, signalId, 0, nullptr, nullptr);
}
+void NetworkStorageSession::setCookiesFromResponse(const URL& firstParty, const SameSiteInfo&, const URL& url, const String& setCookieValue)
+{
+ auto origin = urlToSoupURI(url);
+ if (!origin)
+ return;
+
+ auto firstPartyURI = urlToSoupURI(firstParty);
+ if (!firstPartyURI)
+ return;
+
+ for (auto& cookieString : setCookieValue.split('\n')) {
+ GUniquePtr<SoupCookie> cookie(soup_cookie_parse(cookieString.utf8().data(), origin.get()));
+
+ if (!cookie)
+ continue;
+
+ soup_cookie_jar_add_cookie_full(cookieStorage(), cookie.release(), origin.get(), firstPartyURI.get());
+ }
+}
+
void NetworkStorageSession::deleteCookie(const Cookie& cookie, CompletionHandler<void()>&& completionHandler)
{
GUniquePtr<SoupCookie> targetCookie(cookie.toSoupCookie());
diff --git a/Source/WebCore/platform/text/LocaleICU.cpp b/Source/WebCore/platform/text/LocaleICU.cpp
index 2eaf11c3c0739754768810694c0016d7a21a7951..f25e84fe43e2590829146a1d134776ec549de810 100644
--- a/Source/WebCore/platform/text/LocaleICU.cpp
+++ b/Source/WebCore/platform/text/LocaleICU.cpp
@@ -41,6 +41,7 @@
#include <wtf/TZoneMallocInlines.h>
#include <wtf/text/StringBuffer.h>
#include <wtf/text/StringBuilder.h>
+#include <wtf/TZoneMallocInlines.h>
#include <wtf/unicode/icu/ICUHelpers.h>
#if USE(HARFBUZZ)
diff --git a/Source/WebCore/platform/win/ClipboardUtilitiesWin.cpp b/Source/WebCore/platform/win/ClipboardUtilitiesWin.cpp
index 8e6023c5f1200884723bd0871bf602ba4a37ad04..582365cfb1c9a109308d0133922ee4d2bc0ae7db 100644
--- a/Source/WebCore/platform/win/ClipboardUtilitiesWin.cpp
+++ b/Source/WebCore/platform/win/ClipboardUtilitiesWin.cpp
@@ -39,6 +39,7 @@
#include <wtf/text/StringBuilder.h>
#include <wtf/text/win/WCharStringExtras.h>
#include <wtf/unicode/CharacterNames.h>
+#include "Pasteboard.h"
namespace WebCore {
@@ -690,7 +691,10 @@ template<typename T> void getStringData(IDataObject* data, FORMATETC* format, Ve
STGMEDIUM store;
if (FAILED(data->GetData(format, &store)))
return;
- dataStrings.append(String({ static_cast<T*>(GlobalLock(store.hGlobal)), ::GlobalSize(store.hGlobal) / sizeof(T) }));
+ // The string here should be null terminated, but it could come from another app so lets lock it
+ // to the size to prevent an overflow.
+ String rawString = String({ static_cast<T*>(GlobalLock(store.hGlobal)), ::GlobalSize(store.hGlobal) / sizeof(T) });
+ dataStrings.append(String::fromUTF8(rawString.utf8().data()));
GlobalUnlock(store.hGlobal);
ReleaseStgMedium(&store);
}
diff --git a/Source/WebCore/platform/win/ClipboardUtilitiesWin.h b/Source/WebCore/platform/win/ClipboardUtilitiesWin.h
index 61624f0c555886e11a82e933aa89a093b5273693..4471b458941d3394d99f85e983cf0d86e1a562d3 100644
--- a/Source/WebCore/platform/win/ClipboardUtilitiesWin.h
+++ b/Source/WebCore/platform/win/ClipboardUtilitiesWin.h
@@ -34,6 +34,7 @@ namespace WebCore {
class Document;
class DocumentFragment;
+class Pasteboard;
HGLOBAL createGlobalData(const String&);
HGLOBAL createGlobalData(const Vector<char>&);
diff --git a/Source/WebCore/platform/win/DragDataWin.cpp b/Source/WebCore/platform/win/DragDataWin.cpp
index 0379437d84807e4a8d3846afac5ec8a70e743e70..5b0461bf12535d4900ffaddc2a87826280505233 100644
--- a/Source/WebCore/platform/win/DragDataWin.cpp
+++ b/Source/WebCore/platform/win/DragDataWin.cpp
@@ -40,12 +40,13 @@
namespace WebCore {
-DragData::DragData(const DragDataMap& data, const IntPoint& clientPosition, const IntPoint& globalPosition, OptionSet<DragOperation> sourceOperationMask, OptionSet<DragApplicationFlags> flags, std::optional<PageIdentifier> pageID)
+DragData::DragData(const DragDataMap& data, const IntPoint& clientPosition, const IntPoint& globalPosition, OptionSet<DragOperation> sourceOperationMask, OptionSet<DragApplicationFlags> flags, OptionSet<DragDestinationAction> dragDestinationAction, std::optional<PageIdentifier> pageID)
: m_clientPosition(clientPosition)
, m_globalPosition(globalPosition)
, m_platformDragData(0)
, m_draggingSourceOperationMask(sourceOperationMask)
, m_applicationFlags(flags)
+ , m_dragDestinationActionMask(dragDestinationAction)
, m_pageID(pageID)
, m_dragDataMap(data)
{
@@ -63,7 +64,7 @@ bool DragData::containsURL(FilenameConversionPolicy filenamePolicy) const
|| (filenamePolicy == ConvertFilenames && (m_dragDataMap.contains(filenameWFormat()->cfFormat) || m_dragDataMap.contains(filenameFormat()->cfFormat)));
}
-const DragDataMap& DragData::dragDataMap()
+const DragDataMap& DragData::dragDataMap() const
{
if (!m_dragDataMap.isEmpty() || !m_platformDragData)
return m_dragDataMap;
diff --git a/Source/WebCore/platform/win/KeyEventWin.cpp b/Source/WebCore/platform/win/KeyEventWin.cpp
index f6c0cc49e9c39686bb5a5b36c29762173f2b4d1f..f396b564ee4aa7203d1728ff8460837337e31fdd 100644
--- a/Source/WebCore/platform/win/KeyEventWin.cpp
+++ b/Source/WebCore/platform/win/KeyEventWin.cpp
@@ -41,10 +41,16 @@ namespace WebCore {
static const unsigned short HIGH_BIT_MASK_SHORT = 0x8000;
-void PlatformKeyboardEvent::disambiguateKeyDownEvent(Type, bool)
+void PlatformKeyboardEvent::disambiguateKeyDownEvent(Type type, bool)
{
- // No KeyDown events on Windows to disambiguate.
- ASSERT_NOT_REACHED();
+ m_type = type;
+ if (type == PlatformEvent::Type::RawKeyDown) {
+ m_text = String();
+ m_unmodifiedText = String();
+ } else {
+ m_keyIdentifier = String();
+ m_windowsVirtualKeyCode = 0;
+ }
}
OptionSet<PlatformEvent::Modifier> PlatformKeyboardEvent::currentStateOfModifierKeys()
diff --git a/Source/WebCore/platform/win/PasteboardWin.cpp b/Source/WebCore/platform/win/PasteboardWin.cpp
index 89eb26e07f1bc8174ed50f088a1a9e61e227c627..5949b188bf03caa7c35af1966b3879465f2a92f6 100644
--- a/Source/WebCore/platform/win/PasteboardWin.cpp
+++ b/Source/WebCore/platform/win/PasteboardWin.cpp
@@ -1145,7 +1145,21 @@ void Pasteboard::writeCustomData(const Vector<PasteboardCustomData>& data)
}
clear();
+ if (m_dataObject) {
+ const auto& customData = data.first();
+ customData.forEachPlatformString([&](auto& type, auto& string) {
+ writeString(type, string);
+ });
+ if (customData.hasSameOriginCustomData() || !customData.origin().isEmpty()) {
+ customData.forEachCustomString([&](auto& type, auto& string) {
+ writeString(type, string);
+ });
+ }
+ return;
+ }
+
+ // this is the real real clipboard. Prbaobly need to be doing drag data stuff.
if (::OpenClipboard(m_owner)) {
const auto& customData = data.first();
customData.forEachPlatformStringOrBuffer([](auto& type, auto& stringOrBuffer) {
@@ -1184,4 +1198,25 @@ void Pasteboard::write(const Color&)
{
}
+DragDataMap Pasteboard::createDragDataMap() {
+ DragDataMap dragDataMap;
+ auto dragObject = dataObject();
+ if (!dragObject)
+ return dragDataMap;
+ // Enumerate clipboard content and load it in the map.
+ COMPtr<IEnumFORMATETC> itr;
+
+ if (FAILED(dragObject->EnumFormatEtc(DATADIR_GET, &itr)) || !itr)
+ return dragDataMap;
+
+ FORMATETC dataFormat;
+ while (itr->Next(1, &dataFormat, 0) == S_OK) {
+ Vector<String> dataStrings;
+ getClipboardData(dragObject.get(), &dataFormat, dataStrings);
+ if (!dataStrings.isEmpty())
+ dragDataMap.set(dataFormat.cfFormat, dataStrings);
+ }
+ return dragDataMap;
+}
+
} // namespace WebCore
diff --git a/Source/WebCore/rendering/RenderLayerCompositor.cpp b/Source/WebCore/rendering/RenderLayerCompositor.cpp
index 7cf7bbc03d7824b38b097427587367b50978c2c0..00f87e2b8155d18385cd2aae8461c442266634ef 100644
--- a/Source/WebCore/rendering/RenderLayerCompositor.cpp
+++ b/Source/WebCore/rendering/RenderLayerCompositor.cpp
@@ -1065,8 +1065,10 @@ bool RenderLayerCompositor::updateCompositingLayers(CompositingUpdateType update
return false;
}
+#if !PLATFORM(GTK) // Temporal workaround until https://bugs.webkit.org/show_bug.cgi?id=307077 is fixed
if (!m_compositing && (m_forceCompositingMode || (isRootFrameCompositor() && page().pageOverlayController().overlayCount())))
enableCompositingMode(true);
+#endif
bool isPageScroll = !updateRootArg || updateRootArg == &rootRenderLayer();
CheckedPtr updateRoot = &rootRenderLayer();
diff --git a/Source/WebCore/rendering/RenderTextControl.cpp b/Source/WebCore/rendering/RenderTextControl.cpp
index 7b1911e2444250e1b87bb9fd9b2d6e1e56fa43f0..fdbb83e5ac55b35390f2bf5f383cff5f7bbcf0ae 100644
--- a/Source/WebCore/rendering/RenderTextControl.cpp
+++ b/Source/WebCore/rendering/RenderTextControl.cpp
@@ -244,13 +244,13 @@ void RenderTextControl::layoutExcludedChildren(RelayoutChildren relayoutChildren
}
}
-#if PLATFORM(IOS_FAMILY)
bool RenderTextControl::canScroll() const
{
auto innerText = innerTextElement();
return innerText && innerText->renderer() && innerText->renderer()->hasNonVisibleOverflow();
}
+#if PLATFORM(IOS_FAMILY)
int RenderTextControl::innerLineHeight() const
{
if (auto innerTextElement = this->innerTextElement(); innerTextElement && innerTextElement->renderer())
diff --git a/Source/WebCore/rendering/RenderTextControl.h b/Source/WebCore/rendering/RenderTextControl.h
index 00011d61c20cf7509b03407ecbcc29ce2da0ccca..d939e62c37573487cf4df7a16cf6201b5400cf0c 100644
--- a/Source/WebCore/rendering/RenderTextControl.h
+++ b/Source/WebCore/rendering/RenderTextControl.h
@@ -38,8 +38,8 @@ public:
WEBCORE_EXPORT HTMLTextFormControlElement& NODELETE textFormControlElement() const;
-#if PLATFORM(IOS_FAMILY)
bool canScroll() const;
+#if PLATFORM(IOS_FAMILY)
WEBCORE_EXPORT int innerLineHeight() const;
#endif
diff --git a/Source/WebCore/workers/WorkerConsoleClient.cpp b/Source/WebCore/workers/WorkerConsoleClient.cpp
index fe03d2c8d0625725e07a2aa0eef3a0d9127cf211..9c661ee5f91766bb6d903cfd25f3c7a43d9f3538 100644
--- a/Source/WebCore/workers/WorkerConsoleClient.cpp
+++ b/Source/WebCore/workers/WorkerConsoleClient.cpp
@@ -257,4 +257,6 @@ void WorkerConsoleClient::screenshot(JSC::JSGlobalObject* lexicalGlobalObject, R
InspectorInstrumentation::addMessageToConsole(protect(globalScope()), makeUnique<Inspector::ConsoleMessage>(MessageSource::ConsoleAPI, MessageType::Image, MessageLevel::Log, dataURL, ScriptArguments::create(lexicalGlobalObject, WTF::move(adjustedArguments)), lexicalGlobalObject, /* requestIdentifier */ 0, timestamp));
}
+void WorkerConsoleClient::bindingCalled(JSC::JSGlobalObject*, const String&, const String&) { }
+
} // namespace WebCore
diff --git a/Source/WebCore/workers/WorkerConsoleClient.h b/Source/WebCore/workers/WorkerConsoleClient.h
index 60e744703647b7593426c59814975bf12dc4ebaa..d5156a30396fb2ad7e73c5c5429a07d56df0c928 100644
--- a/Source/WebCore/workers/WorkerConsoleClient.h
+++ b/Source/WebCore/workers/WorkerConsoleClient.h
@@ -59,6 +59,7 @@ private:
void record(JSC::JSGlobalObject*, Ref<Inspector::ScriptArguments>&&) override;
void recordEnd(JSC::JSGlobalObject*, Ref<Inspector::ScriptArguments>&&) override;
void screenshot(JSC::JSGlobalObject*, Ref<Inspector::ScriptArguments>&&) override;
+ void bindingCalled(JSC::JSGlobalObject*, const String& name, const String& arg) override;
WorkerOrWorkletGlobalScope& globalScope() { return m_globalScope; }
diff --git a/Source/WebGPU/WGSL/UniformityAnalysis.cpp b/Source/WebGPU/WGSL/UniformityAnalysis.cpp
index 85806067d986a7f9047708500e1c510fd0df1834..39e066e5882c4fbe8f7b31bfa5d62e3188761709 100644
--- a/Source/WebGPU/WGSL/UniformityAnalysis.cpp
+++ b/Source/WebGPU/WGSL/UniformityAnalysis.cpp
@@ -118,8 +118,10 @@ struct FunctionInfo {
{
switch (severity) {
case SeverityControl::Error: return requiredToBeUniform[0];
+IGNORE_CLANG_WARNINGS_BEGIN("unsafe-buffer-usage")
case SeverityControl::Warning: return requiredToBeUniform[1];
case SeverityControl::Info: return requiredToBeUniform[2];
+IGNORE_CLANG_WARNINGS_END
case SeverityControl::Off: return nullptr;
}
RELEASE_ASSERT_NOT_REACHED();
@@ -311,8 +313,10 @@ std::optional<Error> UniformityGraph::processFunction(AST::Function& function)
m_currentFunction = &info;
info.requiredToBeUniform[0] = info.createNode();
+IGNORE_CLANG_WARNINGS_BEGIN("unsafe-buffer-usage")
info.requiredToBeUniform[1] = info.createNode();
info.requiredToBeUniform[2] = info.createNode();
+IGNORE_CLANG_WARNINGS_END
info.mayBeNonUniform = info.createNode();
info.cfStart = info.createNode();
diff --git a/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp b/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp
index dfc334dff3edea4f775d8f59ba3dd303af861735..de87609382fb0de678b10e8ea77a8c5a6f3acbe9 100644
--- a/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp
+++ b/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp
@@ -99,6 +99,8 @@
#if PLATFORM(COCOA)
#include <wtf/FileSystem.h>
+#include "NetworkDataTaskCocoa.h"
+#include "NetworkSessionCocoa.h"
#include <wtf/OSObjectPtr.h>
#include <wtf/spi/darwin/SandboxSPI.h>
#endif
@@ -1318,6 +1320,14 @@ void NetworkConnectionToWebProcess::clearPageSpecificData(PageIdentifier pageID)
storageSession->clearPageSpecificDataForResourceLoadStatistics(pageID);
}
+void NetworkConnectionToWebProcess::setCookieFromResponse(const URL& firstParty, const SameSiteInfo& sameSiteInfo, const URL& url, const String& setCookieValue)
+{
+ auto* networkStorageSession = storageSession();
+ if (!networkStorageSession)
+ return;
+ networkStorageSession->setCookiesFromResponse(firstParty, sameSiteInfo, url, setCookieValue);
+}
+
void NetworkConnectionToWebProcess::removeStorageAccessForFrame(FrameIdentifier frameID, PageIdentifier pageID)
{
if (CheckedPtr storageSession = m_networkProcess->storageSession(m_sessionID))
diff --git a/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h b/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h
index 5d24c2e36dcdbee25a0bb005bf0a20963d442a31..aff9bb1a0a64d689e15f7be57bed9e5bec80be6a 100644
--- a/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h
+++ b/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h
@@ -399,6 +399,8 @@ private:
void clearPageSpecificData(WebCore::PageIdentifier);
+ void setCookieFromResponse(const URL& firstParty, const WebCore::SameSiteInfo&, const URL& url, const String& setCookieValue);
+
void removeStorageAccessForFrame(WebCore::FrameIdentifier, WebCore::PageIdentifier);
void logUserInteraction(RegistrableDomain&&);
diff --git a/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.messages.in b/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.messages.in
index 6f43a9c68ee5c247184e327bdda83ce65df444f5..b34971ca9e296106dda574f165c4f28d157ecdc6 100644
--- a/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.messages.in
+++ b/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.messages.in
@@ -83,6 +83,8 @@ messages -> NetworkConnectionToWebProcess WantsDispatchMessage {
ClearPageSpecificData(WebCore::PageIdentifier pageID);
+ SetCookieFromResponse(URL firstParty, struct WebCore::SameSiteInfo sameSiteInfo, URL url, String setCookieValue);
+
[EnabledBy=StorageAccessAPIEnabled] RemoveStorageAccessForFrame(WebCore::FrameIdentifier frameID, WebCore::PageIdentifier pageID);
LogUserInteraction(WebCore::RegistrableDomain domain)
ResourceLoadStatisticsUpdated(Vector<WebCore::ResourceLoadStatistics> statistics) -> ()
diff --git a/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm b/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm
index 446f6d91016132ceb2a28122990e844e4576ed4c..0886e0642ac2353de9184b12b8a0d23d6f0f0fd3 100644
--- a/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm
+++ b/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm
@@ -894,6 +894,14 @@ - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)data
resourceResponse.setDeprecatedNetworkLoadMetrics(WebCore::copyTimingData(taskMetrics.get(), networkDataTask->networkLoadMetrics()));
resourceResponse.setProxyName(WTF::move(proxyName));
+
+ __block WebCore::HTTPHeaderMap requestHeaders;
+ NSURLSessionTaskTransactionMetrics *m = dataTask._incompleteTaskMetrics.transactionMetrics.lastObject;
+ [m.request.allHTTPHeaderFields enumerateKeysAndObjectsUsingBlock:^(NSString *name, NSString *value, BOOL *) {
+ requestHeaders.set(String(name), String(value));
+ }];
+ resourceResponse.m_httpRequestHeaderFields = WTF::move(requestHeaders);
+
networkDataTask->didReceiveResponse(WTF::move(resourceResponse), negotiatedLegacyTLS, privateRelayed, [completionHandler = makeBlockPtr(completionHandler), taskIdentifier](WebCore::PolicyAction policyAction) {
#if !LOG_DISABLED
LOG(NetworkSession, "%zu didReceiveResponse completionHandler (%s)", taskIdentifier, toString(policyAction).characters());
diff --git a/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.cpp b/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.cpp
index 0a2c25f815f594b2de6168ffd8b083c625e42e1f..682c4584f34d6fab8b576b331561102d34a3751a 100644
--- a/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.cpp
+++ b/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.cpp
@@ -166,6 +166,7 @@ void NetworkDataTaskCurl::curlDidReceiveResponse(CurlRequest& request, CurlRespo
updateNetworkLoadMetrics(receivedResponse.networkLoadMetrics);
m_response.setDeprecatedNetworkLoadMetrics(Box<NetworkLoadMetrics>::create(WTF::move(receivedResponse.networkLoadMetrics)));
+ m_response.m_httpRequestHeaderFields = request.resourceRequest().httpHeaderFields();
handleCookieHeaders(request.resourceRequest(), receivedResponse);
diff --git a/Source/WebKit/NetworkProcess/mac/com.apple.WebKit.NetworkProcess.sb.in b/Source/WebKit/NetworkProcess/mac/com.apple.WebKit.NetworkProcess.sb.in
index 38aee06c97b6c7d20e0569295bde4192999d9c6e..eb7159615e69a275fe0b52790311209e698458a3 100644
--- a/Source/WebKit/NetworkProcess/mac/com.apple.WebKit.NetworkProcess.sb.in
+++ b/Source/WebKit/NetworkProcess/mac/com.apple.WebKit.NetworkProcess.sb.in
@@ -455,9 +455,11 @@
;; FIXME: This should be removed when <rdar://problem/10479685> is fixed.
;; Restrict AppSandboxed processes from creating /Library/Keychains, but allow access to the contents of /Library/Keychains:
-(allow file-read-data file-read-metadata
- (subpath "/Library/Keychains")
- (home-subpath "/Library/Keychains"))
+;; Playwright begin
+;; (allow file-read-data file-read-metadata
+;; (subpath "/Library/Keychains")
+;; (home-subpath "/Library/Keychains"))
+;; Playwright end
;; Except deny access to new-style iOS Keychain folders which are UUIDs.
(deny file-read* file-write*
diff --git a/Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.cpp b/Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.cpp
index f7edb09dfd0bcee4b60f4bf8ce16f8cbeea937f8..1c10fb6ea21b897015a5c0092fc8f6cd4fb34c0c 100644
--- a/Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.cpp
+++ b/Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.cpp
@@ -427,6 +427,8 @@ void NetworkDataTaskSoup::didSendRequest(GRefPtr<GInputStream>&& inputStream)
else
m_inputStream = WTF::move(inputStream);
+ auto& additionalMetrics = additionalNetworkLoadMetricsForWebInspector();
+ m_response.m_httpRequestHeaderFields = additionalMetrics.requestHeaders;
dispatchDidReceiveResponse();
}
diff --git a/Source/WebKit/PlatformWPE.cmake b/Source/WebKit/PlatformWPE.cmake
index f98ae19e9c5fa4b0601572de46b1e0a1c62e92d8..747157cb6b47441ed2c1ca89465c81a89acc7f2a 100644
--- a/Source/WebKit/PlatformWPE.cmake
+++ b/Source/WebKit/PlatformWPE.cmake
@@ -227,6 +227,7 @@ set(WPE_API_HEADER_TEMPLATES
${WEBKIT_DIR}/UIProcess/API/glib/WebKitWebsitePolicies.h.in
${WEBKIT_DIR}/UIProcess/API/glib/WebKitXRPermissionRequest.h.in
${WEBKIT_DIR}/UIProcess/API/glib/webkit.h.in
+ ${WEBKIT_DIR}/UIProcess/API/gtk/WebKitPointerLockPermissionRequest.h.in
)
if (ENABLE_2022_GLIB_API)
diff --git a/Source/WebKit/PlatformWin.cmake b/Source/WebKit/PlatformWin.cmake
index 86a1febedca9fcbe7203db8cec94e8db1ef25a43..efdc87688149706c783906b643489fbe695d61d2 100644
--- a/Source/WebKit/PlatformWin.cmake
+++ b/Source/WebKit/PlatformWin.cmake
@@ -54,8 +54,13 @@ list(APPEND WebKit_SOURCES
UIProcess/win/AutomationClientWin.cpp
UIProcess/win/AutomationSessionClientWin.cpp
+
+ UIProcess/win/InspectorPlaywrightAgentClientWin.cpp
UIProcess/win/PageClientImpl.cpp
+ UIProcess/win/PageInspectorTargetProxyWin.cpp
UIProcess/win/WebContextMenuProxyWin.cpp
+ UIProcess/win/WebPageInspectorEmulationAgentWin.cpp
+ UIProcess/win/WebPageInspectorInputAgentWin.cpp
UIProcess/win/WebPageProxyWin.cpp
UIProcess/win/WebPopupMenuProxyWin.cpp
UIProcess/win/WebProcessPoolWin.cpp
@@ -71,6 +76,7 @@ list(APPEND WebKit_SOURCES
WebProcess/MediaCache/WebMediaKeyStorageManager.cpp
WebProcess/WebCoreSupport/win/WebPopupMenuWin.cpp
+ WebProcess/WebCoreSupport/win/WebDragClientWin.cpp
WebProcess/WebPage/CoordinatedGraphics/DrawingAreaCoordinatedGraphics.cpp
diff --git a/Source/WebKit/Shared/API/Cocoa/WebKitPrivate.h b/Source/WebKit/Shared/API/Cocoa/WebKitPrivate.h
index 5c7a6999176357ad21ca673db75363f27cf33790..faa9a55d561a185a659519bcaa5a1026fa3b1921 100644
--- a/Source/WebKit/Shared/API/Cocoa/WebKitPrivate.h
+++ b/Source/WebKit/Shared/API/Cocoa/WebKitPrivate.h
@@ -45,6 +45,7 @@
#import <WebKit/WKWebViewPrivate.h>
#import <WebKit/_WKActivatedElementInfo.h>
#import <WebKit/_WKAttachment.h>
+#import <WebKit/_WKBrowserInspector.h>
#import <WebKit/_WKCaptionStyleMenuController.h>
#import <WebKit/_WKContentWorldConfiguration.h>
#import <WebKit/_WKElementAction.h>
diff --git a/Source/WebKit/Shared/AuxiliaryProcess.h b/Source/WebKit/Shared/AuxiliaryProcess.h
index 04ffbae16bdfe24465e635afce7f5042073158a0..9c87adff05fcdc47fb15cc4bcac86c26882c6e3e 100644
--- a/Source/WebKit/Shared/AuxiliaryProcess.h
+++ b/Source/WebKit/Shared/AuxiliaryProcess.h
@@ -216,6 +216,11 @@ struct AuxiliaryProcessInitializationParameters {
IPC::Connection::Identifier connectionIdentifier;
HashMap<String, String> extraInitializationData;
WTF::AuxiliaryProcessType processType;
+// Playwright begin
+#if !PLATFORM(COCOA)
+ bool shouldEnableSharedArrayBuffer { false };
+#endif
+// Playwright end
};
} // namespace WebKit
diff --git a/Source/WebKit/Shared/NativeWebKeyboardEvent.h b/Source/WebKit/Shared/NativeWebKeyboardEvent.h
index 63cfe7fc9385af4f17293ad0e43997e688401cd8..e22b7ee6001ee06a731f01c4ca3ab2d3e2e525a8 100644
--- a/Source/WebKit/Shared/NativeWebKeyboardEvent.h
+++ b/Source/WebKit/Shared/NativeWebKeyboardEvent.h
@@ -33,6 +33,7 @@
#if USE(APPKIT)
#include <wtf/RetainPtr.h>
OBJC_CLASS NSView;
+OBJC_CLASS NSEvent;
#endif
#if PLATFORM(GTK)
@@ -70,11 +71,19 @@ public:
#if USE(APPKIT)
// FIXME: Share iOS's HandledByInputMethod enum here instead of passing a boolean.
NativeWebKeyboardEvent(NSEvent *, bool handledByInputMethod, bool replacesSoftSpace, const Vector<WebCore::KeypressCommand>&);
+ NativeWebKeyboardEvent(WebEventType type, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<WebEventModifier> modifiers, MonotonicTime timestamp, Vector<WebCore::KeypressCommand>&& commands)
+ : WebKeyboardEvent(type, text, unmodifiedText, key, code, keyIdentifier, windowsVirtualKeyCode, nativeVirtualKeyCode, isAutoRepeat, isKeypad, isSystemKey, modifiers, timestamp, WTF::move(commands))
+ {
+ }
#elif PLATFORM(GTK)
NativeWebKeyboardEvent(const NativeWebKeyboardEvent&);
NativeWebKeyboardEvent(GdkEvent*, const String&, bool isAutoRepeat, Vector<String>&& commands);
NativeWebKeyboardEvent(const String&, std::optional<Vector<WebCore::CompositionUnderline>>&&, std::optional<EditingRange>&&);
NativeWebKeyboardEvent(WebEventType, const String& text, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, Vector<String>&& commands, bool isAutoRepeat, bool isKeypad, OptionSet<WebEventModifier>);
+ NativeWebKeyboardEvent(WebEventType type, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<WebEventModifier> modifiers, MonotonicTime timestamp, Vector<String>&& commands)
+ : WebKeyboardEvent(type, text, unmodifiedText, key, code, keyIdentifier, windowsVirtualKeyCode, nativeVirtualKeyCode, isAutoRepeat, isKeypad, isSystemKey, modifiers, timestamp, WTF::move(commands))
+ {
+ }
#elif PLATFORM(IOS_FAMILY)
enum class HandledByInputMethod : bool { No, Yes };
NativeWebKeyboardEvent(::WebEvent *, HandledByInputMethod);
@@ -82,6 +91,10 @@ public:
#if USE(LIBWPE)
enum class HandledByInputMethod : bool { No, Yes };
NativeWebKeyboardEvent(struct wpe_input_keyboard_event*, const String&, bool isAutoRepeat, HandledByInputMethod, std::optional<Vector<WebCore::CompositionUnderline>>&&, std::optional<EditingRange>&&);
+ NativeWebKeyboardEvent(WebEventType type, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<WebEventModifier> modifiers, MonotonicTime timestamp)
+ : WebKeyboardEvent(type, text, unmodifiedText, key, code, keyIdentifier, windowsVirtualKeyCode, nativeVirtualKeyCode, isAutoRepeat, isKeypad, isSystemKey, modifiers, timestamp)
+ {
+ }
#endif
#if ENABLE(WPE_PLATFORM)
NativeWebKeyboardEvent(WPEEvent*, const String&, bool isAutoRepeat);
@@ -92,6 +105,10 @@ public:
NativeWebKeyboardEvent(struct wpe_input_keyboard_event*, const String&, bool isAutoRepeat, HandledByInputMethod, std::optional<Vector<WebCore::CompositionUnderline>>&&, std::optional<EditingRange>&&);
#elif PLATFORM(WIN)
NativeWebKeyboardEvent(HWND, UINT message, WPARAM, LPARAM, Vector<MSG>&& pendingCharEvents);
+ NativeWebKeyboardEvent(WebEventType type, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<WebEventModifier> modifiers, MonotonicTime timestamp)
+ : WebKeyboardEvent(type, text, unmodifiedText, key, code, keyIdentifier, windowsVirtualKeyCode, nativeVirtualKeyCode, isAutoRepeat, isKeypad, isSystemKey, modifiers, timestamp)
+ {
+ }
#endif
#if USE(APPKIT)
diff --git a/Source/WebKit/Shared/NativeWebMouseEvent.h b/Source/WebKit/Shared/NativeWebMouseEvent.h
index 3f1087581732873bef9aab9de8010804a337e3e5..feb044c070a3042b3c4bf2e81078e52d5c8f7382 100644
--- a/Source/WebKit/Shared/NativeWebMouseEvent.h
+++ b/Source/WebKit/Shared/NativeWebMouseEvent.h
@@ -91,6 +91,11 @@ public:
NativeWebMouseEvent(HWND, UINT message, WPARAM, LPARAM, bool, float deviceScaleFactor);
#endif
+#if PLATFORM(GTK) || USE(LIBWPE) || PLATFORM(WIN)
+ NativeWebMouseEvent(WebEventType type, WebMouseEventButton button, unsigned short buttons, const WebCore::IntPoint& position, const WebCore::IntPoint& globalPosition, float deltaX, float deltaY, float deltaZ, int clickCount, OptionSet<WebEventModifier> modifiers, MonotonicTime timestamp)
+ : WebMouseEvent({type, modifiers, timestamp}, button, buttons, position, globalPosition, deltaX, deltaY, deltaZ, clickCount, 0, WebEventInputSource::UserDriven) { }
+#endif
+
#if USE(APPKIT)
NSEvent* nativeEvent() const { return m_nativeEvent.get(); }
#elif PLATFORM(GTK)
diff --git a/Source/WebKit/Shared/NativeWebWheelEvent.h b/Source/WebKit/Shared/NativeWebWheelEvent.h
index b5361fedd7d921f512956d20819c49d425221080..3628908eeaba9dda7c19ded41b6da6e5c148d382 100644
--- a/Source/WebKit/Shared/NativeWebWheelEvent.h
+++ b/Source/WebKit/Shared/NativeWebWheelEvent.h
@@ -79,6 +79,11 @@ public:
NativeWebWheelEvent(HWND, UINT message, WPARAM, LPARAM, float deviceScaleFactor);
#endif
+#if !USE(APPKIT)
+ NativeWebWheelEvent(const WebWheelEvent & webWheelEvent)
+ : WebWheelEvent(webWheelEvent) { }
+#endif
+
#if USE(APPKIT)
NSEvent* nativeEvent() const { return m_nativeEvent.get(); }
#elif PLATFORM(GTK)
diff --git a/Source/WebKit/Shared/WebCoreArgumentCoders.serialization.in b/Source/WebKit/Shared/WebCoreArgumentCoders.serialization.in
index 597e611a1b621f049fa034d7934cb7918cad8f87..5829c63b669d57903b73d7078a41ebfe9006fc89 100644
--- a/Source/WebKit/Shared/WebCoreArgumentCoders.serialization.in
+++ b/Source/WebKit/Shared/WebCoreArgumentCoders.serialization.in
@@ -2728,6 +2728,9 @@ class WebCore::AuthenticationChallenge {
class WebCore::DragData {
#if PLATFORM(COCOA)
String pasteboardName();
+#endif
+#if PLATFORM(WIN)
+ WebCore::DragDataMap dragDataMap();
#endif
WebCore::IntPoint clientPosition();
WebCore::IntPoint globalPosition();
@@ -3160,6 +3163,7 @@ enum class WebCore::WasPrivateRelayed : bool;
String httpStatusText;
String httpVersion;
WebCore::HTTPHeaderMap httpHeaderFields;
+ WebCore::HTTPHeaderMap httpRequestHeaderFields;
std::optional<WebCore::NetworkLoadMetrics> networkLoadMetrics;
WebCore::ResourceResponseBase::Source source;
WebCore::ResourceResponseBase::Type type;
diff --git a/Source/WebKit/Shared/WebKeyboardEvent.cpp b/Source/WebKit/Shared/WebKeyboardEvent.cpp
index fcadde7e024c363ebdf53d1c20436af5d2512e1a..67cd6dce8d6c1bf66e429c29d9ed0a396718cb80 100644
--- a/Source/WebKit/Shared/WebKeyboardEvent.cpp
+++ b/Source/WebKit/Shared/WebKeyboardEvent.cpp
@@ -51,6 +51,24 @@ WebKeyboardEvent::WebKeyboardEvent(WebEvent&& event, const String& text, const S
ASSERT(isKeyboardEventType(type()));
}
+WebKeyboardEvent::WebKeyboardEvent(WebEventType type, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<WebEventModifier> modifiers, MonotonicTime timestamp, Vector<WebCore::KeypressCommand>&& commands)
+ : WebEvent(type, modifiers, timestamp)
+ , m_text(text)
+ , m_unmodifiedText(text)
+ , m_key(key)
+ , m_code(code)
+ , m_keyIdentifier(keyIdentifier)
+ , m_windowsVirtualKeyCode(windowsVirtualKeyCode)
+ , m_nativeVirtualKeyCode(nativeVirtualKeyCode)
+ , m_macCharCode(0)
+ , m_commands(WTF::move(commands))
+ , m_isAutoRepeat(isAutoRepeat)
+ , m_isKeypad(isKeypad)
+ , m_isSystemKey(isSystemKey)
+{
+ ASSERT(isKeyboardEventType(type));
+}
+
#elif PLATFORM(GTK)
WebKeyboardEvent::WebKeyboardEvent(WebEvent&& event, const String& text, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool handledByInputMethod, std::optional<Vector<WebCore::CompositionUnderline>>&& preeditUnderlines, std::optional<EditingRange>&& preeditSelectionRange, Vector<String>&& commands, bool isAutoRepeat, bool isKeypad)
@@ -74,6 +92,24 @@ WebKeyboardEvent::WebKeyboardEvent(WebEvent&& event, const String& text, const S
ASSERT(isKeyboardEventType(type()));
}
+WebKeyboardEvent::WebKeyboardEvent(WebEventType type, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<WebEventModifier> modifiers, MonotonicTime timestamp, Vector<String>&& commands)
+ : WebEvent(type, modifiers, timestamp)
+ , m_text(text)
+ , m_unmodifiedText(text)
+ , m_key(key)
+ , m_code(code)
+ , m_keyIdentifier(keyIdentifier)
+ , m_windowsVirtualKeyCode(windowsVirtualKeyCode)
+ , m_nativeVirtualKeyCode(nativeVirtualKeyCode)
+ , m_macCharCode(0)
+ , m_commands(WTF::move(commands))
+ , m_isAutoRepeat(isAutoRepeat)
+ , m_isKeypad(isKeypad)
+ , m_isSystemKey(isSystemKey)
+{
+ ASSERT(isKeyboardEventType(type));
+}
+
#elif PLATFORM(IOS_FAMILY)
WebKeyboardEvent::WebKeyboardEvent(WebEvent&& event, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, int macCharCode, bool handledByInputMethod, bool isAutoRepeat, bool isKeypad, bool isSystemKey)
@@ -137,6 +173,27 @@ WebKeyboardEvent::WebKeyboardEvent(WebEvent&& event, const String& text, const S
#endif
+#if PLATFORM(WIN) || USE(LIBWPE)
+
+WebKeyboardEvent::WebKeyboardEvent(WebEventType type, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<WebEventModifier> modifiers, MonotonicTime timestamp)
+ : WebEvent(type, modifiers, timestamp)
+ , m_text(text)
+ , m_unmodifiedText(text)
+ , m_key(key)
+ , m_code(code)
+ , m_keyIdentifier(keyIdentifier)
+ , m_windowsVirtualKeyCode(windowsVirtualKeyCode)
+ , m_nativeVirtualKeyCode(nativeVirtualKeyCode)
+ , m_macCharCode(0)
+ , m_isAutoRepeat(isAutoRepeat)
+ , m_isKeypad(isKeypad)
+ , m_isSystemKey(isSystemKey)
+{
+ ASSERT(isKeyboardEventType(type));
+}
+
+#endif
+
WebKeyboardEvent::~WebKeyboardEvent() = default;
bool WebKeyboardEvent::isKeyboardEventType(WebEventType type)
diff --git a/Source/WebKit/Shared/WebKeyboardEvent.h b/Source/WebKit/Shared/WebKeyboardEvent.h
index 8915f44919a131e5e12344362907396b3821e13e..62846c5c837a584c4180d6c5d069fc39c8b58980 100644
--- a/Source/WebKit/Shared/WebKeyboardEvent.h
+++ b/Source/WebKit/Shared/WebKeyboardEvent.h
@@ -42,14 +42,18 @@ public:
#if USE(APPKIT)
WebKeyboardEvent(WebEvent&&, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, int macCharCode, bool handledByInputMethod, const Vector<WebCore::KeypressCommand>&, bool isAutoRepeat, bool isKeypad, bool isSystemKey);
+ WebKeyboardEvent(WebEventType, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<WebEventModifier>, MonotonicTime timestamp, Vector<WebCore::KeypressCommand>&& commands);
#elif PLATFORM(GTK)
WebKeyboardEvent(WebEvent&&, const String& text, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool handledByInputMethod, std::optional<Vector<WebCore::CompositionUnderline>>&&, std::optional<EditingRange>&&, Vector<String>&& commands, bool isAutoRepeat, bool isKeypad);
+ WebKeyboardEvent(WebEventType, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<WebEventModifier>, MonotonicTime timestamp, Vector<String>&& commands);
#elif PLATFORM(IOS_FAMILY)
WebKeyboardEvent(WebEvent&&, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, int macCharCode, bool handledByInputMethod, bool isAutoRepeat, bool isKeypad, bool isSystemKey);
#elif USE(LIBWPE) || ENABLE(WPE_PLATFORM)
WebKeyboardEvent(WebEvent&&, const String& text, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool handledByInputMethod, std::optional<Vector<WebCore::CompositionUnderline>>&&, std::optional<EditingRange>&&, bool isAutoRepeat, bool isKeypad);
+ WebKeyboardEvent(WebEventType, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<WebEventModifier>, MonotonicTime timestamp);
#else
WebKeyboardEvent(WebEvent&&, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, int macCharCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey);
+ WebKeyboardEvent(WebEventType, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<WebEventModifier>, MonotonicTime timestamp);
#endif
const String& text() const LIFETIME_BOUND { return m_text; }
@@ -93,6 +97,7 @@ public:
static String keyCodeStringForGdkKeycode(unsigned);
static String keyIdentifierForGdkKeyval(unsigned);
static int windowsKeyCodeForGdkKeyval(unsigned);
+ static unsigned gdkKeyCodeForWindowsKeyCode(int);
static String singleCharacterStringForGdkKeyval(unsigned);
#endif
diff --git a/Source/WebKit/Shared/WebMouseEvent.h b/Source/WebKit/Shared/WebMouseEvent.h
index 3accf5c66062f746029665e4a9ef970418784df2..e16205860562432eedeb017d354cd0c948b0e036 100644
--- a/Source/WebKit/Shared/WebMouseEvent.h
+++ b/Source/WebKit/Shared/WebMouseEvent.h
@@ -72,6 +72,7 @@ public:
WebMouseEventButton button() const { return m_button; }
unsigned short buttons() const { return m_buttons; }
+ void playwrightSetButtons(unsigned short buttons) { m_buttons = buttons; }
const WebCore::DoublePoint& position() const { return m_position; } // Relative to the view.
void setPosition(const WebCore::DoublePoint& position) { m_position = position; }
const WebCore::DoublePoint& globalPosition() const LIFETIME_BOUND { return m_globalPosition; }
diff --git a/Source/WebKit/Shared/WebPageCreationParameters.h b/Source/WebKit/Shared/WebPageCreationParameters.h
index d0e04502450eedf0dc1e6104f10fe122edee992e..aaa5dfced49e1f20cbd02da81364dbf0285a04d9 100644
--- a/Source/WebKit/Shared/WebPageCreationParameters.h
+++ b/Source/WebKit/Shared/WebPageCreationParameters.h
@@ -317,6 +317,9 @@ struct WebPageCreationParameters {
WebCore::ShouldRelaxThirdPartyCookieBlocking shouldRelaxThirdPartyCookieBlocking { WebCore::ShouldRelaxThirdPartyCookieBlocking::No };
bool httpsUpgradeEnabled { true };
+
+ std::optional<int> deviceOrientationOverride { };
+ bool shouldPauseInInspectorWhenShown { false };
#if ENABLE(APP_HIGHLIGHTS)
WebCore::HighlightVisibility appHighlightsVisible { WebCore::HighlightVisibility::Hidden };
diff --git a/Source/WebKit/Shared/WebPageCreationParameters.serialization.in b/Source/WebKit/Shared/WebPageCreationParameters.serialization.in
index 707a31d075afd590890fb3e0054f256b4a567ac1..55ac3de3488b82b77888101d6677fb76c1b1c00c 100644
--- a/Source/WebKit/Shared/WebPageCreationParameters.serialization.in
+++ b/Source/WebKit/Shared/WebPageCreationParameters.serialization.in
@@ -233,6 +233,9 @@ enum class WebCore::UserInterfaceLayoutDirection : bool;
bool httpsUpgradeEnabled;
+ std::optional<int> deviceOrientationOverride;
+ bool shouldPauseInInspectorWhenShown;
+
#if ENABLE(APP_HIGHLIGHTS)
WebCore::HighlightVisibility appHighlightsVisible;
#endif
diff --git a/Source/WebKit/Shared/glib/ProcessExecutablePathGLib.cpp b/Source/WebKit/Shared/glib/ProcessExecutablePathGLib.cpp
index 64bcde96dfe76998f6ed6297be892c6548123049..be05d2e4f6749ef60a13e2c8cf77e3fa6ffd41f7 100644
--- a/Source/WebKit/Shared/glib/ProcessExecutablePathGLib.cpp
+++ b/Source/WebKit/Shared/glib/ProcessExecutablePathGLib.cpp
@@ -32,7 +32,7 @@
namespace WebKit {
-#if ENABLE(DEVELOPER_MODE)
+#if TRUE
static String getExecutablePath()
{
CString executablePath = FileSystem::currentExecutablePath();
@@ -44,7 +44,7 @@ static String getExecutablePath()
static String findWebKitProcess(const ASCIILiteral processName)
{
-#if ENABLE(DEVELOPER_MODE)
+#if TRUE
static const char* execDirectory = g_getenv("WEBKIT_EXEC_PATH");
if (execDirectory) {
String processPath = FileSystem::pathByAppendingComponent(FileSystem::stringFromFileSystemRepresentation(execDirectory), processName);
diff --git a/Source/WebKit/Shared/gtk/NativeWebKeyboardEventGtk.cpp b/Source/WebKit/Shared/gtk/NativeWebKeyboardEventGtk.cpp
index 6091f843195ae84a25e955304170d84df8ec012e..6c8ce488b96ffeee50371925df704accf03e154c 100644
--- a/Source/WebKit/Shared/gtk/NativeWebKeyboardEventGtk.cpp
+++ b/Source/WebKit/Shared/gtk/NativeWebKeyboardEventGtk.cpp
@@ -51,7 +51,7 @@ NativeWebKeyboardEvent::NativeWebKeyboardEvent(const String& text, std::optional
}
NativeWebKeyboardEvent::NativeWebKeyboardEvent(WebEventType type, const String& text, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, Vector<String>&& commands, bool isAutoRepeat, bool isKeypad, OptionSet<WebEventModifier> modifiers)
- : WebKeyboardEvent(WebEvent(type, modifiers, MonotonicTime::now()), text, key, code, keyIdentifier, windowsVirtualKeyCode, nativeVirtualKeyCode, false, std::nullopt, std::nullopt, WTF::move(commands), isAutoRepeat, isKeypad)
+ : WebKeyboardEvent(WebEvent(type, modifiers, MonotonicTime::now()), text, key, code, keyIdentifier, windowsVirtualKeyCode, nativeVirtualKeyCode, false, std::nullopt, std::nullopt, WTF::move(commands), false, isKeypad)
{
}
diff --git a/Source/WebKit/Shared/gtk/WebKeyboardEventGtk.cpp b/Source/WebKit/Shared/gtk/WebKeyboardEventGtk.cpp
index 092d3c2f493aa18e09f43db2d153d5aa6822e000..65d577e344637c99885b373500d353c1abbd6aea 100644
--- a/Source/WebKit/Shared/gtk/WebKeyboardEventGtk.cpp
+++ b/Source/WebKit/Shared/gtk/WebKeyboardEventGtk.cpp
@@ -1328,4 +1328,244 @@ String WebKeyboardEvent::singleCharacterStringForGdkKeyval(unsigned keyval)
}
}
+static const UncheckedKeyHashMap<int, unsigned>& gdkToWindowsKeyCodeMap()
+{
+ static UncheckedKeyHashMap<int, unsigned>* result;
+ static std::once_flag once;
+ std::call_once(
+ once,
+ [] {
+ const unsigned gdkKeyCodes[] = {
+ GDK_KEY_Cancel,
+ // FIXME: non-keypad keys should take precedence, so we skip GDK_KEY_KP_*
+ // GDK_KEY_KP_0,
+ // GDK_KEY_KP_1,
+ // GDK_KEY_KP_2,
+ // GDK_KEY_KP_3,
+ // GDK_KEY_KP_4,
+ // GDK_KEY_KP_5,
+ // GDK_KEY_KP_6,
+ // GDK_KEY_KP_7,
+ // GDK_KEY_KP_8,
+ // GDK_KEY_KP_9,
+ // GDK_KEY_KP_Multiply,
+ // GDK_KEY_KP_Add,
+ // GDK_KEY_KP_Subtract,
+ // GDK_KEY_KP_Decimal,
+ // GDK_KEY_KP_Divide,
+ // GDK_KEY_KP_Page_Up,
+ // GDK_KEY_KP_Page_Down,
+ // GDK_KEY_KP_End,
+ // GDK_KEY_KP_Home,
+ // GDK_KEY_KP_Left,
+ // GDK_KEY_KP_Up,
+ // GDK_KEY_KP_Right,
+ // GDK_KEY_KP_Down,
+ GDK_KEY_BackSpace,
+ // GDK_KEY_ISO_Left_Tab,
+ // GDK_KEY_3270_BackTab,
+ GDK_KEY_Tab,
+ GDK_KEY_Clear,
+ // GDK_KEY_ISO_Enter,
+ // GDK_KEY_KP_Enter,
+ GDK_KEY_Return,
+ GDK_KEY_Menu,
+ GDK_KEY_Pause,
+ GDK_KEY_AudioPause,
+ GDK_KEY_Caps_Lock,
+ GDK_KEY_Kana_Lock,
+ GDK_KEY_Kana_Shift,
+ GDK_KEY_Hangul,
+ GDK_KEY_Hangul_Hanja,
+ GDK_KEY_Kanji,
+ GDK_KEY_Escape,
+ GDK_KEY_space,
+ GDK_KEY_Page_Up,
+ GDK_KEY_Page_Down,
+ GDK_KEY_End,
+ GDK_KEY_Home,
+ GDK_KEY_Left,
+ GDK_KEY_Up,
+ GDK_KEY_Right,
+ GDK_KEY_Down,
+ GDK_KEY_Select,
+ GDK_KEY_Print,
+ GDK_KEY_Execute,
+ GDK_KEY_Insert,
+ GDK_KEY_KP_Insert,
+ GDK_KEY_Delete,
+ GDK_KEY_KP_Delete,
+ GDK_KEY_Help,
+ GDK_KEY_0,
+ GDK_KEY_parenright,
+ GDK_KEY_1,
+ GDK_KEY_exclam,
+ GDK_KEY_2,
+ GDK_KEY_at,
+ GDK_KEY_3,
+ GDK_KEY_numbersign,
+ GDK_KEY_4,
+ GDK_KEY_dollar,
+ GDK_KEY_5,
+ GDK_KEY_percent,
+ GDK_KEY_6,
+ GDK_KEY_asciicircum,
+ GDK_KEY_7,
+ GDK_KEY_ampersand,
+ GDK_KEY_8,
+ GDK_KEY_asterisk,
+ GDK_KEY_9,
+ GDK_KEY_parenleft,
+ GDK_KEY_a,
+ GDK_KEY_A,
+ GDK_KEY_b,
+ GDK_KEY_B,
+ GDK_KEY_c,
+ GDK_KEY_C,
+ GDK_KEY_d,
+ GDK_KEY_D,
+ GDK_KEY_e,
+ GDK_KEY_E,
+ GDK_KEY_f,
+ GDK_KEY_F,
+ GDK_KEY_g,
+ GDK_KEY_G,
+ GDK_KEY_h,
+ GDK_KEY_H,
+ GDK_KEY_i,
+ GDK_KEY_I,
+ GDK_KEY_j,
+ GDK_KEY_J,
+ GDK_KEY_k,
+ GDK_KEY_K,
+ GDK_KEY_l,
+ GDK_KEY_L,
+ GDK_KEY_m,
+ GDK_KEY_M,
+ GDK_KEY_n,
+ GDK_KEY_N,
+ GDK_KEY_o,
+ GDK_KEY_O,
+ GDK_KEY_p,
+ GDK_KEY_P,
+ GDK_KEY_q,
+ GDK_KEY_Q,
+ GDK_KEY_r,
+ GDK_KEY_R,
+ GDK_KEY_s,
+ GDK_KEY_S,
+ GDK_KEY_t,
+ GDK_KEY_T,
+ GDK_KEY_u,
+ GDK_KEY_U,
+ GDK_KEY_v,
+ GDK_KEY_V,
+ GDK_KEY_w,
+ GDK_KEY_W,
+ GDK_KEY_x,
+ GDK_KEY_X,
+ GDK_KEY_y,
+ GDK_KEY_Y,
+ GDK_KEY_z,
+ GDK_KEY_Z,
+ GDK_KEY_Meta_L,
+ GDK_KEY_Meta_R,
+ GDK_KEY_Sleep,
+ GDK_KEY_Num_Lock,
+ GDK_KEY_Scroll_Lock,
+ GDK_KEY_Shift_L,
+ GDK_KEY_Shift_R,
+ GDK_KEY_Control_L,
+ GDK_KEY_Control_R,
+ GDK_KEY_Alt_L,
+ GDK_KEY_Alt_R,
+ GDK_KEY_Back,
+ GDK_KEY_Forward,
+ GDK_KEY_Refresh,
+ GDK_KEY_Stop,
+ GDK_KEY_Search,
+ GDK_KEY_Favorites,
+ GDK_KEY_HomePage,
+ GDK_KEY_AudioMute,
+ GDK_KEY_AudioLowerVolume,
+ GDK_KEY_AudioRaiseVolume,
+ GDK_KEY_AudioNext,
+ GDK_KEY_AudioPrev,
+ GDK_KEY_AudioStop,
+ GDK_KEY_AudioMedia,
+ GDK_KEY_semicolon,
+ GDK_KEY_colon,
+ GDK_KEY_plus,
+ GDK_KEY_equal,
+ GDK_KEY_comma,
+ GDK_KEY_less,
+ GDK_KEY_minus,
+ GDK_KEY_underscore,
+ GDK_KEY_period,
+ GDK_KEY_greater,
+ GDK_KEY_slash,
+ GDK_KEY_question,
+ GDK_KEY_asciitilde,
+ GDK_KEY_quoteleft,
+ GDK_KEY_bracketleft,
+ GDK_KEY_braceleft,
+ GDK_KEY_backslash,
+ GDK_KEY_bar,
+ GDK_KEY_bracketright,
+ GDK_KEY_braceright,
+ GDK_KEY_quoteright,
+ GDK_KEY_quotedbl,
+ GDK_KEY_AudioRewind,
+ GDK_KEY_AudioForward,
+ GDK_KEY_AudioPlay,
+ GDK_KEY_F1,
+ GDK_KEY_F2,
+ GDK_KEY_F3,
+ GDK_KEY_F4,
+ GDK_KEY_F5,
+ GDK_KEY_F6,
+ GDK_KEY_F7,
+ GDK_KEY_F8,
+ GDK_KEY_F9,
+ GDK_KEY_F10,
+ GDK_KEY_F11,
+ GDK_KEY_F12,
+ GDK_KEY_F13,
+ GDK_KEY_F14,
+ GDK_KEY_F15,
+ GDK_KEY_F16,
+ GDK_KEY_F17,
+ GDK_KEY_F18,
+ GDK_KEY_F19,
+ GDK_KEY_F20,
+ GDK_KEY_F21,
+ GDK_KEY_F22,
+ GDK_KEY_F23,
+ GDK_KEY_F24,
+ GDK_KEY_VoidSymbol,
+ GDK_KEY_Red,
+ GDK_KEY_Green,
+ GDK_KEY_Yellow,
+ GDK_KEY_Blue,
+ GDK_KEY_PowerOff,
+ GDK_KEY_AudioRecord,
+ GDK_KEY_Display,
+ GDK_KEY_Subtitle,
+ GDK_KEY_Video
+ };
+ result = new UncheckedKeyHashMap<int, unsigned>();
+ for (unsigned gdkKeyCode : gdkKeyCodes) {
+ int winKeyCode = WebKeyboardEvent::windowsKeyCodeForGdkKeyval(gdkKeyCode);
+ // If several gdk key codes map to the same win key code first one is used.
+ result->add(winKeyCode, gdkKeyCode);
+ }
+ });
+ return *result;
+}
+
+unsigned WebKeyboardEvent::gdkKeyCodeForWindowsKeyCode(int keycode)
+{
+ return gdkToWindowsKeyCodeMap().get(keycode);
+}
+
} // namespace WebKit
diff --git a/Source/WebKit/Shared/unix/AuxiliaryProcessMain.cpp b/Source/WebKit/Shared/unix/AuxiliaryProcessMain.cpp
index 7d054a56b04d1b19f12e6463077bccb67adcad25..bab6718c22da62179df92dcead696c7610cb4a9d 100644
--- a/Source/WebKit/Shared/unix/AuxiliaryProcessMain.cpp
+++ b/Source/WebKit/Shared/unix/AuxiliaryProcessMain.cpp
@@ -51,6 +51,15 @@ __attribute__((weak)) extern "C" int __llvm_profile_dump(void);
namespace WebKit {
+static bool hasArgument(const char* argument, int argc, char** argv)
+{
+ for (int i = 0; i < argc; ++i) {
+ if (!strcmp(argument, argv[i]))
+ return true;
+ }
+ return false;
+}
+
AuxiliaryProcessMainCommon::AuxiliaryProcessMainCommon()
{
#if ENABLE(BREAKPAD)
@@ -91,6 +100,10 @@ bool AuxiliaryProcessMainCommon::parseCommandLine(int argc, char** argv)
}
#endif
+// Playwright begin
+ if (hasArgument("--enable-shared-array-buffer", argc, argv))
+ m_parameters.shouldEnableSharedArrayBuffer = true;
+// Playwright end
return true;
}
diff --git a/Source/WebKit/Shared/win/AuxiliaryProcessMainWin.cpp b/Source/WebKit/Shared/win/AuxiliaryProcessMainWin.cpp
index b321d93d23d0d1862385b022569dc65323e8691c..ba3bcc9bc20b9512b9288cb2d7e5a3d8b90a0e37 100644
--- a/Source/WebKit/Shared/win/AuxiliaryProcessMainWin.cpp
+++ b/Source/WebKit/Shared/win/AuxiliaryProcessMainWin.cpp
@@ -47,6 +47,10 @@ bool AuxiliaryProcessMainCommon::parseCommandLine(int argc, char** argv)
m_parameters.connectionIdentifier = IPC::Connection::Identifier { reinterpret_cast<HANDLE>(parseIntegerAllowingTrailingJunk<uint64_t>(StringView::fromLatin1(argv[++i])).value_or(0)) };
else if (!strcmp(argv[i], "-processIdentifier") && i + 1 < argc)
m_parameters.processIdentifier = ObjectIdentifier<WebCore::ProcessIdentifierType>(parseIntegerAllowingTrailingJunk<uint64_t>(StringView::fromLatin1(argv[++i])).value_or(0));
+// Playwright begin
+ else if (!strcmp(argv[i], "-enable-shared-array-buffer"))
+ m_parameters.shouldEnableSharedArrayBuffer = true;
+// Playwright end
else if (!strcmp(argv[i], "-configure-jsc-for-testing"))
JSC::Config::configureForTesting();
else if (!strcmp(argv[i], "-disable-jit"))
diff --git a/Source/WebKit/Sources.txt b/Source/WebKit/Sources.txt
index 382ea8985d8781d7d49f12a90bf0ecc65232985f..ebe6f275fed47f09490052f0548641b1dec4b8f4 100644
--- a/Source/WebKit/Sources.txt
+++ b/Source/WebKit/Sources.txt
@@ -403,6 +403,7 @@ UIProcess/AboutSchemeHandler.cpp
UIProcess/AuxiliaryProcessProxy.cpp
UIProcess/BackgroundProcessResponsivenessTimer.cpp
UIProcess/BrowsingContextGroup.cpp
+UIProcess/BrowserInspectorPipe.cpp
UIProcess/DeviceIdHashSaltStorage.cpp
UIProcess/DisplayLink.cpp
UIProcess/DisplayLinkProcessProxyClient.cpp
@@ -414,17 +415,21 @@ UIProcess/FrameLoadState.cpp
UIProcess/FrameProcess.cpp
UIProcess/GeolocationPermissionRequestManagerProxy.cpp
UIProcess/GeolocationPermissionRequestProxy.cpp
+UIProcess/InspectorDialogAgent.cpp
+UIProcess/InspectorPlaywrightAgent.cpp
UIProcess/LegacyGlobalSettings.cpp
UIProcess/MediaKeySystemPermissionRequestManagerProxy.cpp
UIProcess/MediaKeySystemPermissionRequestProxy.cpp
UIProcess/OverrideLanguages.cpp
UIProcess/PageClient.cpp
UIProcess/PageLoadState.cpp
+UIProcess/PlaywrightFullScreenManagerProxyClient.cpp
UIProcess/ProcessActivityGroup.cpp
UIProcess/ProcessAssertion.cpp
UIProcess/ProcessThrottler.cpp
UIProcess/ProvisionalFrameProxy.cpp
UIProcess/ProvisionalPageProxy.cpp
+UIProcess/RemoteInspectorPipe.cpp
UIProcess/RemotePageDrawingAreaProxy.cpp
UIProcess/RemotePageFullscreenManagerProxy.cpp
UIProcess/RemotePagePlaybackSessionManagerProxy.cpp
@@ -472,6 +477,8 @@ UIProcess/WebOpenPanelResultListenerProxy.cpp
UIProcess/WebPageDiagnosticLoggingClient.cpp
UIProcess/WebPageGroup.cpp
UIProcess/WebPageInjectedBundleClient.cpp
+UIProcess/WebPageInspectorEmulationAgent.cpp
+UIProcess/WebPageInspectorInputAgent.cpp
UIProcess/WebPageProxy.cpp
UIProcess/WebPageProxyMessageReceiverRegistration.cpp
UIProcess/WebPageProxyTesting.cpp
@@ -641,6 +648,7 @@ UIProcess/Inspector/WebPageDebuggable.cpp
UIProcess/Inspector/WebPageInspectorController.cpp
UIProcess/Inspector/Agents/InspectorBrowserAgent.cpp
+UIProcess/Inspector/Agents/InspectorScreencastAgent.cpp
UIProcess/Media/AudioSessionRoutingArbitratorProxy.cpp
UIProcess/Media/MediaUsageManager.cpp
diff --git a/Source/WebKit/SourcesCocoa.txt b/Source/WebKit/SourcesCocoa.txt
index 8f5e05d7905c09452701a390277d8528d3c53170..3ac17db7930b41d33d7e0f6ee9564b997967a8a6 100644
--- a/Source/WebKit/SourcesCocoa.txt
+++ b/Source/WebKit/SourcesCocoa.txt
@@ -286,6 +286,7 @@ UIProcess/API/Cocoa/_WKArchiveExclusionRule.mm @nonARC
UIProcess/API/Cocoa/_WKAttachment.mm @nonARC
UIProcess/API/Cocoa/_WKAutomationSession.mm @nonARC
UIProcess/API/Cocoa/_WKAutomationSessionConfiguration.mm @nonARC
+UIProcess/API/Cocoa/_WKBrowserInspector.mm @nonARC
UIProcess/API/Cocoa/_WKContentRuleListAction.mm @nonARC
UIProcess/API/Cocoa/_WKContextMenuElementInfo.mm @nonARC
UIProcess/API/Cocoa/_WKCustomHeaderFields.mm @nonARC @no-unify
diff --git a/Source/WebKit/SourcesGTK.txt b/Source/WebKit/SourcesGTK.txt
index 4b68f079d9d43d1b0bef8e3b31cd0d6f3a730ae9..3799718e6e5791791335171a8adb0365231501bf 100644
--- a/Source/WebKit/SourcesGTK.txt
+++ b/Source/WebKit/SourcesGTK.txt
@@ -134,6 +134,7 @@ UIProcess/API/glib/WebKitAutomationSession.cpp @no-unify
UIProcess/API/glib/WebKitBackForwardList.cpp @no-unify
UIProcess/API/glib/WebKitBackForwardListItem.cpp @no-unify
UIProcess/API/glib/WebKitClipboardPermissionRequest.cpp @no-unify
+UIProcess/API/glib/WebKitBrowserInspector.cpp @no-unify
UIProcess/API/glib/WebKitContextMenuClient.cpp @no-unify
UIProcess/API/glib/WebKitCookieManager.cpp @no-unify
UIProcess/API/glib/WebKitCredential.cpp @no-unify
@@ -263,6 +264,7 @@ UIProcess/linux/MemoryPressureMonitor.cpp
UIProcess/WebsiteData/glib/WebsiteDataStoreGLib.cpp
UIProcess/WebsiteData/soup/WebsiteDataStoreSoup.cpp
+UIProcess/glib/BrowserInspectorWebSocketServer.cpp
UIProcess/glib/DRMMainDevice.cpp @no-unify
UIProcess/glib/DisplayLinkGLib.cpp
UIProcess/glib/DisplayVBlankMonitor.cpp
@@ -270,6 +272,7 @@ UIProcess/glib/DisplayVBlankMonitorDRM.cpp
UIProcess/glib/DisplayVBlankMonitorThreaded.cpp
UIProcess/glib/DisplayVBlankMonitorTimer.cpp
UIProcess/glib/FenceMonitor.cpp
+UIProcess/glib/InspectorPlaywrightAgentClientGLib.cpp
UIProcess/glib/ScreenManager.cpp
UIProcess/glib/SystemSettingsManagerProxy.cpp
UIProcess/glib/WebPageProxyGLib.cpp
@@ -287,9 +290,9 @@ UIProcess/gtk/DisplayX11.cpp @no-unify
UIProcess/gtk/DisplayWayland.cpp @no-unify
UIProcess/gtk/GRefPtrGtk.cpp @no-unify
UIProcess/gtk/GtkUtilities.cpp @no-unify
-UIProcess/gtk/WebDateTimePickerGtk.cpp
UIProcess/gtk/HardwareAccelerationManager.cpp
UIProcess/gtk/KeyBindingTranslator.cpp
+UIProcess/gtk/PageInspectorTargetProxyGtk.cpp
UIProcess/gtk/PointerLockManager.cpp @no-unify
UIProcess/gtk/PointerLockManagerWayland.cpp @no-unify
UIProcess/gtk/PointerLockManagerX11.cpp @no-unify
@@ -303,6 +306,9 @@ UIProcess/gtk/ViewGestureControllerGtk.cpp
UIProcess/gtk/WebColorPickerGtk.cpp
UIProcess/gtk/WebContextMenuProxyGtk.cpp
UIProcess/gtk/WebDataListSuggestionsDropdownGtk.cpp
+UIProcess/gtk/WebDateTimePickerGtk.cpp
+UIProcess/gtk/WebPageInspectorEmulationAgentGtk.cpp
+UIProcess/gtk/WebPageInspectorInputAgentGtk.cpp
UIProcess/gtk/WebPageProxyGtk.cpp @no-unify
UIProcess/gtk/WebPasteboardProxyGtk.cpp
UIProcess/gtk/WebPopupMenuProxyGtk.cpp
diff --git a/Source/WebKit/SourcesWPE.txt b/Source/WebKit/SourcesWPE.txt
index 3d1ed6156127f02614905e30835fa4c6334ae914..fb362b66d00c2081d6eb5380fb2bd7967223f489 100644
--- a/Source/WebKit/SourcesWPE.txt
+++ b/Source/WebKit/SourcesWPE.txt
@@ -138,6 +138,7 @@ UIProcess/API/glib/WebKitAuthenticationRequest.cpp @no-unify
UIProcess/API/glib/WebKitAutomationSession.cpp @no-unify
UIProcess/API/glib/WebKitBackForwardList.cpp @no-unify
UIProcess/API/glib/WebKitBackForwardListItem.cpp @no-unify
+UIProcess/API/glib/WebKitBrowserInspector.cpp @no-unify
UIProcess/API/glib/WebKitContextMenuClient.cpp @no-unify
UIProcess/API/glib/WebKitCookieManager.cpp @no-unify
UIProcess/API/glib/WebKitCredential.cpp @no-unify
@@ -174,6 +175,7 @@ UIProcess/API/glib/WebKitOptionMenu.cpp @no-unify
UIProcess/API/glib/WebKitOptionMenuItem.cpp @no-unify
UIProcess/API/glib/WebKitPermissionRequest.cpp @no-unify
UIProcess/API/glib/WebKitPermissionStateQuery.cpp @no-unify
+UIProcess/API/glib/WebKitPointerLockPermissionRequest.cpp @no-unify
UIProcess/API/glib/WebKitPolicyDecision.cpp @no-unify
UIProcess/API/glib/WebKitPrivate.cpp @no-unify
UIProcess/API/glib/WebKitProtocolHandler.cpp @no-unify
@@ -242,6 +244,7 @@ UIProcess/Gamepad/wpe/PlatformGamepadWPE.cpp
UIProcess/geoclue/GeoclueGeolocationProvider.cpp
+UIProcess/glib/BrowserInspectorWebSocketServer.cpp
UIProcess/glib/DRMMainDevice.cpp @no-unify
UIProcess/glib/DisplayLinkGLib.cpp
UIProcess/glib/DisplayVBlankMonitor.cpp
@@ -249,6 +252,7 @@ UIProcess/glib/DisplayVBlankMonitorDRM.cpp
UIProcess/glib/DisplayVBlankMonitorThreaded.cpp
UIProcess/glib/DisplayVBlankMonitorTimer.cpp
UIProcess/glib/FenceMonitor.cpp
+UIProcess/glib/InspectorPlaywrightAgentClientGLib.cpp
UIProcess/glib/ScreenManager.cpp
UIProcess/glib/SystemSettingsManagerProxy.cpp
UIProcess/glib/WebPageProxyGLib.cpp
@@ -284,9 +288,15 @@ UIProcess/soup/WebProcessPoolSoup.cpp
UIProcess/wpe/AcceleratedBackingStore.cpp
UIProcess/wpe/DisplayVBlankMonitorWPE.cpp
+UIProcess/wpe/PageInspectorTargetProxyWPE.cpp
UIProcess/wpe/ScreenManagerWPE.cpp
UIProcess/wpe/SystemSettingsManagerProxyWPE.cpp
UIProcess/wpe/WPEUtilities.cpp
+UIProcess/wpe/WebColorPickerWPE.cpp
+UIProcess/wpe/WebDataListSuggestionsDropdownWPE.cpp
+UIProcess/wpe/WebDateTimePickerWPE.cpp
+UIProcess/wpe/WebPageInspectorEmulationAgentWPE.cpp
+UIProcess/wpe/WebPageInspectorInputAgentWPE.cpp
UIProcess/wpe/WebPageProxyWPE.cpp
UIProcess/wpe/WebPasteboardProxyWPE.cpp
UIProcess/wpe/WebPreferencesWPE.cpp
diff --git a/Source/WebKit/UIProcess/API/APIPageConfiguration.cpp b/Source/WebKit/UIProcess/API/APIPageConfiguration.cpp
index 367ad615c527a09f3c3d3d86bf7eca87afbc13ed..9ef85591e159555c93e5b7a9635d5e289c22a243 100644
--- a/Source/WebKit/UIProcess/API/APIPageConfiguration.cpp
+++ b/Source/WebKit/UIProcess/API/APIPageConfiguration.cpp
@@ -261,6 +261,11 @@ BrowsingContextGroup* PageConfiguration::preferredBrowsingContextGroup() const
return nullptr;
}
+WebKit::WebPageProxy* PageConfiguration::openerPageForInspector() const
+{
+ return m_data.openerPageForInspector.get();
+}
+
WebPageProxy* PageConfiguration::pageToCloneSessionStorageFrom() const
{
return m_data.pageToCloneSessionStorageFrom.get();
diff --git a/Source/WebKit/UIProcess/API/APIPageConfiguration.h b/Source/WebKit/UIProcess/API/APIPageConfiguration.h
index b2227e338dcd10bfdaaf1a4c4d632003cf9e6f73..3afcd9c4f12d7cf755f9b849da7dfb98812afdf7 100644
--- a/Source/WebKit/UIProcess/API/APIPageConfiguration.h
+++ b/Source/WebKit/UIProcess/API/APIPageConfiguration.h
@@ -173,6 +173,10 @@ public:
WebKit::WebPageProxy* NODELETE relatedPage() const;
void setRelatedPage(WeakPtr<WebKit::WebPageProxy>&& relatedPage) { m_data.relatedPage = WTF::move(relatedPage); }
+ // This is similar to relatedPage(), but it is also set for noopener links.
+ WebKit::WebPageProxy* openerPageForInspector() const;
+ void setOpenerPageForInspector(WeakPtr<WebKit::WebPageProxy>&& openerPageForInspector) { m_data.openerPageForInspector = WTF::move(openerPageForInspector); }
+
WebKit::WebPageProxy* NODELETE pageToCloneSessionStorageFrom() const;
void NODELETE setPageToCloneSessionStorageFrom(WeakPtr<WebKit::WebPageProxy>&&);
@@ -540,6 +544,7 @@ private:
#endif
RefPtr<WebKit::WebPageGroup> pageGroup;
WeakPtr<WebKit::WebPageProxy> relatedPage;
+ WeakPtr<WebKit::WebPageProxy> openerPageForInspector;
Box<std::optional<OpenerInfo>> openerInfo;
WebCore::Site openedSite;
bool processInheritedFromOpener { false };
diff --git a/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.cpp b/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.cpp
index 182dacc96abaab8d5fc9be0658dd1683f48af4db..80d6939f779a5d9a46e1a916cafef718faab9326 100644
--- a/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.cpp
+++ b/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.cpp
@@ -56,6 +56,10 @@ Ref<ProcessPoolConfiguration> ProcessPoolConfiguration::copy()
copy->m_ignoreSynchronousMessagingTimeoutsForTesting = this->m_ignoreSynchronousMessagingTimeoutsForTesting;
copy->m_attrStyleEnabled = this->m_attrStyleEnabled;
copy->m_shouldThrowExceptionForGlobalConstantRedeclaration = this->m_shouldThrowExceptionForGlobalConstantRedeclaration;
+#if PLATFORM(MAC)
+ copy->m_forceOverlayScrollbars = this->m_forceOverlayScrollbars;
+#endif
+ copy->m_overrideLanguages = this->m_overrideLanguages; /* playwright revert fb205fb */
copy->m_alwaysRunsAtBackgroundPriority = this->m_alwaysRunsAtBackgroundPriority;
copy->m_shouldTakeUIBackgroundAssertion = this->m_shouldTakeUIBackgroundAssertion;
copy->m_shouldCaptureDisplayInUIProcess = this->m_shouldCaptureDisplayInUIProcess;
diff --git a/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.h b/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.h
index 2b0e5565fd123126f1c6db65059975a344f152df..99b237e2736cd1b5c0e93dfcef5c81ab29ea74c1 100644
--- a/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.h
+++ b/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.h
@@ -49,7 +49,7 @@ public:
explicit ProcessPoolConfiguration();
virtual ~ProcessPoolConfiguration();
-
+
Ref<ProcessPoolConfiguration> copy();
bool usesSingleWebProcess() const { return m_usesSingleWebProcess; }
@@ -93,10 +93,20 @@ public:
bool attrStyleEnabled() const { return m_attrStyleEnabled; }
void setAttrStyleEnabled(bool enabled) { m_attrStyleEnabled = enabled; }
-
+
bool shouldThrowExceptionForGlobalConstantRedeclaration() const { return m_shouldThrowExceptionForGlobalConstantRedeclaration; }
void setShouldThrowExceptionForGlobalConstantRedeclaration(bool shouldThrow) { m_shouldThrowExceptionForGlobalConstantRedeclaration = shouldThrow; }
-
+
+#if PLATFORM(MAC)
+ bool forceOverlayScrollbars() const { return m_forceOverlayScrollbars; }
+ void setForceOverlayScrollbars(bool forceOverlayScrollbars) { m_forceOverlayScrollbars = forceOverlayScrollbars; }
+#endif
+
+ /* playwright revert fb205fb */
+ const Vector<WTF::String>& overrideLanguages() const { return m_overrideLanguages; }
+ void setOverrideLanguages(Vector<WTF::String>&& languages) { m_overrideLanguages = WTF::move(languages); }
+ /* end playwright revert fb205fb */
+
bool alwaysRunsAtBackgroundPriority() const { return m_alwaysRunsAtBackgroundPriority; }
void setAlwaysRunsAtBackgroundPriority(bool alwaysRunsAtBackgroundPriority) { m_alwaysRunsAtBackgroundPriority = alwaysRunsAtBackgroundPriority; }
@@ -177,6 +187,10 @@ private:
bool m_ignoreSynchronousMessagingTimeoutsForTesting { false };
bool m_attrStyleEnabled { false };
bool m_shouldThrowExceptionForGlobalConstantRedeclaration { true };
+#if PLATFORM(MAC)
+ bool m_forceOverlayScrollbars { false };
+#endif
+ Vector<WTF::String> m_overrideLanguages; /* playwright revert fb205fb */
bool m_alwaysRunsAtBackgroundPriority { false };
bool m_shouldTakeUIBackgroundAssertion { true };
bool m_shouldCaptureDisplayInUIProcess { DEFAULT_CAPTURE_DISPLAY_IN_UI_PROCESS };
diff --git a/Source/WebKit/UIProcess/API/APIUIClient.h b/Source/WebKit/UIProcess/API/APIUIClient.h
index d9f80360027a2e0c9dd5a3594189dddfde53966d..c6862db4346514707fb84427123fb4ce568ffc99 100644
--- a/Source/WebKit/UIProcess/API/APIUIClient.h
+++ b/Source/WebKit/UIProcess/API/APIUIClient.h
@@ -115,6 +115,7 @@ public:
virtual void runJavaScriptAlert(WebKit::WebPageProxy&, const WTF::String&, WebKit::WebFrameProxy*, WebKit::FrameInfoData&&, Function<void()>&& completionHandler) { completionHandler(); }
virtual void runJavaScriptConfirm(WebKit::WebPageProxy&, const WTF::String&, WebKit::WebFrameProxy*, WebKit::FrameInfoData&&, Function<void(bool)>&& completionHandler) { completionHandler(false); }
virtual void runJavaScriptPrompt(WebKit::WebPageProxy&, const WTF::String&, const WTF::String&, WebKit::WebFrameProxy*, WebKit::FrameInfoData&&, Function<void(const WTF::String&)>&& completionHandler) { completionHandler(WTF::String()); }
+ virtual void handleJavaScriptDialog(WebKit::WebPageProxy&, bool, const WTF::String&) { }
virtual void setStatusText(WebKit::WebPageProxy*, const WTF::String&) { }
virtual void mouseDidMoveOverElement(WebKit::WebPageProxy&, const WebKit::WebHitTestResultData&, OptionSet<WebKit::WebEventModifier>) { }
diff --git a/Source/WebKit/UIProcess/API/C/WKInspector.cpp b/Source/WebKit/UIProcess/API/C/WKInspector.cpp
index 5ae69462a4c5a61e098e4df7def6dec3c842e167..e04134e2d91bfc5b1832a7a641614483c748513a 100644
--- a/Source/WebKit/UIProcess/API/C/WKInspector.cpp
+++ b/Source/WebKit/UIProcess/API/C/WKInspector.cpp
@@ -28,6 +28,11 @@
#if !PLATFORM(IOS_FAMILY)
+#if PLATFORM(WIN)
+#include "BrowserInspectorPipe.h"
+#include "InspectorPlaywrightAgentClientWin.h"
+#endif
+
#include "WKAPICast.h"
#include "WebFrameProxy.h"
#include "WebInspectorUIProxy.h"
@@ -131,4 +136,11 @@ void WKInspectorToggleElementSelection(WKInspectorRef inspectorRef)
protect(toImpl(inspectorRef))->toggleElementSelection();
}
+void WKInspectorInitializeRemoteInspectorPipe(ConfigureDataStoreCallback configureDataStore, CreatePageCallback createPage, QuitCallback quit)
+{
+#if PLATFORM(WIN)
+ initializeBrowserInspectorPipe(makeUnique<InspectorPlaywrightAgentClientWin>(configureDataStore, createPage, quit));
+#endif
+}
+
#endif // !PLATFORM(IOS_FAMILY)
diff --git a/Source/WebKit/UIProcess/API/C/WKInspector.h b/Source/WebKit/UIProcess/API/C/WKInspector.h
index 026121d114c5fcad84c1396be8d692625beaa3bd..edd6e5cae033124c589959a42522fde07a42fdf6 100644
--- a/Source/WebKit/UIProcess/API/C/WKInspector.h
+++ b/Source/WebKit/UIProcess/API/C/WKInspector.h
@@ -66,6 +66,10 @@ WK_EXPORT void WKInspectorTogglePageProfiling(WKInspectorRef inspector);
WK_EXPORT bool WKInspectorIsElementSelectionActive(WKInspectorRef inspector);
WK_EXPORT void WKInspectorToggleElementSelection(WKInspectorRef inspector);
+typedef void (*ConfigureDataStoreCallback)(WKWebsiteDataStoreRef dataStore);
+typedef WKPageRef (*CreatePageCallback)(WKPageConfigurationRef configuration);
+typedef void (*QuitCallback)();
+WK_EXPORT void WKInspectorInitializeRemoteInspectorPipe(ConfigureDataStoreCallback, CreatePageCallback, QuitCallback);
#ifdef __cplusplus
}
#endif
diff --git a/Source/WebKit/UIProcess/API/C/WKPage.cpp b/Source/WebKit/UIProcess/API/C/WKPage.cpp
index 3ceafb8efa81d2ea5d6d5db862564e5d9549fd50..5aad4b41ff5975d2e4b499e407a41e3fe1983b90 100644
--- a/Source/WebKit/UIProcess/API/C/WKPage.cpp
+++ b/Source/WebKit/UIProcess/API/C/WKPage.cpp
@@ -1913,6 +1913,13 @@ void WKPageSetPageUIClient(WKPageRef pageRef, const WKPageUIClientBase* wkClient
m_client.addMessageToConsole(toAPI(&page), toAPI(message.impl()), m_client.base.clientInfo);
}
+ void handleJavaScriptDialog(WebPageProxy& page, bool accept, const String& value) final {
+ if (m_client.handleJavaScriptDialog) {
+ m_client.handleJavaScriptDialog(toAPI(&page), accept, toAPI(value.impl()), m_client.base.clientInfo);
+ return;
+ }
+ }
+
void setStatusText(WebPageProxy* page, const String& text) final
{
if (!m_client.setStatusText)
@@ -1950,6 +1957,8 @@ void WKPageSetPageUIClient(WKPageRef pageRef, const WKPageUIClientBase* wkClient
{
if (!m_client.didNotHandleKeyEvent)
return;
+ if (!event.nativeEvent())
+ return;
m_client.didNotHandleKeyEvent(toAPI(page), event.nativeEvent(), m_client.base.clientInfo);
}
diff --git a/Source/WebKit/UIProcess/API/C/WKPageUIClient.h b/Source/WebKit/UIProcess/API/C/WKPageUIClient.h
index ae4a98c2fe5782eb2356dc8b6b486f6b44db6db3..62b2f3c351fe287af11c1ee2815f1fabe044d537 100644
--- a/Source/WebKit/UIProcess/API/C/WKPageUIClient.h
+++ b/Source/WebKit/UIProcess/API/C/WKPageUIClient.h
@@ -98,6 +98,7 @@ typedef void (*WKPageRunBeforeUnloadConfirmPanelCallback)(WKPageRef page, WKStri
typedef void (*WKPageRunJavaScriptAlertCallback)(WKPageRef page, WKStringRef alertText, WKFrameRef frame, WKSecurityOriginRef securityOrigin, WKPageRunJavaScriptAlertResultListenerRef listener, const void *clientInfo);
typedef void (*WKPageRunJavaScriptConfirmCallback)(WKPageRef page, WKStringRef message, WKFrameRef frame, WKSecurityOriginRef securityOrigin, WKPageRunJavaScriptConfirmResultListenerRef listener, const void *clientInfo);
typedef void (*WKPageRunJavaScriptPromptCallback)(WKPageRef page, WKStringRef message, WKStringRef defaultValue, WKFrameRef frame, WKSecurityOriginRef securityOrigin, WKPageRunJavaScriptPromptResultListenerRef listener, const void *clientInfo);
+typedef void (*WKPageHandleJavaScriptDialogCallback)(WKPageRef page, bool accept, WKStringRef value, const void *clientInfo);
typedef void (*WKPageRequestStorageAccessConfirmCallback)(WKPageRef page, WKFrameRef frame, WKStringRef requestingDomain, WKStringRef currentDomain, WKPageRequestStorageAccessConfirmResultListenerRef listener, const void *clientInfo);
typedef void (*WKPageTakeFocusCallback)(WKPageRef page, WKFocusDirection direction, const void *clientInfo);
typedef void (*WKPageFocusCallback)(WKPageRef page, const void *clientInfo);
@@ -1366,6 +1367,7 @@ typedef struct WKPageUIClientV14 {
// Version 14.
WKPageRunWebAuthenticationPanelCallback runWebAuthenticationPanel;
+ WKPageHandleJavaScriptDialogCallback handleJavaScriptDialog;
} WKPageUIClientV14;
typedef struct WKPageUIClientV15 {
@@ -1473,6 +1475,7 @@ typedef struct WKPageUIClientV15 {
// Version 14.
WKPageRunWebAuthenticationPanelCallback runWebAuthenticationPanel;
+ WKPageHandleJavaScriptDialogCallback handleJavaScriptDialog;
// Version 15.
WKPageDecidePolicyForSpeechRecognitionPermissionRequestCallback decidePolicyForSpeechRecognitionPermissionRequest;
@@ -1584,6 +1587,7 @@ typedef struct WKPageUIClientV16 {
// Version 14.
WKPageRunWebAuthenticationPanelCallback runWebAuthenticationPanel;
+ WKPageHandleJavaScriptDialogCallback handleJavaScriptDialog;
// Version 15.
WKPageDecidePolicyForSpeechRecognitionPermissionRequestCallback decidePolicyForSpeechRecognitionPermissionRequest;
@@ -1698,6 +1702,7 @@ typedef struct WKPageUIClientV17 {
// Version 14.
WKPageRunWebAuthenticationPanelCallback runWebAuthenticationPanel;
+ WKPageHandleJavaScriptDialogCallback handleJavaScriptDialog;
// Version 15.
WKPageDecidePolicyForSpeechRecognitionPermissionRequestCallback decidePolicyForSpeechRecognitionPermissionRequest;
@@ -1812,6 +1817,7 @@ typedef struct WKPageUIClientV18 {
// Version 14.
WKPageRunWebAuthenticationPanelCallback runWebAuthenticationPanel;
+ WKPageHandleJavaScriptDialogCallback handleJavaScriptDialog;
// Version 15.
WKPageDecidePolicyForSpeechRecognitionPermissionRequestCallback decidePolicyForSpeechRecognitionPermissionRequest;
@@ -1928,6 +1934,7 @@ typedef struct WKPageUIClientV19 {
// Version 14.
WKPageRunWebAuthenticationPanelCallback runWebAuthenticationPanel;
+ WKPageHandleJavaScriptDialogCallback handleJavaScriptDialog;
// Version 15.
WKPageDecidePolicyForSpeechRecognitionPermissionRequestCallback decidePolicyForSpeechRecognitionPermissionRequest;
diff --git a/Source/WebKit/UIProcess/API/Cocoa/WKUIDelegate.h b/Source/WebKit/UIProcess/API/Cocoa/WKUIDelegate.h
index acaeaef1be6d64f16d56d966db12cf9bb1f0507e..bb81783b20e33f69ceef2d00785a2e9c811dabe8 100644
--- a/Source/WebKit/UIProcess/API/Cocoa/WKUIDelegate.h
+++ b/Source/WebKit/UIProcess/API/Cocoa/WKUIDelegate.h
@@ -153,6 +153,12 @@ WK_SWIFT_UI_ACTOR
*/
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(WK_SWIFT_UI_ACTOR void (^)(NSString * _Nullable result))completionHandler;
+/*! @abstract Handle a JavaScript dialog.
+ @param webView The web view invoking the delegate method.
+ @param accept Whether to accept the dialog.
+ @param value Value to use for prompt dialog.
+ */
+- (void)webView:(WKWebView *)webView handleJavaScriptDialog:(BOOL)accept value:(nullable NSString *)value;
/*! @abstract A delegate to request permission for microphone audio and camera video access.
@param webView The web view invoking the delegate method.
diff --git a/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.h b/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.h
index dcab0400bfdd58f9d16726aba6ce66492f7be34b..a1337cc7ab9f04fea3f51a3003fdb946ce3d34e5 100644
--- a/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.h
+++ b/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.h
@@ -132,6 +132,8 @@ WK_CLASS_AVAILABLE(macos(10.11), ios(9.0))
@property (nullable, nonatomic, copy) NSArray *proxyConfigurations NS_REFINED_FOR_SWIFT API_AVAILABLE(macos(14.0), ios(17.0));
#endif
+- (uint64_t)sessionID;
+
@end
NS_ASSUME_NONNULL_END
diff --git a/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.mm b/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.mm
index 632bf6f982628fe174eac150b36a10c1d7677b09..09f3075420aa9aa84a93c40533d3eea7acbdc587 100644
--- a/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.mm
+++ b/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.mm
@@ -57,6 +57,7 @@
#import "_WKWebPushActionInternal.h"
#import "_WKWebsiteDataStoreConfigurationInternal.h"
#import "_WKWebsiteDataStoreDelegate.h"
+#import <pal/SessionID.h>
#import <WebCore/Credential.h>
#import <WebCore/RegistrableDomain.h>
#import <WebCore/ResourceResponse.h>
@@ -532,6 +533,11 @@ - (void)removeDataOfTypes:(NSSet *)dataTypes modifiedSince:(NSDate *)date comple
});
}
+- (uint64_t) sessionID
+{
+ return _websiteDataStore->sessionID().toUInt64();
+}
+
static Vector<WebKit::WebsiteDataRecord> toWebsiteDataRecords(NSArray *dataRecords)
{
Vector<WebKit::WebsiteDataRecord> result;
diff --git a/Source/WebKit/UIProcess/API/Cocoa/_WKBrowserInspector.h b/Source/WebKit/UIProcess/API/Cocoa/_WKBrowserInspector.h
new file mode 100644
index 0000000000000000000000000000000000000000..8938effdcc896cb45f75e3445fbeac6054f69cc6
--- /dev/null
+++ b/Source/WebKit/UIProcess/API/Cocoa/_WKBrowserInspector.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2019 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import <WebKit/WKFoundation.h>
+#import <WebKit/WKProcessPool.h>
+#import <WebKit/WKWebsiteDataStore.h>
+#import <Foundation/Foundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@class WKWebView;
+
+WK_CLASS_AVAILABLE(macos(10.14.0))
+@interface _WKBrowserContext : NSObject
+@property (nonatomic, strong) WKWebsiteDataStore *dataStore;
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+@property (nonatomic, strong) WKProcessPool *processPool;
+#pragma clang diagnostic pop
+@end
+
+@protocol _WKBrowserInspectorDelegate <NSObject>
+- (WKWebView *)createNewPage:(uint64_t)sessionID;
+- (_WKBrowserContext *)createBrowserContext:(NSString *)proxyServer WithBypassList:(NSString *)proxyBypassList;
+- (void)deleteBrowserContext:(uint64_t)sessionID;
+- (void)quit;
+@end
+
+WK_CLASS_AVAILABLE(macos(10.14.0))
+@interface _WKBrowserInspector : NSObject
++ (void)initializeRemoteInspectorPipe:(id<_WKBrowserInspectorDelegate>)delegate headless:(BOOL)headless;
+@end
+
+
+NS_ASSUME_NONNULL_END
+
diff --git a/Source/WebKit/UIProcess/API/Cocoa/_WKBrowserInspector.mm b/Source/WebKit/UIProcess/API/Cocoa/_WKBrowserInspector.mm
new file mode 100644
index 0000000000000000000000000000000000000000..69eb9c6aa30beb8ea21a0ef647e463043a868ab8
--- /dev/null
+++ b/Source/WebKit/UIProcess/API/Cocoa/_WKBrowserInspector.mm
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2019 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "_WKBrowserInspector.h"
+
+#include "BrowserInspectorPipe.h"
+#include "InspectorPlaywrightAgentClientMac.h"
+#include "PageClientImplMac.h"
+#include "WebKit2Initialize.h"
+
+#import "WKWebView.h"
+
+using namespace WebKit;
+
+@implementation _WKBrowserInspector
+
++ (void)initializeRemoteInspectorPipe:(id<_WKBrowserInspectorDelegate>)delegate headless:(BOOL)headless
+{
+#if ENABLE(REMOTE_INSPECTOR)
+ InitializeWebKit2();
+ PageClientImpl::setHeadless(headless);
+ initializeBrowserInspectorPipe(makeUnique<InspectorPlaywrightAgentClientMac>(delegate, headless));
+#endif
+}
+
+@end
+
+@implementation _WKBrowserContext
+- (void)dealloc
+{
+ [_dataStore release];
+ [_processPool release];
+ _dataStore = nil;
+ _processPool = nil;
+ [super dealloc];
+}
+@end
diff --git a/Source/WebKit/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.h b/Source/WebKit/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.h
index bcfc045d528aff77f639f53b9ebbbc4487050e39..08e1ec9a39e54fff521dbc65822f6c352087b0c0 100644
--- a/Source/WebKit/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.h
+++ b/Source/WebKit/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.h
@@ -67,6 +67,7 @@ WK_EXTERN WK_API_DEPRECATED("Creating and using multiple instances of WKProcessP
@property (nonatomic) pid_t presentingApplicationPID WK_API_AVAILABLE(macos(10.13), ios(11.0));
@property (nonatomic) audit_token_t presentingApplicationProcessToken WK_API_AVAILABLE(macos(10.13), ios(11.3));
@property (nonatomic) BOOL processSwapsOnNavigation WK_API_AVAILABLE(macos(10.14), ios(12.0));
+@property (nonatomic) BOOL forceOverlayScrollbars WK_API_AVAILABLE(macos(10.14));
@property (nonatomic) BOOL alwaysKeepAndReuseSwappedProcesses WK_API_AVAILABLE(macos(10.14), ios(12.0));
@property (nonatomic) BOOL processSwapsOnNavigationWithinSameNonHTTPFamilyProtocol WK_API_AVAILABLE(macos(12.0), ios(15.0));
@property (nonatomic) BOOL prewarmsProcessesAutomatically WK_API_AVAILABLE(macos(10.14.4), ios(12.2));
diff --git a/Source/WebKit/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.mm b/Source/WebKit/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.mm
index 63e3701355c7e47568b4506cdced95a46ff375af..014081a828011fa403676839c27f8514b3b73741 100644
--- a/Source/WebKit/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.mm
+++ b/Source/WebKit/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.mm
@@ -244,6 +244,16 @@ - (BOOL)processSwapsOnNavigation
return _processPoolConfiguration->processSwapsOnNavigation();
}
+- (void)setForceOverlayScrollbars:(BOOL)force
+{
+ _processPoolConfiguration->setForceOverlayScrollbars(force);
+}
+
+- (BOOL)forceOverlayScrollbars
+{
+ return _processPoolConfiguration->forceOverlayScrollbars();
+}
+
- (void)setPrewarmsProcessesAutomatically:(BOOL)prewarms
{
_processPoolConfiguration->setIsAutomaticProcessWarmingEnabled(prewarms);
diff --git a/Source/WebKit/UIProcess/API/Cocoa/_WKUserStyleSheet.h b/Source/WebKit/UIProcess/API/Cocoa/_WKUserStyleSheet.h
index 4974e14214e2bb3e982325b885bab33e54f83998..cacdf8c71fab248d38d2faf03f7affdcfed1ef62 100644
--- a/Source/WebKit/UIProcess/API/Cocoa/_WKUserStyleSheet.h
+++ b/Source/WebKit/UIProcess/API/Cocoa/_WKUserStyleSheet.h
@@ -31,6 +31,7 @@ NS_ASSUME_NONNULL_BEGIN
@class _WKUserContentWorld;
@class WKContentWorld;
@class WKWebView;
+@class WKContentWorld;
typedef NS_ENUM(NSInteger, _WKUserStyleLevel) {
_WKUserStyleUserLevel,
diff --git a/Source/WebKit/UIProcess/API/Cocoa/_WKWebPushSubscriptionData.mm b/Source/WebKit/UIProcess/API/Cocoa/_WKWebPushSubscriptionData.mm
index 4e688f53f9b1022b423e6ae171f042ddfcb858e0..611cd57e8ce91f64bc379b7be952f0e2ceb3e828 100644
--- a/Source/WebKit/UIProcess/API/Cocoa/_WKWebPushSubscriptionData.mm
+++ b/Source/WebKit/UIProcess/API/Cocoa/_WKWebPushSubscriptionData.mm
@@ -28,6 +28,9 @@
#import <WebCore/WebCoreObjCExtras.h>
#import <wtf/cocoa/SpanCocoa.h>
+#import <WebCore/WebCoreObjCExtras.h>
+#import <wtf/cocoa/SpanCocoa.h>
+
@implementation _WKWebPushSubscriptionData
- (void)dealloc
diff --git a/Source/WebKit/UIProcess/API/glib/WebKitBrowserInspector.cpp b/Source/WebKit/UIProcess/API/glib/WebKitBrowserInspector.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..77f295edf36e1f6ca156afbab06501ae6d0e8f11
--- /dev/null
+++ b/Source/WebKit/UIProcess/API/glib/WebKitBrowserInspector.cpp
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2019 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebKitBrowserInspector.h"
+
+#include "BrowserInspectorPipe.h"
+#include "BrowserInspectorWebSocketServer.h"
+#include "InspectorPlaywrightAgentClientGLib.h"
+#include "WebKitBrowserInspectorPrivate.h"
+#include "WebKitWebViewPrivate.h"
+#include <wtf/glib/GRefPtr.h>
+#include <wtf/glib/WTFGType.h>
+
+/**
+ * SECTION: WebKitBrowserInspector
+ * @Short_description: Access to the WebKit browser inspector
+ * @Title: WebKitBrowserInspector
+ *
+ * The WebKit Browser Inspector is an experimental API that provides
+ * access to the inspector via the remote debugging protocol. The protocol
+ * allows to create ephemeral contexts and create pages in them and then
+ * manipulate them using the inspector commands. This may be useful for
+ * the browser automation or remote debugging.
+ *
+ * Currently the protocol can be exposed to the parent process via a unix
+ * pipe.
+ */
+
+enum {
+ CREATE_NEW_PAGE,
+ QUIT_APPLICATION,
+
+ LAST_SIGNAL
+};
+
+struct _WebKitBrowserInspectorPrivate {
+ int unused { 0 };
+};
+
+WEBKIT_DEFINE_TYPE(WebKitBrowserInspector, webkit_browser_inspector, G_TYPE_OBJECT)
+
+static guint signals[LAST_SIGNAL] = { 0, };
+
+static void webkit_browser_inspector_class_init(WebKitBrowserInspectorClass* findClass)
+{
+ GObjectClass* gObjectClass = G_OBJECT_CLASS(findClass);
+
+ /**
+ * WebKitBrowserInspector::create-new-page:
+ * @inspector: the #WebKitBrowserInspector on which the signal is emitted
+ *
+ * Emitted when the inspector is requested to create a new page in the provided
+ * #WebKitWebContext.
+ *
+ * This signal is emitted when inspector receives 'Browser.createPage' command
+ * from its remote client. If the signal is not handled the command will fail.
+ *
+ * Returns: %WebKitWebView that contains created page.
+ */
+ signals[CREATE_NEW_PAGE] = g_signal_new(
+ "create-new-page",
+ G_TYPE_FROM_CLASS(gObjectClass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(WebKitBrowserInspectorClass, create_new_page),
+ nullptr, nullptr,
+ g_cclosure_marshal_generic,
+#if PLATFORM(GTK)
+ GTK_TYPE_WIDGET,
+#else
+ WEBKIT_TYPE_WEB_VIEW,
+#endif
+ 1,
+ WEBKIT_TYPE_WEB_CONTEXT);
+
+ /**
+ * WebKitBrowserInspector::quit-application:
+ * @inspector: the #WebKitBrowserInspector on which the signal is emitted
+ *
+ * Emitted when the inspector is requested to close the browser application.
+ *
+ * This signal is emitted when inspector receives 'Browser.close' command
+ * from its remote client. If the signal is not handled the command will fail.
+ */
+ signals[QUIT_APPLICATION] = g_signal_new(
+ "quit-application",
+ G_TYPE_FROM_CLASS(gObjectClass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(WebKitBrowserInspectorClass, quit_application),
+ nullptr, nullptr,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+WebKit::WebPageProxy* webkitBrowserInspectorCreateNewPageInContext(WebKitWebContext* context)
+{
+ WebKitWebView* newWebView;
+ g_signal_emit(webkit_browser_inspector_get_default(), signals[CREATE_NEW_PAGE], 0, context, &newWebView);
+ if (!newWebView)
+ return nullptr;
+ return &webkitWebViewGetPage(newWebView);
+}
+
+void webkitBrowserInspectorQuitApplication()
+{
+ g_signal_emit(webkit_browser_inspector_get_default(), signals[QUIT_APPLICATION], 0, NULL);
+}
+
+static gpointer createWebKitBrowserInspector(gpointer)
+{
+ static GRefPtr<WebKitBrowserInspector> browserInspector = adoptGRef(WEBKIT_BROWSER_INSPECTOR(g_object_new(WEBKIT_TYPE_BROWSER_INSPECTOR, nullptr)));
+ return browserInspector.get();
+}
+
+/**
+ * webkit_browser_inspector_get_default:
+ *
+ * Gets the default instance of the browser inspector.
+ *
+ * Returns: (transfer none): a #WebKitBrowserInspector
+ */
+WebKitBrowserInspector* webkit_browser_inspector_get_default(void)
+{
+ static GOnce onceInit = G_ONCE_INIT;
+ return WEBKIT_BROWSER_INSPECTOR(g_once(&onceInit, createWebKitBrowserInspector, 0));
+}
+
+/**
+ * webkit_browser_inspector_initialize_pipe:
+ *
+ * Creates browser inspector and configures pipe handler to communicate with
+ * the parent process.
+ */
+void webkit_browser_inspector_initialize_pipe(const char* defaultProxyURI, const char* const* ignoreHosts)
+{
+ WebKit::initializeBrowserInspectorPipe(makeUnique<WebKit::InspectorPlaywrightAgentClientGlib>(String::fromUTF8(defaultProxyURI), ignoreHosts));
+}
+
+/**
+ * webkit_browser_inspector_initialize_web_socket:
+ * @port: port number to start the remote debugging server on
+ * @defaultProxyURI: default proxy URI
+ * @ignoreHosts: list of hosts to ignore for proxy
+ *
+ * Creates browser inspector and configures HTTP server to communicate with
+ * remote debugging clients on the specified port.
+ */
+void webkit_browser_inspector_initialize_web_socket(unsigned port, const char* defaultProxyURI, const char* const* ignoreHosts)
+{
+ WebKit::initializeBrowserInspectorWebSocket(port, makeUnique<WebKit::InspectorPlaywrightAgentClientGlib>(String::fromUTF8(defaultProxyURI), ignoreHosts));
+}
diff --git a/Source/WebKit/UIProcess/API/glib/WebKitBrowserInspectorPrivate.h b/Source/WebKit/UIProcess/API/glib/WebKitBrowserInspectorPrivate.h
new file mode 100644
index 0000000000000000000000000000000000000000..e0b1da48465c850f541532ed961d1b778bea6028
--- /dev/null
+++ b/Source/WebKit/UIProcess/API/glib/WebKitBrowserInspectorPrivate.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2019 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "WebKitBrowserInspector.h"
+#include "WebPageProxy.h"
+
+WebKit::WebPageProxy* webkitBrowserInspectorCreateNewPageInContext(WebKitWebContext*);
+void webkitBrowserInspectorQuitApplication();
diff --git a/Source/WebKit/UIProcess/API/glib/WebKitProtocolHandler.cpp b/Source/WebKit/UIProcess/API/glib/WebKitProtocolHandler.cpp
index c816d0248895d9aa670e2226798237c696451b45..4d317eb4aaa630a97c03d70e7b15b05460354b01 100644
--- a/Source/WebKit/UIProcess/API/glib/WebKitProtocolHandler.cpp
+++ b/Source/WebKit/UIProcess/API/glib/WebKitProtocolHandler.cpp
@@ -160,51 +160,7 @@ static bool canvasAccelerationEnabled(WebKitURISchemeRequest* request)
return webkit_settings_get_enable_2d_canvas_acceleration(webkit_web_view_get_settings(webView));
}
-static bool uiProcessContextIsEGL()
-{
-#if PLATFORM(GTK)
- return Display::singleton().glDisplayIsSharedWithGtk();
-#else
- return true;
-#endif
-}
-
-static const char* openGLAPI()
-{
- if (epoxy_is_desktop_gl())
- return "OpenGL (libepoxy)";
- return "OpenGL ES 2 (libepoxy)";
-}
-
-#if PLATFORM(GTK) || (PLATFORM(WPE) && ENABLE(WPE_PLATFORM))
-static String dmabufRendererWithSupportedBuffers()
-{
- StringBuilder buffers;
- buffers.append("DMABuf (Supported buffers: "_s);
-
-#if PLATFORM(GTK)
- auto mode = AcceleratedBackingStore::rendererBufferTransportMode();
-#else
- OptionSet<RendererBufferTransportMode> mode;
- if (wpe_display_get_drm_device(wpe_display_get_primary()))
- mode.add(RendererBufferTransportMode::Hardware);
- mode.add(RendererBufferTransportMode::SharedMemory);
-#endif
-
- if (mode.contains(RendererBufferTransportMode::Hardware))
- buffers.append("Hardware"_s);
- if (mode.contains(RendererBufferTransportMode::SharedMemory)) {
- if (mode.contains(RendererBufferTransportMode::Hardware))
- buffers.append(", "_s);
- buffers.append("Shared Memory"_s);
- }
-
- buffers.append(')');
- return buffers.toString();
-}
-
#if USE(LIBDRM)
-
// Base on function 'drmGetFormatName' from 'https://gitlab.freedesktop.org/mesa/drm/-/blob/main/xf86drm.c'.
static String webkitDrmGetFormatName(uint32_t format)
{
@@ -258,47 +214,6 @@ static String modifierListToString(const Vector<uint64_t, 1>& modifiers)
#endif
}
-static String renderBufferDescription(WebKitURISchemeRequest* request)
-{
- StringBuilder bufferDescription;
- auto description = webkitWebViewGetRendererBufferDescription(webkit_uri_scheme_request_get_web_view(request));
- if (description.fourcc) {
- auto formatName = webkitDrmGetFormatName(description.fourcc);
- switch (description.type) {
- case RendererBufferDescription::Type::DMABuf: {
- auto modifierName = webkitDrmGetModifierName(description.modifier);
- if (!modifierName.isNull())
- bufferDescription.append("DMA-BUF: "_s, formatName, " ("_s, modifierName, ")"_s);
- else
- bufferDescription.append("Unknown"_s);
- break;
- }
- case RendererBufferDescription::Type::SharedMemory:
- bufferDescription.append("Shared Memory: "_s, formatName);
- break;
-#if OS(ANDROID)
- case RendererBufferDescription::Type::AHardwareBuffer:
- bufferDescription.append("AHardwareBuffer: "_s, formatName);
- break;
-#endif
- }
- switch (description.usage) {
- case RendererBufferFormat::Usage::Rendering:
- bufferDescription.append(" [Rendering]"_s);
- break;
- case RendererBufferFormat::Usage::Scanout:
- bufferDescription.append(" [Scanout]"_s);
- break;
- case RendererBufferFormat::Usage::Mapping:
- bufferDescription.append(" [Mapping]"_s);
- break;
- }
- } else
- bufferDescription.append("Unknown"_s);
-
- return bufferDescription.toString();
-}
-
#if USE(GBM)
static String preferredBufferFormats(WebKitURISchemeRequest* request, JSON::Array& jsonArray)
{
@@ -352,6 +267,87 @@ static String preferredBufferFormats(WebKitURISchemeRequest* request, JSON::Arra
}
#endif // USE(GBM)
#endif // USE(LIBDRM)
+
+static bool uiProcessContextIsEGL()
+{
+#if PLATFORM(GTK)
+ return Display::singleton().glDisplayIsSharedWithGtk();
+#else
+ return true;
+#endif
+}
+
+static const char* openGLAPI()
+{
+ if (epoxy_is_desktop_gl())
+ return "OpenGL (libepoxy)";
+ return "OpenGL ES 2 (libepoxy)";
+}
+
+#if PLATFORM(GTK) || (PLATFORM(WPE) && ENABLE(WPE_PLATFORM))
+static String dmabufRendererWithSupportedBuffers()
+{
+ StringBuilder buffers;
+ buffers.append("DMABuf (Supported buffers: "_s);
+
+#if PLATFORM(GTK)
+ auto mode = AcceleratedBackingStore::rendererBufferTransportMode();
+#else
+ OptionSet<RendererBufferTransportMode> mode;
+ if (wpe_display_get_drm_device(wpe_display_get_primary()))
+ mode.add(RendererBufferTransportMode::Hardware);
+ mode.add(RendererBufferTransportMode::SharedMemory);
+#endif
+
+ if (mode.contains(RendererBufferTransportMode::Hardware))
+ buffers.append("Hardware"_s);
+ if (mode.contains(RendererBufferTransportMode::SharedMemory)) {
+ if (mode.contains(RendererBufferTransportMode::Hardware))
+ buffers.append(", "_s);
+ buffers.append("Shared Memory"_s);
+ }
+
+ buffers.append(')');
+ return buffers.toString();
+}
+
+#if USE(LIBDRM)
+static String renderBufferDescription(WebKitURISchemeRequest* request)
+{
+ StringBuilder bufferDescription;
+ auto description = webkitWebViewGetRendererBufferDescription(webkit_uri_scheme_request_get_web_view(request));
+ if (description.fourcc) {
+ auto formatName = webkitDrmGetFormatName(description.fourcc);
+ switch (description.type) {
+ case RendererBufferDescription::Type::DMABuf: {
+ auto modifierName = webkitDrmGetModifierName(description.modifier);
+ if (!modifierName.isNull())
+ bufferDescription.append("DMA-BUF: "_s, formatName, " ("_s, modifierName, ")"_s);
+ else
+ bufferDescription.append("Unknown"_s);
+ break;
+ }
+ case RendererBufferDescription::Type::SharedMemory:
+ bufferDescription.append("Shared Memory: "_s, formatName);
+ break;
+ }
+ switch (description.usage) {
+ case RendererBufferFormat::Usage::Rendering:
+ bufferDescription.append(" [Rendering]"_s);
+ break;
+ case RendererBufferFormat::Usage::Scanout:
+ bufferDescription.append(" [Scanout]"_s);
+ break;
+ case RendererBufferFormat::Usage::Mapping:
+ bufferDescription.append(" [Mapping]"_s);
+ break;
+ }
+ } else
+ bufferDescription.append("Unknown"_s);
+
+ return bufferDescription.toString();
+}
+#endif // USE(LIBDRM)
#endif // PLATFORM(GTK) || (PLATFORM(WPE) && ENABLE(WPE_PLATFORM))
static String vblankMonitorType(const DisplayVBlankMonitor& monitor)
@@ -382,7 +378,6 @@ static String threadedRenderingInfo(const RenderProcessInfo& info)
static String supportedBufferFormats(const RenderProcessInfo& info, JSON::Array& jsonArray)
{
StringBuilder builder;
-#if PLATFORM(GTK) || (PLATFORM(WPE) && ENABLE(WPE_PLATFORM))
for (const auto& format : info.supportedBufferFormats) {
StringBuilder jsonStringBuilder;
auto formatName = webkitDrmGetFormatName(format.fourcc);
@@ -397,7 +392,6 @@ static String supportedBufferFormats(const RenderProcessInfo& info, JSON::Array&
}
jsonArray.pushString(jsonStringBuilder.toString());
}
-#endif
return builder.toString();
}
#endif
@@ -732,14 +726,18 @@ void WebKitProtocolHandler::handleGPU(WebKitURISchemeRequest* request, RenderPro
if (showBuffersInfo) {
#if PLATFORM(GTK) || (PLATFORM(WPE) && ENABLE(WPE_PLATFORM))
addTableRow(hardwareAccelerationObject, "Renderer"_s, dmabufRendererWithSupportedBuffers());
+#endif
+
#if USE(LIBDRM)
#if USE(GBM)
auto jsonFormats = JSON::Array::create();
auto formatsString = preferredBufferFormats(request, jsonFormats.get());
addTableRow(hardwareAccelerationObject, "Preferred buffer formats"_s, formatsString, WTF::move(jsonFormats));
#endif
- addTableRow(hardwareAccelerationObject, "Buffer format"_s, renderBufferDescription(request));
#endif // USE(LIBDRM)
+
+#if PLATFORM(GTK) || (PLATFORM(WPE) && ENABLE(WPE_PLATFORM))
+ addTableRow(hardwareAccelerationObject, "Buffer format"_s, renderBufferDescription(request));
#endif // PLATFORM(GTK) || (PLATFORM(WPE) && ENABLE(WPE_PLATFORM))
}
diff --git a/Source/WebKit/UIProcess/API/glib/WebKitUIClient.cpp b/Source/WebKit/UIProcess/API/glib/WebKitUIClient.cpp
index e94ec4aae750773fdb635e2b302735f6821ae3ef..eb8547be6916f5f95dc3be86c35292b4f7d7b0c5 100644
--- a/Source/WebKit/UIProcess/API/glib/WebKitUIClient.cpp
+++ b/Source/WebKit/UIProcess/API/glib/WebKitUIClient.cpp
@@ -102,6 +102,10 @@ private:
page.makeViewBlankIfUnpaintedSinceLastLoadCommit();
webkitWebViewRunJavaScriptPrompt(m_webView, message.utf8(), defaultValue.utf8(), WTF::move(completionHandler));
}
+ void handleJavaScriptDialog(WebPageProxy&, bool accept, const String& value) final
+ {
+ webkitWebViewHandleJavaScriptDialog(m_webView, accept, value);
+ }
bool canRunBeforeUnloadConfirmPanel() const final { return true; }
diff --git a/Source/WebKit/UIProcess/API/glib/WebKitWebContext.cpp b/Source/WebKit/UIProcess/API/glib/WebKitWebContext.cpp
index e1e5687811e65ce1f4cbeb082febffef479a279e..352135e3c98948921b5b135805ecc86043bb336a 100644
--- a/Source/WebKit/UIProcess/API/glib/WebKitWebContext.cpp
+++ b/Source/WebKit/UIProcess/API/glib/WebKitWebContext.cpp
@@ -426,10 +426,19 @@ static void webkitWebContextSetProperty(GObject* object, guint propID, const GVa
}
}
+static int webkitWebContext = 0;
+
+int webkitWebContextExistingCount()
+{
+ return webkitWebContext;
+}
+
static void webkitWebContextConstructed(GObject* object)
{
G_OBJECT_CLASS(webkit_web_context_parent_class)->constructed(object);
+ ++webkitWebContext;
+
GUniquePtr<char> bundleFilename(g_build_filename(injectedBundleDirectory(), INJECTED_BUNDLE_FILENAME, nullptr));
WebKitWebContext* webContext = WEBKIT_WEB_CONTEXT(object);
@@ -485,6 +494,8 @@ static void webkitWebContextConstructed(GObject* object)
static void webkitWebContextDispose(GObject* object)
{
+ --webkitWebContext;
+
WebKitWebContextPrivate* priv = WEBKIT_WEB_CONTEXT(object)->priv;
if (!priv->clientsDetached) {
priv->clientsDetached = true;
@@ -946,6 +957,11 @@ WebKitNetworkSession* webkit_web_context_get_network_session_for_automation(WebK
return nullptr;
#endif
}
+
+void webkit_web_context_set_network_session_for_automation(WebKitWebContext* context, WebKitNetworkSession* session)
+{
+ context->priv->automationNetworkSession = session;
+}
#endif
/**
* webkit_web_context_set_cache_model:
diff --git a/Source/WebKit/UIProcess/API/glib/WebKitWebContext.h.in b/Source/WebKit/UIProcess/API/glib/WebKitWebContext.h.in
index 15fe3e8e5652147ba54af266eda66b3962c074b9..d463fa78af375badb239c890da50ba1125e19de8 100644
--- a/Source/WebKit/UIProcess/API/glib/WebKitWebContext.h.in
+++ b/Source/WebKit/UIProcess/API/glib/WebKitWebContext.h.in
@@ -161,6 +161,10 @@ webkit_web_context_set_automation_allowed (WebKitWebContext
#if ENABLE(2022_GLIB_API)
WEBKIT_API WebKitNetworkSession *
webkit_web_context_get_network_session_for_automation(WebKitWebContext *context);
+
+WEBKIT_API void
+webkit_web_context_set_network_session_for_automation(WebKitWebContext *context,
+ WebKitNetworkSession *session);
#endif
WEBKIT_API void
diff --git a/Source/WebKit/UIProcess/API/glib/WebKitWebContextPrivate.h b/Source/WebKit/UIProcess/API/glib/WebKitWebContextPrivate.h
index c1945fbe717a42afc1f51d64a80c7de3fa9009ba..ab63fe19b00ecbd64c9421e6eecad3e25cbb2361 100644
--- a/Source/WebKit/UIProcess/API/glib/WebKitWebContextPrivate.h
+++ b/Source/WebKit/UIProcess/API/glib/WebKitWebContextPrivate.h
@@ -43,3 +43,4 @@ void webkitWebContextInitializeNotificationPermissions(WebKitWebContext*);
#if ENABLE(REMOTE_INSPECTOR)
void webkitWebContextWillCloseAutomationSession(WebKitWebContext*);
#endif
+int webkitWebContextExistingCount();
diff --git a/Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp b/Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp
index 3ed130d4fb0345c7309a240d3a412991e15f9904..10c9c0c89e4a9caf68d8075cde195bbf805e6887 100644
--- a/Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp
+++ b/Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp
@@ -40,6 +40,7 @@
#include "WebContextMenuItem.h"
#include "WebContextMenuItemData.h"
#include "WebFrameProxy.h"
+#include "WebPageInspectorController.h"
#include "WebKitAuthenticationRequestPrivate.h"
#include "WebKitBackForwardListPrivate.h"
#include "WebKitContextMenuClient.h"
@@ -160,6 +161,7 @@ enum {
CLOSE,
SCRIPT_DIALOG,
+ SCRIPT_DIALOG_HANDLED,
DECIDE_POLICY,
PERMISSION_REQUEST,
@@ -546,6 +548,13 @@ GRefPtr<WebKitOptionMenu> WebKitWebViewClient::showOptionMenu(WebKitPopupMenu& p
void WebKitWebViewClient::frameDisplayed(WKWPE::View&)
{
+
+#if USE(SKIA)
+ sk_sp<SkImage> surface(webkitWebViewBackendTakeScreenshot(m_webView->priv->backend.get()));
+ if (surface)
+ getPage(m_webView).inspectorController().didPaint(WTF::move(surface));
+#endif
+
{
SetForScope inFrameDisplayedGuard(m_webView->priv->inFrameDisplayed, true);
for (const auto& callback : m_webView->priv->frameDisplayedCallbacks) {
@@ -653,7 +662,7 @@ static gboolean webkitWebViewDecidePolicy(WebKitWebView*, WebKitPolicyDecision*
static gboolean webkitWebViewPermissionRequest(WebKitWebView*, WebKitPermissionRequest* request)
{
-#if ENABLE(POINTER_LOCK)
+#if ENABLE(POINTER_LOCK) && PLATFORM(GTK)
if (WEBKIT_IS_POINTER_LOCK_PERMISSION_REQUEST(request)) {
webkit_permission_request_allow(request);
return TRUE;
@@ -1001,6 +1010,10 @@ static void webkitWebViewConstructed(GObject* object)
priv->websitePolicies = adoptGRef(webkit_website_policies_new());
Ref configuration = priv->relatedView && priv->relatedView->priv->configurationForNextRelatedView ? priv->relatedView->priv->configurationForNextRelatedView.releaseNonNull() : webkitWebViewCreatePageConfiguration(webView);
+
+ // Playwright: REGRESSION(278896@main): Need to preserve configuration's preferences.
+ configuration->setPreferences(webkitSettingsGetPreferences(priv->settings.get()));
+
webkitWebViewCreatePage(webView, WTF::move(configuration));
webkitWebContextWebViewCreated(priv->context.get(), webView);
@@ -2114,6 +2127,15 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass)
G_TYPE_BOOLEAN, 1,
WEBKIT_TYPE_SCRIPT_DIALOG);
+ signals[SCRIPT_DIALOG_HANDLED] = g_signal_new(
+ "script-dialog-handled",
+ G_TYPE_FROM_CLASS(webViewClass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(WebKitWebViewClass, script_dialog),
+ g_signal_accumulator_true_handled, nullptr,
+ g_cclosure_marshal_generic,
+ G_TYPE_BOOLEAN, 1);
+
/**
* WebKitWebView::decide-policy:
* @web_view: the #WebKitWebView on which the signal is emitted
@@ -2948,6 +2970,23 @@ void webkitWebViewRunJavaScriptBeforeUnloadConfirm(WebKitWebView* webView, const
webkit_script_dialog_unref(webView->priv->currentScriptDialog);
}
+void webkitWebViewHandleJavaScriptDialog(WebKitWebView* webView, bool accept, const String& value) {
+ auto* dialog = webView->priv->currentScriptDialog;
+#if PLATFORM(WPE)
+ dialog->isUserHandled = false;
+#endif
+ webkit_script_dialog_ref(dialog);
+ if (!value.isNull())
+ webkitWebViewSetCurrentScriptDialogUserInput(webView, value);
+ if (accept)
+ webkitWebViewAcceptCurrentScriptDialog(webView);
+ else
+ webkitWebViewDismissCurrentScriptDialog(webView);
+ gboolean returnValue;
+ g_signal_emit(webView, signals[SCRIPT_DIALOG_HANDLED], 0, dialog, &returnValue);
+ webkit_script_dialog_unref(dialog);
+}
+
bool webkitWebViewIsShowingScriptDialog(WebKitWebView* webView)
{
if (!webView->priv->currentScriptDialog)
diff --git a/Source/WebKit/UIProcess/API/glib/WebKitWebViewPrivate.h b/Source/WebKit/UIProcess/API/glib/WebKitWebViewPrivate.h
index 8bff6235bb227ed9e53017f45ce6469dede379fb..34a4c07514c1661ea7e333de5ea674123b809b2f 100644
--- a/Source/WebKit/UIProcess/API/glib/WebKitWebViewPrivate.h
+++ b/Source/WebKit/UIProcess/API/glib/WebKitWebViewPrivate.h
@@ -67,6 +67,7 @@ void webkitWebViewRunJavaScriptAlert(WebKitWebView*, const CString& message, Fun
void webkitWebViewRunJavaScriptConfirm(WebKitWebView*, const CString& message, Function<void(bool)>&& completionHandler);
void webkitWebViewRunJavaScriptPrompt(WebKitWebView*, const CString& message, const CString& defaultText, Function<void(const String&)>&& completionHandler);
void webkitWebViewRunJavaScriptBeforeUnloadConfirm(WebKitWebView*, const CString& message, Function<void(bool)>&& completionHandler);
+void webkitWebViewHandleJavaScriptDialog(WebKitWebView*, bool accept, const String& value);
bool webkitWebViewIsShowingScriptDialog(WebKitWebView*);
bool webkitWebViewIsScriptDialogRunning(WebKitWebView*, WebKitScriptDialog*);
String webkitWebViewGetCurrentScriptDialogMessage(WebKitWebView*);
diff --git a/Source/WebKit/UIProcess/API/glib/webkit.h.in b/Source/WebKit/UIProcess/API/glib/webkit.h.in
index d48845217e514f1fb9dc84917cd8ba7b26046dee..0402761230371a6f9e9e78caaaf2f207fa3c760c 100644
--- a/Source/WebKit/UIProcess/API/glib/webkit.h.in
+++ b/Source/WebKit/UIProcess/API/glib/webkit.h.in
@@ -45,6 +45,7 @@
#include <@API_INCLUDE_PREFIX@/WebKitAutomationSession.h>
#include <@API_INCLUDE_PREFIX@/WebKitBackForwardList.h>
#include <@API_INCLUDE_PREFIX@/WebKitBackForwardListItem.h>
+#include <@API_INCLUDE_PREFIX@/WebKitBrowserInspector.h>
#if PLATFORM(GTK)
#include <@API_INCLUDE_PREFIX@/WebKitClipboardPermissionRequest.h>
#include <@API_INCLUDE_PREFIX@/WebKitColorChooserRequest.h>
diff --git a/Source/WebKit/UIProcess/API/gtk/PageClientImpl.cpp b/Source/WebKit/UIProcess/API/gtk/PageClientImpl.cpp
index a33310d9ef8795338756c5d38da9fdc18fd65d6d..363988712345502a202f9feea21f2ca365ed41c0 100644
--- a/Source/WebKit/UIProcess/API/gtk/PageClientImpl.cpp
+++ b/Source/WebKit/UIProcess/API/gtk/PageClientImpl.cpp
@@ -246,7 +246,7 @@ WebCore::IntPoint PageClientImpl::accessibilityScreenToRootView(const WebCore::I
return screenToRootView(point);
}
-WebCore::IntRect PageClientImpl::rootViewToAccessibilityScreen(const WebCore::IntRect& rect)
+WebCore::IntRect PageClientImpl::rootViewToAccessibilityScreen(const WebCore::IntRect& rect)
{
return rootViewToScreen(rect);
}
@@ -255,6 +255,8 @@ void PageClientImpl::doneWithKeyEvent(const NativeWebKeyboardEvent& event, bool
{
if (wasEventHandled || event.type() != WebEventType::KeyDown || !event.nativeEvent())
return;
+ if (!event.nativeEvent())
+ return;
// Always consider arrow keys as handled, otherwise the GtkWindow key bindings will move the focus.
guint keyval;
@@ -345,9 +347,9 @@ void PageClientImpl::selectionDidChange()
webkitWebViewSelectionDidChange(WEBKIT_WEB_VIEW(m_viewWidget));
}
-RefPtr<ViewSnapshot> PageClientImpl::takeViewSnapshot(std::optional<WebCore::IntRect>&& clipRect)
+RefPtr<ViewSnapshot> PageClientImpl::takeViewSnapshot(std::optional<WebCore::IntRect>&& clipRect, bool nominalResolution)
{
- return webkitWebViewBaseTakeViewSnapshot(WEBKIT_WEB_VIEW_BASE(m_viewWidget), WTF::move(clipRect));
+ return webkitWebViewBaseTakeViewSnapshot(WEBKIT_WEB_VIEW_BASE(m_viewWidget), WTF::move(clipRect), nominalResolution);
}
void PageClientImpl::didChangeContentSize(const IntSize& size)
diff --git a/Source/WebKit/UIProcess/API/gtk/PageClientImpl.h b/Source/WebKit/UIProcess/API/gtk/PageClientImpl.h
index 0dae577227eaac423bdc97d9c859fe5afc2d06c1..8edbe1cb3e7d0f818290122861635c063595c632 100644
--- a/Source/WebKit/UIProcess/API/gtk/PageClientImpl.h
+++ b/Source/WebKit/UIProcess/API/gtk/PageClientImpl.h
@@ -104,7 +104,7 @@ private:
RefPtr<WebDataListSuggestionsDropdown> createDataListSuggestionsDropdown(WebPageProxy&) override;
Ref<WebCore::ValidationBubble> createValidationBubble(String&& message, const WebCore::ValidationBubble::Settings&) final;
void selectionDidChange() override;
- RefPtr<ViewSnapshot> takeViewSnapshot(std::optional<WebCore::IntRect>&&) override;
+ RefPtr<ViewSnapshot> takeViewSnapshot(std::optional<WebCore::IntRect>&&, bool nominalResolution = false) override;
#if ENABLE(DRAG_SUPPORT)
void startDrag(WebCore::SelectionData&&, OptionSet<WebCore::DragOperation>, RefPtr<WebCore::ShareableBitmap>&& dragImage, WebCore::IntPoint&& dragImageHotspot) override;
void didPerformDragControllerAction() override;
diff --git a/Source/WebKit/UIProcess/API/gtk/WebKitBrowserInspector.h b/Source/WebKit/UIProcess/API/gtk/WebKitBrowserInspector.h
new file mode 100644
index 0000000000000000000000000000000000000000..1d6c987019e69d2e1ab97266d01180542534f4b0
--- /dev/null
+++ b/Source/WebKit/UIProcess/API/gtk/WebKitBrowserInspector.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2019 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if !defined(__WEBKIT2_H_INSIDE__) && !defined(BUILDING_WEBKIT)
+#error "Only <webkit2/webkit2.h> can be included directly."
+#endif
+
+#ifndef WebKitBrowserInspector_h
+#define WebKitBrowserInspector_h
+
+#include <glib-object.h>
+#include <webkit/WebKitDefines.h>
+#include <webkit/WebKitWebView.h>
+
+G_BEGIN_DECLS
+
+#define WEBKIT_TYPE_BROWSER_INSPECTOR (webkit_browser_inspector_get_type())
+#define WEBKIT_BROWSER_INSPECTOR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_BROWSER_INSPECTOR, WebKitBrowserInspector))
+#define WEBKIT_IS_BROWSER_INSPECTOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_BROWSER_INSPECTOR))
+#define WEBKIT_BROWSER_INSPECTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WEBKIT_TYPE_BROWSER_INSPECTOR, WebKitBrowserInspectorClass))
+#define WEBKIT_IS_BROWSER_INSPECTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_BROWSER_INSPECTOR))
+#define WEBKIT_BROWSER_INSPECTOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_BROWSER_INSPECTOR, WebKitBrowserInspectorClass))
+
+typedef struct _WebKitBrowserInspector WebKitBrowserInspector;
+typedef struct _WebKitBrowserInspectorClass WebKitBrowserInspectorClass;
+typedef struct _WebKitBrowserInspectorPrivate WebKitBrowserInspectorPrivate;
+
+struct _WebKitBrowserInspector {
+ GObject parent;
+
+ WebKitBrowserInspectorPrivate *priv;
+};
+
+struct _WebKitBrowserInspectorClass {
+ GObjectClass parent_class;
+
+ WebKitWebView *(* create_new_page) (WebKitBrowserInspector *browser_inspector,
+ WebKitWebContext *context);
+ WebKitWebView *(* quit_application) (WebKitBrowserInspector *browser_inspector);
+
+ void (*_webkit_reserved0) (void);
+ void (*_webkit_reserved1) (void);
+ void (*_webkit_reserved2) (void);
+ void (*_webkit_reserved3) (void);
+};
+
+WEBKIT_API GType
+webkit_browser_inspector_get_type (void);
+
+WEBKIT_API WebKitBrowserInspector *
+webkit_browser_inspector_get_default (void);
+
+WEBKIT_API void
+webkit_browser_inspector_initialize_pipe (const char* defaultProxyURI,
+ const char* const* ignoreHosts);
+
+WEBKIT_API void
+webkit_browser_inspector_initialize_web_socket (unsigned port,
+ const char* defaultProxyURI,
+ const char* const* ignoreHosts);
+
+G_END_DECLS
+
+#endif
diff --git a/Source/WebKit/UIProcess/API/gtk/WebKitPointerLockPermissionRequest.h.in b/Source/WebKit/UIProcess/API/gtk/WebKitPointerLockPermissionRequest.h.in
index 496079da90993ac37689b060b69ecd4a67c2b6a8..af30181ca922f16c0f6e245c70e5ce7d8999341f 100644
--- a/Source/WebKit/UIProcess/API/gtk/WebKitPointerLockPermissionRequest.h.in
+++ b/Source/WebKit/UIProcess/API/gtk/WebKitPointerLockPermissionRequest.h.in
@@ -23,7 +23,7 @@
#define WebKitPointerLockPermissionRequest_h
#include <glib-object.h>
-#include <webkit/WebKitDefines.h>
+#include <@API_INCLUDE_PREFIX@/WebKitDefines.h>
G_BEGIN_DECLS
diff --git a/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBase.cpp b/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBase.cpp
index d5bb72f0ffbf99eddebc9819cb3f24fdaffdf468..d248c201e0ee9db63a117b8cde34661595a594fa 100644
--- a/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBase.cpp
+++ b/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBase.cpp
@@ -2879,6 +2879,11 @@ void webkitWebViewBaseResetClickCounter(WebKitWebViewBase* webkitWebViewBase)
#endif
}
+WebKit::AcceleratedBackingStore* webkitWebViewBaseGetAcceleratedBackingStore(WebKitWebViewBase* webkitWebViewBase)
+{
+ return webkitWebViewBase->priv->acceleratedBackingStore.get();
+}
+
void webkitWebViewBaseEnterAcceleratedCompositingMode(WebKitWebViewBase* webkitWebViewBase, const LayerTreeContext& layerTreeContext)
{
ASSERT(webkitWebViewBase->priv->acceleratedBackingStore);
@@ -2935,12 +2940,12 @@ void webkitWebViewBasePageClosed(WebKitWebViewBase* webkitWebViewBase)
webkitWebViewBase->priv->acceleratedBackingStore->update({ });
}
-RefPtr<WebKit::ViewSnapshot> webkitWebViewBaseTakeViewSnapshot(WebKitWebViewBase* webkitWebViewBase, std::optional<IntRect>&& clipRect)
+RefPtr<WebKit::ViewSnapshot> webkitWebViewBaseTakeViewSnapshot(WebKitWebViewBase* webkitWebViewBase, std::optional<IntRect>&& clipRect, bool nominalResolution)
{
WebPageProxy* page = webkitWebViewBase->priv->pageProxy.get();
IntSize size = clipRect ? clipRect->size() : page->viewSize();
- float deviceScale = page->deviceScaleFactor();
+ float deviceScale = nominalResolution ? 1 : page->deviceScaleFactor();
size.scale(deviceScale);
#if !USE(GTK4)
diff --git a/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBasePrivate.h b/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBasePrivate.h
index d84099f5109a4a0a8a0b51d4f46ce059460b8280..48d56239c4595053696a63fa48c69db0706ca19a 100644
--- a/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBasePrivate.h
+++ b/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBasePrivate.h
@@ -27,6 +27,7 @@
#pragma once
+#include "AcceleratedBackingStore.h"
#include "APIPageConfiguration.h"
#include "GRefPtrGtk.h"
#include "GUniquePtrGtk.h"
@@ -105,7 +106,7 @@ void webkitWebViewBaseStartDrag(WebKitWebViewBase*, WebCore::SelectionData&&, Op
void webkitWebViewBaseDidPerformDragControllerAction(WebKitWebViewBase*);
#endif
-RefPtr<WebKit::ViewSnapshot> webkitWebViewBaseTakeViewSnapshot(WebKitWebViewBase*, std::optional<WebCore::IntRect>&&);
+RefPtr<WebKit::ViewSnapshot> webkitWebViewBaseTakeViewSnapshot(WebKitWebViewBase*, std::optional<WebCore::IntRect>&&, bool nominalResolution);
void webkitWebViewBaseSetEnableBackForwardNavigationGesture(WebKitWebViewBase*, bool enabled);
WebKit::ViewGestureController* webkitWebViewBaseViewGestureController(WebKitWebViewBase*);
@@ -147,3 +148,5 @@ void webkitWebViewBaseSetPlugID(WebKitWebViewBase*, const String&);
WebKit::RendererBufferDescription webkitWebViewBaseGetRendererBufferDescription(WebKitWebViewBase*);
void webkitWebViewBaseSetCursor(WebKitWebViewBase*, const WebCore::Cursor&);
+
+WebKit::AcceleratedBackingStore* webkitWebViewBaseGetAcceleratedBackingStore(WebKitWebViewBase*);
diff --git a/Source/WebKit/UIProcess/API/wpe/APIViewClient.h b/Source/WebKit/UIProcess/API/wpe/APIViewClient.h
index 9091ae5198e765c2cfe0584d121afe4f88df3c0e..b0efedec419673ef2bfd0fd79406774e24aa98e9 100644
--- a/Source/WebKit/UIProcess/API/wpe/APIViewClient.h
+++ b/Source/WebKit/UIProcess/API/wpe/APIViewClient.h
@@ -26,6 +26,9 @@
#pragma once
#include "UserMessage.h"
+#if USE(SKIA)
+#include <skia/core/SkImage.h>
+#endif
#include <wtf/CompletionHandler.h>
#include <wtf/TZoneMallocInlines.h>
@@ -50,6 +53,11 @@ public:
virtual bool isGLibBasedAPI() { return false; }
virtual void frameDisplayed(WKWPE::View&) { }
+// Playwright begin
+#if USE(SKIA)
+ virtual sk_sp<SkImage> takeViewScreenshot() { return nullptr; }
+#endif
+// Playwright end
virtual void willStartLoad(WKWPE::View&) { }
virtual void didChangePageID(WKWPE::View&) { }
virtual void didReceiveUserMessage(WKWPE::View&, WebKit::UserMessage&&, CompletionHandler<void(WebKit::UserMessage&&)>&& completionHandler) { completionHandler(WebKit::UserMessage()); }
diff --git a/Source/WebKit/UIProcess/API/wpe/PageClientImpl.cpp b/Source/WebKit/UIProcess/API/wpe/PageClientImpl.cpp
index 44bec4dfe534281e791339bc6eebc3795d65b2c9..4d7cd002b8420382e3628886a7fc4c6229db2702 100644
--- a/Source/WebKit/UIProcess/API/wpe/PageClientImpl.cpp
+++ b/Source/WebKit/UIProcess/API/wpe/PageClientImpl.cpp
@@ -36,9 +36,12 @@
#include "WPEWebViewLegacy.h"
#include "WPEWebViewPlatform.h"
#include "WebColorPicker.h"
+#include "WebColorPickerWPE.h"
+#include "WebDateTimePickerWPE.h"
#include "WebContextMenuProxy.h"
#include "WebContextMenuProxyWPE.h"
#include "WebDataListSuggestionsDropdown.h"
+#include "WebDataListSuggestionsDropdownWPE.h"
#include "WebDateTimePicker.h"
#include "WebKitPopupMenu.h"
#include <WebCore/ActivityState.h>
@@ -62,6 +65,12 @@
#include <wpe/wpe.h>
#endif
+#if USE(SKIA)
+#include <skia/core/SkBitmap.h>
+#include <skia/core/SkCanvas.h>
+#include <skia/core/SkImage.h>
+#endif
+
namespace WebKit {
WTF_MAKE_TZONE_ALLOCATED_IMPL(PageClientImpl);
@@ -230,7 +239,7 @@ WebCore::IntPoint PageClientImpl::accessibilityScreenToRootView(const WebCore::I
WebCore::IntRect PageClientImpl::rootViewToAccessibilityScreen(const WebCore::IntRect& rect)
{
- return rootViewToScreen(rect);
+ return rootViewToScreen(rect);
}
void PageClientImpl::doneWithKeyEvent(const NativeWebKeyboardEvent&, bool)
@@ -318,14 +327,14 @@ Ref<WebContextMenuProxy> PageClientImpl::createContextMenuProxy(WebPageProxy& pa
}
#endif
-RefPtr<WebColorPicker> PageClientImpl::createColorPicker(WebPageProxy&, const WebCore::Color& intialColor, const WebCore::IntRect&, ColorControlSupportsAlpha supportsAlpha, Vector<WebCore::Color>&&, std::optional<WebCore::FrameIdentifier>)
+RefPtr<WebColorPicker> PageClientImpl::createColorPicker(WebPageProxy& page, const WebCore::Color& intialColor, const WebCore::IntRect& rect, ColorControlSupportsAlpha supportsAlpha, Vector<WebCore::Color>&&, std::optional<WebCore::FrameIdentifier> frameID)
{
- return nullptr;
+ return WebColorPickerWPE::create(page, intialColor, rect, frameID);
}
-RefPtr<WebDataListSuggestionsDropdown> PageClientImpl::createDataListSuggestionsDropdown(WebPageProxy&)
+RefPtr<WebKit::WebDataListSuggestionsDropdown> PageClientImpl::createDataListSuggestionsDropdown(WebKit::WebPageProxy& page)
{
- return nullptr;
+ return WebDataListSuggestionsDropdownWPE::create(page);
}
RefPtr<WebDateTimePicker> PageClientImpl::createDateTimePicker(WebPageProxy& page)
@@ -585,11 +594,11 @@ void PageClientImpl::callAfterNextPresentationUpdate(CompletionHandler<void()>&&
m_view.callAfterNextPresentationUpdate(WTF::move(callback));
}
-RefPtr<ViewSnapshot> PageClientImpl::takeViewSnapshot(std::optional<WebCore::IntRect>&& clipRect)
+RefPtr<ViewSnapshot> PageClientImpl::takeViewSnapshot(std::optional<WebCore::IntRect>&& clipRect, bool nominalResolution)
{
#if ENABLE(WPE_PLATFORM)
if (m_view.wpeView()) {
- auto snapshot = static_cast<WKWPE::ViewPlatform&>(m_view).takeViewSnapshot(WTF::move(clipRect));
+ auto snapshot = static_cast<WKWPE::ViewPlatform&>(m_view).takeViewSnapshot(WTF::move(clipRect), nominalResolution);
// FIXME Forward the Expected in https://webkit.org/b/300271
if (snapshot)
return WTF::move(snapshot.value());
@@ -600,4 +609,11 @@ RefPtr<ViewSnapshot> PageClientImpl::takeViewSnapshot(std::optional<WebCore::Int
return nullptr;
}
+#if ENABLE(DATE_AND_TIME_INPUT_TYPES)
+RefPtr<WebDateTimePicker> PageClientImpl::createDateTimePicker(WebPageProxy& page)
+{
+ return WebDateTimePickerWPE::create(page);
+}
+#endif
+
} // namespace WebKit
diff --git a/Source/WebKit/UIProcess/API/wpe/PageClientImpl.h b/Source/WebKit/UIProcess/API/wpe/PageClientImpl.h
index a1f18769eb2398cb467067f7f2d6ad864d1ed0ee..842bc438edd93ad09ddc1012898856e4ac686f00 100644
--- a/Source/WebKit/UIProcess/API/wpe/PageClientImpl.h
+++ b/Source/WebKit/UIProcess/API/wpe/PageClientImpl.h
@@ -193,7 +193,11 @@ private:
WebKitWebResourceLoadManager* webResourceLoadManager() override;
- RefPtr<ViewSnapshot> takeViewSnapshot(std::optional<WebCore::IntRect>&&) override;
+ RefPtr<ViewSnapshot> takeViewSnapshot(std::optional<WebCore::IntRect>&&, bool nominalResolution) override;
+
+#if ENABLE(DATE_AND_TIME_INPUT_TYPES)
+ RefPtr<WebDateTimePicker> createDateTimePicker(WebPageProxy&) override;
+#endif
WKWPE::View& m_view;
DefaultUndoController m_undoController;
diff --git a/Source/WebKit/UIProcess/API/wpe/WPEWebViewPlatform.cpp b/Source/WebKit/UIProcess/API/wpe/WPEWebViewPlatform.cpp
index 32b91bcbf205dfbd36c9275a6167877cf561a172..ce45bcc6e7fdd92efa31d974a8230253fbf3294e 100644
--- a/Source/WebKit/UIProcess/API/wpe/WPEWebViewPlatform.cpp
+++ b/Source/WebKit/UIProcess/API/wpe/WPEWebViewPlatform.cpp
@@ -645,9 +645,9 @@ void ViewPlatform::callAfterNextPresentationUpdate(CompletionHandler<void()>&& c
}
}
-Expected<Ref<ViewSnapshot>, String> ViewPlatform::takeViewSnapshot(std::optional<WebCore::IntRect>&& clipRect)
+Expected<Ref<ViewSnapshot>, String> ViewPlatform::takeViewSnapshot(std::optional<WebCore::IntRect>&& clipRect, bool nominalResolution)
{
- return m_backingStore->takeSnapshot(WTF::move(clipRect));
+ return m_backingStore->takeSnapshot(WTF::move(clipRect), nominalResolution);
}
} // namespace WKWPE
diff --git a/Source/WebKit/UIProcess/API/wpe/WPEWebViewPlatform.h b/Source/WebKit/UIProcess/API/wpe/WPEWebViewPlatform.h
index c3ca21d8e499d08a4e5ebf4a32290114abfae4ee..1de5446d0763256ac826a5e71e51e6d2838172f8 100644
--- a/Source/WebKit/UIProcess/API/wpe/WPEWebViewPlatform.h
+++ b/Source/WebKit/UIProcess/API/wpe/WPEWebViewPlatform.h
@@ -63,7 +63,7 @@ public:
static WebKit::WebPageProxy* platformWebPageProxyForGamepadInput();
#endif
- Expected<Ref<WebKit::ViewSnapshot>, String> takeViewSnapshot(std::optional<WebCore::IntRect>&&);
+ Expected<Ref<WebKit::ViewSnapshot>, String> takeViewSnapshot(std::optional<WebCore::IntRect>&&, bool nominalResolution);
void updateAcceleratedSurface(uint64_t);
WebKit::RendererBufferDescription renderBufferDescription() const;
diff --git a/Source/WebKit/UIProcess/API/wpe/WebKitBrowserInspector.h b/Source/WebKit/UIProcess/API/wpe/WebKitBrowserInspector.h
new file mode 100644
index 0000000000000000000000000000000000000000..22baa003f1220a87d5c1012cd485a6fee1570b22
--- /dev/null
+++ b/Source/WebKit/UIProcess/API/wpe/WebKitBrowserInspector.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2019 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if !defined(__WEBKIT_H_INSIDE__) && !defined(BUILDING_WEBKIT)
+#error "Only <wpe/webkit.h> can be included directly."
+#endif
+
+#ifndef WebKitBrowserInspector_h
+#define WebKitBrowserInspector_h
+
+#include <glib-object.h>
+#include <wpe/WebKitDefines.h>
+#include <wpe/WebKitWebView.h>
+
+G_BEGIN_DECLS
+
+#define WEBKIT_TYPE_BROWSER_INSPECTOR (webkit_browser_inspector_get_type())
+#define WEBKIT_BROWSER_INSPECTOR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_BROWSER_INSPECTOR, WebKitBrowserInspector))
+#define WEBKIT_IS_BROWSER_INSPECTOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_BROWSER_INSPECTOR))
+#define WEBKIT_BROWSER_INSPECTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WEBKIT_TYPE_BROWSER_INSPECTOR, WebKitBrowserInspectorClass))
+#define WEBKIT_IS_BROWSER_INSPECTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_BROWSER_INSPECTOR))
+#define WEBKIT_BROWSER_INSPECTOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_BROWSER_INSPECTOR, WebKitBrowserInspectorClass))
+
+typedef struct _WebKitBrowserInspector WebKitBrowserInspector;
+typedef struct _WebKitBrowserInspectorClass WebKitBrowserInspectorClass;
+typedef struct _WebKitBrowserInspectorPrivate WebKitBrowserInspectorPrivate;
+
+struct _WebKitBrowserInspector {
+ GObject parent;
+
+ WebKitBrowserInspectorPrivate *priv;
+};
+
+struct _WebKitBrowserInspectorClass {
+ GObjectClass parent_class;
+
+ WebKitWebView *(* create_new_page) (WebKitBrowserInspector *browser_inspector,
+ WebKitWebContext *context);
+ WebKitWebView *(* quit_application) (WebKitBrowserInspector *browser_inspector);
+
+ void (*_webkit_reserved0) (void);
+ void (*_webkit_reserved1) (void);
+ void (*_webkit_reserved2) (void);
+ void (*_webkit_reserved3) (void);
+};
+
+WEBKIT_API GType
+webkit_browser_inspector_get_type (void);
+
+WEBKIT_API WebKitBrowserInspector *
+webkit_browser_inspector_get_default (void);
+
+WEBKIT_API void
+webkit_browser_inspector_initialize_pipe (const char* defaultProxyURI,
+ const char* const* ignoreHosts);
+
+WEBKIT_API void
+webkit_browser_inspector_initialize_web_socket (unsigned port,
+ const char* defaultProxyURI,
+ const char* const* ignoreHosts);
+
+G_END_DECLS
+
+#endif
diff --git a/Source/WebKit/UIProcess/API/wpe/WebKitWebViewBackend.cpp b/Source/WebKit/UIProcess/API/wpe/WebKitWebViewBackend.cpp
index 96170b6fd5f7dfc9ae97019f1dae74ee686f3a89..731d1aa724878543872a604c55da6b0affca45b6 100644
--- a/Source/WebKit/UIProcess/API/wpe/WebKitWebViewBackend.cpp
+++ b/Source/WebKit/UIProcess/API/wpe/WebKitWebViewBackend.cpp
@@ -56,6 +56,7 @@ struct _WebKitWebViewBackend {
struct wpe_view_backend* backend;
GDestroyNotify notifyCallback;
gpointer notifyCallbackData;
+ take_screenshot_callback screenshotCallback;
int referenceCount { 1 };
};
@@ -118,6 +119,19 @@ struct wpe_view_backend* webkit_web_view_backend_get_wpe_backend(WebKitWebViewBa
return viewBackend->backend;
}
+void webkit_web_view_backend_set_screenshot_callback(WebKitWebViewBackend *view_backend, take_screenshot_callback callback)
+{
+ view_backend->screenshotCallback = callback;
+}
+
+PlatformImage webkitWebViewBackendTakeScreenshot(WebKitWebViewBackend* view_backend)
+{
+ if (!view_backend->screenshotCallback)
+ return nullptr;
+
+ return view_backend->screenshotCallback(view_backend->notifyCallbackData);
+}
+
namespace WTF {
WTF_DEFINE_GREF_TRAITS(WebKitWebViewBackend, webkitWebViewBackendRef, webkitWebViewBackendUnref)
}
diff --git a/Source/WebKit/UIProcess/API/wpe/WebKitWebViewBackend.h b/Source/WebKit/UIProcess/API/wpe/WebKitWebViewBackend.h
index 16dcc1f69c38cd8ad630bc49d6d69feaa3aa811e..98677028c19c12c3b6d513bb5e45375a1528fe8a 100644
--- a/Source/WebKit/UIProcess/API/wpe/WebKitWebViewBackend.h
+++ b/Source/WebKit/UIProcess/API/wpe/WebKitWebViewBackend.h
@@ -28,6 +28,11 @@
#include <wpe/WebKitDefines.h>
#include <wpe/wpe.h>
+#if defined(USE_SKIA) && USE_SKIA
+#include <skia/core/SkImage.h>
+using PlatformImage = SkImage*;
+#endif
+
G_BEGIN_DECLS
#define WEBKIT_TYPE_WEB_VIEW_BACKEND (webkit_web_view_backend_get_type())
@@ -44,6 +49,12 @@ webkit_web_view_backend_new (struct wpe_view_backend *backend,
WEBKIT_API struct wpe_view_backend *
webkit_web_view_backend_get_wpe_backend (WebKitWebViewBackend *view_backend);
+typedef PlatformImage (*take_screenshot_callback)(gpointer user_data);
+
+WEBKIT_API void
+webkit_web_view_backend_set_screenshot_callback (WebKitWebViewBackend *view_backend,
+ take_screenshot_callback callback);
+
G_END_DECLS
#endif /* WebKitWebViewBackend_h */
diff --git a/Source/WebKit/UIProcess/API/wpe/WebKitWebViewBackendPrivate.h b/Source/WebKit/UIProcess/API/wpe/WebKitWebViewBackendPrivate.h
index 21131a4d26ba115f3249b227d3e1dabd42398c80..7b1a6e98f3c1fb5ef5d54f416c49ba3e6188dcf4 100644
--- a/Source/WebKit/UIProcess/API/wpe/WebKitWebViewBackendPrivate.h
+++ b/Source/WebKit/UIProcess/API/wpe/WebKitWebViewBackendPrivate.h
@@ -32,3 +32,5 @@ WTF_DECLARE_GREF_TRAITS(WebKitWebViewBackend)
void webkitWebViewBackendUnref(WebKitWebViewBackend*);
#endif // USE(LIBWPE)
+
+PlatformImage webkitWebViewBackendTakeScreenshot(WebKitWebViewBackend*);
diff --git a/Source/WebKit/UIProcess/Automation/WebAutomationSession.h b/Source/WebKit/UIProcess/Automation/WebAutomationSession.h
index c38751ae3064aa6a42a3ed8fdb902f70473a8e08..f6bf1a674402bc08f69bccc97058954981ad4ebc 100644
--- a/Source/WebKit/UIProcess/Automation/WebAutomationSession.h
+++ b/Source/WebKit/UIProcess/Automation/WebAutomationSession.h
@@ -318,6 +318,8 @@ public:
void didDestroyFrame(WebCore::FrameIdentifier);
+ static std::optional<String> platformGetBase64EncodedPNGData(const ViewSnapshot&);
+
RefPtr<WebPageProxy> webPageProxyForHandle(const String&);
String effectiveHandleForWebFrameProxy(const WebFrameProxy&);
String handleForWebFrameID(std::optional<WebCore::FrameIdentifier>);
@@ -385,7 +387,6 @@ private:
// Get base64-encoded PNG data from a bitmap.
static std::optional<String> platformGetBase64EncodedPNGData(WebCore::ShareableBitmap::Handle&&);
- static std::optional<String> platformGetBase64EncodedPNGData(const ViewSnapshot&);
// Save base64-encoded file contents to a local file path and return the path.
// This reuses the basename of the remote file path so that the filename exposed to DOM API remains the same.
diff --git a/Source/WebKit/UIProcess/AuxiliaryProcessProxy.cpp b/Source/WebKit/UIProcess/AuxiliaryProcessProxy.cpp
index d2e4f4cf05d2c7ce330319b4116c816c237df2dd..04e2e8d6125daf90a8c0c7aaa69e626f95b044d9 100644
--- a/Source/WebKit/UIProcess/AuxiliaryProcessProxy.cpp
+++ b/Source/WebKit/UIProcess/AuxiliaryProcessProxy.cpp
@@ -176,7 +176,11 @@ void AuxiliaryProcessProxy::getLaunchOptions(ProcessLauncher::LaunchOptions& lau
launchOptions.processCmdPrefix = String::fromUTF8(processCmdPrefix);
#endif // ENABLE(DEVELOPER_MODE) && (PLATFORM(GTK) || PLATFORM(WPE))
+/* playwright revert 50f8fee */
+#if 0
populateOverrideLanguagesLaunchOptions(launchOptions);
+#endif
+/* end playwright revert 50f8fee */
platformGetLaunchOptions(launchOptions);
}
diff --git a/Source/WebKit/UIProcess/AuxiliaryProcessProxy.h b/Source/WebKit/UIProcess/AuxiliaryProcessProxy.h
index 0241fd8531d53a1f773e7c4a2c871e1903816eba..f199f4096d254ce0242c569db600554efac8c226 100644
--- a/Source/WebKit/UIProcess/AuxiliaryProcessProxy.h
+++ b/Source/WebKit/UIProcess/AuxiliaryProcessProxy.h
@@ -296,13 +296,16 @@ protected:
InitializationActivityAndGrant initializationActivityAndGrant();
+ /* playwright revert 50f8fee - make protected to allow use from WebProcessProxy */
+ Vector<String> platformOverrideLanguages() const;
+ /* end playwright revert 50f8fee */
+
private:
virtual void connectionWillOpen(IPC::Connection&);
virtual void processWillShutDown(IPC::Connection&) = 0;
void outgoingMessageQueueIsGrowingLarge();
void populateOverrideLanguagesLaunchOptions(ProcessLauncher::LaunchOptions&) const;
- Vector<String> platformOverrideLanguages() const;
void platformStartConnectionTerminationWatchdog();
// Connection::Client
diff --git a/Source/WebKit/UIProcess/BackingStore.h b/Source/WebKit/UIProcess/BackingStore.h
index 15f1d5ff3973e173c1a3ee3eeb3bdf5e1ec4cd87..6516a47bc4aa788b1b1c09d21254ea9482190f6c 100644
--- a/Source/WebKit/UIProcess/BackingStore.h
+++ b/Source/WebKit/UIProcess/BackingStore.h
@@ -67,6 +67,11 @@ public:
float deviceScaleFactor() const { return m_deviceScaleFactor; }
void paint(PlatformPaintContextPtr, const WebCore::IntRect&);
+#if PLATFORM(GTK)
+ RefPtr<cairo_surface_t> surface() const { return m_surface; }
+#elif USE(SKIA)
+ sk_sp<SkSurface> surface() const { return m_surface; }
+#endif
void incorporateUpdate(UpdateInfo&&);
private:
diff --git a/Source/WebKit/UIProcess/BrowserInspectorPipe.cpp b/Source/WebKit/UIProcess/BrowserInspectorPipe.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..cfb57a48ce387b79613b757e2eb4de2c378aac30
--- /dev/null
+++ b/Source/WebKit/UIProcess/BrowserInspectorPipe.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2019 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "BrowserInspectorPipe.h"
+
+#if ENABLE(REMOTE_INSPECTOR)
+
+#include "InspectorPlaywrightAgent.h"
+#include "InspectorPlaywrightAgentClient.h"
+#include "RemoteInspectorPipe.h"
+#include "WebKit2Initialize.h"
+#include <wtf/NeverDestroyed.h>
+
+namespace WebKit {
+
+void initializeBrowserInspectorPipe(std::unique_ptr<InspectorPlaywrightAgentClient> client)
+{
+ // Initialize main loop before creating inspecor agent and pipe queues.
+ WebKit::InitializeWebKit2();
+
+ class BrowserInspectorPipe {
+ public:
+ BrowserInspectorPipe(std::unique_ptr<InspectorPlaywrightAgentClient> client)
+ : m_playwrightAgent(std::move(client))
+ , m_remoteInspectorPipe(m_playwrightAgent)
+ {
+ }
+
+ InspectorPlaywrightAgent m_playwrightAgent;
+ RemoteInspectorPipe m_remoteInspectorPipe;
+ };
+
+ static NeverDestroyed<BrowserInspectorPipe> pipe(std::move(client));
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(REMOTE_INSPECTOR)
diff --git a/Source/WebKit/UIProcess/BrowserInspectorPipe.h b/Source/WebKit/UIProcess/BrowserInspectorPipe.h
new file mode 100644
index 0000000000000000000000000000000000000000..cd66887de171cda7d15a8e4dc6dbff63665dc619
--- /dev/null
+++ b/Source/WebKit/UIProcess/BrowserInspectorPipe.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2019 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(REMOTE_INSPECTOR)
+
+namespace WebKit {
+
+class InspectorPlaywrightAgentClient;
+
+void initializeBrowserInspectorPipe(std::unique_ptr<InspectorPlaywrightAgentClient> client);
+
+} // namespace WebKit
+
+#endif // ENABLE(REMOTE_INSPECTOR)
diff --git a/Source/WebKit/UIProcess/Cocoa/SOAuthorization/NavigationSOAuthorizationSession.h b/Source/WebKit/UIProcess/Cocoa/SOAuthorization/NavigationSOAuthorizationSession.h
index 45abb108899e19cfe0cecd6716083afbff03d73c..11ced1bb2d03c949cb31435eeeee2a196928a2de 100644
--- a/Source/WebKit/UIProcess/Cocoa/SOAuthorization/NavigationSOAuthorizationSession.h
+++ b/Source/WebKit/UIProcess/Cocoa/SOAuthorization/NavigationSOAuthorizationSession.h
@@ -31,6 +31,7 @@
#include "WebViewDidMoveToWindowObserver.h"
#include <wtf/CompletionHandler.h>
#include <wtf/text/WTFString.h>
+#include <wtf/URL.h>
namespace WebKit {
diff --git a/Source/WebKit/UIProcess/Cocoa/SOAuthorization/WKSOAuthorizationDelegate.h b/Source/WebKit/UIProcess/Cocoa/SOAuthorization/WKSOAuthorizationDelegate.h
index 89d125f7742f81ead8c50f218ecb1771b8000636..baa6cf58ad502c6c033ee6293a6cc8d4ce608e7b 100644
--- a/Source/WebKit/UIProcess/Cocoa/SOAuthorization/WKSOAuthorizationDelegate.h
+++ b/Source/WebKit/UIProcess/Cocoa/SOAuthorization/WKSOAuthorizationDelegate.h
@@ -25,6 +25,7 @@
#if HAVE(APP_SSO)
+#import "SOAuthorizationSession.h"
#import <pal/cocoa/AppSSOSoftLink.h>
namespace WebKit {
diff --git a/Source/WebKit/UIProcess/Cocoa/UIDelegate.h b/Source/WebKit/UIProcess/Cocoa/UIDelegate.h
index 1c037ebba6c9cf3713e0936d4f2327d0d46a626e..e0f463694dea3aae9d8d01376ac62e75e9b0e826 100644
--- a/Source/WebKit/UIProcess/Cocoa/UIDelegate.h
+++ b/Source/WebKit/UIProcess/Cocoa/UIDelegate.h
@@ -105,6 +105,7 @@ private:
void runJavaScriptAlert(WebPageProxy&, const WTF::String&, WebFrameProxy*, FrameInfoData&&, Function<void()>&& completionHandler) final;
void runJavaScriptConfirm(WebPageProxy&, const WTF::String&, WebFrameProxy*, FrameInfoData&&, Function<void(bool)>&& completionHandler) final;
void runJavaScriptPrompt(WebPageProxy&, const WTF::String&, const WTF::String&, WebFrameProxy*, FrameInfoData&&, Function<void(const WTF::String&)>&&) final;
+ void handleJavaScriptDialog(WebKit::WebPageProxy&, bool accept, const WTF::String&) final;
void presentStorageAccessConfirmDialog(const WTF::String& requestingDomain, const WTF::String& currentDomain, CompletionHandler<void(bool)>&&);
void requestStorageAccessConfirm(WebPageProxy&, WebFrameProxy*, const WebCore::RegistrableDomain& requestingDomain, const WebCore::RegistrableDomain& currentDomain, std::optional<WebCore::OrganizationStorageAccessPromptQuirk>&&, CompletionHandler<void(bool)>&&) final;
void decidePolicyForGeolocationPermissionRequest(WebPageProxy&, WebFrameProxy&, const FrameInfoData&, Function<void(bool)>&) final;
@@ -233,6 +234,7 @@ private:
bool webViewRunJavaScriptAlertPanelWithMessageInitiatedByFrameCompletionHandler : 1;
bool webViewRunJavaScriptConfirmPanelWithMessageInitiatedByFrameCompletionHandler : 1;
bool webViewRunJavaScriptTextInputPanelWithPromptDefaultTextInitiatedByFrameCompletionHandler : 1;
+ bool webViewHandleJavaScriptDialogValue : 1;
bool webViewRequestStorageAccessPanelUnderFirstPartyCompletionHandler : 1;
bool webViewRequestStorageAccessPanelForDomainUnderCurrentDomainForQuirkDomainsCompletionHandler : 1;
bool webViewRunBeforeUnloadConfirmPanelWithMessageInitiatedByFrameCompletionHandler : 1;
diff --git a/Source/WebKit/UIProcess/Cocoa/UIDelegate.mm b/Source/WebKit/UIProcess/Cocoa/UIDelegate.mm
index c660d8204b89997bb25637ed24198acf5028e280..6d7c9102b1bc57fd179ba742cf703b1bf3eaf5af 100644
--- a/Source/WebKit/UIProcess/Cocoa/UIDelegate.mm
+++ b/Source/WebKit/UIProcess/Cocoa/UIDelegate.mm
@@ -136,6 +136,7 @@ void UIDelegate::setDelegate(id<WKUIDelegate> delegate)
m_delegateMethods.webViewRunJavaScriptAlertPanelWithMessageInitiatedByFrameCompletionHandler = [delegate respondsToSelector:@selector(webView:runJavaScriptAlertPanelWithMessage:initiatedByFrame:completionHandler:)];
m_delegateMethods.webViewRunJavaScriptConfirmPanelWithMessageInitiatedByFrameCompletionHandler = [delegate respondsToSelector:@selector(webView:runJavaScriptConfirmPanelWithMessage:initiatedByFrame:completionHandler:)];
m_delegateMethods.webViewRunJavaScriptTextInputPanelWithPromptDefaultTextInitiatedByFrameCompletionHandler = [delegate respondsToSelector:@selector(webView:runJavaScriptTextInputPanelWithPrompt:defaultText:initiatedByFrame:completionHandler:)];
+ m_delegateMethods.webViewHandleJavaScriptDialogValue = [delegate respondsToSelector:@selector(webView:handleJavaScriptDialog:value:)];
m_delegateMethods.webViewRequestStorageAccessPanelUnderFirstPartyCompletionHandler = [delegate respondsToSelector:@selector(_webView:requestStorageAccessPanelForDomain:underCurrentDomain:completionHandler:)];
m_delegateMethods.webViewRequestStorageAccessPanelForDomainUnderCurrentDomainForQuirkDomainsCompletionHandler = [delegate respondsToSelector:@selector(_webView:requestStorageAccessPanelForDomain:underCurrentDomain:forQuirkDomains:completionHandler:)];
m_delegateMethods.webViewRunBeforeUnloadConfirmPanelWithMessageInitiatedByFrameCompletionHandler = [delegate respondsToSelector:@selector(_webView:runBeforeUnloadConfirmPanelWithMessage:initiatedByFrame:completionHandler:)];
@@ -502,6 +503,15 @@ void UIDelegate::UIClient::runJavaScriptPrompt(WebPageProxy& page, const WTF::St
}).get()];
}
+void UIDelegate::UIClient::handleJavaScriptDialog(WebKit::WebPageProxy&, bool accept, const WTF::String& value) {
+ if (!m_uiDelegate->m_delegateMethods.webViewHandleJavaScriptDialogValue)
+ return;
+ auto delegate = m_uiDelegate->m_delegate.get();
+ if (!delegate)
+ return;
+ [delegate webView:m_uiDelegate->m_webView.get().get() handleJavaScriptDialog:accept value:value.createNSString().get()];
+}
+
void UIDelegate::UIClient::requestStorageAccessConfirm(WebPageProxy& webPageProxy, WebFrameProxy*, const WebCore::RegistrableDomain& requestingDomain, const WebCore::RegistrableDomain& currentDomain, std::optional<WebCore::OrganizationStorageAccessPromptQuirk>&& organizationStorageAccessPromptQuirk, CompletionHandler<void(bool)>&& completionHandler)
{
RefPtr uiDelegate = m_uiDelegate.get();
diff --git a/Source/WebKit/UIProcess/Cocoa/WebPageProxyCocoa.mm b/Source/WebKit/UIProcess/Cocoa/WebPageProxyCocoa.mm
index 177ac869fe4128bb459d2577d90f6b208e8395a2..e6ade97d800a2119d4abd9e241186915c432fd9c 100644
--- a/Source/WebKit/UIProcess/Cocoa/WebPageProxyCocoa.mm
+++ b/Source/WebKit/UIProcess/Cocoa/WebPageProxyCocoa.mm
@@ -45,7 +45,9 @@
#import "NativeWebKeyboardEvent.h"
#import "NativeWebMouseEvent.h"
#import "NavigationState.h"
+#import "NetworkProcessMessages.h"
#import "PageClient.h"
+#import "PasteboardTypes.h"
#import "PlatformXRSystem.h"
#import "PlaybackSessionManagerProxy.h"
#import "RemoteLayerTreeCommitBundle.h"
@@ -446,11 +448,85 @@ bool WebPageProxy::scrollingUpdatesDisabledForTesting()
void WebPageProxy::startDrag(const DragItem& dragItem, ShareableBitmap::Handle&& dragImageHandle, const std::optional<NodeIdentifier>& nodeID, const std::optional<FrameIdentifier>& frameID)
{
+ if (m_interceptDrags) {
+ NSPasteboard *pasteboard = [NSPasteboard pasteboardWithName: m_overrideDragPasteboardName.createNSString().get()];
+
+ m_dragSelectionData = String([pasteboard name]);
+ if (auto replyID = grantAccessToCurrentPasteboardData(String([pasteboard name]), [] () { }))
+ protect(websiteDataStore().networkProcess())->connection().waitForAsyncReplyAndDispatchImmediately<Messages::NetworkProcess::AllowFilesAccessFromWebProcess>(*replyID, 100_ms);
+ m_dragSourceOperationMask = WebCore::anyDragOperation();
+
+ if (auto& info = dragItem.promisedAttachmentInfo) {
+ auto attachment = attachmentForIdentifier(info.attachmentIdentifier);
+ if (!attachment) {
+ dragCancelled();
+ return;
+ }
+ if (!attachment->utiType().createNSString().get().length) {
+ dragCancelled();
+ return;
+ }
+
+ for (size_t index = 0; index < info.additionalTypesAndData.size(); ++index) {
+ auto nsData = info.additionalTypesAndData[index].second->createNSData();
+ [pasteboard setData:nsData.get() forType:info.additionalTypesAndData[index].first.createNSString().get()];
+ }
+ } else {
+ [pasteboard setString:@"" forType:PasteboardTypes::WebDummyPboardType];
+ }
+ didStartDrag();
+ return;
+ }
+
if (RefPtr pageClient = this->pageClient())
pageClient->startDrag(dragItem, WTF::move(dragImageHandle), nodeID, frameID);
}
-#endif
+void WebPageProxy::releaseInspectorDragPasteboard() {
+ if (!!m_dragSelectionData)
+ m_dragSelectionData = std::nullopt;
+ if (!m_overrideDragPasteboardName.isEmpty()) {
+ NSPasteboard *pasteboard = [NSPasteboard pasteboardWithUniqueName];
+ [pasteboard releaseGlobally];
+ m_overrideDragPasteboardName = ""_s;
+ }
+}
+
+
+void WebPageProxy::setInterceptDrags(bool shouldIntercept) {
+ m_interceptDrags = shouldIntercept;
+ if (m_interceptDrags) {
+ if (m_overrideDragPasteboardName.isEmpty()) {
+ NSPasteboard *pasteboard = [NSPasteboard pasteboardWithUniqueName];
+ m_overrideDragPasteboardName = String([pasteboard name]);
+ }
+ legacyMainFrameProcess().send(Messages::WebPage::SetDragPasteboardName(m_overrideDragPasteboardName), webPageIDInMainFrameProcess());
+ } else {
+ legacyMainFrameProcess().send(Messages::WebPage::SetDragPasteboardName(""_s), webPageIDInMainFrameProcess());
+ }
+}
+
+// FIXME: Move these functions to WebPageProxyIOS.mm.
+#if PLATFORM(IOS_FAMILY)
+
+void WebPageProxy::setPromisedDataForImage(const String&, const SharedMemory::Handle&, const String&, const String&, const String&, const String&, const String&, const SharedMemory::Handle&, const String&)
+{
+ notImplemented();
+}
+
+void WebPageProxy::setDragCaretRect(const IntRect& dragCaretRect)
+{
+ if (m_currentDragCaretRect == dragCaretRect)
+ return;
+
+ auto previousRect = m_currentDragCaretRect;
+ m_currentDragCaretRect = dragCaretRect;
+ pageClient()->didChangeDragCaretRect(previousRect, dragCaretRect);
+}
+
+#endif // PLATFORM(IOS_FAMILY)
+
+#endif // ENABLE(DRAG_SUPPORT)
#if ENABLE(ATTACHMENT_ELEMENT)
diff --git a/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm b/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm
index 4b43164f215ca8e72a68252f36862e25b2742ea8..0804791f8ef0174b905cb18851962f04b43151e4 100644
--- a/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm
+++ b/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm
@@ -451,7 +451,7 @@ ALLOW_DEPRECATED_DECLARATIONS_END
auto screenProperties = WebCore::collectScreenProperties();
parameters.screenProperties = WTF::move(screenProperties);
#if PLATFORM(MAC)
- parameters.useOverlayScrollbars = ([NSScroller preferredScrollerStyle] == NSScrollerStyleOverlay);
+ parameters.useOverlayScrollbars = m_configuration->forceOverlayScrollbars() || ([NSScroller preferredScrollerStyle] == NSScrollerStyleOverlay);
#endif
#if PLATFORM(VISION)
@@ -864,8 +864,8 @@ void WebProcessPool::registerNotificationObservers()
}];
m_scrollerStyleNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:NSPreferredScrollerStyleDidChangeNotification object:nil queue:[NSOperationQueue currentQueue] usingBlock:^(NSNotification *notification) {
- auto scrollbarStyle = [NSScroller preferredScrollerStyle];
- sendToAllProcesses(Messages::WebProcess::ScrollerStylePreferenceChanged(scrollbarStyle));
+ bool useOverlayScrollbars = m_configuration->forceOverlayScrollbars() || ([NSScroller preferredScrollerStyle] == NSScrollerStyleOverlay);
+ sendToAllProcesses(Messages::WebProcess::ScrollerStylePreferenceChanged(useOverlayScrollbars));
}];
m_activationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:NSApplicationDidBecomeActiveNotification object:NSAppSingleton() queue:[NSOperationQueue currentQueue] usingBlock:^(NSNotification *notification) {
diff --git a/Source/WebKit/UIProcess/CoordinatedGraphics/DrawingAreaProxyCoordinatedGraphics.cpp b/Source/WebKit/UIProcess/CoordinatedGraphics/DrawingAreaProxyCoordinatedGraphics.cpp
index be40fa0e3e3e8698c29f70a2b8dac324225aba97..4e6cc206ed0a25914d8df604f61746562fd9c976 100644
--- a/Source/WebKit/UIProcess/CoordinatedGraphics/DrawingAreaProxyCoordinatedGraphics.cpp
+++ b/Source/WebKit/UIProcess/CoordinatedGraphics/DrawingAreaProxyCoordinatedGraphics.cpp
@@ -33,6 +33,7 @@
#include "LayerTreeContext.h"
#include "MessageSenderInlines.h"
#include "UpdateInfo.h"
+#include "WebPageInspectorController.h"
#include "WebPageProxy.h"
#include "WebPreferences.h"
#include "WebProcessPool.h"
@@ -40,6 +41,15 @@
#include <WebCore/Region.h>
#include <optional>
#include <wtf/TZoneMallocInlines.h>
+#include <wtf/Vector.h>
+
+#if PLATFORM(GTK)
+#include "WebKitWebViewBasePrivate.h"
+#include <cairo.h>
+#include <skia/core/SkImage.h>
+#include <skia/core/SkSurface.h>
+#include <skia/core/SkCanvas.h>
+#endif
#if USE(GLIB_EVENT_LOOP)
#include <wtf/glib/RunLoopSourcePriority.h>
@@ -175,6 +185,11 @@ void DrawingAreaProxyCoordinatedGraphics::deviceScaleFactorDidChange(CompletionH
sendWithAsyncReply(Messages::DrawingArea::SetDeviceScaleFactor(page()->deviceScaleFactor()), WTF::move(completionHandler));
}
+void DrawingAreaProxyCoordinatedGraphics::waitForSizeUpdate(Function<void (const DrawingAreaProxyCoordinatedGraphics&)>&& callback)
+{
+ m_callbacks.append(WTF::move(callback));
+}
+
void DrawingAreaProxyCoordinatedGraphics::setBackingStoreIsDiscardable(bool isBackingStoreDiscardable)
{
#if !PLATFORM(WPE) && !PLATFORM(GTK)
@@ -234,6 +249,54 @@ void DrawingAreaProxyCoordinatedGraphics::updateAcceleratedCompositingMode(uint6
updateAcceleratedCompositingMode(layerTreeContext);
}
+#if PLATFORM(GTK)
+void DrawingAreaProxyCoordinatedGraphics::captureFrame()
+{
+ RefPtr<cairo_surface_t> surface;
+ if (isInAcceleratedCompositingMode()) {
+ AcceleratedBackingStore* backingStore = webkitWebViewBaseGetAcceleratedBackingStore(WEBKIT_WEB_VIEW_BASE(protect(page())->viewWidget()));
+ if (!backingStore)
+ return;
+
+ surface = backingStore->surface();
+ }
+
+ if (!surface)
+ return;
+
+ if (cairo_surface_get_type(surface.get()) != CAIRO_SURFACE_TYPE_IMAGE)
+ return;
+
+ // The original surface is upside down, so we flip it to match orientation in other accelerated backing stores.
+ auto flippedSurface = adoptRef(cairo_image_surface_create(CAIRO_FORMAT_ARGB32, cairo_image_surface_get_width(surface.get()), cairo_image_surface_get_height(surface.get())));
+ {
+ RefPtr<cairo_t> cr = adoptRef(cairo_create(flippedSurface.get()));
+ cairo_matrix_t transform;
+ cairo_matrix_init(&transform, 1, 0, 0, -1, 0, cairo_image_surface_get_height(surface.get()));
+ cairo_transform(cr.get(), &transform);
+ cairo_set_source_surface(cr.get(), surface.get(), 0, 0);
+ cairo_paint(cr.get());
+ }
+ cairo_surface_flush(flippedSurface.get());
+
+ unsigned char* data = cairo_image_surface_get_data(flippedSurface.get());
+ int width = cairo_image_surface_get_width(flippedSurface.get());
+ int height = cairo_image_surface_get_height(flippedSurface.get());
+ int stride = cairo_image_surface_get_stride(flippedSurface.get());
+
+ SkImageInfo info = SkImageInfo::Make(
+ width, height,
+ kBGRA_8888_SkColorType, // matches CAIRO_FORMAT_ARGB32 on LE
+ kPremul_SkAlphaType
+ );
+ sk_sp<SkImage> skImage = SkImages::RasterFromData(info, SkData::MakeWithCopy(data, height * stride), stride);
+ if (!skImage)
+ return;
+
+ protect(page())->inspectorController().didPaint(WTF::move(skImage));
+}
+#endif // PLATFORM(GTK)
+
bool DrawingAreaProxyCoordinatedGraphics::alwaysUseCompositing() const
{
if (!page())
@@ -301,6 +364,12 @@ void DrawingAreaProxyCoordinatedGraphics::didUpdateGeometry()
// we need to resend the new size here.
if (m_lastSentSize != size())
sendUpdateGeometry();
+ else {
+ Vector<Function<void (const DrawingAreaProxyCoordinatedGraphics&)>> callbacks;
+ callbacks.swap(m_callbacks);
+ for (auto& cb : callbacks)
+ cb(*this);
+ }
}
#if !PLATFORM(WPE) && !PLATFORM(GTK)
diff --git a/Source/WebKit/UIProcess/CoordinatedGraphics/DrawingAreaProxyCoordinatedGraphics.h b/Source/WebKit/UIProcess/CoordinatedGraphics/DrawingAreaProxyCoordinatedGraphics.h
index 99a1c243ee534edf127f6f932e4d05cb65676528..d880229ef91bfd33e37b5065976fbe3c7f6dc443 100644
--- a/Source/WebKit/UIProcess/CoordinatedGraphics/DrawingAreaProxyCoordinatedGraphics.h
+++ b/Source/WebKit/UIProcess/CoordinatedGraphics/DrawingAreaProxyCoordinatedGraphics.h
@@ -29,6 +29,7 @@
#include "DrawingAreaProxy.h"
#include "LayerTreeContext.h"
+#include <wtf/Function.h>
#include <wtf/RefCounted.h>
#include <wtf/RunLoop.h>
#include <wtf/TZoneMalloc.h>
@@ -60,6 +61,10 @@ public:
bool isInAcceleratedCompositingMode() const { return !m_layerTreeContext.isEmpty(); }
const LayerTreeContext& layerTreeContext() const LIFETIME_BOUND { return m_layerTreeContext; }
+ void waitForSizeUpdate(Function<void (const DrawingAreaProxyCoordinatedGraphics&)>&&);
+#if !PLATFORM(WPE)
+ void captureFrame();
+#endif
void dispatchAfterEnsuringDrawing(CompletionHandler<void()>&&);
@@ -131,6 +136,7 @@ private:
// The last size we sent to the web process.
WebCore::IntSize m_lastSentSize;
+ Vector<Function<void (const DrawingAreaProxyCoordinatedGraphics&)>> m_callbacks;
#if !PLATFORM(WPE) && !PLATFORM(GTK)
bool m_isBackingStoreDiscardable { true };
diff --git a/Source/WebKit/UIProcess/Downloads/DownloadProxy.cpp b/Source/WebKit/UIProcess/Downloads/DownloadProxy.cpp
index 6537111d8f973509b072b3ec0da911d9c1d24f1d..206023b88f3bb0f7b14bcc7600679bce11a9053a 100644
--- a/Source/WebKit/UIProcess/Downloads/DownloadProxy.cpp
+++ b/Source/WebKit/UIProcess/Downloads/DownloadProxy.cpp
@@ -41,8 +41,10 @@
#include <WebCore/MIMETypeRegistry.h>
#include <WebCore/ResourceResponseBase.h>
#include <wtf/FileSystem.h>
+#include <wtf/NeverDestroyed.h>
#include <wtf/text/CString.h>
#include <wtf/text/WTFString.h>
+#include <wtf/UUID.h>
#if PLATFORM(MAC)
#include <pal/spi/mac/QuarantineSPI.h>
@@ -66,7 +68,10 @@ DownloadProxy::DownloadProxy(DownloadProxyMap& downloadProxyMap, WebsiteDataStor
#if HAVE(MODERN_DOWNLOADPROGRESS)
, m_assertion(ProcessAssertion::create(getCurrentProcessID(), "WebKit DownloadProxy DecideDestination"_s, ProcessAssertionType::FinishTaskInterruptable))
#endif
+ , m_uuid(createVersion4UUIDString())
{
+ if (auto* instrumentation = m_dataStore->downloadInstrumentation())
+ instrumentation->downloadCreated(m_uuid, m_request, m_frameInfo->frameInfoData(), originatingPage, this);
}
DownloadProxy::~DownloadProxy()
@@ -86,12 +91,15 @@ void DownloadProxy::cancel(CompletionHandler<void(API::Data*)>&& completionHandl
{
m_downloadIsCancelled = true;
if (m_dataStore) {
- protect(protect(m_dataStore)->networkProcess())->sendWithAsyncReply(Messages::NetworkProcess::CancelDownload(m_downloadID), [weakThis = WeakPtr { *this }, completionHandler = WTF::move(completionHandler)] (std::span<const uint8_t> resumeData) mutable {
+ auto* instrumentation = m_dataStore->downloadInstrumentation();
+ protect(protect(m_dataStore)->networkProcess())->sendWithAsyncReply(Messages::NetworkProcess::CancelDownload(m_downloadID), [weakThis = WeakPtr { *this }, completionHandler = WTF::move(completionHandler), instrumentation] (std::span<const uint8_t> resumeData) mutable {
RefPtr protectedThis = weakThis.get();
if (!protectedThis)
return completionHandler(nullptr);
protectedThis->m_legacyResumeData = createData(resumeData);
completionHandler(protectedThis->m_legacyResumeData.get());
+ if (instrumentation)
+ instrumentation->downloadFinished(protectedThis->m_uuid, "canceled"_s);
if (RefPtr downloadProxyMap = protectedThis->m_downloadProxyMap.get())
downloadProxyMap->downloadFinished(*protectedThis);
});
@@ -182,6 +190,35 @@ void DownloadProxy::decideDestinationWithSuggestedFilename(const WebCore::Resour
else
suggestedFilename = MIMETypeRegistry::appendFileExtensionIfNecessary(suggestedFilename, response.mimeType());
+ if (auto* instrumentation = m_dataStore->downloadInstrumentation())
+ instrumentation->downloadFilenameSuggested(m_uuid, suggestedFilename);
+
+ if (m_dataStore->allowDownloadForAutomation()) {
+ SandboxExtension::Handle sandboxExtensionHandle;
+ String destination;
+ if (*m_dataStore->allowDownloadForAutomation()) {
+ auto downloadPath = m_dataStore->downloadPathForAutomation();
+ FileSystem::makeAllDirectories(downloadPath);
+ destination = FileSystem::pathByAppendingComponent(downloadPath, m_uuid);
+ if (auto handle = SandboxExtension::createHandle(destination, SandboxExtension::Type::ReadWrite))
+ sandboxExtensionHandle = WTF::move(*handle);
+ }
+ m_client->decidePlaceholderPolicy(*this, [completionHandler = WTF::move(completionHandler), destination = WTF::move(destination), sandboxExtensionHandle = WTF::move(sandboxExtensionHandle)] (WebKit::UseDownloadPlaceholder usePlaceholder, const URL& url) mutable {
+ SandboxExtension::Handle placeHolderSandboxExtensionHandle;
+ Vector<uint8_t> bookmarkData;
+ Vector<uint8_t> activityTokenData;
+#if HAVE(MODERN_DOWNLOADPROGRESS)
+ bookmarkData = bookmarkDataForURL(url);
+ activityTokenData = activityAccessToken();
+#else
+ if (auto handle = SandboxExtension::createHandle(url.fileSystemPath(), SandboxExtension::Type::ReadWrite))
+ placeHolderSandboxExtensionHandle = WTF::move(*handle);
+#endif
+ completionHandler(destination, WTF::move(sandboxExtensionHandle), AllowOverwrite::Yes, WebKit::UseDownloadPlaceholder::No, url, WTF::move(placeHolderSandboxExtensionHandle), bookmarkData.span(), activityTokenData.span());
+ });
+ return;
+ }
+
protect(client())->decideDestinationWithSuggestedFilename(*this, response, ResourceResponseBase::sanitizeSuggestedFilename(suggestedFilename), [this, protectedThis = Ref { *this }, completionHandler = WTF::move(completionHandler)] (AllowOverwrite allowOverwrite, String destination) mutable {
SandboxExtension::Handle sandboxExtensionHandle;
if (!destination.isNull()) {
@@ -246,6 +283,8 @@ void DownloadProxy::didFinish()
protect(client())->didFinish(*this);
if (m_downloadIsCancelled)
return;
+ if (auto* instrumentation = m_dataStore->downloadInstrumentation())
+ instrumentation->downloadFinished(m_uuid, String());
// This can cause the DownloadProxy object to be deleted.
if (RefPtr downloadProxyMap = m_downloadProxyMap.get())
@@ -260,6 +299,8 @@ void DownloadProxy::didFail(const ResourceError& error, std::span<const uint8_t>
m_legacyResumeData = createData(resumeData);
protect(client())->didFail(*this, error, m_legacyResumeData.get());
+ if (auto* instrumentation = m_dataStore->downloadInstrumentation())
+ instrumentation->downloadFinished(m_uuid, error.localizedDescription());
// This can cause the DownloadProxy object to be deleted.
if (RefPtr downloadProxyMap = m_downloadProxyMap.get())
diff --git a/Source/WebKit/UIProcess/Downloads/DownloadProxy.h b/Source/WebKit/UIProcess/Downloads/DownloadProxy.h
index be567b89bb406f0ee0df005c83b186cb956025ae..16342e90dcbf94325b8fac5f4c877c5fd372f673 100644
--- a/Source/WebKit/UIProcess/Downloads/DownloadProxy.h
+++ b/Source/WebKit/UIProcess/Downloads/DownloadProxy.h
@@ -168,6 +168,7 @@ private:
#if HAVE(MODERN_DOWNLOADPROGRESS)
RefPtr<ProcessAssertion> m_assertion;
#endif
+ String m_uuid;
};
} // namespace WebKit
diff --git a/Source/WebKit/UIProcess/DrawingAreaProxy.h b/Source/WebKit/UIProcess/DrawingAreaProxy.h
index 546c51f13212c98bf9a26bf1ee804c74d75f241e..e681ec646dd033ade64bae6eabdc472e9e0b8c6a 100644
--- a/Source/WebKit/UIProcess/DrawingAreaProxy.h
+++ b/Source/WebKit/UIProcess/DrawingAreaProxy.h
@@ -96,6 +96,7 @@ public:
const WebCore::IntSize& size() const LIFETIME_BOUND { return m_size; }
bool setSize(const WebCore::IntSize&, const WebCore::IntSize& scrollOffset = { });
+ void waitForSizeUpdate(Function<void ()>&&);
virtual void minimumSizeForAutoLayoutDidChange() { }
virtual void sizeToContentAutoSizeMaximumSizeDidChange() { }
diff --git a/Source/WebKit/UIProcess/Inspector/Agents/InspectorScreencastAgent.cpp b/Source/WebKit/UIProcess/Inspector/Agents/InspectorScreencastAgent.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6a89043bb0b8f6a22ee9af2b271de34989e6a5c1
--- /dev/null
+++ b/Source/WebKit/UIProcess/Inspector/Agents/InspectorScreencastAgent.cpp
@@ -0,0 +1,294 @@
+/*
+ * Copyright (C) 2020 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "InspectorScreencastAgent.h"
+
+#include "PageClient.h"
+#include "WebPageInspectorController.h"
+#include "WebPageProxy.h"
+#include "WebsiteDataStore.h"
+#include <pal/crypto/CryptoDigest.h>
+#include <JavaScriptCore/InspectorFrontendRouter.h>
+#include <WebCore/NotImplemented.h>
+#include <wtf/Compiler.h>
+#include <wtf/RunLoop.h>
+#include <wtf/UUID.h>
+#include <wtf/text/Base64.h>
+
+#if USE(SKIA)
+#include "DrawingAreaProxyCoordinatedGraphics.h"
+#include "DrawingAreaProxy.h"
+#include <skia/core/SkBitmap.h>
+#include <skia/core/SkCanvas.h>
+#include <skia/core/SkImage.h>
+#include <skia/core/SkPixmap.h>
+#include <skia/core/SkData.h>
+#include <skia/core/SkStream.h>
+#include <skia/encode/SkJpegEncoder.h>
+#endif
+
+#if PLATFORM(MAC)
+#include <WebCore/ImageUtilities.h>
+#endif
+
+#if PLATFORM(WIN)
+#include "DrawingAreaProxyWC.h"
+#endif
+
+WTF_ALLOW_UNSAFE_BUFFER_USAGE_BEGIN
+
+namespace WebKit {
+
+const int kMaxFramesInFlight = 1;
+
+using namespace Inspector;
+
+WTF_MAKE_TZONE_ALLOCATED_IMPL(InspectorScreencastAgent);
+
+InspectorScreencastAgent::InspectorScreencastAgent(BackendDispatcher& backendDispatcher, Inspector::FrontendRouter& frontendRouter, WebPageProxy& page)
+ : InspectorAgentBase("Screencast"_s)
+ , m_frontendDispatcher(makeUnique<ScreencastFrontendDispatcher>(frontendRouter))
+ , m_backendDispatcher(ScreencastBackendDispatcher::create(backendDispatcher, this))
+ , m_page(page)
+{
+}
+
+InspectorScreencastAgent::~InspectorScreencastAgent()
+{
+}
+
+void InspectorScreencastAgent::didCreateFrontendAndBackend()
+{
+}
+
+void InspectorScreencastAgent::willDestroyFrontendAndBackend(DisconnectReason)
+{
+}
+
+#if USE(SKIA)
+void InspectorScreencastAgent::didPaint(sk_sp<SkImage>&& surface)
+{
+ if (!m_screencast)
+ return;
+
+ if (m_screencastFramesInFlight > kMaxFramesInFlight)
+ return;
+
+ MonotonicTime timestamp = MonotonicTime::now();
+ sk_sp<SkImage> image(surface);
+
+ // Get actual image size (in device pixels).
+ WebCore::IntSize displaySize(image->width(), image->height());
+ WebCore::IntSize drawingAreaSize = m_page.drawingArea()->size();
+ drawingAreaSize.scale(m_page.deviceScaleFactor());
+ if (drawingAreaSize != displaySize)
+ return;
+
+ {
+ SkPixmap pixmap;
+ if (!image->peekPixels(&pixmap)) {
+ fprintf(stderr, "Failed to peek pixels from SkImage to compute hash\n");
+ return;
+ }
+ // Do not send the same frame over and over.
+ size_t len = pixmap.computeByteSize();
+ auto cryptoDigest = PAL::Crypto::CryptoDigest::create(PAL::Crypto::CryptoDigest::Algorithm::SHA_1);
+ cryptoDigest->addBytes(std::span(reinterpret_cast<const unsigned char*>(pixmap.addr()), len));
+ auto digest = cryptoDigest->computeHash();
+ if (m_lastFrameDigest == digest)
+ return;
+ m_lastFrameDigest = digest;
+ }
+
+ // Scale image to fit width / height
+ double scale = std::min(m_screencastWidth / displaySize.width(), m_screencastHeight / displaySize.height());
+ if (scale < 1) {
+ SkBitmap dstBitmap;
+ dstBitmap.allocPixels(SkImageInfo::MakeN32Premul(displaySize.width() * scale, displaySize.height() * scale));
+ SkCanvas canvas(dstBitmap);
+ canvas.scale(scale, scale);
+ canvas.drawImage(image, 0, 0);
+ image = dstBitmap.asImage();
+ }
+
+ SkPixmap pixmap;
+ if (!image->peekPixels(&pixmap)) {
+ fprintf(stderr, "Failed to peek pixels from SkImage for JPEG encoding\n");
+ return;
+ }
+
+ SkJpegEncoder::Options options;
+ options.fQuality = 90;
+ SkDynamicMemoryWStream stream;
+ if (!SkJpegEncoder::Encode(&stream, pixmap, options)) {
+ fprintf(stderr, "Failed to encode image to JPEG\n");
+ return;
+ }
+ sk_sp<SkData> jpegData = stream.detachAsData();
+ String result = base64EncodeToString(std::span(reinterpret_cast<const unsigned char*>(jpegData->data()), jpegData->size()));
+ ++m_screencastFramesInFlight;
+ m_frontendDispatcher->screencastFrame(result, timestamp.secondsSinceEpoch().value(), displaySize.width(), displaySize.height());
+}
+#endif
+
+Inspector::Protocol::ErrorStringOr<int /* generation */> InspectorScreencastAgent::startScreencast(int width, int height, int toolbarHeight, int quality)
+{
+ if (m_screencast)
+ return makeUnexpected("Already screencasting"_s);
+
+ m_screencast = true;
+ m_screencastWidth = width;
+ m_screencastHeight = height;
+ m_screencastQuality = quality;
+ m_screencastToolbarHeight = toolbarHeight;
+ ++m_screencastGeneration;
+ kickFramesStarted();
+ return m_screencastGeneration;
+}
+
+Inspector::Protocol::ErrorStringOr<void> InspectorScreencastAgent::screencastFrameAck(int generation)
+{
+ if (!m_screencast)
+ return makeUnexpected("Not screencasting"_s);
+
+ if (m_screencastGeneration != generation)
+ return { };
+
+ --m_screencastFramesInFlight;
+ return { };
+}
+
+Inspector::Protocol::ErrorStringOr<void> InspectorScreencastAgent::stopScreencast()
+{
+ if (!m_screencast)
+ return makeUnexpected("Not screencasting"_s);
+
+ m_screencast = false;
+ m_framesAreGoing = false;
+ m_screencastFramesInFlight = 0;
+ m_lastFrameDigest.clear();
+ return { };
+}
+
+void InspectorScreencastAgent::kickFramesStarted()
+{
+ if (!m_framesAreGoing) {
+ m_framesAreGoing = true;
+#if !PLATFORM(WPE)
+ scheduleFrameEncoding();
+#endif
+ }
+ m_page.updateRenderingWithForcedRepaint([] { });
+}
+
+#if !PLATFORM(WPE)
+void InspectorScreencastAgent::scheduleFrameEncoding()
+{
+ if (!m_screencast)
+ return;
+
+ const int fps = 25;
+ RunLoop::mainSingleton().dispatchAfter(Seconds(1.0 / fps), [agent = WeakPtr { this }]() mutable {
+ if (!agent)
+ return;
+ if (!agent->m_page.hasPageClient())
+ return;
+
+ agent->encodeFrame();
+ agent->scheduleFrameEncoding();
+ });
+}
+#endif
+
+#if PLATFORM(MAC)
+void InspectorScreencastAgent::encodeFrame()
+{
+ if (!m_screencast)
+ return;
+
+ RetainPtr<CGImageRef> imageRef = m_page.pageClient()->takeSnapshotForAutomation();
+ if (m_screencast && m_screencastFramesInFlight <= kMaxFramesInFlight) {
+ MonotonicTime timestamp = MonotonicTime::now();
+ CGImage* imagePtr = imageRef.get();
+ WebCore::IntSize imageSize(CGImageGetWidth(imagePtr), CGImageGetHeight(imagePtr));
+ WebCore::IntSize displaySize = imageSize;
+ displaySize.contract(0, m_screencastToolbarHeight);
+ double scale = std::min(m_screencastWidth / displaySize.width(), m_screencastHeight / displaySize.height());
+ RetainPtr<CGImageRef> transformedImageRef;
+ if (scale < 1 || m_screencastToolbarHeight) {
+ WebCore::IntSize screencastSize = displaySize;
+ WebCore::IntSize scaledImageSize = imageSize;
+ if (scale < 1) {
+ screencastSize.scale(scale);
+ scaledImageSize.scale(scale);
+ }
+ auto colorSpace = adoptCF(CGColorSpaceCreateDeviceRGB());
+ auto context = adoptCF(CGBitmapContextCreate(nullptr, screencastSize.width(), screencastSize.height(), 8, 4 * screencastSize.width(), colorSpace.get(), (CGBitmapInfo)kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host));
+ CGContextDrawImage(context.get(), CGRectMake(0, 0, scaledImageSize.width(), scaledImageSize.height()), imagePtr);
+ transformedImageRef = adoptCF(CGBitmapContextCreateImage(context.get()));
+ imagePtr = transformedImageRef.get();
+ }
+ auto data = WebCore::encodeData(imagePtr, "image/jpeg"_s, m_screencastQuality * 0.1);
+
+ // Do not send the same frame over and over.
+ auto cryptoDigest = PAL::Crypto::CryptoDigest::create(PAL::Crypto::CryptoDigest::Algorithm::SHA_1);
+ cryptoDigest->addBytes(std::span(data.mutableSpan().data(), data.size()));
+ auto digest = cryptoDigest->computeHash();
+ if (m_lastFrameDigest != digest) {
+ String base64Data = base64EncodeToString(data);
+ ++m_screencastFramesInFlight;
+ m_frontendDispatcher->screencastFrame(base64Data, timestamp.secondsSinceEpoch().value(), displaySize.width(), displaySize.height());
+ m_lastFrameDigest = digest;
+ }
+ }
+}
+#endif
+
+#if PLATFORM(GTK)
+void InspectorScreencastAgent::encodeFrame()
+{
+ if (!m_screencast)
+ return;
+
+ if (auto* drawingArea = m_page.drawingArea())
+ static_cast<DrawingAreaProxyCoordinatedGraphics*>(drawingArea)->captureFrame();
+}
+#endif
+
+#if PLATFORM(WIN)
+void InspectorScreencastAgent::encodeFrame()
+{
+ if (!m_screencast)
+ return;
+
+ if (auto* drawingArea = m_page.drawingArea())
+ static_cast<DrawingAreaProxyWC*>(drawingArea)->captureFrame();
+}
+#endif
+
+} // namespace WebKit
+
+WTF_ALLOW_UNSAFE_BUFFER_USAGE_END
diff --git a/Source/WebKit/UIProcess/Inspector/Agents/InspectorScreencastAgent.h b/Source/WebKit/UIProcess/Inspector/Agents/InspectorScreencastAgent.h
new file mode 100644
index 0000000000000000000000000000000000000000..afadd2371dffab9d4b92e4245f5622828c8fded1
--- /dev/null
+++ b/Source/WebKit/UIProcess/Inspector/Agents/InspectorScreencastAgent.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2020 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <JavaScriptCore/InspectorAgentBase.h>
+#include <JavaScriptCore/InspectorBackendDispatchers.h>
+#include <JavaScriptCore/InspectorFrontendDispatchers.h>
+
+#include <wtf/Forward.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/WeakPtr.h>
+
+#if USE(SKIA)
+#include <skia/core/SkImage.h>
+#endif
+
+namespace Inspector {
+class BackendDispatcher;
+class FrontendChannel;
+class FrontendRouter;
+class ScreencastFrontendDispatcher;
+}
+
+namespace WebKit {
+class InspectorScreencastAgent;
+}
+
+namespace WTF {
+template<typename T> struct IsDeprecatedWeakRefSmartPointerException;
+template<> struct IsDeprecatedWeakRefSmartPointerException<WebKit::InspectorScreencastAgent> : std::true_type { };
+}
+
+namespace WebKit {
+
+class WebPageProxy;
+
+class InspectorScreencastAgent : public Inspector::InspectorAgentBase, public Inspector::ScreencastBackendDispatcherHandler, public CanMakeWeakPtr<InspectorScreencastAgent> {
+ WTF_MAKE_NONCOPYABLE(InspectorScreencastAgent);
+ WTF_MAKE_TZONE_ALLOCATED(InspectorScreencastAgent);
+public:
+ InspectorScreencastAgent(Inspector::BackendDispatcher& backendDispatcher, Inspector::FrontendRouter& frontendRouter, WebPageProxy& page);
+ ~InspectorScreencastAgent() override;
+
+ void didCreateFrontendAndBackend() override;
+ void willDestroyFrontendAndBackend(Inspector::DisconnectReason) override;
+
+#if USE(SKIA)
+ void didPaint(sk_sp<SkImage>&& surface);
+#endif
+
+ Inspector::Protocol::ErrorStringOr<int /* generation */> startScreencast(int width, int height, int toolbarHeight, int quality) override;
+ Inspector::Protocol::ErrorStringOr<void> screencastFrameAck(int generation) override;
+ Inspector::Protocol::ErrorStringOr<void> stopScreencast() override;
+
+private:
+#if !PLATFORM(WPE)
+ void scheduleFrameEncoding();
+ void encodeFrame();
+#endif
+
+ void kickFramesStarted();
+
+ std::unique_ptr<Inspector::ScreencastFrontendDispatcher> m_frontendDispatcher;
+ Ref<Inspector::ScreencastBackendDispatcher> m_backendDispatcher;
+ WebPageProxy& m_page;
+ Vector<uint8_t> m_lastFrameDigest;
+ bool m_screencast = false;
+ bool m_framesAreGoing = false;
+ double m_screencastWidth = 0;
+ double m_screencastHeight = 0;
+ int m_screencastQuality = 0;
+ int m_screencastToolbarHeight = 0;
+ int m_screencastGeneration = 0;
+ int m_screencastFramesInFlight = 0;
+};
+
+} // namespace WebKit
diff --git a/Source/WebKit/UIProcess/Inspector/PageInspectorTargetProxy.cpp b/Source/WebKit/UIProcess/Inspector/PageInspectorTargetProxy.cpp
index 66e1ddd0ad468d7e9d262442ad0efdbcf7989ea1..28c0a0f7b7edaaf7f30c677594365a436344512d 100644
--- a/Source/WebKit/UIProcess/Inspector/PageInspectorTargetProxy.cpp
+++ b/Source/WebKit/UIProcess/Inspector/PageInspectorTargetProxy.cpp
@@ -59,6 +59,11 @@ std::unique_ptr<PageInspectorTargetProxy> PageInspectorTargetProxy::create(Provi
return target;
}
+std::unique_ptr<PageInspectorTargetProxy> PageInspectorTargetProxy::create(ProvisionalPageProxy& provisionalPage, const String& targetId)
+{
+ return PageInspectorTargetProxy::create(provisionalPage, targetId, Inspector::InspectorTargetType::Page);
+}
+
PageInspectorTargetProxy::PageInspectorTargetProxy(WebPageProxy& page, const String& targetId, Inspector::InspectorTargetType type)
: InspectorTargetProxy(targetId, type)
, m_page(page)
@@ -109,6 +114,31 @@ void PageInspectorTargetProxy::didCommitProvisionalTarget()
m_provisionalPage = nullptr;
}
+void PageInspectorTargetProxy::willResume()
+{
+ if (m_page->hasRunningProcess())
+ m_page->legacyMainFrameProcess().send(Messages::WebPage::ResumeInspectorIfPausedInNewWindow(), m_page->webPageIDInMainFrameProcess());
+}
+
+void PageInspectorTargetProxy::activate(String& error)
+{
+ if (type() != Inspector::InspectorTargetType::Page)
+ return InspectorTarget::activate(error);
+
+ platformActivate(error);
+}
+
+void PageInspectorTargetProxy::close(String& error, bool runBeforeUnload)
+{
+ if (type() != Inspector::InspectorTargetType::Page)
+ return InspectorTarget::close(error, runBeforeUnload);
+
+ if (runBeforeUnload)
+ m_page->tryClose();
+ else
+ m_page->closePage();
+}
+
bool PageInspectorTargetProxy::isProvisional() const
{
return !!m_provisionalPage;
diff --git a/Source/WebKit/UIProcess/Inspector/PageInspectorTargetProxy.h b/Source/WebKit/UIProcess/Inspector/PageInspectorTargetProxy.h
index 88fe6b2104c5e26cee4a975a552e8a2c78f44129..96631d61f1a043d09769098849c4d91ad2cf6b21 100644
--- a/Source/WebKit/UIProcess/Inspector/PageInspectorTargetProxy.h
+++ b/Source/WebKit/UIProcess/Inspector/PageInspectorTargetProxy.h
@@ -44,6 +44,7 @@ class PageInspectorTargetProxy final : public InspectorTargetProxy {
public:
static std::unique_ptr<PageInspectorTargetProxy> create(WebPageProxy&, const String& targetId, Inspector::InspectorTargetType);
static std::unique_ptr<PageInspectorTargetProxy> create(ProvisionalPageProxy&, const String& targetId, Inspector::InspectorTargetType);
+ static std::unique_ptr<PageInspectorTargetProxy> create(ProvisionalPageProxy&, const String& targetId);
PageInspectorTargetProxy(WebPageProxy&, const String& targetId, Inspector::InspectorTargetType);
void didCommitProvisionalTarget() override;
@@ -52,8 +53,13 @@ public:
void connect(Inspector::FrontendChannel::ConnectionType) override;
void disconnect() override;
void sendMessageToTargetBackend(const String&) override;
+ void activate(String& error) override;
+ void close(String& error, bool runBeforeUnload) override;
private:
+ void willResume() override;
+ void platformActivate(String& error) const;
+
WeakRef<WebPageProxy> m_page;
WeakPtr<ProvisionalPageProxy> m_provisionalPage;
};
diff --git a/Source/WebKit/UIProcess/Inspector/WasmDebuggerDebuggable.cpp b/Source/WebKit/UIProcess/Inspector/WasmDebuggerDebuggable.cpp
index 232b5dc1c574e4d4231307fee144aff59b519758..651fc7fe63d80cf093192e4eec1576c7621201e1 100644
--- a/Source/WebKit/UIProcess/Inspector/WasmDebuggerDebuggable.cpp
+++ b/Source/WebKit/UIProcess/Inspector/WasmDebuggerDebuggable.cpp
@@ -28,6 +28,7 @@
#if ENABLE(WEBASSEMBLY_DEBUGGER) && ENABLE(REMOTE_INSPECTOR)
+#include "WebPageProxy.h"
#include "WebProcessProxy.h"
#include "WebProcessProxyMessages.h"
#include <JavaScriptCore/InspectorFrontendChannel.h>
diff --git a/Source/WebKit/UIProcess/Inspector/WebPageInspectorController.cpp b/Source/WebKit/UIProcess/Inspector/WebPageInspectorController.cpp
index 13da6142d0889583d399b4ee9ead9a6850b700b2..626f87341d5eb3d7192d4c80621e84bf9181940f 100644
--- a/Source/WebKit/UIProcess/Inspector/WebPageInspectorController.cpp
+++ b/Source/WebKit/UIProcess/Inspector/WebPageInspectorController.cpp
@@ -26,19 +26,27 @@
#include "config.h"
#include "WebPageInspectorController.h"
+#include "APINavigation.h"
+#include "APIPageConfiguration.h"
#include "APIUIClient.h"
#include "FrameInspectorTarget.h"
#include "FrameInspectorTargetProxy.h"
#include "InspectorBrowserAgent.h"
+#include "InspectorDialogAgent.h"
+#include "InspectorScreencastAgent.h"
#include "PageInspectorTarget.h"
#include "PageInspectorTargetProxy.h"
#include "ProvisionalFrameProxy.h"
#include "ProvisionalPageProxy.h"
#include "WebFrameProxy.h"
#include "WebPageInspectorAgentBase.h"
+#include "WebPageInspectorEmulationAgent.h"
+#include "WebPageInspectorInputAgent.h"
#include "WebPageProxy.h"
#include "WebProcessProxy.h"
#include "WebsiteDataStore.h"
+#include <WebCore/ResourceError.h>
+#include <WebCore/WindowFeatures.h>
#include <JavaScriptCore/InspectorAgentBase.h>
#include <JavaScriptCore/InspectorBackendDispatcher.h>
#include <JavaScriptCore/InspectorBackendDispatchers.h>
@@ -69,6 +77,17 @@ static String getTargetID(const ProvisionalFrameProxy& provisionalFrame)
WTF_MAKE_TZONE_ALLOCATED_IMPL(WebPageInspectorController);
+WebPageInspectorControllerObserver* WebPageInspectorController::s_observer = nullptr;
+
+void WebPageInspectorController::setObserver(WebPageInspectorControllerObserver* observer)
+{
+ s_observer = observer;
+}
+
+WebPageInspectorControllerObserver* WebPageInspectorController::observer() {
+ return s_observer;
+}
+
WebPageInspectorController::WebPageInspectorController(WebPageProxy& inspectedPage)
: m_frontendRouter(FrontendRouter::create())
, m_backendDispatcher(BackendDispatcher::create(m_frontendRouter.copyRef()))
@@ -82,16 +101,92 @@ WebPageInspectorController::WebPageInspectorController(WebPageProxy& inspectedPa
WebPageInspectorController::~WebPageInspectorController() = default;
void WebPageInspectorController::init()
+{
+ auto targetAgent = makeUniqueRef<InspectorTargetAgent>(m_frontendRouter.get(), m_backendDispatcher.get());
+ m_targetAgent = targetAgent.ptr();
+ m_agents.append(WTF::move(targetAgent));
+ auto emulationAgent = makeUniqueRef<WebPageInspectorEmulationAgent>(m_backendDispatcher.get(), m_inspectedPage);
+ m_emulationAgent = emulationAgent.ptr();
+ m_agents.append(WTF::move(emulationAgent));
+ auto inputAgent = makeUniqueRef<WebPageInspectorInputAgent>(m_backendDispatcher.get(), m_inspectedPage);
+ m_inputAgent = inputAgent.ptr();
+ m_agents.append(WTF::move(inputAgent));
+ m_agents.append(makeUniqueRef<InspectorDialogAgent>(m_backendDispatcher.get(), m_frontendRouter.get(), m_inspectedPage));
+ auto screencastAgent = makeUniqueRef<InspectorScreencastAgent>(m_backendDispatcher.get(), m_frontendRouter.get(), m_inspectedPage);
+ m_screecastAgent = screencastAgent.ptr();
+ m_agents.append(WTF::move(screencastAgent));
+ if (s_observer)
+ s_observer->didCreateInspectorController(m_inspectedPage);
+}
+
+void WebPageInspectorController::didInitializeWebPage()
{
String pageTargetId = PageInspectorTarget::toTargetID(m_inspectedPage->webPageIDInMainFrameProcess());
+ // Create target only after attaching to a Web Process first time. Before that
+ // we cannot event establish frontend connection.
+ if (m_targets.contains(pageTargetId))
+ return;
addTarget(PageInspectorTargetProxy::create(protect(m_inspectedPage), pageTargetId, Inspector::InspectorTargetType::Page));
+ if (m_inspectedPage->mainFrame())
+ didCreateFrame(*m_inspectedPage->mainFrame());
}
void WebPageInspectorController::pageClosed()
{
+ String pageTargetId = PageInspectorTarget::toTargetID(m_inspectedPage->webPageIDInMainFrameProcess());
+ removeTarget(pageTargetId);
+
+
disconnectAllFrontends();
m_agents.discardValues();
+
+ if (s_observer)
+ s_observer->willDestroyInspectorController(m_inspectedPage);
+}
+
+bool WebPageInspectorController::pageCrashed(ProcessTerminationReason reason)
+{
+ if (reason != ProcessTerminationReason::Crash)
+ return false;
+ String targetId = PageInspectorTarget::toTargetID(m_inspectedPage->webPageIDInMainFrameProcess());
+ auto it = m_targets.find(targetId);
+ if (it == m_targets.end())
+ return false;
+ m_targetAgent->targetCrashed(*it->value);
+ m_targets.remove(it);
+
+ return m_targetAgent->isConnected();
+}
+
+void WebPageInspectorController::willCreateNewPage(const WebCore::WindowFeatures& features, const URL& url)
+{
+ if (s_observer)
+ s_observer->willCreateNewPage(m_inspectedPage, features, url);
+}
+
+void WebPageInspectorController::didShowPage()
+{
+ if (m_frontendRouter->hasFrontends())
+ m_emulationAgent->didShowPage();
+}
+
+void WebPageInspectorController::didProcessAllPendingKeyboardEvents()
+{
+ if (m_frontendRouter->hasFrontends())
+ m_inputAgent->didProcessAllPendingKeyboardEvents();
+}
+
+void WebPageInspectorController::didProcessAllPendingMouseEvents()
+{
+ if (m_frontendRouter->hasFrontends())
+ m_inputAgent->didProcessAllPendingMouseEvents();
+}
+
+void WebPageInspectorController::didProcessAllPendingWheelEvents()
+{
+ if (m_frontendRouter->hasFrontends())
+ m_inputAgent->didProcessAllPendingWheelEvents();
}
bool WebPageInspectorController::hasLocalFrontend() const
@@ -105,6 +200,14 @@ void WebPageInspectorController::connectFrontend(Inspector::FrontendChannel& fro
bool connectingFirstFrontend = !m_frontendRouter->hasFrontends();
+ // HACK: forcefully disconnect remote connections to show local inspector starting with initial
+ // agents' state.
+ if (frontendChannel.connectionType() == Inspector::FrontendChannel::ConnectionType::Local &&
+ !connectingFirstFrontend && !m_frontendRouter->hasLocalFrontend()) {
+ disconnectAllFrontends();
+ connectingFirstFrontend = true;
+ }
+
m_frontendRouter->connectFrontend(frontendChannel);
if (connectingFirstFrontend)
@@ -124,8 +227,10 @@ void WebPageInspectorController::disconnectFrontend(FrontendChannel& frontendCha
m_frontendRouter->disconnectFrontend(frontendChannel);
bool disconnectingLastFrontend = !m_frontendRouter->hasFrontends();
- if (disconnectingLastFrontend)
+ if (disconnectingLastFrontend) {
m_agents.willDestroyFrontendAndBackend(DisconnectReason::InspectorDestroyed);
+ m_pendingNavigations.clear();
+ }
Ref inspectedPage = m_inspectedPage.get();
inspectedPage->didChangeInspectorFrontendCount(m_frontendRouter->frontendCount());
@@ -149,6 +254,8 @@ void WebPageInspectorController::disconnectAllFrontends()
// Disconnect any remaining remote frontends.
m_frontendRouter->disconnectAllFrontends();
+ m_pendingNavigations.clear();
+
Ref inspectedPage = m_inspectedPage.get();
inspectedPage->didChangeInspectorFrontendCount(m_frontendRouter->frontendCount());
@@ -177,6 +284,66 @@ void WebPageInspectorController::setIndicating(bool indicating)
}
#endif
+#if USE(SKIA)
+void WebPageInspectorController::didPaint(sk_sp<SkImage>&& surface)
+{
+ if (!m_frontendRouter->hasFrontends())
+ return;
+
+ m_screecastAgent->didPaint(WTF::move(surface));
+}
+#endif
+
+
+void WebPageInspectorController::navigate(WebCore::ResourceRequest&& request, WebFrameProxy* frame, NavigationHandler&& completionHandler)
+{
+ auto navigation = m_inspectedPage->loadRequestForInspector(WTF::move(request), frame);
+ if (!navigation) {
+ completionHandler("Failed to navigate"_s, { });
+ return;
+ }
+
+ m_pendingNavigations.set(navigation->navigationID(), WTF::move(completionHandler));
+}
+
+void WebPageInspectorController::didReceivePolicyDecision(WebCore::PolicyAction action, std::optional<WebCore::NavigationIdentifier> navigationID)
+{
+ if (!m_frontendRouter->hasFrontends())
+ return;
+
+ if (!navigationID)
+ return;
+
+ auto completionHandler = m_pendingNavigations.take(*navigationID);
+ if (!completionHandler)
+ return;
+
+ if (action == WebCore::PolicyAction::Ignore)
+ completionHandler("Navigation cancelled"_s, { });
+ else
+ completionHandler(String(), *navigationID);
+}
+
+void WebPageInspectorController::didDestroyNavigation(WebCore::NavigationIdentifier navigationID)
+{
+ if (!m_frontendRouter->hasFrontends())
+ return;
+
+ auto completionHandler = m_pendingNavigations.take(navigationID);
+ if (!completionHandler)
+ return;
+
+ // Inspector initiated navigation is destroyed before policy check only when it
+ // becomes a fragment navigation (which always reuses current navigation).
+ completionHandler(String(), { });
+}
+
+void WebPageInspectorController::didFailProvisionalLoadForFrame(WebCore::NavigationIdentifier navigationID, const WebCore::ResourceError& error)
+{
+ if (s_observer)
+ s_observer->didFailProvisionalLoad(m_inspectedPage, navigationID, error.localizedDescription());
+}
+
void WebPageInspectorController::sendMessageToInspectorFrontend(const String& targetId, const String& message)
{
if (!m_targets.contains(targetId)) {
@@ -191,6 +358,52 @@ void WebPageInspectorController::sendMessageToInspectorFrontend(const String& ta
protect(m_targetAgent)->sendMessageFromTargetToFrontend(targetId, message);
}
+void WebPageInspectorController::setPauseOnStart(bool shouldPause)
+{
+ ASSERT(m_frontendRouter->hasFrontends());
+ m_targetAgent->setPauseOnStart(shouldPause);
+}
+
+bool WebPageInspectorController::shouldPauseLoadRequest() const
+{
+ if (!m_frontendRouter->hasFrontends())
+ return false;
+
+ if (!m_inspectedPage->isPageOpenedByDOMShowingInitialEmptyDocument())
+ return false;
+
+ auto* target = m_targets.get(PageInspectorTarget::toTargetID(m_inspectedPage->webPageIDInMainFrameProcess()));
+ // The method is expeted to be called only when the WebPage has already been
+ // initilized, so the target must exist.
+ ASSERT(target);
+ return target->isPaused();
+}
+
+bool WebPageInspectorController::shouldPauseInInspectorWhenShown() const
+{
+ if (!m_frontendRouter->hasFrontends())
+ return false;
+
+ // Only pause if the page was opened by window.open() or new tab navigation.
+ // We cannot use isPageOpenedByDOMShowingInitialEmptyDocument() here because
+ // this method maybe called from WebPageProxy::initializeWebPage and setOpenedByDOM
+ // is called after the page is initialized.
+ if (!m_inspectedPage->configuration().windowFeatures())
+ return false;
+
+ // The method is called from WebPageProxy::initializePage and the
+ // target is not created yet (it is created after the new page is
+ // initialized and attached to the process).
+ return m_targetAgent->shouldPauseOnStart();
+}
+
+void WebPageInspectorController::setContinueLoadingCallback(WTF::Function<void()>&& callback)
+{
+ auto* target = m_targets.get(PageInspectorTarget::toTargetID(m_inspectedPage->webPageIDInMainFrameProcess()));
+ ASSERT(target);
+ target->setResumeCallback(WTF::move(callback));
+}
+
bool WebPageInspectorController::shouldPauseLoading(const ProvisionalPageProxy& provisionalPage) const
{
if (!m_frontendRouter->hasFrontends())
@@ -210,7 +423,7 @@ void WebPageInspectorController::setContinueLoadingCallback(const ProvisionalPag
void WebPageInspectorController::didCreateProvisionalPage(ProvisionalPageProxy& provisionalPage, WebCore::FrameIdentifier mainFrameID, WebProcessProxy& mainFrameProcess)
{
- addTarget(PageInspectorTargetProxy::create(provisionalPage, getTargetID(provisionalPage), Inspector::InspectorTargetType::Page));
+ addTarget(PageInspectorTargetProxy::create(provisionalPage, getTargetID(provisionalPage)));
if (shouldManageFrameTargets()) {
constexpr bool isProvisional = true;
diff --git a/Source/WebKit/UIProcess/Inspector/WebPageInspectorController.h b/Source/WebKit/UIProcess/Inspector/WebPageInspectorController.h
index f670f9007a9386bf9933e59c32463f697dbb6597..17fa5c0f2860c9423de3e167616d46fa5d857125 100644
--- a/Source/WebKit/UIProcess/Inspector/WebPageInspectorController.h
+++ b/Source/WebKit/UIProcess/Inspector/WebPageInspectorController.h
@@ -28,9 +28,11 @@
#include "InspectorTargetProxy.h"
#include "ProvisionalPageProxy.h"
#include "UIProcess/WebFrameProxy.h"
+#include "ProcessTerminationReason.h"
#include <JavaScriptCore/InspectorAgentRegistry.h>
#include <JavaScriptCore/InspectorTargetAgent.h>
#include <WebCore/FrameIdentifier.h>
+#include <WebCore/NavigationIdentifier.h>
#include <WebCore/PageIdentifier.h>
#include <WebCore/ProcessIdentifier.h>
#include <wtf/CheckedRef.h>
@@ -38,11 +40,29 @@
#include <wtf/Noncopyable.h>
#include <wtf/TZoneMalloc.h>
#include <wtf/text/WTFString.h>
+#include <wtf/URL.h>
+
+#if USE(SKIA)
+#include <skia/core/SkData.h>
+#include <skia/core/SkImage.h>
+#endif
namespace Inspector {
class BackendDispatcher;
class FrontendChannel;
class FrontendRouter;
+class InspectorTarget;
+}
+
+namespace WebCore {
+class ResourceError;
+class ResourceRequest;
+enum class PolicyAction : uint8_t;
+struct WindowFeatures;
+}
+
+namespace PAL {
+class SessionID;
}
namespace WebKit {
@@ -51,6 +71,22 @@ class InspectorBrowserAgent;
class ProvisionalPageProxy;
struct WebPageAgentContext;
+class InspectorScreencastAgent;
+class WebFrameProxy;
+class WebPageInspectorEmulationAgent;
+class WebPageInspectorInputAgent;
+
+class WebPageInspectorControllerObserver {
+public:
+ virtual void didCreateInspectorController(WebPageProxy&) = 0;
+ virtual void willDestroyInspectorController(WebPageProxy&) = 0;
+ virtual void didFailProvisionalLoad(WebPageProxy&, WebCore::NavigationIdentifier, const String& error) = 0;
+ virtual void willCreateNewPage(WebPageProxy&, const WebCore::WindowFeatures&, const URL&) = 0;
+
+protected:
+ virtual ~WebPageInspectorControllerObserver() = default;
+};
+
class WebPageInspectorController {
WTF_MAKE_TZONE_ALLOCATED(WebPageInspectorController);
WTF_MAKE_NONCOPYABLE(WebPageInspectorController);
@@ -59,7 +95,21 @@ public:
~WebPageInspectorController();
void init();
+ void didInitializeWebPage();
+
+ static void setObserver(WebPageInspectorControllerObserver*);
+ static WebPageInspectorControllerObserver* observer();
+
void pageClosed();
+ bool pageCrashed(ProcessTerminationReason);
+
+ void willCreateNewPage(const WebCore::WindowFeatures&, const URL&);
+
+ void didShowPage();
+
+ void didProcessAllPendingKeyboardEvents();
+ void didProcessAllPendingMouseEvents();
+ void didProcessAllPendingWheelEvents();
bool hasLocalFrontend() const;
@@ -72,9 +122,25 @@ public:
#if ENABLE(REMOTE_INSPECTOR)
void setIndicating(bool);
#endif
+#if USE(SKIA)
+ void didPaint(sk_sp<SkImage>&&);
+#endif
+ using NavigationHandler = Function<void(const String&, Markable<WebCore::NavigationIdentifier>)>;
+ void navigate(WebCore::ResourceRequest&&, WebFrameProxy*, NavigationHandler&&);
+ void didReceivePolicyDecision(WebCore::PolicyAction action, std::optional<WebCore::NavigationIdentifier> navigationID);
+
+ void didDestroyNavigation(WebCore::NavigationIdentifier navigationID);
+
+ void didFailProvisionalLoadForFrame(WebCore::NavigationIdentifier navigationID, const WebCore::ResourceError& error);
void sendMessageToInspectorFrontend(const String& targetId, const String& message);
+ void setPauseOnStart(bool);
+
+ bool shouldPauseLoadRequest() const;
+ bool shouldPauseInInspectorWhenShown() const;
+ void setContinueLoadingCallback(WTF::Function<void()>&&);
+
bool shouldPauseLoading(const ProvisionalPageProxy&) const;
void setContinueLoadingCallback(const ProvisionalPageProxy&, WTF::Function<void()>&&);
@@ -111,9 +177,16 @@ private:
CheckedPtr<Inspector::InspectorTargetAgent> m_targetAgent;
HashMap<String, std::unique_ptr<InspectorTargetProxy>> m_targets;
+ WebPageInspectorEmulationAgent* m_emulationAgent { nullptr };
+ WebPageInspectorInputAgent* m_inputAgent { nullptr };
+ InspectorScreencastAgent* m_screecastAgent { nullptr };
+
CheckedPtr<InspectorBrowserAgent> m_enabledBrowserAgent;
bool m_didCreateLazyAgents { false };
+ UncheckedKeyHashMap<WebCore::NavigationIdentifier, NavigationHandler> m_pendingNavigations;
+
+ static WebPageInspectorControllerObserver* s_observer;
};
} // namespace WebKit
diff --git a/Source/WebKit/UIProcess/InspectorDialogAgent.cpp b/Source/WebKit/UIProcess/InspectorDialogAgent.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..53bf0625a4e6af2f4387b9a516604d5e6219cfef
--- /dev/null
+++ b/Source/WebKit/UIProcess/InspectorDialogAgent.cpp
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2019 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "InspectorDialogAgent.h"
+
+#include "APINavigation.h"
+#include "APIUIClient.h"
+#include "WebPageProxy.h"
+#include <JavaScriptCore/InspectorFrontendRouter.h>
+
+
+namespace WebKit {
+
+using namespace Inspector;
+
+WTF_MAKE_TZONE_ALLOCATED_IMPL(InspectorDialogAgent);
+
+InspectorDialogAgent::InspectorDialogAgent(Inspector::BackendDispatcher& backendDispatcher, Inspector::FrontendRouter& frontendRouter, WebPageProxy& page)
+ : InspectorAgentBase("Dialog"_s)
+ , m_frontendDispatcher(makeUnique<DialogFrontendDispatcher>(frontendRouter))
+ , m_backendDispatcher(DialogBackendDispatcher::create(backendDispatcher, this))
+ , m_page(page)
+{
+}
+
+InspectorDialogAgent::~InspectorDialogAgent()
+{
+ disable();
+}
+
+void InspectorDialogAgent::didCreateFrontendAndBackend()
+{
+}
+
+void InspectorDialogAgent::willDestroyFrontendAndBackend(Inspector::DisconnectReason)
+{
+}
+
+Inspector::Protocol::ErrorStringOr<void> InspectorDialogAgent::enable()
+{
+ if (m_page.inspectorDialogAgent())
+ return makeUnexpected("Dialog domain is already enabled."_s);
+
+ m_page.setInspectorDialogAgent(this);
+ return { };
+}
+
+Inspector::Protocol::ErrorStringOr<void> InspectorDialogAgent::disable()
+{
+ if (m_page.inspectorDialogAgent() != this)
+ return { };
+
+ m_page.setInspectorDialogAgent(nullptr);
+ return { };
+}
+
+Inspector::Protocol::ErrorStringOr<void> InspectorDialogAgent::handleJavaScriptDialog(bool accept, const String& value)
+{
+ m_page.uiClient().handleJavaScriptDialog(m_page, accept, value);
+ return { };
+}
+
+void InspectorDialogAgent::javascriptDialogOpening(const String& type, const String& message, const String& defaultValue) {
+ m_frontendDispatcher->javascriptDialogOpening(type, message, defaultValue);
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit/UIProcess/InspectorDialogAgent.h b/Source/WebKit/UIProcess/InspectorDialogAgent.h
new file mode 100644
index 0000000000000000000000000000000000000000..26775d9cfe30d220b14c1b2355a9baf9e6eca815
--- /dev/null
+++ b/Source/WebKit/UIProcess/InspectorDialogAgent.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2019 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "WebEvent.h"
+
+#include <JavaScriptCore/InspectorAgentBase.h>
+#include <JavaScriptCore/InspectorBackendDispatchers.h>
+#include <JavaScriptCore/InspectorFrontendDispatchers.h>
+
+#include <wtf/Forward.h>
+#include <wtf/Noncopyable.h>
+
+namespace Inspector {
+class FrontendChannel;
+class FrontendRouter;
+}
+
+namespace WebKit {
+
+class NativeWebKeyboardEvent;
+class WebPageProxy;
+
+class InspectorDialogAgent : public Inspector::InspectorAgentBase, public Inspector::DialogBackendDispatcherHandler {
+ WTF_MAKE_NONCOPYABLE(InspectorDialogAgent);
+ WTF_MAKE_TZONE_ALLOCATED(InspectorDialogAgent);
+public:
+ InspectorDialogAgent(Inspector::BackendDispatcher& backendDispatcher, Inspector::FrontendRouter& frontendRouter, WebPageProxy& page);
+ ~InspectorDialogAgent() override;
+
+ void didCreateFrontendAndBackend() override;
+ void willDestroyFrontendAndBackend(Inspector::DisconnectReason) override;
+
+ Inspector::Protocol::ErrorStringOr<void> enable() override;
+ Inspector::Protocol::ErrorStringOr<void> disable() override;
+ Inspector::Protocol::ErrorStringOr<void> handleJavaScriptDialog(bool accept, const String& promptText) override;
+
+ void javascriptDialogOpening(const String& type, const String& message, const String& defaultValue = String());
+
+private:
+ void platformHandleJavaScriptDialog(bool accept, const String* promptText);
+ std::unique_ptr<Inspector::DialogFrontendDispatcher> m_frontendDispatcher;
+ Ref<Inspector::DialogBackendDispatcher> m_backendDispatcher;
+ WebPageProxy& m_page;
+};
+
+} // namespace WebKit
diff --git a/Source/WebKit/UIProcess/InspectorPlaywrightAgent.cpp b/Source/WebKit/UIProcess/InspectorPlaywrightAgent.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..635da5eda9d9bbe21c5fa35936656b02c4b3ab46
--- /dev/null
+++ b/Source/WebKit/UIProcess/InspectorPlaywrightAgent.cpp
@@ -0,0 +1,1033 @@
+/*
+ * Copyright (C) 2019 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "InspectorPlaywrightAgent.h"
+
+#if ENABLE(REMOTE_INSPECTOR)
+
+#include "APIGeolocationProvider.h"
+#include "APIHTTPCookieStore.h"
+#include "APIPageConfiguration.h"
+#include "FrameInfoData.h"
+#include "InspectorPlaywrightAgentClient.h"
+#include "InspectorTargetProxy.h"
+#include "NetworkProcessMessages.h"
+#include "NetworkProcessProxy.h"
+#include "PageClient.h"
+#include "PageInspectorTarget.h"
+#include "PlaywrightFullScreenManagerProxyClient.h"
+#include "SandboxExtension.h"
+#include "StorageNamespaceIdentifier.h"
+#include "WebAutomationSession.h"
+#include "WebGeolocationManagerProxy.h"
+#include "WebGeolocationPosition.h"
+#include "WebFrameProxy.h"
+#include "WebInspectorUtilities.h"
+#include "WebPageGroup.h"
+#include "WebPageInspectorController.h"
+#include "WebPageMessages.h"
+#include "WebPageProxy.h"
+#include "WebPreferences.h"
+#include "WebProcessPool.h"
+#include "WebProcessProxy.h"
+#include "WebsiteDataRecord.h"
+#include <WebCore/FrameIdentifier.h>
+#include <WebCore/GeolocationPositionData.h>
+#include <WebCore/InspectorPageAgent.h>
+#include <WebCore/ProcessIdentifier.h>
+#include <WebCore/ResourceRequest.h>
+#include <WebCore/SecurityOriginData.h>
+#include <WebCore/StorageBlockingPolicy.h>
+#include <WebCore/WindowFeatures.h>
+#include <JavaScriptCore/InspectorBackendDispatcher.h>
+#include <JavaScriptCore/InspectorFrontendChannel.h>
+#include <JavaScriptCore/InspectorFrontendRouter.h>
+#include <pal/SessionID.h>
+#include <stdlib.h>
+#include <wtf/HashMap.h>
+#include <wtf/HashSet.h>
+#include <wtf/HexNumber.h>
+#include <wtf/URL.h>
+#include <wtf/text/MakeString.h>
+
+using namespace Inspector;
+
+namespace WebKit {
+
+class InspectorPlaywrightAgent::PageProxyChannel : public FrontendChannel {
+ WTF_DEPRECATED_MAKE_FAST_ALLOCATED(InspectorPlaywrightAgent);
+public:
+ PageProxyChannel(FrontendChannel& frontendChannel, String browserContextID, String pageProxyID, WebPageProxy& page)
+ : m_browserContextID(browserContextID)
+ , m_pageProxyID(pageProxyID)
+ , m_frontendChannel(frontendChannel)
+ , m_page(page)
+ {
+ }
+
+ ~PageProxyChannel() override = default;
+
+ void dispatchMessageFromFrontend(const String& message)
+ {
+ m_page.inspectorController().dispatchMessageFromFrontend(message);
+ }
+
+ WebPageProxy& page() { return m_page; }
+
+ void disconnect()
+ {
+ m_page.inspectorController().disconnectFrontend(*this);
+ }
+
+private:
+ ConnectionType connectionType() const override { return m_frontendChannel.connectionType(); }
+ void sendMessageToFrontend(const String& message) override
+ {
+ m_frontendChannel.sendMessageToFrontend(addTabIdToMessage(message));
+ }
+
+ String addTabIdToMessage(const String& message) {
+ RefPtr<JSON::Value> parsedMessage = JSON::Value::parseJSON(message);
+ if (!parsedMessage)
+ return message;
+
+ RefPtr<JSON::Object> messageObject = parsedMessage->asObject();
+ if (!messageObject)
+ return message;
+
+ messageObject->setString("browserContextId"_s, m_browserContextID);
+ messageObject->setString("pageProxyId"_s, m_pageProxyID);
+ return messageObject->toJSONString();
+ }
+
+ String m_browserContextID;
+ String m_pageProxyID;
+ FrontendChannel& m_frontendChannel;
+ WebPageProxy& m_page;
+};
+
+class OverridenGeolocationProvider final : public API::GeolocationProvider, public CanMakeWeakPtr<OverridenGeolocationProvider> {
+ WTF_MAKE_NONCOPYABLE(OverridenGeolocationProvider);
+public:
+ OverridenGeolocationProvider()
+ : m_position(WebGeolocationPosition::create(WebCore::GeolocationPositionData()))
+ {
+ }
+
+ void setPosition(const Ref<WebGeolocationPosition>& position) {
+ m_position = position;
+ }
+
+private:
+ void startUpdating(WebGeolocationManagerProxy& proxy) override
+ {
+ proxy.providerDidChangePosition(&m_position.get());
+ }
+
+ void stopUpdating(WebGeolocationManagerProxy&) override
+ {
+ }
+
+ void setEnableHighAccuracy(WebGeolocationManagerProxy&, bool enabled) override
+ {
+ }
+
+ Ref<WebGeolocationPosition> m_position;
+};
+
+namespace {
+
+void setGeolocationProvider(BrowserContext* browserContext) {
+ auto provider = makeUnique<OverridenGeolocationProvider>();
+ browserContext->geolocationProvider = *provider;
+ auto* geoManager = browserContext->processPool->supplement<WebGeolocationManagerProxy>();
+ geoManager->setProvider(WTF::move(provider));
+}
+
+String toBrowserContextIDProtocolString(const PAL::SessionID& sessionID)
+{
+ StringBuilder builder;
+ builder.append(hex(sessionID.toUInt64(), 16));
+ return builder.toString();
+}
+
+String toPageProxyIDProtocolString(const WebPageProxy& page)
+{
+ return makeString(page.identifier().toUInt64());
+}
+
+
+static Ref<JSON::ArrayOf<String>> getEnabledWindowFeatures(const WebCore::WindowFeatures& features) {
+ auto result = JSON::ArrayOf<String>::create();
+ if (features.x)
+ result->addItem(makeString("left="_s, String::number(*features.x)));
+ if (features.y)
+ result->addItem(makeString("top="_s, String::number(*features.y)));
+ if (features.width)
+ result->addItem(makeString("width="_s, String::number(*features.width)));
+ if (features.height)
+ result->addItem(makeString("height="_s, String::number(*features.height)));
+ if (features.menuBarVisible)
+ result->addItem("menubar"_s);
+ if (features.toolBarVisible)
+ result->addItem("toolbar"_s);
+ if (features.statusBarVisible)
+ result->addItem("status"_s);
+ if (features.locationBarVisible)
+ result->addItem("location"_s);
+ if (features.scrollbarsVisible)
+ result->addItem("scrollbars"_s);
+ if (features.resizable)
+ result->addItem("resizable"_s);
+ if (features.fullscreen)
+ result->addItem("fullscreen"_s);
+ if (features.dialog)
+ result->addItem("dialog"_s);
+ if (features.noopener)
+ result->addItem("noopener"_s);
+ if (features.noreferrer)
+ result->addItem("noreferrer"_s);
+ for (const auto& additionalFeature : features.additionalFeatures)
+ result->addItem(additionalFeature);
+ return result;
+}
+
+Inspector::Protocol::Playwright::CookieSameSitePolicy cookieSameSitePolicy(WebCore::Cookie::SameSitePolicy policy)
+{
+ switch (policy) {
+ case WebCore::Cookie::SameSitePolicy::None:
+ return Inspector::Protocol::Playwright::CookieSameSitePolicy::None;
+ case WebCore::Cookie::SameSitePolicy::Lax:
+ return Inspector::Protocol::Playwright::CookieSameSitePolicy::Lax;
+ case WebCore::Cookie::SameSitePolicy::Strict:
+ return Inspector::Protocol::Playwright::CookieSameSitePolicy::Strict;
+ }
+ ASSERT_NOT_REACHED();
+ return Inspector::Protocol::Playwright::CookieSameSitePolicy::None;
+}
+
+Ref<Inspector::Protocol::Playwright::Cookie> buildObjectForCookie(const WebCore::Cookie& cookie)
+{
+ return Inspector::Protocol::Playwright::Cookie::create()
+ .setName(cookie.name)
+ .setValue(cookie.value)
+ .setDomain(cookie.domain)
+ .setPath(cookie.path)
+ .setExpires(cookie.expires.value_or(-1))
+ .setHttpOnly(cookie.httpOnly)
+ .setSecure(cookie.secure)
+ .setSession(cookie.session)
+ .setSameSite(cookieSameSitePolicy(cookie.sameSite))
+ .release();
+}
+
+void adjustInspectedPagePreferences(WebPreferences& preferences, std::optional<bool> enableStoragePartitioning)
+{
+ // Set this to true as otherwise updating any preferences will override its
+ // value in the Web Process to false (and InspectorController sets it locally
+ // to true when frontend is connected).
+ preferences.setDeveloperExtrasEnabled(true);
+
+ // Navigation to cached pages doesn't fire some of the events (e.g. execution context created)
+ // that inspector depends on. So we disable the cache when front-end connects.
+ preferences.setUsesBackForwardCache(false);
+
+ // Enable popup debugging.
+ // TODO: allow to set preferences over the inspector protocol or find a better place for this.
+ preferences.setJavaScriptCanOpenWindowsAutomatically(true);
+
+ // Enable media stream.
+ if (!preferences.mediaDevicesEnabled()) {
+ preferences.setMediaDevicesEnabled(true);
+ preferences.setPeerConnectionEnabled(true);
+ }
+
+ if (!enableStoragePartitioning || !*enableStoragePartitioning) {
+ // Disable local storage partitioning. See https://github.com/microsoft/playwright/issues/32230
+ preferences.setStorageBlockingPolicy(static_cast<uint32_t>(WebCore::StorageBlockingPolicy::AllowAll));
+ }
+}
+
+} // namespace
+
+BrowserContext::BrowserContext() = default;
+
+BrowserContext::~BrowserContext() = default;
+
+class InspectorPlaywrightAgent::BrowserContextDeletion {
+ WTF_MAKE_NONCOPYABLE(BrowserContextDeletion);
+ WTF_DEPRECATED_MAKE_FAST_ALLOCATED(InspectorPlaywrightAgent::BrowserContextDeletion);
+public:
+ BrowserContextDeletion(std::unique_ptr<BrowserContext>&& context, size_t numberOfPages, Ref<DeleteContextCallback>&& callback)
+ : m_browserContext(WTF::move(context))
+ , m_numberOfPages(numberOfPages)
+ , m_callback(WTF::move(callback)) { }
+
+ void didDestroyPage(const WebPageProxy& page)
+ {
+ ASSERT(m_browserContext->dataStore->sessionID() == page.sessionID());
+ // Check if new pages have been created during the context destruction and
+ // close all of them if necessary.
+ if (m_numberOfPages == 1) {
+ auto pages = m_browserContext->pages;
+ size_t numberOfPages = pages.size();
+ if (numberOfPages > 1) {
+ m_numberOfPages = numberOfPages;
+ for (auto* existingPage : pages) {
+ if (existingPage != &page)
+ existingPage->closePage();
+ }
+ }
+ }
+ --m_numberOfPages;
+ if (m_numberOfPages)
+ return;
+ m_callback->sendSuccess();
+ }
+
+ bool isFinished() const { return !m_numberOfPages; }
+
+ BrowserContext* context() const { return m_browserContext.get(); }
+
+private:
+ std::unique_ptr<BrowserContext> m_browserContext;
+ size_t m_numberOfPages;
+ Ref<DeleteContextCallback> m_callback;
+};
+
+
+InspectorPlaywrightAgent::InspectorPlaywrightAgent(std::unique_ptr<InspectorPlaywrightAgentClient> client)
+ : m_frontendChannel(nullptr)
+ , m_frontendRouter(FrontendRouter::create())
+ , m_backendDispatcher(BackendDispatcher::create(m_frontendRouter.copyRef()))
+ , m_client(std::move(client))
+ , m_frontendDispatcher(makeUnique<PlaywrightFrontendDispatcher>(m_frontendRouter))
+ , m_playwrightDispatcher(PlaywrightBackendDispatcher::create(m_backendDispatcher.get(), this))
+{
+}
+
+InspectorPlaywrightAgent::~InspectorPlaywrightAgent()
+{
+ if (m_frontendChannel)
+ disconnectFrontend();
+}
+
+void InspectorPlaywrightAgent::connectFrontend(FrontendChannel& frontendChannel)
+{
+ ASSERT(!m_frontendChannel);
+ m_frontendChannel = &frontendChannel;
+ WebPageInspectorController::setObserver(this);
+
+ m_frontendRouter->connectFrontend(frontendChannel);
+}
+
+void InspectorPlaywrightAgent::disconnectFrontend()
+{
+ if (!m_frontendChannel)
+ return;
+
+ disable();
+
+ m_frontendRouter->disconnectFrontend(*m_frontendChannel);
+ ASSERT(!m_frontendRouter->hasFrontends());
+
+ WebPageInspectorController::setObserver(nullptr);
+ m_frontendChannel = nullptr;
+
+ closeImpl([](String error){});
+}
+
+void InspectorPlaywrightAgent::dispatchMessageFromFrontend(const String& message)
+{
+ m_backendDispatcher->dispatch(message, [&](const RefPtr<JSON::Object>& messageObject) {
+ RefPtr<JSON::Value> idValue;
+ if (!messageObject->getValue("id"_s, idValue))
+ return BackendDispatcher::InterceptionResult::Continue;
+ RefPtr<JSON::Value> pageProxyIDValue;
+ if (!messageObject->getValue("pageProxyId"_s, pageProxyIDValue))
+ return BackendDispatcher::InterceptionResult::Continue;
+
+ String pageProxyID;
+ if (!pageProxyIDValue->asString(pageProxyID)) {
+ m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidRequest, "The type of 'pageProxyId' must be string"_s);
+ m_backendDispatcher->sendPendingErrors();
+ return BackendDispatcher::InterceptionResult::Intercepted;
+ }
+
+ if (auto pageProxyChannel = m_pageProxyChannels.get(pageProxyID)) {
+ pageProxyChannel->dispatchMessageFromFrontend(message);
+ return BackendDispatcher::InterceptionResult::Intercepted;
+ }
+
+ std::optional<int> requestId = idValue->asInteger();
+ if (!requestId) {
+ m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidRequest, "The type of 'id' must be number"_s);
+ m_backendDispatcher->sendPendingErrors();
+ return BackendDispatcher::InterceptionResult::Intercepted;
+ }
+
+ m_backendDispatcher->reportProtocolError(*requestId, BackendDispatcher::InvalidParams, "Cannot find page proxy with provided 'pageProxyId'"_s);
+ m_backendDispatcher->sendPendingErrors();
+ return BackendDispatcher::InterceptionResult::Intercepted;
+ });
+}
+
+void InspectorPlaywrightAgent::didCreateInspectorController(WebPageProxy& page)
+{
+ if (!m_isEnabled)
+ return;
+
+ if (isInspectorProcessPool(page.legacyMainFrameProcess().processPool()))
+ return;
+
+ ASSERT(m_frontendChannel);
+
+ String browserContextID = toBrowserContextIDProtocolString(page.sessionID());
+ String pageProxyID = toPageProxyIDProtocolString(page);
+ auto* opener = page.configuration().openerPageForInspector();
+ String openerId;
+ if (opener)
+ openerId = toPageProxyIDProtocolString(*opener);
+
+ BrowserContext* browserContext = getExistingBrowserContext(browserContextID);
+ browserContext->pages.add(&page);
+ m_frontendDispatcher->pageProxyCreated(browserContextID, pageProxyID, openerId);
+
+ // Auto-connect to all new pages.
+ auto pageProxyChannel = makeUnique<PageProxyChannel>(*m_frontendChannel, browserContextID, pageProxyID, page);
+ adjustInspectedPagePreferences(page.preferences(), browserContext->enableStoragePartitioning);
+ page.inspectorController().connectFrontend(*pageProxyChannel);
+ // Always pause new targets if controlled remotely.
+ page.inspectorController().setPauseOnStart(true);
+ m_pageProxyChannels.set(pageProxyID, WTF::move(pageProxyChannel));
+ page.setFullScreenManagerClientOverride(makeUnique<PlaywrightFullScreenManagerProxyClient>(page));
+}
+
+void InspectorPlaywrightAgent::willDestroyInspectorController(WebPageProxy& page)
+{
+ if (!m_isEnabled)
+ return;
+
+ if (isInspectorProcessPool(page.legacyMainFrameProcess().processPool()))
+ return;
+
+ String browserContextID = toBrowserContextIDProtocolString(page.sessionID());
+ BrowserContext* browserContext = getExistingBrowserContext(browserContextID);
+ browserContext->pages.remove(&page);
+ m_frontendDispatcher->pageProxyDestroyed(toPageProxyIDProtocolString(page));
+
+ auto it = m_browserContextDeletions.find(browserContextID);
+ if (it != m_browserContextDeletions.end()) {
+ it->value->didDestroyPage(page);
+ if (it->value->isFinished())
+ m_browserContextDeletions.remove(it);
+ }
+
+ String pageProxyID = toPageProxyIDProtocolString(page);
+ auto channelIt = m_pageProxyChannels.find(pageProxyID);
+ ASSERT(channelIt != m_pageProxyChannels.end());
+ channelIt->value->disconnect();
+ m_pageProxyChannels.remove(channelIt);
+}
+
+void InspectorPlaywrightAgent::didFailProvisionalLoad(WebPageProxy& page, WebCore::NavigationIdentifier navigationID, const String& error)
+{
+ if (!m_isEnabled)
+ return;
+
+ m_frontendDispatcher->provisionalLoadFailed(
+ toPageProxyIDProtocolString(page),
+ String::number(navigationID.toUInt64()), error);
+}
+
+void InspectorPlaywrightAgent::willCreateNewPage(WebPageProxy& page, const WebCore::WindowFeatures& features, const URL& url)
+{
+ if (!m_isEnabled)
+ return;
+
+ m_frontendDispatcher->windowOpen(
+ toPageProxyIDProtocolString(page),
+ url.string(),
+ getEnabledWindowFeatures(features));
+}
+
+static WebsiteDataStore* findDefaultWebsiteDataStore() {
+ WebsiteDataStore* result = nullptr;
+ WebsiteDataStore::forEachWebsiteDataStore([&result] (WebsiteDataStore& dataStore) {
+ if (dataStore.isPersistent()) {
+ RELEASE_ASSERT(result == nullptr);
+ result = &dataStore;
+ }
+ });
+ return result;
+}
+
+Inspector::Protocol::ErrorStringOr<void> InspectorPlaywrightAgent::enable()
+{
+ if (m_isEnabled)
+ return { };
+
+ m_isEnabled = true;
+
+ auto* defaultDataStore = findDefaultWebsiteDataStore();
+ if (!m_defaultContext && defaultDataStore) {
+ auto context = std::make_unique<BrowserContext>();
+ m_defaultContext = context.get();
+ context->processPool = WebProcessPool::allProcessPools().first().ptr();
+ context->dataStore = defaultDataStore;
+ setGeolocationProvider(context.get());
+ // Add default context to the map so that we can easily find it for
+ // created/deleted pages.
+ PAL::SessionID sessionID = context->dataStore->sessionID();
+ m_browserContexts.set(toBrowserContextIDProtocolString(sessionID), WTF::move(context));
+ }
+
+ WebsiteDataStore::forEachWebsiteDataStore([this] (WebsiteDataStore& dataStore) {
+ dataStore.setDownloadInstrumentation(this);
+ });
+ for (Ref pool : WebProcessPool::allProcessPools()) {
+ for (Ref process : pool->processes()) {
+ for (Ref page : process->pages())
+ didCreateInspectorController(WTF::move(page));
+ }
+ }
+ return { };
+}
+
+Inspector::Protocol::ErrorStringOr<void> InspectorPlaywrightAgent::disable()
+{
+ if (!m_isEnabled)
+ return { };
+
+ m_isEnabled = false;
+
+ for (auto it = m_pageProxyChannels.begin(); it != m_pageProxyChannels.end(); ++it)
+ it->value->disconnect();
+ m_pageProxyChannels.clear();
+
+ WebsiteDataStore::forEachWebsiteDataStore([] (WebsiteDataStore& dataStore) {
+ dataStore.setDownloadInstrumentation(nullptr);
+ dataStore.setDownloadForAutomation(std::optional<bool>(), String());
+ });
+ for (auto& it : m_browserContexts) {
+ it.value->dataStore->setDownloadInstrumentation(nullptr);
+ it.value->pages.clear();
+ }
+ m_browserContextDeletions.clear();
+ return { };
+}
+
+Inspector::Protocol::ErrorStringOr<String> InspectorPlaywrightAgent::getInfo()
+{
+#if PLATFORM(MAC)
+ return { "macOS"_s };
+#elif PLATFORM(GTK) || PLATFORM(WPE)
+ return { "Linux"_s };
+#elif PLATFORM(WIN)
+ return { "Windows"_s };
+#else
+#error "Unsupported platform."
+#endif
+}
+
+void InspectorPlaywrightAgent::close(Ref<CloseCallback>&& callback)
+{
+ closeImpl([callback = WTF::move(callback)] (String error) {
+ if (!callback->isActive())
+ return;
+ if (error.isNull())
+ callback->sendSuccess();
+ else
+ callback->sendFailure(error);
+ });
+}
+
+void InspectorPlaywrightAgent::closeImpl(Function<void(String)>&& callback)
+{
+ Vector<Ref<WebPageProxy>> pages;
+ // If Web Process crashed it will be disconnected from its pool until
+ // the page reloads. So we cannot discover such processes and the pages
+ // by traversing all process pools and their processes. Instead we look at
+ // all existing Web Processes wether in a pool or not.
+ for (Ref process : WebProcessProxy::allProcessesForInspector()) {
+ for (Ref page : process->pages())
+ pages.append(WTF::move(page));
+ }
+ for (Ref page : pages)
+ page->closePage();
+
+ if (!m_defaultContext) {
+ m_client->closeBrowser();
+ callback(String());
+ return;
+ }
+
+ m_defaultContext->dataStore->syncLocalStorage([this, callback = WTF::move(callback)] () {
+ if (m_client == nullptr) {
+ callback("no platform delegate to close browser"_s);
+ } else {
+ m_client->closeBrowser();
+ callback(String());
+ }
+ });
+
+}
+
+Inspector::Protocol::ErrorStringOr<String /* browserContextID */> InspectorPlaywrightAgent::createContext(const String& proxyServer, const String& proxyBypassList, std::optional<bool>&& enableStoragePartitioning)
+{
+ String errorString;
+ std::unique_ptr<BrowserContext> browserContext = m_client->createBrowserContext(errorString, proxyServer, proxyBypassList);
+ if (!browserContext)
+ return makeUnexpected(errorString);
+
+ browserContext->enableStoragePartitioning = WTF::move(enableStoragePartitioning);
+ // Ensure network process.
+ browserContext->dataStore->networkProcess();
+ browserContext->dataStore->setDownloadInstrumentation(this);
+ setGeolocationProvider(browserContext.get());
+ PAL::SessionID sessionID = browserContext->dataStore->sessionID();
+ String browserContextID = toBrowserContextIDProtocolString(sessionID);
+ m_browserContexts.set(browserContextID, WTF::move(browserContext));
+ return browserContextID;
+}
+
+void InspectorPlaywrightAgent::deleteContext(const String& browserContextID, Ref<DeleteContextCallback>&& callback)
+{
+ String errorString;
+ BrowserContext* browserContext = lookupBrowserContext(errorString, browserContextID);
+ if (!lookupBrowserContext(errorString, browserContextID)) {
+ callback->sendFailure(errorString);
+ return;
+ }
+
+ if (browserContext == m_defaultContext) {
+ callback->sendFailure("Cannot delete default context"_s);
+ return;
+ }
+
+ auto pages = browserContext->pages;
+ PAL::SessionID sessionID = browserContext->dataStore->sessionID();
+ auto contextHolder = m_browserContexts.take(browserContextID);
+ if (pages.isEmpty()) {
+ callback->sendSuccess();
+ } else {
+ m_browserContextDeletions.set(browserContextID, makeUnique<BrowserContextDeletion>(WTF::move(contextHolder), pages.size(), WTF::move(callback)));
+ for (auto* page : pages)
+ page->closePage();
+ }
+ m_client->deleteBrowserContext(errorString, sessionID);
+}
+
+Inspector::Protocol::ErrorStringOr<String /* pageProxyID */> InspectorPlaywrightAgent::createPage(const String& browserContextID)
+{
+ String errorString;
+ BrowserContext* browserContext = lookupBrowserContext(errorString, browserContextID);
+ if (!browserContext)
+ return makeUnexpected(errorString);
+
+ RefPtr<WebPageProxy> page = m_client->createPage(errorString, *browserContext);
+ if (!page)
+ return makeUnexpected(errorString);
+
+ return toPageProxyIDProtocolString(*page);
+}
+
+WebFrameProxy* InspectorPlaywrightAgent::frameForID(const String& frameID, String& error)
+{
+ std::optional<WebCore::FrameIdentifier> frameIdentifier = WebCore::InspectorPageAgent::parseFrameID(frameID);
+ if (!frameIdentifier) {
+ error = "Invalid frame id"_s;
+ return nullptr;
+ }
+
+ WebFrameProxy* frame = WebFrameProxy::webFrame(*frameIdentifier);
+ if (!frame) {
+ error = "Cannot find web frame for the frame id"_s;
+ return nullptr;
+ }
+
+ return frame;
+}
+
+void InspectorPlaywrightAgent::navigate(const String& url, const String& pageProxyID, const String& frameID, const String& referrer, Ref<NavigateCallback>&& callback)
+{
+ auto* pageProxyChannel = m_pageProxyChannels.get(pageProxyID);
+ if (!pageProxyChannel) {
+ callback->sendFailure("Cannot find page proxy with provided 'pageProxyId'"_s);
+ return;
+ }
+
+ auto resourceRequest = WebCore::ResourceRequest(URL { url });
+
+ if (!!referrer)
+ resourceRequest.setHTTPReferrer(referrer);
+
+ if (!resourceRequest.url().isValid()) {
+ callback->sendFailure("Cannot navigate to invalid URL"_s);
+ return;
+ }
+
+ WebFrameProxy* frame = nullptr;
+ if (!!frameID) {
+ String error;
+ frame = frameForID(frameID, error);
+ if (!frame) {
+ callback->sendFailure(error);
+ return;
+ }
+
+ if (frame->page() != &pageProxyChannel->page()) {
+ callback->sendFailure("Frame with specified is not from the specified page"_s);
+ return;
+ }
+ }
+
+ pageProxyChannel->page().inspectorController().navigate(WTF::move(resourceRequest), frame, [callback = WTF::move(callback)](const String& error, Markable<WebCore::NavigationIdentifier> navigationID) {
+ if (!error.isEmpty()) {
+ callback->sendFailure(error);
+ return;
+ }
+
+ String navigationIDString;
+ if (navigationID)
+ navigationIDString = String::number(navigationID->toUInt64());
+ callback->sendSuccess(navigationIDString);
+ });
+}
+
+Inspector::Protocol::ErrorStringOr<void> InspectorPlaywrightAgent::grantFileReadAccess(const String& pageProxyID, Ref<JSON::Array>&& paths)
+{
+#if ENABLE(SANDBOX_EXTENSIONS)
+ auto* pageProxyChannel = m_pageProxyChannels.get(pageProxyID);
+ if (!pageProxyChannel)
+ return makeUnexpected("Unknown pageProxyID"_s);
+
+ Vector<String> files;
+ for (const auto& value : paths.get()) {
+ String path;
+ if (!value->asString(path))
+ return makeUnexpected("Filr path must be a string"_s);
+
+ files.append(path);
+ }
+
+ auto sandboxExtensionHandles = SandboxExtension::createReadOnlyHandlesForFiles("InspectorPlaywrightAgent::grantFileReadAccess"_s, files);
+ pageProxyChannel->page().legacyMainFrameProcess().send(Messages::WebPage::ExtendSandboxForFilesFromOpenPanel(WTF::move(sandboxExtensionHandles)), pageProxyChannel->page().webPageIDInMainFrameProcess());
+#endif
+ return { };
+}
+
+void InspectorPlaywrightAgent::takePageScreenshot(const String& pageProxyID, int x, int y, int width, int height, std::optional<bool>&& omitDeviceScaleFactor, Ref<TakePageScreenshotCallback>&& callback)
+{
+#if PLATFORM(MAC) || PLATFORM(GTK) || PLATFORM(WPE)
+ auto* pageProxyChannel = m_pageProxyChannels.get(pageProxyID);
+ if (!pageProxyChannel) {
+ callback->sendFailure("Unknown pageProxyID"_s);
+ return;
+ }
+
+ bool nominalResolution = omitDeviceScaleFactor.has_value() && *omitDeviceScaleFactor;
+ WebCore::IntRect clip(x, y, width, height);
+ m_client->takePageScreenshot(pageProxyChannel->page(), WTF::move(clip), nominalResolution, [callback = WTF::move(callback)](const String& error, const String& data) {
+ if (error.isEmpty())
+ callback->sendSuccess(data);
+ else
+ callback->sendFailure(error);
+ });
+#else
+ return callback->sendFailure("This method is not supported on this platform."_s);
+#endif
+}
+
+
+Inspector::Protocol::ErrorStringOr<void> InspectorPlaywrightAgent::setIgnoreCertificateErrors(const String& browserContextID, bool ignore)
+{
+ String errorString;
+ BrowserContext* browserContext = lookupBrowserContext(errorString, browserContextID);
+ if (!errorString.isEmpty())
+ return makeUnexpected(errorString);
+
+ browserContext->dataStore->setIgnoreTLSErrors(ignore);
+ return { };
+}
+
+Inspector::Protocol::ErrorStringOr<void> InspectorPlaywrightAgent::setPageZoomFactor(const String& pageProxyID, double zoomFactor)
+{
+ auto* pageProxyChannel = m_pageProxyChannels.get(pageProxyID);
+ if (!pageProxyChannel)
+ return makeUnexpected("Unknown pageProxyID"_s);
+
+ pageProxyChannel->page().setPageZoomFactor(zoomFactor);
+ return { };
+}
+
+void InspectorPlaywrightAgent::getAllCookies(const String& browserContextID, Ref<GetAllCookiesCallback>&& callback) {
+ String errorString;
+ BrowserContext* browserContext = lookupBrowserContext(errorString, browserContextID);
+ if (!errorString.isEmpty()) {
+ callback->sendFailure(errorString);
+ return;
+ }
+
+ browserContext->dataStore->cookieStore().cookies(
+ [callback = WTF::move(callback)](const Vector<WebCore::Cookie>& allCookies) {
+ if (!callback->isActive())
+ return;
+ auto cookies = JSON::ArrayOf<Inspector::Protocol::Playwright::Cookie>::create();
+
+ for (const auto& cookie : allCookies)
+ cookies->addItem(buildObjectForCookie(cookie));
+ callback->sendSuccess(WTF::move(cookies));
+ });
+}
+
+void InspectorPlaywrightAgent::setCookies(const String& browserContextID, Ref<JSON::Array>&& in_cookies, Ref<SetCookiesCallback>&& callback) {
+ String errorString;
+ BrowserContext* browserContext = lookupBrowserContext(errorString, browserContextID);
+ if (!errorString.isEmpty()) {
+ callback->sendFailure(errorString);
+ return;
+ }
+
+ Vector<WebCore::Cookie> cookies;
+ for (unsigned i = 0; i < in_cookies->length(); ++i) {
+ RefPtr<JSON::Value> item = in_cookies->get(i);
+ RefPtr<JSON::Object> obj = item->asObject();
+ if (!obj) {
+ callback->sendFailure("Invalid cookie payload format"_s);
+ return;
+ }
+
+ WebCore::Cookie cookie;
+ cookie.name = obj->getString("name"_s);
+ cookie.value = obj->getString("value"_s);
+ cookie.domain = obj->getString("domain"_s);
+ cookie.path = obj->getString("path"_s);
+ if (!cookie.name || !cookie.value || !cookie.domain || !cookie.path) {
+ callback->sendFailure("Invalid file payload format"_s);
+ return;
+ }
+
+ std::optional<double> expires = obj->getDouble("expires"_s);
+ if (expires && *expires != -1)
+ cookie.expires = *expires;
+ if (std::optional<bool> value = obj->getBoolean("httpOnly"_s))
+ cookie.httpOnly = *value;
+ if (std::optional<bool> value = obj->getBoolean("secure"_s))
+ cookie.secure = *value;
+ if (std::optional<bool> value = obj->getBoolean("session"_s))
+ cookie.session = *value;
+ String sameSite;
+ if (obj->getString("sameSite"_s, sameSite)) {
+ if (sameSite == "None"_s)
+ cookie.sameSite = WebCore::Cookie::SameSitePolicy::None;
+ if (sameSite == "Lax"_s)
+ cookie.sameSite = WebCore::Cookie::SameSitePolicy::Lax;
+ if (sameSite == "Strict"_s)
+ cookie.sameSite = WebCore::Cookie::SameSitePolicy::Strict;
+#if USE(SOUP)
+ } else {
+ // Cookies are Lax by default in libsoup and will reject cookies with
+ // sameSite: None and secure: false (defaults in WebCore::Cookie).
+ cookie.sameSite = WebCore::Cookie::SameSitePolicy::Lax;
+#endif
+ }
+ cookies.append(WTF::move(cookie));
+ }
+
+ browserContext->dataStore->cookieStore().setCookies(WTF::move(cookies),
+ [callback = WTF::move(callback)]() {
+ if (!callback->isActive())
+ return;
+ callback->sendSuccess();
+ });
+}
+
+void InspectorPlaywrightAgent::deleteAllCookies(const String& browserContextID, Ref<DeleteAllCookiesCallback>&& callback) {
+ String errorString;
+ BrowserContext* browserContext = lookupBrowserContext(errorString, browserContextID);
+ if (!errorString.isEmpty()) {
+ callback->sendFailure(errorString);
+ return;
+ }
+
+ browserContext->dataStore->cookieStore().deleteAllCookies(
+ [callback = WTF::move(callback)]() {
+ if (!callback->isActive())
+ return;
+ callback->sendSuccess();
+ });
+}
+
+Inspector::Protocol::ErrorStringOr<void> InspectorPlaywrightAgent::setLanguages(Ref<JSON::Array>&& languages, const String& browserContextID)
+{
+ String errorString;
+ BrowserContext* browserContext = lookupBrowserContext(errorString, browserContextID);
+ if (!errorString.isEmpty())
+ return makeUnexpected(errorString);
+
+ Vector<String> items;
+ for (const auto& value : languages.get()) {
+ String language;
+ if (!value->asString(language))
+ return makeUnexpected("Language must be a string"_s);
+
+ items.append(language);
+ }
+
+ browserContext->processPool->configuration().setOverrideLanguages(WTF::move(items));
+ return { };
+}
+
+Inspector::Protocol::ErrorStringOr<void> InspectorPlaywrightAgent::setDownloadBehavior(const String& behavior, const String& downloadPath, const String& browserContextID)
+{
+ String errorString;
+ BrowserContext* browserContext = lookupBrowserContext(errorString, browserContextID);
+ if (!errorString.isEmpty())
+ return makeUnexpected(errorString);
+
+ std::optional<bool> allow;
+ if (behavior == "allow"_s)
+ allow = true;
+ if (behavior == "deny"_s)
+ allow = false;
+ browserContext->dataStore->setDownloadForAutomation(allow, downloadPath);
+ return { };
+}
+
+Inspector::Protocol::ErrorStringOr<void> InspectorPlaywrightAgent::setGeolocationOverride(const String& browserContextID, RefPtr<JSON::Object>&& geolocation)
+{
+ String errorString;
+ BrowserContext* browserContext = lookupBrowserContext(errorString, browserContextID);
+ if (!errorString.isEmpty())
+ return makeUnexpected(errorString);
+
+ auto* geoManager = browserContext->processPool->supplement<WebGeolocationManagerProxy>();
+ if (!geoManager)
+ return makeUnexpected("Internal error: geolocation manager is not available."_s);
+
+ if (geolocation) {
+ std::optional<double> timestamp = geolocation->getDouble("timestamp"_s);
+ std::optional<double> latitude = geolocation->getDouble("latitude"_s);
+ std::optional<double> longitude = geolocation->getDouble("longitude"_s);
+ std::optional<double> accuracy = geolocation->getDouble("accuracy"_s);
+ if (!timestamp || !latitude || !longitude || !accuracy)
+ return makeUnexpected("Invalid geolocation format"_s);
+
+ auto position = WebGeolocationPosition::create(WebCore::GeolocationPositionData(*timestamp, *latitude, *longitude, *accuracy));
+ if (!browserContext->geolocationProvider)
+ return makeUnexpected("Internal error: geolocation provider has been destroyed."_s);
+ browserContext->geolocationProvider->setPosition(position);
+ geoManager->providerDidChangePosition(&position.get());
+ } else {
+ geoManager->providerDidFailToDeterminePosition("Position unavailable"_s);
+ }
+ return { };
+}
+
+void InspectorPlaywrightAgent::downloadCreated(const String& uuid, const WebCore::ResourceRequest& request, const FrameInfoData& frameInfoData, WebPageProxy* page, RefPtr<DownloadProxy> download)
+{
+ if (!m_isEnabled)
+ return;
+ String frameID = WebCore::InspectorPageAgent::serializeFrameID(frameInfoData.frameID);
+ m_downloads.set(uuid, download);
+ m_frontendDispatcher->downloadCreated(
+ toPageProxyIDProtocolString(*page),
+ frameID,
+ uuid, request.url().string());
+}
+
+void InspectorPlaywrightAgent::downloadFilenameSuggested(const String& uuid, const String& suggestedFilename)
+{
+ if (!m_isEnabled)
+ return;
+ m_frontendDispatcher->downloadFilenameSuggested(uuid, suggestedFilename);
+}
+
+void InspectorPlaywrightAgent::downloadFinished(const String& uuid, const String& error)
+{
+ if (!m_isEnabled)
+ return;
+ m_frontendDispatcher->downloadFinished(uuid, error);
+ m_downloads.remove(uuid);
+}
+
+Inspector::Protocol::ErrorStringOr<void> InspectorPlaywrightAgent::cancelDownload(const String& uuid)
+{
+ if (!m_isEnabled)
+ return { };
+ auto download = m_downloads.get(uuid);
+ if (!download)
+ return { };
+ download->cancel([] (auto*) {});
+ return { };
+}
+
+void InspectorPlaywrightAgent::clearMemoryCache(const String& browserContextID, Ref<ClearMemoryCacheCallback>&& callback)
+{
+ if (!m_isEnabled) {
+ callback->sendSuccess();
+ return;
+ }
+ String errorString;
+ auto browserContext = lookupBrowserContext(errorString, browserContextID);
+ if (!errorString.isEmpty()) {
+ callback->sendFailure(errorString);
+ return;
+ }
+ browserContext->dataStore->removeData(WebKit::WebsiteDataType::MemoryCache, -WallTime::infinity(), [callback] {
+ callback->sendSuccess();
+ });
+}
+
+BrowserContext* InspectorPlaywrightAgent::getExistingBrowserContext(const String& browserContextID)
+{
+ BrowserContext* browserContext = m_browserContexts.get(browserContextID);
+ if (browserContext)
+ return browserContext;
+
+ auto it = m_browserContextDeletions.find(browserContextID);
+ RELEASE_ASSERT(it != m_browserContextDeletions.end());
+ return it->value->context();
+}
+
+BrowserContext* InspectorPlaywrightAgent::lookupBrowserContext(ErrorString& errorString, const String& browserContextID)
+{
+ if (!browserContextID) {
+ if (!m_defaultContext)
+ errorString = "Browser started with no default context"_s;
+ return m_defaultContext;
+ }
+
+ BrowserContext* browserContext = m_browserContexts.get(browserContextID);
+ if (!browserContext)
+ errorString = "Could not find browser context for given id"_s;
+ return browserContext;
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(REMOTE_INSPECTOR)
diff --git a/Source/WebKit/UIProcess/InspectorPlaywrightAgent.h b/Source/WebKit/UIProcess/InspectorPlaywrightAgent.h
new file mode 100644
index 0000000000000000000000000000000000000000..1e31698788ab79bc3807b9f29fa2ebc026374909
--- /dev/null
+++ b/Source/WebKit/UIProcess/InspectorPlaywrightAgent.h
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2019 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(REMOTE_INSPECTOR)
+
+#include "InspectorPlaywrightAgentClient.h"
+#include <JavaScriptCore/InspectorBackendDispatchers.h>
+#include "WebPageInspectorController.h"
+#include "WebProcessPool.h"
+#include "DownloadProxy.h"
+#include <wtf/HashMap.h>
+#include <wtf/Forward.h>
+#include <wtf/Noncopyable.h>
+#include <WebCore/NavigationIdentifier.h>
+
+namespace Inspector {
+class BackendDispatcher;
+class FrontendChannel;
+class FrontendRouter;
+class PlaywrightFrontendDispatcher;
+}
+
+namespace PAL {
+class SessionID;
+}
+
+namespace WebKit {
+class OverridenGeolocationProvider;
+}
+
+namespace WTF {
+template<typename T> struct IsDeprecatedWeakRefSmartPointerException;
+template<> struct IsDeprecatedWeakRefSmartPointerException<WebKit::OverridenGeolocationProvider> : std::true_type { };
+}
+
+namespace WebKit {
+
+class WebFrameProxy;
+
+class InspectorPlaywrightAgent final
+ : public WebPageInspectorControllerObserver
+ , public Inspector::PlaywrightBackendDispatcherHandler
+ , public DownloadInstrumentation {
+ WTF_MAKE_NONCOPYABLE(InspectorPlaywrightAgent);
+ WTF_DEPRECATED_MAKE_FAST_ALLOCATED(InspectorPlaywrightAgent);
+public:
+ explicit InspectorPlaywrightAgent(std::unique_ptr<InspectorPlaywrightAgentClient> client);
+ ~InspectorPlaywrightAgent() override;
+
+ // Transport
+ void connectFrontend(Inspector::FrontendChannel&);
+ void disconnectFrontend();
+ void dispatchMessageFromFrontend(const String& message);
+
+private:
+ class BrowserContextDeletion;
+ class PageProxyChannel;
+ class TargetHandler;
+
+ // WebPageInspectorControllerObserver
+ void didCreateInspectorController(WebPageProxy&) override;
+ void willDestroyInspectorController(WebPageProxy&) override;
+ void didFailProvisionalLoad(WebPageProxy&, WebCore::NavigationIdentifier navigationID, const String& error) override;
+ void willCreateNewPage(WebPageProxy&, const WebCore::WindowFeatures&, const URL&) override;
+
+ // PlaywrightDispatcherHandler
+ Inspector::Protocol::ErrorStringOr<void> enable() override;
+ Inspector::Protocol::ErrorStringOr<void> disable() override;
+ Inspector::Protocol::ErrorStringOr<String> getInfo() override;
+ void close(Ref<CloseCallback>&&) override;
+ Inspector::Protocol::ErrorStringOr<String /* browserContextID */> createContext(const String& proxyServer, const String& proxyBypassList, std::optional<bool>&& enableStoragePartitioning) override;
+ void deleteContext(const String& browserContextID, Ref<DeleteContextCallback>&& callback) override;
+ Inspector::Protocol::ErrorStringOr<String /* pageProxyID */> createPage(const String& browserContextID) override;
+ void navigate(const String& url, const String& pageProxyID, const String& frameId, const String& referrer, Ref<NavigateCallback>&&) override;
+ Inspector::Protocol::ErrorStringOr<void> grantFileReadAccess(const String& pageProxyID, Ref<JSON::Array>&& paths) override;
+ void takePageScreenshot(const String& pageProxyID, int x, int y, int width, int height, std::optional<bool>&& omitDeviceScaleFactor, Ref<TakePageScreenshotCallback>&&) override;
+ Inspector::Protocol::ErrorStringOr<void> setIgnoreCertificateErrors(const String& browserContextID, bool ignore) override;
+ Inspector::Protocol::ErrorStringOr<void> setPageZoomFactor(const String& pageProxyID, double zoomFactor) override;
+
+ void getAllCookies(const String& browserContextID, Ref<GetAllCookiesCallback>&&) override;
+ void setCookies(const String& browserContextID, Ref<JSON::Array>&& in_cookies, Ref<SetCookiesCallback>&&) override;
+ void deleteAllCookies(const String& browserContextID, Ref<DeleteAllCookiesCallback>&&) override;
+
+ Inspector::Protocol::ErrorStringOr<void> setGeolocationOverride(const String& browserContextID, RefPtr<JSON::Object>&& geolocation) override;
+ Inspector::Protocol::ErrorStringOr<void> setLanguages(Ref<JSON::Array>&& languages, const String& browserContextID) override;
+ Inspector::Protocol::ErrorStringOr<void> setDownloadBehavior(const String& behavior, const String& downloadPath, const String& browserContextID) override;
+ Inspector::Protocol::ErrorStringOr<void> cancelDownload(const String& uuid) override;
+ void clearMemoryCache(const String& browserContextID, Ref<ClearMemoryCacheCallback>&&) override;
+
+ // DownloadInstrumentation
+ void downloadCreated(const String& uuid, const WebCore::ResourceRequest&, const FrameInfoData& frameInfoData, WebPageProxy* page, RefPtr<DownloadProxy> download) override;
+ void downloadFilenameSuggested(const String& uuid, const String& suggestedFilename) override;
+ void downloadFinished(const String& uuid, const String& error) override;
+
+ BrowserContext* getExistingBrowserContext(const String& browserContextID);
+ BrowserContext* lookupBrowserContext(Inspector::ErrorString&, const String& browserContextID);
+ WebFrameProxy* frameForID(const String& frameID, String& error);
+ void closeImpl(Function<void(String)>&&);
+
+ Inspector::FrontendChannel* m_frontendChannel { nullptr };
+ Ref<Inspector::FrontendRouter> m_frontendRouter;
+ Ref<Inspector::BackendDispatcher> m_backendDispatcher;
+ std::unique_ptr<InspectorPlaywrightAgentClient> m_client;
+ std::unique_ptr<Inspector::PlaywrightFrontendDispatcher> m_frontendDispatcher;
+ Ref<Inspector::PlaywrightBackendDispatcher> m_playwrightDispatcher;
+ UncheckedKeyHashMap<String, std::unique_ptr<PageProxyChannel>> m_pageProxyChannels;
+ BrowserContext* m_defaultContext;
+ UncheckedKeyHashMap<String, RefPtr<DownloadProxy>> m_downloads;
+ UncheckedKeyHashMap<String, std::unique_ptr<BrowserContext>> m_browserContexts;
+ UncheckedKeyHashMap<String, std::unique_ptr<BrowserContextDeletion>> m_browserContextDeletions;
+ bool m_isEnabled { false };
+};
+
+} // namespace WebKit
+
+#endif // ENABLE(REMOTE_INSPECTOR)
diff --git a/Source/WebKit/UIProcess/InspectorPlaywrightAgentClient.h b/Source/WebKit/UIProcess/InspectorPlaywrightAgentClient.h
new file mode 100644
index 0000000000000000000000000000000000000000..af71e4077eb0c6f95396de7bfef89a3efb5f12d9
--- /dev/null
+++ b/Source/WebKit/UIProcess/InspectorPlaywrightAgentClient.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2019 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(REMOTE_INSPECTOR)
+
+#include <memory>
+#include <pal/SessionID.h>
+#include <WebCore/IntRect.h>
+#include <wtf/Forward.h>
+#include <wtf/HashSet.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/RefCounted.h>
+#include <wtf/WeakPtr.h>
+
+namespace WebKit {
+
+class OverridenGeolocationProvider;
+class WebsiteDataStore;
+class WebPageProxy;
+class WebProcessPool;
+
+class BrowserContext {
+ WTF_MAKE_NONCOPYABLE(BrowserContext);
+ WTF_DEPRECATED_MAKE_FAST_ALLOCATED(BrowserContext);
+public:
+ BrowserContext();
+ ~BrowserContext();
+
+ RefPtr<WebsiteDataStore> dataStore;
+ RefPtr<WebProcessPool> processPool;
+ HashSet<WebPageProxy*> pages;
+ WeakPtr<OverridenGeolocationProvider> geolocationProvider;
+ std::optional<bool> enableStoragePartitioning;
+};
+
+class InspectorPlaywrightAgentClient {
+public:
+ virtual ~InspectorPlaywrightAgentClient() = default;
+ virtual RefPtr<WebKit::WebPageProxy> createPage(WTF::String& error, const BrowserContext& context) = 0;
+ virtual void closeBrowser() = 0;
+ virtual std::unique_ptr<BrowserContext> createBrowserContext(WTF::String& error, const WTF::String& proxyServer, const WTF::String& proxyBypassList) = 0;
+ virtual void deleteBrowserContext(WTF::String& error, PAL::SessionID) = 0;
+#if PLATFORM(COCOA) || PLATFORM(GTK) || PLATFORM(WPE)
+ virtual void takePageScreenshot(WebPageProxy&, WebCore::IntRect&& clip, bool nominalResolution, CompletionHandler<void(const String&, const String&)>&& completionHandler) = 0;
+#endif
+};
+
+} // namespace WebKit
+
+#endif // ENABLE(REMOTE_INSPECTOR)
diff --git a/Source/WebKit/UIProcess/Launcher/glib/ProcessLauncherGLib.cpp b/Source/WebKit/UIProcess/Launcher/glib/ProcessLauncherGLib.cpp
index 9e0f05585ae96f4ec9ab2390cb015b5307fe85e6..048dfad9f9221fc5389de5d7874a0a67ec61499a 100644
--- a/Source/WebKit/UIProcess/Launcher/glib/ProcessLauncherGLib.cpp
+++ b/Source/WebKit/UIProcess/Launcher/glib/ProcessLauncherGLib.cpp
@@ -160,6 +160,13 @@ void ProcessLauncher::launchProcess()
nargs++;
}
#endif
+// Playwright begin
+ bool enableSharedArrayBuffer = false;
+ if (m_launchOptions.processType == ProcessLauncher::ProcessType::Web && m_client && m_client->shouldEnableSharedArrayBuffer()) {
+ enableSharedArrayBuffer = true;
+ nargs++;
+ }
+// Playwright end
Vector<char*> argv(nargs);
unsigned i = 0;
@@ -175,6 +182,10 @@ void ProcessLauncher::launchProcess()
if (configureJSCForTesting)
argv[i++] = const_cast<char*>("--configure-jsc-for-testing");
#endif
+// Playwright begin
+ if (enableSharedArrayBuffer)
+ argv[i++] = const_cast<char*>("--enable-shared-array-buffer");
+// Playwright end
argv[i++] = nullptr;
// Warning: we want GIO to be able to spawn with posix_spawn() rather than fork()/exec(), in
diff --git a/Source/WebKit/UIProcess/Launcher/win/ProcessLauncherWin.cpp b/Source/WebKit/UIProcess/Launcher/win/ProcessLauncherWin.cpp
index 6723ee0d9943be07bc8ad09d2b678838aca968df..0d7fb3c7b1a4c877a2ff2f2189d12c7d00eb8f7b 100644
--- a/Source/WebKit/UIProcess/Launcher/win/ProcessLauncherWin.cpp
+++ b/Source/WebKit/UIProcess/Launcher/win/ProcessLauncherWin.cpp
@@ -91,14 +91,21 @@ void ProcessLauncher::launchProcess()
commandLineBuilder.append(" -configure-jsc-for-testing"_s);
if (!m_client->isJITEnabled())
commandLineBuilder.append(" -disable-jit"_s);
+// Playwright begin
+ if (m_launchOptions.processType == ProcessLauncher::ProcessType::Web && m_client->shouldEnableSharedArrayBuffer())
+ commandLineBuilder.append(" -enable-shared-array-buffer"_s);
+// Playwright end
commandLineBuilder.append('\0');
auto commandLine = commandLineBuilder.toString().wideCharacters();
STARTUPINFO startupInfo { };
startupInfo.cb = sizeof(startupInfo);
- startupInfo.dwFlags = STARTF_USESHOWWINDOW;
+ startupInfo.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
startupInfo.wShowWindow = SW_HIDE;
+ startupInfo.hStdInput = ::GetStdHandle(STD_INPUT_HANDLE);
+ startupInfo.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE);
+ startupInfo.hStdError = ::GetStdHandle(STD_ERROR_HANDLE);
PROCESS_INFORMATION processInformation { };
BOOL result = ::CreateProcess(0, commandLine.mutableSpan().data(), 0, 0, true, 0, 0, 0, &startupInfo, &processInformation);
diff --git a/Source/WebKit/UIProcess/Media/RemoteMediaSessionManagerProxy.cpp b/Source/WebKit/UIProcess/Media/RemoteMediaSessionManagerProxy.cpp
index e9bf93632655ddfe5104808d67cb1e550e965098..a62ab1cb298654ea69cc8131f275d2cc7fe75602 100644
--- a/Source/WebKit/UIProcess/Media/RemoteMediaSessionManagerProxy.cpp
+++ b/Source/WebKit/UIProcess/Media/RemoteMediaSessionManagerProxy.cpp
@@ -31,6 +31,7 @@
#include "MessageSenderInlines.h"
#include "RemoteMediaSessionClientProxy.h"
#include "RemoteMediaSessionManagerMessages.h"
+#include "RemoteMediaSessionManager.h"
#include "RemoteMediaSessionManagerProxyMessages.h"
#include "RemoteMediaSessionProxy.h"
#include "RemoteMediaSessionState.h"
diff --git a/Source/WebKit/UIProcess/PageClient.h b/Source/WebKit/UIProcess/PageClient.h
index ec8a8accd195844f2ceb5fea0d73bc0ab50ce733..164e60cbc7fbd520d4d43a99021891c770f1fe3e 100644
--- a/Source/WebKit/UIProcess/PageClient.h
+++ b/Source/WebKit/UIProcess/PageClient.h
@@ -77,6 +77,11 @@
#include <WebCore/PlatformTextAlternatives.h>
#endif
+#if USE(SKIA)
+#include <skia/core/SkData.h>
+#include <skia/core/SkImage.h>
+#endif
+
OBJC_CLASS AVPlayerViewController;
OBJC_CLASS CALayer;
OBJC_CLASS NSFileWrapper;
@@ -400,7 +405,15 @@ public:
virtual void selectionDidChange() = 0;
#endif
-#if PLATFORM(COCOA) || PLATFORM(GTK) || PLATFORM(WPE)
+// Paywright begin
+#if PLATFORM(COCOA)
+ virtual RetainPtr<CGImageRef> takeSnapshotForAutomation() = 0;
+#elif PLATFORM(GTK) || PLATFORM(WPE)
+ virtual RefPtr<ViewSnapshot> takeViewSnapshot(std::optional<WebCore::IntRect>&&, bool nominalResolution = false) = 0;
+#endif
+// Paywright end
+
+#if PLATFORM(COCOA)
virtual RefPtr<ViewSnapshot> takeViewSnapshot(std::optional<WebCore::IntRect>&&) = 0;
#endif
diff --git a/Source/WebKit/UIProcess/PlaywrightFullScreenManagerProxyClient.cpp b/Source/WebKit/UIProcess/PlaywrightFullScreenManagerProxyClient.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..95b682567eba682f927317cd3327a531358dfebc
--- /dev/null
+++ b/Source/WebKit/UIProcess/PlaywrightFullScreenManagerProxyClient.cpp
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2023 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include "config.h"
+#include "PlaywrightFullScreenManagerProxyClient.h"
+
+#if ENABLE(FULLSCREEN_API)
+
+#include "WebPageProxy.h"
+
+namespace WebKit {
+using namespace WebCore;
+
+PlaywrightFullScreenManagerProxyClient::PlaywrightFullScreenManagerProxyClient(WebPageProxy& page)
+ : m_pageProxy(page)
+{
+}
+
+void PlaywrightFullScreenManagerProxyClient::enterFullScreen(WebCore::FloatSize, CompletionHandler<void(bool)>&& completionHandler)
+{
+ completionHandler(true);
+}
+
+void PlaywrightFullScreenManagerProxyClient::exitFullScreen(CompletionHandler<void()>&& completionHandler)
+{
+ completionHandler();
+}
+
+void PlaywrightFullScreenManagerProxyClient::beganEnterFullScreen(const WebCore::IntRect&, const WebCore::IntRect&, CompletionHandler<void(bool)>&& completionHandler)
+{
+ completionHandler(true);
+}
+
+void PlaywrightFullScreenManagerProxyClient::beganExitFullScreen(const WebCore::IntRect&, const WebCore::IntRect&, CompletionHandler<void()>&& completionHandler)
+{
+ completionHandler();
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(FULLSCREEN_API)
diff --git a/Source/WebKit/UIProcess/PlaywrightFullScreenManagerProxyClient.h b/Source/WebKit/UIProcess/PlaywrightFullScreenManagerProxyClient.h
new file mode 100644
index 0000000000000000000000000000000000000000..f855bb5ff6e91cc3383fb9a96d32392ff7aa5493
--- /dev/null
+++ b/Source/WebKit/UIProcess/PlaywrightFullScreenManagerProxyClient.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2023 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(FULLSCREEN_API)
+
+#include "WebFullScreenManagerProxy.h"
+
+namespace WebKit {
+
+class WebPageProxy;
+
+class PlaywrightFullScreenManagerProxyClient : public WebFullScreenManagerProxyClient {
+ WTF_DEPRECATED_MAKE_FAST_ALLOCATED(PlaywrightFullScreenManagerProxyClient);
+public:
+ PlaywrightFullScreenManagerProxyClient(WebPageProxy&);
+ ~PlaywrightFullScreenManagerProxyClient() override = default;
+
+private:
+ void closeFullScreenManager() override { }
+ bool isFullScreen() override { return m_isFullScreen; }
+ void enterFullScreen(WebCore::FloatSize mediaDimensions, CompletionHandler<void(bool)>&&) override;
+ void exitFullScreen(CompletionHandler<void()>&&) override;
+ void beganEnterFullScreen(const WebCore::IntRect& initialFrame, const WebCore::IntRect& finalFrame, CompletionHandler<void(bool)>&&) override;
+ void beganExitFullScreen(const WebCore::IntRect& initialFrame, const WebCore::IntRect& finalFrame, CompletionHandler<void()>&&) override;
+
+ WebPageProxy& m_pageProxy;
+ bool m_isFullScreen { false };
+};
+
+} // namespace WebKit
+
+#endif // ENABLE(FULLSCREEN_API)
diff --git a/Source/WebKit/UIProcess/ProvisionalFrameProxy.cpp b/Source/WebKit/UIProcess/ProvisionalFrameProxy.cpp
index 0e8f21982c6499e6886f5db6c193afc43663f29c..43ed4c8837479744a98ef76ceb2911c0e49d3f2b 100644
--- a/Source/WebKit/UIProcess/ProvisionalFrameProxy.cpp
+++ b/Source/WebKit/UIProcess/ProvisionalFrameProxy.cpp
@@ -25,6 +25,7 @@
#include "config.h"
#include "ProvisionalFrameProxy.h"
+#include "WebFrameProxy.h"
#include "FrameProcess.h"
#include "ProvisionalFrameCreationParameters.h"
diff --git a/Source/WebKit/UIProcess/ProvisionalPageProxy.h b/Source/WebKit/UIProcess/ProvisionalPageProxy.h
index 90b6b6b10906e9bf9f4229dc413421380be8a01a..0620c78e35e40e5b4997ab3813cac98cfdef7372 100644
--- a/Source/WebKit/UIProcess/ProvisionalPageProxy.h
+++ b/Source/WebKit/UIProcess/ProvisionalPageProxy.h
@@ -32,8 +32,10 @@
#include "ProcessThrottler.h"
#include "SandboxExtension.h"
#include "WebFramePolicyListenerProxy.h"
+#include "WebPageProxy.h"
#include "WebPageProxyIdentifier.h"
#include "WebPageProxyMessageReceiverRegistration.h"
+#include "WebsiteDataStore.h"
#include <WebCore/DiagnosticLoggingClient.h>
#include <WebCore/FrameIdentifier.h>
#include <WebCore/FrameLoaderClient.h>
@@ -74,7 +76,6 @@ class WebBackForwardListItem;
class WebFrameProxy;
class WebPageProxy;
class WebProcessProxy;
-class WebsiteDataStore;
struct FrameInfoData;
struct NavigationActionData;
diff --git a/Source/WebKit/UIProcess/RemoteInspectorPipe.cpp b/Source/WebKit/UIProcess/RemoteInspectorPipe.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a5fe95e4019e5b2b4e510174111166fb36089e9a
--- /dev/null
+++ b/Source/WebKit/UIProcess/RemoteInspectorPipe.cpp
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2019 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "RemoteInspectorPipe.h"
+
+#if ENABLE(REMOTE_INSPECTOR)
+
+#include "InspectorPlaywrightAgent.h"
+#include <JavaScriptCore/InspectorFrontendChannel.h>
+#include <wtf/Compiler.h>
+#include <wtf/MainThread.h>
+#include <wtf/RunLoop.h>
+#include <wtf/UniqueArray.h>
+#include <wtf/Vector.h>
+#include <wtf/WorkQueue.h>
+
+#if OS(UNIX)
+#include <stdio.h>
+#include <unistd.h>
+#endif
+
+#if PLATFORM(WIN)
+#include <io.h>
+#endif
+
+WTF_ALLOW_UNSAFE_BUFFER_USAGE_BEGIN
+
+namespace WebKit {
+
+namespace {
+
+const int readFD = 3;
+const int writeFD = 4;
+
+const size_t kWritePacketSize = 1 << 16;
+
+#if PLATFORM(WIN)
+HANDLE readHandle;
+HANDLE writeHandle;
+#endif
+
+size_t ReadBytes(void* buffer, size_t size, bool exact_size)
+{
+ size_t bytesRead = 0;
+ while (bytesRead < size) {
+#if PLATFORM(WIN)
+ DWORD sizeRead = 0;
+ bool hadError = !ReadFile(readHandle, static_cast<char*>(buffer) + bytesRead,
+ size - bytesRead, &sizeRead, nullptr);
+#else
+ int sizeRead = read(readFD, static_cast<char*>(buffer) + bytesRead,
+ size - bytesRead);
+ if (sizeRead < 0 && errno == EINTR)
+ continue;
+ bool hadError = sizeRead <= 0;
+#endif
+ if (hadError) {
+ return 0;
+ }
+ bytesRead += sizeRead;
+ if (!exact_size)
+ break;
+ }
+ return bytesRead;
+}
+
+void WriteBytes(const char* bytes, size_t size)
+{
+ size_t totalWritten = 0;
+ while (totalWritten < size) {
+ size_t length = size - totalWritten;
+ if (length > kWritePacketSize)
+ length = kWritePacketSize;
+#if PLATFORM(WIN)
+ DWORD bytesWritten = 0;
+ bool hadError = !WriteFile(writeHandle, bytes + totalWritten, static_cast<DWORD>(length), &bytesWritten, nullptr);
+#else
+ int bytesWritten = write(writeFD, bytes + totalWritten, length);
+ if (bytesWritten < 0 && errno == EINTR)
+ continue;
+ bool hadError = bytesWritten <= 0;
+#endif
+ if (hadError)
+ return;
+ totalWritten += bytesWritten;
+ }
+}
+
+} // namespace
+
+class RemoteInspectorPipe::RemoteFrontendChannel : public Inspector::FrontendChannel {
+ WTF_DEPRECATED_MAKE_FAST_ALLOCATED(RemoteInspectorPipe::RemoteFrontendChannel);
+public:
+ RemoteFrontendChannel()
+ : m_senderQueue(WorkQueue::create("Inspector pipe writer"_s))
+ {
+ }
+
+ ~RemoteFrontendChannel() override = default;
+
+ ConnectionType connectionType() const override
+ {
+ return ConnectionType::Remote;
+ }
+
+ void sendMessageToFrontend(const String& message) override
+ {
+ m_senderQueue->dispatch([message = message.isolatedCopy()]() {
+ auto utf8 = message.utf8();
+ WriteBytes(utf8.data(), utf8.length());
+ WriteBytes("\0", 1);
+ });
+ }
+
+private:
+ Ref<WorkQueue> m_senderQueue;
+};
+
+RemoteInspectorPipe::RemoteInspectorPipe(InspectorPlaywrightAgent& playwrightAgent)
+ : m_playwrightAgent(playwrightAgent)
+{
+ m_remoteFrontendChannel = makeUnique<RemoteFrontendChannel>();
+ start();
+}
+
+RemoteInspectorPipe::~RemoteInspectorPipe()
+{
+ stop();
+}
+
+bool RemoteInspectorPipe::start()
+{
+ if (m_receiverThread)
+ return true;
+
+#if PLATFORM(WIN)
+ readHandle = reinterpret_cast<HANDLE>(_get_osfhandle(readFD));
+ writeHandle = reinterpret_cast<HANDLE>(_get_osfhandle(writeFD));
+#endif
+
+ m_playwrightAgent.connectFrontend(*m_remoteFrontendChannel);
+ m_terminated = false;
+ m_receiverThread = Thread::create("Inspector pipe reader"_s, [this] {
+ workerRun();
+ });
+ return true;
+}
+
+void RemoteInspectorPipe::stop()
+{
+ if (!m_receiverThread)
+ return;
+
+ m_playwrightAgent.disconnectFrontend();
+
+ m_terminated = true;
+ m_receiverThread->waitForCompletion();
+ m_receiverThread = nullptr;
+}
+
+void RemoteInspectorPipe::workerRun()
+{
+ const size_t bufSize = 256 * 1024;
+ auto buffer = makeUniqueArray<char>(bufSize);
+ Vector<char> line;
+ while (!m_terminated) {
+ size_t size = ReadBytes(buffer.get(), bufSize, false);
+ if (!size) {
+ RunLoop::mainSingleton().dispatch([this] {
+ if (!m_terminated)
+ m_playwrightAgent.disconnectFrontend();
+ });
+ break;
+ }
+ size_t start = 0;
+ size_t end = line.size();
+ line.append(std::span { buffer.get(), size });
+ while (true) {
+ for (; end < line.size(); ++end) {
+ if (line[end] == '\0')
+ break;
+ }
+ if (end == line.size())
+ break;
+
+ if (end > start) {
+ String message = String::fromUTF8({ line.mutableSpan().data() + start, end - start });
+ RunLoop::mainSingleton().dispatch([this, message = WTF::move(message)] {
+ if (!m_terminated)
+ m_playwrightAgent.dispatchMessageFromFrontend(message);
+ });
+ }
+ ++end;
+ start = end;
+ }
+ if (start != 0 && start < line.size())
+ memmove(line.mutableSpan().data(), line.mutableSpan().data() + start, line.size() - start);
+ line.shrink(line.size() - start);
+ }
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(REMOTE_INSPECTOR)
+
+WTF_ALLOW_UNSAFE_BUFFER_USAGE_END
diff --git a/Source/WebKit/UIProcess/RemoteInspectorPipe.h b/Source/WebKit/UIProcess/RemoteInspectorPipe.h
new file mode 100644
index 0000000000000000000000000000000000000000..23626aa70d5a14e6484c81e05b146b375379be4f
--- /dev/null
+++ b/Source/WebKit/UIProcess/RemoteInspectorPipe.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2019 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(REMOTE_INSPECTOR)
+
+#include <wtf/Ref.h>
+#include <wtf/RefPtr.h>
+#include <wtf/Threading.h>
+
+namespace Inspector {
+class FrontendChannel;
+}
+
+namespace WebKit {
+
+class InspectorPlaywrightAgent;
+
+class RemoteInspectorPipe {
+ WTF_MAKE_NONCOPYABLE(RemoteInspectorPipe);
+ WTF_DEPRECATED_MAKE_FAST_ALLOCATED(RemoteInspectorPipe);
+public:
+ explicit RemoteInspectorPipe(InspectorPlaywrightAgent&);
+ ~RemoteInspectorPipe();
+
+private:
+ class RemoteFrontendChannel;
+
+ bool start();
+ void stop();
+
+ void workerRun();
+
+ RefPtr<Thread> m_receiverThread;
+ std::atomic<bool> m_terminated { false };
+ std::unique_ptr<Inspector::FrontendChannel> m_remoteFrontendChannel;
+ InspectorPlaywrightAgent& m_playwrightAgent;
+};
+
+} // namespace WebKit
+
+#endif // ENABLE(REMOTE_INSPECTOR)
diff --git a/Source/WebKit/UIProcess/RemoteLayerTree/RemoteAnimationTimeline.cpp b/Source/WebKit/UIProcess/RemoteLayerTree/RemoteAnimationTimeline.cpp
index 7ef986965d3fda34b4f09279c62bdad40712ab12..5e0bc508f72bbbd0bcb4bb1254782028961867a9 100644
--- a/Source/WebKit/UIProcess/RemoteLayerTree/RemoteAnimationTimeline.cpp
+++ b/Source/WebKit/UIProcess/RemoteLayerTree/RemoteAnimationTimeline.cpp
@@ -30,6 +30,7 @@
#import "RemoteAnimationUtilities.h"
#import <wtf/TZoneMallocInlines.h>
+#import <wtf/MonotonicTime.h>
namespace WebKit {
diff --git a/Source/WebKit/UIProcess/RemoteLayerTree/mac/RemoteScrollingTreeMac.mm b/Source/WebKit/UIProcess/RemoteLayerTree/mac/RemoteScrollingTreeMac.mm
index 07e7aec9d5f53dd4adfb83b6626f469621362663..18d049adb49ab565f60e9e1dded55da1a6aaaf3a 100644
--- a/Source/WebKit/UIProcess/RemoteLayerTree/mac/RemoteScrollingTreeMac.mm
+++ b/Source/WebKit/UIProcess/RemoteLayerTree/mac/RemoteScrollingTreeMac.mm
@@ -46,6 +46,7 @@
#import <pal/spi/cocoa/QuartzCoreSPI.h>
#import <wtf/SetForScope.h>
#import <wtf/TZoneMallocInlines.h>
+#import <wtf/SetForScope.h>
#import <wtf/text/TextStream.h>
namespace WebKit {
diff --git a/Source/WebKit/UIProcess/RemotePagePlaybackSessionManagerProxy.h b/Source/WebKit/UIProcess/RemotePagePlaybackSessionManagerProxy.h
index 3f6cd845733e2e8f5e25c318e7ab54f77032d4cf..e4399bfd734a28ef5df5ec855b7c78b46634c91d 100644
--- a/Source/WebKit/UIProcess/RemotePagePlaybackSessionManagerProxy.h
+++ b/Source/WebKit/UIProcess/RemotePagePlaybackSessionManagerProxy.h
@@ -28,11 +28,11 @@
#if PLATFORM(IOS_FAMILY) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE))
#include "MessageReceiver.h"
+#include "PlaybackSessionManagerProxy.h"
#include <WebCore/PageIdentifier.h>
namespace WebKit {
-class PlaybackSessionManagerProxy;
class WebProcessProxy;
class RemotePagePlaybackSessionManagerProxy : public IPC::MessageReceiver, public RefCounted<RemotePagePlaybackSessionManagerProxy> {
diff --git a/Source/WebKit/UIProcess/RemotePageProxy.cpp b/Source/WebKit/UIProcess/RemotePageProxy.cpp
index f7a0ee83fa8ee37d1c6d927f167b6e6bb647d817..919494d9b459a94d17617a0b514552e21cd21a29 100644
--- a/Source/WebKit/UIProcess/RemotePageProxy.cpp
+++ b/Source/WebKit/UIProcess/RemotePageProxy.cpp
@@ -37,6 +37,7 @@
#include "ProvisionalFrameProxy.h"
#include "RemotePageDrawingAreaProxy.h"
#include "RemotePageFullscreenManagerProxy.h"
+#include "RemotePagePlaybackSessionManagerProxy.h"
#include "RemotePageScreenOrientationManagerProxy.h"
#include "RemotePageVisitedLinkStoreRegistration.h"
#include "RemotePageWebDeviceOrientationUpdateProviderProxy.h"
@@ -56,6 +57,7 @@
#include <WebCore/RemoteUserInputEventData.h>
#include <wtf/TZoneMallocInlines.h>
+
#if ENABLE(FULLSCREEN_API)
#include "WebFullScreenManagerProxy.h"
#endif
diff --git a/Source/WebKit/UIProcess/TextExtractionAssertionScope.h b/Source/WebKit/UIProcess/TextExtractionAssertionScope.h
index 986c0812fedd2be938675ef5de41041e9fc76a0b..69da96c1e1ccb3b6d6b142ccb3b337f0bcb14957 100644
--- a/Source/WebKit/UIProcess/TextExtractionAssertionScope.h
+++ b/Source/WebKit/UIProcess/TextExtractionAssertionScope.h
@@ -25,13 +25,12 @@
#pragma once
+#include "WebPageProxy.h"
#include <wtf/FastMalloc.h>
#include <wtf/WeakPtr.h>
namespace WebKit {
-class WebPageProxy;
-
class TextExtractionAssertionScope {
WTF_MAKE_TZONE_ALLOCATED(TextExtractionAssertionScope);
WTF_MAKE_NONCOPYABLE(TextExtractionAssertionScope);
diff --git a/Source/WebKit/UIProcess/WebContextMenuProxy.h b/Source/WebKit/UIProcess/WebContextMenuProxy.h
index 364666d82ffd69aef6cb4f8d63b61ae13e163d87..a491699c43502e6feae3b3df73b3558a79bb73e3 100644
--- a/Source/WebKit/UIProcess/WebContextMenuProxy.h
+++ b/Source/WebKit/UIProcess/WebContextMenuProxy.h
@@ -51,6 +51,7 @@ public:
void deref() const final { RefCounted::deref(); }
virtual void show();
+ virtual void hide() {}
WebPageProxy* page() const { return m_page.get(); }
const FrameInfoData& frameInfo() const LIFETIME_BOUND { return m_frameInfo; }
diff --git a/Source/WebKit/UIProcess/WebPageInspectorEmulationAgent.cpp b/Source/WebKit/UIProcess/WebPageInspectorEmulationAgent.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..cc495bff7d10aeb071ba30002d292b82e26d51b7
--- /dev/null
+++ b/Source/WebKit/UIProcess/WebPageInspectorEmulationAgent.cpp
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2019 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebPageInspectorEmulationAgent.h"
+
+#include "APIPageConfiguration.h"
+#include "WebPageProxy.h"
+#include "WebPreferences.h"
+#include "PageClient.h"
+#include <JavaScriptCore/InspectorFrontendRouter.h>
+#include <WebCore/Credential.h>
+
+
+namespace WebKit {
+
+using namespace Inspector;
+
+WTF_MAKE_TZONE_ALLOCATED_IMPL(WebPageInspectorEmulationAgent);
+
+WebPageInspectorEmulationAgent::WebPageInspectorEmulationAgent(BackendDispatcher& backendDispatcher, WebPageProxy& page)
+ : InspectorAgentBase("Emulation"_s)
+ , m_backendDispatcher(EmulationBackendDispatcher::create(backendDispatcher, this))
+ , m_page(page)
+{
+}
+
+WebPageInspectorEmulationAgent::~WebPageInspectorEmulationAgent()
+{
+}
+
+void WebPageInspectorEmulationAgent::didCreateFrontendAndBackend()
+{
+}
+
+void WebPageInspectorEmulationAgent::willDestroyFrontendAndBackend(DisconnectReason)
+{
+ m_commandsToRunWhenShown.clear();
+}
+
+void WebPageInspectorEmulationAgent::setDeviceMetricsOverride(int width, int height, bool fixedlayout, std::optional<double>&& deviceScaleFactor, Ref<SetDeviceMetricsOverrideCallback>&& callback)
+{
+#if PLATFORM(GTK)
+ // On gtk, fixed layout doesn't work with compositing enabled
+ // FIXME: This turns off compositing forever, even if fixedLayout is disabled.
+ if (fixedlayout) {
+ auto copy = m_page.preferences().copy();
+ copy->setAcceleratedCompositingEnabled(false);
+ m_page.setPreferences(copy);
+ }
+#endif
+
+ if (deviceScaleFactor)
+ m_page.setCustomDeviceScaleFactor(deviceScaleFactor.value(), [] { });
+ m_page.setUseFixedLayout(fixedlayout);
+ if (!m_page.pageClient()->isActiveViewVisible() && m_page.configuration().relatedPage()) {
+ m_commandsToRunWhenShown.append([this, width, height, callback = WTF::move(callback)]() mutable {
+ setSize(width, height, WTF::move(callback));
+ });
+ } else {
+ setSize(width, height, WTF::move(callback));
+ }
+}
+
+void WebPageInspectorEmulationAgent::setSize(int width, int height, Ref<SetDeviceMetricsOverrideCallback>&& callback)
+{
+ platformSetSize(width, height, [callback = WTF::move(callback)](const String& error) {
+ if (error.isEmpty())
+ callback->sendSuccess();
+ else
+ callback->sendFailure(error);
+ });
+}
+
+Inspector::Protocol::ErrorStringOr<void> WebPageInspectorEmulationAgent::setJavaScriptEnabled(bool enabled)
+{
+ auto copy = m_page.preferences().copy();
+ copy->setJavaScriptEnabled(enabled);
+ m_page.setPreferences(copy);
+ return { };
+}
+
+Inspector::Protocol::ErrorStringOr<void> WebPageInspectorEmulationAgent::setAuthCredentials(const String& username, const String& password, const String& origin)
+{
+ if (username.isNull() && password.isNull())
+ m_page.setAuthCredentialsForAutomation(std::nullopt, std::nullopt);
+ else
+ m_page.setAuthCredentialsForAutomation(WebCore::Credential(username, password, WebCore::CredentialPersistence::Permanent), URL(origin));
+ return { };
+}
+
+Inspector::Protocol::ErrorStringOr<void> WebPageInspectorEmulationAgent::setActiveAndFocused(std::optional<bool>&& active)
+{
+ m_page.setActiveForAutomation(WTF::move(active));
+ return { };
+}
+
+Inspector::Protocol::ErrorStringOr<void> WebPageInspectorEmulationAgent::grantPermissions(const String& origin, Ref<JSON::Array>&& values)
+{
+ HashSet<String> set;
+ for (const auto& value : values.get()) {
+ String name;
+ if (!value->asString(name))
+ return makeUnexpected("Permission must be a string"_s);
+
+ set.add(name);
+ }
+ m_permissions.set(origin, WTF::move(set));
+ m_page.setPermissionsForAutomation(m_permissions);
+ return { };
+}
+
+Inspector::Protocol::ErrorStringOr<void> WebPageInspectorEmulationAgent::resetPermissions()
+{
+ m_permissions.clear();
+ m_page.setPermissionsForAutomation(m_permissions);
+ return { };
+}
+
+Inspector::Protocol::ErrorStringOr<void> WebPageInspectorEmulationAgent::setOrientationOverride(std::optional<int>&& angle)
+{
+#if ENABLE(ORIENTATION_EVENTS)
+ m_page.setOrientationOverride(WTF::move(angle));
+ return { };
+#else
+ UNUSED_PARAM(angle);
+ return makeUnexpected("Orientation events are disabled in this build"_s);
+#endif
+}
+
+
+void WebPageInspectorEmulationAgent::didShowPage()
+{
+ for (auto& command : m_commandsToRunWhenShown)
+ command();
+ m_commandsToRunWhenShown.clear();
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit/UIProcess/WebPageInspectorEmulationAgent.h b/Source/WebKit/UIProcess/WebPageInspectorEmulationAgent.h
new file mode 100644
index 0000000000000000000000000000000000000000..8c772fb1b67ec7d83cbe2394d8ab04787a4412a8
--- /dev/null
+++ b/Source/WebKit/UIProcess/WebPageInspectorEmulationAgent.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2019 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <JavaScriptCore/InspectorAgentBase.h>
+#include <JavaScriptCore/InspectorBackendDispatchers.h>
+
+#include <wtf/Forward.h>
+#include <wtf/Function.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/Vector.h>
+
+namespace Inspector {
+class BackendDispatcher;
+class FrontendChannel;
+class FrontendRouter;
+}
+
+namespace WebKit {
+
+class WebPageProxy;
+
+class WebPageInspectorEmulationAgent : public Inspector::InspectorAgentBase, public Inspector::EmulationBackendDispatcherHandler {
+ WTF_MAKE_NONCOPYABLE(WebPageInspectorEmulationAgent);
+ WTF_MAKE_TZONE_ALLOCATED(WebPageInspectorEmulationAgent);
+public:
+ WebPageInspectorEmulationAgent(Inspector::BackendDispatcher& backendDispatcher, WebPageProxy& page);
+ ~WebPageInspectorEmulationAgent() override;
+
+ void didCreateFrontendAndBackend() override;
+ void willDestroyFrontendAndBackend(Inspector::DisconnectReason) override;
+
+ void setDeviceMetricsOverride(int width, int height, bool fixedlayout, std::optional<double>&& deviceScaleFactor, Ref<SetDeviceMetricsOverrideCallback>&&) override;
+ Inspector::Protocol::ErrorStringOr<void> setJavaScriptEnabled(bool enabled) override;
+ Inspector::Protocol::ErrorStringOr<void> setAuthCredentials(const String&, const String&, const String&) override;
+ Inspector::Protocol::ErrorStringOr<void> setActiveAndFocused(std::optional<bool>&&) override;
+ Inspector::Protocol::ErrorStringOr<void> grantPermissions(const String& origin, Ref<JSON::Array>&& permissions) override;
+ Inspector::Protocol::ErrorStringOr<void> resetPermissions() override;
+ Inspector::Protocol::ErrorStringOr<void> setOrientationOverride(std::optional<int>&& angle) override;
+
+ void didShowPage();
+
+private:
+ void setSize(int width, int height, Ref<SetDeviceMetricsOverrideCallback>&& callback);
+ void platformSetSize(int width, int height, Function<void (const String& error)>&&);
+
+ Ref<Inspector::EmulationBackendDispatcher> m_backendDispatcher;
+ WebPageProxy& m_page;
+ Vector<Function<void()>> m_commandsToRunWhenShown;
+ UncheckedKeyHashMap<String, HashSet<String>> m_permissions;
+};
+
+} // namespace WebKit
diff --git a/Source/WebKit/UIProcess/WebPageInspectorInputAgent.cpp b/Source/WebKit/UIProcess/WebPageInspectorInputAgent.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a29ae94cda78928fab928bbdd250f8cd1c8b4cc5
--- /dev/null
+++ b/Source/WebKit/UIProcess/WebPageInspectorInputAgent.cpp
@@ -0,0 +1,397 @@
+/*
+ * Copyright (C) 2019 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "MessageSenderInlines.h"
+#include "WebPageInspectorInputAgent.h"
+
+#include "NativeWebKeyboardEvent.h"
+#include "NativeWebMouseEvent.h"
+#include "NativeWebWheelEvent.h"
+#include "WebPageProxy.h"
+#include "WebProcessProxy.h"
+#include "WebTouchEvent.h"
+#include "WebWheelEvent.h"
+#include <wtf/MathExtras.h>
+#include <wtf/HexNumber.h>
+#include <WebCore/Scrollbar.h>
+
+#include "WebPageMessages.h"
+
+namespace WebKit {
+
+using namespace Inspector;
+
+WTF_MAKE_TZONE_ALLOCATED_IMPL(WebPageInspectorInputAgent);
+
+namespace {
+
+template<class T>
+class CallbackList {
+ WTF_DEPRECATED_MAKE_FAST_ALLOCATED(CallbackList);
+public:
+ ~CallbackList()
+ {
+ for (const auto& callback : m_callbacks)
+ callback->sendFailure("Page closed"_s);
+ }
+
+ void append(Ref<T>&& callback)
+ {
+ m_callbacks.append(WTF::move(callback));
+ }
+
+ void sendSuccess()
+ {
+ for (const auto& callback : m_callbacks)
+ callback->sendSuccess();
+ m_callbacks.clear();
+ }
+
+private:
+ Vector<Ref<T>> m_callbacks;
+};
+
+} // namespace
+
+class WebPageInspectorInputAgent::KeyboardCallbacks : public CallbackList<Inspector::InputBackendDispatcherHandler::DispatchKeyEventCallback> {
+};
+
+class WebPageInspectorInputAgent::MouseCallbacks : public CallbackList<Inspector::InputBackendDispatcherHandler::DispatchMouseEventCallback> {
+};
+
+class WebPageInspectorInputAgent::WheelCallbacks : public CallbackList<Inspector::InputBackendDispatcherHandler::DispatchWheelEventCallback> {
+};
+
+WebPageInspectorInputAgent::WebPageInspectorInputAgent(Inspector::BackendDispatcher& backendDispatcher, WebPageProxy& page)
+ : InspectorAgentBase("Input"_s)
+ , m_backendDispatcher(InputBackendDispatcher::create(backendDispatcher, this))
+ , m_page(page)
+{
+}
+
+WebPageInspectorInputAgent::~WebPageInspectorInputAgent() = default;
+
+void WebPageInspectorInputAgent::didProcessAllPendingKeyboardEvents()
+{
+ m_keyboardCallbacks->sendSuccess();
+}
+
+void WebPageInspectorInputAgent::didProcessAllPendingMouseEvents()
+{
+ m_page.setInterceptDrags(false);
+ m_mouseCallbacks->sendSuccess();
+}
+
+void WebPageInspectorInputAgent::didProcessAllPendingWheelEvents()
+{
+ m_wheelCallbacks->sendSuccess();
+}
+
+void WebPageInspectorInputAgent::didCreateFrontendAndBackend()
+{
+ m_keyboardCallbacks = makeUnique<KeyboardCallbacks>();
+ m_mouseCallbacks = makeUnique<MouseCallbacks>();
+ m_wheelCallbacks = makeUnique<WheelCallbacks>();
+}
+
+void WebPageInspectorInputAgent::willDestroyFrontendAndBackend(Inspector::DisconnectReason)
+{
+ m_keyboardCallbacks = nullptr;
+ m_mouseCallbacks = nullptr;
+ m_wheelCallbacks = nullptr;
+}
+
+static String keyIdentifierForKey(const String& key)
+{
+ if (key.length() == 1)
+ return makeString("U+"_s, hex(toASCIIUpper(key.codeUnitAt(0)), 4));
+ if (key == "Delete"_s)
+ return "U+007F"_s;
+ if (key == "Backspace"_s)
+ return "U+0008"_s;
+ if (key == "ArrowUp"_s)
+ return "Up"_s;
+ if (key == "ArrowDown"_s)
+ return "Down"_s;
+ if (key == "ArrowLeft"_s)
+ return "Left"_s;
+ if (key == "ArrowRight"_s)
+ return "Right"_s;
+ if (key == "Tab"_s)
+ return "U+0009"_s;
+ if (key == "Pause"_s)
+ return "Pause"_s;
+ if (key == "ScrollLock"_s)
+ return "Scroll"_s;
+ return key;
+}
+
+void WebPageInspectorInputAgent::dispatchKeyEvent(const String& type, std::optional<int>&& modifiers, const String& text, const String& unmodifiedText, const String& code, const String& key, std::optional<int>&& windowsVirtualKeyCode, std::optional<int>&& nativeVirtualKeyCode, std::optional<bool>&& autoRepeat, std::optional<bool>&& isKeypad, std::optional<bool>&& isSystemKey, RefPtr<JSON::Array>&& commands, Ref<Inspector::InputBackendDispatcherHandler::DispatchKeyEventCallback>&& callback)
+{
+ WebEventType eventType;
+ if (type == "keyDown"_s) {
+ eventType = WebEventType::KeyDown;
+ } else if (type == "keyUp"_s) {
+ eventType = WebEventType::KeyUp;
+ } else {
+ callback->sendFailure("Unsupported event type."_s);
+ return;
+ }
+ OptionSet<WebEventModifier> eventModifiers;
+ if (modifiers)
+ eventModifiers = eventModifiers.fromRaw(*modifiers);
+ int eventWindowsVirtualKeyCode = 0;
+ if (windowsVirtualKeyCode)
+ eventWindowsVirtualKeyCode = *windowsVirtualKeyCode;
+ int eventNativeVirtualKeyCode = 0;
+ if (nativeVirtualKeyCode)
+ eventNativeVirtualKeyCode = *nativeVirtualKeyCode;
+ Vector<String> eventCommands;
+ if (commands) {
+ for (const auto& value : *commands) {
+ String command;
+ if (!value->asString(command)) {
+ callback->sendFailure("Command must be string"_s);
+ return;
+ }
+ eventCommands.append(command);
+ }
+ }
+
+ String keyIdentifier = keyIdentifierForKey(key);
+
+ bool eventIsAutoRepeat = false;
+ if (autoRepeat)
+ eventIsAutoRepeat = *autoRepeat;
+ bool eventIsKeypad = false;
+ if (isKeypad)
+ eventIsKeypad = *isKeypad;
+ bool eventIsSystemKey = false;
+ if (isSystemKey)
+ eventIsSystemKey = *isSystemKey;
+ MonotonicTime timestamp = MonotonicTime::now();
+
+ // cancel any active drag on Escape
+ if (eventType == WebEventType::KeyDown && key == "Escape"_s && m_page.cancelDragIfNeeded()) {
+ callback->sendSuccess();
+ return;
+ }
+
+ m_keyboardCallbacks->append(WTF::move(callback));
+ platformDispatchKeyEvent(
+ eventType,
+ text,
+ unmodifiedText,
+ key,
+ code,
+ keyIdentifier,
+ eventWindowsVirtualKeyCode,
+ eventNativeVirtualKeyCode,
+ eventIsAutoRepeat,
+ eventIsKeypad,
+ eventIsSystemKey,
+ eventModifiers,
+ eventCommands,
+ timestamp);
+}
+
+void WebPageInspectorInputAgent::dispatchMouseEvent(const String& type, int x, int y, std::optional<int>&& modifiers, const String& button, std::optional<int>&& buttons, std::optional<int>&& clickCount, std::optional<int>&& deltaX, std::optional<int>&& deltaY, Ref<DispatchMouseEventCallback>&& callback)
+{
+ WebEventType eventType = WebEventType::MouseMove;
+ if (type == "down"_s)
+ eventType = WebEventType::MouseDown;
+ else if (type == "up"_s)
+ eventType = WebEventType::MouseUp;
+ else if (type == "move"_s)
+ eventType = WebEventType::MouseMove;
+ else {
+ callback->sendFailure("Unsupported event type"_s);
+ return;
+ }
+
+ OptionSet<WebEventModifier> eventModifiers;
+ if (modifiers)
+ eventModifiers = eventModifiers.fromRaw(*modifiers);
+
+ WebMouseEventButton eventButton = WebMouseEventButton::None;
+ if (!!button) {
+ if (button == "left"_s)
+ eventButton = WebMouseEventButton::Left;
+ else if (button == "middle"_s)
+ eventButton = WebMouseEventButton::Middle;
+ else if (button == "right"_s)
+ eventButton = WebMouseEventButton::Right;
+ else if (button == "none"_s)
+ eventButton = WebMouseEventButton::None;
+ else {
+ callback->sendFailure("Unsupported eventButton"_s);
+ return;
+ }
+ }
+
+ unsigned short eventButtons = 0;
+ if (buttons)
+ eventButtons = *buttons;
+
+ int eventClickCount = 0;
+ if (clickCount)
+ eventClickCount = *clickCount;
+ int eventDeltaX = 0;
+ if (deltaX)
+ eventDeltaX = *deltaX;
+ int eventDeltaY = 0;
+ if (deltaY)
+ eventDeltaY = *deltaY;
+ m_mouseCallbacks->append(WTF::move(callback));
+
+ // Convert css coordinates to view coordinates (dip).
+ double totalScale = m_page.pageScaleFactor() * m_page.viewScaleFactor() * m_page.pageZoomFactor();
+ x = clampToInteger(roundf(x * totalScale));
+ y = clampToInteger(roundf(y * totalScale));
+ eventDeltaX = clampToInteger(roundf(eventDeltaX * totalScale));
+ eventDeltaY = clampToInteger(roundf(eventDeltaY * totalScale));
+
+ // We intercept any drags generated by this mouse event
+ // to prevent them from creating actual drags in the host
+ // operating system. This is turned off in the callback.
+ m_page.setInterceptDrags(true);
+#if PLATFORM(MAC)
+ UNUSED_VARIABLE(eventType);
+ UNUSED_VARIABLE(eventButton);
+ UNUSED_VARIABLE(eventClickCount);
+ platformDispatchMouseEvent(type, x, y, WTF::move(modifiers), button, WTF::move(clickCount), eventButtons);
+#elif PLATFORM(GTK) || PLATFORM(WPE) || PLATFORM(WIN)
+ MonotonicTime timestamp = MonotonicTime::now();
+ NativeWebMouseEvent event(
+ eventType,
+ eventButton,
+ eventButtons,
+ {x, y},
+ WebCore::IntPoint(),
+ eventDeltaX,
+ eventDeltaY,
+ 0,
+ eventClickCount,
+ eventModifiers,
+ timestamp);
+ m_page.handleMouseEvent(event);
+#endif
+}
+
+void WebPageInspectorInputAgent::dispatchTapEvent(int x, int y, std::optional<int>&& modifiers, Ref<DispatchTapEventCallback>&& callback)
+{
+ m_page.legacyMainFrameProcess().sendWithAsyncReply(Messages::WebPage::FakeTouchTap(WebCore::IntPoint(x, y), modifiers ? *modifiers : 0), [callback]() {
+ callback->sendSuccess();
+ }, m_page.webPageIDInMainFrameProcess());
+}
+
+void WebPageInspectorInputAgent::dispatchTouchEvent(const String& type, std::optional<int>&& modifiers, RefPtr<JSON::Array>&& in_touchPoints, Ref<DispatchTouchEventCallback>&& callback)
+{
+ float rotationAngle = 0.0;
+ float force = 1.0;
+ const WebCore::DoubleSize radius(1, 1);
+
+ uint8_t unsignedModifiers = modifiers ? static_cast<uint8_t>(*modifiers) : 0;
+ OptionSet<WebEventModifier> eventModifiers;
+ eventModifiers = eventModifiers.fromRaw(unsignedModifiers);
+
+ WebPlatformTouchPoint::State state;
+ if (type == "touchStart"_s)
+ state = WebPlatformTouchPoint::State::Pressed;
+ else if (type == "touchMove"_s)
+ state = WebPlatformTouchPoint::State::Moved;
+ else if (type == "touchEnd"_s)
+ state = WebPlatformTouchPoint::State::Released;
+ else if (type == "touchCancel"_s)
+ state = WebPlatformTouchPoint::State::Cancelled;
+ else {
+ callback->sendFailure("Unsupported event type"_s);
+ return;
+ }
+
+ Vector<WebPlatformTouchPoint> touchPoints;
+ for (unsigned i = 0; i < in_touchPoints->length(); ++i) {
+ RefPtr<JSON::Value> item = in_touchPoints->get(i);
+ RefPtr<JSON::Object> obj = item->asObject();
+ if (!obj) {
+ callback->sendFailure("Invalid TouchPoint format"_s);
+ return;
+ }
+ std::optional<int> x = obj->getInteger("x"_s);
+ if (!x) {
+ callback->sendFailure("TouchPoint does not have x"_s);
+ return;
+ }
+ std::optional<int> y = obj->getInteger("y"_s);
+ if (!y) {
+ callback->sendFailure("TouchPoint does not have y"_s);
+ return;
+ }
+ std::optional<int> optionalId = obj->getInteger("id"_s);
+ int id = optionalId ? *optionalId : 0;
+ const WebCore::IntPoint position(*x, *y);
+ touchPoints.append(WebPlatformTouchPoint(id, state, position, position, radius, rotationAngle, force));
+ }
+
+ WebTouchEvent touchEvent({WebEventType::TouchStart, eventModifiers, MonotonicTime::now()}, WTF::move(touchPoints), {}, {});
+ m_page.legacyMainFrameProcess().sendWithAsyncReply(Messages::WebPage::TouchEvent(touchEvent), [callback] (std::optional<WebEventType> eventType, bool) {
+ if (!eventType) {
+ callback->sendFailure("Failed to dispatch touch event."_s);
+ return;
+ }
+ callback->sendSuccess();
+ }, m_page.webPageIDInMainFrameProcess());
+}
+
+void WebPageInspectorInputAgent::dispatchWheelEvent(int x, int y, std::optional<int>&& modifiers, std::optional<int>&& deltaX, std::optional<int>&& deltaY, Ref<DispatchWheelEventCallback>&& callback)
+{
+ OptionSet<WebEventModifier> eventModifiers;
+ if (modifiers)
+ eventModifiers = eventModifiers.fromRaw(*modifiers);
+
+ float eventDeltaX = 0.0f;
+ if (deltaX)
+ eventDeltaX = *deltaX;
+ float eventDeltaY = 0.0f;
+ if (deltaY)
+ eventDeltaY = *deltaY;
+ m_wheelCallbacks->append(WTF::move(callback));
+
+ // Convert css coordinates to view coordinates (dip).
+ double totalScale = m_page.pageScaleFactor() * m_page.viewScaleFactor() * m_page.pageZoomFactor();
+ x = clampToInteger(roundf(x * totalScale));
+ y = clampToInteger(roundf(y * totalScale));
+
+ MonotonicTime timestamp = MonotonicTime::now();
+ WebCore::FloatSize delta = {-eventDeltaX, -eventDeltaY};
+ WebCore::FloatSize wheelTicks = delta;
+ wheelTicks.scale(1.0f / WebCore::Scrollbar::pixelsPerLineStep());
+ WebWheelEvent webEvent({WebEventType::Wheel, eventModifiers, timestamp}, {x, y}, {x, y}, delta, wheelTicks, WebWheelEvent::Granularity::ScrollByPixelWheelEvent);
+ NativeWebWheelEvent event(webEvent);
+ m_page.handleNativeWheelEvent(event);
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit/UIProcess/WebPageInspectorInputAgent.h b/Source/WebKit/UIProcess/WebPageInspectorInputAgent.h
new file mode 100644
index 0000000000000000000000000000000000000000..fb0cd51d362dfd8af2370f43ecb8835c96450f21
--- /dev/null
+++ b/Source/WebKit/UIProcess/WebPageInspectorInputAgent.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2019 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "WebEvent.h"
+#include "WebKeyboardEvent.h"
+#include "WebMouseEvent.h"
+#include <JavaScriptCore/InspectorAgentBase.h>
+#include <JavaScriptCore/InspectorBackendDispatchers.h>
+#include <wtf/Forward.h>
+#include <wtf/Noncopyable.h>
+
+namespace Inspector {
+class BackendDispatcher;
+class FrontendChannel;
+class FrontendRouter;
+}
+
+namespace WebKit {
+
+class NativeWebKeyboardEvent;
+class WebPageProxy;
+
+class WebPageInspectorInputAgent : public Inspector::InspectorAgentBase, public Inspector::InputBackendDispatcherHandler {
+ WTF_MAKE_NONCOPYABLE(WebPageInspectorInputAgent);
+ WTF_MAKE_TZONE_ALLOCATED(WebPageInspectorInputAgent);
+public:
+ WebPageInspectorInputAgent(Inspector::BackendDispatcher& backendDispatcher, WebPageProxy& page);
+ ~WebPageInspectorInputAgent() override;
+
+ void didProcessAllPendingKeyboardEvents();
+ void didProcessAllPendingMouseEvents();
+ void didProcessAllPendingWheelEvents();
+
+ void didCreateFrontendAndBackend() override;
+ void willDestroyFrontendAndBackend(Inspector::DisconnectReason) override;
+
+ // Protocol handler
+ void dispatchKeyEvent(const String& type, std::optional<int>&& modifiers, const String& text, const String& unmodifiedText, const String& code, const String& key, std::optional<int>&& windowsVirtualKeyCode, std::optional<int>&& nativeVirtualKeyCode, std::optional<bool>&& autoRepeat, std::optional<bool>&& isKeypad, std::optional<bool>&& isSystemKey, RefPtr<JSON::Array>&&, Ref<DispatchKeyEventCallback>&& callback) override;
+ void dispatchMouseEvent(const String& type, int x, int y, std::optional<int>&& modifiers, const String& button, std::optional<int>&& buttons, std::optional<int>&& clickCount, std::optional<int>&& deltaX, std::optional<int>&& deltaY, Ref<DispatchMouseEventCallback>&& callback) override;
+ void dispatchTapEvent(int x, int y, std::optional<int>&& modifiers, Ref<DispatchTapEventCallback>&& callback) override;
+ void dispatchTouchEvent(const String& type, std::optional<int>&& modifiers, RefPtr<JSON::Array>&& touchPoints, Ref<DispatchTouchEventCallback>&& callback) override;
+ void dispatchWheelEvent(int x, int y, std::optional<int>&& modifiers, std::optional<int>&& deltaX, std::optional<int>&& deltaY, Ref<DispatchWheelEventCallback>&& callback) override;
+
+private:
+ void platformDispatchKeyEvent(WebEventType type, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<WebEventModifier> modifiers, Vector<String>& commands, MonotonicTime timestamp);
+#if PLATFORM(MAC)
+ void platformDispatchMouseEvent(const String& type, int x, int y, std::optional<int>&& modifier, const String& button, std::optional<int>&& clickCount, unsigned short buttons);
+#endif
+
+ Ref<Inspector::InputBackendDispatcher> m_backendDispatcher;
+ WebPageProxy& m_page;
+ // Keep track of currently active modifiers across multiple keystrokes.
+ // Most platforms do not track current modifiers from synthesized events.
+ unsigned m_currentModifiers { 0 };
+ class KeyboardCallbacks;
+ std::unique_ptr<KeyboardCallbacks> m_keyboardCallbacks;
+ class MouseCallbacks;
+ std::unique_ptr<MouseCallbacks> m_mouseCallbacks;
+ class WheelCallbacks;
+ std::unique_ptr<WheelCallbacks> m_wheelCallbacks;
+};
+
+} // namespace WebKit
diff --git a/Source/WebKit/UIProcess/WebPageProxy.cpp b/Source/WebKit/UIProcess/WebPageProxy.cpp
index b51fd21469a35bea05d91465215e463dd9be078d..87789a4c6edfd8b48bcb3f083cc8b4edb3c5a498 100644
--- a/Source/WebKit/UIProcess/WebPageProxy.cpp
+++ b/Source/WebKit/UIProcess/WebPageProxy.cpp
@@ -219,6 +219,7 @@
#include <WebCore/CaptureDeviceManager.h>
#include <WebCore/CaptureDeviceWithCapabilities.h>
#include <WebCore/ChromeClient.h>
+#include <WebCore/Color.h>
#include <WebCore/CompositionHighlight.h>
#include <WebCore/CrossSiteNavigationDataTransfer.h>
#include <WebCore/CryptoKey.h>
@@ -232,6 +233,7 @@
#include <WebCore/DigitalCredentialsProtocols.h>
#include <WebCore/DigitalCredentialsRequestData.h>
#include <WebCore/DigitalCredentialsResponseData.h>
+#include <WebCore/DiagnosticLoggingResultType.h>
#include <WebCore/DragController.h>
#include <WebCore/DragData.h>
#include <WebCore/DragEventTargetData.h>
@@ -260,6 +262,7 @@
#include <WebCore/ModalContainerTypes.h>
#include <WebCore/NotImplemented.h>
#include <WebCore/OrganizationStorageAccessPromptQuirk.h>
+#include <WebCore/PageIdentifier.h>
#include <WebCore/PerformanceLoggingClient.h>
#include <WebCore/PermissionDescriptor.h>
#include <WebCore/PermissionState.h>
@@ -269,10 +272,12 @@
#include <WebCore/Quirks.h>
#include <WebCore/RealtimeMediaSourceCenter.h>
#include <WebCore/ReferrerPolicy.h>
+#include <WebCore/RegistrableDomain.h>
#include <WebCore/RemoteUserInputEventData.h>
#include <WebCore/RenderEmbeddedObject.h>
#include <WebCore/ResourceLoadStatistics.h>
#include <WebCore/RunJavaScriptParameters.h>
+#include <WebCore/ScreenOrientationType.h>
#include <WebCore/SecurityOrigin.h>
#include <WebCore/SecurityOriginData.h>
#include <WebCore/SerializedCryptoKeyWrap.h>
@@ -366,7 +371,7 @@
#include "ViewSnapshotStore.h"
#endif
-#if PLATFORM(GTK)
+#if PLATFORM(GTK) || PLATFORM(WPE)
#include <WebCore/SelectionData.h>
#endif
@@ -496,6 +501,17 @@ static constexpr Seconds tryCloseTimeoutDelay = 50_ms;
static constexpr Seconds audibleActivityClearDelay = 10_s;
#endif
+static WebCore::ScreenOrientationType toScreenOrientationType(int angle)
+{
+ if (angle == -90)
+ return WebCore::ScreenOrientationType::LandscapeSecondary;
+ if (angle == 180)
+ return WebCore::ScreenOrientationType::PortraitSecondary;
+ if (angle == 90)
+ return WebCore::ScreenOrientationType::LandscapePrimary;
+ return WebCore::ScreenOrientationType::PortraitPrimary;
+}
+
#if PLATFORM(COCOA)
static WorkQueue& sharedFileQueueSingleton()
{
@@ -1105,6 +1121,10 @@ WebPageProxy::~WebPageProxy()
ASSERT(webPageProxyMap().get(m_identifier) == this);
webPageProxyMap().remove(m_identifier);
+
+#if PLATFORM(COCOA)
+ releaseInspectorDragPasteboard();
+#endif
}
void WebPageProxy::addAllMessageReceivers()
@@ -1678,7 +1698,7 @@ void WebPageProxy::didAttachToRunningProcess()
#if ENABLE(FULLSCREEN_API)
ASSERT(!m_fullScreenManager);
- m_fullScreenManager = WebFullScreenManagerProxy::create(*this, protect(protect(pageClient())->fullScreenManagerProxyClient()).get());
+ m_fullScreenManager = WebFullScreenManagerProxy::create(*this, m_fullScreenManagerClientOverride ? *m_fullScreenManagerClientOverride : protect(protect(pageClient())->fullScreenManagerProxyClient()).get());
#endif
#if ENABLE(VIDEO_PRESENTATION_MODE)
ASSERT(!m_playbackSessionManager);
@@ -1710,7 +1730,7 @@ void WebPageProxy::didAttachToRunningProcess()
#endif
#if !PLATFORM(IOS_FAMILY)
- auto currentOrientation = WebCore::naturalScreenOrientationType();
+ auto currentOrientation = m_deviceOrientationOverride ? toScreenOrientationType(*m_deviceOrientationOverride) : WebCore::naturalScreenOrientationType();
#else
auto currentOrientation = toScreenOrientationType(m_deviceOrientation);
#endif
@@ -1850,6 +1870,7 @@ void WebPageProxy::initializeWebPage(const Site& site, WebCore::SandboxFlags eff
if (preferences->siteIsolationEnabled())
browsingContextGroup->addPage(*this);
process->send(Messages::WebProcess::CreateWebPage(m_webPageID, creationParameters(process, *protect(drawingArea()), m_mainFrame->frameID(), std::nullopt)), 0);
+ m_inspectorController->didInitializeWebPage();
#if ENABLE(WINDOW_PROXY_PROPERTY_ACCESS_NOTIFICATION)
internals().frameLoadStateObserver = WebPageProxyFrameLoadStateObserver::create();
@@ -2171,6 +2192,21 @@ WebProcessProxy& WebPageProxy::ensureRunningProcess()
return m_legacyMainFrameProcess;
}
+RefPtr<API::Navigation> WebPageProxy::loadRequestForInspector(WebCore::ResourceRequest&& request, WebFrameProxy* frame)
+{
+ if (!frame || frame == mainFrame())
+ return loadRequest(WTF::move(request), WebCore::ShouldOpenExternalURLsPolicy::ShouldNotAllow);
+
+ auto navigation = m_navigationState->createLoadRequestNavigation(legacyMainFrameProcess().coreProcessIdentifier(), ResourceRequest(request), m_backForwardList->currentItem());
+ LoadParameters loadParameters;
+ loadParameters.navigationID = navigation->navigationID();
+ loadParameters.request = WTF::move(request);
+ loadParameters.shouldOpenExternalURLsPolicy = WebCore::ShouldOpenExternalURLsPolicy::ShouldNotAllow;
+ loadParameters.shouldTreatAsContinuingLoad = ShouldTreatAsContinuingLoad::No;
+ m_legacyMainFrameProcess->send(Messages::WebPage::LoadRequestInFrameForInspector(WTF::move(loadParameters), frame->frameID()), m_webPageID);
+ return navigation;
+}
+
RefPtr<API::Navigation> WebPageProxy::loadRequest(WebCore::ResourceRequest&& request, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy, NavigationUpgradeToHTTPSBehavior navigationUpgradeToHTTPSBehavior, std::unique_ptr<NavigationActionData>&& lastNavigationAction, API::Object* userData, bool isRequestFromClientOrUserInput)
{
if (m_isClosed)
@@ -2296,11 +2332,29 @@ void WebPageProxy::loadRequestWithNavigationShared(Ref<WebProcessProxy>&& proces
navigation->setIsLoadedWithNavigationShared(true);
protectedProcess->markProcessAsRecentlyUsed();
- if (!protectedProcess->isLaunching() || !url.protocolIsFile())
- protectedProcess->send(Messages::WebPage::LoadRequest(WTF::move(loadParameters)), webPageID);
+
+ // Pause loading for new window navigation.
+ Function<void()> continuation = [
+ weakThis = WeakPtr { protectedThis },
+ weakProcess = WeakPtr { protectedProcess },
+ loadParameters = WTF::move(loadParameters),
+ webPageID,
+ url
+ ]() mutable {
+ RefPtr innerProtectedProcess = weakProcess.get();
+ RefPtr innerProtectedThis = weakThis.get();
+ if (!innerProtectedProcess || !innerProtectedThis)
+ return;
+ if (!innerProtectedProcess->isLaunching() || !url.protocolIsFile())
+ innerProtectedProcess->send(Messages::WebPage::LoadRequest(WTF::move(loadParameters)), webPageID);
+ else
+ innerProtectedProcess->send(Messages::WebPage::LoadRequestWaitingForProcessLaunch(WTF::move(loadParameters), innerProtectedThis->internals().pageLoadState.resourceDirectoryURL(), innerProtectedThis->identifier(), true), webPageID);
+ innerProtectedProcess->startResponsivenessTimer();
+ };
+ if (protectedThis->m_inspectorController->shouldPauseLoadRequest())
+ protectedThis->m_inspectorController->setContinueLoadingCallback(WTF::move(continuation));
else
- protectedProcess->send(Messages::WebPage::LoadRequestWaitingForProcessLaunch(WTF::move(loadParameters), protectedThis->pageLoadState().resourceDirectoryURL(), protectedThis->identifier(), true), webPageID);
- protectedProcess->startResponsivenessTimer();
+ continuation();
});
}
@@ -2896,6 +2950,53 @@ RefPtr<WebAutomationSession> WebPageProxy::activeAutomationSession() const
return m_configuration->processPool().automationSession();
}
+void WebPageProxy::setAuthCredentialsForAutomation(std::optional<WebCore::Credential>&& credentials, std::optional<URL>&& origin)
+{
+ m_credentialsForAutomation = WTF::move(credentials);
+ m_authOriginForAutomation = WTF::move(origin);
+}
+
+void WebPageProxy::setPermissionsForAutomation(const UncheckedKeyHashMap<String, HashSet<String>>& permissions)
+{
+ m_permissionsForAutomation = permissions;
+}
+
+void WebPageProxy::setOrientationOverride(std::optional<int>&& angle)
+{
+ m_deviceOrientationOverride = WTF::move(angle);
+ auto deviceOrientation = toScreenOrientationType(m_deviceOrientationOverride.value_or(0));
+ if (m_screenOrientationManager)
+ m_screenOrientationManager->setCurrentOrientation(deviceOrientation);
+ m_legacyMainFrameProcess->send(Messages::WebPage::SetDeviceOrientation(m_deviceOrientationOverride.value_or(0)), webPageIDInMainFrameProcess());
+}
+
+std::optional<bool> WebPageProxy::permissionForAutomation(const String& origin, const String& permission) const
+{
+ auto permissions = m_permissionsForAutomation.find(origin);
+ if (permissions == m_permissionsForAutomation.end())
+ permissions = m_permissionsForAutomation.find("*"_s);
+ if (permissions == m_permissionsForAutomation.end())
+ return std::nullopt;
+ return permissions->value.contains(permission);
+}
+
+void WebPageProxy::setActiveForAutomation(std::optional<bool> active) {
+ m_activeForAutomation = active;
+ OptionSet<ActivityState> state;
+ state.add(ActivityState::IsFocused);
+ state.add(ActivityState::WindowIsActive);
+ state.add(ActivityState::IsVisible);
+ state.add(ActivityState::IsVisibleOrOccluded);
+ activityStateDidChange(state);
+}
+
+void WebPageProxy::logToStderr(const String& str)
+{
+WTF_ALLOW_UNSAFE_BUFFER_USAGE_BEGIN
+ fprintf(stderr, "RENDERER: %s\n", str.utf8().data());
+WTF_ALLOW_UNSAFE_BUFFER_USAGE_END
+}
+
void WebPageProxy::sendMessageToInspectorFrontend(const String& targetId, const String& message)
{
m_inspectorController->sendMessageToInspectorFrontend(targetId, message);
@@ -3199,6 +3300,24 @@ void WebPageProxy::updateActivityState(OptionSet<ActivityState> flagsToUpdate)
bool wasVisible = isViewVisible();
RefPtr pageClient = this->pageClient();
internals().activityState.remove(flagsToUpdate);
+
+ if (m_activeForAutomation) {
+ if (*m_activeForAutomation) {
+ if (flagsToUpdate & ActivityState::IsFocused)
+ internals().activityState.add(ActivityState::IsFocused);
+ if (flagsToUpdate & ActivityState::WindowIsActive)
+ internals().activityState.add(ActivityState::WindowIsActive);
+ if (flagsToUpdate & ActivityState::IsVisible)
+ internals().activityState.add(ActivityState::IsVisible);
+ if (flagsToUpdate & ActivityState::IsVisibleOrOccluded)
+ internals().activityState.add(ActivityState::IsVisibleOrOccluded);
+ }
+ flagsToUpdate.remove(ActivityState::IsFocused);
+ flagsToUpdate.remove(ActivityState::WindowIsActive);
+ flagsToUpdate.remove(ActivityState::IsVisible);
+ flagsToUpdate.remove(ActivityState::IsVisibleOrOccluded);
+ }
+
if (flagsToUpdate & ActivityState::IsFocused && pageClient->isViewFocused())
internals().activityState.add(ActivityState::IsFocused);
if (flagsToUpdate & ActivityState::WindowIsActive && pageClient->isViewWindowActive())
@@ -3988,7 +4107,7 @@ void WebPageProxy::performDragOperation(DragData& dragData, const String& dragSt
if (!hasRunningProcess())
return;
-#if PLATFORM(GTK)
+#if PLATFORM(GTK) || PLATFORM(WPE)
URL url { dragData.asURL() };
if (url.protocolIsFile())
protect(legacyMainFrameProcess())->assumeReadAccessToBaseURL(*this, url.string(), [] { });
@@ -4031,6 +4150,8 @@ void WebPageProxy::performDragControllerAction(DragControllerAction action, Drag
if (!hasRunningProcess())
return;
+ m_dragEventsQueued++;
+
auto completionHandler = [this, protectedThis = Ref { *this }, action, dragData] (std::optional<WebCore::DragOperation> dragOperation, WebCore::DragHandlingMethod dragHandlingMethod, bool mouseIsOverFileInput, unsigned numberOfItemsToBeAccepted, const IntRect& insertionRect, const IntRect& editableElementRect, std::optional<WebCore::RemoteUserInputEventData> remoteUserInputEventData) mutable {
if (!m_pageClient)
return;
@@ -4042,7 +4163,7 @@ void WebPageProxy::performDragControllerAction(DragControllerAction action, Drag
dragData.setClientPosition(roundedIntPoint(remoteUserInputEventData->transformedPoint));
performDragControllerAction(action, dragData, remoteUserInputEventData->targetFrameID);
};
-#if PLATFORM(GTK)
+#if PLATFORM(GTK) || PLATFORM(WPE)
ASSERT(dragData.platformData());
sendWithAsyncReplyToProcessContainingFrame(frameID, Messages::WebPage::PerformDragControllerAction(action, dragData.clientPosition(), dragData.globalPosition(), dragData.draggingSourceOperationMask(), *dragData.platformData(), dragData.flags()), WTF::move(completionHandler));
#else
@@ -4077,17 +4198,36 @@ void WebPageProxy::didPerformDragControllerAction(std::optional<WebCore::DragOpe
setDragCaretRect(insertionRect);
if (RefPtr pageClient = this->pageClient())
pageClient->didPerformDragControllerAction();
+ m_dragEventsQueued--;
+ if (m_dragEventsQueued == 0 && internals().mouseEventQueue.isEmpty())
+ m_inspectorController->didProcessAllPendingMouseEvents();
}
#if PLATFORM(GTK) || PLATFORM(WPE)
void WebPageProxy::startDrag(SelectionData&& selectionData, OptionSet<WebCore::DragOperation> dragOperationMask, std::optional<ShareableBitmap::Handle>&& dragImageHandle, IntPoint&& dragImageHotspot)
{
+ if (m_interceptDrags) {
+ m_dragSelectionData = WTF::move(selectionData);
+ m_dragSourceOperationMask = dragOperationMask;
+ } else {
#if PLATFORM(GTK)
- if (RefPtr pageClient = this->pageClient()) {
- RefPtr dragImage = dragImageHandle ? ShareableBitmap::create(WTF::move(*dragImageHandle)) : nullptr;
- pageClient->startDrag(WTF::move(selectionData), dragOperationMask, WTF::move(dragImage), WTF::move(dragImageHotspot));
+ if (RefPtr pageClient = this->pageClient()) {
+ RefPtr dragImage = dragImageHandle ? ShareableBitmap::create(WTF::move(*dragImageHandle)) : nullptr;
+ pageClient->startDrag(WTF::move(selectionData), dragOperationMask, WTF::move(dragImage), WTF::move(dragImageHotspot));
+ }
+#endif
}
+ didStartDrag();
+}
#endif
+
+#if PLATFORM(WIN) && ENABLE(DRAG_SUPPORT)
+void WebPageProxy::startDrag(WebCore::DragDataMap&& dragDataMap)
+{
+ if (m_interceptDrags) {
+ m_dragSelectionData = WTF::move(dragDataMap);
+ m_dragSourceOperationMask = WebCore::anyDragOperation();
+ }
didStartDrag();
}
#endif
@@ -4108,6 +4248,24 @@ void WebPageProxy::dragEnded(const IntPoint& clientPosition, const IntPoint& glo
setDragCaretRect({ });
}
+bool WebPageProxy::cancelDragIfNeeded() {
+ if (!m_dragSelectionData)
+ return false;
+ m_dragSelectionData = std::nullopt;
+#if PLATFORM(COCOA)
+ releaseInspectorDragPasteboard();
+#endif
+
+ dragEnded(m_lastMousePositionForDrag, IntPoint(), m_dragSourceOperationMask);
+ return true;
+}
+
+#if !PLATFORM(COCOA)
+void WebPageProxy::setInterceptDrags(bool shouldIntercept) {
+ m_interceptDrags = shouldIntercept;
+}
+#endif
+
void WebPageProxy::didStartDrag(const std::optional<FrameIdentifier>& targetFrameID)
{
if (!hasRunningProcess())
@@ -4116,6 +4274,25 @@ void WebPageProxy::didStartDrag(const std::optional<FrameIdentifier>& targetFram
discardQueuedMouseEvents();
sendToProcessContainingFrame(targetFrameID, Messages::WebPage::DidStartDrag(targetFrameID));
+ if (m_interceptDrags) {
+ {
+#if PLATFORM(WIN) || PLATFORM(COCOA)
+ DragData dragData(*m_dragSelectionData, m_lastMousePositionForDrag, WebCore::IntPoint(), m_dragSourceOperationMask);
+#else
+ DragData dragData(&*m_dragSelectionData, m_lastMousePositionForDrag, WebCore::IntPoint(), m_dragSourceOperationMask);
+#endif
+ dragEntered(dragData);
+ }
+
+ {
+#if PLATFORM(WIN) || PLATFORM(COCOA)
+ DragData dragData(*m_dragSelectionData, m_lastMousePositionForDrag, WebCore::IntPoint(), m_dragSourceOperationMask);
+#else
+ DragData dragData(&*m_dragSelectionData, m_lastMousePositionForDrag, WebCore::IntPoint(), m_dragSourceOperationMask);
+#endif
+ dragUpdated(dragData);
+ }
+ }
}
void WebPageProxy::dragCancelled()
@@ -4300,26 +4477,47 @@ void WebPageProxy::processNextQueuedMouseEvent()
auto eventType = event->type();
startResponsivenessTimerForMouseEvent(*targetFrame, eventType);
- std::optional<Vector<SandboxExtension::Handle>> sandboxExtensions;
+ m_lastMousePositionForDrag = roundedIntPoint(event->position());
+ if (!m_dragSelectionData) {
+ std::optional<Vector<SandboxExtension::Handle>> sandboxExtensions;
#if PLATFORM(MAC)
- bool eventMayStartDrag = !m_currentDragOperation && eventType == WebEventType::MouseMove && event->button() != WebMouseEventButton::None;
- if (eventMayStartDrag)
- sandboxExtensions = SandboxExtension::createHandlesForMachLookup({ "com.apple.iconservices"_s, "com.apple.iconservices.store"_s }, process->auditToken(), SandboxExtension::MachBootstrapOptions::EnableMachBootstrap);
+ bool eventMayStartDrag = !m_currentDragOperation && eventType == WebEventType::MouseMove && event->button() != WebMouseEventButton::None;
+ if (eventMayStartDrag)
+ sandboxExtensions = SandboxExtension::createHandlesForMachLookup({ "com.apple.iconservices"_s, "com.apple.iconservices.store"_s }, process->auditToken(), SandboxExtension::MachBootstrapOptions::EnableMachBootstrap);
#endif
- auto eventWithCoalescedEvents = event;
+ auto eventWithCoalescedEvents = event;
- if (event->type() == WebEventType::MouseMove) {
- internals().coalescedMouseEvents.append(event);
- eventWithCoalescedEvents->setCoalescedEvents(internals().coalescedMouseEvents);
- }
+ if (event->type() == WebEventType::MouseMove) {
+ internals().coalescedMouseEvents.append(event);
+ eventWithCoalescedEvents->setCoalescedEvents(internals().coalescedMouseEvents);
+ }
- LOG_WITH_STREAM(MouseHandling, stream << "UIProcess: sent mouse event " << eventType << " (queue size " << internals().mouseEventQueue.size() << ", coalesced events size " << internals().coalescedMouseEvents.size() << ")");
+ LOG_WITH_STREAM(MouseHandling, stream << "UIProcess: sent mouse event " << eventType << " (queue size " << internals().mouseEventQueue.size() << ", coalesced events size " << internals().coalescedMouseEvents.size() << ")");
- sendMouseEvent(targetFrame->frameID(), eventWithCoalescedEvents, WTF::move(sandboxExtensions));
+ sendMouseEvent(m_mainFrame->frameID(), eventWithCoalescedEvents, WTF::move(sandboxExtensions));
- internals().coalescedMouseEvents.clear();
+ internals().coalescedMouseEvents.clear();
+ } else {
+#if PLATFORM(WIN) || PLATFORM(COCOA)
+ DragData dragData(*m_dragSelectionData, roundedIntPoint(event->position()), roundedIntPoint(event->globalPosition()), m_dragSourceOperationMask);
+#else
+ DragData dragData(&*m_dragSelectionData, roundedIntPoint(event->position()), roundedIntPoint(event->globalPosition()), m_dragSourceOperationMask);
+#endif
+ if (eventType == WebEventType::MouseMove) {
+ dragUpdated(dragData);
+ } else if (eventType == WebEventType::MouseUp) {
+ if (m_currentDragOperation && m_dragSourceOperationMask.containsAny(m_currentDragOperation.value())) {
+ SandboxExtension::Handle sandboxExtensionHandle;
+ Vector<SandboxExtension::Handle> sandboxExtensionsForUpload;
+ performDragOperation(dragData, ""_s, WTF::move(sandboxExtensionHandle), WTF::move(sandboxExtensionsForUpload));
+ }
+ m_dragSelectionData = std::nullopt;
+ dragEnded(roundedIntPoint(event->position()), roundedIntPoint(event->globalPosition()), m_dragSourceOperationMask);
+ }
+ didReceiveEventIPC(process->connection(), eventType, true, std::nullopt);
+ }
}
#if ENABLE(MAC_GESTURE_EVENTS)
@@ -4586,6 +4784,8 @@ void WebPageProxy::wheelEventHandlingCompleted(bool wasHandled)
if (RefPtr automationSession = m_configuration->processPool().automationSession())
automationSession->wheelEventsFlushedForPage(*this);
+
+ m_inspectorController->didProcessAllPendingWheelEvents();
}
void WebPageProxy::cacheWheelEventScrollingAccelerationCurve(const NativeWebWheelEvent& nativeWheelEvent)
@@ -4729,7 +4929,7 @@ static TrackingType mergeTrackingTypes(TrackingType a, TrackingType b)
void WebPageProxy::updateTouchEventTracking(const WebTouchEvent& touchStartEvent)
{
-#if PLATFORM(COCOA)
+#if PLATFORM(IOS_FAMILY)
for (auto& touchPoint : touchStartEvent.touchPoints()) {
auto location = touchPoint.locationInRootView();
auto update = [this, location](TrackingType& trackingType, EventTrackingRegions::EventType eventType) {
@@ -5571,6 +5771,7 @@ Ref<WebPageProxy> WebPageProxy::navigationOriginatingPage(const FrameInfoData& f
void WebPageProxy::receivedPolicyDecision(PolicyAction action, API::Navigation* navigation, std::optional<std::pair<Ref<API::WebsitePolicies>, Ref<WebProcessProxy>>>&& websitePoliciesAndProcess, Ref<API::NavigationAction>&& navigationAction, WillContinueLoadInNewProcess willContinueLoadInNewProcess, std::optional<SandboxExtension::Handle> sandboxExtensionHandle, std::optional<PolicyDecisionConsoleMessage>&& consoleMessage, CompletionHandler<void(PolicyDecision&&)>&& completionHandler)
{
+ m_inspectorController->didReceivePolicyDecision(action, navigation ? std::optional { navigation->navigationID() } : std::nullopt);
if (!hasRunningProcess())
return completionHandler(PolicyDecision { });
@@ -6671,6 +6872,7 @@ void WebPageProxy::viewScaleFactorDidChange(IPC::Connection& connection, double
MESSAGE_CHECK_BASE(scaleFactorIsValid(scaleFactor), connection);
if (!legacyMainFrameProcess().hasConnection(connection))
return;
+ m_viewScaleFactor = scaleFactor;
forEachWebContentProcess([&] (auto& process, auto pageID) {
if (&process == &legacyMainFrameProcess())
@@ -7524,6 +7726,7 @@ void WebPageProxy::didDestroyNavigationShared(Ref<WebProcessProxy>&& process, We
RefPtr protectedPageClient { pageClient() };
m_navigationState->didDestroyNavigation(process->coreProcessIdentifier(), navigationID);
+ m_inspectorController->didDestroyNavigation(navigationID);
}
void WebPageProxy::didStartProvisionalLoadForFrame(IPC::Connection& connection, FrameIdentifier frameID, FrameInfoData&& frameInfo, ResourceRequest&& request, std::optional<WebCore::NavigationIdentifier> navigationID, URL&& url, URL&& unreachableURL, const UserData& userData, WallTime timestamp)
@@ -7918,6 +8121,8 @@ void WebPageProxy::didFailProvisionalLoadForFrameShared(Ref<WebProcessProxy>&& p
m_failingProvisionalLoadURL = { };
m_allowsLoadingAlternateHTMLForFailingProvisionalLoadURL = true;
+ m_inspectorController->didFailProvisionalLoadForFrame(*navigationID, error);
+
// If the provisional page's load fails then we destroy the provisional page.
if (m_provisionalPage && m_provisionalPage->mainFrame() == &frame && (willContinueLoading == WillContinueLoading::No))
m_provisionalPage = nullptr;
@@ -9687,6 +9892,8 @@ void WebPageProxy::createNewPage(IPC::Connection& connection, WindowFeatures&& w
if (RefPtr page = originatingFrameInfo->page())
openerAppInitiatedState = page->lastNavigationWasAppInitiated();
+ m_inspectorController->willCreateNewPage(windowFeatures, request.url());
+
auto completionHandler = [
this,
protectedThis = Ref { *this },
@@ -9774,6 +9981,7 @@ void WebPageProxy::createNewPage(IPC::Connection& connection, WindowFeatures&& w
configuration->setInitialReferrerPolicy(effectiveReferrerPolicy);
configuration->setWindowFeatures(WTF::move(windowFeatures));
configuration->setOpenedMainFrameName(openedMainFrameName);
+ configuration->setOpenerPageForInspector(*this);
if (RefPtr openerFrame = WebFrameProxy::webFrame(originatingFrameInfoData.frameID); navigationActionData.hasOpener && openerFrame) {
configuration->setRelatedPage(*this);
@@ -9809,6 +10017,7 @@ void WebPageProxy::createNewPage(IPC::Connection& connection, WindowFeatures&& w
void WebPageProxy::showPage()
{
m_uiClient->showPage(this);
+ m_inspectorController->didShowPage();
}
bool WebPageProxy::hasOpenedPage() const
@@ -9952,6 +10161,10 @@ void WebPageProxy::closePage()
if (isClosed())
return;
+#if ENABLE(CONTEXT_MENUS)
+ if (m_activeContextMenu)
+ m_activeContextMenu->hide();
+#endif
WEBPAGEPROXY_RELEASE_LOG(Process, "closePage:");
if (RefPtr pageClient = this->pageClient())
pageClient->clearAllEditCommands();
@@ -9991,6 +10204,8 @@ void WebPageProxy::runJavaScriptAlert(IPC::Connection& connection, FrameIdentifi
auto showModal = [protectedThis = Ref { *this }](RefPtr<WebFrameProxy>&& frame, FrameInfoData&& frameInfo, String&& message, CompletionHandler<void()>&& reply) mutable {
protectedThis->runModalJavaScriptDialog(WTF::move(frame), WTF::move(frameInfo), WTF::move(message), [reply = WTF::move(reply)](WebPageProxy& page, WebFrameProxy* frame, FrameInfoData&& frameInfo, String&& message, CompletionHandler<void()>&& completion) mutable {
+ if (page.m_inspectorDialogAgent)
+ page.m_inspectorDialogAgent->javascriptDialogOpening("alert"_s, message);
page.m_uiClient->runJavaScriptAlert(page, WTF::move(message), frame, WTF::move(frameInfo), [reply = WTF::move(reply), completion = WTF::move(completion)]() mutable {
reply();
completion();
@@ -10024,6 +10239,8 @@ void WebPageProxy::runJavaScriptConfirm(IPC::Connection& connection, FrameIdenti
if (RefPtr automationSession = configuration().processPool().automationSession())
automationSession->willShowJavaScriptDialog(*this, message, std::nullopt);
}
+ if (m_inspectorDialogAgent)
+ m_inspectorDialogAgent->javascriptDialogOpening("confirm"_s, message);
auto showModal = [protectedThis = Ref { *this }](RefPtr<WebFrameProxy>&& frame, FrameInfoData&& frameInfo, String&& message, CompletionHandler<void(bool)>&& reply) mutable {
protectedThis->runModalJavaScriptDialog(WTF::move(frame), WTF::move(frameInfo), WTF::move(message), [reply = WTF::move(reply)](WebPageProxy& page, WebFrameProxy* frame, FrameInfoData&& frameInfo, String&& message, CompletionHandler<void()>&& completion) mutable {
@@ -10060,6 +10277,8 @@ void WebPageProxy::runJavaScriptPrompt(IPC::Connection& connection, FrameIdentif
if (RefPtr automationSession = configuration().processPool().automationSession())
automationSession->willShowJavaScriptDialog(*this, message, defaultValue);
}
+ if (m_inspectorDialogAgent)
+ m_inspectorDialogAgent->javascriptDialogOpening("prompt"_s, message, defaultValue);
auto showModal = [protectedThis = Ref { *this }](RefPtr<WebFrameProxy>&& frame, FrameInfoData&& frameInfo, String&& message, String&& defaultValue, CompletionHandler<void(const String&)>&& reply) mutable {
protectedThis->runModalJavaScriptDialog(WTF::move(frame), WTF::move(frameInfo), WTF::move(message), [reply = WTF::move(reply), defaultValue = WTF::move(defaultValue)](WebPageProxy& page, WebFrameProxy* frame, FrameInfoData&& frameInfo, String&& message, CompletionHandler<void()>&& completion) mutable {
@@ -10274,6 +10493,8 @@ void WebPageProxy::runBeforeUnloadConfirmPanel(IPC::Connection& connection, Fram
return;
}
}
+ if (m_inspectorDialogAgent)
+ m_inspectorDialogAgent->javascriptDialogOpening("beforeunload"_s, message);
// Since runBeforeUnloadConfirmPanel() can spin a nested run loop we need to turn off the responsiveness timer and the tryClose timer.
webProcess->stopResponsivenessTimer();
@@ -10963,6 +11184,11 @@ void WebPageProxy::resourceLoadDidCompleteWithError(ResourceLoadInfo&& loadInfo,
}
#if ENABLE(FULLSCREEN_API)
+void WebPageProxy::setFullScreenManagerClientOverride(std::unique_ptr<WebFullScreenManagerProxyClient>&& client)
+{
+ m_fullScreenManagerClientOverride = WTF::move(client);
+}
+
WebFullScreenManagerProxy* WebPageProxy::fullScreenManager()
{
return m_fullScreenManager.get();
@@ -11092,6 +11318,17 @@ void WebPageProxy::requestDOMPasteAccess(IPC::Connection& connection, DOMPasteAc
}
}
+ if (isControlledByAutomation()) {
+ DOMPasteAccessResponse response = DOMPasteAccessResponse::DeniedForGesture;
+ if (permissionForAutomation(originIdentifier, "clipboard-read"_s).value_or(false)) {
+ response = DOMPasteAccessResponse::GrantedForGesture;
+ // Grant access to general pasteboard.
+ willPerformPasteCommand(DOMPasteAccessCategory::General, [] () { }, frameID);
+ }
+ completionHandler(response);
+ return;
+ }
+
protect(pageClient())->requestDOMPasteAccess(pasteAccessCategory, requiresInteraction, elementRect, originIdentifier, WTF::move(completionHandler));
}
@@ -12074,6 +12311,8 @@ void WebPageProxy::mouseEventHandlingCompleted(std::optional<WebEventType> event
if (RefPtr automationSession = configuration().processPool().automationSession())
automationSession->mouseEventsFlushedForPage(*this);
didFinishProcessingAllPendingMouseEvents();
+ if (m_dragEventsQueued == 0)
+ m_inspectorController->didProcessAllPendingMouseEvents();
}
}
@@ -12132,6 +12371,7 @@ void WebPageProxy::keyEventHandlingCompleted(std::optional<WebEventType> eventTy
if (RefPtr automationSession = configuration().processPool().automationSession())
automationSession->keyboardEventsFlushedForPage(*this);
didFinishProcessingAllPendingKeyEvents();
+ m_inspectorController->didProcessAllPendingKeyboardEvents();
}
}
@@ -12576,7 +12816,10 @@ void WebPageProxy::dispatchProcessDidTerminate(WebProcessProxy& process, Process
protect(browsingContextGroup())->processDidTerminate(*this, process);
}
- bool handledByClient = false;
+ bool handledByClient = m_inspectorController->pageCrashed(reason);
+ if (handledByClient)
+ return;
+
if (m_loaderClient)
handledByClient = reason != ProcessTerminationReason::RequestedByClient && m_loaderClient->processDidCrash(*this);
else
@@ -13251,6 +13494,9 @@ WebPageCreationParameters WebPageProxy::creationParameters(WebProcessProxy& proc
parameters.allowPostingLegacySynchronousMessages = m_configuration->allowPostingLegacySynchronousMessages();
parameters.backgroundTextExtractionEnabled = m_configuration->backgroundTextExtractionEnabled();
+ parameters.deviceOrientationOverride = m_deviceOrientationOverride;
+ parameters.shouldPauseInInspectorWhenShown = m_inspectorController->shouldPauseInInspectorWhenShown();
+
#if ENABLE(APP_HIGHLIGHTS)
parameters.appHighlightsVisible = appHighlightsVisibility() ? HighlightVisibility::Visible : HighlightVisibility::Hidden;
#endif
@@ -13429,8 +13675,47 @@ void WebPageProxy::allowGamepadAccess()
#endif // ENABLE(GAMEPAD)
+bool WebPageProxy::shouldSendAutomationCredentialsForProtectionSpace(const WebProtectionSpace& protectionSpace)
+{
+ if (m_authOriginForAutomation.has_value() && !m_authOriginForAutomation.value().isEmpty()) {
+ switch (protectionSpace.serverType()) {
+ case WebCore::ProtectionSpace::ServerType::HTTP:
+ if (m_authOriginForAutomation.value().protocol() != "http"_s)
+ return false;
+ break;
+ case WebCore::ProtectionSpace::ServerType::HTTPS:
+ if (m_authOriginForAutomation.value().protocol() != "https"_s)
+ return false;
+ break;
+ default:
+ return false;
+ }
+
+ if (protectionSpace.host() != m_authOriginForAutomation.value().host())
+ return false;
+
+ if (protectionSpace.port() != m_authOriginForAutomation.value().port().value_or(0))
+ return false;
+ }
+ return true;
+}
+
void WebPageProxy::didReceiveAuthenticationChallengeProxy(Ref<AuthenticationChallengeProxy>&& authenticationChallenge, NegotiatedLegacyTLS negotiatedLegacyTLS)
{
+ if (authenticationChallenge->core().protectionSpace().authenticationScheme() == WebCore::ProtectionSpaceBaseAuthenticationScheme::ServerTrustEvaluationRequested && websiteDataStore().ignoreTLSErrors()) {
+ authenticationChallenge->listener().completeChallenge(AuthenticationChallengeDisposition::UseCredential, WebCore::Credential("accept server trust"_s, ""_s, WebCore::CredentialPersistence::None));
+ return;
+ }
+
+ if (m_credentialsForAutomation.has_value()) {
+ if (m_credentialsForAutomation->isEmpty() || authenticationChallenge->core().previousFailureCount() ||
+ !shouldSendAutomationCredentialsForProtectionSpace(*authenticationChallenge->protectionSpace())) {
+ authenticationChallenge->listener().completeChallenge(AuthenticationChallengeDisposition::PerformDefaultHandling);
+ return;
+ }
+ authenticationChallenge->listener().completeChallenge(AuthenticationChallengeDisposition::UseCredential, *m_credentialsForAutomation);
+ return;
+ }
if (negotiatedLegacyTLS == NegotiatedLegacyTLS::Yes) {
m_navigationClient->shouldAllowLegacyTLS(*this, authenticationChallenge.get(), [this, protectedThis = Ref { *this }, authenticationChallenge] (bool shouldAllowLegacyTLS) {
if (shouldAllowLegacyTLS)
@@ -13526,6 +13811,12 @@ void WebPageProxy::requestGeolocationPermissionForFrame(IPC::Connection& connect
request->deny();
};
+ if (isControlledByAutomation()) {
+ auto securityOrigin = frameInfo.securityOrigin.securityOrigin();
+ completionHandler(permissionForAutomation(securityOrigin->toString(), "geolocation"_s).value_or(false));
+ return;
+ }
+
// FIXME: Once iOS migrates to the new WKUIDelegate SPI, clean this up
// and make it one UIClient call that calls the completionHandler with false
// if there is no delegate instead of returning the completionHandler
@@ -13634,6 +13925,12 @@ void WebPageProxy::queryPermission(const ClientOrigin& clientOrigin, const Permi
shouldChangeDeniedToPrompt = false;
if (sessionID().isEphemeral()) {
+ auto permission = permissionForAutomation(clientOrigin.topOrigin.toString(), name);
+ if (permission.has_value()) {
+ completionHandler(permission.value() ? PermissionState::Granted : PermissionState::Denied);
+ return;
+ }
+
completionHandler(shouldChangeDeniedToPrompt ? PermissionState::Prompt : PermissionState::Denied);
return;
}
@@ -13648,6 +13945,12 @@ void WebPageProxy::queryPermission(const ClientOrigin& clientOrigin, const Permi
return;
}
+ auto permission = permissionForAutomation(clientOrigin.topOrigin.toString(), name);
+ if (permission.has_value()) {
+ completionHandler(permission.value() ? PermissionState::Granted : PermissionState::Denied);
+ return;
+ }
+
if (!canAPISucceed) {
completionHandler(shouldChangeDeniedToPrompt ? PermissionState::Prompt : PermissionState::Denied);
return;
diff --git a/Source/WebKit/UIProcess/WebPageProxy.h b/Source/WebKit/UIProcess/WebPageProxy.h
index c304883cbac2d21900bd09c7d7bc6e9701597e15..7083a7d4aba95ae552cbeb2b20440448a740ddca 100644
--- a/Source/WebKit/UIProcess/WebPageProxy.h
+++ b/Source/WebKit/UIProcess/WebPageProxy.h
@@ -28,6 +28,7 @@
// Including more headers here slows down build times a lot.
// Use forward declarations and WebPageProxyInternals.h instead.
#include "APIObject.h"
+#include "APIWebsitePolicies.h"
#include "MessageReceiver.h"
#include <wtf/ApproximateTime.h>
#include <wtf/CheckedRef.h>
@@ -40,6 +41,20 @@
#include <wtf/SwiftBridging.h>
#include <wtf/UniqueRef.h>
#include <wtf/WeakHashSet.h>
+#include "InspectorDialogAgent.h"
+#include "WebProtectionSpace.h"
+#include <WebCore/Credential.h>
+#include <WebCore/IntRect.h>
+#include "WebPageDiagnosticLoggingClient.h"
+#include "WebPageInjectedBundleClient.h"
+#include "WebPreferences.h"
+#include "ViewSnapshotStore.h"
+
+OBJC_CLASS NSPasteboard;
+
+#if PLATFORM(GTK) || PLATFORM(WPE)
+#include <WebCore/SelectionData.h>
+#endif
#if USE(COORDINATED_GRAPHICS) && HAVE(DISPLAY_LINK)
#include "DisplayLinkObserverID.h"
@@ -127,6 +142,7 @@ class DragData;
class Exception;
class FloatPoint;
class FloatQuad;
+typedef HashMap<unsigned, Vector<String>> DragDataMap;
class FloatRect;
class FloatSize;
class FontAttributeChanges;
@@ -839,6 +855,8 @@ public:
RefPtr<WebAutomationSession> activeAutomationSession() const;
+ InspectorDialogAgent* inspectorDialogAgent() { return m_inspectorDialogAgent; }
+ void setInspectorDialogAgent(InspectorDialogAgent * dialogAgent) { m_inspectorDialogAgent = dialogAgent; }
WebPageInspectorController& inspectorController() LIFETIME_BOUND { return m_inspectorController.get(); }
#if PLATFORM(IOS_FAMILY)
@@ -872,6 +890,7 @@ public:
bool NODELETE hasSleepDisabler() const;
#if ENABLE(FULLSCREEN_API)
+ void setFullScreenManagerClientOverride(std::unique_ptr<WebFullScreenManagerProxyClient>&&);
WebFullScreenManagerProxy* NODELETE fullScreenManager();
void setFullScreenClientForTesting(std::unique_ptr<WebKit::WebFullScreenManagerProxyClient>&&);
@@ -940,6 +959,12 @@ public:
void setPageLoadStateObserver(RefPtr<PageLoadStateObserverBase>&&);
+ void setAuthCredentialsForAutomation(std::optional<WebCore::Credential>&&, std::optional<URL>&&);
+ void setPermissionsForAutomation(const UncheckedKeyHashMap<String, HashSet<String>>&);
+ void setOrientationOverride(std::optional<int>&& angle);
+ void setActiveForAutomation(std::optional<bool> active);
+ void logToStderr(const String& str);
+
void initializeWebPage(const WebCore::Site&, WebCore::SandboxFlags, WebCore::ReferrerPolicy);
void setDrawingArea(RefPtr<DrawingAreaProxy>&&);
@@ -971,6 +996,8 @@ public:
RefPtr<API::Navigation> loadRequest(WebCore::ResourceRequest&&, WebCore::ShouldOpenExternalURLsPolicy, WebCore::NavigationUpgradeToHTTPSBehavior);
RefPtr<API::Navigation> loadRequest(WebCore::ResourceRequest&&, WebCore::ShouldOpenExternalURLsPolicy, WebCore::NavigationUpgradeToHTTPSBehavior, std::unique_ptr<NavigationActionData>&&, API::Object* userData = nullptr, bool isRequestFromClientOrUserInput = true);
+ RefPtr<API::Navigation> loadRequestForInspector(WebCore::ResourceRequest&&, WebFrameProxy*);
+
RefPtr<API::Navigation> loadFile(const String& fileURL, const String& resourceDirectoryURL, bool isAppInitiated = true, API::Object* userData = nullptr);
RefPtr<API::Navigation> loadData(Ref<WebCore::SharedBuffer>&&, const String& MIMEType, const String& encoding, const String& baseURL, API::Object* userData = nullptr);
RefPtr<API::Navigation> loadData(Ref<WebCore::SharedBuffer>&&, const String& MIMEType, const String& encoding, const String& baseURL, API::Object* userData, WebCore::ShouldOpenExternalURLsPolicy);
@@ -1072,6 +1099,7 @@ public:
void restoreSelectionInFocusedEditableElement();
PageClient* NODELETE pageClient() const;
+ bool hasPageClient() const { return !!m_pageClient; }
void setViewNeedsDisplay(const WebCore::Region&);
void requestScroll(const WebCore::FloatPoint& scrollPosition, const WebCore::IntPoint& scrollOrigin, WebCore::ScrollIsAnimated, WebCore::InterruptScrollAnimation);
@@ -1755,11 +1783,14 @@ public:
void didStartDrag(const std::optional<WebCore::FrameIdentifier>& = std::nullopt);
void dragCancelled();
void setDragCaretRect(const WebCore::IntRect&);
+ void setInterceptDrags(bool shouldIntercept);
+ bool cancelDragIfNeeded();
#if PLATFORM(COCOA)
void propagateDragAndDrop(DragEventForwardingData&&, const String&, WebCore::DragData&&);
void startDrag(const WebCore::DragItem&, WebCore::ShareableBitmapHandle&& dragImageHandle, const std::optional<WebCore::NodeIdentifier>&, const std::optional<WebCore::FrameIdentifier>& = std::nullopt);
void setPromisedDataForImage(IPC::Connection&, const String& pasteboardName, WebCore::SharedMemoryHandle&& imageHandle, const String& filename, const String& extension,
const String& title, const String& url, const String& visibleURL, WebCore::SharedMemoryHandle&& archiveHandle, const String& originIdentifier);
+ void releaseInspectorDragPasteboard();
#endif
#if PLATFORM(GTK) || PLATFORM(WPE)
void startDrag(WebCore::SelectionData&&, OptionSet<WebCore::DragOperation>, std::optional<WebCore::ShareableBitmapHandle>&& dragImage, WebCore::IntPoint&& dragImageHotspot);
@@ -1767,6 +1798,9 @@ public:
#if ENABLE(MODEL_PROCESS)
void modelDragEnded(const WebCore::NodeIdentifier);
#endif
+#if PLATFORM(WIN)
+ void startDrag(WebCore::DragDataMap&& dragDataMap);
+#endif
#endif
void processDidBecomeUnresponsive(WebProcessProxy&);
@@ -2030,6 +2064,7 @@ public:
void setViewportSizeForCSSViewportUnits(const WebCore::FloatSize&);
WebCore::FloatSize NODELETE viewportSizeForCSSViewportUnits() const;
+ bool shouldSendAutomationCredentialsForProtectionSpace(const WebProtectionSpace&);
void didReceiveAuthenticationChallengeProxy(Ref<AuthenticationChallengeProxy>&&, NegotiatedLegacyTLS);
void negotiatedLegacyTLS();
void didNegotiateModernTLS(const URL&);
@@ -2063,6 +2098,8 @@ public:
// TODO Replace RefPtr with Expected for error reporting https://webkit.org/b/300271
RefPtr<ViewSnapshot> takeViewSnapshot(std::optional<WebCore::IntRect>&&);
RefPtr<ViewSnapshot> takeViewSnapshot(std::optional<WebCore::IntRect>&&, ForceSoftwareCapturingViewportSnapshot);
+#elif PLATFORM(WPE)
+ RefPtr<ViewSnapshot> takeViewSnapshot(std::optional<WebCore::IntRect>&&) { return nullptr; }
#endif
void serializeAndWrapCryptoKey(IPC::Connection&, WebCore::CryptoKeyData&&, CompletionHandler<void(std::optional<Vector<uint8_t>>&&)>&&);
@@ -3202,6 +3239,7 @@ private:
RefPtr<API::Navigation> launchProcessForReload();
void requestNotificationPermission(const String& originString, CompletionHandler<void(bool allowed)>&&);
+ std::optional<bool> permissionForAutomation(const String& origin, const String& permission) const;
#if ENABLE(WEB_ARCHIVE)
bool NODELETE shouldAlwaysPromptForPermission(WebCore::PermissionName) const;
@@ -3752,11 +3790,13 @@ private:
String m_openedMainFrameName;
RefPtr<WebInspectorUIProxy> m_inspector;
+ InspectorDialogAgent* m_inspectorDialogAgent { nullptr };
Deque<std::pair<WebUndoStepID, UndoOrRedo>> m_pendingUndoRedo;
uint32_t m_undoVersion { 0 };
#if ENABLE(FULLSCREEN_API)
+ std::unique_ptr<WebFullScreenManagerProxyClient> m_fullScreenManagerClientOverride;
RefPtr<WebFullScreenManagerProxy> m_fullScreenManager;
std::unique_ptr<API::FullscreenClient> m_fullscreenClient;
#endif
@@ -3962,6 +4002,22 @@ private:
std::optional<WebCore::DragOperation> m_currentDragOperation;
bool m_currentDragIsOverFileInput { false };
unsigned m_currentDragNumberOfFilesToBeAccepted { 0 };
+ WebCore::IntRect m_currentDragCaretRect;
+ WebCore::IntRect m_currentDragCaretEditableElementRect;
+ bool m_interceptDrags { false };
+ OptionSet<WebCore::DragOperation> m_dragSourceOperationMask;
+ WebCore::IntPoint m_lastMousePositionForDrag;
+ int m_dragEventsQueued = 0;
+#if PLATFORM(COCOA)
+ std::optional<String> m_dragSelectionData;
+ String m_overrideDragPasteboardName;
+#endif
+#if PLATFORM(GTK) || PLATFORM(WPE)
+ std::optional<WebCore::SelectionData> m_dragSelectionData;
+#endif
+#if PLATFORM(WIN)
+ std::optional<WebCore::DragDataMap> m_dragSelectionData;
+#endif
#endif
bool m_mainFrameHasHorizontalScrollbar { false };
@@ -4132,6 +4188,11 @@ private:
RefPtr<API::Object> messageBody;
};
Vector<InjectedBundleMessage> m_pendingInjectedBundleMessages;
+ std::optional<WebCore::Credential> m_credentialsForAutomation;
+ std::optional<URL> m_authOriginForAutomation;
+ UncheckedKeyHashMap<String, HashSet<String>> m_permissionsForAutomation;
+ std::optional<int> m_deviceOrientationOverride;
+ std::optional<bool> m_activeForAutomation;
#if PLATFORM(IOS_FAMILY) && ENABLE(DEVICE_ORIENTATION)
RefPtr<WebDeviceOrientationUpdateProviderProxy> m_webDeviceOrientationUpdateProviderProxy;
diff --git a/Source/WebKit/UIProcess/WebPageProxy.messages.in b/Source/WebKit/UIProcess/WebPageProxy.messages.in
index 155543cbd71b814586ab391daaa2efa2d11c22ea..b39e2260133f4aa7fe9580496bd4237b3fd52629 100644
--- a/Source/WebKit/UIProcess/WebPageProxy.messages.in
+++ b/Source/WebKit/UIProcess/WebPageProxy.messages.in
@@ -35,6 +35,7 @@ messages -> WebPageProxy {
RunJavaScriptConfirm(WebCore::FrameIdentifier frameID, struct WebKit::FrameInfoData frameInfo, String message) -> (bool result) Synchronous
RunJavaScriptPrompt(WebCore::FrameIdentifier frameID, struct WebKit::FrameInfoData frameInfo, String message, String defaultValue) -> (String result) Synchronous
MouseDidMoveOverElement(struct WebKit::WebHitTestResultData hitTestResultData, OptionSet<WebKit::WebEventModifier> modifiers)
+ LogToStderr(String text)
DidReceiveEventIPC(enum:uint32_t WebKit::WebEventType eventType, bool handled, struct std::optional<WebCore::RemoteUserInputEventData> remoteUserInputEventData)
SetCursor(WebCore::Cursor cursor)
@@ -365,6 +366,10 @@ messages -> WebPageProxy {
StartDrag(WebCore::SelectionData selectionData, OptionSet<WebCore::DragOperation> dragOperationMask, std::optional<WebCore::ShareableBitmapHandle> dragImage, WebCore::IntPoint dragImageHotspot)
#endif
+#if PLATFORM(WIN) && ENABLE(DRAG_SUPPORT)
+ StartDrag(HashMap<unsigned, Vector<String>> dragDataMap)
+#endif
+
#if PLATFORM(IOS_FAMILY) && ENABLE(DRAG_SUPPORT)
WillReceiveEditDragSnapshot()
DidReceiveEditDragSnapshot(RefPtr<WebCore::TextIndicator> textIndicator)
diff --git a/Source/WebKit/UIProcess/WebProcessCache.cpp b/Source/WebKit/UIProcess/WebProcessCache.cpp
index 1593c4e060fb5fbf399c7d53cb7a81896b945556..c10a4b847f118012380a8d8f35984c81c841d697 100644
--- a/Source/WebKit/UIProcess/WebProcessCache.cpp
+++ b/Source/WebKit/UIProcess/WebProcessCache.cpp
@@ -125,6 +125,10 @@ bool WebProcessCache::canCacheProcess(WebProcessProxy& process) const
return false;
}
+ auto sessionID = process.websiteDataStore()->sessionID();
+ if (sessionID.isEphemeral() && !process.processPool().hasPagesUsingWebsiteDataStore(*process.websiteDataStore()))
+ return false;
+
return true;
}
diff --git a/Source/WebKit/UIProcess/WebProcessPool.cpp b/Source/WebKit/UIProcess/WebProcessPool.cpp
index c9e5f1f1a7dfed59616429838f635538c34124f9..af87d3e1c00f0513658180c5fb397621c1b5505a 100644
--- a/Source/WebKit/UIProcess/WebProcessPool.cpp
+++ b/Source/WebKit/UIProcess/WebProcessPool.cpp
@@ -423,10 +423,10 @@ void WebProcessPool::setAutomationClient(std::unique_ptr<API::AutomationClient>&
void WebProcessPool::setOverrideLanguages(Vector<String>&& languages)
{
- WebKit::setOverrideLanguages(WTF::move(languages));
+ m_configuration->setOverrideLanguages(WTF::move(languages));
LOG_WITH_STREAM(Language, stream << "WebProcessPool is setting OverrideLanguages: " << languages);
- sendToAllProcesses(Messages::WebProcess::UserPreferredLanguagesChanged(overrideLanguages()));
+ sendToAllProcesses(Messages::WebProcess::UserPreferredLanguagesChanged(m_configuration->overrideLanguages()));
#if ENABLE(GPU_PROCESS)
if (RefPtr gpuProcess = GPUProcessProxy::singletonIfCreated())
@@ -434,9 +434,10 @@ void WebProcessPool::setOverrideLanguages(Vector<String>&& languages)
#endif
#if USE(SOUP)
for (Ref networkProcess : NetworkProcessProxy::allNetworkProcesses())
- networkProcess->send(Messages::NetworkProcess::UserPreferredLanguagesChanged(overrideLanguages()), 0);
+ networkProcess->send(Messages::NetworkProcess::UserPreferredLanguagesChanged(m_configuration->overrideLanguages()), 0);
#endif
}
+/* end playwright revert fb205fb */
void WebProcessPool::fullKeyboardAccessModeChanged(bool fullKeyboardAccessEnabled)
{
@@ -977,7 +978,7 @@ void WebProcessPool::initializeNewWebProcess(WebProcessProxy& process, WebsiteDa
#endif
parameters.cacheModel = LegacyGlobalSettings::singleton().cacheModel();
- parameters.overrideLanguages = overrideLanguages();
+ parameters.overrideLanguages = configuration().overrideLanguages(); /* playwright revert fb205fb */
LOG_WITH_STREAM(Language, stream << "WebProcessPool is initializing a new web process with overrideLanguages: " << parameters.overrideLanguages);
parameters.urlSchemesRegisteredAsSecure = copyToVector(LegacyGlobalSettings::singleton().schemesToRegisterAsSecure());
@@ -1056,7 +1057,7 @@ void WebProcessPool::initializeNewWebProcess(WebProcessProxy& process, WebsiteDa
if (!injectedBundleInitializationUserData)
injectedBundleInitializationUserData = m_injectedBundleInitializationUserData;
parameters.initializationUserData = UserData(process.transformObjectsToHandles(injectedBundleInitializationUserData.get()));
-
+
if (websiteDataStore)
parameters.websiteDataStoreParameters = webProcessDataStoreParameters(process, *websiteDataStore);
@@ -1150,14 +1151,14 @@ void WebProcessPool::processDidFinishLaunching(WebProcessProxy& process)
// Sometimes the memorySampler gets initialized after process initialization has happened but before the process has finished launching
// so check if it needs to be started here
if (m_memorySamplerEnabled) {
- SandboxExtension::Handle sampleLogSandboxHandle;
+ SandboxExtension::Handle sampleLogSandboxHandle;
WallTime now = WallTime::now();
auto sampleLogFilePath = makeString("WebProcess"_s, now.secondsSinceEpoch().secondsAs<uint64_t>(), "pid"_s, process.processID());
if (auto handleAndFilePath = SandboxExtension::createHandleForTemporaryFile(sampleLogFilePath, SandboxExtension::Type::ReadWrite)) {
sampleLogSandboxHandle = WTF::move(handleAndFilePath->first);
sampleLogFilePath = WTF::move(handleAndFilePath->second);
}
-
+
process.send(Messages::WebProcess::StartMemorySampler(WTF::move(sampleLogSandboxHandle), sampleLogFilePath, m_memorySamplerInterval), 0);
}
@@ -1327,6 +1328,12 @@ Ref<WebPageProxy> WebProcessPool::createWebPage(PageClient& pageClient, Ref<API:
auto enhancedSecurity = (protect(pageConfiguration->preferences())->forceEnhancedSecurity() || pageConfiguration->isEnhancedSecurityEnabled() || useEnhancedSecurityFallback) ? EnhancedSecurity::EnabledPolicy : EnhancedSecurity::Disabled;
RefPtr relatedPage = pageConfiguration->relatedPage();
+
+ // Fix WPE/GTK crashes after 310806@main. upstream-status (pending). See issue https://github.com/microsoft/playwright-browsers/issues/2171
+ // Ensure popups inherit the StorageBlockingPolicy of the parent so they stay compatible for same-process popup creation.
+ if (relatedPage)
+ pageConfiguration->preferences().setStorageBlockingPolicy(relatedPage->preferences().storageBlockingPolicy());
+
bool siteIsolationEnabled = protect(pageConfiguration->preferences())->siteIsolationEnabled();
if (siteIsolationEnabled)
protect(pageConfiguration->preferences())->setUseUIProcessForBackForwardItemLoading(true);
@@ -1358,9 +1365,9 @@ Ref<WebPageProxy> WebProcessPool::createWebPage(PageClient& pageClient, Ref<API:
}
Ref userContentController = pageConfiguration->userContentController();
-
+
ASSERT(process);
-
+
process->setAllowTestOnlyIPC(pageConfiguration->allowTestOnlyIPC());
auto page = process->createWebPage(pageClient, WTF::move(pageConfiguration));
@@ -1745,18 +1752,18 @@ void WebProcessPool::setEnhancedAccessibility(bool flag)
{
sendToAllProcesses(Messages::WebProcess::SetEnhancedAccessibility(flag));
}
-
+
void WebProcessPool::startMemorySampler(const double interval)
-{
+{
// For new WebProcesses we will also want to start the Memory Sampler
m_memorySamplerEnabled = true;
m_memorySamplerInterval = interval;
-
+
// For UIProcess
#if ENABLE(MEMORY_SAMPLER)
WebMemorySampler::singleton()->start(interval);
#endif
-
+
for (auto& process : m_processes) {
if (!process->canSendMessage())
continue;
@@ -1775,10 +1782,10 @@ void WebProcessPool::startMemorySampler(const double interval)
}
void WebProcessPool::stopMemorySampler()
-{
+{
// For WebProcess
m_memorySamplerEnabled = false;
-
+
// For UIProcess
#if ENABLE(MEMORY_SAMPLER)
WebMemorySampler::singleton()->stop();
@@ -1830,7 +1837,7 @@ void WebProcessPool::setAutomationSession(RefPtr<WebAutomationSession>&& automat
{
if (RefPtr previousSession = m_automationSession)
previousSession->setProcessPool(nullptr);
-
+
m_automationSession = WTF::move(automationSession);
#if ENABLE(REMOTE_INSPECTOR)
@@ -2403,7 +2410,7 @@ std::tuple<Ref<WebProcessProxy>, RefPtr<SuspendedPageProxy>, ASCIILiteral> WebPr
}
auto reason = "Navigation is cross-site"_s;
-
+
if (m_configuration->alwaysKeepAndReuseSwappedProcesses()) {
LOG(ProcessSwapping, "(ProcessSwapping) Considering re-use of a previously cached process for domain %s", targetSite.domain().string().utf8().data());
@@ -2508,7 +2515,7 @@ void WebProcessPool::setDomainsWithUserInteraction(HashSet<WebCore::RegistrableD
}
void WebProcessPool::setDomainsWithCrossPageStorageAccess(HashMap<TopFrameDomain, Vector<SubResourceDomain>>&& domains, CompletionHandler<void()>&& completionHandler)
-{
+{
Ref callbackAggregator = CallbackAggregator::create(WTF::move(completionHandler));
for (Ref process : borrow(this->processes()).get())
diff --git a/Source/WebKit/UIProcess/WebProcessProxy.cpp b/Source/WebKit/UIProcess/WebProcessProxy.cpp
index 1f2073d6c2900da0994e09c3edaee6c67298fade..b7a2870799a36988a051efe48c62f1d975156751 100644
--- a/Source/WebKit/UIProcess/WebProcessProxy.cpp
+++ b/Source/WebKit/UIProcess/WebProcessProxy.cpp
@@ -215,6 +215,11 @@ Vector<Ref<WebProcessProxy>> WebProcessProxy::allProcesses()
});
}
+Vector<Ref<WebProcessProxy>> WebProcessProxy::allProcessesForInspector()
+{
+ return copyToVector(allProcesses());
+}
+
RefPtr<WebProcessProxy> WebProcessProxy::processForIdentifier(ProcessIdentifier identifier)
{
return allProcessMap().get(identifier);
@@ -583,6 +588,26 @@ void WebProcessProxy::getLaunchOptions(ProcessLauncher::LaunchOptions& launchOpt
if (WebKit::isInspectorProcessPool(processPool()))
launchOptions.extraInitializationData.add<HashTranslatorASCIILiteral>("inspector-process"_s, "1"_s);
+ /* playwright revert fb205fb, 50f8fee */
+ LOG(Language, "WebProcessProxy is getting launch options.");
+ auto overrideLanguages = m_processPool->configuration().overrideLanguages();
+ if (overrideLanguages.isEmpty()) {
+ LOG(Language, "overrideLanguages() reports empty. Calling platformOverrideLanguages()");
+ overrideLanguages = platformOverrideLanguages();
+ }
+ if (!overrideLanguages.isEmpty()) {
+ StringBuilder languageString;
+ for (size_t i = 0; i < overrideLanguages.size(); ++i) {
+ if (i)
+ languageString.append(',');
+ languageString.append(overrideLanguages[i]);
+ }
+ LOG_WITH_STREAM(Language, stream << "Setting WebProcess's launch OverrideLanguages to " << languageString);
+ launchOptions.extraInitializationData.add<HashTranslatorASCIILiteral>("OverrideLanguages"_s, languageString.toString());
+ } else
+ LOG(Language, "overrideLanguages is still empty. Not setting WebProcess's launch OverrideLanguages.");
+ /* end playwright revert fb205fb, 50f8fee */
+
launchOptions.nonValidInjectedCodeAllowed = shouldAllowNonValidInjectedCode();
if (isPrewarmed())
diff --git a/Source/WebKit/UIProcess/WebProcessProxy.h b/Source/WebKit/UIProcess/WebProcessProxy.h
index 2bf85bf9e81bcca1c2c0830004a3cb6ef67708d0..4284c4b480346514dd3ba1ad4c01802ff151753b 100644
--- a/Source/WebKit/UIProcess/WebProcessProxy.h
+++ b/Source/WebKit/UIProcess/WebProcessProxy.h
@@ -208,6 +208,7 @@ public:
static void forWebPagesWithOrigin(PAL::SessionID, const WebCore::SecurityOriginData&, NOESCAPE const Function<void(WebPageProxy&)>&);
static Vector<std::pair<WebCore::ProcessIdentifier, WebCore::RegistrableDomain>> allowedFirstPartiesForCookies();
+ static Vector<Ref<WebProcessProxy>> allProcessesForInspector();
void initializeWebProcess(WebProcessCreationParameters&&);
diff --git a/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp b/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp
index 200b1f02601242c6e2240ab6bbb7d2b7e093e5b4..a95b9dfb1939a1fb2ae271e34a00d7201dfe06aa 100644
--- a/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp
+++ b/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp
@@ -315,15 +315,10 @@ SOAuthorizationCoordinator& WebsiteDataStore::soAuthorizationCoordinator(const W
static Ref<NetworkProcessProxy> networkProcessForSession(PAL::SessionID sessionID)
{
-#if ((PLATFORM(GTK) || PLATFORM(WPE)) && !ENABLE(2022_GLIB_API))
- if (sessionID.isEphemeral()) {
- // Reuse a previous persistent session network process for ephemeral sessions.
- for (auto& dataStore : allDataStores().values()) {
- if (dataStore->isPersistent())
- return dataStore->networkProcess();
- }
- }
+// Playwright begin
+#if PLATFORM(GTK) || PLATFORM(WPE)
return NetworkProcessProxy::create();
+// Playwright end
#else
UNUSED_PARAM(sessionID);
return NetworkProcessProxy::ensureDefaultNetworkProcess();
@@ -2100,6 +2095,15 @@ void WebsiteDataStore::setCacheModelSynchronouslyForTesting(CacheModel cacheMode
processPool->setCacheModelSynchronouslyForTesting(cacheModel);
}
+// Playwright begin
+#if !USE(SOUP)
+void WebsiteDataStore::setIgnoreTLSErrors(bool ignoreTLSErrors)
+{
+ m_ignoreTLSErrors = ignoreTLSErrors;
+}
+#endif
+// Playwright begin
+
Vector<WebsiteDataStoreParameters> WebsiteDataStore::parametersFromEachWebsiteDataStore()
{
return WTF::map(allDataStores(), [](auto& entry) {
@@ -2524,6 +2528,12 @@ void WebsiteDataStore::lastPageLoadNetworkActivityCompletionCodeForTesting(WebCo
protect(networkProcess())->lastPageLoadNetworkActivityCompletionCodeForTesting(m_sessionID, pageID, WTF::move(completionHandler));
}
+void WebsiteDataStore::setDownloadForAutomation(std::optional<bool> allow, const String& downloadPath)
+{
+ m_allowDownloadForAutomation = allow;
+ m_downloadPathForAutomation = downloadPath;
+}
+
#if ENABLE(APP_BOUND_DOMAINS)
void WebsiteDataStore::hasAppBoundSession(CompletionHandler<void(bool)>&& completionHandler) const
{
diff --git a/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h b/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h
index 8de753cfce229075cbfa2bc7a81eab3d2fe1fb03..f78922cea6147503e3bcbcf8869ebda2518ef62c 100644
--- a/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h
+++ b/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h
@@ -103,6 +103,7 @@ class DeviceIdHashSaltStorage;
class DownloadProxy;
class NetworkProcessProxy;
class SOAuthorizationCoordinator;
+class DownloadProxy;
class VirtualAuthenticatorManager;
class WebPageProxy;
class WebProcessPool;
@@ -118,6 +119,7 @@ enum class UnifiedOriginStorageLevel : uint8_t;
enum class WebsiteDataFetchOption : uint8_t;
enum class WebsiteDataType : uint32_t;
+struct FrameInfoData;
struct ITPThirdPartyData;
struct NetworkProcessConnectionInfo;
struct WebPushMessage;
@@ -127,6 +129,14 @@ struct WebsiteDataStoreParameters;
enum RemoveDataTaskCounterType { };
using RemoveDataTaskCounter = RefCounter<RemoveDataTaskCounterType>;
+class DownloadInstrumentation {
+public:
+ virtual void downloadCreated(const String& uuid, const WebCore::ResourceRequest&, const FrameInfoData& frameInfoData, WebPageProxy* page, RefPtr<DownloadProxy> download) = 0;
+ virtual void downloadFilenameSuggested(const String& uuid, const String& suggestedFilename) = 0;
+ virtual void downloadFinished(const String& uuid, const String& error) = 0;
+ virtual ~DownloadInstrumentation() = default;
+};
+
class WebsiteDataStore : public API::ObjectImpl<API::Object::Type::WebsiteDataStore>, public CanMakeWeakPtr<WebsiteDataStore> {
public:
static WebsiteDataStore& defaultDataStore();
@@ -330,8 +340,10 @@ public:
#if USE(SOUP)
void setPersistentCredentialStorageEnabled(bool);
bool persistentCredentialStorageEnabled() const { return m_persistentCredentialStorageEnabled && isPersistent(); }
+#endif
void setIgnoreTLSErrors(bool);
bool ignoreTLSErrors() const { return m_ignoreTLSErrors; }
+#if USE(SOUP)
void setNetworkProxySettings(WebCore::SoupNetworkProxySettings&&);
const WebCore::SoupNetworkProxySettings& networkProxySettings() const LIFETIME_BOUND { return m_networkProxySettings; }
void setCookiePersistentStorage(const String&, SoupCookiePersistentStorageType);
@@ -422,6 +434,12 @@ public:
static const String& defaultBaseDataDirectory();
#endif
+ void setDownloadForAutomation(std::optional<bool> allow, const String& downloadPath);
+ std::optional<bool> allowDownloadForAutomation() { return m_allowDownloadForAutomation; };
+ String downloadPathForAutomation() { return m_downloadPathForAutomation; };
+ void setDownloadInstrumentation(DownloadInstrumentation* instrumentation) { m_downloadInstrumentation = instrumentation; };
+ DownloadInstrumentation* downloadInstrumentation() { return m_downloadInstrumentation; };
+
void resetQuota(CompletionHandler<void()>&&);
void resetStoragePersistedState(CompletionHandler<void()>&&);
#if PLATFORM(IOS_FAMILY)
@@ -642,7 +660,9 @@ private:
#if USE(SOUP)
bool m_persistentCredentialStorageEnabled { true };
- bool m_ignoreTLSErrors { true };
+#endif
+ bool m_ignoreTLSErrors { false };
+#if USE(SOUP)
WebCore::SoupNetworkProxySettings m_networkProxySettings;
String m_cookiePersistentStoragePath;
SoupCookiePersistentStorageType m_cookiePersistentStorageType { SoupCookiePersistentStorageType::SQLite };
@@ -669,6 +689,10 @@ private:
const RefPtr<API::HTTPCookieStore> m_cookieStore;
RefPtr<NetworkProcessProxy> m_networkProcess;
+ std::optional<bool> m_allowDownloadForAutomation;
+ String m_downloadPathForAutomation;
+ DownloadInstrumentation* m_downloadInstrumentation { nullptr };
+
#if HAVE(APP_SSO)
const std::unique_ptr<SOAuthorizationCoordinator> m_soAuthorizationCoordinator;
#endif
diff --git a/Source/WebKit/UIProcess/cairo/BackingStoreCairo.cpp b/Source/WebKit/UIProcess/cairo/BackingStoreCairo.cpp
index ad30e3705de228f71b2206a9da314451bbb2ca00..e46d97003021b06d17f66dd60f7ffcf2c69049cb 100644
--- a/Source/WebKit/UIProcess/cairo/BackingStoreCairo.cpp
+++ b/Source/WebKit/UIProcess/cairo/BackingStoreCairo.cpp
@@ -31,6 +31,7 @@
#if USE(CAIRO)
#include "UpdateInfo.h"
+#include "WebPageProxy.h"
#include <WebCore/CairoUtilities.h>
#include <WebCore/GraphicsContextCairo.h>
#include <WebCore/IntRect.h>
diff --git a/Source/WebKit/UIProcess/geoclue/GeoclueGeolocationProvider.cpp b/Source/WebKit/UIProcess/geoclue/GeoclueGeolocationProvider.cpp
index b79d617e64cbfb9d6e8faa811a0bf2890e75fe05..1b022935348aa29760e13c6ceaa2a97cca21977e 100644
--- a/Source/WebKit/UIProcess/geoclue/GeoclueGeolocationProvider.cpp
+++ b/Source/WebKit/UIProcess/geoclue/GeoclueGeolocationProvider.cpp
@@ -114,6 +114,14 @@ void GeoclueGeolocationProvider::stop()
}
m_sourceType = LocationProviderSource::Unknown;
+ stopGeoclueClient();
+ g_cancellable_cancel(m_cancellable_start.get());
+ m_cancellable_start = nullptr;
+ g_cancellable_cancel(m_cancellable_setup.get());
+ m_cancellable_setup = nullptr;
+ g_cancellable_cancel(m_cancellable_create.get());
+ m_cancellable_create = nullptr;
+ destroyStateLater();
}
void GeoclueGeolocationProvider::setEnableHighAccuracy(bool enabled)
@@ -386,6 +394,8 @@ void GeoclueGeolocationProvider::createGeoclueClient(const char* clientPath)
return;
}
+ g_cancellable_cancel(m_cancellable_create.get());
+ m_cancellable_create = adoptGRef(g_cancellable_new());
g_dbus_proxy_new_for_bus(G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, nullptr,
"org.freedesktop.GeoClue2", clientPath, "org.freedesktop.GeoClue2.Client", m_cancellable.get(),
[](GObject*, GAsyncResult* result, gpointer userData) {
diff --git a/Source/WebKit/UIProcess/geoclue/GeoclueGeolocationProvider.h b/Source/WebKit/UIProcess/geoclue/GeoclueGeolocationProvider.h
index 96bf77411e2e1f4c835f56b409dc179977d197ee..512af5ffce511711b502248e34e49e45e85dbc4e 100644
--- a/Source/WebKit/UIProcess/geoclue/GeoclueGeolocationProvider.h
+++ b/Source/WebKit/UIProcess/geoclue/GeoclueGeolocationProvider.h
@@ -92,6 +92,9 @@ private:
unsigned responseSignalId;
} m_portal;
GRefPtr<GCancellable> m_cancellable;
+ GRefPtr<GCancellable> m_cancellable_start;
+ GRefPtr<GCancellable> m_cancellable_setup;
+ GRefPtr<GCancellable> m_cancellable_create;
UpdateNotifyFunction m_updateNotifyFunction;
LocationProviderSource m_sourceType { LocationProviderSource::Unknown };
RunLoop::Timer m_destroyLaterTimer;
diff --git a/Source/WebKit/UIProcess/glib/BrowserInspectorWebSocketServer.cpp b/Source/WebKit/UIProcess/glib/BrowserInspectorWebSocketServer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..00483c4a7fdd24c93702c773687643ad045e7127
--- /dev/null
+++ b/Source/WebKit/UIProcess/glib/BrowserInspectorWebSocketServer.cpp
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2026 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "BrowserInspectorWebSocketServer.h"
+
+#if ENABLE(REMOTE_INSPECTOR)
+
+#include "InspectorPlaywrightAgent.h"
+#include "InspectorPlaywrightAgentClient.h"
+#include "WebKit2Initialize.h"
+#include <glib-object.h>
+#include <libsoup/soup-websocket-connection.h>
+#include <libsoup/soup.h>
+#include <wtf/glib/GRefPtr.h>
+#include <wtf/NeverDestroyed.h>
+
+namespace WebKit {
+
+namespace {
+
+class WebSocketFrontendChannel : public Inspector::FrontendChannel {
+ WTF_DEPRECATED_MAKE_FAST_ALLOCATED(WebSocketFrontendChannel);
+public:
+ explicit WebSocketFrontendChannel(SoupWebsocketConnection* connection)
+ : m_connection(connection)
+ {
+ }
+
+ ~WebSocketFrontendChannel() override = default;
+
+private:
+ ConnectionType connectionType() const override
+ {
+ return ConnectionType::Remote;
+ }
+
+ void sendMessageToFrontend(const String& message) override
+ {
+ soup_websocket_connection_send_text(m_connection.get(), message.utf8().data());
+ }
+
+ GRefPtr<SoupWebsocketConnection> m_connection;
+};
+
+class BrowserInspectorWebSocketServer {
+public:
+ BrowserInspectorWebSocketServer(std::unique_ptr<InspectorPlaywrightAgentClient> client, GRefPtr<SoupServer> soupServer)
+ : m_playwrightAgent(std::move(client))
+ , m_soupServer(std::move(soupServer))
+ {
+ soup_server_add_websocket_handler(m_soupServer.get(), nullptr, nullptr, nullptr, &BrowserInspectorWebSocketServer::handleWebSocketConnection, this, nullptr);
+ }
+
+private:
+ static void handleWebSocketConnection(SoupServer*, SoupServerMessage*, const char* path, SoupWebsocketConnection* connection, gpointer userData)
+ {
+ auto server = static_cast<BrowserInspectorWebSocketServer*>(userData);
+ if (!server->handleWebSocketConnection(connection)) {
+ soup_websocket_connection_close(connection, SOUP_WEBSOCKET_CLOSE_POLICY_VIOLATION, "WebSocket connection already established");
+ return;
+ }
+
+ g_signal_connect(connection, "closed", G_CALLBACK(+[](SoupWebsocketConnection* connection, gpointer userData) {
+ auto server = static_cast<BrowserInspectorWebSocketServer*>(userData);
+ server->handleConnectionClosed(connection);
+ }), server);
+
+ g_signal_connect(connection, "message", G_CALLBACK(+[] (SoupWebsocketConnection*, SoupWebsocketDataType messageType, GBytes* message, gpointer userData) {
+ auto server = static_cast<BrowserInspectorWebSocketServer*>(userData);
+ server->handleWebSocketMessage(messageType, message);
+ }), server);
+ }
+
+
+ void handleConnectionClosed(SoupWebsocketConnection* connection)
+ {
+ if (m_frontendChannel) {
+ m_playwrightAgent.disconnectFrontend();
+ m_frontendChannel.reset();
+ }
+ }
+
+ void handleWebSocketMessage(SoupWebsocketDataType messageType, GBytes* message)
+ {
+ if (messageType != SOUP_WEBSOCKET_DATA_TEXT) {
+ fprintf(stderr, "WebSocket message received non-text message: %d\n", messageType);
+ return;
+ }
+
+ gsize messageSize;
+ gconstpointer messageData = g_bytes_get_data(message, &messageSize);
+ String messageString = String::fromUTF8(std::span<const char8_t>(static_cast<const char8_t*>(messageData), messageSize));
+ fprintf(stderr, "WebSocket message received: %s\n", messageString.utf8().data());
+ m_playwrightAgent.dispatchMessageFromFrontend(messageString);
+ }
+
+ bool handleWebSocketConnection(SoupWebsocketConnection* connection)
+ {
+ if (m_frontendChannel) {
+ fprintf(stderr, "WebSocket connection already established\n");
+ return false;
+ }
+ m_frontendChannel = std::make_unique<WebSocketFrontendChannel>(connection);
+ m_playwrightAgent.connectFrontend(*m_frontendChannel);
+ return true;
+ }
+
+ InspectorPlaywrightAgent m_playwrightAgent;
+ GRefPtr<SoupServer> m_soupServer;
+ std::unique_ptr<WebSocketFrontendChannel> m_frontendChannel;
+};
+
+} // namespace
+
+void initializeBrowserInspectorWebSocket(unsigned port, std::unique_ptr<InspectorPlaywrightAgentClient> client)
+{
+ // Initialize main loop before creating inspector agent and starting the server.
+ WebKit::InitializeWebKit2();
+
+ GRefPtr<SoupServer> soupServer = adoptGRef(soup_server_new("server-header", "WebKit-Playwright-WSS", nullptr));
+
+ GUniqueOutPtr<GError> error;
+ const SoupServerListenOptions options = static_cast<SoupServerListenOptions>(0);
+ if (!soup_server_listen_local(soupServer.get(), port, options, &error.outPtr())) {
+ fprintf(stderr, "Failed to start WebSocket server at port %u: %s\n", port, error->message);
+ return;
+ }
+
+ int actualPort = port;
+ if (!actualPort) {
+ GSList* uris = soup_server_get_uris(soupServer.get());
+ g_assert_nonnull(uris);
+ GUri* uri = static_cast<GUri*>(uris->data);
+ actualPort = g_uri_get_port(uri);
+ g_slist_free_full(uris, reinterpret_cast<GDestroyNotify>(g_uri_unref));
+ }
+ if (actualPort == -1) {
+ fprintf(stderr, "Failed to start WebSocket server\n");
+ return;
+ }
+
+ static NeverDestroyed<BrowserInspectorWebSocketServer> server(std::move(client), std::move(soupServer));
+
+ fprintf(stderr, "Playwright listening on ws://localhost:%d\n", actualPort);
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(REMOTE_INSPECTOR)
diff --git a/Source/WebKit/UIProcess/glib/BrowserInspectorWebSocketServer.h b/Source/WebKit/UIProcess/glib/BrowserInspectorWebSocketServer.h
new file mode 100644
index 0000000000000000000000000000000000000000..bd30f58d2d4afe85060eabf3bb178c20c0c73828
--- /dev/null
+++ b/Source/WebKit/UIProcess/glib/BrowserInspectorWebSocketServer.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2026 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(REMOTE_INSPECTOR)
+
+namespace WebKit {
+
+class InspectorPlaywrightAgentClient;
+
+void initializeBrowserInspectorWebSocket(unsigned port, std::unique_ptr<InspectorPlaywrightAgentClient> client);
+
+} // namespace WebKit
+
+#endif // ENABLE(REMOTE_INSPECTOR)
+
diff --git a/Source/WebKit/UIProcess/glib/InspectorPlaywrightAgentClientGLib.cpp b/Source/WebKit/UIProcess/glib/InspectorPlaywrightAgentClientGLib.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e5a8e68580d8ba7ad968d1736220793711214988
--- /dev/null
+++ b/Source/WebKit/UIProcess/glib/InspectorPlaywrightAgentClientGLib.cpp
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2019 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "InspectorPlaywrightAgentClientGLib.h"
+
+#if ENABLE(REMOTE_INSPECTOR)
+
+#include "InspectorPlaywrightAgent.h"
+#include "PageClient.h"
+#include "ViewSnapshotStore.h"
+#include "WebAutomationSession.h"
+#include "WebKitBrowserInspectorPrivate.h"
+#include "WebKitWebContextPrivate.h"
+#include "WebKitWebsiteDataManagerPrivate.h"
+#include "WebKitWebViewPrivate.h"
+#include "WebPageProxy.h"
+#include <wtf/HashMap.h>
+#include <wtf/RefPtr.h>
+#include <wtf/text/Base64.h>
+#include <wtf/text/StringView.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebKit {
+
+static WebCore::SoupNetworkProxySettings parseRawProxySettings(const String& proxyServer, const char* const* ignoreHosts)
+{
+ WebCore::SoupNetworkProxySettings settings;
+ if (proxyServer.isEmpty())
+ return settings;
+
+ settings.mode = WebCore::SoupNetworkProxySettings::Mode::Custom;
+ settings.defaultProxyURL = proxyServer.utf8();
+ settings.ignoreHosts.reset(g_strdupv(const_cast<char**>(ignoreHosts)));
+ return settings;
+}
+
+static WebCore::SoupNetworkProxySettings parseProxySettings(const String& proxyServer, const String& proxyBypassList)
+{
+ Vector<const char*> ignoreHosts;
+ if (!proxyBypassList.isEmpty()) {
+ Vector<String> tokens = proxyBypassList.split(',');
+ Vector<CString> protectTokens;
+ for (String token : tokens) {
+ CString cstr = token.utf8();
+ ignoreHosts.append(cstr.data());
+ protectTokens.append(WTF::move(cstr));
+ }
+ }
+ ignoreHosts.append(nullptr);
+ return parseRawProxySettings(proxyServer, ignoreHosts.mutableSpan().data());
+}
+
+InspectorPlaywrightAgentClientGlib::InspectorPlaywrightAgentClientGlib(const WTF::String& proxyURI, const char* const* ignoreHosts)
+ : m_proxySettings(parseRawProxySettings(proxyURI, ignoreHosts))
+{
+}
+
+RefPtr<WebPageProxy> InspectorPlaywrightAgentClientGlib::createPage(WTF::String& error, const BrowserContext& browserContext)
+{
+ auto sessionID = browserContext.dataStore->sessionID();
+ WebKitWebContext* context = m_idToContext.get(sessionID);
+ if (!context && !browserContext.dataStore->isPersistent()) {
+ ASSERT_NOT_REACHED();
+ error = "Context with provided id not found"_s;
+ return nullptr;
+ }
+
+ RefPtr<WebPageProxy> page = webkitBrowserInspectorCreateNewPageInContext(context);
+ if (page == nullptr) {
+ error = "Failed to create new page in the context"_s;
+ return nullptr;
+ }
+
+ if (context == nullptr && sessionID != page->sessionID()) {
+ ASSERT_NOT_REACHED();
+ error = " Failed to create new page in default context"_s;
+ return nullptr;
+ }
+
+ return page;
+}
+
+void InspectorPlaywrightAgentClientGlib::closeBrowser()
+{
+ m_idToContext.clear();
+ webkitBrowserInspectorQuitApplication();
+ if (webkitWebContextExistingCount() > 1)
+ fprintf(stderr, "LEAK: %d contexts are still alive when closing browser\n", webkitWebContextExistingCount());
+}
+
+std::unique_ptr<BrowserContext> InspectorPlaywrightAgentClientGlib::createBrowserContext(WTF::String& error, const WTF::String& proxyServer, const WTF::String& proxyBypassList)
+{
+ GRefPtr<WebKitWebContext> context = adoptGRef(WEBKIT_WEB_CONTEXT(g_object_new(WEBKIT_TYPE_WEB_CONTEXT, nullptr)));
+ if (!context) {
+ error = "Failed to create GLib ephemeral context"_s;
+ return nullptr;
+ }
+
+ GRefPtr<WebKitNetworkSession> networkSession = adoptGRef(webkit_network_session_new_ephemeral());
+ webkit_web_context_set_network_session_for_automation(context.get(), networkSession.get());
+ GRefPtr<WebKitWebsiteDataManager> data_manager = webkit_network_session_get_website_data_manager(networkSession.get());
+
+ auto browserContext = std::make_unique<BrowserContext>();
+ browserContext->processPool = &webkitWebContextGetProcessPool(context.get());
+ browserContext->dataStore = &webkitWebsiteDataManagerGetDataStore(data_manager.get());
+ PAL::SessionID sessionID = browserContext.get()->dataStore->sessionID();
+ m_idToContext.set(sessionID, WTF::move(context));
+
+ if (!proxyServer.isEmpty()) {
+ WebCore::SoupNetworkProxySettings contextProxySettings = parseProxySettings(proxyServer, proxyBypassList);
+ browserContext->dataStore->setNetworkProxySettings(WTF::move(contextProxySettings));
+ } else {
+ browserContext->dataStore->setNetworkProxySettings(WebCore::SoupNetworkProxySettings(m_proxySettings));
+ }
+ return browserContext;
+}
+
+void InspectorPlaywrightAgentClientGlib::deleteBrowserContext(WTF::String& error, PAL::SessionID sessionID)
+{
+ m_idToContext.remove(sessionID);
+}
+
+void InspectorPlaywrightAgentClientGlib::takePageScreenshot(WebPageProxy& page, WebCore::IntRect&& clip, bool nominalResolution, CompletionHandler<void(const String&, const String&)>&& completionHandler)
+{
+ page.callAfterNextPresentationUpdate([protectedPage = Ref{ page }, clip = WTF::move(clip), nominalResolution, completionHandler = WTF::move(completionHandler)]() mutable {
+#if PLATFORM(GTK) || (PLATFORM(WPE) && USE(SKIA))
+ RefPtr<ViewSnapshot> viewSnapshot = protectedPage->pageClient()->takeViewSnapshot(WTF::move(clip), nominalResolution);
+ if (viewSnapshot) {
+ std::optional<String> data = WebAutomationSession::platformGetBase64EncodedPNGData(*viewSnapshot);
+ if (data) {
+ completionHandler(emptyString(), makeString("data:image/png;base64,"_s, *data));
+ return;
+ }
+ }
+#endif
+ completionHandler("Failed to take screenshot"_s, emptyString());
+ });
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(REMOTE_INSPECTOR)
diff --git a/Source/WebKit/UIProcess/glib/InspectorPlaywrightAgentClientGLib.h b/Source/WebKit/UIProcess/glib/InspectorPlaywrightAgentClientGLib.h
new file mode 100644
index 0000000000000000000000000000000000000000..68bc7b610703bfcd3eff0d1c032092f6967fdc16
--- /dev/null
+++ b/Source/WebKit/UIProcess/glib/InspectorPlaywrightAgentClientGLib.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2019 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(REMOTE_INSPECTOR)
+
+#include "InspectorPlaywrightAgentClient.h"
+#include <WebCore/SoupNetworkProxySettings.h>
+#include "WebKitWebContext.h"
+#include <wtf/Forward.h>
+#include <wtf/HashMap.h>
+#include <wtf/glib/GRefPtr.h>
+#include <wtf/text/StringHash.h>
+
+namespace WebKit {
+
+class InspectorPlaywrightAgentClientGlib : public InspectorPlaywrightAgentClient {
+ WTF_DEPRECATED_MAKE_FAST_ALLOCATED(InspectorPlaywrightAgentClientGlib);
+public:
+ InspectorPlaywrightAgentClientGlib(const WTF::String& proxyURI, const char* const* ignoreHosts);
+ ~InspectorPlaywrightAgentClientGlib() override = default;
+
+ RefPtr<WebPageProxy> createPage(WTF::String& error, const BrowserContext&) override;
+ void closeBrowser() override;
+ std::unique_ptr<BrowserContext> createBrowserContext(WTF::String& error, const WTF::String& proxyServer, const WTF::String& proxyBypassList) override;
+ void deleteBrowserContext(WTF::String& error, PAL::SessionID) override;
+ void takePageScreenshot(WebPageProxy&, WebCore::IntRect&& clip, bool nominalResolution, CompletionHandler<void(const String&, const String&)>&& completionHandler) override;
+
+private:
+ WebKitWebContext* findContext(WTF::String& error, PAL::SessionID);
+
+ UncheckedKeyHashMap<PAL::SessionID, GRefPtr<WebKitWebContext>> m_idToContext;
+ WebCore::SoupNetworkProxySettings m_proxySettings;
+};
+
+} // namespace API
+
+#endif // ENABLE(REMOTE_INSPECTOR)
diff --git a/Source/WebKit/UIProcess/glib/WebProcessPoolGLib.cpp b/Source/WebKit/UIProcess/glib/WebProcessPoolGLib.cpp
index e69e33b4359e24075e9054f014f5e5ab488b78c7..f395398acf790cc4fa80122dd4f59381ee03f5ac 100644
--- a/Source/WebKit/UIProcess/glib/WebProcessPoolGLib.cpp
+++ b/Source/WebKit/UIProcess/glib/WebProcessPoolGLib.cpp
@@ -127,6 +127,8 @@ static OptionSet<AvailableInputDevices> availableInputDevices()
return toAvailableInputDevices(gdk_seat_get_capabilities(seat));
}
#endif
+ if (!WebCore::screenHasTouchDeviceOverride() || !WebCore::screenHasTouchDeviceOverride().value())
+ return AvailableInputDevices::Mouse;
#if ENABLE(TOUCH_EVENTS)
return AvailableInputDevices::Touchscreen;
#else
diff --git a/Source/WebKit/UIProcess/gtk/AcceleratedBackingStore.cpp b/Source/WebKit/UIProcess/gtk/AcceleratedBackingStore.cpp
index 3dd2a77a24c59cb7fb1f01d3a74d75267a0f36bf..a020ccc929af8c9130ecca0125e5229ee8670e54 100644
--- a/Source/WebKit/UIProcess/gtk/AcceleratedBackingStore.cpp
+++ b/Source/WebKit/UIProcess/gtk/AcceleratedBackingStore.cpp
@@ -864,4 +864,30 @@ RefPtr<NativeImage> AcceleratedBackingStore::bufferAsNativeImageForTesting() con
return m_committedBuffer->asNativeImageForTesting();
}
+// Playwright begin
+cairo_surface_t* AcceleratedBackingStore::surface()
+{
+ RefPtr<Buffer> buffer = m_committedBuffer.get();
+ if (!buffer)
+ return nullptr;
+
+ RefPtr<cairo_surface_t> surface = buffer->surface();
+ if (!surface)
+ return nullptr;
+
+ // The original surface is upside down, so we flip it to match orientation in other accelerated backing stores.
+ m_flippedSurface = adoptRef(cairo_image_surface_create(CAIRO_FORMAT_ARGB32, cairo_image_surface_get_width(surface.get()), cairo_image_surface_get_height(surface.get())));
+ {
+ RefPtr<cairo_t> cr = adoptRef(cairo_create(m_flippedSurface.get()));
+ cairo_matrix_t transform;
+ cairo_matrix_init(&transform, 1, 0, 0, -1, 0, cairo_image_surface_get_height(surface.get()) / buffer->deviceScaleFactor());
+ cairo_transform(cr.get(), &transform);
+ cairo_set_source_surface(cr.get(), surface.get(), 0, 0);
+ cairo_paint(cr.get());
+ }
+ cairo_surface_flush(m_flippedSurface.get());
+ return m_flippedSurface.get();
+}
+// Playwright end
+
} // namespace WebKit
diff --git a/Source/WebKit/UIProcess/gtk/AcceleratedBackingStore.h b/Source/WebKit/UIProcess/gtk/AcceleratedBackingStore.h
index 2a15a005441f41bcc3a44ce666dabeab7ab671f2..cc802e0634696b9455cd650527886c35a14a3ea3 100644
--- a/Source/WebKit/UIProcess/gtk/AcceleratedBackingStore.h
+++ b/Source/WebKit/UIProcess/gtk/AcceleratedBackingStore.h
@@ -42,6 +42,7 @@
#include <wtf/unix/UnixFileDescriptor.h>
typedef void *EGLImage;
+typedef struct _cairo_surface cairo_surface_t;
#if USE(GBM)
#include <WebCore/DMABufBuffer.h>
@@ -86,6 +87,7 @@ public:
void unrealize();
RendererBufferDescription bufferDescription() const;
RefPtr<WebCore::NativeImage> bufferAsNativeImageForTesting() const;
+ cairo_surface_t* surface();
private:
explicit AcceleratedBackingStore(WebPageProxy&);
@@ -268,6 +270,10 @@ private:
RefPtr<Buffer> m_committedBuffer;
Rects m_pendingDamageRects;
HashMap<uint64_t, RefPtr<Buffer>> m_buffers;
+// Playwright begin
+ RefPtr<cairo_surface_t> m_flippedSurface;
+// Playwright end
+
};
} // namespace WebKit
diff --git a/Source/WebKit/UIProcess/gtk/InspectorTargetProxyGtk.cpp b/Source/WebKit/UIProcess/gtk/InspectorTargetProxyGtk.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8f661f8c62dc091670f9474db037e7eee0ec37ce
--- /dev/null
+++ b/Source/WebKit/UIProcess/gtk/InspectorTargetProxyGtk.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2019 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "InspectorTargetProxy.h"
+
+#include "WebPageProxy.h"
+#include "GtkUtilities.h"
+#include <gtk/gtk.h>
+
+namespace WebKit {
+
+void InspectorTargetProxy::platformActivate(String& error) const
+{
+ GtkWidget* parent = GTK_WIDGET(gtk_widget_get_root(m_page->viewWidget()));
+ if (WebCore::widgetIsOnscreenToplevelWindow(parent))
+ gtk_window_present(GTK_WINDOW(parent));
+ else
+ error = "The view is not on screen"_s;
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit/UIProcess/gtk/PageInspectorTargetProxyGtk.cpp b/Source/WebKit/UIProcess/gtk/PageInspectorTargetProxyGtk.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4412881043189ba16e7803eeab98bce574ab9267
--- /dev/null
+++ b/Source/WebKit/UIProcess/gtk/PageInspectorTargetProxyGtk.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2019 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PageInspectorTargetProxy.h"
+
+#include "WebPageProxy.h"
+#include "GtkUtilities.h"
+#include <gtk/gtk.h>
+
+namespace WebKit {
+
+void PageInspectorTargetProxy::platformActivate(String& error) const
+{
+ GtkWidget* parent = GTK_WIDGET(gtk_widget_get_root(m_page->viewWidget()));
+ if (widgetIsOnscreenToplevelWindow(parent))
+ gtk_window_present(GTK_WINDOW(parent));
+ else
+ error = "The view is not on screen"_s;
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit/UIProcess/gtk/SystemSettingsManagerProxyGtk.cpp b/Source/WebKit/UIProcess/gtk/SystemSettingsManagerProxyGtk.cpp
index ed7f7adafd75f27ce458324b50144b28fb225565..3864cd324b918f97283a7d99dad753c84e3cb748 100644
--- a/Source/WebKit/UIProcess/gtk/SystemSettingsManagerProxyGtk.cpp
+++ b/Source/WebKit/UIProcess/gtk/SystemSettingsManagerProxyGtk.cpp
@@ -128,6 +128,8 @@ int SystemSettingsManagerProxy::xftDPI() const
bool SystemSettingsManagerProxy::followFontSystemSettings() const
{
+ // Align with WPE's behavior, which always returns false.
+ return false;
#if USE(GTK4)
#if GTK_CHECK_VERSION(4, 16, 0)
GtkFontRendering fontRendering;
diff --git a/Source/WebKit/UIProcess/gtk/WebPageInspectorEmulationAgentGtk.cpp b/Source/WebKit/UIProcess/gtk/WebPageInspectorEmulationAgentGtk.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5dd29805ed464ae7641b44193caca700fa9f8a1e
--- /dev/null
+++ b/Source/WebKit/UIProcess/gtk/WebPageInspectorEmulationAgentGtk.cpp
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2019 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "DrawingAreaProxyCoordinatedGraphics.h"
+#include "WebPageInspectorEmulationAgent.h"
+#include "WebPageProxy.h"
+#include "GtkUtilities.h"
+#include "GtkVersioning.h"
+#include <WebCore/IntSize.h>
+#include <gtk/gtk.h>
+
+namespace WebKit {
+
+static bool windowHasManyTabs(GtkWidget* widget) {
+ for (GtkWidget* parent = gtk_widget_get_parent(widget); parent; parent = gtk_widget_get_parent(parent)) {
+ if (GTK_IS_NOTEBOOK(parent)) {
+ int pages = gtk_notebook_get_n_pages(GTK_NOTEBOOK(parent));
+ return pages > 1;
+ }
+ }
+ return false;
+}
+
+void WebPageInspectorEmulationAgent::platformSetSize(int width, int height, Function<void (const String& error)>&& callback)
+{
+ WebCore::IntSize viewSize(width, height);
+ GtkWidget* viewWidget = m_page.viewWidget();
+ GtkWidget* window = gtk_widget_get_toplevel(viewWidget);
+ if (!window) {
+ callback("Cannot find parent window"_s);
+ return;
+ }
+ if (!GTK_IS_WINDOW(window)) {
+ callback("Toplevel is not a window"_s);
+ return;
+ }
+ GtkAllocation viewAllocation;
+ gtk_widget_get_allocation(viewWidget, &viewAllocation);
+
+ // In GTK4 newly added tabs will have allocation size of 0x0, before the tab is shown.
+ // This is a Ctrl+click scenario. We invoke callback right away to not stall.
+ if (!viewAllocation.width && !viewAllocation.height && windowHasManyTabs(viewWidget)) {
+ callback(String());
+ return;
+ }
+
+ if (viewAllocation.width == width && viewAllocation.height == height) {
+ callback(String());
+ return;
+ }
+
+ GtkAllocation windowAllocation;
+ gtk_widget_get_allocation(window, &windowAllocation);
+
+ width += windowAllocation.width - viewAllocation.width;
+ height += windowAllocation.height - viewAllocation.height;
+
+ if (auto* drawingArea = static_cast<DrawingAreaProxyCoordinatedGraphics*>(m_page.drawingArea())) {
+ bool didNotHaveInitialAllocation = (!windowAllocation.width && !windowAllocation.height) ||
+ // Default size for new windows from browser_window_init in Tools/MiniBrowser/gtk/BrowserWindow.c.
+ (windowAllocation.width == 1024 && windowAllocation.height == 768);
+ // The callback can only be called if the page is still alive, so we can safely capture `this`.
+ drawingArea->waitForSizeUpdate([this, callback = WTF::move(callback), didNotHaveInitialAllocation, viewSize](const DrawingAreaProxyCoordinatedGraphics& drawingArea) mutable {
+ if (viewSize == drawingArea.size()) {
+ callback(String());
+ return;
+ }
+ if (didNotHaveInitialAllocation) {
+ // In gtk4 resize request may be lost (overridden by default one) if the window is not yet
+ // allocated when we are changing the size, so we try again.
+ platformSetSize(viewSize.width(), viewSize.height(), WTF::move(callback));
+ return;
+ }
+ callback("Failed to resize window"_s);
+ });
+ } else {
+ callback("No backing store for window"_s);
+ }
+ // Depending on whether default size has been applied or not, we need to
+ // do one of the calls, so we just do both.
+ gtk_window_set_default_size(GTK_WINDOW(window), width, height);
+ gtk_widget_set_size_request(window, width, height);
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit/UIProcess/gtk/WebPageInspectorInputAgentGtk.cpp b/Source/WebKit/UIProcess/gtk/WebPageInspectorInputAgentGtk.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..40355b2c69d7a94e924451b5fe1c0b96ff025663
--- /dev/null
+++ b/Source/WebKit/UIProcess/gtk/WebPageInspectorInputAgentGtk.cpp
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2019 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebPageInspectorInputAgent.h"
+
+#include "KeyBindingTranslator.h"
+#include "NativeWebKeyboardEvent.h"
+#include "WebPageProxy.h"
+#include <WebCore/PlatformKeyboardEvent.h>
+
+namespace WebKit {
+
+static unsigned modifiersToEventState(OptionSet<WebEventModifier> modifiers)
+{
+ unsigned state = 0;
+ if (modifiers.contains(WebEventModifier::ControlKey))
+ state |= GDK_CONTROL_MASK;
+ if (modifiers.contains(WebEventModifier::ShiftKey))
+ state |= GDK_SHIFT_MASK;
+ if (modifiers.contains(WebEventModifier::AltKey))
+ state |= GDK_META_MASK;
+ if (modifiers.contains(WebEventModifier::CapsLockKey))
+ state |= GDK_LOCK_MASK;
+ return state;
+}
+
+void WebPageInspectorInputAgent::platformDispatchKeyEvent(WebEventType type, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<WebEventModifier> modifiers, Vector<String>& macCommands, MonotonicTime timestamp)
+{
+ Vector<String> commands;
+ const guint keyVal = WebKeyboardEvent::gdkKeyCodeForWindowsKeyCode(windowsVirtualKeyCode);
+ if (keyVal) {
+ unsigned state = modifiersToEventState(modifiers);
+ commands = KeyBindingTranslator().commandsForKeyval(keyVal, state);
+ }
+ NativeWebKeyboardEvent event(
+ type,
+ text,
+ unmodifiedText,
+ key,
+ code,
+ keyIdentifier,
+ windowsVirtualKeyCode,
+ nativeVirtualKeyCode,
+ isAutoRepeat,
+ isKeypad,
+ isSystemKey,
+ modifiers,
+ timestamp,
+ WTF::move(commands));
+ m_page.handleKeyboardEvent(event);
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit/UIProcess/gtk/WebPasteboardProxyGtk.cpp b/Source/WebKit/UIProcess/gtk/WebPasteboardProxyGtk.cpp
index baeb21c5cee36343d37fdf552cc36b26b2d5213e..d9efcdf56227966efafe53ba82c98673a47a9959 100644
--- a/Source/WebKit/UIProcess/gtk/WebPasteboardProxyGtk.cpp
+++ b/Source/WebKit/UIProcess/gtk/WebPasteboardProxyGtk.cpp
@@ -85,8 +85,10 @@ void WebPasteboardProxy::setPrimarySelectionOwner(WebFrameProxy* frame)
if (m_primarySelectionOwner == frame)
return;
- if (m_primarySelectionOwner)
- m_primarySelectionOwner->collapseSelection();
+// Playwright begin: do not change selection in another page!
+ // if (m_primarySelectionOwner)
+ // m_primarySelectionOwner->collapseSelection();
+// Playwright end
m_primarySelectionOwner = frame;
}
diff --git a/Source/WebKit/UIProcess/mac/CorrectionPanel.h b/Source/WebKit/UIProcess/mac/CorrectionPanel.h
index 8afb6132fad823816f84328a8b0a1a514f998bf7..54b582e60f4b16b3c7ba038c8c52466cce9875c4 100644
--- a/Source/WebKit/UIProcess/mac/CorrectionPanel.h
+++ b/Source/WebKit/UIProcess/mac/CorrectionPanel.h
@@ -33,11 +33,10 @@
#import <AppKit/NSSpellChecker.h>
#import <WebCore/AlternativeTextClient.h>
#import <wtf/RetainPtr.h>
+#import "WebViewImpl.h"
namespace WebKit {
-class WebViewImpl;
-
class CorrectionPanel {
public:
CorrectionPanel();
diff --git a/Source/WebKit/UIProcess/mac/InspectorPlaywrightAgentClientMac.h b/Source/WebKit/UIProcess/mac/InspectorPlaywrightAgentClientMac.h
new file mode 100644
index 0000000000000000000000000000000000000000..edb4581e8f1f484976a9081d37cb61e54b9b81c5
--- /dev/null
+++ b/Source/WebKit/UIProcess/mac/InspectorPlaywrightAgentClientMac.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2019 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "InspectorPlaywrightAgentClient.h"
+#include <wtf/Forward.h>
+
+OBJC_PROTOCOL(_WKBrowserInspectorDelegate);
+
+namespace WebKit {
+
+class InspectorPlaywrightAgentClientMac : public InspectorPlaywrightAgentClient {
+ WTF_DEPRECATED_MAKE_FAST_ALLOCATED(InspectorPlaywrightAgentClientMac);
+public:
+ InspectorPlaywrightAgentClientMac(_WKBrowserInspectorDelegate* delegate, bool headless);
+ ~InspectorPlaywrightAgentClientMac() override = default;
+
+ RefPtr<WebPageProxy> createPage(WTF::String& error, const BrowserContext&) override;
+ void closeBrowser() override;
+ std::unique_ptr<BrowserContext> createBrowserContext(WTF::String& error, const WTF::String& proxyServer, const WTF::String& proxyBypassList) override;
+ void deleteBrowserContext(WTF::String& error, PAL::SessionID) override;
+ void takePageScreenshot(WebPageProxy&, WebCore::IntRect&& clip, bool nominalResolution, CompletionHandler<void(const String&, const String&)>&& completionHandler) override;
+
+private:
+ _WKBrowserInspectorDelegate* delegate_;
+ bool headless_;
+};
+
+
+} // namespace API
diff --git a/Source/WebKit/UIProcess/mac/InspectorPlaywrightAgentClientMac.mm b/Source/WebKit/UIProcess/mac/InspectorPlaywrightAgentClientMac.mm
new file mode 100644
index 0000000000000000000000000000000000000000..409444cd94c22ff0662d786c95b04688ce2ea7b3
--- /dev/null
+++ b/Source/WebKit/UIProcess/mac/InspectorPlaywrightAgentClientMac.mm
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2019 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+#import "InspectorPlaywrightAgentClientMac.h"
+
+#import "PageClient.h"
+#import "WebPageProxy.h"
+#import "WebProcessPool.h"
+#import "WebsiteDataStore.h"
+#import "_WKBrowserInspector.h"
+#import "WKProcessPoolInternal.h"
+#import "WKWebsiteDataStoreInternal.h"
+#import "WKWebView.h"
+#import "WKWebViewInternal.h"
+#import <WebCore/ImageUtilities.h>
+#import <wtf/RefPtr.h>
+#import <wtf/text/WTFString.h>
+
+namespace WebKit {
+
+InspectorPlaywrightAgentClientMac::InspectorPlaywrightAgentClientMac(_WKBrowserInspectorDelegate* delegate, bool headless)
+ : delegate_(delegate),
+ headless_(headless)
+{
+}
+
+RefPtr<WebPageProxy> InspectorPlaywrightAgentClientMac::createPage(WTF::String& error, const BrowserContext& browserContext)
+{
+ auto sessionID = browserContext.dataStore->sessionID();
+ WKWebView *webView = [delegate_ createNewPage:sessionID.toUInt64()];
+ if (!webView) {
+ error = "Internal error: can't create page in given context"_s;
+ return nil;
+ }
+ return [webView _page].get();
+}
+
+void InspectorPlaywrightAgentClientMac::closeBrowser()
+{
+ [delegate_ quit];
+}
+
+std::unique_ptr<BrowserContext> InspectorPlaywrightAgentClientMac::createBrowserContext(WTF::String& error, const WTF::String& proxyServer, const WTF::String& proxyBypassList)
+{
+ _WKBrowserContext* wkBrowserContext = [[delegate_ createBrowserContext:proxyServer.createNSString().get() WithBypassList:proxyBypassList.createNSString().get()] autorelease];
+ auto browserContext = std::make_unique<BrowserContext>();
+ browserContext->processPool = &static_cast<WebProcessPool&>([[wkBrowserContext processPool] _apiObject]);
+ browserContext->dataStore = &static_cast<WebsiteDataStore&>([[wkBrowserContext dataStore] _apiObject]);
+ return browserContext;
+}
+
+void InspectorPlaywrightAgentClientMac::deleteBrowserContext(WTF::String& error, PAL::SessionID sessionID)
+{
+ [delegate_ deleteBrowserContext:sessionID.toUInt64()];
+}
+
+void InspectorPlaywrightAgentClientMac::takePageScreenshot(WebPageProxy& page, WebCore::IntRect&& clipRect, bool, CompletionHandler<void(const String&, const String&)>&& completionHandler)
+{
+ int toolbarHeight = headless_ ? 0 : 59;
+ page.callAfterNextPresentationUpdate([protectedPage = Ref { page }, toolbarHeight, clipRect = WTF::move(clipRect), completionHandler = WTF::move(completionHandler)]() mutable {
+ RetainPtr<CGImageRef> imageRef = protectedPage->pageClient()->takeSnapshotForAutomation();
+ if (!imageRef) {
+ completionHandler("Could not take view snapshot"_s, emptyString());
+ return;
+ }
+
+ clipRect.move(0, toolbarHeight);
+ RetainPtr<CGImageRef> transformedImageRef = adoptCF(CGImageCreateWithImageInRect(imageRef.get(), clipRect));
+ completionHandler(emptyString(), WebCore::encodeDataURL(transformedImageRef.get(), "image/png"_s, std::nullopt));
+ });
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit/UIProcess/mac/InspectorTargetProxyMac.mm b/Source/WebKit/UIProcess/mac/InspectorTargetProxyMac.mm
new file mode 100644
index 0000000000000000000000000000000000000000..8adbd51bfecad2a273117588bf50f8f741850d14
--- /dev/null
+++ b/Source/WebKit/UIProcess/mac/InspectorTargetProxyMac.mm
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2019 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+#import "InspectorTargetProxy.h"
+#import "WebPageProxy.h"
+
+#if PLATFORM(MAC)
+
+namespace WebKit {
+
+void InspectorTargetProxy::platformActivate(String& error) const
+{
+ NSWindow* window = m_page->platformWindow();
+ [window makeKeyAndOrderFront:nil];
+}
+
+} // namespace WebKit
+
+#endif
diff --git a/Source/WebKit/UIProcess/mac/PageClientImplMac.h b/Source/WebKit/UIProcess/mac/PageClientImplMac.h
index a621f334b3f1a1d2ea1c4bba63d73fa0757fe2bd..3d6b14a3a2a8a6f42f8da31b535e76715b6fe20a 100644
--- a/Source/WebKit/UIProcess/mac/PageClientImplMac.h
+++ b/Source/WebKit/UIProcess/mac/PageClientImplMac.h
@@ -31,9 +31,11 @@
#include "PageClientImplCocoa.h"
#include "WebFullScreenManagerProxy.h"
#include <WebCore/DOMPasteAccess.h>
+#include <wtf/CheckedPtr.h>
#include <wtf/CompletionHandler.h>
#include <wtf/Forward.h>
#include <wtf/WeakObjCPtr.h>
+#include <wtf/WeakPtr.h>
@class WKEditorUndoTarget;
@class WKView;
@@ -61,6 +63,8 @@ class PageClientImpl final : public PageClientImplCocoa
WTF_OVERRIDE_DELETE_FOR_CHECKED_PTR(PageClientImpl);
#endif
public:
+ static void setHeadless(bool headless);
+
PageClientImpl(NSView *, WKWebView *);
virtual ~PageClientImpl();
@@ -177,6 +181,9 @@ private:
void updateAcceleratedCompositingMode(const LayerTreeContext&) override;
void didFirstLayerFlush(const LayerTreeContext&) override;
+// Paywright begin
+ RetainPtr<CGImageRef> takeSnapshotForAutomation() override;
+// Paywright end
RefPtr<ViewSnapshot> takeViewSnapshot(std::optional<WebCore::IntRect>&&) override;
RefPtr<ViewSnapshot> takeViewSnapshot(std::optional<WebCore::IntRect>&&, ForceSoftwareCapturingViewportSnapshot) override;
void wheelEventWasNotHandledByWebCore(const NativeWebWheelEvent&) override;
@@ -233,6 +240,10 @@ private:
void beganExitFullScreen(const WebCore::IntRect& initialFrame, const WebCore::IntRect& finalFrame, CompletionHandler<void()>&&) override;
#endif
+#if ENABLE(TOUCH_EVENTS)
+ void doneWithTouchEvent(const WebTouchEvent&, bool wasEventHandled) override;
+#endif
+
void navigationGestureDidBegin() override;
void navigationGestureWillEnd(bool willNavigate, WebBackForwardListItem&) override;
void navigationGestureDidEnd(bool willNavigate, WebBackForwardListItem&) override;
diff --git a/Source/WebKit/UIProcess/mac/PageClientImplMac.mm b/Source/WebKit/UIProcess/mac/PageClientImplMac.mm
index 23ae9a262af01284fadc90a18436b77af5752c24..730af4dee8db0f9a5dcf34623d499f4619e0d83d 100644
--- a/Source/WebKit/UIProcess/mac/PageClientImplMac.mm
+++ b/Source/WebKit/UIProcess/mac/PageClientImplMac.mm
@@ -113,6 +113,13 @@ using namespace WebCore;
WTF_MAKE_TZONE_ALLOCATED_IMPL(PageClientImpl);
+static bool _headless = false;
+
+// static
+void PageClientImpl::setHeadless(bool headless) {
+ _headless = headless;
+}
+
PageClientImpl::PageClientImpl(NSView *view, WKWebView *webView)
: PageClientImplCocoa(webView)
, m_view(view)
@@ -172,6 +179,9 @@ NSWindow *PageClientImpl::activeWindow() const
bool PageClientImpl::isViewWindowActive()
{
+ if (_headless)
+ return true;
+
ASSERT(hasProcessPrivilege(ProcessPrivilege::CanCommunicateWithWindowServer));
RetainPtr activeViewWindow = activeWindow();
return activeViewWindow.get().isKeyWindow || (activeViewWindow && [NSApp keyWindow] == activeViewWindow.get());
@@ -179,6 +189,9 @@ bool PageClientImpl::isViewWindowActive()
bool PageClientImpl::isViewFocused()
{
+ if (_headless)
+ return true;
+
// FIXME: This is called from the WebPageProxy constructor before we have a WebViewImpl.
// Once WebViewImpl and PageClient merge, this won't be a problem.
if (CheckedPtr impl = m_impl.get())
@@ -202,6 +215,9 @@ void PageClientImpl::makeFirstResponder()
bool PageClientImpl::isViewVisible(NSView *view, NSWindow *viewWindow) const
{
+ if (_headless)
+ return true;
+
auto windowIsOccluded = [&]()->bool {
return m_impl && m_impl->windowOcclusionDetectionEnabled() && (viewWindow.occlusionState & NSWindowOcclusionStateVisible) != NSWindowOcclusionStateVisible;
};
@@ -300,7 +316,8 @@ void PageClientImpl::didRelaunchProcess()
void PageClientImpl::preferencesDidChange()
{
- protect(m_impl)->preferencesDidChange();
+ if (CheckedPtr impl = m_impl.get())
+ impl->preferencesDidChange();
}
void PageClientImpl::toolTipChanged(const String& oldToolTip, const String& newToolTip)
@@ -533,6 +550,8 @@ IntRect PageClientImpl::rootViewToAccessibilityScreen(const IntRect& rect)
void PageClientImpl::doneWithKeyEvent(const NativeWebKeyboardEvent& event, bool eventWasHandled)
{
+ if (!event.nativeEvent())
+ return;
protect(m_impl)->doneWithKeyEvent(RetainPtr { event.nativeEvent() }.get(), eventWasHandled);
}
@@ -552,6 +571,8 @@ void PageClientImpl::computeHasVisualSearchResults(const URL& imageURL, Shareabl
RefPtr<WebPopupMenuProxy> PageClientImpl::createPopupMenuProxy(WebPageProxy& page)
{
+ if (_headless)
+ return nullptr;
return WebPopupMenuProxyMac::create(m_view.get().get(), protect(page.popupMenuClient()));
}
@@ -677,6 +698,12 @@ CALayer *PageClientImpl::footerBannerLayer() const
return m_impl->footerBannerLayer();
}
+// Paywright begin
+RetainPtr<CGImageRef> PageClientImpl::takeSnapshotForAutomation() {
+ return m_impl->takeSnapshotForAutomation();
+}
+// Paywright begin
+
RefPtr<ViewSnapshot> PageClientImpl::takeViewSnapshot(std::optional<WebCore::IntRect>&&)
{
return protect(m_impl)->takeViewSnapshot();
@@ -898,6 +925,13 @@ void PageClientImpl::beganExitFullScreen(const IntRect& initialFrame, const IntR
#endif // ENABLE(FULLSCREEN_API)
+#if ENABLE(TOUCH_EVENTS)
+void PageClientImpl::doneWithTouchEvent(const WebTouchEvent& event, bool wasEventHandled)
+{
+ notImplemented();
+}
+#endif // ENABLE(TOUCH_EVENTS)
+
void PageClientImpl::navigationGestureDidBegin()
{
protect(m_impl)->dismissContentRelativeChildWindowsWithAnimation(true);
@@ -1078,6 +1112,9 @@ void PageClientImpl::requestScrollToRect(const WebCore::FloatRect& targetRect, c
bool PageClientImpl::windowIsFrontWindowUnderMouse(const NativeWebMouseEvent& event)
{
+ // Simulated event.
+ if (!event.nativeEvent())
+ return false;
return protect(m_impl)->windowIsFrontWindowUnderMouse(RetainPtr { event.nativeEvent() }.get());
}
diff --git a/Source/WebKit/UIProcess/mac/PageInspectorTargetProxyMac.mm b/Source/WebKit/UIProcess/mac/PageInspectorTargetProxyMac.mm
new file mode 100644
index 0000000000000000000000000000000000000000..cdeaad88feeb7c0d0d6ec485c73928030741904a
--- /dev/null
+++ b/Source/WebKit/UIProcess/mac/PageInspectorTargetProxyMac.mm
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2019 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+#import "PageInspectorTargetProxy.h"
+#import "WebPageProxy.h"
+
+#if PLATFORM(MAC)
+
+namespace WebKit {
+
+void PageInspectorTargetProxy::platformActivate(String& error) const
+{
+ NSWindow* window = m_page->platformWindow();
+ [window makeKeyAndOrderFront:nil];
+}
+
+} // namespace WebKit
+
+#endif
diff --git a/Source/WebKit/UIProcess/mac/SecItemShimProxy.messages.in b/Source/WebKit/UIProcess/mac/SecItemShimProxy.messages.in
index f46895285dbc84c624537a194814c18f771a0c08..29ef9e5afa13b8d2b47b7f2dd4ce37846b61c35f 100644
--- a/Source/WebKit/UIProcess/mac/SecItemShimProxy.messages.in
+++ b/Source/WebKit/UIProcess/mac/SecItemShimProxy.messages.in
@@ -20,6 +20,7 @@
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#if ENABLE(SEC_ITEM_SHIM)
[
DispatchedFrom=Networking,
DispatchedTo=UI,
@@ -27,9 +28,8 @@
]
messages -> SecItemShimProxy {
-#if ENABLE(SEC_ITEM_SHIM)
SecItemRequestSync(WebKit::SecItemRequestData request) -> (std::optional<WebKit::SecItemResponseData> response) Synchronous
SecItemRequest(WebKit::SecItemRequestData request) -> (std::optional<WebKit::SecItemResponseData> response)
-#endif
}
+#endif
diff --git a/Source/WebKit/UIProcess/mac/WKTextAnimationManagerMac.mm b/Source/WebKit/UIProcess/mac/WKTextAnimationManagerMac.mm
index 6cfc616d5492bd12f7516ff2d6a67e77705f42b0..fd2e2a98b1db2c469a7f18fb2b7cbfbdc8ea3a8b 100644
--- a/Source/WebKit/UIProcess/mac/WKTextAnimationManagerMac.mm
+++ b/Source/WebKit/UIProcess/mac/WKTextAnimationManagerMac.mm
@@ -35,6 +35,7 @@
#import "WebViewImpl.h"
#import <WebCore/NativeImage.h>
#import <WebCore/TextAnimationTypes.h>
+#import <WebKit/WKWebView.h>
#import <pal/cocoa/WritingToolsUISoftLink.h>
@interface WKTextAnimationTypeEffectData : NSObject
diff --git a/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.h b/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.h
index d063c571127353548110ca306fabf076cae2c966..015f0932a0b9da6888365eb072f7c6d5d048b9bb 100644
--- a/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.h
+++ b/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.h
@@ -87,6 +87,7 @@ private:
void show() override;
void showContextMenuWithItems(Vector<Ref<WebContextMenuItem>>&&) override;
void useContextMenuItems(Vector<Ref<WebContextMenuItem>>&&) override;
+ void hide() override;
bool showAfterPostProcessingContextData();
diff --git a/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.mm b/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.mm
index 960f2529fe031dd6799c5d0d16ebf899089620e6..0a9e4684a6a149cffc4addc64b3b79bffc07211b 100644
--- a/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.mm
+++ b/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.mm
@@ -543,6 +543,12 @@ RetainPtr<NSMenuItem> WebContextMenuProxyMac::createShareMenuItem(ShareMenuItemT
}
#endif
+void WebContextMenuProxyMac::hide()
+{
+ if (m_menu)
+ [m_menu cancelTracking];
+}
+
void WebContextMenuProxyMac::show()
{
#if ENABLE(SERVICE_CONTROLS)
diff --git a/Source/WebKit/UIProcess/mac/WebPageInspectorEmulationAgentMac.mm b/Source/WebKit/UIProcess/mac/WebPageInspectorEmulationAgentMac.mm
new file mode 100644
index 0000000000000000000000000000000000000000..6113f4cd60a5d72b8ead61176cb43200803478ed
--- /dev/null
+++ b/Source/WebKit/UIProcess/mac/WebPageInspectorEmulationAgentMac.mm
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2019 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+#import "WebPageInspectorEmulationAgent.h"
+
+#import "WebPageProxy.h"
+
+namespace WebKit {
+
+void WebPageInspectorEmulationAgent::platformSetSize(int width, int height, Function<void (const String& error)>&& callback)
+{
+ NSWindow* window = m_page.platformWindow();
+ NSRect windowRect = [window frame];
+ NSRect viewRect = window.contentLayoutRect;
+ windowRect.size.width += width - viewRect.size.width;
+ windowRect.size.height += height - viewRect.size.height;
+ [window setFrame:windowRect display:YES animate:NO];
+ callback(String());
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit/UIProcess/mac/WebPageInspectorInputAgentMac.mm b/Source/WebKit/UIProcess/mac/WebPageInspectorInputAgentMac.mm
new file mode 100644
index 0000000000000000000000000000000000000000..e6d3a8764ef084790a4ca4e9891b09ddcbb70781
--- /dev/null
+++ b/Source/WebKit/UIProcess/mac/WebPageInspectorInputAgentMac.mm
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2019 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+#import "NativeWebMouseEvent.h"
+#import "NetworkProcessMessages.h"
+#import "NetworkProcessProxy.h"
+#import "WebPageInspectorInputAgent.h"
+#import "WebPageProxy.h"
+#import "WebPageProxyMessages.h"
+#import "WebsiteDataStore.h"
+#import <WebCore/IntPoint.h>
+#import <WebCore/IntSize.h>
+#import "NativeWebKeyboardEvent.h"
+
+namespace WebKit {
+
+using namespace WebCore;
+
+void WebPageInspectorInputAgent::platformDispatchMouseEvent(const String& type, int x, int y, std::optional<int>&& optionalModifiers, const String& button, std::optional<int>&& optionalClickCount, unsigned short buttons) {
+ IntPoint locationInWindow(x, y);
+
+ NSEventModifierFlags modifiers = 0;
+ if (optionalModifiers) {
+ int inputModifiers = *optionalModifiers;
+ if (inputModifiers & 1)
+ modifiers |= NSEventModifierFlagShift;
+ if (inputModifiers & 2)
+ modifiers |= NSEventModifierFlagControl;
+ if (inputModifiers & 4)
+ modifiers |= NSEventModifierFlagOption;
+ if (inputModifiers & 8)
+ modifiers |= NSEventModifierFlagCommand;
+ }
+ int clickCount = optionalClickCount ? *optionalClickCount : 0;
+
+ NSTimeInterval timestamp = [NSDate timeIntervalSinceReferenceDate];
+ NSWindow *window = m_page.platformWindow();
+ NSInteger windowNumber = window.windowNumber;
+
+ NSEventType downEventType;
+ NSEventType dragEventType;
+ NSEventType upEventType;
+
+ if (!button || button == "none"_s) {
+ downEventType = NSEventTypeMouseMoved;
+ dragEventType = NSEventTypeMouseMoved;
+ upEventType = NSEventTypeMouseMoved;
+ } else if (button == "left"_s) {
+ downEventType = NSEventTypeLeftMouseDown;
+ dragEventType = NSEventTypeLeftMouseDragged;
+ upEventType = NSEventTypeLeftMouseUp;
+ } else if (button == "middle"_s) {
+ downEventType = NSEventTypeOtherMouseDown;
+ dragEventType = NSEventTypeOtherMouseDragged;
+ upEventType = NSEventTypeOtherMouseUp;
+ } else if (button == "right"_s) {
+ downEventType = NSEventTypeRightMouseDown;
+ dragEventType = NSEventTypeRightMouseDragged;
+ upEventType = NSEventTypeRightMouseUp;
+ } else {
+ return;
+ }
+
+ NSInteger eventNumber = 0;
+
+ NSEvent* event;
+ if (type == "move"_s) {
+ event = [NSEvent mouseEventWithType:dragEventType location:locationInWindow modifierFlags:modifiers timestamp:timestamp windowNumber:windowNumber context:nil eventNumber:eventNumber clickCount:clickCount pressure:0.0f];
+ } else if (type == "down"_s) {
+ event = [NSEvent mouseEventWithType:downEventType location:locationInWindow modifierFlags:modifiers timestamp:timestamp windowNumber:windowNumber context:nil eventNumber:eventNumber clickCount:clickCount pressure:WebCore::ForceAtClick];
+ } else if (type == "up"_s) {
+ event = [NSEvent mouseEventWithType:upEventType location:locationInWindow modifierFlags:modifiers timestamp:timestamp windowNumber:windowNumber context:nil eventNumber:eventNumber clickCount:clickCount pressure:0.0f];
+ } else {
+ return;
+ }
+
+ if (button == "middle"_s) {
+ CGEventRef cgEvent = [event CGEvent];
+ CGEventSetIntegerValueField(cgEvent, kCGMouseEventButtonNumber, kCGMouseButtonCenter);
+ event = [NSEvent eventWithCGEvent:cgEvent];
+ }
+
+ NativeWebMouseEvent nativeEvent(event, nil, [window contentView], WebKit::WebEventInputSource::UserDriven);
+ nativeEvent.playwrightSetButtons(buttons);
+ m_page.handleMouseEvent(nativeEvent);
+}
+
+void WebPageInspectorInputAgent::platformDispatchKeyEvent(WebEventType type, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<WebEventModifier> modifiers, Vector<String>& commands, MonotonicTime timestamp)
+{
+ Vector<WebCore::KeypressCommand> macCommands;
+ for (const String& command : commands) {
+ m_page.registerKeypressCommandName(command);
+ macCommands.append(WebCore::KeypressCommand(command));
+ }
+ if (text.length() > 0 && macCommands.size() == 0)
+ macCommands.append(WebCore::KeypressCommand("insertText:"_s, text));
+ if (!macCommands.isEmpty())
+ if (auto replyID = m_page.grantAccessToCurrentPasteboardData(NSPasteboardNameGeneral, [] () { }))
+ protect(m_page.websiteDataStore().networkProcess())->connection().waitForAsyncReplyAndDispatchImmediately<Messages::NetworkProcess::AllowFilesAccessFromWebProcess>(*replyID, 100_ms);
+ NativeWebKeyboardEvent event(
+ type,
+ text,
+ unmodifiedText,
+ key,
+ code,
+ keyIdentifier,
+ windowsVirtualKeyCode,
+ nativeVirtualKeyCode,
+ isAutoRepeat,
+ isKeypad,
+ isSystemKey,
+ modifiers,
+ timestamp,
+ WTF::move(macCommands));
+ m_page.handleKeyboardEvent(event);
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit/UIProcess/mac/WebViewImpl.h b/Source/WebKit/UIProcess/mac/WebViewImpl.h
index 00f01a73b212bdc22a7da18c3ce1441735cec72f..ec0714a8b65d0323de74d09d039373059708f528 100644
--- a/Source/WebKit/UIProcess/mac/WebViewImpl.h
+++ b/Source/WebKit/UIProcess/mac/WebViewImpl.h
@@ -39,6 +39,7 @@
#include "WKLayoutMode.h"
#include "WebMouseEvent.h"
#include <WebCore/DOMPasteAccess.h>
+#include <WebCore/FrameIdentifier.h>
#include <WebCore/DigitalCredentialsRequestData.h>
#include <WebCore/FocusDirection.h>
#include <WebCore/HTMLMediaElementIdentifier.h>
@@ -615,6 +616,9 @@ public:
void provideDataForPasteboard(NSPasteboard *, NSString *type);
NSArray *namesOfPromisedFilesDroppedAtDestination(NSURL *dropDestination);
+// Paywright begin
+ RetainPtr<CGImageRef> takeSnapshotForAutomation();
+// Paywright end
RefPtr<ViewSnapshot> takeViewSnapshot();
RefPtr<ViewSnapshot> takeViewSnapshot(ForceSoftwareCapturingViewportSnapshot);
void saveBackForwardSnapshotForCurrentItem();
diff --git a/Source/WebKit/UIProcess/mac/WebViewImpl.mm b/Source/WebKit/UIProcess/mac/WebViewImpl.mm
index 3899b38da4dab24c275d8ac5e17e5ad39c54501a..e473f92023b209565c7e558503d25b847947e918 100644
--- a/Source/WebKit/UIProcess/mac/WebViewImpl.mm
+++ b/Source/WebKit/UIProcess/mac/WebViewImpl.mm
@@ -2604,6 +2604,11 @@ WebCore::DestinationColorSpace WebViewImpl::colorSpace()
if (!m_colorSpace)
m_colorSpace = [NSColorSpace sRGBColorSpace];
}
+ // Playwright begin
+ // window.colorSpace is sometimes null on popup windows in headless mode
+ if (!m_colorSpace)
+ return WebCore::DestinationColorSpace::SRGB();
+ // Playwright end
ASSERT(m_colorSpace);
return WebCore::DestinationColorSpace { [m_colorSpace CGColorSpace] };
@@ -5059,6 +5064,17 @@ static RetainPtr<CGImageRef> takeWindowSnapshot(CGSWindowID windowID, bool captu
return WebCore::cgWindowListCreateImage(CGRectNull, kCGWindowListOptionIncludingWindow, windowID, imageOptions);
}
+// Paywright begin
+RetainPtr<CGImageRef> WebViewImpl::takeSnapshotForAutomation() {
+ NSWindow *window = [m_view window];
+
+ CGSWindowID windowID = (CGSWindowID)window.windowNumber;
+ if (!windowID || !window.isVisible)
+ return nullptr;
+ return takeWindowSnapshot(windowID, true, ForceSoftwareCapturingViewportSnapshot::Yes);
+}
+// Paywright end
+
RefPtr<ViewSnapshot> WebViewImpl::takeViewSnapshot()
{
return takeViewSnapshot(ForceSoftwareCapturingViewportSnapshot::No);
diff --git a/Source/WebKit/UIProcess/wc/DrawingAreaProxyWC.cpp b/Source/WebKit/UIProcess/wc/DrawingAreaProxyWC.cpp
index 2a5f7ebbd13e88c0141fb1a1b5212bafcedff04d..77bf2c0a74f5263dc85281b3eb261875b13ca332 100644
--- a/Source/WebKit/UIProcess/wc/DrawingAreaProxyWC.cpp
+++ b/Source/WebKit/UIProcess/wc/DrawingAreaProxyWC.cpp
@@ -35,6 +35,7 @@
#include "MessageSenderInlines.h"
#include "UpdateInfo.h"
#include "WebPageProxy.h"
+#include "WebPageInspectorController.h"
#include <WebCore/Region.h>
namespace WebKit {
@@ -116,6 +117,19 @@ void DrawingAreaProxyWC::discardBackingStore()
m_backingStore = std::nullopt;
}
+void DrawingAreaProxyWC::captureFrame()
+{
+ if (!m_backingStore)
+ return;
+ auto surface = m_backingStore->surface();
+ if (!surface)
+ return;
+ auto image = surface->makeImageSnapshot();
+ if (!image)
+ return;
+ page()->inspectorController().didPaint(WTF::move(image));
+}
+
} // namespace WebKit
#endif // USE(GRAPHICS_LAYER_WC)
diff --git a/Source/WebKit/UIProcess/wc/DrawingAreaProxyWC.h b/Source/WebKit/UIProcess/wc/DrawingAreaProxyWC.h
index 5ede972f4b6efe213ccdd866ef77594acfcbf162..67f66b7c685eea3478b6386e1ec449d94dfff17f 100644
--- a/Source/WebKit/UIProcess/wc/DrawingAreaProxyWC.h
+++ b/Source/WebKit/UIProcess/wc/DrawingAreaProxyWC.h
@@ -50,6 +50,8 @@ public:
void paint(PlatformPaintContextPtr, const WebCore::IntRect&, WebCore::Region& unpaintedRegion);
+ void captureFrame();
+
private:
DrawingAreaProxyWC(WebPageProxy&, WebProcessProxy&);
diff --git a/Source/WebKit/UIProcess/win/InspectorPlaywrightAgentClientWin.cpp b/Source/WebKit/UIProcess/win/InspectorPlaywrightAgentClientWin.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..01d4c66fc3c471ecf58a66e18512fc78d4465d8b
--- /dev/null
+++ b/Source/WebKit/UIProcess/win/InspectorPlaywrightAgentClientWin.cpp
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2020 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "InspectorPlaywrightAgentClientWin.h"
+
+#if ENABLE(REMOTE_INSPECTOR)
+
+#include "APIPageConfiguration.h"
+#include "APIProcessPoolConfiguration.h"
+#include "InspectorPlaywrightAgent.h"
+#include "WebPageProxy.h"
+#include "WebsiteDataStore.h"
+#include "WebPreferences.h"
+#include "WebProcessPool.h"
+#include "WebView.h"
+#include "WKAPICast.h"
+#include <WebCore/CurlProxySettings.h>
+#include <wtf/HashMap.h>
+#include <wtf/RefPtr.h>
+#include <wtf/text/StringView.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebKit {
+
+InspectorPlaywrightAgentClientWin::InspectorPlaywrightAgentClientWin(ConfigureDataStoreCallback configureDataStore, CreatePageCallback createPage, QuitCallback quit)
+ : m_configureDataStore(configureDataStore)
+ , m_createPage(createPage)
+ , m_quit(quit)
+{
+}
+
+RefPtr<WebPageProxy> InspectorPlaywrightAgentClientWin::createPage(WTF::String& error, const BrowserContext& context)
+{
+ auto conf = API::PageConfiguration::create();
+ conf->setProcessPool(context.processPool.get());
+ conf->setWebsiteDataStore(context.dataStore.get());
+ return toImpl(m_createPage(toAPI(&conf.get())));
+}
+
+void InspectorPlaywrightAgentClientWin::closeBrowser()
+{
+ m_quit();
+}
+
+std::unique_ptr<BrowserContext> InspectorPlaywrightAgentClientWin::createBrowserContext(WTF::String& error, const WTF::String& proxyServer, const WTF::String& proxyBypassList)
+{
+ auto config = API::ProcessPoolConfiguration::create();
+ auto browserContext = std::make_unique<BrowserContext>();
+ browserContext->processPool = WebKit::WebProcessPool::create(config);
+ browserContext->dataStore = WebKit::WebsiteDataStore::createNonPersistent();
+ m_configureDataStore(toAPI(browserContext->dataStore.get()));
+ if (!proxyServer.isEmpty()) {
+ URL proxyURL = URL(URL(), proxyServer);
+ WebCore::CurlProxySettings settings(WTF::move(proxyURL), String(proxyBypassList));
+ browserContext->dataStore->setNetworkProxySettings(WTF::move(settings));
+ }
+ return browserContext;
+}
+
+void InspectorPlaywrightAgentClientWin::deleteBrowserContext(WTF::String& error, PAL::SessionID sessionID)
+{
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(REMOTE_INSPECTOR)
diff --git a/Source/WebKit/UIProcess/win/InspectorPlaywrightAgentClientWin.h b/Source/WebKit/UIProcess/win/InspectorPlaywrightAgentClientWin.h
new file mode 100644
index 0000000000000000000000000000000000000000..18be1f2e544e3069df48cdd1e55ad8536f57802a
--- /dev/null
+++ b/Source/WebKit/UIProcess/win/InspectorPlaywrightAgentClientWin.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2020 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(REMOTE_INSPECTOR)
+
+#include "InspectorPlaywrightAgentClient.h"
+#include <WebKit/WKInspector.h>
+#include <wtf/Forward.h>
+#include <wtf/text/StringHash.h>
+
+typedef void (*ConfigureDataStoreCallback)(WKWebsiteDataStoreRef dataStore);
+typedef WKPageRef (*CreatePageCallback)(WKPageConfigurationRef configuration);
+typedef void (*QuitCallback)();
+
+namespace WebKit {
+
+class InspectorPlaywrightAgentClientWin : public InspectorPlaywrightAgentClient {
+ WTF_DEPRECATED_MAKE_FAST_ALLOCATED(InspectorPlaywrightAgentClientWin);
+public:
+ InspectorPlaywrightAgentClientWin(ConfigureDataStoreCallback, CreatePageCallback, QuitCallback);
+ ~InspectorPlaywrightAgentClientWin() override = default;
+
+ RefPtr<WebPageProxy> createPage(WTF::String& error, const BrowserContext&) override;
+ void closeBrowser() override;
+ std::unique_ptr<BrowserContext> createBrowserContext(WTF::String& error, const WTF::String& proxyServer, const WTF::String& proxyBypassList) override;
+ void deleteBrowserContext(WTF::String& error, PAL::SessionID) override;
+
+private:
+ ConfigureDataStoreCallback m_configureDataStore;
+ CreatePageCallback m_createPage;
+ QuitCallback m_quit;
+};
+
+} // namespace API
+
+#endif // ENABLE(REMOTE_INSPECTOR)
diff --git a/Source/WebKit/UIProcess/win/InspectorTargetProxyWin.cpp b/Source/WebKit/UIProcess/win/InspectorTargetProxyWin.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..135a60361fa8fbf907382625e7c8dd4ea64ceb94
--- /dev/null
+++ b/Source/WebKit/UIProcess/win/InspectorTargetProxyWin.cpp
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2020 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "InspectorTargetProxy.h"
+#include "WebPageProxy.h"
+
+namespace WebKit {
+
+void InspectorTargetProxy::platformActivate(String& error) const
+{
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit/UIProcess/win/PageInspectorTargetProxyWin.cpp b/Source/WebKit/UIProcess/win/PageInspectorTargetProxyWin.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6469d95bbe7abe4c2dd77848e17462467eda78d0
--- /dev/null
+++ b/Source/WebKit/UIProcess/win/PageInspectorTargetProxyWin.cpp
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2020 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PageInspectorTargetProxy.h"
+#include "WebPageProxy.h"
+
+namespace WebKit {
+
+void PageInspectorTargetProxy::platformActivate(String& error) const
+{
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit/UIProcess/win/WebContextMenuProxyWin.cpp b/Source/WebKit/UIProcess/win/WebContextMenuProxyWin.cpp
index 8017b507ce2f0d67922035b1d41b9898f5dddb8c..7e40f52a0e878aeaa0aa38199b432377a6dc4cfd 100644
--- a/Source/WebKit/UIProcess/win/WebContextMenuProxyWin.cpp
+++ b/Source/WebKit/UIProcess/win/WebContextMenuProxyWin.cpp
@@ -114,5 +114,11 @@ WebContextMenuProxyWin::~WebContextMenuProxyWin()
::DestroyMenu(m_menu);
}
+void WebContextMenuProxyWin::hide()
+{
+ if (m_menu)
+ ::EndMenu();
+}
+
} // namespace WebKit
#endif // ENABLE(CONTEXT_MENUS)
diff --git a/Source/WebKit/UIProcess/win/WebContextMenuProxyWin.h b/Source/WebKit/UIProcess/win/WebContextMenuProxyWin.h
index ad633673cb4f1c5979aee23c0c3fd32f1b7421a2..2204867f7d2d6c756f17c968c1767ee667aca8c7 100644
--- a/Source/WebKit/UIProcess/win/WebContextMenuProxyWin.h
+++ b/Source/WebKit/UIProcess/win/WebContextMenuProxyWin.h
@@ -47,6 +47,7 @@ public:
private:
WebContextMenuProxyWin(WebPageProxy&, FrameInfoData&&, ContextMenuContextData&&, const UserData&);
void showContextMenuWithItems(Vector<Ref<WebContextMenuItem>>&&) override;
+ void hide() override;
HMENU m_menu;
};
diff --git a/Source/WebKit/UIProcess/win/WebPageInspectorEmulationAgentWin.cpp b/Source/WebKit/UIProcess/win/WebPageInspectorEmulationAgentWin.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..df55ee613ec085cb85ed12b45deff3a1b046861c
--- /dev/null
+++ b/Source/WebKit/UIProcess/win/WebPageInspectorEmulationAgentWin.cpp
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2020 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebPageInspectorEmulationAgent.h"
+#include "WebPageProxy.h"
+
+namespace WebKit {
+
+void WebPageInspectorEmulationAgent::platformSetSize(int width, int height, Function<void (const String& error)>&& callback)
+{
+ HWND viewHwnd = reinterpret_cast<HWND>(m_page.viewWidget());
+ HWND windowHwnd = GetAncestor(viewHwnd, GA_ROOT);
+ RECT viewRect;
+ RECT windowRect;
+
+ if (!windowHwnd || !GetWindowRect(windowHwnd, &windowRect)) {
+ callback("Could not retrieve window size"_s);
+ return;
+ }
+ if (!GetWindowRect(viewHwnd, &viewRect)) {
+ callback("Could retrieve view size"_s);
+ return;
+ }
+
+ width += windowRect.right - windowRect.left - viewRect.right + viewRect.left;
+ height += windowRect.bottom - windowRect.top - viewRect.bottom + viewRect.top;
+
+ if (!SetWindowPos(windowHwnd, 0, 0, 0, width, height, SWP_NOCOPYBITS | SWP_NOSENDCHANGING | SWP_NOMOVE)) {
+ callback("Could not resize window"_s);
+ return;
+ }
+ callback(String());
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit/UIProcess/win/WebPageInspectorInputAgentWin.cpp b/Source/WebKit/UIProcess/win/WebPageInspectorInputAgentWin.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..36fc7af8eb98b3f70d255ee858dccf580fae6679
--- /dev/null
+++ b/Source/WebKit/UIProcess/win/WebPageInspectorInputAgentWin.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2020 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include "config.h"
+#include "WebPageInspectorInputAgent.h"
+
+#include "NativeWebKeyboardEvent.h"
+#include "WebPageProxy.h"
+#include <WebCore/PlatformKeyboardEvent.h>
+
+namespace WebKit {
+
+void WebPageInspectorInputAgent::platformDispatchKeyEvent(WebEventType type, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<WebEventModifier> modifiers, Vector<String>& macCommands, MonotonicTime timestamp)
+{
+ NativeWebKeyboardEvent event(
+ type,
+ text,
+ unmodifiedText,
+ key,
+ code,
+ keyIdentifier,
+ windowsVirtualKeyCode,
+ nativeVirtualKeyCode,
+ isAutoRepeat,
+ isKeypad,
+ isSystemKey,
+ modifiers,
+ timestamp);
+ m_page.handleKeyboardEvent(event);
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit/UIProcess/win/WebView.cpp b/Source/WebKit/UIProcess/win/WebView.cpp
index 0dab0688f2a24f27477f346e9f1c791763a10b86..003b1ef6c8e9c292b870076677d6cfd915858b05 100644
--- a/Source/WebKit/UIProcess/win/WebView.cpp
+++ b/Source/WebKit/UIProcess/win/WebView.cpp
@@ -570,7 +570,7 @@ LRESULT WebView::onSizeEvent(HWND hwnd, UINT, WPARAM, LPARAM lParam, bool& handl
float intrinsicDeviceScaleFactor = deviceScaleFactorForWindow(hwnd);
if (m_page)
m_page->setIntrinsicDeviceScaleFactor(intrinsicDeviceScaleFactor);
- m_viewSize = expandedIntSize(FloatSize(LOWORD(lParam), HIWORD(lParam)) / intrinsicDeviceScaleFactor);
+ m_viewSize = expandedIntSize(FloatSize(LOWORD(lParam), HIWORD(lParam)));
if (m_page && m_page->drawingArea()) {
// FIXME specify correctly layerPosition.
diff --git a/Source/WebKit/UIProcess/wpe/AcceleratedBackingStore.cpp b/Source/WebKit/UIProcess/wpe/AcceleratedBackingStore.cpp
index 0705d7a9536a44a09c410d9e0e14b99c7ce5623e..7c9d8a156147707740cd984c170271593dcdacbd 100644
--- a/Source/WebKit/UIProcess/wpe/AcceleratedBackingStore.cpp
+++ b/Source/WebKit/UIProcess/wpe/AcceleratedBackingStore.cpp
@@ -231,7 +231,7 @@ static Expected<SkImageInfo, String> getImageInfoFromBuffer(const GRefPtr<WPEBu
return makeUnexpected("Failed to extract snapshot pixel information"_s);
}
-static Expected<Ref<ViewSnapshot>, String> saveBufferSnapshot(const GRefPtr<WPEBuffer>& buffer, std::optional<WebCore::IntRect>&& clipRect)
+static Expected<Ref<ViewSnapshot>, String> saveBufferSnapshot(const GRefPtr<WPEBuffer>& buffer, std::optional<WebCore::IntRect>&& clipRect, bool nominalResolution)
{
GUniqueOutPtr<GError> error;
GBytes* pixels = wpe_buffer_import_to_pixels(buffer.get(), &error.outPtr());
@@ -249,33 +249,39 @@ static Expected<Ref<ViewSnapshot>, String> saveBufferSnapshot(const GRefPtr<WPEB
if (!info)
return makeUnexpected(info.error());
- SkPixmap pixmap(info.value(), g_bytes_get_data(bytes.get(), nullptr), info->minRowBytes());
+ sk_sp<SkImage> fullScreenshot = SkImage::MakeRasterDirect(info, pixelsData, info->minRowBytes());
- if (clipRect) {
- SkIRect clippedRect = SkIRect::MakeXYWH(clipRect->x(), clipRect->y(), clipRect->width(), clipRect->height());
- SkImageInfo clippedInfo = info->makeWH(clipRect->width(), clipRect->height());
- SkPixmap clippedPixmap(info.value(), nullptr, clippedInfo.minRowBytes());
- if (!pixmap.extractSubset(&clippedPixmap, clippedRect))
- return makeUnexpected("Failed to extract clipped snapshot"_s);
- pixmap = clippedPixmap;
- }
-
- auto image = SkImages::RasterFromPixmap(pixmap, [](const void*, void* context) {
- g_bytes_unref(static_cast<GBytes*>(context));
- }, bytes.leakRef());
+ float deviceScale = m_view.page().deviceScaleFactor();
+ if (!clipRect && (!nominalResolution || deviceScale == 1))
+ return { ViewSnapshot::create(WTF::move(fullScreenshot)) };
- if (!image)
- return makeUnexpected("Failed to create snapshot image"_s);
+ WebCore::IntSize size = clipRect ? clipRect->size() : m_view.page().viewSize();
+ if (!nominalResolution) {
+ size.scale(deviceScale);
+ if (clipRect)
+ clipRect->scale(deviceScale);
+ }
- return { ViewSnapshot::create(WTF::move(image)) };
+ SkBitmap bitmap;
+ bitmap.allocPixels(SkImageInfo::Make(size.width(), size.height(), kN32_SkColorType, kPremul_SkAlphaType));
+ SkCanvas canvas(bitmap);
+ if (clipRect) {
+ canvas.translate(-clipRect->x(), -clipRect->y());
+ SkRect rect = SkRect::MakeXYWH(clipRect->x(), clipRect->y(), clipRect->width(), clipRect->height());
+ canvas.clipRect(rect);
+ }
+ if (nominalResolution)
+ canvas.scale(1/deviceScale, 1/deviceScale);
+ canvas.drawImage(fullScreenshot, 0, 0);
+ return { ViewSnapshot::create(WTF::move(bitmap.asImage())) };
}
-Expected<Ref<ViewSnapshot>, String> AcceleratedBackingStore::takeSnapshot(std::optional<WebCore::IntRect>&& clipRect)
+Expected<Ref<ViewSnapshot>, String> AcceleratedBackingStore::takeSnapshot(std::optional<WebCore::IntRect>&& clipRect, bool nominalResolution)
{
if (!m_committedBuffer && !m_pendingBuffer) [[unlikely]]
return makeUnexpected("No buffer to create snapshot from"_s);
- return saveBufferSnapshot(m_committedBuffer ? m_committedBuffer : m_pendingBuffer, WTF::move(clipRect));
+ return saveBufferSnapshot(m_committedBuffer ? m_committedBuffer : m_pendingBuffer, WTF::move(clipRect), nominalResolution);
}
void AcceleratedBackingStore::renderPendingBuffer()
diff --git a/Source/WebKit/UIProcess/wpe/AcceleratedBackingStore.h b/Source/WebKit/UIProcess/wpe/AcceleratedBackingStore.h
index dcb02699a62caf8b79e21259287419b76bb71b77..905c613a2550fe4442666b35b393e75784405f07 100644
--- a/Source/WebKit/UIProcess/wpe/AcceleratedBackingStore.h
+++ b/Source/WebKit/UIProcess/wpe/AcceleratedBackingStore.h
@@ -73,7 +73,7 @@ public:
void updateSurfaceID(uint64_t);
- Expected<Ref<ViewSnapshot>, String> takeSnapshot(std::optional<WebCore::IntRect>&&);
+ Expected<Ref<ViewSnapshot>, String> takeSnapshot(std::optional<WebCore::IntRect>&&, bool nominalResolution);
RendererBufferDescription bufferDescription() const;
diff --git a/Source/WebKit/UIProcess/wpe/PageInspectorTargetProxyWPE.cpp b/Source/WebKit/UIProcess/wpe/PageInspectorTargetProxyWPE.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..912e1919a1e2a29ad221114ff312ef118d323093
--- /dev/null
+++ b/Source/WebKit/UIProcess/wpe/PageInspectorTargetProxyWPE.cpp
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2019 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PageInspectorTargetProxy.h"
+
+#include "WebPageProxy.h"
+#include <wpe/wpe.h>
+
+namespace WebKit {
+
+void PageInspectorTargetProxy::platformActivate(String& error) const
+{
+ struct wpe_view_backend* backend = m_page->viewBackend();
+ wpe_view_backend_add_activity_state(backend, wpe_view_activity_state_visible | wpe_view_activity_state_focused | wpe_view_activity_state_in_window);
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit/UIProcess/wpe/WebColorPickerWPE.cpp b/Source/WebKit/UIProcess/wpe/WebColorPickerWPE.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b3c6d0a59daca4667ca8c709dad7816492389b47
--- /dev/null
+++ b/Source/WebKit/UIProcess/wpe/WebColorPickerWPE.cpp
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2015 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebColorPickerWPE.h"
+
+#include "WebPageProxy.h"
+
+namespace WebKit {
+using namespace WebCore;
+
+Ref<WebColorPickerWPE> WebColorPickerWPE::create(WebPageProxy& page, const Color& initialColor, const IntRect& rect, std::optional<WebCore::FrameIdentifier> frameID)
+{
+ return adoptRef(*new WebColorPickerWPE(page, initialColor, rect, frameID));
+}
+
+WebColorPickerWPE::WebColorPickerWPE(WebPageProxy& page, const Color& initialColor, const IntRect&, std::optional<WebCore::FrameIdentifier> frameID)
+ : WebColorPicker(&page.colorPickerClient(), frameID)
+{
+}
+
+WebColorPickerWPE::~WebColorPickerWPE()
+{
+ endPicker();
+}
+
+void WebColorPickerWPE::endPicker()
+{
+}
+
+void WebColorPickerWPE::showColorPicker(const Color& color, const IntRect&)
+{
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit/UIProcess/wpe/WebColorPickerWPE.h b/Source/WebKit/UIProcess/wpe/WebColorPickerWPE.h
new file mode 100644
index 0000000000000000000000000000000000000000..7f588248e107a19f5b700fb8e0fe51d1c5cf5aac
--- /dev/null
+++ b/Source/WebKit/UIProcess/wpe/WebColorPickerWPE.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2015 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WebColorPickerWPE_h
+#define WebColorPickerWPE_h
+
+#include "WebColorPicker.h"
+
+typedef struct _GtkColorChooser GtkColorChooser;
+
+namespace WebCore {
+class Color;
+class IntRect;
+}
+
+namespace WebKit {
+
+class WebColorPickerWPE : public WebColorPicker {
+public:
+ static Ref<WebColorPickerWPE> create(WebPageProxy&, const WebCore::Color&, const WebCore::IntRect&, std::optional<WebCore::FrameIdentifier> = std::nullopt);
+ virtual ~WebColorPickerWPE();
+
+ void endPicker() override;
+ void showColorPicker(const WebCore::Color&, const WebCore::IntRect&) override;
+
+protected:
+ WebColorPickerWPE(WebPageProxy&, const WebCore::Color&, const WebCore::IntRect&, std::optional<WebCore::FrameIdentifier> = std::nullopt);
+};
+
+} // namespace WebKit
+
+#endif // WebColorPickerWPE_h
diff --git a/Source/WebKit/UIProcess/wpe/WebDataListSuggestionsDropdownWPE.cpp b/Source/WebKit/UIProcess/wpe/WebDataListSuggestionsDropdownWPE.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c3ac81529d4dfb7070a9e1c30d4634eb10382713
--- /dev/null
+++ b/Source/WebKit/UIProcess/wpe/WebDataListSuggestionsDropdownWPE.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2019 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebDataListSuggestionsDropdownWPE.h"
+
+#include "WebPageProxy.h"
+#include <WebCore/DataListSuggestionInformation.h>
+
+namespace WebKit {
+
+WebDataListSuggestionsDropdownWPE::WebDataListSuggestionsDropdownWPE(WebPageProxy& page)
+ : WebDataListSuggestionsDropdown(page)
+{
+}
+
+WebDataListSuggestionsDropdownWPE::~WebDataListSuggestionsDropdownWPE()
+{
+}
+
+void WebDataListSuggestionsDropdownWPE::platformShow(WebCore::DataListSuggestionInformation&& information)
+{
+}
+
+void WebDataListSuggestionsDropdownWPE::handleKeydownWithIdentifier(const String& key)
+{
+}
+
+void WebDataListSuggestionsDropdownWPE::close()
+{
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit/UIProcess/wpe/WebDataListSuggestionsDropdownWPE.h b/Source/WebKit/UIProcess/wpe/WebDataListSuggestionsDropdownWPE.h
new file mode 100644
index 0000000000000000000000000000000000000000..07a7cd3ab025616a41dc809e843a7f393b8e8e2f
--- /dev/null
+++ b/Source/WebKit/UIProcess/wpe/WebDataListSuggestionsDropdownWPE.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2019 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "WebDataListSuggestionsDropdown.h"
+
+namespace WebKit {
+
+class WebPageProxy;
+
+class WebDataListSuggestionsDropdownWPE final : public WebDataListSuggestionsDropdown {
+public:
+ static Ref<WebDataListSuggestionsDropdown> create(WebPageProxy& page)
+ {
+ return adoptRef(*new WebDataListSuggestionsDropdownWPE(page));
+ }
+
+ ~WebDataListSuggestionsDropdownWPE();
+
+private:
+ WebDataListSuggestionsDropdownWPE(WebPageProxy&);
+
+ void platformShow(WebCore::DataListSuggestionInformation&&) final;
+ void handleKeydownWithIdentifier(const String&) final;
+ void close() final;
+};
+
+} // namespace WebKit
diff --git a/Source/WebKit/UIProcess/wpe/WebDateTimePickerWPE.cpp b/Source/WebKit/UIProcess/wpe/WebDateTimePickerWPE.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a44463faf011fbab08f87bb7007a5e71c2a73758
--- /dev/null
+++ b/Source/WebKit/UIProcess/wpe/WebDateTimePickerWPE.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ * Copyright (C) 2021 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebDateTimePickerWPE.h"
+
+#if ENABLE(DATE_AND_TIME_INPUT_TYPES)
+
+using namespace WebCore;
+
+namespace WebKit {
+
+Ref<WebDateTimePickerWPE> WebDateTimePickerWPE::create(WebPageProxy& page)
+{
+ return adoptRef(*new WebDateTimePickerWPE(page));
+}
+
+WebDateTimePickerWPE::~WebDateTimePickerWPE()
+{
+}
+
+WebDateTimePickerWPE::WebDateTimePickerWPE(WebPageProxy& page)
+ : WebDateTimePicker(page)
+{
+}
+
+void WebDateTimePickerWPE::showDateTimePicker(WebCore::DateTimeChooserParameters&& params)
+{
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(DATE_AND_TIME_INPUT_TYPES)
diff --git a/Source/WebKit/UIProcess/wpe/WebDateTimePickerWPE.h b/Source/WebKit/UIProcess/wpe/WebDateTimePickerWPE.h
new file mode 100644
index 0000000000000000000000000000000000000000..0c0e3fce33b06ee72c4c29d2a4abe9644f4cc895
--- /dev/null
+++ b/Source/WebKit/UIProcess/wpe/WebDateTimePickerWPE.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ * Copyright (C) 2021 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(DATE_AND_TIME_INPUT_TYPES)
+
+#include "WebDateTimePicker.h"
+#include <WebCore/DateComponents.h>
+#include <WebCore/DateTimeChooserParameters.h>
+
+namespace WebKit {
+
+class WebDateTimePickerWPE final : public WebDateTimePicker {
+public:
+ static Ref<WebDateTimePickerWPE> create(WebPageProxy&);
+ ~WebDateTimePickerWPE();
+
+private:
+ WebDateTimePickerWPE(WebPageProxy&);
+
+ void showDateTimePicker(WebCore::DateTimeChooserParameters&&) final;
+};
+
+} // namespace WebKit
+
+#endif // ENABLE(DATE_AND_TIME_INPUT_TYPES)
diff --git a/Source/WebKit/UIProcess/wpe/WebPageInspectorEmulationAgentWPE.cpp b/Source/WebKit/UIProcess/wpe/WebPageInspectorEmulationAgentWPE.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..493c44f0051a748d6570070f8b169e0e781370f4
--- /dev/null
+++ b/Source/WebKit/UIProcess/wpe/WebPageInspectorEmulationAgentWPE.cpp
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2019 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebPageInspectorEmulationAgent.h"
+
+#include "DrawingAreaProxyCoordinatedGraphics.h"
+#include "WebPageProxy.h"
+#include <wpe/wpe.h>
+
+namespace WebKit {
+
+void WebPageInspectorEmulationAgent::platformSetSize(int width, int height, Function<void (const String& error)>&& callback)
+{
+ WebCore::IntSize viewSize(width, height);
+ if (m_page.viewSize() == viewSize) {
+ callback(String());
+ return;
+ }
+
+ struct wpe_view_backend* backend = m_page.viewBackend();
+ wpe_view_backend_dispatch_set_size(backend, viewSize.width(), viewSize.height());
+ if (auto* drawingArea = static_cast<DrawingAreaProxyCoordinatedGraphics*>(m_page.drawingArea())) {
+ drawingArea->waitForSizeUpdate([callback = WTF::move(callback)](const DrawingAreaProxyCoordinatedGraphics&) mutable {
+ callback(String());
+ });
+ } else
+ callback(String());
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit/UIProcess/wpe/WebPageInspectorInputAgentWPE.cpp b/Source/WebKit/UIProcess/wpe/WebPageInspectorInputAgentWPE.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c6af56767484e2889208c96d454a0924f290ba9c
--- /dev/null
+++ b/Source/WebKit/UIProcess/wpe/WebPageInspectorInputAgentWPE.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2019 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebPageInspectorInputAgent.h"
+
+#include "NativeWebKeyboardEvent.h"
+#include "WebPageProxy.h"
+#include <WebCore/PlatformKeyboardEvent.h>
+#include <wpe/wpe.h>
+
+namespace WebKit {
+
+void WebPageInspectorInputAgent::platformDispatchKeyEvent(WebEventType type, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<WebEventModifier> modifiers, Vector<String>& macCommands, MonotonicTime timestamp)
+{
+ NativeWebKeyboardEvent event(
+ type,
+ text,
+ unmodifiedText,
+ key,
+ code,
+ keyIdentifier,
+ windowsVirtualKeyCode,
+ nativeVirtualKeyCode,
+ isAutoRepeat,
+ isKeypad,
+ isSystemKey,
+ modifiers,
+ timestamp);
+ m_page.handleKeyboardEvent(event);
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit/UIProcess/wpe/WebPreferencesWPE.cpp b/Source/WebKit/UIProcess/wpe/WebPreferencesWPE.cpp
index 9b688ad328317fea4fd96ce66e9714bad8f0f937..402a36a9c565e13ec298aa7f014f0d9208ebddb7 100644
--- a/Source/WebKit/UIProcess/wpe/WebPreferencesWPE.cpp
+++ b/Source/WebKit/UIProcess/wpe/WebPreferencesWPE.cpp
@@ -33,6 +33,10 @@ void WebPreferences::platformInitializeStore()
setAcceleratedCompositingEnabled(true);
setForceCompositingMode(true);
setThreadedScrollingEnabled(true);
+
+ // Playwright override begin
+ setThreadedScrollingEnabled(false);
+ // Playwright override end
}
} // namespace WebKit
diff --git a/Source/WebKit/WebKit.xcodeproj/project.pbxproj b/Source/WebKit/WebKit.xcodeproj/project.pbxproj
index 1b110e60239dfe1599a356d71f02b9bfe2e9a17c..1af727420f121f24a564e7756d41b51a3623f040 100644
--- a/Source/WebKit/WebKit.xcodeproj/project.pbxproj
+++ b/Source/WebKit/WebKit.xcodeproj/project.pbxproj
@@ -1570,6 +1570,7 @@
5CABDC8722C40FED001EDE8E /* APIMessageListener.h in Headers */ = {isa = PBXBuildFile; fileRef = 5CABDC8322C40FA7001EDE8E /* APIMessageListener.h */; };
5CADDE05215046BD0067D309 /* WKWebProcess.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C74300E21500492004BFA17 /* WKWebProcess.h */; settings = {ATTRIBUTES = (Private, ); }; };
5CAECB6627465AE400AB78D0 /* UnifiedSource115.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5CAECB5E27465AE300AB78D0 /* UnifiedSource115.cpp */; };
+ BF2C49ED7AD83CB7BC93CC92 /* UnifiedSource116.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1D7178FBC4EDB168CDB0B04D /* UnifiedSource116.cpp */; };
5CAF7AA726F93AB00003F19E /* adattributiond.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5CAF7AA526F93A950003F19E /* adattributiond.cpp */; };
5CAFDE452130846300B1F7E1 /* _WKInspector.h in Headers */ = {isa = PBXBuildFile; fileRef = 5CAFDE422130843500B1F7E1 /* _WKInspector.h */; settings = {ATTRIBUTES = (Private, ); }; };
5CAFDE472130846A00B1F7E1 /* _WKInspectorInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 5CAFDE442130843600B1F7E1 /* _WKInspectorInternal.h */; };
@@ -2393,6 +2394,18 @@
DF0C5F28252ECB8E00D921DB /* WKDownload.h in Headers */ = {isa = PBXBuildFile; fileRef = DF0C5F24252ECB8D00D921DB /* WKDownload.h */; settings = {ATTRIBUTES = (Public, ); }; };
DF0C5F2A252ECB8E00D921DB /* WKDownloadDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = DF0C5F26252ECB8E00D921DB /* WKDownloadDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; };
DF0C5F2B252ED44000D921DB /* WKDownloadInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = DF0C5F25252ECB8E00D921DB /* WKDownloadInternal.h */; };
+ D71A94322370E025002C4D9E /* InspectorPlaywrightAgentClientMac.h in Headers */ = {isa = PBXBuildFile; fileRef = D71A94302370E025002C4D9E /* InspectorPlaywrightAgentClientMac.h */; };
+ D71A94342370E07A002C4D9E /* InspectorPlaywrightAgentClient.h in Headers */ = {isa = PBXBuildFile; fileRef = D71A94332370E07A002C4D9E /* InspectorPlaywrightAgentClient.h */; };
+ D71A943A2370F061002C4D9E /* RemoteInspectorPipe.h in Headers */ = {isa = PBXBuildFile; fileRef = D71A94392370F060002C4D9E /* RemoteInspectorPipe.h */; };
+ D71A94422371F67E002C4D9E /* WebPageInspectorEmulationAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = D71A943F2371F67E002C4D9E /* WebPageInspectorEmulationAgent.h */; };
+ D71A94432371F67E002C4D9E /* WebPageInspectorInputAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = D71A94402371F67E002C4D9E /* WebPageInspectorInputAgent.h */; };
+ D71A944A2372290B002C4D9E /* _WKBrowserInspector.h in Headers */ = {isa = PBXBuildFile; fileRef = D71A94492372290B002C4D9E /* _WKBrowserInspector.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ D71A944C237239FB002C4D9E /* BrowserInspectorPipe.h in Headers */ = {isa = PBXBuildFile; fileRef = D71A944B237239FB002C4D9E /* BrowserInspectorPipe.h */; };
+ D76D6888238DBD81008D314B /* InspectorDialogAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = D76D6887238DBD80008D314B /* InspectorDialogAgent.h */; };
+ D79902B1236E9404005D6F7E /* WebPageInspectorEmulationAgentMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = D79902AE236E9404005D6F7E /* WebPageInspectorEmulationAgentMac.mm */; };
+ D79902B2236E9404005D6F7E /* PageInspectorTargetProxyMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = D79902AF236E9404005D6F7E /* PageInspectorTargetProxyMac.mm */; };
+ D79902B3236E9404005D6F7E /* WebPageInspectorInputAgentMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = D79902B0236E9404005D6F7E /* WebPageInspectorInputAgentMac.mm */; };
+ D7EB04E72372A73B00F744CE /* InspectorPlaywrightAgentClientMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = D7EB04E62372A73B00F744CE /* InspectorPlaywrightAgentClientMac.mm */; };
DF462E0F23F22F5500EFF35F /* WKHTTPCookieStorePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = DF462E0E23F22F5300EFF35F /* WKHTTPCookieStorePrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
DF462E1223F338BE00EFF35F /* WKContentWorldPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = DF462E1123F338AD00EFF35F /* WKContentWorldPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
DF7A231C291B088D00B98DF3 /* WKSnapshotConfigurationPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = DF7A231B291B088D00B98DF3 /* WKSnapshotConfigurationPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -2500,6 +2513,8 @@
E5BEF6822130C48000F31111 /* WebDataListSuggestionsDropdownIOS.h in Headers */ = {isa = PBXBuildFile; fileRef = E5BEF6802130C47F00F31111 /* WebDataListSuggestionsDropdownIOS.h */; };
E5CB07DC20E1678F0022C183 /* WKFormColorControl.h in Headers */ = {isa = PBXBuildFile; fileRef = E5CB07DA20E1678F0022C183 /* WKFormColorControl.h */; };
E5CBA76427A318E100DF7858 /* UnifiedSource120.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5CBA75F27A3187800DF7858 /* UnifiedSource120.cpp */; };
+ E5CBA77427A318E100DF7858 /* UnifiedSource121.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5CBA76F27A3187800DF7858 /* UnifiedSource121.cpp */; };
+ E5CBA78427A318E100DF7858 /* UnifiedSource122.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5CBA77F27A3187800DF7858 /* UnifiedSource122.cpp */; };
E5CBA76527A318E100DF7858 /* UnifiedSource118.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5CBA76127A3187900DF7858 /* UnifiedSource118.cpp */; };
E5CBA76627A318E100DF7858 /* UnifiedSource116.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5CBA76327A3187B00DF7858 /* UnifiedSource116.cpp */; };
E5CBA76727A318E100DF7858 /* UnifiedSource119.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5CBA76027A3187900DF7858 /* UnifiedSource119.cpp */; };
@@ -2546,6 +2561,8 @@
F3EEEE592DB318270038CC1D /* BidiBrowserAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = F3EEEE572DB318270038CC1D /* BidiBrowserAgent.h */; };
F3EEEE5A2DB318270038CC1D /* BidiBrowserAgent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F3EEEE582DB318270038CC1D /* BidiBrowserAgent.cpp */; };
F404455C2D5CFB56000E587E /* AppKitSoftLink.h in Headers */ = {isa = PBXBuildFile; fileRef = F404455A2D5CFB56000E587E /* AppKitSoftLink.h */; };
+ F33C7AC7249AD79C0018BE41 /* libwebrtc.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F33C7AC6249AD79C0018BE41 /* libwebrtc.dylib */; };
+ F3867F0A24607D4E008F0F31 /* InspectorScreencastAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = F3867F0424607D2B008F0F31 /* InspectorScreencastAgent.h */; };
F409BA181E6E64BC009DA28E /* WKDragDestinationAction.h in Headers */ = {isa = PBXBuildFile; fileRef = F409BA171E6E64B3009DA28E /* WKDragDestinationAction.h */; settings = {ATTRIBUTES = (Private, ); }; };
F40C3B712AB401C5007A3567 /* WKDatePickerPopoverController.h in Headers */ = {isa = PBXBuildFile; fileRef = F40C3B6F2AB40167007A3567 /* WKDatePickerPopoverController.h */; };
F41145682CD939E0004CDBD1 /* _WKTouchEventGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = F41145652CD939E0004CDBD1 /* _WKTouchEventGenerator.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -6721,6 +6738,7 @@
5CABDC8522C40FCC001EDE8E /* WKMessageListener.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKMessageListener.h; sourceTree = "<group>"; };
5CABE07A28F60E8A00D83FD9 /* WebPushMessage.serialization.in */ = {isa = PBXFileReference; lastKnownFileType = text; path = WebPushMessage.serialization.in; sourceTree = "<group>"; };
5CADDE0D2151AA010067D309 /* AuthenticationChallengeDisposition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AuthenticationChallengeDisposition.h; sourceTree = "<group>"; };
+ 1D7178FBC4EDB168CDB0B04D /* UnifiedSource116.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = UnifiedSource116.cpp; sourceTree = "<group>"; };
5CAECB5E27465AE300AB78D0 /* UnifiedSource115.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = UnifiedSource115.cpp; sourceTree = "<group>"; };
5CAF7AA426F93A750003F19E /* adattributiond */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = adattributiond; sourceTree = BUILT_PRODUCTS_DIR; };
5CAF7AA526F93A950003F19E /* adattributiond.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = adattributiond.cpp; sourceTree = "<group>"; };
@@ -8553,6 +8571,19 @@
DF0C5F24252ECB8D00D921DB /* WKDownload.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKDownload.h; sourceTree = "<group>"; };
DF0C5F25252ECB8E00D921DB /* WKDownloadInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKDownloadInternal.h; sourceTree = "<group>"; };
DF0C5F26252ECB8E00D921DB /* WKDownloadDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKDownloadDelegate.h; sourceTree = "<group>"; };
+ D71A942C2370DF81002C4D9E /* WKBrowserInspector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKBrowserInspector.h; sourceTree = "<group>"; };
+ D71A94302370E025002C4D9E /* InspectorPlaywrightAgentClientMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorPlaywrightAgentClientMac.h; sourceTree = "<group>"; };
+ D71A94332370E07A002C4D9E /* InspectorPlaywrightAgentClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorPlaywrightAgentClient.h; sourceTree = "<group>"; };
+ D71A94392370F060002C4D9E /* RemoteInspectorPipe.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RemoteInspectorPipe.h; sourceTree = "<group>"; };
+ D71A943F2371F67E002C4D9E /* WebPageInspectorEmulationAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebPageInspectorEmulationAgent.h; sourceTree = "<group>"; };
+ D71A94402371F67E002C4D9E /* WebPageInspectorInputAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebPageInspectorInputAgent.h; sourceTree = "<group>"; };
+ D71A94492372290B002C4D9E /* _WKBrowserInspector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _WKBrowserInspector.h; sourceTree = "<group>"; };
+ D71A944B237239FB002C4D9E /* BrowserInspectorPipe.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BrowserInspectorPipe.h; sourceTree = "<group>"; };
+ D76D6887238DBD80008D314B /* InspectorDialogAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorDialogAgent.h; sourceTree = "<group>"; };
+ D79902AE236E9404005D6F7E /* WebPageInspectorEmulationAgentMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebPageInspectorEmulationAgentMac.mm; sourceTree = "<group>"; };
+ D79902AF236E9404005D6F7E /* PageInspectorTargetProxyMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PageInspectorTargetProxyMac.mm; sourceTree = "<group>"; };
+ D79902B0236E9404005D6F7E /* WebPageInspectorInputAgentMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebPageInspectorInputAgentMac.mm; sourceTree = "<group>"; };
+ D7EB04E62372A73B00F744CE /* InspectorPlaywrightAgentClientMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = InspectorPlaywrightAgentClientMac.mm; sourceTree = "<group>"; };
DF462E0E23F22F5300EFF35F /* WKHTTPCookieStorePrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKHTTPCookieStorePrivate.h; sourceTree = "<group>"; };
DF462E1123F338AD00EFF35F /* WKContentWorldPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKContentWorldPrivate.h; sourceTree = "<group>"; };
DF58C6311371AC5800F9A37C /* NativeWebWheelEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NativeWebWheelEvent.h; sourceTree = "<group>"; };
@@ -8748,6 +8779,8 @@
E5CBA76127A3187900DF7858 /* UnifiedSource118.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = UnifiedSource118.cpp; sourceTree = "<group>"; };
E5CBA76227A3187900DF7858 /* UnifiedSource117.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = UnifiedSource117.cpp; sourceTree = "<group>"; };
E5CBA76327A3187B00DF7858 /* UnifiedSource116.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = UnifiedSource116.cpp; sourceTree = "<group>"; };
+ E5CBA76F27A3187800DF7858 /* UnifiedSource121.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = UnifiedSource121.cpp; sourceTree = "<group>"; };
+ E5CBA77F27A3187800DF7858 /* UnifiedSource122.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = UnifiedSource122.cpp; sourceTree = "<group>"; };
E5DEFA6726F8F42600AB68DB /* PhotosUISPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PhotosUISPI.h; sourceTree = "<group>"; };
E838FCAF2DE90BF800703353 /* ISO18013MobileDocumentRequest+Extras.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ISO18013MobileDocumentRequest+Extras.swift"; sourceTree = "<group>"; };
E88885662DC914C400C572B8 /* WKISO18013Request.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WKISO18013Request.h; sourceTree = "<group>"; };
@@ -8812,6 +8845,9 @@
F404455A2D5CFB56000E587E /* AppKitSoftLink.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppKitSoftLink.h; sourceTree = "<group>"; };
F404455B2D5CFB56000E587E /* AppKitSoftLink.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = AppKitSoftLink.mm; sourceTree = "<group>"; };
F4063DDE2D71481E00F3FE6E /* LLVMProfiling.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LLVMProfiling.h; sourceTree = "<group>"; };
+ F33C7AC6249AD79C0018BE41 /* libwebrtc.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; path = libwebrtc.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
+ F3867F0324607D2B008F0F31 /* InspectorScreencastAgent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorScreencastAgent.cpp; sourceTree = "<group>"; };
+ F3867F0424607D2B008F0F31 /* InspectorScreencastAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorScreencastAgent.h; sourceTree = "<group>"; };
F409BA171E6E64B3009DA28E /* WKDragDestinationAction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKDragDestinationAction.h; sourceTree = "<group>"; };
F40C3B6F2AB40167007A3567 /* WKDatePickerPopoverController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WKDatePickerPopoverController.h; sourceTree = "<group>"; };
F40C3B702AB40167007A3567 /* WKDatePickerPopoverController.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = WKDatePickerPopoverController.mm; sourceTree = "<group>"; };
@@ -9345,6 +9381,7 @@
3766F9EE189A1241003CF19B /* JavaScriptCore.framework in Frameworks */,
3766F9F1189A1254003CF19B /* libicucore.dylib in Frameworks */,
7B9FC5BB28A5233B007570E7 /* libWebKitPlatform.a in Frameworks */,
+ F33C7AC7249AD79C0018BE41 /* libwebrtc.dylib in Frameworks */,
3766F9EF189A1244003CF19B /* QuartzCore.framework in Frameworks */,
37694525184FC6B600CDE21F /* Security.framework in Frameworks */,
37BEC4DD1948FC6A008B4286 /* WebCore.framework in Frameworks */,
@@ -12710,6 +12747,7 @@
99788ACA1F421DCA00C08000 /* _WKAutomationSessionConfiguration.mm */,
990D28A81C6404B000986977 /* _WKAutomationSessionDelegate.h */,
990D28AF1C65203900986977 /* _WKAutomationSessionInternal.h */,
+ D71A94492372290B002C4D9E /* _WKBrowserInspector.h */,
5C4609E222430E4C009943C2 /* _WKContentRuleListAction.h */,
5C4609E322430E4D009943C2 /* _WKContentRuleListAction.mm */,
5C4609E422430E4D009943C2 /* _WKContentRuleListActionInternal.h */,
@@ -14517,6 +14555,7 @@
E34B110C27C46BC6006D2F2E /* libWebCoreTestShim.dylib */,
E34B110F27C46D09006D2F2E /* libWebCoreTestSupport.dylib */,
DDE992F4278D06D900F60D26 /* libWebKitAdditions.a */,
+ F33C7AC6249AD79C0018BE41 /* libwebrtc.dylib */,
57A9FF15252C6AEF006A2040 /* libWTF.a */,
5750F32A2032D4E500389347 /* LocalAuthentication.framework */,
570DAAB0230273D200E8FC04 /* NearField.framework */,
@@ -15117,6 +15156,8 @@
children = (
9197940423DBC4BB00257892 /* InspectorBrowserAgent.cpp */,
9197940323DBC4BB00257892 /* InspectorBrowserAgent.h */,
+ F3867F0324607D2B008F0F31 /* InspectorScreencastAgent.cpp */,
+ F3867F0424607D2B008F0F31 /* InspectorScreencastAgent.h */,
);
path = Agents;
sourceTree = "<group>";
@@ -15932,6 +15973,7 @@
E1513C65166EABB200149FCB /* AuxiliaryProcessProxy.h */,
46A2B6061E5675A200C3DEDA /* BackgroundProcessResponsivenessTimer.cpp */,
46A2B6071E5675A200C3DEDA /* BackgroundProcessResponsivenessTimer.h */,
+ D71A944B237239FB002C4D9E /* BrowserInspectorPipe.h */,
5C6D69352AC3935D0099BDAF /* BrowsingContextGroup.cpp */,
5C6D69362AC3935D0099BDAF /* BrowsingContextGroup.h */,
5CA98549210BEB5A0057EB6B /* BrowsingWarning.h */,
@@ -15962,6 +16004,8 @@
BC06F43912DBCCFB002D78DE /* GeolocationPermissionRequestProxy.cpp */,
BC06F43812DBCCFB002D78DE /* GeolocationPermissionRequestProxy.h */,
2DD5A72A1EBF09A7009BA597 /* HiddenPageThrottlingAutoIncreasesCounter.h */,
+ D76D6887238DBD80008D314B /* InspectorDialogAgent.h */,
+ D71A94332370E07A002C4D9E /* InspectorPlaywrightAgentClient.h */,
5CEABA2B2333251400797797 /* LegacyGlobalSettings.cpp */,
5CEABA2A2333247700797797 /* LegacyGlobalSettings.h */,
31607F3819627002009B87DA /* LegacySessionStateCoding.h */,
@@ -15992,6 +16036,7 @@
4683569B21E81CC7006E27A3 /* ProvisionalPageProxy.cpp */,
4683569A21E81CC7006E27A3 /* ProvisionalPageProxy.h */,
411B89CB27B2B89600F9EBD3 /* QueryPermissionResultCallback.h */,
+ D71A94392370F060002C4D9E /* RemoteInspectorPipe.h */,
5CCB54DC2A4FEA6A0005FAA8 /* RemotePageDrawingAreaProxy.cpp */,
5CCB54DB2A4FEA6A0005FAA8 /* RemotePageDrawingAreaProxy.h */,
FABBBC802D35AC6800820017 /* RemotePageFullscreenManagerProxy.cpp */,
@@ -16113,6 +16158,8 @@
BC7B6204129A0A6700D174A4 /* WebPageGroup.h */,
2D9EA3101A96D9EB002D2807 /* WebPageInjectedBundleClient.cpp */,
2D9EA30E1A96CBFF002D2807 /* WebPageInjectedBundleClient.h */,
+ D71A943F2371F67E002C4D9E /* WebPageInspectorEmulationAgent.h */,
+ D71A94402371F67E002C4D9E /* WebPageInspectorInputAgent.h */,
9B7F8A502C785725000057F3 /* WebPageLoadTiming.h */,
BC111B0B112F5E4F00337BAB /* WebPageProxy.cpp */,
BC032DCB10F4389F0058C15A /* WebPageProxy.h */,
@@ -16307,6 +16354,7 @@
BC646C1911DD399F006455B0 /* WKBackForwardListItemRef.h */,
BC646C1611DD399F006455B0 /* WKBackForwardListRef.cpp */,
BC646C1711DD399F006455B0 /* WKBackForwardListRef.h */,
+ D71A942C2370DF81002C4D9E /* WKBrowserInspector.h */,
BCB9E24A1120E15C00A137E0 /* WKContext.cpp */,
BCB9E2491120E15C00A137E0 /* WKContext.h */,
1AE52F9319201F6B00A1FA37 /* WKContextConfigurationRef.cpp */,
@@ -16890,8 +16938,11 @@
B878B613133428DC006888E9 /* CorrectionPanel.h */,
B878B614133428DC006888E9 /* CorrectionPanel.mm */,
7AFA6F682A9F57C50055322A /* DisplayLinkMac.cpp */,
+ D71A94302370E025002C4D9E /* InspectorPlaywrightAgentClientMac.h */,
+ D7EB04E62372A73B00F744CE /* InspectorPlaywrightAgentClientMac.mm */,
0FCB4E5818BBE3D9000FCFC9 /* PageClientImplMac.h */,
0FCB4E5918BBE3D9000FCFC9 /* PageClientImplMac.mm */,
+ D79902AF236E9404005D6F7E /* PageInspectorTargetProxyMac.mm */,
E18E6909169B563F009B6670 /* SecItemShimProxy.cpp */,
E18E690A169B563F009B6670 /* SecItemShimProxy.h */,
E18E690D169B57DF009B6670 /* SecItemShimProxy.messages.in */,
@@ -16911,6 +16962,8 @@
E568B92120A3AC6A00E3C856 /* WebDataListSuggestionsDropdownMac.mm */,
E55CD20124D09F1F0042DB9C /* WebDateTimePickerMac.h */,
E55CD20224D09F1F0042DB9C /* WebDateTimePickerMac.mm */,
+ D79902AE236E9404005D6F7E /* WebPageInspectorEmulationAgentMac.mm */,
+ D79902B0236E9404005D6F7E /* WebPageInspectorInputAgentMac.mm */,
BC857E8512B71EBB00EDEB2E /* WebPageProxyMac.mm */,
BC5750951268F3C6006F0F12 /* WebPopupMenuProxyMac.h */,
BC5750961268F3C6006F0F12 /* WebPopupMenuProxyMac.mm */,
@@ -17739,6 +17792,7 @@
99788ACB1F421DDA00C08000 /* _WKAutomationSessionConfiguration.h in Headers */,
990D28AC1C6420CF00986977 /* _WKAutomationSessionDelegate.h in Headers */,
990D28B11C65208D00986977 /* _WKAutomationSessionInternal.h in Headers */,
+ D71A944A2372290B002C4D9E /* _WKBrowserInspector.h in Headers */,
CD89ACBD2EA696A300C76423 /* _WKCaptionStyleMenuController.h in Headers */,
97C476282ECD33A6004D1492 /* _WKCaptionStyleMenuControllerInternal.h in Headers */,
5C4609E7224317B4009943C2 /* _WKContentRuleListAction.h in Headers */,
@@ -18059,6 +18113,7 @@
E170876C16D6CA6900F99226 /* BlobRegistryProxy.h in Headers */,
4F601432155C5AA2001FBDE0 /* BlockingResponseMap.h in Headers */,
1A5705111BE410E600874AF1 /* BlockSPI.h in Headers */,
+ D71A944C237239FB002C4D9E /* BrowserInspectorPipe.h in Headers */,
5CA9854A210BEB640057EB6B /* BrowsingWarning.h in Headers */,
A7E69BCC2B2117A100D43D3F /* BufferAndBackendInfo.h in Headers */,
BC3065FA1259344E00E71278 /* CacheModel.h in Headers */,
@@ -18265,7 +18320,11 @@
BC14DF77120B5B7900826C0C /* InjectedBundleScriptWorld.h in Headers */,
CE550E152283752200D28791 /* InsertTextOptions.h in Headers */,
9197940523DBC4BB00257892 /* InspectorBrowserAgent.h in Headers */,
+ D76D6888238DBD81008D314B /* InspectorDialogAgent.h in Headers */,
996B2B9D25E257FF00719379 /* InspectorExtensionDelegate.h in Headers */,
+ D71A94342370E07A002C4D9E /* InspectorPlaywrightAgentClient.h in Headers */,
+ D71A94322370E025002C4D9E /* InspectorPlaywrightAgentClientMac.h in Headers */,
+ F3867F0A24607D4E008F0F31 /* InspectorScreencastAgent.h in Headers */,
A5E391FD2183C1F800C8FB31 /* InspectorTargetProxy.h in Headers */,
07AE8FBD2F3BC4F300A4C0CA /* InteractionInformationAtPosition.h in Headers */,
07AE8FC22F3BC58200A4C0CA /* InteractionInformationRequest.h in Headers */,
@@ -18550,6 +18609,7 @@
07E065142F19E01000ECDA2E /* RemoteGPU.h in Headers */,
0F6E7C532C4C386800F1DB85 /* RemoteGraphicsContextMessages.h in Headers */,
F451C0FE2703B263002BA03B /* RemoteGraphicsContextProxy.h in Headers */,
+ D71A943A2370F061002C4D9E /* RemoteInspectorPipe.h in Headers */,
2D47B56D1810714E003A3AEE /* RemoteLayerBackingStore.h in Headers */,
2DDF731518E95060004F5A66 /* RemoteLayerBackingStoreCollection.h in Headers */,
5F4D67D682584880B7E5A569 /* RemoteLayerTreeCommitBundle.h in Headers */,
@@ -18995,6 +19055,8 @@
939EF87029D112EE00F23AEE /* WebPageInlines.h in Headers */,
9197940823DBC4CB00257892 /* WebPageInspectorAgentBase.h in Headers */,
A513F5402154A5D700662841 /* WebPageInspectorController.h in Headers */,
+ D71A94422371F67E002C4D9E /* WebPageInspectorEmulationAgent.h in Headers */,
+ D71A94432371F67E002C4D9E /* WebPageInspectorInputAgent.h in Headers */,
C0CE72A11247E71D00BC0EC4 /* WebPageMessages.h in Headers */,
2D5C9D0619C81D8F00B3C5C1 /* WebPageOverlay.h in Headers */,
939EF86F29D0C17300F23AEE /* WebPageProxy.h in Headers */,
@@ -21880,6 +21942,7 @@
522F792928D50EBB0069B45B /* HidService.mm in Sources */,
2749F6442146561B008380BF /* InjectedBundleNodeHandle.cpp in Sources */,
2749F6452146561E008380BF /* InjectedBundleRangeHandle.cpp in Sources */,
+ D7EB04E72372A73B00F744CE /* InspectorPlaywrightAgentClientMac.mm in Sources */,
074D6A652F385435006089F6 /* IntRectCG.swift in Sources */,
5CF250AF2EE06491006A7172 /* IPCTesterReceiver.swift in Sources */,
5C448C662EE06E11008931C7 /* IPCTesterReceiverMessageReceiver.swift in Sources */,
@@ -21899,6 +21962,7 @@
FA5AAE9C2E6A217A00FE693D /* NetworkSoftLink.mm in Sources */,
EEEEBCBD2EE35A8B000FF6AG /* NSGlassEffectView+Extras.swift in Sources */,
DD4BDE7B2CA38213001A3339 /* ObjectiveCBlockConversions.swift in Sources */,
+ D79902B2236E9404005D6F7E /* PageInspectorTargetProxyMac.mm in Sources */,
1CB9138F2E8C6D500002BCB7 /* PlatformUnifiedSource1-ARC.mm in Sources */,
1CB913932E8C71920002BCB7 /* PlatformUnifiedSource2-ARC.mm in Sources */,
A1B849382F3D9F02004256A1 /* PlaybackSessionInterfaceAVKit.mm in Sources */,
@@ -22242,6 +22306,8 @@
078B04A02CF18EAB00B453A6 /* WebPage+NavigationPreferences.swift in Sources */,
071467782DFE84E500F77867 /* WebPage+Transferable.swift in Sources */,
07CB79962CE9435700199C49 /* WebPage.swift in Sources */,
+ D79902B1236E9404005D6F7E /* WebPageInspectorEmulationAgentMac.mm in Sources */,
+ D79902B3236E9404005D6F7E /* WebPageInspectorInputAgentMac.mm in Sources */,
0715310F2F3037C100B56C0E /* WebPageProxy.swift in Sources */,
7CE9CE101FA0767A000177DE /* WebPageUpdatePreferences.cpp in Sources */,
079A4DA12D72CC0D00CA387F /* WebPageWebView.swift in Sources */,
diff --git a/Source/WebKit/WebProcess/Inspector/FrameInspectorTarget.cpp b/Source/WebKit/WebProcess/Inspector/FrameInspectorTarget.cpp
index c49360b01f22bed75a9c92b9d4ea0dbbb66d5617..0b6f28c163680d51bfee78e37613fa73b31e05dc 100644
--- a/Source/WebKit/WebProcess/Inspector/FrameInspectorTarget.cpp
+++ b/Source/WebKit/WebProcess/Inspector/FrameInspectorTarget.cpp
@@ -93,4 +93,13 @@ String FrameInspectorTarget::toTargetID(WebCore::FrameIdentifier frameID, WebCor
return makeString("frame-"_s, frameID.toUInt64(), '-', processID.toUInt64());
}
+void FrameInspectorTarget::didCreateSubframe(WebFrame& frame)
+{
+ if (!m_channel)
+ return;
+
+ // Auto connect to the subframe if the parent frame is inspected.
+ frame.connectInspector(static_cast<Inspector::FrontendChannel*>(m_channel.get())->connectionType());
+}
+
} // namespace WebKit
diff --git a/Source/WebKit/WebProcess/Inspector/FrameInspectorTarget.h b/Source/WebKit/WebProcess/Inspector/FrameInspectorTarget.h
index 2b2820a4ded07d459f3342d5457c0747c2db2215..261c255b95071b7e02365904935381c789970d48 100644
--- a/Source/WebKit/WebProcess/Inspector/FrameInspectorTarget.h
+++ b/Source/WebKit/WebProcess/Inspector/FrameInspectorTarget.h
@@ -56,6 +56,8 @@ public:
static String toTargetID(WebCore::FrameIdentifier, WebCore::ProcessIdentifier);
+ void didCreateSubframe(WebFrame&);
+
private:
WeakRef<WebFrame> m_frame;
std::unique_ptr<UIProcessForwardingFrontendChannel> m_channel;
diff --git a/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp b/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp
index ef050f1bf94dc201a89055164a5c0c9f33b9bbad..2e228513e686dd67e3e8129670b0ad374a5f54d2 100644
--- a/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp
+++ b/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp
@@ -273,6 +273,11 @@ void WebLoaderStrategy::scheduleLoad(ResourceLoader& resourceLoader, CachedResou
}
#endif
+ if (m_emulateOfflineState) {
+ scheduleInternallyFailedLoad(resourceLoader);
+ return;
+ }
+
#if ENABLE(PDFJS)
if (tryLoadingUsingPDFJSHandler(resourceLoader, trackingParameters))
return;
@@ -294,12 +299,16 @@ void WebLoaderStrategy::scheduleLoad(ResourceLoader& resourceLoader, CachedResou
}
if (InspectorInstrumentationWebKit::shouldInterceptRequest(resourceLoader)) {
- InspectorInstrumentationWebKit::interceptRequest(resourceLoader, [this, protectedThis = Ref { *this }, protectedResourceLoader = Ref { resourceLoader }, trackingParameters, shouldClearReferrerOnHTTPSToHTTPRedirect, resource = RefPtr { resource }](const ResourceRequest& request) {
- auto& resourceLoader = protectedResourceLoader.get();
- WEBLOADERSTRATEGY_RELEASE_LOG("scheduleLoad: intercepted URL will be scheduled with the NetworkProcess");
- scheduleLoadFromNetworkProcess(resourceLoader, request, *trackingParameters, shouldClearReferrerOnHTTPSToHTTPRedirect, maximumBufferingTime(resource));
- });
- return;
+ bool isMainFrameNavigation = resourceLoader.frame() && resourceLoader.frame()->isMainFrame() && resourceLoader.options().mode == FetchOptions::Mode::Navigate;
+ // Do not intercept navigation request which could already have been intercepted and resumed.
+ if (!(isMainFrameNavigation && m_existingNetworkResourceLoadIdentifierToResume)) {
+ InspectorInstrumentationWebKit::interceptRequest(resourceLoader, [this, protectedThis = Ref { *this }, protectedResourceLoader = Ref { resourceLoader }, trackingParameters, shouldClearReferrerOnHTTPSToHTTPRedirect, resource = RefPtr { resource }](const ResourceRequest& request) {
+ auto& resourceLoader = protectedResourceLoader.get();
+ WEBLOADERSTRATEGY_RELEASE_LOG("scheduleLoad: intercepted URL will be scheduled with the NetworkProcess");
+ scheduleLoadFromNetworkProcess(resourceLoader, request, *trackingParameters, shouldClearReferrerOnHTTPSToHTTPRedirect, maximumBufferingTime(resource));
+ });
+ return;
+ }
}
WEBLOADERSTRATEGY_RELEASE_LOG_FORWARDABLE(WebLoaderStrategyScheduleLoad);
@@ -431,7 +440,7 @@ static void addParametersShared(const LocalFrame* frame, NetworkResourceLoadPara
parameters.linkPreconnectEarlyHintsEnabled = mainFrame->settings().linkPreconnectEarlyHintsEnabled();
}
-void WebLoaderStrategy::scheduleLoadFromNetworkProcess(ResourceLoader& resourceLoader, const ResourceRequest& request, const WebResourceLoader::TrackingParameters& trackingParameters, bool shouldClearReferrerOnHTTPSToHTTPRedirect, Seconds maximumBufferingTime)
+bool WebLoaderStrategy::fillParametersForNetworkProcessLoad(ResourceLoader& resourceLoader, const ResourceRequest& request, const WebResourceLoader::TrackingParameters& trackingParameters, bool shouldClearReferrerOnHTTPSToHTTPRedirect, Seconds maximumBufferingTime, NetworkResourceLoadParameters& loadParameters)
{
auto identifier = *resourceLoader.identifier();
@@ -443,10 +452,10 @@ void WebLoaderStrategy::scheduleLoadFromNetworkProcess(ResourceLoader& resourceL
&& resourceLoader.frameLoader()->notifier().isInitialRequestIdentifier(identifier)
? MainFrameMainResource::Yes : MainFrameMainResource::No;
if (!page->allowsLoadFromURL(request.url(), mainFrameMainResource)) {
- RunLoop::mainSingleton().dispatch([resourceLoader = Ref { resourceLoader }, error = blockedError(request)] {
+ RunLoop::mainSingleton().dispatch([resourceLoader = Ref { resourceLoader }, error = platformStrategies()->loaderStrategy()->blockedError(request)] {
resourceLoader->didFail(error);
});
- return;
+ return false;
}
}
@@ -456,19 +465,6 @@ void WebLoaderStrategy::scheduleLoadFromNetworkProcess(ResourceLoader& resourceL
LOG(NetworkScheduling, "(WebProcess) WebLoaderStrategy::scheduleLoad, url '%s' will be scheduled with the NetworkProcess with priority %d, storedCredentialsPolicy %i", resourceLoader.url().string().latin1().data(), static_cast<int>(resourceLoader.request().priority()), (int)storedCredentialsPolicy);
- NetworkResourceLoadParameters loadParameters {
- trackingParameters.webPageProxyID,
- trackingParameters.pageID,
- trackingParameters.frameID,
- request
- };
- if (!loadParameters.createSandboxExtensionHandlesIfNecessary()) {
- RunLoop::mainSingleton().dispatch([resourceLoader = Ref { resourceLoader }, error = blockedError(request)] {
- resourceLoader->didFail(error);
- });
- return;
- }
-
loadParameters.identifier = identifier;
loadParameters.parentPID = legacyPresentingApplicationPID();
loadParameters.contentSniffingPolicy = contentSniffingPolicy;
@@ -563,14 +559,11 @@ void WebLoaderStrategy::scheduleLoadFromNetworkProcess(ResourceLoader& resourceL
if (loadParameters.options.mode != FetchOptions::Mode::Navigate) {
ASSERT(loadParameters.sourceOrigin);
- if (!loadParameters.sourceOrigin) {
- WEBLOADERSTRATEGY_RELEASE_LOG_ERROR("scheduleLoad: no sourceOrigin (priority=%d)", static_cast<int>(resourceLoader.request().priority()));
- scheduleInternallyFailedLoad(resourceLoader);
- return;
- }
+ if (!loadParameters.sourceOrigin)
+ return false;
}
- loadParameters.shouldRestrictHTTPResponseAccess = shouldPerformSecurityChecks();
+ loadParameters.shouldRestrictHTTPResponseAccess = true;
loadParameters.isMainFrameNavigation = isMainFrameNavigation;
if (loadParameters.isMainFrameNavigation && document) {
@@ -635,6 +628,30 @@ void WebLoaderStrategy::scheduleLoadFromNetworkProcess(ResourceLoader& resourceL
if (RefPtr handle = resourceLoader.cachedResource())
loadParameters.isInitiatorPrefetch = handle->type() == CachedResource::Type::LinkPrefetch;
+ return true;
+}
+
+void WebLoaderStrategy::scheduleLoadFromNetworkProcess(ResourceLoader& resourceLoader, const ResourceRequest& request, const WebResourceLoader::TrackingParameters& trackingParameters, bool shouldClearReferrerOnHTTPSToHTTPRedirect, Seconds maximumBufferingTime)
+{
+ NetworkResourceLoadParameters loadParameters {
+ trackingParameters.webPageProxyID,
+ trackingParameters.pageID,
+ trackingParameters.frameID,
+ request
+ };
+ if (!loadParameters.createSandboxExtensionHandlesIfNecessary()) {
+ RunLoop::mainSingleton().dispatch([resourceLoader = Ref { resourceLoader }, error = blockedError(request)] {
+ resourceLoader->didFail(error);
+ });
+ return;
+ }
+
+ if (!fillParametersForNetworkProcessLoad(resourceLoader, request, trackingParameters, shouldClearReferrerOnHTTPSToHTTPRedirect, maximumBufferingTime, loadParameters)) {
+ WEBLOADERSTRATEGY_RELEASE_LOG_ERROR("scheduleLoad: no sourceOrigin (priority=%d)", static_cast<int>(resourceLoader.request().priority()));
+ scheduleInternallyFailedLoad(resourceLoader);
+ return;
+ }
+
std::optional<NetworkResourceLoadIdentifier> existingNetworkResourceLoadIdentifierToResume;
if (loadParameters.isMainFrameNavigation)
existingNetworkResourceLoadIdentifierToResume = std::exchange(m_existingNetworkResourceLoadIdentifierToResume, std::nullopt);
@@ -650,7 +667,7 @@ void WebLoaderStrategy::scheduleLoadFromNetworkProcess(ResourceLoader& resourceL
}
auto loader = WebResourceLoader::create(resourceLoader, trackingParameters);
- m_webResourceLoaders.set(identifier, WTF::move(loader));
+ m_webResourceLoaders.set(*resourceLoader.identifier(), WTF::move(loader));
}
void WebLoaderStrategy::scheduleInternallyFailedLoad(WebCore::ResourceLoader& resourceLoader)
@@ -1070,7 +1087,7 @@ void WebLoaderStrategy::didFinishPreconnection(WebCore::ResourceLoaderIdentifier
bool WebLoaderStrategy::isOnLine() const
{
- return m_isOnLine;
+ return m_emulateOfflineState ? false : m_isOnLine;
}
void WebLoaderStrategy::addOnlineStateChangeListener(Function<void(bool)>&& listener)
@@ -1096,6 +1113,11 @@ void WebLoaderStrategy::isResourceLoadFinished(CachedResource& resource, Complet
void WebLoaderStrategy::setOnLineState(bool isOnLine)
{
+ if (m_emulateOfflineState) {
+ m_isOnLine = isOnLine;
+ return;
+ }
+
if (m_isOnLine == isOnLine)
return;
@@ -1104,6 +1126,12 @@ void WebLoaderStrategy::setOnLineState(bool isOnLine)
listener(isOnLine);
}
+void WebLoaderStrategy::setEmulateOfflineState(bool offline) {
+ m_emulateOfflineState = offline;
+ for (auto& listener : m_onlineStateChangeListeners)
+ listener(offline ? false : m_isOnLine);
+}
+
void WebLoaderStrategy::setCaptureExtraNetworkLoadMetricsEnabled(bool enabled)
{
WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::NetworkConnectionToWebProcess::SetCaptureExtraNetworkLoadMetricsEnabled(enabled), 0);
diff --git a/Source/WebKit/WebProcess/Network/WebLoaderStrategy.h b/Source/WebKit/WebProcess/Network/WebLoaderStrategy.h
index ab7f322fc4e1b340bb0acdc84d4f7ba39a6e0df0..d79aea95dc4e2ead71a161b24c0e1f081fad4404 100644
--- a/Source/WebKit/WebProcess/Network/WebLoaderStrategy.h
+++ b/Source/WebKit/WebProcess/Network/WebLoaderStrategy.h
@@ -26,6 +26,7 @@
#pragma once
#include "NetworkResourceLoadIdentifier.h"
+#include "NetworkResourceLoadParameters.h"
#include "WebResourceLoader.h"
#include <WebCore/LoaderStrategy.h>
#include <WebCore/ResourceError.h>
@@ -98,6 +99,9 @@ public:
bool isOnLine() const final;
void addOnlineStateChangeListener(Function<void(bool)>&&) final;
void setOnLineState(bool);
+ void setEmulateOfflineState(bool) final;
+
+ bool fillParametersForNetworkProcessLoad(WebCore::ResourceLoader&, const WebCore::ResourceRequest&, const WebResourceLoader::TrackingParameters&, bool shouldClearReferrerOnHTTPSToHTTPRedirect, Seconds maximumBufferingTime, NetworkResourceLoadParameters&);
void setExistingNetworkResourceLoadIdentifierToResume(std::optional<NetworkResourceLoadIdentifier> existingNetworkResourceLoadIdentifierToResume) { m_existingNetworkResourceLoadIdentifierToResume = existingNetworkResourceLoadIdentifierToResume; }
@@ -166,6 +170,7 @@ private:
Vector<Function<void(bool)>> m_onlineStateChangeListeners;
std::optional<NetworkResourceLoadIdentifier> m_existingNetworkResourceLoadIdentifierToResume;
bool m_isOnLine { true };
+ bool m_emulateOfflineState { false };
};
} // namespace WebKit
diff --git a/Source/WebKit/WebProcess/Network/WebResourceLoader.cpp b/Source/WebKit/WebProcess/Network/WebResourceLoader.cpp
index 24c2649b31ce74a91911c8d8ff9be630dc29d576..11e1b09f7fe0573374f887bcbe57e25e4a8f6b87 100644
--- a/Source/WebKit/WebProcess/Network/WebResourceLoader.cpp
+++ b/Source/WebKit/WebProcess/Network/WebResourceLoader.cpp
@@ -236,9 +236,6 @@ void WebResourceLoader::didReceiveResponse(ResourceResponse&& response, PrivateR
coreLoader->didReceiveResponse(ResourceResponse { inspectorResponse }, [this, protectedThis = Ref { *this }, interceptedRequestIdentifier, policyDecisionCompletionHandler = WTF::move(policyDecisionCompletionHandler), overrideData = WTF::move(overrideData)]() mutable {
RefPtr coreLoader = m_coreLoader;
- if (policyDecisionCompletionHandler)
- policyDecisionCompletionHandler();
-
if (!m_coreLoader || !coreLoader->identifier()) {
m_interceptController.continueResponse(interceptedRequestIdentifier);
return;
@@ -255,6 +252,8 @@ void WebResourceLoader::didReceiveResponse(ResourceResponse&& response, PrivateR
}
});
});
+ if (policyDecisionCompletionHandler)
+ policyDecisionCompletionHandler();
return;
}
diff --git a/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp b/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp
index 83519d3b8b16ad84a162f99ec6e3c9f9a0525e73..5cb5b17e983ef538c12bcaa81fe9e425cd622f06 100644
--- a/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp
+++ b/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp
@@ -503,6 +503,9 @@ void WebChromeClient::addMessageToConsole(MessageSource source, MessageLevel lev
if (!page)
return;
+ if (level == MessageLevel::Error)
+ page->send(Messages::WebPageProxy::LogToStderr(message));
+
#if !PLATFORM(COCOA)
page->injectedBundleUIClient().willAddMessageToConsole(page.get(), source, level, message, lineNumber, columnNumber, sourceID);
#endif
diff --git a/Source/WebKit/WebProcess/WebCoreSupport/WebDragClient.cpp b/Source/WebKit/WebProcess/WebCoreSupport/WebDragClient.cpp
index b3f2fc81270244d1e52568f2355b7e4390ce4ae3..7e34067a3c7dc61a355ac1ddd7c7a874d6bc0771 100644
--- a/Source/WebKit/WebProcess/WebCoreSupport/WebDragClient.cpp
+++ b/Source/WebKit/WebProcess/WebCoreSupport/WebDragClient.cpp
@@ -53,7 +53,7 @@ OptionSet<DragSourceAction> WebDragClient::dragSourceActionMaskForPoint(const In
return m_page.get()->allowedDragSourceActions();
}
-#if !PLATFORM(COCOA) && !PLATFORM(GTK) && !PLATFORM(WPE)
+#if !PLATFORM(COCOA) && !PLATFORM(GTK) && !PLATFORM(WPE) && !PLATFORM(WIN)
void WebDragClient::startDrag(DragItem, DataTransfer&, Frame&, const std::optional<NodeIdentifier>&)
{
}
diff --git a/Source/WebKit/WebProcess/WebCoreSupport/WebUserMediaClient.cpp b/Source/WebKit/WebProcess/WebCoreSupport/WebUserMediaClient.cpp
index 23fdfa0d3d98fc703324372684208e5c4b190dbd..529870b21ab6f2ecd41eaea822186b325d7e1ff7 100644
--- a/Source/WebKit/WebProcess/WebCoreSupport/WebUserMediaClient.cpp
+++ b/Source/WebKit/WebProcess/WebCoreSupport/WebUserMediaClient.cpp
@@ -26,6 +26,7 @@
#include "UserMediaPermissionRequestManager.h"
#include "WebPage.h"
#include "WebPageProxyMessages.h"
+#include <WebCore/ContextDestructionObserverInlines.h>
#include <WebCore/UserMediaController.h>
#include <WebCore/UserMediaRequest.h>
#include <wtf/TZoneMallocInlines.h>
diff --git a/Source/WebKit/WebProcess/WebCoreSupport/cocoa/WebDragClientCocoa.mm b/Source/WebKit/WebProcess/WebCoreSupport/cocoa/WebDragClientCocoa.mm
index bad45b79e581bd66fabf6c09189ed05317a1946e..08cbd2fa2d6283b29168ee3d0140bd35bb878098 100644
--- a/Source/WebKit/WebProcess/WebCoreSupport/cocoa/WebDragClientCocoa.mm
+++ b/Source/WebKit/WebProcess/WebCoreSupport/cocoa/WebDragClientCocoa.mm
@@ -131,7 +131,8 @@ static RefPtr<WebCore::CachedImage> cachedImage(Element& element)
void WebDragClient::declareAndWriteDragImage(const String& pasteboardName, Element& element, const URL& url, const String& label, LocalFrame*)
{
- ASSERT(pasteboardName == String(NSPasteboardNameDrag));
+ if (pasteboardName != String(NSPasteboardNameDrag))
+ return;
RefPtr image = cachedImage(element);
diff --git a/Source/WebKit/WebProcess/WebCoreSupport/win/WebDragClientWin.cpp b/Source/WebKit/WebProcess/WebCoreSupport/win/WebDragClientWin.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..741ef5b11fe8718529105339cda0fab597bad9de
--- /dev/null
+++ b/Source/WebKit/WebProcess/WebCoreSupport/win/WebDragClientWin.cpp
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2011 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebDragClient.h"
+
+#if ENABLE(DRAG_SUPPORT)
+
+#include "MessageSenderInlines.h"
+#include "WebPage.h"
+#include "WebPageProxyMessages.h"
+#include <WebCore/DataTransfer.h>
+#include <WebCore/DragData.h>
+#include <WebCore/NodeIdentifier.h>
+#include <WebCore/Pasteboard.h>
+#include <WebCore/ShareableBitmap.h>
+#include <wtf/win/GDIObject.h>
+
+#include <optional>
+
+namespace WebKit {
+using namespace WebCore;
+
+void WebDragClient::didConcludeEditDrag()
+{
+}
+
+void WebDragClient::startDrag(DragItem, DataTransfer& dataTransfer, Frame& frame, const std::optional<NodeIdentifier>&)
+{
+ m_page->willStartDrag();
+ m_page->send(Messages::WebPageProxy::StartDrag(dataTransfer.pasteboard().createDragDataMap()));
+}
+
+}; // namespace WebKit.
+
+#endif // ENABLE(DRAG_SUPPORT)
diff --git a/Source/WebKit/WebProcess/WebPage/DrawingArea.cpp b/Source/WebKit/WebProcess/WebPage/DrawingArea.cpp
index 5ac78eb5880335f49a9a6f2690626e46fbcac7f4..aa12d9c96279054e01cc9e82e78547a75702a85f 100644
--- a/Source/WebKit/WebProcess/WebPage/DrawingArea.cpp
+++ b/Source/WebKit/WebProcess/WebPage/DrawingArea.cpp
@@ -27,6 +27,7 @@
#include "DrawingArea.h"
#include "DrawingAreaMessages.h"
+#include "DrawingAreaProxyMessages.h"
#include "Logging.h"
#include "WebPage.h"
#include "WebPageCreationParameters.h"
diff --git a/Source/WebKit/WebProcess/WebPage/WebCookieJar.cpp b/Source/WebKit/WebProcess/WebPage/WebCookieJar.cpp
index 42644873c3a43e84452298c131d1d356eed6b36c..9718fb79e8918809099bc3eedd1cdfc7d751a575 100644
--- a/Source/WebKit/WebProcess/WebPage/WebCookieJar.cpp
+++ b/Source/WebKit/WebProcess/WebPage/WebCookieJar.cpp
@@ -43,6 +43,7 @@
#include <WebCore/FrameLoader.h>
#include <WebCore/LocalFrame.h>
#include <WebCore/LocalFrameLoaderClient.h>
+#include <WebCore/ResourceLoader.h>
#include <WebCore/ScriptTrackingPrivacyCategory.h>
#include <WebCore/Settings.h>
#include <WebCore/StorageSessionProvider.h>
@@ -446,6 +447,12 @@ void WebCookieJar::setOptInCookiePartitioningEnabled(bool enabled)
}
#endif
+void WebCookieJar::setCookieFromResponse(ResourceLoader& loader, const String& setCookieValue)
+{
+ const auto& request = loader.request();
+ WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::NetworkConnectionToWebProcess::SetCookieFromResponse(request.firstPartyForCookies(), SameSiteInfo::create(request), request.url(), setCookieValue), 0);
+}
+
#if !PLATFORM(COCOA)
String WebCookieJar::cookiesInPartitionedCookieStorage(const WebCore::Document&, const URL&, const WebCore::SameSiteInfo&) const
diff --git a/Source/WebKit/WebProcess/WebPage/WebCookieJar.h b/Source/WebKit/WebProcess/WebPage/WebCookieJar.h
index a7ad18fc1201e5de2cc1528539a765599ecfc41e..ebea233bc54ab6e56fb7093ff63e2368e8670ccd 100644
--- a/Source/WebKit/WebProcess/WebPage/WebCookieJar.h
+++ b/Source/WebKit/WebProcess/WebPage/WebCookieJar.h
@@ -81,6 +81,8 @@ public:
void setOptInCookiePartitioningEnabled(bool);
#endif
+ void setCookieFromResponse(WebCore::ResourceLoader&, const String& setCookieValue);
+
private:
WebCookieJar();
diff --git a/Source/WebKit/WebProcess/WebPage/WebFrame.cpp b/Source/WebKit/WebProcess/WebPage/WebFrame.cpp
index 2a3aa30f08da8e00e790dbdbac574c986a3a4f0a..9b70be2682defadef10da8b69af50ca115878cf6 100644
--- a/Source/WebKit/WebProcess/WebPage/WebFrame.cpp
+++ b/Source/WebKit/WebProcess/WebPage/WebFrame.cpp
@@ -181,6 +181,9 @@ Ref<WebFrame> WebFrame::createSubframe(WebPage& page, WebFrame& parent, const At
ASSERT(ownerElement.document().frame());
coreFrame->init();
+ if (parent.m_inspectorTarget)
+ parent.m_inspectorTarget->didCreateSubframe(frame);
+
return frame;
}
diff --git a/Source/WebKit/WebProcess/WebPage/WebPage.cpp b/Source/WebKit/WebProcess/WebPage/WebPage.cpp
index ead5b0db7cebdf2053358cc3a45c8298d0b0ad83..7b92d1d6e59cb5fbaaf9b0f638e25e7b2b2f2d63 100644
--- a/Source/WebKit/WebProcess/WebPage/WebPage.cpp
+++ b/Source/WebKit/WebProcess/WebPage/WebPage.cpp
@@ -264,6 +264,7 @@
#include <WebCore/ImageAnalysisQueue.h>
#include <WebCore/ImageOverlay.h>
#include <WebCore/ImageUtilities.h>
+#include <WebCore/InspectorInstrumentationWebKit.h>
#include <WebCore/JSDOMExceptionHandling.h>
#include <WebCore/JSNode.h>
#include <WebCore/KeyboardEvent.h>
@@ -1227,6 +1228,14 @@ WebPage::WebPage(PageIdentifier pageID, WebPageCreationParameters&& parameters)
setLinkDecorationFilteringData(WTF::move(parameters.linkDecorationFilteringData));
setAllowedQueryParametersForAdvancedPrivacyProtections(WTF::move(parameters.allowedQueryParametersForAdvancedPrivacyProtections));
#endif
+ if (parameters.deviceOrientationOverride)
+ page->setOverrideOrientation(parameters.deviceOrientationOverride);
+ // For popup windows WebPage::Show() maybe called in the next lines from the constructor,
+ // at which point the page is not in the WebProcess's map yet and it is not safe to
+ // dispatch nested message loop and receive IPC messages. To mitigate that, the actual
+ // pause is postponed until the page is added to the map.
+ if (parameters.shouldPauseInInspectorWhenShown)
+ m_page->inspectorController().pauseOnStart(parameters.windowFeatures ? PageInspectorController::PauseCondition::WHEN_CREATION_FINISHED : PageInspectorController::PauseCondition::WHEN_SHOWN);
if (parameters.windowFeatures) {
page->applyWindowFeatures(*parameters.windowFeatures);
page->chrome().show();
@@ -2217,6 +2226,22 @@ void WebPage::loadDidCommitInAnotherProcess(WebCore::FrameIdentifier frameID, st
frame->loadDidCommitInAnotherProcess(layerHostingContextIdentifier);
}
+void WebPage::loadRequestInFrameForInspector(LoadParameters&& loadParameters, WebCore::FrameIdentifier frameID)
+{
+ WebFrame* frame = WebProcess::singleton().webFrame(frameID);
+ if (!frame) {
+ send(Messages::WebPageProxy::DidDestroyNavigation(*loadParameters.navigationID));
+ return;
+ }
+
+ // FIXME: use m_pendingNavigationID instead?
+ m_pendingFrameNavigationID = loadParameters.navigationID;
+
+ FrameLoadRequest frameLoadRequest { *frame->coreLocalFrame(), WTF::move(loadParameters.request) };
+ frame->coreLocalFrame()->loader().load(WTF::move(frameLoadRequest));
+ ASSERT(!m_pendingFrameNavigationID);
+}
+
void WebPage::loadRequest(LoadParameters&& loadParameters)
{
WEBPAGE_RELEASE_LOG_FORWARDABLE(Loading, WebPageLoadRequest, loadParameters.navigationID ? loadParameters.navigationID->toUInt64() : 0, static_cast<unsigned>(loadParameters.shouldTreatAsContinuingLoad), loadParameters.request.isAppInitiated(), loadParameters.existingNetworkResourceLoadIdentifierToResume ? loadParameters.existingNetworkResourceLoadIdentifierToResume->toUInt64() : 0);
@@ -2408,7 +2433,9 @@ void WebPage::stopLoading()
void WebPage::stopLoadingDueToProcessSwap()
{
SetForScope isStoppingLoadingDueToProcessSwap(m_isStoppingLoadingDueToProcessSwap, true);
+ InspectorInstrumentationWebKit::setStoppingLoadingDueToProcessSwap(m_page.get(), true);
stopLoading();
+ InspectorInstrumentationWebKit::setStoppingLoadingDueToProcessSwap(m_page.get(), false);
}
bool WebPage::defersLoading() const
@@ -2997,7 +3024,7 @@ void WebPage::viewportPropertiesDidChange(const ViewportArguments& viewportArgum
#if PLATFORM(IOS_FAMILY)
if (m_viewportConfiguration.setViewportArguments(viewportArguments))
viewportConfigurationChanged();
-#elif PLATFORM(GTK) || PLATFORM(WPE)
+#elif PLATFORM(GTK) || PLATFORM(WPE) || PLATFORM(WIN) || PLATFORM(MAC)
// Adjust view dimensions when using fixed layout.
RefPtr localMainFrame = this->localMainFrame();
RefPtr view = localMainFrame ? localMainFrame->view() : nullptr;
@@ -3858,6 +3885,13 @@ void WebPage::flushDeferredIntersectionObservations()
protect(corePage())->flushDeferredIntersectionObservations();
}
+#if ENABLE(ORIENTATION_EVENTS)
+void WebPage::setDeviceOrientation(WebCore::IntDegrees deviceOrientation)
+{
+ m_page->setOverrideOrientation(deviceOrientation);
+}
+#endif
+
void WebPage::flushDeferredDidReceiveMouseEvent()
{
if (auto info = std::exchange(m_deferredDidReceiveMouseEvent, std::nullopt))
@@ -4147,6 +4181,100 @@ void WebPage::touchEvent(const WebTouchEvent& touchEvent, CompletionHandler<void
completionHandler(touchEvent.type(), handled);
}
+
+void WebPage::fakeTouchTap(const WebCore::IntPoint& position, uint8_t modifiers, CompletionHandler<void()>&& completionHandler)
+{
+ SetForScope<bool> userIsInteractingChange { m_userIsInteracting, true };
+
+ bool handled = false;
+
+ uint32_t id = 0;
+ float radiusX = 1.0;
+ float radiusY = 1.0;
+ float rotationAngle = 0.0;
+ float force = 1.0;
+ const WebCore::DoubleSize radius(radiusX,radiusY);
+ const WebCore::DoublePoint screenPosition = position;
+ OptionSet<WebEventModifier> eventModifiers;
+ eventModifiers = eventModifiers.fromRaw(modifiers);
+
+ {
+ Vector<WebPlatformTouchPoint> touchPoints;
+ WebPlatformTouchPoint::State state = WebPlatformTouchPoint::State::Pressed;
+ touchPoints.append(WebPlatformTouchPoint(id, state, screenPosition, position, radius, rotationAngle, force));
+
+ WebTouchEvent touchEvent({WebEventType::TouchStart, eventModifiers, MonotonicTime::now()}, WTF::move(touchPoints), {}, {});
+
+ CurrentEvent currentEvent(touchEvent);
+ handled = handleTouchEvent(m_page->mainFrame().frameID(), touchEvent, m_page.get()).value_or(false);
+ }
+ {
+ Vector<WebPlatformTouchPoint> touchPoints;
+ WebPlatformTouchPoint::State state = WebPlatformTouchPoint::State::Released;
+ touchPoints.append(WebPlatformTouchPoint(id, state, screenPosition, position, radius, rotationAngle, force));
+
+ WebTouchEvent touchEvent({WebEventType::TouchEnd, eventModifiers, MonotonicTime::now()}, WTF::move(touchPoints), {}, {});
+
+ CurrentEvent currentEvent(touchEvent);
+ handled = handleTouchEvent(m_page->mainFrame().frameID(), touchEvent, m_page.get()).value_or(false) || handled;
+ }
+ if (!handled) {
+ FloatPoint adjustedPoint;
+
+ auto* localMainFrame = dynamicDowncast<LocalFrame>(m_page->mainFrame());
+ if (!localMainFrame)
+ return;
+
+ RefPtr nodeRespondingToClick = localMainFrame->nodeRespondingToClickEvents(position, adjustedPoint);
+ Frame* frameRespondingToClick = nodeRespondingToClick ? nodeRespondingToClick->document().frame() : nullptr;
+ IntPoint adjustedIntPoint = roundedIntPoint(adjustedPoint);
+ if (!frameRespondingToClick) {
+ completionHandler();
+ return;
+ }
+ double force = 0.0;
+ SyntheticClickType syntheticClickType = SyntheticClickType::OneFingerTap;
+
+ auto modifiers = PlatformKeyboardEvent::currentStateOfModifierKeys();
+ localMainFrame->eventHandler().mouseMoved(PlatformMouseEvent(
+ adjustedIntPoint,
+ adjustedIntPoint,
+ MouseButton::None,
+ PlatformEvent::Type::MouseMoved,
+ 0,
+ modifiers,
+ MonotonicTime::now(),
+ force,
+ syntheticClickType,
+ MouseEventInputSource::UserDriven
+ ));
+ localMainFrame->eventHandler().handleMousePressEvent(PlatformMouseEvent(
+ adjustedIntPoint,
+ adjustedIntPoint,
+ MouseButton::Left,
+ PlatformEvent::Type::MousePressed,
+ 1,
+ modifiers,
+ MonotonicTime::now(),
+ force,
+ syntheticClickType,
+ MouseEventInputSource::UserDriven
+ ));
+ localMainFrame->eventHandler().handleMouseReleaseEvent(PlatformMouseEvent(
+ adjustedIntPoint,
+ adjustedIntPoint,
+ MouseButton::Left,
+ PlatformEvent::Type::MouseReleased,
+ 1,
+ modifiers,
+ MonotonicTime::now(),
+ force,
+ syntheticClickType,
+ MouseEventInputSource::UserDriven
+ ));
+ }
+ completionHandler();
+}
#endif
void WebPage::cancelPointer(WebCore::PointerID pointerId, const WebCore::IntPoint& documentPoint)
@@ -4247,6 +4375,16 @@ void WebPage::sendMessageToTargetBackend(const String& message)
ensureInspectorTarget()->sendMessageToTargetBackend(message);
}
+void WebPage::resumeInspectorIfPausedInNewWindow()
+{
+ m_page->inspectorController().resumeIfPausedInNewWindow();
+}
+
+void WebPage::didAddWebPageToWebProcess()
+{
+ m_page->inspectorController().didFinishPageCreation();
+}
+
void WebPage::insertNewlineInQuotedContent()
{
RefPtr frame = corePage()->focusController().focusedOrMainFrame();
@@ -4489,6 +4627,7 @@ void WebPage::setMainFrameDocumentVisualUpdatesAllowed(bool allowed)
void WebPage::show()
{
send(Messages::WebPageProxy::ShowPage());
+ m_page->inspectorController().didShowPage();
}
void WebPage::setIsTakingSnapshotsForApplicationSuspension(bool isTakingSnapshotsForApplicationSuspension)
@@ -5561,7 +5700,7 @@ NotificationPermissionRequestManager* WebPage::notificationPermissionRequestMana
#if ENABLE(DRAG_SUPPORT)
-#if PLATFORM(GTK)
+#if PLATFORM(GTK) || PLATFORM(WPE)
void WebPage::performDragControllerAction(DragControllerAction action, const IntPoint& clientPosition, const IntPoint& globalPosition, OptionSet<DragOperation> draggingSourceOperationMask, SelectionData&& selectionData, OptionSet<DragApplicationFlags> flags, CompletionHandler<void(std::optional<DragOperation>, DragHandlingMethod, bool, unsigned, IntRect, IntRect, std::optional<RemoteUserInputEventData>)>&& completionHandler)
{
if (!m_page)
@@ -7932,6 +8071,10 @@ void WebPage::didCommitLoad(WebFrame* frame)
if (frame && frame->isMainFrame())
m_networkResourceRequestIdentifiersForPageLoadTiming.clear();
+// Playwright begin
+ if (frame->isMainFrame())
+ send(Messages::WebPageProxy::ViewScaleFactorDidChange(viewScaleFactor()));
+// Playwright end
}
void WebPage::didFinishDocumentLoad(WebFrame& frame)
@@ -8234,6 +8377,9 @@ Ref<DocumentLoader> WebPage::createDocumentLoader(LocalFrame& frame, ResourceReq
m_allowsContentJavaScriptFromMostRecentNavigation = m_internals->pendingWebsitePolicies->allowsContentJavaScript;
WebsitePoliciesData::applyToDocumentLoader(*std::exchange(m_internals->pendingWebsitePolicies, std::nullopt), documentLoader);
}
+ } else if (m_pendingFrameNavigationID) {
+ documentLoader->setNavigationID(*m_pendingFrameNavigationID);
+ m_pendingFrameNavigationID = std::nullopt;
}
return documentLoader;
diff --git a/Source/WebKit/WebProcess/WebPage/WebPage.h b/Source/WebKit/WebProcess/WebPage/WebPage.h
index 122efe1deb60835d3b834995d672374bae5ad557..1e9ad7f9665bb9256b3036e1dcb471d2bbe0f081 100644
--- a/Source/WebKit/WebProcess/WebPage/WebPage.h
+++ b/Source/WebKit/WebProcess/WebPage/WebPage.h
@@ -49,6 +49,7 @@
#include <WebCore/NodeIdentifier.h>
#include <WebCore/NowPlayingMetadataObserver.h>
#include <WebCore/OwnerPermissionsPolicyData.h>
+#include <WebCore/Page.h>
#include <WebCore/PageIdentifier.h>
#include <WebCore/PageOverlay.h>
#include <WebCore/PlatformLayerIdentifier.h>
@@ -1403,11 +1404,11 @@ public:
void clearSelection();
void restoreSelectionInFocusedEditableElement();
-#if ENABLE(DRAG_SUPPORT) && PLATFORM(GTK)
+#if ENABLE(DRAG_SUPPORT) && (PLATFORM(GTK) || PLATFORM(WPE))
void performDragControllerAction(DragControllerAction, const WebCore::IntPoint& clientPosition, const WebCore::IntPoint& globalPosition, OptionSet<WebCore::DragOperation> draggingSourceOperationMask, WebCore::SelectionData&&, OptionSet<WebCore::DragApplicationFlags>, CompletionHandler<void(std::optional<WebCore::DragOperation>, WebCore::DragHandlingMethod, bool, unsigned, WebCore::IntRect, WebCore::IntRect, std::optional<WebCore::RemoteUserInputEventData>)>&&);
#endif
-#if ENABLE(DRAG_SUPPORT) && !PLATFORM(GTK)
+#if ENABLE(DRAG_SUPPORT) && !PLATFORM(GTK) && !PLATFORM(WPE)
void performDragControllerAction(std::optional<WebCore::FrameIdentifier>, DragControllerAction, WebCore::DragData&&, CompletionHandler<void(std::optional<WebCore::DragOperation>, WebCore::DragHandlingMethod, bool, unsigned, WebCore::IntRect, WebCore::IntRect, std::optional<WebCore::RemoteUserInputEventData>)>&&);
void performDragOperation(std::optional<WebCore::FrameIdentifier>, WebCore::DragData&&, SandboxExtension::Handle&&, Vector<SandboxExtension::Handle>&&, CompletionHandler<void(DragOperationResult dragOperationResult)>&&);
#endif
@@ -1425,6 +1426,9 @@ public:
#if ENABLE(MODEL_PROCESS)
void modelDragEnded(WebCore::NodeIdentifier);
#endif
+#if PLATFORM(MAC)
+ void setDragPasteboardName(const String& pasteboardName) { m_page->setDragPasteboardName(pasteboardName); }
+#endif
#endif
#if ENABLE(MODEL_PROCESS)
@@ -1526,8 +1530,11 @@ public:
void gestureEvent(WebCore::FrameIdentifier, const WebGestureEvent&, CompletionHandler<void(std::optional<WebEventType>, bool, std::optional<WebCore::RemoteUserInputEventData>)>&&);
#endif
-#if PLATFORM(IOS_FAMILY)
+#if ENABLE(ORIENTATION_EVENTS)
void setDeviceOrientation(WebCore::IntDegrees);
+#endif
+
+#if PLATFORM(IOS_FAMILY)
void dynamicViewportSizeUpdate(const DynamicViewportSizeUpdate&);
bool scaleWasSetByUIProcess() const { return m_scaleWasSetByUIProcess; }
void willStartUserTriggeredZooming();
@@ -1688,6 +1695,8 @@ public:
void connectInspector(Inspector::FrontendChannel::ConnectionType);
void disconnectInspector();
void sendMessageToTargetBackend(const String& message);
+ void resumeInspectorIfPausedInNewWindow();
+ void didAddWebPageToWebProcess();
void insertNewlineInQuotedContent();
@@ -2126,6 +2135,7 @@ public:
void showContextMenuFromFrame(const FrameInfoData&, const ContextMenuContextData&, const UserData&);
#endif
void loadRequest(LoadParameters&&);
+ void loadRequestInFrameForInspector(LoadParameters&&, WebCore::FrameIdentifier);
void setObscuredContentInsets(const WebCore::FloatBoxExtent&);
@@ -2348,6 +2358,7 @@ private:
void updatePotentialTapSecurityOrigin(const WebTouchEvent&, bool wasHandled);
#elif ENABLE(TOUCH_EVENTS)
void touchEvent(const WebTouchEvent&, CompletionHandler<void(std::optional<WebEventType>, bool)>&&);
+ void fakeTouchTap(const WebCore::IntPoint& position, uint8_t modifiers, CompletionHandler<void()>&& completionHandler);
#endif
void cancelPointer(WebCore::PointerID, const WebCore::IntPoint&);
@@ -3171,6 +3182,7 @@ private:
bool m_isAppNapEnabled { true };
Markable<WebCore::NavigationIdentifier> m_pendingNavigationID;
+ Markable<WebCore::NavigationIdentifier> m_pendingFrameNavigationID;
bool m_mainFrameProgressCompleted { false };
bool m_shouldDispatchFakeMouseMoveEvents { true };
diff --git a/Source/WebKit/WebProcess/WebPage/WebPage.messages.in b/Source/WebKit/WebProcess/WebPage/WebPage.messages.in
index 7ae88ddd41930501d121e488a5e2d96693a87865..323373fdcb1c47583b05ced86bc96a9ff3080ed7 100644
--- a/Source/WebKit/WebProcess/WebPage/WebPage.messages.in
+++ b/Source/WebKit/WebProcess/WebPage/WebPage.messages.in
@@ -84,10 +84,13 @@ messages -> WebPage WantsAsyncDispatchMessage {
CancelPotentialTap()
#endif
+#if ENABLE(ORIENTATION_EVENTS)
+ SetDeviceOrientation(WebCore::IntDegrees deviceOrientation)
+#endif
+
#if PLATFORM(IOS_FAMILY)
SetSceneIdentifier(String sceneIdentifier)
SetViewportConfigurationViewLayoutSize(WebCore::FloatSize size, double scaleFactor, double minimumEffectiveDeviceWidth)
- SetDeviceOrientation(WebCore::IntDegrees deviceOrientation)
SetOverrideViewportArguments(struct std::optional<WebCore::ViewportArguments> arguments)
DynamicViewportSizeUpdate(struct WebKit::DynamicViewportSizeUpdate target)
@@ -174,6 +177,7 @@ messages -> WebPage WantsAsyncDispatchMessage {
ConnectInspector(Inspector::FrontendChannel::ConnectionType connectionType)
DisconnectInspector()
SendMessageToTargetBackend(String message)
+ ResumeInspectorIfPausedInNewWindow();
#if ENABLE(REMOTE_INSPECTOR)
SetIndicating(bool indicating);
@@ -184,6 +188,7 @@ messages -> WebPage WantsAsyncDispatchMessage {
#endif
#if !ENABLE(IOS_TOUCH_EVENTS) && ENABLE(TOUCH_EVENTS)
TouchEvent(WebKit::WebTouchEvent event) -> (enum:uint32_t std::optional<WebKit::WebEventType> eventType, bool handled)
+ FakeTouchTap(WebCore::IntPoint position, uint8_t modifiers) -> () Async
#endif
CancelPointer(WebCore::PointerID pointerId, WebCore::IntPoint documentPoint)
@@ -210,6 +215,7 @@ messages -> WebPage WantsAsyncDispatchMessage {
LoadDataInFrame(std::span<const uint8_t> data, String MIMEType, String encodingName, URL baseURL, WebCore::FrameIdentifier frameID)
LoadRequest(struct WebKit::LoadParameters loadParameters)
LoadDidCommitInAnotherProcess(WebCore::FrameIdentifier frameID, std::optional<WebCore::LayerHostingContextIdentifier> layerHostingContextIdentifier)
+ LoadRequestInFrameForInspector(struct WebKit::LoadParameters loadParameters, WebCore::FrameIdentifier frameID)
LoadRequestWaitingForProcessLaunch(struct WebKit::LoadParameters loadParameters, URL resourceDirectoryURL, WebKit::WebPageProxyIdentifier pageID, bool checkAssumedReadAccessToResourceURL)
LoadData(struct WebKit::LoadParameters loadParameters)
LoadSimulatedRequestAndResponse(struct WebKit::LoadParameters loadParameters, WebCore::ResourceResponse simulatedResponse)
@@ -376,10 +382,10 @@ messages -> WebPage WantsAsyncDispatchMessage {
RemoveLayerForFindOverlay() -> ()
# Drag and drop.
-#if PLATFORM(GTK) && ENABLE(DRAG_SUPPORT)
+#if (PLATFORM(GTK) || PLATFORM(WPE)) && ENABLE(DRAG_SUPPORT)
PerformDragControllerAction(enum:uint8_t WebKit::DragControllerAction action, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, OptionSet<WebCore::DragOperation> draggingSourceOperationMask, WebCore::SelectionData selection, OptionSet<WebCore::DragApplicationFlags> flags) -> (enum:uint8_t std::optional<WebCore::DragOperation> dragOperation, enum:uint8_t WebCore::DragHandlingMethod dragHandlingMethod, bool mouseIsOverFileInput, unsigned numberOfItemsToBeAccepted, WebCore::IntRect insertionRect, WebCore::IntRect editableElementRect, struct std::optional<WebCore::RemoteUserInputEventData> remoteUserInputEventData)
#endif
-#if !PLATFORM(GTK) && ENABLE(DRAG_SUPPORT)
+#if !PLATFORM(GTK) && !PLATFORM(WPE) && ENABLE(DRAG_SUPPORT)
PerformDragControllerAction(std::optional<WebCore::FrameIdentifier> frameID, enum:uint8_t WebKit::DragControllerAction action, WebCore::DragData dragData) -> (enum:uint8_t std::optional<WebCore::DragOperation> dragOperation, enum:uint8_t WebCore::DragHandlingMethod dragHandlingMethod, bool mouseIsOverFileInput, unsigned numberOfItemsToBeAccepted, WebCore::IntRect insertionRect, WebCore::IntRect editableElementRect, struct std::optional<WebCore::RemoteUserInputEventData> remoteUserInputEventData)
PerformDragOperation(std::optional<WebCore::FrameIdentifier> frameID, WebCore::DragData dragData, WebKit::SandboxExtensionHandle sandboxExtensionHandle, Vector<WebKit::SandboxExtensionHandle> sandboxExtensionsForUpload) -> (WebKit::DragOperationResult dragOperationResult)
#endif
@@ -399,6 +405,10 @@ messages -> WebPage WantsAsyncDispatchMessage {
ModelDragEnded(WebCore::NodeIdentifier nodeID)
#endif
+#if PLATFORM(MAC) && ENABLE(DRAG_SUPPORT)
+ SetDragPasteboardName(String pasteboardName)
+#endif
+
#if PLATFORM(IOS_FAMILY) && ENABLE(DRAG_SUPPORT)
RequestDragStart(std::optional<WebCore::FrameIdentifier> remoteFrameID, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, OptionSet<WebCore::DragSourceAction> allowedActionsMask) -> (struct WebKit::DragInitiationResult result)
RequestAdditionalItemsForDragSession(std::optional<WebCore::FrameIdentifier> rootFrameID, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, OptionSet<WebCore::DragSourceAction> allowedActionsMask) -> (struct WebKit::DragInitiationResult result)
diff --git a/Source/WebKit/WebProcess/WebPage/glib/WebPageGLib.cpp b/Source/WebKit/WebProcess/WebPage/glib/WebPageGLib.cpp
index 081c8dd9bc9402d909fba5359f90c686deb9987a..b9e548e8886861fa8013f5d8af1c893f5f4a3b99 100644
--- a/Source/WebKit/WebProcess/WebPage/glib/WebPageGLib.cpp
+++ b/Source/WebKit/WebProcess/WebPage/glib/WebPageGLib.cpp
@@ -224,16 +224,23 @@ String WebPage::platformUserAgent(const URL& url) const
bool WebPage::hoverSupportedByPrimaryPointingDevice() const
{
+ if (screenHasTouchDeviceOverride())
+ return !screenHasTouchDeviceOverride().value();
return WebProcess::singleton().primaryPointingDevice() == AvailableInputDevices::Mouse;
}
bool WebPage::hoverSupportedByAnyAvailablePointingDevice() const
{
+ if (screenHasTouchDeviceOverride())
+ return !screenHasTouchDeviceOverride().value();
return WebProcess::singleton().availableInputDevices().contains(AvailableInputDevices::Mouse);
}
std::optional<PointerCharacteristics> WebPage::pointerCharacteristicsOfPrimaryPointingDevice() const
{
+ if (screenHasTouchDeviceOverride() && screenHasTouchDeviceOverride().value())
+ return PointerCharacteristics::Coarse;
+
const auto& primaryPointingDevice = WebProcess::singleton().primaryPointingDevice();
if (primaryPointingDevice == AvailableInputDevices::Mouse)
return PointerCharacteristics::Fine;
@@ -244,6 +251,9 @@ std::optional<PointerCharacteristics> WebPage::pointerCharacteristicsOfPrimaryPo
OptionSet<PointerCharacteristics> WebPage::pointerCharacteristicsOfAllAvailablePointingDevices() const
{
+ if (screenHasTouchDeviceOverride() && screenHasTouchDeviceOverride().value())
+ return PointerCharacteristics::Coarse;
+
OptionSet<PointerCharacteristics> pointerCharacteristics;
const auto& availableInputs = WebProcess::singleton().availableInputDevices();
if (availableInputs.contains(AvailableInputDevices::Mouse))
diff --git a/Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm b/Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm
index 497cb8e358ace370d15803fda7c62bc51021e9e0..37a0f3a170729652cd74fd11d8e7e994c1305736 100644
--- a/Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm
+++ b/Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm
@@ -732,21 +732,37 @@ String WebPage::platformUserAgent(const URL&) const
bool WebPage::hoverSupportedByPrimaryPointingDevice() const
{
+#if ENABLE(TOUCH_EVENTS)
+ return !screenHasTouchDevice();
+#else
return true;
+#endif
}
bool WebPage::hoverSupportedByAnyAvailablePointingDevice() const
{
+#if ENABLE(TOUCH_EVENTS)
+ return !screenHasTouchDevice();
+#else
return true;
+#endif
}
std::optional<PointerCharacteristics> WebPage::pointerCharacteristicsOfPrimaryPointingDevice() const
{
+#if ENABLE(TOUCH_EVENTS)
+ if (screenHasTouchDevice())
+ return PointerCharacteristics::Coarse;
+#endif
return PointerCharacteristics::Fine;
}
OptionSet<PointerCharacteristics> WebPage::pointerCharacteristicsOfAllAvailablePointingDevices() const
{
+#if ENABLE(TOUCH_EVENTS)
+ if (screenHasTouchDevice())
+ return PointerCharacteristics::Coarse;
+#endif
return PointerCharacteristics::Fine;
}
diff --git a/Source/WebKit/WebProcess/WebPage/win/WebPageWin.cpp b/Source/WebKit/WebProcess/WebPage/win/WebPageWin.cpp
index d32f7d2dd108647aeba05007a371b8c7381232a7..00da787b3ac4d312006a92475701c13366a1d740 100644
--- a/Source/WebKit/WebProcess/WebPage/win/WebPageWin.cpp
+++ b/Source/WebKit/WebProcess/WebPage/win/WebPageWin.cpp
@@ -45,6 +45,7 @@
#include <WebCore/NotImplemented.h>
#include <WebCore/Page.h>
#include <WebCore/PlatformKeyboardEvent.h>
+#include <WebCore/PlatformScreen.h>
#include <WebCore/PointerCharacteristics.h>
#include <WebCore/Settings.h>
#include <WebCore/SharedBuffer.h>
@@ -83,21 +84,37 @@ String WebPage::platformUserAgent(const URL&) const
bool WebPage::hoverSupportedByPrimaryPointingDevice() const
{
+#if ENABLE(TOUCH_EVENTS)
+ return !screenHasTouchDevice();
+#else
return true;
+#endif
}
bool WebPage::hoverSupportedByAnyAvailablePointingDevice() const
{
+#if ENABLE(TOUCH_EVENTS)
+ return !screenHasTouchDevice();
+#else
return true;
+#endif
}
std::optional<PointerCharacteristics> WebPage::pointerCharacteristicsOfPrimaryPointingDevice() const
{
+#if ENABLE(TOUCH_EVENTS)
+ if (screenHasTouchDevice())
+ return PointerCharacteristics::Coarse;
+#endif
return PointerCharacteristics::Fine;
}
OptionSet<PointerCharacteristics> WebPage::pointerCharacteristicsOfAllAvailablePointingDevices() const
{
+#if ENABLE(TOUCH_EVENTS)
+ if (screenHasTouchDevice())
+ return PointerCharacteristics::Coarse;
+#endif
return PointerCharacteristics::Fine;
}
diff --git a/Source/WebKit/WebProcess/WebProcess.cpp b/Source/WebKit/WebProcess/WebProcess.cpp
index 09651c68a3694eda504e88f3dda0cad5cd97a3c6..f4a0d15d58a30b4fa059659ba99bd4aa91ed327d 100644
--- a/Source/WebKit/WebProcess/WebProcess.cpp
+++ b/Source/WebKit/WebProcess/WebProcess.cpp
@@ -95,6 +95,7 @@
#include "WebsiteData.h"
#include "WebsiteDataStoreParameters.h"
#include "WebsiteDataType.h"
+#include <JavaScriptCore/IdentifiersFactory.h>
#include <JavaScriptCore/JSLock.h>
#include <JavaScriptCore/MemoryStatistics.h>
#include <JavaScriptCore/WasmFaultSignalHandler.h>
@@ -427,6 +428,14 @@ void WebProcess::initializeProcess(const AuxiliaryProcessInitializationParameter
{
JSC::Options::AllowUnfinalizedAccessScope scope;
JSC::Options::allowNonSPTagging() = false;
+ // Playwright begin
+ // SharedBufferArray is enabled only on Mac via XPC sercvice "enable-shared-array-buffer" option.
+ // For other platforms, enable it here.
+#if !PLATFORM(COCOA)
+ if (parameters.shouldEnableSharedArrayBuffer)
+ JSC::Options::useSharedArrayBuffer() = true;
+#endif
+ // Playwright end
JSC::Options::notifyOptionsChanged();
}
@@ -434,6 +443,8 @@ void WebProcess::initializeProcess(const AuxiliaryProcessInitializationParameter
platformInitializeProcess(parameters);
updateCPULimit();
+
+ Inspector::IdentifiersFactory::initializeWithProcessID(parameters.processIdentifier->toUInt64());
}
void WebProcess::initializeConnection(IPC::Connection* connection)
@@ -1058,6 +1069,7 @@ void WebProcess::createWebPage(PageIdentifier pageID, WebPageCreationParameters&
m_hasPendingAccessibilityUnsuspension = false;
accessibilityRelayProcessSuspended(false);
}
+ page->didAddWebPageToWebProcess();
}
Awaitable<unsigned> WebProcess::countWebPagesForTesting()
diff --git a/Source/WebKitLegacy/mac/WebView/WebHTMLView.mm b/Source/WebKitLegacy/mac/WebView/WebHTMLView.mm
index ba7911b2efe2ffdde8ab90f3c81817f65a43b2f0..259418a4eca2bb6ed9af2a62fbda155849c2f349 100644
--- a/Source/WebKitLegacy/mac/WebView/WebHTMLView.mm
+++ b/Source/WebKitLegacy/mac/WebView/WebHTMLView.mm
@@ -4207,7 +4207,7 @@ ALLOW_DEPRECATED_DECLARATIONS_END
_private->handlingMouseDownEvent = NO;
}
-#if ENABLE(TOUCH_EVENTS)
+#if ENABLE(IOS_TOUCH_EVENTS)
- (void)touch:(WebEvent *)event
{
diff --git a/Source/WebKitLegacy/mac/WebView/WebView.mm b/Source/WebKitLegacy/mac/WebView/WebView.mm
index bec7313812c922a7175d0f9aca27818066d54df8..8af7c061efe469493d5e2f38679b7038fb483c34 100644
--- a/Source/WebKitLegacy/mac/WebView/WebView.mm
+++ b/Source/WebKitLegacy/mac/WebView/WebView.mm
@@ -3976,7 +3976,7 @@ + (void)_doNotStartObservingNetworkReachability
}
#endif // PLATFORM(IOS_FAMILY)
-#if ENABLE(TOUCH_EVENTS)
+#if ENABLE(IOS_TOUCH_EVENTS)
- (NSArray *)_touchEventRegions
{
@@ -4018,7 +4018,7 @@ - (NSArray *)_touchEventRegions
}).autorelease();
}
-#endif // ENABLE(TOUCH_EVENTS)
+#endif // ENABLE(IOS_TOUCH_EVENTS)
// For backwards compatibility with the WebBackForwardList API, we honor both
// a per-WebView and a per-preferences setting for whether to use the back/forward cache.
diff --git a/Source/cmake/OptionsGTK.cmake b/Source/cmake/OptionsGTK.cmake
index 1f1b576f84c8ad254868d8e2b2f4f0429ea59d06..11e5f0d982166f5f5c6e44984d48b912409cfff4 100644
--- a/Source/cmake/OptionsGTK.cmake
+++ b/Source/cmake/OptionsGTK.cmake
@@ -9,6 +9,10 @@ set(USER_AGENT_BRANDING "" CACHE STRING "Branding to add to user agent string")
# Update Source/WTF/wtf/Platform.h to match required GLib versions.
find_package(GLib 2.70.0 REQUIRED COMPONENTS GioUnix Thread Module)
+
+set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
+set(THREADS_PREFER_PTHREAD_FLAG TRUE)
+
find_package(Cairo 1.16.0 REQUIRED)
find_package(LibGcrypt 1.7.0 REQUIRED)
find_package(Soup3 3.0.0 REQUIRED)
@@ -72,6 +76,10 @@ WEBKIT_OPTION_DEFINE(USE_SYSTEM_UNIFDEF "Whether to use a system-provided unifde
WEBKIT_OPTION_DEPEND(USE_SYSTEM_SYSPROF_CAPTURE USE_SYSPROF_CAPTURE)
+# Playwright begin.
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(USE_SYSTEM_SYSPROF_CAPTURE PRIVATE OFF)
+# Playwright end.
+
SET_AND_EXPOSE_TO_BUILD(ENABLE_DEVELOPER_MODE ${DEVELOPER_MODE})
if (DEVELOPER_MODE)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_API_TESTS PRIVATE ON)
@@ -150,6 +158,21 @@ WEBKIT_OPTION_DEFAULT_PORT_VALUE(USE_SKIA PRIVATE ON)
WEBKIT_OPTION_DEPEND(ENABLE_GPU_PROCESS USE_GBM)
+# Playwright begin.
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_GAMEPAD PUBLIC OFF)
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_PDFJS PUBLIC OFF)
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_RECORDER PRIVATE OFF)
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_THUNDER PRIVATE OFF)
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEBXR PRIVATE OFF)
+
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_APPLICATION_MANIFEST PRIVATE ON)
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_CURSOR_VISIBILITY PRIVATE ON)
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_DEVICE_ORIENTATION PRIVATE ON)
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_GAMEPAD PRIVATE ON)
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_SPEECH_SYNTHESIS PRIVATE ON)
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_POINTER_LOCK PRIVATE ON)
+# Playwright end.
+
include(GStreamerDependencies)
WEBKIT_OPTION_DEPEND(ENABLE_WEBXR ENABLE_GAMEPAD)
diff --git a/Source/cmake/OptionsWPE.cmake b/Source/cmake/OptionsWPE.cmake
index 9be932f3cc9a86cc27ff355409f96a8e0501eba0..f89f186c5986a702b25bf844be36fbe293cbf43b 100644
--- a/Source/cmake/OptionsWPE.cmake
+++ b/Source/cmake/OptionsWPE.cmake
@@ -37,6 +37,9 @@ else ()
set(ENABLE_MEDIA_SESSION_DEFAULT ON)
endif ()
+set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
+set(THREADS_PREFER_PTHREAD_FLAG TRUE)
+
WEBKIT_OPTION_BEGIN()
SET_AND_EXPOSE_TO_BUILD(ENABLE_DEVELOPER_MODE ${DEVELOPER_MODE})
@@ -94,6 +97,22 @@ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEBXR PRIVATE ${ENABLE_EXPERIMENTAL_FEAT
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEBXR_HIT_TEST PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEBXR_LAYERS PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
+# Playwright begin.
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MINIBROWSER PUBLIC ON)
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_PDFJS PUBLIC OFF)
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_RECORDER PRIVATE OFF)
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_THUNDER PRIVATE OFF)
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEBXR PRIVATE OFF)
+
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_APPLICATION_MANIFEST PRIVATE ON)
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_CURSOR_VISIBILITY PRIVATE ON)
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_DARK_MODE_CSS PRIVATE ON)
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_DRAG_SUPPORT PRIVATE ON)
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_DEVICE_ORIENTATION PRIVATE ON)
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_SPEECH_SYNTHESIS PRIVATE ON)
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_POINTER_LOCK PRIVATE ON)
+# Playwright end.
+
# Public options specific to the WPE port. Do not add any options here unless
# there is a strong reason we should support changing the value of the option,
# and the option is not relevant to other WebKit ports.
@@ -132,6 +151,11 @@ WEBKIT_OPTION_DEPEND(ENABLE_DOCUMENTATION ENABLE_INTROSPECTION)
WEBKIT_OPTION_DEPEND(ENABLE_WPE_QT_API ENABLE_WPE_PLATFORM)
WEBKIT_OPTION_DEPEND(USE_SYSTEM_SYSPROF_CAPTURE USE_SYSPROF_CAPTURE)
+# Playwright begin.
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WPE_QT_API PUBLIC OFF)
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(USE_SYSTEM_SYSPROF_CAPTURE PRIVATE OFF)
+# Playwright end.
+
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_BUBBLEWRAP_SANDBOX PUBLIC ON)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEMORY_SAMPLER PRIVATE ON)
diff --git a/Source/cmake/OptionsWin.cmake b/Source/cmake/OptionsWin.cmake
index da6c3b5fd4901b64c616d2b38cb1d9b70c810e71..99380f834b6b3ac5b4afdf68dfa002c0cdf606d3 100644
--- a/Source/cmake/OptionsWin.cmake
+++ b/Source/cmake/OptionsWin.cmake
@@ -113,6 +113,14 @@ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_FTPDIR PRIVATE OFF)
SET_AND_EXPOSE_TO_BUILD(ENABLE_WEBDRIVER_KEYBOARD_INTERACTIONS ON)
SET_AND_EXPOSE_TO_BUILD(ENABLE_WEBDRIVER_MOUSE_INTERACTIONS ON)
+# Plawright begin
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_DARK_MODE_CSS PRIVATE ON)
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_DEVICE_ORIENTATION PRIVATE ON)
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_NOTIFICATIONS PRIVATE ON)
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_POINTER_LOCK PRIVATE ON)
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_TOUCH_EVENTS PRIVATE ON)
+# Playwright end
+
WEBKIT_OPTION_END()
set(USE_ANGLE_EGL ON)
diff --git a/Source/cmake/WebKitCompilerFlags.cmake b/Source/cmake/WebKitCompilerFlags.cmake
index 5a9e12cee71f979e15f686f89a9bec6d992a2faf..1a79d778c8a36050fc2b0b42388bb050fa612d49 100644
--- a/Source/cmake/WebKitCompilerFlags.cmake
+++ b/Source/cmake/WebKitCompilerFlags.cmake
@@ -152,7 +152,7 @@ macro(WEBKIT_ADD_TARGET_CXX_FLAGS _target)
endmacro()
-option(DEVELOPER_MODE_FATAL_WARNINGS "Build with warnings as errors if DEVELOPER_MODE is also enabled" ON)
+option(DEVELOPER_MODE_FATAL_WARNINGS "Build with warnings as errors if DEVELOPER_MODE is also enabled" OFF)
set(DEVELOPER_MODE_CXX_FLAGS)
if (DEVELOPER_MODE AND DEVELOPER_MODE_FATAL_WARNINGS)
if (MSVC)
diff --git a/Tools/DumpRenderTree/DerivedSources.make b/Tools/DumpRenderTree/DerivedSources.make
index e5859ed734046a3dc37a5c184e8a43fc9f858004..1235b8315d2ce5d6990474e525857770a7660e61 100644
--- a/Tools/DumpRenderTree/DerivedSources.make
+++ b/Tools/DumpRenderTree/DerivedSources.make
@@ -73,8 +73,8 @@ $(IDL_FILE_NAMES_LIST) : $(UICONTEXT_INTERFACES:%=%.idl)
JS%.h JS%.cpp : %.idl $(SCRIPTS) $(IDL_ATTRIBUTES_FILE) $(IDL_FILE_NAMES_LIST) $(FEATURE_AND_PLATFORM_FLAGS_RESPONSE_FILE)
@echo Generating bindings for $*...
$(PERL) -I $(WebCoreScripts) -I $(UISCRIPTCONTEXT_DIR) -I $(DumpRenderTree)/Bindings $(WebCoreScripts)/generate-bindings.pl --defines "$(FEATURE_AND_PLATFORM_DEFINES)" --idlFileNamesList $(IDL_FILE_NAMES_LIST) --outputDir . --generator DumpRenderTree --idlAttributesFile $(IDL_ATTRIBUTES_FILE) $<
-#
+#
WEB_PREFERENCES_GENERATED_FILES = \
TestOptionsGeneratedWebKitLegacyKeyMapping.cpp \
diff --git a/Tools/MiniBrowser/gtk/BrowserTab.c b/Tools/MiniBrowser/gtk/BrowserTab.c
index 0e7f9c7bb7ccb52ccb579ff464a5904aaab2baed..65999b8d7c2dfd1aecc58fe93504aa9cb6965dd8 100644
--- a/Tools/MiniBrowser/gtk/BrowserTab.c
+++ b/Tools/MiniBrowser/gtk/BrowserTab.c
@@ -118,19 +118,38 @@ static void isLoadingChanged(WebKitWebView *webView, GParamSpec *paramSpec, Brow
}
}
+static gboolean response_policy_decision_can_show(WebKitResponsePolicyDecision *responseDecision)
+{
+ if (webkit_response_policy_decision_is_mime_type_supported(responseDecision))
+ return TRUE;
+ WebKitURIResponse* response = webkit_response_policy_decision_get_response(responseDecision);
+ const guint statusCode = webkit_uri_response_get_status_code(response);
+ if (statusCode == 205 || statusCode == 204)
+ return TRUE;
+ const gchar* mimeType = webkit_uri_response_get_mime_type(response);
+ if (!mimeType || mimeType[0] == '\0')
+ return FALSE;
+ // https://bugs.webkit.org/show_bug.cgi?id=277204 / Ubuntu 24.04 / glib 2.76+ or higher
+ if (g_ascii_strcasecmp(mimeType, "application/x-zerosize") == 0)
+ return TRUE;
+ return FALSE;
+}
+
static gboolean decidePolicy(WebKitWebView *webView, WebKitPolicyDecision *decision, WebKitPolicyDecisionType decisionType, BrowserTab *tab)
{
if (decisionType != WEBKIT_POLICY_DECISION_TYPE_RESPONSE)
return FALSE;
WebKitResponsePolicyDecision *responseDecision = WEBKIT_RESPONSE_POLICY_DECISION(decision);
- if (webkit_response_policy_decision_is_mime_type_supported(responseDecision))
- return FALSE;
-
if (!webkit_response_policy_decision_is_main_frame_main_resource(responseDecision))
return FALSE;
- webkit_policy_decision_download(decision);
+ if (!response_policy_decision_can_show(responseDecision)) {
+ webkit_policy_decision_download(decision);
+ return TRUE;
+ }
+
+ webkit_policy_decision_use(decision);
return TRUE;
}
@@ -181,6 +200,11 @@ static void loadChanged(WebKitWebView *webView, WebKitLoadEvent loadEvent, Brows
#endif
}
+static gboolean loadFailed()
+{
+ return TRUE;
+}
+
static GtkWidget *createInfoBarQuestionMessage(const char *title, const char *text)
{
GtkWidget *dialog = gtk_info_bar_new_with_buttons("No", GTK_RESPONSE_NO, "Yes", GTK_RESPONSE_YES, NULL);
@@ -806,6 +830,7 @@ static void browserTabConstructed(GObject *gObject)
g_signal_connect(tab->webView, "notify::is-loading", G_CALLBACK(isLoadingChanged), tab);
g_signal_connect(tab->webView, "decide-policy", G_CALLBACK(decidePolicy), tab);
g_signal_connect(tab->webView, "load-changed", G_CALLBACK(loadChanged), tab);
+ g_signal_connect(tab->webView, "load-failed", G_CALLBACK(loadFailed), tab);
g_signal_connect(tab->webView, "load-failed-with-tls-errors", G_CALLBACK(loadFailedWithTLSerrors), tab);
g_signal_connect(tab->webView, "permission-request", G_CALLBACK(decidePermissionRequest), tab);
g_signal_connect(tab->webView, "run-color-chooser", G_CALLBACK(runColorChooserCallback), tab);
@@ -861,6 +886,9 @@ static char *getInternalURI(const char *uri)
if (g_str_has_prefix(uri, "about:") && !g_str_equal(uri, "about:blank"))
return g_strconcat(BROWSER_ABOUT_SCHEME, uri + strlen ("about"), NULL);
+ if (!g_str_has_prefix(uri, "http://") && !g_str_has_prefix(uri, "https://") && !g_str_has_prefix(uri, "file://"))
+ return g_strconcat("http://", uri, NULL);
+
return g_strdup(uri);
}
diff --git a/Tools/MiniBrowser/gtk/BrowserWindow.c b/Tools/MiniBrowser/gtk/BrowserWindow.c
index d39b809a879babcdbbf4b5f7687204df5ccc43f3..a784ea4e693332aee731c4b8949ddb33af7dff9f 100644
--- a/Tools/MiniBrowser/gtk/BrowserWindow.c
+++ b/Tools/MiniBrowser/gtk/BrowserWindow.c
@@ -73,7 +73,7 @@ struct _BrowserWindowClass {
GtkApplicationWindowClass parent;
};
-static const char *defaultWindowTitle = "WebKitGTK MiniBrowser";
+static const char *defaultWindowTitle = "🎭 Playwright";
static const gdouble minimumZoomLevel = 0.5;
static const gdouble maximumZoomLevel = 3;
static const gdouble defaultZoomLevel = 1;
@@ -157,17 +157,11 @@ static void webViewURIChanged(WebKitWebView *webView, GParamSpec *pspec, Browser
static void webViewTitleChanged(WebKitWebView *webView, GParamSpec *pspec, BrowserWindow *window)
{
const char *title = webkit_web_view_get_title(webView);
+ char *privateTitle = NULL;
if (!title)
title = defaultWindowTitle;
- char *privateTitle = NULL;
- if (webkit_web_view_is_controlled_by_automation(webView))
- privateTitle = g_strdup_printf("[Automation] %s", title);
-#if GTK_CHECK_VERSION(3, 98, 0)
- else if (webkit_network_session_is_ephemeral(webkit_web_view_get_network_session(webView)))
-#else
- else if (webkit_web_view_is_ephemeral(webView))
-#endif
- privateTitle = g_strdup_printf("[Private] %s", title);
+ else
+ privateTitle = g_strdup_printf("🎭 Playwright: %s", title);
gtk_window_set_title(GTK_WINDOW(window), privateTitle ? privateTitle : title);
g_free(privateTitle);
}
@@ -524,8 +518,12 @@ static gboolean webViewDecidePolicy(WebKitWebView *webView, WebKitPolicyDecision
return FALSE;
WebKitNavigationAction *navigationAction = webkit_navigation_policy_decision_get_navigation_action(WEBKIT_NAVIGATION_POLICY_DECISION(decision));
- if (webkit_navigation_action_get_navigation_type(navigationAction) != WEBKIT_NAVIGATION_TYPE_LINK_CLICKED
- || webkit_navigation_action_get_mouse_button(navigationAction) != GDK_BUTTON_MIDDLE)
+ if (webkit_navigation_action_get_navigation_type(navigationAction) != WEBKIT_NAVIGATION_TYPE_LINK_CLICKED)
+ return FALSE;
+
+ guint modifiers = webkit_navigation_action_get_modifiers(navigationAction);
+ if (webkit_navigation_action_get_mouse_button(navigationAction) != GDK_BUTTON_MIDDLE &&
+ (webkit_navigation_action_get_mouse_button(navigationAction) != GDK_BUTTON_PRIMARY || (modifiers & (GDK_CONTROL_MASK | GDK_SHIFT_MASK)) == 0))
return FALSE;
/* Multiple tabs are not allowed in editor mode. */
@@ -1502,6 +1500,20 @@ static gboolean browserWindowDeleteEvent(GtkWidget *widget, GdkEventAny* event)
}
#endif
+static void zero_widget_measure (GtkWidget *widget,
+ GtkOrientation orientation,
+ int for_size,
+ int *minimum_size,
+ int *natural_size,
+ int *minimum_baseline,
+ int *natural_baseline)
+{
+ *minimum_size = 10;
+ *natural_size = 10;
+ // *minimum_baseline = 10;
+ // *natural_baseline = 10;
+}
+
static void browser_window_class_init(BrowserWindowClass *klass)
{
GObjectClass *gobjectClass = G_OBJECT_CLASS(klass);
@@ -1515,6 +1527,13 @@ static void browser_window_class_init(BrowserWindowClass *klass)
GtkWidgetClass *widgetClass = GTK_WIDGET_CLASS(klass);
widgetClass->delete_event = browserWindowDeleteEvent;
#endif
+
+// Playwrigth begin
+// Override preferred (which is minimum :-) size to 0 so that we can
+// emulate arbitrary resolution.
+ GtkWidgetClass* browserWidgetClass = GTK_WIDGET_CLASS(klass);
+ browserWidgetClass->measure = zero_widget_measure;
+// Playwrigth end
}
/* Public API. */
diff --git a/Tools/MiniBrowser/gtk/BrowserWindow.h b/Tools/MiniBrowser/gtk/BrowserWindow.h
index 1fd07efb828b85b6d8def6c6cd92a0c11debfe1b..da9fac7975d477857ead2adb1d67108d51716d15 100644
--- a/Tools/MiniBrowser/gtk/BrowserWindow.h
+++ b/Tools/MiniBrowser/gtk/BrowserWindow.h
@@ -42,7 +42,7 @@ G_BEGIN_DECLS
#define BROWSER_IS_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), BROWSER_TYPE_WINDOW))
#define BROWSER_IS_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), BROWSER_TYPE_WINDOW))
#define BROWSER_WINDOW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), BROWSER_TYPE_WINDOW, BrowserWindowClass))
-#define BROWSER_DEFAULT_URL "http://www.webkitgtk.org/"
+#define BROWSER_DEFAULT_URL "about:blank"
#define BROWSER_ABOUT_SCHEME "minibrowser-about"
typedef struct _BrowserWindow BrowserWindow;
diff --git a/Tools/MiniBrowser/gtk/main.c b/Tools/MiniBrowser/gtk/main.c
index dc20509081346978e0da4a7833f6d4ce733717ac..817bd32756f0c8279beb4c23bee4b1e6f2ded960 100644
--- a/Tools/MiniBrowser/gtk/main.c
+++ b/Tools/MiniBrowser/gtk/main.c
@@ -66,9 +66,15 @@ static char* timeZone;
static gboolean enableITP;
static gboolean exitAfterLoad;
static gboolean webProcessCrashed;
+static gboolean inspectorPipe;
+static gint remoteDebuggingPort = -1;
+static gboolean headless;
+static gboolean noStartupWindow;
+static const char *userDataDir;
static gboolean printVersion;
static char *configFile;
static GSettings *interfaceSettings;
+static GtkApplication *browserApplication = NULL;
#if !GTK_CHECK_VERSION(3, 98, 0)
static gboolean enableSandbox;
@@ -174,6 +180,11 @@ static const GOptionEntry commandLineOptions[] =
{ "time-zone", 't', 0, G_OPTION_ARG_STRING, &timeZone, "Set time zone", "TIMEZONE" },
{ "version", 'v', 0, G_OPTION_ARG_NONE, &printVersion, "Print the WebKitGTK version", NULL },
{ "config", 'C', 0, G_OPTION_ARG_FILENAME, &configFile, "Path to a configuration file", "PATH" },
+ { "inspector-pipe", 0, 0, G_OPTION_ARG_NONE, &inspectorPipe, "Open pipe connection to the remote inspector", NULL },
+ { "remote-debugging-port", 0, 0, G_OPTION_ARG_INT, &remoteDebuggingPort, "Start remote debugging server on the specified port", NULL },
+ { "user-data-dir", 0, 0, G_OPTION_ARG_STRING, &userDataDir, "Default profile persistence folder location", NULL },
+ { "headless", 0, 0, G_OPTION_ARG_NONE, &headless, "Noop headless operation", NULL },
+ { "no-startup-window", 0, 0, G_OPTION_ARG_NONE, &noStartupWindow, "Do not open default page", NULL },
{ G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &uriArguments, 0, "[URL…]" },
{ 0, 0, 0, 0, 0, 0, 0 }
};
@@ -730,6 +741,64 @@ static void filterSavedCallback(WebKitUserContentFilterStore *store, GAsyncResul
g_main_loop_quit(data->mainLoop);
}
+static WebKitSettings* createPlaywrightSettings() {
+ WebKitSettings* webkitSettings = webkit_settings_new();
+ // FIXME(Playwright): in GTK4, WEBKIT_HARDWARE_ACCELERATION_POLICY_ALWAYS is the default, but the page content is just black in that case.
+ webkit_settings_set_hardware_acceleration_policy(webkitSettings, WEBKIT_HARDWARE_ACCELERATION_POLICY_NEVER);
+ return webkitSettings;
+}
+
+static WebKitWebContext *persistentWebContext = NULL;
+
+static WebKitWebView *createNewPage(WebKitBrowserInspector *browser_inspector, WebKitWebContext *context)
+{
+ if (context == NULL)
+ context = persistentWebContext;
+
+ WebKitWebView *newWebView = WEBKIT_WEB_VIEW(g_object_new(WEBKIT_TYPE_WEB_VIEW,
+ "web-context", context,
+ "settings", createPlaywrightSettings(),
+ "network-session", webkit_web_context_get_network_session_for_automation(context),
+ "is-controlled-by-automation", TRUE,
+ NULL));
+ GtkWidget *newWindow = browser_window_new(NULL, context, webkit_web_context_get_network_session_for_automation(context));
+ gtk_window_set_application(GTK_WINDOW(newWindow), browserApplication);
+ browser_window_append_view(BROWSER_WINDOW(newWindow), newWebView);
+ gtk_widget_grab_focus(GTK_WIDGET(newWebView));
+ gtk_widget_show(GTK_WIDGET(newWindow));
+ webkit_web_view_load_uri(newWebView, "about:blank");
+ return newWebView;
+}
+
+static void quitBroserApplication(WebKitBrowserInspector* browser_inspector)
+{
+ g_application_release(G_APPLICATION(browserApplication));
+}
+
+static void keepApplicationAliveUntilQuit(GApplication *application)
+{
+ // Reference the application, it will be released in quitBroserApplication.
+ g_application_hold(application);
+ WebKitBrowserInspector* browserInspector = webkit_browser_inspector_get_default();
+ g_signal_connect(browserInspector, "quit-application", G_CALLBACK(quitBroserApplication), NULL);
+}
+
+static void configureBrowserInspectorPipe()
+{
+ WebKitBrowserInspector* browserInspector = webkit_browser_inspector_get_default();
+ g_signal_connect(browserInspector, "create-new-page", G_CALLBACK(createNewPage), NULL);
+
+ webkit_browser_inspector_initialize_pipe(proxy, ignoreHosts);
+}
+
+static void configureBrowserInspectorPort()
+{
+ WebKitBrowserInspector* browserInspector = webkit_browser_inspector_get_default();
+ g_signal_connect(browserInspector, "create-new-page", G_CALLBACK(createNewPage), NULL);
+
+ webkit_browser_inspector_initialize_web_socket(remoteDebuggingPort, proxy, ignoreHosts);
+}
+
static void startup(GApplication *application)
{
const char *actionAccels[] = {
@@ -788,22 +857,39 @@ static void setupDarkMode(GtkSettings *settings)
static void activate(GApplication *application, WebKitSettings *webkitSettings)
{
+ if (inspectorPipe)
+ configureBrowserInspectorPipe();
+ else if (remoteDebuggingPort != -1)
+ configureBrowserInspectorPort();
+
+ if (noStartupWindow) {
+ keepApplicationAliveUntilQuit(application);
+ g_clear_object(&webkitSettings);
+ return;
+ }
#if GTK_CHECK_VERSION(3, 98, 0)
WebKitWebContext *webContext = g_object_new(WEBKIT_TYPE_WEB_CONTEXT, "time-zone-override", timeZone, NULL);
webkit_web_context_set_automation_allowed(webContext, automationMode);
g_signal_connect(webContext, "automation-started", G_CALLBACK(automationStartedCallback), application);
WebKitNetworkSession *networkSession;
- if (automationMode)
- networkSession = g_object_ref(webkit_web_context_get_network_session_for_automation(webContext));
- else if (privateMode)
+ if (userDataDir) {
+ char *dataDirectory = g_build_filename(userDataDir, "data", NULL);
+ char *cacheDirectory = g_build_filename(userDataDir, "cache", NULL);
+ networkSession = webkit_network_session_new(dataDirectory, cacheDirectory);
+ g_free(dataDirectory);
+ g_free(cacheDirectory);
+ cookiesFile = g_build_filename(userDataDir, "cookies.txt", NULL);
+ } else if (inspectorPipe || remoteDebuggingPort != -1 || privateMode || automationMode) {
networkSession = webkit_network_session_new_ephemeral();
- else {
+ } else {
g_autofree char *dataDirectory = profileDirectory ? g_build_filename(profileDirectory, "data", NULL) : g_build_filename(g_get_user_data_dir(), "webkitgtk-" WEBKITGTK_API_VERSION, "MiniBrowser", NULL);
g_autofree char *cacheDirectory = profileDirectory ? g_build_filename(profileDirectory, "cache", NULL) : g_build_filename(g_get_user_cache_dir(), "webkitgtk-" WEBKITGTK_API_VERSION, "MiniBrowser", NULL);
networkSession = webkit_network_session_new(dataDirectory, cacheDirectory);
}
+ webkit_web_context_set_network_session_for_automation(webContext, networkSession);
+
webkit_network_session_set_itp_enabled(networkSession, enableITP);
if (!automationMode) {
@@ -838,9 +924,12 @@ static void activate(GApplication *application, WebKitSettings *webkitSettings)
}
#else
WebKitWebsiteDataManager *manager;
- if (privateMode || automationMode)
+ if (userDataDir) {
+ manager = webkit_website_data_manager_new("base-data-directory", userDataDir, "base-cache-directory", userDataDir, NULL);
+ cookiesFile = g_build_filename(userDataDir, "cookies.txt", NULL);
+ } else if (inspectorPipe || remoteDebuggingPort != -1 || privateMode || automationMode) {
manager = webkit_website_data_manager_new_ephemeral();
- else {
+ } else {
g_autofree char *dataDirectory = profileDirectory ? g_build_filename(profileDirectory, "data", NULL) : g_build_filename(g_get_user_data_dir(), "webkitgtk-" WEBKITGTK_API_VERSION, "MiniBrowser", NULL);
g_autofree char *cacheDirectory = profileDirectory ? g_build_filename(profileDirectory, "cache", NULL) : g_build_filename(g_get_user_cache_dir(), "webkitgtk-" WEBKITGTK_API_VERSION, "MiniBrowser", NULL);
manager = webkit_website_data_manager_new("base-data-directory", dataDirectory, "base-cache-directory", cacheDirectory, NULL);
@@ -888,6 +977,7 @@ static void activate(GApplication *application, WebKitSettings *webkitSettings)
// Enable the favicon database.
webkit_web_context_set_favicon_database_directory(webContext, NULL);
#endif
+ persistentWebContext = webContext;
webkit_web_context_register_uri_scheme(webContext, BROWSER_ABOUT_SCHEME, (WebKitURISchemeRequestCallback)aboutURISchemeRequestCallback, NULL, NULL);
@@ -952,9 +1042,7 @@ static void activate(GApplication *application, WebKitSettings *webkitSettings)
if (exitAfterLoad)
exitAfterWebViewLoadFinishes(webView, application);
}
- gchar *url = argumentToURL(uriArguments[i]);
- webkit_web_view_load_uri(webView, url);
- g_free(url);
+ webkit_web_view_load_uri(webView, uriArguments[i]);
}
} else {
WebKitWebView *webView = createBrowserTab(mainWindow, webkitSettings, userContentManager, defaultWebsitePolicies);
@@ -1004,7 +1092,7 @@ int main(int argc, char *argv[])
g_option_context_add_group(context, gst_init_get_option_group());
#endif
- WebKitSettings *webkitSettings = webkit_settings_new();
+ WebKitSettings *webkitSettings = createPlaywrightSettings();
webkit_settings_set_enable_developer_extras(webkitSettings, TRUE);
webkit_settings_set_enable_webgl(webkitSettings, TRUE);
webkit_settings_set_enable_media_stream(webkitSettings, TRUE);
@@ -1056,9 +1144,11 @@ int main(int argc, char *argv[])
}
GtkApplication *application = gtk_application_new("org.webkitgtk.MiniBrowser", G_APPLICATION_NON_UNIQUE);
+ browserApplication = application;
g_signal_connect(application, "startup", G_CALLBACK(startup), NULL);
g_signal_connect(application, "activate", G_CALLBACK(activate), webkitSettings);
g_application_run(G_APPLICATION(application), 0, NULL);
+ browserApplication = NULL;
g_object_unref(application);
g_clear_object(&interfaceSettings);
diff --git a/Tools/MiniBrowser/wpe/main.cpp b/Tools/MiniBrowser/wpe/main.cpp
index c8cd8719368bc3be7b97b315c64162ced5b7c351..7a7b2d3b0ebc31690f5877694118ddfc311ee5cf 100644
--- a/Tools/MiniBrowser/wpe/main.cpp
+++ b/Tools/MiniBrowser/wpe/main.cpp
@@ -56,6 +56,9 @@ static gboolean privateMode;
static const char* profileDirectory;
static gboolean automationMode;
static gboolean ignoreTLSErrors;
+static gboolean inspectorPipe;
+static gboolean noStartupWindow;
+static const char* userDataDir;
static const char* contentFilter;
static const char* cookiesFile;
static const char* cookiesPolicy;
@@ -141,6 +144,9 @@ static const GOptionEntry commandLineOptions[] =
{ "config-file", 0, 0, G_OPTION_ARG_FILENAME, &configFile, "Config file to load for settings", "FILE" },
{ "size", 's', 0, G_OPTION_ARG_CALLBACK, reinterpret_cast<gpointer>(parseWindowSize), "Specify the window size to use, e.g. --size=\"800x600\"", nullptr },
{ "version", 'v', 0, G_OPTION_ARG_NONE, &printVersion, "Print the WPE version", nullptr },
+ { "inspector-pipe", 'v', 0, G_OPTION_ARG_NONE, &inspectorPipe, "Expose remote debugging protocol over pipe", nullptr },
+ { "user-data-dir", 0, 0, G_OPTION_ARG_STRING, &userDataDir, "Default profile persistence folder location", "FILE" },
+ { "no-startup-window", 0, 0, G_OPTION_ARG_NONE, &noStartupWindow, "Do not open default page", nullptr },
{ G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &uriArguments, nullptr, "[URL]" },
{ nullptr, 0, 0, G_OPTION_ARG_NONE, nullptr, nullptr, nullptr }
};
@@ -331,15 +337,38 @@ static void filterSavedCallback(WebKitUserContentFilterStore *store, GAsyncResul
g_main_loop_quit(data->mainLoop);
}
+static gboolean webViewLoadFailed()
+{
+ return TRUE;
+}
+
static void webViewClose(WebKitWebView* webView, gpointer user_data)
{
// Hash table key delete func takes care of unref'ing the view
g_hash_table_remove(openViews, webView);
- if (!g_hash_table_size(openViews))
+ if (!g_hash_table_size(openViews) && user_data)
g_application_quit(G_APPLICATION(user_data));
}
-static WebKitWebView* createWebView(WebKitWebView* webView, WebKitNavigationAction*, gpointer user_data)
+static gboolean scriptDialog(WebKitWebView*, WebKitScriptDialog* dialog, gpointer)
+{
+ if (inspectorPipe)
+ webkit_script_dialog_ref(dialog);
+ return TRUE;
+}
+
+static gboolean scriptDialogHandled(WebKitWebView*, WebKitScriptDialog* dialog, gpointer)
+{
+ if (inspectorPipe)
+ webkit_script_dialog_unref(dialog);
+ return TRUE;
+}
+
+static gboolean webViewDecidePolicy(WebKitWebView *webView, WebKitPolicyDecision *decision, WebKitPolicyDecisionType decisionType, gpointer);
+
+static WebKitWebView* createWebView(WebKitWebView* webView, WebKitNavigationAction*, gpointer user_data);
+
+static WebKitWebView* createWebViewImpl(WebKitWebView* webView, WebKitWebContext *webContext, gpointer user_data)
{
#if defined(USE_LIBWPE) && USE_LIBWPE
auto backend = createViewBackend(defaultWindowWidthLegacyAPI, defaultWindowHeightLegacyAPI);
@@ -356,14 +385,31 @@ static WebKitWebView* createWebView(WebKitWebView* webView, WebKitNavigationActi
}
#endif
- auto* newWebView = WEBKIT_WEB_VIEW(g_object_new(WEBKIT_TYPE_WEB_VIEW,
+// Playwright begin
+ if (headlessMode) {
+ webkit_web_view_backend_set_screenshot_callback(viewBackend,
+ [](gpointer data) {
+ return static_cast<WPEToolingBackends::HeadlessViewBackend*>(data)->snapshot();
+ });
+ }
+// Playwright end
+ WebKitWebView* newWebView;
+ if (webView) {
+ newWebView = WEBKIT_WEB_VIEW(g_object_new(WEBKIT_TYPE_WEB_VIEW,
#if defined(USE_LIBWPE) && USE_LIBWPE
- "backend", viewBackend,
+ "backend", viewBackend,
#endif
- "related-view", webView,
- "settings", webkit_web_view_get_settings(webView),
- "user-content-manager", webkit_web_view_get_user_content_manager(webView),
- nullptr));
+ "related-view", webView,
+ nullptr));
+ } else {
+ newWebView = WEBKIT_WEB_VIEW(g_object_new(WEBKIT_TYPE_WEB_VIEW,
+#if defined(USE_LIBWPE) && USE_LIBWPE
+ "backend", viewBackend,
+#endif
+ "web-context", webContext,
+ "is-controlled-by-automation", TRUE,
+ nullptr));
+ }
#if ENABLE_WPE_PLATFORM
if (auto* wpeView = webkit_web_view_get_wpe_view(newWebView)) {
@@ -375,9 +421,13 @@ static WebKitWebView* createWebView(WebKitWebView* webView, WebKitNavigationActi
g_signal_connect(newWebView, "create", G_CALLBACK(createWebView), user_data);
g_signal_connect(newWebView, "close", G_CALLBACK(webViewClose), user_data);
-
+// Playwright begin
+ g_signal_connect(newWebView, "load-failed", G_CALLBACK(webViewLoadFailed), nullptr);
+ g_signal_connect(newWebView, "script-dialog", G_CALLBACK(scriptDialog), nullptr);
+ g_signal_connect(newWebView, "script-dialog-handled", G_CALLBACK(scriptDialogHandled), nullptr);
+ g_signal_connect(newWebView, "decide-policy", G_CALLBACK(webViewDecidePolicy), nullptr);
+// Playwright end
g_hash_table_add(openViews, newWebView);
-
return newWebView;
}
@@ -468,24 +518,112 @@ static void loadConfigFile(WebKitSettings* webkitSettings
}
#if defined(USE_LIBWPE) && USE_LIBWPE
+static WebKitWebView* createWebView(WebKitWebView* webView, WebKitNavigationAction*, gpointer user_data)
+{
+ return createWebViewImpl(webView, nullptr, user_data);
+}
+
+inline bool response_policy_decision_can_show(WebKitResponsePolicyDecision* responseDecision)
+{
+ if (webkit_response_policy_decision_is_mime_type_supported(responseDecision))
+ return true;
+ auto response = webkit_response_policy_decision_get_response(responseDecision);
+ const auto statusCode = webkit_uri_response_get_status_code(response);
+ if (statusCode == 205 || statusCode == 204)
+ return true;
+ const gchar* mimeType = webkit_uri_response_get_mime_type(response);
+ if (!mimeType || mimeType[0] == '\0')
+ return false;
+ // https://bugs.webkit.org/show_bug.cgi?id=277204 / Ubuntu 24.04 / glib 2.76+ or higher
+ if (g_ascii_strcasecmp(mimeType, "application/x-zerosize") == 0)
+ return true;
+ return false;
+}
+
+static gboolean webViewDecidePolicy(WebKitWebView *webView, WebKitPolicyDecision *decision, WebKitPolicyDecisionType decisionType, gpointer user_data)
+{
+ if (decisionType == WEBKIT_POLICY_DECISION_TYPE_RESPONSE) {
+ WebKitResponsePolicyDecision *responseDecision = WEBKIT_RESPONSE_POLICY_DECISION(decision);
+ if (!webkit_response_policy_decision_is_main_frame_main_resource(responseDecision))
+ return FALSE;
+
+ if (!response_policy_decision_can_show(responseDecision)) {
+ webkit_policy_decision_download(decision);
+ return TRUE;
+ }
+
+ webkit_policy_decision_use(decision);
+ return TRUE;
+ }
+
+ if (decisionType != WEBKIT_POLICY_DECISION_TYPE_NAVIGATION_ACTION)
+ return FALSE;
+
+ WebKitNavigationAction *navigationAction = webkit_navigation_policy_decision_get_navigation_action(WEBKIT_NAVIGATION_POLICY_DECISION(decision));
+ if (webkit_navigation_action_get_navigation_type(navigationAction) != WEBKIT_NAVIGATION_TYPE_LINK_CLICKED)
+ return FALSE;
+
+ guint modifiers = webkit_navigation_action_get_modifiers(navigationAction);
+ if (webkit_navigation_action_get_mouse_button(navigationAction) != 2 /* GDK_BUTTON_MIDDLE */ &&
+ (webkit_navigation_action_get_mouse_button(navigationAction) != 1 /* GDK_BUTTON_PRIMARY */ || (modifiers & (wpe_input_keyboard_modifier_control | wpe_input_keyboard_modifier_shift)) == 0))
+ return FALSE;
+
+ /* Open a new tab if link clicked with the middle button, shift+click or ctrl+click. */
+ WebKitWebView* newWebView = createWebViewImpl(nullptr, webkit_web_view_get_context(webView), user_data);
+ webkit_web_view_load_request(newWebView, webkit_navigation_action_get_request(navigationAction));
+
+ webkit_policy_decision_ignore(decision);
+ return TRUE;
+}
+
+static WebKitWebContext *persistentWebContext = NULL;
+
+static WebKitWebView* createNewPage(WebKitBrowserInspector*, WebKitWebContext *webContext)
+{
+ if (!webContext)
+ webContext = persistentWebContext;
+ WebKitWebView* webView = createWebViewImpl(nullptr, webContext, nullptr);
+ webkit_web_view_load_uri(webView, "about:blank");
+ return webView;
+}
+
+static void quitBroserApplication(WebKitBrowserInspector*, gpointer data)
+{
+ GApplication* application = static_cast<GApplication*>(data);
+ g_application_quit(application);
+}
+
+static void configureBrowserInspector(GApplication* application)
+{
+ WebKitBrowserInspector* browserInspector = webkit_browser_inspector_get_default();
+ g_signal_connect(browserInspector, "create-new-page", G_CALLBACK(createNewPage), NULL);
+ g_signal_connect(browserInspector, "quit-application", G_CALLBACK(quitBroserApplication), application);
+ webkit_browser_inspector_initialize_pipe(proxy, ignoreHosts);
+}
+
static void activate(GApplication* application, WPEToolingBackends::ViewBackend* backend)
#else
static void activate(GApplication* application, gpointer)
#endif
{
g_application_hold(application);
+ if (noStartupWindow)
+ return;
#if ENABLE_2022_GLIB_API
WebKitNetworkSession* networkSession = nullptr;
if (!automationMode) {
- if (privateMode)
+ if (userDataDir) {
+ networkSession = webkit_network_session_new(userDataDir, userDataDir);
+ cookiesFile = g_build_filename(userDataDir, "cookies.txt", nullptr);
+ } else if (inspectorPipe || privateMode || automationMode) {
networkSession = webkit_network_session_new_ephemeral();
- else if (profileDirectory) {
+ } else if (profileDirectory) {
g_autofree char* dataDirectory = g_build_filename(profileDirectory, "data", nullptr);
g_autofree char* cacheDirectory = g_build_filename(profileDirectory, "cache", nullptr);
networkSession = webkit_network_session_new(dataDirectory, cacheDirectory);
- } else
+ } else {
networkSession = webkit_network_session_new(nullptr, nullptr);
-
+ }
webkit_network_session_set_itp_enabled(networkSession, enableITP);
if (proxy) {
@@ -512,19 +650,22 @@ static void activate(GApplication* application, gpointer)
webkit_cookie_manager_set_persistent_storage(cookieManager, cookiesFile, storageType);
}
}
-
auto* webContext = WEBKIT_WEB_CONTEXT(g_object_new(WEBKIT_TYPE_WEB_CONTEXT, "time-zone-override", timeZone, nullptr));
+ webkit_web_context_set_network_session_for_automation(webContext, networkSession);
#else
- WebKitWebsiteDataManager* manager;
- if (privateMode || automationMode)
+ WebKitWebsiteDataManager *manager;
+ if (userDataDir) {
+ manager = webkit_website_data_manager_new("base-data-directory", userDataDir, "base-cache-directory", userDataDir, NULL);
+ cookiesFile = g_build_filename(userDataDir, "cookies.txt", NULL);
+ } else if (inspectorPipe || privateMode || automationMode) {
manager = webkit_website_data_manager_new_ephemeral();
- else if (profileDirectory) {
+ } else if (profileDirectory) {
g_autofree char* dataDirectory = g_build_filename(profileDirectory, "data", nullptr);
g_autofree char* cacheDirectory = g_build_filename(profileDirectory, "cache", nullptr);
webkit_website_data_manager_new("base-data-directory", dataDirectory, "base-cache-directory", cacheDirectory, nullptr);
- } else
- webkit_website_data_manager_new(nullptr);
-
+ } else {
+ manager = webkit_website_data_manager_new(NULL);
+ }
webkit_website_data_manager_set_itp_enabled(manager, enableITP);
if (proxy) {
@@ -555,6 +696,7 @@ static void activate(GApplication* application, gpointer)
}
#endif
+ persistentWebContext = webContext;
g_autoptr(WebKitUserContentManager) userContentManager = nullptr;
if (contentFilter) {
g_autoptr(GFile) contentFilterFile = g_file_new_for_commandline_arg(contentFilter);
@@ -637,6 +779,15 @@ static void activate(GApplication* application, gpointer)
"autoplay", WEBKIT_AUTOPLAY_ALLOW,
nullptr);
+// Playwright begin
+ if (headlessMode) {
+ webkit_web_view_backend_set_screenshot_callback(viewBackend,
+ [](gpointer data) {
+ return static_cast<WPEToolingBackends::HeadlessViewBackend*>(data)->snapshot();
+ });
+ }
+// Playwright end
+
auto* webView = WEBKIT_WEB_VIEW(g_object_new(WEBKIT_TYPE_WEB_VIEW,
#if defined(USE_LIBWPE) && USE_LIBWPE
"backend", viewBackend,
@@ -699,12 +850,16 @@ static void activate(GApplication* application, gpointer)
#endif
}
- openViews = g_hash_table_new_full(nullptr, nullptr, g_object_unref, nullptr);
-
g_signal_connect(webContext, "automation-started", G_CALLBACK(automationStartedCallback), webView);
g_signal_connect(webView, "permission-request", G_CALLBACK(decidePermissionRequest), nullptr);
g_signal_connect(webView, "create", G_CALLBACK(createWebView), application);
g_signal_connect(webView, "close", G_CALLBACK(webViewClose), application);
+// Playwright begin
+ g_signal_connect(webView, "load-failed", G_CALLBACK(webViewLoadFailed), nullptr);
+ g_signal_connect(webView, "script-dialog", G_CALLBACK(scriptDialog), nullptr);
+ g_signal_connect(webView, "script-dialog-handled", G_CALLBACK(scriptDialogHandled), nullptr);
+ g_signal_connect(webView, "decide-policy", G_CALLBACK(webViewDecidePolicy), nullptr);
+// Playwright end
g_hash_table_add(openViews, webView);
WebKitColor color;
@@ -712,16 +867,11 @@ static void activate(GApplication* application, gpointer)
webkit_web_view_set_background_color(webView, &color);
if (uriArguments) {
- const char* uri = uriArguments[0];
- if (g_str_equal(uri, "about:gpu"))
- uri = "webkit://gpu";
-
- GFile* file = g_file_new_for_commandline_arg(uri);
- char* url = g_file_get_uri(file);
- g_object_unref(file);
- webkit_web_view_load_uri(webView, url);
- g_free(url);
- } else if (!automationMode)
+ // Playwright: avoid weird url transformation like http://trac.webkit.org/r240840
+ webkit_web_view_load_uri(webView, uriArguments[0]);
+ } else if (automationMode || inspectorPipe)
+ webkit_web_view_load_uri(webView, "about:blank");
+ else
webkit_web_view_load_uri(webView, "https://wpewebkit.org");
g_object_unref(webContext);
@@ -816,12 +966,18 @@ int main(int argc, char *argv[])
}
#endif
+ openViews = g_hash_table_new_full(nullptr, nullptr, g_object_unref, nullptr);
+
GApplication* application = g_application_new("org.wpewebkit.MiniBrowser", G_APPLICATION_NON_UNIQUE);
#if defined(USE_LIBWPE) && USE_LIBWPE
g_signal_connect(application, "activate", G_CALLBACK(activate), backend.release());
#else
g_signal_connect(application, "activate", G_CALLBACK(activate), nullptr);
#endif
+
+ if (inspectorPipe)
+ configureBrowserInspector(application);
+
g_application_run(application, 0, nullptr);
g_object_unref(application);
diff --git a/Tools/PlatformWin.cmake b/Tools/PlatformWin.cmake
index 1067b31bc989748dfcc5502209d36d001b9b239e..7629263fb8bc93dca6dfc01c75eed8d2921fce1f 100644
--- a/Tools/PlatformWin.cmake
+++ b/Tools/PlatformWin.cmake
@@ -1,3 +1,7 @@
if (ENABLE_MINIBROWSER)
add_subdirectory(MiniBrowser/win)
endif ()
+
+if (ENABLE_WEBKIT)
+ add_subdirectory(Playwright/win)
+endif ()
diff --git a/Tools/Scripts/generate-bundle b/Tools/Scripts/generate-bundle
index 2050bc1c4e2f94461cfe25dbc53762afdc6b9f53..cd43f62318d661bf2558a1b8005f37de19eb0f15 100755
--- a/Tools/Scripts/generate-bundle
+++ b/Tools/Scripts/generate-bundle
@@ -41,7 +41,6 @@ sys.path.insert(0, os.path.join(top_level_directory, 'Tools', 'flatpak'))
sys.path.insert(0, os.path.join(top_level_directory, 'Tools', 'jhbuild'))
sys.path.insert(0, os.path.join(top_level_directory, 'Tools', 'Scripts', 'webkitpy'))
import jhbuildutils
-import flatpakutils
from binary_bundling.ldd import SharedObjectResolver
from binary_bundling.bundle import BinaryBundler
@@ -896,7 +895,7 @@ class BundleCreator(object):
_log.info('Copy basic GTK icons.')
icons_target_dir = os.path.join(target_sys_share_dir, 'icons')
os.makedirs(icons_target_dir)
- gtk_icon_basedir = '/run/host/share/icons' if flatpakutils.is_sandboxed() else '/usr/share/icons'
+ gtk_icon_basedir = '/usr/share/icons'
gtk_target_icon_dir = os.path.join(icons_target_dir, 'hicolor')
gtk_icon_dirs_copied = 0
for gtk_icon_theme in ['Adwaita', 'hicolor', 'gnome']:
@@ -975,9 +974,7 @@ def main():
parser.add_argument('--builder-name', action='store', dest='builder_name')
options = parser.parse_args()
- flatpakutils.run_in_sandbox_if_available([sys.argv[0], '--flatpak-' + options.platform] + sys.argv[1:])
- if not flatpakutils.is_sandboxed():
- jhbuildutils.enter_jhbuild_environment_if_available(options.platform)
+ jhbuildutils.enter_jhbuild_environment_if_available(options.platform)
configure_logging(options.log_level)
bundle_creator = BundleCreator(options.configuration, options.platform, options.bundle_binary, options.syslibs, options.ldd,
diff --git a/Tools/WebKitTestRunner/CMakeLists.txt b/Tools/WebKitTestRunner/CMakeLists.txt
index ba703658cf8c56ad1768333b70938e67e8b36777..804487a7082024733d5012dcc62b9784c268bb55 100644
--- a/Tools/WebKitTestRunner/CMakeLists.txt
+++ b/Tools/WebKitTestRunner/CMakeLists.txt
@@ -99,6 +99,10 @@ set(TestRunnerInjectedBundle_PRIVATE_LIBRARIES
)
set(TestRunnerInjectedBundle_FRAMEWORKS ${WebKitTestRunner_FRAMEWORKS})
+if (NOT USE_SYSTEM_MALLOC)
+ list(APPEND WebKitTestRunnerInjectedBundle_LIBRARIES bmalloc)
+endif ()
+
set(TestRunnerInjectedBundle_IDL_FILES
"${WebKitTestRunner_DIR}/InjectedBundle/Bindings/AccessibilityController.idl"
"${WebKitTestRunner_DIR}/InjectedBundle/Bindings/AccessibilityTextMarker.idl"
diff --git a/Tools/WebKitTestRunner/TestController.cpp b/Tools/WebKitTestRunner/TestController.cpp
index 9a61e6421c74f12bc565fad0f706cbb246bb784f..0a2bf450b5577c39c8e3645205d9e6f3ff470d93 100644
--- a/Tools/WebKitTestRunner/TestController.cpp
+++ b/Tools/WebKitTestRunner/TestController.cpp
@@ -792,6 +792,7 @@ PlatformWebView* TestController::createOtherPlatformWebView(PlatformWebView* par
nullptr, // requestStorageAccessConfirm
nullptr, // shouldAllowDeviceOrientationAndMotionAccess
nullptr, // runWebAuthenticationPanel
+ 0, // handleJavaScriptDialog
nullptr, // decidePolicyForSpeechRecognitionPermissionRequest
nullptr, // decidePolicyForMediaKeySystemPermissionRequest
nullptr, // queryPermission
@@ -1272,6 +1273,7 @@ void TestController::createWebViewWithOptions(const TestOptions& options)
nullptr, // requestStorageAccessConfirm
shouldAllowDeviceOrientationAndMotionAccess,
runWebAuthenticationPanel,
+ 0, // handleJavaScriptDialog
nullptr, // decidePolicyForSpeechRecognitionPermissionRequest
decidePolicyForMediaKeySystemPermissionRequest,
queryPermission,
diff --git a/Tools/WebKitTestRunner/mac/EventSenderProxy.mm b/Tools/WebKitTestRunner/mac/EventSenderProxy.mm
index 12a89be783e49c44edfca8d27f1fc3ddd24255e9..2ba827c958fa3558b0cd36f9e5b7537493fef362 100644
--- a/Tools/WebKitTestRunner/mac/EventSenderProxy.mm
+++ b/Tools/WebKitTestRunner/mac/EventSenderProxy.mm
@@ -1031,4 +1031,51 @@ void EventSenderProxy::scaleGestureEnd(double scale)
#endif // ENABLE(MAC_GESTURE_EVENTS)
+#if ENABLE(TOUCH_EVENTS)
+void EventSenderProxy::addTouchPoint(int, int)
+{
+}
+
+void EventSenderProxy::updateTouchPoint(int, int, int)
+{
+}
+
+void EventSenderProxy::touchStart()
+{
+}
+
+void EventSenderProxy::touchMove()
+{
+}
+
+void EventSenderProxy::touchEnd()
+{
+}
+
+void EventSenderProxy::touchCancel()
+{
+}
+
+void EventSenderProxy::clearTouchPoints()
+{
+}
+
+void EventSenderProxy::releaseTouchPoint(int)
+{
+}
+
+void EventSenderProxy::cancelTouchPoint(int)
+{
+}
+
+void EventSenderProxy::setTouchPointRadius(int, int)
+{
+}
+
+void EventSenderProxy::setTouchModifier(WKEventModifiers, bool)
+{
+}
+#endif // ENABLE(TOUCH_EVENTS)
+
+
} // namespace WTR
diff --git a/Tools/jhbuild/jhbuild-minimal.modules b/Tools/jhbuild/jhbuild-minimal.modules
index d526231f288ca82f4928d75ee9847b919b72bbfb..c904fac94196a8eb9888abf83b0db5ab69b3a993 100644
--- a/Tools/jhbuild/jhbuild-minimal.modules
+++ b/Tools/jhbuild/jhbuild-minimal.modules
@@ -69,8 +69,8 @@
<cmake id="libwpe">
<branch repo="github-tarball"
module="WebPlatformForEmbedded/libwpe/releases/download/${version}/libwpe-${version}.tar.xz"
- version="1.14.1"
- hash="sha256:b1d0cdcf0f8dbb494e65b0f7913e357106da9a0d57f4fbb7b9d1238a6dbe9ade"/>
+ version="1.16.0"
+ hash="sha256:c7f3a3c6b3d006790d486dc7cceda2b6d2e329de07f33bc47dfc53f00f334b2a"/>
</cmake>
<meson id="wpebackend-fdo">
@@ -79,8 +79,8 @@
</dependencies>
<branch repo="github-tarball"
module="Igalia/WPEBackend-fdo/releases/download/${version}/wpebackend-fdo-${version}.tar.xz"
- version="1.14.2"
- hash="sha256:93c9766ae9864eeaeaee2b0a74f22cbca08df42c1a1bdb55b086f2528e380d38">
+ version="1.14.3"
+ hash="sha256:10121842595a850291db3e82f3db0b9984df079022d386ce42c2b8508159dc6c">
</branch>
</meson>
@@ -188,7 +188,6 @@
</meson>
<meson id="libsoup" mesonargs="-Dgssapi=disabled -Dvapi=disabled -Dntlm=disabled -Dsysprof=disabled -Dautobahn=disabled -Dpkcs11_tests=disabled">
- <pkg-config>libsoup-3.0.pc</pkg-config>
<dependencies>
<dep package="glib"/>
<dep package="glib-networking"/>
@@ -196,8 +195,8 @@
</dependencies>
<branch module="GNOME/libsoup.git"
repo="github.com"
- tag="3.6.0"
- version="3.6.0"
+ tag="3.6.5"
+ version="3.6.5"
checkoutdir="libsoup-${version}"/>
</meson>
diff --git a/Tools/wpe/backends/fdo/HeadlessViewBackendFdo.cpp b/Tools/wpe/backends/fdo/HeadlessViewBackendFdo.cpp
index 6186d81869dbbb346ec5a62f2bbba88e2320d5e7..25b5615339b74cd56042b89f723993023cbb58ca 100644
--- a/Tools/wpe/backends/fdo/HeadlessViewBackendFdo.cpp
+++ b/Tools/wpe/backends/fdo/HeadlessViewBackendFdo.cpp
@@ -175,28 +175,27 @@ void HeadlessViewBackend::updateSnapshot(PlatformBuffer exportedBuffer)
return;
}
- auto info = SkImageInfo::MakeN32Premul(m_width, m_height, SkColorSpace::MakeSRGB());
+ uint32_t width = std::max(0, wl_shm_buffer_get_width(shmBuffer));
+ uint32_t height = std::max(0, wl_shm_buffer_get_height(shmBuffer));
+ if (!width || !height) {
+ fprintf(stderr, "HeadlessViewBackend::updateSnapshot shmBuffer is empty: %ux%u\n", width, height);
+ return;
+ }
+
+ auto info = SkImageInfo::MakeN32Premul(width, height, SkColorSpace::MakeSRGB());
uint32_t bufferStride = info.minRowBytes();
- uint8_t* buffer = new uint8_t[bufferStride * m_height];
- memset(buffer, 0, bufferStride * m_height);
+ uint32_t stride = std::max(0, wl_shm_buffer_get_stride(shmBuffer));
+ if (bufferStride != stride) {
+ fprintf(stderr, "bufferStride != stride: %u != %u\n", bufferStride, stride);
+ return;
+ }
+ uint8_t* buffer = new uint8_t[bufferStride * height];
{
- uint32_t width = std::min<uint32_t>(m_width, std::max(0, wl_shm_buffer_get_width(shmBuffer)));
- uint32_t height = std::min<uint32_t>(m_height, std::max(0, wl_shm_buffer_get_height(shmBuffer)));
- uint32_t stride = std::max(0, wl_shm_buffer_get_stride(shmBuffer));
-
wl_shm_buffer_begin_access(shmBuffer);
auto* data = static_cast<uint8_t*>(wl_shm_buffer_get_data(shmBuffer));
- for (uint32_t y = 0; y < height; ++y) {
- for (uint32_t x = 0; x < width; ++x) {
- buffer[bufferStride * y + 4 * x + 0] = data[stride * y + 4 * x + 0];
- buffer[bufferStride * y + 4 * x + 1] = data[stride * y + 4 * x + 1];
- buffer[bufferStride * y + 4 * x + 2] = data[stride * y + 4 * x + 2];
- buffer[bufferStride * y + 4 * x + 3] = data[stride * y + 4 * x + 3];
- }
- }
-
+ memcpy(buffer, data, bufferStride * height);
wl_shm_buffer_end_access(shmBuffer);
}
diff --git a/WebKit.xcworkspace/contents.xcworkspacedata b/WebKit.xcworkspace/contents.xcworkspacedata
index 5d6492124eb520ce2b25f5c62775438103050ed3..1c0ea8a3258b5676b81fb00360e2c0589cc93e18 100644
--- a/WebKit.xcworkspace/contents.xcworkspacedata
+++ b/WebKit.xcworkspace/contents.xcworkspacedata
@@ -4,6 +4,9 @@
<FileRef
location = "group:Configurations">
</FileRef>
+ <FileRef
+ location = "group:Tools/Playwright/Playwright.xcodeproj">
+ </FileRef>
<FileRef
location = "group:Source/bmalloc/bmalloc.xcodeproj">
</FileRef>
diff --git a/WebKit.xcworkspace/xcshareddata/xcschemes/Everything up to WebKit + Tools.xcscheme b/WebKit.xcworkspace/xcshareddata/xcschemes/Everything up to WebKit + Tools.xcscheme
index 30f8a76f6050c407ab563814f614b3b848c168ff..d5fd599e4865f147d7ca8cfbcd6a4bedf6baa9e5 100644
--- a/WebKit.xcworkspace/xcshareddata/xcschemes/Everything up to WebKit + Tools.xcscheme
+++ b/WebKit.xcworkspace/xcshareddata/xcschemes/Everything up to WebKit + Tools.xcscheme
@@ -202,6 +202,20 @@
ReferencedContainer = "container:Tools/SwiftBrowser/SwiftBrowser.xcodeproj">
</BuildableReference>
</BuildActionEntry>
+ <BuildActionEntry
+ buildForTesting = "YES"
+ buildForRunning = "YES"
+ buildForProfiling = "YES"
+ buildForArchiving = "YES"
+ buildForAnalyzing = "YES">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "8D1107260486CEB800E47091"
+ BuildableName = "Playwright.app"
+ BlueprintName = "Playwright"
+ ReferencedContainer = "container:Tools/Playwright/Playwright.xcodeproj">
+ </BuildableReference>
+ </BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"