22938 lines
1022 KiB
Diff
22938 lines
1022 KiB
Diff
diff --git a/Source/JavaScriptCore/CMakeLists.txt b/Source/JavaScriptCore/CMakeLists.txt
|
|
index b52d8892843f6b934081c0e0b9f93264626937b5..d076e8ad848680e0a0b7790ff4b11bb768c72523 100644
|
|
--- a/Source/JavaScriptCore/CMakeLists.txt
|
|
+++ b/Source/JavaScriptCore/CMakeLists.txt
|
|
@@ -1401,21 +1401,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 a92c371597d3af93bc7dd936efb1046ad899eaec..dc94df080778cb9b38b6a9cc3213d922505ff323 100644
|
|
--- a/Source/JavaScriptCore/DerivedSources-input.xcfilelist
|
|
+++ b/Source/JavaScriptCore/DerivedSources-input.xcfilelist
|
|
@@ -99,20 +99,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 706f3548b9a40b323d49af7d61f5bc59692a0da6..c2b49f4b97f34e512442c1a790ba794df2ae26cd 100644
|
|
--- a/Source/JavaScriptCore/DerivedSources.make
|
|
+++ b/Source/JavaScriptCore/DerivedSources.make
|
|
@@ -302,21 +302,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 4113ddb45d4a8d08379d4dc56c44cde56162accf..e00cb9cb01a7a241f3f25b1e4cdc2fcaee92b3ac 100644
|
|
--- a/Source/JavaScriptCore/inspector/IdentifiersFactory.h
|
|
+++ b/Source/JavaScriptCore/inspector/IdentifiersFactory.h
|
|
@@ -31,6 +31,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 8b39848154ecab9f7daa2d21c85562a319cd06d7..c8a1f44cb4516993899ffe1404b6c3865d42433a 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::PropertyNameArray 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 1f5d0adbf624bd24ef1e525967e6e82e8c37b4e5..4fe0f364b4ccd11774bf29f772e0a568549a4322 100644
|
|
--- a/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.cpp
|
|
+++ b/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.cpp
|
|
@@ -102,7 +102,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);
|
|
|
|
@@ -147,6 +147,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 2eba743177c016a3415d4a5deafc552e842dd0fa..939d14be7a2703777652467f0f60e67ef1c5e0f8 100644
|
|
--- a/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.h
|
|
+++ b/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.h
|
|
@@ -83,8 +83,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 d408d364f1986983161f9d44efbc8bc6f6898676..1375ce9990f0c63d7e6f33ee62930051d6cd44cb 100644
|
|
--- a/Source/JavaScriptCore/inspector/InspectorFrontendRouter.cpp
|
|
+++ b/Source/JavaScriptCore/inspector/InspectorFrontendRouter.cpp
|
|
@@ -49,7 +49,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 0cc2127c9c12c2d82dea9550bad73f4ffb99ba24..8ca65cc042d435cbc0e05dcc5c5dfc958eb24f5a 100644
|
|
--- a/Source/JavaScriptCore/inspector/InspectorTarget.cpp
|
|
+++ b/Source/JavaScriptCore/inspector/InspectorTarget.cpp
|
|
@@ -44,6 +44,8 @@ void InspectorTarget::resume()
|
|
ASSERT(m_isPaused);
|
|
m_isPaused = false;
|
|
|
|
+ willResume();
|
|
+
|
|
if (m_resumeCallback) {
|
|
m_resumeCallback();
|
|
m_resumeCallback = nullptr;
|
|
@@ -52,7 +54,6 @@ void InspectorTarget::resume()
|
|
|
|
void InspectorTarget::setResumeCallback(WTF::Function<void()>&& callback)
|
|
{
|
|
- ASSERT(!m_resumeCallback);
|
|
m_resumeCallback = WTFMove(callback);
|
|
}
|
|
|
|
diff --git a/Source/JavaScriptCore/inspector/InspectorTarget.h b/Source/JavaScriptCore/inspector/InspectorTarget.h
|
|
index b555c2e5a071d0a6a016061cc60755449557556d..d019346f0932296d15212c76a4a9b56beb565ff4 100644
|
|
--- a/Source/JavaScriptCore/inspector/InspectorTarget.h
|
|
+++ b/Source/JavaScriptCore/inspector/InspectorTarget.h
|
|
@@ -66,8 +66,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 c33e236f5228e21c6d5e0ea9bd97d07cdcb70640..7f160aec0f13e8c936aa7dea769d4e160d716452 100644
|
|
--- a/Source/JavaScriptCore/inspector/JSGlobalObjectConsoleClient.cpp
|
|
+++ b/Source/JavaScriptCore/inspector/JSGlobalObjectConsoleClient.cpp
|
|
@@ -222,6 +222,14 @@ void JSGlobalObjectConsoleClient::screenshot(JSGlobalObject*, Ref<ScriptArgument
|
|
warnUnimplemented("console.screenshot"_s);
|
|
}
|
|
|
|
+void JSGlobalObjectConsoleClient::bindingCalled(JSGlobalObject*, const String&, const String&)
|
|
+{
|
|
+ if (LIKELY(!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 6bbd0729a65b4a901e7da4dc50cc47c669bd9897..452b25d0e8eba3df1d5f6623dc222048bef120cd 100644
|
|
--- a/Source/JavaScriptCore/inspector/JSGlobalObjectConsoleClient.h
|
|
+++ b/Source/JavaScriptCore/inspector/JSGlobalObjectConsoleClient.h
|
|
@@ -64,6 +64,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 0cb6efeef2430faa5dbd812f71d4abfd5f6eb9df..787ec6a5f8413c0a9dc133cb0e51ccdab58d40d0 100644
|
|
--- a/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.cpp
|
|
+++ b/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.cpp
|
|
@@ -194,9 +194,8 @@ void InspectorRuntimeAgent::callFunctionOn(const Protocol::Runtime::RemoteObject
|
|
void InspectorRuntimeAgent::callFunctionOn(InjectedScript& injectedScript, const Protocol::Runtime::RemoteObjectId& objectId, 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>&& callback)
|
|
{
|
|
ASSERT(!injectedScript.hasNoValue());
|
|
-
|
|
JSC::Debugger::TemporarilyDisableExceptionBreakpoints temporarilyDisableExceptionBreakpoints(m_debugger);
|
|
-
|
|
+
|
|
bool pauseAndMute = doNotPauseOnExceptionsAndMuteConsole.value_or(false);
|
|
if (pauseAndMute) {
|
|
temporarilyDisableExceptionBreakpoints.replace();
|
|
@@ -215,6 +214,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 816633a6dfc75a1248f6edb44807e5d4f602568c..687fb7dadfad9357e15a27e0869fa145c46fb39a 100644
|
|
--- a/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.h
|
|
+++ b/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.h
|
|
@@ -64,6 +64,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 e47c6ca59f37fbf18ca8a393df72e0472363fabd..b393465540595220561ae00afb85408279710864 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)
|
|
{
|
|
ASSERT_WITH_MESSAGE(m_targets.get(targetId), "Sending a message from an untracked target to the frontend.");
|
|
@@ -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 04377b714a6ccb5294c65d592e74350621d470ba..b6de937bfa3e6185ce29f4e432d327a3cedee6df 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 27c65fbda226f1cd5bfd68944fe87fb9b2a688a6..b036f050859ee88004a7bf6daa4bb73835360615 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",
|
|
@@ -268,6 +278,16 @@
|
|
{ "name": "width", "type": "number" },
|
|
{ "name": "height", "type": "number" }
|
|
]
|
|
+ },
|
|
+ {
|
|
+ "id": "FilePayload",
|
|
+ "type": "object",
|
|
+ "description": "Data to construct File object.",
|
|
+ "properties": [
|
|
+ { "name": "name", "type": "string", "description": "File name." },
|
|
+ { "name": "type", "type": "string", "description": "File type." },
|
|
+ { "name": "data", "type": "string", "description": "Base64-encoded file data." }
|
|
+ ]
|
|
}
|
|
],
|
|
"commands": [
|
|
@@ -697,7 +717,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": [
|
|
@@ -774,6 +797,47 @@
|
|
"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": "files", "type": "array", "items": { "$ref": "FilePayload" }, "optional": true, "description": "Files to set" },
|
|
+ { "name": "paths", "type": "array", "items": { "type": "string" }, "optional": true, "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 96af27ece2ac200e11c4311b3ca0d9d3b5a048da..3168f7806fcbdabec07acc5e304bae1e3736240a 100644
|
|
--- a/Source/JavaScriptCore/inspector/protocol/Network.json
|
|
+++ b/Source/JavaScriptCore/inspector/protocol/Network.json
|
|
@@ -352,6 +352,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 3d032713a7f3bb9645bfc7d42455a0494b5376c0..913dda5e90b86cc5f8e4ca6881f6db57520a7f66 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,50 @@
|
|
{ "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": "AXNode",
|
|
+ "type": "object",
|
|
+ "description": "Accessibility Node",
|
|
+ "properties": [
|
|
+ { "name": "role", "type": "string", "description": "The role."},
|
|
+ { "name": "name", "type": "string","optional": true, "description": "A human readable name for the node."},
|
|
+ { "name": "value", "type": "any", "optional": true, "description": "The current value of the node."},
|
|
+ { "name": "description", "type": "string", "optional": true, "description": "An additional human readable description of the node."},
|
|
+ { "name": "keyshortcuts", "type": "string", "optional": true, "description": "Keyboard shortcuts associated with this node."},
|
|
+ { "name": "roledescription", "type": "string", "optional": true, "description": "A human readable alternative to the role."},
|
|
+ { "name": "valuetext", "type": "string", "optional": true, "description": "A description of the current value."},
|
|
+ { "name": "disabled", "type": "boolean", "optional": true, "description": "Whether the node is disabled."},
|
|
+ { "name": "expanded", "type": "boolean", "optional": true, "description": "Whether the node is expanded or collapsed."},
|
|
+ { "name": "focused", "type": "boolean", "optional": true, "description": "Whether the node is focused."},
|
|
+ { "name": "modal", "type": "boolean", "optional": true, "description": "Whether the node is modal."},
|
|
+ { "name": "multiselectable", "type": "boolean", "optional": true, "description": "Whether more than one child can be selected."},
|
|
+ { "name": "readonly", "type": "boolean", "optional": true, "description": "Whether the node is read only."},
|
|
+ { "name": "required", "type": "boolean", "optional": true, "description": "Whether the node is required."},
|
|
+ { "name": "selected", "type": "boolean", "optional": true, "description": "Whether the node is selected in its parent node."},
|
|
+ { "name": "checked", "type": "string", "optional": true, "enum": ["true", "false", "mixed"], "description": "Whether the checkbox is checked, or \"mixed\"."},
|
|
+ { "name": "pressed", "type": "string", "optional": true, "enum": ["true", "false", "mixed"], "description": "Whether the toggle button is checked, or \"mixed\"."},
|
|
+ { "name": "level", "type": "integer", "optional": true, "description": "The level of a heading."},
|
|
+ { "name": "valuemin", "type": "number", "optional": true, "description": "The minimum value in a node."},
|
|
+ { "name": "valuemax", "type": "number", "optional": true, "description": "The maximum value in a node."},
|
|
+ { "name": "autocomplete", "type": "string", "optional": true, "description": "What kind of autocomplete is supported by a control."},
|
|
+ { "name": "haspopup", "type": "string", "optional": true, "description": "What kind of popup is currently being shown for a node."},
|
|
+ { "name": "invalid", "type": "string", "optional": true, "enum": ["true", "false", "grammar", "spelling"], "description": "Whether and in what way this node's value is invalid."},
|
|
+ { "name": "orientation", "type": "string", "optional": true, "description": "Whether the node is oriented horizontally or vertically."},
|
|
+ { "name": "focusable", "type": "boolean", "optional": true, "description": "Whether the node is focusable."},
|
|
+ { "name": "children", "type": "array", "optional": true, "items": { "$ref": "AXNode"}, "description": "Child AXNodes of this node, if any."},
|
|
+ { "name": "found", "type": "boolean", "optional": true, "description": "True if this AXNode corresponds with the ObjectId passed into acessibilitySnapshot."}
|
|
+ ]
|
|
+ },
|
|
+ {
|
|
+ "id": "Insets",
|
|
+ "type": "object",
|
|
+ "properties": [
|
|
+ { "name": "top", "type": "number" },
|
|
+ { "name": "right", "type": "number" },
|
|
+ { "name": "bottom", "type": "number" },
|
|
+ { "name": "left", "type": "number" }
|
|
+ ]
|
|
}
|
|
],
|
|
"commands": [
|
|
@@ -145,6 +203,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": "navigate",
|
|
"description": "Navigates current page to the given URL.",
|
|
@@ -161,6 +227,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.",
|
|
@@ -285,6 +359,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.",
|
|
@@ -305,7 +401,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)." }
|
|
@@ -323,12 +420,64 @@
|
|
{
|
|
"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": "accessibilitySnapshot",
|
|
+ "description": "Serializes and returns all of the accessibility nodes of the page.",
|
|
+ "parameters": [
|
|
+ { "name": "objectId", "type": "string", "optional": true, "description": "Object Id of a node to find in the accessibility tree."}
|
|
+ ],
|
|
+ "returns": [
|
|
+ { "name": "axNode", "$ref": "AXNode", "description": "The root AXNode."}
|
|
+ ]
|
|
+ },
|
|
+ {
|
|
+ "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": [
|
|
@@ -336,14 +485,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." }
|
|
]
|
|
},
|
|
{
|
|
@@ -353,6 +504,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.",
|
|
@@ -381,7 +540,8 @@
|
|
"targetTypes": ["page"],
|
|
"parameters": [
|
|
{ "name": "frameId", "$ref": "Network.FrameId", "description": "Id of the frame that has scheduled a navigation." },
|
|
- { "name": "delay", "type": "number", "description": "Delay (in seconds) until the navigation is scheduled to begin. The navigation is not guaranteed to start." }
|
|
+ { "name": "delay", "type": "number", "description": "Delay (in seconds) until the navigation is scheduled to begin. The navigation is not guaranteed to start." },
|
|
+ { "name": "targetIsCurrentFrame", "type": "boolean", "description": "Whether the naviation will happen in the same frame." }
|
|
]
|
|
},
|
|
{
|
|
@@ -392,6 +552,22 @@
|
|
{ "name": "frameId", "$ref": "Network.FrameId", "description": "Id of the frame that has cleared its scheduled navigation." }
|
|
]
|
|
},
|
|
+ {
|
|
+ "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.",
|
|
@@ -399,6 +575,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..440dd95173e066a886de120fb3dab7597d85feb6
|
|
--- /dev/null
|
|
+++ b/Source/JavaScriptCore/inspector/protocol/Playwright.json
|
|
@@ -0,0 +1,315 @@
|
|
+{
|
|
+ "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" }
|
|
+ ],
|
|
+ "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": false, "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" }
|
|
+ ]
|
|
+ },
|
|
+ {
|
|
+ "name": "screencastFinished",
|
|
+ "parameters": [
|
|
+ { "name": "screencastId", "$ref": "Screencast.ScreencastId", "description": "Unique identifier of the screencast." }
|
|
+ ]
|
|
+ }
|
|
+ ]
|
|
+}
|
|
diff --git a/Source/JavaScriptCore/inspector/protocol/Runtime.json b/Source/JavaScriptCore/inspector/protocol/Runtime.json
|
|
index 301b88eb1607b0975c3fa81d91045eb5403378ec..0e2ae5d96b3cdcc20ecc95ddc7b49538dcb3c302 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..73a4e53ced3acc41316bb8d4c787306d3f28a27e
|
|
--- /dev/null
|
|
+++ b/Source/JavaScriptCore/inspector/protocol/Screencast.json
|
|
@@ -0,0 +1,64 @@
|
|
+{
|
|
+ "domain": "Screencast",
|
|
+ "availability": ["web"],
|
|
+ "types": [
|
|
+ {
|
|
+ "id": "ScreencastId",
|
|
+ "type": "string",
|
|
+ "description": "Unique identifier of the screencast."
|
|
+ }
|
|
+ ],
|
|
+ "commands": [
|
|
+ {
|
|
+ "name": "startVideo",
|
|
+ "description": "Starts recoring video to speified file.",
|
|
+ "parameters": [
|
|
+ { "name": "file", "type": "string", "description": "Output file location." },
|
|
+ { "name": "width", "type": "integer" },
|
|
+ { "name": "height", "type": "integer" },
|
|
+ { "name": "toolbarHeight", "type": "integer" }
|
|
+ ],
|
|
+ "returns": [
|
|
+ { "name": "screencastId", "$ref": "ScreencastId", "description": "Unique identifier of the screencast." }
|
|
+ ]
|
|
+ },
|
|
+ {
|
|
+ "name": "stopVideo",
|
|
+ "async": true,
|
|
+ "description": "Stops recoding video. Returns after the file has been closed."
|
|
+ },
|
|
+ {
|
|
+ "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": "deviceWidth", "type": "integer" },
|
|
+ { "name": "deviceHeight", "type": "integer" }
|
|
+ ]
|
|
+ }
|
|
+ ]
|
|
+}
|
|
diff --git a/Source/JavaScriptCore/inspector/protocol/Target.json b/Source/JavaScriptCore/inspector/protocol/Target.json
|
|
index 52920cded24a9c6b0ef6fb4e518664955db4f9fa..bbbabc4e7259088b9404e8cc07eecd6f45077da0 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", "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 24891ad836086fd23024fcb4d08ca63f6974c812..29f4b6b1923383fec7a99d28a4e815dc4536d160 100644
|
|
--- a/Source/JavaScriptCore/runtime/ConsoleClient.h
|
|
+++ b/Source/JavaScriptCore/runtime/ConsoleClient.h
|
|
@@ -78,6 +78,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 ArgumentRequirement { ArgumentRequired, ArgumentNotRequired };
|
|
diff --git a/Source/ThirdParty/libwebrtc/CMakeLists.txt b/Source/ThirdParty/libwebrtc/CMakeLists.txt
|
|
index 2ccb951b0cf57707b68ce5e971c5e191b91f2bd0..6ff141b41f4b6c279c367ad66d5c2b6adede8646 100644
|
|
--- a/Source/ThirdParty/libwebrtc/CMakeLists.txt
|
|
+++ b/Source/ThirdParty/libwebrtc/CMakeLists.txt
|
|
@@ -532,6 +532,11 @@ set(webrtc_SOURCES
|
|
Source/third_party/crc32c/src/src/crc32c.cc
|
|
Source/third_party/crc32c/src/src/crc32c_portable.cc
|
|
Source/third_party/crc32c/src/src/crc32c_sse42.cc
|
|
+# Playwright begin
|
|
+ Source/third_party/libwebm/mkvmuxer/mkvmuxer.cc
|
|
+ Source/third_party/libwebm/mkvmuxer/mkvmuxerutil.cc
|
|
+ Source/third_party/libwebm/mkvmuxer/mkvwriter.cc
|
|
+# Playwright end
|
|
Source/third_party/libyuv/source/compare.cc
|
|
Source/third_party/libyuv/source/compare_common.cc
|
|
Source/third_party/libyuv/source/compare_gcc.cc
|
|
@@ -695,7 +700,6 @@ set(webrtc_SOURCES
|
|
Source/webrtc/api/video_codecs/builtin_video_encoder_factory.cc
|
|
Source/webrtc/api/video_codecs/h264_profile_level_id.cc
|
|
Source/webrtc/api/video_codecs/h265_profile_tier_level.cc
|
|
- Source/webrtc/api/video_codecs/libaom_av1_encoder_factory.cc
|
|
Source/webrtc/api/video_codecs/scalability_mode.cc
|
|
Source/webrtc/api/video_codecs/scalability_mode_helper.cc
|
|
Source/webrtc/api/video_codecs/sdp_video_format.cc
|
|
@@ -2350,6 +2354,11 @@ set(webrtc_INCLUDE_DIRECTORIES PRIVATE
|
|
Source/third_party/libsrtp/config
|
|
Source/third_party/libsrtp/crypto/include
|
|
Source/third_party/libsrtp/include
|
|
+# Playwright begin
|
|
+ Source/third_party/libwebm
|
|
+ Source/third_party/libvpx/source/libvpx
|
|
+ Source/third_party/libvpx/source/libvpx/third_party/googletest/src/include
|
|
+# Playwright end
|
|
Source/third_party/libyuv/include
|
|
Source/third_party/opus/src/celt
|
|
Source/third_party/opus/src/include
|
|
diff --git a/Source/ThirdParty/libwebrtc/Configurations/Base-libwebrtc.xcconfig b/Source/ThirdParty/libwebrtc/Configurations/Base-libwebrtc.xcconfig
|
|
index 0c5c8e689bdddec766f9de5bffd4444a5e068d77..330dd1f585e530722178c65c883641a2b8c0f1bd 100644
|
|
--- a/Source/ThirdParty/libwebrtc/Configurations/Base-libwebrtc.xcconfig
|
|
+++ b/Source/ThirdParty/libwebrtc/Configurations/Base-libwebrtc.xcconfig
|
|
@@ -24,6 +24,8 @@
|
|
HEADER_SEARCH_PATHS = Source Source/third_party/libsrtp/crypto/include Source/third_party/libsrtp/include Source/third_party/boringssl/src/include Source/third_party/libyuv/include Source/webrtc/webkit_sdk/objc/Framework/Headers Source/webrtc/common_audio/signal_processing/include Source/webrtc/modules/audio_coding/codecs/isac/main/include Source/third_party/opus/src/celt Source/third_party/opus/src/include Source/third_party/opus/src/src Source/webrtc/modules/audio_device/mac Source/webrtc/modules/audio_device/ios Source/webrtc Source/webrtc/webkit_sdk/objc Source/webrtc/webkit_sdk/objc/base Source/webrtc/webkit_sdk/objc/Framework/Classes Source/third_party/libsrtp/config Source/webrtc/webkit_sdk/objc/Framework/Classes/Common Source/webrtc/webkit_sdk/objc/Framework/Classes/Video Source/webrtc/webkit_sdk/objc/Framework/Classes/PeerConnection Source/third_party/abseil-cpp Source/third_party/libvpx/source/libvpx Source/third_party/libwebm/webm_parser/include Source/third_party/crc32c/config Source/third_party/crc32c/include Source/third_party/crc32c/src/include Source/third_party/libaom/source/libaom;
|
|
USE_HEADERMAP = NO;
|
|
|
|
+HEADER_SEARCH_PATHS = ${HEADER_SEARCH_PATHS} Source/third_party/libwebm/mkvmuxer Source/third_party/libvpx/source/libvpx/third_party/libwebm;
|
|
+
|
|
WARNING_CFLAGS = -Wno-deprecated-declarations $(inherited);
|
|
|
|
// FIXME: Set WEBRTC_USE_BUILTIN_ISAC_FIX and WEBRTC_USE_BUILTIN_ISAC_FLOAT for iOS and Mac
|
|
diff --git a/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.exp b/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.exp
|
|
index 6c754858a3ea883a65ad022ce16b6c45ae65ee35..15f968472712e1a2a88672ed290b103cf9d620ec 100644
|
|
--- a/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.exp
|
|
+++ b/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.exp
|
|
@@ -421,3 +421,16 @@ __ZNK8mkvmuxer7Segment16GetTrackByNumberEy
|
|
__ZN8mkvmuxer6Tracks11kAv1CodecIdE
|
|
__ZN8mkvmuxer6Tracks11kVp8CodecIdE
|
|
__ZN8mkvmuxer6Tracks11kVp9CodecIdE
|
|
+__ZN8mkvmuxer11SegmentInfo4InitEv
|
|
+__ZN8mkvmuxer9MkvWriterC1EP7__sFILE
|
|
+_ARGBToI420
|
|
+_vpx_codec_destroy
|
|
+_vpx_codec_enc_config_default
|
|
+_vpx_codec_enc_init_ver
|
|
+_vpx_codec_encode
|
|
+_vpx_codec_err_to_string
|
|
+_vpx_codec_error
|
|
+_vpx_codec_get_cx_data
|
|
+_vpx_codec_iface_name
|
|
+_vpx_codec_version_str
|
|
+_vpx_codec_vp8_cx
|
|
diff --git a/Source/ThirdParty/libwebrtc/libwebrtc.xcodeproj/project.pbxproj b/Source/ThirdParty/libwebrtc/libwebrtc.xcodeproj/project.pbxproj
|
|
index 2c30b5b08d589c82def812fb881a63cb6e49e7b4..c76a8a2963923bf54c3d134aa2594150c43a4b3c 100644
|
|
--- a/Source/ThirdParty/libwebrtc/libwebrtc.xcodeproj/project.pbxproj
|
|
+++ b/Source/ThirdParty/libwebrtc/libwebrtc.xcodeproj/project.pbxproj
|
|
@@ -55,6 +55,20 @@
|
|
};
|
|
/* End PBXAggregateTarget section */
|
|
|
|
+/* Begin PBXAggregateTarget section */
|
|
+ F31720AC27FE215900EEE407 /* Copy libvpx headers */ = {
|
|
+ isa = PBXAggregateTarget;
|
|
+ buildConfigurationList = F31720B027FE215900EEE407 /* Build configuration list for PBXAggregateTarget "Copy libvpx headers" */;
|
|
+ buildPhases = (
|
|
+ F31720B127FE216400EEE407 /* ShellScript */,
|
|
+ );
|
|
+ dependencies = (
|
|
+ );
|
|
+ name = "Copy libvpx headers";
|
|
+ productName = "Copy libvpx headers";
|
|
+ };
|
|
+/* End PBXAggregateTarget section */
|
|
+
|
|
/* Begin PBXBuildFile section */
|
|
2D6BFF60280A93DF00A1A74F /* video_coding.h in Headers */ = {isa = PBXBuildFile; fileRef = 4131C45B234C81710028A615 /* video_coding.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
|
2D6BFF61280A93EC00A1A74F /* video_codec_initializer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4131C45E234C81720028A615 /* video_codec_initializer.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
|
@@ -5772,6 +5786,13 @@
|
|
remoteGlobalIDString = DDF30D0527C5C003006A526F;
|
|
remoteInfo = absl;
|
|
};
|
|
+ F31720B327FE273100EEE407 /* PBXContainerItemProxy */ = {
|
|
+ isa = PBXContainerItemProxy;
|
|
+ containerPortal = FB39D0701200ED9200088E69 /* Project object */;
|
|
+ proxyType = 1;
|
|
+ remoteGlobalIDString = F31720AC27FE215900EEE407;
|
|
+ remoteInfo = "Copy libvpx headers";
|
|
+ };
|
|
/* End PBXContainerItemProxy section */
|
|
|
|
/* Begin PBXCopyFilesBuildPhase section */
|
|
@@ -24241,6 +24262,7 @@
|
|
);
|
|
dependencies = (
|
|
410B3827292B73E90003E515 /* PBXTargetDependency */,
|
|
+ F31720B427FE273100EEE407 /* PBXTargetDependency */,
|
|
DD2E76E827C6B69A00F2A74C /* PBXTargetDependency */,
|
|
CDEBB4CC24C01AB400ADBD44 /* PBXTargetDependency */,
|
|
411ED040212E0811004320BA /* PBXTargetDependency */,
|
|
@@ -24334,6 +24356,7 @@
|
|
4460B8B92B155B6A00392062 /* vp9_qp_parser_fuzzer */,
|
|
444A6EF02AEADFC9005FE121 /* vp9_replay_fuzzer */,
|
|
44945C512B9BA1C300447FFD /* webm_fuzzer */,
|
|
+ F31720AC27FE215900EEE407 /* Copy libvpx headers */,
|
|
);
|
|
};
|
|
/* End PBXProject section */
|
|
@@ -24437,6 +24460,23 @@
|
|
shellPath = /bin/sh;
|
|
shellScript = "[ -z \"${WK_DERIVED_SDK_HEADERS_DIR}\" -o -d \"${WK_DERIVED_SDK_HEADERS_DIR}\" ] && touch \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
|
};
|
|
+ F31720B127FE216400EEE407 /* ShellScript */ = {
|
|
+ isa = PBXShellScriptBuildPhase;
|
|
+ buildActionMask = 2147483647;
|
|
+ files = (
|
|
+ );
|
|
+ inputFileListPaths = (
|
|
+ );
|
|
+ inputPaths = (
|
|
+ );
|
|
+ outputFileListPaths = (
|
|
+ );
|
|
+ outputPaths = (
|
|
+ );
|
|
+ runOnlyForDeploymentPostprocessing = 0;
|
|
+ shellPath = /bin/sh;
|
|
+ shellScript = "PRIVATE_HEADERS_FOLDER_PATH=usr/local/include\n\nif [[ \"${DEPLOYMENT_LOCATION}\" == \"NO\" ]]; then\n PRIVATE_HEADERS_PATH=\"${TARGET_BUILD_DIR%/}/${PRIVATE_HEADERS_FOLDER_PATH}\"\nelse\n PRIVATE_HEADERS_PATH=\"${DSTROOT}${INSTALL_PATH_PREFIX%/}/${PRIVATE_HEADERS_FOLDER_PATH}\"\nfi;\n\necho \"#### PRIVATE_HEADERS_PATH = ${PRIVATE_HEADERS_PATH}\"\necho\n\nmkdir -p \"${PRIVATE_HEADERS_PATH}\"\n\nrsync -av --no-owner --no-group --prune-empty-dirs --exclude \".svn\" --exclude \"usr\" --include \"*/\" --include \"*.h\" --exclude \"*\" \"${SRCROOT}/Source/third_party/libyuv/include/\" \"${PRIVATE_HEADERS_PATH}\"\n\nrsync -av --no-owner --no-group --prune-empty-dirs --exclude \".svn\" --exclude \"usr\" --exclude \"src\" --exclude \"internal\" --include \"*/\" --include \"*.h\" --exclude \"*\" \"${SRCROOT}/Source/third_party/libvpx/source/libvpx/vpx\" \"${PRIVATE_HEADERS_PATH}\"\n\nrsync -av --no-owner --no-group --prune-empty-dirs --exclude \".svn\" --exclude \"usr\" --include \"*/\" --include \"*.h\" --exclude \"*\" \"${SRCROOT}/Source/third_party/libwebm/\" \"${PRIVATE_HEADERS_PATH}\"\n\n";
|
|
+ };
|
|
/* End PBXShellScriptBuildPhase section */
|
|
|
|
/* Begin PBXSourcesBuildPhase section */
|
|
@@ -27400,6 +27440,11 @@
|
|
target = DDF30D0527C5C003006A526F /* absl */;
|
|
targetProxy = DD2E76E727C6B69A00F2A74C /* PBXContainerItemProxy */;
|
|
};
|
|
+ F31720B427FE273100EEE407 /* PBXTargetDependency */ = {
|
|
+ isa = PBXTargetDependency;
|
|
+ target = F31720AC27FE215900EEE407 /* Copy libvpx headers */;
|
|
+ targetProxy = F31720B327FE273100EEE407 /* PBXContainerItemProxy */;
|
|
+ };
|
|
/* End PBXTargetDependency section */
|
|
|
|
/* Begin XCBuildConfiguration section */
|
|
@@ -28167,6 +28212,27 @@
|
|
};
|
|
name = Production;
|
|
};
|
|
+ F31720AD27FE215900EEE407 /* Debug */ = {
|
|
+ isa = XCBuildConfiguration;
|
|
+ buildSettings = {
|
|
+ PRODUCT_NAME = "$(TARGET_NAME)";
|
|
+ };
|
|
+ name = Debug;
|
|
+ };
|
|
+ F31720AE27FE215900EEE407 /* Release */ = {
|
|
+ isa = XCBuildConfiguration;
|
|
+ buildSettings = {
|
|
+ PRODUCT_NAME = "$(TARGET_NAME)";
|
|
+ };
|
|
+ name = Release;
|
|
+ };
|
|
+ F31720AF27FE215900EEE407 /* Production */ = {
|
|
+ isa = XCBuildConfiguration;
|
|
+ buildSettings = {
|
|
+ PRODUCT_NAME = "$(TARGET_NAME)";
|
|
+ };
|
|
+ name = Production;
|
|
+ };
|
|
FB39D0711200ED9200088E69 /* Debug */ = {
|
|
isa = XCBuildConfiguration;
|
|
baseConfigurationReference = 5D7C59C71208C68B001C873E /* DebugRelease.xcconfig */;
|
|
@@ -28549,6 +28615,16 @@
|
|
defaultConfigurationIsVisible = 0;
|
|
defaultConfigurationName = Production;
|
|
};
|
|
+ F31720B027FE215900EEE407 /* Build configuration list for PBXAggregateTarget "Copy libvpx headers" */ = {
|
|
+ isa = XCConfigurationList;
|
|
+ buildConfigurations = (
|
|
+ F31720AD27FE215900EEE407 /* Debug */,
|
|
+ F31720AE27FE215900EEE407 /* Release */,
|
|
+ F31720AF27FE215900EEE407 /* Production */,
|
|
+ );
|
|
+ defaultConfigurationIsVisible = 0;
|
|
+ defaultConfigurationName = Production;
|
|
+ };
|
|
FB39D0731200ED9200088E69 /* Build configuration list for PBXProject "libwebrtc" */ = {
|
|
isa = XCConfigurationList;
|
|
buildConfigurations = (
|
|
diff --git a/Source/ThirdParty/skia/CMakeLists.txt b/Source/ThirdParty/skia/CMakeLists.txt
|
|
index 74b12c3ccae8b65ad3a35063bece92a9ecb27cbe..1656508a1c5a2103b2bab3068305c6bdba7f0208 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 ()
|
|
@@ -947,6 +949,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 02d962ba310f7e231c84657823766c834ae5b6a6..44587b824e07c1d8a9fa99b32a02da0ddd2ca52c 100644
|
|
--- a/Source/WTF/Scripts/Preferences/UnifiedWebPreferences.yaml
|
|
+++ b/Source/WTF/Scripts/Preferences/UnifiedWebPreferences.yaml
|
|
@@ -602,6 +602,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
|
|
@@ -612,7 +613,7 @@ AsyncClipboardAPIEnabled:
|
|
default: false
|
|
WebKit:
|
|
"PLATFORM(COCOA) || PLATFORM(GTK)" : 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
|
|
|
|
BlobRegistryTopOriginPartitioningEnabled:
|
|
@@ -2270,6 +2268,7 @@ CrossOriginEmbedderPolicyEnabled:
|
|
WebCore:
|
|
default: false
|
|
|
|
+# Playwright: disable setting.
|
|
CrossOriginOpenerPolicyEnabled:
|
|
type: bool
|
|
status: stable
|
|
@@ -2310,7 +2309,7 @@ CustomPasteboardDataEnabled:
|
|
WebKitLegacy:
|
|
default: false
|
|
WebKit:
|
|
- "PLATFORM(COCOA) || PLATFORM(GTK) || PLATFORM(WIN)": true
|
|
+ "PLATFORM(COCOA) || PLATFORM(GTK) || PLATFORM(WPE) || PLATFORM(WIN)": true
|
|
default: false
|
|
|
|
DOMAudioSessionEnabled:
|
|
@@ -2343,6 +2342,7 @@ DOMAudioSessionFullEnabled:
|
|
WebCore:
|
|
default: false
|
|
|
|
+# Playwright: enable on all platforms to align with Safari.
|
|
DOMPasteAccessRequestsEnabled:
|
|
type: bool
|
|
status: internal
|
|
@@ -2354,7 +2354,7 @@ DOMPasteAccessRequestsEnabled:
|
|
default: false
|
|
WebKit:
|
|
"PLATFORM(IOS) || PLATFORM(MAC) || PLATFORM(GTK) || PLATFORM(VISION)": true
|
|
- default: false
|
|
+ default: true
|
|
WebCore:
|
|
default: false
|
|
|
|
@@ -2420,10 +2420,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
|
|
|
|
@@ -2436,7 +2436,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
|
|
@@ -2691,7 +2691,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
|
|
@@ -3143,10 +3143,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
|
|
|
|
@@ -3707,7 +3707,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
|
|
@@ -3740,7 +3740,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
|
|
@@ -3756,7 +3756,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
|
|
@@ -3788,7 +3788,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
|
|
@@ -3836,6 +3836,7 @@ InspectorAttachmentSide:
|
|
WebKit:
|
|
default: 0
|
|
|
|
+# Playwright: disable setting.
|
|
InspectorStartsAttached:
|
|
type: bool
|
|
status: embedder
|
|
@@ -3843,7 +3844,7 @@ InspectorStartsAttached:
|
|
exposed: [ WebKit ]
|
|
defaultValue:
|
|
WebKit:
|
|
- default: true
|
|
+ default: false
|
|
|
|
InspectorWindowFrame:
|
|
type: String
|
|
@@ -5778,7 +5779,7 @@ PermissionsAPIEnabled:
|
|
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
|
|
@@ -5841,6 +5842,19 @@ PitchCorrectionAlgorithm:
|
|
WebCore:
|
|
default: MediaPlayerEnums::PitchCorrectionAlgorithm::BestAllAround
|
|
|
|
+# Playwright: add preference 'PointerLockEnabled'.
|
|
+PointerLockEnabled:
|
|
+ type: bool
|
|
+ status: embedder
|
|
+ condition: ENABLE(POINTER_LOCK)
|
|
+ defaultValue:
|
|
+ WebKitLegacy:
|
|
+ default: true
|
|
+ WebKit:
|
|
+ default: true
|
|
+ WebCore:
|
|
+ default: true
|
|
+
|
|
PointerLockOptionsEnabled:
|
|
type: bool
|
|
status: stable
|
|
@@ -6420,7 +6434,7 @@ ScreenOrientationAPIEnabled:
|
|
WebKitLegacy:
|
|
default: false
|
|
WebKit:
|
|
- default: WebKit::defaultShouldEnableScreenOrientationAPI()
|
|
+ default: true
|
|
WebCore:
|
|
default: false
|
|
sharedPreferenceForWebProcess: true
|
|
@@ -7879,6 +7893,7 @@ UseCGDisplayListsForDOMRendering:
|
|
default: true
|
|
sharedPreferenceForWebProcess: true
|
|
|
|
+# Playwright: force-disable on Windows.
|
|
UseGPUProcessForCanvasRenderingEnabled:
|
|
type: bool
|
|
status: stable
|
|
@@ -7891,7 +7906,7 @@ UseGPUProcessForCanvasRenderingEnabled:
|
|
defaultValue:
|
|
WebKit:
|
|
"ENABLE(GPU_PROCESS_BY_DEFAULT)": true
|
|
- "USE(GRAPHICS_LAYER_WC)": true
|
|
+ "USE(GRAPHICS_LAYER_WC)": false
|
|
default: false
|
|
|
|
UseGPUProcessForDOMRenderingEnabled:
|
|
@@ -7936,6 +7951,7 @@ UseGPUProcessForMediaEnabled:
|
|
sharedPreferenceForWebProcess: true
|
|
mediaPlaybackRelated: true
|
|
|
|
+# Playwright: force-disable on Windows.
|
|
UseGPUProcessForWebGLEnabled:
|
|
type: bool
|
|
status: internal
|
|
@@ -7947,7 +7963,7 @@ UseGPUProcessForWebGLEnabled:
|
|
default: false
|
|
WebKit:
|
|
"ENABLE(GPU_PROCESS_BY_DEFAULT) && ENABLE(GPU_PROCESS_WEBGL_BY_DEFAULT)": true
|
|
- "USE(GRAPHICS_LAYER_WC)": true
|
|
+ "USE(GRAPHICS_LAYER_WC)": false
|
|
default: false
|
|
WebCore:
|
|
"ENABLE(GPU_PROCESS_BY_DEFAULT) && ENABLE(GPU_PROCESS_WEBGL_BY_DEFAULT)": true
|
|
diff --git a/Source/WTF/wtf/PlatformEnable.h b/Source/WTF/wtf/PlatformEnable.h
|
|
index d86540738b2e5e66811b67dd07889c6188126dd7..128f697e7a46b2c6af7716933ee8845228eaba0e 100644
|
|
--- a/Source/WTF/wtf/PlatformEnable.h
|
|
+++ b/Source/WTF/wtf/PlatformEnable.h
|
|
@@ -385,7 +385,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 !defined(ENABLE_OVERFLOW_SCROLLING_TOUCH)
|
|
@@ -502,7 +502,7 @@
|
|
#endif
|
|
|
|
#if !defined(ENABLE_TOUCH_EVENTS)
|
|
-#define ENABLE_TOUCH_EVENTS 0
|
|
+#define ENABLE_TOUCH_EVENTS 1
|
|
#endif
|
|
|
|
#if !defined(ENABLE_TOUCH_ACTION_REGIONS)
|
|
diff --git a/Source/WTF/wtf/PlatformEnableCocoa.h b/Source/WTF/wtf/PlatformEnableCocoa.h
|
|
index bacd225fea9dc695e021649fc6d74012e300be27..9e5497d6f0ecca35bbb5fc2a53f36ee8a3b39435 100644
|
|
--- a/Source/WTF/wtf/PlatformEnableCocoa.h
|
|
+++ b/Source/WTF/wtf/PlatformEnableCocoa.h
|
|
@@ -813,7 +813,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/PlatformHave.h b/Source/WTF/wtf/PlatformHave.h
|
|
index 93e12dd54312a4c8479687b9f175c948250339f8..b39779453f1d51c302e5c5a39d58594a63eb22a2 100644
|
|
--- a/Source/WTF/wtf/PlatformHave.h
|
|
+++ b/Source/WTF/wtf/PlatformHave.h
|
|
@@ -1220,7 +1220,8 @@
|
|
#endif
|
|
|
|
#if PLATFORM(MAC)
|
|
-#define HAVE_GPU_AVAILABILITY_CHECK 1
|
|
+// Playwright: disable the check to make WebGL always work.
|
|
+#define HAVE_GPU_AVAILABILITY_CHECK 0
|
|
#endif
|
|
|
|
#if !defined(HAVE_LOCKDOWN_MODE_PDF_ADDITIONS) && \
|
|
diff --git a/Source/WTF/wtf/unicode/UTF8Conversion.h b/Source/WTF/wtf/unicode/UTF8Conversion.h
|
|
index 007b8fe3292f326504013be8198ae020f7aacf35..1c722c473732ffe05fdb61010fa4417e3e399d1f 100644
|
|
--- a/Source/WTF/wtf/unicode/UTF8Conversion.h
|
|
+++ b/Source/WTF/wtf/unicode/UTF8Conversion.h
|
|
@@ -27,6 +27,11 @@
|
|
|
|
#include <wtf/text/LChar.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 6b62ff89947f5a393ee50381af9f6ddfecc91037..202376ddb4a475a23e0379e26f866451c6e184ba 100644
|
|
--- a/Source/WebCore/DerivedSources.make
|
|
+++ b/Source/WebCore/DerivedSources.make
|
|
@@ -1221,6 +1221,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 \
|
|
@@ -1821,9 +1825,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 d66eb4a0c175ab495ef10bd393115165b5545fc2..cd89bd44bd2a8b3036c3446c01475bf726a3a18a 100644
|
|
--- a/Source/WebCore/Modules/geolocation/Geolocation.cpp
|
|
+++ b/Source/WebCore/Modules/geolocation/Geolocation.cpp
|
|
@@ -361,8 +361,9 @@ bool Geolocation::shouldBlockGeolocationRequests()
|
|
bool isSecure = SecurityOrigin::isSecure(document->url()) || document->isSecureContext();
|
|
bool hasMixedContent = !document->foundMixedContent().isEmpty();
|
|
bool isLocalOrigin = securityOrigin()->isLocal();
|
|
+ bool isPotentiallyTrustworthy = securityOrigin()->isPotentiallyTrustworthy();
|
|
if (document->canAccessResource(ScriptExecutionContext::ResourceType::Geolocation) != ScriptExecutionContext::HasResourceAccess::No) {
|
|
- if (isLocalOrigin || (isSecure && !hasMixedContent))
|
|
+ if (isLocalOrigin || (isSecure && !hasMixedContent) || isPotentiallyTrustworthy)
|
|
return false;
|
|
}
|
|
|
|
diff --git a/Source/WebCore/Modules/speech/cocoa/WebSpeechRecognizerTask.mm b/Source/WebCore/Modules/speech/cocoa/WebSpeechRecognizerTask.mm
|
|
index b2b0391c120d527a9ab4bc6daf8bff7ea5d03cf7..d490a95f89f21536fce4f403b86399160abefc23 100644
|
|
--- a/Source/WebCore/Modules/speech/cocoa/WebSpeechRecognizerTask.mm
|
|
+++ b/Source/WebCore/Modules/speech/cocoa/WebSpeechRecognizerTask.mm
|
|
@@ -195,6 +195,7 @@ - (void)sendEndIfNeeded
|
|
|
|
- (void)speechRecognizer:(SFSpeechRecognizer *)speechRecognizer availabilityDidChange:(BOOL)available
|
|
{
|
|
+ UNUSED_PARAM(speechRecognizer);
|
|
ASSERT(isMainThread());
|
|
|
|
if (available || !_task)
|
|
@@ -208,6 +209,7 @@ - (void)speechRecognizer:(SFSpeechRecognizer *)speechRecognizer availabilityDidC
|
|
|
|
- (void)speechRecognitionTask:(SFSpeechRecognitionTask *)task didHypothesizeTranscription:(SFTranscription *)transcription
|
|
{
|
|
+ UNUSED_PARAM(task);
|
|
ASSERT(isMainThread());
|
|
|
|
[self sendSpeechStartIfNeeded];
|
|
@@ -216,6 +218,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))
|
|
@@ -229,6 +232,7 @@ - (void)speechRecognitionTask:(SFSpeechRecognitionTask *)task didFinishRecogniti
|
|
|
|
- (void)speechRecognitionTaskWasCancelled:(SFSpeechRecognitionTask *)task
|
|
{
|
|
+ UNUSED_PARAM(task);
|
|
ASSERT(isMainThread());
|
|
|
|
[self sendSpeechEndIfNeeded];
|
|
diff --git a/Source/WebCore/PlatformWPE.cmake b/Source/WebCore/PlatformWPE.cmake
|
|
index 7bbcd501126a7b83986f5d1f5a077779441dc1fe..13e68ac853603d8e7da1b42f5c8073ebdab83264 100644
|
|
--- a/Source/WebCore/PlatformWPE.cmake
|
|
+++ b/Source/WebCore/PlatformWPE.cmake
|
|
@@ -60,6 +60,8 @@ list(APPEND WebCore_PRIVATE_FRAMEWORK_HEADERS
|
|
platform/graphics/gbm/PlatformDisplayGBM.h
|
|
|
|
platform/graphics/libwpe/PlatformDisplayLibWPE.h
|
|
+
|
|
+ platform/wpe/SelectionData.h
|
|
)
|
|
|
|
set(WebCore_USER_AGENT_SCRIPTS_DEPENDENCIES ${WEBCORE_DIR}/platform/wpe/RenderThemeWPE.cpp)
|
|
diff --git a/Source/WebCore/SourcesCocoa.txt b/Source/WebCore/SourcesCocoa.txt
|
|
index 7cd931c48dd3c7c4cc6136c91692054ca98e6ddf..e32cfb28521033f1713bd963ba9825a9500f4fc9 100644
|
|
--- a/Source/WebCore/SourcesCocoa.txt
|
|
+++ b/Source/WebCore/SourcesCocoa.txt
|
|
@@ -733,3 +733,9 @@ testing/cocoa/WebViewVisualIdentificationOverlay.mm
|
|
platform/graphics/angle/GraphicsContextGLANGLE.cpp @no-unify
|
|
platform/graphics/cocoa/GraphicsContextGLCocoa.mm @no-unify
|
|
platform/graphics/cv/GraphicsContextGLCVCocoa.mm @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 9cc9f51e48b3058ea29da389629c021bcf05e202..978ac405073534ba6fa79f483d885643a4722fd8 100644
|
|
--- a/Source/WebCore/SourcesGTK.txt
|
|
+++ b/Source/WebCore/SourcesGTK.txt
|
|
@@ -112,3 +112,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 f785335022a20f31c8941c0aabd8895a17f71a3e..a3516d2db0cef38b3257b4b8653711f90f24c257 100644
|
|
--- a/Source/WebCore/SourcesWPE.txt
|
|
+++ b/Source/WebCore/SourcesWPE.txt
|
|
@@ -46,6 +46,8 @@ editing/libwpe/EditorLibWPE.cpp
|
|
|
|
loader/soup/ResourceLoaderSoup.cpp
|
|
|
|
+page/wpe/DragControllerWPE.cpp
|
|
+
|
|
page/linux/ResourceUsageOverlayLinux.cpp
|
|
page/linux/ResourceUsageThreadLinux.cpp
|
|
|
|
@@ -89,6 +91,17 @@ platform/text/LocaleICU.cpp
|
|
platform/unix/LoggingUnix.cpp
|
|
platform/unix/SharedMemoryUnix.cpp
|
|
|
|
+platform/wpe/DragDataWPE.cpp
|
|
+platform/wpe/DragImageWPE.cpp
|
|
platform/wpe/PlatformScreenWPE.cpp
|
|
|
|
platform/xdg/MIMETypeRegistryXdg.cpp
|
|
+
|
|
+// Playwright: begin.
|
|
+platform/wpe/SelectionData.cpp
|
|
+
|
|
+JSSpeechSynthesisErrorCode.cpp
|
|
+JSSpeechSynthesisErrorEvent.cpp
|
|
+JSSpeechSynthesisErrorEventInit.cpp
|
|
+JSSpeechSynthesisEventInit.cpp
|
|
+// Playwright: end.
|
|
diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj
|
|
index d58402bdd7423c3274088b4e35a22922a107062a..4dc6b7adcaf5a34ffbe0b4aad5552a17daa926e7 100644
|
|
--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj
|
|
+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj
|
|
@@ -6404,6 +6404,13 @@
|
|
EE0C7E042CE845CB0043DAF8 /* CSSPositionTryRule.h in Headers */ = {isa = PBXBuildFile; fileRef = EE0C7E002CE845CB0043DAF8 /* CSSPositionTryRule.h */; };
|
|
EE0D3C492D2F4B4C00072978 /* StageModeOperations.h in Headers */ = {isa = PBXBuildFile; fileRef = EE0D3C482D2F4AE600072978 /* StageModeOperations.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 */; };
|
|
F32BDCD92363AACA0073B6AE /* UserGestureEmulationScope.h in Headers */ = {isa = PBXBuildFile; fileRef = F32BDCD72363AACA0073B6AE /* UserGestureEmulationScope.h */; };
|
|
F344C7141125B82C00F26EEE /* InspectorFrontendClient.h in Headers */ = {isa = PBXBuildFile; fileRef = F344C7121125B82C00F26EEE /* InspectorFrontendClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
|
|
@@ -21038,6 +21045,14 @@
|
|
EE7A169F2C607BFA0057B563 /* StartViewTransitionOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = StartViewTransitionOptions.h; sourceTree = "<group>"; };
|
|
EFB7287B2124C73D005C2558 /* CanvasActivityRecord.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CanvasActivityRecord.cpp; sourceTree = "<group>"; };
|
|
EFCC6C8D20FE914000A2321B /* CanvasActivityRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CanvasActivityRecord.h; 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>"; };
|
|
F32BDCD52363AAC90073B6AE /* UserGestureEmulationScope.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UserGestureEmulationScope.cpp; sourceTree = "<group>"; };
|
|
@@ -28800,6 +28815,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 */,
|
|
F4E1965F21F26E4E00285078 /* UndoItem.cpp */,
|
|
2ECDBAD521D8906300F00ECD /* UndoItem.h */,
|
|
@@ -35771,6 +35791,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 */,
|
|
@@ -38569,6 +38591,7 @@
|
|
AD6E71AB1668899D00320C13 /* DocumentSharedObjectPool.h */,
|
|
6BDB5DC1227BD3B800919770 /* DocumentStorageAccess.cpp */,
|
|
6BDB5DC0227BD3B800919770 /* DocumentStorageAccess.h */,
|
|
+ F050E17323AD6A800011CE47 /* DocumentTouch.cpp */,
|
|
7CE7FA5B1EF882300060C9D6 /* DocumentTouch.cpp */,
|
|
7CE7FA591EF882300060C9D6 /* DocumentTouch.h */,
|
|
A8185F3209765765005826D9 /* DocumentType.cpp */,
|
|
@@ -43482,6 +43505,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 */,
|
|
@@ -44827,6 +44852,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 */,
|
|
BE88E0C21715CE2600658D98 /* TrackListBase.h in Headers */,
|
|
@@ -46007,6 +46033,8 @@
|
|
2D22830323A8470700364B7E /* CursorMac.mm in Sources */,
|
|
5CBD59592280E926002B22AA /* CustomHeaderFields.cpp in Sources */,
|
|
07E4BDBF2A3A5FAB000D5509 /* DictationCaretAnimator.cpp in Sources */,
|
|
+ F050E17423AD6A800011CE47 /* DocumentTouch.cpp in Sources */,
|
|
+ 329C0C2528BD96EB00F187D2 /* ElementName.cpp in Sources */,
|
|
7CE6CBFD187F394900D46BF5 /* FormatConverter.cpp in Sources */,
|
|
4667EA3E2968D9DA00BAB1E2 /* GameControllerHapticEffect.mm in Sources */,
|
|
46FE73D32968E52000B8064C /* GameControllerHapticEngines.mm in Sources */,
|
|
@@ -46098,6 +46126,9 @@
|
|
CE88EE262414467B007F29C2 /* TextAlternativeWithRange.mm 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 */,
|
|
538EC8031F96AF81004D22A8 /* UnifiedSource1-mm.mm in Sources */,
|
|
538EC8021F96AF81004D22A8 /* UnifiedSource1.cpp in Sources */,
|
|
538EC8051F96AF81004D22A8 /* UnifiedSource2-mm.mm in Sources */,
|
|
diff --git a/Source/WebCore/accessibility/AccessibilityObject.cpp b/Source/WebCore/accessibility/AccessibilityObject.cpp
|
|
index c6efab7897b328d46bfbca84f84fca8ad39bff48..bc5826d14817244396ddae91e57dde1312a4407e 100644
|
|
--- a/Source/WebCore/accessibility/AccessibilityObject.cpp
|
|
+++ b/Source/WebCore/accessibility/AccessibilityObject.cpp
|
|
@@ -70,6 +70,7 @@
|
|
#include "HTMLTableSectionElement.h"
|
|
#include "HTMLTextAreaElement.h"
|
|
#include "HitTestResult.h"
|
|
+#include "InspectorInstrumentation.h"
|
|
#include "LocalFrame.h"
|
|
#include "LocalizedStrings.h"
|
|
#include "MathMLNames.h"
|
|
@@ -3987,7 +3988,12 @@ AccessibilityObjectInclusion AccessibilityObject::defaultObjectInclusion() const
|
|
if (roleValue() == AccessibilityRole::ApplicationDialog)
|
|
return AccessibilityObjectInclusion::IncludeObject;
|
|
|
|
- return accessibilityPlatformIncludesObject();
|
|
+ AccessibilityObjectInclusion platformBehavior = accessibilityPlatformIncludesObject();
|
|
+ if (platformBehavior != AccessibilityObjectInclusion::DefaultBehavior) {
|
|
+ if (auto* page = this->page())
|
|
+ InspectorInstrumentation::maybeOverrideDefaultObjectInclusion(*page, platformBehavior);
|
|
+ }
|
|
+ return platformBehavior;
|
|
}
|
|
|
|
bool AccessibilityObject::isWithinHiddenWebArea() const
|
|
diff --git a/Source/WebCore/bindings/js/WebCoreBuiltinNames.h b/Source/WebCore/bindings/js/WebCoreBuiltinNames.h
|
|
index 0a0523ff37b7a51dc2152f074fb57b17883bd80f..715881ff75557f4e9165b521061e4b7a35286eba 100644
|
|
--- a/Source/WebCore/bindings/js/WebCoreBuiltinNames.h
|
|
+++ b/Source/WebCore/bindings/js/WebCoreBuiltinNames.h
|
|
@@ -187,6 +187,8 @@ namespace WebCore {
|
|
macro(DelayNode) \
|
|
macro(DeprecationReportBody) \
|
|
macro(DigitalCredential) \
|
|
+ macro(DeviceMotionEvent) \
|
|
+ macro(DeviceOrientationEvent) \
|
|
macro(DocumentTimeline) \
|
|
macro(DynamicsCompressorNode) \
|
|
macro(ElementInternals) \
|
|
diff --git a/Source/WebCore/css/query/MediaQueryFeatures.cpp b/Source/WebCore/css/query/MediaQueryFeatures.cpp
|
|
index 83e2a42d3f09289d61217f63a121611a92aae85d..f4dfda8e9dc1dd9ad221272f09e1bd7f49afa1e0 100644
|
|
--- a/Source/WebCore/css/query/MediaQueryFeatures.cpp
|
|
+++ b/Source/WebCore/css/query/MediaQueryFeatures.cpp
|
|
@@ -496,7 +496,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 };
|
|
}
|
|
};
|
|
@@ -682,6 +686,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 c6f2dca0d4aede2bea015d1cca45dff434425938..e6f41af39befe69f47d0e0953f7d689c338ca184 100644
|
|
--- a/Source/WebCore/dom/DataTransfer.cpp
|
|
+++ b/Source/WebCore/dom/DataTransfer.cpp
|
|
@@ -523,6 +523,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 34ef2f454a732d39acae04987584cab5638b8c60..5e7b788612718dffe3423c89d96141b5b53621fb 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 d59cba0b1c3e1876614476cd887fa1b2a9619d0c..565987a3f9ef7dc29edf8315cebe51b00953dc84 100644
|
|
--- a/Source/WebCore/dom/DeviceMotionEvent.idl
|
|
+++ b/Source/WebCore/dom/DeviceMotionEvent.idl
|
|
@@ -25,6 +25,7 @@
|
|
|
|
[
|
|
Conditional=DEVICE_ORIENTATION,
|
|
+ EnabledBySetting=DeviceOrientationEventEnabled,
|
|
Exposed=Window
|
|
] interface DeviceMotionEvent : Event {
|
|
readonly attribute Acceleration? acceleration;
|
|
diff --git a/Source/WebCore/dom/DeviceOrientationEvent.idl b/Source/WebCore/dom/DeviceOrientationEvent.idl
|
|
index 9043052540b13d8120fb641de6337af46c3b36ef..a0f89e64b64640d2d4dbc14734868c4d4b03fc6f 100644
|
|
--- a/Source/WebCore/dom/DeviceOrientationEvent.idl
|
|
+++ b/Source/WebCore/dom/DeviceOrientationEvent.idl
|
|
@@ -25,6 +25,7 @@
|
|
|
|
[
|
|
Conditional=DEVICE_ORIENTATION,
|
|
+ EnabledBySetting=DeviceOrientationEventEnabled,
|
|
Exposed=Window
|
|
] interface DeviceOrientationEvent : Event {
|
|
readonly attribute unrestricted double? alpha;
|
|
diff --git a/Source/WebCore/dom/Document+PointerLock.idl b/Source/WebCore/dom/Document+PointerLock.idl
|
|
index 2e9c9fda6a920cd8904432bd1bdbfbf32d01c085..2fd33597e905b0544665ff765f310945305a0c4a 100644
|
|
--- a/Source/WebCore/dom/Document+PointerLock.idl
|
|
+++ b/Source/WebCore/dom/Document+PointerLock.idl
|
|
@@ -25,6 +25,7 @@
|
|
|
|
// https://w3c.github.io/pointerlock/#extensions-to-the-document-interface
|
|
[
|
|
+ EnabledBySetting=PointerLockEnabled,
|
|
Conditional=POINTER_LOCK
|
|
] partial interface Document {
|
|
attribute EventHandler onpointerlockchange;
|
|
diff --git a/Source/WebCore/dom/DocumentOrShadowRoot+PointerLock.idl b/Source/WebCore/dom/DocumentOrShadowRoot+PointerLock.idl
|
|
index 9b8dbfc15ce078702321abcd6c0e636df7a60510..2956f7098e87af10ab8f5584b456ce9a6d432a20 100644
|
|
--- a/Source/WebCore/dom/DocumentOrShadowRoot+PointerLock.idl
|
|
+++ b/Source/WebCore/dom/DocumentOrShadowRoot+PointerLock.idl
|
|
@@ -25,6 +25,7 @@
|
|
|
|
// https://w3c.github.io/pointerlock/#extensions-to-the-documentorshadowroot-mixin
|
|
[
|
|
+ EnabledBySetting=PointerLockEnabled,
|
|
Conditional=POINTER_LOCK
|
|
] partial interface mixin DocumentOrShadowRoot {
|
|
readonly attribute Element? pointerLockElement;
|
|
diff --git a/Source/WebCore/dom/Element+PointerLock.idl b/Source/WebCore/dom/Element+PointerLock.idl
|
|
index 9b344003de17b96d8b9ca8c7f32143a27543b1ea..2208a3f2b7d930bcd291e65b474d4c3023d2a7e4 100644
|
|
--- a/Source/WebCore/dom/Element+PointerLock.idl
|
|
+++ b/Source/WebCore/dom/Element+PointerLock.idl
|
|
@@ -24,6 +24,7 @@
|
|
*/
|
|
|
|
[
|
|
+ EnabledBySetting=PointerLockEnabled,
|
|
Conditional=POINTER_LOCK
|
|
] partial interface Element {
|
|
// Returns Promise<undefined> if PointerLockOptionsEnabled Runtime Flag is set, otherwise returns undefined.
|
|
diff --git a/Source/WebCore/dom/PointerEvent.cpp b/Source/WebCore/dom/PointerEvent.cpp
|
|
index e0a0916f197cd80b728b89f95fb240374acdb78a..54eb987c3b53784263de9bdc2ee05c6ca8d68f53 100644
|
|
--- a/Source/WebCore/dom/PointerEvent.cpp
|
|
+++ b/Source/WebCore/dom/PointerEvent.cpp
|
|
@@ -28,9 +28,12 @@
|
|
|
|
#include "EventNames.h"
|
|
#include "MouseEventTypes.h"
|
|
+#include "MouseEvent.h"
|
|
#include "Node.h"
|
|
+#include "PlatformTouchEvent.h"
|
|
#include "PointerEventTypeNames.h"
|
|
#include <wtf/TZoneMallocInlines.h>
|
|
+#include <wtf/IsoMallocInlines.h>
|
|
|
|
namespace WebCore {
|
|
|
|
@@ -292,4 +295,59 @@ void PointerEvent::receivedTarget()
|
|
predictedEvent->setTarget(this->target());
|
|
}
|
|
|
|
+#if ENABLE(TOUCH_EVENTS) && !PLATFORM(IOS_FAMILY) && !PLATFORM(WPE)
|
|
+
|
|
+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 IntPoint& touchDelta)
|
|
+{
|
|
+ const auto& type = pointerEventType(event.touchPoints().at(touchIndex).state());
|
|
+ return adoptRef(*new PointerEvent(type, event, coalescedEvents, predictedEvents, typeCanBubble(type), typeIsCancelable(type), touchIndex, isPrimary, WTFMove(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 IntPoint& touchDelta)
|
|
+{
|
|
+ const auto& type = pointerEventType(event.touchPoints().at(touchIndex).state());
|
|
+ return adoptRef(*new PointerEvent(type, event, coalescedEvents, predictedEvents, canBubble, isCancelable, touchIndex, isPrimary, WTFMove(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 IntPoint& touchDelta)
|
|
+{
|
|
+ return adoptRef(*new PointerEvent(type, event, coalescedEvents, predictedEvents, typeCanBubble(type), typeIsCancelable(type), touchIndex, isPrimary, WTFMove(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 IntPoint& touchDelta)
|
|
+ : MouseEvent(EventInterfaceType::PointerEvent, type, canBubble, isCancelable, typeIsComposed(type), event.timestamp().approximateMonotonicTime(), WTFMove(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, { }, { }, IsSimulated::No, IsTrusted::Yes)
|
|
+ , m_pointerId(event.touchPoints().at(touchIndex).id())
|
|
+ , m_width(2 * event.touchPoints().at(touchIndex).radiusX())
|
|
+ , m_height(2 * event.touchPoints().at(touchIndex).radiusY())
|
|
+ , 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)
|
|
+
|
|
} // namespace WebCore
|
|
diff --git a/Source/WebCore/dom/PointerEvent.h b/Source/WebCore/dom/PointerEvent.h
|
|
index b034595d01bb63f3d72183c427fcc14695339ae2..1886e4bbba04c6177fad1562c891f2aeff0a8247 100644
|
|
--- a/Source/WebCore/dom/PointerEvent.h
|
|
+++ b/Source/WebCore/dom/PointerEvent.h
|
|
@@ -34,6 +34,8 @@
|
|
|
|
#if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS_FAMILY)
|
|
#include "PlatformTouchEventIOS.h"
|
|
+#else
|
|
+#include "PlatformTouchEvent.h"
|
|
#endif
|
|
|
|
#if ENABLE(TOUCH_EVENTS) && PLATFORM(WPE)
|
|
@@ -94,7 +96,7 @@ 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))
|
|
+#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 IntPoint& 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 IntPoint& 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 IntPoint& touchDelta = { });
|
|
@@ -173,7 +175,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))
|
|
+#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 IntPoint& touchDelta = { });
|
|
#endif
|
|
|
|
diff --git a/Source/WebCore/editing/libwpe/EditorLibWPE.cpp b/Source/WebCore/editing/libwpe/EditorLibWPE.cpp
|
|
index 7813532cc52d582c42aebc979a1ecd1137765f08..c01cbd53ad2430a6ffab9a80fc73e74a8523800a 100644
|
|
--- a/Source/WebCore/editing/libwpe/EditorLibWPE.cpp
|
|
+++ b/Source/WebCore/editing/libwpe/EditorLibWPE.cpp
|
|
@@ -34,6 +34,7 @@
|
|
#include "NotImplemented.h"
|
|
#include "Pasteboard.h"
|
|
#include "Settings.h"
|
|
+#include "WebContentReader.h"
|
|
#include "markup.h"
|
|
|
|
namespace WebCore {
|
|
@@ -99,6 +100,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 28d2a4af93da12474d1b699f6f0c46522514e3bb..0f20c78e509cce10e4179a1be91173b3de16db10 100644
|
|
--- a/Source/WebCore/html/FileInputType.cpp
|
|
+++ b/Source/WebCore/html/FileInputType.cpp
|
|
@@ -37,6 +37,7 @@
|
|
#include "HTMLNames.h"
|
|
#include "Icon.h"
|
|
#include "InputTypeNames.h"
|
|
+#include "InspectorInstrumentation.h"
|
|
#include "LocalFrame.h"
|
|
#include "LocalizedStrings.h"
|
|
#include "MIMETypeRegistry.h"
|
|
@@ -160,6 +161,11 @@ void FileInputType::handleDOMActivateEvent(Event& event)
|
|
if (input.isDisabledFormControl())
|
|
return;
|
|
|
|
+ bool intercept = false;
|
|
+ InspectorInstrumentation::runOpenPanel(input.document().frame(), element(), &intercept);
|
|
+ if (intercept)
|
|
+ return;
|
|
+
|
|
if (!UserGestureIndicator::processingUserGesture())
|
|
return;
|
|
|
|
@@ -345,7 +351,9 @@ void FileInputType::setFiles(RefPtr<FileList>&& files, RequestIcon shouldRequest
|
|
pathsChanged = true;
|
|
else {
|
|
for (unsigned i = 0; i < length; ++i) {
|
|
- if (files->file(i).path() != m_fileList->file(i).path() || !FileSystem::fileIDsAreEqual(files->file(i).fileID(), m_fileList->file(i).fileID())) {
|
|
+ if (files->file(i).path() != m_fileList->file(i).path() || !FileSystem::fileIDsAreEqual(files->file(i).fileID(), m_fileList->file(i).fileID()) ||
|
|
+ // Files created from Blob have empty path.
|
|
+ (files->file(i).path().isEmpty() && files->file(i).name() != m_fileList->file(i).name())) {
|
|
pathsChanged = true;
|
|
break;
|
|
}
|
|
diff --git a/Source/WebCore/inspector/InspectorController.cpp b/Source/WebCore/inspector/InspectorController.cpp
|
|
index 79d7f4b39f4bc4ec2535bb355e567e39bc1f9ffa..6d1c4513780476767b4c51c8dcd3afd30088176d 100644
|
|
--- a/Source/WebCore/inspector/InspectorController.cpp
|
|
+++ b/Source/WebCore/inspector/InspectorController.cpp
|
|
@@ -295,6 +295,8 @@ void InspectorController::disconnectFrontend(FrontendChannel& frontendChannel)
|
|
|
|
// Unplug all instrumentations since they aren't needed now.
|
|
InspectorInstrumentation::unregisterInstrumentingAgents(m_instrumentingAgents.get());
|
|
+
|
|
+ m_pauseOnStart = PauseCondition::DONT_PAUSE;
|
|
}
|
|
|
|
m_inspectorClient->frontendCountChanged(m_frontendRouter->frontendCount());
|
|
@@ -314,6 +316,8 @@ void InspectorController::disconnectAllFrontends()
|
|
// The frontend should call setInspectorFrontendClient(nullptr) under closeWindow().
|
|
ASSERT(!m_inspectorFrontendClient);
|
|
|
|
+ m_pauseOnStart = PauseCondition::DONT_PAUSE;
|
|
+
|
|
if (!m_frontendRouter->hasFrontends())
|
|
return;
|
|
|
|
@@ -397,8 +401,8 @@ void InspectorController::inspect(Node* node)
|
|
if (!enabled())
|
|
return;
|
|
|
|
- if (!hasRemoteFrontend())
|
|
- show();
|
|
+ // HACK: Always attempt to show inspector even if there is a remote connection.
|
|
+ show();
|
|
|
|
ensureDOMAgent().inspect(node);
|
|
}
|
|
@@ -541,4 +545,34 @@ void InspectorController::didComposite(LocalFrame& frame)
|
|
InspectorInstrumentation::didComposite(frame);
|
|
}
|
|
|
|
+void InspectorController::pauseOnStart(PauseCondition condition)
|
|
+{
|
|
+ m_pauseOnStart = condition;
|
|
+}
|
|
+
|
|
+void InspectorController::resumeIfPausedInNewWindow()
|
|
+{
|
|
+ m_pauseOnStart = PauseCondition::DONT_PAUSE;
|
|
+}
|
|
+
|
|
+void InspectorController::didFinishPageCreation()
|
|
+{
|
|
+ if (m_pauseOnStart == PauseCondition::WHEN_CREATION_FINISHED)
|
|
+ runLoopWhilePaused();
|
|
+}
|
|
+
|
|
+void InspectorController::didShowPage()
|
|
+{
|
|
+ if (m_pauseOnStart == PauseCondition::WHEN_SHOWN)
|
|
+ runLoopWhilePaused();
|
|
+}
|
|
+
|
|
+void InspectorController::runLoopWhilePaused()
|
|
+{
|
|
+ while (m_pauseOnStart != PauseCondition::DONT_PAUSE) {
|
|
+ if (RunLoop::cycle() == RunLoop::CycleResult::Stop)
|
|
+ break;
|
|
+ }
|
|
+}
|
|
+
|
|
} // namespace WebCore
|
|
diff --git a/Source/WebCore/inspector/InspectorController.h b/Source/WebCore/inspector/InspectorController.h
|
|
index 4f5c1e836876710a554455ec53733f72db63de58..774c4a66af84664a7a83ba0790d147f7bbb4236a 100644
|
|
--- a/Source/WebCore/inspector/InspectorController.h
|
|
+++ b/Source/WebCore/inspector/InspectorController.h
|
|
@@ -106,6 +106,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; }
|
|
@@ -136,6 +142,7 @@ private:
|
|
|
|
PageAgentContext pageAgentContext();
|
|
void createLazyAgents();
|
|
+ void runLoopWhilePaused();
|
|
|
|
WeakRef<Page> m_page;
|
|
Ref<InstrumentingAgents> m_instrumentingAgents;
|
|
@@ -159,6 +166,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/InspectorInstrumentation.cpp b/Source/WebCore/inspector/InspectorInstrumentation.cpp
|
|
index 7e789f4b0704d574b3bf180b2417822d9ee33994..80e6b4bc7810af19265d24e0de861c8ea2728999 100644
|
|
--- a/Source/WebCore/inspector/InspectorInstrumentation.cpp
|
|
+++ b/Source/WebCore/inspector/InspectorInstrumentation.cpp
|
|
@@ -583,6 +583,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 (auto* pageAgent = instrumentingAgents.enabledPageAgent())
|
|
@@ -666,6 +672,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())
|
|
@@ -698,20 +710,17 @@ void InspectorInstrumentation::didReceiveScriptResponseImpl(InstrumentingAgents&
|
|
|
|
void InspectorInstrumentation::domContentLoadedEventFiredImpl(InstrumentingAgents& instrumentingAgents, LocalFrame& frame)
|
|
{
|
|
- if (!frame.isMainFrame())
|
|
- return;
|
|
-
|
|
if (auto* pageAgent = instrumentingAgents.enabledPageAgent())
|
|
- pageAgent->domContentEventFired();
|
|
+ pageAgent->domContentEventFired(frame);
|
|
}
|
|
|
|
void InspectorInstrumentation::loadEventFiredImpl(InstrumentingAgents& instrumentingAgents, LocalFrame* frame)
|
|
{
|
|
- if (!frame || !frame->isMainFrame())
|
|
+ if (!frame)
|
|
return;
|
|
|
|
if (auto* pageAgent = instrumentingAgents.enabledPageAgent())
|
|
- pageAgent->loadEventFired();
|
|
+ pageAgent->loadEventFired(*frame);
|
|
}
|
|
|
|
void InspectorInstrumentation::frameDetachedFromParentImpl(InstrumentingAgents& instrumentingAgents, LocalFrame& frame)
|
|
@@ -791,12 +800,6 @@ void InspectorInstrumentation::frameDocumentUpdatedImpl(InstrumentingAgents& ins
|
|
pageDOMDebuggerAgent->frameDocumentUpdated(frame);
|
|
}
|
|
|
|
-void InspectorInstrumentation::loaderDetachedFromFrameImpl(InstrumentingAgents& instrumentingAgents, DocumentLoader& loader)
|
|
-{
|
|
- if (auto* inspectorPageAgent = instrumentingAgents.enabledPageAgent())
|
|
- inspectorPageAgent->loaderDetachedFromFrame(loader);
|
|
-}
|
|
-
|
|
void InspectorInstrumentation::frameStartedLoadingImpl(InstrumentingAgents& instrumentingAgents, LocalFrame& frame)
|
|
{
|
|
if (frame.isMainFrame()) {
|
|
@@ -827,10 +830,10 @@ void InspectorInstrumentation::frameStoppedLoadingImpl(InstrumentingAgents& inst
|
|
inspectorPageAgent->frameStoppedLoading(frame);
|
|
}
|
|
|
|
-void InspectorInstrumentation::frameScheduledNavigationImpl(InstrumentingAgents& instrumentingAgents, Frame& frame, Seconds delay)
|
|
+void InspectorInstrumentation::frameScheduledNavigationImpl(InstrumentingAgents& instrumentingAgents, Frame& frame, Seconds delay, bool targetIsCurrentFrame)
|
|
{
|
|
if (auto* inspectorPageAgent = instrumentingAgents.enabledPageAgent())
|
|
- inspectorPageAgent->frameScheduledNavigation(frame, delay);
|
|
+ inspectorPageAgent->frameScheduledNavigation(frame, delay, targetIsCurrentFrame);
|
|
}
|
|
|
|
void InspectorInstrumentation::frameClearedScheduledNavigationImpl(InstrumentingAgents& instrumentingAgents, Frame& frame)
|
|
@@ -845,6 +848,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)
|
|
{
|
|
@@ -897,6 +906,12 @@ void InspectorInstrumentation::interceptResponseImpl(InstrumentingAgents& instru
|
|
networkAgent->interceptResponse(response, identifier, WTFMove(handler));
|
|
}
|
|
|
|
+void InspectorInstrumentation::setStoppingLoadingDueToProcessSwapImpl(InstrumentingAgents& instrumentingAgents, bool value)
|
|
+{
|
|
+ if (auto* networkAgent = instrumentingAgents.enabledNetworkAgent())
|
|
+ networkAgent->setStoppingLoadingDueToProcessSwap(value);
|
|
+}
|
|
+
|
|
// JavaScriptCore InspectorDebuggerAgent should know Console MessageTypes.
|
|
static bool isConsoleAssertMessage(MessageSource source, MessageType type)
|
|
{
|
|
@@ -1015,6 +1030,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())
|
|
@@ -1305,6 +1326,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;
|
|
@@ -1321,6 +1372,13 @@ InstrumentingAgents& InspectorInstrumentation::instrumentingAgents(Page& page)
|
|
return page.inspectorController().m_instrumentingAgents.get();
|
|
}
|
|
|
|
+void InspectorInstrumentation::maybeOverrideDefaultObjectInclusion(Page& page, AccessibilityObjectInclusion& inclusion) {
|
|
+ if (InspectorPageAgent* pageAgent = instrumentingAgents(page).enabledPageAgent()) {
|
|
+ if (pageAgent->doingAccessibilitySnapshot())
|
|
+ inclusion = AccessibilityObjectInclusion::DefaultBehavior;
|
|
+ }
|
|
+}
|
|
+
|
|
InstrumentingAgents* InspectorInstrumentation::instrumentingAgents(ScriptExecutionContext& context)
|
|
{
|
|
// Using RefPtr makes us hit the m_inRemovedLastRefFunction assert.
|
|
diff --git a/Source/WebCore/inspector/InspectorInstrumentation.h b/Source/WebCore/inspector/InspectorInstrumentation.h
|
|
index c338ad466f69c4b03121e0b17fbc9a4729654aff..6139fb2b5e0364bce1a5720200943f3005f541c3 100644
|
|
--- a/Source/WebCore/inspector/InspectorInstrumentation.h
|
|
+++ b/Source/WebCore/inspector/InspectorInstrumentation.h
|
|
@@ -31,6 +31,7 @@
|
|
|
|
#pragma once
|
|
|
|
+#include "AXCoreObject.h"
|
|
#include "CSSSelector.h"
|
|
#include "CanvasBase.h"
|
|
#include "CanvasRenderingContext.h"
|
|
@@ -44,6 +45,7 @@
|
|
#include "LocalFrame.h"
|
|
#include "LocalFrameView.h"
|
|
#include "Page.h"
|
|
+#include "ResourceError.h"
|
|
#include "ResourceLoader.h"
|
|
#include "ResourceLoaderIdentifier.h"
|
|
#include "StorageArea.h"
|
|
@@ -77,6 +79,7 @@ class DOMWrapperWorld;
|
|
class Document;
|
|
class DocumentLoader;
|
|
class EventListener;
|
|
+class HTMLInputElement;
|
|
class HTTPHeaderMap;
|
|
class InspectorTimelineAgent;
|
|
class InstrumentingAgents;
|
|
@@ -194,6 +197,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&);
|
|
@@ -206,6 +210,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&);
|
|
@@ -232,13 +237,13 @@ 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(Frame&);
|
|
- static void frameScheduledNavigation(Frame&, Seconds delay);
|
|
+ static void frameScheduledNavigation(Frame&, Seconds delay, bool targetIsCurrentFrame);
|
|
static void frameClearedScheduledNavigation(Frame&);
|
|
static void accessibilitySettingsDidChange(Page&);
|
|
+ static void didNavigateWithinPage(LocalFrame&);
|
|
#if ENABLE(DARK_MODE_CSS)
|
|
static void defaultAppearanceDidChange(Page&);
|
|
#endif
|
|
@@ -249,6 +254,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(Page&, std::unique_ptr<Inspector::ConsoleMessage>);
|
|
static void addMessageToConsole(WorkerOrWorkletGlobalScope&, std::unique_ptr<Inspector::ConsoleMessage>);
|
|
@@ -270,6 +276,7 @@ public:
|
|
static void stopProfiling(Page&, 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>);
|
|
|
|
@@ -323,6 +330,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(); }
|
|
@@ -339,6 +352,8 @@ public:
|
|
static void registerInstrumentingAgents(InstrumentingAgents&);
|
|
static void unregisterInstrumentingAgents(InstrumentingAgents&);
|
|
|
|
+ static void maybeOverrideDefaultObjectInclusion(Page&, AccessibilityObjectInclusion&);
|
|
+
|
|
private:
|
|
static void didClearWindowObjectInWorldImpl(InstrumentingAgents&, LocalFrame&, DOMWrapperWorld&);
|
|
static bool isDebuggerPausedImpl(InstrumentingAgents&);
|
|
@@ -418,6 +433,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&);
|
|
@@ -432,6 +448,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);
|
|
@@ -442,13 +459,13 @@ 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 frameScheduledNavigationImpl(InstrumentingAgents&, Frame&, Seconds delay);
|
|
+ static void frameScheduledNavigationImpl(InstrumentingAgents&, Frame&, Seconds delay, bool targetIsCurrentFrame);
|
|
static void frameClearedScheduledNavigationImpl(InstrumentingAgents&, Frame&);
|
|
static void accessibilitySettingsDidChangeImpl(InstrumentingAgents&);
|
|
+ static void didNavigateWithinPageImpl(InstrumentingAgents&, LocalFrame&);
|
|
#if ENABLE(DARK_MODE_CSS)
|
|
static void defaultAppearanceDidChangeImpl(InstrumentingAgents&);
|
|
#endif
|
|
@@ -459,6 +476,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>);
|
|
|
|
@@ -473,6 +491,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>);
|
|
|
|
@@ -526,6 +545,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& instrumentingAgents(Page&);
|
|
static InstrumentingAgents& instrumentingAgents(WorkerOrWorkletGlobalScope&);
|
|
static InstrumentingAgents& instrumentingAgents(ServiceWorkerGlobalScope&);
|
|
@@ -1071,6 +1096,13 @@ inline void InspectorInstrumentation::applyUserAgentOverride(LocalFrame& frame,
|
|
applyUserAgentOverrideImpl(*agents, userAgent);
|
|
}
|
|
|
|
+inline void InspectorInstrumentation::applyPlatformOverride(LocalFrame& frame, String& platform)
|
|
+{
|
|
+ FAST_RETURN_IF_NO_FRONTENDS(void());
|
|
+ if (auto* agents = instrumentingAgents(frame))
|
|
+ applyPlatformOverrideImpl(*agents, platform);
|
|
+}
|
|
+
|
|
inline void InspectorInstrumentation::applyEmulatedMedia(LocalFrame& frame, AtomString& media)
|
|
{
|
|
FAST_RETURN_IF_NO_FRONTENDS(void());
|
|
@@ -1173,6 +1205,13 @@ 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());
|
|
+ if (auto* agents = instrumentingAgents(frame))
|
|
+ didReceiveMainResourceErrorImpl(*agents, frame, error);
|
|
+}
|
|
+
|
|
inline void InspectorInstrumentation::continueAfterXFrameOptionsDenied(LocalFrame& frame, ResourceLoaderIdentifier identifier, DocumentLoader& loader, const ResourceResponse& response)
|
|
{
|
|
// Treat the same as didReceiveResponse.
|
|
@@ -1263,13 +1302,6 @@ inline void InspectorInstrumentation::frameDocumentUpdated(LocalFrame& frame)
|
|
frameDocumentUpdatedImpl(*agents, frame);
|
|
}
|
|
|
|
-inline void InspectorInstrumentation::loaderDetachedFromFrame(LocalFrame& frame, DocumentLoader& loader)
|
|
-{
|
|
- FAST_RETURN_IF_NO_FRONTENDS(void());
|
|
- if (auto* agents = instrumentingAgents(frame))
|
|
- loaderDetachedFromFrameImpl(*agents, loader);
|
|
-}
|
|
-
|
|
inline void InspectorInstrumentation::frameStartedLoading(LocalFrame& frame)
|
|
{
|
|
FAST_RETURN_IF_NO_FRONTENDS(void());
|
|
@@ -1291,11 +1323,11 @@ inline void InspectorInstrumentation::frameStoppedLoading(LocalFrame& frame)
|
|
frameStoppedLoadingImpl(*agents, frame);
|
|
}
|
|
|
|
-inline void InspectorInstrumentation::frameScheduledNavigation(Frame& frame, Seconds delay)
|
|
+inline void InspectorInstrumentation::frameScheduledNavigation(Frame& frame, Seconds delay, bool targetIsCurrentFrame)
|
|
{
|
|
FAST_RETURN_IF_NO_FRONTENDS(void());
|
|
if (auto* agents = instrumentingAgents(frame))
|
|
- frameScheduledNavigationImpl(*agents, frame, delay);
|
|
+ frameScheduledNavigationImpl(*agents, frame, delay, targetIsCurrentFrame);
|
|
}
|
|
|
|
inline void InspectorInstrumentation::frameClearedScheduledNavigation(Frame& frame)
|
|
@@ -1311,6 +1343,13 @@ inline void InspectorInstrumentation::accessibilitySettingsDidChange(Page& page)
|
|
accessibilitySettingsDidChangeImpl(instrumentingAgents(page));
|
|
}
|
|
|
|
+inline void InspectorInstrumentation::didNavigateWithinPage(LocalFrame& frame)
|
|
+{
|
|
+ FAST_RETURN_IF_NO_FRONTENDS(void());
|
|
+ if (auto* agents = instrumentingAgents(frame))
|
|
+ didNavigateWithinPageImpl(*agents, frame);
|
|
+}
|
|
+
|
|
#if ENABLE(DARK_MODE_CSS)
|
|
inline void InspectorInstrumentation::defaultAppearanceDidChange(Page& page)
|
|
{
|
|
@@ -1363,6 +1402,13 @@ inline void InspectorInstrumentation::interceptResponse(const LocalFrame& frame,
|
|
interceptResponseImpl(*agents, response, identifier, WTFMove(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());
|
|
@@ -1679,6 +1725,11 @@ inline void InspectorInstrumentation::performanceMark(ScriptExecutionContext& co
|
|
performanceMarkImpl(*agents, label, WTFMove(startTime));
|
|
}
|
|
|
|
+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());
|
|
@@ -1735,6 +1786,42 @@ 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());
|
|
+ if (auto* agents = instrumentingAgents(*frame))
|
|
+ runOpenPanelImpl(*agents, 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());
|
|
+ if (auto* agents = instrumentingAgents(frame))
|
|
+ willCheckNavigationPolicyImpl(*agents, frame);
|
|
+}
|
|
+
|
|
+inline void InspectorInstrumentation::didCheckNavigationPolicy(LocalFrame& frame, bool cancel)
|
|
+{
|
|
+ FAST_RETURN_IF_NO_FRONTENDS(void());
|
|
+ if (auto* agents = instrumentingAgents(frame))
|
|
+ didCheckNavigationPolicyImpl(*agents, 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 a67a1244fa526ad5759068e97e0d220f59565d6e..0048589109fccb9472fe35a410337771b1063d72 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, WTFMove(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 c028341e84e59a6b1b16107fd74feb21f70b12ab..d385418ac34e8f315f201801a2c65226c8f6fee2 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, WTFMove(handler));
|
|
}
|
|
|
|
+inline void InspectorInstrumentationWebKit::setStoppingLoadingDueToProcessSwap(Page* page, bool value)
|
|
+{
|
|
+ FAST_RETURN_IF_NO_FRONTENDS(void());
|
|
+ setStoppingLoadingDueToProcessSwapInternal(page, value);
|
|
+}
|
|
+
|
|
}
|
|
diff --git a/Source/WebCore/inspector/agents/InspectorDOMAgent.cpp b/Source/WebCore/inspector/agents/InspectorDOMAgent.cpp
|
|
index a477bad0c14c9304b9c2f03aa4e690e8b27a7756..fcb712a41223ec4698337a8b17999e0ca049ae40 100644
|
|
--- a/Source/WebCore/inspector/agents/InspectorDOMAgent.cpp
|
|
+++ b/Source/WebCore/inspector/agents/InspectorDOMAgent.cpp
|
|
@@ -56,6 +56,7 @@
|
|
#include "Cookie.h"
|
|
#include "CookieJar.h"
|
|
#include "CustomElementRegistry.h"
|
|
+#include "DirectoryFileListCreator.h"
|
|
#include "DOMEditor.h"
|
|
#include "DOMException.h"
|
|
#include "DOMPatchSupport.h"
|
|
@@ -67,9 +68,14 @@
|
|
#include "Event.h"
|
|
#include "EventListener.h"
|
|
#include "EventNames.h"
|
|
+#include "File.h"
|
|
+#include <FileChooser.h>
|
|
+#include "FileList.h"
|
|
+#include "FloatQuad.h"
|
|
#include "FrameTree.h"
|
|
#include "HTMLElement.h"
|
|
#include "HTMLFrameOwnerElement.h"
|
|
+#include "HTMLInputElement.h"
|
|
#include "HTMLMediaElement.h"
|
|
#include "HTMLNames.h"
|
|
#include "HTMLScriptElement.h"
|
|
@@ -103,12 +109,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"
|
|
@@ -150,7 +158,8 @@ using namespace HTMLNames;
|
|
static const size_t maxTextSize = 10000;
|
|
static const UChar horizontalEllipsisUChar[] = { 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;
|
|
@@ -169,7 +178,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)
|
|
@@ -196,6 +205,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);
|
|
@@ -476,6 +499,20 @@ Node* InspectorDOMAgent::assertNode(Inspector::Protocol::ErrorString& errorStrin
|
|
return node.get();
|
|
}
|
|
|
|
+Node* InspectorDOMAgent::assertNode(Protocol::ErrorString& errorString, std::optional<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);
|
|
@@ -1550,16 +1587,7 @@ Inspector::Protocol::ErrorStringOr<void> InspectorDOMAgent::highlightNode(std::o
|
|
Inspector::Protocol::ErrorStringOr<void> InspectorDOMAgent::highlightNode(std::optional<Inspector::Protocol::DOM::NodeId>&& nodeId, const Inspector::Protocol::Runtime::RemoteObjectId& objectId, Ref<JSON::Object>&& highlightInspectorObject, RefPtr<JSON::Object>&& gridOverlayInspectorObject, RefPtr<JSON::Object>&& flexOverlayInspectorObject, std::optional<bool>&& showRulers)
|
|
{
|
|
Inspector::Protocol::ErrorString errorString;
|
|
-
|
|
- Node* node = nullptr;
|
|
- 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;
|
|
-
|
|
+ Node* node = assertNode(errorString, WTFMove(nodeId), objectId);
|
|
if (!node)
|
|
return makeUnexpected(errorString);
|
|
|
|
@@ -1814,15 +1842,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 } };
|
|
+}
|
|
+
|
|
+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 { };
|
|
+}
|
|
+
|
|
+Protocol::ErrorStringOr<Ref<JSON::ArrayOf<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<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;
|
|
+ Node* node = nullptr;
|
|
+ if (!!frameId) {
|
|
+ auto* pageAgent = m_instrumentingAgents.enabledPageAgent();
|
|
+ if (!pageAgent)
|
|
+ return makeUnexpected("Page domain must be enabled"_s);
|
|
|
|
- Node* node = assertNode(errorString, nodeId);
|
|
+ auto* frame = pageAgent->assertFrame(errorString, frameId);
|
|
+ if (!frame)
|
|
+ return makeUnexpected(errorString);
|
|
+
|
|
+ node = frame->ownerElement();
|
|
+ } else {
|
|
+ node = assertNode(errorString, WTFMove(nodeId), objectId);
|
|
+ }
|
|
if (!node)
|
|
return makeUnexpected(errorString);
|
|
|
|
- auto object = resolveNode(node, objectGroup);
|
|
+ auto object = resolveNode(node, objectGroup, WTFMove(contextId));
|
|
if (!object)
|
|
return makeUnexpected("Missing injected script for given nodeId"_s);
|
|
|
|
@@ -3088,7 +3260,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)
|
|
{
|
|
Document* document = &node->document();
|
|
if (auto* templateHost = document->templateDocumentHost())
|
|
@@ -3097,12 +3269,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)
|
|
@@ -3210,4 +3388,89 @@ Inspector::Protocol::ErrorStringOr<Ref<Inspector::Protocol::DOM::MediaStats>> In
|
|
#endif
|
|
}
|
|
|
|
+void InspectorDOMAgent::setInputFiles(const String& objectId, RefPtr<JSON::Array>&& files, RefPtr<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() != Node::ELEMENT_NODE || node->nodeName() != "INPUT"_s) {
|
|
+ callback->sendFailure("Not an input node"_s);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (!(bool(files) ^ bool(paths))) {
|
|
+ callback->sendFailure("Exactly one of files and paths should be specified"_s);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ HTMLInputElement* element = static_cast<HTMLInputElement*>(node);
|
|
+ Vector<Ref<File>> fileObjects;
|
|
+ if (files) {
|
|
+ for (unsigned i = 0; i < files->length(); ++i) {
|
|
+ RefPtr<JSON::Value> item = files->get(i);
|
|
+ RefPtr<JSON::Object> obj = item->asObject();
|
|
+ if (!obj) {
|
|
+ callback->sendFailure("Invalid file payload format"_s);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ String name;
|
|
+ String type;
|
|
+ String data;
|
|
+ if (!obj->getString("name"_s, name) || !obj->getString("type"_s, type) || !obj->getString("data"_s, data)) {
|
|
+ callback->sendFailure("Invalid file payload format"_s);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ std::optional<Vector<uint8_t>> buffer = base64Decode(data);
|
|
+ if (!buffer) {
|
|
+ callback->sendFailure("Unable to decode given content"_s);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ ScriptExecutionContext* context = element->scriptExecutionContext();
|
|
+ fileObjects.append(File::create(context, Blob::create(context, WTFMove(*buffer), type), name));
|
|
+ }
|
|
+ RefPtr<FileList> fileList = FileList::create(WTFMove(fileObjects));
|
|
+ element->setFiles(WTFMove(fileList));
|
|
+ callback->sendSuccess();
|
|
+ } else {
|
|
+ if (element->hasAttributeWithoutSynchronization(webkitdirectoryAttr)) {
|
|
+ auto directoryFileListCreator = DirectoryFileListCreator::create([element = RefPtr { element }, callback = WTFMove(callback)](Ref<FileList>&& fileList) mutable {
|
|
+ ASSERT(isMainThread());
|
|
+ element->setFiles(WTFMove(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(WTFMove(fileObjects));
|
|
+ element->setFiles(WTFMove(fileList));
|
|
+ callback->sendSuccess();
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
} // namespace WebCore
|
|
diff --git a/Source/WebCore/inspector/agents/InspectorDOMAgent.h b/Source/WebCore/inspector/agents/InspectorDOMAgent.h
|
|
index 0d1406e0a1d061e2336bbd49c56328ce93351f14..4187fb453adebfd98f91ebbf99e38a072ef8942b 100644
|
|
--- a/Source/WebCore/inspector/agents/InspectorDOMAgent.h
|
|
+++ b/Source/WebCore/inspector/agents/InspectorDOMAgent.h
|
|
@@ -59,6 +59,7 @@ namespace WebCore {
|
|
|
|
class AXCoreObject;
|
|
class CharacterData;
|
|
+class Color;
|
|
class DOMEditor;
|
|
class Document;
|
|
class Element;
|
|
@@ -94,6 +95,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.
|
|
@@ -137,7 +139,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);
|
|
@@ -174,6 +176,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, RefPtr<JSON::Array>&& files, RefPtr<JSON::Array>&& paths, Ref<SetInputFilesCallback>&& callback);
|
|
|
|
// InspectorInstrumentation
|
|
Inspector::Protocol::DOM::NodeId identifierForNode(Node&);
|
|
@@ -215,7 +221,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*);
|
|
@@ -227,12 +233,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();
|
|
@@ -262,7 +271,6 @@ private:
|
|
void processAccessibilityChildren(AXCoreObject&, JSON::ArrayOf<Inspector::Protocol::DOM::NodeId>&);
|
|
|
|
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 6db0a3c6a46a4be5cb6f9f0e6fcbc61ac552e438..cae87102e8228cb944cec4a6ebe83b7d3a0e29bc 100644
|
|
--- a/Source/WebCore/inspector/agents/InspectorNetworkAgent.cpp
|
|
+++ b/Source/WebCore/inspector/agents/InspectorNetworkAgent.cpp
|
|
@@ -59,6 +59,7 @@
|
|
#include "MIMETypeRegistry.h"
|
|
#include "MemoryCache.h"
|
|
#include "NetworkResourcesData.h"
|
|
+#include "NetworkStateNotifier.h"
|
|
#include "Page.h"
|
|
#include "PlatformStrategies.h"
|
|
#include "ProgressTracker.h"
|
|
@@ -345,8 +346,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) {
|
|
@@ -399,6 +400,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));
|
|
@@ -685,6 +688,9 @@ void InspectorNetworkAgent::didFailLoading(ResourceLoaderIdentifier identifier,
|
|
String requestId = IdentifiersFactory::requestId(identifier.toUInt64());
|
|
|
|
if (loader && m_resourcesData->resourceType(requestId) == InspectorPageAgent::DocumentResource) {
|
|
+ if (m_stoppingLoadingDueToProcessSwap)
|
|
+ return;
|
|
+
|
|
auto* frame = loader->frame();
|
|
if (frame && frame->loader().documentLoader() && frame->document()) {
|
|
m_resourcesData->addResourceSharedBuffer(requestId,
|
|
@@ -914,6 +920,7 @@ Inspector::Protocol::ErrorStringOr<void> InspectorNetworkAgent::disable()
|
|
m_instrumentingAgents.setEnabledNetworkAgent(nullptr);
|
|
m_resourcesData->clear();
|
|
m_extraRequestHeaders.clear();
|
|
+ m_stoppingLoadingDueToProcessSwap = false;
|
|
|
|
continuePendingRequests();
|
|
continuePendingResponses();
|
|
@@ -966,6 +973,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)
|
|
@@ -1215,6 +1223,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) {
|
|
@@ -1244,6 +1257,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));
|
|
@@ -1339,14 +1355,23 @@ 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(WTFMove(explicitHeaders));
|
|
response.setHTTPHeaderField(HTTPHeaderName::ContentType, response.mimeType());
|
|
- loader->didReceiveResponse(response, [loader, buffer = data.releaseNonNull()]() {
|
|
+
|
|
+ auto* frame = loader->frame();
|
|
+ if (!setCookieValue.isEmpty() && frame && frame->page())
|
|
+ frame->page()->cookieJar().setCookieFromResponse(*loader.get(), setCookieValue);
|
|
+
|
|
+ loader->didReceiveResponse(response, [loader, buffer = data.releaseNonNull()]() mutable {
|
|
if (loader->reachedTerminalState())
|
|
return;
|
|
|
|
@@ -1409,6 +1434,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 { };
|
|
+}
|
|
+
|
|
bool InspectorNetworkAgent::shouldTreatAsText(const String& mimeType)
|
|
{
|
|
return startsWithLettersIgnoringASCIICase(mimeType, "text/"_s)
|
|
diff --git a/Source/WebCore/inspector/agents/InspectorNetworkAgent.h b/Source/WebCore/inspector/agents/InspectorNetworkAgent.h
|
|
index eda400879afb10b687fcbb317c9fdbb3be9c94cd..f3a382c44b53e6b1507fc046e22bff684abd55f9 100644
|
|
--- a/Source/WebCore/inspector/agents/InspectorNetworkAgent.h
|
|
+++ b/Source/WebCore/inspector/agents/InspectorNetworkAgent.h
|
|
@@ -34,6 +34,8 @@
|
|
#include "InspectorInstrumentation.h"
|
|
#include "InspectorPageAgent.h"
|
|
#include "InspectorWebAgentBase.h"
|
|
+#include "ResourceError.h"
|
|
+#include "SharedBuffer.h"
|
|
#include "WebSocket.h"
|
|
#include <JavaScriptCore/InspectorBackendDispatchers.h>
|
|
#include <JavaScriptCore/InspectorFrontendDispatchers.h>
|
|
@@ -102,6 +104,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 willRecalculateStyle();
|
|
@@ -133,6 +136,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>>&);
|
|
@@ -259,6 +263,7 @@ private:
|
|
bool m_enabled { false };
|
|
bool m_loadingXHRSynchronously { false };
|
|
bool m_interceptionEnabled { false };
|
|
+ bool m_stoppingLoadingDueToProcessSwap { false };
|
|
};
|
|
|
|
} // namespace WebCore
|
|
diff --git a/Source/WebCore/inspector/agents/InspectorPageAgent.cpp b/Source/WebCore/inspector/agents/InspectorPageAgent.cpp
|
|
index 322ae350279461c5c213a760444580421cb89682..6fc187ab25a6c76c41880fdf63acda1f9bb132cc 100644
|
|
--- a/Source/WebCore/inspector/agents/InspectorPageAgent.cpp
|
|
+++ b/Source/WebCore/inspector/agents/InspectorPageAgent.cpp
|
|
@@ -32,19 +32,27 @@
|
|
#include "config.h"
|
|
#include "InspectorPageAgent.h"
|
|
|
|
+#include "AXCoreObject.h"
|
|
+#include "AXObjectCache.h"
|
|
+#include "BackForwardController.h"
|
|
#include "CachedResource.h"
|
|
#include "CachedResourceLoader.h"
|
|
#include "Cookie.h"
|
|
#include "CookieJar.h"
|
|
+#include "CustomHeaderFields.h"
|
|
#include "DOMWrapperWorld.h"
|
|
#include "DocumentInlines.h"
|
|
#include "DocumentLoader.h"
|
|
+#include "Editor.h"
|
|
#include "ElementInlines.h"
|
|
+#include "FocusController.h"
|
|
#include "ForcedAccessibilityValue.h"
|
|
#include "FrameLoadRequest.h"
|
|
#include "FrameLoader.h"
|
|
+#include "FrameLoaderClient.h"
|
|
#include "FrameSnapshotting.h"
|
|
#include "HTMLFrameOwnerElement.h"
|
|
+#include "HTMLInputElement.h"
|
|
#include "HTMLNames.h"
|
|
#include "ImageBuffer.h"
|
|
#include "InspectorClient.h"
|
|
@@ -57,24 +65,38 @@
|
|
#include "MIMETypeRegistry.h"
|
|
#include "MemoryCache.h"
|
|
#include "Page.h"
|
|
+#include "PageRuntimeAgent.h"
|
|
+#include "PlatformScreen.h"
|
|
#include "RenderObject.h"
|
|
#include "RenderTheme.h"
|
|
+#include "DeprecatedGlobalSettings.h"
|
|
+#include "SimpleRange.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 <pal/text/TextEncoding.h>
|
|
+#include "TextIterator.h"
|
|
+#include "TypingCommand.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/ObjectIdentifier.h>
|
|
+#include <wtf/Ref.h>
|
|
+#include <wtf/RefPtr.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)
|
|
@@ -96,6 +118,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;
|
|
+}
|
|
+
|
|
static bool decodeBuffer(std::span<const uint8_t> buffer, const String& textEncodingName, String* result)
|
|
{
|
|
if (buffer.data()) {
|
|
@@ -348,6 +375,7 @@ InspectorPageAgent::InspectorPageAgent(PageAgentContext& context, InspectorClien
|
|
, m_frontendDispatcher(makeUnique<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)
|
|
{
|
|
@@ -377,12 +405,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()
|
|
{
|
|
m_instrumentingAgents.setEnabledPageAgent(nullptr);
|
|
+ m_interceptFileChooserDialog = false;
|
|
+ m_bypassCSP = false;
|
|
|
|
setShowPaintRects(false);
|
|
#if !PLATFORM(IOS_FAMILY)
|
|
@@ -435,6 +471,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::navigate(const String& url)
|
|
{
|
|
RefPtr localMainFrame = m_inspectedPage->localMainFrame();
|
|
@@ -461,6 +513,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();
|
|
@@ -474,6 +533,12 @@ Inspector::Protocol::ErrorStringOr<void> InspectorPageAgent::overrideSetting(Ins
|
|
inspectedPageSettings.setAuthorAndUserStylesEnabledInspectorOverride(value);
|
|
return { };
|
|
|
|
+#if ENABLE(DEVICE_ORIENTATION)
|
|
+ case Protocol::Page::Setting::DeviceOrientationEventEnabled:
|
|
+ inspectedPageSettings.setDeviceOrientationEventEnabled(value.value_or(false));
|
|
+ return { };
|
|
+#endif
|
|
+
|
|
case Inspector::Protocol::Page::Setting::ICECandidateFilteringEnabled:
|
|
inspectedPageSettings.setICECandidateFilteringEnabledInspectorOverride(value);
|
|
return { };
|
|
@@ -500,6 +565,39 @@ Inspector::Protocol::ErrorStringOr<void> InspectorPageAgent::overrideSetting(Ins
|
|
m_client->setDeveloperPreferenceOverride(InspectorClient::DeveloperPreference::NeedsSiteSpecificQuirks, value);
|
|
return { };
|
|
|
|
+#if ENABLE(NOTIFICATIONS)
|
|
+ case Protocol::Page::Setting::NotificationsEnabled:
|
|
+ inspectedPageSettings.setNotificationsEnabled(value.value_or(false));
|
|
+ return { };
|
|
+#endif
|
|
+
|
|
+#if ENABLE(FULLSCREEN_API)
|
|
+ case Protocol::Page::Setting::FullScreenEnabled:
|
|
+ inspectedPageSettings.setFullScreenEnabled(value.value_or(false));
|
|
+ return { };
|
|
+#endif
|
|
+
|
|
+ case Protocol::Page::Setting::InputTypeMonthEnabled:
|
|
+ inspectedPageSettings.setInputTypeMonthEnabled(value.value_or(false));
|
|
+ return { };
|
|
+
|
|
+ case Protocol::Page::Setting::InputTypeWeekEnabled:
|
|
+ inspectedPageSettings.setInputTypeWeekEnabled(value.value_or(false));
|
|
+ return { };
|
|
+
|
|
+ case 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 Protocol::Page::Setting::PointerLockEnabled:
|
|
+ inspectedPageSettings.setPointerLockEnabled(value.value_or(false));
|
|
+ return { };
|
|
+#endif
|
|
+
|
|
case Inspector::Protocol::Page::Setting::ScriptEnabled:
|
|
inspectedPageSettings.setScriptEnabledInspectorOverride(value);
|
|
return { };
|
|
@@ -512,6 +610,12 @@ Inspector::Protocol::ErrorStringOr<void> InspectorPageAgent::overrideSetting(Ins
|
|
inspectedPageSettings.setShowRepaintCounterInspectorOverride(value);
|
|
return { };
|
|
|
|
+#if ENABLE(MEDIA_STREAM)
|
|
+ case Protocol::Page::Setting::SpeechRecognitionEnabled:
|
|
+ inspectedPageSettings.setSpeechRecognitionEnabled(value.value_or(false));
|
|
+ return { };
|
|
+#endif
|
|
+
|
|
case Inspector::Protocol::Page::Setting::WebSecurityEnabled:
|
|
inspectedPageSettings.setWebSecurityEnabledInspectorOverride(value);
|
|
return { };
|
|
@@ -919,15 +1023,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)
|
|
@@ -935,13 +1040,38 @@ void InspectorPageAgent::frameNavigated(LocalFrame& frame)
|
|
m_frontendDispatcher->frameNavigated(buildObjectForFrame(&frame));
|
|
}
|
|
|
|
+String InspectorPageAgent::serializeFrameID(FrameIdentifier frameID)
|
|
+{
|
|
+ return makeString(frameID.processIdentifier().toUInt64(), '.', frameID.object().toUInt64());
|
|
+}
|
|
+
|
|
+std::optional<FrameIdentifier> InspectorPageAgent::parseFrameID(String frameID)
|
|
+{
|
|
+ size_t dotPos = frameID.find("."_s);
|
|
+ if (dotPos == notFound)
|
|
+ return std::nullopt;
|
|
+
|
|
+ if (!frameID.containsOnlyASCII())
|
|
+ return std::nullopt;
|
|
+
|
|
+ String processIDString = frameID.left(dotPos);
|
|
+ uint64_t pid = strtoull(processIDString.ascii().data(), 0, 10);
|
|
+ auto processID = ObjectIdentifier<WebCore::ProcessIdentifierType>(pid);
|
|
+ String frameIDString = frameID.substring(dotPos + 1);
|
|
+ uint64_t frameIDNumber = strtoull(frameIDString.ascii().data(), 0, 10);
|
|
+ return WebCore::FrameIdentifier {
|
|
+ ObjectIdentifier<WebCore::FrameIdentifierType>(frameIDNumber),
|
|
+ processID
|
|
+ };
|
|
+}
|
|
+
|
|
void InspectorPageAgent::frameDetached(LocalFrame& frame)
|
|
{
|
|
- auto identifier = m_frameToIdentifier.take(frame);
|
|
- if (identifier.isNull())
|
|
+ String identifier = serializeFrameID(frame.frameID());
|
|
+ if (!m_identifierToFrame.take(identifier))
|
|
return;
|
|
+
|
|
m_frontendDispatcher->frameDetached(identifier);
|
|
- m_identifierToFrame.remove(identifier);
|
|
}
|
|
|
|
Frame* InspectorPageAgent::frameForId(const Inspector::Protocol::Network::FrameId& frameId)
|
|
@@ -953,20 +1083,21 @@ String InspectorPageAgent::frameId(Frame* frame)
|
|
{
|
|
if (!frame)
|
|
return emptyString();
|
|
- return m_frameToIdentifier.ensure(*frame, [this, frame] {
|
|
- auto identifier = IdentifiersFactory::createIdentifier();
|
|
- m_identifierToFrame.set(identifier, frame);
|
|
- return identifier;
|
|
- }).iterator->value;
|
|
+ String identifier = serializeFrameID(frame->frameID());
|
|
+ m_identifierToFrame.set(identifier, frame);
|
|
+ return identifier;
|
|
}
|
|
|
|
String InspectorPageAgent::loaderId(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());
|
|
}
|
|
|
|
LocalFrame* InspectorPageAgent::assertFrame(Inspector::Protocol::ErrorString& errorString, const Inspector::Protocol::Network::FrameId& frameId)
|
|
@@ -977,11 +1108,6 @@ LocalFrame* InspectorPageAgent::assertFrame(Inspector::Protocol::ErrorString& er
|
|
return frame;
|
|
}
|
|
|
|
-void InspectorPageAgent::loaderDetachedFromFrame(DocumentLoader& loader)
|
|
-{
|
|
- m_loaderToIdentifier.remove(&loader);
|
|
-}
|
|
-
|
|
void InspectorPageAgent::frameStartedLoading(LocalFrame& frame)
|
|
{
|
|
m_frontendDispatcher->frameStartedLoading(frameId(&frame));
|
|
@@ -992,9 +1118,9 @@ void InspectorPageAgent::frameStoppedLoading(LocalFrame& frame)
|
|
m_frontendDispatcher->frameStoppedLoading(frameId(&frame));
|
|
}
|
|
|
|
-void InspectorPageAgent::frameScheduledNavigation(Frame& frame, Seconds delay)
|
|
+void InspectorPageAgent::frameScheduledNavigation(Frame& frame, Seconds delay, bool targetIsCurrentFrame)
|
|
{
|
|
- m_frontendDispatcher->frameScheduledNavigation(frameId(&frame), delay.value());
|
|
+ m_frontendDispatcher->frameScheduledNavigation(frameId(&frame), delay.value(), targetIsCurrentFrame);
|
|
}
|
|
|
|
void InspectorPageAgent::frameClearedScheduledNavigation(Frame& frame)
|
|
@@ -1041,6 +1167,12 @@ void InspectorPageAgent::defaultUserPreferencesDidChange()
|
|
m_frontendDispatcher->defaultUserPreferencesDidChange(WTFMove(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()
|
|
{
|
|
@@ -1054,6 +1186,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 }));
|
|
@@ -1101,6 +1236,51 @@ void InspectorPageAgent::didRecalculateStyle()
|
|
protectedOverlay()->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);
|
|
@@ -1194,6 +1374,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())
|
|
@@ -1221,11 +1407,13 @@ Inspector::Protocol::ErrorStringOr<String> InspectorPageAgent::snapshotNode(Insp
|
|
return snapshot->toDataURL("image/png"_s, std::nullopt, PreserveResolution::Yes);
|
|
}
|
|
|
|
-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 { { }, ImageBufferPixelFormat::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();
|
|
@@ -1239,6 +1427,43 @@ Inspector::Protocol::ErrorStringOr<String> InspectorPageAgent::snapshotRect(int
|
|
return snapshot->toDataURL("image/png"_s, std::nullopt, PreserveResolution::Yes);
|
|
}
|
|
|
|
+Protocol::ErrorStringOr<void> InspectorPageAgent::setForcedColors(std::optional<Protocol::Page::ForcedColors>&& forcedColors)
|
|
+{
|
|
+ if (!forcedColors) {
|
|
+ m_inspectedPage->setUseForcedColorsOverride(std::nullopt);
|
|
+ return { };
|
|
+ }
|
|
+
|
|
+ switch (*forcedColors) {
|
|
+ case Protocol::Page::ForcedColors::Active:
|
|
+ m_inspectedPage->setUseForcedColorsOverride(true);
|
|
+ return { };
|
|
+ case Protocol::Page::ForcedColors::None:
|
|
+ m_inspectedPage->setUseForcedColorsOverride(false);
|
|
+ return { };
|
|
+ }
|
|
+
|
|
+ ASSERT_NOT_REACHED();
|
|
+ return { };
|
|
+}
|
|
+
|
|
+Protocol::ErrorStringOr<void> InspectorPageAgent::setTimeZone(const String& timeZone)
|
|
+{
|
|
+ bool success = WTF::setTimeZoneOverride(timeZone);
|
|
+ if (!success)
|
|
+ return makeUnexpected(makeString("Invalid time zone "_s, timeZone));
|
|
+
|
|
+ return { };
|
|
+}
|
|
+
|
|
+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()
|
|
{
|
|
@@ -1255,7 +1480,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())
|
|
@@ -1273,6 +1497,498 @@ Inspector::Protocol::ErrorStringOr<void> InspectorPageAgent::setScreenSizeOverri
|
|
localMainFrame->setOverrideScreenSize(FloatSize(width.value_or(0), height.value_or(0)));
|
|
return { };
|
|
}
|
|
-#endif
|
|
+
|
|
+Protocol::ErrorStringOr<void> InspectorPageAgent::insertText(const String& text)
|
|
+{
|
|
+ UserGestureIndicator indicator { IsProcessingUserGesture::Yes };
|
|
+ RefPtr frame = m_inspectedPage->checkedFocusController()->focusedOrMainFrame();
|
|
+ if (!frame)
|
|
+ return { };
|
|
+
|
|
+ if (frame->editor().hasComposition()) {
|
|
+ frame->editor().confirmComposition(text);
|
|
+ } else {
|
|
+ Document* focusedDocument = frame->document();
|
|
+ TypingCommand::insertText(*focusedDocument, text, nullptr, { });
|
|
+ }
|
|
+ return { };
|
|
+}
|
|
+
|
|
+static String roleFromObject(RefPtr<AXCoreObject> axObject)
|
|
+{
|
|
+ String computedRoleString = axObject->computedRoleString();
|
|
+ if (!computedRoleString.isEmpty())
|
|
+ return computedRoleString;
|
|
+ AccessibilityRole role = axObject->roleValue();
|
|
+ switch(role) {
|
|
+ case AccessibilityRole::Application:
|
|
+ return "Application"_s;
|
|
+ case AccessibilityRole::ApplicationAlert:
|
|
+ return "ApplicationAlert"_s;
|
|
+ case AccessibilityRole::ApplicationAlertDialog:
|
|
+ return "ApplicationAlertDialog"_s;
|
|
+ case AccessibilityRole::ApplicationDialog:
|
|
+ return "ApplicationDialog"_s;
|
|
+ case AccessibilityRole::ApplicationLog:
|
|
+ return "ApplicationLog"_s;
|
|
+ case AccessibilityRole::ApplicationMarquee:
|
|
+ return "ApplicationMarquee"_s;
|
|
+ case AccessibilityRole::ApplicationStatus:
|
|
+ return "ApplicationStatus"_s;
|
|
+ case AccessibilityRole::ApplicationTimer:
|
|
+ return "ApplicationTimer"_s;
|
|
+ case AccessibilityRole::Audio:
|
|
+ return "Audio"_s;
|
|
+ case AccessibilityRole::Blockquote:
|
|
+ return "Blockquote"_s;
|
|
+ case AccessibilityRole::Button:
|
|
+ return "Button"_s;
|
|
+ case AccessibilityRole::Canvas:
|
|
+ return "Canvas"_s;
|
|
+ case AccessibilityRole::Caption:
|
|
+ return "Caption"_s;
|
|
+ case AccessibilityRole::Cell:
|
|
+ return "Cell"_s;
|
|
+ case AccessibilityRole::Checkbox:
|
|
+ return "CheckBox"_s;
|
|
+ case AccessibilityRole::Code:
|
|
+ return "Code"_s;
|
|
+ case AccessibilityRole::ColorWell:
|
|
+ return "ColorWell"_s;
|
|
+ case AccessibilityRole::Column:
|
|
+ return "Column"_s;
|
|
+ case AccessibilityRole::ColumnHeader:
|
|
+ return "ColumnHeader"_s;
|
|
+ case AccessibilityRole::ComboBox:
|
|
+ return "ComboBox"_s;
|
|
+ case AccessibilityRole::DateTime:
|
|
+ return "DateTime"_s;
|
|
+ case AccessibilityRole::Definition:
|
|
+ return "Definition"_s;
|
|
+ case AccessibilityRole::Deletion:
|
|
+ return "Deletion"_s;
|
|
+ case AccessibilityRole::DescriptionList:
|
|
+ return "DescriptionList"_s;
|
|
+ case AccessibilityRole::DescriptionListTerm:
|
|
+ return "DescriptionListTerm"_s;
|
|
+ case AccessibilityRole::DescriptionListDetail:
|
|
+ return "DescriptionListDetail"_s;
|
|
+ case AccessibilityRole::Details:
|
|
+ return "Details"_s;
|
|
+ case AccessibilityRole::Directory:
|
|
+ return "Directory"_s;
|
|
+ case AccessibilityRole::Document:
|
|
+ return "Document"_s;
|
|
+ case AccessibilityRole::DocumentArticle:
|
|
+ return "DocumentArticle"_s;
|
|
+ case AccessibilityRole::DocumentMath:
|
|
+ return "DocumentMath"_s;
|
|
+ case AccessibilityRole::DocumentNote:
|
|
+ return "DocumentNote"_s;
|
|
+ case AccessibilityRole::Emphasis:
|
|
+ return "Emphasis"_s;
|
|
+ case AccessibilityRole::Feed:
|
|
+ return "Feed"_s;
|
|
+ case AccessibilityRole::Figure:
|
|
+ return "Figure"_s;
|
|
+ case AccessibilityRole::Footer:
|
|
+ return "Footer"_s;
|
|
+ case AccessibilityRole::Footnote:
|
|
+ return "Footnote"_s;
|
|
+ case AccessibilityRole::Form:
|
|
+ return "Form"_s;
|
|
+ case AccessibilityRole::Generic:
|
|
+ return "Generic"_s;
|
|
+ case AccessibilityRole::GraphicsDocument:
|
|
+ return "GraphicsDocument"_s;
|
|
+ case AccessibilityRole::GraphicsObject:
|
|
+ return "GraphicsObject"_s;
|
|
+ case AccessibilityRole::GraphicsSymbol:
|
|
+ return "GraphicsSymbol"_s;
|
|
+ case AccessibilityRole::Grid:
|
|
+ return "Grid"_s;
|
|
+ case AccessibilityRole::GridCell:
|
|
+ return "GridCell"_s;
|
|
+ case AccessibilityRole::Group:
|
|
+ return "Group"_s;
|
|
+ case AccessibilityRole::Heading:
|
|
+ return "Heading"_s;
|
|
+ case AccessibilityRole::HorizontalRule:
|
|
+ return "HorizontalRule"_s;
|
|
+ case AccessibilityRole::Ignored:
|
|
+ return "Ignored"_s;
|
|
+ case AccessibilityRole::Inline:
|
|
+ return "Inline"_s;
|
|
+ case AccessibilityRole::Image:
|
|
+ return "Image"_s;
|
|
+ case AccessibilityRole::ImageMap:
|
|
+ return "ImageMap"_s;
|
|
+ case AccessibilityRole::ImageMapLink:
|
|
+ return "ImageMapLink"_s;
|
|
+ case AccessibilityRole::Insertion:
|
|
+ return "Insertion"_s;
|
|
+ case AccessibilityRole::Label:
|
|
+ return "Label"_s;
|
|
+ case AccessibilityRole::LandmarkBanner:
|
|
+ return "LandmarkBanner"_s;
|
|
+ case AccessibilityRole::LandmarkComplementary:
|
|
+ return "LandmarkComplementary"_s;
|
|
+ case AccessibilityRole::LandmarkContentInfo:
|
|
+ return "LandmarkContentInfo"_s;
|
|
+ case AccessibilityRole::LandmarkDocRegion:
|
|
+ return "LandmarkDocRegion"_s;
|
|
+ case AccessibilityRole::LandmarkMain:
|
|
+ return "LandmarkMain"_s;
|
|
+ case AccessibilityRole::LandmarkNavigation:
|
|
+ return "LandmarkNavigation"_s;
|
|
+ case AccessibilityRole::LandmarkRegion:
|
|
+ return "LandmarkRegion"_s;
|
|
+ case AccessibilityRole::LandmarkSearch:
|
|
+ return "LandmarkSearch"_s;
|
|
+ case AccessibilityRole::Legend:
|
|
+ return "Legend"_s;
|
|
+ case AccessibilityRole::LineBreak:
|
|
+ return "LineBreak"_s;
|
|
+ case AccessibilityRole::Link:
|
|
+ return "Link"_s;
|
|
+ case AccessibilityRole::List:
|
|
+ return "List"_s;
|
|
+ case AccessibilityRole::ListBox:
|
|
+ return "ListBox"_s;
|
|
+ case AccessibilityRole::ListBoxOption:
|
|
+ return "ListBoxOption"_s;
|
|
+ case AccessibilityRole::ListItem:
|
|
+ return "ListItem"_s;
|
|
+ case AccessibilityRole::ListMarker:
|
|
+ return "ListMarker"_s;
|
|
+ case AccessibilityRole::Mark:
|
|
+ return "Mark"_s;
|
|
+ case AccessibilityRole::MathElement:
|
|
+ return "MathElement"_s;
|
|
+ case AccessibilityRole::Menu:
|
|
+ return "Menu"_s;
|
|
+ case AccessibilityRole::MenuBar:
|
|
+ return "MenuBar"_s;
|
|
+ case AccessibilityRole::MenuItem:
|
|
+ return "MenuItem"_s;
|
|
+ case AccessibilityRole::MenuItemCheckbox:
|
|
+ return "MenuItemCheckbox"_s;
|
|
+ case AccessibilityRole::MenuItemRadio:
|
|
+ return "MenuItemRadio"_s;
|
|
+ case AccessibilityRole::MenuListPopup:
|
|
+ return "MenuListPopup"_s;
|
|
+ case AccessibilityRole::MenuListOption:
|
|
+ return "MenuListOption"_s;
|
|
+ case AccessibilityRole::Meter:
|
|
+ return "Meter"_s;
|
|
+ case AccessibilityRole::Model:
|
|
+ return "Model"_s;
|
|
+ case AccessibilityRole::Paragraph:
|
|
+ return "Paragraph"_s;
|
|
+ case AccessibilityRole::PopUpButton:
|
|
+ return "PopUpButton"_s;
|
|
+ case AccessibilityRole::Pre:
|
|
+ return "Pre"_s;
|
|
+ case AccessibilityRole::Presentational:
|
|
+ return "Presentational"_s;
|
|
+ case AccessibilityRole::ProgressIndicator:
|
|
+ return "ProgressIndicator"_s;
|
|
+ case AccessibilityRole::RadioButton:
|
|
+ return "RadioButton"_s;
|
|
+ case AccessibilityRole::RadioGroup:
|
|
+ return "RadioGroup"_s;
|
|
+ case AccessibilityRole::RemoteFrame:
|
|
+ return "RemoteFrame"_s;
|
|
+ case AccessibilityRole::RowHeader:
|
|
+ return "RowHeader"_s;
|
|
+ case AccessibilityRole::Row:
|
|
+ return "Row"_s;
|
|
+ case AccessibilityRole::RowGroup:
|
|
+ return "RowGroup"_s;
|
|
+ case AccessibilityRole::RubyInline:
|
|
+ return "RubyInline"_s;
|
|
+ case AccessibilityRole::RubyText:
|
|
+ return "RubyText"_s;
|
|
+ case AccessibilityRole::ScrollArea:
|
|
+ return "ScrollArea"_s;
|
|
+ case AccessibilityRole::ScrollBar:
|
|
+ return "ScrollBar"_s;
|
|
+ case AccessibilityRole::SearchField:
|
|
+ return "SearchField"_s;
|
|
+ case AccessibilityRole::Slider:
|
|
+ return "Slider"_s;
|
|
+ case AccessibilityRole::SliderThumb:
|
|
+ return "SliderThumb"_s;
|
|
+ case AccessibilityRole::SpinButton:
|
|
+ return "SpinButton"_s;
|
|
+ case AccessibilityRole::SpinButtonPart:
|
|
+ return "SpinButtonPart"_s;
|
|
+ case AccessibilityRole::Splitter:
|
|
+ return "Splitter"_s;
|
|
+ case AccessibilityRole::StaticText:
|
|
+ return "StaticText"_s;
|
|
+ case AccessibilityRole::Strong:
|
|
+ return "Strong"_s;
|
|
+ case AccessibilityRole::Subscript:
|
|
+ return "Subscript"_s;
|
|
+ case AccessibilityRole::Suggestion:
|
|
+ return "Suggestion"_s;
|
|
+ case AccessibilityRole::Summary:
|
|
+ return "Summary"_s;
|
|
+ case AccessibilityRole::Superscript:
|
|
+ return "Superscript"_s;
|
|
+ case AccessibilityRole::Switch:
|
|
+ return "Switch"_s;
|
|
+ case AccessibilityRole::SVGRoot:
|
|
+ return "SVGRoot"_s;
|
|
+ case AccessibilityRole::SVGText:
|
|
+ return "SVGText"_s;
|
|
+ case AccessibilityRole::SVGTSpan:
|
|
+ return "SVGTSpan"_s;
|
|
+ case AccessibilityRole::SVGTextPath:
|
|
+ return "SVGTextPath"_s;
|
|
+ case AccessibilityRole::TabGroup:
|
|
+ return "TabGroup"_s;
|
|
+ case AccessibilityRole::TabList:
|
|
+ return "TabList"_s;
|
|
+ case AccessibilityRole::TabPanel:
|
|
+ return "TabPanel"_s;
|
|
+ case AccessibilityRole::Tab:
|
|
+ return "Tab"_s;
|
|
+ case AccessibilityRole::Table:
|
|
+ return "Table"_s;
|
|
+ case AccessibilityRole::TableHeaderContainer:
|
|
+ return "TableHeaderContainer"_s;
|
|
+ case AccessibilityRole::TextArea:
|
|
+ return "TextArea"_s;
|
|
+ case AccessibilityRole::TextGroup:
|
|
+ return "TextGroup"_s;
|
|
+ case AccessibilityRole::Term:
|
|
+ return "Term"_s;
|
|
+ case AccessibilityRole::Time:
|
|
+ return "Time"_s;
|
|
+ case AccessibilityRole::Tree:
|
|
+ return "Tree"_s;
|
|
+ case AccessibilityRole::TreeGrid:
|
|
+ return "TreeGrid"_s;
|
|
+ case AccessibilityRole::TreeItem:
|
|
+ return "TreeItem"_s;
|
|
+ case AccessibilityRole::TextField:
|
|
+ return "TextField"_s;
|
|
+ case AccessibilityRole::ToggleButton:
|
|
+ return "ToggleButton"_s;
|
|
+ case AccessibilityRole::Toolbar:
|
|
+ return "Toolbar"_s;
|
|
+ case AccessibilityRole::Unknown:
|
|
+ return "Unknown"_s;
|
|
+ case AccessibilityRole::UserInterfaceTooltip:
|
|
+ return "UserInterfaceTooltip"_s;
|
|
+ case AccessibilityRole::Video:
|
|
+ return "Video"_s;
|
|
+ case AccessibilityRole::WebApplication:
|
|
+ return "WebApplication"_s;
|
|
+ case AccessibilityRole::WebArea:
|
|
+ return "WebArea"_s;
|
|
+ case AccessibilityRole::WebCoreLink:
|
|
+ return "WebCoreLink"_s;
|
|
+ };
|
|
+ return "Unknown"_s;
|
|
+}
|
|
+
|
|
+static Ref<Inspector::Protocol::Page::AXNode> snapshotForAXObject(WTF::RefPtr<WebCore::AXCoreObject> axObject, Node* nodeToFind)
|
|
+{
|
|
+ auto axNode = Inspector::Protocol::Page::AXNode::create()
|
|
+ .setRole(roleFromObject(axObject))
|
|
+ .release();
|
|
+ auto* liveObject = dynamicDowncast<AccessibilityObject>(axObject.get());
|
|
+
|
|
+ if (liveObject && !liveObject->computedLabel().isEmpty())
|
|
+ axNode->setName(liveObject->computedLabel());
|
|
+ if (!axObject->stringValue().isEmpty())
|
|
+ axNode->setValue(JSON::Value::create(axObject->stringValue()));
|
|
+ if (liveObject && !liveObject->description().isEmpty())
|
|
+ axNode->setDescription(liveObject->description());
|
|
+ if (!axObject->keyShortcuts().isEmpty())
|
|
+ axNode->setKeyshortcuts(axObject->keyShortcuts());
|
|
+ if (!axObject->valueDescription().isEmpty())
|
|
+ axNode->setValuetext(axObject->valueDescription());
|
|
+ if (!axObject->roleDescription().isEmpty())
|
|
+ axNode->setRoledescription(axObject->roleDescription());
|
|
+ if (!axObject->isEnabled())
|
|
+ axNode->setDisabled(!axObject->isEnabled());
|
|
+ if (axObject->supportsExpanded())
|
|
+ axNode->setExpanded(axObject->isExpanded());
|
|
+ if (axObject->isFocused())
|
|
+ axNode->setFocused(axObject->isFocused());
|
|
+ if (axObject->isModalNode())
|
|
+ axNode->setModal(axObject->isModalNode());
|
|
+ if (axObject->isMultiSelectable())
|
|
+ axNode->setMultiselectable(axObject->isMultiSelectable());
|
|
+ if (liveObject && liveObject->supportsReadOnly() && !axObject->canSetValueAttribute() && axObject->isEnabled())
|
|
+ axNode->setReadonly(true);
|
|
+ if (axObject->supportsRequiredAttribute())
|
|
+ axNode->setRequired(axObject->isRequired());
|
|
+ if (axObject->isSelected())
|
|
+ axNode->setSelected(axObject->isSelected());
|
|
+ if (axObject->supportsChecked()) {
|
|
+ AccessibilityButtonState checkedState = axObject->checkboxOrRadioValue();
|
|
+ switch (checkedState) {
|
|
+ case AccessibilityButtonState::On:
|
|
+ axNode->setChecked(Inspector::Protocol::Page::AXNode::Checked::True);
|
|
+ break;
|
|
+ case AccessibilityButtonState::Off:
|
|
+ axNode->setChecked(Inspector::Protocol::Page::AXNode::Checked::False);
|
|
+ break;
|
|
+ case AccessibilityButtonState::Mixed:
|
|
+ axNode->setChecked(Inspector::Protocol::Page::AXNode::Checked::Mixed);
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ unsigned level = axObject->hierarchicalLevel() ? axObject->hierarchicalLevel() : axObject->headingLevel();
|
|
+ if (level)
|
|
+ axNode->setLevel(level);
|
|
+ if (axObject->minValueForRange() != 0)
|
|
+ axNode->setValuemin(axObject->minValueForRange());
|
|
+ if (axObject->maxValueForRange() != 0)
|
|
+ axNode->setValuemax(axObject->maxValueForRange());
|
|
+ if (liveObject && liveObject->supportsAutoComplete())
|
|
+ axNode->setAutocomplete(axObject->autoCompleteValue());
|
|
+ if (axObject->hasPopup())
|
|
+ axNode->setHaspopup(axObject->popupValue());
|
|
+
|
|
+ String invalidValue = axObject->invalidStatus();
|
|
+ if (invalidValue != "false"_s) {
|
|
+ if (invalidValue == "grammar"_s)
|
|
+ axNode->setInvalid(Inspector::Protocol::Page::AXNode::Invalid::Grammar);
|
|
+ else if (invalidValue == "spelling"_s)
|
|
+ axNode->setInvalid(Inspector::Protocol::Page::AXNode::Invalid::Spelling);
|
|
+ else // Future versions of ARIA may allow additional truthy values. Ex. format, order, or size.
|
|
+ axNode->setInvalid(Inspector::Protocol::Page::AXNode::Invalid::True);
|
|
+ }
|
|
+ switch (axObject->orientation()) {
|
|
+ case AccessibilityOrientation::Undefined:
|
|
+ break;
|
|
+ case AccessibilityOrientation::Vertical:
|
|
+ axNode->setOrientation("vertical"_s);
|
|
+ break;
|
|
+ case AccessibilityOrientation::Horizontal:
|
|
+ axNode->setOrientation("horizontal"_s);
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ if (axObject->isKeyboardFocusable())
|
|
+ axNode->setFocusable(axObject->isKeyboardFocusable());
|
|
+
|
|
+ if (nodeToFind && axObject->node() == nodeToFind)
|
|
+ axNode->setFound(true);
|
|
+
|
|
+ if (!axObject->children().isEmpty()) {
|
|
+ Ref<JSON::ArrayOf<Inspector::Protocol::Page::AXNode>> children = JSON::ArrayOf<Inspector::Protocol::Page::AXNode>::create();
|
|
+ for (auto& childObject : axObject->children())
|
|
+ children->addItem(snapshotForAXObject(childObject.ptr(), nodeToFind));
|
|
+ axNode->setChildren(WTFMove(children));
|
|
+ }
|
|
+ return axNode;
|
|
+}
|
|
+
|
|
+
|
|
+Protocol::ErrorStringOr<Ref<Protocol::Page::AXNode>> InspectorPageAgent::accessibilitySnapshot(const String& objectId)
|
|
+{
|
|
+ if (!WebCore::AXObjectCache::accessibilityEnabled())
|
|
+ WebCore::AXObjectCache::enableAccessibility();
|
|
+
|
|
+ auto* localMainFrame = dynamicDowncast<LocalFrame>(m_inspectedPage->mainFrame());
|
|
+ if (!localMainFrame)
|
|
+ return makeUnexpected("No local main frame"_s);
|
|
+
|
|
+ RefPtr document = localMainFrame->document();
|
|
+ if (!document)
|
|
+ return makeUnexpected("No document for main frame"_s);
|
|
+
|
|
+ AXObjectCache* axObjectCache = document->axObjectCache();
|
|
+ if (!axObjectCache)
|
|
+ return makeUnexpected("No AXObjectCache for main document"_s);
|
|
+
|
|
+ AXCoreObject* axObject = axObjectCache->rootObjectForFrame(*localMainFrame);
|
|
+ if (!axObject)
|
|
+ return makeUnexpected("No AXObject for main document"_s);
|
|
+
|
|
+ Node* node = nullptr;
|
|
+ if (!objectId.isEmpty()) {
|
|
+ InspectorDOMAgent* domAgent = m_instrumentingAgents.persistentDOMAgent();
|
|
+ ASSERT(domAgent);
|
|
+ node = domAgent->nodeForObjectId(objectId);
|
|
+ if (!node)
|
|
+ return makeUnexpected("No Node for objectId"_s);
|
|
+ }
|
|
+
|
|
+ m_doingAccessibilitySnapshot = true;
|
|
+ Ref<Inspector::Protocol::Page::AXNode> axNode = snapshotForAXObject(RefPtr { axObject }, node);
|
|
+ m_doingAccessibilitySnapshot = false;
|
|
+ return axNode;
|
|
+}
|
|
+
|
|
+Protocol::ErrorStringOr<void> InspectorPageAgent::setInterceptFileChooserDialog(bool enabled)
|
|
+{
|
|
+ m_interceptFileChooserDialog = enabled;
|
|
+ return { };
|
|
+}
|
|
+
|
|
+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(WTFMove(color)));
|
|
+ return { };
|
|
+}
|
|
+
|
|
+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, WTFMove(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);
|
|
+ for (auto* world : worlds)
|
|
+ localFrame->windowProxy().jsWindowProxy(*world)->window();
|
|
+ }
|
|
+}
|
|
+
|
|
+Protocol::ErrorStringOr<void> InspectorPageAgent::setBypassCSP(bool enabled)
|
|
+{
|
|
+ m_bypassCSP = enabled;
|
|
+ return { };
|
|
+}
|
|
+
|
|
+Protocol::ErrorStringOr<void> InspectorPageAgent::crash()
|
|
+{
|
|
+ WTFCrash();
|
|
+ return { };
|
|
+}
|
|
+
|
|
+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 7daa8d1d5c96afe1829aa21ccb8ed1b8ebcc3861..da57245795d7cb287daaaaf5d09a523c0f88fcc7 100644
|
|
--- a/Source/WebCore/inspector/agents/InspectorPageAgent.h
|
|
+++ b/Source/WebCore/inspector/agents/InspectorPageAgent.h
|
|
@@ -32,8 +32,10 @@
|
|
#pragma once
|
|
|
|
#include "CachedResource.h"
|
|
+#include "FrameIdentifier.h"
|
|
#include "InspectorWebAgentBase.h"
|
|
#include "LayoutRect.h"
|
|
+#include "ProcessIdentifier.h"
|
|
#include <JavaScriptCore/InspectorBackendDispatchers.h>
|
|
#include <JavaScriptCore/InspectorFrontendDispatchers.h>
|
|
#include <JavaScriptCore/InspectorProtocolObjects.h>
|
|
@@ -43,11 +45,16 @@
|
|
#include <wtf/WeakRef.h>
|
|
#include <wtf/text/WTFString.h>
|
|
|
|
+namespace Inspector {
|
|
+class InjectedScriptManager;
|
|
+}
|
|
+
|
|
namespace WebCore {
|
|
|
|
class DOMWrapperWorld;
|
|
class DocumentLoader;
|
|
class Frame;
|
|
+class HTMLInputElement;
|
|
class InspectorClient;
|
|
class InspectorOverlay;
|
|
class LocalFrame;
|
|
@@ -80,6 +87,8 @@ public:
|
|
OtherResource,
|
|
};
|
|
|
|
+ WEBCORE_EXPORT static String serializeFrameID(FrameIdentifier frameID);
|
|
+ WEBCORE_EXPORT static std::optional<FrameIdentifier> parseFrameID(String frameID);
|
|
static bool sharedBufferContent(RefPtr<FragmentedSharedBuffer>&&, const String& textEncodingName, bool withBase64Encode, String* result);
|
|
static Vector<CachedResource*> cachedResourcesForFrame(LocalFrame*);
|
|
static void resourceContent(Inspector::Protocol::ErrorString&, LocalFrame*, const URL&, String* result, bool* base64Encoded);
|
|
@@ -100,8 +109,11 @@ 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> navigate(const String& url);
|
|
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();
|
|
@@ -117,45 +129,65 @@ 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<Ref<Inspector::Protocol::Page::AXNode>> accessibilitySnapshot(const String& objectId);
|
|
+ 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 frameStartedLoading(LocalFrame&);
|
|
void frameStoppedLoading(LocalFrame&);
|
|
- void frameScheduledNavigation(Frame&, Seconds delay);
|
|
+ void frameScheduledNavigation(Frame&, Seconds delay, bool targetIsCurrentFrame);
|
|
void frameClearedScheduledNavigation(Frame&);
|
|
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);
|
|
+ bool doingAccessibilitySnapshot() const { return m_doingAccessibilitySnapshot; };
|
|
|
|
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*>&);
|
|
|
|
Ref<InspectorOverlay> protectedOverlay() const;
|
|
|
|
@@ -173,17 +205,22 @@ private:
|
|
RefPtr<Inspector::PageBackendDispatcher> m_backendDispatcher;
|
|
|
|
WeakRef<Page> m_inspectedPage;
|
|
+ Inspector::InjectedScriptManager& m_injectedScriptManager;
|
|
InspectorClient* m_client { nullptr };
|
|
WeakRef<InspectorOverlay> m_overlay;
|
|
|
|
- WeakHashMap<Frame, String> m_frameToIdentifier;
|
|
MemoryCompactRobinHoodHashMap<String, WeakPtr<Frame>> m_identifierToFrame;
|
|
HashMap<DocumentLoader*, String> m_loaderToIdentifier;
|
|
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_doingAccessibilitySnapshot { 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 0cc351959aaa96bd427ecbf75dd2ba51e730fc30..fb2b6c842a2e2b819ce746403e33550c0d4e2440 100644
|
|
--- a/Source/WebCore/inspector/agents/page/PageRuntimeAgent.cpp
|
|
+++ b/Source/WebCore/inspector/agents/page/PageRuntimeAgent.cpp
|
|
@@ -34,6 +34,7 @@
|
|
|
|
#include "DOMWrapperWorld.h"
|
|
#include "Document.h"
|
|
+#include "FrameLoader.h"
|
|
#include "InspectorPageAgent.h"
|
|
#include "InstrumentingAgents.h"
|
|
#include "JSDOMWindowCustom.h"
|
|
@@ -42,6 +43,7 @@
|
|
#include "Page.h"
|
|
#include "PageConsoleClient.h"
|
|
#include "ScriptController.h"
|
|
+#include "ScriptSourceCode.h"
|
|
#include "SecurityOrigin.h"
|
|
#include "UserGestureEmulationScope.h"
|
|
#include <JavaScriptCore/InjectedScript.h>
|
|
@@ -88,13 +90,74 @@ Inspector::Protocol::ErrorStringOr<void> PageRuntimeAgent::disable()
|
|
{
|
|
m_instrumentingAgents.setEnabledPageRuntimeAgent(nullptr);
|
|
|
|
+ m_bindingNames.clear();
|
|
+
|
|
return InspectorRuntimeAgent::disable();
|
|
}
|
|
|
|
void PageRuntimeAgent::frameNavigated(LocalFrame& frame)
|
|
{
|
|
+ auto* pageAgent = m_instrumentingAgents.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 = JSC::jsDynamicCast<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)));
|
|
+}
|
|
+
|
|
+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)
|
|
@@ -103,7 +166,26 @@ void PageRuntimeAgent::didClearWindowObjectInWorld(LocalFrame& frame, DOMWrapper
|
|
if (!pageAgent)
|
|
return;
|
|
|
|
+ if (pageAgent->ignoreDidClearWindowObject())
|
|
+ return;
|
|
+
|
|
+ if (world.isNormal()) {
|
|
+ for (const auto& name : m_bindingNames)
|
|
+ addBindingToFrame(frame, name);
|
|
+ }
|
|
+
|
|
+ pageAgent->setIgnoreDidClearWindowObject(true);
|
|
notifyContextCreated(pageAgent->frameId(&frame), frame.script().globalObject(world), world);
|
|
+ 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 +224,6 @@ void PageRuntimeAgent::reportExecutionContextCreation()
|
|
return;
|
|
|
|
m_inspectedPage->forEachLocalFrame([&](LocalFrame& frame) {
|
|
- if (!frame.script().canExecuteScripts(ReasonForCallingCanExecuteScripts::NotAboutToExecuteScript))
|
|
- return;
|
|
-
|
|
auto frameId = pageAgent->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 ab49ddd13fc6e1ed967cf501afb0230c1e795159..5ea038212cedc1a7b250588b616225edad6f643c 100644
|
|
--- a/Source/WebCore/inspector/agents/page/PageRuntimeAgent.h
|
|
+++ b/Source/WebCore/inspector/agents/page/PageRuntimeAgent.h
|
|
@@ -38,6 +38,7 @@
|
|
|
|
namespace JSC {
|
|
class CallFrame;
|
|
+class JSGlobalObject;
|
|
}
|
|
|
|
namespace WebCore {
|
|
@@ -59,10 +60,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>&&);
|
|
@@ -77,6 +81,7 @@ private:
|
|
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 8fb27c1045b8073d1487d5b61ccdec23a395bfd1..5008052f587ca4ba90da973c539188deb9551621 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:
|
|
@@ -80,6 +81,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 858e5866d005b40ce61b79c607c4e5530f23f582..ec3d856897d821aeb4ba8616598932b19b1bcf3f 100644
|
|
--- a/Source/WebCore/loader/DocumentLoader.cpp
|
|
+++ b/Source/WebCore/loader/DocumentLoader.cpp
|
|
@@ -773,8 +773,10 @@ void DocumentLoader::willSendRequest(ResourceRequest&& newRequest, const Resourc
|
|
if (!didReceiveRedirectResponse)
|
|
return completionHandler(WTFMove(newRequest));
|
|
|
|
+ InspectorInstrumentation::willCheckNavigationPolicy(*frame);
|
|
auto navigationPolicyCompletionHandler = [this, protectedThis = Ref { *this }, frame, completionHandler = WTFMove(completionHandler)] (ResourceRequest&& request, WeakPtr<FormState>&&, NavigationPolicyDecision navigationPolicyDecision) mutable {
|
|
m_waitingForNavigationPolicy = false;
|
|
+ InspectorInstrumentation::didCheckNavigationPolicy(*frame, navigationPolicyDecision != NavigationPolicyDecision::ContinueLoad);
|
|
switch (navigationPolicyDecision) {
|
|
case NavigationPolicyDecision::IgnoreLoad:
|
|
case NavigationPolicyDecision::LoadWillContinueInAnotherProcess:
|
|
@@ -1573,11 +1575,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 564f944a63868ced85f3c412a4df6dce8d257929..b2228742433ef7f478c20328e62e159d6a051b10 100644
|
|
--- a/Source/WebCore/loader/DocumentLoader.h
|
|
+++ b/Source/WebCore/loader/DocumentLoader.h
|
|
@@ -224,6 +224,8 @@ public:
|
|
|
|
WEBCORE_EXPORT virtual void detachFromFrame(LoadWillContinueInAnotherProcess);
|
|
|
|
+ void replacedByFragmentNavigation(LocalFrame&);
|
|
+
|
|
WEBCORE_EXPORT FrameLoader* frameLoader() const;
|
|
WEBCORE_EXPORT RefPtr<FrameLoader> protectedFrameLoader() const;
|
|
WEBCORE_EXPORT SubresourceLoader* mainResourceLoader() const;
|
|
diff --git a/Source/WebCore/loader/FrameLoader.cpp b/Source/WebCore/loader/FrameLoader.cpp
|
|
index 7073bb8cdc33fcffd7864505cc9dbeb96202e140..d7bf4bb0695d20eb8e479a703a331ba345fb213b 100644
|
|
--- a/Source/WebCore/loader/FrameLoader.cpp
|
|
+++ b/Source/WebCore/loader/FrameLoader.cpp
|
|
@@ -1319,6 +1319,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();
|
|
@@ -1850,6 +1851,7 @@ void FrameLoader::loadWithDocumentLoader(DocumentLoader* loader, FrameLoadType t
|
|
const String& httpMethod = loader->request().httpMethod();
|
|
|
|
if (shouldPerformFragmentNavigation(isFormSubmission, httpMethod, policyChecker().loadType(), newURL)) {
|
|
+ loader->replacedByFragmentNavigation(m_frame);
|
|
|
|
RefPtr oldDocumentLoader = m_documentLoader;
|
|
NavigationAction action { frame->protectedDocument().releaseNonNull(), loader->request(), InitiatedByMainFrame::Unknown, loader->isRequestFromClientOrUserInput(), policyChecker().loadType(), isFormSubmission };
|
|
@@ -1887,7 +1889,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, WTFMove(formState), [this, frame, allowNavigationToInvalidURL, completionHandler = completionHandlerCaller.release()] (const ResourceRequest& request, WeakPtr<FormState>&& weakFormState, NavigationPolicyDecision navigationPolicyDecision) mutable {
|
|
+ InspectorInstrumentation::didCheckNavigationPolicy(m_frame, navigationPolicyDecision != NavigationPolicyDecision::ContinueLoad);
|
|
continueLoadAfterNavigationPolicy(request, RefPtr { weakFormState.get() }.get(), navigationPolicyDecision, allowNavigationToInvalidURL);
|
|
completionHandler();
|
|
}, policyDecisionMode);
|
|
@@ -3178,10 +3182,15 @@ String FrameLoader::userAgent(const URL& url) const
|
|
|
|
String FrameLoader::navigatorPlatform() const
|
|
{
|
|
+ String platform;
|
|
+
|
|
auto customNavigatorPlatform = m_frame->mainFrame().customNavigatorPlatform();
|
|
if (!customNavigatorPlatform.isEmpty())
|
|
- return customNavigatorPlatform;
|
|
- return String();
|
|
+ platform = customNavigatorPlatform;
|
|
+
|
|
+ InspectorInstrumentation::applyPlatformOverride(m_frame, platform);
|
|
+
|
|
+ return platform;
|
|
}
|
|
|
|
void FrameLoader::dispatchOnloadEvents()
|
|
@@ -3638,6 +3647,8 @@ void FrameLoader::receivedMainResourceError(const ResourceError& error, LoadWill
|
|
checkCompleted();
|
|
if (frame->page())
|
|
checkLoadComplete(loadWillContinueInAnotherProcess);
|
|
+
|
|
+ InspectorInstrumentation::didReceiveMainResourceError(m_frame, error);
|
|
}
|
|
|
|
void FrameLoader::continueFragmentScrollAfterNavigationPolicy(const ResourceRequest& request, const SecurityOrigin* requesterOrigin, bool shouldContinue, NavigationHistoryBehavior historyHandling)
|
|
@@ -4522,9 +4533,6 @@ String FrameLoader::referrer() const
|
|
|
|
void FrameLoader::dispatchDidClearWindowObjectsInAllWorlds()
|
|
{
|
|
- if (!protectedFrame()->checkedScript()->canExecuteScripts(ReasonForCallingCanExecuteScripts::NotAboutToExecuteScript))
|
|
- return;
|
|
-
|
|
Vector<Ref<DOMWrapperWorld>> worlds;
|
|
ScriptController::getAllWorlds(worlds);
|
|
for (auto& world : worlds)
|
|
@@ -4534,13 +4542,12 @@ void FrameLoader::dispatchDidClearWindowObjectsInAllWorlds()
|
|
void FrameLoader::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld& world)
|
|
{
|
|
Ref frame = m_frame.get();
|
|
- if (!frame->checkedScript()->canExecuteScripts(ReasonForCallingCanExecuteScripts::NotAboutToExecuteScript) || !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 (frame->checkedScript()->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 1b34dfdd2a8e56beab49591a3517aba02c510ee6..768b895c132b73d935198cbfc2126a227a656b46 100644
|
|
--- a/Source/WebCore/loader/LoaderStrategy.h
|
|
+++ b/Source/WebCore/loader/LoaderStrategy.h
|
|
@@ -86,6 +86,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/NavigationScheduler.cpp b/Source/WebCore/loader/NavigationScheduler.cpp
|
|
index 5f70f737d06ced029e3b86a4dc93fd49e8ff4cae..15e6c42cbd4733b526493c3c7dfbea62e70ddb0c 100644
|
|
--- a/Source/WebCore/loader/NavigationScheduler.cpp
|
|
+++ b/Source/WebCore/loader/NavigationScheduler.cpp
|
|
@@ -806,7 +806,7 @@ void NavigationScheduler::startTimer()
|
|
|
|
Seconds delay = 1_s * m_redirect->delay();
|
|
m_timer.startOneShot(delay);
|
|
- InspectorInstrumentation::frameScheduledNavigation(frame, delay);
|
|
+ InspectorInstrumentation::frameScheduledNavigation(frame, delay, m_redirect->targetIsCurrentFrame());
|
|
m_redirect->didStartTimer(frame, m_timer); // m_redirect may be null on return (e.g. the client canceled the load)
|
|
}
|
|
|
|
diff --git a/Source/WebCore/loader/ProgressTracker.cpp b/Source/WebCore/loader/ProgressTracker.cpp
|
|
index 171c80cd90bdc8cc16c5e037b25f07faef0dec4e..0869f1be1699dd1548a2e4df6612d7fff42e3093 100644
|
|
--- a/Source/WebCore/loader/ProgressTracker.cpp
|
|
+++ b/Source/WebCore/loader/ProgressTracker.cpp
|
|
@@ -163,6 +163,8 @@ void ProgressTracker::progressCompleted(LocalFrame& frame)
|
|
if (!m_numProgressTrackedFrames || originatingProgressFrame == &frame)
|
|
finalProgressComplete();
|
|
|
|
+ InspectorInstrumentation::frameStoppedLoading(frame);
|
|
+
|
|
m_client->didChangeEstimatedProgress();
|
|
}
|
|
|
|
@@ -189,8 +191,6 @@ void ProgressTracker::finalProgressComplete()
|
|
m_client->progressFinished(*frame);
|
|
protectedPage()->progressFinished(*frame);
|
|
frame->protectedLoader()->loadProgressingStatusChanged();
|
|
-
|
|
- InspectorInstrumentation::frameStoppedLoading(*frame);
|
|
}
|
|
}
|
|
|
|
diff --git a/Source/WebCore/loader/cache/CachedResourceLoader.cpp b/Source/WebCore/loader/cache/CachedResourceLoader.cpp
|
|
index 6fc201b47f8bb970faba58fa195cc2964b42e45c..f77592b2664d435e00bcf83820e4e8ccb110aeb6 100644
|
|
--- a/Source/WebCore/loader/cache/CachedResourceLoader.cpp
|
|
+++ b/Source/WebCore/loader/cache/CachedResourceLoader.cpp
|
|
@@ -1166,8 +1166,11 @@ ResourceErrorOr<CachedResourceHandle<CachedResource>> CachedResourceLoader::requ
|
|
|
|
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.get()) {
|
|
bool madeHTTPS { request.resourceRequest().wasSchemeOptimisticallyUpgraded() };
|
|
@@ -1801,8 +1804,9 @@ Vector<Ref<SVGImage>> CachedResourceLoader::allCachedSVGImages() const
|
|
|
|
ResourceErrorOr<CachedResourceHandle<CachedResource>> CachedResourceLoader::preload(CachedResource::Type type, CachedResourceRequest&& request)
|
|
{
|
|
- if (InspectorInstrumentation::willIntercept(protectedFrame().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(protectedFrame().get(), request.resourceRequest()))
|
|
+ // return makeUnexpected(ResourceError { errorDomainWebKitInternal, 0, request.resourceRequest().url(), "Inspector intercept"_s });
|
|
|
|
RefPtr document = m_document.get();
|
|
ASSERT(document);
|
|
diff --git a/Source/WebCore/page/ChromeClient.h b/Source/WebCore/page/ChromeClient.h
|
|
index 5352cc44f68f9038f7bd64214853fae160f9ba9d..76a9c273cd758af99c2ed4645876b594c55b0ea1 100644
|
|
--- a/Source/WebCore/page/ChromeClient.h
|
|
+++ b/Source/WebCore/page/ChromeClient.h
|
|
@@ -362,7 +362,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 408ddc7c6541d80568d126ea5ecdb17caf7b10d3..d588b0c5003f8e39cb03cbf28258b7657d86a04f 100644
|
|
--- a/Source/WebCore/page/EventHandler.cpp
|
|
+++ b/Source/WebCore/page/EventHandler.cpp
|
|
@@ -4462,6 +4462,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;
|
|
|
|
@@ -5053,6 +5059,7 @@ static HitTestResult hitTestResultInFrame(LocalFrame* frame, const LayoutPoint&
|
|
return result;
|
|
}
|
|
|
|
+WTF_ALLOW_UNSAFE_BUFFER_USAGE_BEGIN
|
|
HandleUserInputEventResult EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
|
|
{
|
|
Ref frame = m_frame.get();
|
|
@@ -5126,7 +5133,7 @@ HandleUserInputEventResult EventHandler::handleTouchEvent(const PlatformTouchEve
|
|
|
|
// Increment the platform touch id by 1 to avoid storing a key of 0 in the hashmap.
|
|
unsigned touchPointTargetKey = point.id() + 1;
|
|
-#if PLATFORM(WPE)
|
|
+#if !ENABLE(IOS_TOUCH_EVENTS)
|
|
bool pointerCancelled = false;
|
|
#endif
|
|
RefPtr<EventTarget> touchTarget;
|
|
@@ -5173,7 +5180,7 @@ HandleUserInputEventResult EventHandler::handleTouchEvent(const PlatformTouchEve
|
|
// we also remove it from the map.
|
|
touchTarget = m_originatingTouchPointTargets.take(touchPointTargetKey);
|
|
|
|
-#if PLATFORM(WPE)
|
|
+#if !ENABLE(IOS_TOUCH_EVENTS)
|
|
HitTestResult result = hitTestResultAtPoint(pagePoint, hitType | HitTestRequest::Type::AllowChildFrameContent);
|
|
pointerTarget = result.targetElement();
|
|
pointerCancelled = (pointerTarget != touchTarget);
|
|
@@ -5196,7 +5203,7 @@ HandleUserInputEventResult EventHandler::handleTouchEvent(const PlatformTouchEve
|
|
if (!targetFrame)
|
|
continue;
|
|
|
|
-#if PLATFORM(WPE)
|
|
+#if !ENABLE(IOS_TOUCH_EVENTS)
|
|
// FIXME: WPE currently does not send touch stationary events, so create a naive TouchReleased PlatformTouchPoint
|
|
// on release if the hit test result changed since the previous TouchPressed or TouchMoved
|
|
if (pointState == PlatformTouchPoint::TouchReleased && pointerCancelled) {
|
|
@@ -5286,6 +5293,7 @@ HandleUserInputEventResult EventHandler::handleTouchEvent(const PlatformTouchEve
|
|
|
|
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 676ca3ed5df66159852331a1373cdef66295fd3f..ed0dbb2445822df19e3d013e1ebe2cbaaa8d20eb 100644
|
|
--- a/Source/WebCore/page/FocusController.cpp
|
|
+++ b/Source/WebCore/page/FocusController.cpp
|
|
@@ -586,13 +586,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/FrameSnapshotting.cpp b/Source/WebCore/page/FrameSnapshotting.cpp
|
|
index 0c099f95827d6f9fe307704ef9d7754fbb3d24f7..8e36dd7dca078f2de0c1733c8d462d17b2a3d5c4 100644
|
|
--- a/Source/WebCore/page/FrameSnapshotting.cpp
|
|
+++ b/Source/WebCore/page/FrameSnapshotting.cpp
|
|
@@ -111,7 +111,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;
|
|
|
|
@@ -130,6 +130,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;
|
|
@@ -138,7 +140,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 3ab70c27fef52f5d933cd2338a7c2f96e2debc88..39fc13df5ce132f8d028cd5039c607fe8963ddcf 100644
|
|
--- a/Source/WebCore/page/FrameSnapshotting.h
|
|
+++ b/Source/WebCore/page/FrameSnapshotting.h
|
|
@@ -56,6 +56,7 @@ enum class SnapshotFlags : uint16_t {
|
|
Accelerated = 1 << 8,
|
|
ExcludeReplacedContent = 1 << 9,
|
|
PaintWith3xBaseScale = 1 << 10,
|
|
+ OmitDeviceScaleFactor = 1 << 11,
|
|
};
|
|
|
|
struct SnapshotOptions {
|
|
diff --git a/Source/WebCore/page/History.cpp b/Source/WebCore/page/History.cpp
|
|
index adc6185687b6fcee3a49819d0149cde24a4485bf..a33e5db46933c514abce86e3f264de9b7e7c20d9 100644
|
|
--- a/Source/WebCore/page/History.cpp
|
|
+++ b/Source/WebCore/page/History.cpp
|
|
@@ -32,6 +32,7 @@
|
|
#include "FrameLoader.h"
|
|
#include "HistoryController.h"
|
|
#include "HistoryItem.h"
|
|
+#include "InspectorInstrumentation.h"
|
|
#include "LocalFrame.h"
|
|
#include "LocalFrameLoaderClient.h"
|
|
#include "Logging.h"
|
|
@@ -309,6 +310,8 @@ ExceptionOr<void> History::stateObjectAdded(RefPtr<SerializedScriptValue>&& data
|
|
}
|
|
|
|
frame->loader().updateURLAndHistory(fullURL, WTFMove(data), historyBehavior);
|
|
+ InspectorInstrumentation::didNavigateWithinPage(*frame);
|
|
+
|
|
return { };
|
|
}
|
|
|
|
diff --git a/Source/WebCore/page/LocalFrame.cpp b/Source/WebCore/page/LocalFrame.cpp
|
|
index 090657b2602a09708b6b859952b466fcca07f174..ce5df33671b65494c0d222ed9086d7fe828f3702 100644
|
|
--- a/Source/WebCore/page/LocalFrame.cpp
|
|
+++ b/Source/WebCore/page/LocalFrame.cpp
|
|
@@ -41,6 +41,7 @@
|
|
#include "CachedResourceLoader.h"
|
|
#include "Chrome.h"
|
|
#include "ChromeClient.h"
|
|
+#include "ComposedTreeIterator.h"
|
|
#include "DocumentLoader.h"
|
|
#include "DocumentType.h"
|
|
#include "Editing.h"
|
|
@@ -57,6 +58,7 @@
|
|
#include "FrameSelection.h"
|
|
#include "GraphicsContext.h"
|
|
#include "GraphicsLayer.h"
|
|
+#include "HTMLAreaElement.h"
|
|
#include "HTMLAttachmentElement.h"
|
|
#include "HTMLFormControlElement.h"
|
|
#include "HTMLFormElement.h"
|
|
@@ -79,6 +81,7 @@
|
|
#include "Logging.h"
|
|
#include "Navigator.h"
|
|
#include "NodeList.h"
|
|
+#include "NodeRenderStyle.h"
|
|
#include "NodeTraversal.h"
|
|
#include "Page.h"
|
|
#include "ProcessSyncClient.h"
|
|
@@ -202,6 +205,7 @@ LocalFrame::LocalFrame(Page& page, ClientCreator&& clientCreator, FrameIdentifie
|
|
|
|
void LocalFrame::init()
|
|
{
|
|
+ InspectorInstrumentation::frameAttached(this);
|
|
protectedLoader()->init();
|
|
}
|
|
|
|
@@ -431,7 +435,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)
|
|
@@ -1501,6 +1505,364 @@ void LocalFrame::reportResourceMonitoringWarning()
|
|
|
|
#endif
|
|
|
|
+#if !PLATFORM(IOS_FAMILY)
|
|
+
|
|
+void LocalFrame::betterApproximateNode(const IntPoint& testPoint, const NodeQualifier& nodeQualifierFunction, Node*& best, Node* failedNode, IntPoint& bestPoint, IntRect& bestRect, const IntRect& testRect)
|
|
+{
|
|
+ IntRect candidateRect;
|
|
+ constexpr OptionSet<HitTestRequest::Type> hitType { HitTestRequest::Type::ReadOnly, HitTestRequest::Type::Active, HitTestRequest::Type::DisallowUserAgentShadowContent, HitTestRequest::Type::AllowVisibleChildFrameContentOnly };
|
|
+ auto* candidate = nodeQualifierFunction(eventHandler().hitTestResultAtPoint(testPoint, hitType), failedNode, &candidateRect);
|
|
+
|
|
+ // Bail if we have no candidate, or the candidate is already equal to our current best node,
|
|
+ // or our candidate is the avoidedNode and there is a current best node.
|
|
+ if (!candidate || candidate == best)
|
|
+ return;
|
|
+
|
|
+ // The document should never be considered the best alternative.
|
|
+ if (candidate->isDocumentNode())
|
|
+ return;
|
|
+
|
|
+ if (best) {
|
|
+ IntRect bestIntersect = intersection(testRect, bestRect);
|
|
+ IntRect candidateIntersect = intersection(testRect, candidateRect);
|
|
+ // if the candidate intersection is smaller than the current best intersection, bail.
|
|
+ if (candidateIntersect.width() * candidateIntersect.height() <= bestIntersect.width() * bestIntersect.height())
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ // At this point we either don't have a previous best, or our current candidate has a better intersection.
|
|
+ best = candidate;
|
|
+ bestPoint = testPoint;
|
|
+ bestRect = candidateRect;
|
|
+}
|
|
+
|
|
+bool LocalFrame::hitTestResultAtViewportLocation(const FloatPoint& viewportLocation, HitTestResult& hitTestResult, IntPoint& center)
|
|
+{
|
|
+ if (!m_doc || !m_doc->renderView())
|
|
+ return false;
|
|
+
|
|
+ FrameView* view = m_view.get();
|
|
+ if (!view)
|
|
+ return false;
|
|
+
|
|
+ center = view->windowToContents(roundedIntPoint(viewportLocation));
|
|
+ constexpr OptionSet<HitTestRequest::Type> hitType { HitTestRequest::Type::ReadOnly, HitTestRequest::Type::Active, HitTestRequest::Type::DisallowUserAgentShadowContent, HitTestRequest::Type::AllowVisibleChildFrameContentOnly };
|
|
+ hitTestResult = eventHandler().hitTestResultAtPoint(center, hitType);
|
|
+ return true;
|
|
+}
|
|
+
|
|
+WTF_ALLOW_UNSAFE_BUFFER_USAGE_BEGIN
|
|
+Node* LocalFrame::qualifyingNodeAtViewportLocation(const FloatPoint& viewportLocation, FloatPoint& adjustedViewportLocation, const NodeQualifier& nodeQualifierFunction, ShouldApproximate shouldApproximate, ShouldFindRootEditableElement shouldFindRootEditableElement)
|
|
+{
|
|
+ adjustedViewportLocation = viewportLocation;
|
|
+
|
|
+ IntPoint testCenter;
|
|
+ HitTestResult candidateInfo;
|
|
+ if (!hitTestResultAtViewportLocation(viewportLocation, candidateInfo, testCenter))
|
|
+ return nullptr;
|
|
+
|
|
+ IntPoint bestPoint = testCenter;
|
|
+
|
|
+ // We have the candidate node at the location, check whether it or one of its ancestors passes
|
|
+ // the qualifier function, which typically checks if the node responds to a particular event type.
|
|
+ Node* approximateNode = nodeQualifierFunction(candidateInfo, 0, 0);
|
|
+
|
|
+ if (shouldFindRootEditableElement == ShouldFindRootEditableElement::Yes && approximateNode && approximateNode->isContentEditable()) {
|
|
+ // If we are in editable content, we look for the root editable element.
|
|
+ approximateNode = approximateNode->rootEditableElement();
|
|
+ // If we have a focusable node, there is no need to approximate.
|
|
+ if (approximateNode)
|
|
+ shouldApproximate = ShouldApproximate::No;
|
|
+ }
|
|
+
|
|
+ float scale = page() ? page()->pageScaleFactor() : 1;
|
|
+#if PLATFORM(IOS_FAMILY)
|
|
+ float ppiFactor = screenPPIFactor();
|
|
+#else
|
|
+ float ppiFactor = 326; // most popular iPhone PPI
|
|
+#endif
|
|
+
|
|
+ static const float unscaledSearchRadius = 15;
|
|
+ int searchRadius = static_cast<int>(unscaledSearchRadius * ppiFactor / scale);
|
|
+
|
|
+ if (approximateNode && shouldApproximate == ShouldApproximate::Yes) {
|
|
+ const float testOffsets[] = {
|
|
+ -.3f, -.3f,
|
|
+ -.6f, -.6f,
|
|
+ +.3f, +.3f,
|
|
+ -.9f, -.9f,
|
|
+ };
|
|
+
|
|
+ Node* originalApproximateNode = approximateNode;
|
|
+ for (unsigned n = 0; n < std::size(testOffsets); n += 2) {
|
|
+ IntSize testOffset(testOffsets[n] * searchRadius, testOffsets[n + 1] * searchRadius);
|
|
+ IntPoint testPoint = testCenter + testOffset;
|
|
+
|
|
+ constexpr OptionSet<HitTestRequest::Type> hitType { HitTestRequest::Type::ReadOnly, HitTestRequest::Type::Active, HitTestRequest::Type::DisallowUserAgentShadowContent, HitTestRequest::Type::AllowChildFrameContent };
|
|
+ auto candidateInfo = eventHandler().hitTestResultAtPoint(testPoint, hitType);
|
|
+ Node* candidateNode = nodeQualifierFunction(candidateInfo, 0, 0);
|
|
+ if (candidateNode && candidateNode->isDescendantOf(originalApproximateNode)) {
|
|
+ approximateNode = candidateNode;
|
|
+ bestPoint = testPoint;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ } else if (!approximateNode && shouldApproximate == ShouldApproximate::Yes) {
|
|
+ // Grab the closest parent element of our failed candidate node.
|
|
+ Node* candidate = candidateInfo.innerNode();
|
|
+ Node* failedNode = candidate;
|
|
+
|
|
+ while (candidate && !candidate->isElementNode())
|
|
+ candidate = candidate->parentInComposedTree();
|
|
+
|
|
+ if (candidate)
|
|
+ failedNode = candidate;
|
|
+
|
|
+ // The center point was tested earlier.
|
|
+ const float testOffsets[] = {
|
|
+ -.3f, -.3f,
|
|
+ +.3f, -.3f,
|
|
+ -.3f, +.3f,
|
|
+ +.3f, +.3f,
|
|
+ -.6f, -.6f,
|
|
+ +.6f, -.6f,
|
|
+ -.6f, +.6f,
|
|
+ +.6f, +.6f,
|
|
+ -1.f, 0,
|
|
+ +1.f, 0,
|
|
+ 0, +1.f,
|
|
+ 0, -1.f,
|
|
+ };
|
|
+ IntRect bestFrame;
|
|
+ IntRect testRect(testCenter, IntSize());
|
|
+ testRect.inflate(searchRadius);
|
|
+ int currentTestRadius = 0;
|
|
+ for (unsigned n = 0; n < std::size(testOffsets); n += 2) {
|
|
+ IntSize testOffset(testOffsets[n] * searchRadius, testOffsets[n + 1] * searchRadius);
|
|
+ IntPoint testPoint = testCenter + testOffset;
|
|
+ int testRadius = std::max(abs(testOffset.width()), abs(testOffset.height()));
|
|
+ if (testRadius > currentTestRadius) {
|
|
+ // Bail out with the best match within a radius
|
|
+ currentTestRadius = testRadius;
|
|
+ if (approximateNode)
|
|
+ break;
|
|
+ }
|
|
+ betterApproximateNode(testPoint, nodeQualifierFunction, approximateNode, failedNode, bestPoint, bestFrame, testRect);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (approximateNode) {
|
|
+ IntPoint p = m_view->contentsToWindow(bestPoint);
|
|
+ adjustedViewportLocation = p;
|
|
+ if (shouldFindRootEditableElement == ShouldFindRootEditableElement::Yes && approximateNode->isContentEditable()) {
|
|
+ // When in editable content, look for the root editable node again,
|
|
+ // since this could be the node found with the approximation.
|
|
+ approximateNode = approximateNode->rootEditableElement();
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return approximateNode;
|
|
+}
|
|
+WTF_ALLOW_UNSAFE_BUFFER_USAGE_END
|
|
+
|
|
+Node* LocalFrame::deepestNodeAtLocation(const FloatPoint& viewportLocation)
|
|
+{
|
|
+ IntPoint center;
|
|
+ HitTestResult hitTestResult;
|
|
+ if (!hitTestResultAtViewportLocation(viewportLocation, hitTestResult, center))
|
|
+ return nullptr;
|
|
+
|
|
+ return hitTestResult.innerNode();
|
|
+}
|
|
+
|
|
+static bool nodeIsMouseFocusable(Node& node)
|
|
+{
|
|
+ if (!is<Element>(node))
|
|
+ return false;
|
|
+
|
|
+ auto& element = downcast<Element>(node);
|
|
+ if (element.isMouseFocusable())
|
|
+ return true;
|
|
+
|
|
+ if (RefPtr shadowRoot = element.shadowRoot()) {
|
|
+ if (shadowRoot->delegatesFocus()) {
|
|
+ for (auto& node : composedTreeDescendants(element)) {
|
|
+ if (is<Element>(node) && downcast<Element>(node).isMouseFocusable())
|
|
+ return true;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return false;
|
|
+}
|
|
+
|
|
+static bool nodeWillRespondToMouseEvents(Node& node)
|
|
+{
|
|
+ return node.willRespondToMouseClickEvents() || node.willRespondToMouseMoveEvents() || nodeIsMouseFocusable(node);
|
|
+}
|
|
+
|
|
+Node* LocalFrame::approximateNodeAtViewportLocationLegacy(const FloatPoint& viewportLocation, FloatPoint& adjustedViewportLocation)
|
|
+{
|
|
+ // This function is only used for UIWebView.
|
|
+ auto&& ancestorRespondingToClickEvents = [](const HitTestResult& hitTestResult, Node* terminationNode, IntRect* nodeBounds) -> Node* {
|
|
+ bool bodyHasBeenReached = false;
|
|
+ bool pointerCursorStillValid = true;
|
|
+
|
|
+ if (nodeBounds)
|
|
+ *nodeBounds = IntRect();
|
|
+
|
|
+ auto node = hitTestResult.innerNode();
|
|
+ if (!node)
|
|
+ return nullptr;
|
|
+
|
|
+ Node* pointerCursorNode = nullptr;
|
|
+ for (; node && node != terminationNode; node = node->parentInComposedTree()) {
|
|
+ // We only accept pointer nodes before reaching the body tag.
|
|
+ if (node->hasTagName(HTMLNames::bodyTag)) {
|
|
+ // Make sure we cover the case of an empty editable body.
|
|
+ if (!pointerCursorNode && node->isContentEditable())
|
|
+ pointerCursorNode = node;
|
|
+ bodyHasBeenReached = true;
|
|
+ pointerCursorStillValid = false;
|
|
+ }
|
|
+
|
|
+ // If we already have a pointer, and we reach a table, don't accept it.
|
|
+ if (pointerCursorNode && (node->hasTagName(HTMLNames::tableTag) || node->hasTagName(HTMLNames::tbodyTag)))
|
|
+ pointerCursorStillValid = false;
|
|
+
|
|
+ // If we haven't reached the body, and we are still paying attention to pointer cursors, and the node has a pointer cursor.
|
|
+ if (pointerCursorStillValid && node->renderStyle() && node->renderStyle()->cursor() == CursorType::Pointer)
|
|
+ pointerCursorNode = node;
|
|
+ else if (pointerCursorNode) {
|
|
+ // We want the lowest unbroken chain of pointer cursors.
|
|
+ pointerCursorStillValid = false;
|
|
+ }
|
|
+
|
|
+ if (nodeWillRespondToMouseEvents(*node)) {
|
|
+ // If we're at the body or higher, use the pointer cursor node (which may be null).
|
|
+ if (bodyHasBeenReached)
|
|
+ node = pointerCursorNode;
|
|
+
|
|
+ // If we are interested about the frame, use it.
|
|
+ if (nodeBounds) {
|
|
+ // This is a check to see whether this node is an area element. The only way this can happen is if this is the first check.
|
|
+ if (node == hitTestResult.innerNode() && node != hitTestResult.innerNonSharedNode() && is<HTMLAreaElement>(*node))
|
|
+ *nodeBounds = snappedIntRect(downcast<HTMLAreaElement>(*node).computeRect(hitTestResult.innerNonSharedNode()->renderer()));
|
|
+ else if (node && node->renderer())
|
|
+ *nodeBounds = node->renderer()->absoluteBoundingBoxRect(true);
|
|
+ }
|
|
+
|
|
+ return node;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return nullptr;
|
|
+ };
|
|
+
|
|
+ return qualifyingNodeAtViewportLocation(viewportLocation, adjustedViewportLocation, WTFMove(ancestorRespondingToClickEvents), ShouldApproximate::Yes);
|
|
+}
|
|
+
|
|
+static inline NodeQualifier ancestorRespondingToClickEventsNodeQualifier(SecurityOrigin* securityOrigin = nullptr)
|
|
+{
|
|
+ return [securityOrigin](const HitTestResult& hitTestResult, Node* terminationNode, IntRect* nodeBounds) -> Node* {
|
|
+ if (nodeBounds)
|
|
+ *nodeBounds = IntRect();
|
|
+
|
|
+ auto node = hitTestResult.innerNode();
|
|
+ if (!node || (securityOrigin && !securityOrigin->isSameOriginAs(node->document().securityOrigin())))
|
|
+ return nullptr;
|
|
+
|
|
+ for (; node && node != terminationNode; node = node->parentInComposedTree()) {
|
|
+ if (nodeWillRespondToMouseEvents(*node)) {
|
|
+ // If we are interested about the frame, use it.
|
|
+ if (nodeBounds) {
|
|
+ // This is a check to see whether this node is an area element. The only way this can happen is if this is the first check.
|
|
+ if (node == hitTestResult.innerNode() && node != hitTestResult.innerNonSharedNode() && is<HTMLAreaElement>(*node))
|
|
+ *nodeBounds = snappedIntRect(downcast<HTMLAreaElement>(*node).computeRect(hitTestResult.innerNonSharedNode()->renderer()));
|
|
+ else if (node && node->renderer())
|
|
+ *nodeBounds = node->renderer()->absoluteBoundingBoxRect(true);
|
|
+ }
|
|
+
|
|
+ return node;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return nullptr;
|
|
+ };
|
|
+}
|
|
+
|
|
+Node* LocalFrame::nodeRespondingToClickEvents(const FloatPoint& viewportLocation, FloatPoint& adjustedViewportLocation, SecurityOrigin* securityOrigin)
|
|
+{
|
|
+ return qualifyingNodeAtViewportLocation(viewportLocation, adjustedViewportLocation, ancestorRespondingToClickEventsNodeQualifier(securityOrigin), ShouldApproximate::Yes);
|
|
+}
|
|
+
|
|
+Node* LocalFrame::nodeRespondingToDoubleClickEvent(const FloatPoint& viewportLocation, FloatPoint& adjustedViewportLocation)
|
|
+{
|
|
+ auto&& ancestorRespondingToDoubleClickEvent = [](const HitTestResult& hitTestResult, Node* terminationNode, IntRect* nodeBounds) -> Node* {
|
|
+ if (nodeBounds)
|
|
+ *nodeBounds = IntRect();
|
|
+
|
|
+ auto* node = hitTestResult.innerNode();
|
|
+ if (!node)
|
|
+ return nullptr;
|
|
+
|
|
+ for (; node && node != terminationNode; node = node->parentInComposedTree()) {
|
|
+ if (!node->hasEventListeners(eventNames().dblclickEvent))
|
|
+ continue;
|
|
+#if ENABLE(TOUCH_EVENTS)
|
|
+ if (!node->allowsDoubleTapGesture())
|
|
+ continue;
|
|
+#endif
|
|
+ if (nodeBounds && node->renderer())
|
|
+ *nodeBounds = node->renderer()->absoluteBoundingBoxRect(true);
|
|
+ return node;
|
|
+ }
|
|
+ return nullptr;
|
|
+ };
|
|
+
|
|
+ return qualifyingNodeAtViewportLocation(viewportLocation, adjustedViewportLocation, WTFMove(ancestorRespondingToDoubleClickEvent), ShouldApproximate::Yes);
|
|
+}
|
|
+
|
|
+Node* LocalFrame::nodeRespondingToInteraction(const FloatPoint& viewportLocation, FloatPoint& adjustedViewportLocation)
|
|
+{
|
|
+ return qualifyingNodeAtViewportLocation(viewportLocation, adjustedViewportLocation, ancestorRespondingToClickEventsNodeQualifier(), ShouldApproximate::Yes, ShouldFindRootEditableElement::No);
|
|
+}
|
|
+
|
|
+Node* LocalFrame::nodeRespondingToScrollWheelEvents(const FloatPoint& viewportLocation)
|
|
+{
|
|
+ auto&& ancestorRespondingToScrollWheelEvents = [](const HitTestResult& hitTestResult, Node* terminationNode, IntRect* nodeBounds) -> Node* {
|
|
+ if (nodeBounds)
|
|
+ *nodeBounds = IntRect();
|
|
+
|
|
+ Node* scrollingAncestor = nullptr;
|
|
+ for (Node* node = hitTestResult.innerNode(); node && node != terminationNode && !node->hasTagName(HTMLNames::bodyTag); node = node->parentNode()) {
|
|
+ RenderObject* renderer = node->renderer();
|
|
+ if (!renderer)
|
|
+ continue;
|
|
+
|
|
+ if ((renderer->isRenderTextControlSingleLine() || renderer->isRenderTextControlMultiLine()) && downcast<RenderTextControl>(*renderer).canScroll()) {
|
|
+ scrollingAncestor = node;
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ auto& style = renderer->style();
|
|
+
|
|
+ if (renderer->hasNonVisibleOverflow()
|
|
+ && (style.overflowY() == Overflow::Auto || style.overflowY() == Overflow::Scroll
|
|
+ || style.overflowX() == Overflow::Auto || style.overflowX() == Overflow::Scroll)) {
|
|
+ scrollingAncestor = node;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return scrollingAncestor;
|
|
+ };
|
|
+
|
|
+ FloatPoint adjustedViewportLocation;
|
|
+ return qualifyingNodeAtViewportLocation(viewportLocation, adjustedViewportLocation, WTFMove(ancestorRespondingToScrollWheelEvents), ShouldApproximate::No);
|
|
+}
|
|
+
|
|
+#endif // !PLATFORM(IOS_FAMILY)
|
|
+
|
|
} // namespace WebCore
|
|
|
|
#undef FRAME_RELEASE_LOG_ERROR
|
|
diff --git a/Source/WebCore/page/LocalFrame.h b/Source/WebCore/page/LocalFrame.h
|
|
index 82f67e2e21e64b95800696a6bb22f15298866979..26a1bc0736e00964a5beb151bb53c430c36e029d 100644
|
|
--- a/Source/WebCore/page/LocalFrame.h
|
|
+++ b/Source/WebCore/page/LocalFrame.h
|
|
@@ -28,8 +28,10 @@
|
|
#pragma once
|
|
|
|
#include "AdjustViewSizeOrNot.h"
|
|
+#include "DOMPasteAccess.h"
|
|
#include "Document.h"
|
|
#include "Frame.h"
|
|
+#include "IntDegrees.h"
|
|
#include "ScrollTypes.h"
|
|
#include "UserScriptTypes.h"
|
|
#include <wtf/CheckedRef.h>
|
|
@@ -116,8 +118,8 @@ enum {
|
|
};
|
|
|
|
enum OverflowScrollAction { DoNotPerformOverflowScroll, PerformOverflowScroll };
|
|
-using NodeQualifier = Function<Node* (const HitTestResult&, Node* terminationNode, IntRect* nodeBounds)>;
|
|
#endif
|
|
+using NodeQualifier = Function<Node* (const HitTestResult&, Node* terminationNode, IntRect* nodeBounds)>;
|
|
|
|
class LocalFrame final : public Frame {
|
|
public:
|
|
@@ -227,10 +229,6 @@ public:
|
|
WEBCORE_EXPORT DataDetectionResultsStorage& dataDetectionResults();
|
|
#endif
|
|
|
|
-#if PLATFORM(IOS_FAMILY)
|
|
- const ViewportArguments& viewportArguments() const;
|
|
- WEBCORE_EXPORT void setViewportArguments(const ViewportArguments&);
|
|
-
|
|
WEBCORE_EXPORT Node* deepestNodeAtLocation(const FloatPoint& viewportLocation);
|
|
WEBCORE_EXPORT Node* nodeRespondingToClickEvents(const FloatPoint& viewportLocation, FloatPoint& adjustedViewportLocation, SecurityOrigin* = nullptr);
|
|
WEBCORE_EXPORT Node* nodeRespondingToDoubleClickEvent(const FloatPoint& viewportLocation, FloatPoint& adjustedViewportLocation);
|
|
@@ -238,6 +236,10 @@ public:
|
|
WEBCORE_EXPORT Node* nodeRespondingToScrollWheelEvents(const FloatPoint& viewportLocation);
|
|
WEBCORE_EXPORT Node* approximateNodeAtViewportLocationLegacy(const FloatPoint& viewportLocation, FloatPoint& adjustedViewportLocation);
|
|
|
|
+#if PLATFORM(IOS_FAMILY)
|
|
+ const ViewportArguments& viewportArguments() const;
|
|
+ WEBCORE_EXPORT void setViewportArguments(const ViewportArguments&);
|
|
+
|
|
WEBCORE_EXPORT NSArray *wordsInCurrentParagraph() const;
|
|
WEBCORE_EXPORT CGRect renderRectForPoint(CGPoint, bool* isReplaced, float* fontSize) const;
|
|
|
|
@@ -305,6 +307,7 @@ public:
|
|
|
|
WEBCORE_EXPORT FloatSize screenSize() const;
|
|
void setOverrideScreenSize(FloatSize&&);
|
|
+ bool hasScreenSizeOverride() const { return !m_overrideScreenSize.isEmpty(); }
|
|
|
|
void selfOnlyRef();
|
|
void selfOnlyDeref();
|
|
@@ -373,7 +376,6 @@ private:
|
|
#if ENABLE(DATA_DETECTION)
|
|
std::unique_ptr<DataDetectionResultsStorage> m_dataDetectionResults;
|
|
#endif
|
|
-#if PLATFORM(IOS_FAMILY)
|
|
void betterApproximateNode(const IntPoint& testPoint, const NodeQualifier&, Node*& best, Node* failedNode, IntPoint& bestPoint, IntRect& bestRect, const IntRect& testRect);
|
|
bool hitTestResultAtViewportLocation(const FloatPoint& viewportLocation, HitTestResult&, IntPoint& center);
|
|
|
|
@@ -381,6 +383,7 @@ private:
|
|
enum class ShouldFindRootEditableElement : bool { No, Yes };
|
|
Node* qualifyingNodeAtViewportLocation(const FloatPoint& viewportLocation, FloatPoint& adjustedViewportLocation, const NodeQualifier&, ShouldApproximate, ShouldFindRootEditableElement = ShouldFindRootEditableElement::Yes);
|
|
|
|
+#if PLATFORM(IOS_FAMILY)
|
|
void setTimersPausedInternal(bool);
|
|
|
|
ViewportArguments m_viewportArguments;
|
|
diff --git a/Source/WebCore/page/Page.cpp b/Source/WebCore/page/Page.cpp
|
|
index 916d2cc402fb668d19143022b5e3c58838a8920d..0f389d033511bdc7ef92fb4bd8a7525f92a23daa 100644
|
|
--- a/Source/WebCore/page/Page.cpp
|
|
+++ b/Source/WebCore/page/Page.cpp
|
|
@@ -655,6 +655,45 @@ void Page::setOverrideViewportArguments(const std::optional<ViewportArguments>&
|
|
localTopDocument->updateViewportArguments();
|
|
}
|
|
|
|
+FloatSize Page::screenSize()
|
|
+{
|
|
+ auto* localMainFrame = dynamicDowncast<LocalFrame>(mainFrame());
|
|
+ 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;
|
|
+ auto* localMainFrame = dynamicDowncast<LocalFrame>(mainFrame());
|
|
+ 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;
|
|
+
|
|
+ auto* localMainFrame = dynamicDowncast<LocalFrame>(mainFrame());
|
|
+ if (localMainFrame)
|
|
+ localMainFrame->orientationChanged();
|
|
+}
|
|
+#endif
|
|
+
|
|
ScrollingCoordinator* Page::scrollingCoordinator()
|
|
{
|
|
if (!m_scrollingCoordinator && m_settings->scrollingCoordinatorEnabled()) {
|
|
@@ -4211,6 +4250,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 11c3b26d33342999041fb464ad487cd7dc0e6891..41bfb065fe96f08c21f296e2565770dbf81d163e 100644
|
|
--- a/Source/WebCore/page/Page.h
|
|
+++ b/Source/WebCore/page/Page.h
|
|
@@ -365,6 +365,9 @@ public:
|
|
const ViewportArguments* overrideViewportArguments() const { 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();
|
|
WEBCORE_EXPORT Ref<PluginData> protectedPluginData();
|
|
@@ -462,6 +465,10 @@ public:
|
|
#if ENABLE(DRAG_SUPPORT)
|
|
DragController& dragController() { return m_dragController.get(); }
|
|
const DragController& dragController() const { 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; }
|
|
WEBCORE_EXPORT CheckedRef<FocusController> checkedFocusController() const;
|
|
@@ -647,6 +654,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; }
|
|
@@ -1116,6 +1127,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
|
|
@@ -1392,6 +1408,9 @@ private:
|
|
|
|
#if ENABLE(DRAG_SUPPORT)
|
|
const UniqueRef<DragController> m_dragController;
|
|
+#if PLATFORM(MAC)
|
|
+ String m_overrideDragPasteboardName;
|
|
+#endif
|
|
#endif
|
|
std::unique_ptr<FocusController> m_focusController;
|
|
#if ENABLE(CONTEXT_MENUS)
|
|
@@ -1469,6 +1488,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 };
|
|
@@ -1651,6 +1672,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/PageConsoleClient.cpp b/Source/WebCore/page/PageConsoleClient.cpp
|
|
index 33ef23f456d389c876f7d66732a1ae9bb2ed7662..f0d38ba2208975e9a31f634096caf20ecb7340be 100644
|
|
--- a/Source/WebCore/page/PageConsoleClient.cpp
|
|
+++ b/Source/WebCore/page/PageConsoleClient.cpp
|
|
@@ -456,4 +456,9 @@ Ref<Page> PageConsoleClient::protectedPage() const
|
|
return m_page.get();
|
|
}
|
|
|
|
+void PageConsoleClient::bindingCalled(JSC::JSGlobalObject* globalObject, const String& name, const String& arg)
|
|
+{
|
|
+ InspectorInstrumentation::bindingCalled(m_page, globalObject, name, arg);
|
|
+}
|
|
+
|
|
} // namespace WebCore
|
|
diff --git a/Source/WebCore/page/PageConsoleClient.h b/Source/WebCore/page/PageConsoleClient.h
|
|
index 153fc36199f26adbfb61cbef6744ffe31a68b951..cc667e06700013fd5e994467e19536d2e4cab189 100644
|
|
--- a/Source/WebCore/page/PageConsoleClient.h
|
|
+++ b/Source/WebCore/page/PageConsoleClient.h
|
|
@@ -86,6 +86,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;
|
|
|
|
Ref<Page> protectedPage() const;
|
|
|
|
diff --git a/Source/WebCore/page/PointerCaptureController.cpp b/Source/WebCore/page/PointerCaptureController.cpp
|
|
index ad7f92bf398348be7823247931ce71d5a1c2296e..accabfd4f44199f026ca7bb9ea058bfe3d0ad8f8 100644
|
|
--- a/Source/WebCore/page/PointerCaptureController.cpp
|
|
+++ b/Source/WebCore/page/PointerCaptureController.cpp
|
|
@@ -205,7 +205,7 @@ bool PointerCaptureController::preventsCompatibilityMouseEventsForIdentifier(Poi
|
|
return capturingData && capturingData->preventsCompatibilityMouseEvents;
|
|
}
|
|
|
|
-#if ENABLE(TOUCH_EVENTS) && (PLATFORM(IOS_FAMILY) || PLATFORM(WPE))
|
|
+#if ENABLE(TOUCH_EVENTS)
|
|
static bool hierarchyHasCapturingEventListeners(Element* target, const AtomString& eventName)
|
|
{
|
|
for (RefPtr<ContainerNode> currentNode = target; currentNode; currentNode = currentNode->parentInComposedTree()) {
|
|
@@ -555,7 +555,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))
|
|
+#if ENABLE(TOUCH_EVENTS)
|
|
capturingData->previousTarget = nullptr;
|
|
#endif
|
|
|
|
diff --git a/Source/WebCore/page/PointerCaptureController.h b/Source/WebCore/page/PointerCaptureController.h
|
|
index b7e3f7cbd54e6ba9419de1bbf70594f3c2771d41..abb08ab5f5a979d7a40af30a27fddfe163db2b12 100644
|
|
--- a/Source/WebCore/page/PointerCaptureController.h
|
|
+++ b/Source/WebCore/page/PointerCaptureController.h
|
|
@@ -60,7 +60,7 @@ public:
|
|
|
|
RefPtr<PointerEvent> pointerEventForMouseEvent(const MouseEvent&, PointerID, const String& pointerType);
|
|
|
|
-#if ENABLE(TOUCH_EVENTS) && (PLATFORM(IOS_FAMILY) || PLATFORM(WPE))
|
|
+#if ENABLE(TOUCH_EVENTS)
|
|
void dispatchEventForTouchAtIndex(EventTarget&, const PlatformTouchEvent&, unsigned, bool isPrimary, WindowProxy&, const IntPoint&);
|
|
#endif
|
|
|
|
@@ -81,12 +81,12 @@ private:
|
|
WeakPtr<Document, WeakPtrImplWithEventTargetData> activeDocument;
|
|
RefPtr<Element> pendingTargetOverride;
|
|
RefPtr<Element> targetOverride;
|
|
-#if ENABLE(TOUCH_EVENTS) && (PLATFORM(IOS_FAMILY) || PLATFORM(WPE))
|
|
+#if ENABLE(TOUCH_EVENTS)
|
|
RefPtr<Element> previousTarget;
|
|
#endif
|
|
bool hasAnyElement() const {
|
|
return pendingTargetOverride || targetOverride
|
|
-#if ENABLE(TOUCH_EVENTS) && (PLATFORM(IOS_FAMILY) || PLATFORM(WPE))
|
|
+#if ENABLE(TOUCH_EVENTS)
|
|
|| previousTarget
|
|
#endif
|
|
;
|
|
diff --git a/Source/WebCore/page/Screen.cpp b/Source/WebCore/page/Screen.cpp
|
|
index 24ed7c019bea4df52f2883db0e40bdbc2dc74ebd..a788f534d9e0e8124153c7f380b4fdb232c51a1a 100644
|
|
--- a/Source/WebCore/page/Screen.cpp
|
|
+++ b/Source/WebCore/page/Screen.cpp
|
|
@@ -124,6 +124,9 @@ int Screen::availLeft() const
|
|
if (shouldApplyScreenFingerprintingProtections(*frame))
|
|
return 0;
|
|
|
|
+ if (frame->hasScreenSizeOverride())
|
|
+ return 0;
|
|
+
|
|
return static_cast<int>(screenAvailableRect(frame->protectedView().get()).x());
|
|
}
|
|
|
|
@@ -139,6 +142,9 @@ int Screen::availTop() const
|
|
if (shouldApplyScreenFingerprintingProtections(*frame))
|
|
return 0;
|
|
|
|
+ if (frame->hasScreenSizeOverride())
|
|
+ return 0;
|
|
+
|
|
return static_cast<int>(screenAvailableRect(frame->protectedView().get()).y());
|
|
}
|
|
|
|
@@ -154,6 +160,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(frame->protectedView().get()).height());
|
|
}
|
|
|
|
@@ -169,6 +178,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(frame->protectedView().get()).width());
|
|
}
|
|
|
|
diff --git a/Source/WebCore/page/csp/ContentSecurityPolicy.cpp b/Source/WebCore/page/csp/ContentSecurityPolicy.cpp
|
|
index 51933cf69017936dfa08823d4a1a778d3d64db71..2101a8ab75fc7adf5ebcbf245e2083a2b750271b 100644
|
|
--- a/Source/WebCore/page/csp/ContentSecurityPolicy.cpp
|
|
+++ b/Source/WebCore/page/csp/ContentSecurityPolicy.cpp
|
|
@@ -348,6 +348,8 @@ bool ContentSecurityPolicy::allowContentSecurityPolicySourceStarToMatchAnyProtoc
|
|
template<typename Predicate, typename... Args>
|
|
typename std::enable_if<!std::is_convertible<Predicate, ContentSecurityPolicy::ViolatedDirectiveCallback>::value, bool>::type ContentSecurityPolicy::allPoliciesWithDispositionAllow(Disposition disposition, Predicate&& predicate, Args&&... args) const
|
|
{
|
|
+ if (InspectorInstrumentation::shouldBypassCSP(m_scriptExecutionContext.get()))
|
|
+ return true;
|
|
bool isReportOnly = disposition == ContentSecurityPolicy::Disposition::ReportOnly;
|
|
for (auto& policy : m_policies) {
|
|
if (policy->isReportOnly() != isReportOnly)
|
|
@@ -361,6 +363,8 @@ typename std::enable_if<!std::is_convertible<Predicate, ContentSecurityPolicy::V
|
|
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) {
|
|
@@ -377,6 +381,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)(std::forward<Args>(args)...)) {
|
|
diff --git a/Source/WebCore/page/wpe/DragControllerWPE.cpp b/Source/WebCore/page/wpe/DragControllerWPE.cpp
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..803239911006cfb3b03ea911c003f2d233f67600
|
|
--- /dev/null
|
|
+++ b/Source/WebCore/page/wpe/DragControllerWPE.cpp
|
|
@@ -0,0 +1,80 @@
|
|
+/*
|
|
+ * 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 "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/Cairo.cmake b/Source/WebCore/platform/Cairo.cmake
|
|
index 29492dd39b08db28aad2bf2439eb3e2bbcf25ad7..2b603cb8440b1b5057c87fcbd6909c61bae4ceb8 100644
|
|
--- a/Source/WebCore/platform/Cairo.cmake
|
|
+++ b/Source/WebCore/platform/Cairo.cmake
|
|
@@ -14,6 +14,7 @@ list(APPEND WebCore_PRIVATE_FRAMEWORK_HEADERS
|
|
platform/graphics/cairo/ImageBufferCairoBackend.h
|
|
platform/graphics/cairo/ImageBufferCairoImageSurfaceBackend.h
|
|
platform/graphics/cairo/ImageBufferCairoSurfaceBackend.h
|
|
+ platform/graphics/cairo/ImageBufferUtilitiesCairo.h
|
|
platform/graphics/cairo/RefPtrCairo.h
|
|
)
|
|
|
|
diff --git a/Source/WebCore/platform/DragData.h b/Source/WebCore/platform/DragData.h
|
|
index 2ebb3221cb3818f20abc7b7c3307ea7644f49d49..e0bffb6f5adee0b0a202340f633c2def1955b384 100644
|
|
--- a/Source/WebCore/platform/DragData.h
|
|
+++ b/Source/WebCore/platform/DragData.h
|
|
@@ -47,7 +47,7 @@ typedef void* DragDataRef;
|
|
|
|
#elif PLATFORM(WIN)
|
|
typedef struct IDataObject* DragDataRef;
|
|
-#elif PLATFORM(GTK)
|
|
+#elif PLATFORM(GTK) || PLATFORM(WPE)
|
|
namespace WebCore {
|
|
class SelectionData;
|
|
}
|
|
@@ -92,8 +92,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
|
|
@@ -143,7 +143,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/DragImage.cpp b/Source/WebCore/platform/DragImage.cpp
|
|
index 2f4e02e783ac512aeb76e0abe7e253b57bfda937..94e0c9335720324a746f300a26b17a28eedf2197 100644
|
|
--- a/Source/WebCore/platform/DragImage.cpp
|
|
+++ b/Source/WebCore/platform/DragImage.cpp
|
|
@@ -280,7 +280,7 @@ DragImage::~DragImage()
|
|
deleteDragImage(m_dragImageRef);
|
|
}
|
|
|
|
-#if !PLATFORM(COCOA) && !PLATFORM(GTK) && !PLATFORM(WIN)
|
|
+#if !PLATFORM(COCOA) && !PLATFORM(GTK) && !PLATFORM(WIN) && !PLATFORM(WPE)
|
|
|
|
IntSize dragImageSize(DragImageRef)
|
|
{
|
|
diff --git a/Source/WebCore/platform/Pasteboard.h b/Source/WebCore/platform/Pasteboard.h
|
|
index 1b1a1147d4948e9281a114281e95d57d3b0ccf27..e21ccb98542cc582ad2489d301cb29c2b0c03f4b 100644
|
|
--- a/Source/WebCore/platform/Pasteboard.h
|
|
+++ b/Source/WebCore/platform/Pasteboard.h
|
|
@@ -46,7 +46,7 @@ OBJC_CLASS NSString;
|
|
OBJC_CLASS NSArray;
|
|
#endif
|
|
|
|
-#if PLATFORM(GTK)
|
|
+#if PLATFORM(GTK) || PLATFORM(WPE)
|
|
#include "SelectionData.h"
|
|
#endif
|
|
|
|
@@ -108,7 +108,7 @@ struct PasteboardURL {
|
|
#if PLATFORM(MAC)
|
|
String userVisibleForm;
|
|
#endif
|
|
-#if PLATFORM(GTK)
|
|
+#if PLATFORM(GTK) || PLATFORM(WPE)
|
|
String markup;
|
|
#endif
|
|
};
|
|
@@ -197,6 +197,11 @@ public:
|
|
#endif
|
|
#endif
|
|
|
|
+#if PLATFORM(WPE) && ENABLE(DRAG_SUPPORT)
|
|
+ explicit Pasteboard(std::unique_ptr<PasteboardContext>&&, SelectionData&);
|
|
+ explicit Pasteboard(std::unique_ptr<PasteboardContext>&&, SelectionData&&);
|
|
+#endif
|
|
+
|
|
#if PLATFORM(WIN)
|
|
explicit Pasteboard(std::unique_ptr<PasteboardContext>&&, IDataObject*);
|
|
explicit Pasteboard(std::unique_ptr<PasteboardContext>&&, WCDataObject*);
|
|
@@ -264,6 +269,12 @@ public:
|
|
int64_t changeCount() const;
|
|
#endif
|
|
|
|
+#if PLATFORM(WPE)
|
|
+ const SelectionData& selectionData() const {
|
|
+ return *m_selectionData;
|
|
+ }
|
|
+#endif
|
|
+
|
|
#if PLATFORM(IOS_FAMILY)
|
|
explicit Pasteboard(std::unique_ptr<PasteboardContext>&&, int64_t changeCount);
|
|
explicit Pasteboard(std::unique_ptr<PasteboardContext>&&, const String& pasteboardName);
|
|
@@ -306,6 +317,7 @@ public:
|
|
COMPtr<IDataObject> dataObject() const { return m_dataObject; }
|
|
WEBCORE_EXPORT void setExternalDataObject(IDataObject*);
|
|
const DragDataMap& dragDataMap() const { 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.
|
|
@@ -358,6 +370,10 @@ private:
|
|
int64_t m_changeCount { 0 };
|
|
#endif
|
|
|
|
+#if PLATFORM(WPE)
|
|
+ std::optional<SelectionData> m_selectionData;
|
|
+#endif
|
|
+
|
|
#if PLATFORM(COCOA)
|
|
String m_pasteboardName;
|
|
int64_t m_changeCount;
|
|
@@ -373,6 +389,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 63ffd6ca32c3baee03db2a9419c4f7e9de45388a..c60c7a8d1f110472117c8c4e969fd05fef71f908 100644
|
|
--- a/Source/WebCore/platform/PlatformKeyboardEvent.h
|
|
+++ b/Source/WebCore/platform/PlatformKeyboardEvent.h
|
|
@@ -135,6 +135,7 @@ namespace WebCore {
|
|
static String keyCodeForHardwareKeyCode(unsigned);
|
|
static String keyIdentifierForGdkKeyCode(unsigned);
|
|
static int windowsKeyCodeForGdkKeyCode(unsigned);
|
|
+ static unsigned gdkKeyCodeForWindowsKeyCode(int);
|
|
static String singleCharacterString(unsigned);
|
|
#endif
|
|
|
|
@@ -143,6 +144,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 ef0abc9a93e878897ffc9d2497a3da0fca5b37b7..8868e20e3720ce33d3148cea5c3bcdaf2ff2c4e5 100644
|
|
--- a/Source/WebCore/platform/PlatformScreen.cpp
|
|
+++ b/Source/WebCore/platform/PlatformScreen.cpp
|
|
@@ -85,3 +85,25 @@ 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;
|
|
+}
|
|
+
|
|
+bool screenHasTouchDevice() {
|
|
+ if (screenHasTouchDeviceOverride)
|
|
+ return screenHasTouchDeviceOverride.value();
|
|
+ return platformScreenHasTouchDevice();
|
|
+}
|
|
+bool screenIsTouchPrimaryInputDevice() {
|
|
+ if (screenHasTouchDeviceOverride)
|
|
+ return screenHasTouchDeviceOverride.value();
|
|
+ return platformScreenIsTouchPrimaryInputDevice();
|
|
+}
|
|
+
|
|
+} // namespace WebCore
|
|
+#endif
|
|
diff --git a/Source/WebCore/platform/PlatformScreen.h b/Source/WebCore/platform/PlatformScreen.h
|
|
index dfef4ecbfb44cc985d1d26eaceae855cb427c002..665da262aeb6524f48b2de2418a474a65d0ef754 100644
|
|
--- a/Source/WebCore/platform/PlatformScreen.h
|
|
+++ b/Source/WebCore/platform/PlatformScreen.h
|
|
@@ -160,12 +160,16 @@ WEBCORE_EXPORT float screenScaleFactor(UIScreen * = nullptr);
|
|
#endif
|
|
|
|
#if ENABLE(TOUCH_EVENTS)
|
|
-#if PLATFORM(GTK) || PLATFORM(WPE)
|
|
+WEBCORE_EXPORT void setScreenHasTouchDeviceOverride(bool);
|
|
+
|
|
WEBCORE_EXPORT bool screenHasTouchDevice();
|
|
WEBCORE_EXPORT bool screenIsTouchPrimaryInputDevice();
|
|
+#if PLATFORM(GTK) || PLATFORM(WPE)
|
|
+bool platformScreenHasTouchDevice();
|
|
+bool platformScreenIsTouchPrimaryInputDevice();
|
|
#else
|
|
-constexpr bool screenHasTouchDevice() { return true; }
|
|
-constexpr bool screenIsTouchPrimaryInputDevice() { return true; }
|
|
+constexpr bool platformScreenHasTouchDevice() { return true; }
|
|
+constexpr bool platformScreenIsTouchPrimaryInputDevice() { return true; }
|
|
#endif
|
|
#endif
|
|
|
|
diff --git a/Source/WebCore/platform/PlatformTouchEvent.h b/Source/WebCore/platform/PlatformTouchEvent.h
|
|
index 23f011953c66f401553bedfaef3485af215ae083..a73da2ebe47f0d8dc57f3d0159e8f299abb61c96 100644
|
|
--- a/Source/WebCore/platform/PlatformTouchEvent.h
|
|
+++ b/Source/WebCore/platform/PlatformTouchEvent.h
|
|
@@ -42,7 +42,7 @@ public:
|
|
|
|
const Vector<PlatformTouchEvent>& predictedEvents() const { 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/PlatformTouchPoint.h b/Source/WebCore/platform/PlatformTouchPoint.h
|
|
index 34715d27b529750fc866db87cd330b5184286771..3eefa218af075f76d98012cdeae7e4b344850116 100644
|
|
--- a/Source/WebCore/platform/PlatformTouchPoint.h
|
|
+++ b/Source/WebCore/platform/PlatformTouchPoint.h
|
|
@@ -49,7 +49,7 @@ public:
|
|
{
|
|
}
|
|
|
|
-#if PLATFORM(WPE)
|
|
+#if !ENABLE(IOS_TOUCH_EVENTS)
|
|
// FIXME: since WPE currently does not send touch stationary events, we need to be able to
|
|
// create a PlatformTouchPoint of type TouchCancelled artificially
|
|
PlatformTouchPoint(unsigned id, State state, IntPoint screenPos, IntPoint pos)
|
|
diff --git a/Source/WebCore/platform/Skia.cmake b/Source/WebCore/platform/Skia.cmake
|
|
index 31460a79014b0a8b21fdfe71759af14ff2da46d7..f2594d701502102fed89d711694b64e05a863aaa 100644
|
|
--- a/Source/WebCore/platform/Skia.cmake
|
|
+++ b/Source/WebCore/platform/Skia.cmake
|
|
@@ -13,6 +13,7 @@ list(APPEND WebCore_PRIVATE_FRAMEWORK_HEADERS
|
|
|
|
platform/graphics/skia/GraphicsContextSkia.h
|
|
platform/graphics/skia/ImageBufferSkiaBackend.h
|
|
+ platform/graphics/skia/ImageBufferUtilitiesSkia.h
|
|
platform/graphics/skia/SkiaHarfBuzzFont.h
|
|
platform/graphics/skia/SkiaHarfBuzzFontCache.h
|
|
platform/graphics/skia/SkiaPaintingEngine.h
|
|
diff --git a/Source/WebCore/platform/adwaita/ScrollbarThemeAdwaita.cpp b/Source/WebCore/platform/adwaita/ScrollbarThemeAdwaita.cpp
|
|
index 492c5e76290c2379cda40b9663f5f67ff8f66360..096752985edf39960eb4be6eb733ebe3713313cb 100644
|
|
--- a/Source/WebCore/platform/adwaita/ScrollbarThemeAdwaita.cpp
|
|
+++ b/Source/WebCore/platform/adwaita/ScrollbarThemeAdwaita.cpp
|
|
@@ -46,7 +46,7 @@
|
|
|
|
namespace WebCore {
|
|
|
|
-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/cairo/ImageBufferUtilitiesCairo.cpp b/Source/WebCore/platform/graphics/cairo/ImageBufferUtilitiesCairo.cpp
|
|
index d137ffd1a8ed0b788bd28197c6d7e9f7d14e852f..dcf8bf3f7ee6b037a370712e2ac36b6e2e4bbebc 100644
|
|
--- a/Source/WebCore/platform/graphics/cairo/ImageBufferUtilitiesCairo.cpp
|
|
+++ b/Source/WebCore/platform/graphics/cairo/ImageBufferUtilitiesCairo.cpp
|
|
@@ -48,6 +48,13 @@
|
|
#include <wtf/glib/GUniquePtr.h>
|
|
#endif
|
|
|
|
+#if PLATFORM(WPE) || PLATFORM(WIN)
|
|
+#include <stdio.h> // Needed by jpeglib.h for FILE.
|
|
+extern "C" {
|
|
+#include "jpeglib.h"
|
|
+}
|
|
+#endif
|
|
+
|
|
namespace WebCore {
|
|
|
|
#if !PLATFORM(GTK)
|
|
@@ -65,8 +72,75 @@ static bool encodeImage(cairo_surface_t* image, const String& mimeType, Vector<u
|
|
return cairo_surface_write_to_png_stream(image, writeFunction, output) == CAIRO_STATUS_SUCCESS;
|
|
}
|
|
|
|
-Vector<uint8_t> encodeData(cairo_surface_t* image, const String& mimeType, std::optional<double>)
|
|
+static Vector<uint8_t> encodeJpeg(cairo_surface_t* image, int quality)
|
|
+{
|
|
+ if (cairo_surface_get_type(image) != CAIRO_SURFACE_TYPE_IMAGE) {
|
|
+ fprintf(stderr, "Unexpected cairo surface type: %d\n", cairo_surface_get_type(image));
|
|
+ return { };
|
|
+ }
|
|
+
|
|
+ if (cairo_image_surface_get_format(image) != CAIRO_FORMAT_ARGB32) {
|
|
+ fprintf(stderr, "Unexpected surface image format: %d\n", cairo_image_surface_get_format(image));
|
|
+ return { };
|
|
+ }
|
|
+
|
|
+ struct jpeg_compress_struct info;
|
|
+ struct jpeg_error_mgr error;
|
|
+ info.err = jpeg_std_error(&error);
|
|
+ jpeg_create_compress(&info);
|
|
+
|
|
+ unsigned char* bufferPtr = nullptr;
|
|
+ unsigned long bufferSize;
|
|
+ jpeg_mem_dest(&info, &bufferPtr, &bufferSize);
|
|
+ info.image_width = cairo_image_surface_get_width(image);
|
|
+ info.image_height = cairo_image_surface_get_height(image);
|
|
+
|
|
+#ifndef LIBJPEG_TURBO_VERSION
|
|
+ COMPILE_ASSERT(false, only_libjpeg_turbo_is_supported);
|
|
+#endif
|
|
+
|
|
+#if CPU(LITTLE_ENDIAN)
|
|
+ info.in_color_space = JCS_EXT_BGRA;
|
|
+#else
|
|
+ info.in_color_space = JCS_EXT_ARGB;
|
|
+#endif
|
|
+ // # of color components in input image
|
|
+ info.input_components = 4;
|
|
+
|
|
+ jpeg_set_defaults(&info);
|
|
+ jpeg_set_quality(&info, quality, true);
|
|
+
|
|
+ jpeg_start_compress(&info, true);
|
|
+
|
|
+ while (info.next_scanline < info.image_height)
|
|
+ {
|
|
+ JSAMPROW row = cairo_image_surface_get_data(image) + (info.next_scanline * cairo_image_surface_get_stride(image));
|
|
+ if (jpeg_write_scanlines(&info, &row, 1) != 1) {
|
|
+ fprintf(stderr, "JPEG library failed to encode line\n");
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ jpeg_finish_compress(&info);
|
|
+ jpeg_destroy_compress(&info);
|
|
+
|
|
+ Vector<uint8_t> output;
|
|
+ output.append(std::span { bufferPtr, bufferSize });
|
|
+ // Cannot use unique_ptr as bufferPtr changes during compression. GUniquePtr would work
|
|
+ // but it's under GLib and won't work on Windows.
|
|
+ free(bufferPtr);
|
|
+ return output;
|
|
+}
|
|
+
|
|
+Vector<uint8_t> encodeData(cairo_surface_t* image, const String& mimeType, std::optional<double> quality)
|
|
{
|
|
+ if (mimeType == "image/jpeg"_s) {
|
|
+ int qualityPercent = 100;
|
|
+ if (quality)
|
|
+ qualityPercent = static_cast<int>(*quality * 100.0 + 0.5);
|
|
+ return encodeJpeg(image, qualityPercent);
|
|
+ }
|
|
+
|
|
Vector<uint8_t> encodedImage;
|
|
if (!image || !encodeImage(image, mimeType, &encodedImage))
|
|
return { };
|
|
diff --git a/Source/WebCore/platform/graphics/cg/ImageBufferUtilitiesCG.h b/Source/WebCore/platform/graphics/cg/ImageBufferUtilitiesCG.h
|
|
index 5b659c763b9754b025a63f89522954cc39915b9a..448b50a2b131361a75d3f816cdcbb6a102551280 100644
|
|
--- a/Source/WebCore/platform/graphics/cg/ImageBufferUtilitiesCG.h
|
|
+++ b/Source/WebCore/platform/graphics/cg/ImageBufferUtilitiesCG.h
|
|
@@ -38,7 +38,7 @@ WEBCORE_EXPORT uint8_t verifyImageBufferIsBigEnough(std::span<const uint8_t> buf
|
|
|
|
RetainPtr<CFStringRef> utiFromImageBufferMIMEType(const String& mimeType);
|
|
CFStringRef jpegUTI();
|
|
-Vector<uint8_t> encodeData(CGImageRef, const String& mimeType, std::optional<double> quality);
|
|
+WEBCORE_EXPORT Vector<uint8_t> encodeData(CGImageRef, const String& mimeType, std::optional<double> quality);
|
|
Vector<uint8_t> encodeData(const PixelBuffer&, const String& mimeType, std::optional<double> quality);
|
|
Vector<uint8_t> encodeData(std::span<const uint8_t>, const String& mimeType, std::optional<double> quality);
|
|
|
|
diff --git a/Source/WebCore/platform/graphics/filters/software/FEComponentTransferSoftwareApplier.h b/Source/WebCore/platform/graphics/filters/software/FEComponentTransferSoftwareApplier.h
|
|
index 3d0ab7eceaf2a6321685bc362eb9b25600fd98fd..2d7e9a399bf2e9dc3f373d5fa3db99fa0908bd9d 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 3f0b75a0702db1ed10334c80e4813094571f588c..ea5ff6b7e7bd4c3b8babebc294d7d7c94fc6afb6 100644
|
|
--- a/Source/WebCore/platform/graphics/win/ComplexTextControllerUniscribe.cpp
|
|
+++ b/Source/WebCore/platform/graphics/win/ComplexTextControllerUniscribe.cpp
|
|
@@ -169,6 +169,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 UChar> cp, unsigned stringLocation, const Font* font)
|
|
{
|
|
if (!font) {
|
|
@@ -198,6 +225,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 UChar* str = cp.data() + items[i].iCharPos;
|
|
diff --git a/Source/WebCore/platform/gtk/PlatformKeyboardEventGtk.cpp b/Source/WebCore/platform/gtk/PlatformKeyboardEventGtk.cpp
|
|
index 2b7d3dc70fdfec767d8caa13966c4051ee73aead..7fa8e155bef817c837042c8d6c4dcb84864232bc 100644
|
|
--- a/Source/WebCore/platform/gtk/PlatformKeyboardEventGtk.cpp
|
|
+++ b/Source/WebCore/platform/gtk/PlatformKeyboardEventGtk.cpp
|
|
@@ -37,8 +37,10 @@
|
|
#include <gdk/gdk.h>
|
|
#include <gdk/gdkkeysyms.h>
|
|
#include <pal/text/TextEncoding.h>
|
|
+#include <wtf/HashMap.h>
|
|
#include <wtf/HexNumber.h>
|
|
#include <wtf/text/MakeString.h>
|
|
+#include <mutex>
|
|
|
|
namespace WebCore {
|
|
|
|
@@ -1302,6 +1304,246 @@ int PlatformKeyboardEvent::windowsKeyCodeForGdkKeyCode(unsigned keycode)
|
|
|
|
}
|
|
|
|
+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 = PlatformKeyboardEvent::windowsKeyCodeForGdkKeyCode(gdkKeyCode);
|
|
+ // If several gdk key codes map to the same win key code first one is used.
|
|
+ result->add(winKeyCode, gdkKeyCode);
|
|
+ }
|
|
+ });
|
|
+ return *result;
|
|
+}
|
|
+
|
|
+unsigned PlatformKeyboardEvent::gdkKeyCodeForWindowsKeyCode(int keycode)
|
|
+{
|
|
+ return gdkToWindowsKeyCodeMap().get(keycode);
|
|
+}
|
|
+
|
|
String PlatformKeyboardEvent::singleCharacterString(unsigned val)
|
|
{
|
|
switch (val) {
|
|
diff --git a/Source/WebCore/platform/gtk/PlatformScreenGtk.cpp b/Source/WebCore/platform/gtk/PlatformScreenGtk.cpp
|
|
index 9ea18000578dd47295b2ce4da7fa00b39b5cac81..41bdd2d741b469acb134220df7e0c10209bd9f62 100644
|
|
--- a/Source/WebCore/platform/gtk/PlatformScreenGtk.cpp
|
|
+++ b/Source/WebCore/platform/gtk/PlatformScreenGtk.cpp
|
|
@@ -132,7 +132,7 @@ bool screenSupportsExtendedColor(Widget*)
|
|
}
|
|
|
|
#if ENABLE(TOUCH_EVENTS)
|
|
-bool screenHasTouchDevice()
|
|
+bool platformScreenHasTouchDevice()
|
|
{
|
|
auto* display = gdk_display_get_default();
|
|
if (!display)
|
|
@@ -142,7 +142,7 @@ bool screenHasTouchDevice()
|
|
return seat ? gdk_seat_get_capabilities(seat) & GDK_SEAT_CAPABILITY_TOUCH : true;
|
|
}
|
|
|
|
-bool screenIsTouchPrimaryInputDevice()
|
|
+bool platformScreenIsTouchPrimaryInputDevice()
|
|
{
|
|
auto* display = gdk_display_get_default();
|
|
if (!display)
|
|
diff --git a/Source/WebCore/platform/libwpe/PasteboardLibWPE.cpp b/Source/WebCore/platform/libwpe/PasteboardLibWPE.cpp
|
|
index ae439e30f1fb239d18e1164e8896dfb272c75673..4cf29eda13d1f2dc2f03750c0ef8985b17de7f50 100644
|
|
--- a/Source/WebCore/platform/libwpe/PasteboardLibWPE.cpp
|
|
+++ b/Source/WebCore/platform/libwpe/PasteboardLibWPE.cpp
|
|
@@ -32,6 +32,10 @@
|
|
#include "PasteboardStrategy.h"
|
|
#include "PlatformStrategies.h"
|
|
|
|
+#if ENABLE(DRAG_SUPPORT)
|
|
+#include "DragData.h"
|
|
+#endif
|
|
+
|
|
namespace WebCore {
|
|
|
|
std::unique_ptr<Pasteboard> Pasteboard::createForCopyAndPaste(std::unique_ptr<PasteboardContext>&& context)
|
|
@@ -52,9 +56,28 @@ bool Pasteboard::hasData()
|
|
return !types.isEmpty();
|
|
}
|
|
|
|
-Vector<String> Pasteboard::typesSafeForBindings(const String&)
|
|
+Vector<String> Pasteboard::typesSafeForBindings(const String& origin)
|
|
{
|
|
- notImplemented();
|
|
+ if (m_selectionData) {
|
|
+ ListHashSet<String> types;
|
|
+ if (auto& buffer = m_selectionData->customData()) {
|
|
+ auto customData = PasteboardCustomData::fromSharedBuffer(*buffer);
|
|
+ if (customData.origin() == origin) {
|
|
+ for (auto& type : customData.orderedTypes())
|
|
+ types.add(type);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (m_selectionData->hasText())
|
|
+ types.add("text/plain"_s);
|
|
+ if (m_selectionData->hasMarkup())
|
|
+ types.add("text/html"_s);
|
|
+ if (m_selectionData->hasURIList())
|
|
+ types.add("text/uri-list"_s);
|
|
+
|
|
+ return copyToVector(types);
|
|
+ }
|
|
+
|
|
return { };
|
|
}
|
|
|
|
@@ -67,23 +90,55 @@ Vector<String> Pasteboard::typesForLegacyUnsafeBindings()
|
|
|
|
String Pasteboard::readOrigin()
|
|
{
|
|
- notImplemented(); // webkit.org/b/177633: [GTK] Move to new Pasteboard API
|
|
+ if (m_selectionData) {
|
|
+ if (auto& buffer = m_selectionData->customData())
|
|
+ return PasteboardCustomData::fromSharedBuffer(*buffer).origin();
|
|
+
|
|
+ return { };
|
|
+ }
|
|
+
|
|
return { };
|
|
}
|
|
|
|
String Pasteboard::readString(const String& type)
|
|
{
|
|
+ if (m_selectionData) {
|
|
+ if (type == "text/plain"_s)
|
|
+ return m_selectionData->text();;
|
|
+ if (type == "text/html"_s)
|
|
+ return m_selectionData->markup();
|
|
+ if (type == "Files"_s || type == "text/uri-list"_s)
|
|
+ return m_selectionData->uriList();
|
|
+ return { };
|
|
+ }
|
|
+
|
|
return platformStrategies()->pasteboardStrategy()->readStringFromPasteboard(0, type, name(), context());
|
|
}
|
|
|
|
-String Pasteboard::readStringInCustomData(const String&)
|
|
+String Pasteboard::readStringInCustomData(const String& type)
|
|
{
|
|
+ if (m_selectionData) {
|
|
+ if (auto& buffer = m_selectionData->customData())
|
|
+ return PasteboardCustomData::fromSharedBuffer(*buffer).readStringInCustomData(type);
|
|
+
|
|
+ return { };
|
|
+ }
|
|
+
|
|
notImplemented();
|
|
return { };
|
|
}
|
|
|
|
void Pasteboard::writeString(const String& type, const String& text)
|
|
{
|
|
+ if (m_selectionData) {
|
|
+ if (type == "Files"_s || type == "text/uri-list"_s)
|
|
+ m_selectionData->setURIList(text);
|
|
+ else if (type == "text/html"_s)
|
|
+ m_selectionData->setMarkup(text);
|
|
+ else if (type == "text/plain"_s)
|
|
+ m_selectionData->setText(text);
|
|
+ return;
|
|
+ }
|
|
platformStrategies()->pasteboardStrategy()->writeToPasteboard(type, text);
|
|
}
|
|
|
|
@@ -111,7 +166,12 @@ void Pasteboard::read(PasteboardFileReader&, std::optional<size_t>)
|
|
|
|
void Pasteboard::write(const PasteboardURL& url)
|
|
{
|
|
- platformStrategies()->pasteboardStrategy()->writeToPasteboard("text/plain;charset=utf-8"_s, url.url.string());
|
|
+ if (m_selectionData) {
|
|
+ m_selectionData->clearAll();
|
|
+ m_selectionData->setURL(url.url, url.title);
|
|
+ } else {
|
|
+ platformStrategies()->pasteboardStrategy()->writeToPasteboard("text/plain;charset=utf-8"_s, url.url.string());
|
|
+ }
|
|
}
|
|
|
|
void Pasteboard::writeTrustworthyWebURLsPboardType(const PasteboardURL&)
|
|
@@ -119,8 +179,16 @@ void Pasteboard::writeTrustworthyWebURLsPboardType(const PasteboardURL&)
|
|
notImplemented();
|
|
}
|
|
|
|
-void Pasteboard::write(const PasteboardImage&)
|
|
+void Pasteboard::write(const PasteboardImage& pasteboardImage)
|
|
{
|
|
+ if (m_selectionData) {
|
|
+ m_selectionData->clearAll();
|
|
+ if (!pasteboardImage.url.url.isEmpty()) {
|
|
+ m_selectionData->setURL(pasteboardImage.url.url, pasteboardImage.url.title);
|
|
+ m_selectionData->setMarkup(pasteboardImage.url.markup);
|
|
+ }
|
|
+ m_selectionData->setImage(pasteboardImage.image.get());
|
|
+ }
|
|
}
|
|
|
|
void Pasteboard::write(const PasteboardBuffer&)
|
|
@@ -129,7 +197,13 @@ void Pasteboard::write(const PasteboardBuffer&)
|
|
|
|
void Pasteboard::write(const PasteboardWebContent& content)
|
|
{
|
|
- platformStrategies()->pasteboardStrategy()->writeToPasteboard(content);
|
|
+ if (m_selectionData) {
|
|
+ m_selectionData->clearAll();
|
|
+ m_selectionData->setText(content.text);
|
|
+ m_selectionData->setMarkup(content.markup);
|
|
+ } else {
|
|
+ platformStrategies()->pasteboardStrategy()->writeToPasteboard(content);
|
|
+ }
|
|
}
|
|
|
|
Pasteboard::FileContentState Pasteboard::fileContentState()
|
|
@@ -152,14 +226,54 @@ void Pasteboard::writePlainText(const String& text, SmartReplaceOption)
|
|
writeString("text/plain;charset=utf-8"_s, text);
|
|
}
|
|
|
|
-void Pasteboard::writeCustomData(const Vector<PasteboardCustomData>&)
|
|
+void Pasteboard::writeCustomData(const Vector<PasteboardCustomData>& data)
|
|
{
|
|
+ if (m_selectionData) {
|
|
+ if (!data.isEmpty()) {
|
|
+ const auto& customData = data[0];
|
|
+ customData.forEachPlatformString([this] (auto& type, auto& string) {
|
|
+ writeString(type, string);
|
|
+ });
|
|
+ if (customData.hasSameOriginCustomData() || !customData.origin().isEmpty())
|
|
+ m_selectionData->setCustomData(customData.createSharedBuffer());
|
|
+ }
|
|
+ return;
|
|
+ }
|
|
}
|
|
|
|
void Pasteboard::write(const Color&)
|
|
{
|
|
}
|
|
|
|
+#if ENABLE(DRAG_SUPPORT)
|
|
+
|
|
+Pasteboard::Pasteboard(std::unique_ptr<PasteboardContext>&& context, SelectionData&& selectionData)
|
|
+ : m_context(WTFMove(context))
|
|
+ , m_selectionData(WTFMove(selectionData))
|
|
+{
|
|
+}
|
|
+
|
|
+Pasteboard::Pasteboard(std::unique_ptr<PasteboardContext>&& context, SelectionData& selectionData)
|
|
+ : m_context(WTFMove(context))
|
|
+ , m_selectionData(selectionData)
|
|
+{
|
|
+}
|
|
+
|
|
+std::unique_ptr<Pasteboard> Pasteboard::createForDragAndDrop(std::unique_ptr<PasteboardContext>&& context)
|
|
+{
|
|
+ return makeUnique<Pasteboard>(WTFMove(context), SelectionData());
|
|
+}
|
|
+
|
|
+std::unique_ptr<Pasteboard> Pasteboard::create(const DragData& dragData)
|
|
+{
|
|
+ RELEASE_ASSERT(dragData.platformData());
|
|
+ return makeUnique<Pasteboard>(dragData.createPasteboardContext(), *dragData.platformData());
|
|
+}
|
|
+void Pasteboard::setDragImage(DragImage, const IntPoint&)
|
|
+{
|
|
+}
|
|
+#endif
|
|
+
|
|
} // namespace WebCore
|
|
|
|
#endif // USE(LIBWPE)
|
|
diff --git a/Source/WebCore/platform/libwpe/PlatformKeyboardEventLibWPE.cpp b/Source/WebCore/platform/libwpe/PlatformKeyboardEventLibWPE.cpp
|
|
index a8674916429908cabb86bd95dc5b3da217e1556b..6a464e2b0c1c45cd4e8effba678b8dde9dd870da 100644
|
|
--- a/Source/WebCore/platform/libwpe/PlatformKeyboardEventLibWPE.cpp
|
|
+++ b/Source/WebCore/platform/libwpe/PlatformKeyboardEventLibWPE.cpp
|
|
@@ -30,9 +30,11 @@
|
|
|
|
#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>
|
|
|
|
namespace WebCore {
|
|
|
|
@@ -1303,6 +1305,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 065c1b362537547bc732bd9ded7e801ddf938ef8..448321a8388b7075173061caf8c9b272997e02fd 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())
|
|
{
|
|
@@ -54,72 +62,26 @@ void PlatformPasteboard::performAsDataOwner(DataOwnerType, NOESCAPE Function<voi
|
|
|
|
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({ 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({ 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;charset=utf-8"_s;
|
|
-
|
|
- CString textString = content.text.utf8();
|
|
- CString markupString = content.markup.utf8();
|
|
-
|
|
- 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() };
|
|
-
|
|
- wpe_pasteboard_write(m_pasteboard, &map);
|
|
-
|
|
- 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);
|
|
-
|
|
- 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/network/HTTPHeaderMap.cpp b/Source/WebCore/platform/network/HTTPHeaderMap.cpp
|
|
index 1178c8fb001994bc9e6166376a367d9bc148913c..fcc6534568cad6b42a819a435f84ba2b9baae6f8 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 8c57734966ccfaf38dbb7fd956e71f3d3f65a477..594e5031caba89142535a16c2fb132bb878aab21 100644
|
|
--- a/Source/WebCore/platform/network/NetworkStorageSession.h
|
|
+++ b/Source/WebCore/platform/network/NetworkStorageSession.h
|
|
@@ -200,6 +200,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 bc4d0a6059710f349685b9782079e17f19e289fa..f15d5944bf4259248c1dcc11bd536e5398cb7f03 100644
|
|
--- a/Source/WebCore/platform/network/ResourceResponseBase.cpp
|
|
+++ b/Source/WebCore/platform/network/ResourceResponseBase.cpp
|
|
@@ -78,6 +78,7 @@ ResourceResponseBase::ResourceResponseBase(std::optional<ResourceResponseData> d
|
|
, m_httpStatusText(data ? data->httpStatusText : String { })
|
|
, m_httpVersion(data ? data->httpVersion : String { })
|
|
, m_httpHeaderFields(data ? data->httpHeaderFields : HTTPHeaderMap { })
|
|
+ , m_httpRequestHeaderFields(data ? data->httpRequestHeaderFields : HTTPHeaderMap { })
|
|
, m_networkLoadMetrics(data && data->networkLoadMetrics ? Box<NetworkLoadMetrics>::create(*data->networkLoadMetrics) : Box<NetworkLoadMetrics> { })
|
|
, m_certificateInfo(data ? data->certificateInfo : std::nullopt)
|
|
, m_httpStatusCode(data ? data->httpStatusCode : 0)
|
|
@@ -904,6 +905,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,
|
|
@@ -979,6 +981,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)
|
|
@@ -1038,6 +1045,7 @@ std::optional<WebCore::ResourceResponseData> Coder<WebCore::ResourceResponseData
|
|
WTFMove(*httpStatusText),
|
|
WTFMove(*httpVersion),
|
|
WTFMove(*httpHeaderFields),
|
|
+ WTFMove(*httpRequestHeaderFields),
|
|
std::nullopt,
|
|
*source,
|
|
*type,
|
|
diff --git a/Source/WebCore/platform/network/ResourceResponseBase.h b/Source/WebCore/platform/network/ResourceResponseBase.h
|
|
index be9d60dc24eec83f9b7fad5c9bbcdffc2cbd3bb4..9fe86dc133adb69e21a1e9067ea0b2a130f3def6 100644
|
|
--- a/Source/WebCore/platform/network/ResourceResponseBase.h
|
|
+++ b/Source/WebCore/platform/network/ResourceResponseBase.h
|
|
@@ -256,6 +256,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;
|
|
@@ -297,7 +302,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)
|
|
+ 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)
|
|
: url(WTFMove(url))
|
|
, mimeType(WTFMove(mimeType))
|
|
, expectedContentLength(expectedContentLength)
|
|
@@ -306,6 +311,7 @@ struct ResourceResponseData {
|
|
, httpStatusText(WTFMove(httpStatusText))
|
|
, httpVersion(WTFMove(httpVersion))
|
|
, httpHeaderFields(WTFMove(httpHeaderFields))
|
|
+ , httpRequestHeaderFields(WTFMove(httpRequestHeaderFields))
|
|
, networkLoadMetrics(WTFMove(networkLoadMetrics))
|
|
, source(source)
|
|
, type(type)
|
|
@@ -329,6 +335,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 ab7a9d832f0573bd402c5643d3eee3aa3e3b33c6..7dcb122411c4b6bf45c05e3a6edf7b133c5d9e9e 100644
|
|
--- a/Source/WebCore/platform/network/cocoa/NetworkStorageSessionCocoa.mm
|
|
+++ b/Source/WebCore/platform/network/cocoa/NetworkStorageSessionCocoa.mm
|
|
@@ -552,6 +552,22 @@ 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)
|
|
+{
|
|
+ Vector<String> cookieValues = setCookieValue.split('\n');
|
|
+ size_t count = cookieValues.size();
|
|
+ auto* cookies = [NSMutableArray arrayWithCapacity:count];
|
|
+ for (const auto& cookieValue : cookieValues) {
|
|
+ NSString* cookieString = (NSString *)cookieValue;
|
|
+ NSString* cookieKey = @"Set-Cookie";
|
|
+ NSDictionary* headers = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObject:cookieString] forKeys:[NSArray arrayWithObject:cookieKey]];
|
|
+ NSArray<NSHTTPCookie*>* parsedCookies = [NSHTTPCookie cookiesWithResponseHeaderFields:headers forURL:(NSURL *)url];
|
|
+ [cookies addObject:parsedCookies[0]];
|
|
+ }
|
|
+ NSURL *cookieURL = url;
|
|
+ setHTTPCookiesForURL(cookieStorage().get(), cookies, cookieURL, firstParty, sameSiteInfo);
|
|
+}
|
|
+
|
|
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 37e129136c69b27d509acc01f10be42a8a1fe35a..9df0babc8f82372925fddf2211a7c8c908f3bb18 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/CurlStream.cpp b/Source/WebCore/platform/network/curl/CurlStream.cpp
|
|
index d07f26d77447d05fa2b086d04e6aa105c3d6b4b1..52b09365fff63fa4099320d0eebc1d498e0c068e 100644
|
|
--- a/Source/WebCore/platform/network/curl/CurlStream.cpp
|
|
+++ b/Source/WebCore/platform/network/curl/CurlStream.cpp
|
|
@@ -37,7 +37,7 @@ namespace WebCore {
|
|
|
|
WTF_MAKE_TZONE_ALLOCATED_IMPL(CurlStream);
|
|
|
|
-CurlStream::CurlStream(CurlStreamScheduler& scheduler, CurlStreamID streamID, URL&& url, ServerTrustEvaluation serverTrustEvaluation, LocalhostAlias localhostAlias)
|
|
+CurlStream::CurlStream(CurlStreamScheduler& scheduler, CurlStreamID streamID, bool ignoreCertificateErrors, URL&& url, ServerTrustEvaluation serverTrustEvaluation, LocalhostAlias localhostAlias)
|
|
: m_scheduler(scheduler)
|
|
, m_streamID(streamID)
|
|
{
|
|
@@ -52,6 +52,9 @@ CurlStream::CurlStream(CurlStreamScheduler& scheduler, CurlStreamID streamID, UR
|
|
m_curlHandle->disableServerTrustEvaluation();
|
|
|
|
m_curlHandle->enableConnectionOnly();
|
|
+ if (ignoreCertificateErrors)
|
|
+ m_curlHandle->disableServerTrustEvaluation();
|
|
+
|
|
|
|
auto errorCode = m_curlHandle->perform();
|
|
if (errorCode != CURLE_OK) {
|
|
diff --git a/Source/WebCore/platform/network/curl/CurlStream.h b/Source/WebCore/platform/network/curl/CurlStream.h
|
|
index 96c3d2c216d522cf5c8b53b06a87eb849d159618..b595a1cfe961ad98364d8893014ab5c2fc1007f5 100644
|
|
--- a/Source/WebCore/platform/network/curl/CurlStream.h
|
|
+++ b/Source/WebCore/platform/network/curl/CurlStream.h
|
|
@@ -56,12 +56,12 @@ public:
|
|
virtual void didFail(CurlStreamID, CURLcode, CertificateInfo&&) = 0;
|
|
};
|
|
|
|
- static std::unique_ptr<CurlStream> create(CurlStreamScheduler& scheduler, CurlStreamID streamID, URL&& url, ServerTrustEvaluation serverTrustEvaluation, LocalhostAlias localhostAlias)
|
|
+ static std::unique_ptr<CurlStream> create(CurlStreamScheduler& scheduler, CurlStreamID streamID, bool ignoreCertificateErrors, URL&& url, ServerTrustEvaluation serverTrustEvaluation, LocalhostAlias localhostAlias)
|
|
{
|
|
- return makeUnique<CurlStream>(scheduler, streamID, WTFMove(url), serverTrustEvaluation, localhostAlias);
|
|
+ return makeUnique<CurlStream>(scheduler, streamID, ignoreCertificateErrors, WTFMove(url), serverTrustEvaluation, localhostAlias);
|
|
}
|
|
|
|
- CurlStream(CurlStreamScheduler&, CurlStreamID, URL&&, ServerTrustEvaluation, LocalhostAlias);
|
|
+ CurlStream(CurlStreamScheduler&, CurlStreamID, bool ignoreCertificateErrors, URL&&, ServerTrustEvaluation, LocalhostAlias);
|
|
virtual ~CurlStream();
|
|
|
|
void send(UniqueArray<uint8_t>&&, size_t);
|
|
diff --git a/Source/WebCore/platform/network/curl/CurlStreamScheduler.cpp b/Source/WebCore/platform/network/curl/CurlStreamScheduler.cpp
|
|
index 83c4ca7871e536077f2d0a1a8ba6e2b4adb584da..12a49c124283fbe50ac17ecaa0c1e6fee32741d6 100644
|
|
--- a/Source/WebCore/platform/network/curl/CurlStreamScheduler.cpp
|
|
+++ b/Source/WebCore/platform/network/curl/CurlStreamScheduler.cpp
|
|
@@ -43,7 +43,7 @@ CurlStreamScheduler::~CurlStreamScheduler()
|
|
ASSERT(isMainThread());
|
|
}
|
|
|
|
-CurlStreamID CurlStreamScheduler::createStream(const URL& url, CurlStream::Client& client, CurlStream::ServerTrustEvaluation serverTrustEvaluation, CurlStream::LocalhostAlias localhostAlias)
|
|
+CurlStreamID CurlStreamScheduler::createStream(const URL& url, bool ignoreCertificateErrors, CurlStream::Client& client, CurlStream::ServerTrustEvaluation serverTrustEvaluation, CurlStream::LocalhostAlias localhostAlias)
|
|
{
|
|
ASSERT(isMainThread());
|
|
|
|
@@ -54,8 +54,8 @@ CurlStreamID CurlStreamScheduler::createStream(const URL& url, CurlStream::Clien
|
|
auto streamID = m_currentStreamID;
|
|
m_clientList.add(streamID, &client);
|
|
|
|
- callOnWorkerThread([this, streamID, url = url.isolatedCopy(), serverTrustEvaluation, localhostAlias]() mutable {
|
|
- m_streamList.add(streamID, CurlStream::create(*this, streamID, WTFMove(url), serverTrustEvaluation, localhostAlias));
|
|
+ callOnWorkerThread([this, streamID, ignoreCertificateErrors, url = url.isolatedCopy(), serverTrustEvaluation, localhostAlias]() mutable {
|
|
+ m_streamList.add(streamID, CurlStream::create(*this, streamID, ignoreCertificateErrors, WTFMove(url), serverTrustEvaluation, localhostAlias));
|
|
});
|
|
|
|
return streamID;
|
|
diff --git a/Source/WebCore/platform/network/curl/CurlStreamScheduler.h b/Source/WebCore/platform/network/curl/CurlStreamScheduler.h
|
|
index 2d7a77d759aaea9a541030af5e6015a8ed9c97a4..a0c947d325c984045dbbdf2580d19a32eea86ada 100644
|
|
--- a/Source/WebCore/platform/network/curl/CurlStreamScheduler.h
|
|
+++ b/Source/WebCore/platform/network/curl/CurlStreamScheduler.h
|
|
@@ -39,7 +39,7 @@ public:
|
|
CurlStreamScheduler();
|
|
virtual ~CurlStreamScheduler();
|
|
|
|
- WEBCORE_EXPORT CurlStreamID createStream(const URL&, CurlStream::Client&, CurlStream::ServerTrustEvaluation, CurlStream::LocalhostAlias);
|
|
+ WEBCORE_EXPORT CurlStreamID createStream(const URL&, bool ignoreCertificateErrors, CurlStream::Client&, CurlStream::ServerTrustEvaluation, CurlStream::LocalhostAlias);
|
|
WEBCORE_EXPORT void destroyStream(CurlStreamID);
|
|
WEBCORE_EXPORT void send(CurlStreamID, UniqueArray<uint8_t>&&, size_t);
|
|
|
|
diff --git a/Source/WebCore/platform/network/curl/NetworkStorageSessionCurl.cpp b/Source/WebCore/platform/network/curl/NetworkStorageSessionCurl.cpp
|
|
index b422dee5926a14aab7a20ea4de9d51080b2b3fea..d5735a2097e18f5c94fa0695fde6ff7a4ffda823 100644
|
|
--- a/Source/WebCore/platform/network/curl/NetworkStorageSessionCurl.cpp
|
|
+++ b/Source/WebCore/platform/network/curl/NetworkStorageSessionCurl.cpp
|
|
@@ -135,6 +135,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 c191cdc193019db8efc2c597bb3c87b3a318bcd6..35ad719201c4505c43c20701dffce0adcfb241f6 100644
|
|
--- a/Source/WebCore/platform/network/soup/NetworkStorageSessionSoup.cpp
|
|
+++ b/Source/WebCore/platform/network/soup/NetworkStorageSessionSoup.cpp
|
|
@@ -528,6 +528,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/win/ClipboardUtilitiesWin.cpp b/Source/WebCore/platform/win/ClipboardUtilitiesWin.cpp
|
|
index bbcc12d58f7b5df3462c93617f6ef19eef403cf2..b255b05da89248a99ff11965ceae840ef45b9fab 100644
|
|
--- a/Source/WebCore/platform/win/ClipboardUtilitiesWin.cpp
|
|
+++ b/Source/WebCore/platform/win/ClipboardUtilitiesWin.cpp
|
|
@@ -40,6 +40,7 @@
|
|
#include <wtf/text/StringBuilder.h>
|
|
#include <wtf/text/win/WCharStringExtras.h>
|
|
#include <wtf/unicode/CharacterNames.h>
|
|
+#include "Pasteboard.h"
|
|
|
|
namespace WebCore {
|
|
|
|
@@ -691,7 +692,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 c3ffc7392c0b7fa099a7dd4e4be977cdee1c803c..9570dbb0f2c42ca38598a8898183c9b310f858ab 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 d450bf9d0fd1f0bf8f28db483ac9d3d60fa9d114..72a59403a0b5493aea4a8e28eb15eac24b652b09 100644
|
|
--- a/Source/WebCore/platform/win/KeyEventWin.cpp
|
|
+++ b/Source/WebCore/platform/win/KeyEventWin.cpp
|
|
@@ -243,10 +243,16 @@ PlatformKeyboardEvent::PlatformKeyboardEvent(HWND, WPARAM code, LPARAM keyData,
|
|
{
|
|
}
|
|
|
|
-void PlatformKeyboardEvent::disambiguateKeyDownEvent(Type, bool)
|
|
+void PlatformKeyboardEvent::disambiguateKeyDownEvent(Type type, bool backwardsCompatibility)
|
|
{
|
|
- // 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 8aab5ddd1dc749ecdd02ac59eb81f16294d67235..31cfdfb8dd2e174f39470421c59d9e520ddf84de 100644
|
|
--- a/Source/WebCore/platform/win/PasteboardWin.cpp
|
|
+++ b/Source/WebCore/platform/win/PasteboardWin.cpp
|
|
@@ -1142,7 +1142,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) {
|
|
@@ -1181,4 +1195,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/platform/wpe/DragDataWPE.cpp b/Source/WebCore/platform/wpe/DragDataWPE.cpp
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..fbd32d390129129fd5b213f7f9c3e96bdca9355b
|
|
--- /dev/null
|
|
+++ b/Source/WebCore/platform/wpe/DragDataWPE.cpp
|
|
@@ -0,0 +1,92 @@
|
|
+/*
|
|
+ * This library is free software; you can redistribute it and/or
|
|
+ * modify it under the terms of the GNU Lesser General Public
|
|
+ * License as published by the Free Software Foundation; either
|
|
+ * version 2 of the License, or (at your option) any later version.
|
|
+ *
|
|
+ * This library is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ * Lesser General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU Lesser General Public
|
|
+ * License along with this library; if not, write to the Free Software
|
|
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
+ */
|
|
+
|
|
+#include "config.h"
|
|
+#include "DragData.h"
|
|
+#include "SelectionData.h"
|
|
+
|
|
+namespace WebCore {
|
|
+
|
|
+bool DragData::canSmartReplace() const
|
|
+{
|
|
+ return false;
|
|
+}
|
|
+
|
|
+bool DragData::containsColor() const
|
|
+{
|
|
+ return false;
|
|
+}
|
|
+
|
|
+bool DragData::containsFiles() const
|
|
+{
|
|
+ return m_platformDragData->hasFilenames();
|
|
+}
|
|
+
|
|
+unsigned DragData::numberOfFiles() const
|
|
+{
|
|
+ return m_platformDragData->filenames().size();
|
|
+}
|
|
+
|
|
+Vector<String> DragData::asFilenames() const
|
|
+{
|
|
+ return m_platformDragData->filenames();
|
|
+}
|
|
+
|
|
+bool DragData::containsPlainText() const
|
|
+{
|
|
+ return m_platformDragData->hasText();
|
|
+}
|
|
+
|
|
+String DragData::asPlainText() const
|
|
+{
|
|
+ return m_platformDragData->text();
|
|
+}
|
|
+
|
|
+Color DragData::asColor() const
|
|
+{
|
|
+ return Color();
|
|
+}
|
|
+
|
|
+bool DragData::containsCompatibleContent(DraggingPurpose) const
|
|
+{
|
|
+ return containsPlainText() || containsURL() || containsColor() || containsFiles();
|
|
+}
|
|
+
|
|
+bool DragData::containsURL(FilenameConversionPolicy filenamePolicy) const
|
|
+{
|
|
+ return !asURL(filenamePolicy).isEmpty();
|
|
+}
|
|
+
|
|
+String DragData::asURL(FilenameConversionPolicy filenamePolicy, String* title) const
|
|
+{
|
|
+ if (!m_platformDragData->hasURL())
|
|
+ return String();
|
|
+ if (filenamePolicy != ConvertFilenames) {
|
|
+ if (m_platformDragData->url().protocolIsFile())
|
|
+ return { };
|
|
+ }
|
|
+
|
|
+ if (title)
|
|
+ *title = m_platformDragData->urlLabel();
|
|
+ return m_platformDragData->url().string();
|
|
+}
|
|
+
|
|
+bool DragData::shouldMatchStyleOnDrop() const
|
|
+{
|
|
+ return false;
|
|
+}
|
|
+
|
|
+}
|
|
diff --git a/Source/WebCore/platform/wpe/DragImageWPE.cpp b/Source/WebCore/platform/wpe/DragImageWPE.cpp
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..5a20bfaacd42d27bee5f843483d6b60d9dee9dbd
|
|
--- /dev/null
|
|
+++ b/Source/WebCore/platform/wpe/DragImageWPE.cpp
|
|
@@ -0,0 +1,73 @@
|
|
+/*
|
|
+ * Copyright (C) 2010,2017 Igalia S.L.
|
|
+ *
|
|
+ * This library is free software; you can redistribute it and/or
|
|
+ * modify it under the terms of the GNU Lesser General Public
|
|
+ * License as published by the Free Software Foundation; either
|
|
+ * version 2 of the License, or (at your option) any later version.
|
|
+ *
|
|
+ * This library is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ * Lesser General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU Lesser General Public
|
|
+ * License along with this library; if not, write to the Free Software
|
|
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
+ */
|
|
+
|
|
+#include "config.h"
|
|
+#include "DragImage.h"
|
|
+#include "NotImplemented.h"
|
|
+
|
|
+#include "Image.h"
|
|
+
|
|
+namespace WebCore {
|
|
+
|
|
+IntSize dragImageSize(DragImageRef)
|
|
+{
|
|
+ notImplemented();
|
|
+ return { 0, 0 };
|
|
+}
|
|
+
|
|
+void deleteDragImage(DragImageRef)
|
|
+{
|
|
+ notImplemented();
|
|
+}
|
|
+
|
|
+DragImageRef scaleDragImage(DragImageRef, FloatSize)
|
|
+{
|
|
+ notImplemented();
|
|
+ return nullptr;
|
|
+}
|
|
+
|
|
+DragImageRef dissolveDragImageToFraction(DragImageRef image, float)
|
|
+{
|
|
+ notImplemented();
|
|
+ return image;
|
|
+}
|
|
+
|
|
+DragImageRef createDragImageFromImage(Image* image, ImageOrientation, GraphicsClient*, float)
|
|
+{
|
|
+ return image->currentNativeImage()->platformImage();
|
|
+}
|
|
+
|
|
+
|
|
+DragImageRef createDragImageIconForCachedImageFilename(const String&)
|
|
+{
|
|
+ notImplemented();
|
|
+ return nullptr;
|
|
+}
|
|
+
|
|
+DragImageRef createDragImageForLink(Element&, URL&, const String&, TextIndicatorData&, float)
|
|
+{
|
|
+ notImplemented();
|
|
+ return nullptr;
|
|
+}
|
|
+
|
|
+DragImageRef createDragImageForColor(const Color&, const FloatRect&, float, Path&)
|
|
+{
|
|
+ return nullptr;
|
|
+}
|
|
+
|
|
+}
|
|
diff --git a/Source/WebCore/platform/wpe/PlatformScreenWPE.cpp b/Source/WebCore/platform/wpe/PlatformScreenWPE.cpp
|
|
index 77bdff686770e56f5445fa12216c6bff93bb5cfb..e16583ea6298864df9c8b82cb0686b2afb18ce95 100644
|
|
--- a/Source/WebCore/platform/wpe/PlatformScreenWPE.cpp
|
|
+++ b/Source/WebCore/platform/wpe/PlatformScreenWPE.cpp
|
|
@@ -151,12 +151,12 @@ bool screenSupportsExtendedColor(Widget*)
|
|
}
|
|
|
|
#if ENABLE(TOUCH_EVENTS)
|
|
-bool screenHasTouchDevice()
|
|
+bool platformScreenHasTouchDevice()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
-bool screenIsTouchPrimaryInputDevice()
|
|
+bool platformScreenIsTouchPrimaryInputDevice()
|
|
{
|
|
return true;
|
|
}
|
|
diff --git a/Source/WebCore/platform/wpe/SelectionData.cpp b/Source/WebCore/platform/wpe/SelectionData.cpp
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..947bfe6576780038ecb87ea9bda116adb19dfd71
|
|
--- /dev/null
|
|
+++ b/Source/WebCore/platform/wpe/SelectionData.cpp
|
|
@@ -0,0 +1,151 @@
|
|
+/*
|
|
+ * Copyright (C) 2009, Martin Robinson
|
|
+ *
|
|
+ * This library is free software; you can redistribute it and/or
|
|
+ * modify it under the terms of the GNU Lesser General Public
|
|
+ * License as published by the Free Software Foundation; either
|
|
+ * version 2 of the License, or (at your option) any later version.
|
|
+ *
|
|
+ * This library is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ * Lesser General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU Lesser General Public
|
|
+ * License along with this library; if not, write to the Free Software
|
|
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
+ */
|
|
+
|
|
+#include "config.h"
|
|
+#include "SelectionData.h"
|
|
+
|
|
+#include <wtf/glib/GUniquePtr.h>
|
|
+#include <wtf/text/CString.h>
|
|
+#include <wtf/text/StringBuilder.h>
|
|
+
|
|
+namespace WebCore {
|
|
+
|
|
+SelectionData::SelectionData(const String& text, const String& markup, const URL& url, const String& uriList, RefPtr<WebCore::Image>&& image, RefPtr<WebCore::SharedBuffer>&& buffer, bool canSmartReplace)
|
|
+{
|
|
+ if (!text.isEmpty())
|
|
+ setText(text);
|
|
+ if (!markup.isEmpty())
|
|
+ setMarkup(markup);
|
|
+ if (!url.isEmpty())
|
|
+ setURL(url, String());
|
|
+ if (!uriList.isEmpty())
|
|
+ setURIList(uriList);
|
|
+ if (image)
|
|
+ setImage(WTFMove(image));
|
|
+ if (buffer)
|
|
+ setCustomData(buffer.releaseNonNull());
|
|
+ setCanSmartReplace(canSmartReplace);
|
|
+}
|
|
+
|
|
+static void replaceNonBreakingSpaceWithSpace(String& str)
|
|
+{
|
|
+ static const UChar NonBreakingSpaceCharacter = 0xA0;
|
|
+ static const UChar SpaceCharacter = ' ';
|
|
+ str = makeStringByReplacingAll(str, NonBreakingSpaceCharacter, SpaceCharacter);
|
|
+}
|
|
+
|
|
+void SelectionData::setText(const String& newText)
|
|
+{
|
|
+ m_text = newText;
|
|
+ replaceNonBreakingSpaceWithSpace(m_text);
|
|
+}
|
|
+
|
|
+void SelectionData::setURIList(const String& uriListString)
|
|
+{
|
|
+ m_uriList = uriListString;
|
|
+
|
|
+ // This code is originally from: platform/chromium/ChromiumDataObject.cpp.
|
|
+ // FIXME: We should make this code cross-platform eventually.
|
|
+
|
|
+ // Line separator is \r\n per RFC 2483 - however, for compatibility
|
|
+ // reasons we also allow just \n here.
|
|
+
|
|
+ // Process the input and copy the first valid URL into the url member.
|
|
+ // In case no URLs can be found, subsequent calls to getData("URL")
|
|
+ // will get an empty string. This is in line with the HTML5 spec (see
|
|
+ // "The DragEvent and DataTransfer interfaces"). Also extract all filenames
|
|
+ // from the URI list.
|
|
+ bool setURL = hasURL();
|
|
+ for (auto& line : uriListString.split('\n')) {
|
|
+ line = line.trim(deprecatedIsSpaceOrNewline);
|
|
+ if (line.isEmpty())
|
|
+ continue;
|
|
+ if (line[0] == '#')
|
|
+ continue;
|
|
+
|
|
+ URL url = URL(URL(), line);
|
|
+ if (url.isValid()) {
|
|
+ if (!setURL) {
|
|
+ m_url = url;
|
|
+ setURL = true;
|
|
+ }
|
|
+
|
|
+ GUniqueOutPtr<GError> error;
|
|
+ GUniquePtr<gchar> filename(g_filename_from_uri(line.utf8().data(), 0, &error.outPtr()));
|
|
+ if (!error && filename)
|
|
+ m_filenames.append(String::fromUTF8(filename.get()));
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+void SelectionData::setURL(const URL& url, const String& label)
|
|
+{
|
|
+ m_url = url;
|
|
+ if (m_uriList.isEmpty())
|
|
+ m_uriList = url.string();
|
|
+
|
|
+ if (!hasText())
|
|
+ setText(url.string());
|
|
+
|
|
+ if (hasMarkup())
|
|
+ return;
|
|
+
|
|
+ String actualLabel(label);
|
|
+ if (actualLabel.isEmpty())
|
|
+ actualLabel = url.string();
|
|
+
|
|
+ StringBuilder markup;
|
|
+ markup.append("<a href=\""_s);
|
|
+ markup.append(url.string());
|
|
+ markup.append("\">"_s);
|
|
+ GUniquePtr<gchar> escaped(g_markup_escape_text(actualLabel.utf8().data(), -1));
|
|
+ markup.append(String::fromUTF8(escaped.get()));
|
|
+ markup.append("</a>"_s);
|
|
+ setMarkup(markup.toString());
|
|
+}
|
|
+
|
|
+const String& SelectionData::urlLabel() const
|
|
+{
|
|
+ if (hasText())
|
|
+ return text();
|
|
+
|
|
+ if (hasURL())
|
|
+ return url().string();
|
|
+
|
|
+ return emptyString();
|
|
+}
|
|
+
|
|
+void SelectionData::clearAllExceptFilenames()
|
|
+{
|
|
+ clearText();
|
|
+ clearMarkup();
|
|
+ clearURIList();
|
|
+ clearURL();
|
|
+ clearImage();
|
|
+ clearCustomData();
|
|
+
|
|
+ m_canSmartReplace = false;
|
|
+}
|
|
+
|
|
+void SelectionData::clearAll()
|
|
+{
|
|
+ clearAllExceptFilenames();
|
|
+ m_filenames.clear();
|
|
+}
|
|
+
|
|
+} // namespace WebCore
|
|
diff --git a/Source/WebCore/platform/wpe/SelectionData.h b/Source/WebCore/platform/wpe/SelectionData.h
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..a76b583a1e65cd6999fab4784c22dd9cb48d6aeb
|
|
--- /dev/null
|
|
+++ b/Source/WebCore/platform/wpe/SelectionData.h
|
|
@@ -0,0 +1,85 @@
|
|
+/*
|
|
+ * Copyright (C) 2009, Martin Robinson
|
|
+ *
|
|
+ * This library is free software; you can redistribute it and/or
|
|
+ * modify it under the terms of the GNU Lesser General Public
|
|
+ * License as published by the Free Software Foundation; either
|
|
+ * version 2 of the License, or (at your option) any later version.
|
|
+ *
|
|
+ * This library is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ * Lesser General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU Lesser General Public
|
|
+ * License along with this library; if not, write to the Free Software
|
|
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
+ */
|
|
+
|
|
+#pragma once
|
|
+
|
|
+#include "Image.h"
|
|
+#include "SharedBuffer.h"
|
|
+#include <wtf/HashMap.h>
|
|
+#include <wtf/URL.h>
|
|
+#include <wtf/text/StringHash.h>
|
|
+
|
|
+namespace WebCore {
|
|
+
|
|
+class SelectionData {
|
|
+ WTF_MAKE_FAST_ALLOCATED;
|
|
+public:
|
|
+ void setText(const String&);
|
|
+ const String& text() const { return m_text; }
|
|
+ bool hasText() const { return !m_text.isEmpty(); }
|
|
+ void clearText() { m_text = emptyString(); }
|
|
+
|
|
+ void setMarkup(const String& newMarkup) { m_markup = newMarkup; }
|
|
+ const String& markup() const { return m_markup; }
|
|
+ bool hasMarkup() const { return !m_markup.isEmpty(); }
|
|
+ void clearMarkup() { m_markup = emptyString(); }
|
|
+
|
|
+ void setURL(const URL&, const String&);
|
|
+ const URL& url() const { return m_url; }
|
|
+ const String& urlLabel() const;
|
|
+ bool hasURL() const { return !m_url.isEmpty() && m_url.isValid(); }
|
|
+ void clearURL() { m_url = URL(); }
|
|
+
|
|
+ void setURIList(const String&);
|
|
+ const String& uriList() const { return m_uriList; }
|
|
+ const Vector<String>& filenames() const { return m_filenames; }
|
|
+ bool hasURIList() const { return !m_uriList.isEmpty(); }
|
|
+ bool hasFilenames() const { return !m_filenames.isEmpty(); }
|
|
+ void clearURIList() { m_uriList = emptyString(); }
|
|
+
|
|
+ void setImage(RefPtr<Image>&& newImage) { m_image = WTFMove(newImage); }
|
|
+ const RefPtr<Image>& image() const { return m_image; }
|
|
+ bool hasImage() const { return m_image; }
|
|
+ void clearImage() { m_image = nullptr; }
|
|
+
|
|
+ void setCanSmartReplace(bool canSmartReplace) { m_canSmartReplace = canSmartReplace; }
|
|
+ bool canSmartReplace() const { return m_canSmartReplace; }
|
|
+
|
|
+ void setCustomData(Ref<SharedBuffer>&& buffer) { m_customData = WTFMove(buffer); }
|
|
+ const RefPtr<SharedBuffer>& customData() const { return m_customData; }
|
|
+ bool hasCustomData() const { return !!m_customData; }
|
|
+ void clearCustomData() { m_customData = nullptr; }
|
|
+
|
|
+ void clearAll();
|
|
+ void clearAllExceptFilenames();
|
|
+
|
|
+ SelectionData(const String& text, const String& markup, const URL&, const String& uriList, RefPtr<WebCore::Image>&&, RefPtr<WebCore::SharedBuffer>&&, bool);
|
|
+ SelectionData() = default;
|
|
+
|
|
+private:
|
|
+ String m_text;
|
|
+ String m_markup;
|
|
+ URL m_url;
|
|
+ String m_uriList;
|
|
+ Vector<String> m_filenames;
|
|
+ RefPtr<Image> m_image;
|
|
+ bool m_canSmartReplace { false };
|
|
+ RefPtr<SharedBuffer> m_customData;
|
|
+};
|
|
+
|
|
+} // namespace WebCore
|
|
diff --git a/Source/WebCore/rendering/RenderTextControl.cpp b/Source/WebCore/rendering/RenderTextControl.cpp
|
|
index 015f1d0d829c0a1ef2c0cc137eb4967fa7bfe67a..25a6d41d2e08d50004749298f9555024a895b61c 100644
|
|
--- a/Source/WebCore/rendering/RenderTextControl.cpp
|
|
+++ b/Source/WebCore/rendering/RenderTextControl.cpp
|
|
@@ -228,13 +228,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
|
|
{
|
|
auto innerText = innerTextElement();
|
|
diff --git a/Source/WebCore/rendering/RenderTextControl.h b/Source/WebCore/rendering/RenderTextControl.h
|
|
index faf34133df0bf205072145ffbab8163b93d3c874..fdc4554952e0e33f8827bb3d00c827dec966ad15 100644
|
|
--- a/Source/WebCore/rendering/RenderTextControl.h
|
|
+++ b/Source/WebCore/rendering/RenderTextControl.h
|
|
@@ -38,9 +38,9 @@ public:
|
|
WEBCORE_EXPORT HTMLTextFormControlElement& textFormControlElement() const;
|
|
WEBCORE_EXPORT Ref<HTMLTextFormControlElement> protectedTextFormControlElement() const;
|
|
|
|
-#if PLATFORM(IOS_FAMILY)
|
|
bool canScroll() const;
|
|
|
|
+#if PLATFORM(IOS_FAMILY)
|
|
// Returns the line height of the inner renderer.
|
|
int innerLineHeight() const override;
|
|
#endif
|
|
diff --git a/Source/WebCore/workers/WorkerConsoleClient.cpp b/Source/WebCore/workers/WorkerConsoleClient.cpp
|
|
index 5b64d59511778572142eae5e48b16cfaa1040d49..7082cd677870f4c359130bc065bdee097c82feda 100644
|
|
--- a/Source/WebCore/workers/WorkerConsoleClient.cpp
|
|
+++ b/Source/WebCore/workers/WorkerConsoleClient.cpp
|
|
@@ -104,4 +104,6 @@ void WorkerConsoleClient::recordEnd(JSC::JSGlobalObject*, Ref<ScriptArguments>&&
|
|
// FIXME: <https://webkit.org/b/243361> Web Inspector: support console screenshots in a Worker
|
|
void WorkerConsoleClient::screenshot(JSC::JSGlobalObject*, Ref<ScriptArguments>&&) { }
|
|
|
|
+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 db95c8273bd0deb3f903a45d02fc07bbbd8ab305..bf88228b4c838b90d11d430cc9429d5130631afa 100644
|
|
--- a/Source/WebCore/workers/WorkerConsoleClient.h
|
|
+++ b/Source/WebCore/workers/WorkerConsoleClient.h
|
|
@@ -58,6 +58,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& m_globalScope;
|
|
};
|
|
diff --git a/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp b/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp
|
|
index e185fc809df730737ff85c349ad17dce10d246f0..b1ccbc16b185ac76ecffb753b6aed2ae1eb8e39a 100644
|
|
--- a/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp
|
|
+++ b/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp
|
|
@@ -96,6 +96,8 @@
|
|
|
|
#if PLATFORM(COCOA)
|
|
#include <wtf/OSObjectPtr.h>
|
|
+#include "NetworkDataTaskCocoa.h"
|
|
+#include "NetworkSessionCocoa.h"
|
|
#endif
|
|
|
|
#if ENABLE(APPLE_PAY_REMOTE_UI)
|
|
@@ -1232,6 +1234,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 (auto* storageSession = protectedNetworkProcess()->storageSession(m_sessionID))
|
|
diff --git a/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h b/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h
|
|
index 706ceb9edc7de45d731db75c656a7a9ad5780cbe..49a6735a5936a8b6daab556a7df89b254157e14f 100644
|
|
--- a/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h
|
|
+++ b/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h
|
|
@@ -380,6 +380,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 a8f2e3cd5cef58c0e390a9cc8c3d18c9d24ffbda..fdbc166682cd3ec9fdbba737757331e46fd93364 100644
|
|
--- a/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.messages.in
|
|
+++ b/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.messages.in
|
|
@@ -80,6 +80,8 @@ messages -> NetworkConnectionToWebProcess WantsDispatchMessage {
|
|
|
|
ClearPageSpecificData(WebCore::PageIdentifier pageID);
|
|
|
|
+ SetCookieFromResponse(URL firstParty, struct WebCore::SameSiteInfo sameSiteInfo, URL url, String setCookieValue);
|
|
+
|
|
RemoveStorageAccessForFrame(WebCore::FrameIdentifier frameID, WebCore::PageIdentifier pageID);
|
|
LogUserInteraction(WebCore::RegistrableDomain domain)
|
|
ResourceLoadStatisticsUpdated(Vector<WebCore::ResourceLoadStatistics> statistics) -> ()
|
|
diff --git a/Source/WebKit/NetworkProcess/NetworkProcess.cpp b/Source/WebKit/NetworkProcess/NetworkProcess.cpp
|
|
index 40718b455299eb28978d999d2088579564b06fd4..9ada150a661beda8b4411c5b6e669c72e0895a75 100644
|
|
--- a/Source/WebKit/NetworkProcess/NetworkProcess.cpp
|
|
+++ b/Source/WebKit/NetworkProcess/NetworkProcess.cpp
|
|
@@ -653,6 +653,12 @@ void NetworkProcess::registrableDomainsExemptFromWebsiteDataDeletion(PAL::Sessio
|
|
completionHandler({ });
|
|
}
|
|
|
|
+void NetworkProcess::setIgnoreCertificateErrors(PAL::SessionID sessionID, bool ignore)
|
|
+{
|
|
+ if (auto* networkSession = this->networkSession(sessionID))
|
|
+ networkSession->setIgnoreCertificateErrors(ignore);
|
|
+}
|
|
+
|
|
void NetworkProcess::dumpResourceLoadStatistics(PAL::SessionID sessionID, CompletionHandler<void(String)>&& completionHandler)
|
|
{
|
|
if (auto* session = networkSession(sessionID)) {
|
|
diff --git a/Source/WebKit/NetworkProcess/NetworkProcess.h b/Source/WebKit/NetworkProcess/NetworkProcess.h
|
|
index c6b478b2564a0fb550118e43a9749101c2aa7361..2a45c0dc4e3947b84ed1da124c02ccfff7834cbb 100644
|
|
--- a/Source/WebKit/NetworkProcess/NetworkProcess.h
|
|
+++ b/Source/WebKit/NetworkProcess/NetworkProcess.h
|
|
@@ -84,6 +84,7 @@ class SessionID;
|
|
|
|
namespace WebCore {
|
|
class CertificateInfo;
|
|
+struct Cookie;
|
|
class CurlProxySettings;
|
|
class ProtectionSpace;
|
|
class NetworkStorageSession;
|
|
@@ -234,6 +235,9 @@ public:
|
|
|
|
void registrableDomainsWithLastAccessedTime(PAL::SessionID, CompletionHandler<void(std::optional<HashMap<RegistrableDomain, WallTime>>)>&&);
|
|
void registrableDomainsExemptFromWebsiteDataDeletion(PAL::SessionID, CompletionHandler<void(HashSet<RegistrableDomain>)>&&);
|
|
+
|
|
+ void setIgnoreCertificateErrors(PAL::SessionID, bool);
|
|
+
|
|
void clearPrevalentResource(PAL::SessionID, RegistrableDomain&&, CompletionHandler<void()>&&);
|
|
void clearUserInteraction(PAL::SessionID, RegistrableDomain&&, CompletionHandler<void()>&&);
|
|
void deleteAndRestrictWebsiteDataForRegistrableDomains(PAL::SessionID, OptionSet<WebsiteDataType>, RegistrableDomainsToDeleteOrRestrictWebsiteDataFor&&, CompletionHandler<void(HashSet<RegistrableDomain>&&)>&&);
|
|
diff --git a/Source/WebKit/NetworkProcess/NetworkProcess.messages.in b/Source/WebKit/NetworkProcess/NetworkProcess.messages.in
|
|
index 24124fdb6ad7f5447345764a8481342557ceba8e..204e00738921f21e70af8398a9350cd49a4640ce 100644
|
|
--- a/Source/WebKit/NetworkProcess/NetworkProcess.messages.in
|
|
+++ b/Source/WebKit/NetworkProcess/NetworkProcess.messages.in
|
|
@@ -90,6 +90,8 @@ messages -> NetworkProcess : AuxiliaryProcess WantsAsyncDispatchMessage {
|
|
|
|
SetInspectionForServiceWorkersAllowed(PAL::SessionID sessionID, bool inspectable)
|
|
|
|
+ SetIgnoreCertificateErrors(PAL::SessionID sessionID, bool ignoreTLSErrors)
|
|
+
|
|
ClearPrevalentResource(PAL::SessionID sessionID, WebCore::RegistrableDomain resourceDomain) -> ()
|
|
ClearUserInteraction(PAL::SessionID sessionID, WebCore::RegistrableDomain resourceDomain) -> ()
|
|
DumpResourceLoadStatistics(PAL::SessionID sessionID) -> (String dumpedStatistics)
|
|
diff --git a/Source/WebKit/NetworkProcess/NetworkSession.h b/Source/WebKit/NetworkProcess/NetworkSession.h
|
|
index 679cf1fc291f262f90d42f5d597361c67eb0f4c0..527015014b15f9efca45dd054f541b4be416eafe 100644
|
|
--- a/Source/WebKit/NetworkProcess/NetworkSession.h
|
|
+++ b/Source/WebKit/NetworkProcess/NetworkSession.h
|
|
@@ -207,6 +207,9 @@ public:
|
|
|
|
void lowMemoryHandler(WTF::Critical);
|
|
|
|
+ void setIgnoreCertificateErrors(bool ignore) { m_ignoreCertificateErrors = ignore; }
|
|
+ bool ignoreCertificateErrors() { return m_ignoreCertificateErrors; }
|
|
+
|
|
void removeSoftUpdateLoader(ServiceWorkerSoftUpdateLoader* loader) { m_softUpdateLoaders.remove(loader); }
|
|
void addNavigationPreloaderTask(ServiceWorkerFetchTask&);
|
|
ServiceWorkerFetchTask* navigationPreloaderTaskFromFetchIdentifier(WebCore::FetchIdentifier);
|
|
@@ -343,6 +346,7 @@ protected:
|
|
bool m_privateClickMeasurementDebugModeEnabled { false };
|
|
std::optional<WebCore::PrivateClickMeasurement> m_ephemeralMeasurement;
|
|
bool m_isRunningEphemeralMeasurementTest { false };
|
|
+ bool m_ignoreCertificateErrors { false };
|
|
|
|
HashSet<Ref<NetworkResourceLoader>> m_keptAliveLoads;
|
|
|
|
diff --git a/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm b/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm
|
|
index 0d2fcd76b91d7f9afa8c2378ab1109f12386a6c2..ff01afba3686fd8f81e1ad914f0171d3fd40e0fb 100644
|
|
--- a/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm
|
|
+++ b/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm
|
|
@@ -805,6 +805,8 @@ - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didRece
|
|
|
|
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
|
|
sessionCocoa->setClientAuditToken(challenge);
|
|
+ if (sessionCocoa->ignoreCertificateErrors())
|
|
+ return completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]);
|
|
|
|
negotiatedLegacyTLS = checkForLegacyTLS(task._incompleteTaskMetrics.transactionMetrics.lastObject);
|
|
if (negotiatedLegacyTLS == NegotiatedLegacyTLS::Yes && task._preconnect)
|
|
@@ -1146,6 +1148,14 @@ - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)data
|
|
|
|
resourceResponse.setDeprecatedNetworkLoadMetrics(WebCore::copyTimingData(taskMetrics, networkDataTask->networkLoadMetrics()));
|
|
resourceResponse.setProxyName(WTFMove(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 = WTFMove(requestHeaders);
|
|
+
|
|
networkDataTask->didReceiveResponse(WTFMove(resourceResponse), negotiatedLegacyTLS, privateRelayed, [completionHandler = makeBlockPtr(completionHandler), taskIdentifier](WebCore::PolicyAction policyAction) {
|
|
#if !LOG_DISABLED
|
|
LOG(NetworkSession, "%llu didReceiveResponse completionHandler (%d)", taskIdentifier, policyAction);
|
|
diff --git a/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.cpp b/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.cpp
|
|
index 50cd0b45a2fa5be6f217b686b2ff703b74c06078..c2d6b10762def97a222197d1e6f45d31d3b7a49b 100644
|
|
--- a/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.cpp
|
|
+++ b/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.cpp
|
|
@@ -80,10 +80,18 @@ NetworkDataTaskCurl::NetworkDataTaskCurl(NetworkSession& session, NetworkDataTas
|
|
blockCookies();
|
|
restrictRequestReferrerToOriginIfNeeded(request);
|
|
|
|
- m_curlRequest = createCurlRequest(WTFMove(request));
|
|
- if (!m_initialCredential.isEmpty()) {
|
|
- m_curlRequest->setUserPass(m_initialCredential.user(), m_initialCredential.password());
|
|
- m_curlRequest->setAuthenticationScheme(ProtectionSpace::AuthenticationScheme::HTTPBasic);
|
|
+ if (request.url().protocolIsData()) {
|
|
+ DataURLDecoder::decode(request.url(), { }, DataURLDecoder::ShouldValidatePadding::Yes, [this, protectedThis = Ref { *this }](auto decodeResult) mutable {
|
|
+ didReadDataURL(WTFMove(decodeResult));
|
|
+ });
|
|
+ } else {
|
|
+ m_curlRequest = createCurlRequest(WTFMove(request));
|
|
+ if (!m_initialCredential.isEmpty()) {
|
|
+ m_curlRequest->setUserPass(m_initialCredential.user(), m_initialCredential.password());
|
|
+ m_curlRequest->setAuthenticationScheme(ProtectionSpace::AuthenticationScheme::HTTPBasic);
|
|
+ }
|
|
+ if (m_session->ignoreCertificateErrors())
|
|
+ m_curlRequest->disableServerTrustEvaluation();
|
|
}
|
|
}
|
|
|
|
@@ -166,6 +174,7 @@ void NetworkDataTaskCurl::curlDidReceiveResponse(CurlRequest& request, CurlRespo
|
|
|
|
updateNetworkLoadMetrics(receivedResponse.networkLoadMetrics);
|
|
m_response.setDeprecatedNetworkLoadMetrics(Box<NetworkLoadMetrics>::create(WTFMove(receivedResponse.networkLoadMetrics)));
|
|
+ m_response.m_httpRequestHeaderFields = request.resourceRequest().httpHeaderFields();
|
|
|
|
handleCookieHeaders(request.resourceRequest(), receivedResponse);
|
|
|
|
@@ -294,6 +303,36 @@ bool NetworkDataTaskCurl::shouldRedirectAsGET(const ResourceRequest& request, bo
|
|
return false;
|
|
}
|
|
|
|
+void NetworkDataTaskCurl::didReadDataURL(std::optional<DataURLDecoder::Result>&& result)
|
|
+{
|
|
+ if (state() == State::Canceling || state() == State::Completed)
|
|
+ return;
|
|
+
|
|
+ m_dataURLResult = WTFMove(result);
|
|
+ m_response = ResourceResponse::dataURLResponse(firstRequest().url(), m_dataURLResult.value());
|
|
+ invokeDidReceiveResponse();
|
|
+}
|
|
+
|
|
+void NetworkDataTaskCurl::downloadDataURL(Download& download)
|
|
+{
|
|
+ if (!m_dataURLResult) {
|
|
+ deleteDownloadFile();
|
|
+ download.didFail(internalError(firstRequest().url()), std::span<const uint8_t>());
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (-1 == FileSystem::writeToFile(m_downloadDestinationFile, std::span<const uint8_t>(m_dataURLResult.value().data.data(), m_dataURLResult.value().data.size()))) {
|
|
+ deleteDownloadFile();
|
|
+ download.didFail(ResourceError(CURLE_WRITE_ERROR, m_response.url()), std::span<const uint8_t>());
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ download.didReceiveData(m_dataURLResult.value().data.size(), 0, 0);
|
|
+ FileSystem::closeFile(m_downloadDestinationFile);
|
|
+ m_downloadDestinationFile = FileSystem::invalidPlatformFileHandle;
|
|
+ download.didFinish();
|
|
+}
|
|
+
|
|
void NetworkDataTaskCurl::invokeDidReceiveResponse()
|
|
{
|
|
didReceiveResponse(ResourceResponse(m_response), NegotiatedLegacyTLS::No, PrivateRelayed::No, std::nullopt, [this, protectedThis = Ref { *this }](PolicyAction policyAction) {
|
|
@@ -323,6 +362,8 @@ void NetworkDataTaskCurl::invokeDidReceiveResponse()
|
|
download->didCreateDestination(m_pendingDownloadLocation);
|
|
if (m_curlRequest)
|
|
m_curlRequest->completeDidReceiveResponse();
|
|
+ else if (firstRequest().url().protocolIsData())
|
|
+ downloadDataURL(download);
|
|
break;
|
|
}
|
|
default:
|
|
@@ -411,6 +452,8 @@ void NetworkDataTaskCurl::willPerformHTTPRedirection()
|
|
m_curlRequest->setUserPass(m_initialCredential.user(), m_initialCredential.password());
|
|
m_curlRequest->setAuthenticationScheme(ProtectionSpace::AuthenticationScheme::HTTPBasic);
|
|
}
|
|
+ if (m_session->ignoreCertificateErrors())
|
|
+ m_curlRequest->disableServerTrustEvaluation();
|
|
|
|
if (m_state != State::Suspended) {
|
|
m_state = State::Suspended;
|
|
diff --git a/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.h b/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.h
|
|
index fc4d15308fcb12b084a65d058aec9e67fcf6021f..b1a689989c68798e6308b1da7b3bd7c066497114 100644
|
|
--- a/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.h
|
|
+++ b/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.h
|
|
@@ -28,6 +28,7 @@
|
|
#include "NetworkDataTask.h"
|
|
#include "NetworkLoadParameters.h"
|
|
#include <WebCore/CurlRequestClient.h>
|
|
+#include <WebCore/DataURLDecoder.h>
|
|
#include <WebCore/FrameIdentifier.h>
|
|
#include <WebCore/PageIdentifier.h>
|
|
#include <WebCore/ProtectionSpace.h>
|
|
@@ -43,6 +44,8 @@ class SharedBuffer;
|
|
|
|
namespace WebKit {
|
|
|
|
+class Download;
|
|
+
|
|
class NetworkDataTaskCurl final : public NetworkDataTask, public WebCore::CurlRequestClient {
|
|
public:
|
|
static Ref<NetworkDataTask> create(NetworkSession& session, NetworkDataTaskClient& client, const NetworkLoadParameters& parameters)
|
|
@@ -76,6 +79,9 @@ private:
|
|
void curlDidComplete(WebCore::CurlRequest&, WebCore::NetworkLoadMetrics&&) override;
|
|
void curlDidFailWithError(WebCore::CurlRequest&, WebCore::ResourceError&&, WebCore::CertificateInfo&&) override;
|
|
|
|
+ void didReadDataURL(std::optional<WebCore::DataURLDecoder::Result>&&);
|
|
+ void downloadDataURL(Download&);
|
|
+
|
|
void invokeDidReceiveResponse();
|
|
|
|
bool shouldStartHTTPRedirection();
|
|
@@ -114,6 +120,9 @@ private:
|
|
unsigned m_authFailureCount { 0 };
|
|
|
|
bool m_allowOverwriteDownload { false };
|
|
+
|
|
+ std::optional<WebCore::DataURLDecoder::Result> m_dataURLResult;
|
|
+
|
|
FileSystem::PlatformFileHandle m_downloadDestinationFile { FileSystem::invalidPlatformFileHandle };
|
|
|
|
bool m_blockingCookies { false };
|
|
diff --git a/Source/WebKit/NetworkProcess/curl/NetworkSessionCurl.cpp b/Source/WebKit/NetworkProcess/curl/NetworkSessionCurl.cpp
|
|
index a6f84189b7163563874a148c9bf1c8afb42bb446..8b5db0010c4be8e24efd121e4ccba0568e6f4bed 100644
|
|
--- a/Source/WebKit/NetworkProcess/curl/NetworkSessionCurl.cpp
|
|
+++ b/Source/WebKit/NetworkProcess/curl/NetworkSessionCurl.cpp
|
|
@@ -68,7 +68,7 @@ void NetworkSessionCurl::clearAlternativeServices(WallTime)
|
|
|
|
std::unique_ptr<WebSocketTask> NetworkSessionCurl::createWebSocketTask(WebPageProxyIdentifier webPageProxyID, std::optional<FrameIdentifier>, std::optional<PageIdentifier>, NetworkSocketChannel& channel, const WebCore::ResourceRequest& request, const String& protocol, const WebCore::ClientOrigin& clientOrigin, bool, bool, OptionSet<WebCore::AdvancedPrivacyProtections>, StoredCredentialsPolicy)
|
|
{
|
|
- return makeUnique<WebSocketTask>(channel, webPageProxyID, request, protocol, clientOrigin);
|
|
+ return makeUnique<WebSocketTask>(channel, webPageProxyID, request, protocol, ignoreCertificateErrors(), clientOrigin);
|
|
}
|
|
|
|
void NetworkSessionCurl::didReceiveChallenge(WebSocketTask& webSocketTask, WebCore::AuthenticationChallenge&& challenge, CompletionHandler<void(WebKit::AuthenticationChallengeDisposition, const WebCore::Credential&)>&& challengeCompletionHandler)
|
|
diff --git a/Source/WebKit/NetworkProcess/curl/WebSocketTaskCurl.cpp b/Source/WebKit/NetworkProcess/curl/WebSocketTaskCurl.cpp
|
|
index 1853b717d021c5ec5c79abb61bec684460646a7a..625b921890a75c521bdf6fc3a5fd4bf3e9d74006 100644
|
|
--- a/Source/WebKit/NetworkProcess/curl/WebSocketTaskCurl.cpp
|
|
+++ b/Source/WebKit/NetworkProcess/curl/WebSocketTaskCurl.cpp
|
|
@@ -39,11 +39,12 @@
|
|
namespace WebKit {
|
|
WTF_MAKE_TZONE_ALLOCATED_IMPL(WebSocketTask);
|
|
|
|
-WebSocketTask::WebSocketTask(NetworkSocketChannel& channel, WebPageProxyIdentifier webProxyPageID, const WebCore::ResourceRequest& request, const String& protocol, const WebCore::ClientOrigin& clientOrigin)
|
|
+WebSocketTask::WebSocketTask(NetworkSocketChannel& channel, WebPageProxyIdentifier webProxyPageID, const WebCore::ResourceRequest& request, const String& protocol, bool ignoreCertificateErrors, const WebCore::ClientOrigin& clientOrigin)
|
|
: m_channel(channel)
|
|
, m_webProxyPageID(webProxyPageID)
|
|
, m_request(request.isolatedCopy())
|
|
, m_protocol(protocol)
|
|
+ , m_ignoreCertificateErrors(ignoreCertificateErrors)
|
|
, m_scheduler(WebCore::CurlContext::singleton().streamScheduler())
|
|
{
|
|
// We use topOrigin in case of service worker websocket connections, for which pageID does not link to a real page.
|
|
@@ -55,7 +56,7 @@ WebSocketTask::WebSocketTask(NetworkSocketChannel& channel, WebPageProxyIdentifi
|
|
if (networkSession() && networkSession()->networkProcess().localhostAliasesForTesting().contains<StringViewHashTranslator>(m_request.url().host()))
|
|
localhostAlias = WebCore::CurlStream::LocalhostAlias::Enable;
|
|
|
|
- m_streamID = m_scheduler.createStream(request.url(), *this, WebCore::CurlStream::ServerTrustEvaluation::Enable, localhostAlias);
|
|
+ m_streamID = m_scheduler.createStream(request.url(), ignoreCertificateErrors, *this, WebCore::CurlStream::ServerTrustEvaluation::Enable, localhostAlias);
|
|
channel.didSendHandshakeRequest(WebCore::ResourceRequest(m_request));
|
|
}
|
|
|
|
@@ -265,7 +266,7 @@ void WebSocketTask::tryServerTrustEvaluation(WebCore::AuthenticationChallenge&&
|
|
if (networkSession() && networkSession()->networkProcess().localhostAliasesForTesting().contains<StringViewHashTranslator>(m_request.url().host()))
|
|
localhostAlias = WebCore::CurlStream::LocalhostAlias::Enable;
|
|
|
|
- m_streamID = m_scheduler.createStream(m_request.url(), *this, WebCore::CurlStream::ServerTrustEvaluation::Disable, localhostAlias);
|
|
+ m_streamID = m_scheduler.createStream(m_request.url(), m_ignoreCertificateErrors, *this, WebCore::CurlStream::ServerTrustEvaluation::Disable, localhostAlias);
|
|
} else
|
|
didFail(WTFMove(errorReason));
|
|
});
|
|
diff --git a/Source/WebKit/NetworkProcess/curl/WebSocketTaskCurl.h b/Source/WebKit/NetworkProcess/curl/WebSocketTaskCurl.h
|
|
index 0ef9f38c7662f922b7a8e4da81613799b0fddc68..45704b96df02cead2f21fd948455502793a1508c 100644
|
|
--- a/Source/WebKit/NetworkProcess/curl/WebSocketTaskCurl.h
|
|
+++ b/Source/WebKit/NetworkProcess/curl/WebSocketTaskCurl.h
|
|
@@ -55,7 +55,7 @@ class WebSocketTask : public CanMakeWeakPtr<WebSocketTask>, public CanMakeChecke
|
|
WTF_MAKE_TZONE_ALLOCATED(WebSocketTask);
|
|
WTF_OVERRIDE_DELETE_FOR_CHECKED_PTR(WebSocketTask);
|
|
public:
|
|
- WebSocketTask(NetworkSocketChannel&, WebPageProxyIdentifier, const WebCore::ResourceRequest&, const String& protocol, const WebCore::ClientOrigin&);
|
|
+ WebSocketTask(NetworkSocketChannel&, WebPageProxyIdentifier, const WebCore::ResourceRequest&, const String& protocol, bool ignoreCertificateErrors, const WebCore::ClientOrigin&);
|
|
virtual ~WebSocketTask();
|
|
|
|
void sendString(std::span<const uint8_t>, CompletionHandler<void()>&&);
|
|
@@ -110,6 +110,7 @@ private:
|
|
WebPageProxyIdentifier m_webProxyPageID;
|
|
WebCore::ResourceRequest m_request;
|
|
String m_protocol;
|
|
+ bool m_ignoreCertificateErrors { false };
|
|
WebCore::SecurityOriginData m_topOrigin;
|
|
|
|
WebCore::CurlStreamScheduler& m_scheduler;
|
|
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 a6d86f1388e8cae7c3939d1ecffb2c46eb5054c5..9e11224335211908fe8bf14edc4c22e9e4934582 100644
|
|
--- a/Source/WebKit/NetworkProcess/mac/com.apple.WebKit.NetworkProcess.sb.in
|
|
+++ b/Source/WebKit/NetworkProcess/mac/com.apple.WebKit.NetworkProcess.sb.in
|
|
@@ -451,9 +451,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 4fd4b7c714f0c6364f7c239b9e25af3428ffd1fd..56d6e55721c077a34dee36ea7043395331d453bb 100644
|
|
--- a/Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.cpp
|
|
+++ b/Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.cpp
|
|
@@ -461,6 +461,8 @@ void NetworkDataTaskSoup::didSendRequest(GRefPtr<GInputStream>&& inputStream)
|
|
m_networkLoadMetrics.responseStart = MonotonicTime::now();
|
|
#endif
|
|
|
|
+ auto& additionalMetrics = additionalNetworkLoadMetricsForWebInspector();
|
|
+ m_response.m_httpRequestHeaderFields = additionalMetrics.requestHeaders;
|
|
dispatchDidReceiveResponse();
|
|
}
|
|
|
|
@@ -563,6 +565,8 @@ bool NetworkDataTaskSoup::acceptCertificate(GTlsCertificate* certificate, GTlsCe
|
|
{
|
|
ASSERT(m_soupMessage);
|
|
URL url = soupURIToURL(soup_message_get_uri(m_soupMessage.get()));
|
|
+ if (m_session->ignoreCertificateErrors())
|
|
+ return true;
|
|
auto error = static_cast<NetworkSessionSoup&>(*m_session).soupNetworkSession().checkTLSErrors(url, certificate, tlsErrors);
|
|
if (!error)
|
|
return true;
|
|
diff --git a/Source/WebKit/NetworkProcess/soup/NetworkSessionSoup.cpp b/Source/WebKit/NetworkProcess/soup/NetworkSessionSoup.cpp
|
|
index c0c9bf6f4f1879efb8dfdd24951ef67ae373fa2f..48aeb8ac1324a58dc59bdb125c8ec4e317e24fd2 100644
|
|
--- a/Source/WebKit/NetworkProcess/soup/NetworkSessionSoup.cpp
|
|
+++ b/Source/WebKit/NetworkProcess/soup/NetworkSessionSoup.cpp
|
|
@@ -100,6 +100,11 @@ void NetworkSessionSoup::clearCredentials(WallTime)
|
|
#endif
|
|
}
|
|
|
|
+static gboolean webSocketAcceptCertificateCallbackIgnoreTLSErrors(GTlsConnection* connection, GTlsCertificate* certificate, GTlsCertificateFlags errors, NetworkSessionSoup* session)
|
|
+{
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
#if USE(SOUP2)
|
|
static gboolean webSocketAcceptCertificateCallback(GTlsConnection* connection, GTlsCertificate* certificate, GTlsCertificateFlags errors, NetworkSessionSoup* session)
|
|
{
|
|
@@ -130,12 +135,16 @@ std::unique_ptr<WebSocketTask> NetworkSessionSoup::createWebSocketTask(WebPagePr
|
|
#if USE(SOUP2)
|
|
g_signal_connect(soupMessage.get(), "network-event", G_CALLBACK(webSocketMessageNetworkEventCallback), this);
|
|
#else
|
|
- g_signal_connect(soupMessage.get(), "accept-certificate", G_CALLBACK(+[](SoupMessage* message, GTlsCertificate* certificate, GTlsCertificateFlags errors, NetworkSessionSoup* session) -> gboolean {
|
|
- if (DeprecatedGlobalSettings::allowsAnySSLCertificate())
|
|
- return TRUE;
|
|
-
|
|
- return !session->soupNetworkSession().checkTLSErrors(soup_message_get_uri(message), certificate, errors);
|
|
- }), this);
|
|
+ if (ignoreCertificateErrors()) {
|
|
+ g_signal_connect(soupMessage.get(), "accept-certificate", G_CALLBACK(webSocketAcceptCertificateCallbackIgnoreTLSErrors), this);
|
|
+ } else {
|
|
+ g_signal_connect(soupMessage.get(), "accept-certificate", G_CALLBACK(+[](SoupMessage* message, GTlsCertificate* certificate, GTlsCertificateFlags errors, NetworkSessionSoup* session) -> gboolean {
|
|
+ if (DeprecatedGlobalSettings::allowsAnySSLCertificate())
|
|
+ return TRUE;
|
|
+
|
|
+ return !session->soupNetworkSession().checkTLSErrors(soup_message_get_uri(message), certificate, errors);
|
|
+ }), this);
|
|
+ }
|
|
#endif
|
|
}
|
|
|
|
diff --git a/Source/WebKit/PlatformGTK.cmake b/Source/WebKit/PlatformGTK.cmake
|
|
index 2f33b1c02a7d0e352a5662c19b44cfa7a161b8f5..263d65ba51319116f161db5918439c081cde43fd 100644
|
|
--- a/Source/WebKit/PlatformGTK.cmake
|
|
+++ b/Source/WebKit/PlatformGTK.cmake
|
|
@@ -320,6 +320,9 @@ list(APPEND WebKit_SYSTEM_INCLUDE_DIRECTORIES
|
|
${GSTREAMER_PBUTILS_INCLUDE_DIRS}
|
|
${GTK_INCLUDE_DIRS}
|
|
${LIBSOUP_INCLUDE_DIRS}
|
|
+# Playwright begin
|
|
+ ${LIBVPX_INCLUDE_DIRS}
|
|
+# Playwright end
|
|
)
|
|
|
|
list(APPEND WebKit_INTERFACE_INCLUDE_DIRECTORIES
|
|
@@ -356,6 +359,9 @@ if (USE_LIBWEBRTC)
|
|
list(APPEND WebKit_SYSTEM_INCLUDE_DIRECTORIES
|
|
"${THIRDPARTY_DIR}/libwebrtc/Source/"
|
|
"${THIRDPARTY_DIR}/libwebrtc/Source/webrtc"
|
|
+# Playwright begin
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/include"
|
|
+# Playwright end
|
|
)
|
|
endif ()
|
|
|
|
@@ -407,6 +413,12 @@ else ()
|
|
set(WebKitGTK_ENUM_HEADER_TEMPLATE ${WEBKIT_DIR}/UIProcess/API/gtk/WebKitEnumTypesGtk3.h.in)
|
|
endif ()
|
|
|
|
+# Playwright begin
|
|
+list(APPEND WebKit_PRIVATE_INCLUDE_DIRECTORIES
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libwebm"
|
|
+)
|
|
+# Playwright end
|
|
+
|
|
# To generate WebKitEnumTypes.h we want to use all installed headers, except WebKitEnumTypes.h itself.
|
|
set(WebKitGTK_ENUM_GENERATION_HEADERS ${WebKitGTK_INSTALLED_HEADERS})
|
|
list(REMOVE_ITEM WebKitGTK_ENUM_GENERATION_HEADERS ${WebKitGTK_DERIVED_SOURCES_DIR}/webkit/WebKitEnumTypes.h)
|
|
diff --git a/Source/WebKit/PlatformWPE.cmake b/Source/WebKit/PlatformWPE.cmake
|
|
index 8376382ba17ea308210e2a46a60a90a2da2d013c..7935f07612a7ce44cae17e4a8650dcee36ceb49b 100644
|
|
--- a/Source/WebKit/PlatformWPE.cmake
|
|
+++ b/Source/WebKit/PlatformWPE.cmake
|
|
@@ -114,6 +114,8 @@ list(APPEND WebKit_SERIALIZATION_IN_FILES
|
|
Shared/glib/UserMessage.serialization.in
|
|
|
|
Shared/soup/WebCoreArgumentCodersSoup.serialization.in
|
|
+
|
|
+ Shared/libwpe/ArgumentCodersWPE.serialization.in
|
|
)
|
|
|
|
list(APPEND WebKit_DERIVED_SOURCES
|
|
@@ -213,6 +215,7 @@ set(WPE_API_HEADER_TEMPLATES
|
|
${WEBKIT_DIR}/UIProcess/API/glib/WebKitWindowProperties.h.in
|
|
${WEBKIT_DIR}/UIProcess/API/glib/WebKitWebsitePolicies.h.in
|
|
${WEBKIT_DIR}/UIProcess/API/glib/webkit.h.in
|
|
+ ${WEBKIT_DIR}/UIProcess/API/gtk/WebKitPointerLockPermissionRequest.h.in
|
|
)
|
|
|
|
if (ENABLE_2022_GLIB_API)
|
|
@@ -423,7 +426,16 @@ list(APPEND WebKit_SYSTEM_INCLUDE_DIRECTORIES
|
|
${GIO_UNIX_INCLUDE_DIRS}
|
|
${GLIB_INCLUDE_DIRS}
|
|
${LIBSOUP_INCLUDE_DIRS}
|
|
+# Playwright begin
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/include"
|
|
+# Playwright end
|
|
+)
|
|
+
|
|
+# Playwright begin
|
|
+list(APPEND WebKit_PRIVATE_INCLUDE_DIRECTORIES
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libwebm"
|
|
)
|
|
+# Playwright end
|
|
|
|
list(APPEND WebKit_LIBRARIES
|
|
WPE::libwpe
|
|
diff --git a/Source/WebKit/PlatformWin.cmake b/Source/WebKit/PlatformWin.cmake
|
|
index e0e9b52c43ee0742f705159c1369f2938b9c4956..05fa7d93a721f200143e9d3ac45a75ce942afc88 100644
|
|
--- a/Source/WebKit/PlatformWin.cmake
|
|
+++ b/Source/WebKit/PlatformWin.cmake
|
|
@@ -54,8 +54,13 @@ list(APPEND WebKit_SOURCES
|
|
UIProcess/WebsiteData/win/WebsiteDataStoreWin.cpp
|
|
|
|
UIProcess/win/AutomationClientWin.cpp
|
|
+
|
|
+ UIProcess/win/InspectorTargetProxyWin.cpp
|
|
+ UIProcess/win/InspectorPlaywrightAgentClientWin.cpp
|
|
UIProcess/win/PageClientImpl.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/AcceleratedSurface.cpp
|
|
|
|
@@ -120,8 +126,81 @@ list(APPEND WebKit_PUBLIC_FRAMEWORK_HEADERS
|
|
|
|
list(APPEND WebKit_PRIVATE_LIBRARIES
|
|
comctl32
|
|
+ ${LIBVPX_CUSTOM_LIBRARY}
|
|
+)
|
|
+
|
|
+# Playwright begin
|
|
+list(APPEND WebKit_SYSTEM_INCLUDE_DIRECTORIES
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/include"
|
|
+ "${LIBVPX_CUSTOM_INCLUDE_DIR}"
|
|
+)
|
|
+
|
|
+list(APPEND WebKit_PRIVATE_INCLUDE_DIRECTORIES
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libwebm"
|
|
)
|
|
|
|
+set(vpxutils_SOURCES
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libwebm/mkvmuxer/mkvmuxer.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libwebm/mkvmuxer/mkvmuxerutil.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libwebm/mkvmuxer/mkvwriter.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/compare.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/compare_common.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/compare_gcc.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/compare_msa.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/compare_neon64.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/compare_neon.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/compare_win.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/convert_argb.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/convert.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/convert_from_argb.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/convert_from.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/convert_jpeg.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/convert_to_argb.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/convert_to_i420.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/cpu_id.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/mjpeg_decoder.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/mjpeg_validate.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/planar_functions.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/rotate_any.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/rotate_argb.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/rotate.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/rotate_common.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/rotate_gcc.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/rotate_msa.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/rotate_neon64.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/rotate_neon.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/rotate_win.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/row_any.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/row_common.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/row_gcc.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/row_msa.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/row_neon64.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/row_neon.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/row_win.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/scale_any.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/scale_argb.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/scale.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/scale_common.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/scale_gcc.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/scale_msa.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/scale_neon64.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/scale_neon.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/scale_rvv.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/scale_uv.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/scale_win.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/video_common.cc"
|
|
+)
|
|
+
|
|
+add_library(vpxutils STATIC ${vpxutils_SOURCES})
|
|
+
|
|
+target_include_directories(vpxutils PRIVATE
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/include"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libwebm"
|
|
+)
|
|
+
|
|
+target_link_libraries(WebKit PRIVATE vpxutils)
|
|
+# Playwright end
|
|
+
|
|
list(APPEND WebProcess_SOURCES
|
|
WebProcess/EntryPoint/win/WebProcessMain.cpp
|
|
|
|
diff --git a/Source/WebKit/Shared/AuxiliaryProcess.h b/Source/WebKit/Shared/AuxiliaryProcess.h
|
|
index 4510beb0b7403138abef4c9b5e892271fe8beaab..dae8f31ef187d7b086dd84d7e356839dc2811154 100644
|
|
--- a/Source/WebKit/Shared/AuxiliaryProcess.h
|
|
+++ b/Source/WebKit/Shared/AuxiliaryProcess.h
|
|
@@ -212,6 +212,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 c72c9733800b6f836c4d3ccb0b50d40c3ee83067..e2955ddebe388d886ca43d733dce0eb58256ce8b 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,23 +71,39 @@ 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, WallTime timestamp, Vector<WebCore::KeypressCommand>&& commands)
|
|
+ : WebKeyboardEvent(type, text, unmodifiedText, key, code, keyIdentifier, windowsVirtualKeyCode, nativeVirtualKeyCode, isAutoRepeat, isKeypad, isSystemKey, modifiers, timestamp, WTFMove(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, WallTime timestamp, Vector<String>&& commands)
|
|
+ : WebKeyboardEvent(type, text, unmodifiedText, key, code, keyIdentifier, windowsVirtualKeyCode, nativeVirtualKeyCode, isAutoRepeat, isKeypad, isSystemKey, modifiers, timestamp, WTFMove(commands))
|
|
+ {
|
|
+ }
|
|
#elif PLATFORM(IOS_FAMILY)
|
|
enum class HandledByInputMethod : bool { No, Yes };
|
|
NativeWebKeyboardEvent(::WebEvent *, HandledByInputMethod);
|
|
#elif 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, WallTime timestamp)
|
|
+ : WebKeyboardEvent(type, text, unmodifiedText, key, code, keyIdentifier, windowsVirtualKeyCode, nativeVirtualKeyCode, isAutoRepeat, isKeypad, isSystemKey, modifiers, timestamp)
|
|
+ {
|
|
+ }
|
|
#if PLATFORM(WPE) && ENABLE(WPE_PLATFORM)
|
|
NativeWebKeyboardEvent(WPEEvent*, const String&, bool isAutoRepeat);
|
|
NativeWebKeyboardEvent(const String&, std::optional<Vector<WebCore::CompositionUnderline>>&&, std::optional<EditingRange>&&);
|
|
#endif
|
|
#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, WallTime 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 a39b6dd673e1639f9fe64c23dd054f0ff57f7464..4026f6244889e5a0ee85edb72696d0be20ba531d 100644
|
|
--- a/Source/WebKit/Shared/NativeWebMouseEvent.h
|
|
+++ b/Source/WebKit/Shared/NativeWebMouseEvent.h
|
|
@@ -87,6 +87,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, WallTime timestamp)
|
|
+ : WebMouseEvent({type, modifiers, timestamp}, button, buttons, position, globalPosition, deltaX, deltaY, deltaZ, clickCount) { }
|
|
+#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 f8e96218fd2671d1c0aca5e549efe0d8b94ef0f9..6cebd61bceb39c08e916fe991e4c3fc6f34b4704 100644
|
|
--- a/Source/WebKit/Shared/NativeWebWheelEvent.h
|
|
+++ b/Source/WebKit/Shared/NativeWebWheelEvent.h
|
|
@@ -74,7 +74,8 @@ public:
|
|
#elif PLATFORM(WIN)
|
|
NativeWebWheelEvent(HWND, UINT message, WPARAM, LPARAM, float deviceScaleFactor);
|
|
#endif
|
|
-
|
|
+ NativeWebWheelEvent(const WebWheelEvent & webWheelEvent)
|
|
+ : WebWheelEvent(webWheelEvent) { }
|
|
#if USE(APPKIT)
|
|
NSEvent* nativeEvent() const { return m_nativeEvent.get(); }
|
|
#elif PLATFORM(GTK)
|
|
diff --git a/Source/WebKit/Shared/Pasteboard.serialization.in b/Source/WebKit/Shared/Pasteboard.serialization.in
|
|
index ea1eb9f00feaaecf73bdddc37c904e88f43bfa85..8a631e5293a11abd650958baad4e967840a9a526 100644
|
|
--- a/Source/WebKit/Shared/Pasteboard.serialization.in
|
|
+++ b/Source/WebKit/Shared/Pasteboard.serialization.in
|
|
@@ -73,7 +73,7 @@ header: <WebCore/Pasteboard.h>
|
|
#if PLATFORM(MAC)
|
|
String userVisibleForm
|
|
#endif
|
|
-#if PLATFORM(GTK)
|
|
+#if PLATFORM(GTK) || PLATFORM(WPE)
|
|
String markup
|
|
#endif
|
|
};
|
|
diff --git a/Source/WebKit/Shared/WebCoreArgumentCoders.serialization.in b/Source/WebKit/Shared/WebCoreArgumentCoders.serialization.in
|
|
index db25c4a2dbb7fd8f9e0885757655eed1ebf64d35..1c21752b0f3710d7dfb0c70421c17de740274439 100644
|
|
--- a/Source/WebKit/Shared/WebCoreArgumentCoders.serialization.in
|
|
+++ b/Source/WebKit/Shared/WebCoreArgumentCoders.serialization.in
|
|
@@ -2814,6 +2814,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();
|
|
@@ -3621,6 +3624,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 8040819bba9dcde87311aaafe7d8177d0e07281d..24972c0a357324d27910ae6ff1979d1c6b8bc758 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, WallTime 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(WTFMove(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, WallTime 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(WTFMove(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, WallTime 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()
|
|
{
|
|
}
|
|
diff --git a/Source/WebKit/Shared/WebKeyboardEvent.h b/Source/WebKit/Shared/WebKeyboardEvent.h
|
|
index 8e4e2d6d5ebb08fba210fe0a328d45290348dd11..32a43192ec1e918c33b1b046b71d2ec571dc92ff 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>, WallTime 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>, WallTime 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)
|
|
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>, WallTime 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>, WallTime timestamp);
|
|
#endif
|
|
|
|
const String& text() const { return m_text; }
|
|
diff --git a/Source/WebKit/Shared/WebMouseEvent.h b/Source/WebKit/Shared/WebMouseEvent.h
|
|
index fd4722dd38df74f259d8add02025549022a0a205..e1c33f6d766707170935b3e77e81098cc8e3786d 100644
|
|
--- a/Source/WebKit/Shared/WebMouseEvent.h
|
|
+++ b/Source/WebKit/Shared/WebMouseEvent.h
|
|
@@ -70,6 +70,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::IntPoint& position() const { return m_position; } // Relative to the view.
|
|
void setPosition(const WebCore::IntPoint& position) { m_position = position; }
|
|
const WebCore::IntPoint& globalPosition() const { return m_globalPosition; }
|
|
diff --git a/Source/WebKit/Shared/WebPageCreationParameters.h b/Source/WebKit/Shared/WebPageCreationParameters.h
|
|
index 95aa13fdc5bd9d5ece8f3ff4279c0ebe03f3cdef..bde8a24fcce390b859f6241c9816eb6430376d6b 100644
|
|
--- a/Source/WebKit/Shared/WebPageCreationParameters.h
|
|
+++ b/Source/WebKit/Shared/WebPageCreationParameters.h
|
|
@@ -309,6 +309,8 @@ struct WebPageCreationParameters {
|
|
WebCore::ShouldRelaxThirdPartyCookieBlocking shouldRelaxThirdPartyCookieBlocking { WebCore::ShouldRelaxThirdPartyCookieBlocking::No };
|
|
|
|
bool httpsUpgradeEnabled { true };
|
|
+
|
|
+ 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 0c9594c44a6f1962642835b221b1c27d15cc33d7..b6898b100be0fe64aba87305711846f066bf9459 100644
|
|
--- a/Source/WebKit/Shared/WebPageCreationParameters.serialization.in
|
|
+++ b/Source/WebKit/Shared/WebPageCreationParameters.serialization.in
|
|
@@ -229,6 +229,8 @@ enum class WebCore::UserInterfaceLayoutDirection : bool;
|
|
|
|
bool httpsUpgradeEnabled;
|
|
|
|
+ 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 40d482a1860598391363027e63b010b3ce32b014..e654ae5e7c54b788badd463b1f2b653160d0370e 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 char* 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), StringView::fromLatin1(processName));
|
|
diff --git a/Source/WebKit/Shared/gtk/NativeWebKeyboardEventGtk.cpp b/Source/WebKit/Shared/gtk/NativeWebKeyboardEventGtk.cpp
|
|
index 8d33ceb065fb3e90372b0c696779189d07838da0..6e3194c3e96e46bfa09f8d706324e6515df1e7f4 100644
|
|
--- a/Source/WebKit/Shared/gtk/NativeWebKeyboardEventGtk.cpp
|
|
+++ b/Source/WebKit/Shared/gtk/NativeWebKeyboardEventGtk.cpp
|
|
@@ -51,12 +51,12 @@ 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, WallTime::now()), text, key, code, keyIdentifier, windowsVirtualKeyCode, nativeVirtualKeyCode, false, std::nullopt, std::nullopt, WTFMove(commands), isAutoRepeat, isKeypad)
|
|
+ : WebKeyboardEvent(WebEvent(type, modifiers, WallTime::now()), text, key, code, keyIdentifier, windowsVirtualKeyCode, nativeVirtualKeyCode, false, std::nullopt, std::nullopt, WTFMove(commands), false, isKeypad)
|
|
{
|
|
}
|
|
|
|
NativeWebKeyboardEvent::NativeWebKeyboardEvent(const NativeWebKeyboardEvent& event)
|
|
- : WebKeyboardEvent(WebEvent(event.type(), event.modifiers(), event.timestamp()), event.text(), event.key(), event.code(), event.keyIdentifier(), event.windowsVirtualKeyCode(), event.nativeVirtualKeyCode(), event.handledByInputMethod(), std::optional<Vector<WebCore::CompositionUnderline>>(event.preeditUnderlines()), std::optional<EditingRange>(event.preeditSelectionRange()), Vector<String>(event.commands()), event.isAutoRepeat(), event.isKeypad())
|
|
+ : WebKeyboardEvent(event)
|
|
, m_nativeEvent(event.nativeEvent() ? constructNativeEvent(event.nativeEvent()) : nullptr)
|
|
{
|
|
}
|
|
diff --git a/Source/WebKit/Shared/gtk/NativeWebMouseEventGtk.cpp b/Source/WebKit/Shared/gtk/NativeWebMouseEventGtk.cpp
|
|
index 9a1c3f09c756ea368ac2d68e183a13e2eb47ead7..01c738376230f83376d80d6d225543a3914943dd 100644
|
|
--- a/Source/WebKit/Shared/gtk/NativeWebMouseEventGtk.cpp
|
|
+++ b/Source/WebKit/Shared/gtk/NativeWebMouseEventGtk.cpp
|
|
@@ -61,7 +61,7 @@ NativeWebMouseEvent::NativeWebMouseEvent(WebEventType type, WebMouseEventButton
|
|
}
|
|
|
|
NativeWebMouseEvent::NativeWebMouseEvent(const NativeWebMouseEvent& event)
|
|
- : WebMouseEvent(WebEvent(event.type(), event.modifiers(), event.timestamp()), event.button(), event.buttons(), event.position(), event.globalPosition(), event.deltaX(), event.deltaY(), event.deltaZ(), event.clickCount(), 0, WebMouseEventSyntheticClickType::NoTap, event.isTouchEvent(), event.pointerId(), event.pointerType())
|
|
+ : WebMouseEvent(event)
|
|
, m_nativeEvent(event.nativeEvent() ? constructNativeEvent(const_cast<GdkEvent*>(event.nativeEvent())) : nullptr)
|
|
{
|
|
}
|
|
diff --git a/Source/WebKit/Shared/libwpe/ArgumentCodersWPE.serialization.in b/Source/WebKit/Shared/libwpe/ArgumentCodersWPE.serialization.in
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..f4f09d171ebf9774b3f8744751d220d35941fcb5
|
|
--- /dev/null
|
|
+++ b/Source/WebKit/Shared/libwpe/ArgumentCodersWPE.serialization.in
|
|
@@ -0,0 +1,32 @@
|
|
+# Copyright (C) 2024 Igalia, S.L. All rights reserved.
|
|
+#
|
|
+# Redistribution and use in source and binary forms, with or without
|
|
+# modification, are permitted provided that the following conditions
|
|
+# are met:
|
|
+# 1. Redistributions of source code must retain the above copyright
|
|
+# notice, this list of conditions and the following disclaimer.
|
|
+# 2. Redistributions in binary form must reproduce the above copyright
|
|
+# notice, this list of conditions and the following disclaimer in the
|
|
+# documentation and/or other materials provided with the distribution.
|
|
+#
|
|
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
|
|
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
+# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
|
|
+# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
+
|
|
+header: <WebCore/SelectionData.h>
|
|
+class WebCore::SelectionData {
|
|
+ String text()
|
|
+ String markup()
|
|
+ URL url()
|
|
+ String uriList()
|
|
+ RefPtr<WebCore::Image> image()
|
|
+ RefPtr<WebCore::SharedBuffer> customData()
|
|
+ bool canSmartReplace()
|
|
+}
|
|
diff --git a/Source/WebKit/Shared/unix/AuxiliaryProcessMain.cpp b/Source/WebKit/Shared/unix/AuxiliaryProcessMain.cpp
|
|
index 7fcd22cd2172cd7fa77aee12ad5cfcf7a435abba..bc822b40eea889fb0499dd4e78f89f04d87c64a1 100644
|
|
--- a/Source/WebKit/Shared/unix/AuxiliaryProcessMain.cpp
|
|
+++ b/Source/WebKit/Shared/unix/AuxiliaryProcessMain.cpp
|
|
@@ -40,6 +40,15 @@
|
|
|
|
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)
|
|
@@ -94,6 +103,10 @@ WTF_ALLOW_UNSAFE_BUFFER_USAGE_END
|
|
}
|
|
#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 053e9336017d8818b3cbea79ce7c145fd5c46274..5632498d6ef875df80fc68ec206a9d08e5d05a6f 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/Shared/win/WebEventFactory.cpp b/Source/WebKit/Shared/win/WebEventFactory.cpp
|
|
index 23ec85c142892f8f9bee7d063c3ff0cafe6c53a5..4f0021ad12ded82b7ac958fc6c752410ce2ac764 100644
|
|
--- a/Source/WebKit/Shared/win/WebEventFactory.cpp
|
|
+++ b/Source/WebKit/Shared/win/WebEventFactory.cpp
|
|
@@ -484,7 +484,7 @@ WebKeyboardEvent WebEventFactory::createWebKeyboardEvent(HWND hwnd, UINT message
|
|
#if ENABLE(TOUCH_EVENTS)
|
|
WebTouchEvent WebEventFactory::createWebTouchEvent()
|
|
{
|
|
- return WebTouchEvent();
|
|
+ return WebTouchEvent({ WebEventType::TouchMove, OptionSet<WebEventModifier> { }, WallTime::now()}, { }, { }, { });
|
|
}
|
|
#endif // ENABLE(TOUCH_EVENTS)
|
|
|
|
diff --git a/Source/WebKit/Sources.txt b/Source/WebKit/Sources.txt
|
|
index 1a8bb4ce0d39f7d03264bb010be3158f3bd87000..34e2d4d603fae0acc8ace9afb8e3ff549e87bf07 100644
|
|
--- a/Source/WebKit/Sources.txt
|
|
+++ b/Source/WebKit/Sources.txt
|
|
@@ -389,6 +389,7 @@ Shared/XR/XRDeviceProxy.cpp
|
|
UIProcess/AuxiliaryProcessProxy.cpp
|
|
UIProcess/BackgroundProcessResponsivenessTimer.cpp
|
|
UIProcess/BrowsingContextGroup.cpp
|
|
+UIProcess/BrowserInspectorPipe.cpp
|
|
UIProcess/DeviceIdHashSaltStorage.cpp
|
|
UIProcess/DisplayLink.cpp
|
|
UIProcess/DisplayLinkProcessProxyClient.cpp
|
|
@@ -398,16 +399,20 @@ 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/ModelElementController.cpp
|
|
UIProcess/OverrideLanguages.cpp
|
|
UIProcess/PageLoadState.cpp
|
|
+UIProcess/PlaywrightFullScreenManagerProxyClient.cpp
|
|
UIProcess/ProcessAssertion.cpp
|
|
UIProcess/ProcessThrottler.cpp
|
|
UIProcess/ProvisionalFrameProxy.cpp
|
|
UIProcess/ProvisionalPageProxy.cpp
|
|
+UIProcess/RemoteInspectorPipe.cpp
|
|
UIProcess/RemotePageDrawingAreaProxy.cpp
|
|
UIProcess/RemotePageFullscreenManagerProxy.cpp
|
|
UIProcess/RemotePageProxy.cpp
|
|
@@ -450,6 +455,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
|
|
@@ -596,7 +603,11 @@ UIProcess/Inspector/WebInspectorUtilities.cpp
|
|
UIProcess/Inspector/WebPageDebuggable.cpp
|
|
UIProcess/Inspector/WebPageInspectorController.cpp
|
|
|
|
+UIProcess/Inspector/Agents/CairoJpegEncoder.cpp
|
|
UIProcess/Inspector/Agents/InspectorBrowserAgent.cpp
|
|
+UIProcess/Inspector/Agents/InspectorScreencastAgent.cpp
|
|
+UIProcess/Inspector/Agents/ScreencastEncoder.cpp
|
|
+UIProcess/Inspector/Agents/WebMFileWriter.cpp
|
|
|
|
UIProcess/Media/AudioSessionRoutingArbitratorProxy.cpp
|
|
UIProcess/Media/MediaUsageManager.cpp
|
|
diff --git a/Source/WebKit/SourcesCocoa.txt b/Source/WebKit/SourcesCocoa.txt
|
|
index 19e2664300bd081ae5124d6b08055c028f04ebb2..5b851c95b75262264dec59503b74c2548b9ee737 100644
|
|
--- a/Source/WebKit/SourcesCocoa.txt
|
|
+++ b/Source/WebKit/SourcesCocoa.txt
|
|
@@ -270,6 +270,7 @@ UIProcess/API/Cocoa/_WKArchiveExclusionRule.mm
|
|
UIProcess/API/Cocoa/_WKAttachment.mm
|
|
UIProcess/API/Cocoa/_WKAutomationSession.mm
|
|
UIProcess/API/Cocoa/_WKAutomationSessionConfiguration.mm
|
|
+UIProcess/API/Cocoa/_WKBrowserInspector.mm
|
|
UIProcess/API/Cocoa/_WKContentRuleListAction.mm
|
|
UIProcess/API/Cocoa/_WKContextMenuElementInfo.mm
|
|
UIProcess/API/Cocoa/_WKCustomHeaderFields.mm @no-unify
|
|
@@ -467,6 +468,7 @@ UIProcess/Inspector/ios/WKInspectorHighlightView.mm
|
|
UIProcess/Inspector/ios/WKInspectorNodeSearchGestureRecognizer.mm
|
|
|
|
UIProcess/Inspector/mac/RemoteWebInspectorUIProxyMac.mm
|
|
+UIProcess/Inspector/mac/ScreencastEncoderMac.mm
|
|
UIProcess/Inspector/mac/WebInspectorUIProxyMac.mm
|
|
UIProcess/Inspector/mac/WKInspectorResourceURLSchemeHandler.mm
|
|
UIProcess/Inspector/mac/WKInspectorViewController.mm
|
|
diff --git a/Source/WebKit/SourcesGTK.txt b/Source/WebKit/SourcesGTK.txt
|
|
index 3c8d209cba714f7df7c1e78d951886692ca58b09..2d893bdc430f9e81a3369a9470d21134aa63c9a1 100644
|
|
--- a/Source/WebKit/SourcesGTK.txt
|
|
+++ b/Source/WebKit/SourcesGTK.txt
|
|
@@ -122,6 +122,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
|
|
@@ -252,6 +253,7 @@ UIProcess/glib/DisplayVBlankMonitor.cpp
|
|
UIProcess/glib/DisplayVBlankMonitorDRM.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
|
|
@@ -270,6 +272,7 @@ UIProcess/gtk/DisplayX11.cpp @no-unify
|
|
UIProcess/gtk/DisplayWayland.cpp @no-unify
|
|
UIProcess/gtk/WebDateTimePickerGtk.cpp
|
|
UIProcess/gtk/HardwareAccelerationManager.cpp
|
|
+UIProcess/gtk/InspectorTargetProxyGtk.cpp
|
|
UIProcess/gtk/KeyBindingTranslator.cpp
|
|
UIProcess/gtk/PointerLockManager.cpp @no-unify
|
|
UIProcess/gtk/PointerLockManagerWayland.cpp @no-unify
|
|
@@ -283,6 +286,8 @@ UIProcess/gtk/ViewGestureControllerGtk.cpp
|
|
UIProcess/gtk/WebColorPickerGtk.cpp
|
|
UIProcess/gtk/WebContextMenuProxyGtk.cpp
|
|
UIProcess/gtk/WebDataListSuggestionsDropdownGtk.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 42931a643d8ff85469b5e162a42e9a09a8bdca3f..f962949675b8de7b79e6d56bb8bb3f342b39dfe8 100644
|
|
--- a/Source/WebKit/SourcesWPE.txt
|
|
+++ b/Source/WebKit/SourcesWPE.txt
|
|
@@ -124,6 +124,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
|
|
@@ -157,6 +158,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
|
|
@@ -221,6 +223,7 @@ UIProcess/glib/DisplayVBlankMonitor.cpp
|
|
UIProcess/glib/DisplayVBlankMonitorDRM.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
|
|
@@ -254,8 +257,14 @@ UIProcess/linux/MemoryPressureMonitor.cpp
|
|
UIProcess/soup/WebProcessPoolSoup.cpp
|
|
|
|
UIProcess/wpe/AcceleratedBackingStoreDMABuf.cpp
|
|
+UIProcess/wpe/InspectorTargetProxyWPE.cpp
|
|
UIProcess/wpe/ScreenManagerWPE.cpp
|
|
UIProcess/wpe/SystemSettingsManagerProxyWPE.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/WebPreferencesWPE.cpp
|
|
|
|
@@ -282,6 +291,8 @@ WebProcess/WebCoreSupport/glib/WebEditorClientGLib.cpp
|
|
|
|
WebProcess/WebCoreSupport/soup/WebFrameNetworkingContext.cpp
|
|
|
|
+WebProcess/WebCoreSupport/wpe/WebDragClientWPE.cpp
|
|
+
|
|
WebProcess/WebCoreSupport/wpe/WebEditorClientWPE.cpp
|
|
|
|
WebProcess/WebPage/AcceleratedSurface.cpp
|
|
diff --git a/Source/WebKit/UIProcess/API/APIPageConfiguration.cpp b/Source/WebKit/UIProcess/API/APIPageConfiguration.cpp
|
|
index 0f27d0e97c1039ad5c95086c0e7eb72f4fe85db1..9ca848d9e0c78bce8b77721debf18deba76f4b2c 100644
|
|
--- a/Source/WebKit/UIProcess/API/APIPageConfiguration.cpp
|
|
+++ b/Source/WebKit/UIProcess/API/APIPageConfiguration.cpp
|
|
@@ -275,6 +275,11 @@ WebPageProxy* PageConfiguration::relatedPage() const
|
|
return m_data.relatedPage.get();
|
|
}
|
|
|
|
+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 ba3fed377d5f2a799fbf7b38a5bc2f03efbe7535..e4c41d0a444d12f80d0402591dfa39e8e68e4fd0 100644
|
|
--- a/Source/WebKit/UIProcess/API/APIPageConfiguration.h
|
|
+++ b/Source/WebKit/UIProcess/API/APIPageConfiguration.h
|
|
@@ -160,6 +160,10 @@ public:
|
|
WebKit::WebPageProxy* relatedPage() const;
|
|
void setRelatedPage(WeakPtr<WebKit::WebPageProxy>&& relatedPage) { m_data.relatedPage = WTFMove(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 = WTFMove(openerPageForInspector); }
|
|
+
|
|
WebKit::WebPageProxy* pageToCloneSessionStorageFrom() const;
|
|
void setPageToCloneSessionStorageFrom(WeakPtr<WebKit::WebPageProxy>&&);
|
|
|
|
@@ -518,6 +522,7 @@ private:
|
|
#endif
|
|
RefPtr<WebKit::WebPageGroup> pageGroup;
|
|
WeakPtr<WebKit::WebPageProxy> relatedPage;
|
|
+ WeakPtr<WebKit::WebPageProxy> openerPageForInspector;
|
|
std::optional<OpenerInfo> openerInfo;
|
|
WebCore::Site openedSite;
|
|
WTF::String openedMainFrameName;
|
|
diff --git a/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.cpp b/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.cpp
|
|
index e256b905bf9727aa7c8a48012237a6a6bc9acdbc..4e855c441af6f235f0fd8dfdd57b9bd6e4646492 100644
|
|
--- a/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.cpp
|
|
+++ b/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.cpp
|
|
@@ -52,6 +52,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 d2e8261c6db000aa41697b3bb50e2bea149edcdf..500c38b81d6804f64ff891e32b2c72ed98c9a629 100644
|
|
--- a/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.h
|
|
+++ b/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.h
|
|
@@ -96,6 +96,16 @@ public:
|
|
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 = WTFMove(languages); }
|
|
+ /* end playwright revert fb205fb */
|
|
+
|
|
bool alwaysRunsAtBackgroundPriority() const { return m_alwaysRunsAtBackgroundPriority; }
|
|
void setAlwaysRunsAtBackgroundPriority(bool alwaysRunsAtBackgroundPriority) { m_alwaysRunsAtBackgroundPriority = alwaysRunsAtBackgroundPriority; }
|
|
|
|
@@ -178,6 +188,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 fdfb6489e3b5f8b70da8918e72612c74ada771f6..fe58191302f84065523d048463b0b6b2fe71c394 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>, Object*) { }
|
|
diff --git a/Source/WebKit/UIProcess/API/C/WKInspector.cpp b/Source/WebKit/UIProcess/API/C/WKInspector.cpp
|
|
index 8ecba5bacfa39f9f5309a127e2c0aed527373a04..0873b91211c89b9cddab9ed74120c0b77e4c6aec 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)
|
|
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 2e9502e5767eb93b7a2d6488a113e69f953f3e4a..56969ab93991ef77dc020e0d3f7b7e4e71324416 100644
|
|
--- a/Source/WebKit/UIProcess/API/C/WKPage.cpp
|
|
+++ b/Source/WebKit/UIProcess/API/C/WKPage.cpp
|
|
@@ -1899,6 +1899,13 @@ void WKPageSetPageUIClient(WKPageRef pageRef, const WKPageUIClientBase* wkClient
|
|
completionHandler(String());
|
|
}
|
|
|
|
+ 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)
|
|
@@ -1928,6 +1935,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 1484f064ec89ee8c25c35df9f0a4462896699415..0622f4d5fc9144b9059395d9d0730a4ae00b7497 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);
|
|
@@ -1364,6 +1365,7 @@ typedef struct WKPageUIClientV14 {
|
|
|
|
// Version 14.
|
|
WKPageRunWebAuthenticationPanelCallback runWebAuthenticationPanel;
|
|
+ WKPageHandleJavaScriptDialogCallback handleJavaScriptDialog;
|
|
} WKPageUIClientV14;
|
|
|
|
typedef struct WKPageUIClientV15 {
|
|
@@ -1471,6 +1473,7 @@ typedef struct WKPageUIClientV15 {
|
|
|
|
// Version 14.
|
|
WKPageRunWebAuthenticationPanelCallback runWebAuthenticationPanel;
|
|
+ WKPageHandleJavaScriptDialogCallback handleJavaScriptDialog;
|
|
|
|
// Version 15.
|
|
WKPageDecidePolicyForSpeechRecognitionPermissionRequestCallback decidePolicyForSpeechRecognitionPermissionRequest;
|
|
@@ -1582,6 +1585,7 @@ typedef struct WKPageUIClientV16 {
|
|
|
|
// Version 14.
|
|
WKPageRunWebAuthenticationPanelCallback runWebAuthenticationPanel;
|
|
+ WKPageHandleJavaScriptDialogCallback handleJavaScriptDialog;
|
|
|
|
// Version 15.
|
|
WKPageDecidePolicyForSpeechRecognitionPermissionRequestCallback decidePolicyForSpeechRecognitionPermissionRequest;
|
|
@@ -1696,6 +1700,7 @@ typedef struct WKPageUIClientV17 {
|
|
|
|
// Version 14.
|
|
WKPageRunWebAuthenticationPanelCallback runWebAuthenticationPanel;
|
|
+ WKPageHandleJavaScriptDialogCallback handleJavaScriptDialog;
|
|
|
|
// Version 15.
|
|
WKPageDecidePolicyForSpeechRecognitionPermissionRequestCallback decidePolicyForSpeechRecognitionPermissionRequest;
|
|
@@ -1810,6 +1815,7 @@ typedef struct WKPageUIClientV18 {
|
|
|
|
// Version 14.
|
|
WKPageRunWebAuthenticationPanelCallback runWebAuthenticationPanel;
|
|
+ WKPageHandleJavaScriptDialogCallback handleJavaScriptDialog;
|
|
|
|
// Version 15.
|
|
WKPageDecidePolicyForSpeechRecognitionPermissionRequestCallback decidePolicyForSpeechRecognitionPermissionRequest;
|
|
@@ -1926,6 +1932,7 @@ typedef struct WKPageUIClientV19 {
|
|
|
|
// Version 14.
|
|
WKPageRunWebAuthenticationPanelCallback runWebAuthenticationPanel;
|
|
+ WKPageHandleJavaScriptDialogCallback handleJavaScriptDialog;
|
|
|
|
// Version 15.
|
|
WKPageDecidePolicyForSpeechRecognitionPermissionRequestCallback decidePolicyForSpeechRecognitionPermissionRequest;
|
|
diff --git a/Source/WebKit/UIProcess/API/Cocoa/WKPreferences.mm b/Source/WebKit/UIProcess/API/Cocoa/WKPreferences.mm
|
|
index 53350803b70ce91ba7d326b94435f7cbca375afa..4595ba4208f1a2e7864b2b0ed6e66db42c2d00a6 100644
|
|
--- a/Source/WebKit/UIProcess/API/Cocoa/WKPreferences.mm
|
|
+++ b/Source/WebKit/UIProcess/API/Cocoa/WKPreferences.mm
|
|
@@ -712,6 +712,16 @@ - (void)_setMediaCaptureRequiresSecureConnection:(BOOL)requiresSecureConnection
|
|
_preferences->setMediaCaptureRequiresSecureConnection(requiresSecureConnection);
|
|
}
|
|
|
|
+- (BOOL)_alternateWebMPlayerEnabled
|
|
+{
|
|
+ return _preferences->alternateWebMPlayerEnabled();
|
|
+}
|
|
+
|
|
+- (void)_setAlternateWebMPlayerEnabled:(BOOL)enabled
|
|
+{
|
|
+ _preferences->setAlternateWebMPlayerEnabled(enabled);
|
|
+}
|
|
+
|
|
- (double)_inactiveMediaCaptureStreamRepromptIntervalInMinutes
|
|
{
|
|
return _preferences->inactiveMediaCaptureStreamRepromptIntervalInMinutes();
|
|
diff --git a/Source/WebKit/UIProcess/API/Cocoa/WKPreferencesPrivate.h b/Source/WebKit/UIProcess/API/Cocoa/WKPreferencesPrivate.h
|
|
index 34d46d52f796ed9b06fafabd03864229cdd307ab..a74a1ea9f9a55421bd569d958d7c0baa8618ca6d 100644
|
|
--- a/Source/WebKit/UIProcess/API/Cocoa/WKPreferencesPrivate.h
|
|
+++ b/Source/WebKit/UIProcess/API/Cocoa/WKPreferencesPrivate.h
|
|
@@ -119,6 +119,7 @@ typedef NS_ENUM(NSInteger, _WKPitchCorrectionAlgorithm) {
|
|
@property (nonatomic, setter=_setMockCaptureDevicesEnabled:) BOOL _mockCaptureDevicesEnabled WK_API_AVAILABLE(macos(10.13), ios(11.0));
|
|
@property (nonatomic, setter=_setMockCaptureDevicesPromptEnabled:) BOOL _mockCaptureDevicesPromptEnabled WK_API_AVAILABLE(macos(10.13.4), ios(11.3));
|
|
@property (nonatomic, setter=_setMediaCaptureRequiresSecureConnection:) BOOL _mediaCaptureRequiresSecureConnection WK_API_AVAILABLE(macos(10.13), ios(11.0));
|
|
+@property (nonatomic, setter=_setAlternateWebMPlayerEnabled:) BOOL _alternateWebMPlayerEnabled WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
|
|
@property (nonatomic, setter=_setEnumeratingAllNetworkInterfacesEnabled:) BOOL _enumeratingAllNetworkInterfacesEnabled WK_API_AVAILABLE(macos(10.13), ios(11.0));
|
|
@property (nonatomic, setter=_setICECandidateFilteringEnabled:) BOOL _iceCandidateFilteringEnabled WK_API_AVAILABLE(macos(10.13.4), ios(11.3));
|
|
@property (nonatomic, setter=_setInactiveMediaCaptureStreamRepromptIntervalInMinutes:) double _inactiveMediaCaptureStreamRepromptIntervalInMinutes WK_API_AVAILABLE(macos(10.13.4), ios(11.3));
|
|
diff --git a/Source/WebKit/UIProcess/API/Cocoa/WKUIDelegate.h b/Source/WebKit/UIProcess/API/Cocoa/WKUIDelegate.h
|
|
index ef512c7ba09298b2291d0248988574163ff2e7c8..d42e7f9f7b66840b68e61ce46b4bbd6254518ef7 100644
|
|
--- a/Source/WebKit/UIProcess/API/Cocoa/WKUIDelegate.h
|
|
+++ b/Source/WebKit/UIProcess/API/Cocoa/WKUIDelegate.h
|
|
@@ -149,6 +149,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 eff4cf557033561ab20762d93a58c2d71f5505f0..9418e2c51e50190dee2b5d7c854eacea8c5a4b76 100644
|
|
--- a/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.h
|
|
+++ b/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.h
|
|
@@ -126,6 +126,8 @@ WK_CLASS_AVAILABLE(macos(10.11), ios(9.0))
|
|
#endif
|
|
#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 97a87094e648a15e2501fb39a46bf0fbb4cb50d9..b08c212a0372175859645f7dba0c704fe865451c 100644
|
|
--- a/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.mm
|
|
+++ b/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.mm
|
|
@@ -55,6 +55,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>
|
|
@@ -552,6 +553,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..5fabe06a3289689246c36dfd96eb9900a48b2b0f
|
|
--- /dev/null
|
|
+++ b/Source/WebKit/UIProcess/API/Cocoa/_WKBrowserInspector.h
|
|
@@ -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.
|
|
+ */
|
|
+
|
|
+#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;
|
|
+@property (nonatomic, strong) WKProcessPool *processPool;
|
|
+@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 426c7cbc897e22fd2e962dd3744959975d6ae6a0..f7a52359d7d42f970ef424b6c702b0ec1121a902 100644
|
|
--- a/Source/WebKit/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.h
|
|
+++ b/Source/WebKit/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.h
|
|
@@ -67,6 +67,7 @@ WK_CLASS_AVAILABLE(macos(10.10), ios(8.0))
|
|
@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 38b516d32edc4038508c664e0c4dc804cd477787..891dd8b2451ab771e451ea8ef74906d364e76007 100644
|
|
--- a/Source/WebKit/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.mm
|
|
+++ b/Source/WebKit/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.mm
|
|
@@ -241,6 +241,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 0a78daba00961bf10564a0b53067960b71d8b61d..696408b77c82e205a134edf2ee17ff971af226f3 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..575245fc1f279a75f7e74c26652cf772a2fc95b7
|
|
--- /dev/null
|
|
+++ b/Source/WebKit/UIProcess/API/glib/WebKitBrowserInspector.cpp
|
|
@@ -0,0 +1,158 @@
|
|
+/*
|
|
+ * 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 "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));
|
|
+}
|
|
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/WebKitUIClient.cpp b/Source/WebKit/UIProcess/API/glib/WebKitUIClient.cpp
|
|
index 9b6d8db85df969e609de036fac67374226ecd48e..2b293d5f24e562f06859432580f2cdfe40f8b9a6 100644
|
|
--- a/Source/WebKit/UIProcess/API/glib/WebKitUIClient.cpp
|
|
+++ b/Source/WebKit/UIProcess/API/glib/WebKitUIClient.cpp
|
|
@@ -101,6 +101,10 @@ private:
|
|
page.makeViewBlankIfUnpaintedSinceLastLoadCommit();
|
|
webkitWebViewRunJavaScriptPrompt(m_webView, message.utf8(), defaultValue.utf8(), WTFMove(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 5479cf466e1ba77ede37ff980e78bee85bbb094c..224c04a4bd9de6ad5661b15071c1267a57430547 100644
|
|
--- a/Source/WebKit/UIProcess/API/glib/WebKitWebContext.cpp
|
|
+++ b/Source/WebKit/UIProcess/API/glib/WebKitWebContext.cpp
|
|
@@ -423,10 +423,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 7d8de31fc7e373871e89ab41fc8f3a63fceea1c6..7d2785ed1798bd661d0f98e5ab68037d3cd02c51 100644
|
|
--- a/Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp
|
|
+++ b/Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp
|
|
@@ -37,6 +37,7 @@
|
|
#include "WebContextMenuItem.h"
|
|
#include "WebContextMenuItemData.h"
|
|
#include "WebFrameProxy.h"
|
|
+#include "WebPageInspectorController.h"
|
|
#include "WebKitAuthenticationRequestPrivate.h"
|
|
#include "WebKitBackForwardListPrivate.h"
|
|
#include "WebKitContextMenuClient.h"
|
|
@@ -150,6 +151,7 @@ enum {
|
|
CLOSE,
|
|
|
|
SCRIPT_DIALOG,
|
|
+ SCRIPT_DIALOG_HANDLED,
|
|
|
|
DECIDE_POLICY,
|
|
PERMISSION_REQUEST,
|
|
@@ -518,6 +520,16 @@ 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(WTFMove(surface));
|
|
+#elif USE(CAIRO)
|
|
+ if (RefPtr<cairo_surface_t> surface = adoptRef(webkitWebViewBackendTakeScreenshot(m_webView->priv->backend.get())))
|
|
+ getPage(m_webView).inspectorController().didPaint(surface.get());
|
|
+#endif
|
|
+
|
|
{
|
|
SetForScope inFrameDisplayedGuard(m_webView->priv->inFrameDisplayed, true);
|
|
for (const auto& callback : m_webView->priv->frameDisplayedCallbacks) {
|
|
@@ -534,6 +546,18 @@ void WebKitWebViewClient::frameDisplayed(WKWPE::View&)
|
|
}
|
|
}
|
|
|
|
+#if USE(SKIA)
|
|
+sk_sp<SkImage> WebKitWebViewClient::takeViewScreenshot()
|
|
+{
|
|
+ return sk_sp<SkImage>(webkitWebViewBackendTakeScreenshot(m_webView->priv->backend.get()));
|
|
+}
|
|
+#elif USE(CAIRO)
|
|
+cairo_surface_t* WebKitWebViewClient::takeViewScreenshot()
|
|
+{
|
|
+ return webkitWebViewBackendTakeScreenshot(m_webView->priv->backend.get());
|
|
+}
|
|
+#endif
|
|
+
|
|
void WebKitWebViewClient::willStartLoad(WKWPE::View&)
|
|
{
|
|
webkitWebViewWillStartLoad(m_webView);
|
|
@@ -620,7 +644,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;
|
|
@@ -943,6 +967,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, WTFMove(configuration));
|
|
webkitWebContextWebViewCreated(priv->context.get(), webView);
|
|
|
|
@@ -1982,6 +2010,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
|
|
@@ -2767,6 +2804,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 bf5b4c2bcca722e4d008f12194344c29c0db8824..ee6ee6b476ac28dee3a5983d03ba89ad0c9eb9ff 100644
|
|
--- a/Source/WebKit/UIProcess/API/glib/WebKitWebViewPrivate.h
|
|
+++ b/Source/WebKit/UIProcess/API/glib/WebKitWebViewPrivate.h
|
|
@@ -64,6 +64,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 763cd55f7abca011ac8bc4fef7f233bf52854cda..bd43917b274bf19ff9f3d96b7e80e20710372cba 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 986edbe2d0b6ff2ed5717a14a71f26c973604f0c..c688cc026456686a54916857ba0396702ebf4a1e 100644
|
|
--- a/Source/WebKit/UIProcess/API/gtk/PageClientImpl.cpp
|
|
+++ b/Source/WebKit/UIProcess/API/gtk/PageClientImpl.cpp
|
|
@@ -270,6 +270,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;
|
|
@@ -362,9 +364,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), WTFMove(clipRect));
|
|
+ return webkitWebViewBaseTakeViewSnapshot(WEBKIT_WEB_VIEW_BASE(m_viewWidget), WTFMove(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 bd11269e156a92ce0e44cab3da4e4adde5142f64..1761d7541f226232b16ba8da3a6d609280037389 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(const 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..45221096280941d747ef3f46749b1466b2d70090
|
|
--- /dev/null
|
|
+++ b/Source/WebKit/UIProcess/API/gtk/WebKitBrowserInspector.h
|
|
@@ -0,0 +1,81 @@
|
|
+/*
|
|
+ * 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);
|
|
+
|
|
+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 597dcdbd94e8899f60fc9a0566698fd142170926..8d7f77586e25d299c3043128536fd3801eccde4a 100644
|
|
--- a/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBase.cpp
|
|
+++ b/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBase.cpp
|
|
@@ -2873,6 +2873,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);
|
|
@@ -2929,12 +2934,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 3b8ca9470bab69dc26313111a79f954b10b30bf4..5c056dd6734f42d24bc168b4f5ba436584b3f7a8 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 "InputMethodState.h"
|
|
#include "RendererBufferFormat.h"
|
|
@@ -104,7 +105,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*);
|
|
|
|
@@ -145,3 +146,5 @@ void webkitWebViewBaseSetPlugID(WebKitWebViewBase*, const String&);
|
|
#endif
|
|
|
|
WebKit::RendererBufferFormat webkitWebViewBaseGetRendererBufferFormat(WebKitWebViewBase*);
|
|
+
|
|
+WebKit::AcceleratedBackingStore* webkitWebViewBaseGetAcceleratedBackingStore(WebKitWebViewBase*);
|
|
diff --git a/Source/WebKit/UIProcess/API/wpe/APIViewClient.h b/Source/WebKit/UIProcess/API/wpe/APIViewClient.h
|
|
index 7636ad733e7be66a74f8fede966b0acb905a5842..cf54287353d1e529c6765e3caf8d283abe1e3472 100644
|
|
--- a/Source/WebKit/UIProcess/API/wpe/APIViewClient.h
|
|
+++ b/Source/WebKit/UIProcess/API/wpe/APIViewClient.h
|
|
@@ -26,6 +26,12 @@
|
|
#pragma once
|
|
|
|
#include "UserMessage.h"
|
|
+#if USE(CAIRO)
|
|
+#include <cairo.h>
|
|
+#endif
|
|
+#if USE(SKIA)
|
|
+#include <skia/core/SkImage.h>
|
|
+#endif
|
|
#include <wtf/CompletionHandler.h>
|
|
#include <wtf/TZoneMallocInlines.h>
|
|
|
|
@@ -50,6 +56,13 @@ public:
|
|
virtual bool isGLibBasedAPI() { return false; }
|
|
|
|
virtual void frameDisplayed(WKWPE::View&) { }
|
|
+// Playwright begin
|
|
+#if USE(CAIRO)
|
|
+ virtual cairo_surface_t* takeViewScreenshot() { return nullptr; }
|
|
+#elif 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 76f77a9a50f721e2d71def6ca5c81ad68274653a..c9b583bd70d87586fd7ea727c20ada6f01dffb72 100644
|
|
--- a/Source/WebKit/UIProcess/API/wpe/PageClientImpl.cpp
|
|
+++ b/Source/WebKit/UIProcess/API/wpe/PageClientImpl.cpp
|
|
@@ -35,9 +35,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>
|
|
@@ -55,6 +58,12 @@
|
|
#include <wpe/wpe-platform.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);
|
|
@@ -299,14 +308,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>&&)
|
|
+RefPtr<WebColorPicker> PageClientImpl::createColorPicker(WebPageProxy& page, const WebCore::Color& intialColor, const WebCore::IntRect& rect, ColorControlSupportsAlpha supportsAlpha, Vector<WebCore::Color>&&)
|
|
{
|
|
- return nullptr;
|
|
+ return WebColorPickerWPE::create(page, intialColor, rect);
|
|
}
|
|
|
|
-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)
|
|
@@ -518,6 +527,64 @@ void PageClientImpl::selectionDidChange()
|
|
m_view.selectionDidChange();
|
|
}
|
|
|
|
+#if USE(SKIA)
|
|
+sk_sp<SkImage> PageClientImpl::takeViewSnapshot(std::optional<WebCore::IntRect>&& clipRect, bool nominalResolution)
|
|
+{
|
|
+ sk_sp<SkImage> fullScreenshot = m_view.client().takeViewScreenshot();
|
|
+ float deviceScale = m_view.page().deviceScaleFactor();
|
|
+ if (!clipRect && (!nominalResolution || deviceScale == 1))
|
|
+ return fullScreenshot;
|
|
+
|
|
+ WebCore::IntSize size = clipRect ? clipRect->size() : m_view.page().viewSize();
|
|
+ if (!nominalResolution) {
|
|
+ size.scale(deviceScale);
|
|
+ if (clipRect)
|
|
+ clipRect->scale(deviceScale);
|
|
+ }
|
|
+
|
|
+ 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 bitmap.asImage();
|
|
+}
|
|
+#elif USE(CAIRO)
|
|
+RefPtr<cairo_surface_t> PageClientImpl::takeViewSnapshot(std::optional<WebCore::IntRect>&& clipRect, bool nominalResolution)
|
|
+{
|
|
+ RefPtr<cairo_surface_t> fullScreenshot = adoptRef(m_view.client().takeViewScreenshot());
|
|
+ float deviceScale = m_view.page().deviceScaleFactor();
|
|
+ if (!clipRect && (!nominalResolution || deviceScale == 1))
|
|
+ return fullScreenshot;
|
|
+
|
|
+ WebCore::IntSize size = clipRect ? clipRect->size() : m_view.page().viewSize();
|
|
+ if (!nominalResolution) {
|
|
+ size.scale(deviceScale);
|
|
+ if (clipRect)
|
|
+ clipRect->scale(deviceScale);
|
|
+ }
|
|
+ RefPtr<cairo_surface_t> surface = adoptRef(cairo_image_surface_create(CAIRO_FORMAT_RGB24, size.width(), size.height()));
|
|
+ RefPtr<cairo_t> cr = adoptRef(cairo_create(surface.get()));
|
|
+ if (clipRect) {
|
|
+ cairo_translate(cr.get(), -clipRect->x(), -clipRect->y());
|
|
+ cairo_rectangle(cr.get(), clipRect->x(), clipRect->y(), clipRect->width(), clipRect->height());
|
|
+ cairo_clip(cr.get());
|
|
+ }
|
|
+ if (nominalResolution)
|
|
+ cairo_scale(cr.get(), 1/deviceScale, 1/deviceScale);
|
|
+ cairo_set_source_surface(cr.get(), fullScreenshot.get(), 0, 0);
|
|
+ cairo_paint(cr.get());
|
|
+ return surface;
|
|
+}
|
|
+#endif
|
|
+
|
|
+
|
|
WebKitWebResourceLoadManager* PageClientImpl::webResourceLoadManager()
|
|
{
|
|
return m_view.webResourceLoadManager();
|
|
@@ -528,4 +595,11 @@ void PageClientImpl::callAfterNextPresentationUpdate(CompletionHandler<void()>&&
|
|
m_view.callAfterNextPresentationUpdate(WTFMove(callback));
|
|
}
|
|
|
|
+#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 c9b5db9dc3005f78212b295ecbf1eac95b24f2dd..c15b6879d6167ec8b4bbe4b1deeb12eb38fe2e10 100644
|
|
--- a/Source/WebKit/UIProcess/API/wpe/PageClientImpl.h
|
|
+++ b/Source/WebKit/UIProcess/API/wpe/PageClientImpl.h
|
|
@@ -181,9 +181,17 @@ private:
|
|
void didChangeWebPageID() const override;
|
|
|
|
void selectionDidChange() override;
|
|
-
|
|
+#if USE(SKIA)
|
|
+ sk_sp<SkImage> takeViewSnapshot(std::optional<WebCore::IntRect>&&, bool nominalResolution) override;
|
|
+#elif USE(CAIRO)
|
|
+ RefPtr<cairo_surface_t> takeViewSnapshot(std::optional<WebCore::IntRect>&&, bool nominalResolution) override;
|
|
+#endif
|
|
WebKitWebResourceLoadManager* webResourceLoadManager() override;
|
|
|
|
+#if ENABLE(DATE_AND_TIME_INPUT_TYPES)
|
|
+ RefPtr<WebDateTimePicker> createDateTimePicker(WebPageProxy&) override;
|
|
+#endif
|
|
+
|
|
WKWPE::View& m_view;
|
|
#if ENABLE(FULLSCREEN_API)
|
|
std::unique_ptr<WebFullScreenManagerProxyClient> m_fullscreenClientForTesting;
|
|
diff --git a/Source/WebKit/UIProcess/API/wpe/WebKitBrowserInspector.h b/Source/WebKit/UIProcess/API/wpe/WebKitBrowserInspector.h
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..273c5105cdf1638955cea01128c9bbab3e64436c
|
|
--- /dev/null
|
|
+++ b/Source/WebKit/UIProcess/API/wpe/WebKitBrowserInspector.h
|
|
@@ -0,0 +1,81 @@
|
|
+/*
|
|
+ * 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);
|
|
+
|
|
+G_END_DECLS
|
|
+
|
|
+#endif
|
|
diff --git a/Source/WebKit/UIProcess/API/wpe/WebKitWebViewBackend.cpp b/Source/WebKit/UIProcess/API/wpe/WebKitWebViewBackend.cpp
|
|
index 763bda5b29304f7ed7133c0a8158e6c8b94c5ea1..8ed962e8c1af62b9b73a68348d0d88765429861d 100644
|
|
--- a/Source/WebKit/UIProcess/API/wpe/WebKitWebViewBackend.cpp
|
|
+++ b/Source/WebKit/UIProcess/API/wpe/WebKitWebViewBackend.cpp
|
|
@@ -54,6 +54,7 @@ struct _WebKitWebViewBackend {
|
|
struct wpe_view_backend* backend;
|
|
GDestroyNotify notifyCallback;
|
|
gpointer notifyCallbackData;
|
|
+ take_screenshot_callback screenshotCallback;
|
|
int referenceCount { 1 };
|
|
};
|
|
|
|
@@ -116,6 +117,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 {
|
|
|
|
template <> WebKitWebViewBackend* refGPtr(WebKitWebViewBackend* ptr)
|
|
diff --git a/Source/WebKit/UIProcess/API/wpe/WebKitWebViewBackend.h b/Source/WebKit/UIProcess/API/wpe/WebKitWebViewBackend.h
|
|
index 16dcc1f69c38cd8ad630bc49d6d69feaa3aa811e..efa3814a8e896e02b955dea0be70bdc5828e3d82 100644
|
|
--- a/Source/WebKit/UIProcess/API/wpe/WebKitWebViewBackend.h
|
|
+++ b/Source/WebKit/UIProcess/API/wpe/WebKitWebViewBackend.h
|
|
@@ -28,6 +28,15 @@
|
|
#include <wpe/WebKitDefines.h>
|
|
#include <wpe/wpe.h>
|
|
|
|
+#if defined(USE_CAIRO) && USE_CAIRO
|
|
+#include <cairo.h>
|
|
+using PlatformImage = cairo_surface_t*;
|
|
+#endif
|
|
+#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 +53,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 e4b92ace1531090ae38a7aec3d3d4febf19aee84..b66b573f9148c39c5ce2738add6cd01a9a352be8 100644
|
|
--- a/Source/WebKit/UIProcess/API/wpe/WebKitWebViewBackendPrivate.h
|
|
+++ b/Source/WebKit/UIProcess/API/wpe/WebKitWebViewBackendPrivate.h
|
|
@@ -31,3 +31,5 @@ template <> void derefGPtr(WebKitWebViewBackend* ptr);
|
|
}
|
|
|
|
void webkitWebViewBackendUnref(WebKitWebViewBackend*);
|
|
+
|
|
+PlatformImage webkitWebViewBackendTakeScreenshot(WebKitWebViewBackend*);
|
|
diff --git a/Source/WebKit/UIProcess/API/wpe/WebKitWebViewClient.h b/Source/WebKit/UIProcess/API/wpe/WebKitWebViewClient.h
|
|
index 2f1182cb91a00353eace0b71612df096391c2450..d71d7fc724b046fab41285bb8f390cb6af6520ca 100644
|
|
--- a/Source/WebKit/UIProcess/API/wpe/WebKitWebViewClient.h
|
|
+++ b/Source/WebKit/UIProcess/API/wpe/WebKitWebViewClient.h
|
|
@@ -51,6 +51,13 @@ private:
|
|
bool isGLibBasedAPI() override { return true; }
|
|
|
|
void frameDisplayed(WKWPE::View&) override;
|
|
+// Playwright begin
|
|
+#if USE(CAIRO)
|
|
+ cairo_surface_t* takeViewScreenshot() override;
|
|
+#elif USE(SKIA)
|
|
+ sk_sp<SkImage> takeViewScreenshot() override;
|
|
+#endif
|
|
+// Playwright end
|
|
void willStartLoad(WKWPE::View&) override;
|
|
void didChangePageID(WKWPE::View&) override;
|
|
void didReceiveUserMessage(WKWPE::View&, WebKit::UserMessage&&, CompletionHandler<void(WebKit::UserMessage&&)>&&) override;
|
|
diff --git a/Source/WebKit/UIProcess/Automation/WebAutomationSession.h b/Source/WebKit/UIProcess/Automation/WebAutomationSession.h
|
|
index 8c97bd6e955005ba6246715aac63c4d675f5a713..1440dd5233d20ada05fee01a1916ad784a745214 100644
|
|
--- a/Source/WebKit/UIProcess/Automation/WebAutomationSession.h
|
|
+++ b/Source/WebKit/UIProcess/Automation/WebAutomationSession.h
|
|
@@ -279,6 +279,8 @@ public:
|
|
|
|
void didDestroyFrame(WebCore::FrameIdentifier);
|
|
|
|
+ static std::optional<String> platformGetBase64EncodedPNGData(const ViewSnapshot&);
|
|
+
|
|
private:
|
|
RefPtr<WebPageProxy> webPageProxyForHandle(const String&);
|
|
String handleForWebPageProxy(const WebPageProxy&);
|
|
@@ -329,7 +331,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 601d3874b710ca87c18a2dbcfbfb7368ac61d602..26c9ae063679b6f97be8c6cce8432aad3e90b3a4 100644
|
|
--- a/Source/WebKit/UIProcess/AuxiliaryProcessProxy.cpp
|
|
+++ b/Source/WebKit/UIProcess/AuxiliaryProcessProxy.cpp
|
|
@@ -172,7 +172,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 eed9d40f00e29fd1e36a2c7893639544439e53ce..eeb0b85018d13f46279eb5b9d281fdc34de92e02 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 945c62704e0b25f04e9ee4be88b21f88aeda8bd9..409c1c560b2462bf59f19dfee7941748b54fd22c 100644
|
|
--- a/Source/WebKit/UIProcess/BackingStore.h
|
|
+++ b/Source/WebKit/UIProcess/BackingStore.h
|
|
@@ -67,6 +67,7 @@ public:
|
|
float deviceScaleFactor() const { return m_deviceScaleFactor; }
|
|
|
|
void paint(PlatformPaintContextPtr, const WebCore::IntRect&);
|
|
+ RefPtr<cairo_surface_t> surface() const { return m_surface; }
|
|
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/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 8d9915d0802f215ea2a3e298b8653636338250b9..50e0ad091bcfc6356708ccfaf242787188e49a82 100644
|
|
--- a/Source/WebKit/UIProcess/Cocoa/UIDelegate.h
|
|
+++ b/Source/WebKit/UIProcess/Cocoa/UIDelegate.h
|
|
@@ -102,6 +102,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;
|
|
@@ -220,6 +221,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 da5818f79cb0f7a384af46f4d39eae4d2cf573df..44bf65e9a20428656d7eac39b9470c72e97987cf 100644
|
|
--- a/Source/WebKit/UIProcess/Cocoa/UIDelegate.mm
|
|
+++ b/Source/WebKit/UIProcess/Cocoa/UIDelegate.mm
|
|
@@ -135,6 +135,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:)];
|
|
@@ -466,6 +467,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];
|
|
+}
|
|
+
|
|
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 c0c9d8098ce76a6c2f7860165f990a854fbcc0e9..082322d49bf84f3b15e66c9cb89125d64f16d80a 100644
|
|
--- a/Source/WebKit/UIProcess/Cocoa/WebPageProxyCocoa.mm
|
|
+++ b/Source/WebKit/UIProcess/Cocoa/WebPageProxyCocoa.mm
|
|
@@ -42,7 +42,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 "QuickLookThumbnailLoader.h"
|
|
@@ -326,11 +328,86 @@ bool WebPageProxy::scrollingUpdatesDisabledForTesting()
|
|
|
|
void WebPageProxy::startDrag(const DragItem& dragItem, ShareableBitmap::Handle&& dragImageHandle)
|
|
{
|
|
+ if (m_interceptDrags) {
|
|
+ NSPasteboard *pasteboard = [NSPasteboard pasteboardWithName: m_overrideDragPasteboardName];
|
|
+
|
|
+ m_dragSelectionData = String([pasteboard name]);
|
|
+ if (auto replyID = grantAccessToCurrentPasteboardData(String([pasteboard name]), [] () { }))
|
|
+ websiteDataStore().protectedNetworkProcess()->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;
|
|
+ }
|
|
+ NSString *utiType = attachment->utiType();
|
|
+ if (!utiType.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];
|
|
+ }
|
|
+ } else {
|
|
+ [pasteboard setString:@"" forType:PasteboardTypes::WebDummyPboardType];
|
|
+ }
|
|
+ didStartDrag();
|
|
+ return;
|
|
+ }
|
|
+
|
|
if (RefPtr pageClient = this->pageClient())
|
|
pageClient->startDrag(dragItem, WTFMove(dragImageHandle));
|
|
}
|
|
|
|
-#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 d14a7dfa79daabce7bd835aa76625937e6107aad..0907c8ac8e9407231df5661180d3766b5c263dfd 100644
|
|
--- a/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm
|
|
+++ b/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm
|
|
@@ -432,7 +432,7 @@ ALLOW_DEPRECATED_DECLARATIONS_END
|
|
auto screenProperties = WebCore::collectScreenProperties();
|
|
parameters.screenProperties = WTFMove(screenProperties);
|
|
#if PLATFORM(MAC)
|
|
- parameters.useOverlayScrollbars = ([NSScroller preferredScrollerStyle] == NSScrollerStyleOverlay);
|
|
+ parameters.useOverlayScrollbars = m_configuration->forceOverlayScrollbars() || ([NSScroller preferredScrollerStyle] == NSScrollerStyleOverlay);
|
|
#endif
|
|
|
|
#if (PLATFORM(IOS) || PLATFORM(VISION)) && HAVE(AGX_COMPILER_SERVICE)
|
|
@@ -841,8 +841,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:NSApp queue:[NSOperationQueue currentQueue] usingBlock:^(NSNotification *notification) {
|
|
diff --git a/Source/WebKit/UIProcess/CoordinatedGraphics/DrawingAreaProxyCoordinatedGraphics.cpp b/Source/WebKit/UIProcess/CoordinatedGraphics/DrawingAreaProxyCoordinatedGraphics.cpp
|
|
index 9b45c78e2fd36e825c4e67d8e824771128c8fe15..9f748e729fce8103278b3888552d5c374ed6bc67 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,8 +41,10 @@
|
|
#include <WebCore/Region.h>
|
|
#include <optional>
|
|
#include <wtf/TZoneMallocInlines.h>
|
|
+#include <wtf/Vector.h>
|
|
|
|
#if PLATFORM(GTK)
|
|
+#include "WebKitWebViewBasePrivate.h"
|
|
#include <gtk/gtk.h>
|
|
#endif
|
|
|
|
@@ -49,6 +52,13 @@
|
|
#include <wtf/glib/RunLoopSourcePriority.h>
|
|
#endif
|
|
|
|
+#if PLATFORM(WIN)
|
|
+#include <cairo-win32.h>
|
|
+#include <windows.h>
|
|
+#include <WebCore/HWndDC.h>
|
|
+#include <WebCore/RefPtrCairo.h>
|
|
+#endif
|
|
+
|
|
namespace WebKit {
|
|
using namespace WebCore;
|
|
|
|
@@ -182,6 +192,11 @@ void DrawingAreaProxyCoordinatedGraphics::deviceScaleFactorDidChange(CompletionH
|
|
sendWithAsyncReply(Messages::DrawingArea::SetDeviceScaleFactor(m_webPageProxy->deviceScaleFactor()), WTFMove(completionHandler));
|
|
}
|
|
|
|
+void DrawingAreaProxyCoordinatedGraphics::waitForSizeUpdate(Function<void (const DrawingAreaProxyCoordinatedGraphics&)>&& callback)
|
|
+{
|
|
+ m_callbacks.append(WTFMove(callback));
|
|
+}
|
|
+
|
|
void DrawingAreaProxyCoordinatedGraphics::setBackingStoreIsDiscardable(bool isBackingStoreDiscardable)
|
|
{
|
|
#if !PLATFORM(WPE)
|
|
@@ -243,6 +258,45 @@ void DrawingAreaProxyCoordinatedGraphics::updateAcceleratedCompositingMode(uint6
|
|
updateAcceleratedCompositingMode(layerTreeContext);
|
|
}
|
|
|
|
+#if PLATFORM(WIN)
|
|
+void DrawingAreaProxyCoordinatedGraphics::didChangeAcceleratedCompositingMode(bool enabled)
|
|
+{
|
|
+ m_isInAcceleratedCompositingMode = enabled;
|
|
+}
|
|
+#endif
|
|
+
|
|
+#if !PLATFORM(WPE)
|
|
+void DrawingAreaProxyCoordinatedGraphics::captureFrame()
|
|
+{
|
|
+ RefPtr<cairo_surface_t> surface;
|
|
+#if PLATFORM(WIN)
|
|
+ HWndDC dc;
|
|
+ if (m_isInAcceleratedCompositingMode) {
|
|
+ dc.setHWnd(reinterpret_cast<HWND>(protectedWebPageProxy()->viewWidget()));
|
|
+ surface = adoptRef(cairo_win32_surface_create(dc));
|
|
+#else
|
|
+ if (isInAcceleratedCompositingMode()) {
|
|
+# if PLATFORM(GTK)
|
|
+ AcceleratedBackingStore* backingStore = webkitWebViewBaseGetAcceleratedBackingStore(WEBKIT_WEB_VIEW_BASE(protectedWebPageProxy()->viewWidget()));
|
|
+ if (!backingStore)
|
|
+ return;
|
|
+
|
|
+ surface = backingStore->surface();
|
|
+# else
|
|
+ fprintf(stderr, "captureFrame() is not supported in accelerated compositing mode on this platform.\n");
|
|
+# endif
|
|
+#endif
|
|
+ } else if (m_backingStore) {
|
|
+ surface = m_backingStore->surface();
|
|
+ }
|
|
+
|
|
+ if (!surface)
|
|
+ return;
|
|
+
|
|
+ protectedWebPageProxy()->inspectorController().didPaint(surface.get());
|
|
+}
|
|
+#endif
|
|
+
|
|
bool DrawingAreaProxyCoordinatedGraphics::alwaysUseCompositing() const
|
|
{
|
|
if (!m_webPageProxy)
|
|
@@ -310,6 +364,12 @@ void DrawingAreaProxyCoordinatedGraphics::didUpdateGeometry()
|
|
// we need to resend the new size here.
|
|
if (m_lastSentSize != m_size)
|
|
sendUpdateGeometry();
|
|
+ else {
|
|
+ Vector<Function<void (const DrawingAreaProxyCoordinatedGraphics&)>> callbacks;
|
|
+ callbacks.swap(m_callbacks);
|
|
+ for (auto& cb : callbacks)
|
|
+ cb(*this);
|
|
+ }
|
|
}
|
|
|
|
#if !PLATFORM(WPE)
|
|
diff --git a/Source/WebKit/UIProcess/CoordinatedGraphics/DrawingAreaProxyCoordinatedGraphics.h b/Source/WebKit/UIProcess/CoordinatedGraphics/DrawingAreaProxyCoordinatedGraphics.h
|
|
index 9c2bde0db0e4032a32e6ae02dc45af335df92f7a..7ae72e6c791c264ea7e0db4c93a0422b5b699e19 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 { return m_layerTreeContext; }
|
|
+ void waitForSizeUpdate(Function<void (const DrawingAreaProxyCoordinatedGraphics&)>&&);
|
|
+#if !PLATFORM(WPE)
|
|
+ void captureFrame();
|
|
+#endif
|
|
|
|
void dispatchAfterEnsuringDrawing(CompletionHandler<void()>&&);
|
|
|
|
@@ -86,6 +91,9 @@ private:
|
|
void exitAcceleratedCompositingMode(uint64_t backingStoreStateID, UpdateInfo&&) override;
|
|
void updateAcceleratedCompositingMode(uint64_t backingStoreStateID, const LayerTreeContext&) override;
|
|
void dispatchPresentationCallbacksAfterFlushingLayers(IPC::Connection&, Vector<IPC::AsyncReplyID>&&) override;
|
|
+#if PLATFORM(WIN)
|
|
+ void didChangeAcceleratedCompositingMode(bool enabled) override;
|
|
+#endif
|
|
|
|
bool shouldSendWheelEventsToEventDispatcher() const override { return true; }
|
|
|
|
@@ -129,6 +137,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)
|
|
bool m_isBackingStoreDiscardable { true };
|
|
@@ -137,6 +146,10 @@ private:
|
|
RunLoop::Timer m_discardBackingStoreTimer;
|
|
#endif
|
|
std::unique_ptr<DrawingMonitor> m_drawingMonitor;
|
|
+
|
|
+#if PLATFORM(WIN)
|
|
+ bool m_isInAcceleratedCompositingMode { false };
|
|
+#endif
|
|
};
|
|
|
|
} // namespace WebKit
|
|
diff --git a/Source/WebKit/UIProcess/Downloads/DownloadProxy.cpp b/Source/WebKit/UIProcess/Downloads/DownloadProxy.cpp
|
|
index 5d0385c213e4951ca9bec3c17bd2135887348cb0..634193dc71e82245b5017709bb93cfb5fdfede83 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>
|
|
@@ -89,7 +91,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()
|
|
@@ -109,12 +114,15 @@ void DownloadProxy::cancel(CompletionHandler<void(API::Data*)>&& completionHandl
|
|
{
|
|
m_downloadIsCancelled = true;
|
|
if (m_dataStore) {
|
|
- protectedDataStore()->protectedNetworkProcess()->sendWithAsyncReply(Messages::NetworkProcess::CancelDownload(m_downloadID), [weakThis = WeakPtr { *this }, completionHandler = WTFMove(completionHandler)] (std::span<const uint8_t> resumeData) mutable {
|
|
+ auto* instrumentation = m_dataStore->downloadInstrumentation();
|
|
+ protectedDataStore()->protectedNetworkProcess()->sendWithAsyncReply(Messages::NetworkProcess::CancelDownload(m_downloadID), [weakThis = WeakPtr { *this }, completionHandler = WTFMove(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);
|
|
});
|
|
@@ -186,6 +194,33 @@ void DownloadProxy::decideDestinationWithSuggestedFilename(const WebCore::Resour
|
|
suggestedFilename = m_suggestedFilename;
|
|
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()) {
|
|
+ destination = FileSystem::pathByAppendingComponent(m_dataStore->downloadPathForAutomation(), m_uuid);
|
|
+ if (auto handle = SandboxExtension::createHandle(destination, SandboxExtension::Type::ReadWrite))
|
|
+ sandboxExtensionHandle = WTFMove(*handle);
|
|
+ }
|
|
+ m_client->decidePlaceholderPolicy(*this, [completionHandler = WTFMove(completionHandler), destination = WTFMove(destination), sandboxExtensionHandle = WTFMove(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 = WTFMove(*handle);
|
|
+#endif
|
|
+ completionHandler(destination, WTFMove(sandboxExtensionHandle), AllowOverwrite::Yes, WebKit::UseDownloadPlaceholder::No, url, WTFMove(placeHolderSandboxExtensionHandle), bookmarkData.span(), activityTokenData.span());
|
|
+ });
|
|
+ return;
|
|
+ }
|
|
+
|
|
protectedClient()->decideDestinationWithSuggestedFilename(*this, response, ResourceResponseBase::sanitizeSuggestedFilename(suggestedFilename), [this, protectedThis = Ref { *this }, completionHandler = WTFMove(completionHandler)] (AllowOverwrite allowOverwrite, String destination) mutable {
|
|
SandboxExtension::Handle sandboxExtensionHandle;
|
|
if (!destination.isNull()) {
|
|
@@ -250,6 +285,8 @@ void DownloadProxy::didFinish()
|
|
m_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())
|
|
@@ -264,6 +301,8 @@ void DownloadProxy::didFail(const ResourceError& error, std::span<const uint8_t>
|
|
m_legacyResumeData = createData(resumeData);
|
|
|
|
m_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 d82b401d7d58a34fadd38c61ef3b0f521ed432e4..9403574a7d238282998065729ec9e9d165c37f2f 100644
|
|
--- a/Source/WebKit/UIProcess/Downloads/DownloadProxy.h
|
|
+++ b/Source/WebKit/UIProcess/Downloads/DownloadProxy.h
|
|
@@ -166,6 +166,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 e1f55b4a7fbc452ca1f2eb025b0c88ec9f4b845f..4e4238f4f656208c0f11822406172ea13a21e2d4 100644
|
|
--- a/Source/WebKit/UIProcess/DrawingAreaProxy.h
|
|
+++ b/Source/WebKit/UIProcess/DrawingAreaProxy.h
|
|
@@ -94,6 +94,7 @@ public:
|
|
|
|
const WebCore::IntSize& size() const { return m_size; }
|
|
bool setSize(const WebCore::IntSize&, const WebCore::IntSize& scrollOffset = { });
|
|
+ void waitForSizeUpdate(Function<void ()>&&);
|
|
|
|
virtual void minimumSizeForAutoLayoutDidChange() { }
|
|
virtual void sizeToContentAutoSizeMaximumSizeDidChange() { }
|
|
@@ -181,6 +182,10 @@ private:
|
|
virtual void update(uint64_t /* backingStoreStateID */, UpdateInfo&&) { }
|
|
virtual void exitAcceleratedCompositingMode(uint64_t /* backingStoreStateID */, UpdateInfo&&) { }
|
|
#endif
|
|
+
|
|
+#if PLATFORM(WIN)
|
|
+ virtual void didChangeAcceleratedCompositingMode(bool) { }
|
|
+#endif
|
|
};
|
|
|
|
} // namespace WebKit
|
|
diff --git a/Source/WebKit/UIProcess/DrawingAreaProxy.messages.in b/Source/WebKit/UIProcess/DrawingAreaProxy.messages.in
|
|
index b03ac2dcf12c771da4a2347b81e5ba93fbd5f6a4..b69c5d3244306e1d1c10206d499d9a833a3efeec 100644
|
|
--- a/Source/WebKit/UIProcess/DrawingAreaProxy.messages.in
|
|
+++ b/Source/WebKit/UIProcess/DrawingAreaProxy.messages.in
|
|
@@ -35,4 +35,7 @@ messages -> DrawingAreaProxy {
|
|
Update(uint64_t stateID, struct WebKit::UpdateInfo updateInfo) CanDispatchOutOfOrder
|
|
ExitAcceleratedCompositingMode(uint64_t backingStoreStateID, struct WebKit::UpdateInfo updateInfo)
|
|
#endif
|
|
+#if PLATFORM(WIN)
|
|
+ DidChangeAcceleratedCompositingMode(bool enabled)
|
|
+#endif
|
|
}
|
|
diff --git a/Source/WebKit/UIProcess/Inspector/Agents/CairoJpegEncoder.cpp b/Source/WebKit/UIProcess/Inspector/Agents/CairoJpegEncoder.cpp
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..8d20e2aa36ba0f7996c20a6a02792c7f151bbed5
|
|
--- /dev/null
|
|
+++ b/Source/WebKit/UIProcess/Inspector/Agents/CairoJpegEncoder.cpp
|
|
@@ -0,0 +1,246 @@
|
|
+/* Copyright 2018 Bernhard R. Fischer, 4096R/8E24F29D <bf@abenteuerland.at>
|
|
+ *
|
|
+ * This file is part of Cairo_JPG.
|
|
+ *
|
|
+ * Cairo_JPG is free software: you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU Lesser General Public License as published by
|
|
+ * the Free Software Foundation, either version 3 of the License, or
|
|
+ * (at your option) any later version.
|
|
+ *
|
|
+ * Cairo_JPG is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+ * GNU Lesser General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with Cairo_JPG. If not, see <https://www.gnu.org/licenses/>.
|
|
+ */
|
|
+
|
|
+/*! \file cairo_jpg.c
|
|
+ * This file contains two functions for reading and writing JPEG files from
|
|
+ * and to Cairo image surfaces. It uses the functions from the libjpeg.
|
|
+ * Most of the code is directly derived from the online example at
|
|
+ * http://libjpeg-turbo.virtualgl.org/Documentation/Documentation
|
|
+ *
|
|
+ * All prototypes are defined in cairo_jpg.h All functions and their parameters
|
|
+ * and return values are described below directly at the functions. You may
|
|
+ * also have a look at the preprocessor macros defined below.
|
|
+ *
|
|
+ * To compile this code you need to have installed the packages libcairo2-dev
|
|
+ * and libjpeg-dev. Compile with the following to create an object file to link
|
|
+ * with your code:
|
|
+ * gcc -std=c99 -Wall -c `pkg-config cairo libjpeg --cflags --libs` cairo_jpg.c
|
|
+ * Use the following command to include the main() function and create an
|
|
+ * executable for testing of this code:
|
|
+ * gcc -std=c99 -Wall -o cairo_jpg -DCAIRO_JPEG_MAIN `pkg-config cairo libjpeg --cflags --libs` cairo_jpg.c
|
|
+ *
|
|
+ * @author Bernhard R. Fischer, 4096R/8E24F29D bf@abenteuerland.at
|
|
+ * @version 2020/01/18
|
|
+ * @license LGPL3.
|
|
+ */
|
|
+
|
|
+#include "config.h"
|
|
+
|
|
+#if USE(CAIRO) || PLATFORM(GTK)
|
|
+
|
|
+#include "CairoJpegEncoder.h"
|
|
+
|
|
+#include <stdio.h>
|
|
+#include <stdlib.h>
|
|
+#include <stdint.h>
|
|
+#include <sys/types.h>
|
|
+#include <sys/stat.h>
|
|
+#include <cairo.h>
|
|
+extern "C" {
|
|
+#include "jpeglib.h"
|
|
+}
|
|
+
|
|
+/*! Macro to activate main() function. This is only used for testing. Comment
|
|
+ * it out (#undef) if you link this file to your own program.
|
|
+ */
|
|
+//#define CAIRO_JPEG_MAIN
|
|
+//
|
|
+/*! Define this to use an alternate implementation of
|
|
+ * cairo_image_surface_create_from_jpeg() which fstat(3)s the file before
|
|
+ * reading (see below). For huge files this /may/ be slightly faster.
|
|
+ */
|
|
+#undef CAIRO_JPEG_USE_FSTAT
|
|
+
|
|
+/*! This is the read block size for the stream reader
|
|
+ * cairo_image_surface_create_from_jpeg_stream().
|
|
+ */
|
|
+#ifdef USE_CAIRO_READ_FUNC_LEN_T
|
|
+#define CAIRO_JPEG_IO_BLOCK_SIZE 4096
|
|
+#else
|
|
+/*! Block size has to be one if cairo_read_func_t is in use because of the lack
|
|
+ * to detect EOF (truncated reads).
|
|
+ */
|
|
+#define CAIRO_JPEG_IO_BLOCK_SIZE 1
|
|
+/*! In case of original cairo_read_func_t is used fstat() should be used for
|
|
+ * performance reasons (see CAIRO_JPEG_USE_FSTAT above).
|
|
+ */
|
|
+#define CAIRO_JPEG_USE_FSTAT
|
|
+#endif
|
|
+
|
|
+/*! Define this to test jpeg creation with non-image surfaces. This is only for
|
|
+ * testing and is to be used together with CAIRO_JPEG_MAIN.
|
|
+ */
|
|
+#undef CAIRO_JPEG_TEST_SIMILAR
|
|
+#if defined(CAIRO_JPEG_TEST_SIMILAR) && defined(CAIRO_JPEG_MAIN)
|
|
+#include <cairo-pdf.h>
|
|
+#endif
|
|
+
|
|
+
|
|
+#ifndef LIBJPEG_TURBO_VERSION
|
|
+/*! This function makes a covnersion for "odd" pixel sizes which typically is a
|
|
+ * conversion from a 3-byte to a 4-byte (or more) pixel size or vice versa.
|
|
+ * The conversion is done from the source buffer src to the destination buffer
|
|
+ * dst. The caller MUST ensure that src and dst have the correct memory size.
|
|
+ * This is dw * num for dst and sw * num for src. src and dst may point to the
|
|
+ * same memory address.
|
|
+ * @param dst Pointer to destination buffer.
|
|
+ * @param dw Pixel width (in bytes) of pixels in destination buffer, dw >= 3.
|
|
+ * @param src Pointer to source buffer.
|
|
+ * @param sw Pixel width (in bytes) of pixels in source buffer, sw >= 3.
|
|
+ * @param num Number of pixels to convert, num >= 1;
|
|
+ */
|
|
+static void pix_conv(unsigned char *dst, int dw, const unsigned char *src, int sw, int num)
|
|
+{
|
|
+ int si, di;
|
|
+
|
|
+ // safety check
|
|
+ if (dw < 3 || sw < 3 || dst == NULL || src == NULL)
|
|
+ return;
|
|
+
|
|
+ num--;
|
|
+ for (si = num * sw, di = num * dw; si >= 0; si -= sw, di -= dw)
|
|
+ {
|
|
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
|
+ dst[di + 2] = src[si ];
|
|
+ dst[di + 1] = src[si + 1];
|
|
+ dst[di + 0] = src[si + 2];
|
|
+#else
|
|
+ // FIXME: This is untested, it may be wrong.
|
|
+ dst[di - 3] = src[si - 3];
|
|
+ dst[di - 2] = src[si - 2];
|
|
+ dst[di - 1] = src[si - 1];
|
|
+#endif
|
|
+ }
|
|
+}
|
|
+#endif
|
|
+
|
|
+
|
|
+/*! This function creates a JPEG file in memory from a Cairo image surface.
|
|
+ * @param sfc Pointer to a Cairo surface. It should be an image surface of
|
|
+ * either CAIRO_FORMAT_ARGB32 or CAIRO_FORMAT_RGB24. Other formats are
|
|
+ * converted to CAIRO_FORMAT_RGB24 before compression.
|
|
+ * Please note that this may give unexpected results because JPEG does not
|
|
+ * support transparency. Thus, default background color is used to replace
|
|
+ * transparent regions. The default background color is black if not specified
|
|
+ * explicitly. Thus converting e.g. PDF surfaces without having any specific
|
|
+ * background color set will apear with black background and not white as you
|
|
+ * might expect. In such cases it is suggested to manually convert the surface
|
|
+ * to RGB24 before calling this function.
|
|
+ * @param data Pointer to a memory pointer. This parameter receives a pointer
|
|
+ * to the memory area where the final JPEG data is found in memory. This
|
|
+ * function reserves the memory properly and it has to be freed by the caller
|
|
+ * with free(3).
|
|
+ * @param len Pointer to a variable of type size_t which will receive the final
|
|
+ * lenght of the memory buffer.
|
|
+ * @param quality Compression quality, 0-100.
|
|
+ * @return On success the function returns CAIRO_STATUS_SUCCESS. In case of
|
|
+ * error CAIRO_STATUS_INVALID_FORMAT is returned.
|
|
+ */
|
|
+cairo_status_t cairo_image_surface_write_to_jpeg_mem(cairo_surface_t *sfc, unsigned char **data, size_t *len, int quality)
|
|
+{
|
|
+ struct jpeg_compress_struct cinfo;
|
|
+ struct jpeg_error_mgr jerr;
|
|
+ JSAMPROW row_pointer[1];
|
|
+ cairo_surface_t *other = NULL;
|
|
+
|
|
+ // check valid input format (must be IMAGE_SURFACE && (ARGB32 || RGB24))
|
|
+ if (cairo_surface_get_type(sfc) != CAIRO_SURFACE_TYPE_IMAGE ||
|
|
+ (cairo_image_surface_get_format(sfc) != CAIRO_FORMAT_ARGB32 &&
|
|
+ cairo_image_surface_get_format(sfc) != CAIRO_FORMAT_RGB24))
|
|
+ {
|
|
+ // create a similar surface with a proper format if supplied input format
|
|
+ // does not fulfill the requirements
|
|
+ double x1, y1, x2, y2;
|
|
+ other = sfc;
|
|
+ cairo_t *ctx = cairo_create(other);
|
|
+ // get extents of original surface
|
|
+ cairo_clip_extents(ctx, &x1, &y1, &x2, &y2);
|
|
+ cairo_destroy(ctx);
|
|
+
|
|
+ // create new image surface
|
|
+ sfc = cairo_surface_create_similar_image(other, CAIRO_FORMAT_RGB24, x2 - x1, y2 - y1);
|
|
+ if (cairo_surface_status(sfc) != CAIRO_STATUS_SUCCESS)
|
|
+ return CAIRO_STATUS_INVALID_FORMAT;
|
|
+
|
|
+ // paint original surface to new surface
|
|
+ ctx = cairo_create(sfc);
|
|
+ cairo_set_source_surface(ctx, other, 0, 0);
|
|
+ cairo_paint(ctx);
|
|
+ cairo_destroy(ctx);
|
|
+ }
|
|
+
|
|
+ // finish queued drawing operations
|
|
+ cairo_surface_flush(sfc);
|
|
+
|
|
+ // init jpeg compression structures
|
|
+ cinfo.err = jpeg_std_error(&jerr);
|
|
+ jpeg_create_compress(&cinfo);
|
|
+
|
|
+ // set compression parameters
|
|
+ unsigned long targetSize;
|
|
+ jpeg_mem_dest(&cinfo, data, &targetSize);
|
|
+
|
|
+ cinfo.image_width = cairo_image_surface_get_width(sfc);
|
|
+ cinfo.image_height = cairo_image_surface_get_height(sfc);
|
|
+#ifdef LIBJPEG_TURBO_VERSION
|
|
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
|
+ //cinfo.in_color_space = JCS_EXT_BGRX;
|
|
+ cinfo.in_color_space = cairo_image_surface_get_format(sfc) == CAIRO_FORMAT_ARGB32 ? JCS_EXT_BGRA : JCS_EXT_BGRX;
|
|
+#else
|
|
+ //cinfo.in_color_space = JCS_EXT_XRGB;
|
|
+ cinfo.in_color_space = cairo_image_surface_get_format(sfc) == CAIRO_FORMAT_ARGB32 ? JCS_EXT_ARGB : JCS_EXT_XRGB;
|
|
+#endif
|
|
+ cinfo.input_components = 4;
|
|
+#else
|
|
+ cinfo.in_color_space = JCS_RGB;
|
|
+ cinfo.input_components = 3;
|
|
+#endif
|
|
+ jpeg_set_defaults(&cinfo);
|
|
+ jpeg_set_quality(&cinfo, quality, TRUE);
|
|
+
|
|
+ // start compressor
|
|
+ jpeg_start_compress(&cinfo, TRUE);
|
|
+
|
|
+ // loop over all lines and compress
|
|
+ while (cinfo.next_scanline < cinfo.image_height)
|
|
+ {
|
|
+#ifdef LIBJPEG_TURBO_VERSION
|
|
+ row_pointer[0] = cairo_image_surface_get_data(sfc) + (cinfo.next_scanline
|
|
+ * cairo_image_surface_get_stride(sfc));
|
|
+#else
|
|
+ unsigned char row_buf[3 * cinfo.image_width];
|
|
+ pix_conv(row_buf, 3, cairo_image_surface_get_data(sfc) +
|
|
+ (cinfo.next_scanline * cairo_image_surface_get_stride(sfc)), 4, cinfo.image_width);
|
|
+ row_pointer[0] = row_buf;
|
|
+#endif
|
|
+ (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
|
|
+ }
|
|
+
|
|
+ // finalize and close everything
|
|
+ jpeg_finish_compress(&cinfo);
|
|
+ jpeg_destroy_compress(&cinfo);
|
|
+
|
|
+ // destroy temporary image surface (if available)
|
|
+ if (other != NULL)
|
|
+ cairo_surface_destroy(sfc);
|
|
+
|
|
+ *len = targetSize;
|
|
+ return CAIRO_STATUS_SUCCESS;
|
|
+}
|
|
+
|
|
+#endif
|
|
diff --git a/Source/WebKit/UIProcess/Inspector/Agents/CairoJpegEncoder.h b/Source/WebKit/UIProcess/Inspector/Agents/CairoJpegEncoder.h
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..4ec8b96bbbddf8a7b042f53a8068754a384fc7ad
|
|
--- /dev/null
|
|
+++ b/Source/WebKit/UIProcess/Inspector/Agents/CairoJpegEncoder.h
|
|
@@ -0,0 +1,30 @@
|
|
+/*
|
|
+ * Copyright (C) Microsoft. All rights reserved.
|
|
+ *
|
|
+ * Redistribution and use in source and binary forms, with or without
|
|
+ * modification, are permitted provided that the following conditions
|
|
+ * are met:
|
|
+ * 1. Redistributions of source code must retain the above copyright
|
|
+ * notice, this list of conditions and the following disclaimer.
|
|
+ * 2. Redistributions in binary form must reproduce the above copyright
|
|
+ * notice, this list of conditions and the following disclaimer in the
|
|
+ * documentation and/or other materials provided with the distribution.
|
|
+ *
|
|
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
|
|
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
|
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
|
|
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
|
+ * THE POSSIBILITY OF SUCH DAMAGE.
|
|
+ */
|
|
+
|
|
+#pragma once
|
|
+
|
|
+#include <cairo.h>
|
|
+
|
|
+cairo_status_t cairo_image_surface_write_to_jpeg_mem(cairo_surface_t *sfc, unsigned char **data, size_t *len, int quality);
|
|
diff --git a/Source/WebKit/UIProcess/Inspector/Agents/InspectorScreencastAgent.cpp b/Source/WebKit/UIProcess/Inspector/Agents/InspectorScreencastAgent.cpp
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..033bf77bca2de127e55cbf55a9e0b0c358fc81f9
|
|
--- /dev/null
|
|
+++ b/Source/WebKit/UIProcess/Inspector/Agents/InspectorScreencastAgent.cpp
|
|
@@ -0,0 +1,392 @@
|
|
+/*
|
|
+ * 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 "ScreencastEncoder.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 USE(CAIRO) || PLATFORM(GTK)
|
|
+#include "CairoJpegEncoder.h"
|
|
+#include "DrawingAreaProxyCoordinatedGraphics.h"
|
|
+#include "DrawingAreaProxy.h"
|
|
+#endif
|
|
+
|
|
+#if PLATFORM(MAC)
|
|
+#include <WebCore/ImageBufferUtilitiesCG.h>
|
|
+#endif
|
|
+
|
|
+WTF_ALLOW_UNSAFE_BUFFER_USAGE_BEGIN
|
|
+
|
|
+namespace WebKit {
|
|
+
|
|
+const int kMaxFramesInFlight = 1;
|
|
+
|
|
+using namespace Inspector;
|
|
+
|
|
+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(FrontendRouter*, BackendDispatcher*)
|
|
+{
|
|
+}
|
|
+
|
|
+void InspectorScreencastAgent::willDestroyFrontendAndBackend(DisconnectReason)
|
|
+{
|
|
+ if (!m_encoder)
|
|
+ return;
|
|
+
|
|
+ // The agent may be destroyed when the callback is invoked.
|
|
+ m_encoder->finish([sessionID = m_page.websiteDataStore().sessionID(), screencastID = WTFMove(m_currentScreencastID)] {
|
|
+ if (WebPageInspectorController::observer())
|
|
+ WebPageInspectorController::observer()->didFinishScreencast(sessionID, screencastID);
|
|
+ });
|
|
+
|
|
+ m_encoder = nullptr;
|
|
+}
|
|
+
|
|
+#if USE(SKIA) && !PLATFORM(GTK)
|
|
+void InspectorScreencastAgent::didPaint(sk_sp<SkImage>&& surface)
|
|
+{
|
|
+ sk_sp<SkImage> image(surface);
|
|
+#if PLATFORM(WPE)
|
|
+ // 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;
|
|
+ }
|
|
+#else
|
|
+ WebCore::IntSize displaySize = m_page.drawingArea()->size();
|
|
+#endif
|
|
+ // Do not WTFMove image here as it is used below
|
|
+ if (m_encoder)
|
|
+ m_encoder->encodeFrame(sk_sp<SkImage>(image), displaySize);
|
|
+ if (m_screencast) {
|
|
+ {
|
|
+ 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::CryptoDigest::create(PAL::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;
|
|
+ }
|
|
+
|
|
+ if (m_screencastFramesInFlight > kMaxFramesInFlight)
|
|
+ return;
|
|
+ // 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, displaySize.width(), displaySize.height());
|
|
+ }
|
|
+}
|
|
+#endif
|
|
+
|
|
+#if USE(CAIRO) || PLATFORM(GTK)
|
|
+void InspectorScreencastAgent::didPaint(cairo_surface_t* surface)
|
|
+{
|
|
+#if PLATFORM(WPE)
|
|
+ // Get actual image size (in device pixels).
|
|
+ WebCore::IntSize displaySize(cairo_image_surface_get_width(surface), cairo_image_surface_get_height(surface));
|
|
+
|
|
+ WebCore::IntSize drawingAreaSize = m_page.drawingArea()->size();
|
|
+ drawingAreaSize.scale(m_page.deviceScaleFactor());
|
|
+ if (drawingAreaSize != displaySize) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+#else
|
|
+ WebCore::IntSize displaySize = m_page.drawingArea()->size();
|
|
+#endif
|
|
+ if (m_encoder)
|
|
+ m_encoder->encodeFrame(surface, displaySize);
|
|
+ if (m_screencast) {
|
|
+
|
|
+ {
|
|
+ // Do not send the same frame over and over.
|
|
+ unsigned char *data = cairo_image_surface_get_data(surface);
|
|
+ int stride = cairo_image_surface_get_stride(surface);
|
|
+ int height = cairo_image_surface_get_height(surface);
|
|
+ auto cryptoDigest = PAL::CryptoDigest::create(PAL::CryptoDigest::Algorithm::SHA_1);
|
|
+ cryptoDigest->addBytes(std::span(data, stride * height));
|
|
+ auto digest = cryptoDigest->computeHash();
|
|
+ if (m_lastFrameDigest == digest)
|
|
+ return;
|
|
+ m_lastFrameDigest = digest;
|
|
+ }
|
|
+
|
|
+ if (m_screencastFramesInFlight > kMaxFramesInFlight)
|
|
+ return;
|
|
+ // Scale image to fit width / height
|
|
+ double scale = std::min(m_screencastWidth / displaySize.width(), m_screencastHeight / displaySize.height());
|
|
+ RefPtr<cairo_surface_t> scaledSurface;
|
|
+ if (scale < 1) {
|
|
+ WebCore::IntSize scaledSize = displaySize;
|
|
+ scaledSize.scale(scale);
|
|
+ cairo_matrix_t transform;
|
|
+ cairo_matrix_init_scale(&transform, scale, scale);
|
|
+ scaledSurface = adoptRef(cairo_image_surface_create(CAIRO_FORMAT_ARGB32, scaledSize.width(), scaledSize.height()));
|
|
+ RefPtr<cairo_t> cr = adoptRef(cairo_create(scaledSurface.get()));
|
|
+ cairo_transform(cr.get(), &transform);
|
|
+ cairo_set_source_surface(cr.get(), surface, 0, 0);
|
|
+ cairo_paint(cr.get());
|
|
+ surface = scaledSurface.get();
|
|
+ }
|
|
+ unsigned char *data = nullptr;
|
|
+ size_t len = 0;
|
|
+ cairo_image_surface_write_to_jpeg_mem(surface, &data, &len, m_screencastQuality);
|
|
+ String result = base64EncodeToString(std::span(data, len));
|
|
+ ++m_screencastFramesInFlight;
|
|
+ m_frontendDispatcher->screencastFrame(result, displaySize.width(), displaySize.height());
|
|
+ }
|
|
+}
|
|
+#endif
|
|
+
|
|
+Inspector::Protocol::ErrorStringOr<String /* screencastID */> InspectorScreencastAgent::startVideo(const String& file, int width, int height, int toolbarHeight)
|
|
+{
|
|
+ if (m_encoder)
|
|
+ return makeUnexpected("Already recording"_s);
|
|
+
|
|
+ if (width < 10 || width > 10000 || height < 10 || height > 10000)
|
|
+ return makeUnexpected("Invalid size"_s);
|
|
+
|
|
+ String errorString;
|
|
+ m_encoder = ScreencastEncoder::create(errorString, file, WebCore::IntSize(width, height));
|
|
+ if (!m_encoder)
|
|
+ return makeUnexpected(errorString);
|
|
+
|
|
+ m_currentScreencastID = createVersion4UUIDString();
|
|
+
|
|
+#if PLATFORM(MAC)
|
|
+ m_encoder->setOffsetTop(toolbarHeight);
|
|
+#endif
|
|
+
|
|
+ kickFramesStarted();
|
|
+ return { { m_currentScreencastID } };
|
|
+}
|
|
+
|
|
+void InspectorScreencastAgent::stopVideo(Ref<StopVideoCallback>&& callback)
|
|
+{
|
|
+ if (!m_encoder) {
|
|
+ callback->sendFailure("Not recording"_s);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ // The agent may be destroyed when the callback is invoked.
|
|
+ m_encoder->finish([sessionID = m_page.websiteDataStore().sessionID(), screencastID = WTFMove(m_currentScreencastID), callback = WTFMove(callback)] {
|
|
+ if (WebPageInspectorController::observer())
|
|
+ WebPageInspectorController::observer()->didFinishScreencast(sessionID, screencastID);
|
|
+ callback->sendSuccess();
|
|
+ });
|
|
+ m_encoder = nullptr;
|
|
+ if (!m_screencast)
|
|
+ m_framesAreGoing = false;
|
|
+}
|
|
+
|
|
+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_screencastFramesInFlight = 0;
|
|
+ ++m_screencastGeneration;
|
|
+ kickFramesStarted();
|
|
+ return m_screencastGeneration;
|
|
+}
|
|
+
|
|
+Inspector::Protocol::ErrorStringOr<void> InspectorScreencastAgent::screencastFrameAck(int generation)
|
|
+{
|
|
+ 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;
|
|
+ if (!m_encoder)
|
|
+ m_framesAreGoing = false;
|
|
+ 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_encoder && !m_screencast)
|
|
+ return;
|
|
+
|
|
+ RunLoop::main().dispatchAfter(Seconds(1.0 / ScreencastEncoder::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_encoder && !m_screencast)
|
|
+ return;
|
|
+ RetainPtr<CGImageRef> imageRef = m_page.pageClient()->takeSnapshotForAutomation();
|
|
+ if (m_screencast && m_screencastFramesInFlight <= kMaxFramesInFlight) {
|
|
+ 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::CryptoDigest::create(PAL::CryptoDigest::Algorithm::SHA_1);
|
|
+ cryptoDigest->addBytes(std::span(data.data(), data.size()));
|
|
+ auto digest = cryptoDigest->computeHash();
|
|
+ if (m_lastFrameDigest != digest) {
|
|
+ String base64Data = base64EncodeToString(data);
|
|
+ ++m_screencastFramesInFlight;
|
|
+ m_frontendDispatcher->screencastFrame(base64Data, displaySize.width(), displaySize.height());
|
|
+ m_lastFrameDigest = digest;
|
|
+ }
|
|
+ }
|
|
+ if (m_encoder)
|
|
+ m_encoder->encodeFrame(WTFMove(imageRef));
|
|
+}
|
|
+#endif
|
|
+
|
|
+#if (USE(CAIRO) && !PLATFORM(WPE)) || PLATFORM(GTK)
|
|
+void InspectorScreencastAgent::encodeFrame()
|
|
+{
|
|
+ if (!m_encoder && !m_screencast)
|
|
+ return;
|
|
+
|
|
+ if (auto* drawingArea = m_page.drawingArea())
|
|
+ static_cast<DrawingAreaProxyCoordinatedGraphics*>(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..f53bb59c65a4ced0360e473fb9ed9a36d1179310
|
|
--- /dev/null
|
|
+++ b/Source/WebKit/UIProcess/Inspector/Agents/InspectorScreencastAgent.h
|
|
@@ -0,0 +1,109 @@
|
|
+/*
|
|
+ * 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>
|
|
+
|
|
+#if USE(CAIRO) || PLATFORM(GTK)
|
|
+#include <cairo.h>
|
|
+#endif
|
|
+
|
|
+#include <wtf/Forward.h>
|
|
+#include <wtf/Noncopyable.h>
|
|
+#include <wtf/WeakPtr.h>
|
|
+
|
|
+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 ScreencastEncoder;
|
|
+class WebPageProxy;
|
|
+
|
|
+class InspectorScreencastAgent : public Inspector::InspectorAgentBase, public Inspector::ScreencastBackendDispatcherHandler, public CanMakeWeakPtr<InspectorScreencastAgent> {
|
|
+ WTF_MAKE_NONCOPYABLE(InspectorScreencastAgent);
|
|
+ WTF_MAKE_FAST_ALLOCATED;
|
|
+public:
|
|
+ InspectorScreencastAgent(Inspector::BackendDispatcher& backendDispatcher, Inspector::FrontendRouter& frontendRouter, WebPageProxy& page);
|
|
+ ~InspectorScreencastAgent() override;
|
|
+
|
|
+ void didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*) override;
|
|
+ void willDestroyFrontendAndBackend(Inspector::DisconnectReason) override;
|
|
+
|
|
+#if USE(SKIA) && !PLATFORM(GTK)
|
|
+ void didPaint(sk_sp<SkImage>&& surface);
|
|
+#endif
|
|
+#if USE(CAIRO) || PLATFORM(GTK)
|
|
+ void didPaint(cairo_surface_t*);
|
|
+#endif
|
|
+
|
|
+ Inspector::Protocol::ErrorStringOr<String /* screencastID */> startVideo(const String& file, int width, int height, int toolbarHeight) override;
|
|
+ void stopVideo(Ref<StopVideoCallback>&&) override;
|
|
+
|
|
+ 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;
|
|
+ RefPtr<ScreencastEncoder> m_encoder;
|
|
+ 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;
|
|
+ String m_currentScreencastID;
|
|
+};
|
|
+
|
|
+} // namespace WebKit
|
|
diff --git a/Source/WebKit/UIProcess/Inspector/Agents/ScreencastEncoder.cpp b/Source/WebKit/UIProcess/Inspector/Agents/ScreencastEncoder.cpp
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..bec42378013c93ee6bd37f62a1d6a1c68d167fa3
|
|
--- /dev/null
|
|
+++ b/Source/WebKit/UIProcess/Inspector/Agents/ScreencastEncoder.cpp
|
|
@@ -0,0 +1,443 @@
|
|
+/*
|
|
+ * Copyright (c) 2010, The WebM Project authors. All rights reserved.
|
|
+ * Copyright (c) 2013 The Chromium Authors. All rights reserved.
|
|
+ * 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 "ScreencastEncoder.h"
|
|
+
|
|
+#include "WebMFileWriter.h"
|
|
+#include <algorithm>
|
|
+#include <libyuv.h>
|
|
+#include <vpx/vp8.h>
|
|
+#include <vpx/vp8cx.h>
|
|
+#include <vpx/vpx_encoder.h>
|
|
+#include <wtf/Compiler.h>
|
|
+#include <wtf/RunLoop.h>
|
|
+#include <wtf/UniqueArray.h>
|
|
+#include <wtf/WorkQueue.h>
|
|
+#include <wtf/text/MakeString.h>
|
|
+#include <wtf/text/StringConcatenateNumbers.h>
|
|
+
|
|
+#if USE(SKIA) && !PLATFORM(GTK)
|
|
+#include <skia/core/SkBitmap.h>
|
|
+#include <skia/core/SkCanvas.h>
|
|
+#include <skia/core/SkData.h>
|
|
+#include <skia/core/SkImage.h>
|
|
+#endif
|
|
+
|
|
+#if USE(CAIRO) || PLATFORM(GTK)
|
|
+#include <WebCore/RefPtrCairo.h>
|
|
+#endif
|
|
+
|
|
+WTF_ALLOW_UNSAFE_BUFFER_USAGE_BEGIN
|
|
+
|
|
+using namespace WebCore;
|
|
+
|
|
+namespace WebKit {
|
|
+
|
|
+namespace {
|
|
+
|
|
+struct VpxCodecDeleter {
|
|
+ void operator()(vpx_codec_ctx_t* codec) {
|
|
+ if (codec) {
|
|
+ vpx_codec_err_t ret = vpx_codec_destroy(codec);
|
|
+ if (ret != VPX_CODEC_OK)
|
|
+ fprintf(stderr, "Failed to encode frame: %s\n", vpx_codec_error(codec));
|
|
+ }
|
|
+ }
|
|
+};
|
|
+
|
|
+using ScopedVpxCodec = std::unique_ptr<vpx_codec_ctx_t, VpxCodecDeleter>;
|
|
+
|
|
+// Number of timebase unints per one frame.
|
|
+constexpr int timeScale = 1000;
|
|
+
|
|
+// Defines the dimension of a macro block. This is used to compute the active
|
|
+// map for the encoder.
|
|
+const int kMacroBlockSize = 16;
|
|
+
|
|
+void createImage(unsigned int width, unsigned int height,
|
|
+ std::unique_ptr<vpx_image_t>& out_image,
|
|
+ std::unique_ptr<uint8_t[]>& out_image_buffer) {
|
|
+ std::unique_ptr<vpx_image_t> image(new vpx_image_t());
|
|
+ memset(image.get(), 0, sizeof(vpx_image_t));
|
|
+
|
|
+ // libvpx seems to require both to be assigned.
|
|
+ image->d_w = width;
|
|
+ image->w = width;
|
|
+ image->d_h = height;
|
|
+ image->h = height;
|
|
+
|
|
+ // I420
|
|
+ image->fmt = VPX_IMG_FMT_YV12;
|
|
+ image->x_chroma_shift = 1;
|
|
+ image->y_chroma_shift = 1;
|
|
+
|
|
+ // libyuv's fast-path requires 16-byte aligned pointers and strides, so pad
|
|
+ // the Y, U and V planes' strides to multiples of 16 bytes.
|
|
+ const int y_stride = ((image->w - 1) & ~15) + 16;
|
|
+ const int uv_unaligned_stride = y_stride >> image->x_chroma_shift;
|
|
+ const int uv_stride = ((uv_unaligned_stride - 1) & ~15) + 16;
|
|
+
|
|
+ // libvpx accesses the source image in macro blocks, and will over-read
|
|
+ // if the image is not padded out to the next macroblock: crbug.com/119633.
|
|
+ // Pad the Y, U and V planes' height out to compensate.
|
|
+ // Assuming macroblocks are 16x16, aligning the planes' strides above also
|
|
+ // macroblock aligned them.
|
|
+ static_assert(kMacroBlockSize == 16, "macroblock_size_not_16");
|
|
+ const int y_rows = ((image->h - 1) & ~(kMacroBlockSize-1)) + kMacroBlockSize;
|
|
+ const int uv_rows = y_rows >> image->y_chroma_shift;
|
|
+
|
|
+ // Allocate a YUV buffer large enough for the aligned data & padding.
|
|
+ const int buffer_size = y_stride * y_rows + 2*uv_stride * uv_rows;
|
|
+ std::unique_ptr<uint8_t[]> image_buffer(new uint8_t[buffer_size]);
|
|
+
|
|
+ // Reset image value to 128 so we just need to fill in the y plane.
|
|
+ memset(image_buffer.get(), 128, buffer_size);
|
|
+
|
|
+ // Fill in the information for |image_|.
|
|
+ unsigned char* uchar_buffer =
|
|
+ reinterpret_cast<unsigned char*>(image_buffer.get());
|
|
+ image->planes[0] = uchar_buffer;
|
|
+ image->planes[1] = image->planes[0] + y_stride * y_rows;
|
|
+ image->planes[2] = image->planes[1] + uv_stride * uv_rows;
|
|
+ image->stride[0] = y_stride;
|
|
+ image->stride[1] = uv_stride;
|
|
+ image->stride[2] = uv_stride;
|
|
+
|
|
+ out_image = std::move(image);
|
|
+ out_image_buffer = std::move(image_buffer);
|
|
+}
|
|
+
|
|
+} // namespace
|
|
+
|
|
+class ScreencastEncoder::VPXFrame {
|
|
+ WTF_MAKE_NONCOPYABLE(VPXFrame);
|
|
+ WTF_MAKE_FAST_ALLOCATED;
|
|
+public:
|
|
+#if USE(SKIA) && !PLATFORM(GTK)
|
|
+ explicit VPXFrame(sk_sp<SkImage>&& surface)
|
|
+ : m_surface(WTFMove(surface))
|
|
+ { }
|
|
+#elif USE(CAIRO) || PLATFORM(GTK)
|
|
+ explicit VPXFrame(RefPtr<cairo_surface_t>&& surface)
|
|
+ : m_surface(WTFMove(surface))
|
|
+ { }
|
|
+#elif PLATFORM(MAC)
|
|
+ VPXFrame(RetainPtr<CGImageRef> windowImage, int offsetTop)
|
|
+ : m_windowImage(WTFMove(windowImage))
|
|
+ , m_offsetTop(offsetTop)
|
|
+ { }
|
|
+#endif
|
|
+
|
|
+ void setDuration(Seconds duration) { m_duration = duration; }
|
|
+ Seconds duration() const { return m_duration; }
|
|
+
|
|
+ void convertToVpxImage(vpx_image_t* image)
|
|
+ {
|
|
+#if USE(SKIA) && !PLATFORM(GTK)
|
|
+ // Convert the updated region to YUV ready for encoding.
|
|
+ SkImageInfo info = SkImageInfo::Make(m_surface->width(), m_surface->height(), kN32_SkColorType, kPremul_SkAlphaType);
|
|
+ int argb_stride = info.minRowBytes();
|
|
+ size_t bufferSize = info.computeByteSize(argb_stride);
|
|
+ UniqueArray<uint8_t> buffer = makeUniqueArray<uint8_t>(bufferSize);
|
|
+ uint8_t* argb_data = buffer.get();
|
|
+ if (!m_surface->readPixels(info, argb_data, argb_stride, 0, 0))
|
|
+ fprintf(stderr, "Read SkImage to ARGB buffer\n");
|
|
+#elif USE(CAIRO) || PLATFORM(GTK)
|
|
+ // Convert the updated region to YUV ready for encoding.
|
|
+ const uint8_t* argb_data = cairo_image_surface_get_data(m_surface.get());
|
|
+ int argb_stride = cairo_image_surface_get_stride(m_surface.get());
|
|
+#elif PLATFORM(MAC)
|
|
+ int argb_stride = image->w * 4;
|
|
+ UniqueArray<uint8_t> buffer = makeUniqueArray<uint8_t>(argb_stride * image->h);
|
|
+ uint8_t* argb_data = buffer.get();
|
|
+ ScreencastEncoder::imageToARGB(m_windowImage.get(), argb_data, image->w, image->h, m_offsetTop);
|
|
+#endif
|
|
+ const int y_stride = image->stride[0];
|
|
+ ASSERT(image->stride[1] == image->stride[2]);
|
|
+ const int uv_stride = image->stride[1];
|
|
+ uint8_t* y_data = image->planes[0];
|
|
+ uint8_t* u_data = image->planes[1];
|
|
+ uint8_t* v_data = image->planes[2];
|
|
+
|
|
+ // TODO: redraw only damaged regions?
|
|
+ libyuv::ARGBToI420(argb_data, argb_stride,
|
|
+ y_data, y_stride,
|
|
+ u_data, uv_stride,
|
|
+ v_data, uv_stride,
|
|
+ image->w, image->h);
|
|
+ }
|
|
+
|
|
+private:
|
|
+#if USE(SKIA) && !PLATFORM(GTK)
|
|
+ sk_sp<SkImage> m_surface;
|
|
+#elif USE(CAIRO) || PLATFORM(GTK)
|
|
+ RefPtr<cairo_surface_t> m_surface;
|
|
+#elif PLATFORM(MAC)
|
|
+ RetainPtr<CGImageRef> m_windowImage;
|
|
+ int m_offsetTop { 0 };
|
|
+#endif
|
|
+ Seconds m_duration;
|
|
+};
|
|
+
|
|
+
|
|
+class ScreencastEncoder::VPXCodec {
|
|
+public:
|
|
+ VPXCodec(ScopedVpxCodec codec, vpx_codec_enc_cfg_t cfg, FILE* file)
|
|
+ : m_encoderQueue(WorkQueue::create("Screencast encoder"_s))
|
|
+ , m_codec(WTFMove(codec))
|
|
+ , m_cfg(cfg)
|
|
+ , m_file(file)
|
|
+ , m_writer(new WebMFileWriter(file, &m_cfg))
|
|
+ {
|
|
+ createImage(cfg.g_w, cfg.g_h, m_image, m_imageBuffer);
|
|
+ }
|
|
+
|
|
+ void encodeFrameAsync(std::unique_ptr<VPXFrame>&& frame)
|
|
+ {
|
|
+ m_encoderQueue->dispatch([this, frame = WTFMove(frame)] {
|
|
+ frame->convertToVpxImage(m_image.get());
|
|
+ double frameCount = frame->duration().seconds() * fps;
|
|
+ // For long duration repeat frame at 1 fps to ensure last frame duration is short enough.
|
|
+ // TODO: figure out why simply passing duration doesn't work well.
|
|
+ for (;frameCount > 1.5; frameCount -= 1) {
|
|
+ encodeFrame(m_image.get(), timeScale);
|
|
+ }
|
|
+ encodeFrame(m_image.get(), std::max<int>(1, frameCount * timeScale));
|
|
+ });
|
|
+ }
|
|
+
|
|
+ void finishAsync(Function<void()>&& callback)
|
|
+ {
|
|
+ m_encoderQueue->dispatch([this, callback = WTFMove(callback)] {
|
|
+ finish();
|
|
+ callback();
|
|
+ });
|
|
+ }
|
|
+
|
|
+private:
|
|
+ bool encodeFrame(vpx_image_t *img, int duration)
|
|
+ {
|
|
+ vpx_codec_iter_t iter = nullptr;
|
|
+ const vpx_codec_cx_pkt_t *pkt = nullptr;
|
|
+ int flags = 0;
|
|
+ const vpx_codec_err_t res = vpx_codec_encode(m_codec.get(), img, m_pts, duration, flags, VPX_DL_REALTIME);
|
|
+ if (res != VPX_CODEC_OK) {
|
|
+ fprintf(stderr, "Failed to encode frame: %s\n", vpx_codec_error(m_codec.get()));
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ bool gotPkts = false;
|
|
+ while ((pkt = vpx_codec_get_cx_data(m_codec.get(), &iter)) != nullptr) {
|
|
+ gotPkts = true;
|
|
+
|
|
+ if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) {
|
|
+ if (!m_writer->writeFrame(pkt)) {
|
|
+ fprintf(stderr, "Failed to write compressed frame\n");
|
|
+ return false;
|
|
+ }
|
|
+ ++m_frameCount;
|
|
+ m_pts += pkt->data.frame.duration;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return gotPkts;
|
|
+ }
|
|
+
|
|
+ void finish()
|
|
+ {
|
|
+ // Flush encoder.
|
|
+ while (encodeFrame(nullptr, 1))
|
|
+ ++m_frameCount;
|
|
+
|
|
+ m_writer->finish();
|
|
+ fclose(m_file);
|
|
+ }
|
|
+
|
|
+ Ref<WorkQueue> m_encoderQueue;
|
|
+ ScopedVpxCodec m_codec;
|
|
+ vpx_codec_enc_cfg_t m_cfg;
|
|
+ FILE* m_file { nullptr };
|
|
+ std::unique_ptr<WebMFileWriter> m_writer;
|
|
+ int m_frameCount { 0 };
|
|
+ int64_t m_pts { 0 };
|
|
+ std::unique_ptr<uint8_t[]> m_imageBuffer;
|
|
+ std::unique_ptr<vpx_image_t> m_image;
|
|
+};
|
|
+
|
|
+ScreencastEncoder::ScreencastEncoder(std::unique_ptr<VPXCodec>&& vpxCodec, IntSize size)
|
|
+ : m_vpxCodec(WTFMove(vpxCodec))
|
|
+ , m_size(size)
|
|
+{
|
|
+ ASSERT(!size.isZero());
|
|
+}
|
|
+
|
|
+ScreencastEncoder::~ScreencastEncoder()
|
|
+{
|
|
+}
|
|
+
|
|
+RefPtr<ScreencastEncoder> ScreencastEncoder::create(String& errorString, const String& filePath, IntSize size)
|
|
+{
|
|
+ vpx_codec_iface_t* codec_interface = vpx_codec_vp8_cx();
|
|
+ if (!codec_interface) {
|
|
+ errorString = "Codec not found."_s;
|
|
+ return nullptr;
|
|
+ }
|
|
+
|
|
+ if (size.width() <= 0 || size.height() <= 0 || (size.width() % 2) != 0 || (size.height() % 2) != 0) {
|
|
+ errorString = makeString("Invalid frame size: "_s, size.width(), "x"_s, size.height());
|
|
+ return nullptr;
|
|
+ }
|
|
+
|
|
+ vpx_codec_enc_cfg_t cfg;
|
|
+ memset(&cfg, 0, sizeof(cfg));
|
|
+ vpx_codec_err_t error = vpx_codec_enc_config_default(codec_interface, &cfg, 0);
|
|
+ if (error) {
|
|
+ errorString = makeString("Failed to get default codec config: "_s, unsafeSpan(vpx_codec_err_to_string(error)));
|
|
+ return nullptr;
|
|
+ }
|
|
+
|
|
+ cfg.g_w = size.width();
|
|
+ cfg.g_h = size.height();
|
|
+ cfg.g_timebase.num = 1;
|
|
+ cfg.g_timebase.den = fps * timeScale;
|
|
+ cfg.g_error_resilient = VPX_ERROR_RESILIENT_DEFAULT;
|
|
+
|
|
+ ScopedVpxCodec codec(new vpx_codec_ctx_t);
|
|
+ if (vpx_codec_enc_init(codec.get(), codec_interface, &cfg, 0)) {
|
|
+ errorString = makeString("Failed to initialize encoder: "_s, unsafeSpan(vpx_codec_error(codec.get())));
|
|
+ return nullptr;
|
|
+ }
|
|
+
|
|
+ FILE* file = fopen(filePath.utf8().data(), "wb");
|
|
+ if (!file) {
|
|
+ errorString = makeString("Failed to open file '"_s, filePath, "' for writing: "_s, unsafeSpan(strerror(errno)));
|
|
+ return nullptr;
|
|
+ }
|
|
+
|
|
+ std::unique_ptr<VPXCodec> vpxCodec(new VPXCodec(WTFMove(codec), cfg, file));
|
|
+ return adoptRef(new ScreencastEncoder(WTFMove(vpxCodec), size));
|
|
+}
|
|
+
|
|
+void ScreencastEncoder::flushLastFrame()
|
|
+{
|
|
+ MonotonicTime now = MonotonicTime::now();
|
|
+ if (m_lastFrameTimestamp) {
|
|
+ // If previous frame encoding failed for some rason leave the timestampt intact.
|
|
+ if (!m_lastFrame)
|
|
+ return;
|
|
+
|
|
+ Seconds seconds = now - m_lastFrameTimestamp;
|
|
+ m_lastFrame->setDuration(seconds);
|
|
+ m_vpxCodec->encodeFrameAsync(WTFMove(m_lastFrame));
|
|
+ }
|
|
+ m_lastFrameTimestamp = now;
|
|
+}
|
|
+
|
|
+#if USE(SKIA) && !PLATFORM(GTK)
|
|
+void ScreencastEncoder::encodeFrame(sk_sp<SkImage>&& image, IntSize size)
|
|
+{
|
|
+ flushLastFrame();
|
|
+ // Note that in WPE drawing area size is updated asynchronously and may differ from acutal
|
|
+ // size of the surface.
|
|
+ if (size.isZero()) {
|
|
+ return;
|
|
+ }
|
|
+ SkBitmap surface;
|
|
+ surface.allocPixels(SkImageInfo::Make(m_size.width(), m_size.height(), kBGRA_8888_SkColorType, kPremul_SkAlphaType));
|
|
+ SkCanvas canvas(surface);
|
|
+ SkMatrix transform;
|
|
+ if (size.width() > m_size.width() || size.height() > m_size.height()) {
|
|
+ // If no scale is specified shrink to fit the frame.
|
|
+ double scale = std::min(static_cast<double>(m_size.width()) / size.width(),
|
|
+ static_cast<double>(m_size.height()) / size.height());
|
|
+ transform.setScale(scale, scale);
|
|
+ canvas.setMatrix(transform);
|
|
+ }
|
|
+ // Record top left part of the drawing area that fits into the frame.
|
|
+ canvas.drawImage(image, 0, 0);
|
|
+ m_lastFrame = makeUnique<VPXFrame>(surface.asImage());
|
|
+}
|
|
+#elif USE(CAIRO) || PLATFORM(GTK)
|
|
+void ScreencastEncoder::encodeFrame(cairo_surface_t* drawingAreaSurface, IntSize size)
|
|
+{
|
|
+ flushLastFrame();
|
|
+ // Note that in WPE drawing area size is updated asynchronously and may differ from acutal
|
|
+ // size of the surface.
|
|
+ if (size.isZero()) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ RefPtr<cairo_surface_t> surface = adoptRef(cairo_image_surface_create(CAIRO_FORMAT_ARGB32, m_size.width(), m_size.height()));
|
|
+ {
|
|
+ RefPtr<cairo_t> cr = adoptRef(cairo_create(surface.get()));
|
|
+
|
|
+ cairo_matrix_t transform;
|
|
+ if (size.width() > m_size.width() || size.height() > m_size.height()) {
|
|
+ // If no scale is specified shrink to fit the frame.
|
|
+ double scale = std::min(static_cast<double>(m_size.width()) / size.width(),
|
|
+ static_cast<double>(m_size.height()) / size.height());
|
|
+ cairo_matrix_init_scale(&transform, scale, scale);
|
|
+ cairo_transform(cr.get(), &transform);
|
|
+ }
|
|
+
|
|
+ // Record top left part of the drawing area that fits into the frame.
|
|
+ cairo_set_source_surface(cr.get(), drawingAreaSurface, 0, 0);
|
|
+ cairo_paint(cr.get());
|
|
+ }
|
|
+ cairo_surface_flush(surface.get());
|
|
+
|
|
+ m_lastFrame = makeUnique<VPXFrame>(WTFMove(surface));
|
|
+}
|
|
+#elif PLATFORM(MAC)
|
|
+void ScreencastEncoder::encodeFrame(RetainPtr<CGImageRef>&& windowImage)
|
|
+{
|
|
+ flushLastFrame();
|
|
+
|
|
+ m_lastFrame = makeUnique<VPXFrame>(WTFMove(windowImage), m_offsetTop);
|
|
+}
|
|
+#endif
|
|
+
|
|
+void ScreencastEncoder::finish(Function<void()>&& callback)
|
|
+{
|
|
+ if (!m_vpxCodec) {
|
|
+ callback();
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ flushLastFrame();
|
|
+ m_vpxCodec->finishAsync([protectRef = Ref { *this }, callback = WTFMove(callback)] () mutable {
|
|
+ RunLoop::main().dispatch([callback = WTFMove(callback)] {
|
|
+ callback();
|
|
+ });
|
|
+ });
|
|
+}
|
|
+
|
|
+
|
|
+} // namespace WebKit
|
|
+
|
|
+WTF_ALLOW_UNSAFE_BUFFER_USAGE_END
|
|
diff --git a/Source/WebKit/UIProcess/Inspector/Agents/ScreencastEncoder.h b/Source/WebKit/UIProcess/Inspector/Agents/ScreencastEncoder.h
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..caf0474267c1bda6346f7b025b6646bb4f1b56d9
|
|
--- /dev/null
|
|
+++ b/Source/WebKit/UIProcess/Inspector/Agents/ScreencastEncoder.h
|
|
@@ -0,0 +1,82 @@
|
|
+/*
|
|
+ * 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 <WebCore/IntSize.h>
|
|
+#include <wtf/Forward.h>
|
|
+#include <wtf/MonotonicTime.h>
|
|
+#include <wtf/Noncopyable.h>
|
|
+#include <wtf/ThreadSafeRefCounted.h>
|
|
+#include <wtf/WeakPtr.h>
|
|
+
|
|
+#if USE(CAIRO) || PLATFORM(GTK)
|
|
+#include <cairo.h>
|
|
+#endif
|
|
+
|
|
+namespace WebKit {
|
|
+
|
|
+class WebPageProxy;
|
|
+
|
|
+class ScreencastEncoder : public ThreadSafeRefCounted<ScreencastEncoder> {
|
|
+ WTF_MAKE_NONCOPYABLE(ScreencastEncoder);
|
|
+ WTF_MAKE_FAST_ALLOCATED;
|
|
+public:
|
|
+ static constexpr int fps = 25;
|
|
+
|
|
+ static RefPtr<ScreencastEncoder> create(String& errorString, const String& filePath, WebCore::IntSize);
|
|
+
|
|
+ class VPXCodec;
|
|
+ ScreencastEncoder(std::unique_ptr<VPXCodec>&&, WebCore::IntSize);
|
|
+ ~ScreencastEncoder();
|
|
+
|
|
+#if USE(SKIA) && !PLATFORM(GTK)
|
|
+ void encodeFrame(sk_sp<SkImage>&&, WebCore::IntSize);
|
|
+#elif USE(CAIRO) || PLATFORM(GTK)
|
|
+ void encodeFrame(cairo_surface_t*, WebCore::IntSize);
|
|
+#elif PLATFORM(MAC)
|
|
+ void encodeFrame(RetainPtr<CGImageRef>&&);
|
|
+ void setOffsetTop(int offset) { m_offsetTop = offset;}
|
|
+#endif
|
|
+
|
|
+ void finish(Function<void()>&& callback);
|
|
+
|
|
+private:
|
|
+ void flushLastFrame();
|
|
+#if PLATFORM(MAC)
|
|
+ static void imageToARGB(CGImageRef, uint8_t* rgba_data, int width, int height, int offsetTop);
|
|
+#endif
|
|
+
|
|
+ std::unique_ptr<VPXCodec> m_vpxCodec;
|
|
+ const WebCore::IntSize m_size;
|
|
+ MonotonicTime m_lastFrameTimestamp;
|
|
+ class VPXFrame;
|
|
+ std::unique_ptr<VPXFrame> m_lastFrame;
|
|
+#if PLATFORM(MAC)
|
|
+ int m_offsetTop { 0 };
|
|
+#endif
|
|
+};
|
|
+
|
|
+} // namespace WebKit
|
|
diff --git a/Source/WebKit/UIProcess/Inspector/Agents/WebMFileWriter.cpp b/Source/WebKit/UIProcess/Inspector/Agents/WebMFileWriter.cpp
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..9b269b356e206f0252245a1497adb0d05128c9b4
|
|
--- /dev/null
|
|
+++ b/Source/WebKit/UIProcess/Inspector/Agents/WebMFileWriter.cpp
|
|
@@ -0,0 +1,69 @@
|
|
+/*
|
|
+ * Copyright (c) 2014 The WebM project authors. All Rights Reserved.
|
|
+ * 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 "WebMFileWriter.h"
|
|
+
|
|
+#include <string>
|
|
+#include "mkvmuxer/mkvmuxerutil.h"
|
|
+
|
|
+namespace WebKit {
|
|
+
|
|
+WebMFileWriter::WebMFileWriter(FILE* file, vpx_codec_enc_cfg_t* cfg)
|
|
+ : m_cfg(cfg)
|
|
+ , m_writer(new mkvmuxer::MkvWriter(file))
|
|
+ , m_segment(new mkvmuxer::Segment()) {
|
|
+ m_segment->Init(m_writer.get());
|
|
+ m_segment->set_mode(mkvmuxer::Segment::kFile);
|
|
+ m_segment->OutputCues(true);
|
|
+
|
|
+ mkvmuxer::SegmentInfo* info = m_segment->GetSegmentInfo();
|
|
+ std::string version = "Playwright " + std::string(vpx_codec_version_str());
|
|
+ info->set_writing_app(version.c_str());
|
|
+
|
|
+ // Add vp8 track.
|
|
+ m_videoTrackId = m_segment->AddVideoTrack(
|
|
+ static_cast<int>(m_cfg->g_w), static_cast<int>(m_cfg->g_h), 0);
|
|
+ if (!m_videoTrackId) {
|
|
+ fprintf(stderr, "Failed to add video track\n");
|
|
+ }
|
|
+}
|
|
+
|
|
+WebMFileWriter::~WebMFileWriter() {}
|
|
+
|
|
+bool WebMFileWriter::writeFrame(const vpx_codec_cx_pkt_t* pkt) {
|
|
+ int64_t pts_ns = pkt->data.frame.pts * 1000000000ll * m_cfg->g_timebase.num /
|
|
+ m_cfg->g_timebase.den;
|
|
+ return m_segment->AddFrame(static_cast<uint8_t*>(pkt->data.frame.buf),
|
|
+ pkt->data.frame.sz, m_videoTrackId, pts_ns,
|
|
+ pkt->data.frame.flags & VPX_FRAME_IS_KEY);
|
|
+}
|
|
+
|
|
+void WebMFileWriter::finish() {
|
|
+ m_segment->Finalize();
|
|
+}
|
|
+
|
|
+} // namespace WebKit
|
|
diff --git a/Source/WebKit/UIProcess/Inspector/Agents/WebMFileWriter.h b/Source/WebKit/UIProcess/Inspector/Agents/WebMFileWriter.h
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..e2ce910f3fd7f587add552275b7e7176cf8b2723
|
|
--- /dev/null
|
|
+++ b/Source/WebKit/UIProcess/Inspector/Agents/WebMFileWriter.h
|
|
@@ -0,0 +1,53 @@
|
|
+/*
|
|
+ * 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 <memory>
|
|
+#include <stdio.h>
|
|
+#include <stdlib.h>
|
|
+#include "vpx/vpx_encoder.h"
|
|
+
|
|
+#include "mkvmuxer/mkvmuxer.h"
|
|
+#include "mkvmuxer/mkvwriter.h"
|
|
+
|
|
+namespace WebKit {
|
|
+
|
|
+class WebMFileWriter {
|
|
+public:
|
|
+ WebMFileWriter(FILE*, vpx_codec_enc_cfg_t* cfg);
|
|
+ ~WebMFileWriter();
|
|
+
|
|
+ bool writeFrame(const vpx_codec_cx_pkt_t* pkt);
|
|
+ void finish();
|
|
+
|
|
+private:
|
|
+ vpx_codec_enc_cfg_t* m_cfg = nullptr;
|
|
+ std::unique_ptr<mkvmuxer::MkvWriter> m_writer;
|
|
+ std::unique_ptr<mkvmuxer::Segment> m_segment;
|
|
+ uint64_t m_videoTrackId = 0;
|
|
+};
|
|
+
|
|
+} // namespace WebKit
|
|
diff --git a/Source/WebKit/UIProcess/Inspector/InspectorTargetProxy.cpp b/Source/WebKit/UIProcess/Inspector/InspectorTargetProxy.cpp
|
|
index 77bdb25abf77bc0f7f00d3dbd57b0eb751c99488..6d3a93a009cff0f70f2b1a1e674827c24a26a947 100644
|
|
--- a/Source/WebKit/UIProcess/Inspector/InspectorTargetProxy.cpp
|
|
+++ b/Source/WebKit/UIProcess/Inspector/InspectorTargetProxy.cpp
|
|
@@ -28,7 +28,7 @@
|
|
|
|
#include "MessageSenderInlines.h"
|
|
#include "ProvisionalPageProxy.h"
|
|
-#include "WebFrameProxy.h"
|
|
+#include "WebPageInspectorController.h"
|
|
#include "WebPageInspectorTarget.h"
|
|
#include "WebPageMessages.h"
|
|
#include "WebPageProxy.h"
|
|
@@ -46,13 +46,13 @@ std::unique_ptr<InspectorTargetProxy> InspectorTargetProxy::create(WebPageProxy&
|
|
return makeUnique<InspectorTargetProxy>(page, targetId, type);
|
|
}
|
|
|
|
-std::unique_ptr<InspectorTargetProxy> InspectorTargetProxy::create(ProvisionalPageProxy& provisionalPage, const String& targetId, Inspector::InspectorTargetType type)
|
|
+std::unique_ptr<InspectorTargetProxy> InspectorTargetProxy::create(ProvisionalPageProxy& provisionalPage, const String& targetId)
|
|
{
|
|
RefPtr page = provisionalPage.page();
|
|
if (!page)
|
|
return nullptr;
|
|
|
|
- auto target = InspectorTargetProxy::create(*page, targetId, type);
|
|
+ auto target = InspectorTargetProxy::create(*page, targetId, Inspector::InspectorTargetType::Page);
|
|
target->m_provisionalPage = provisionalPage;
|
|
return target;
|
|
}
|
|
@@ -105,6 +105,31 @@ void InspectorTargetProxy::didCommitProvisionalTarget()
|
|
m_provisionalPage = nullptr;
|
|
}
|
|
|
|
+void InspectorTargetProxy::willResume()
|
|
+{
|
|
+ if (m_page->hasRunningProcess())
|
|
+ m_page->legacyMainFrameProcess().send(Messages::WebPage::ResumeInspectorIfPausedInNewWindow(), m_page->webPageIDInMainFrameProcess());
|
|
+}
|
|
+
|
|
+void InspectorTargetProxy::activate(String& error)
|
|
+{
|
|
+ if (m_type != Inspector::InspectorTargetType::Page)
|
|
+ return InspectorTarget::activate(error);
|
|
+
|
|
+ platformActivate(error);
|
|
+}
|
|
+
|
|
+void InspectorTargetProxy::close(String& error, bool runBeforeUnload)
|
|
+{
|
|
+ if (m_type != Inspector::InspectorTargetType::Page)
|
|
+ return InspectorTarget::close(error, runBeforeUnload);
|
|
+
|
|
+ if (runBeforeUnload)
|
|
+ m_page->tryClose();
|
|
+ else
|
|
+ m_page->closePage();
|
|
+}
|
|
+
|
|
bool InspectorTargetProxy::isProvisional() const
|
|
{
|
|
return !!m_provisionalPage;
|
|
diff --git a/Source/WebKit/UIProcess/Inspector/InspectorTargetProxy.h b/Source/WebKit/UIProcess/Inspector/InspectorTargetProxy.h
|
|
index edd6e7f1799279ed3d0eb81b6c2eef9f5b375134..d4231f84f3c52641f4d9e88559e8e1a4845b7163 100644
|
|
--- a/Source/WebKit/UIProcess/Inspector/InspectorTargetProxy.h
|
|
+++ b/Source/WebKit/UIProcess/Inspector/InspectorTargetProxy.h
|
|
@@ -38,12 +38,12 @@ class WebPageProxy;
|
|
// NOTE: This UIProcess side InspectorTarget doesn't care about the frontend channel, since
|
|
// any target -> frontend messages will be routed to the WebPageProxy with a targetId.
|
|
|
|
-class InspectorTargetProxy final : public Inspector::InspectorTarget {
|
|
+class InspectorTargetProxy : public Inspector::InspectorTarget {
|
|
WTF_MAKE_TZONE_ALLOCATED(InspectorTargetProxy);
|
|
WTF_MAKE_NONCOPYABLE(InspectorTargetProxy);
|
|
public:
|
|
static std::unique_ptr<InspectorTargetProxy> create(WebPageProxy&, const String& targetId, Inspector::InspectorTargetType);
|
|
- static std::unique_ptr<InspectorTargetProxy> create(ProvisionalPageProxy&, const String& targetId, Inspector::InspectorTargetType);
|
|
+ static std::unique_ptr<InspectorTargetProxy> create(ProvisionalPageProxy&, const String& targetId);
|
|
InspectorTargetProxy(WebPageProxy&, const String& targetId, Inspector::InspectorTargetType);
|
|
~InspectorTargetProxy() = default;
|
|
|
|
@@ -56,8 +56,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;
|
|
String m_identifier;
|
|
Inspector::InspectorTargetType m_type;
|
|
diff --git a/Source/WebKit/UIProcess/Inspector/WebPageInspectorController.cpp b/Source/WebKit/UIProcess/Inspector/WebPageInspectorController.cpp
|
|
index e4f2f719746ed69b1226be2d47b16666f2067772..96956711b594d80ea9cbdce11a6f62b2992530aa 100644
|
|
--- a/Source/WebKit/UIProcess/Inspector/WebPageInspectorController.cpp
|
|
+++ b/Source/WebKit/UIProcess/Inspector/WebPageInspectorController.cpp
|
|
@@ -26,13 +26,22 @@
|
|
#include "config.h"
|
|
#include "WebPageInspectorController.h"
|
|
|
|
+#include "APINavigation.h"
|
|
+#include "APIPageConfiguration.h"
|
|
#include "APIUIClient.h"
|
|
#include "InspectorBrowserAgent.h"
|
|
+#include "InspectorDialogAgent.h"
|
|
+#include "InspectorScreencastAgent.h"
|
|
#include "ProvisionalPageProxy.h"
|
|
#include "WebFrameProxy.h"
|
|
#include "WebPageInspectorAgentBase.h"
|
|
+#include "WebPageInspectorEmulationAgent.h"
|
|
+#include "WebPageInspectorInputAgent.h"
|
|
#include "WebPageInspectorTarget.h"
|
|
#include "WebPageProxy.h"
|
|
+#include "WebPreferences.h"
|
|
+#include <WebCore/ResourceError.h>
|
|
+#include <WebCore/WindowFeatures.h>
|
|
#include <JavaScriptCore/InspectorAgentBase.h>
|
|
#include <JavaScriptCore/InspectorBackendDispatcher.h>
|
|
#include <JavaScriptCore/InspectorBackendDispatchers.h>
|
|
@@ -52,34 +61,115 @@ static String getTargetID(const ProvisionalPageProxy& provisionalPage)
|
|
|
|
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()))
|
|
, m_inspectedPage(inspectedPage)
|
|
{
|
|
- auto targetAgent = makeUnique<InspectorTargetAgent>(m_frontendRouter.get(), m_backendDispatcher.get());
|
|
- m_targetAgent = targetAgent.get();
|
|
- m_agents.append(WTFMove(targetAgent));
|
|
}
|
|
|
|
WebPageInspectorController::~WebPageInspectorController() = default;
|
|
|
|
-Ref<WebPageProxy> WebPageInspectorController::protectedInspectedPage()
|
|
+WeakRef<WebPageProxy> WebPageInspectorController::protectedInspectedPage()
|
|
{
|
|
- return m_inspectedPage.get();
|
|
+ return m_inspectedPage;
|
|
}
|
|
|
|
void WebPageInspectorController::init()
|
|
{
|
|
- String pageTargetId = WebPageInspectorTarget::toTargetID(m_inspectedPage->webPageIDInMainFrameProcess());
|
|
- createInspectorTarget(pageTargetId, Inspector::InspectorTargetType::Page);
|
|
+ auto targetAgent = makeUnique<InspectorTargetAgent>(m_frontendRouter.get(), m_backendDispatcher.get());
|
|
+ m_targetAgent = targetAgent.get();
|
|
+ m_agents.append(WTFMove(targetAgent));
|
|
+ auto emulationAgent = makeUnique<WebPageInspectorEmulationAgent>(m_backendDispatcher.get(), m_inspectedPage);
|
|
+ m_emulationAgent = emulationAgent.get();
|
|
+ m_agents.append(WTFMove(emulationAgent));
|
|
+ auto inputAgent = makeUnique<WebPageInspectorInputAgent>(m_backendDispatcher.get(), m_inspectedPage);
|
|
+ m_inputAgent = inputAgent.get();
|
|
+ m_agents.append(WTFMove(inputAgent));
|
|
+ m_agents.append(makeUnique<InspectorDialogAgent>(m_backendDispatcher.get(), m_frontendRouter.get(), m_inspectedPage));
|
|
+ auto screencastAgent = makeUnique<InspectorScreencastAgent>(m_backendDispatcher.get(), m_frontendRouter.get(), m_inspectedPage);
|
|
+ m_screecastAgent = screencastAgent.get();
|
|
+ m_agents.append(WTFMove(screencastAgent));
|
|
+ if (s_observer)
|
|
+ s_observer->didCreateInspectorController(m_inspectedPage);
|
|
+}
|
|
+
|
|
+void WebPageInspectorController::didInitializeWebPage()
|
|
+{
|
|
+ String pageTargetID = WebPageInspectorTarget::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;
|
|
+ createInspectorTarget(pageTargetID, Inspector::InspectorTargetType::Page);
|
|
}
|
|
|
|
void WebPageInspectorController::pageClosed()
|
|
{
|
|
+ String pageTargetId = WebPageInspectorTarget::toTargetID(m_inspectedPage->webPageIDInMainFrameProcess());
|
|
+ destroyInspectorTarget(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 = WebPageInspectorTarget::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
|
|
@@ -93,6 +183,17 @@ 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;
|
|
+ }
|
|
+
|
|
+ if (connectingFirstFrontend)
|
|
+ adjustPageSettings();
|
|
+
|
|
m_frontendRouter->connectFrontend(frontendChannel);
|
|
|
|
if (connectingFirstFrontend)
|
|
@@ -112,8 +213,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();
|
|
+ }
|
|
|
|
auto inspectedPage = protectedInspectedPage();
|
|
inspectedPage->didChangeInspectorFrontendCount(m_frontendRouter->frontendCount());
|
|
@@ -137,6 +240,8 @@ void WebPageInspectorController::disconnectAllFrontends()
|
|
// Disconnect any remaining remote frontends.
|
|
m_frontendRouter->disconnectAllFrontends();
|
|
|
|
+ m_pendingNavigations.clear();
|
|
+
|
|
auto inspectedPage = protectedInspectedPage();
|
|
inspectedPage->didChangeInspectorFrontendCount(m_frontendRouter->frontendCount());
|
|
|
|
@@ -165,6 +270,75 @@ void WebPageInspectorController::setIndicating(bool indicating)
|
|
}
|
|
#endif
|
|
|
|
+#if USE(SKIA) && !PLATFORM(GTK)
|
|
+void WebPageInspectorController::didPaint(sk_sp<SkImage>&& surface)
|
|
+{
|
|
+ if (!m_frontendRouter->hasFrontends())
|
|
+ return;
|
|
+
|
|
+ m_screecastAgent->didPaint(WTFMove(surface));
|
|
+}
|
|
+#endif
|
|
+#if USE(CAIRO) || PLATFORM(GTK)
|
|
+void WebPageInspectorController::didPaint(cairo_surface_t* surface)
|
|
+{
|
|
+ if (!m_frontendRouter->hasFrontends())
|
|
+ return;
|
|
+
|
|
+ m_screecastAgent->didPaint(surface);
|
|
+}
|
|
+#endif
|
|
+
|
|
+
|
|
+void WebPageInspectorController::navigate(WebCore::ResourceRequest&& request, WebFrameProxy* frame, NavigationHandler&& completionHandler)
|
|
+{
|
|
+ auto navigation = m_inspectedPage->loadRequestForInspector(WTFMove(request), frame);
|
|
+ if (!navigation) {
|
|
+ completionHandler("Failed to navigate"_s, { });
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ m_pendingNavigations.set(navigation->navigationID(), WTFMove(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::createInspectorTarget(const String& targetId, Inspector::InspectorTargetType type)
|
|
{
|
|
addTarget(InspectorTargetProxy::create(protectedInspectedPage(), targetId, type));
|
|
@@ -184,6 +358,52 @@ void WebPageInspectorController::sendMessageToInspectorFrontend(const String& ta
|
|
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(WebPageInspectorTarget::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(WebPageInspectorTarget::toTargetID(m_inspectedPage->webPageIDInMainFrameProcess()));
|
|
+ ASSERT(target);
|
|
+ target->setResumeCallback(WTFMove(callback));
|
|
+}
|
|
+
|
|
bool WebPageInspectorController::shouldPauseLoading(const ProvisionalPageProxy& provisionalPage) const
|
|
{
|
|
if (!m_frontendRouter->hasFrontends())
|
|
@@ -203,7 +423,7 @@ void WebPageInspectorController::setContinueLoadingCallback(const ProvisionalPag
|
|
|
|
void WebPageInspectorController::didCreateProvisionalPage(ProvisionalPageProxy& provisionalPage)
|
|
{
|
|
- addTarget(InspectorTargetProxy::create(provisionalPage, getTargetID(provisionalPage), Inspector::InspectorTargetType::Page));
|
|
+ addTarget(InspectorTargetProxy::create(provisionalPage, getTargetID(provisionalPage)));
|
|
}
|
|
|
|
void WebPageInspectorController::willDestroyProvisionalPage(const ProvisionalPageProxy& provisionalPage)
|
|
@@ -287,4 +507,29 @@ void WebPageInspectorController::browserExtensionsDisabled(HashSet<String>&& ext
|
|
m_enabledBrowserAgent->extensionsDisabled(WTFMove(extensionIDs));
|
|
}
|
|
|
|
+void WebPageInspectorController::adjustPageSettings()
|
|
+{
|
|
+ // 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).
|
|
+ m_inspectedPage->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.
|
|
+ m_inspectedPage->preferences().setUsesBackForwardCache(false);
|
|
+
|
|
+ // Enable popup debugging.
|
|
+ // TODO: allow to set preferences over the inspector protocol or find a better place for this.
|
|
+ m_inspectedPage->preferences().setJavaScriptCanOpenWindowsAutomatically(true);
|
|
+
|
|
+ // Enable media stream.
|
|
+ if (!m_inspectedPage->preferences().mediaDevicesEnabled()) {
|
|
+ m_inspectedPage->preferences().setMediaDevicesEnabled(true);
|
|
+ m_inspectedPage->preferences().setPeerConnectionEnabled(true);
|
|
+ }
|
|
+
|
|
+ // Disable local storage partitioning. See https://github.com/microsoft/playwright/issues/32230
|
|
+ m_inspectedPage->preferences().setStorageBlockingPolicy(static_cast<uint32_t>(WebCore::StorageBlockingPolicy::AllowAll));
|
|
+}
|
|
+
|
|
} // namespace WebKit
|
|
diff --git a/Source/WebKit/UIProcess/Inspector/WebPageInspectorController.h b/Source/WebKit/UIProcess/Inspector/WebPageInspectorController.h
|
|
index 29457fc3c76c963bf50b44c011f64398efbae676..3e098aae8cd02d26aa32a6e15ed16e95695afaf7 100644
|
|
--- a/Source/WebKit/UIProcess/Inspector/WebPageInspectorController.h
|
|
+++ b/Source/WebKit/UIProcess/Inspector/WebPageInspectorController.h
|
|
@@ -26,19 +26,43 @@
|
|
#pragma once
|
|
|
|
#include "InspectorTargetProxy.h"
|
|
+#include "ProcessTerminationReason.h"
|
|
#include <JavaScriptCore/InspectorAgentRegistry.h>
|
|
#include <JavaScriptCore/InspectorTargetAgent.h>
|
|
+#include <WebCore/NavigationIdentifier.h>
|
|
#include <WebCore/PageIdentifier.h>
|
|
#include <wtf/CheckedRef.h>
|
|
#include <wtf/Forward.h>
|
|
#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
|
|
+
|
|
+#if USE(CAIRO) || PLATFORM(GTK)
|
|
+#include <cairo.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 {
|
|
@@ -46,6 +70,23 @@ namespace WebKit {
|
|
class InspectorBrowserAgent;
|
|
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;
|
|
+ virtual void didFinishScreencast(const PAL::SessionID& sessionID, const String& screencastID) = 0;
|
|
+
|
|
+protected:
|
|
+ virtual ~WebPageInspectorControllerObserver() = default;
|
|
+};
|
|
+
|
|
class WebPageInspectorController {
|
|
WTF_MAKE_TZONE_ALLOCATED(WebPageInspectorController);
|
|
WTF_MAKE_NONCOPYABLE(WebPageInspectorController);
|
|
@@ -54,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;
|
|
|
|
@@ -67,11 +122,30 @@ public:
|
|
#if ENABLE(REMOTE_INSPECTOR)
|
|
void setIndicating(bool);
|
|
#endif
|
|
+#if USE(SKIA) && !PLATFORM(GTK)
|
|
+ void didPaint(sk_sp<SkImage>&&);
|
|
+#endif
|
|
+#if USE(CAIRO) || PLATFORM(GTK)
|
|
+ void didPaint(cairo_surface_t*);
|
|
+#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 createInspectorTarget(const String& targetId, Inspector::InspectorTargetType);
|
|
void destroyInspectorTarget(const String& targetId);
|
|
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()>&&);
|
|
|
|
@@ -86,11 +160,12 @@ public:
|
|
void browserExtensionsDisabled(HashSet<String>&&);
|
|
|
|
private:
|
|
- Ref<WebPageProxy> protectedInspectedPage();
|
|
+ WeakRef<WebPageProxy> protectedInspectedPage();
|
|
WebPageAgentContext webPageAgentContext();
|
|
void createLazyAgents();
|
|
|
|
void addTarget(std::unique_ptr<InspectorTargetProxy>&&);
|
|
+ void adjustPageSettings();
|
|
|
|
Ref<Inspector::FrontendRouter> m_frontendRouter;
|
|
Ref<Inspector::BackendDispatcher> m_backendDispatcher;
|
|
@@ -101,9 +176,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/Inspector/mac/ScreencastEncoderMac.mm b/Source/WebKit/UIProcess/Inspector/mac/ScreencastEncoderMac.mm
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..6a04ee480bc3a8270a7de20b1cd0da718242b4c1
|
|
--- /dev/null
|
|
+++ b/Source/WebKit/UIProcess/Inspector/mac/ScreencastEncoderMac.mm
|
|
@@ -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 "ScreencastEncoder.h"
|
|
+
|
|
+#include <algorithm>
|
|
+#include <CoreGraphics/CoreGraphics.h>
|
|
+#include <wtf/RetainPtr.h>
|
|
+
|
|
+namespace WebKit {
|
|
+
|
|
+void ScreencastEncoder::imageToARGB(CGImageRef image, uint8_t* argb_data, int width, int height, int offsetTop)
|
|
+{
|
|
+ size_t bitsPerComponent = 8;
|
|
+ size_t bytesPerPixel = 4;
|
|
+ size_t bytesPerRow = bytesPerPixel * width;
|
|
+ RetainPtr<CGColorSpaceRef> colorSpace = adoptCF(CGColorSpaceCreateDeviceRGB());
|
|
+ RetainPtr<CGContextRef> context = adoptCF(CGBitmapContextCreate(argb_data, width, height, bitsPerComponent, bytesPerRow, colorSpace.get(), (CGBitmapInfo)kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Little));
|
|
+ double imageWidth = CGImageGetWidth(image);
|
|
+ double imageHeight = CGImageGetHeight(image);
|
|
+ double pageHeight = imageHeight - offsetTop;
|
|
+ double ratio = 1;
|
|
+ if (imageWidth > width || pageHeight > height) {
|
|
+ ratio = std::min(width / imageWidth, height / pageHeight);
|
|
+ }
|
|
+ imageWidth *= ratio;
|
|
+ imageHeight *= ratio;
|
|
+ pageHeight *= ratio;
|
|
+ CGContextDrawImage(context.get(), CGRectMake(0, height - pageHeight, imageWidth, imageHeight), image);
|
|
+}
|
|
+
|
|
+} // namespace WebKit
|
|
diff --git a/Source/WebKit/UIProcess/InspectorDialogAgent.cpp b/Source/WebKit/UIProcess/InspectorDialogAgent.cpp
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..663f92f0df76042cf6385b056f8a917d688259f9
|
|
--- /dev/null
|
|
+++ b/Source/WebKit/UIProcess/InspectorDialogAgent.cpp
|
|
@@ -0,0 +1,88 @@
|
|
+/*
|
|
+ * 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;
|
|
+
|
|
+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(Inspector::FrontendRouter*, Inspector::BackendDispatcher*)
|
|
+{
|
|
+}
|
|
+
|
|
+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..d0e11ed81a6257c011df23d5870da7403f8e9fe4
|
|
--- /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_FAST_ALLOCATED;
|
|
+public:
|
|
+ InspectorDialogAgent(Inspector::BackendDispatcher& backendDispatcher, Inspector::FrontendRouter& frontendRouter, WebPageProxy& page);
|
|
+ ~InspectorDialogAgent() override;
|
|
+
|
|
+ void didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*) 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..7535756c45428e307e27807d31884ae6c5216543
|
|
--- /dev/null
|
|
+++ b/Source/WebKit/UIProcess/InspectorPlaywrightAgent.cpp
|
|
@@ -0,0 +1,1011 @@
|
|
+/*
|
|
+ * 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 "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 "WebPageInspectorTarget.h"
|
|
+#include "WebPageMessages.h"
|
|
+#include "WebPageProxy.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/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_MAKE_FAST_ALLOCATED;
|
|
+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(WTFMove(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();
|
|
+}
|
|
+
|
|
+} // namespace
|
|
+
|
|
+BrowserContext::BrowserContext() = default;
|
|
+
|
|
+BrowserContext::~BrowserContext() = default;
|
|
+
|
|
+class InspectorPlaywrightAgent::BrowserContextDeletion {
|
|
+ WTF_MAKE_NONCOPYABLE(BrowserContextDeletion);
|
|
+ WTF_MAKE_FAST_ALLOCATED;
|
|
+public:
|
|
+ BrowserContextDeletion(std::unique_ptr<BrowserContext>&& context, size_t numberOfPages, Ref<DeleteContextCallback>&& callback)
|
|
+ : m_browserContext(WTFMove(context))
|
|
+ , m_numberOfPages(numberOfPages)
|
|
+ , m_callback(WTFMove(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);
|
|
+ page.inspectorController().connectFrontend(*pageProxyChannel);
|
|
+ // Always pause new targets if controlled remotely.
|
|
+ page.inspectorController().setPauseOnStart(true);
|
|
+ m_pageProxyChannels.set(pageProxyID, WTFMove(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));
|
|
+}
|
|
+
|
|
+void InspectorPlaywrightAgent::didFinishScreencast(const PAL::SessionID& sessionID, const String& screencastID)
|
|
+{
|
|
+ if (!m_isEnabled)
|
|
+ return;
|
|
+
|
|
+ m_frontendDispatcher->screencastFinished(screencastID);
|
|
+}
|
|
+
|
|
+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), WTFMove(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(WTFMove(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 = WTFMove(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(WTFMove(page));
|
|
+ }
|
|
+ for (Ref page : pages)
|
|
+ page->closePage();
|
|
+
|
|
+ if (!m_defaultContext) {
|
|
+ m_client->closeBrowser();
|
|
+ callback(String());
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ m_defaultContext->dataStore->syncLocalStorage([this, callback = WTFMove(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)
|
|
+{
|
|
+ String errorString;
|
|
+ std::unique_ptr<BrowserContext> browserContext = m_client->createBrowserContext(errorString, proxyServer, proxyBypassList);
|
|
+ if (!browserContext)
|
|
+ return makeUnexpected(errorString);
|
|
+
|
|
+ // 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, WTFMove(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>(WTFMove(contextHolder), pages.size(), WTFMove(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;
|
|
+ }
|
|
+
|
|
+ WebCore::ResourceRequest resourceRequest { 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(WTFMove(resourceRequest), frame, [callback = WTFMove(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(WTFMove(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(), WTFMove(clip), nominalResolution, [callback = WTFMove(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);
|
|
+
|
|
+ PAL::SessionID sessionID = browserContext->dataStore->sessionID();
|
|
+ NetworkProcessProxy& networkProcess = browserContext->dataStore->networkProcess();
|
|
+ networkProcess.send(Messages::NetworkProcess::SetIgnoreCertificateErrors(sessionID, ignore), 0);
|
|
+ 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 = WTFMove(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(WTFMove(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(WTFMove(cookie));
|
|
+ }
|
|
+
|
|
+ browserContext->dataStore->cookieStore().setCookies(WTFMove(cookies),
|
|
+ [callback = WTFMove(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 = WTFMove(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(WTFMove(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;
|
|
+ }
|
|
+ auto browserContext = getExistingBrowserContext(browserContextID);
|
|
+ if (!browserContext) {
|
|
+ callback->sendSuccess();
|
|
+ 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..f9185788a118f57e98bec149909a206dc1aa5d99
|
|
--- /dev/null
|
|
+++ b/Source/WebKit/UIProcess/InspectorPlaywrightAgent.h
|
|
@@ -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.
|
|
+ */
|
|
+
|
|
+#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_MAKE_FAST_ALLOCATED;
|
|
+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;
|
|
+ void didFinishScreencast(const PAL::SessionID& sessionID, const String& screencastID) 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) 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..e7a3dcc533294bb6e12f65d79b5b716bd3c12236
|
|
--- /dev/null
|
|
+++ b/Source/WebKit/UIProcess/InspectorPlaywrightAgentClient.h
|
|
@@ -0,0 +1,73 @@
|
|
+/*
|
|
+ * 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_MAKE_FAST_ALLOCATED;
|
|
+public:
|
|
+ BrowserContext();
|
|
+ ~BrowserContext();
|
|
+
|
|
+ RefPtr<WebsiteDataStore> dataStore;
|
|
+ RefPtr<WebProcessPool> processPool;
|
|
+ HashSet<WebPageProxy*> pages;
|
|
+ WeakPtr<OverridenGeolocationProvider> geolocationProvider;
|
|
+};
|
|
+
|
|
+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 9959b634faa60d620d4aac6635b31914bb063979..a8a38fe41b5fdc2836d068cc69940a5b21876e8d 100644
|
|
--- a/Source/WebKit/UIProcess/Launcher/glib/ProcessLauncherGLib.cpp
|
|
+++ b/Source/WebKit/UIProcess/Launcher/glib/ProcessLauncherGLib.cpp
|
|
@@ -168,6 +168,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
|
|
|
|
WTF_ALLOW_UNSAFE_BUFFER_USAGE_BEGIN // GTK/WPE port
|
|
|
|
@@ -188,6 +195,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;
|
|
|
|
WTF_ALLOW_UNSAFE_BUFFER_USAGE_END
|
|
diff --git a/Source/WebKit/UIProcess/Launcher/win/ProcessLauncherWin.cpp b/Source/WebKit/UIProcess/Launcher/win/ProcessLauncherWin.cpp
|
|
index a108acd8a4503a07309fe8c54afc80b0f4175eae..1421d9a761042c31a6ecf3cc78ce3f0e96109abe 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.data(), 0, 0, true, 0, 0, 0, &startupInfo, &processInformation);
|
|
|
|
diff --git a/Source/WebKit/UIProcess/PageClient.h b/Source/WebKit/UIProcess/PageClient.h
|
|
index a5e7596eea86c6b7bdecf0a3adc906c3007a2f5d..2507c278685870936a6a26e9dd0d3474bcde51bc 100644
|
|
--- a/Source/WebKit/UIProcess/PageClient.h
|
|
+++ b/Source/WebKit/UIProcess/PageClient.h
|
|
@@ -75,6 +75,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;
|
|
@@ -96,6 +101,12 @@ OBJC_CLASS WKView;
|
|
#endif
|
|
#endif
|
|
|
|
+#if PLATFORM(GTK) || PLATFORM(WPE)
|
|
+#if USE(CAIRO)
|
|
+#include <WebCore/RefPtrCairo.h>
|
|
+#endif
|
|
+#endif
|
|
+
|
|
namespace API {
|
|
class Attachment;
|
|
class HitTestResult;
|
|
@@ -376,7 +387,20 @@ public:
|
|
virtual void selectionDidChange() = 0;
|
|
#endif
|
|
|
|
-#if PLATFORM(COCOA) || PLATFORM(GTK)
|
|
+// Paywright begin
|
|
+#if PLATFORM(COCOA)
|
|
+ virtual RetainPtr<CGImageRef> takeSnapshotForAutomation() = 0;
|
|
+#elif PLATFORM(WPE)
|
|
+#if USE(SKIA)
|
|
+ virtual sk_sp<SkImage> takeViewSnapshot(std::optional<WebCore::IntRect>&&, bool nominalResolution = false) = 0;
|
|
+#elif USE(CAIRO)
|
|
+ virtual RefPtr<cairo_surface_t> takeViewSnapshot(std::optional<WebCore::IntRect>&&, bool nominalResolution = false) = 0;
|
|
+#endif
|
|
+#elif PLATFORM(GTK)
|
|
+ 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..a8a92a6c5f4b03724decc97828291f6f27cfc6aa
|
|
--- /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_MAKE_FAST_ALLOCATED;
|
|
+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 3399db4087c395fbc516cc90f20f70d535a31c65..ec217611aa4a5823567c5cde84a211a2dcfb26be 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/RemoteInspectorPipe.cpp b/Source/WebKit/UIProcess/RemoteInspectorPipe.cpp
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..b1ddac8c1442cb4da17f50d92599ef9aff6d4066
|
|
--- /dev/null
|
|
+++ b/Source/WebKit/UIProcess/RemoteInspectorPipe.cpp
|
|
@@ -0,0 +1,230 @@
|
|
+/*
|
|
+ * 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_MAKE_FAST_ALLOCATED;
|
|
+
|
|
+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::main().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.data() + start, end - start });
|
|
+ RunLoop::main().dispatch([this, message = WTFMove(message)] {
|
|
+ if (!m_terminated)
|
|
+ m_playwrightAgent.dispatchMessageFromFrontend(message);
|
|
+ });
|
|
+ }
|
|
+ ++end;
|
|
+ start = end;
|
|
+ }
|
|
+ if (start != 0 && start < line.size())
|
|
+ memmove(line.data(), line.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..6d04f9290135069359ce6bf8726546482fd1dc95
|
|
--- /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_MAKE_FAST_ALLOCATED;
|
|
+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/WebContextMenuProxy.h b/Source/WebKit/UIProcess/WebContextMenuProxy.h
|
|
index c951d8577473371d8eb59ad651451737349c4389..b38cd0967ae45733a94594fd25900ddc1d49c3f6 100644
|
|
--- a/Source/WebKit/UIProcess/WebContextMenuProxy.h
|
|
+++ b/Source/WebKit/UIProcess/WebContextMenuProxy.h
|
|
@@ -49,6 +49,7 @@ public:
|
|
void deref() const final { RefCounted::deref(); }
|
|
|
|
virtual void show();
|
|
+ virtual void hide() {}
|
|
|
|
WebPageProxy* page() const { return m_page.get(); }
|
|
|
|
diff --git a/Source/WebKit/UIProcess/WebPageInspectorEmulationAgent.cpp b/Source/WebKit/UIProcess/WebPageInspectorEmulationAgent.cpp
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..0a8d10ae990997684766df46719c65aa8dd77f28
|
|
--- /dev/null
|
|
+++ b/Source/WebKit/UIProcess/WebPageInspectorEmulationAgent.cpp
|
|
@@ -0,0 +1,159 @@
|
|
+/*
|
|
+ * 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;
|
|
+
|
|
+WebPageInspectorEmulationAgent::WebPageInspectorEmulationAgent(BackendDispatcher& backendDispatcher, WebPageProxy& page)
|
|
+ : InspectorAgentBase("Emulation"_s)
|
|
+ , m_backendDispatcher(EmulationBackendDispatcher::create(backendDispatcher, this))
|
|
+ , m_page(page)
|
|
+{
|
|
+}
|
|
+
|
|
+WebPageInspectorEmulationAgent::~WebPageInspectorEmulationAgent()
|
|
+{
|
|
+}
|
|
+
|
|
+void WebPageInspectorEmulationAgent::didCreateFrontendAndBackend(FrontendRouter*, BackendDispatcher*)
|
|
+{
|
|
+}
|
|
+
|
|
+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()->isViewVisible() && m_page.configuration().relatedPage()) {
|
|
+ m_commandsToRunWhenShown.append([this, width, height, callback = WTFMove(callback)]() mutable {
|
|
+ setSize(width, height, WTFMove(callback));
|
|
+ });
|
|
+ } else {
|
|
+ setSize(width, height, WTFMove(callback));
|
|
+ }
|
|
+}
|
|
+
|
|
+void WebPageInspectorEmulationAgent::setSize(int width, int height, Ref<SetDeviceMetricsOverrideCallback>&& callback)
|
|
+{
|
|
+ platformSetSize(width, height, [callback = WTFMove(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 && !!password)
|
|
+ m_page.setAuthCredentialsForAutomation(WebCore::Credential(username, password, WebCore::CredentialPersistence::Permanent), URL(origin));
|
|
+ else
|
|
+ m_page.setAuthCredentialsForAutomation(std::optional<WebCore::Credential>(), std::optional<URL>());
|
|
+ return { };
|
|
+}
|
|
+
|
|
+Inspector::Protocol::ErrorStringOr<void> WebPageInspectorEmulationAgent::setActiveAndFocused(std::optional<bool>&& active)
|
|
+{
|
|
+ m_page.setActiveForAutomation(WTFMove(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, WTFMove(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(WTFMove(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..d00d00ce8fd800dc1497b36b8a495c5b9aef6f58
|
|
--- /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_FAST_ALLOCATED;
|
|
+public:
|
|
+ WebPageInspectorEmulationAgent(Inspector::BackendDispatcher& backendDispatcher, WebPageProxy& page);
|
|
+ ~WebPageInspectorEmulationAgent() override;
|
|
+
|
|
+ void didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*) 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..6cb20d95c1cd8682b025cfdf4ac74f49fd8e9cda
|
|
--- /dev/null
|
|
+++ b/Source/WebKit/UIProcess/WebPageInspectorInputAgent.cpp
|
|
@@ -0,0 +1,394 @@
|
|
+/*
|
|
+ * 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 "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;
|
|
+
|
|
+namespace {
|
|
+
|
|
+template<class T>
|
|
+class CallbackList {
|
|
+ WTF_MAKE_FAST_ALLOCATED;
|
|
+public:
|
|
+ ~CallbackList()
|
|
+ {
|
|
+ for (const auto& callback : m_callbacks)
|
|
+ callback->sendFailure("Page closed"_s);
|
|
+ }
|
|
+
|
|
+ void append(Ref<T>&& callback)
|
|
+ {
|
|
+ m_callbacks.append(WTFMove(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(Inspector::FrontendRouter*, Inspector::BackendDispatcher*)
|
|
+{
|
|
+ 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.characterAt(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;
|
|
+ WallTime timestamp = WallTime::now();
|
|
+
|
|
+ // cancel any active drag on Escape
|
|
+ if (eventType == WebEventType::KeyDown && key == "Escape"_s && m_page.cancelDragIfNeeded()) {
|
|
+ callback->sendSuccess();
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ m_keyboardCallbacks->append(WTFMove(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(WTFMove(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, WTFMove(modifiers), button, WTFMove(clickCount), eventButtons);
|
|
+#elif PLATFORM(GTK) || PLATFORM(WPE) || PLATFORM(WIN)
|
|
+ WallTime timestamp = WallTime::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::IntSize 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, WallTime::now()}, WTFMove(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(WTFMove(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));
|
|
+
|
|
+ WallTime timestamp = WallTime::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::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..26a2a3c0791c334f811ec99a630314f8e8521d02
|
|
--- /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_FAST_ALLOCATED;
|
|
+public:
|
|
+ WebPageInspectorInputAgent(Inspector::BackendDispatcher& backendDispatcher, WebPageProxy& page);
|
|
+ ~WebPageInspectorInputAgent() override;
|
|
+
|
|
+ void didProcessAllPendingKeyboardEvents();
|
|
+ void didProcessAllPendingMouseEvents();
|
|
+ void didProcessAllPendingWheelEvents();
|
|
+
|
|
+ void didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*) 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, WallTime 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 92eef3dd76340b6f1761c0bfbe6e7a0896f532f2..daae2e0dfdddf8d44b075b2ddc6c65861c1847e8 100644
|
|
--- a/Source/WebKit/UIProcess/WebPageProxy.cpp
|
|
+++ b/Source/WebKit/UIProcess/WebPageProxy.cpp
|
|
@@ -200,6 +200,7 @@
|
|
#include <WebCore/ArchiveError.h>
|
|
#include <WebCore/BitmapImage.h>
|
|
#include <WebCore/CaptureDeviceManager.h>
|
|
+#include <WebCore/Color.h>
|
|
#include <WebCore/CompositionHighlight.h>
|
|
#include <WebCore/CrossSiteNavigationDataTransfer.h>
|
|
#include <WebCore/DOMPasteAccess.h>
|
|
@@ -210,6 +211,7 @@
|
|
#include <WebCore/DigitalCredentialRequestOptions.h>
|
|
#include <WebCore/DigitalCredentialsRequestData.h>
|
|
#include <WebCore/DigitalCredentialsResponseData.h>
|
|
+#include <WebCore/DiagnosticLoggingResultType.h>
|
|
#include <WebCore/DragController.h>
|
|
#include <WebCore/DragData.h>
|
|
#include <WebCore/ElementContext.h>
|
|
@@ -233,6 +235,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>
|
|
@@ -240,10 +243,13 @@
|
|
#include <WebCore/PublicSuffixStore.h>
|
|
#include <WebCore/Quirks.h>
|
|
#include <WebCore/RealtimeMediaSourceCenter.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/SecurityOriginData.h>
|
|
#include <WebCore/SerializedCryptoKeyWrap.h>
|
|
#include <WebCore/SerializedScriptValue.h>
|
|
#include <WebCore/ShareData.h>
|
|
@@ -330,6 +336,9 @@
|
|
#if USE(GBM)
|
|
#include "AcceleratedBackingStoreDMABuf.h"
|
|
#endif
|
|
+#endif
|
|
+
|
|
+#if PLATFORM(GTK) || PLATFORM(WPE)
|
|
#include <WebCore/SelectionData.h>
|
|
#endif
|
|
|
|
@@ -455,6 +464,8 @@ static constexpr Seconds tryCloseTimeoutDelay = 50_ms;
|
|
static constexpr Seconds audibleActivityClearDelay = 10_s;
|
|
#endif
|
|
|
|
+using namespace WebCore;
|
|
+
|
|
DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, webPageProxyCounter, ("WebPageProxy"));
|
|
|
|
#if PLATFORM(COCOA)
|
|
@@ -966,6 +977,10 @@ WebPageProxy::~WebPageProxy()
|
|
#endif
|
|
|
|
internals().updatePlayingMediaDidChangeTimer.stop();
|
|
+
|
|
+#if PLATFORM(COCOA)
|
|
+ releaseInspectorDragPasteboard();
|
|
+#endif
|
|
}
|
|
|
|
Ref<WebPageProxy> WebPageProxy::Internals::protectedPage() const
|
|
@@ -1548,7 +1563,7 @@ void WebPageProxy::didAttachToRunningProcess()
|
|
|
|
#if ENABLE(FULLSCREEN_API)
|
|
ASSERT(!m_fullScreenManager);
|
|
- m_fullScreenManager = WebFullScreenManagerProxy::create(*this, protectedPageClient()->fullScreenManagerProxyClient());
|
|
+ m_fullScreenManager = WebFullScreenManagerProxy::create(*this, m_fullScreenManagerClientOverride ? *m_fullScreenManagerClientOverride : protectedPageClient()->fullScreenManagerProxyClient());
|
|
#endif
|
|
#if ENABLE(VIDEO_PRESENTATION_MODE)
|
|
ASSERT(!m_playbackSessionManager);
|
|
@@ -1714,6 +1729,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, *m_drawingArea, m_mainFrame->frameID(), std::nullopt)), 0);
|
|
+ m_inspectorController->didInitializeWebPage();
|
|
|
|
#if ENABLE(WINDOW_PROXY_PROPERTY_ACCESS_NOTIFICATION)
|
|
internals().frameLoadStateObserver = makeUniqueWithoutRefCountedCheck<WebPageProxyFrameLoadStateObserver>(*this);
|
|
@@ -2006,6 +2022,21 @@ Ref<WebProcessProxy> WebPageProxy::ensureProtectedRunningProcess()
|
|
return ensureRunningProcess();
|
|
}
|
|
|
|
+RefPtr<API::Navigation> WebPageProxy::loadRequestForInspector(WebCore::ResourceRequest&& request, WebFrameProxy* frame)
|
|
+{
|
|
+ if (!frame || frame == mainFrame())
|
|
+ return loadRequest(WTFMove(request), WebCore::ShouldOpenExternalURLsPolicy::ShouldNotAllow);
|
|
+
|
|
+ auto navigation = m_navigationState->createLoadRequestNavigation(legacyMainFrameProcess().coreProcessIdentifier(), ResourceRequest(request), m_backForwardList->currentItem());
|
|
+ LoadParameters loadParameters;
|
|
+ loadParameters.navigationID = navigation->navigationID();
|
|
+ loadParameters.request = WTFMove(request);
|
|
+ loadParameters.shouldOpenExternalURLsPolicy = WebCore::ShouldOpenExternalURLsPolicy::ShouldNotAllow;
|
|
+ loadParameters.shouldTreatAsContinuingLoad = ShouldTreatAsContinuingLoad::No;
|
|
+ m_legacyMainFrameProcess->send(Messages::WebPage::LoadRequestInFrameForInspector(WTFMove(loadParameters), frame->frameID()), m_webPageID);
|
|
+ return navigation;
|
|
+}
|
|
+
|
|
RefPtr<API::Navigation> WebPageProxy::loadRequest(WebCore::ResourceRequest&& request, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy, IsPerformingHTTPFallback isPerformingHTTPFallback, std::unique_ptr<NavigationActionData>&& lastNavigationAction, API::Object* userData)
|
|
{
|
|
if (m_isClosed)
|
|
@@ -2062,8 +2093,8 @@ void WebPageProxy::loadRequestWithNavigationShared(Ref<WebProcessProxy>&& proces
|
|
|
|
auto url = request.url();
|
|
#if PLATFORM(COCOA)
|
|
- bool urlIsInvalidButNotNull = !url.isValid() && !url.isNull();
|
|
- if (urlIsInvalidButNotNull && WTF::linkedOnOrAfterSDKWithBehavior(SDKAlignedBehavior::ConvertsInvalidURLsToNull)) {
|
|
+ bool urlIsInvalidButNotEmpty = !url.isValid() && !url.isEmpty();
|
|
+ if (urlIsInvalidButNotEmpty && WTF::linkedOnOrAfterSDKWithBehavior(SDKAlignedBehavior::ConvertsInvalidURLsToNull)) {
|
|
RunLoop::protectedMain()->dispatch([weakThis = WeakPtr { *this }, request, navigation = Ref { navigation }] {
|
|
RefPtr protectedThis = weakThis.get();
|
|
if (!protectedThis)
|
|
@@ -2116,11 +2147,29 @@ void WebPageProxy::loadRequestWithNavigationShared(Ref<WebProcessProxy>&& proces
|
|
|
|
navigation->setIsLoadedWithNavigationShared(true);
|
|
protectedProcess->markProcessAsRecentlyUsed();
|
|
- if (!protectedProcess->isLaunching() || !url.protocolIsFile())
|
|
- protectedProcess->send(Messages::WebPage::LoadRequest(WTFMove(loadParameters)), webPageID);
|
|
+
|
|
+ // Pause loading for new window navigation.
|
|
+ Function<void()> continuation = [
|
|
+ weakThis = WeakPtr { protectedThis },
|
|
+ weakProcess = WeakPtr { protectedProcess },
|
|
+ loadParameters = WTFMove(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(WTFMove(loadParameters)), webPageID);
|
|
+ else
|
|
+ innerProtectedProcess->send(Messages::WebPage::LoadRequestWaitingForProcessLaunch(WTFMove(loadParameters), innerProtectedThis->internals().pageLoadState.resourceDirectoryURL(), innerProtectedThis->identifier(), true), webPageID);
|
|
+ innerProtectedProcess->startResponsivenessTimer();
|
|
+ };
|
|
+ if (protectedThis->m_inspectorController->shouldPauseLoadRequest())
|
|
+ protectedThis->m_inspectorController->setContinueLoadingCallback(WTFMove(continuation));
|
|
else
|
|
- protectedProcess->send(Messages::WebPage::LoadRequestWaitingForProcessLaunch(WTFMove(loadParameters), protectedThis->pageLoadState().resourceDirectoryURL(), protectedThis->identifier(), true), webPageID);
|
|
- protectedProcess->startResponsivenessTimer();
|
|
+ continuation();
|
|
});
|
|
}
|
|
|
|
@@ -2671,6 +2720,61 @@ void WebPageProxy::setControlledByAutomation(bool controlled)
|
|
protectedWebsiteDataStore()->protectedNetworkProcess()->send(Messages::NetworkProcess::SetSessionIsControlledByAutomation(m_websiteDataStore->sessionID(), m_controlledByAutomation), 0);
|
|
}
|
|
|
|
+void WebPageProxy::setAuthCredentialsForAutomation(std::optional<WebCore::Credential>&& credentials, std::optional<URL>&& origin)
|
|
+{
|
|
+ m_credentialsForAutomation = WTFMove(credentials);
|
|
+ m_authOriginForAutomation = WTFMove(origin);
|
|
+}
|
|
+
|
|
+void WebPageProxy::setPermissionsForAutomation(const UncheckedKeyHashMap<String, HashSet<String>>& permissions)
|
|
+{
|
|
+ m_permissionsForAutomation = permissions;
|
|
+}
|
|
+
|
|
+static inline 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;
|
|
+}
|
|
+
|
|
+void WebPageProxy::setOrientationOverride(std::optional<int>&& angle)
|
|
+{
|
|
+ auto deviceOrientation = toScreenOrientationType(angle.value_or(0));
|
|
+ if (m_screenOrientationManager)
|
|
+ m_screenOrientationManager->setCurrentOrientation(deviceOrientation);
|
|
+ m_legacyMainFrameProcess->send(Messages::WebPage::SetDeviceOrientation(angle.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)
|
|
+{
|
|
+ fprintf(stderr, "RENDERER: %s\n", str.utf8().data());
|
|
+}
|
|
+
|
|
void WebPageProxy::createInspectorTarget(IPC::Connection& connection, const String& targetId, Inspector::InspectorTargetType type)
|
|
{
|
|
MESSAGE_CHECK_BASE(!targetId.isEmpty(), connection);
|
|
@@ -2924,6 +3028,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())
|
|
@@ -3706,7 +3828,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())
|
|
protectedLegacyMainFrameProcess()->assumeReadAccessToBaseURL(*this, url.string(), [] { });
|
|
@@ -3734,6 +3856,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;
|
|
@@ -3745,7 +3869,7 @@ void WebPageProxy::performDragControllerAction(DragControllerAction action, Drag
|
|
dragData.setClientPosition(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()), WTFMove(completionHandler));
|
|
#else
|
|
@@ -3780,14 +3904,35 @@ 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)
|
|
+#if PLATFORM(GTK) || PLATFORM(WPE)
|
|
void WebPageProxy::startDrag(SelectionData&& selectionData, OptionSet<WebCore::DragOperation> dragOperationMask, std::optional<ShareableBitmap::Handle>&& dragImageHandle, IntPoint&& dragImageHotspot)
|
|
{
|
|
- if (RefPtr pageClient = this->pageClient()) {
|
|
- RefPtr dragImage = dragImageHandle ? ShareableBitmap::create(WTFMove(*dragImageHandle)) : nullptr;
|
|
- pageClient->startDrag(WTFMove(selectionData), dragOperationMask, WTFMove(dragImage), WTFMove(dragImageHotspot));
|
|
+ if (m_interceptDrags) {
|
|
+ m_dragSelectionData = WTFMove(selectionData);
|
|
+ m_dragSourceOperationMask = dragOperationMask;
|
|
+ } else {
|
|
+#if PLATFORM(GTK)
|
|
+ if (RefPtr pageClient = this->pageClient()) {
|
|
+ RefPtr dragImage = dragImageHandle ? ShareableBitmap::create(WTFMove(*dragImageHandle)) : nullptr;
|
|
+ pageClient->startDrag(WTFMove(selectionData), dragOperationMask, WTFMove(dragImage), WTFMove(dragImageHotspot));
|
|
+ }
|
|
+#endif
|
|
+ }
|
|
+ didStartDrag();
|
|
+}
|
|
+#endif
|
|
+
|
|
+#if PLATFORM(WIN) && ENABLE(DRAG_SUPPORT)
|
|
+void WebPageProxy::startDrag(WebCore::DragDataMap&& dragDataMap)
|
|
+{
|
|
+ if (m_interceptDrags) {
|
|
+ m_dragSelectionData = WTFMove(dragDataMap);
|
|
+ m_dragSourceOperationMask = WebCore::anyDragOperation();
|
|
}
|
|
didStartDrag();
|
|
}
|
|
@@ -3809,6 +3954,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()
|
|
{
|
|
if (!hasRunningProcess())
|
|
@@ -3816,6 +3979,26 @@ void WebPageProxy::didStartDrag()
|
|
|
|
discardQueuedMouseEvents();
|
|
send(Messages::WebPage::DidStartDrag());
|
|
+
|
|
+ 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()
|
|
@@ -3981,26 +4164,47 @@ void WebPageProxy::processNextQueuedMouseEvent()
|
|
process->startResponsivenessTimer();
|
|
}
|
|
|
|
- std::optional<Vector<SandboxExtension::Handle>> sandboxExtensions;
|
|
+ m_lastMousePositionForDrag = 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(m_mainFrame->frameID(), eventWithCoalescedEvents, WTFMove(sandboxExtensions));
|
|
+ sendMouseEvent(m_mainFrame->frameID(), eventWithCoalescedEvents, WTFMove(sandboxExtensions));
|
|
|
|
- internals().coalescedMouseEvents.clear();
|
|
+ internals().coalescedMouseEvents.clear();
|
|
+ } else {
|
|
+#if PLATFORM(WIN) || PLATFORM(COCOA)
|
|
+ DragData dragData(*m_dragSelectionData, event.position(), event.globalPosition(), m_dragSourceOperationMask);
|
|
+#else
|
|
+ DragData dragData(&*m_dragSelectionData, event.position(), 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, WTFMove(sandboxExtensionHandle), WTFMove(sandboxExtensionsForUpload));
|
|
+ }
|
|
+ m_dragSelectionData = std::nullopt;
|
|
+ dragEnded(event.position(), event.globalPosition(), m_dragSourceOperationMask);
|
|
+ }
|
|
+ didReceiveEvent(eventType, true, std::nullopt);
|
|
+ }
|
|
}
|
|
|
|
void WebPageProxy::doAfterProcessingAllPendingMouseEvents(WTF::Function<void ()>&& action)
|
|
@@ -4197,6 +4401,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)
|
|
@@ -4332,7 +4538,7 @@ static TrackingType mergeTrackingTypes(TrackingType a, TrackingType b)
|
|
|
|
void WebPageProxy::updateTouchEventTracking(const WebTouchEvent& touchStartEvent)
|
|
{
|
|
-#if ENABLE(ASYNC_SCROLLING) && PLATFORM(COCOA)
|
|
+#if ENABLE(ASYNC_SCROLLING) && PLATFORM(IOS_FAMILY)
|
|
for (auto& touchPoint : touchStartEvent.touchPoints()) {
|
|
auto location = touchPoint.locationInRootView();
|
|
auto update = [this, location](TrackingType& trackingType, EventTrackingRegions::EventType eventType) {
|
|
@@ -4971,6 +5177,7 @@ void WebPageProxy::receivedNavigationActionPolicyDecision(WebProcessProxy& proce
|
|
|
|
void WebPageProxy::receivedPolicyDecision(PolicyAction action, API::Navigation* navigation, RefPtr<API::WebsitePolicies>&& websitePolicies, 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 { });
|
|
|
|
@@ -5967,6 +6174,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())
|
|
@@ -6609,6 +6817,7 @@ void WebPageProxy::didDestroyNavigationShared(Ref<WebProcessProxy>&& process, We
|
|
RefPtr protectedPageClient { pageClient() };
|
|
|
|
protectedNavigationState()->didDestroyNavigation(process->coreProcessIdentifier(), navigationID);
|
|
+ m_inspectorController->didDestroyNavigation(navigationID);
|
|
}
|
|
|
|
void WebPageProxy::didStartProvisionalLoadForFrame(FrameIdentifier frameID, FrameInfoData&& frameInfo, ResourceRequest&& request, std::optional<WebCore::NavigationIdentifier> navigationID, URL&& url, URL&& unreachableURL, const UserData& userData, WallTime timestamp)
|
|
@@ -6947,6 +7156,8 @@ void WebPageProxy::didFailProvisionalLoadForFrameShared(Ref<WebProcessProxy>&& p
|
|
|
|
m_failingProvisionalLoadURL = { };
|
|
|
|
+ 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;
|
|
@@ -8395,8 +8606,9 @@ void WebPageProxy::createNewPage(IPC::Connection& connection, WindowFeatures&& w
|
|
if (RefPtr page = originatingFrameInfo->page())
|
|
openerAppInitiatedState = page->lastNavigationWasAppInitiated();
|
|
|
|
- auto navigationDataForNewProcess = navigationActionData.hasOpener ? nullptr : makeUnique<NavigationActionData>(navigationActionData);
|
|
+ m_inspectorController->willCreateNewPage(windowFeatures, request.url());
|
|
|
|
+ auto navigationDataForNewProcess = navigationActionData.hasOpener ? nullptr : makeUnique<NavigationActionData>(navigationActionData);
|
|
auto completionHandler = [
|
|
this,
|
|
protectedThis = Ref { *this },
|
|
@@ -8469,6 +8681,7 @@ void WebPageProxy::createNewPage(IPC::Connection& connection, WindowFeatures&& w
|
|
configuration->setOpenedMainFrameName(openedMainFrameName);
|
|
if (!protectedPreferences()->siteIsolationEnabled())
|
|
configuration->setRelatedPage(*this);
|
|
+ configuration->setOpenerPageForInspector(*this);
|
|
|
|
if (RefPtr openerFrame = WebFrameProxy::webFrame(originatingFrameInfoData.frameID); navigationActionData.hasOpener && openerFrame) {
|
|
configuration->setOpenerInfo({ {
|
|
@@ -8491,6 +8704,7 @@ void WebPageProxy::createNewPage(IPC::Connection& connection, WindowFeatures&& w
|
|
void WebPageProxy::showPage()
|
|
{
|
|
m_uiClient->showPage(this);
|
|
+ m_inspectorController->didShowPage();
|
|
}
|
|
|
|
bool WebPageProxy::hasOpenedPage() const
|
|
@@ -8622,6 +8836,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();
|
|
@@ -8660,6 +8878,8 @@ void WebPageProxy::runJavaScriptAlert(IPC::Connection& connection, FrameIdentifi
|
|
}
|
|
|
|
runModalJavaScriptDialog(WTFMove(frame), WTFMove(frameInfo), message, [reply = WTFMove(reply)](WebPageProxy& page, WebFrameProxy* frame, FrameInfoData&& frameInfo, const String& message, CompletionHandler<void()>&& completion) mutable {
|
|
+ if (page.m_inspectorDialogAgent)
|
|
+ page.m_inspectorDialogAgent->javascriptDialogOpening("alert"_s, message);
|
|
page.m_uiClient->runJavaScriptAlert(page, message, frame, WTFMove(frameInfo), [reply = WTFMove(reply), completion = WTFMove(completion)]() mutable {
|
|
reply();
|
|
completion();
|
|
@@ -8682,6 +8902,8 @@ void WebPageProxy::runJavaScriptConfirm(IPC::Connection& connection, FrameIdenti
|
|
if (RefPtr automationSession = configuration().processPool().automationSession())
|
|
automationSession->willShowJavaScriptDialog(*this);
|
|
}
|
|
+ if (m_inspectorDialogAgent)
|
|
+ m_inspectorDialogAgent->javascriptDialogOpening("confirm"_s, message);
|
|
|
|
runModalJavaScriptDialog(WTFMove(frame), WTFMove(frameInfo), message, [reply = WTFMove(reply)](WebPageProxy& page, WebFrameProxy* frame, FrameInfoData&& frameInfo, const String& message, CompletionHandler<void()>&& completion) mutable {
|
|
page.m_uiClient->runJavaScriptConfirm(page, message, frame, WTFMove(frameInfo), [reply = WTFMove(reply), completion = WTFMove(completion)](bool result) mutable {
|
|
@@ -8706,6 +8928,8 @@ void WebPageProxy::runJavaScriptPrompt(IPC::Connection& connection, FrameIdentif
|
|
if (RefPtr automationSession = configuration().processPool().automationSession())
|
|
automationSession->willShowJavaScriptDialog(*this);
|
|
}
|
|
+ if (m_inspectorDialogAgent)
|
|
+ m_inspectorDialogAgent->javascriptDialogOpening("prompt"_s, message, defaultValue);
|
|
|
|
runModalJavaScriptDialog(WTFMove(frame), WTFMove(frameInfo), message, [reply = WTFMove(reply), defaultValue](WebPageProxy& page, WebFrameProxy* frame, FrameInfoData&& frameInfo, const String& message, CompletionHandler<void()>&& completion) mutable {
|
|
page.m_uiClient->runJavaScriptPrompt(page, message, defaultValue, frame, WTFMove(frameInfo), [reply = WTFMove(reply), completion = WTFMove(completion)](auto& result) mutable {
|
|
@@ -8841,6 +9065,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.
|
|
protectedLegacyMainFrameProcess()->stopResponsivenessTimer();
|
|
@@ -9454,6 +9680,11 @@ void WebPageProxy::resourceLoadDidCompleteWithError(ResourceLoadInfo&& loadInfo,
|
|
}
|
|
|
|
#if ENABLE(FULLSCREEN_API)
|
|
+void WebPageProxy::setFullScreenManagerClientOverride(std::unique_ptr<WebFullScreenManagerProxyClient>&& client)
|
|
+{
|
|
+ m_fullScreenManagerClientOverride = WTFMove(client);
|
|
+}
|
|
+
|
|
WebFullScreenManagerProxy* WebPageProxy::fullScreenManager()
|
|
{
|
|
return m_fullScreenManager.get();
|
|
@@ -9576,6 +9807,17 @@ void WebPageProxy::requestDOMPasteAccess(DOMPasteAccessCategory pasteAccessCateg
|
|
}
|
|
}
|
|
|
|
+ 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;
|
|
+ }
|
|
+
|
|
protectedPageClient()->requestDOMPasteAccess(pasteAccessCategory, requiresInteraction, elementRect, originIdentifier, WTFMove(completionHandler));
|
|
}
|
|
|
|
@@ -10605,6 +10847,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();
|
|
}
|
|
}
|
|
|
|
@@ -10640,6 +10884,7 @@ void WebPageProxy::keyEventHandlingCompleted(std::optional<WebEventType> eventTy
|
|
if (!canProcessMoreKeyEvents) {
|
|
if (RefPtr automationSession = configuration().processPool().automationSession())
|
|
automationSession->keyboardEventsFlushedForPage(*this);
|
|
+ m_inspectorController->didProcessAllPendingKeyboardEvents();
|
|
}
|
|
}
|
|
|
|
@@ -11064,7 +11309,10 @@ void WebPageProxy::dispatchProcessDidTerminate(WebProcessProxy& process, Process
|
|
if (protectedPreferences()->siteIsolationEnabled())
|
|
protectedBrowsingContextGroup()->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
|
|
@@ -11719,6 +11967,8 @@ WebPageCreationParameters WebPageProxy::creationParameters(WebProcessProxy& proc
|
|
parameters.canUseCredentialStorage = m_canUseCredentialStorage;
|
|
|
|
parameters.httpsUpgradeEnabled = preferences->upgradeKnownHostsToHTTPSEnabled() ? m_configuration->httpsUpgradeEnabled() : false;
|
|
+
|
|
+ parameters.shouldPauseInInspectorWhenShown = m_inspectorController->shouldPauseInInspectorWhenShown();
|
|
|
|
#if ENABLE(APP_HIGHLIGHTS)
|
|
parameters.appHighlightsVisible = appHighlightsVisibility() ? HighlightVisibility::Visible : HighlightVisibility::Hidden;
|
|
@@ -11882,8 +12132,42 @@ 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 (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)
|
|
@@ -11979,6 +12263,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
|
|
@@ -12043,6 +12333,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;
|
|
}
|
|
@@ -12057,6 +12353,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 5eb0a3d277ecd9a0ea9c2e4f1223205bff9cb5a4..b770b73fb96af5dd106c8e66d02590c1650efbe6 100644
|
|
--- a/Source/WebKit/UIProcess/WebPageProxy.h
|
|
+++ b/Source/WebKit/UIProcess/WebPageProxy.h
|
|
@@ -26,6 +26,7 @@
|
|
#pragma once
|
|
|
|
#include "APIObject.h"
|
|
+#include "APIWebsitePolicies.h"
|
|
#include "MessageReceiver.h"
|
|
#include <WebCore/BoxExtents.h>
|
|
#include <WebCore/CryptoKeyData.h>
|
|
@@ -44,6 +45,20 @@
|
|
#include <wtf/ProcessID.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(DICTATION_ALTERNATIVES)
|
|
#include <WebCore/PlatformTextAlternatives.h>
|
|
@@ -128,6 +143,7 @@ class DragData;
|
|
class Exception;
|
|
class FloatPoint;
|
|
class FloatQuad;
|
|
+typedef UncheckedKeyHashMap<unsigned, Vector<String>> DragDataMap;
|
|
class FloatRect;
|
|
class FloatSize;
|
|
class FontAttributeChanges;
|
|
@@ -729,6 +745,8 @@ public:
|
|
void setControlledByAutomation(bool);
|
|
|
|
WebPageInspectorController& inspectorController() { return *m_inspectorController; }
|
|
+ InspectorDialogAgent* inspectorDialogAgent() { return m_inspectorDialogAgent; }
|
|
+ void setInspectorDialogAgent(InspectorDialogAgent * dialogAgent) { m_inspectorDialogAgent = dialogAgent; }
|
|
|
|
#if PLATFORM(IOS_FAMILY)
|
|
void showInspectorIndication();
|
|
@@ -763,6 +781,7 @@ public:
|
|
bool hasSleepDisabler() const;
|
|
|
|
#if ENABLE(FULLSCREEN_API)
|
|
+ void setFullScreenManagerClientOverride(std::unique_ptr<WebFullScreenManagerProxyClient>&&);
|
|
WebFullScreenManagerProxy* fullScreenManager();
|
|
void setFullScreenClientForTesting(std::unique_ptr<WebKit::WebFullScreenManagerProxyClient>&&);
|
|
|
|
@@ -853,6 +872,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);
|
|
void setDrawingArea(RefPtr<DrawingAreaProxy>&&);
|
|
|
|
@@ -884,6 +909,8 @@ public:
|
|
RefPtr<API::Navigation> loadRequest(WebCore::ResourceRequest&&, WebCore::ShouldOpenExternalURLsPolicy, WebCore::IsPerformingHTTPFallback);
|
|
RefPtr<API::Navigation> loadRequest(WebCore::ResourceRequest&&, WebCore::ShouldOpenExternalURLsPolicy, WebCore::IsPerformingHTTPFallback, std::unique_ptr<NavigationActionData>&&, API::Object* userData = nullptr);
|
|
|
|
+ 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);
|
|
@@ -972,6 +999,7 @@ public:
|
|
|
|
PageClient* pageClient() const;
|
|
RefPtr<PageClient> protectedPageClient() const;
|
|
+ bool hasPageClient() const { return !!m_pageClient; }
|
|
|
|
void setViewNeedsDisplay(const WebCore::Region&);
|
|
void requestScroll(const WebCore::FloatPoint& scrollPosition, const WebCore::IntPoint& scrollOrigin, WebCore::ScrollIsAnimated);
|
|
@@ -1609,14 +1637,20 @@ public:
|
|
void didStartDrag();
|
|
void dragCancelled();
|
|
void setDragCaretRect(const WebCore::IntRect&);
|
|
+ void setInterceptDrags(bool shouldIntercept);
|
|
+ bool cancelDragIfNeeded();
|
|
#if PLATFORM(COCOA)
|
|
void startDrag(const WebCore::DragItem&, WebCore::ShareableBitmapHandle&& dragImageHandle);
|
|
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)
|
|
+#if PLATFORM(GTK) || PLATFORM(WPE)
|
|
void startDrag(WebCore::SelectionData&&, OptionSet<WebCore::DragOperation>, std::optional<WebCore::ShareableBitmapHandle>&& dragImage, WebCore::IntPoint&& dragImageHotspot);
|
|
#endif
|
|
+#if PLATFORM(WIN)
|
|
+ void startDrag(WebCore::DragDataMap&& dragDataMap);
|
|
+#endif
|
|
#endif
|
|
|
|
void processDidBecomeUnresponsive();
|
|
@@ -1869,6 +1903,7 @@ public:
|
|
void setViewportSizeForCSSViewportUnits(const WebCore::FloatSize&);
|
|
WebCore::FloatSize viewportSizeForCSSViewportUnits() const;
|
|
|
|
+ bool shouldSendAutomationCredentialsForProtectionSpace(const WebProtectionSpace&);
|
|
void didReceiveAuthenticationChallengeProxy(Ref<AuthenticationChallengeProxy>&&, NegotiatedLegacyTLS);
|
|
void negotiatedLegacyTLS();
|
|
void didNegotiateModernTLS(const URL&);
|
|
@@ -1902,6 +1937,8 @@ public:
|
|
#if PLATFORM(COCOA) || PLATFORM(GTK)
|
|
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 wrapCryptoKey(Vector<uint8_t>&&, CompletionHandler<void(std::optional<Vector<uint8_t>>&&)>&&);
|
|
@@ -2901,6 +2938,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;
|
|
|
|
void didChangeContentSize(const WebCore::IntSize&);
|
|
void didChangeIntrinsicContentSize(const WebCore::IntSize&);
|
|
@@ -3424,8 +3462,10 @@ RefPtr<SpeechRecognitionPermissionManager> protectedSpeechRecognitionPermissionM
|
|
String m_openedMainFrameName;
|
|
|
|
RefPtr<WebInspectorUIProxy> m_inspector;
|
|
+ InspectorDialogAgent* m_inspectorDialogAgent { nullptr };
|
|
|
|
#if ENABLE(FULLSCREEN_API)
|
|
+ std::unique_ptr<WebFullScreenManagerProxyClient> m_fullScreenManagerClientOverride;
|
|
RefPtr<WebFullScreenManagerProxy> m_fullScreenManager;
|
|
std::unique_ptr<API::FullscreenClient> m_fullscreenClient;
|
|
#endif
|
|
@@ -3622,6 +3662,22 @@ RefPtr<SpeechRecognitionPermissionManager> protectedSpeechRecognitionPermissionM
|
|
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 };
|
|
@@ -3795,6 +3851,10 @@ RefPtr<SpeechRecognitionPermissionManager> protectedSpeechRecognitionPermissionM
|
|
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<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 d1b9a0bec55cf3c64792b6c0c527c973a6ef3cdd..4b132c98aabe3dffef13b01e6251bdb7305ce200 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, WebKit::UserData userData)
|
|
+ LogToStderr(String text)
|
|
|
|
DidReceiveEvent(enum:uint8_t WebKit::WebEventType eventType, bool handled, struct std::optional<WebCore::RemoteUserInputEventData> remoteUserInputEventData)
|
|
SetCursor(WebCore::Cursor cursor)
|
|
@@ -336,10 +337,14 @@ messages -> WebPageProxy {
|
|
StartDrag(struct WebCore::DragItem dragItem, WebCore::ShareableBitmapHandle dragImage)
|
|
SetPromisedDataForImage(String pasteboardName, WebCore::SharedMemory::Handle imageHandle, String filename, String extension, String title, String url, String visibleURL, WebCore::SharedMemory::Handle archiveHandle, String originIdentifier)
|
|
#endif
|
|
-#if PLATFORM(GTK) && ENABLE(DRAG_SUPPORT)
|
|
+#if (PLATFORM(GTK) || PLATFORM(WPE)) && ENABLE(DRAG_SUPPORT)
|
|
StartDrag(WebCore::SelectionData selectionData, OptionSet<WebCore::DragOperation> dragOperationMask, std::optional<WebCore::ShareableBitmapHandle> dragImage, WebCore::IntPoint dragImageHotspot)
|
|
#endif
|
|
|
|
+#if PLATFORM(WIN) && ENABLE(DRAG_SUPPORT)
|
|
+ StartDrag(UncheckedKeyHashMap<unsigned, Vector<String>> dragDataMap)
|
|
+#endif
|
|
+
|
|
#if PLATFORM(IOS_FAMILY) && ENABLE(DRAG_SUPPORT)
|
|
DidHandleDragStartRequest(bool started)
|
|
DidHandleAdditionalDragItemsRequest(bool added)
|
|
diff --git a/Source/WebKit/UIProcess/WebProcessCache.cpp b/Source/WebKit/UIProcess/WebProcessCache.cpp
|
|
index 9153b4da4d4f8de14f27e9ee2e8c89059e9573f5..035009bdcf5651aedd9604e47dc02fbfcccc62a9 100644
|
|
--- a/Source/WebKit/UIProcess/WebProcessCache.cpp
|
|
+++ b/Source/WebKit/UIProcess/WebProcessCache.cpp
|
|
@@ -100,6 +100,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 c035cc55b3810bef6d30b753ee325905d8fbc6ab..d129f7ebbf7a9a5e97e09fd7ce6e58040a960abc 100644
|
|
--- a/Source/WebKit/UIProcess/WebProcessPool.cpp
|
|
+++ b/Source/WebKit/UIProcess/WebProcessPool.cpp
|
|
@@ -445,10 +445,10 @@ void WebProcessPool::setAutomationClient(std::unique_ptr<API::AutomationClient>&
|
|
|
|
void WebProcessPool::setOverrideLanguages(Vector<String>&& languages)
|
|
{
|
|
- WebKit::setOverrideLanguages(WTFMove(languages));
|
|
+ m_configuration->setOverrideLanguages(WTFMove(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())
|
|
@@ -456,9 +456,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)
|
|
{
|
|
@@ -947,7 +948,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.urlSchemesRegisteredAsEmptyDocument = copyToVector(m_schemesToRegisterAsEmptyDocument);
|
|
diff --git a/Source/WebKit/UIProcess/WebProcessProxy.cpp b/Source/WebKit/UIProcess/WebProcessProxy.cpp
|
|
index 1ac3aeb44691040950f6992d77e6489d9c58744f..3b4ebb055f9d9e7b3c64bfbf830239a7d1baf770 100644
|
|
--- a/Source/WebKit/UIProcess/WebProcessProxy.cpp
|
|
+++ b/Source/WebKit/UIProcess/WebProcessProxy.cpp
|
|
@@ -201,6 +201,11 @@ Vector<Ref<WebProcessProxy>> WebProcessProxy::allProcesses()
|
|
});
|
|
}
|
|
|
|
+Vector<Ref<WebProcessProxy>> WebProcessProxy::allProcessesForInspector()
|
|
+{
|
|
+ return copyToVector(allProcesses());
|
|
+}
|
|
+
|
|
RefPtr<WebProcessProxy> WebProcessProxy::processForIdentifier(ProcessIdentifier identifier)
|
|
{
|
|
return allProcessMap().get(identifier);
|
|
@@ -568,6 +573,26 @@ void WebProcessProxy::getLaunchOptions(ProcessLauncher::LaunchOptions& launchOpt
|
|
if (WebKit::isInspectorProcessPool(protectedProcessPool()))
|
|
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 b82965d62515b10373be40b28e4ba567821d5994..e05268412a251474c64fc4b3bafa25363bc87057 100644
|
|
--- a/Source/WebKit/UIProcess/WebProcessProxy.h
|
|
+++ b/Source/WebKit/UIProcess/WebProcessProxy.h
|
|
@@ -184,6 +184,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 7b9780cb47d824cc47054333aad47754d6a0725c..34bb946afd3de5354e5a3759506537d2dd1af586 100644
|
|
--- a/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp
|
|
+++ b/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp
|
|
@@ -314,7 +314,8 @@ SOAuthorizationCoordinator& WebsiteDataStore::soAuthorizationCoordinator(const W
|
|
|
|
static Ref<NetworkProcessProxy> networkProcessForSession(PAL::SessionID sessionID)
|
|
{
|
|
-#if ((PLATFORM(GTK) || PLATFORM(WPE)) && !ENABLE(2022_GLIB_API))
|
|
+// Playwright wants to isolate per BrowserContext.
|
|
+#if ((PLATFORM(GTK) || PLATFORM(WPE)))
|
|
if (sessionID.isEphemeral()) {
|
|
// Reuse a previous persistent session network process for ephemeral sessions.
|
|
for (auto& dataStore : allDataStores().values()) {
|
|
@@ -2507,6 +2508,12 @@ void WebsiteDataStore::originDirectoryForTesting(WebCore::ClientOrigin&& origin,
|
|
protectedNetworkProcess()->websiteDataOriginDirectoryForTesting(m_sessionID, WTFMove(origin), type, WTFMove(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 0439774485211a729ccd8b0c041c41547ea28625..e09aff8b56357687de4a417b1bdd644907bb8c23 100644
|
|
--- a/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h
|
|
+++ b/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h
|
|
@@ -98,6 +98,7 @@ class DeviceIdHashSaltStorage;
|
|
class DownloadProxy;
|
|
class NetworkProcessProxy;
|
|
class SOAuthorizationCoordinator;
|
|
+class DownloadProxy;
|
|
class VirtualAuthenticatorManager;
|
|
class WebPageProxy;
|
|
class WebProcessPool;
|
|
@@ -113,6 +114,7 @@ enum class UnifiedOriginStorageLevel : uint8_t;
|
|
enum class WebsiteDataFetchOption : uint8_t;
|
|
enum class WebsiteDataType : uint32_t;
|
|
|
|
+struct FrameInfoData;
|
|
struct ITPThirdPartyData;
|
|
struct NetworkProcessConnectionInfo;
|
|
struct WebPushMessage;
|
|
@@ -122,6 +124,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 Ref<WebsiteDataStore> defaultDataStore();
|
|
@@ -319,11 +329,13 @@ public:
|
|
const WebCore::CurlProxySettings& networkProxySettings() const { return m_proxySettings; }
|
|
#endif
|
|
|
|
-#if USE(SOUP)
|
|
+#if USE(SOUP) || PLATFORM(COCOA) || PLATFORM(WIN)
|
|
void setPersistentCredentialStorageEnabled(bool);
|
|
bool persistentCredentialStorageEnabled() const { return m_persistentCredentialStorageEnabled && isPersistent(); }
|
|
void setIgnoreTLSErrors(bool);
|
|
bool ignoreTLSErrors() const { return m_ignoreTLSErrors; }
|
|
+#endif
|
|
+#if USE(SOUP)
|
|
void setNetworkProxySettings(WebCore::SoupNetworkProxySettings&&);
|
|
const WebCore::SoupNetworkProxySettings& networkProxySettings() const { return m_networkProxySettings; }
|
|
void setCookiePersistentStorage(const String&, SoupCookiePersistentStorageType);
|
|
@@ -420,6 +432,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)
|
|
@@ -614,9 +632,11 @@ private:
|
|
WebCore::CurlProxySettings m_proxySettings;
|
|
#endif
|
|
|
|
-#if USE(SOUP)
|
|
+#if USE(SOUP) || PLATFORM(COCOA) || PLATFORM(WIN)
|
|
bool m_persistentCredentialStorageEnabled { true };
|
|
bool m_ignoreTLSErrors { true };
|
|
+#endif
|
|
+#if USE(SOUP)
|
|
WebCore::SoupNetworkProxySettings m_networkProxySettings;
|
|
String m_cookiePersistentStoragePath;
|
|
SoupCookiePersistentStorageType m_cookiePersistentStorageType { SoupCookiePersistentStorageType::SQLite };
|
|
@@ -643,6 +663,10 @@ private:
|
|
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)
|
|
std::unique_ptr<SOAuthorizationCoordinator> m_soAuthorizationCoordinator;
|
|
#endif
|
|
diff --git a/Source/WebKit/UIProcess/geoclue/GeoclueGeolocationProvider.cpp b/Source/WebKit/UIProcess/geoclue/GeoclueGeolocationProvider.cpp
|
|
index ac64c2a3cb5d1e8e46ba1835623a5c12825e3ea1..6ad7a5adc5198ae035c5cb815b6db8f033910f3a 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/InspectorPlaywrightAgentClientGLib.cpp b/Source/WebKit/UIProcess/glib/InspectorPlaywrightAgentClientGLib.cpp
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..ac01ad1653b22a0f22c45a196659e68fc22d7f32
|
|
--- /dev/null
|
|
+++ b/Source/WebKit/UIProcess/glib/InspectorPlaywrightAgentClientGLib.cpp
|
|
@@ -0,0 +1,201 @@
|
|
+/*
|
|
+ * 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"
|
|
+#if USE(CAIRO)
|
|
+#include <WebCore/ImageBufferUtilitiesCairo.h>
|
|
+#endif
|
|
+#if USE(SKIA)
|
|
+#include <WebCore/ImageBufferUtilitiesSkia.h>
|
|
+#endif
|
|
+#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(WTFMove(cstr));
|
|
+ }
|
|
+ }
|
|
+ ignoreHosts.append(nullptr);
|
|
+ return parseRawProxySettings(proxyServer, ignoreHosts.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)
|
|
+{
|
|
+#if !ENABLE(2022_GLIB_API)
|
|
+ GRefPtr<WebKitWebsiteDataManager> data_manager = adoptGRef(webkit_website_data_manager_new_ephemeral());
|
|
+#endif
|
|
+ GRefPtr<WebKitWebContext> context = adoptGRef(WEBKIT_WEB_CONTEXT(g_object_new(WEBKIT_TYPE_WEB_CONTEXT,
|
|
+#if !ENABLE(2022_GLIB_API)
|
|
+ "website-data-manager", data_manager.get(),
|
|
+#endif
|
|
+ // WPE has PSON enabled by default and doesn't have such parameter.
|
|
+#if PLATFORM(GTK)
|
|
+#if !ENABLE(2022_GLIB_API)
|
|
+ "process-swap-on-cross-site-navigation-enabled", true,
|
|
+#endif
|
|
+#endif
|
|
+ nullptr)));
|
|
+ if (!context) {
|
|
+ error = "Failed to create GLib ephemeral context"_s;
|
|
+ return nullptr;
|
|
+ }
|
|
+
|
|
+#if ENABLE(2022_GLIB_API)
|
|
+ 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());
|
|
+#endif
|
|
+
|
|
+ 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, WTFMove(context));
|
|
+
|
|
+ if (!proxyServer.isEmpty()) {
|
|
+ WebCore::SoupNetworkProxySettings contextProxySettings = parseProxySettings(proxyServer, proxyBypassList);
|
|
+ browserContext->dataStore->setNetworkProxySettings(WTFMove(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 = WTFMove(clip), nominalResolution, completionHandler = WTFMove(completionHandler)]() mutable {
|
|
+#if PLATFORM(GTK)
|
|
+ RefPtr<ViewSnapshot> viewSnapshot = protectedPage->pageClient()->takeViewSnapshot(WTFMove(clip), nominalResolution);
|
|
+ if (viewSnapshot) {
|
|
+ std::optional<String> data = WebAutomationSession::platformGetBase64EncodedPNGData(*viewSnapshot);
|
|
+ if (data) {
|
|
+ completionHandler(emptyString(), makeString("data:image/png;base64,"_s, *data));
|
|
+ return;
|
|
+ }
|
|
+ }
|
|
+#elif PLATFORM(WPE)
|
|
+#if USE(SKIA)
|
|
+ sk_sp<SkImage> protectPtr = protectedPage->pageClient()->takeViewSnapshot(WTFMove(clip), nominalResolution);
|
|
+ SkImage* surface = protectPtr.get();
|
|
+#elif USE(CAIRO)
|
|
+ cairo_surface_t* surface = nullptr;
|
|
+ RefPtr<cairo_surface_t> protectPtr = protectedPage->pageClient()->takeViewSnapshot(WTFMove(clip), nominalResolution);
|
|
+ surface = protectPtr.get();
|
|
+#endif
|
|
+ if (surface) {
|
|
+ Vector<uint8_t> encodeData = WebCore::encodeData(surface, "image/png"_s, std::nullopt);
|
|
+ completionHandler(emptyString(), makeString("data:image/png;base64,"_s, base64Encoded(encodeData)));
|
|
+ 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..441442d899e4088f5c24ae9f70c3e4ffa1e6d340
|
|
--- /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_MAKE_FAST_ALLOCATED;
|
|
+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/gtk/AcceleratedBackingStore.h b/Source/WebKit/UIProcess/gtk/AcceleratedBackingStore.h
|
|
index 5529f52048b24290f424e877cd9dbfb890e02ffb..c2b76b6188dd9596c4a1f31c137daff7d7644c7f 100644
|
|
--- a/Source/WebKit/UIProcess/gtk/AcceleratedBackingStore.h
|
|
+++ b/Source/WebKit/UIProcess/gtk/AcceleratedBackingStore.h
|
|
@@ -32,6 +32,7 @@
|
|
#include <wtf/WeakPtr.h>
|
|
|
|
typedef struct _cairo cairo_t;
|
|
+typedef struct _cairo_surface cairo_surface_t;
|
|
|
|
#if USE(GTK4)
|
|
typedef struct _GdkSnapshot GdkSnapshot;
|
|
@@ -62,6 +63,8 @@ public:
|
|
#else
|
|
virtual bool paint(cairo_t*, const WebCore::IntRect&) = 0;
|
|
#endif
|
|
+ virtual cairo_surface_t* surface() { return nullptr; }
|
|
+
|
|
virtual void realize() { };
|
|
virtual void unrealize() { };
|
|
virtual int renderHostFileDescriptor() { return -1; }
|
|
diff --git a/Source/WebKit/UIProcess/gtk/AcceleratedBackingStoreDMABuf.cpp b/Source/WebKit/UIProcess/gtk/AcceleratedBackingStoreDMABuf.cpp
|
|
index 461ce4fddb98edbf06be61d4b47f3256439f70a8..64b0c2e09a1ae8487bc8b2610f209a228a6988f6 100644
|
|
--- a/Source/WebKit/UIProcess/gtk/AcceleratedBackingStoreDMABuf.cpp
|
|
+++ b/Source/WebKit/UIProcess/gtk/AcceleratedBackingStoreDMABuf.cpp
|
|
@@ -812,4 +812,30 @@ RefPtr<WebCore::NativeImage> AcceleratedBackingStoreDMABuf::bufferAsNativeImageF
|
|
return m_committedBuffer->asNativeImageForTesting();
|
|
}
|
|
|
|
+// Playwright begin
|
|
+cairo_surface_t* AcceleratedBackingStoreDMABuf::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/AcceleratedBackingStoreDMABuf.h b/Source/WebKit/UIProcess/gtk/AcceleratedBackingStoreDMABuf.h
|
|
index aedb88b1031475a603b6d15eb4fc042153c9b8c1..e6aca4b0e577dd2c729d262ff9b3d4d8fb27ef23 100644
|
|
--- a/Source/WebKit/UIProcess/gtk/AcceleratedBackingStoreDMABuf.h
|
|
+++ b/Source/WebKit/UIProcess/gtk/AcceleratedBackingStoreDMABuf.h
|
|
@@ -98,6 +98,7 @@ private:
|
|
#else
|
|
bool paint(cairo_t*, const WebCore::IntRect&) override;
|
|
#endif
|
|
+ cairo_surface_t* surface() override;
|
|
void unrealize() override;
|
|
void update(const LayerTreeContext&) override;
|
|
RendererBufferFormat bufferFormat() const override;
|
|
@@ -253,6 +254,9 @@ private:
|
|
RefPtr<Buffer> m_committedBuffer;
|
|
WebCore::Region m_pendingDamageRegion;
|
|
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..bf78de1915940c2d3292514cf0fe4e682b636f70
|
|
--- /dev/null
|
|
+++ b/Source/WebKit/UIProcess/gtk/InspectorTargetProxyGtk.cpp
|
|
@@ -0,0 +1,48 @@
|
|
+/*
|
|
+ * 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 <WebCore/GtkUtilities.h>
|
|
+#include <gtk/gtk.h>
|
|
+
|
|
+namespace WebKit {
|
|
+
|
|
+void InspectorTargetProxy::platformActivate(String& error) const
|
|
+{
|
|
+#if USE(GTK4)
|
|
+ GtkWidget* parent = GTK_WIDGET(gtk_widget_get_root(m_page->viewWidget()));
|
|
+#else
|
|
+ GtkWidget* parent = gtk_widget_get_toplevel(m_page->viewWidget());
|
|
+#endif
|
|
+ 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/SystemSettingsManagerProxyGtk.cpp b/Source/WebKit/UIProcess/gtk/SystemSettingsManagerProxyGtk.cpp
|
|
index aa702b018d881739fb464246e7c7d7236adfe97b..f711e1608e6d8b988d2d0bc99893d5b0137a07ae 100644
|
|
--- a/Source/WebKit/UIProcess/gtk/SystemSettingsManagerProxyGtk.cpp
|
|
+++ b/Source/WebKit/UIProcess/gtk/SystemSettingsManagerProxyGtk.cpp
|
|
@@ -117,6 +117,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..7d9672b0f831b5b7f6acf14ede26e1e8e9a65389
|
|
--- /dev/null
|
|
+++ b/Source/WebKit/UIProcess/gtk/WebPageInspectorEmulationAgentGtk.cpp
|
|
@@ -0,0 +1,117 @@
|
|
+/*
|
|
+ * 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 <WebCore/IntSize.h>
|
|
+#include <gtk/gtk.h>
|
|
+
|
|
+namespace WebKit {
|
|
+
|
|
+#if USE(GTK4)
|
|
+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;
|
|
+}
|
|
+#endif
|
|
+
|
|
+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);
|
|
+#if USE(GTK4)
|
|
+ // 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 righ await to not stall.
|
|
+ if (!viewAllocation.width && !viewAllocation.height && windowHasManyTabs(viewWidget)) {
|
|
+ callback(String());
|
|
+ return;
|
|
+ }
|
|
+#endif
|
|
+ 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;
|
|
+ // The callback can only be called if the page is still alive, so we can safely capture `this`.
|
|
+ drawingArea->waitForSizeUpdate([this, callback = WTFMove(callback), didNotHaveInitialAllocation, viewSize](const DrawingAreaProxyCoordinatedGraphics& drawingArea) mutable {
|
|
+#if USE(GTK4)
|
|
+ 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(), WTFMove(callback));
|
|
+ return;
|
|
+ }
|
|
+ callback("Failed to resize window"_s);
|
|
+#else
|
|
+ UNUSED_PARAM(this);
|
|
+ UNUSED_PARAM(didNotHaveInitialAllocation);
|
|
+ UNUSED_PARAM(drawingArea);
|
|
+ callback(String());
|
|
+#endif
|
|
+ });
|
|
+ } else {
|
|
+ callback("No backing store for window"_s);
|
|
+ }
|
|
+#if USE(GTK4)
|
|
+ // 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);
|
|
+#else
|
|
+ gtk_window_resize(GTK_WINDOW(window), width, height);
|
|
+#endif
|
|
+}
|
|
+
|
|
+} // namespace WebKit
|
|
diff --git a/Source/WebKit/UIProcess/gtk/WebPageInspectorInputAgentGtk.cpp b/Source/WebKit/UIProcess/gtk/WebPageInspectorInputAgentGtk.cpp
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..36ab6e9aec9f8d79fb13a8a49beadaafb3da58f5
|
|
--- /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, WallTime timestamp)
|
|
+{
|
|
+ Vector<String> commands;
|
|
+ const guint keyVal = WebCore::PlatformKeyboardEvent::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,
|
|
+ WTFMove(commands));
|
|
+ m_page.handleKeyboardEvent(event);
|
|
+}
|
|
+
|
|
+} // namespace WebKit
|
|
diff --git a/Source/WebKit/UIProcess/gtk/WebPasteboardProxyGtk.cpp b/Source/WebKit/UIProcess/gtk/WebPasteboardProxyGtk.cpp
|
|
index cedf117035055756084863d1e8db8594e4a8b8d2..bae8c9d90d1f34324bbb98a52815af98d23e5257 100644
|
|
--- a/Source/WebKit/UIProcess/gtk/WebPasteboardProxyGtk.cpp
|
|
+++ b/Source/WebKit/UIProcess/gtk/WebPasteboardProxyGtk.cpp
|
|
@@ -78,8 +78,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/InspectorPlaywrightAgentClientMac.h b/Source/WebKit/UIProcess/mac/InspectorPlaywrightAgentClientMac.h
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..2aabc02a4b5432f68a6e85fd9689775608f05a67
|
|
--- /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_MAKE_FAST_ALLOCATED;
|
|
+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..a5c8b963636b24d4bb8ad090e4a19aedecbf56c3
|
|
--- /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/ImageBufferUtilitiesCG.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 WithBypassList:proxyBypassList] 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 = WTFMove(clipRect), completionHandler = WTFMove(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::dataURL(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 51744982af6f55f269d407cfb82638a4eaba8a5c..3cb319ef5fd54de9397f8065a8b05ca7ff82ccee 100644
|
|
--- a/Source/WebKit/UIProcess/mac/PageClientImplMac.h
|
|
+++ b/Source/WebKit/UIProcess/mac/PageClientImplMac.h
|
|
@@ -60,6 +60,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();
|
|
|
|
@@ -175,6 +177,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;
|
|
@@ -228,6 +233,10 @@ private:
|
|
void beganExitFullScreen(const WebCore::IntRect& initialFrame, const WebCore::IntRect& finalFrame, CompletionHandler<void()>&&) override;
|
|
#endif
|
|
|
|
+#if ENABLE(TOUCH_EVENTS)
|
|
+ void doneWithTouchEvent(const NativeWebTouchEvent&, 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 6f5fd6287d435161dd7a7269fccc32cada2aabd5..79f171aaba64bca6a6bc853edb5b77effbabf664 100644
|
|
--- a/Source/WebKit/UIProcess/mac/PageClientImplMac.mm
|
|
+++ b/Source/WebKit/UIProcess/mac/PageClientImplMac.mm
|
|
@@ -116,6 +116,13 @@ namespace WebKit {
|
|
|
|
using namespace WebCore;
|
|
|
|
+static bool _headless = false;
|
|
+
|
|
+// static
|
|
+void PageClientImpl::setHeadless(bool headless) {
|
|
+ _headless = headless;
|
|
+}
|
|
+
|
|
PageClientImpl::PageClientImpl(NSView *view, WKWebView *webView)
|
|
: PageClientImplCocoa(webView)
|
|
, m_view(view)
|
|
@@ -169,6 +176,9 @@ NSWindow *PageClientImpl::activeWindow() const
|
|
|
|
bool PageClientImpl::isViewWindowActive()
|
|
{
|
|
+ if (_headless)
|
|
+ return true;
|
|
+
|
|
ASSERT(hasProcessPrivilege(ProcessPrivilege::CanCommunicateWithWindowServer));
|
|
NSWindow *activeViewWindow = activeWindow();
|
|
return activeViewWindow.isKeyWindow || (activeViewWindow && [NSApp keyWindow] == activeViewWindow);
|
|
@@ -176,6 +186,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 (!m_impl)
|
|
@@ -199,6 +212,9 @@ void PageClientImpl::makeFirstResponder()
|
|
|
|
bool PageClientImpl::isViewVisible()
|
|
{
|
|
+ if (_headless)
|
|
+ return true;
|
|
+
|
|
NSView *activeView = this->activeView();
|
|
NSWindow *activeViewWindow = activeWindow();
|
|
|
|
@@ -282,7 +298,8 @@ void PageClientImpl::didRelaunchProcess()
|
|
|
|
void PageClientImpl::preferencesDidChange()
|
|
{
|
|
- m_impl->preferencesDidChange();
|
|
+ if (m_impl)
|
|
+ m_impl->preferencesDidChange();
|
|
}
|
|
|
|
void PageClientImpl::toolTipChanged(const String& oldToolTip, const String& newToolTip)
|
|
@@ -489,6 +506,8 @@ IntRect PageClientImpl::rootViewToAccessibilityScreen(const IntRect& rect)
|
|
|
|
void PageClientImpl::doneWithKeyEvent(const NativeWebKeyboardEvent& event, bool eventWasHandled)
|
|
{
|
|
+ if (!event.nativeEvent())
|
|
+ return;
|
|
m_impl->doneWithKeyEvent(event.nativeEvent(), eventWasHandled);
|
|
}
|
|
|
|
@@ -508,6 +527,8 @@ void PageClientImpl::computeHasVisualSearchResults(const URL& imageURL, Shareabl
|
|
|
|
RefPtr<WebPopupMenuProxy> PageClientImpl::createPopupMenuProxy(WebPageProxy& page)
|
|
{
|
|
+ if (_headless)
|
|
+ return nullptr;
|
|
return WebPopupMenuProxyMac::create(m_view, page.popupMenuClient());
|
|
}
|
|
|
|
@@ -643,6 +664,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 m_impl->takeViewSnapshot();
|
|
@@ -858,6 +885,13 @@ void PageClientImpl::beganExitFullScreen(const IntRect& initialFrame, const IntR
|
|
|
|
#endif // ENABLE(FULLSCREEN_API)
|
|
|
|
+#if ENABLE(TOUCH_EVENTS)
|
|
+void PageClientImpl::doneWithTouchEvent(const NativeWebTouchEvent& event, bool wasEventHandled)
|
|
+{
|
|
+ notImplemented();
|
|
+}
|
|
+#endif // ENABLE(TOUCH_EVENTS)
|
|
+
|
|
void PageClientImpl::navigationGestureDidBegin()
|
|
{
|
|
m_impl->dismissContentRelativeChildWindowsWithAnimation(true);
|
|
@@ -1036,6 +1070,9 @@ void PageClientImpl::requestScrollToRect(const WebCore::FloatRect& targetRect, c
|
|
|
|
bool PageClientImpl::windowIsFrontWindowUnderMouse(const NativeWebMouseEvent& event)
|
|
{
|
|
+ // Simulated event.
|
|
+ if (!event.nativeEvent())
|
|
+ return false;
|
|
return m_impl->windowIsFrontWindowUnderMouse(event.nativeEvent());
|
|
}
|
|
|
|
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/WebContextMenuProxyMac.h b/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.h
|
|
index 1904f5ddedb75ee74aa84154fb9af248646c2fa2..af987387cc6537c225dd80515560c840319157f2 100644
|
|
--- a/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.h
|
|
+++ b/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.h
|
|
@@ -81,6 +81,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 c962b29e655a421e3199505d2aa8546a83dbd583..85dc988495ba9b4eef48ee501afb5f854b687678 100644
|
|
--- a/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.mm
|
|
+++ b/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.mm
|
|
@@ -538,6 +538,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..dd52991f936aa1c046b404801ee97237d0a55748
|
|
--- /dev/null
|
|
+++ b/Source/WebKit/UIProcess/mac/WebPageInspectorInputAgentMac.mm
|
|
@@ -0,0 +1,135 @@
|
|
+/*
|
|
+ * 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 = NSEventTypeLeftMouseDragged;
|
|
+ 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;
|
|
+ }
|
|
+
|
|
+ NativeWebMouseEvent nativeEvent(event, nil, [window contentView]);
|
|
+ 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, WallTime 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, [] () { }))
|
|
+ m_page.websiteDataStore().protectedNetworkProcess()->connection().waitForAsyncReplyAndDispatchImmediately<Messages::NetworkProcess::AllowFilesAccessFromWebProcess>(*replyID, 100_ms);
|
|
+ NativeWebKeyboardEvent event(
|
|
+ type,
|
|
+ text,
|
|
+ unmodifiedText,
|
|
+ key,
|
|
+ code,
|
|
+ keyIdentifier,
|
|
+ windowsVirtualKeyCode,
|
|
+ nativeVirtualKeyCode,
|
|
+ isAutoRepeat,
|
|
+ isKeypad,
|
|
+ isSystemKey,
|
|
+ modifiers,
|
|
+ timestamp,
|
|
+ WTFMove(macCommands));
|
|
+ m_page.handleKeyboardEvent(event);
|
|
+}
|
|
+
|
|
+} // namespace WebKit
|
|
diff --git a/Source/WebKit/UIProcess/mac/WebViewImpl.h b/Source/WebKit/UIProcess/mac/WebViewImpl.h
|
|
index 13b4e79c748071d02fedd8bced9ef0304943c51d..5830a3a3145b103a041cd2ff6666f8eff7666e3b 100644
|
|
--- a/Source/WebKit/UIProcess/mac/WebViewImpl.h
|
|
+++ b/Source/WebKit/UIProcess/mac/WebViewImpl.h
|
|
@@ -566,6 +566,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 9fe23e004a89f08ca6583181b01a72b5025c1d93..3028a0946be2d5fe51d92fd1de5bc0668bbb55c8 100644
|
|
--- a/Source/WebKit/UIProcess/mac/WebViewImpl.mm
|
|
+++ b/Source/WebKit/UIProcess/mac/WebViewImpl.mm
|
|
@@ -2415,6 +2415,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] };
|
|
@@ -4587,6 +4592,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/win/InspectorPlaywrightAgentClientWin.cpp b/Source/WebKit/UIProcess/win/InspectorPlaywrightAgentClientWin.cpp
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..4f54a9445e5a7ecdb750c5c521da4f397776e633
|
|
--- /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(WTFMove(proxyURL), String(proxyBypassList));
|
|
+ browserContext->dataStore->setNetworkProxySettings(WTFMove(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..df18883b2b7d22d73540cb084d3dd5291231097d
|
|
--- /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_MAKE_FAST_ALLOCATED;
|
|
+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/WebContextMenuProxyWin.cpp b/Source/WebKit/UIProcess/win/WebContextMenuProxyWin.cpp
|
|
index bae35256ed815f7dac0b11ae439531d4ef3cb108..81e063b50a0132f8b36f3461f95d2ce1968198f5 100644
|
|
--- a/Source/WebKit/UIProcess/win/WebContextMenuProxyWin.cpp
|
|
+++ b/Source/WebKit/UIProcess/win/WebContextMenuProxyWin.cpp
|
|
@@ -115,5 +115,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 e7f71156d7a897ab477d0d7f167b2c2992cdb161..325d8813afff13d86a4892a8e99738f19c2729ac 100644
|
|
--- a/Source/WebKit/UIProcess/win/WebContextMenuProxyWin.h
|
|
+++ b/Source/WebKit/UIProcess/win/WebContextMenuProxyWin.h
|
|
@@ -49,6 +49,7 @@ public:
|
|
private:
|
|
WebContextMenuProxyWin(WebPageProxy&, FrameInfoData&&, ContextMenuContextData&&, const UserData&);
|
|
void showContextMenuWithItems(Vector<Ref<WebContextMenuItem>>&&) override;
|
|
+ void hide() override;
|
|
|
|
HMENU m_menu;
|
|
FrameInfoData m_frameInfo;
|
|
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..8b474c730139b44a13c9d5b2d13ee20403e3e7f3
|
|
--- /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, WallTime 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 5180da3ec22d56e8a9520e31cad076d86ae5be9f..f01be74573843e7b374c34035c09f114bdc7349c 100644
|
|
--- a/Source/WebKit/UIProcess/win/WebView.cpp
|
|
+++ b/Source/WebKit/UIProcess/win/WebView.cpp
|
|
@@ -576,7 +576,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/InspectorTargetProxyWPE.cpp b/Source/WebKit/UIProcess/wpe/InspectorTargetProxyWPE.cpp
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..24da079059ed4a45131e18d7fbf56a29a54bd513
|
|
--- /dev/null
|
|
+++ b/Source/WebKit/UIProcess/wpe/InspectorTargetProxyWPE.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 "InspectorTargetProxy.h"
|
|
+
|
|
+#include "WebPageProxy.h"
|
|
+#include <wpe/wpe.h>
|
|
+
|
|
+namespace WebKit {
|
|
+
|
|
+void InspectorTargetProxy::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..7df77e30c2e7303dc6aaad560434e5b8e35f4f3c
|
|
--- /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)
|
|
+{
|
|
+ return adoptRef(*new WebColorPickerWPE(page, initialColor, rect));
|
|
+}
|
|
+
|
|
+WebColorPickerWPE::WebColorPickerWPE(WebPageProxy& page, const Color& initialColor, const IntRect&)
|
|
+ : WebColorPicker(&page.colorPickerClient())
|
|
+{
|
|
+}
|
|
+
|
|
+WebColorPickerWPE::~WebColorPickerWPE()
|
|
+{
|
|
+ endPicker();
|
|
+}
|
|
+
|
|
+void WebColorPickerWPE::endPicker()
|
|
+{
|
|
+}
|
|
+
|
|
+void WebColorPickerWPE::showColorPicker(const Color& color)
|
|
+{
|
|
+}
|
|
+
|
|
+} // namespace WebKit
|
|
diff --git a/Source/WebKit/UIProcess/wpe/WebColorPickerWPE.h b/Source/WebKit/UIProcess/wpe/WebColorPickerWPE.h
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..da58334235809cfed62e90150784bf2506f7a8f2
|
|
--- /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&);
|
|
+ virtual ~WebColorPickerWPE();
|
|
+
|
|
+ void endPicker() override;
|
|
+ void showColorPicker(const WebCore::Color&) override;
|
|
+
|
|
+protected:
|
|
+ WebColorPickerWPE(WebPageProxy&, const WebCore::Color&, const WebCore::IntRect&);
|
|
+};
|
|
+
|
|
+} // 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..694eb24db4a407553da12fb0a25d8963fd0ef6ac
|
|
--- /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::show(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..5d4b0d204b7dc564564d2126e9f256fa4f4bd6f6
|
|
--- /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 show(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..182398f24909cbc42cac897d66546991f46c1d5d
|
|
--- /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 = WTFMove(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..a7d88f8c745f95af21db71dcfce368ba4832a328
|
|
--- /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, WallTime 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 53f900a15956048fd25f9b0d54d6b74580612abb..133eaf568fa054d93ebf3a41e8f78b02fb0a39f7 100644
|
|
--- a/Source/WebKit/WebKit.xcodeproj/project.pbxproj
|
|
+++ b/Source/WebKit/WebKit.xcodeproj/project.pbxproj
|
|
@@ -1542,6 +1542,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 */; };
|
|
@@ -2323,6 +2324,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 /* InspectorTargetProxyMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = D79902AF236E9404005D6F7E /* InspectorTargetProxyMac.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, ); }; };
|
|
@@ -2422,6 +2435,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 */; };
|
|
@@ -2447,6 +2462,9 @@
|
|
ED82A7F2128C6FAF004477B3 /* WKBundlePageOverlay.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A22F0FF1289FCD90085E74F /* WKBundlePageOverlay.h */; settings = {ATTRIBUTES = (Private, ); }; };
|
|
EEFE72792D64FE5600DC6214 /* StageModeInteractionState.h in Headers */ = {isa = PBXBuildFile; fileRef = EEFE72782D64FE5600DC6214 /* StageModeInteractionState.h */; };
|
|
F404455C2D5CFB56000E587E /* AppKitSoftLink.h in Headers */ = {isa = PBXBuildFile; fileRef = F404455A2D5CFB56000E587E /* AppKitSoftLink.h */; };
|
|
+ F303B849249A8D640031DE5C /* ScreencastEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = F303B848249A8D3A0031DE5C /* ScreencastEncoder.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, ); }; };
|
|
@@ -6307,6 +6325,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>"; };
|
|
@@ -8025,6 +8044,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 /* InspectorTargetProxyMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = InspectorTargetProxyMac.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>"; };
|
|
@@ -8198,6 +8230,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>"; };
|
|
EB0D312D275AE13300863D8F /* com.apple.webkit.webpushd.mac.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = com.apple.webkit.webpushd.mac.plist; sourceTree = "<group>"; };
|
|
EB0D312E275AE13300863D8F /* com.apple.webkit.webpushd.ios.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = com.apple.webkit.webpushd.ios.plist; sourceTree = "<group>"; };
|
|
@@ -8234,6 +8268,14 @@
|
|
F036978715F4BF0500C3A80E /* WebColorPicker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebColorPicker.cpp; sourceTree = "<group>"; };
|
|
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>"; };
|
|
+ F303B847249A8D3A0031DE5C /* ScreencastEncoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScreencastEncoder.cpp; sourceTree = "<group>"; };
|
|
+ F303B848249A8D3A0031DE5C /* ScreencastEncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScreencastEncoder.h; sourceTree = "<group>"; };
|
|
+ F31E2DA424C76E4B004B2775 /* WebMFileWriter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebMFileWriter.cpp; sourceTree = "<group>"; };
|
|
+ F31E2DA524C76E4C004B2775 /* WebMFileWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebMFileWriter.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>"; };
|
|
+ F3970344249BD4CE003E1A22 /* ScreencastEncoderMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ScreencastEncoderMac.mm; 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; name = WKDatePickerPopoverController.h; path = ios/forms/WKDatePickerPopoverController.h; sourceTree = "<group>"; };
|
|
F40C3B702AB40167007A3567 /* WKDatePickerPopoverController.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = WKDatePickerPopoverController.mm; path = ios/forms/WKDatePickerPopoverController.mm; sourceTree = "<group>"; };
|
|
@@ -8592,6 +8634,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 */,
|
|
@@ -11661,6 +11704,7 @@
|
|
99788ACA1F421DCA00C08000 /* _WKAutomationSessionConfiguration.mm */,
|
|
990D28A81C6404B000986977 /* _WKAutomationSessionDelegate.h */,
|
|
990D28AF1C65203900986977 /* _WKAutomationSessionInternal.h */,
|
|
+ D71A94492372290B002C4D9E /* _WKBrowserInspector.h */,
|
|
5C4609E222430E4C009943C2 /* _WKContentRuleListAction.h */,
|
|
5C4609E322430E4D009943C2 /* _WKContentRuleListAction.mm */,
|
|
5C4609E422430E4D009943C2 /* _WKContentRuleListActionInternal.h */,
|
|
@@ -13028,6 +13072,7 @@
|
|
E34B110C27C46BC6006D2F2E /* libWebCoreTestShim.dylib */,
|
|
E34B110F27C46D09006D2F2E /* libWebCoreTestSupport.dylib */,
|
|
DDE992F4278D06D900F60D26 /* libWebKitAdditions.a */,
|
|
+ F33C7AC6249AD79C0018BE41 /* libwebrtc.dylib */,
|
|
57A9FF15252C6AEF006A2040 /* libWTF.a */,
|
|
5750F32A2032D4E500389347 /* LocalAuthentication.framework */,
|
|
570DAAB0230273D200E8FC04 /* NearField.framework */,
|
|
@@ -13609,6 +13654,12 @@
|
|
children = (
|
|
9197940423DBC4BB00257892 /* InspectorBrowserAgent.cpp */,
|
|
9197940323DBC4BB00257892 /* InspectorBrowserAgent.h */,
|
|
+ F3867F0324607D2B008F0F31 /* InspectorScreencastAgent.cpp */,
|
|
+ F3867F0424607D2B008F0F31 /* InspectorScreencastAgent.h */,
|
|
+ F303B847249A8D3A0031DE5C /* ScreencastEncoder.cpp */,
|
|
+ F303B848249A8D3A0031DE5C /* ScreencastEncoder.h */,
|
|
+ F31E2DA424C76E4B004B2775 /* WebMFileWriter.cpp */,
|
|
+ F31E2DA524C76E4C004B2775 /* WebMFileWriter.h */,
|
|
);
|
|
path = Agents;
|
|
sourceTree = "<group>";
|
|
@@ -13617,6 +13668,7 @@
|
|
isa = PBXGroup;
|
|
children = (
|
|
A5D3504D1D78F0D2005124A9 /* RemoteWebInspectorUIProxyMac.mm */,
|
|
+ F3970344249BD4CE003E1A22 /* ScreencastEncoderMac.mm */,
|
|
1CA8B935127C774E00576C2B /* WebInspectorUIProxyMac.mm */,
|
|
99A7ACE326012919006D57FD /* WKInspectorResourceURLSchemeHandler.h */,
|
|
99A7ACE42601291A006D57FD /* WKInspectorResourceURLSchemeHandler.mm */,
|
|
@@ -14353,6 +14405,7 @@
|
|
E1513C65166EABB200149FCB /* AuxiliaryProcessProxy.h */,
|
|
46A2B6061E5675A200C3DEDA /* BackgroundProcessResponsivenessTimer.cpp */,
|
|
46A2B6071E5675A200C3DEDA /* BackgroundProcessResponsivenessTimer.h */,
|
|
+ D71A944B237239FB002C4D9E /* BrowserInspectorPipe.h */,
|
|
5C6D69352AC3935D0099BDAF /* BrowsingContextGroup.cpp */,
|
|
5C6D69362AC3935D0099BDAF /* BrowsingContextGroup.h */,
|
|
5CA98549210BEB5A0057EB6B /* BrowsingWarning.h */,
|
|
@@ -14377,6 +14430,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 */,
|
|
@@ -14410,6 +14465,7 @@
|
|
1A0C227D2451130A00ED614D /* QuickLookThumbnailingSoftLink.mm */,
|
|
1AEE57232409F142002005D6 /* QuickLookThumbnailLoader.h */,
|
|
1AEE57242409F142002005D6 /* QuickLookThumbnailLoader.mm */,
|
|
+ D71A94392370F060002C4D9E /* RemoteInspectorPipe.h */,
|
|
5CCB54DC2A4FEA6A0005FAA8 /* RemotePageDrawingAreaProxy.cpp */,
|
|
5CCB54DB2A4FEA6A0005FAA8 /* RemotePageDrawingAreaProxy.h */,
|
|
FABBBC802D35AC6800820017 /* RemotePageFullscreenManagerProxy.cpp */,
|
|
@@ -14512,6 +14568,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 */,
|
|
@@ -14690,6 +14748,7 @@
|
|
BC646C1911DD399F006455B0 /* WKBackForwardListItemRef.h */,
|
|
BC646C1611DD399F006455B0 /* WKBackForwardListRef.cpp */,
|
|
BC646C1711DD399F006455B0 /* WKBackForwardListRef.h */,
|
|
+ D71A942C2370DF81002C4D9E /* WKBrowserInspector.h */,
|
|
BCB9E24A1120E15C00A137E0 /* WKContext.cpp */,
|
|
BCB9E2491120E15C00A137E0 /* WKContext.h */,
|
|
1AE52F9319201F6B00A1FA37 /* WKContextConfigurationRef.cpp */,
|
|
@@ -15265,6 +15324,9 @@
|
|
07EF07592745A8160066EA04 /* DisplayCaptureSessionManager.h */,
|
|
07EF07582745A8160066EA04 /* DisplayCaptureSessionManager.mm */,
|
|
7AFA6F682A9F57C50055322A /* DisplayLinkMac.cpp */,
|
|
+ D71A94302370E025002C4D9E /* InspectorPlaywrightAgentClientMac.h */,
|
|
+ D7EB04E62372A73B00F744CE /* InspectorPlaywrightAgentClientMac.mm */,
|
|
+ D79902AF236E9404005D6F7E /* InspectorTargetProxyMac.mm */,
|
|
1AFDE65B1954E8D500C48FFA /* LegacySessionStateCoding.cpp */,
|
|
0FCB4E5818BBE3D9000FCFC9 /* PageClientImplMac.h */,
|
|
0FCB4E5918BBE3D9000FCFC9 /* PageClientImplMac.mm */,
|
|
@@ -15288,6 +15350,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 */,
|
|
@@ -16361,6 +16425,7 @@
|
|
99788ACB1F421DDA00C08000 /* _WKAutomationSessionConfiguration.h in Headers */,
|
|
990D28AC1C6420CF00986977 /* _WKAutomationSessionDelegate.h in Headers */,
|
|
990D28B11C65208D00986977 /* _WKAutomationSessionInternal.h in Headers */,
|
|
+ D71A944A2372290B002C4D9E /* _WKBrowserInspector.h in Headers */,
|
|
5C4609E7224317B4009943C2 /* _WKContentRuleListAction.h in Headers */,
|
|
5C4609E8224317BB009943C2 /* _WKContentRuleListActionInternal.h in Headers */,
|
|
9B4CE9512CD99B7C00351173 /* _WKContentWorldConfiguration.h in Headers */,
|
|
@@ -16669,6 +16734,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 */,
|
|
@@ -16853,7 +16919,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 */,
|
|
C5BCE5DF1C50766A00CDE3FA /* InteractionInformationAtPosition.h in Headers */,
|
|
2D4D2C811DF60BF3002EB10C /* InteractionInformationRequest.h in Headers */,
|
|
@@ -17115,6 +17185,7 @@
|
|
0F6E7C532C4C386800F1DB85 /* RemoteDisplayListRecorderMessages.h in Headers */,
|
|
F451C0FE2703B263002BA03B /* RemoteDisplayListRecorderProxy.h in Headers */,
|
|
A78A5FE42B0EB39E005036D3 /* RemoteImageBufferSetIdentifier.h in Headers */,
|
|
+ D71A943A2370F061002C4D9E /* RemoteInspectorPipe.h in Headers */,
|
|
2D47B56D1810714E003A3AEE /* RemoteLayerBackingStore.h in Headers */,
|
|
2DDF731518E95060004F5A66 /* RemoteLayerBackingStoreCollection.h in Headers */,
|
|
1AB16AEA164B3A8800290D62 /* RemoteLayerTreeContext.h in Headers */,
|
|
@@ -17170,6 +17241,7 @@
|
|
E1E552C516AE065F004ED653 /* SandboxInitializationParameters.h in Headers */,
|
|
E36FF00327F36FBD004BE21A /* SandboxStateVariables.h in Headers */,
|
|
7BAB111025DD02B3008FC479 /* ScopedActiveMessageReceiveQueue.h in Headers */,
|
|
+ F303B849249A8D640031DE5C /* ScreencastEncoder.h in Headers */,
|
|
463BB93A2B9D08D80098C5C3 /* ScriptMessageHandlerIdentifier.h in Headers */,
|
|
F4E28A362C923814008120DD /* ScriptTelemetry.h in Headers */,
|
|
E4D54D0421F1D72D007E3C36 /* ScrollingTreeFrameScrollingNodeRemoteIOS.h in Headers */,
|
|
@@ -17530,6 +17602,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 */,
|
|
A543E30C215C8A8D00279CD9 /* WebPageInspectorTarget.h in Headers */,
|
|
A543E30D215C8A9000279CD9 /* WebPageInspectorTargetController.h in Headers */,
|
|
A543E307215AD13700279CD9 /* WebPageInspectorTargetFrontendChannel.h in Headers */,
|
|
@@ -20064,7 +20138,43 @@
|
|
522F792928D50EBB0069B45B /* HidService.mm in Sources */,
|
|
2749F6442146561B008380BF /* InjectedBundleNodeHandle.cpp in Sources */,
|
|
2749F6452146561E008380BF /* InjectedBundleRangeHandle.cpp in Sources */,
|
|
+ D7EB04E72372A73B00F744CE /* InspectorPlaywrightAgentClientMac.mm in Sources */,
|
|
+ D79902B2236E9404005D6F7E /* InspectorTargetProxyMac.mm in Sources */,
|
|
+ 1CC94E532AC92F190045F269 /* JSWebExtensionAPIAction.mm in Sources */,
|
|
+ 1C2B4D4B2A819D0D00C528A1 /* JSWebExtensionAPIAlarms.mm in Sources */,
|
|
+ 1C8ECFEA2AFC7DCB007BAA62 /* JSWebExtensionAPICommands.mm in Sources */,
|
|
+ 1C40052C2B2B953D00F2D9EE /* JSWebExtensionAPICookies.mm in Sources */,
|
|
+ 331102402B17B99800B21C8C /* JSWebExtensionAPIDeclarativeNetRequest.mm in Sources */,
|
|
+ 1C517F452B74393C00C46EDC /* JSWebExtensionAPIDevTools.mm in Sources */,
|
|
+ 1C517F432B74393C00C46EDC /* JSWebExtensionAPIDevToolsExtensionPanel.mm in Sources */,
|
|
+ 1C517F472B74393C00C46EDC /* JSWebExtensionAPIDevToolsInspectedWindow.mm in Sources */,
|
|
+ 1C517F462B74393C00C46EDC /* JSWebExtensionAPIDevToolsNetwork.mm in Sources */,
|
|
+ 1C517F412B74393C00C46EDC /* JSWebExtensionAPIDevToolsPanels.mm in Sources */,
|
|
+ B6114A7F29394A1600380B1B /* JSWebExtensionAPIEvent.mm in Sources */,
|
|
+ 1C5DC471290B33A20061EC62 /* JSWebExtensionAPIExtension.mm in Sources */,
|
|
+ B6CCAAB929A445E90092E846 /* JSWebExtensionAPILocalization.mm in Sources */,
|
|
+ 1CCEE4532B0989FC0034E059 /* JSWebExtensionAPIMenus.mm in Sources */,
|
|
+ 1C5DC4552908AC900061EC62 /* JSWebExtensionAPINamespace.mm in Sources */,
|
|
+ 1C386F362AF409F9004108F0 /* JSWebExtensionAPINotifications.mm in Sources */,
|
|
+ B61AFA4929510D0F008220B1 /* JSWebExtensionAPIPermissions.mm in Sources */,
|
|
+ 1C9A15CF2ABDF1E2002CC12A /* JSWebExtensionAPIPort.mm in Sources */,
|
|
+ 1C5DC472290B33A60061EC62 /* JSWebExtensionAPIRuntime.mm in Sources */,
|
|
+ B63E9A6F2AAF2B2D005F4561 /* JSWebExtensionAPIScripting.mm in Sources */,
|
|
+ 029D6BB22C407AA30068CF99 /* JSWebExtensionAPISidebarAction.mm in Sources */,
|
|
+ 029D6BB12C407AA30068CF99 /* JSWebExtensionAPISidePanel.mm in Sources */,
|
|
+ B63C10342B51C0B6004A69B8 /* JSWebExtensionAPIStorage.mm in Sources */,
|
|
+ B63C10372B51C102004A69B8 /* JSWebExtensionAPIStorageArea.mm in Sources */,
|
|
+ 1C5ACFAB2A96F8D500C041C0 /* JSWebExtensionAPITabs.mm in Sources */,
|
|
+ 1C15497F2926C073001B9E5B /* JSWebExtensionAPITest.mm in Sources */,
|
|
1C0F05BE2CFA5D2E007D1F62 /* JSWebExtensionAPIUnified.mm in Sources */,
|
|
+ 3375A3772942A19D0028536D /* JSWebExtensionAPIWebNavigation.mm in Sources */,
|
|
+ 33F68338293FF6F5005C63C0 /* JSWebExtensionAPIWebNavigationEvent.mm in Sources */,
|
|
+ B63A99772B7EA002004611FD /* JSWebExtensionAPIWebPageNamespace.mm in Sources */,
|
|
+ B63A99782B7EA002004611FD /* JSWebExtensionAPIWebPageRuntime.mm in Sources */,
|
|
+ 3399E1532B59EFD7008BFB60 /* JSWebExtensionAPIWebRequest.mm in Sources */,
|
|
+ 337042022B58A0B70077FF78 /* JSWebExtensionAPIWebRequestEvent.mm in Sources */,
|
|
+ 1C5ACFA62A96F8C400C041C0 /* JSWebExtensionAPIWindows.mm in Sources */,
|
|
+ 1C5ACFA72A96F8C400C041C0 /* JSWebExtensionAPIWindowsEvent.mm in Sources */,
|
|
1C5DC45F2909B05A0061EC62 /* JSWebExtensionWrapperCocoa.mm in Sources */,
|
|
C14D37FE24ACE086007FF014 /* LaunchServicesDatabaseManager.mm in Sources */,
|
|
C1710CF724AA643200D7C112 /* LaunchServicesDatabaseObserver.mm in Sources */,
|
|
@@ -20425,6 +20535,8 @@
|
|
074E87E12CF8EA3D0059E469 /* WebPage+NavigationDeciding.swift in Sources */,
|
|
078B04A02CF18EAB00B453A6 /* WebPage+NavigationPreferences.swift in Sources */,
|
|
07CB79962CE9435700199C49 /* WebPage.swift in Sources */,
|
|
+ D79902B1236E9404005D6F7E /* WebPageInspectorEmulationAgentMac.mm in Sources */,
|
|
+ D79902B3236E9404005D6F7E /* WebPageInspectorInputAgentMac.mm in Sources */,
|
|
7CE9CE101FA0767A000177DE /* WebPageUpdatePreferences.cpp in Sources */,
|
|
7CEB00DD1FA69ABE0065473B /* WebPreferencesFeatures.cpp in Sources */,
|
|
7CF1907125338F3800ABE183 /* WebPreferencesGetterSetters.cpp in Sources */,
|
|
diff --git a/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp b/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp
|
|
index ac0032c3bf918b6dcadd21c18700f1adb74e9a78..4f55fe73551265aa22f743e7ec006e2c9b213463 100644
|
|
--- a/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp
|
|
+++ b/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp
|
|
@@ -247,6 +247,11 @@ void WebLoaderStrategy::scheduleLoad(ResourceLoader& resourceLoader, CachedResou
|
|
}
|
|
#endif
|
|
|
|
+ if (m_emulateOfflineState) {
|
|
+ scheduleInternallyFailedLoad(resourceLoader);
|
|
+ return;
|
|
+ }
|
|
+
|
|
#if ENABLE(PDFJS)
|
|
if (tryLoadingUsingPDFJSHandler(resourceLoader, trackingParameters))
|
|
return;
|
|
@@ -256,12 +261,16 @@ void WebLoaderStrategy::scheduleLoad(ResourceLoader& resourceLoader, CachedResou
|
|
return;
|
|
|
|
if (InspectorInstrumentationWebKit::shouldInterceptRequest(resourceLoader)) {
|
|
- InspectorInstrumentationWebKit::interceptRequest(resourceLoader, [this, protectedResourceLoader = Ref { resourceLoader }, trackingParameters, shouldClearReferrerOnHTTPSToHTTPRedirect, 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, protectedResourceLoader = Ref { resourceLoader }, trackingParameters, shouldClearReferrerOnHTTPSToHTTPRedirect, 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(WEBLOADERSTRATEGY_SCHEDULELOAD);
|
|
@@ -383,7 +392,8 @@ 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)
|
|
+// static
|
|
+bool WebLoaderStrategy::fillParametersForNetworkProcessLoad(ResourceLoader& resourceLoader, const ResourceRequest& request, const WebResourceLoader::TrackingParameters& trackingParameters, bool shouldClearReferrerOnHTTPSToHTTPRedirect, Seconds maximumBufferingTime, NetworkResourceLoadParameters& loadParameters)
|
|
{
|
|
auto identifier = *resourceLoader.identifier();
|
|
|
|
@@ -395,10 +405,10 @@ void WebLoaderStrategy::scheduleLoadFromNetworkProcess(ResourceLoader& resourceL
|
|
&& resourceLoader.frameLoader()->notifier().isInitialRequestIdentifier(identifier)
|
|
? MainFrameMainResource::Yes : MainFrameMainResource::No;
|
|
if (!page->allowsLoadFromURL(request.url(), mainFrameMainResource)) {
|
|
- RunLoop::protectedMain()->dispatch([resourceLoader = Ref { resourceLoader }, error = blockedError(request)] {
|
|
+ RunLoop::protectedMain()->dispatch([resourceLoader = Ref { resourceLoader }, error = platformStrategies()->loaderStrategy()->blockedError(request)] {
|
|
resourceLoader->didFail(error);
|
|
});
|
|
- return;
|
|
+ return false;
|
|
}
|
|
}
|
|
|
|
@@ -408,7 +418,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;
|
|
loadParameters.identifier = identifier;
|
|
loadParameters.webPageProxyID = trackingParameters.webPageProxyID;
|
|
loadParameters.webPageID = trackingParameters.pageID;
|
|
@@ -499,14 +508,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)
|
|
@@ -547,6 +553,17 @@ void WebLoaderStrategy::scheduleLoadFromNetworkProcess(ResourceLoader& resourceL
|
|
}
|
|
|
|
ASSERT((loadParameters.webPageID && loadParameters.webFrameID) || loadParameters.clientCredentialPolicy == ClientCredentialPolicy::CannotAskClientForCredentials);
|
|
+ return true;
|
|
+}
|
|
+
|
|
+void WebLoaderStrategy::scheduleLoadFromNetworkProcess(ResourceLoader& resourceLoader, const ResourceRequest& request, const WebResourceLoader::TrackingParameters& trackingParameters, bool shouldClearReferrerOnHTTPSToHTTPRedirect, Seconds maximumBufferingTime)
|
|
+{
|
|
+ NetworkResourceLoadParameters loadParameters;
|
|
+ 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)
|
|
@@ -562,7 +579,7 @@ void WebLoaderStrategy::scheduleLoadFromNetworkProcess(ResourceLoader& resourceL
|
|
}
|
|
|
|
auto loader = WebResourceLoader::create(resourceLoader, trackingParameters);
|
|
- m_webResourceLoaders.set(identifier, WTFMove(loader));
|
|
+ m_webResourceLoaders.set(*resourceLoader.identifier(), WTFMove(loader));
|
|
}
|
|
|
|
void WebLoaderStrategy::scheduleInternallyFailedLoad(WebCore::ResourceLoader& resourceLoader)
|
|
@@ -966,7 +983,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)
|
|
@@ -993,6 +1010,11 @@ void WebLoaderStrategy::isResourceLoadFinished(CachedResource& resource, Complet
|
|
|
|
void WebLoaderStrategy::setOnLineState(bool isOnLine)
|
|
{
|
|
+ if (m_emulateOfflineState) {
|
|
+ m_isOnLine = isOnLine;
|
|
+ return;
|
|
+ }
|
|
+
|
|
if (m_isOnLine == isOnLine)
|
|
return;
|
|
|
|
@@ -1001,6 +1023,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 dc88916914daebf7c421dc56c2be70fd47727a96..829fdad0490a5e4db8822fbc48c5f19a2c2e0703 100644
|
|
--- a/Source/WebKit/WebProcess/Network/WebLoaderStrategy.h
|
|
+++ b/Source/WebKit/WebProcess/Network/WebLoaderStrategy.h
|
|
@@ -44,6 +44,7 @@ struct FetchOptions;
|
|
namespace WebKit {
|
|
|
|
class NetworkProcessConnection;
|
|
+class NetworkResourceLoadParameters;
|
|
class WebFrame;
|
|
class WebPage;
|
|
class WebProcess;
|
|
@@ -96,6 +97,9 @@ public:
|
|
bool isOnLine() const final;
|
|
void addOnlineStateChangeListener(Function<void(bool)>&&) final;
|
|
void setOnLineState(bool);
|
|
+ void setEmulateOfflineState(bool) final;
|
|
+
|
|
+ static bool fillParametersForNetworkProcessLoad(WebCore::ResourceLoader&, const WebCore::ResourceRequest&, const WebResourceLoader::TrackingParameters&, bool shouldClearReferrerOnHTTPSToHTTPRedirect, Seconds maximumBufferingTime, NetworkResourceLoadParameters&);
|
|
|
|
void setExistingNetworkResourceLoadIdentifierToResume(std::optional<NetworkResourceLoadIdentifier> existingNetworkResourceLoadIdentifierToResume) { m_existingNetworkResourceLoadIdentifierToResume = existingNetworkResourceLoadIdentifierToResume; }
|
|
|
|
@@ -164,6 +168,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 f0c21a35614b000e0a835ef4a4038feb0224842b..f9aecb9ed77192c00a3173521f72bd840ea6b571 100644
|
|
--- a/Source/WebKit/WebProcess/Network/WebResourceLoader.cpp
|
|
+++ b/Source/WebKit/WebProcess/Network/WebResourceLoader.cpp
|
|
@@ -202,9 +202,6 @@ void WebResourceLoader::didReceiveResponse(ResourceResponse&& response, PrivateR
|
|
|
|
coreLoader->didReceiveResponse(inspectorResponse, [this, protectedThis = Ref { *this }, interceptedRequestIdentifier, policyDecisionCompletionHandler = WTFMove(policyDecisionCompletionHandler), overrideData = WTFMove(overrideData)]() mutable {
|
|
RefPtr coreLoader = m_coreLoader;
|
|
- if (policyDecisionCompletionHandler)
|
|
- policyDecisionCompletionHandler();
|
|
-
|
|
if (!m_coreLoader || !coreLoader->identifier()) {
|
|
m_interceptController.continueResponse(interceptedRequestIdentifier);
|
|
return;
|
|
@@ -221,6 +218,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 33b01034cea7fc023ba4bef55142ae2700d5e48c..0b0236832df43047a7808af0d422a4572231dc5e 100644
|
|
--- a/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp
|
|
+++ b/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp
|
|
@@ -490,6 +490,8 @@ void WebChromeClient::addMessageToConsole(MessageSource source, MessageLevel lev
|
|
{
|
|
// Notify the bundle client.
|
|
auto page = protectedPage();
|
|
+ if (level == MessageLevel::Error)
|
|
+ page->send(Messages::WebPageProxy::LogToStderr(message));
|
|
page->injectedBundleUIClient().willAddMessageToConsole(page.ptr(), source, level, message, lineNumber, columnNumber, sourceID);
|
|
}
|
|
|
|
diff --git a/Source/WebKit/WebProcess/WebCoreSupport/WebDragClient.cpp b/Source/WebKit/WebProcess/WebCoreSupport/WebDragClient.cpp
|
|
index dd03326b1ad54e1d363d722cfe86bb779fbeead1..f54d631dc4034c995cbd74ec6b545c3c7dd25990 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->allowedDragSourceActions();
|
|
}
|
|
|
|
-#if !PLATFORM(COCOA) && !PLATFORM(GTK)
|
|
+#if !PLATFORM(COCOA) && !PLATFORM(GTK) && !PLATFORM(WPE) && !PLATFORM(WIN)
|
|
void WebDragClient::startDrag(DragItem, DataTransfer&, Frame&)
|
|
{
|
|
}
|
|
diff --git a/Source/WebKit/WebProcess/WebCoreSupport/mac/WebDragClientMac.mm b/Source/WebKit/WebProcess/WebCoreSupport/mac/WebDragClientMac.mm
|
|
index 2713e431893efd17c95d163f14aec45b27e0d6fc..b96b1d9cba20af611837915412fa4202667e800d 100644
|
|
--- a/Source/WebKit/WebProcess/WebCoreSupport/mac/WebDragClientMac.mm
|
|
+++ b/Source/WebKit/WebProcess/WebCoreSupport/mac/WebDragClientMac.mm
|
|
@@ -128,7 +128,8 @@ static 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;
|
|
|
|
WebCore::CachedImage* 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..66972b66094050b2429a927861ff7d0d30925ef0
|
|
--- /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 "ArgumentCodersWPE.h"
|
|
+#include "MessageSenderInlines.h"
|
|
+#include "WebPage.h"
|
|
+#include "WebPageProxyMessages.h"
|
|
+#include <WebCore/DataTransfer.h>
|
|
+#include <WebCore/DragData.h>
|
|
+#include <WebCore/Pasteboard.h>
|
|
+#include <WebCore/ShareableBitmap.h>
|
|
+#include <wtf/win/GDIObject.h>
|
|
+
|
|
+//#include <WebCore/SelectionData.h>
|
|
+
|
|
+namespace WebKit {
|
|
+using namespace WebCore;
|
|
+
|
|
+void WebDragClient::didConcludeEditDrag()
|
|
+{
|
|
+}
|
|
+
|
|
+void WebDragClient::startDrag(DragItem, DataTransfer& dataTransfer, Frame& frame)
|
|
+{
|
|
+ m_page->willStartDrag();
|
|
+ m_page->send(Messages::WebPageProxy::StartDrag(dataTransfer.pasteboard().createDragDataMap()));
|
|
+}
|
|
+
|
|
+}; // namespace WebKit.
|
|
+
|
|
+#endif // ENABLE(DRAG_SUPPORT)
|
|
diff --git a/Source/WebKit/WebProcess/WebCoreSupport/wpe/WebDragClientWPE.cpp b/Source/WebKit/WebProcess/WebCoreSupport/wpe/WebDragClientWPE.cpp
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..226b3bf6bd83d2606a0aeb627ae9302fd3bcf874
|
|
--- /dev/null
|
|
+++ b/Source/WebKit/WebProcess/WebCoreSupport/wpe/WebDragClientWPE.cpp
|
|
@@ -0,0 +1,56 @@
|
|
+/*
|
|
+ * 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 "WebPage.h"
|
|
+#include "WebPageProxyMessages.h"
|
|
+#include <WebCore/DataTransfer.h>
|
|
+#include <WebCore/DragData.h>
|
|
+#include <WebCore/Pasteboard.h>
|
|
+#include <WebCore/SelectionData.h>
|
|
+#include <WebCore/ShareableBitmap.h>
|
|
+
|
|
+namespace WebKit {
|
|
+using namespace WebCore;
|
|
+
|
|
+void WebDragClient::didConcludeEditDrag()
|
|
+{
|
|
+}
|
|
+
|
|
+void WebDragClient::startDrag(DragItem, DataTransfer& dataTransfer, Frame&)
|
|
+{
|
|
+ m_page->willStartDrag();
|
|
+
|
|
+ std::optional<ShareableBitmap::Handle> handle;
|
|
+ m_page->send(Messages::WebPageProxy::StartDrag(dataTransfer.pasteboard().selectionData(), dataTransfer.sourceOperationMask(), WTFMove(handle), dataTransfer.dragLocation()));
|
|
+}
|
|
+
|
|
+}; // namespace WebKit.
|
|
+
|
|
+#endif // ENABLE(DRAG_SUPPORT)
|
|
diff --git a/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/DrawingAreaCoordinatedGraphics.cpp b/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/DrawingAreaCoordinatedGraphics.cpp
|
|
index ac7fa01ba9a3828cf4c48cacc862aab95145093e..3246812f8ebb8833b2172f9f5f00dff6053387c9 100644
|
|
--- a/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/DrawingAreaCoordinatedGraphics.cpp
|
|
+++ b/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/DrawingAreaCoordinatedGraphics.cpp
|
|
@@ -39,6 +39,7 @@
|
|
#include "WebPreferencesKeys.h"
|
|
#include "WebProcess.h"
|
|
#include <WebCore/GraphicsContext.h>
|
|
+#include <WebCore/InspectorController.h>
|
|
#include <WebCore/LocalFrame.h>
|
|
#include <WebCore/LocalFrameView.h>
|
|
#include <WebCore/Page.h>
|
|
@@ -562,6 +563,11 @@ void DrawingAreaCoordinatedGraphics::enterAcceleratedCompositingMode(GraphicsLay
|
|
m_scrollOffset = IntSize();
|
|
m_displayTimer.stop();
|
|
m_isWaitingForDidUpdate = false;
|
|
+// Playwright begin
|
|
+#if PLATFORM(WIN)
|
|
+ didChangeAcceleratedCompositingMode(true);
|
|
+#endif
|
|
+// Playwright end
|
|
}
|
|
|
|
void DrawingAreaCoordinatedGraphics::sendEnterAcceleratedCompositingModeIfNeeded()
|
|
@@ -619,6 +625,11 @@ void DrawingAreaCoordinatedGraphics::exitAcceleratedCompositingMode()
|
|
// UI process, we still need to let it know about the new contents, so send an Update message.
|
|
send(Messages::DrawingAreaProxy::Update(0, WTFMove(updateInfo)));
|
|
}
|
|
+// Playwright begin
|
|
+#if PLATFORM(WIN)
|
|
+ didChangeAcceleratedCompositingMode(false);
|
|
+#endif
|
|
+// Playwright end
|
|
}
|
|
|
|
void DrawingAreaCoordinatedGraphics::scheduleDisplay()
|
|
diff --git a/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/LayerTreeHost.h b/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/LayerTreeHost.h
|
|
index f19473587ec9f1ce8fb2e249feaf1e45b0ec1b80..0908807628b0f96925d3b669b6962f3553f422ca 100644
|
|
--- a/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/LayerTreeHost.h
|
|
+++ b/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/LayerTreeHost.h
|
|
@@ -138,6 +138,7 @@ public:
|
|
#if PLATFORM(WPE) && USE(GBM) && ENABLE(WPE_PLATFORM)
|
|
void preferredBufferFormatsDidChange();
|
|
#endif
|
|
+
|
|
private:
|
|
void updateRootLayer();
|
|
WebCore::FloatRect visibleContentsRect() const;
|
|
diff --git a/Source/WebKit/WebProcess/WebPage/DrawingArea.cpp b/Source/WebKit/WebProcess/WebPage/DrawingArea.cpp
|
|
index 5ba445d43ad37ff55f239660cddeada7abe2a6e8..ee3bfd8a34d4e7ea4d632cd8524457f5fb57ef15 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"
|
|
@@ -115,6 +116,13 @@ void DrawingArea::tryMarkLayersVolatile(CompletionHandler<void(bool)>&& completi
|
|
completionFunction(true);
|
|
}
|
|
|
|
+#if PLATFORM(WIN)
|
|
+void DrawingArea::didChangeAcceleratedCompositingMode(bool enabled)
|
|
+{
|
|
+ send(Messages::DrawingAreaProxy::DidChangeAcceleratedCompositingMode(enabled));
|
|
+}
|
|
+#endif
|
|
+
|
|
void DrawingArea::removeMessageReceiverIfNeeded()
|
|
{
|
|
if (m_hasRemovedMessageReceiver)
|
|
diff --git a/Source/WebKit/WebProcess/WebPage/DrawingArea.h b/Source/WebKit/WebProcess/WebPage/DrawingArea.h
|
|
index 6c61c9a0ee5b7a11408d5a0a06f37035e9601e25..a5ddf926e95182bd3575147aff2123f3e6a77109 100644
|
|
--- a/Source/WebKit/WebProcess/WebPage/DrawingArea.h
|
|
+++ b/Source/WebKit/WebProcess/WebPage/DrawingArea.h
|
|
@@ -172,6 +172,9 @@ public:
|
|
virtual bool enterAcceleratedCompositingModeIfNeeded() = 0;
|
|
virtual void backgroundColorDidChange() { };
|
|
#endif
|
|
+#if PLATFORM(WIN)
|
|
+ void didChangeAcceleratedCompositingMode(bool enabled);
|
|
+#endif
|
|
|
|
#if PLATFORM(WPE) && USE(GBM) && ENABLE(WPE_PLATFORM)
|
|
virtual void preferredBufferFormatsDidChange() { }
|
|
diff --git a/Source/WebKit/WebProcess/WebPage/WebCookieJar.cpp b/Source/WebKit/WebProcess/WebPage/WebCookieJar.cpp
|
|
index 70a6c3c9ed0fcf42393df2c0fb66eb50d290030d..06fb88ca78db70de4bd4ed9cdf33172bee1a958e 100644
|
|
--- a/Source/WebKit/WebProcess/WebPage/WebCookieJar.cpp
|
|
+++ b/Source/WebKit/WebProcess/WebPage/WebCookieJar.cpp
|
|
@@ -44,6 +44,7 @@
|
|
#include <WebCore/LocalFrame.h>
|
|
#include <WebCore/LocalFrameLoaderClient.h>
|
|
#include <WebCore/Page.h>
|
|
+#include <WebCore/ResourceLoader.h>
|
|
#include <WebCore/ScriptTelemetryCategory.h>
|
|
#include <WebCore/Settings.h>
|
|
#include <WebCore/StorageSessionProvider.h>
|
|
@@ -445,6 +446,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 f9c1d07d4e1f4b5421a627a179ed4f86cf1a1b92..9a8089ed85eebbfb8af0804dfbc0698bcb5993d6 100644
|
|
--- a/Source/WebKit/WebProcess/WebPage/WebCookieJar.h
|
|
+++ b/Source/WebKit/WebProcess/WebPage/WebCookieJar.h
|
|
@@ -77,6 +77,8 @@ public:
|
|
|
|
void clearCache() final;
|
|
|
|
+ void setCookieFromResponse(WebCore::ResourceLoader&, const String& setCookieValue);
|
|
+
|
|
#if HAVE(ALLOW_ONLY_PARTITIONED_COOKIES)
|
|
void setOptInCookiePartitioningEnabled(bool);
|
|
#endif
|
|
diff --git a/Source/WebKit/WebProcess/WebPage/WebPage.cpp b/Source/WebKit/WebProcess/WebPage/WebPage.cpp
|
|
index a790490171adbb2bd153e84f37df524099d11496..6aa0bc62374ce01171b04d7025105ba155ecaf80 100644
|
|
--- a/Source/WebKit/WebProcess/WebPage/WebPage.cpp
|
|
+++ b/Source/WebKit/WebProcess/WebPage/WebPage.cpp
|
|
@@ -241,6 +241,7 @@
|
|
#include <WebCore/ImageAnalysisQueue.h>
|
|
#include <WebCore/ImageOverlay.h>
|
|
#include <WebCore/InspectorController.h>
|
|
+#include <WebCore/InspectorInstrumentationWebKit.h>
|
|
#include <WebCore/JSDOMExceptionHandling.h>
|
|
#include <WebCore/KeyboardEvent.h>
|
|
#include <WebCore/LegacySchemeRegistry.h>
|
|
@@ -1156,6 +1157,12 @@ WebPage::WebPage(PageIdentifier pageID, WebPageCreationParameters&& parameters)
|
|
setLinkDecorationFilteringData(WTFMove(parameters.linkDecorationFilteringData));
|
|
setAllowedQueryParametersForAdvancedPrivacyProtections(WTFMove(parameters.allowedQueryParametersForAdvancedPrivacyProtections));
|
|
#endif
|
|
+ // 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 ? InspectorController::PauseCondition::WHEN_CREATION_FINISHED : InspectorController::PauseCondition::WHEN_SHOWN);
|
|
if (parameters.windowFeatures) {
|
|
page->applyWindowFeatures(*parameters.windowFeatures);
|
|
page->chrome().show();
|
|
@@ -2094,6 +2101,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(), loadParameters.request };
|
|
+ frame->coreLocalFrame()->loader().load(WTFMove(frameLoadRequest));
|
|
+ ASSERT(!m_pendingFrameNavigationID);
|
|
+}
|
|
+
|
|
void WebPage::loadRequest(LoadParameters&& loadParameters)
|
|
{
|
|
WEBPAGE_RELEASE_LOG_FORWARDABLE(Loading, WEBPAGE_LOADREQUEST, loadParameters.navigationID ? loadParameters.navigationID->toUInt64() : 0, static_cast<unsigned>(loadParameters.shouldTreatAsContinuingLoad), loadParameters.request.isAppInitiated(), loadParameters.existingNetworkResourceLoadIdentifierToResume ? loadParameters.existingNetworkResourceLoadIdentifierToResume->toUInt64() : 0);
|
|
@@ -2289,7 +2312,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
|
|
@@ -2865,7 +2890,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;
|
|
@@ -3652,6 +3677,13 @@ void WebPage::flushDeferredScrollEvents()
|
|
protectedCorePage()->flushDeferredScrollEvents();
|
|
}
|
|
|
|
+#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))
|
|
@@ -3913,6 +3945,97 @@ 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::IntSize radius(radiusX,radiusY);
|
|
+ const WebCore::IntPoint 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, WallTime::now()}, WTFMove(touchPoints), {}, {});
|
|
+
|
|
+ CurrentEvent currentEvent(touchEvent);
|
|
+ handled = handleTouchEvent(m_page->mainFrame().frameID(), touchEvent, m_page.get()).wasHandled();
|
|
+ }
|
|
+ {
|
|
+ Vector<WebPlatformTouchPoint> touchPoints;
|
|
+ WebPlatformTouchPoint::State state = WebPlatformTouchPoint::State::Released;
|
|
+ touchPoints.append(WebPlatformTouchPoint(id, state, screenPosition, position, radius, rotationAngle, force));
|
|
+
|
|
+ WebTouchEvent touchEvent({WebEventType::TouchEnd, eventModifiers, WallTime::now()}, WTFMove(touchPoints), {}, {});
|
|
+
|
|
+ CurrentEvent currentEvent(touchEvent);
|
|
+ handled = handleTouchEvent(m_page->mainFrame().frameID(), touchEvent, m_page.get()).wasHandled() || handled;
|
|
+ }
|
|
+ if (!handled) {
|
|
+ FloatPoint adjustedPoint;
|
|
+
|
|
+ auto* localMainFrame = dynamicDowncast<LocalFrame>(m_page->mainFrame());
|
|
+ if (!localMainFrame)
|
|
+ return;
|
|
+
|
|
+ Node* 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,
|
|
+ WallTime::now(),
|
|
+ force,
|
|
+ syntheticClickType
|
|
+ ));
|
|
+ localMainFrame->eventHandler().handleMousePressEvent(PlatformMouseEvent(
|
|
+ adjustedIntPoint,
|
|
+ adjustedIntPoint,
|
|
+ MouseButton::Left,
|
|
+ PlatformEvent::Type::MousePressed,
|
|
+ 1,
|
|
+ modifiers,
|
|
+ WallTime::now(),
|
|
+ force,
|
|
+ syntheticClickType
|
|
+ ));
|
|
+ localMainFrame->eventHandler().handleMouseReleaseEvent(PlatformMouseEvent(
|
|
+ adjustedIntPoint,
|
|
+ adjustedIntPoint,
|
|
+ MouseButton::Left,
|
|
+ PlatformEvent::Type::MouseReleased,
|
|
+ 1,
|
|
+ modifiers,
|
|
+ WallTime::now(),
|
|
+ force,
|
|
+ syntheticClickType
|
|
+ ));
|
|
+ }
|
|
+ completionHandler();
|
|
+}
|
|
#endif
|
|
|
|
void WebPage::cancelPointer(WebCore::PointerID pointerId, const WebCore::IntPoint& documentPoint)
|
|
@@ -4001,6 +4124,16 @@ void WebPage::sendMessageToTargetBackend(const String& targetId, const String& m
|
|
m_inspectorTargetController->sendMessageToTargetBackend(targetId, message);
|
|
}
|
|
|
|
+void WebPage::resumeInspectorIfPausedInNewWindow()
|
|
+{
|
|
+ m_page->inspectorController().resumeIfPausedInNewWindow();
|
|
+}
|
|
+
|
|
+void WebPage::didAddWebPageToWebProcess()
|
|
+{
|
|
+ m_page->inspectorController().didFinishPageCreation();
|
|
+}
|
|
+
|
|
void WebPage::insertNewlineInQuotedContent()
|
|
{
|
|
RefPtr frame = protectedCorePage()->checkedFocusController()->focusedOrMainFrame();
|
|
@@ -4251,6 +4384,7 @@ void WebPage::setMainFrameDocumentVisualUpdatesAllowed(bool allowed)
|
|
void WebPage::show()
|
|
{
|
|
send(Messages::WebPageProxy::ShowPage());
|
|
+ m_page->inspectorController().didShowPage();
|
|
}
|
|
|
|
void WebPage::setIsTakingSnapshotsForApplicationSuspension(bool isTakingSnapshotsForApplicationSuspension)
|
|
@@ -5439,7 +5573,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)
|
|
@@ -7914,6 +8048,10 @@ void WebPage::didCommitLoad(WebFrame* frame)
|
|
#endif
|
|
|
|
flushDeferredDidReceiveMouseEvent();
|
|
+// Playwright begin
|
|
+ if (frame->isMainFrame())
|
|
+ send(Messages::WebPageProxy::ViewScaleFactorDidChange(viewScaleFactor()));
|
|
+// Playwright end
|
|
}
|
|
|
|
void WebPage::didFinishDocumentLoad(WebFrame& frame)
|
|
@@ -8233,6 +8371,9 @@ Ref<DocumentLoader> WebPage::createDocumentLoader(LocalFrame& frame, const Resou
|
|
WebsitePoliciesData::applyToDocumentLoader(WTFMove(*m_internals->pendingWebsitePolicies), documentLoader);
|
|
m_internals->pendingWebsitePolicies = std::nullopt;
|
|
}
|
|
+ } 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 889f9a1c62a652c3de5e5edb14c9781932b8ef7b..1a708ef7835d63cdaf60db1eb4d5ade6808152b0 100644
|
|
--- a/Source/WebKit/WebProcess/WebPage/WebPage.h
|
|
+++ b/Source/WebKit/WebProcess/WebPage/WebPage.h
|
|
@@ -43,6 +43,7 @@
|
|
#include <WebCore/MediaKeySystemRequest.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>
|
|
@@ -1256,11 +1257,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(WebCore::DragData&&, SandboxExtensionHandle&&, Vector<SandboxExtensionHandle>&&, CompletionHandler<void(bool)>&&);
|
|
#endif
|
|
@@ -1275,6 +1276,9 @@ public:
|
|
void didStartDrag();
|
|
void dragCancelled();
|
|
OptionSet<WebCore::DragSourceAction> allowedDragSourceActions() const { return m_allowedDragSourceActions; }
|
|
+#if PLATFORM(MAC)
|
|
+ void setDragPasteboardName(const String& pasteboardName) { m_page->setDragPasteboardName(pasteboardName); }
|
|
+#endif
|
|
#endif
|
|
|
|
#if ENABLE(MODEL_PROCESS)
|
|
@@ -1361,8 +1365,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();
|
|
@@ -1513,6 +1520,8 @@ public:
|
|
void connectInspector(const String& targetId, Inspector::FrontendChannel::ConnectionType);
|
|
void disconnectInspector(const String& targetId);
|
|
void sendMessageToTargetBackend(const String& targetId, const String& message);
|
|
+ void resumeInspectorIfPausedInNewWindow();
|
|
+ void didAddWebPageToWebProcess();
|
|
|
|
void insertNewlineInQuotedContent();
|
|
|
|
@@ -1930,6 +1939,7 @@ public:
|
|
void showContextMenuFromFrame(const FrameInfoData&, const ContextMenuContextData&, const UserData&);
|
|
#endif
|
|
void loadRequest(LoadParameters&&);
|
|
+ void loadRequestInFrameForInspector(LoadParameters&&, WebCore::FrameIdentifier);
|
|
|
|
void setObscuredContentInsets(const WebCore::FloatBoxExtent&);
|
|
|
|
@@ -2121,6 +2131,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&);
|
|
@@ -2884,6 +2895,7 @@ private:
|
|
UserActivity m_userActivity;
|
|
|
|
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 d38d0ecfb0e77838cc6d24b199c8be5d30d13953..1b6ddebd36f1a53a1d34a9157dffc9e8147dae19 100644
|
|
--- a/Source/WebKit/WebProcess/WebPage/WebPage.messages.in
|
|
+++ b/Source/WebKit/WebProcess/WebPage/WebPage.messages.in
|
|
@@ -57,10 +57,13 @@ messages -> WebPage WantsAsyncDispatchMessage {
|
|
MouseEvent(WebCore::FrameIdentifier frameID, WebKit::WebMouseEvent event, std::optional<Vector<WebKit::SandboxExtensionHandle>> sandboxExtensions)
|
|
SetLastKnownMousePosition(WebCore::FrameIdentifier frameID, WebCore::IntPoint eventPoint, WebCore::IntPoint globalPoint);
|
|
|
|
+#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(std::optional<WebCore::ViewportArguments> arguments)
|
|
DynamicViewportSizeUpdate(struct WebKit::DynamicViewportSizeUpdate target)
|
|
|
|
@@ -152,6 +155,7 @@ messages -> WebPage WantsAsyncDispatchMessage {
|
|
ConnectInspector(String targetId, Inspector::FrontendChannel::ConnectionType connectionType)
|
|
DisconnectInspector(String targetId)
|
|
SendMessageToTargetBackend(String targetId, String message)
|
|
+ ResumeInspectorIfPausedInNewWindow();
|
|
|
|
#if ENABLE(REMOTE_INSPECTOR)
|
|
SetIndicating(bool indicating);
|
|
@@ -162,6 +166,7 @@ messages -> WebPage WantsAsyncDispatchMessage {
|
|
#endif
|
|
#if !ENABLE(IOS_TOUCH_EVENTS) && ENABLE(TOUCH_EVENTS)
|
|
TouchEvent(WebKit::WebTouchEvent event) -> (std::optional<WebKit::WebEventType> eventType, bool handled)
|
|
+ FakeTouchTap(WebCore::IntPoint position, uint8_t modifiers) -> () Async
|
|
#endif
|
|
|
|
CancelPointer(WebCore::PointerID pointerId, WebCore::IntPoint documentPoint)
|
|
@@ -189,6 +194,7 @@ messages -> WebPage WantsAsyncDispatchMessage {
|
|
CreateProvisionalFrame(struct WebKit::ProvisionalFrameCreationParameters creationParameters)
|
|
DestroyProvisionalFrame(WebCore::FrameIdentifier frameID);
|
|
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)
|
|
@@ -352,10 +358,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) -> (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) -> (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(WebCore::DragData dragData, WebKit::SandboxExtensionHandle sandboxExtensionHandle, Vector<WebKit::SandboxExtensionHandle> sandboxExtensionsForUpload) -> (bool handled)
|
|
#endif
|
|
@@ -371,6 +377,10 @@ messages -> WebPage WantsAsyncDispatchMessage {
|
|
StageModeSessionDidEnd(std::optional<WebCore::ElementIdentifier> elementID)
|
|
#endif
|
|
|
|
+#if PLATFORM(MAC) && ENABLE(DRAG_SUPPORT)
|
|
+ SetDragPasteboardName(String pasteboardName)
|
|
+#endif
|
|
+
|
|
#if PLATFORM(IOS_FAMILY) && ENABLE(DRAG_SUPPORT)
|
|
RequestDragStart(WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, OptionSet<WebCore::DragSourceAction> allowedActionsMask)
|
|
RequestAdditionalItemsForDragSession(WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, OptionSet<WebCore::DragSourceAction> allowedActionsMask)
|
|
diff --git a/Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm b/Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm
|
|
index 740a118cfe40d803ecccbf2025efa7b813d9b918..c8acb88dd1f3b47332e3928035f74b8bd3c57049 100644
|
|
--- a/Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm
|
|
+++ b/Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm
|
|
@@ -696,21 +696,37 @@ String WebPage::platformUserAgent(const URL&) const
|
|
|
|
bool WebPage::hoverSupportedByPrimaryPointingDevice() const
|
|
{
|
|
+#if ENABLE(TOUCH_EVENTS)
|
|
+ return !screenIsTouchPrimaryInputDevice();
|
|
+#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 (screenIsTouchPrimaryInputDevice())
|
|
+ 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 f17f5d719d892309ed9c7093384945866b5117b9..1dba47bbf0dbd0362548423a74b380346dbea147 100644
|
|
--- a/Source/WebKit/WebProcess/WebPage/win/WebPageWin.cpp
|
|
+++ b/Source/WebKit/WebProcess/WebPage/win/WebPageWin.cpp
|
|
@@ -43,6 +43,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>
|
|
@@ -81,21 +82,37 @@ String WebPage::platformUserAgent(const URL&) const
|
|
|
|
bool WebPage::hoverSupportedByPrimaryPointingDevice() const
|
|
{
|
|
+#if ENABLE(TOUCH_EVENTS)
|
|
+ return !screenIsTouchPrimaryInputDevice();
|
|
+#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 (screenIsTouchPrimaryInputDevice())
|
|
+ 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 aeaaf015db254f2562085e003a84c29ea8636611..6779f7b116db8f9a0686bef70965cdf9a7d2d6f4 100644
|
|
--- a/Source/WebKit/WebProcess/WebProcess.cpp
|
|
+++ b/Source/WebKit/WebProcess/WebProcess.cpp
|
|
@@ -91,6 +91,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>
|
|
@@ -378,6 +379,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();
|
|
}
|
|
|
|
@@ -385,6 +394,8 @@ void WebProcess::initializeProcess(const AuxiliaryProcessInitializationParameter
|
|
|
|
platformInitializeProcess(parameters);
|
|
updateCPULimit();
|
|
+
|
|
+ Inspector::IdentifiersFactory::initializeWithProcessID(parameters.processIdentifier->toUInt64());
|
|
}
|
|
|
|
void WebProcess::initializeConnection(IPC::Connection* connection)
|
|
@@ -953,6 +964,7 @@ void WebProcess::createWebPage(PageIdentifier pageID, WebPageCreationParameters&
|
|
accessibilityRelayProcessSuspended(false);
|
|
}
|
|
ASSERT(result.iterator->value);
|
|
+ result.iterator->value->didAddWebPageToWebProcess();
|
|
}
|
|
|
|
void WebProcess::removeWebPage(PageIdentifier pageID)
|
|
diff --git a/Source/WebKitLegacy/mac/WebView/WebHTMLView.mm b/Source/WebKitLegacy/mac/WebView/WebHTMLView.mm
|
|
index 60dc8836dbd8ed1f3f4a2e476d91be6ca7ab0840..20dcdedb9e4eb742c213193eddaa947ac10ec219 100644
|
|
--- a/Source/WebKitLegacy/mac/WebView/WebHTMLView.mm
|
|
+++ b/Source/WebKitLegacy/mac/WebView/WebHTMLView.mm
|
|
@@ -4223,7 +4223,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 e3a23565b11b4dc4eafa3616e15d04e528de8f94..366cf2dd2348350b6dd133ce660ca5b1f73d88d3 100644
|
|
--- a/Source/WebKitLegacy/mac/WebView/WebView.mm
|
|
+++ b/Source/WebKitLegacy/mac/WebView/WebView.mm
|
|
@@ -3991,7 +3991,7 @@ + (void)_doNotStartObservingNetworkReachability
|
|
}
|
|
#endif // PLATFORM(IOS_FAMILY)
|
|
|
|
-#if ENABLE(TOUCH_EVENTS)
|
|
+#if ENABLE(IOS_TOUCH_EVENTS)
|
|
|
|
- (NSArray *)_touchEventRegions
|
|
{
|
|
@@ -4033,7 +4033,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/FindLibVPX.cmake b/Source/cmake/FindLibVPX.cmake
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..dd6a53e2d57318489b7e49dd7373706d5d9dc387
|
|
--- /dev/null
|
|
+++ b/Source/cmake/FindLibVPX.cmake
|
|
@@ -0,0 +1,25 @@
|
|
+# Find LibVPX
|
|
+
|
|
+find_package(PkgConfig QUIET)
|
|
+pkg_check_modules(PC_LIBVPX REQUIRED vpx)
|
|
+
|
|
+find_path(LIBVPX_INCLUDE_DIRS
|
|
+ NAMES vpx/vp8.h
|
|
+ HINTS ${PC_LIBVPX_INCLUDEDIR}
|
|
+ ${PC_LIBVPX_INCLUDE_DIRS}
|
|
+)
|
|
+
|
|
+find_library(LIBVPX_LIBRARIES
|
|
+ NAMES vpx
|
|
+ HINTS ${PC_LIBVPX_LIBDIR}
|
|
+ ${PC_LIBVPX_LIBRARY_DIRS}
|
|
+)
|
|
+
|
|
+include(FindPackageHandleStandardArgs)
|
|
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibVPX REQUIRED_VARS LIBVPX_INCLUDE_DIRS LIBVPX_LIBRARIES
|
|
+ VERSION_VAR PC_LIBVPX_VERSION)
|
|
+
|
|
+mark_as_advanced(
|
|
+ LIBVPX_INCLUDE_DIRS
|
|
+ LIBVPX_LIBRARIES
|
|
+)
|
|
diff --git a/Source/cmake/OptionsGTK.cmake b/Source/cmake/OptionsGTK.cmake
|
|
index d46ee01c5af78d95469d7cfdb7144e8863f00d5a..4a6d5d34007183f28853e6c5192f282b3925a7ae 100644
|
|
--- a/Source/cmake/OptionsGTK.cmake
|
|
+++ b/Source/cmake/OptionsGTK.cmake
|
|
@@ -8,6 +8,10 @@ SET_PROJECT_VERSION(2 47 4)
|
|
set(USER_AGENT_BRANDING "" CACHE STRING "Branding to add to user agent string")
|
|
|
|
find_package(GLIB 2.70.0 REQUIRED COMPONENTS gio gio-unix gobject gthread gmodule)
|
|
+
|
|
+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(Libtasn1 REQUIRED)
|
|
@@ -23,6 +27,10 @@ find_package(ZLIB REQUIRED)
|
|
find_package(WebP REQUIRED COMPONENTS demux)
|
|
find_package(ATSPI 2.5.3)
|
|
|
|
+# Playwright begin
|
|
+find_package(LibVPX REQUIRED)
|
|
+# Playwright end
|
|
+
|
|
include(GStreamerDefinitions)
|
|
include(FindGLibCompileResources)
|
|
|
|
@@ -70,6 +78,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)
|
|
@@ -148,6 +160,20 @@ endif ()
|
|
|
|
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_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)
|
|
|
|
# Finalize the value for all options. Do not attempt to use an option before
|
|
diff --git a/Source/cmake/OptionsWPE.cmake b/Source/cmake/OptionsWPE.cmake
|
|
index bb046a1110023fbd6641943d4b677d1fc68cdea5..d34028c618600a172225246db9286e2a7ab1b9eb 100644
|
|
--- a/Source/cmake/OptionsWPE.cmake
|
|
+++ b/Source/cmake/OptionsWPE.cmake
|
|
@@ -22,6 +22,9 @@ find_package(WebP REQUIRED COMPONENTS demux)
|
|
find_package(WPE REQUIRED)
|
|
find_package(ZLIB REQUIRED)
|
|
|
|
+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})
|
|
@@ -84,6 +87,21 @@ if (WPE_VERSION VERSION_GREATER_EQUAL 1.13.90)
|
|
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_GAMEPAD PUBLIC ON)
|
|
endif ()
|
|
|
|
+# 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_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.
|
|
@@ -119,6 +137,11 @@ WEBKIT_OPTION_DEPEND(USE_QT6 ENABLE_WPE_PLATFORM)
|
|
WEBKIT_OPTION_DEPEND(USE_SKIA_OPENTYPE_SVG USE_SKIA)
|
|
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 b43e68ea44419ed9ea7f539df747cff5d9e4bb36..f62b9a303ad3aba3f04220f1ca9dd208cf3380d4 100644
|
|
--- a/Source/cmake/OptionsWin.cmake
|
|
+++ b/Source/cmake/OptionsWin.cmake
|
|
@@ -76,6 +76,27 @@ find_package(ZLIB 1.2.11 REQUIRED)
|
|
find_package(LibPSL 0.20.2 REQUIRED)
|
|
find_package(WebP REQUIRED COMPONENTS demux)
|
|
|
|
+# Playwright begin
|
|
+set(LIBVPX_PACKAGE_PATH "C:\\vcpkg\\packages\\libvpx_x64-windows")
|
|
+file(TO_CMAKE_PATH "${LIBVPX_PACKAGE_PATH}" LIBVPX_PACKAGE_PATH)
|
|
+message(STATUS "Using LIBVPX_PACKAGE_PATH = ${LIBVPX_PACKAGE_PATH}")
|
|
+
|
|
+find_library(LIBVPX_CUSTOM_LIBRARY vpx.lib
|
|
+ HINTS ${LIBVPX_PACKAGE_PATH}/lib
|
|
+ REQUIRED
|
|
+ NO_DEFAULT_PATH
|
|
+)
|
|
+message(STATUS "Found LIBVPX_CUSTOM_LIBRARY = ${LIBVPX_CUSTOM_LIBRARY}")
|
|
+
|
|
+find_path(LIBVPX_CUSTOM_INCLUDE_DIR
|
|
+ NAMES vpx/vp8.h
|
|
+ HINTS ${LIBVPX_PACKAGE_PATH}/include
|
|
+ REQUIRED
|
|
+ NO_DEFAULT_PATH
|
|
+)
|
|
+message(STATUS "Found LIBVPX_CUSTOM_INCLUDE_DIR = ${LIBVPX_CUSTOM_INCLUDE_DIR}")
|
|
+# Playwright end
|
|
+
|
|
WEBKIT_OPTION_BEGIN()
|
|
|
|
# FIXME: Most of these options should not be public.
|
|
@@ -133,6 +154,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 4882f3de3d9cb011a666563f0bc0e142a705518f..d3f674bf78792088a60a631c245a1fa86dca4d53 100644
|
|
--- a/Source/cmake/WebKitCompilerFlags.cmake
|
|
+++ b/Source/cmake/WebKitCompilerFlags.cmake
|
|
@@ -122,7 +122,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)
|
|
if (DEVELOPER_MODE AND DEVELOPER_MODE_FATAL_WARNINGS)
|
|
if (MSVC)
|
|
set(FATAL_WARNINGS_FLAG /WX)
|
|
diff --git a/Tools/DumpRenderTree/DerivedSources.make b/Tools/DumpRenderTree/DerivedSources.make
|
|
index 576835410df6deac60f0158f1d2d1ef1e5f4c78d..9b492cfe5fef8de340a80f2af70a7d68672ef2e4 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_DEFINE_DEPENDENCIES)
|
|
@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 6d48c378699e87f55bbd2550d4971a295b831a24..efb0d8e1e0f7db5d4ce81bc58a97e6c4034ff0b3 100644
|
|
--- a/Tools/MiniBrowser/gtk/BrowserTab.c
|
|
+++ b/Tools/MiniBrowser/gtk/BrowserTab.c
|
|
@@ -117,19 +117,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;
|
|
}
|
|
|
|
@@ -180,6 +199,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);
|
|
@@ -746,6 +770,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);
|
|
@@ -798,6 +823,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..2862876cb515da09db653e71659d64215a636758 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,28 @@ static gboolean browserWindowDeleteEvent(GtkWidget *widget, GdkEventAny* event)
|
|
}
|
|
#endif
|
|
|
|
+#if GTK_CHECK_VERSION(3, 98, 0)
|
|
+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;
|
|
+}
|
|
+#else
|
|
+static void zeroPreferredSize(GtkWidget* widget, gint* minimumSize, gint* naturalSize)
|
|
+{
|
|
+ *minimumSize = 10;
|
|
+ *naturalSize = 10;
|
|
+}
|
|
+#endif
|
|
+
|
|
static void browser_window_class_init(BrowserWindowClass *klass)
|
|
{
|
|
GObjectClass *gobjectClass = G_OBJECT_CLASS(klass);
|
|
@@ -1515,6 +1535,19 @@ 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.
|
|
+#if GTK_CHECK_VERSION(3, 98, 0)
|
|
+ GtkWidgetClass* browserWidgetClass = GTK_WIDGET_CLASS(klass);
|
|
+ browserWidgetClass->measure = zero_widget_measure;
|
|
+#else
|
|
+ GtkWidgetClass* browserWidgetClass = GTK_WIDGET_CLASS(klass);
|
|
+ browserWidgetClass->get_preferred_width = zeroPreferredSize;
|
|
+ browserWidgetClass->get_preferred_height = zeroPreferredSize;
|
|
+#endif
|
|
+// 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 8433f5360dc4a5f43b68b67192fb3d9bf5064cf1..9fa8f53e90fe5a32be1c8e7a9daa64047640e9f6 100644
|
|
--- a/Tools/MiniBrowser/gtk/main.c
|
|
+++ b/Tools/MiniBrowser/gtk/main.c
|
|
@@ -75,9 +75,14 @@ static char* timeZone;
|
|
static gboolean enableITP;
|
|
static gboolean exitAfterLoad;
|
|
static gboolean webProcessCrashed;
|
|
+static gboolean inspectorPipe;
|
|
+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;
|
|
@@ -182,6 +187,10 @@ 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 },
|
|
+ { "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 }
|
|
};
|
|
@@ -739,6 +748,70 @@ static void filterSavedCallback(WebKitUserContentFilterStore *store, GAsyncResul
|
|
g_main_loop_quit(data->mainLoop);
|
|
}
|
|
|
|
+static WebKitSettings* createPlaywrightSettings() {
|
|
+ WebKitSettings* webkitSettings = webkit_settings_new();
|
|
+#if GTK_CHECK_VERSION(3, 98, 0)
|
|
+ // 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);
|
|
+#else
|
|
+ // Playwright: revert to the default state before https://github.com/WebKit/WebKit/commit/a73a25b9ea9229987c8fa7b2e092e6324cb17913
|
|
+ webkit_settings_set_hardware_acceleration_policy(webkitSettings, WEBKIT_HARDWARE_ACCELERATION_POLICY_NEVER);
|
|
+ webkit_settings_set_hardware_acceleration_policy(webkitSettings, WEBKIT_HARDWARE_ACCELERATION_POLICY_ON_DEMAND);
|
|
+#endif
|
|
+ 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(),
|
|
+#if GTK_CHECK_VERSION(3, 98, 0)
|
|
+ "network-session", webkit_web_context_get_network_session_for_automation(context),
|
|
+#else
|
|
+ "is-ephemeral", webkit_web_context_is_ephemeral(context),
|
|
+#endif
|
|
+ "is-controlled-by-automation", TRUE,
|
|
+ NULL));
|
|
+#if GTK_CHECK_VERSION(3, 98, 0)
|
|
+ GtkWidget *newWindow = browser_window_new(NULL, context, webkit_web_context_get_network_session_for_automation(context));
|
|
+#else
|
|
+ GtkWidget *newWindow = browser_window_new(NULL, context);
|
|
+#endif
|
|
+ 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 startup(GApplication *application)
|
|
{
|
|
const char *actionAccels[] = {
|
|
@@ -797,17 +870,30 @@ static void setupDarkMode(GtkSettings *settings)
|
|
|
|
static void activate(GApplication *application, WebKitSettings *webkitSettings)
|
|
{
|
|
+ if (inspectorPipe)
|
|
+ configureBrowserInspectorPipe();
|
|
+
|
|
+ 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 || privateMode || automationMode) {
|
|
networkSession = webkit_network_session_new_ephemeral();
|
|
- else {
|
|
+ } else {
|
|
char *dataDirectory = g_build_filename(g_get_user_data_dir(), "webkitgtk-" WEBKITGTK_API_VERSION, "MiniBrowser", NULL);
|
|
char *cacheDirectory = g_build_filename(g_get_user_cache_dir(), "webkitgtk-" WEBKITGTK_API_VERSION, "MiniBrowser", NULL);
|
|
networkSession = webkit_network_session_new(dataDirectory, cacheDirectory);
|
|
@@ -815,6 +901,8 @@ static void activate(GApplication *application, WebKitSettings *webkitSettings)
|
|
g_free(cacheDirectory);
|
|
}
|
|
|
|
+ webkit_web_context_set_network_session_for_automation(webContext, networkSession);
|
|
+
|
|
webkit_network_session_set_itp_enabled(networkSession, enableITP);
|
|
|
|
if (!automationMode) {
|
|
@@ -849,9 +937,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 || privateMode || automationMode) {
|
|
manager = webkit_website_data_manager_new_ephemeral();
|
|
- else {
|
|
+ } else {
|
|
char *dataDirectory = g_build_filename(g_get_user_data_dir(), "webkitgtk-" WEBKITGTK_API_VERSION, "MiniBrowser", NULL);
|
|
char *cacheDirectory = 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);
|
|
@@ -901,6 +992,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);
|
|
|
|
@@ -965,9 +1057,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);
|
|
@@ -1017,7 +1107,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);
|
|
@@ -1069,9 +1159,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 f5403031c914d7fedeb4649c4891beb7d681007e..eb1fe97ebb4e55eb1d4443e5f66566471ad9733f 100644
|
|
--- a/Tools/MiniBrowser/wpe/main.cpp
|
|
+++ b/Tools/MiniBrowser/wpe/main.cpp
|
|
@@ -49,6 +49,9 @@ static gboolean headlessMode;
|
|
static gboolean privateMode;
|
|
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;
|
|
@@ -127,6 +130,9 @@ static const GOptionEntry commandLineOptions[] =
|
|
#endif
|
|
{ "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 }
|
|
};
|
|
@@ -285,15 +291,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)
|
|
{
|
|
auto backend = createViewBackend(defaultWindowWidthLegacyAPI, defaultWindowHeightLegacyAPI);
|
|
WebKitWebViewBackend* viewBackend = nullptr;
|
|
@@ -308,12 +337,27 @@ static WebKitWebView* createWebView(WebKitWebView* webView, WebKitNavigationActi
|
|
}, backend.release());
|
|
}
|
|
|
|
- auto* newWebView = WEBKIT_WEB_VIEW(g_object_new(WEBKIT_TYPE_WEB_VIEW,
|
|
- "backend", viewBackend,
|
|
- "related-view", webView,
|
|
- "settings", webkit_web_view_get_settings(webView),
|
|
- "user-content-manager", webkit_web_view_get_user_content_manager(webView),
|
|
- nullptr));
|
|
+// 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,
|
|
+ "backend", viewBackend,
|
|
+ "related-view", webView,
|
|
+ nullptr));
|
|
+ } else {
|
|
+ newWebView = WEBKIT_WEB_VIEW(g_object_new(WEBKIT_TYPE_WEB_VIEW,
|
|
+ "backend", viewBackend,
|
|
+ "web-context", webContext,
|
|
+ "is-controlled-by-automation", TRUE,
|
|
+ nullptr));
|
|
+ }
|
|
|
|
#if ENABLE_WPE_PLATFORM
|
|
if (auto* wpeView = webkit_web_view_get_wpe_view(newWebView)) {
|
|
@@ -328,6 +372,10 @@ static WebKitWebView* createWebView(WebKitWebView* webView, WebKitNavigationActi
|
|
|
|
g_hash_table_add(openViews, newWebView);
|
|
|
|
+ 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);
|
|
return newWebView;
|
|
}
|
|
|
|
@@ -415,13 +463,105 @@ void loadConfigFile(WPESettings* settings)
|
|
}
|
|
#endif
|
|
|
|
+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)
|
|
{
|
|
g_application_hold(application);
|
|
+ if (noStartupWindow)
|
|
+ return;
|
|
#if ENABLE_2022_GLIB_API
|
|
WebKitNetworkSession* networkSession = nullptr;
|
|
if (!automationMode) {
|
|
- networkSession = privateMode ? webkit_network_session_new_ephemeral() : webkit_network_session_new(nullptr, nullptr);
|
|
+ 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 {
|
|
+ networkSession = webkit_network_session_new(nullptr, nullptr);
|
|
+ }
|
|
webkit_network_session_set_itp_enabled(networkSession, enableITP);
|
|
|
|
if (proxy) {
|
|
@@ -448,10 +588,18 @@ static void activate(GApplication* application, WPEToolingBackends::ViewBackend*
|
|
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
|
|
- auto* manager = (privateMode || automationMode) ? webkit_website_data_manager_new_ephemeral() : webkit_website_data_manager_new(nullptr);
|
|
+ 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 {
|
|
+ manager = webkit_website_data_manager_new(NULL);
|
|
+ }
|
|
webkit_website_data_manager_set_itp_enabled(manager, enableITP);
|
|
|
|
if (proxy) {
|
|
@@ -482,6 +630,7 @@ static void activate(GApplication* application, WPEToolingBackends::ViewBackend*
|
|
}
|
|
#endif
|
|
|
|
+ persistentWebContext = webContext;
|
|
WebKitUserContentManager* userContentManager = nullptr;
|
|
if (contentFilter) {
|
|
GFile* contentFilterFile = g_file_new_for_commandline_arg(contentFilter);
|
|
@@ -560,6 +709,15 @@ static void activate(GApplication* application, WPEToolingBackends::ViewBackend*
|
|
"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,
|
|
"backend", viewBackend,
|
|
"web-context", webContext,
|
|
@@ -606,8 +764,6 @@ static void activate(GApplication* application, WPEToolingBackends::ViewBackend*
|
|
}
|
|
#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);
|
|
@@ -619,16 +775,11 @@ static void activate(GApplication* application, WPEToolingBackends::ViewBackend*
|
|
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);
|
|
@@ -725,8 +876,14 @@ int main(int argc, char *argv[])
|
|
}
|
|
}
|
|
|
|
+ openViews = g_hash_table_new_full(nullptr, nullptr, g_object_unref, nullptr);
|
|
+
|
|
GApplication* application = g_application_new("org.wpewebkit.MiniBrowser", G_APPLICATION_NON_UNIQUE);
|
|
g_signal_connect(application, "activate", G_CALLBACK(activate), backend.release());
|
|
+
|
|
+ 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/build-webkit b/Tools/Scripts/build-webkit
|
|
index ad5ecfe242d13ef1b363215361ae15091a3ffd2a..417325f1742625caf6aff22c9d0b1f5ac061743b 100755
|
|
--- a/Tools/Scripts/build-webkit
|
|
+++ b/Tools/Scripts/build-webkit
|
|
@@ -273,7 +273,7 @@ if (isAppleCocoaWebKit()) {
|
|
push @projects, ("Source/WebKit");
|
|
|
|
if (!isEmbeddedWebKit()) {
|
|
- push @projects, ("Tools/MiniBrowser");
|
|
+ push @projects, ("Tools/Playwright");
|
|
|
|
# WebInspectorUI must come after JavaScriptCore and WebCore but before WebKit and WebKit2
|
|
my $webKitIndex = first { $projects[$_] eq "Source/WebKitLegacy" } 0..$#projects;
|
|
diff --git a/Tools/WebKitTestRunner/CMakeLists.txt b/Tools/WebKitTestRunner/CMakeLists.txt
|
|
index 9e53f459e444b9c10fc5248f0e8059df6c1e0041..c17c875a7dd3ca05c4489578ab32378bca45a7c9 100644
|
|
--- a/Tools/WebKitTestRunner/CMakeLists.txt
|
|
+++ b/Tools/WebKitTestRunner/CMakeLists.txt
|
|
@@ -95,6 +95,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 ea8a7dc0d6b63e28ca39e8ecb77fa6c2c3889d32..b3c292fb5db977649e90fbc598626d27ab39a349 100644
|
|
--- a/Tools/WebKitTestRunner/TestController.cpp
|
|
+++ b/Tools/WebKitTestRunner/TestController.cpp
|
|
@@ -1087,6 +1087,7 @@ void TestController::createWebViewWithOptions(const TestOptions& options)
|
|
0, // requestStorageAccessConfirm
|
|
shouldAllowDeviceOrientationAndMotionAccess,
|
|
runWebAuthenticationPanel,
|
|
+ 0, // handleJavaScriptDialog
|
|
0,
|
|
decidePolicyForMediaKeySystemPermissionRequest,
|
|
queryPermission,
|
|
diff --git a/Tools/WebKitTestRunner/mac/EventSenderProxy.mm b/Tools/WebKitTestRunner/mac/EventSenderProxy.mm
|
|
index 0435d345aadde9eaa3a4b7e8625e0872db8c1840..856c36909fd15a178bf1e929aec3d391196f7d36 100644
|
|
--- a/Tools/WebKitTestRunner/mac/EventSenderProxy.mm
|
|
+++ b/Tools/WebKitTestRunner/mac/EventSenderProxy.mm
|
|
@@ -961,4 +961,51 @@ void EventSenderProxy::waitForPendingMouseEvents()
|
|
}
|
|
}
|
|
|
|
+#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 3a0b7425900b14ce2aa0d48aa914cd69bff1f332..22fb1ab2ea76e1e253c79ba1fa3fa448f7584b43 100644
|
|
--- a/Tools/jhbuild/jhbuild-minimal.modules
|
|
+++ b/Tools/jhbuild/jhbuild-minimal.modules
|
|
@@ -67,8 +67,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">
|
|
@@ -77,8 +77,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>
|
|
|
|
@@ -186,7 +186,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"/>
|
|
diff --git a/Tools/wpe/backends/fdo/HeadlessViewBackendFdo.cpp b/Tools/wpe/backends/fdo/HeadlessViewBackendFdo.cpp
|
|
index df22308266c6f69d24a60905f8d05e4e80f21b9b..2d0838070dc10793418cbb648b095a5ffa76f1b8 100644
|
|
--- a/Tools/wpe/backends/fdo/HeadlessViewBackendFdo.cpp
|
|
+++ b/Tools/wpe/backends/fdo/HeadlessViewBackendFdo.cpp
|
|
@@ -210,32 +210,30 @@ void HeadlessViewBackend::updateSnapshot(PlatformBuffer exportedBuffer)
|
|
return;
|
|
}
|
|
|
|
+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;
|
|
+}
|
|
+
|
|
#if defined(USE_CAIRO) && USE_CAIRO
|
|
- uint32_t bufferStride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, m_width);
|
|
+ uint32_t bufferStride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width);
|
|
#elif defined(USE_SKIA) && USE_SKIA
|
|
- auto info = SkImageInfo::MakeN32Premul(m_width, m_height, SkColorSpace::MakeSRGB());
|
|
+ auto info = SkImageInfo::MakeN32Premul(width, height, SkColorSpace::MakeSRGB());
|
|
uint32_t bufferStride = info.minRowBytes();
|
|
#endif
|
|
- 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);
|
|
}
|
|
|
|
@@ -244,7 +242,7 @@ void HeadlessViewBackend::updateSnapshot(PlatformBuffer exportedBuffer)
|
|
cairo_surface_destroy(m_snapshot);
|
|
|
|
m_snapshot = cairo_image_surface_create_for_data(buffer, CAIRO_FORMAT_ARGB32,
|
|
- m_width, m_height, cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, m_width));
|
|
+ width, height, cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width));
|
|
|
|
static cairo_user_data_key_t bufferKey;
|
|
cairo_surface_set_user_data(m_snapshot, &bufferKey, buffer,
|
|
diff --git a/WebKit.xcworkspace/contents.xcworkspacedata b/WebKit.xcworkspace/contents.xcworkspacedata
|
|
index a0f02e61be7e667c6ba164ca578109af36ac28d9..8f5af2e82c167ba6798fb7fde24a9f641f6554a5 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 ded307890926eaf0ca169aaef39ea08bd982a47a..2db0c0abdda702fdff9314ba341b63c5d09289bc 100644
|
|
--- a/WebKit.xcworkspace/xcshareddata/xcschemes/Everything up to WebKit + Tools.xcscheme
|
|
+++ b/WebKit.xcworkspace/xcshareddata/xcschemes/Everything up to WebKit + Tools.xcscheme
|
|
@@ -188,6 +188,20 @@
|
|
ReferencedContainer = "container:Tools/MobileMiniBrowser/MobileMiniBrowser.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"
|