mirror of
https://github.com/microsoft/playwright.git
synced 2024-12-15 22:22:53 +03:00
17056 lines
760 KiB
Diff
17056 lines
760 KiB
Diff
diff --git a/Source/JavaScriptCore/CMakeLists.txt b/Source/JavaScriptCore/CMakeLists.txt
|
|
index 5b4c5848c58ca66bc656edaa8ff3c9cff7ecf01f..4828a53bf575407e3bd29016f6b820c8d71dd427 100644
|
|
--- a/Source/JavaScriptCore/CMakeLists.txt
|
|
+++ b/Source/JavaScriptCore/CMakeLists.txt
|
|
@@ -1171,22 +1171,27 @@ 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/Database.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.make b/Source/JavaScriptCore/DerivedSources.make
|
|
index 9a9eae93f69c7faaadf2b25c7d26aa99a6d588bf..5732b5f68f1d1db5dcd27b2bd65727114973a320 100644
|
|
--- a/Source/JavaScriptCore/DerivedSources.make
|
|
+++ b/Source/JavaScriptCore/DerivedSources.make
|
|
@@ -265,22 +265,27 @@ 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/Database.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/bindings/ScriptValue.cpp b/Source/JavaScriptCore/bindings/ScriptValue.cpp
|
|
index 7968b90a73b282df5982256a6edcb2d6e574396e..6cc034017ae9b2f35c9c526633052586db920ee4 100644
|
|
--- a/Source/JavaScriptCore/bindings/ScriptValue.cpp
|
|
+++ b/Source/JavaScriptCore/bindings/ScriptValue.cpp
|
|
@@ -79,7 +79,10 @@ static RefPtr<JSON::Value> jsToInspectorValue(JSGlobalObject* globalObject, JSVa
|
|
PropertyNameArray propertyNames(vm, PropertyNameMode::Strings, PrivateSymbolMode::Exclude);
|
|
object.methodTable(vm)->getOwnPropertyNames(&object, globalObject, propertyNames, EnumerationMode());
|
|
for (auto& name : propertyNames) {
|
|
- auto inspectorValue = jsToInspectorValue(globalObject, object.get(globalObject, name), maxDepth);
|
|
+ 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/IdentifiersFactory.cpp b/Source/JavaScriptCore/inspector/IdentifiersFactory.cpp
|
|
index 95cd87b01b15cb8667e57bc5bb51a71f06bc3760..0481fa93227f297be9d9cf000c5a72235956a390 100644
|
|
--- a/Source/JavaScriptCore/inspector/IdentifiersFactory.cpp
|
|
+++ b/Source/JavaScriptCore/inspector/IdentifiersFactory.cpp
|
|
@@ -30,14 +30,21 @@
|
|
namespace Inspector {
|
|
|
|
namespace {
|
|
+static uint64_t s_processID = 0;
|
|
static long s_lastUsedIdentifier = 0;
|
|
}
|
|
|
|
static String addPrefixToIdentifier(const String& identifier)
|
|
{
|
|
- return makeString("0.", identifier);
|
|
+ return makeString(s_processID, ".", identifier);
|
|
}
|
|
|
|
+void IdentifiersFactory::initializeWithProcessID(uint64_t processID) {
|
|
+ ASSERT(!s_processID);
|
|
+ s_processID = processID;
|
|
+}
|
|
+
|
|
+
|
|
String IdentifiersFactory::createIdentifier()
|
|
{
|
|
return addPrefixToIdentifier(String::number(++s_lastUsedIdentifier));
|
|
diff --git a/Source/JavaScriptCore/inspector/IdentifiersFactory.h b/Source/JavaScriptCore/inspector/IdentifiersFactory.h
|
|
index eb25aedee4cd9ebe007e06c2515b37ee095b06f4..badf6559595c8377db1089ca3c25008e1be2c8f1 100644
|
|
--- a/Source/JavaScriptCore/inspector/IdentifiersFactory.h
|
|
+++ b/Source/JavaScriptCore/inspector/IdentifiersFactory.h
|
|
@@ -31,6 +31,7 @@ namespace Inspector {
|
|
|
|
class JS_EXPORT_PRIVATE IdentifiersFactory {
|
|
public:
|
|
+ static void initializeWithProcessID(uint64_t);
|
|
static String createIdentifier();
|
|
static String requestId(unsigned long identifier);
|
|
};
|
|
diff --git a/Source/JavaScriptCore/inspector/InjectedScript.cpp b/Source/JavaScriptCore/inspector/InjectedScript.cpp
|
|
index 6909a339ea2e3de600f55fd6fe4683646171e0a7..0a502d6e6c7efa3195c8aaaaec434a08e7465554 100644
|
|
--- a/Source/JavaScriptCore/inspector/InjectedScript.cpp
|
|
+++ b/Source/JavaScriptCore/inspector/InjectedScript.cpp
|
|
@@ -289,6 +289,10 @@ RefPtr<Protocol::Runtime::RemoteObject> InjectedScript::wrapObject(JSC::JSValue
|
|
auto callResult = callFunctionWithEvalEnabled(wrapFunction);
|
|
if (!callResult)
|
|
return nullptr;
|
|
+ auto callResultValue = callResult.value();
|
|
+ // callResultValue could be missing if the execution was terminated
|
|
+ if (!callResultValue)
|
|
+ return nullptr;
|
|
|
|
auto resultValue = toInspectorValue(globalObject(), callResult.value());
|
|
if (!resultValue)
|
|
diff --git a/Source/JavaScriptCore/inspector/InjectedScriptSource.js b/Source/JavaScriptCore/inspector/InjectedScriptSource.js
|
|
index cd593a24af4fe24ba59577b73b26947765edcc32..1f7a04d72065dbd60761c1a72f3254f953d3b9a9 100644
|
|
--- a/Source/JavaScriptCore/inspector/InjectedScriptSource.js
|
|
+++ b/Source/JavaScriptCore/inspector/InjectedScriptSource.js
|
|
@@ -136,7 +136,7 @@ let InjectedScript = class InjectedScript
|
|
return;
|
|
}
|
|
|
|
- if (!(promiseObject instanceof Promise)) {
|
|
+ if (InjectedScriptHost.internalConstructorName(promiseObject) !== 'Promise') {
|
|
callback("Object with given id is not a Promise");
|
|
return;
|
|
}
|
|
diff --git a/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.cpp b/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.cpp
|
|
index 033a1b4713352777ee0de5ed53e64f8391f9d74f..fc356dec4b1518547a4217def6a7b5f1d97330fb 100644
|
|
--- a/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.cpp
|
|
+++ b/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.cpp
|
|
@@ -101,7 +101,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);
|
|
|
|
@@ -146,6 +146,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<Optional<long>> scopedRequestId(m_currentRequestId, requestId);
|
|
diff --git a/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.h b/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.h
|
|
index 8a5efb316e9d09337ada2323dc6f926056a9c2f9..f3dcc8fcc087f474abc88cea837d11ff3e5faeff 100644
|
|
--- a/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.h
|
|
+++ b/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.h
|
|
@@ -84,7 +84,10 @@ public:
|
|
};
|
|
|
|
void registerDispatcherForDomain(const String& domain, SupplementalBackendDispatcher*);
|
|
- void dispatch(const String& message);
|
|
+
|
|
+ enum class InterceptionResult { Intercepted, Continue };
|
|
+ using Interceptor = WTF::Function<InterceptionResult(const RefPtr<JSON::Object>&)>;
|
|
+ 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 4b95964db4d902b4b7f4b0b4c40afea51654ff2f..966a5927702b65edb343369decafda7fc83eaec7 100644
|
|
--- a/Source/JavaScriptCore/inspector/InspectorTarget.h
|
|
+++ b/Source/JavaScriptCore/inspector/InspectorTarget.h
|
|
@@ -56,8 +56,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"; }
|
|
+ virtual void close(String& error, bool /* runBeforeUnload */) { error = "Target cannot be closed"; }
|
|
|
|
private:
|
|
+ virtual void willResume() { }
|
|
+
|
|
WTF::Function<void()> m_resumeCallback;
|
|
bool m_isPaused { false };
|
|
};
|
|
diff --git a/Source/JavaScriptCore/inspector/agents/InspectorTargetAgent.cpp b/Source/JavaScriptCore/inspector/agents/InspectorTargetAgent.cpp
|
|
index 508eb02ec95c52408384a1e2b77648afd426dd9d..05f483dced4b62ffdd60b0a0447504802e1f5711 100644
|
|
--- a/Source/JavaScriptCore/inspector/agents/InspectorTargetAgent.cpp
|
|
+++ b/Source/JavaScriptCore/inspector/agents/InspectorTargetAgent.cpp
|
|
@@ -87,6 +87,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, 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.");
|
|
@@ -144,7 +172,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)
|
|
@@ -159,6 +197,18 @@ void InspectorTargetAgent::didCommitProvisionalTarget(const String& oldTargetID,
|
|
m_frontendDispatcher->didCommitProvisionalTarget(oldTargetID, committedTargetID);
|
|
}
|
|
|
|
+void InspectorTargetAgent::ensureConnected(const String& targetID)
|
|
+{
|
|
+ if (!m_isConnected)
|
|
+ return;
|
|
+
|
|
+ auto* target = m_targets.get(targetID);
|
|
+ if (!target)
|
|
+ return;
|
|
+
|
|
+ target->connect(connectionType());
|
|
+}
|
|
+
|
|
FrontendChannel::ConnectionType InspectorTargetAgent::connectionType() const
|
|
{
|
|
return m_router.hasLocalFrontend() ? Inspector::FrontendChannel::ConnectionType::Local : Inspector::FrontendChannel::ConnectionType::Remote;
|
|
diff --git a/Source/JavaScriptCore/inspector/agents/InspectorTargetAgent.h b/Source/JavaScriptCore/inspector/agents/InspectorTargetAgent.h
|
|
index edcd489b76e080827e0741f14bab09f9ea9303d4..25a20c38575604ca1702a23ccf55c2024a07d993 100644
|
|
--- a/Source/JavaScriptCore/inspector/agents/InspectorTargetAgent.h
|
|
+++ b/Source/JavaScriptCore/inspector/agents/InspectorTargetAgent.h
|
|
@@ -43,22 +43,28 @@ public:
|
|
~InspectorTargetAgent();
|
|
|
|
// InspectorAgentBase
|
|
- void didCreateFrontendAndBackend(FrontendRouter*, BackendDispatcher*);
|
|
- void willDestroyFrontendAndBackend(DisconnectReason);
|
|
+ void didCreateFrontendAndBackend(FrontendRouter*, BackendDispatcher*) override;
|
|
+ void willDestroyFrontendAndBackend(DisconnectReason) override;
|
|
|
|
// TargetBackendDispatcherHandler
|
|
- Protocol::ErrorStringOr<void> setPauseOnStart(bool);
|
|
- Protocol::ErrorStringOr<void> resume(const String& targetId);
|
|
- Protocol::ErrorStringOr<void> sendMessageToTarget(const String& targetId, const String& message);
|
|
+ Protocol::ErrorStringOr<void> setPauseOnStart(bool) override;
|
|
+ Protocol::ErrorStringOr<void> resume(const String& targetId) override;
|
|
+ Protocol::ErrorStringOr<void> sendMessageToTarget(const String& targetId, const String& message) override;
|
|
+ Protocol::ErrorStringOr<void> activate(const String& targetId) override;
|
|
+ Protocol::ErrorStringOr<void> close(const String& targetId, Optional<bool>&& runBeforeUnload) override;
|
|
|
|
// Target lifecycle.
|
|
void targetCreated(InspectorTarget&);
|
|
void targetDestroyed(InspectorTarget&);
|
|
+ void targetCrashed(InspectorTarget&);
|
|
void didCommitProvisionalTarget(const String& oldTargetID, const String& committedTargetID);
|
|
+ void ensureConnected(const String& targetID);
|
|
|
|
// Target messages.
|
|
void sendMessageFromTargetToFrontend(const String& targetId, const String& message);
|
|
|
|
+ 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 998bc4afe68ec70502a009b7bf5ed1de9758ab31..e50d833cee34a9d0a8349b193ced87dc10d93381 100644
|
|
--- a/Source/JavaScriptCore/inspector/protocol/DOM.json
|
|
+++ b/Source/JavaScriptCore/inspector/protocol/DOM.json
|
|
@@ -79,6 +79,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",
|
|
@@ -167,6 +177,16 @@
|
|
{ "name": "borderColor", "$ref": "RGBAColor", "optional": true, "description": "The border highlight fill color (default: transparent)." },
|
|
{ "name": "marginColor", "$ref": "RGBAColor", "optional": true, "description": "The margin highlight fill color (default: transparent)." }
|
|
]
|
|
+ },
|
|
+ {
|
|
+ "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": [
|
|
@@ -509,7 +529,9 @@
|
|
"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": "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": [
|
|
@@ -576,6 +598,45 @@
|
|
"parameters": [
|
|
{ "name": "allow", "type": "boolean" }
|
|
]
|
|
+ },
|
|
+ {
|
|
+ "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" }, "description": "Files to set" }
|
|
+ ]
|
|
}
|
|
],
|
|
"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..3f28f8e41b39c517369c8ca69415486a75657489
|
|
--- /dev/null
|
|
+++ b/Source/JavaScriptCore/inspector/protocol/Emulation.json
|
|
@@ -0,0 +1,51 @@
|
|
+{
|
|
+ "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": "deviceScaleFactor", "type": "number" },
|
|
+ { "name": "fixedLayout", "type": "boolean" }
|
|
+ ]
|
|
+ },
|
|
+ {
|
|
+ "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": "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."
|
|
+ }
|
|
+ ]
|
|
+}
|
|
diff --git a/Source/JavaScriptCore/inspector/protocol/Input.json b/Source/JavaScriptCore/inspector/protocol/Input.json
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..587287d52fde2735cbae34a27a0f673b7e38e1a7
|
|
--- /dev/null
|
|
+++ b/Source/JavaScriptCore/inspector/protocol/Input.json
|
|
@@ -0,0 +1,188 @@
|
|
+{
|
|
+ "domain": "Input",
|
|
+ "availability": ["web"],
|
|
+ "types": [
|
|
+ {
|
|
+ "id": "TimeSinceEpoch",
|
|
+ "description": "UTC time in seconds, counted from January 1, 1970.",
|
|
+ "type": "number"
|
|
+ }
|
|
+ ],
|
|
+ "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": "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"
|
|
+ }
|
|
+ ]
|
|
+ }
|
|
+ ]
|
|
+}
|
|
diff --git a/Source/JavaScriptCore/inspector/protocol/Network.json b/Source/JavaScriptCore/inspector/protocol/Network.json
|
|
index 65ab2092b0ffd0ead3da1ddccd398d4f4179f51a..2d9ef40a20df819193c9a5867fbf6f8f8bf46b48 100644
|
|
--- a/Source/JavaScriptCore/inspector/protocol/Network.json
|
|
+++ b/Source/JavaScriptCore/inspector/protocol/Network.json
|
|
@@ -321,6 +321,13 @@
|
|
{ "name": "requestId", "$ref": "RequestId", "description": "Identifier for the intercepted Network request to fail." },
|
|
{ "name": "errorType", "$ref": "ResourceErrorType", "description": "Deliver error reason for the request failure." }
|
|
]
|
|
+ },
|
|
+ {
|
|
+ "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 fde4f6964d40e8a565116be2bc692a451c2da106..a1ccbc2c6df9d938d30614e15239bb5000a874ff 100644
|
|
--- a/Source/JavaScriptCore/inspector/protocol/Page.json
|
|
+++ b/Source/JavaScriptCore/inspector/protocol/Page.json
|
|
@@ -27,7 +27,7 @@
|
|
{
|
|
"id": "ResourceType",
|
|
"type": "string",
|
|
- "enum": ["Document", "StyleSheet", "Image", "Font", "Script", "XHR", "Fetch", "Ping", "Beacon", "WebSocket", "Other"],
|
|
+ "enum": ["Document", "StyleSheet", "Image", "Font", "Script", "XHR", "Fetch", "Ping", "Beacon", "WebSocket", "EventSource", "Other"],
|
|
"description": "Resource type as it was perceived by the rendering engine."
|
|
},
|
|
{
|
|
@@ -112,6 +112,41 @@
|
|
{ "name": "secure", "type": "boolean", "description": "True if cookie is secure." },
|
|
{ "name": "sameSite", "$ref": "CookieSameSitePolicy", "description": "Cookie Same-Site policy." }
|
|
]
|
|
+ },
|
|
+ {
|
|
+ "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": "multiline", "type": "boolean", "optional": true, "description": "Whether the node text input supports multiline."},
|
|
+ { "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."}
|
|
+ ]
|
|
}
|
|
],
|
|
"commands": [
|
|
@@ -131,6 +166,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.",
|
|
@@ -270,6 +313,20 @@
|
|
{ "name": "appearance", "$ref": "Appearance", "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.",
|
|
@@ -304,6 +361,70 @@
|
|
"returns": [
|
|
{ "name": "data", "type": "string", "description": "Base64-encoded web archive." }
|
|
]
|
|
+ },
|
|
+ {
|
|
+ "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": "setScreenSizeOverride",
|
|
+ "description": "Overrides screen size with provided values.",
|
|
+ "parameters": [
|
|
+ { "name": "width", "type": "integer" },
|
|
+ { "name": "height", "type": "integer" }
|
|
+ ]
|
|
+ },
|
|
+ {
|
|
+ "name": "setOrientationOverride",
|
|
+ "description": "Overrides window.orientation with provided value.",
|
|
+ "parameters": [
|
|
+ { "name": "angle", "type": "integer", "optional": true }
|
|
+ ]
|
|
}
|
|
],
|
|
"events": [
|
|
@@ -311,14 +432,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." }
|
|
]
|
|
},
|
|
{
|
|
@@ -328,6 +451,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.",
|
|
@@ -367,6 +498,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": "defaultAppearanceDidChange",
|
|
"description": "Fired when page's default appearance changes, even if there is a forced appearance.",
|
|
@@ -375,6 +522,28 @@
|
|
"parameters": [
|
|
{ "name": "appearance", "$ref": "Appearance", "description": "Name of the appearance that is active (not considering any forced appearance.)" }
|
|
]
|
|
+ },
|
|
+ {
|
|
+ "name": "willRequestOpenWindow",
|
|
+ "description": "Fired when page tries to open a new window.",
|
|
+ "parameters": [
|
|
+ { "name": "url", "type": "string" }
|
|
+ ]
|
|
+ },
|
|
+ {
|
|
+ "name": "didRequestOpenWindow",
|
|
+ "description": "Fired after page did try to open a new window.",
|
|
+ "parameters": [
|
|
+ { "name": "opened", "type": "boolean" }
|
|
+ ]
|
|
+ },
|
|
+ {
|
|
+ "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..ce69bc6a10b49460c73110e54b2936afe5dd4ebf
|
|
--- /dev/null
|
|
+++ b/Source/JavaScriptCore/inspector/protocol/Playwright.json
|
|
@@ -0,0 +1,244 @@
|
|
+{
|
|
+ "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": "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": "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": "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": "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." }
|
|
+ ]
|
|
+ }
|
|
+ ],
|
|
+ "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/Screencast.json b/Source/JavaScriptCore/inspector/protocol/Screencast.json
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..a51b42b2a2b575927509e11dc7241ab6f203c104
|
|
--- /dev/null
|
|
+++ b/Source/JavaScriptCore/inspector/protocol/Screencast.json
|
|
@@ -0,0 +1,31 @@
|
|
+{
|
|
+ "domain": "Screencast",
|
|
+ "availability": ["web"],
|
|
+ "types": [
|
|
+ {
|
|
+ "id": "ScreencastId",
|
|
+ "type": "string",
|
|
+ "description": "Unique identifier of the screencast."
|
|
+ }
|
|
+ ],
|
|
+ "commands": [
|
|
+ {
|
|
+ "name": "start",
|
|
+ "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": "scale", "type": "number", "optional": true }
|
|
+ ],
|
|
+ "returns": [
|
|
+ { "name": "screencastId", "$ref": "ScreencastId", "description": "Unique identifier of the screencast." }
|
|
+ ]
|
|
+ },
|
|
+ {
|
|
+ "name": "stop",
|
|
+ "async": true,
|
|
+ "description": "Stops recoding video. Returns after the file has been closed."
|
|
+ }
|
|
+ ]
|
|
+}
|
|
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/inspector/protocol/Worker.json b/Source/JavaScriptCore/inspector/protocol/Worker.json
|
|
index 638612413466efc87b737e8a81042ed07ca12703..6f9e518ff0bfa2a6228675d25b6b785f1ed3022a 100644
|
|
--- a/Source/JavaScriptCore/inspector/protocol/Worker.json
|
|
+++ b/Source/JavaScriptCore/inspector/protocol/Worker.json
|
|
@@ -16,7 +16,7 @@
|
|
"description": "Sent after the frontend has sent all initialization messages and can resume this worker. This command is required to allow execution in the worker.",
|
|
"parameters": [
|
|
{ "name": "workerId", "type": "string" }
|
|
- ]
|
|
+ ]
|
|
},
|
|
{
|
|
"name": "sendMessageToWorker",
|
|
@@ -33,7 +33,8 @@
|
|
"parameters": [
|
|
{ "name": "workerId", "type": "string" },
|
|
{ "name": "url", "type": "string" },
|
|
- { "name": "name", "type": "string" }
|
|
+ { "name": "name", "type": "string" },
|
|
+ { "name": "frameId", "$ref": "Network.FrameId", "description": "Id of the frame this worker belongs to." }
|
|
]
|
|
},
|
|
{
|
|
diff --git a/Source/JavaScriptCore/runtime/DateConversion.cpp b/Source/JavaScriptCore/runtime/DateConversion.cpp
|
|
index 955756ba405f400970610f9a68c7ed42a67cb015..1520c0a1475a90de2795e4ccd8919c1bb1384066 100644
|
|
--- a/Source/JavaScriptCore/runtime/DateConversion.cpp
|
|
+++ b/Source/JavaScriptCore/runtime/DateConversion.cpp
|
|
@@ -100,17 +100,23 @@ String formatDateTime(const GregorianDateTime& t, DateTimeFormat format, bool as
|
|
appendNumber<2>(builder, offset / 60);
|
|
appendNumber<2>(builder, offset % 60);
|
|
|
|
-#if OS(WINDOWS)
|
|
- TIME_ZONE_INFORMATION timeZoneInformation;
|
|
- GetTimeZoneInformation(&timeZoneInformation);
|
|
- const WCHAR* winTimeZoneName = t.isDST() ? timeZoneInformation.DaylightName : timeZoneInformation.StandardName;
|
|
- String timeZoneName(winTimeZoneName);
|
|
+ String timeZoneName;
|
|
+ if (!WTF::timeZoneDisplayNameForAutomation().isEmpty()) {
|
|
+ timeZoneName = WTF::timeZoneDisplayNameForAutomation();
|
|
+ } else {
|
|
+ #if OS(WINDOWS)
|
|
+ TIME_ZONE_INFORMATION timeZoneInformation;
|
|
+ GetTimeZoneInformation(&timeZoneInformation);
|
|
+ const WCHAR* winTimeZoneName = t.isDST() ? timeZoneInformation.DaylightName : timeZoneInformation.StandardName;
|
|
+ timeZoneName = String(winTimeZoneName);
|
|
#else
|
|
- struct tm gtm = t;
|
|
- char timeZoneName[70];
|
|
- strftime(timeZoneName, sizeof(timeZoneName), "%Z", >m);
|
|
+ struct tm gtm = t;
|
|
+ char tzName[70];
|
|
+ strftime(tzName, sizeof(tzName), "%Z", >m);
|
|
+ timeZoneName = String(tzName);
|
|
#endif
|
|
- if (timeZoneName[0]) {
|
|
+ }
|
|
+ if (!timeZoneName.isEmpty()) {
|
|
builder.appendLiteral(" (");
|
|
builder.append(timeZoneName);
|
|
builder.append(')');
|
|
diff --git a/Source/JavaScriptCore/runtime/IntlDateTimeFormat.cpp b/Source/JavaScriptCore/runtime/IntlDateTimeFormat.cpp
|
|
index f51cb02ee88d86c997a2332c5cc0d01b4641be1c..342ad6b5402afaa7883e3656d15641667ff45edd 100644
|
|
--- a/Source/JavaScriptCore/runtime/IntlDateTimeFormat.cpp
|
|
+++ b/Source/JavaScriptCore/runtime/IntlDateTimeFormat.cpp
|
|
@@ -34,6 +34,7 @@
|
|
#include "ObjectConstructor.h"
|
|
#include <unicode/ucal.h>
|
|
#include <unicode/uenum.h>
|
|
+#include <wtf/DateMath.h>
|
|
#include <wtf/text/StringBuilder.h>
|
|
#include <wtf/unicode/icu/ICUHelpers.h>
|
|
|
|
@@ -93,6 +94,10 @@ static ALWAYS_INLINE bool isUTCEquivalent(StringView timeZone)
|
|
// https://tc39.es/ecma402/#sec-defaulttimezone
|
|
static String defaultTimeZone()
|
|
{
|
|
+ String tz = WTF::timeZoneForAutomation();
|
|
+ if (!tz.isEmpty())
|
|
+ return tz;
|
|
+
|
|
String canonical;
|
|
|
|
Vector<UChar, 32> buffer;
|
|
diff --git a/Source/ThirdParty/libwebrtc/CMakeLists.txt b/Source/ThirdParty/libwebrtc/CMakeLists.txt
|
|
index 70ccc9bd0e1d8d57cbfdc5fea72fe9aae5203864..90027ec135a7f42068f501138d5cf15f609abb17 100644
|
|
--- a/Source/ThirdParty/libwebrtc/CMakeLists.txt
|
|
+++ b/Source/ThirdParty/libwebrtc/CMakeLists.txt
|
|
@@ -292,6 +292,11 @@ set(webrtc_SOURCES
|
|
Source/third_party/jsoncpp/source/src/lib_json/json_reader.cpp
|
|
Source/third_party/jsoncpp/source/src/lib_json/json_value.cpp
|
|
Source/third_party/jsoncpp/source/src/lib_json/json_writer.cpp
|
|
+# 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
|
|
@@ -1467,6 +1472,9 @@ target_include_directories(webrtc PRIVATE
|
|
Source/third_party/libsrtp/config
|
|
Source/third_party/libsrtp/crypto/include
|
|
Source/third_party/libsrtp/include
|
|
+# Playwright begin
|
|
+ Source/third_party/libwebm
|
|
+# 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/libwebrtc.mac.exp b/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.mac.exp
|
|
index 5af5b06e4e3c41c708b5e75cb9fb918245a80e77..5fc27a4400a712f2289b6a586b3f10c11d6eb940 100644
|
|
--- a/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.mac.exp
|
|
+++ b/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.mac.exp
|
|
@@ -327,3 +327,23 @@ __ZN6webrtc14ParseCandidateERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9a
|
|
__ZN7cricket27ICE_CANDIDATE_COMPONENT_RTPE
|
|
__ZNK3rtc13SocketAddress5IsNilEv
|
|
__ZN6webrtc23isMatchingBundleVersionEPKc
|
|
+__ZN8mkvmuxer11SegmentInfo15set_writing_appEPKc
|
|
+__ZN8mkvmuxer11SegmentInfo4InitEv
|
|
+__ZN8mkvmuxer7Segment10OutputCuesEb
|
|
+__ZN8mkvmuxer7Segment13AddVideoTrackEiii
|
|
+__ZN8mkvmuxer7Segment4InitEPNS_10IMkvWriterE
|
|
+__ZN8mkvmuxer7Segment8AddFrameEPKhyyyb
|
|
+__ZN8mkvmuxer7Segment8FinalizeEv
|
|
+__ZN8mkvmuxer7SegmentC1Ev
|
|
+__ZN8mkvmuxer7SegmentD1Ev
|
|
+__ZN8mkvmuxer9MkvWriterC1EP7__sFILE
|
|
+_ARGBToI420
|
|
+_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/Configurations/libwebrtc.xcconfig b/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.xcconfig
|
|
index d4f74d7584c3270d73c37036ac0daa223f740cd4..5fa5977130542f699cbd0984ac9786d23785aa9d 100644
|
|
--- a/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.xcconfig
|
|
+++ b/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.xcconfig
|
|
@@ -18,7 +18,7 @@ DYLIB_INSTALL_NAME_BASE_WK_RELOCATABLE_FRAMEWORKS_ = $(DYLIB_INSTALL_NAME_BASE);
|
|
DYLIB_INSTALL_NAME_BASE_WK_RELOCATABLE_FRAMEWORKS_YES = @loader_path/../../../;
|
|
|
|
GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
|
|
-HEADER_SEARCH_PATHS = Source Source/third_party/jsoncpp/source/include Source/third_party/libsrtp/crypto/include Source/third_party/libsrtp/include Source/third_party/boringssl/src/include Source/third_party/libyuv/include Source/third_party/usrsctp Source/third_party/usrsctp/usrsctplib Source/third_party/usrsctp/usrsctplib/usrsctplib Source/webrtc/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/third_party/usrsctp/usrsctplib/usrsctplib/netinet Source/webrtc/modules/audio_device/ios Source/webrtc Source/webrtc/sdk/objc Source/webrtc/sdk/objc/base Source/webrtc/sdk/objc/Framework/Classes Source/third_party/libsrtp/config Source/webrtc/sdk/objc/Framework/Classes/Common Source/webrtc/sdk/objc/Framework/Classes/Video Source/webrtc/sdk/objc/Framework/Classes/PeerConnection Source/third_party/abseil-cpp Source/third_party/libvpx/source/libvpx Source/third_party/libwebm/webm_parser/include;
|
|
+HEADER_SEARCH_PATHS = Source Source/third_party/jsoncpp/source/include Source/third_party/libsrtp/crypto/include Source/third_party/libsrtp/include Source/third_party/boringssl/src/include Source/third_party/libyuv/include Source/third_party/usrsctp Source/third_party/usrsctp/usrsctplib Source/third_party/usrsctp/usrsctplib/usrsctplib Source/webrtc/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/third_party/usrsctp/usrsctplib/usrsctplib/netinet Source/webrtc/modules/audio_device/ios Source/webrtc Source/webrtc/sdk/objc Source/webrtc/sdk/objc/base Source/webrtc/sdk/objc/Framework/Classes Source/third_party/libsrtp/config Source/webrtc/sdk/objc/Framework/Classes/Common Source/webrtc/sdk/objc/Framework/Classes/Video Source/webrtc/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/libvpx/source/libvpx/third_party/libwebm;
|
|
|
|
PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/libwebrtc;
|
|
USE_HEADERMAP = NO;
|
|
diff --git a/Source/ThirdParty/libwebrtc/libwebrtc.xcodeproj/project.pbxproj b/Source/ThirdParty/libwebrtc/libwebrtc.xcodeproj/project.pbxproj
|
|
index 4e4a5381f8700d4be3c13e300232227bbc6c1080..e92c0b4662d8dd9c5dafba7fbf43d845e91edfe1 100644
|
|
--- a/Source/ThirdParty/libwebrtc/libwebrtc.xcodeproj/project.pbxproj
|
|
+++ b/Source/ThirdParty/libwebrtc/libwebrtc.xcodeproj/project.pbxproj
|
|
@@ -3888,6 +3888,9 @@
|
|
CDFD2FCD24C4DAF70048DAC3 /* status.h in Copy webm headers */ = {isa = PBXBuildFile; fileRef = CDEBB40624C0191A00ADBD44 /* status.h */; };
|
|
CDFD2FCE24C4DAF70048DAC3 /* webm_parser.h in Copy webm headers */ = {isa = PBXBuildFile; fileRef = CDEBB40824C0191A00ADBD44 /* webm_parser.h */; };
|
|
CDFD2FD024C4DB2F0048DAC3 /* vp9_header_parser.h in Copy common headers */ = {isa = PBXBuildFile; fileRef = CDFD2F9624C4B2F90048DAC3 /* vp9_header_parser.h */; };
|
|
+ F3B7819924C7CC5200FCB122 /* mkvmuxerutil.cc in Sources */ = {isa = PBXBuildFile; fileRef = F3B7819624C7CC5100FCB122 /* mkvmuxerutil.cc */; };
|
|
+ F3B7819A24C7CC5200FCB122 /* mkvmuxer.cc in Sources */ = {isa = PBXBuildFile; fileRef = F3B7819724C7CC5200FCB122 /* mkvmuxer.cc */; };
|
|
+ F3B7819B24C7CC5200FCB122 /* mkvwriter.cc in Sources */ = {isa = PBXBuildFile; fileRef = F3B7819824C7CC5200FCB122 /* mkvwriter.cc */; };
|
|
/* End PBXBuildFile section */
|
|
|
|
/* Begin PBXBuildRule section */
|
|
@@ -8401,6 +8404,9 @@
|
|
CDEBB49D24C0191A00ADBD44 /* master_parser.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = master_parser.h; sourceTree = "<group>"; };
|
|
CDFD2F9624C4B2F90048DAC3 /* vp9_header_parser.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = vp9_header_parser.h; sourceTree = "<group>"; };
|
|
CDFD2F9A24C4B2F90048DAC3 /* vp9_header_parser.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = vp9_header_parser.cc; sourceTree = "<group>"; };
|
|
+ F3B7819624C7CC5100FCB122 /* mkvmuxerutil.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = mkvmuxerutil.cc; path = mkvmuxer/mkvmuxerutil.cc; sourceTree = "<group>"; };
|
|
+ F3B7819724C7CC5200FCB122 /* mkvmuxer.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = mkvmuxer.cc; path = mkvmuxer/mkvmuxer.cc; sourceTree = "<group>"; };
|
|
+ F3B7819824C7CC5200FCB122 /* mkvwriter.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = mkvwriter.cc; path = mkvmuxer/mkvwriter.cc; sourceTree = "<group>"; };
|
|
FB39D0D11200F0E300088E69 /* libwebrtc.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libwebrtc.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
|
|
/* End PBXFileReference section */
|
|
|
|
@@ -15283,6 +15289,7 @@
|
|
isa = PBXGroup;
|
|
children = (
|
|
CDFD2F9224C4B2F90048DAC3 /* common */,
|
|
+ F3B7819524C7CC1300FCB122 /* mkvmuxer */,
|
|
CDEBB19224C0191800ADBD44 /* webm_parser */,
|
|
);
|
|
path = libwebm;
|
|
@@ -15417,6 +15424,16 @@
|
|
path = common;
|
|
sourceTree = "<group>";
|
|
};
|
|
+ F3B7819524C7CC1300FCB122 /* mkvmuxer */ = {
|
|
+ isa = PBXGroup;
|
|
+ children = (
|
|
+ F3B7819724C7CC5200FCB122 /* mkvmuxer.cc */,
|
|
+ F3B7819624C7CC5100FCB122 /* mkvmuxerutil.cc */,
|
|
+ F3B7819824C7CC5200FCB122 /* mkvwriter.cc */,
|
|
+ );
|
|
+ name = mkvmuxer;
|
|
+ sourceTree = "<group>";
|
|
+ };
|
|
FB39D06E1200ED9200088E69 = {
|
|
isa = PBXGroup;
|
|
children = (
|
|
@@ -17527,7 +17544,7 @@
|
|
);
|
|
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\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/webrtc\" \"${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/abseil-cpp/absl\" \"${PRIVATE_HEADERS_PATH}\"\n";
|
|
+ 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\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/webrtc\" \"${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/abseil-cpp/absl\" \"${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";
|
|
};
|
|
5CD286461E6E154E0094FDC8 /* Check for Weak VTables and Externals */ = {
|
|
isa = PBXShellScriptBuildPhase;
|
|
@@ -18676,6 +18693,7 @@
|
|
419C82F51FE20EB50040C30F /* audio_encoder_opus.cc in Sources */,
|
|
419C82F31FE20EB50040C30F /* audio_encoder_opus_config.cc in Sources */,
|
|
4140B8201E4E3383007409E6 /* audio_encoder_pcm.cc in Sources */,
|
|
+ F3B7819A24C7CC5200FCB122 /* mkvmuxer.cc in Sources */,
|
|
5CDD8FFE1E43CE3A00621E92 /* audio_encoder_pcm16b.cc in Sources */,
|
|
5CD285461E6A61D20094FDC8 /* audio_format.cc in Sources */,
|
|
41DDB26F212679D200296D47 /* audio_format_to_string.cc in Sources */,
|
|
@@ -18798,6 +18816,7 @@
|
|
4131C1C0234B8A4A0028A615 /* connection.cc in Sources */,
|
|
4131C1D2234B8A4B0028A615 /* connection_info.cc in Sources */,
|
|
5CDD8A931E43C00F00621E92 /* constant_pcm_packet_source.cc in Sources */,
|
|
+ F3B7819B24C7CC5200FCB122 /* mkvwriter.cc in Sources */,
|
|
5CDD8B891E43C2B500621E92 /* constants.c in Sources */,
|
|
4131C291234B8CC40028A615 /* constants.cc in Sources */,
|
|
41FCBB3921B1F8FC00A5DF27 /* control_handler.cc in Sources */,
|
|
@@ -19362,6 +19381,7 @@
|
|
4131C53B234C8B190028A615 /* rtc_event_rtp_packet_outgoing.cc in Sources */,
|
|
4131C552234C8B190028A615 /* rtc_event_video_receive_stream_config.cc in Sources */,
|
|
4131C554234C8B190028A615 /* rtc_event_video_send_stream_config.cc in Sources */,
|
|
+ F3B7819924C7CC5200FCB122 /* mkvmuxerutil.cc in Sources */,
|
|
4131C3CF234B98420028A615 /* rtc_stats.cc in Sources */,
|
|
4131BF2D234B88200028A615 /* rtc_stats_collector.cc in Sources */,
|
|
4131C3CE234B98420028A615 /* rtc_stats_report.cc in Sources */,
|
|
diff --git a/Source/WTF/Scripts/Preferences/WebPreferences.yaml b/Source/WTF/Scripts/Preferences/WebPreferences.yaml
|
|
index aee36b257f4eb5c7fb8db2211ca69ee66b66a68c..d7b03ee0c10ce819894a6b558b84f1ee1f017137 100644
|
|
--- a/Source/WTF/Scripts/Preferences/WebPreferences.yaml
|
|
+++ b/Source/WTF/Scripts/Preferences/WebPreferences.yaml
|
|
@@ -801,7 +801,7 @@ InspectorStartsAttached:
|
|
exposed: [ WebKit ]
|
|
defaultValue:
|
|
WebKit:
|
|
- default: true
|
|
+ default: false
|
|
|
|
InspectorWindowFrame:
|
|
type: String
|
|
diff --git a/Source/WTF/Scripts/Preferences/WebPreferencesExperimental.yaml b/Source/WTF/Scripts/Preferences/WebPreferencesExperimental.yaml
|
|
index 9500726db25da53613193f3db147b2d8e6ae94b4..d4e49342ac322bb0c0bb7f6b4b8c9bb8b9d892e4 100644
|
|
--- a/Source/WTF/Scripts/Preferences/WebPreferencesExperimental.yaml
|
|
+++ b/Source/WTF/Scripts/Preferences/WebPreferencesExperimental.yaml
|
|
@@ -476,7 +476,7 @@ MaskWebGLStringsEnabled:
|
|
WebKitLegacy:
|
|
default: true
|
|
WebKit:
|
|
- default: true
|
|
+ default: false
|
|
|
|
# FIXME: This is on by default in WebKit2. Perhaps we should consider turning it on for WebKitLegacy as well.
|
|
MediaCapabilitiesExtensionsEnabled:
|
|
diff --git a/Source/WTF/wtf/DateMath.cpp b/Source/WTF/wtf/DateMath.cpp
|
|
index af92f674770349cc8e7be9a53b1cee6e7840e781..f0a960db046292a3505d339a333f03098f3d8418 100644
|
|
--- a/Source/WTF/wtf/DateMath.cpp
|
|
+++ b/Source/WTF/wtf/DateMath.cpp
|
|
@@ -76,9 +76,14 @@
|
|
#include <limits>
|
|
#include <stdint.h>
|
|
#include <time.h>
|
|
+#include <unicode/ucal.h>
|
|
#include <wtf/Assertions.h>
|
|
#include <wtf/ASCIICType.h>
|
|
+#include <wtf/Language.h>
|
|
+#include <wtf/NeverDestroyed.h>
|
|
+#include <wtf/ThreadSpecific.h>
|
|
#include <wtf/text/StringBuilder.h>
|
|
+#include <wtf/unicode/UTF8Conversion.h>
|
|
|
|
#if OS(WINDOWS)
|
|
#include <windows.h>
|
|
@@ -92,6 +97,18 @@ template<unsigned length> inline bool startsWithLettersIgnoringASCIICase(const c
|
|
return equalLettersIgnoringASCIICase(string, lowercaseLetters, length - 1);
|
|
}
|
|
|
|
+struct TimeZoneForAutomation {
|
|
+ UCalendar* cal;
|
|
+ String id;
|
|
+ String displayName;
|
|
+};
|
|
+
|
|
+static TimeZoneForAutomation& innerTimeZoneForAutomation()
|
|
+{
|
|
+ static NeverDestroyed<WTF::ThreadSpecific<TimeZoneForAutomation>> timeZoneForAutomation;
|
|
+ return *timeZoneForAutomation.get();
|
|
+}
|
|
+
|
|
/* Constants */
|
|
|
|
const char* const weekdayName[7] = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
|
|
@@ -318,6 +335,14 @@ static double calculateDSTOffset(time_t localTime, double utcOffset)
|
|
// Returns combined offset in millisecond (UTC + DST).
|
|
LocalTimeOffset calculateLocalTimeOffset(double ms, TimeType inputTimeType)
|
|
{
|
|
+ TimeZoneForAutomation& tz = innerTimeZoneForAutomation();
|
|
+ if (tz.cal) {
|
|
+ UErrorCode status = U_ZERO_ERROR;
|
|
+ ucal_setMillis(tz.cal, ms, &status);
|
|
+ int32_t offset = ucal_get(tz.cal, UCAL_ZONE_OFFSET, &status);
|
|
+ int32_t dstOffset = ucal_get(tz.cal, UCAL_DST_OFFSET, &status);
|
|
+ return LocalTimeOffset(dstOffset, offset + dstOffset);
|
|
+ }
|
|
#if HAVE(TM_GMTOFF)
|
|
double localToUTCTimeOffset = inputTimeType == LocalTime ? calculateUTCOffset() : 0;
|
|
#else
|
|
@@ -1019,4 +1044,65 @@ String makeRFC2822DateString(unsigned dayOfWeek, unsigned day, unsigned month, u
|
|
return stringBuilder.toString();
|
|
}
|
|
|
|
+bool setTimeZoneForAutomation(const String& timeZone)
|
|
+{
|
|
+ innerTimeZoneForAutomation().displayName = String();
|
|
+ if (innerTimeZoneForAutomation().cal) {
|
|
+ ucal_close(innerTimeZoneForAutomation().cal);
|
|
+ innerTimeZoneForAutomation().cal = nullptr;
|
|
+ }
|
|
+ if (timeZone.isEmpty()) {
|
|
+ innerTimeZoneForAutomation().id = String();
|
|
+ return true;
|
|
+ }
|
|
+
|
|
+ // Timezone is ascii.
|
|
+ Vector<UChar> buffer(timeZone.length());
|
|
+ UChar* bufferStart = buffer.data();
|
|
+ CString ctz = timeZone.utf8();
|
|
+ if (!Unicode::convertUTF8ToUTF16(ctz.data(), ctz.data() + ctz.length(), &bufferStart, bufferStart + timeZone.length()))
|
|
+ return false;
|
|
+
|
|
+ Vector<UChar, 32> canonicalBuffer(32);
|
|
+ UErrorCode status = U_ZERO_ERROR;
|
|
+ auto canonicalLength = ucal_getCanonicalTimeZoneID(buffer.data(), buffer.size(), canonicalBuffer.data(), canonicalBuffer.size(), nullptr, &status);
|
|
+ if (status == U_BUFFER_OVERFLOW_ERROR) {
|
|
+ status = U_ZERO_ERROR;
|
|
+ canonicalBuffer.grow(canonicalLength);
|
|
+ ucal_getCanonicalTimeZoneID(buffer.data(), buffer.size(), canonicalBuffer.data(), canonicalLength, nullptr, &status);
|
|
+ }
|
|
+ if (!U_SUCCESS(status))
|
|
+ return false;
|
|
+
|
|
+ UCalendar* cal = ucal_open(canonicalBuffer.data(), canonicalLength, nullptr, UCAL_TRADITIONAL, &status);
|
|
+ if (!U_SUCCESS(status))
|
|
+ return false;
|
|
+
|
|
+ Vector<UChar, 32> displayNameBuffer(32);
|
|
+ auto displayNameLength = ucal_getTimeZoneDisplayName(cal, UCAL_STANDARD, defaultLanguage().utf8().data(), displayNameBuffer.data(), displayNameBuffer.size(), &status);
|
|
+ if (status == U_BUFFER_OVERFLOW_ERROR) {
|
|
+ status = U_ZERO_ERROR;
|
|
+ displayNameBuffer.grow(displayNameLength);
|
|
+ ucal_getTimeZoneDisplayName(cal, UCAL_STANDARD, defaultLanguage().utf8().data(), displayNameBuffer.data(), displayNameLength, &status);
|
|
+ }
|
|
+ if (!U_SUCCESS(status))
|
|
+ return false;
|
|
+
|
|
+ TimeZoneForAutomation& tzfa = innerTimeZoneForAutomation();
|
|
+ tzfa.cal = cal;
|
|
+ tzfa.id = String(canonicalBuffer.data(), canonicalLength);
|
|
+ tzfa.displayName = String(displayNameBuffer.data(), displayNameLength);
|
|
+ return true;
|
|
+}
|
|
+
|
|
+String timeZoneForAutomation()
|
|
+{
|
|
+ return innerTimeZoneForAutomation().id;
|
|
+}
|
|
+
|
|
+String timeZoneDisplayNameForAutomation()
|
|
+{
|
|
+ return innerTimeZoneForAutomation().displayName;
|
|
+}
|
|
+
|
|
} // namespace WTF
|
|
diff --git a/Source/WTF/wtf/DateMath.h b/Source/WTF/wtf/DateMath.h
|
|
index 246ba67c764b629042a7927d24fe89b049d82a0b..68d536878d1f0ba832d1c1d3e36e10b8227bbfac 100644
|
|
--- a/Source/WTF/wtf/DateMath.h
|
|
+++ b/Source/WTF/wtf/DateMath.h
|
|
@@ -389,6 +389,10 @@ inline int dayInMonthFromDayInYear(int dayInYear, bool leapYear)
|
|
return d - step;
|
|
}
|
|
|
|
+WTF_EXPORT_PRIVATE bool setTimeZoneForAutomation(const String& timeZone);
|
|
+WTF_EXPORT_PRIVATE String timeZoneForAutomation();
|
|
+WTF_EXPORT_PRIVATE String timeZoneDisplayNameForAutomation();
|
|
+
|
|
// Returns combined offset in millisecond (UTC + DST).
|
|
WTF_EXPORT_PRIVATE LocalTimeOffset calculateLocalTimeOffset(double utcInMilliseconds, TimeType = UTCTime);
|
|
|
|
diff --git a/Source/WTF/wtf/PlatformEnable.h b/Source/WTF/wtf/PlatformEnable.h
|
|
index 4a225bd7b7604248e33a6275c9c9dc884606cad0..ae94fe2390df3b2e874816571320e79c7629e0c3 100644
|
|
--- a/Source/WTF/wtf/PlatformEnable.h
|
|
+++ b/Source/WTF/wtf/PlatformEnable.h
|
|
@@ -398,7 +398,7 @@
|
|
#endif
|
|
|
|
#if !defined(ENABLE_ORIENTATION_EVENTS)
|
|
-#define ENABLE_ORIENTATION_EVENTS 0
|
|
+#define ENABLE_ORIENTATION_EVENTS 1
|
|
#endif
|
|
|
|
#if OS(WINDOWS)
|
|
@@ -467,7 +467,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/PlatformHave.h b/Source/WTF/wtf/PlatformHave.h
|
|
index f6284617b30fba6484764fa4cf15668ffe3be084..ecfa030527b48f1cf3fe2f705d9a0a88d7825a43 100644
|
|
--- a/Source/WTF/wtf/PlatformHave.h
|
|
+++ b/Source/WTF/wtf/PlatformHave.h
|
|
@@ -335,7 +335,7 @@
|
|
#define HAVE_NSHTTPCOOKIESTORAGE__INITWITHIDENTIFIER_WITH_INACCURATE_NULLABILITY 1
|
|
#endif
|
|
|
|
-#if PLATFORM(MAC) || PLATFORM(IOS) || PLATFORM(MACCATALYST)
|
|
+#if PLATFORM(MAC) || PLATFORM(IOS) || PLATFORM(MACCATALYST) || PLATFORM(GTK) || PLATFORM(WPE) || PLATFORM(WIN)
|
|
#define HAVE_OS_DARK_MODE_SUPPORT 1
|
|
#endif
|
|
|
|
diff --git a/Source/WebCore/Modules/geolocation/Geolocation.cpp b/Source/WebCore/Modules/geolocation/Geolocation.cpp
|
|
index 6d5be9a591a272cd67d6e9d097b30505bdf8ae5e..8f67ba28c380e844c8e4191ee704466559d88f97 100644
|
|
--- a/Source/WebCore/Modules/geolocation/Geolocation.cpp
|
|
+++ b/Source/WebCore/Modules/geolocation/Geolocation.cpp
|
|
@@ -356,8 +356,9 @@ bool Geolocation::shouldBlockGeolocationRequests()
|
|
bool isSecure = SecurityOrigin::isSecure(document()->url());
|
|
bool hasMixedContent = !document()->foundMixedContent().isEmpty();
|
|
bool isLocalOrigin = securityOrigin()->isLocal();
|
|
+ bool isPotentiallyTrustworthy = securityOrigin()->isPotentiallyTrustworthy();
|
|
if (securityOrigin()->canRequestGeolocation()) {
|
|
- if (isLocalOrigin || (isSecure && !hasMixedContent) || isRequestFromIBooks())
|
|
+ if (isLocalOrigin || isPotentiallyTrustworthy || (isSecure && !hasMixedContent) || isRequestFromIBooks())
|
|
return false;
|
|
}
|
|
|
|
diff --git a/Source/WebCore/SourcesCocoa.txt b/Source/WebCore/SourcesCocoa.txt
|
|
index 058523b77c4683333507e3ed564363aac6277d02..5cb64ccce4a2f47abf218c980e0ae128dbed7175 100644
|
|
--- a/Source/WebCore/SourcesCocoa.txt
|
|
+++ b/Source/WebCore/SourcesCocoa.txt
|
|
@@ -605,3 +605,9 @@ platform/graphics/angle/TemporaryANGLESetting.cpp @no-unify
|
|
// Derived Sources
|
|
|
|
WHLSLStandardLibraryFunctionMap.cpp
|
|
+
|
|
+// Playwright begin
|
|
+JSTouch.cpp
|
|
+JSTouchEvent.cpp
|
|
+JSTouchList.cpp
|
|
+// Playwright end
|
|
diff --git a/Source/WebCore/WebCore.order b/Source/WebCore/WebCore.order
|
|
index d643d5bbfbed5b4e3bb1358e36096dcaf66d5d8a..5a0a8ffa1ab74ccf0858e69e35127d49c21c326d 100644
|
|
--- a/Source/WebCore/WebCore.order
|
|
+++ b/Source/WebCore/WebCore.order
|
|
@@ -3093,7 +3093,6 @@ __ZN7WebCore14DocumentLoader23stopLoadingSubresourcesEv
|
|
__ZN7WebCore14DocumentLoader18stopLoadingPlugInsEv
|
|
__ZN7WebCore14DocumentLoader15detachFromFrameEv
|
|
__ZN7WebCore20ApplicationCacheHost22setDOMApplicationCacheEPNS_19DOMApplicationCacheE
|
|
-__ZN7WebCore24InspectorInstrumentation27loaderDetachedFromFrameImplEPNS_19InstrumentingAgentsEPNS_14DocumentLoaderE
|
|
__ZN7WebCore14DocumentLoaderD0Ev
|
|
__ZN7WebCore14DocumentLoaderD2Ev
|
|
__ZN7WebCore14DocumentLoader17clearMainResourceEv
|
|
diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj
|
|
index fd74038305f6198d918e368a444fdd782adf9ab7..9c3e6fe69ff41f77e4e147717e90b27c1b13815d 100644
|
|
--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj
|
|
+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj
|
|
@@ -5143,6 +5143,14 @@
|
|
EDE3A5000C7A430600956A37 /* ColorMac.h in Headers */ = {isa = PBXBuildFile; fileRef = EDE3A4FF0C7A430600956A37 /* ColorMac.h */; settings = {ATTRIBUTES = (Private, ); }; };
|
|
EDEC98030AED7E170059137F /* WebCorePrefix.h in Headers */ = {isa = PBXBuildFile; fileRef = EDEC98020AED7E170059137F /* WebCorePrefix.h */; };
|
|
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 */; };
|
|
+ F050E17223AD669F0011CE47 /* TouchEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = F050E17023AD669F0011CE47 /* TouchEvent.h */; settings = {ATTRIBUTES = (Private, ); }; };
|
|
+ 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, ); }; };
|
|
@@ -16206,6 +16214,14 @@
|
|
EDEC98020AED7E170059137F /* WebCorePrefix.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = WebCorePrefix.h; sourceTree = "<group>"; tabWidth = 4; usesTabs = 0; };
|
|
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>"; };
|
|
@@ -21619,7 +21635,12 @@
|
|
81F65FF513788FAA00FF6F2D /* DragState.h */,
|
|
1AF326770D78B9440068F0C4 /* EditorClient.h */,
|
|
93C09A800B064F00005ABD4D /* EventHandler.cpp */,
|
|
+ F050E16F23AD669E0011CE47 /* TouchEvent.cpp */,
|
|
+ F050E17023AD669F0011CE47 /* TouchEvent.h */,
|
|
93C09A520B064DB3005ABD4D /* EventHandler.h */,
|
|
+ F050E16923AD660C0011CE47 /* Touch.cpp */,
|
|
+ F050E16C23AD66630011CE47 /* TouchList.cpp */,
|
|
+ F050E16B23AD66620011CE47 /* TouchList.h */,
|
|
E0FEF371B27C53EAC1C1FBEE /* EventSource.cpp */,
|
|
E0FEF371B17C53EAC1C1FBEE /* EventSource.h */,
|
|
E0FEF371B07C53EAC1C1FBEE /* EventSource.idl */,
|
|
@@ -27009,7 +27030,9 @@
|
|
B2C3D9EC0D006C1D00EF6F26 /* text */,
|
|
E1EE8B6B2412B2A700E794D6 /* xr */,
|
|
DFDB912CF8E88A6DA1AD264F /* AbortableTaskQueue.h */,
|
|
+ F050E16623AC9C070011CE47 /* PlatformTouchEvent.h */,
|
|
49AE2D94134EE5F90072920A /* CalculationValue.cpp */,
|
|
+ F050E17623AD70C40011CE47 /* PlatformTouchPoint.h */,
|
|
49AE2D95134EE5F90072920A /* CalculationValue.h */,
|
|
C330A22113EC196B0000B45B /* ColorChooser.h */,
|
|
C37CDEBC149EF2030042090D /* ColorChooserClient.h */,
|
|
@@ -29434,6 +29457,7 @@
|
|
BCCFBAE70B5152ED0001F1D7 /* DocumentParser.h */,
|
|
AD6E71AA1668899D00320C13 /* DocumentSharedObjectPool.cpp */,
|
|
AD6E71AB1668899D00320C13 /* DocumentSharedObjectPool.h */,
|
|
+ F050E17323AD6A800011CE47 /* DocumentTouch.cpp */,
|
|
6BDB5DC1227BD3B800919770 /* DocumentStorageAccess.cpp */,
|
|
6BDB5DC0227BD3B800919770 /* DocumentStorageAccess.h */,
|
|
86D982F6125C154000AD9E3D /* DocumentTiming.h */,
|
|
@@ -30470,6 +30494,7 @@
|
|
93C4F6EB1108F9A50099D0DB /* AccessibilityScrollbar.h in Headers */,
|
|
29489FC712C00F0300D83F0F /* AccessibilityScrollView.h in Headers */,
|
|
0709FC4E1025DEE30059CDBA /* AccessibilitySlider.h in Headers */,
|
|
+ F050E16D23AD66630011CE47 /* TouchList.h in Headers */,
|
|
29D7BCFA1444AF7D0070619C /* AccessibilitySpinButton.h in Headers */,
|
|
69A6CBAD1C6BE42C00B836E9 /* AccessibilitySVGElement.h in Headers */,
|
|
AAC08CF315F941FD00F1E188 /* AccessibilitySVGRoot.h in Headers */,
|
|
@@ -32418,6 +32443,7 @@
|
|
6E4ABCD5138EA0B70071D291 /* JSHTMLUnknownElement.h in Headers */,
|
|
E44614170CD6826900FADA75 /* JSHTMLVideoElement.h in Headers */,
|
|
81BE20D311F4BC3200915DFA /* JSIDBCursor.h in Headers */,
|
|
+ F050E17823AD70C50011CE47 /* PlatformTouchPoint.h in Headers */,
|
|
7C3D8EF01E0B21430023B084 /* JSIDBCursorDirection.h in Headers */,
|
|
C585A68311D4FB08004C3E4B /* JSIDBDatabase.h in Headers */,
|
|
C585A69711D4FB13004C3E4B /* JSIDBFactory.h in Headers */,
|
|
@@ -34365,9 +34391,11 @@
|
|
B2C3DA3A0D006C1D00EF6F26 /* TextCodec.h in Headers */,
|
|
26E98A10130A9FCA008EB7B2 /* TextCodecASCIIFastPath.h in Headers */,
|
|
DF95B14A24FDAFD300B1F4D7 /* TextCodecCJK.h in Headers */,
|
|
+ F050E16823AC9C080011CE47 /* PlatformTouchEvent.h in Headers */,
|
|
B2C3DA3C0D006C1D00EF6F26 /* TextCodecICU.h in Headers */,
|
|
B2C3DA3E0D006C1D00EF6F26 /* TextCodecLatin1.h in Headers */,
|
|
57EF5E601D20C83900171E60 /* TextCodecReplacement.h in Headers */,
|
|
+ F050E17223AD669F0011CE47 /* TouchEvent.h in Headers */,
|
|
B2C3DA400D006C1D00EF6F26 /* TextCodecUserDefined.h in Headers */,
|
|
B2C3DA420D006C1D00EF6F26 /* TextCodecUTF16.h in Headers */,
|
|
9343CB8212F25E510033C5EE /* TextCodecUTF8.h in Headers */,
|
|
@@ -35357,6 +35385,7 @@
|
|
51058ADF1D67C229009A538C /* MockGamepad.cpp in Sources */,
|
|
51058AE11D67C229009A538C /* MockGamepadProvider.cpp in Sources */,
|
|
CDF2B0121820540600F2B424 /* MockMediaPlayerMediaSource.cpp in Sources */,
|
|
+ F050E17423AD6A800011CE47 /* DocumentTouch.cpp in Sources */,
|
|
CDF2B0141820540600F2B424 /* MockMediaSourcePrivate.cpp in Sources */,
|
|
CDF2B0161820540700F2B424 /* MockSourceBufferPrivate.cpp in Sources */,
|
|
2D9BF7421DBFDC27007A7D99 /* NavigatorEME.cpp in Sources */,
|
|
@@ -35388,6 +35417,7 @@
|
|
6E72F54F229DCD1300B3E151 /* TemporaryANGLESetting.cpp in Sources */,
|
|
CE88EE262414467B007F29C2 /* TextAlternativeWithRange.mm in Sources */,
|
|
51DF6D800B92A18E00C2DC85 /* ThreadCheck.mm in Sources */,
|
|
+ F050E17123AD669F0011CE47 /* TouchEvent.cpp in Sources */,
|
|
538EC8031F96AF81004D22A8 /* UnifiedSource1-mm.mm in Sources */,
|
|
538EC8021F96AF81004D22A8 /* UnifiedSource1.cpp in Sources */,
|
|
538EC8051F96AF81004D22A8 /* UnifiedSource2-mm.mm in Sources */,
|
|
@@ -35436,6 +35466,7 @@
|
|
538EC8881F993F9C004D22A8 /* UnifiedSource23.cpp in Sources */,
|
|
DE5F85801FA1ABF4006DB63A /* UnifiedSource24-mm.mm in Sources */,
|
|
538EC8891F993F9D004D22A8 /* UnifiedSource24.cpp in Sources */,
|
|
+ F050E16E23AD66630011CE47 /* TouchList.cpp in Sources */,
|
|
DE5F85811FA1ABF4006DB63A /* UnifiedSource25-mm.mm in Sources */,
|
|
538EC88A1F993F9D004D22A8 /* UnifiedSource25.cpp in Sources */,
|
|
DE5F85821FA1ABF4006DB63A /* UnifiedSource26-mm.mm in Sources */,
|
|
@@ -35968,6 +35999,7 @@
|
|
2D8B92F1203D13E1009C868F /* UnifiedSource516.cpp in Sources */,
|
|
2D8B92F2203D13E1009C868F /* UnifiedSource517.cpp in Sources */,
|
|
2D8B92F3203D13E1009C868F /* UnifiedSource518.cpp in Sources */,
|
|
+ F050E16A23AD660C0011CE47 /* Touch.cpp in Sources */,
|
|
2D8B92F4203D13E1009C868F /* UnifiedSource519.cpp in Sources */,
|
|
2D8B92F5203D13E1009C868F /* UnifiedSource520.cpp in Sources */,
|
|
2D8B92F6203D13E1009C868F /* UnifiedSource521.cpp in Sources */,
|
|
diff --git a/Source/WebCore/accessibility/AccessibilityObject.cpp b/Source/WebCore/accessibility/AccessibilityObject.cpp
|
|
index dc856667a52b96b9201f266e01aae199feab39b7..ee2d99e10e3db27f620fec0809fe008d38aae48a 100644
|
|
--- a/Source/WebCore/accessibility/AccessibilityObject.cpp
|
|
+++ b/Source/WebCore/accessibility/AccessibilityObject.cpp
|
|
@@ -58,6 +58,7 @@
|
|
#include "HTMLParserIdioms.h"
|
|
#include "HTMLTextAreaElement.h"
|
|
#include "HitTestResult.h"
|
|
+#include "InspectorInstrumentation.h"
|
|
#include "LocalizedStrings.h"
|
|
#include "MathMLNames.h"
|
|
#include "NodeList.h"
|
|
@@ -3241,10 +3242,15 @@ AccessibilityObjectInclusion AccessibilityObject::defaultObjectInclusion() const
|
|
|
|
if (useParentData ? m_isIgnoredFromParentData.isPresentationalChildOfAriaRole : isPresentationalChildOfAriaRole())
|
|
return AccessibilityObjectInclusion::IgnoreObject;
|
|
-
|
|
- return accessibilityPlatformIncludesObject();
|
|
+
|
|
+ AccessibilityObjectInclusion platformBehavior = accessibilityPlatformIncludesObject();
|
|
+ if (platformBehavior != AccessibilityObjectInclusion::DefaultBehavior) {
|
|
+ if (auto* page = this->page())
|
|
+ InspectorInstrumentation::maybeOverrideDefaultObjectInclusion(*page, platformBehavior);
|
|
+ }
|
|
+ return platformBehavior;
|
|
}
|
|
-
|
|
+
|
|
bool AccessibilityObject::accessibilityIsIgnored() const
|
|
{
|
|
AXComputedObjectAttributeCache* attributeCache = nullptr;
|
|
diff --git a/Source/WebCore/css/MediaQueryEvaluator.cpp b/Source/WebCore/css/MediaQueryEvaluator.cpp
|
|
index c8a849d98d04e3d23d349ede31dad76c20fb17f8..b5dcc6f0cd2a0785ad050e3d8e6ff2679a585282 100644
|
|
--- a/Source/WebCore/css/MediaQueryEvaluator.cpp
|
|
+++ b/Source/WebCore/css/MediaQueryEvaluator.cpp
|
|
@@ -390,7 +390,7 @@ static bool deviceAspectRatioEvaluate(CSSValue* value, const CSSToLengthConversi
|
|
if (!value)
|
|
return true;
|
|
|
|
- auto size = screenRect(frame.mainFrame().view()).size();
|
|
+ auto size = frame.page()->screenSize();
|
|
bool result = compareAspectRatioValue(value, size.width(), size.height(), op);
|
|
LOG_WITH_STREAM(MediaQueries, stream << " deviceAspectRatioEvaluate: " << op << " " << aspectRatioValueAsString(value) << " actual screen size " << size << ": " << result);
|
|
return result;
|
|
@@ -508,7 +508,7 @@ static bool deviceHeightEvaluate(CSSValue* value, const CSSToLengthConversionDat
|
|
if (!value)
|
|
return true;
|
|
int length;
|
|
- auto height = screenRect(frame.mainFrame().view()).height();
|
|
+ auto height = frame.page()->screenSize().height();
|
|
if (!computeLength(value, !frame.document()->inQuirksMode(), conversionData, length))
|
|
return false;
|
|
|
|
@@ -523,8 +523,10 @@ static bool deviceWidthEvaluate(CSSValue* value, const CSSToLengthConversionData
|
|
// assume if we have a device, assume non-zero
|
|
if (!value)
|
|
return true;
|
|
+ if (!frame.mainFrame().view())
|
|
+ return false;
|
|
int length;
|
|
- auto width = screenRect(frame.mainFrame().view()).width();
|
|
+ auto width = frame.page()->screenSize().width();
|
|
if (!computeLength(value, !frame.document()->inQuirksMode(), conversionData, length))
|
|
return false;
|
|
|
|
diff --git a/Source/WebCore/dom/PointerEvent.cpp b/Source/WebCore/dom/PointerEvent.cpp
|
|
index 3cc7f016fb8414d7385c1189a7595940d1972a4b..5a7fc02255900a9f9705567e79ee43718436cf2d 100644
|
|
--- a/Source/WebCore/dom/PointerEvent.cpp
|
|
+++ b/Source/WebCore/dom/PointerEvent.cpp
|
|
@@ -129,4 +129,61 @@ EventInterface PointerEvent::eventInterface() const
|
|
return PointerEventInterfaceType;
|
|
}
|
|
|
|
+#if ENABLE(TOUCH_EVENTS) && !PLATFORM(IOS_FAMILY)
|
|
+
|
|
+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();
|
|
+}
|
|
+
|
|
+static short buttonForType(const AtomString& type)
|
|
+{
|
|
+ return type == eventNames().pointermoveEvent ? -1 : 0;
|
|
+}
|
|
+
|
|
+static unsigned short buttonsForType(const AtomString& type)
|
|
+{
|
|
+ // We have contact with the touch surface for most events except when we've released the touch or canceled it.
|
|
+ return (type == eventNames().pointerupEvent || type == eventNames().pointeroutEvent || type == eventNames().pointerleaveEvent || type == eventNames().pointercancelEvent) ? 0 : 1;
|
|
+}
|
|
+
|
|
+Ref<PointerEvent> PointerEvent::create(const PlatformTouchEvent& event, unsigned index, bool isPrimary, Ref<WindowProxy>&& view)
|
|
+{
|
|
+ const auto& type = pointerEventType(event.touchPoints().at(index).state());
|
|
+ return adoptRef(*new PointerEvent(type, event, typeIsCancelable(type), index, isPrimary, WTFMove(view)));
|
|
+}
|
|
+
|
|
+Ref<PointerEvent> PointerEvent::create(const String& type, const PlatformTouchEvent& event, unsigned index, bool isPrimary, Ref<WindowProxy>&& view)
|
|
+{
|
|
+ return adoptRef(*new PointerEvent(type, event, typeIsCancelable(type), index, isPrimary, WTFMove(view)));
|
|
+}
|
|
+
|
|
+PointerEvent::PointerEvent(const AtomString& type, const PlatformTouchEvent& event, IsCancelable isCancelable, unsigned index, bool isPrimary, Ref<WindowProxy>&& view)
|
|
+ : MouseEvent(type, typeCanBubble(type), isCancelable, typeIsComposed(type), event.timestamp().approximateMonotonicTime(), WTFMove(view), 0, event.touchPoints().at(index).pos(), event.touchPoints().at(index).pos(), { }, event.modifiers(), buttonForType(type), buttonsForType(type), nullptr, 0, 0, IsSimulated::No, IsTrusted::Yes)
|
|
+ , m_pointerId(2)
|
|
+ , m_width(2 * event.touchPoints().at(index).radiusX())
|
|
+ , m_height(2 * event.touchPoints().at(index).radiusY())
|
|
+ , m_pressure(event.touchPoints().at(index).force())
|
|
+ , m_pointerType(PointerEvent::touchPointerType())
|
|
+ , m_isPrimary(isPrimary)
|
|
+{
|
|
+}
|
|
+
|
|
+#endif // ENABLE(TOUCH_EVENTS) && !PLATFORM(IOS_FAMILY)
|
|
+
|
|
} // namespace WebCore
|
|
diff --git a/Source/WebCore/dom/PointerEvent.h b/Source/WebCore/dom/PointerEvent.h
|
|
index 4310f235a12ca941c613794ac3ab572b68a2b4f8..7a8e56455777174c46cb3ea6359025dc5409b8c6 100644
|
|
--- a/Source/WebCore/dom/PointerEvent.h
|
|
+++ b/Source/WebCore/dom/PointerEvent.h
|
|
@@ -33,6 +33,8 @@
|
|
|
|
#if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS_FAMILY)
|
|
#include "PlatformTouchEventIOS.h"
|
|
+#else
|
|
+#include "PlatformTouchEvent.h"
|
|
#endif
|
|
|
|
namespace WebCore {
|
|
@@ -79,7 +81,7 @@ public:
|
|
static Ref<PointerEvent> create(const String& type, short button, const MouseEvent&);
|
|
static Ref<PointerEvent> create(const String& type, PointerID, const String& pointerType, IsPrimary = IsPrimary::No);
|
|
|
|
-#if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS_FAMILY)
|
|
+#if ENABLE(TOUCH_EVENTS)
|
|
static Ref<PointerEvent> create(const PlatformTouchEvent&, unsigned touchIndex, bool isPrimary, Ref<WindowProxy>&&);
|
|
static Ref<PointerEvent> create(const String& type, const PlatformTouchEvent&, unsigned touchIndex, bool isPrimary, Ref<WindowProxy>&&);
|
|
#endif
|
|
@@ -123,7 +125,7 @@ private:
|
|
PointerEvent(const AtomString&, Init&&);
|
|
PointerEvent(const AtomString& type, short button, const MouseEvent&);
|
|
PointerEvent(const AtomString& type, PointerID, const String& pointerType, IsPrimary);
|
|
-#if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS_FAMILY)
|
|
+#if ENABLE(TOUCH_EVENTS)
|
|
PointerEvent(const AtomString& type, const PlatformTouchEvent&, IsCancelable isCancelable, unsigned touchIndex, bool isPrimary, Ref<WindowProxy>&&);
|
|
#endif
|
|
|
|
diff --git a/Source/WebCore/dom/UserGestureIndicator.cpp b/Source/WebCore/dom/UserGestureIndicator.cpp
|
|
index 76399ab574d94d73c5abc08f8df7901979e58273..8df80e34cda19470e305d5696bf108bd8de5fa8c 100644
|
|
--- a/Source/WebCore/dom/UserGestureIndicator.cpp
|
|
+++ b/Source/WebCore/dom/UserGestureIndicator.cpp
|
|
@@ -67,8 +67,7 @@ UserGestureIndicator::UserGestureIndicator(Optional<ProcessingUserGestureState>
|
|
|
|
if (state)
|
|
currentToken() = UserGestureToken::create(state.value(), gestureType);
|
|
-
|
|
- if (document && currentToken()->processingUserGesture() && state) {
|
|
+ if (document && state && currentToken()->processingUserGesture()) {
|
|
document->updateLastHandledUserGestureTimestamp(currentToken()->startTime());
|
|
if (processInteractionStyle == ProcessInteractionStyle::Immediate)
|
|
ResourceLoadObserver::shared().logUserInteractionWithReducedTimeResolution(document->topDocument());
|
|
diff --git a/Source/WebCore/html/FileInputType.cpp b/Source/WebCore/html/FileInputType.cpp
|
|
index de06188e522381e034914f539af45166907767c9..900c152116b75e14e990a2810402afc49eaca78d 100644
|
|
--- a/Source/WebCore/html/FileInputType.cpp
|
|
+++ b/Source/WebCore/html/FileInputType.cpp
|
|
@@ -36,6 +36,7 @@
|
|
#include "HTMLNames.h"
|
|
#include "Icon.h"
|
|
#include "InputTypeNames.h"
|
|
+#include "InspectorInstrumentation.h"
|
|
#include "LocalizedStrings.h"
|
|
#include "MIMETypeRegistry.h"
|
|
#include "RenderFileUploadControl.h"
|
|
@@ -211,6 +212,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;
|
|
|
|
diff --git a/Source/WebCore/inspector/InspectorController.cpp b/Source/WebCore/inspector/InspectorController.cpp
|
|
index 630df71790c63b6e75873451a1740f86f67e02de..568beed149797df3d208c1a59c049e2d23ab7ffa 100644
|
|
--- a/Source/WebCore/inspector/InspectorController.cpp
|
|
+++ b/Source/WebCore/inspector/InspectorController.cpp
|
|
@@ -371,8 +371,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);
|
|
}
|
|
@@ -513,4 +513,24 @@ void InspectorController::didComposite(Frame& frame)
|
|
InspectorInstrumentation::didComposite(frame);
|
|
}
|
|
|
|
+void InspectorController::pauseWhenShown()
|
|
+{
|
|
+ m_pauseWhenShown = true;
|
|
+}
|
|
+
|
|
+void InspectorController::resumeIfPausedInNewWindow()
|
|
+{
|
|
+ m_pauseWhenShown = false;
|
|
+}
|
|
+
|
|
+void InspectorController::didShowNewWindow()
|
|
+{
|
|
+ if (!m_pauseWhenShown)
|
|
+ return;
|
|
+ while (m_pauseWhenShown) {
|
|
+ if (RunLoop::cycle() == RunLoop::CycleResult::Stop)
|
|
+ break;
|
|
+ }
|
|
+}
|
|
+
|
|
} // namespace WebCore
|
|
diff --git a/Source/WebCore/inspector/InspectorController.h b/Source/WebCore/inspector/InspectorController.h
|
|
index b3118080ac5f61b233a5f4998ea9a63dc95cca75..d4240bacd7cf3855b203965eb14eb0611881afc8 100644
|
|
--- a/Source/WebCore/inspector/InspectorController.h
|
|
+++ b/Source/WebCore/inspector/InspectorController.h
|
|
@@ -101,6 +101,10 @@ public:
|
|
WEBCORE_EXPORT void willComposite(Frame&);
|
|
WEBCORE_EXPORT void didComposite(Frame&);
|
|
|
|
+ WEBCORE_EXPORT void pauseWhenShown();
|
|
+ WEBCORE_EXPORT void resumeIfPausedInNewWindow();
|
|
+ WEBCORE_EXPORT void didShowNewWindow();
|
|
+
|
|
bool isUnderTest() const { return m_isUnderTest; }
|
|
void setIsUnderTest(bool isUnderTest) { m_isUnderTest = isUnderTest; }
|
|
WEBCORE_EXPORT void evaluateForTestInFrontend(const String& script);
|
|
@@ -150,6 +154,7 @@ private:
|
|
bool m_isAutomaticInspection { false };
|
|
bool m_pauseAfterInitialization = { false };
|
|
bool m_didCreateLazyAgents { false };
|
|
+ bool m_pauseWhenShown { false };
|
|
};
|
|
|
|
} // namespace WebCore
|
|
diff --git a/Source/WebCore/inspector/InspectorInstrumentation.cpp b/Source/WebCore/inspector/InspectorInstrumentation.cpp
|
|
index 1d65a452759fd02532232fffbfb70376f0afef90..3134459af0bc3c744bd580bf7b283b7420097217 100644
|
|
--- a/Source/WebCore/inspector/InspectorInstrumentation.cpp
|
|
+++ b/Source/WebCore/inspector/InspectorInstrumentation.cpp
|
|
@@ -627,6 +627,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, Frame& frame, const ResourceError&)
|
|
+{
|
|
+ if (auto* pageRuntimeAgent = instrumentingAgents.enabledPageRuntimeAgent())
|
|
+ pageRuntimeAgent->didReceiveMainResourceError(frame);
|
|
+}
|
|
+
|
|
void InspectorInstrumentation::willLoadXHRSynchronouslyImpl(InstrumentingAgents& instrumentingAgents)
|
|
{
|
|
if (auto* networkAgent = instrumentingAgents.enabledNetworkAgent())
|
|
@@ -659,20 +665,17 @@ void InspectorInstrumentation::didReceiveScriptResponseImpl(InstrumentingAgents&
|
|
|
|
void InspectorInstrumentation::domContentLoadedEventFiredImpl(InstrumentingAgents& instrumentingAgents, Frame& frame)
|
|
{
|
|
- if (!frame.isMainFrame())
|
|
- return;
|
|
-
|
|
if (auto* pageAgent = instrumentingAgents.enabledPageAgent())
|
|
- pageAgent->domContentEventFired();
|
|
+ pageAgent->domContentEventFired(frame);
|
|
}
|
|
|
|
void InspectorInstrumentation::loadEventFiredImpl(InstrumentingAgents& instrumentingAgents, Frame* frame)
|
|
{
|
|
- if (!frame || !frame->isMainFrame())
|
|
+ if (!frame)
|
|
return;
|
|
|
|
if (auto* pageAgent = instrumentingAgents.enabledPageAgent())
|
|
- pageAgent->loadEventFired();
|
|
+ pageAgent->loadEventFired(*frame);
|
|
}
|
|
|
|
void InspectorInstrumentation::frameDetachedFromParentImpl(InstrumentingAgents& instrumentingAgents, Frame& frame)
|
|
@@ -753,12 +756,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, Frame& frame)
|
|
{
|
|
if (frame.isMainFrame()) {
|
|
@@ -795,6 +792,12 @@ void InspectorInstrumentation::frameClearedScheduledNavigationImpl(Instrumenting
|
|
inspectorPageAgent->frameClearedScheduledNavigation(frame);
|
|
}
|
|
|
|
+void InspectorInstrumentation::didNavigateWithinPageImpl(InstrumentingAgents& instrumentingAgents, Frame& frame)
|
|
+{
|
|
+ if (InspectorPageAgent* inspectorPageAgent = instrumentingAgents.enabledPageAgent())
|
|
+ inspectorPageAgent->didNavigateWithinPage(frame);
|
|
+}
|
|
+
|
|
#if ENABLE(DARK_MODE_CSS) || HAVE(OS_DARK_MODE_SUPPORT)
|
|
void InspectorInstrumentation::defaultAppearanceDidChangeImpl(InstrumentingAgents& instrumentingAgents, bool useDarkAppearance)
|
|
{
|
|
@@ -1320,6 +1323,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, Frame& 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::willCheckNewWindowPolicyImpl(InstrumentingAgents& instrumentingAgents, const URL& url)
|
|
+{
|
|
+ if (InspectorPageAgent* pageAgent = instrumentingAgents.enabledPageAgent())
|
|
+ pageAgent->willCheckNewWindowPolicy(url);
|
|
+}
|
|
+
|
|
+void InspectorInstrumentation::didCheckNewWindowPolicyImpl(InstrumentingAgents& instrumentingAgents, bool allowed)
|
|
+{
|
|
+ if (InspectorPageAgent* pageAgent = instrumentingAgents.enabledPageAgent())
|
|
+ pageAgent->didCheckNewWindowPolicy(allowed);
|
|
+}
|
|
+
|
|
InstrumentingAgents& InspectorInstrumentation::instrumentingAgentsForWorkerGlobalScope(WorkerGlobalScope& workerGlobalScope)
|
|
{
|
|
return workerGlobalScope.inspectorController().m_instrumentingAgents;
|
|
@@ -1331,6 +1364,13 @@ InstrumentingAgents& InspectorInstrumentation::instrumentingAgentsForPage(Page&
|
|
return page.inspectorController().m_instrumentingAgents.get();
|
|
}
|
|
|
|
+void InspectorInstrumentation::maybeOverrideDefaultObjectInclusion(Page& page, AccessibilityObjectInclusion& inclusion) {
|
|
+ if (InspectorPageAgent* pageAgent = InspectorInstrumentation::instrumentingAgentsForPage(page).enabledPageAgent()) {
|
|
+ if (pageAgent->doingAccessibilitySnapshot())
|
|
+ inclusion = AccessibilityObjectInclusion::DefaultBehavior;
|
|
+ }
|
|
+}
|
|
+
|
|
InstrumentingAgents* InspectorInstrumentation::instrumentingAgentsForContext(ScriptExecutionContext& context)
|
|
{
|
|
if (is<Document>(context))
|
|
diff --git a/Source/WebCore/inspector/InspectorInstrumentation.h b/Source/WebCore/inspector/InspectorInstrumentation.h
|
|
index 5ad79e0d16a9532b81c8b5af80aacace59869d1e..a42a5b0c224b979703366a16e97a3332a3471b55 100644
|
|
--- a/Source/WebCore/inspector/InspectorInstrumentation.h
|
|
+++ b/Source/WebCore/inspector/InspectorInstrumentation.h
|
|
@@ -31,6 +31,7 @@
|
|
|
|
#pragma once
|
|
|
|
+#include "AccessibilityObjectInterface.h"
|
|
#include "CSSSelector.h"
|
|
#include "CallTracerTypes.h"
|
|
#include "CanvasBase.h"
|
|
@@ -80,6 +81,7 @@ class DOMWrapperWorld;
|
|
class Document;
|
|
class DocumentLoader;
|
|
class EventListener;
|
|
+class HTMLInputElement;
|
|
class HTTPHeaderMap;
|
|
class InspectorTimelineAgent;
|
|
class InstrumentingAgents;
|
|
@@ -200,6 +202,7 @@ public:
|
|
static void didReceiveData(Frame*, unsigned long identifier, const char* data, int dataLength, int encodedDataLength);
|
|
static void didFinishLoading(Frame*, DocumentLoader*, unsigned long identifier, const NetworkLoadMetrics&, ResourceLoader*);
|
|
static void didFailLoading(Frame*, DocumentLoader*, unsigned long identifier, const ResourceError&);
|
|
+ static void didReceiveMainResourceError(Frame&, const ResourceError&);
|
|
|
|
static void willSendRequest(WorkerGlobalScope&, unsigned long identifier, ResourceRequest&);
|
|
static void didReceiveResourceResponse(WorkerGlobalScope&, unsigned long identifier, const ResourceResponse&);
|
|
@@ -226,11 +229,11 @@ public:
|
|
static void frameDetachedFromParent(Frame&);
|
|
static void didCommitLoad(Frame&, DocumentLoader*);
|
|
static void frameDocumentUpdated(Frame&);
|
|
- static void loaderDetachedFromFrame(Frame&, DocumentLoader&);
|
|
static void frameStartedLoading(Frame&);
|
|
static void frameStoppedLoading(Frame&);
|
|
static void frameScheduledNavigation(Frame&, Seconds delay);
|
|
static void frameClearedScheduledNavigation(Frame&);
|
|
+ static void didNavigateWithinPage(Frame&);
|
|
#if ENABLE(DARK_MODE_CSS) || HAVE(OS_DARK_MODE_SUPPORT)
|
|
static void defaultAppearanceDidChange(Page&, bool useDarkAppearance);
|
|
#endif
|
|
@@ -325,6 +328,12 @@ public:
|
|
static void layerTreeDidChange(Page*);
|
|
static void renderLayerDestroyed(Page*, const RenderLayer&);
|
|
|
|
+ static void runOpenPanel(Frame*, HTMLInputElement*, bool*);
|
|
+ static void frameAttached(Frame*);
|
|
+ static bool shouldBypassCSP(ScriptExecutionContext*);
|
|
+ static void willCheckNewWindowPolicy(Frame&, const URL&);
|
|
+ static void didCheckNewWindowPolicy(Frame&, bool allowed);
|
|
+
|
|
static void frontendCreated();
|
|
static void frontendDeleted();
|
|
static bool hasFrontends() { return InspectorInstrumentationPublic::hasFrontends(); }
|
|
@@ -340,6 +349,8 @@ public:
|
|
static void registerInstrumentingAgents(InstrumentingAgents&);
|
|
static void unregisterInstrumentingAgents(InstrumentingAgents&);
|
|
|
|
+ static void maybeOverrideDefaultObjectInclusion(Page&, AccessibilityObjectInclusion&);
|
|
+
|
|
private:
|
|
static void didClearWindowObjectInWorldImpl(InstrumentingAgents&, Frame&, DOMWrapperWorld&);
|
|
static bool isDebuggerPausedImpl(InstrumentingAgents&);
|
|
@@ -426,6 +437,7 @@ private:
|
|
static void didReceiveDataImpl(InstrumentingAgents&, unsigned long identifier, const char* data, int dataLength, int encodedDataLength);
|
|
static void didFinishLoadingImpl(InstrumentingAgents&, unsigned long identifier, DocumentLoader*, const NetworkLoadMetrics&, ResourceLoader*);
|
|
static void didFailLoadingImpl(InstrumentingAgents&, unsigned long identifier, DocumentLoader*, const ResourceError&);
|
|
+ static void didReceiveMainResourceErrorImpl(InstrumentingAgents&, Frame&, const ResourceError&);
|
|
static void willLoadXHRSynchronouslyImpl(InstrumentingAgents&);
|
|
static void didLoadXHRSynchronouslyImpl(InstrumentingAgents&);
|
|
static void scriptImportedImpl(InstrumentingAgents&, unsigned long identifier, const String& sourceString);
|
|
@@ -436,11 +448,11 @@ private:
|
|
static void frameDetachedFromParentImpl(InstrumentingAgents&, Frame&);
|
|
static void didCommitLoadImpl(InstrumentingAgents&, Frame&, DocumentLoader*);
|
|
static void frameDocumentUpdatedImpl(InstrumentingAgents&, Frame&);
|
|
- static void loaderDetachedFromFrameImpl(InstrumentingAgents&, DocumentLoader&);
|
|
static void frameStartedLoadingImpl(InstrumentingAgents&, Frame&);
|
|
static void frameStoppedLoadingImpl(InstrumentingAgents&, Frame&);
|
|
static void frameScheduledNavigationImpl(InstrumentingAgents&, Frame&, Seconds delay);
|
|
static void frameClearedScheduledNavigationImpl(InstrumentingAgents&, Frame&);
|
|
+ static void didNavigateWithinPageImpl(InstrumentingAgents&, Frame&);
|
|
#if ENABLE(DARK_MODE_CSS) || HAVE(OS_DARK_MODE_SUPPORT)
|
|
static void defaultAppearanceDidChangeImpl(InstrumentingAgents&, bool useDarkAppearance);
|
|
#endif
|
|
@@ -531,6 +543,12 @@ private:
|
|
static void layerTreeDidChangeImpl(InstrumentingAgents&);
|
|
static void renderLayerDestroyedImpl(InstrumentingAgents&, const RenderLayer&);
|
|
|
|
+ static void runOpenPanelImpl(InstrumentingAgents&, HTMLInputElement*, bool*);
|
|
+ static void frameAttachedImpl(InstrumentingAgents&, Frame&);
|
|
+ static bool shouldBypassCSPImpl(InstrumentingAgents&);
|
|
+ static void willCheckNewWindowPolicyImpl(InstrumentingAgents&, const URL&);
|
|
+ static void didCheckNewWindowPolicyImpl(InstrumentingAgents&, bool allowed);
|
|
+
|
|
static InstrumentingAgents& instrumentingAgentsForPage(Page&);
|
|
static InstrumentingAgents& instrumentingAgentsForWorkerGlobalScope(WorkerGlobalScope&);
|
|
|
|
@@ -1119,6 +1137,13 @@ inline void InspectorInstrumentation::didFailLoading(Frame* frame, DocumentLoade
|
|
didFailLoadingImpl(*instrumentingAgents, identifier, loader, error);
|
|
}
|
|
|
|
+inline void InspectorInstrumentation::didReceiveMainResourceError(Frame& frame, const ResourceError& error)
|
|
+{
|
|
+ FAST_RETURN_IF_NO_FRONTENDS(void());
|
|
+ if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame))
|
|
+ didReceiveMainResourceErrorImpl(*instrumentingAgents, frame, error);
|
|
+}
|
|
+
|
|
inline void InspectorInstrumentation::didFailLoading(WorkerGlobalScope& workerGlobalScope, unsigned long identifier, const ResourceError& error)
|
|
{
|
|
didFailLoadingImpl(instrumentingAgentsForWorkerGlobalScope(workerGlobalScope), identifier, nullptr, error);
|
|
@@ -1214,13 +1239,6 @@ inline void InspectorInstrumentation::frameDocumentUpdated(Frame& frame)
|
|
frameDocumentUpdatedImpl(*instrumentingAgents, frame);
|
|
}
|
|
|
|
-inline void InspectorInstrumentation::loaderDetachedFromFrame(Frame& frame, DocumentLoader& loader)
|
|
-{
|
|
- FAST_RETURN_IF_NO_FRONTENDS(void());
|
|
- if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame))
|
|
- loaderDetachedFromFrameImpl(*instrumentingAgents, loader);
|
|
-}
|
|
-
|
|
inline void InspectorInstrumentation::frameStartedLoading(Frame& frame)
|
|
{
|
|
FAST_RETURN_IF_NO_FRONTENDS(void());
|
|
@@ -1249,6 +1267,13 @@ inline void InspectorInstrumentation::frameClearedScheduledNavigation(Frame& fra
|
|
frameClearedScheduledNavigationImpl(*instrumentingAgents, frame);
|
|
}
|
|
|
|
+inline void InspectorInstrumentation::didNavigateWithinPage(Frame& frame)
|
|
+{
|
|
+ FAST_RETURN_IF_NO_FRONTENDS(void());
|
|
+ if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame))
|
|
+ didNavigateWithinPageImpl(*instrumentingAgents, frame);
|
|
+}
|
|
+
|
|
#if ENABLE(DARK_MODE_CSS) || HAVE(OS_DARK_MODE_SUPPORT)
|
|
inline void InspectorInstrumentation::defaultAppearanceDidChange(Page& page, bool useDarkAppearance)
|
|
{
|
|
@@ -1723,6 +1748,42 @@ inline void InspectorInstrumentation::renderLayerDestroyed(Page* page, const Ren
|
|
renderLayerDestroyedImpl(*instrumentingAgents, renderLayer);
|
|
}
|
|
|
|
+inline void InspectorInstrumentation::runOpenPanel(Frame* frame, HTMLInputElement* element, bool* intercept)
|
|
+{
|
|
+ FAST_RETURN_IF_NO_FRONTENDS(void());
|
|
+ if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(*frame))
|
|
+ runOpenPanelImpl(*instrumentingAgents, element, intercept);
|
|
+}
|
|
+
|
|
+inline void InspectorInstrumentation::frameAttached(Frame* frame)
|
|
+{
|
|
+ FAST_RETURN_IF_NO_FRONTENDS(void());
|
|
+ if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame))
|
|
+ frameAttachedImpl(*instrumentingAgents, *frame);
|
|
+}
|
|
+
|
|
+inline bool InspectorInstrumentation::shouldBypassCSP(ScriptExecutionContext* context)
|
|
+{
|
|
+ FAST_RETURN_IF_NO_FRONTENDS(false);
|
|
+ if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForContext(context))
|
|
+ return shouldBypassCSPImpl(*instrumentingAgents);
|
|
+ return false;
|
|
+}
|
|
+
|
|
+inline void InspectorInstrumentation::willCheckNewWindowPolicy(Frame& frame, const URL& url)
|
|
+{
|
|
+ FAST_RETURN_IF_NO_FRONTENDS(void());
|
|
+ if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame))
|
|
+ willCheckNewWindowPolicyImpl(*instrumentingAgents, url);
|
|
+}
|
|
+
|
|
+inline void InspectorInstrumentation::didCheckNewWindowPolicy(Frame& frame, bool allowed)
|
|
+{
|
|
+ FAST_RETURN_IF_NO_FRONTENDS(void());
|
|
+ if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame))
|
|
+ didCheckNewWindowPolicyImpl(*instrumentingAgents, allowed);
|
|
+}
|
|
+
|
|
inline InstrumentingAgents* InspectorInstrumentation::instrumentingAgentsForContext(ScriptExecutionContext* context)
|
|
{
|
|
return context ? instrumentingAgentsForContext(*context) : nullptr;
|
|
diff --git a/Source/WebCore/inspector/agents/InspectorDOMAgent.cpp b/Source/WebCore/inspector/agents/InspectorDOMAgent.cpp
|
|
index f6c83ea43b81e59816130269a28b1a6623b99854..128d828b41b1249c4c7bb9f054e370982c0905bc 100644
|
|
--- a/Source/WebCore/inspector/agents/InspectorDOMAgent.cpp
|
|
+++ b/Source/WebCore/inspector/agents/InspectorDOMAgent.cpp
|
|
@@ -61,12 +61,16 @@
|
|
#include "Event.h"
|
|
#include "EventListener.h"
|
|
#include "EventNames.h"
|
|
+#include "File.h"
|
|
+#include "FileList.h"
|
|
#include "Frame.h"
|
|
#include "FrameTree.h"
|
|
#include "FrameView.h"
|
|
#include "FullscreenManager.h"
|
|
+#include "FloatQuad.h"
|
|
#include "HTMLElement.h"
|
|
#include "HTMLFrameOwnerElement.h"
|
|
+#include "HTMLInputElement.h"
|
|
#include "HTMLMediaElement.h"
|
|
#include "HTMLNames.h"
|
|
#include "HTMLParserIdioms.h"
|
|
@@ -93,11 +97,14 @@
|
|
#include "Page.h"
|
|
#include "Pasteboard.h"
|
|
#include "PseudoElement.h"
|
|
+#include "RenderLayer.h"
|
|
+#include "RenderObject.h"
|
|
#include "RenderStyle.h"
|
|
#include "RenderStyleConstants.h"
|
|
#include "ScriptState.h"
|
|
#include "SelectorChecker.h"
|
|
#include "ShadowRoot.h"
|
|
+#include "SharedBuffer.h"
|
|
#include "StaticNodeList.h"
|
|
#include "StyleProperties.h"
|
|
#include "StyleResolver.h"
|
|
@@ -129,7 +136,8 @@ using namespace HTMLNames;
|
|
static const size_t maxTextSize = 10000;
|
|
static const UChar ellipsisUChar[] = { 0x2026, 0 };
|
|
|
|
-static Color parseColor(RefPtr<JSON::Object>&& colorObject)
|
|
+// static
|
|
+Color InspectorDOMAgent::parseColor(RefPtr<JSON::Object>&& colorObject)
|
|
{
|
|
if (!colorObject)
|
|
return Color::transparentBlack;
|
|
@@ -148,7 +156,7 @@ static Color parseColor(RefPtr<JSON::Object>&& colorObject)
|
|
|
|
static Color parseConfigColor(const String& fieldName, JSON::Object& configObject)
|
|
{
|
|
- return parseColor(configObject.getObject(fieldName));
|
|
+ return InspectorDOMAgent::parseColor(configObject.getObject(fieldName));
|
|
}
|
|
|
|
static bool parseQuad(Ref<JSON::Array>&& quadArray, FloatQuad* quad)
|
|
@@ -431,6 +439,20 @@ Node* InspectorDOMAgent::assertNode(Protocol::ErrorString& errorString, Protocol
|
|
return node;
|
|
}
|
|
|
|
+Node* InspectorDOMAgent::assertNode(Protocol::ErrorString& errorString, 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(Protocol::ErrorString& errorString, Protocol::DOM::NodeId nodeId)
|
|
{
|
|
Node* node = assertNode(errorString, nodeId);
|
|
@@ -1389,16 +1411,7 @@ Protocol::ErrorStringOr<void> InspectorDOMAgent::highlightSelector(Ref<JSON::Obj
|
|
Protocol::ErrorStringOr<void> InspectorDOMAgent::highlightNode(Ref<JSON::Object>&& highlightInspectorObject, Optional<Protocol::DOM::NodeId>&& nodeId, const Protocol::Runtime::RemoteObjectId& objectId)
|
|
{
|
|
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);
|
|
|
|
@@ -1560,15 +1573,137 @@ Protocol::ErrorStringOr<void> InspectorDOMAgent::setInspectedNode(Protocol::DOM:
|
|
return { };
|
|
}
|
|
|
|
-Protocol::ErrorStringOr<Ref<Protocol::Runtime::RemoteObject>> InspectorDOMAgent::resolveNode(Protocol::DOM::NodeId nodeId, const String& objectGroup)
|
|
+static FloatPoint contentsToRootView(FrameView& containingView, const FloatPoint& point)
|
|
{
|
|
- Protocol::ErrorString errorString;
|
|
+ return containingView.convertToRootView(point - toFloatSize(containingView.documentScrollPositionRelativeToViewOrigin()));
|
|
+}
|
|
|
|
- Node* node = assertNode(errorString, nodeId);
|
|
+static void frameQuadToViewport(FrameView& containingView, FloatQuad& quad, float pageScaleFactor)
|
|
+{
|
|
+ // Return css (not dip) coordinates by scaling back.
|
|
+ quad.setP1(contentsToRootView(containingView, quad.p1()).scaled(1 / pageScaleFactor));
|
|
+ quad.setP2(contentsToRootView(containingView, quad.p2()).scaled(1 / pageScaleFactor));
|
|
+ quad.setP3(contentsToRootView(containingView, quad.p3()).scaled(1 / pageScaleFactor));
|
|
+ quad.setP4(contentsToRootView(containingView, quad.p4()).scaled(1 / pageScaleFactor));
|
|
+}
|
|
+
|
|
+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);
|
|
+ String frameId = pageAgent->frameId(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();
|
|
+ if (!renderer)
|
|
+ return makeUnexpected("Node does not have a layout object"_s);
|
|
+
|
|
+ bool insideFixed;
|
|
+ LayoutRect absoluteBounds = renderer->absoluteBoundingBoxRect(true, &insideFixed);
|
|
+ if (rect) {
|
|
+ Optional<double> x = rect->getDouble("x");
|
|
+ Optional<double> y = rect->getDouble("y");
|
|
+ Optional<double> width = rect->getDouble("width");
|
|
+ Optional<double> height = rect->getDouble("height");
|
|
+ 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)));
|
|
+ }
|
|
+ // Note: we should use ScrollAlignment::alignCenterIfNotVisible, but
|
|
+ // RenderLayer insists on no horizontal scroll if enough of the rect is visible.
|
|
+ ScrollAlignment alignment = ScrollAlignment::alignCenterAlways;
|
|
+ renderer->scrollRectToVisible(absoluteBounds, insideFixed, { SelectionRevealMode::Reveal, alignment, alignment, ShouldAllowCrossOriginScrolling::Yes });
|
|
+ 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);
|
|
+
|
|
+ RenderObject* renderer = node->renderer();
|
|
+ if (!renderer)
|
|
+ return makeUnexpected("Node doesn't have renderer"_s);
|
|
+
|
|
+ // Ensure quads are up to date.
|
|
+ m_inspectedPage.isolatedUpdateRendering();
|
|
+
|
|
+ Frame* containingFrame = renderer->document().frame();
|
|
+ FrameView* containingView = containingFrame ? containingFrame->view() : nullptr;
|
|
+ if (!containingView)
|
|
+ return makeUnexpected("Internal error: no containing view"_s);
|
|
+
|
|
+ Vector<FloatQuad> quads;
|
|
+ renderer->absoluteQuads(quads);
|
|
+ for (auto& quad : quads)
|
|
+ frameQuadToViewport(*containingView, quad, m_inspectedPage.pageScaleFactor());
|
|
+ return buildArrayOfQuads(quads);
|
|
+}
|
|
+
|
|
+Protocol::ErrorStringOr<Ref<Protocol::Runtime::RemoteObject>> InspectorDOMAgent::resolveNode(Optional<Inspector::Protocol::DOM::NodeId>&& nodeId, const String& objectId, Optional<int>&& contextId, const String& objectGroup)
|
|
+{
|
|
+ Protocol::ErrorString errorString;
|
|
+ Node* 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);
|
|
|
|
@@ -2759,7 +2894,7 @@ Protocol::ErrorStringOr<Protocol::DOM::NodeId> InspectorDOMAgent::pushNodeByPath
|
|
return makeUnexpected("Missing node for given path"_s);
|
|
}
|
|
|
|
-RefPtr<Protocol::Runtime::RemoteObject> InspectorDOMAgent::resolveNode(Node* node, const String& objectGroup)
|
|
+RefPtr<Inspector::Protocol::Runtime::RemoteObject> InspectorDOMAgent::resolveNode(Node* node, const String& objectGroup, Optional<int>&& contextId)
|
|
{
|
|
Document* document = &node->document();
|
|
if (auto* templateHost = document->templateDocumentHost())
|
|
@@ -2768,12 +2903,16 @@ RefPtr<Protocol::Runtime::RemoteObject> InspectorDOMAgent::resolveNode(Node* nod
|
|
if (!frame)
|
|
return nullptr;
|
|
|
|
- auto& state = *mainWorldExecState(frame);
|
|
- auto injectedScript = m_injectedScriptManager.injectedScriptFor(&state);
|
|
+ InjectedScript injectedScript;
|
|
+ if (contextId) {
|
|
+ injectedScript = m_injectedScriptManager.injectedScriptForId(*contextId);
|
|
+ } else {
|
|
+ injectedScript = m_injectedScriptManager.injectedScriptFor(mainWorldExecState(frame));
|
|
+ }
|
|
if (injectedScript.hasNoValue())
|
|
return nullptr;
|
|
|
|
- return injectedScript.wrapObject(nodeAsScriptValue(state, node), objectGroup);
|
|
+ return injectedScript.wrapObject(nodeAsScriptValue(*injectedScript.globalObject(), node), objectGroup);
|
|
}
|
|
|
|
Node* InspectorDOMAgent::scriptValueAsNode(JSC::JSValue value)
|
|
@@ -2796,4 +2935,42 @@ Protocol::ErrorStringOr<void> InspectorDOMAgent::setAllowEditingUserAgentShadowT
|
|
return { };
|
|
}
|
|
|
|
+Protocol::ErrorStringOr<void> InspectorDOMAgent::setInputFiles(const String& objectId, Ref<JSON::Array>&& files) {
|
|
+ InjectedScript injectedScript = m_injectedScriptManager.injectedScriptForObjectId(objectId);
|
|
+ if (injectedScript.hasNoValue())
|
|
+ return makeUnexpected("Can not find element's context for given id"_s);
|
|
+
|
|
+ Node* node = scriptValueAsNode(injectedScript.findObjectById(objectId));
|
|
+ if (!node)
|
|
+ return makeUnexpected("Can not find element for given id"_s);
|
|
+
|
|
+ if (node->nodeType() != Node::ELEMENT_NODE || node->nodeName() != "INPUT")
|
|
+ return makeUnexpected("Not an input node"_s);
|
|
+
|
|
+ HTMLInputElement* element = static_cast<HTMLInputElement*>(node);
|
|
+ Vector<Ref<File>> fileObjects;
|
|
+ for (unsigned i = 0; i < files->length(); ++i) {
|
|
+ RefPtr<JSON::Value> item = files->get(i);
|
|
+ RefPtr<JSON::Object> obj = item->asObject();
|
|
+ if (!obj)
|
|
+ return makeUnexpected("Invalid file payload format"_s);
|
|
+
|
|
+ String name;
|
|
+ String type;
|
|
+ String data;
|
|
+ if (!obj->getString("name", name) || !obj->getString("type", type) || !obj->getString("data", data))
|
|
+ return makeUnexpected("Invalid file payload format"_s);
|
|
+
|
|
+ Vector<uint8_t> buffer;
|
|
+ if (!base64Decode(data, buffer))
|
|
+ return makeUnexpected("Unable to decode given content"_s);
|
|
+
|
|
+ ScriptExecutionContext* context = element->scriptExecutionContext();
|
|
+ fileObjects.append(File::create(context, Blob::create(context, SharedBuffer::create(WTFMove(buffer)), type), name));
|
|
+ }
|
|
+ RefPtr<FileList> fileList = FileList::create(WTFMove(fileObjects));
|
|
+ element->setFiles(WTFMove(fileList));
|
|
+ return { };
|
|
+}
|
|
+
|
|
} // namespace WebCore
|
|
diff --git a/Source/WebCore/inspector/agents/InspectorDOMAgent.h b/Source/WebCore/inspector/agents/InspectorDOMAgent.h
|
|
index 7f2872df49e0d40ab020cd9884ded00308f1a2a6..a2512f35fdea0d0f6ea9393354461e022c2576f3 100644
|
|
--- a/Source/WebCore/inspector/agents/InspectorDOMAgent.h
|
|
+++ b/Source/WebCore/inspector/agents/InspectorDOMAgent.h
|
|
@@ -55,6 +55,7 @@ namespace WebCore {
|
|
|
|
class AXCoreObject;
|
|
class CharacterData;
|
|
+class Color;
|
|
class DOMEditor;
|
|
class Document;
|
|
class Element;
|
|
@@ -87,6 +88,7 @@ public:
|
|
static String toErrorString(Exception&&);
|
|
|
|
static String documentURLString(Document*);
|
|
+ static 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.
|
|
@@ -130,7 +132,7 @@ public:
|
|
Inspector::Protocol::ErrorStringOr<std::tuple<String /* searchId */, int /* resultCount */>> performSearch(const String& query, RefPtr<JSON::Array>&& nodeIds, 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(Optional<Inspector::Protocol::DOM::NodeId>&& nodeId, const String& objectId, 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);
|
|
@@ -153,6 +155,10 @@ public:
|
|
Inspector::Protocol::ErrorStringOr<void> focus(Inspector::Protocol::DOM::NodeId);
|
|
Inspector::Protocol::ErrorStringOr<void> setInspectedNode(Inspector::Protocol::DOM::NodeId);
|
|
Inspector::Protocol::ErrorStringOr<void> setAllowEditingUserAgentShadowTrees(bool);
|
|
+ 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);
|
|
+ Inspector::Protocol::ErrorStringOr<void> setInputFiles(const String& objectId, Ref<JSON::Array>&& files);
|
|
|
|
// InspectorInstrumentation
|
|
Inspector::Protocol::DOM::NodeId identifierForNode(Node&);
|
|
@@ -190,7 +196,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, Optional<int>&& contextId);
|
|
bool handleMousePress();
|
|
void mouseDidMoveOverElement(const HitTestResult&, unsigned modifierFlags);
|
|
void inspect(Node*);
|
|
@@ -201,12 +207,15 @@ public:
|
|
void reset();
|
|
|
|
Node* assertNode(Inspector::Protocol::ErrorString&, Inspector::Protocol::DOM::NodeId);
|
|
+ Node* assertNode(Inspector::Protocol::ErrorString&, 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();
|
|
@@ -235,7 +244,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/InspectorDOMStorageAgent.h b/Source/WebCore/inspector/agents/InspectorDOMStorageAgent.h
|
|
index 3386cb879f1178c1b9635775c9a0e864f5b94c52..d2350182f5f061855e8ca172779ad60ee73b39fb 100644
|
|
--- a/Source/WebCore/inspector/agents/InspectorDOMStorageAgent.h
|
|
+++ b/Source/WebCore/inspector/agents/InspectorDOMStorageAgent.h
|
|
@@ -40,6 +40,7 @@ class DOMStorageFrontendDispatcher;
|
|
|
|
namespace WebCore {
|
|
|
|
+class Color;
|
|
class Frame;
|
|
class Page;
|
|
class SecurityOrigin;
|
|
diff --git a/Source/WebCore/inspector/agents/InspectorNetworkAgent.cpp b/Source/WebCore/inspector/agents/InspectorNetworkAgent.cpp
|
|
index 575382e4390dd31dbf404fc72662b2206071c7e8..e8d30e12a11b8d24d39c8201375f09b9b108a65b 100644
|
|
--- a/Source/WebCore/inspector/agents/InspectorNetworkAgent.cpp
|
|
+++ b/Source/WebCore/inspector/agents/InspectorNetworkAgent.cpp
|
|
@@ -45,6 +45,7 @@
|
|
#include "DocumentThreadableLoader.h"
|
|
#include "FormData.h"
|
|
#include "Frame.h"
|
|
+#include "FormData.h"
|
|
#include "FrameLoader.h"
|
|
#include "HTTPHeaderMap.h"
|
|
#include "HTTPHeaderNames.h"
|
|
@@ -57,6 +58,7 @@
|
|
#include "MIMETypeRegistry.h"
|
|
#include "MemoryCache.h"
|
|
#include "NetworkResourcesData.h"
|
|
+#include "NetworkStateNotifier.h"
|
|
#include "Page.h"
|
|
#include "PlatformStrategies.h"
|
|
#include "ProgressTracker.h"
|
|
@@ -490,8 +492,14 @@ static InspectorPageAgent::ResourceType resourceTypeForLoadType(InspectorInstrum
|
|
|
|
void InspectorNetworkAgent::willSendRequest(unsigned long identifier, DocumentLoader* loader, ResourceRequest& request, const ResourceResponse& redirectResponse)
|
|
{
|
|
- auto* cachedResource = loader ? InspectorPageAgent::cachedResource(loader->frame(), request.url()) : nullptr;
|
|
- willSendRequest(identifier, loader, request, redirectResponse, resourceTypeForCachedResource(cachedResource));
|
|
+ InspectorPageAgent::ResourceType resourceType;
|
|
+ if (request.initiatorIdentifier() == initiatorIdentifierForEventSource()) {
|
|
+ resourceType = InspectorPageAgent::EventSource;
|
|
+ } else {
|
|
+ auto* cachedResource = loader ? InspectorPageAgent::cachedResource(loader->frame(), request.url()) : nullptr;
|
|
+ resourceType = resourceTypeForCachedResource(cachedResource);
|
|
+ }
|
|
+ willSendRequest(identifier, loader, request, redirectResponse, resourceType);
|
|
}
|
|
|
|
void InspectorNetworkAgent::willSendRequestOfType(unsigned long identifier, DocumentLoader* loader, ResourceRequest& request, InspectorInstrumentation::LoadType loadType)
|
|
@@ -1105,8 +1113,7 @@ bool InspectorNetworkAgent::willIntercept(const ResourceRequest& request)
|
|
if (!m_interceptionEnabled)
|
|
return false;
|
|
|
|
- return shouldIntercept(request.url(), Protocol::Network::NetworkStage::Request)
|
|
- || shouldIntercept(request.url(), Protocol::Network::NetworkStage::Response);
|
|
+ return shouldIntercept(request.url(), Protocol::Network::NetworkStage::Response);
|
|
}
|
|
|
|
bool InspectorNetworkAgent::shouldInterceptRequest(const ResourceRequest& request)
|
|
@@ -1189,6 +1196,9 @@ Protocol::ErrorStringOr<void> InspectorNetworkAgent::interceptWithRequest(const
|
|
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));
|
|
@@ -1292,6 +1302,8 @@ Protocol::ErrorStringOr<void> InspectorNetworkAgent::interceptRequestWithRespons
|
|
response.setHTTPHeaderFields(WTFMove(explicitHeaders));
|
|
response.setHTTPHeaderField(HTTPHeaderName::ContentType, response.mimeType());
|
|
loader->didReceiveResponse(response, [loader, buffer = data.releaseNonNull()]() mutable {
|
|
+ if (loader->reachedTerminalState())
|
|
+ return;
|
|
if (buffer->size())
|
|
loader->didReceiveBuffer(WTFMove(buffer), buffer->size(), DataPayloadWholeResource);
|
|
loader->didFinishLoading(NetworkLoadMetrics());
|
|
@@ -1332,6 +1344,12 @@ Protocol::ErrorStringOr<void> InspectorNetworkAgent::interceptRequestWithError(c
|
|
return { };
|
|
}
|
|
|
|
+Inspector::Protocol::ErrorStringOr<void> InspectorNetworkAgent::setEmulateOfflineState(bool offline)
|
|
+{
|
|
+ platformStrategies()->loaderStrategy()->setEmulateOfflineState(offline);
|
|
+ return { };
|
|
+}
|
|
+
|
|
bool InspectorNetworkAgent::shouldTreatAsText(const String& mimeType)
|
|
{
|
|
return startsWithLettersIgnoringASCIICase(mimeType, "text/")
|
|
@@ -1373,6 +1391,12 @@ Optional<String> InspectorNetworkAgent::textContentForCachedResource(CachedResou
|
|
return WTF::nullopt;
|
|
}
|
|
|
|
+// static
|
|
+String InspectorNetworkAgent::initiatorIdentifierForEventSource()
|
|
+{
|
|
+ return "InspectorNetworkAgent: eventSource"_s;
|
|
+}
|
|
+
|
|
bool InspectorNetworkAgent::cachedResourceContent(CachedResource& resource, String* result, bool* base64Encoded)
|
|
{
|
|
ASSERT(result);
|
|
diff --git a/Source/WebCore/inspector/agents/InspectorNetworkAgent.h b/Source/WebCore/inspector/agents/InspectorNetworkAgent.h
|
|
index 933601761667417ebe5de301586869ccc64fc3da..f63a95c3c45980d5606971b83881e8245df11403 100644
|
|
--- a/Source/WebCore/inspector/agents/InspectorNetworkAgent.h
|
|
+++ b/Source/WebCore/inspector/agents/InspectorNetworkAgent.h
|
|
@@ -71,6 +71,7 @@ public:
|
|
static Ref<TextResourceDecoder> createTextDecoder(const String& mimeType, const String& textEncodingName);
|
|
static Optional<String> textContentForCachedResource(CachedResource&);
|
|
static bool cachedResourceContent(CachedResource&, String* result, bool* base64Encoded);
|
|
+ static String initiatorIdentifierForEventSource();
|
|
|
|
// InspectorAgentBase
|
|
void didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*) final;
|
|
@@ -93,6 +94,7 @@ public:
|
|
Inspector::Protocol::ErrorStringOr<void> interceptWithResponse(const Inspector::Protocol::Network::RequestId&, const String& content, bool base64Encoded, const String& mimeType, Optional<int>&& status, const String& statusText, RefPtr<JSON::Object>&& headers) final;
|
|
Inspector::Protocol::ErrorStringOr<void> interceptRequestWithResponse(const Inspector::Protocol::Network::RequestId&, const String& content, bool base64Encoded, const String& mimeType, int status, const String& statusText, Ref<JSON::Object>&& headers) final;
|
|
Inspector::Protocol::ErrorStringOr<void> interceptRequestWithError(const Inspector::Protocol::Network::RequestId&, Inspector::Protocol::Network::ResourceErrorType) final;
|
|
+ Inspector::Protocol::ErrorStringOr<void> setEmulateOfflineState(bool offline) final;
|
|
|
|
// InspectorInstrumentation
|
|
void willRecalculateStyle();
|
|
diff --git a/Source/WebCore/inspector/agents/InspectorPageAgent.cpp b/Source/WebCore/inspector/agents/InspectorPageAgent.cpp
|
|
index e1008edf1c6d453234e29a63d8a0e7a35cc812f4..02fecbf8cdc93b930ab06ac1d98b25f4f94d147c 100644
|
|
--- a/Source/WebCore/inspector/agents/InspectorPageAgent.cpp
|
|
+++ b/Source/WebCore/inspector/agents/InspectorPageAgent.cpp
|
|
@@ -32,19 +32,25 @@
|
|
#include "config.h"
|
|
#include "InspectorPageAgent.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 "Document.h"
|
|
#include "DocumentLoader.h"
|
|
+#include "FocusController.h"
|
|
#include "Frame.h"
|
|
#include "FrameLoadRequest.h"
|
|
#include "FrameLoader.h"
|
|
+#include "FrameLoaderClient.h"
|
|
#include "FrameSnapshotting.h"
|
|
#include "FrameView.h"
|
|
#include "HTMLFrameOwnerElement.h"
|
|
+#include "HTMLInputElement.h"
|
|
#include "HTMLNames.h"
|
|
#include "ImageBuffer.h"
|
|
#include "InspectorClient.h"
|
|
@@ -55,19 +61,28 @@
|
|
#include "MIMETypeRegistry.h"
|
|
#include "MemoryCache.h"
|
|
#include "Page.h"
|
|
+#include "PageRuntimeAgent.h"
|
|
#include "RenderObject.h"
|
|
#include "RenderTheme.h"
|
|
+#include "RuntimeEnabledFeatures.h"
|
|
#include "ScriptController.h"
|
|
#include "ScriptSourceCode.h"
|
|
+#include "ScriptState.h"
|
|
#include "SecurityOrigin.h"
|
|
#include "Settings.h"
|
|
#include "StyleScope.h"
|
|
#include "TextEncoding.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/Ref.h>
|
|
+#include <wtf/RefPtr.h>
|
|
#include <wtf/Stopwatch.h>
|
|
#include <wtf/text/Base64.h>
|
|
#include <wtf/text/StringBuilder.h>
|
|
@@ -80,11 +95,15 @@
|
|
#include "LegacyWebArchive.h"
|
|
#endif
|
|
|
|
-
|
|
namespace WebCore {
|
|
|
|
using namespace Inspector;
|
|
|
|
+static HashMap<String, Ref<DOMWrapperWorld>>& createdUserWorlds() {
|
|
+ static NeverDestroyed<HashMap<String, Ref<DOMWrapperWorld>>> nameToWorld;
|
|
+ return nameToWorld;
|
|
+}
|
|
+
|
|
static bool decodeBuffer(const char* buffer, unsigned size, const String& textEncodingName, String* result)
|
|
{
|
|
if (buffer) {
|
|
@@ -234,6 +253,8 @@ Protocol::Page::ResourceType InspectorPageAgent::resourceTypeJSON(InspectorPageA
|
|
return Protocol::Page::ResourceType::Beacon;
|
|
case WebSocketResource:
|
|
return Protocol::Page::ResourceType::WebSocket;
|
|
+ case EventSource:
|
|
+ return Protocol::Page::ResourceType::EventSource;
|
|
case OtherResource:
|
|
return Protocol::Page::ResourceType::Other;
|
|
#if ENABLE(APPLICATION_MANIFEST)
|
|
@@ -321,6 +342,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)
|
|
{
|
|
@@ -352,12 +374,20 @@ Protocol::ErrorStringOr<void> InspectorPageAgent::enable()
|
|
defaultAppearanceDidChange(m_inspectedPage.defaultUseDarkAppearance());
|
|
#endif
|
|
|
|
+ if (!createdUserWorlds().isEmpty()) {
|
|
+ Vector<DOMWrapperWorld*> worlds;
|
|
+ for (const auto& world : createdUserWorlds().values())
|
|
+ worlds.append(world.ptr());
|
|
+ ensureUserWorldsExistInAllFrames(worlds);
|
|
+ }
|
|
return { };
|
|
}
|
|
|
|
Protocol::ErrorStringOr<void> InspectorPageAgent::disable()
|
|
{
|
|
m_instrumentingAgents.setEnabledPageAgent(nullptr);
|
|
+ m_interceptFileChooserDialog = false;
|
|
+ m_bypassCSP = false;
|
|
|
|
setShowPaintRects(false);
|
|
#if !PLATFORM(IOS_FAMILY)
|
|
@@ -406,6 +436,22 @@ Protocol::ErrorStringOr<void> InspectorPageAgent::reload(Optional<bool>&& ignore
|
|
return { };
|
|
}
|
|
|
|
+Protocol::ErrorStringOr<void> InspectorPageAgent::goBack()
|
|
+{
|
|
+ if (!m_inspectedPage.backForward().goBack())
|
|
+ return makeUnexpected("Failed to go back"_s);
|
|
+
|
|
+ return { };
|
|
+}
|
|
+
|
|
+Protocol::ErrorStringOr<void> InspectorPageAgent::goForward()
|
|
+{
|
|
+ if (!m_inspectedPage.backForward().goForward())
|
|
+ return makeUnexpected("Failed to go forward"_s);
|
|
+
|
|
+ return { };
|
|
+}
|
|
+
|
|
Protocol::ErrorStringOr<void> InspectorPageAgent::navigate(const String& url)
|
|
{
|
|
UserGestureIndicator indicator { ProcessingUserGesture };
|
|
@@ -801,15 +847,16 @@ Protocol::ErrorStringOr<void> InspectorPageAgent::setShowPaintRects(bool show)
|
|
return { };
|
|
}
|
|
|
|
-void InspectorPageAgent::domContentEventFired()
|
|
+void InspectorPageAgent::domContentEventFired(Frame& 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(Frame& frame)
|
|
{
|
|
- m_frontendDispatcher->loadEventFired(timestamp());
|
|
+ m_frontendDispatcher->loadEventFired(timestamp(), frameId(&frame));
|
|
}
|
|
|
|
void InspectorPageAgent::frameNavigated(Frame& frame)
|
|
@@ -817,13 +864,23 @@ void InspectorPageAgent::frameNavigated(Frame& frame)
|
|
m_frontendDispatcher->frameNavigated(buildObjectForFrame(&frame));
|
|
}
|
|
|
|
+String InspectorPageAgent::makeFrameID(ProcessIdentifier processID, FrameIdentifier frameID)
|
|
+{
|
|
+ return makeString(processID.toUInt64(), ".", frameID.toUInt64());
|
|
+}
|
|
+
|
|
+static String globalIDForFrame(Frame& frame)
|
|
+{
|
|
+ return InspectorPageAgent::makeFrameID(Process::identifier(), *frame.loader().client().frameID());
|
|
+}
|
|
+
|
|
void InspectorPageAgent::frameDetached(Frame& frame)
|
|
{
|
|
- auto identifier = m_frameToIdentifier.take(&frame);
|
|
- if (identifier.isNull())
|
|
+ String identifier = globalIDForFrame(frame);
|
|
+ if (!m_identifierToFrame.take(identifier))
|
|
return;
|
|
+
|
|
m_frontendDispatcher->frameDetached(identifier);
|
|
- m_identifierToFrame.remove(identifier);
|
|
}
|
|
|
|
Frame* InspectorPageAgent::frameForId(const Protocol::Network::FrameId& frameId)
|
|
@@ -835,20 +892,18 @@ 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 = globalIDForFrame(*frame);
|
|
+ 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;
|
|
+
|
|
+ return String::number(loader->loaderIDForInspector());
|
|
}
|
|
|
|
Frame* InspectorPageAgent::assertFrame(Protocol::ErrorString& errorString, const Protocol::Network::FrameId& frameId)
|
|
@@ -859,11 +914,6 @@ Frame* InspectorPageAgent::assertFrame(Protocol::ErrorString& errorString, const
|
|
return frame;
|
|
}
|
|
|
|
-void InspectorPageAgent::loaderDetachedFromFrame(DocumentLoader& loader)
|
|
-{
|
|
- m_loaderToIdentifier.remove(&loader);
|
|
-}
|
|
-
|
|
void InspectorPageAgent::frameStartedLoading(Frame& frame)
|
|
{
|
|
m_frontendDispatcher->frameStartedLoading(frameId(&frame));
|
|
@@ -884,6 +934,12 @@ void InspectorPageAgent::frameClearedScheduledNavigation(Frame& frame)
|
|
m_frontendDispatcher->frameClearedScheduledNavigation(frameId(&frame));
|
|
}
|
|
|
|
+void InspectorPageAgent::didNavigateWithinPage(Frame& frame)
|
|
+{
|
|
+ String url = frame.document()->url().string();
|
|
+ m_frontendDispatcher->navigatedWithinDocument(frameId(&frame), url);
|
|
+}
|
|
+
|
|
#if ENABLE(DARK_MODE_CSS) || HAVE(OS_DARK_MODE_SUPPORT)
|
|
void InspectorPageAgent::defaultAppearanceDidChange(bool useDarkAppearance)
|
|
{
|
|
@@ -943,6 +999,52 @@ void InspectorPageAgent::didRecalculateStyle()
|
|
m_overlay->update();
|
|
}
|
|
|
|
+void InspectorPageAgent::runOpenPanel(HTMLInputElement* element, bool* intercept)
|
|
+{
|
|
+ if (m_interceptFileChooserDialog) {
|
|
+ *intercept = true;
|
|
+ } else {
|
|
+ return;
|
|
+ }
|
|
+ Document& document = element->document();
|
|
+ auto* frame = document.frame();
|
|
+ if (!frame)
|
|
+ return;
|
|
+
|
|
+ auto& state = *mainWorldExecState(frame);
|
|
+ auto injectedScript = m_injectedScriptManager.injectedScriptFor(&state);
|
|
+ if (injectedScript.hasNoValue())
|
|
+ return;
|
|
+
|
|
+ auto object = injectedScript.wrapObject(InspectorDOMAgent::nodeAsScriptValue(state, element), WTF::String());
|
|
+ if (!object)
|
|
+ return;
|
|
+
|
|
+ m_frontendDispatcher->fileChooserOpened(frameId(frame), object.releaseNonNull());
|
|
+}
|
|
+
|
|
+void InspectorPageAgent::frameAttached(Frame& frame)
|
|
+{
|
|
+ Frame* parent = frame.tree().parent();
|
|
+ String parentFrameId = frameId(parent);
|
|
+ m_frontendDispatcher->frameAttached(frameId(&frame), parentFrameId);
|
|
+}
|
|
+
|
|
+bool InspectorPageAgent::shouldBypassCSP()
|
|
+{
|
|
+ return m_bypassCSP;
|
|
+}
|
|
+
|
|
+void InspectorPageAgent::willCheckNewWindowPolicy(const URL& url)
|
|
+{
|
|
+ m_frontendDispatcher->willRequestOpenWindow(url.string());
|
|
+}
|
|
+
|
|
+void InspectorPageAgent::didCheckNewWindowPolicy(bool allowed)
|
|
+{
|
|
+ m_frontendDispatcher->didRequestOpenWindow(allowed);
|
|
+}
|
|
+
|
|
Ref<Protocol::Page::Frame> InspectorPageAgent::buildObjectForFrame(Frame* frame)
|
|
{
|
|
ASSERT_ARG(frame, frame);
|
|
@@ -1094,6 +1196,27 @@ Protocol::ErrorStringOr<String> InspectorPageAgent::snapshotRect(int x, int y, i
|
|
return snapshot->toDataURL("image/png"_s, WTF::nullopt, PreserveResolution::Yes);
|
|
}
|
|
|
|
+Protocol::ErrorStringOr<void> InspectorPageAgent::setTimeZone(const String& timeZone)
|
|
+{
|
|
+ bool success = WTF::setTimeZoneForAutomation(timeZone);
|
|
+ if (!success)
|
|
+ return makeUnexpected("Invalid time zone " + timeZone);
|
|
+
|
|
+ return { };
|
|
+}
|
|
+
|
|
+Protocol::ErrorStringOr<void> InspectorPageAgent::setTouchEmulationEnabled(bool enabled)
|
|
+{
|
|
+#if ENABLE(TOUCH_EVENTS)
|
|
+ RuntimeEnabledFeatures::sharedFeatures().setTouchEventsEnabled(enabled);
|
|
+ return { };
|
|
+#else
|
|
+ UNUSED_PARAM(enabled);
|
|
+ return makeUnexpected("Not supported"_s);
|
|
+#endif
|
|
+}
|
|
+
|
|
+
|
|
#if ENABLE(WEB_ARCHIVE) && USE(CF)
|
|
Protocol::ErrorStringOr<String> InspectorPageAgent::archive()
|
|
{
|
|
@@ -1106,4 +1229,541 @@ Protocol::ErrorStringOr<String> InspectorPageAgent::archive()
|
|
}
|
|
#endif
|
|
|
|
+Protocol::ErrorStringOr<void> InspectorPageAgent::insertText(const String& text)
|
|
+{
|
|
+ UserGestureIndicator indicator { ProcessingUserGesture };
|
|
+ Document* focusedDocument = m_inspectedPage.focusController().focusedOrMainFrame().document();
|
|
+ TypingCommand::insertText(*focusedDocument, text, 0);
|
|
+ return { };
|
|
+}
|
|
+
|
|
+static String roleFromObject(RefPtr<AXCoreObject> axObject)
|
|
+{
|
|
+ String computedRoleString = axObject->computedRoleString();
|
|
+ if (!computedRoleString.isEmpty())
|
|
+ return computedRoleString;
|
|
+ AccessibilityRole role = axObject->roleValue();
|
|
+ switch(role) {
|
|
+ case AccessibilityRole::Annotation:
|
|
+ return "Annotation";
|
|
+ case AccessibilityRole::Application:
|
|
+ return "Application";
|
|
+ case AccessibilityRole::ApplicationAlert:
|
|
+ return "ApplicationAlert";
|
|
+ case AccessibilityRole::ApplicationAlertDialog:
|
|
+ return "ApplicationAlertDialog";
|
|
+ case AccessibilityRole::ApplicationDialog:
|
|
+ return "ApplicationDialog";
|
|
+ case AccessibilityRole::ApplicationGroup:
|
|
+ return "ApplicationGroup";
|
|
+ case AccessibilityRole::ApplicationLog:
|
|
+ return "ApplicationLog";
|
|
+ case AccessibilityRole::ApplicationMarquee:
|
|
+ return "ApplicationMarquee";
|
|
+ case AccessibilityRole::ApplicationStatus:
|
|
+ return "ApplicationStatus";
|
|
+ case AccessibilityRole::ApplicationTextGroup:
|
|
+ return "ApplicationTextGroup";
|
|
+ case AccessibilityRole::ApplicationTimer:
|
|
+ return "ApplicationTimer";
|
|
+ case AccessibilityRole::Audio:
|
|
+ return "Audio";
|
|
+ case AccessibilityRole::Blockquote:
|
|
+ return "Blockquote";
|
|
+ case AccessibilityRole::Browser:
|
|
+ return "Browser";
|
|
+ case AccessibilityRole::BusyIndicator:
|
|
+ return "BusyIndicator";
|
|
+ case AccessibilityRole::Button:
|
|
+ return "Button";
|
|
+ case AccessibilityRole::Canvas:
|
|
+ return "Canvas";
|
|
+ case AccessibilityRole::Caption:
|
|
+ return "Caption";
|
|
+ case AccessibilityRole::Cell:
|
|
+ return "Cell";
|
|
+ case AccessibilityRole::CheckBox:
|
|
+ return "CheckBox";
|
|
+ case AccessibilityRole::ColorWell:
|
|
+ return "ColorWell";
|
|
+ case AccessibilityRole::Column:
|
|
+ return "Column";
|
|
+ case AccessibilityRole::ColumnHeader:
|
|
+ return "ColumnHeader";
|
|
+ case AccessibilityRole::ComboBox:
|
|
+ return "ComboBox";
|
|
+ case AccessibilityRole::Definition:
|
|
+ return "Definition";
|
|
+ case AccessibilityRole::Deletion:
|
|
+ return "Deletion";
|
|
+ case AccessibilityRole::DescriptionList:
|
|
+ return "DescriptionList";
|
|
+ case AccessibilityRole::DescriptionListTerm:
|
|
+ return "DescriptionListTerm";
|
|
+ case AccessibilityRole::DescriptionListDetail:
|
|
+ return "DescriptionListDetail";
|
|
+ case AccessibilityRole::Details:
|
|
+ return "Details";
|
|
+ case AccessibilityRole::Directory:
|
|
+ return "Directory";
|
|
+ case AccessibilityRole::DisclosureTriangle:
|
|
+ return "DisclosureTriangle";
|
|
+ case AccessibilityRole::Div:
|
|
+ return "Div";
|
|
+ case AccessibilityRole::Document:
|
|
+ return "Document";
|
|
+ case AccessibilityRole::DocumentArticle:
|
|
+ return "DocumentArticle";
|
|
+ case AccessibilityRole::DocumentMath:
|
|
+ return "DocumentMath";
|
|
+ case AccessibilityRole::DocumentNote:
|
|
+ return "DocumentNote";
|
|
+ case AccessibilityRole::Drawer:
|
|
+ return "Drawer";
|
|
+ case AccessibilityRole::EditableText:
|
|
+ return "EditableText";
|
|
+ case AccessibilityRole::Feed:
|
|
+ return "Feed";
|
|
+ case AccessibilityRole::Figure:
|
|
+ return "Figure";
|
|
+ case AccessibilityRole::Footer:
|
|
+ return "Footer";
|
|
+ case AccessibilityRole::Footnote:
|
|
+ return "Footnote";
|
|
+ case AccessibilityRole::Form:
|
|
+ return "Form";
|
|
+ case AccessibilityRole::GraphicsDocument:
|
|
+ return "GraphicsDocument";
|
|
+ case AccessibilityRole::GraphicsObject:
|
|
+ return "GraphicsObject";
|
|
+ case AccessibilityRole::GraphicsSymbol:
|
|
+ return "GraphicsSymbol";
|
|
+ case AccessibilityRole::Grid:
|
|
+ return "Grid";
|
|
+ case AccessibilityRole::GridCell:
|
|
+ return "GridCell";
|
|
+ case AccessibilityRole::Group:
|
|
+ return "Group";
|
|
+ case AccessibilityRole::GrowArea:
|
|
+ return "GrowArea";
|
|
+ case AccessibilityRole::Heading:
|
|
+ return "Heading";
|
|
+ case AccessibilityRole::HelpTag:
|
|
+ return "HelpTag";
|
|
+ case AccessibilityRole::HorizontalRule:
|
|
+ return "HorizontalRule";
|
|
+ case AccessibilityRole::Ignored:
|
|
+ return "Ignored";
|
|
+ case AccessibilityRole::Inline:
|
|
+ return "Inline";
|
|
+ case AccessibilityRole::Image:
|
|
+ return "Image";
|
|
+ case AccessibilityRole::ImageMap:
|
|
+ return "ImageMap";
|
|
+ case AccessibilityRole::ImageMapLink:
|
|
+ return "ImageMapLink";
|
|
+ case AccessibilityRole::Incrementor:
|
|
+ return "Incrementor";
|
|
+ case AccessibilityRole::Insertion:
|
|
+ return "Insertion";
|
|
+ case AccessibilityRole::Label:
|
|
+ return "Label";
|
|
+ case AccessibilityRole::LandmarkBanner:
|
|
+ return "LandmarkBanner";
|
|
+ case AccessibilityRole::LandmarkComplementary:
|
|
+ return "LandmarkComplementary";
|
|
+ case AccessibilityRole::LandmarkContentInfo:
|
|
+ return "LandmarkContentInfo";
|
|
+ case AccessibilityRole::LandmarkDocRegion:
|
|
+ return "LandmarkDocRegion";
|
|
+ case AccessibilityRole::LandmarkMain:
|
|
+ return "LandmarkMain";
|
|
+ case AccessibilityRole::LandmarkNavigation:
|
|
+ return "LandmarkNavigation";
|
|
+ case AccessibilityRole::LandmarkRegion:
|
|
+ return "LandmarkRegion";
|
|
+ case AccessibilityRole::LandmarkSearch:
|
|
+ return "LandmarkSearch";
|
|
+ case AccessibilityRole::Legend:
|
|
+ return "Legend";
|
|
+ case AccessibilityRole::Link:
|
|
+ return "Link";
|
|
+ case AccessibilityRole::List:
|
|
+ return "List";
|
|
+ case AccessibilityRole::ListBox:
|
|
+ return "ListBox";
|
|
+ case AccessibilityRole::ListBoxOption:
|
|
+ return "ListBoxOption";
|
|
+ case AccessibilityRole::ListItem:
|
|
+ return "ListItem";
|
|
+ case AccessibilityRole::ListMarker:
|
|
+ return "ListMarker";
|
|
+ case AccessibilityRole::Mark:
|
|
+ return "Mark";
|
|
+ case AccessibilityRole::MathElement:
|
|
+ return "MathElement";
|
|
+ case AccessibilityRole::Matte:
|
|
+ return "Matte";
|
|
+ case AccessibilityRole::Menu:
|
|
+ return "Menu";
|
|
+ case AccessibilityRole::MenuBar:
|
|
+ return "MenuBar";
|
|
+ case AccessibilityRole::MenuButton:
|
|
+ return "MenuButton";
|
|
+ case AccessibilityRole::MenuItem:
|
|
+ return "MenuItem";
|
|
+ case AccessibilityRole::MenuItemCheckbox:
|
|
+ return "MenuItemCheckbox";
|
|
+ case AccessibilityRole::MenuItemRadio:
|
|
+ return "MenuItemRadio";
|
|
+ case AccessibilityRole::MenuListPopup:
|
|
+ return "MenuListPopup";
|
|
+ case AccessibilityRole::MenuListOption:
|
|
+ return "MenuListOption";
|
|
+ case AccessibilityRole::Meter:
|
|
+ return "Meter";
|
|
+ case AccessibilityRole::Outline:
|
|
+ return "Outline";
|
|
+ case AccessibilityRole::Paragraph:
|
|
+ return "Paragraph";
|
|
+ case AccessibilityRole::PopUpButton:
|
|
+ return "PopUpButton";
|
|
+ case AccessibilityRole::Pre:
|
|
+ return "Pre";
|
|
+ case AccessibilityRole::Presentational:
|
|
+ return "Presentational";
|
|
+ case AccessibilityRole::ProgressIndicator:
|
|
+ return "ProgressIndicator";
|
|
+ case AccessibilityRole::RadioButton:
|
|
+ return "RadioButton";
|
|
+ case AccessibilityRole::RadioGroup:
|
|
+ return "RadioGroup";
|
|
+ case AccessibilityRole::RowHeader:
|
|
+ return "RowHeader";
|
|
+ case AccessibilityRole::Row:
|
|
+ return "Row";
|
|
+ case AccessibilityRole::RowGroup:
|
|
+ return "RowGroup";
|
|
+ case AccessibilityRole::RubyBase:
|
|
+ return "RubyBase";
|
|
+ case AccessibilityRole::RubyBlock:
|
|
+ return "RubyBlock";
|
|
+ case AccessibilityRole::RubyInline:
|
|
+ return "RubyInline";
|
|
+ case AccessibilityRole::RubyRun:
|
|
+ return "RubyRun";
|
|
+ case AccessibilityRole::RubyText:
|
|
+ return "RubyText";
|
|
+ case AccessibilityRole::Ruler:
|
|
+ return "Ruler";
|
|
+ case AccessibilityRole::RulerMarker:
|
|
+ return "RulerMarker";
|
|
+ case AccessibilityRole::ScrollArea:
|
|
+ return "ScrollArea";
|
|
+ case AccessibilityRole::ScrollBar:
|
|
+ return "ScrollBar";
|
|
+ case AccessibilityRole::SearchField:
|
|
+ return "SearchField";
|
|
+ case AccessibilityRole::Sheet:
|
|
+ return "Sheet";
|
|
+ case AccessibilityRole::Slider:
|
|
+ return "Slider";
|
|
+ case AccessibilityRole::SliderThumb:
|
|
+ return "SliderThumb";
|
|
+ case AccessibilityRole::SpinButton:
|
|
+ return "SpinButton";
|
|
+ case AccessibilityRole::SpinButtonPart:
|
|
+ return "SpinButtonPart";
|
|
+ case AccessibilityRole::SplitGroup:
|
|
+ return "SplitGroup";
|
|
+ case AccessibilityRole::Splitter:
|
|
+ return "Splitter";
|
|
+ case AccessibilityRole::StaticText:
|
|
+ return "StaticText";
|
|
+ case AccessibilityRole::Subscript:
|
|
+ return "Subscript";
|
|
+ case AccessibilityRole::Summary:
|
|
+ return "Summary";
|
|
+ case AccessibilityRole::Superscript:
|
|
+ return "Superscript";
|
|
+ case AccessibilityRole::Switch:
|
|
+ return "Switch";
|
|
+ case AccessibilityRole::SystemWide:
|
|
+ return "SystemWide";
|
|
+ case AccessibilityRole::SVGRoot:
|
|
+ return "SVGRoot";
|
|
+ case AccessibilityRole::SVGText:
|
|
+ return "SVGText";
|
|
+ case AccessibilityRole::SVGTSpan:
|
|
+ return "SVGTSpan";
|
|
+ case AccessibilityRole::SVGTextPath:
|
|
+ return "SVGTextPath";
|
|
+ case AccessibilityRole::TabGroup:
|
|
+ return "TabGroup";
|
|
+ case AccessibilityRole::TabList:
|
|
+ return "TabList";
|
|
+ case AccessibilityRole::TabPanel:
|
|
+ return "TabPanel";
|
|
+ case AccessibilityRole::Tab:
|
|
+ return "Tab";
|
|
+ case AccessibilityRole::Table:
|
|
+ return "Table";
|
|
+ case AccessibilityRole::TableHeaderContainer:
|
|
+ return "TableHeaderContainer";
|
|
+ case AccessibilityRole::TextArea:
|
|
+ return "TextArea";
|
|
+ case AccessibilityRole::TextGroup:
|
|
+ return "TextGroup";
|
|
+ case AccessibilityRole::Term:
|
|
+ return "Term";
|
|
+ case AccessibilityRole::Time:
|
|
+ return "Time";
|
|
+ case AccessibilityRole::Tree:
|
|
+ return "Tree";
|
|
+ case AccessibilityRole::TreeGrid:
|
|
+ return "TreeGrid";
|
|
+ case AccessibilityRole::TreeItem:
|
|
+ return "TreeItem";
|
|
+ case AccessibilityRole::TextField:
|
|
+ return "TextField";
|
|
+ case AccessibilityRole::ToggleButton:
|
|
+ return "ToggleButton";
|
|
+ case AccessibilityRole::Toolbar:
|
|
+ return "Toolbar";
|
|
+ case AccessibilityRole::Unknown:
|
|
+ return "Unknown";
|
|
+ case AccessibilityRole::UserInterfaceTooltip:
|
|
+ return "UserInterfaceTooltip";
|
|
+ case AccessibilityRole::ValueIndicator:
|
|
+ return "ValueIndicator";
|
|
+ case AccessibilityRole::Video:
|
|
+ return "Video";
|
|
+ case AccessibilityRole::WebApplication:
|
|
+ return "WebApplication";
|
|
+ case AccessibilityRole::WebArea:
|
|
+ return "WebArea";
|
|
+ case AccessibilityRole::WebCoreLink:
|
|
+ return "WebCoreLink";
|
|
+ case AccessibilityRole::Window:
|
|
+ return "Window";
|
|
+ };
|
|
+ return "Unknown";
|
|
+}
|
|
+
|
|
+static Ref<Inspector::Protocol::Page::AXNode> snapshotForAXObject(RefPtr<AXCoreObject> axObject, Node* nodeToFind)
|
|
+{
|
|
+ auto axNode = Inspector::Protocol::Page::AXNode::create()
|
|
+ .setRole(roleFromObject(axObject))
|
|
+ .release();
|
|
+
|
|
+ if (!axObject->computedLabel().isEmpty())
|
|
+ axNode->setName(axObject->computedLabel());
|
|
+ if (!axObject->stringValue().isEmpty())
|
|
+ axNode->setValue(JSON::Value::create(axObject->stringValue()));
|
|
+ if (!axObject->accessibilityDescription().isEmpty())
|
|
+ axNode->setDescription(axObject->accessibilityDescription());
|
|
+ if (!axObject->keyShortcutsValue().isEmpty())
|
|
+ axNode->setKeyshortcuts(axObject->keyShortcutsValue());
|
|
+ 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());
|
|
+ bool multiline = axObject->ariaIsMultiline() || axObject->roleValue() == AccessibilityRole::TextArea;
|
|
+ if (multiline)
|
|
+ axNode->setMultiline(multiline);
|
|
+ if (axObject->isMultiSelectable())
|
|
+ axNode->setMultiselectable(axObject->isMultiSelectable());
|
|
+ if (axObject->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;
|
|
+ }
|
|
+ }
|
|
+ if (axObject->supportsPressed()) {
|
|
+ AccessibilityButtonState checkedState = axObject->checkboxOrRadioValue();
|
|
+ switch (checkedState) {
|
|
+ case AccessibilityButtonState::On:
|
|
+ axNode->setPressed(Inspector::Protocol::Page::AXNode::Pressed::True);
|
|
+ break;
|
|
+ case AccessibilityButtonState::Off:
|
|
+ axNode->setPressed(Inspector::Protocol::Page::AXNode::Pressed::False);
|
|
+ break;
|
|
+ case AccessibilityButtonState::Mixed:
|
|
+ axNode->setPressed(Inspector::Protocol::Page::AXNode::Pressed::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 (axObject->supportsAutoComplete())
|
|
+ axNode->setAutocomplete(axObject->autoCompleteValue());
|
|
+ if (axObject->hasPopup())
|
|
+ axNode->setHaspopup(axObject->popupValue());
|
|
+
|
|
+ String invalidValue = axObject->invalidStatus();
|
|
+ if (invalidValue != "false") {
|
|
+ if (invalidValue == "grammar")
|
|
+ axNode->setInvalid(Inspector::Protocol::Page::AXNode::Invalid::Grammar);
|
|
+ else if (invalidValue == "spelling")
|
|
+ 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->hasChildren()) {
|
|
+ Ref<JSON::ArrayOf<Inspector::Protocol::Page::AXNode>> children = JSON::ArrayOf<Inspector::Protocol::Page::AXNode>::create();
|
|
+ for (auto& childObject : axObject->children())
|
|
+ children->addItem(snapshotForAXObject(childObject, 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 document = makeRefPtr(m_inspectedPage.mainFrame().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->rootObject();
|
|
+ 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(makeRefPtr(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)
|
|
+{
|
|
+ FrameView* view = m_inspectedPage.mainFrame().view();
|
|
+ if (!view)
|
|
+ return makeUnexpected("Internal error: No frame view to set color two"_s);
|
|
+
|
|
+ if (!color) {
|
|
+ view->updateBackgroundRecursively(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()) {
|
|
+ for (auto* world : worlds)
|
|
+ frame->windowProxy().jsWindowProxy(*world)->window();
|
|
+ }
|
|
+}
|
|
+
|
|
+Protocol::ErrorStringOr<void> InspectorPageAgent::setBypassCSP(bool enabled)
|
|
+{
|
|
+ m_bypassCSP = enabled;
|
|
+ return { };
|
|
+}
|
|
+
|
|
+Protocol::ErrorStringOr<void> InspectorPageAgent::crash()
|
|
+{
|
|
+ CRASH();
|
|
+ return { };
|
|
+}
|
|
+
|
|
+Protocol::ErrorStringOr<void> InspectorPageAgent::setScreenSizeOverride(int width, int height)
|
|
+{
|
|
+ Optional<FloatSize> size;
|
|
+ if (width && height)
|
|
+ size = FloatSize(width, height);
|
|
+ m_inspectedPage.setOverrideScreenSize(size);
|
|
+ return { };
|
|
+}
|
|
+
|
|
+Protocol::ErrorStringOr<void> InspectorPageAgent::setOrientationOverride(Optional<int>&& angle)
|
|
+{
|
|
+#if ENABLE(ORIENTATION_EVENTS)
|
|
+ m_inspectedPage.setOverrideOrientation(WTFMove(angle));
|
|
+ return { };
|
|
+#else
|
|
+ UNUSED_PARAM(angle);
|
|
+ return makeUnexpected("Orientation events are disabled in this build");
|
|
+#endif
|
|
+}
|
|
+
|
|
} // namespace WebCore
|
|
diff --git a/Source/WebCore/inspector/agents/InspectorPageAgent.h b/Source/WebCore/inspector/agents/InspectorPageAgent.h
|
|
index d2b065e13651fafe747325f02e7701fbf1e8e45e..3b5db3e7404fc890acab9864d23bbbc6b54b27fd 100644
|
|
--- a/Source/WebCore/inspector/agents/InspectorPageAgent.h
|
|
+++ b/Source/WebCore/inspector/agents/InspectorPageAgent.h
|
|
@@ -34,17 +34,23 @@
|
|
#include "CachedResource.h"
|
|
#include "InspectorWebAgentBase.h"
|
|
#include "LayoutRect.h"
|
|
+#include "ProcessIdentifier.h"
|
|
#include <JavaScriptCore/InspectorBackendDispatchers.h>
|
|
#include <JavaScriptCore/InspectorFrontendDispatchers.h>
|
|
#include <wtf/HashMap.h>
|
|
#include <wtf/Seconds.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 Page;
|
|
@@ -69,12 +75,14 @@ public:
|
|
PingResource,
|
|
BeaconResource,
|
|
WebSocketResource,
|
|
+ EventSource,
|
|
#if ENABLE(APPLICATION_MANIFEST)
|
|
ApplicationManifestResource,
|
|
#endif
|
|
OtherResource,
|
|
};
|
|
|
|
+ WEBCORE_EXPORT static String makeFrameID(ProcessIdentifier processID, FrameIdentifier frameID);
|
|
static bool sharedBufferContent(RefPtr<SharedBuffer>&&, const String& textEncodingName, bool withBase64Encode, String* result);
|
|
static Vector<CachedResource*> cachedResourcesForFrame(Frame*);
|
|
static void resourceContent(Inspector::Protocol::ErrorString&, Frame*, const URL&, String* result, bool* base64Encoded);
|
|
@@ -95,6 +103,8 @@ public:
|
|
Inspector::Protocol::ErrorStringOr<void> enable();
|
|
Inspector::Protocol::ErrorStringOr<void> disable();
|
|
Inspector::Protocol::ErrorStringOr<void> reload(Optional<bool>&& ignoreCache, 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> overrideSetting(Inspector::Protocol::Page::Setting, Optional<bool>&& value);
|
|
@@ -114,22 +124,34 @@ public:
|
|
#if ENABLE(DARK_MODE_CSS) || HAVE(OS_DARK_MODE_SUPPORT)
|
|
Inspector::Protocol::ErrorStringOr<void> setForcedAppearance(Optional<Inspector::Protocol::Page::Appearance>&&);
|
|
#endif
|
|
+ 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);
|
|
#if ENABLE(WEB_ARCHIVE) && USE(CF)
|
|
Inspector::Protocol::ErrorStringOr<String> archive();
|
|
#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> setScreenSizeOverride(int width, int height);
|
|
+ Inspector::Protocol::ErrorStringOr<void> setOrientationOverride(Optional<int>&& angle);
|
|
+
|
|
// InspectorInstrumentation
|
|
- void domContentEventFired();
|
|
- void loadEventFired();
|
|
+ void domContentEventFired(Frame&);
|
|
+ void loadEventFired(Frame&);
|
|
void frameNavigated(Frame&);
|
|
void frameDetached(Frame&);
|
|
- void loaderDetachedFromFrame(DocumentLoader&);
|
|
void frameStartedLoading(Frame&);
|
|
void frameStoppedLoading(Frame&);
|
|
void frameScheduledNavigation(Frame&, Seconds delay);
|
|
void frameClearedScheduledNavigation(Frame&);
|
|
+ void didNavigateWithinPage(Frame&);
|
|
#if ENABLE(DARK_MODE_CSS) || HAVE(OS_DARK_MODE_SUPPORT)
|
|
void defaultAppearanceDidChange(bool useDarkAppearance);
|
|
#endif
|
|
@@ -140,6 +162,12 @@ public:
|
|
void didLayout();
|
|
void didScroll();
|
|
void didRecalculateStyle();
|
|
+ void runOpenPanel(HTMLInputElement* element, bool* intercept);
|
|
+ void frameAttached(Frame&);
|
|
+ bool shouldBypassCSP();
|
|
+ void willCheckNewWindowPolicy(const URL&);
|
|
+ void didCheckNewWindowPolicy(bool allowed);
|
|
+ bool doingAccessibilitySnapshot() const { return m_doingAccessibilitySnapshot; };
|
|
|
|
Frame* frameForId(const Inspector::Protocol::Network::FrameId&);
|
|
WEBCORE_EXPORT String frameId(Frame*);
|
|
@@ -148,6 +176,7 @@ public:
|
|
|
|
private:
|
|
double timestamp();
|
|
+ void ensureUserWorldsExistInAllFrames(const Vector<DOMWrapperWorld*>&);
|
|
|
|
static bool mainResourceContent(Frame*, bool withBase64Encode, String* result);
|
|
static bool dataContent(const char* data, unsigned size, const String& textEncodingName, bool withBase64Encode, String* result);
|
|
@@ -159,17 +188,19 @@ private:
|
|
RefPtr<Inspector::PageBackendDispatcher> m_backendDispatcher;
|
|
|
|
Page& m_inspectedPage;
|
|
+ Inspector::InjectedScriptManager& m_injectedScriptManager;
|
|
InspectorClient* m_client { nullptr };
|
|
InspectorOverlay* m_overlay { nullptr };
|
|
|
|
- HashMap<Frame*, String> m_frameToIdentifier;
|
|
HashMap<String, Frame*> m_identifierToFrame;
|
|
- HashMap<DocumentLoader*, String> m_loaderToIdentifier;
|
|
String m_userAgentOverride;
|
|
String 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 };
|
|
};
|
|
|
|
} // namespace WebCore
|
|
diff --git a/Source/WebCore/inspector/agents/InspectorWorkerAgent.cpp b/Source/WebCore/inspector/agents/InspectorWorkerAgent.cpp
|
|
index 33caa0aa2079ad4081cc29605a53537c24d66bef..4b74d397d4de9a7eba3d5530538443d8907726aa 100644
|
|
--- a/Source/WebCore/inspector/agents/InspectorWorkerAgent.cpp
|
|
+++ b/Source/WebCore/inspector/agents/InspectorWorkerAgent.cpp
|
|
@@ -161,7 +161,11 @@ void InspectorWorkerAgent::connectToWorkerInspectorProxy(WorkerInspectorProxy& p
|
|
|
|
m_connectedProxies.set(proxy.identifier(), &proxy);
|
|
|
|
- m_frontendDispatcher->workerCreated(proxy.identifier(), proxy.url().string(), proxy.name());
|
|
+ ASSERT(is<Document>(proxy.scriptExecutionContext()));
|
|
+ Document& document = downcast<Document>(*proxy.scriptExecutionContext());
|
|
+ auto* pageAgent = m_instrumentingAgents.enabledPageAgent();
|
|
+ m_frontendDispatcher->workerCreated(proxy.identifier(), proxy.url().string(), proxy.name(),
|
|
+ pageAgent ? pageAgent->frameId(document.frame()) : emptyString());
|
|
}
|
|
|
|
void InspectorWorkerAgent::disconnectFromWorkerInspectorProxy(WorkerInspectorProxy& proxy)
|
|
diff --git a/Source/WebCore/inspector/agents/page/PageDebuggerAgent.cpp b/Source/WebCore/inspector/agents/page/PageDebuggerAgent.cpp
|
|
index 6187268bd275181e98f45ee0fa7e16a7509bc160..4b6457e9f92e07b69f46efbd58ea29d5d904d819 100644
|
|
--- a/Source/WebCore/inspector/agents/page/PageDebuggerAgent.cpp
|
|
+++ b/Source/WebCore/inspector/agents/page/PageDebuggerAgent.cpp
|
|
@@ -38,6 +38,7 @@
|
|
#include "Frame.h"
|
|
#include "InspectorPageAgent.h"
|
|
#include "InstrumentingAgents.h"
|
|
+#include "JSDOMWindowBase.h"
|
|
#include "Page.h"
|
|
#include "PageConsoleClient.h"
|
|
#include "PageDebugger.h"
|
|
@@ -70,7 +71,11 @@ bool PageDebuggerAgent::enabled() const
|
|
|
|
Protocol::ErrorStringOr<std::tuple<Ref<Protocol::Runtime::RemoteObject>, Optional<bool> /* wasThrown */, Optional<int> /* savedResultIndex */>> PageDebuggerAgent::evaluateOnCallFrame(const Protocol::Debugger::CallFrameId& callFrameId, const String& expression, const String& objectGroup, Optional<bool>&& includeCommandLineAPI, Optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, Optional<bool>&& returnByValue, Optional<bool>&& generatePreview, Optional<bool>&& saveResult, Optional<bool>&& emulateUserGesture)
|
|
{
|
|
- UserGestureEmulationScope userGestureScope(m_inspectedPage, emulateUserGesture && *emulateUserGesture);
|
|
+ InjectedScript injectedScript = injectedScriptManager().injectedScriptForObjectId(callFrameId);
|
|
+ JSC::JSGlobalObject* globalObject = injectedScript.globalObject();
|
|
+ Document* document = globalObject ? activeDOMWindow(*globalObject).document() : nullptr;
|
|
+ auto shouldEmulateUserGesture = emulateUserGesture && *emulateUserGesture;
|
|
+ UserGestureEmulationScope userGestureScope(m_inspectedPage, shouldEmulateUserGesture, document);
|
|
|
|
return WebDebuggerAgent::evaluateOnCallFrame(callFrameId, expression, objectGroup, WTFMove(includeCommandLineAPI), WTFMove(doNotPauseOnExceptionsAndMuteConsole), WTFMove(returnByValue), WTFMove(generatePreview), WTFMove(saveResult), WTFMove(emulateUserGesture));
|
|
}
|
|
diff --git a/Source/WebCore/inspector/agents/page/PageRuntimeAgent.cpp b/Source/WebCore/inspector/agents/page/PageRuntimeAgent.cpp
|
|
index 00e69f1aa2e3f8ea2f445e8dd446dd16ea6363df..92d45059ca6d87ddf7b6cc12033267a4c108a73c 100644
|
|
--- a/Source/WebCore/inspector/agents/page/PageRuntimeAgent.cpp
|
|
+++ b/Source/WebCore/inspector/agents/page/PageRuntimeAgent.cpp
|
|
@@ -35,12 +35,14 @@
|
|
#include "DOMWrapperWorld.h"
|
|
#include "Document.h"
|
|
#include "Frame.h"
|
|
+#include "FrameLoader.h"
|
|
#include "InspectorPageAgent.h"
|
|
#include "InstrumentingAgents.h"
|
|
#include "JSDOMWindowBase.h"
|
|
#include "Page.h"
|
|
#include "PageConsoleClient.h"
|
|
#include "ScriptController.h"
|
|
+#include "ScriptSourceCode.h"
|
|
#include "ScriptState.h"
|
|
#include "SecurityOrigin.h"
|
|
#include "UserGestureEmulationScope.h"
|
|
@@ -103,6 +105,15 @@ void PageRuntimeAgent::didClearWindowObjectInWorld(Frame& frame, DOMWrapperWorld
|
|
notifyContextCreated(pageAgent->frameId(&frame), frame.script().globalObject(world), world);
|
|
}
|
|
|
|
+void PageRuntimeAgent::didReceiveMainResourceError(Frame& frame)
|
|
+{
|
|
+ if (frame.loader().stateMachine().isDisplayingInitialEmptyDocument()) {
|
|
+ // Ensure execution context is created for the empty docment to make
|
|
+ // it usable in case loading failed.
|
|
+ mainWorldExecState(&frame);
|
|
+ }
|
|
+}
|
|
+
|
|
InjectedScript PageRuntimeAgent::injectedScriptForEval(Protocol::ErrorString& errorString, Optional<Protocol::Runtime::ExecutionContextId>&& executionContextId)
|
|
{
|
|
if (!executionContextId) {
|
|
@@ -191,13 +202,23 @@ void PageRuntimeAgent::notifyContextCreated(const Protocol::Network::FrameId& fr
|
|
|
|
Protocol::ErrorStringOr<std::tuple<Ref<Protocol::Runtime::RemoteObject>, Optional<bool> /* wasThrown */, Optional<int> /* savedResultIndex */>> PageRuntimeAgent::evaluate(const String& expression, const String& objectGroup, Optional<bool>&& includeCommandLineAPI, Optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, Optional<Protocol::Runtime::ExecutionContextId>&& executionContextId, Optional<bool>&& returnByValue, Optional<bool>&& generatePreview, Optional<bool>&& saveResult, Optional<bool>&& emulateUserGesture)
|
|
{
|
|
- UserGestureEmulationScope userGestureScope(m_inspectedPage, emulateUserGesture && *emulateUserGesture);
|
|
+ String errorString;
|
|
+ InjectedScript injectedScript = injectedScriptForEval(errorString, Optional(executionContextId));
|
|
+ if (!errorString.isEmpty())
|
|
+ return makeUnexpected(errorString);
|
|
+
|
|
+ JSC::JSGlobalObject* globalObject = injectedScript.globalObject();
|
|
+ Document* document = globalObject ? activeDOMWindow(*globalObject).document() : nullptr;
|
|
+ UserGestureEmulationScope userGestureScope(m_inspectedPage, emulateUserGesture && *emulateUserGesture, document);
|
|
return InspectorRuntimeAgent::evaluate(expression, objectGroup, WTFMove(includeCommandLineAPI), WTFMove(doNotPauseOnExceptionsAndMuteConsole), WTFMove(executionContextId), WTFMove(returnByValue), WTFMove(generatePreview), WTFMove(saveResult), WTFMove(emulateUserGesture));
|
|
}
|
|
|
|
Protocol::ErrorStringOr<std::tuple<Ref<Protocol::Runtime::RemoteObject>, Optional<bool> /* wasThrown */>> PageRuntimeAgent::callFunctionOn(const Protocol::Runtime::RemoteObjectId& objectId, const String& expression, RefPtr<JSON::Array>&& optionalArguments, Optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, Optional<bool>&& returnByValue, Optional<bool>&& generatePreview, Optional<bool>&& emulateUserGesture)
|
|
{
|
|
- UserGestureEmulationScope userGestureScope(m_inspectedPage, emulateUserGesture && *emulateUserGesture);
|
|
+ InjectedScript injectedScript = injectedScriptManager().injectedScriptForObjectId(objectId);
|
|
+ JSC::JSGlobalObject* globalObject = injectedScript.globalObject();
|
|
+ Document* document = globalObject ? activeDOMWindow(*globalObject).document() : nullptr;
|
|
+ UserGestureEmulationScope userGestureScope(m_inspectedPage, emulateUserGesture && *emulateUserGesture, document);
|
|
return InspectorRuntimeAgent::callFunctionOn(objectId, expression, WTFMove(optionalArguments), WTFMove(doNotPauseOnExceptionsAndMuteConsole), WTFMove(returnByValue), WTFMove(generatePreview), WTFMove(emulateUserGesture));
|
|
}
|
|
|
|
diff --git a/Source/WebCore/inspector/agents/page/PageRuntimeAgent.h b/Source/WebCore/inspector/agents/page/PageRuntimeAgent.h
|
|
index 298465c52b42464c2733659e07f3f760174a95eb..3b7ac5a5e6fba11bfbc3d641e5a312db5f1391a8 100644
|
|
--- a/Source/WebCore/inspector/agents/page/PageRuntimeAgent.h
|
|
+++ b/Source/WebCore/inspector/agents/page/PageRuntimeAgent.h
|
|
@@ -62,6 +62,7 @@ public:
|
|
// InspectorInstrumentation
|
|
void frameNavigated(Frame&);
|
|
void didClearWindowObjectInWorld(Frame&, DOMWrapperWorld&);
|
|
+ void didReceiveMainResourceError(Frame&);
|
|
|
|
private:
|
|
Inspector::InjectedScript injectedScriptForEval(Inspector::Protocol::ErrorString&, Optional<Inspector::Protocol::Runtime::ExecutionContextId>&&);
|
|
@@ -72,7 +73,6 @@ private:
|
|
|
|
std::unique_ptr<Inspector::RuntimeFrontendDispatcher> m_frontendDispatcher;
|
|
RefPtr<Inspector::RuntimeBackendDispatcher> m_backendDispatcher;
|
|
-
|
|
InstrumentingAgents& m_instrumentingAgents;
|
|
|
|
Page& m_inspectedPage;
|
|
diff --git a/Source/WebCore/inspector/agents/page/UserGestureEmulationScope.cpp b/Source/WebCore/inspector/agents/page/UserGestureEmulationScope.cpp
|
|
index 633bce6e8f3c0785632eb7f26d172f6016b3efd9..14f531504bb2b96646d1a48092a0b132b0510f55 100644
|
|
--- a/Source/WebCore/inspector/agents/page/UserGestureEmulationScope.cpp
|
|
+++ b/Source/WebCore/inspector/agents/page/UserGestureEmulationScope.cpp
|
|
@@ -39,9 +39,9 @@
|
|
|
|
namespace WebCore {
|
|
|
|
-UserGestureEmulationScope::UserGestureEmulationScope(Page& inspectedPage, bool emulateUserGesture)
|
|
+UserGestureEmulationScope::UserGestureEmulationScope(Page& inspectedPage, bool emulateUserGesture, Document* document)
|
|
: m_pageChromeClient(inspectedPage.chrome().client())
|
|
- , m_gestureIndicator(emulateUserGesture ? Optional<ProcessingUserGestureState>(ProcessingUserGesture) : WTF::nullopt)
|
|
+ , m_gestureIndicator(emulateUserGesture ? Optional<ProcessingUserGestureState>(ProcessingUserGesture) : WTF::nullopt, document)
|
|
, m_emulateUserGesture(emulateUserGesture)
|
|
, m_userWasInteracting(false)
|
|
{
|
|
diff --git a/Source/WebCore/inspector/agents/page/UserGestureEmulationScope.h b/Source/WebCore/inspector/agents/page/UserGestureEmulationScope.h
|
|
index b94ed78ad3dbea19543c1fd54653f0481e52fb7c..6341c7ff7ef53577f33c19ecad1b8bfbd674d051 100644
|
|
--- a/Source/WebCore/inspector/agents/page/UserGestureEmulationScope.h
|
|
+++ b/Source/WebCore/inspector/agents/page/UserGestureEmulationScope.h
|
|
@@ -38,11 +38,12 @@ namespace WebCore {
|
|
|
|
class ChromeClient;
|
|
class Page;
|
|
+class Document;
|
|
|
|
class UserGestureEmulationScope {
|
|
WTF_MAKE_NONCOPYABLE(UserGestureEmulationScope);
|
|
public:
|
|
- UserGestureEmulationScope(Page& inspectedPage, bool emulateUserGesture);
|
|
+ UserGestureEmulationScope(Page& inspectedPage, bool emulateUserGesture, Document* document);
|
|
~UserGestureEmulationScope();
|
|
|
|
private:
|
|
diff --git a/Source/WebCore/loader/DocumentLoader.cpp b/Source/WebCore/loader/DocumentLoader.cpp
|
|
index 7c99510855700d855de43e52803d14d76bf9d562..9f4a76ec0b45783dc92942f78cdccac5291b0ceb 100644
|
|
--- a/Source/WebCore/loader/DocumentLoader.cpp
|
|
+++ b/Source/WebCore/loader/DocumentLoader.cpp
|
|
@@ -1326,8 +1326,6 @@ void DocumentLoader::detachFromFrame()
|
|
if (!m_frame)
|
|
return;
|
|
|
|
- InspectorInstrumentation::loaderDetachedFromFrame(*m_frame, *this);
|
|
-
|
|
observeFrame(nullptr);
|
|
}
|
|
|
|
diff --git a/Source/WebCore/loader/DocumentLoader.h b/Source/WebCore/loader/DocumentLoader.h
|
|
index c21678201701d3fa8d41c9ef45ee824eddff64bf..f1f23cf11fd4d646d57118df361ab77a1b5530d2 100644
|
|
--- a/Source/WebCore/loader/DocumentLoader.h
|
|
+++ b/Source/WebCore/loader/DocumentLoader.h
|
|
@@ -166,9 +166,13 @@ public:
|
|
|
|
WEBCORE_EXPORT virtual void detachFromFrame();
|
|
|
|
+ virtual void replacedByFragmentNavigation(Frame&) { }
|
|
+
|
|
WEBCORE_EXPORT FrameLoader* frameLoader() const;
|
|
WEBCORE_EXPORT SubresourceLoader* mainResourceLoader() const;
|
|
WEBCORE_EXPORT RefPtr<SharedBuffer> mainResourceData() const;
|
|
+
|
|
+ virtual uint64_t loaderIDForInspector() { return 0; }
|
|
|
|
DocumentWriter& writer() const { return m_writer; }
|
|
|
|
diff --git a/Source/WebCore/loader/FrameLoader.cpp b/Source/WebCore/loader/FrameLoader.cpp
|
|
index 58e83fb655bd4d7592386ebd82fcf7b100e31940..e7386c6ec0f47874df5512125011d911385a27f4 100644
|
|
--- a/Source/WebCore/loader/FrameLoader.cpp
|
|
+++ b/Source/WebCore/loader/FrameLoader.cpp
|
|
@@ -1171,6 +1171,7 @@ void FrameLoader::loadInSameDocument(const URL& url, SerializedScriptValue* stat
|
|
}
|
|
|
|
m_client->dispatchDidNavigateWithinPage();
|
|
+ InspectorInstrumentation::didNavigateWithinPage(m_frame);
|
|
|
|
m_frame.document()->statePopped(stateObject ? Ref<SerializedScriptValue> { *stateObject } : SerializedScriptValue::nullValue());
|
|
m_client->dispatchDidPopStateWithinPage();
|
|
@@ -1482,6 +1483,7 @@ void FrameLoader::load(FrameLoadRequest&& request)
|
|
|
|
void FrameLoader::loadWithNavigationAction(const ResourceRequest& request, NavigationAction&& action, FrameLoadType type, RefPtr<FormState>&& formState, AllowNavigationToInvalidURL allowNavigationToInvalidURL, CompletionHandler<void()>&& completionHandler)
|
|
{
|
|
+ InspectorInstrumentation::frameScheduledNavigation(m_frame, Seconds(0));
|
|
FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "loadWithNavigationAction: frame load started");
|
|
|
|
Ref<DocumentLoader> loader = m_client->createDocumentLoader(request, defaultSubstituteDataForURL(request.url()));
|
|
@@ -1585,6 +1587,8 @@ 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<DocumentLoader> oldDocumentLoader = m_documentLoader;
|
|
NavigationAction action { *m_frame.document(), loader->request(), InitiatedByMainFrame::Unknown, policyChecker().loadType(), isFormSubmission };
|
|
|
|
@@ -3150,6 +3154,8 @@ void FrameLoader::receivedMainResourceError(const ResourceError& error)
|
|
checkCompleted();
|
|
if (m_frame.page())
|
|
checkLoadComplete();
|
|
+
|
|
+ InspectorInstrumentation::didReceiveMainResourceError(m_frame, error);
|
|
}
|
|
|
|
void FrameLoader::continueFragmentScrollAfterNavigationPolicy(const ResourceRequest& request, bool shouldContinue)
|
|
@@ -3909,9 +3915,6 @@ String FrameLoader::referrer() const
|
|
|
|
void FrameLoader::dispatchDidClearWindowObjectsInAllWorlds()
|
|
{
|
|
- if (!m_frame.script().canExecuteScripts(NotAboutToExecuteScript))
|
|
- return;
|
|
-
|
|
Vector<Ref<DOMWrapperWorld>> worlds;
|
|
ScriptController::getAllWorlds(worlds);
|
|
for (auto& world : worlds)
|
|
@@ -3920,13 +3923,13 @@ void FrameLoader::dispatchDidClearWindowObjectsInAllWorlds()
|
|
|
|
void FrameLoader::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld& world)
|
|
{
|
|
- if (!m_frame.script().canExecuteScripts(NotAboutToExecuteScript) || !m_frame.windowProxy().existingJSWindowProxy(world))
|
|
- return;
|
|
-
|
|
- m_client->dispatchDidClearWindowObjectInWorld(world);
|
|
+ if (m_frame.windowProxy().existingJSWindowProxy(world)) {
|
|
+ if (m_frame.script().canExecuteScripts(NotAboutToExecuteScript))
|
|
+ m_client->dispatchDidClearWindowObjectInWorld(world);
|
|
|
|
- if (Page* page = m_frame.page())
|
|
- page->inspectorController().didClearWindowObjectInWorld(m_frame, world);
|
|
+ if (Page* page = m_frame.page())
|
|
+ page->inspectorController().didClearWindowObjectInWorld(m_frame, world);
|
|
+ }
|
|
|
|
InspectorInstrumentation::didClearWindowObjectInWorld(m_frame, world);
|
|
}
|
|
diff --git a/Source/WebCore/loader/LoaderStrategy.h b/Source/WebCore/loader/LoaderStrategy.h
|
|
index 6097d2650766a2c87a60426272ae6aba0358b297..9f6e41db65a1745a0d9bb343a762e1960a4b5586 100644
|
|
--- a/Source/WebCore/loader/LoaderStrategy.h
|
|
+++ b/Source/WebCore/loader/LoaderStrategy.h
|
|
@@ -80,6 +80,7 @@ public:
|
|
|
|
virtual bool isOnLine() const = 0;
|
|
virtual void addOnlineStateChangeListener(WTF::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/PolicyChecker.cpp b/Source/WebCore/loader/PolicyChecker.cpp
|
|
index 276148a63f36cc46ae0cf2bb535c33f2aa07e30b..998e983870098b620cf154819379aa0b039f7e66 100644
|
|
--- a/Source/WebCore/loader/PolicyChecker.cpp
|
|
+++ b/Source/WebCore/loader/PolicyChecker.cpp
|
|
@@ -46,6 +46,7 @@
|
|
#include "HTMLFormElement.h"
|
|
#include "HTMLFrameOwnerElement.h"
|
|
#include "HTMLPlugInElement.h"
|
|
+#include "InspectorInstrumentation.h"
|
|
#include "Logging.h"
|
|
#include <wtf/CompletionHandler.h>
|
|
|
|
@@ -259,26 +260,32 @@ void FrameLoader::PolicyChecker::checkNewWindowPolicy(NavigationAction&& navigat
|
|
|
|
auto blobURLLifetimeExtension = extendBlobURLLifetimeIfNecessary(request, nullptr);
|
|
|
|
+ InspectorInstrumentation::willCheckNewWindowPolicy(m_frame, request.url());
|
|
auto requestIdentifier = PolicyCheckIdentifier::create();
|
|
m_frame.loader().client().dispatchDecidePolicyForNewWindowAction(navigationAction, request, formState.get(), frameName, requestIdentifier, [frame = makeRef(m_frame), request,
|
|
formState = WTFMove(formState), frameName, navigationAction, function = WTFMove(function), blobURLLifetimeExtension = WTFMove(blobURLLifetimeExtension),
|
|
requestIdentifier] (PolicyAction policyAction, PolicyCheckIdentifier responseIdentifier) mutable {
|
|
|
|
- if (!responseIdentifier.isValidFor(requestIdentifier))
|
|
+ if (!responseIdentifier.isValidFor(requestIdentifier)) {
|
|
+ InspectorInstrumentation::didCheckNewWindowPolicy(frame.get(), false);
|
|
return function({ }, nullptr, { }, { }, ShouldContinuePolicyCheck::No);
|
|
+ }
|
|
|
|
switch (policyAction) {
|
|
case PolicyAction::Download:
|
|
frame->loader().client().startDownload(request);
|
|
FALLTHROUGH;
|
|
case PolicyAction::Ignore:
|
|
+ InspectorInstrumentation::didCheckNewWindowPolicy(frame.get(), false);
|
|
function({ }, nullptr, { }, { }, ShouldContinuePolicyCheck::No);
|
|
return;
|
|
case PolicyAction::StopAllLoads:
|
|
ASSERT_NOT_REACHED();
|
|
+ InspectorInstrumentation::didCheckNewWindowPolicy(frame.get(), false);
|
|
function({ }, nullptr, { }, { }, ShouldContinuePolicyCheck::No);
|
|
return;
|
|
case PolicyAction::Use:
|
|
+ InspectorInstrumentation::didCheckNewWindowPolicy(frame.get(), true);
|
|
function(request, makeWeakPtr(formState.get()), frameName, navigationAction, ShouldContinuePolicyCheck::Yes);
|
|
return;
|
|
}
|
|
diff --git a/Source/WebCore/loader/ProgressTracker.cpp b/Source/WebCore/loader/ProgressTracker.cpp
|
|
index e24fded2225f1c1918f454017566717e20484eab..30e4b7a986418c4b4f6c799b858b608206e22bb5 100644
|
|
--- a/Source/WebCore/loader/ProgressTracker.cpp
|
|
+++ b/Source/WebCore/loader/ProgressTracker.cpp
|
|
@@ -154,6 +154,8 @@ void ProgressTracker::progressCompleted(Frame& frame)
|
|
if (!m_numProgressTrackedFrames || m_originatingProgressFrame == &frame)
|
|
finalProgressComplete();
|
|
|
|
+ InspectorInstrumentation::frameStoppedLoading(frame);
|
|
+
|
|
m_client->didChangeEstimatedProgress();
|
|
}
|
|
|
|
@@ -179,8 +181,6 @@ void ProgressTracker::finalProgressComplete()
|
|
frame->loader().client().setMainFrameDocumentReady(true);
|
|
m_client->progressFinished(*frame);
|
|
frame->loader().loadProgressingStatusChanged();
|
|
-
|
|
- InspectorInstrumentation::frameStoppedLoading(*frame);
|
|
}
|
|
|
|
void ProgressTracker::incrementProgress(unsigned long identifier, const ResourceResponse& response)
|
|
diff --git a/Source/WebCore/page/ChromeClient.h b/Source/WebCore/page/ChromeClient.h
|
|
index e096732ec5a23a0498298a052eebe50ab14092a8..7ae98a00b9e4dd82e90444a39a9b640bd20d8bda 100644
|
|
--- a/Source/WebCore/page/ChromeClient.h
|
|
+++ b/Source/WebCore/page/ChromeClient.h
|
|
@@ -284,7 +284,7 @@ public:
|
|
#endif
|
|
|
|
#if ENABLE(ORIENTATION_EVENTS)
|
|
- virtual int deviceOrientation() const = 0;
|
|
+ virtual int deviceOrientation() const { return 0; }
|
|
#endif
|
|
|
|
#if ENABLE(INPUT_TYPE_COLOR)
|
|
diff --git a/Source/WebCore/page/EventHandler.cpp b/Source/WebCore/page/EventHandler.cpp
|
|
index 4935b73e2ef615cb5b2f07554eea20d4c06d654b..fadb703c2900655cd122bdb3dc8e145c22a79309 100644
|
|
--- a/Source/WebCore/page/EventHandler.cpp
|
|
+++ b/Source/WebCore/page/EventHandler.cpp
|
|
@@ -121,6 +121,7 @@
|
|
|
|
#if ENABLE(TOUCH_EVENTS) && !ENABLE(IOS_TOUCH_EVENTS)
|
|
#include "PlatformTouchEvent.h"
|
|
+#include "PointerCaptureController.h"
|
|
#endif
|
|
|
|
#if ENABLE(MAC_GESTURE_EVENTS)
|
|
@@ -828,9 +829,7 @@ bool EventHandler::handleMousePressEvent(const MouseEventWithHitTestResults& eve
|
|
m_mousePressNode = event.targetNode();
|
|
m_frame.document()->setFocusNavigationStartingNode(event.targetNode());
|
|
|
|
-#if ENABLE(DRAG_SUPPORT)
|
|
m_dragStartPosition = event.event().position();
|
|
-#endif
|
|
|
|
m_mousePressed = true;
|
|
m_selectionInitiationState = HaveNotStartedSelection;
|
|
@@ -869,8 +868,6 @@ VisiblePosition EventHandler::selectionExtentRespectingEditingBoundary(const Vis
|
|
return targetNode->renderer()->positionForPoint(LayoutPoint(selectionEndPoint), nullptr);
|
|
}
|
|
|
|
-#if ENABLE(DRAG_SUPPORT)
|
|
-
|
|
#if !PLATFORM(IOS_FAMILY)
|
|
|
|
bool EventHandler::supportsSelectionUpdatesOnMouseDrag() const
|
|
@@ -892,8 +889,10 @@ bool EventHandler::handleMouseDraggedEvent(const MouseEventWithHitTestResults& e
|
|
|
|
Ref<Frame> protectedFrame(m_frame);
|
|
|
|
+#if ENABLE(DRAG_SUPPORT)
|
|
if (handleDrag(event, checkDragHysteresis))
|
|
return true;
|
|
+#endif
|
|
|
|
Node* targetNode = event.targetNode();
|
|
if (event.event().button() != LeftButton || !targetNode)
|
|
@@ -914,7 +913,9 @@ bool EventHandler::handleMouseDraggedEvent(const MouseEventWithHitTestResults& e
|
|
ASSERT(m_mouseDownMayStartSelect || m_mouseDownMayStartAutoscroll);
|
|
#endif
|
|
|
|
+#if ENABLE(DRAG_SUPPORT)
|
|
m_mouseDownMayStartDrag = false;
|
|
+#endif
|
|
|
|
if (m_mouseDownMayStartAutoscroll && !panScrollInProgress()) {
|
|
m_autoscrollController->startAutoscrollForSelection(renderer);
|
|
@@ -931,6 +932,8 @@ bool EventHandler::handleMouseDraggedEvent(const MouseEventWithHitTestResults& e
|
|
return true;
|
|
}
|
|
|
|
+#if ENABLE(DRAG_SUPPORT)
|
|
+
|
|
bool EventHandler::eventMayStartDrag(const PlatformMouseEvent& event) const
|
|
{
|
|
// This is a pre-flight check of whether the event might lead to a drag being started. Be careful
|
|
@@ -962,6 +965,8 @@ bool EventHandler::eventMayStartDrag(const PlatformMouseEvent& event) const
|
|
return targetElement && page->dragController().draggableElement(&m_frame, targetElement, result.roundedPointInInnerNodeFrame(), state);
|
|
}
|
|
|
|
+#endif // ENABLE(DRAG_SUPPORT)
|
|
+
|
|
void EventHandler::updateSelectionForMouseDrag()
|
|
{
|
|
if (!supportsSelectionUpdatesOnMouseDrag())
|
|
@@ -1053,7 +1058,6 @@ void EventHandler::updateSelectionForMouseDrag(const HitTestResult& hitTestResul
|
|
m_frame.selection().setSelectionByMouseIfDifferent(newSelection, m_frame.selection().granularity(),
|
|
FrameSelection::EndPointsAdjustmentMode::AdjustAtBidiBoundary);
|
|
}
|
|
-#endif // ENABLE(DRAG_SUPPORT)
|
|
|
|
void EventHandler::lostMouseCapture()
|
|
{
|
|
@@ -1101,9 +1105,7 @@ bool EventHandler::handleMouseReleaseEvent(const MouseEventWithHitTestResults& e
|
|
// on the selection, the selection goes away. However, if we are
|
|
// editing, place the caret.
|
|
if (m_mouseDownWasSingleClickInSelection && m_selectionInitiationState != ExtendedSelection
|
|
-#if ENABLE(DRAG_SUPPORT)
|
|
&& m_dragStartPosition == event.event().position()
|
|
-#endif
|
|
&& m_frame.selection().isRange()
|
|
&& event.event().button() != RightButton) {
|
|
VisibleSelection newSelection;
|
|
@@ -2064,10 +2066,8 @@ bool EventHandler::handleMouseMoveEvent(const PlatformMouseEvent& platformMouseE
|
|
|
|
swallowEvent = !dispatchMouseEvent(eventNames().mousemoveEvent, mouseEvent.targetNode(), 0, platformMouseEvent, FireMouseOverOut::Yes);
|
|
|
|
-#if ENABLE(DRAG_SUPPORT)
|
|
if (!swallowEvent)
|
|
swallowEvent = handleMouseDraggedEvent(mouseEvent);
|
|
-#endif
|
|
|
|
return swallowEvent;
|
|
}
|
|
@@ -4229,7 +4229,8 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
|
|
allTouchReleased = false;
|
|
}
|
|
|
|
- for (auto& point : points) {
|
|
+ for (unsigned index = 0; index < points.size(); index++) {
|
|
+ auto& point = points[index];
|
|
PlatformTouchPoint::State pointState = point.state();
|
|
LayoutPoint pagePoint = documentPointForWindowPoint(m_frame, point.pos());
|
|
|
|
@@ -4355,6 +4356,9 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
|
|
changedTouches[pointState].m_touches->append(WTFMove(touch));
|
|
changedTouches[pointState].m_targets.add(touchTarget);
|
|
}
|
|
+ document.page()->pointerCaptureController().dispatchEventForTouchAtIndex(
|
|
+ *touchTarget, event, index, index == 0, *document.windowProxy());
|
|
+
|
|
}
|
|
m_touchPressed = touches->length() > 0;
|
|
if (allTouchReleased)
|
|
diff --git a/Source/WebCore/page/EventHandler.h b/Source/WebCore/page/EventHandler.h
|
|
index 171ae47f77a67b3d132f04ce6bebb85344dc1de6..e3889f211bfaac614bab5613c267e4b50e35a332 100644
|
|
--- a/Source/WebCore/page/EventHandler.h
|
|
+++ b/Source/WebCore/page/EventHandler.h
|
|
@@ -132,9 +132,7 @@ public:
|
|
|
|
WEBCORE_EXPORT VisiblePosition selectionExtentRespectingEditingBoundary(const VisibleSelection&, const LayoutPoint&, Node*);
|
|
|
|
-#if ENABLE(DRAG_SUPPORT)
|
|
void updateSelectionForMouseDrag();
|
|
-#endif
|
|
|
|
#if ENABLE(PAN_SCROLLING)
|
|
void didPanScrollStart();
|
|
@@ -364,10 +362,8 @@ private:
|
|
bool handleMousePressEventDoubleClick(const MouseEventWithHitTestResults&);
|
|
bool handleMousePressEventTripleClick(const MouseEventWithHitTestResults&);
|
|
|
|
-#if ENABLE(DRAG_SUPPORT)
|
|
bool handleMouseDraggedEvent(const MouseEventWithHitTestResults&, CheckDragHysteresis = ShouldCheckDragHysteresis);
|
|
bool shouldAllowMouseDownToStartDrag() const;
|
|
-#endif
|
|
|
|
WEBCORE_EXPORT bool handleMouseReleaseEvent(const MouseEventWithHitTestResults&);
|
|
|
|
@@ -464,10 +460,8 @@ private:
|
|
void defaultTabEventHandler(KeyboardEvent&);
|
|
void defaultArrowEventHandler(FocusDirection, KeyboardEvent&);
|
|
|
|
-#if ENABLE(DRAG_SUPPORT)
|
|
OptionSet<DragSourceAction> updateDragSourceActionsAllowed() const;
|
|
bool supportsSelectionUpdatesOnMouseDrag() const;
|
|
-#endif
|
|
|
|
// The following are called at the beginning of handleMouseUp and handleDrag.
|
|
// If they return true it indicates that they have consumed the event.
|
|
@@ -475,9 +469,10 @@ private:
|
|
|
|
#if ENABLE(DRAG_SUPPORT)
|
|
bool eventLoopHandleMouseDragged(const MouseEventWithHitTestResults&);
|
|
- void updateSelectionForMouseDrag(const HitTestResult&);
|
|
#endif
|
|
|
|
+ void updateSelectionForMouseDrag(const HitTestResult&);
|
|
+
|
|
enum class SetOrClearLastScrollbar { Clear, Set };
|
|
void updateLastScrollbarUnderMouse(Scrollbar*, SetOrClearLastScrollbar);
|
|
|
|
@@ -527,10 +522,7 @@ private:
|
|
enum SelectionInitiationState { HaveNotStartedSelection, PlacedCaret, ExtendedSelection };
|
|
SelectionInitiationState m_selectionInitiationState { HaveNotStartedSelection };
|
|
|
|
-#if ENABLE(DRAG_SUPPORT)
|
|
LayoutPoint m_dragStartPosition;
|
|
-#endif
|
|
-
|
|
Timer m_hoverTimer;
|
|
bool m_hasScheduledCursorUpdate { false };
|
|
|
|
diff --git a/Source/WebCore/page/EventSource.cpp b/Source/WebCore/page/EventSource.cpp
|
|
index 757765c3b4872d5a6f92b34e3f2ac67eaaf2dd82..69c4ef67941cee93213ccac1aa04d2cb1db08782 100644
|
|
--- a/Source/WebCore/page/EventSource.cpp
|
|
+++ b/Source/WebCore/page/EventSource.cpp
|
|
@@ -36,6 +36,7 @@
|
|
#include "CachedResourceRequestInitiators.h"
|
|
#include "ContentSecurityPolicy.h"
|
|
#include "EventNames.h"
|
|
+#include "InspectorNetworkAgent.h"
|
|
#include "MessageEvent.h"
|
|
#include "ResourceError.h"
|
|
#include "ResourceRequest.h"
|
|
@@ -97,6 +98,7 @@ void EventSource::connect()
|
|
ASSERT(!m_requestInFlight);
|
|
|
|
ResourceRequest request { m_url };
|
|
+ request.setInitiatorIdentifier(InspectorNetworkAgent::initiatorIdentifierForEventSource());
|
|
request.setHTTPMethod("GET");
|
|
request.setHTTPHeaderField(HTTPHeaderName::Accept, "text/event-stream");
|
|
request.setHTTPHeaderField(HTTPHeaderName::CacheControl, "no-cache");
|
|
diff --git a/Source/WebCore/page/Frame.cpp b/Source/WebCore/page/Frame.cpp
|
|
index bd3497c1a220015656e002045e4e6177c39398b5..eea459157c107ed4a6ad261cf11bfb1f14726df4 100644
|
|
--- a/Source/WebCore/page/Frame.cpp
|
|
+++ b/Source/WebCore/page/Frame.cpp
|
|
@@ -39,6 +39,7 @@
|
|
#include "CachedResourceLoader.h"
|
|
#include "Chrome.h"
|
|
#include "ChromeClient.h"
|
|
+#include "ComposedTreeIterator.h"
|
|
#include "DOMWindow.h"
|
|
#include "DocumentTimeline.h"
|
|
#include "DocumentType.h"
|
|
@@ -71,6 +72,7 @@
|
|
#include "NavigationScheduler.h"
|
|
#include "Navigator.h"
|
|
#include "NodeList.h"
|
|
+#include "NodeRenderStyle.h"
|
|
#include "NodeTraversal.h"
|
|
#include "Page.h"
|
|
#include "ProcessWarming.h"
|
|
@@ -179,6 +181,7 @@ Frame::Frame(Page& page, HTMLFrameOwnerElement* ownerElement, UniqueRef<FrameLoa
|
|
void Frame::init()
|
|
{
|
|
m_loader->init();
|
|
+ InspectorInstrumentation::frameAttached(this);
|
|
}
|
|
|
|
Ref<Frame> Frame::create(Page* page, HTMLFrameOwnerElement* ownerElement, UniqueRef<FrameLoaderClient>&& client)
|
|
@@ -338,7 +341,7 @@ void Frame::orientationChanged()
|
|
int Frame::orientation() const
|
|
{
|
|
if (m_page)
|
|
- return m_page->chrome().client().deviceOrientation();
|
|
+ return m_page->orientation();
|
|
return 0;
|
|
}
|
|
#endif // ENABLE(ORIENTATION_EVENTS)
|
|
@@ -1106,6 +1109,358 @@ TextStream& operator<<(TextStream& ts, const Frame& frame)
|
|
return ts;
|
|
}
|
|
|
|
+void Frame::betterApproximateNode(const IntPoint& testPoint, const NodeQualifier& nodeQualifierFunction, Node*& best, Node* failedNode, IntPoint& bestPoint, IntRect& bestRect, const IntRect& testRect)
|
|
+{
|
|
+ IntRect candidateRect;
|
|
+ constexpr OptionSet<HitTestRequest::RequestType> hitType { HitTestRequest::ReadOnly, HitTestRequest::Active, HitTestRequest::DisallowUserAgentShadowContent, HitTestRequest::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 Frame::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::RequestType> hitType { HitTestRequest::ReadOnly, HitTestRequest::Active, HitTestRequest::DisallowUserAgentShadowContent, HitTestRequest::AllowVisibleChildFrameContentOnly };
|
|
+ hitTestResult = eventHandler().hitTestResultAtPoint(center, hitType);
|
|
+ return true;
|
|
+}
|
|
+
|
|
+Node* Frame::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 < WTF_ARRAY_LENGTH(testOffsets); n += 2) {
|
|
+ IntSize testOffset(testOffsets[n] * searchRadius, testOffsets[n + 1] * searchRadius);
|
|
+ IntPoint testPoint = testCenter + testOffset;
|
|
+
|
|
+ constexpr OptionSet<HitTestRequest::RequestType> hitType { HitTestRequest::ReadOnly, HitTestRequest::Active, HitTestRequest::DisallowUserAgentShadowContent, HitTestRequest::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 < WTF_ARRAY_LENGTH(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;
|
|
+}
|
|
+
|
|
+Node* Frame::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 (auto shadowRoot = makeRefPtr(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* Frame::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* Frame::nodeRespondingToClickEvents(const FloatPoint& viewportLocation, FloatPoint& adjustedViewportLocation, SecurityOrigin* securityOrigin)
|
|
+{
|
|
+ return qualifyingNodeAtViewportLocation(viewportLocation, adjustedViewportLocation, ancestorRespondingToClickEventsNodeQualifier(securityOrigin), ShouldApproximate::Yes);
|
|
+}
|
|
+
|
|
+Node* Frame::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* Frame::nodeRespondingToInteraction(const FloatPoint& viewportLocation, FloatPoint& adjustedViewportLocation)
|
|
+{
|
|
+ return qualifyingNodeAtViewportLocation(viewportLocation, adjustedViewportLocation, ancestorRespondingToClickEventsNodeQualifier(), ShouldApproximate::Yes, ShouldFindRootEditableElement::No);
|
|
+}
|
|
+
|
|
+Node* Frame::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->isTextField() || renderer->isTextArea()) && downcast<RenderTextControl>(*renderer).canScroll()) {
|
|
+ scrollingAncestor = node;
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ auto& style = renderer->style();
|
|
+
|
|
+ if (renderer->hasOverflowClip()
|
|
+ && (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);
|
|
+}
|
|
+
|
|
} // namespace WebCore
|
|
|
|
#undef RELEASE_LOG_ERROR_IF_ALLOWED
|
|
diff --git a/Source/WebCore/page/Frame.h b/Source/WebCore/page/Frame.h
|
|
index 50c65f5e5b0753c1e6d307b213b5200c450aa30a..ff2efc36b1a256767624db9bd47a46d01c8f0392 100644
|
|
--- a/Source/WebCore/page/Frame.h
|
|
+++ b/Source/WebCore/page/Frame.h
|
|
@@ -109,8 +109,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)>;
|
|
|
|
enum {
|
|
LayerTreeFlagsIncludeDebugInfo = 1 << 0,
|
|
@@ -228,10 +228,6 @@ public:
|
|
NSArray *dataDetectionResults() const { return m_dataDetectionResults.get(); }
|
|
#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);
|
|
@@ -239,6 +235,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;
|
|
|
|
@@ -346,7 +346,6 @@ private:
|
|
#if ENABLE(DATA_DETECTION)
|
|
RetainPtr<NSArray> 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);
|
|
|
|
@@ -354,6 +353,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/FrameSnapshotting.cpp b/Source/WebCore/page/FrameSnapshotting.cpp
|
|
index efc6c0ef136a4b6a99a66487e7387f404baf4a3b..81cdfb027f2cc5171756cf9dbe7e9b6907f5625a 100644
|
|
--- a/Source/WebCore/page/FrameSnapshotting.cpp
|
|
+++ b/Source/WebCore/page/FrameSnapshotting.cpp
|
|
@@ -114,7 +114,12 @@ std::unique_ptr<ImageBuffer> snapshotFrameRectWithClip(Frame& frame, const IntRe
|
|
std::unique_ptr<ImageBuffer> buffer = ImageBuffer::create(imageRect.size(), RenderingMode::Unaccelerated, scaleFactor);
|
|
if (!buffer)
|
|
return nullptr;
|
|
+#if !PLATFORM(MAC)
|
|
+ buffer->context().scale(scaleFactor);
|
|
+#endif
|
|
buffer->context().translate(-imageRect.x(), -imageRect.y());
|
|
+ if (coordinateSpace != FrameView::ViewCoordinates)
|
|
+ buffer->context().scale(1 / frame.page()->pageScaleFactor());
|
|
|
|
if (!clipRects.isEmpty()) {
|
|
Path clipPath;
|
|
@@ -123,7 +128,10 @@ std::unique_ptr<ImageBuffer> snapshotFrameRectWithClip(Frame& frame, const IntRe
|
|
buffer->context().clipPath(clipPath);
|
|
}
|
|
|
|
- frame.view()->paintContentsForSnapshot(buffer->context(), imageRect, shouldIncludeSelection, coordinateSpace);
|
|
+ FloatRect fr = imageRect;
|
|
+ if (coordinateSpace != FrameView::ViewCoordinates)
|
|
+ fr.scale(frame.page()->pageScaleFactor());
|
|
+ frame.view()->paintContentsForSnapshot(buffer->context(), enclosingIntRect(fr), shouldIncludeSelection, coordinateSpace);
|
|
return buffer;
|
|
}
|
|
|
|
diff --git a/Source/WebCore/page/FrameView.cpp b/Source/WebCore/page/FrameView.cpp
|
|
index aa0e21bfd9d476e3a4f5d2dba5342bfcbb897049..8068f68b6d253c9317df70118b573e96c5b5c941 100644
|
|
--- a/Source/WebCore/page/FrameView.cpp
|
|
+++ b/Source/WebCore/page/FrameView.cpp
|
|
@@ -3004,7 +3004,7 @@ void FrameView::setBaseBackgroundColor(const Color& backgroundColor)
|
|
|
|
void FrameView::updateBackgroundRecursively(const Optional<Color>& backgroundColor)
|
|
{
|
|
-#if HAVE(OS_DARK_MODE_SUPPORT)
|
|
+#if HAVE(OS_DARK_MODE_SUPPORT) && (defined(WTF_PLATFORM_MAC) && WTF_PLATFORM_MAC) || (defined(WTF_PLATFORM_IOS_FAMILY) && WTF_PLATFORM_IOS_FAMILY)
|
|
Color baseBackgroundColor = backgroundColor.valueOr(RenderTheme::singleton().systemColor(CSSValueAppleSystemControlBackground, styleColorOptions()));
|
|
#else
|
|
Color baseBackgroundColor = backgroundColor.valueOr(Color::white);
|
|
diff --git a/Source/WebCore/page/History.cpp b/Source/WebCore/page/History.cpp
|
|
index 38fd7b29b53eab484e30963b51c8ae525c5d7a38..3c2f2104e3f364d3d6201e3009a448b4db317d03 100644
|
|
--- a/Source/WebCore/page/History.cpp
|
|
+++ b/Source/WebCore/page/History.cpp
|
|
@@ -33,6 +33,7 @@
|
|
#include "FrameLoaderClient.h"
|
|
#include "HistoryController.h"
|
|
#include "HistoryItem.h"
|
|
+#include "InspectorInstrumentation.h"
|
|
#include "Logging.h"
|
|
#include "NavigationScheduler.h"
|
|
#include "Page.h"
|
|
@@ -260,6 +261,7 @@ ExceptionOr<void> History::stateObjectAdded(RefPtr<SerializedScriptValue>&& data
|
|
|
|
if (!urlString.isEmpty())
|
|
frame->document()->updateURLForPushOrReplaceState(fullURL);
|
|
+ InspectorInstrumentation::didNavigateWithinPage(*frame);
|
|
|
|
if (stateObjectType == StateObjectType::Push) {
|
|
frame->loader().history().pushState(WTFMove(data), title, fullURL.string());
|
|
diff --git a/Source/WebCore/page/Page.cpp b/Source/WebCore/page/Page.cpp
|
|
index 5e072c83e9e4c42741fdcf289106df7a8c7fb145..ba7ec3f7ece225466b7ebf6e4d49a425128866a0 100644
|
|
--- a/Source/WebCore/page/Page.cpp
|
|
+++ b/Source/WebCore/page/Page.cpp
|
|
@@ -89,6 +89,7 @@
|
|
#include "PerformanceLoggingClient.h"
|
|
#include "PerformanceMonitor.h"
|
|
#include "PlatformMediaSessionManager.h"
|
|
+#include "PlatformScreen.h"
|
|
#include "PlatformStrategies.h"
|
|
#include "PlugInClient.h"
|
|
#include "PluginData.h"
|
|
@@ -432,6 +433,37 @@ void Page::setOverrideViewportArguments(const Optional<ViewportArguments>& viewp
|
|
document->updateViewportArguments();
|
|
}
|
|
|
|
+FloatSize Page::screenSize()
|
|
+{
|
|
+ return m_overrideScreenSize.valueOr(screenRect(mainFrame().view()).size());
|
|
+}
|
|
+
|
|
+void Page::setOverrideScreenSize(Optional<FloatSize> size)
|
|
+{
|
|
+ if (size == m_overrideScreenSize)
|
|
+ return;
|
|
+
|
|
+ m_overrideScreenSize = size;
|
|
+ if (auto* document = mainFrame().document())
|
|
+ document->updateViewportArguments();
|
|
+}
|
|
+
|
|
+#if ENABLE(ORIENTATION_EVENTS)
|
|
+int Page::orientation() const
|
|
+{
|
|
+ return m_overrideOrientation.valueOr(chrome().client().deviceOrientation());
|
|
+}
|
|
+
|
|
+void Page::setOverrideOrientation(Optional<int> orientation)
|
|
+{
|
|
+ if (orientation == m_overrideOrientation)
|
|
+ return;
|
|
+
|
|
+ m_overrideOrientation = orientation;
|
|
+ mainFrame().orientationChanged();
|
|
+}
|
|
+#endif
|
|
+
|
|
ScrollingCoordinator* Page::scrollingCoordinator()
|
|
{
|
|
if (!m_scrollingCoordinator && m_settings->scrollingCoordinatorEnabled()) {
|
|
diff --git a/Source/WebCore/page/Page.h b/Source/WebCore/page/Page.h
|
|
index a020e881a26ae651f551462015d84cea9725a0a8..89eead8acf91ba2707782fef353465754030c1b7 100644
|
|
--- a/Source/WebCore/page/Page.h
|
|
+++ b/Source/WebCore/page/Page.h
|
|
@@ -243,6 +243,9 @@ public:
|
|
const Optional<ViewportArguments>& overrideViewportArguments() const { return m_overrideViewportArguments; }
|
|
WEBCORE_EXPORT void setOverrideViewportArguments(const Optional<ViewportArguments>&);
|
|
|
|
+ WEBCORE_EXPORT FloatSize screenSize();
|
|
+ void setOverrideScreenSize(Optional<FloatSize> size);
|
|
+
|
|
static void refreshPlugins(bool reload);
|
|
WEBCORE_EXPORT PluginData& pluginData();
|
|
void clearPluginData();
|
|
@@ -800,6 +803,11 @@ public:
|
|
|
|
WEBCORE_EXPORT Vector<Ref<Element>> editableElementsInRect(const FloatRect&) const;
|
|
|
|
+#if ENABLE(ORIENTATION_EVENTS)
|
|
+ int orientation() const;
|
|
+ void setOverrideOrientation(Optional<int>);
|
|
+#endif
|
|
+
|
|
#if ENABLE(DEVICE_ORIENTATION) && PLATFORM(IOS_FAMILY)
|
|
DeviceOrientationUpdateProvider* deviceOrientationUpdateProvider() const { return m_deviceOrientationUpdateProvider.get(); }
|
|
#endif
|
|
@@ -1107,6 +1115,11 @@ private:
|
|
#endif
|
|
|
|
Optional<ViewportArguments> m_overrideViewportArguments;
|
|
+ Optional<FloatSize> m_overrideScreenSize;
|
|
+
|
|
+#if ENABLE(ORIENTATION_EVENTS)
|
|
+ Optional<int> m_overrideOrientation;
|
|
+#endif
|
|
|
|
#if ENABLE(DEVICE_ORIENTATION) && PLATFORM(IOS_FAMILY)
|
|
RefPtr<DeviceOrientationUpdateProvider> m_deviceOrientationUpdateProvider;
|
|
diff --git a/Source/WebCore/page/PointerCaptureController.cpp b/Source/WebCore/page/PointerCaptureController.cpp
|
|
index d37f5889e219d828e09ae72343d8ebd3fecfb08f..7b0f956fc187f4747b93f6b8d8b7697c889d5361 100644
|
|
--- a/Source/WebCore/page/PointerCaptureController.cpp
|
|
+++ b/Source/WebCore/page/PointerCaptureController.cpp
|
|
@@ -181,7 +181,7 @@ bool PointerCaptureController::preventsCompatibilityMouseEventsForIdentifier(Poi
|
|
return iterator != m_activePointerIdsToCapturingData.end() && iterator->value.preventsCompatibilityMouseEvents;
|
|
}
|
|
|
|
-#if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS_FAMILY)
|
|
+#if ENABLE(TOUCH_EVENTS)
|
|
static bool hierarchyHasCapturingEventListeners(Element* target, const AtomString& eventName)
|
|
{
|
|
for (ContainerNode* curr = target; curr; curr = curr->parentInComposedTree()) {
|
|
@@ -463,7 +463,7 @@ void PointerCaptureController::cancelPointer(PointerID pointerId, const IntPoint
|
|
capturingData.pendingTargetOverride = nullptr;
|
|
capturingData.cancelled = true;
|
|
|
|
-#if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS_FAMILY)
|
|
+#if ENABLE(TOUCH_EVENTS)
|
|
capturingData.previousTarget = nullptr;
|
|
#endif
|
|
|
|
diff --git a/Source/WebCore/page/PointerCaptureController.h b/Source/WebCore/page/PointerCaptureController.h
|
|
index 33bdbd20f4aaca7db33e055bdbea79c69800b3db..e8d329292d4b1fe6e49d74cb07a66339e63accdb 100644
|
|
--- a/Source/WebCore/page/PointerCaptureController.h
|
|
+++ b/Source/WebCore/page/PointerCaptureController.h
|
|
@@ -57,7 +57,7 @@ public:
|
|
|
|
RefPtr<PointerEvent> pointerEventForMouseEvent(const MouseEvent&);
|
|
|
|
-#if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS_FAMILY)
|
|
+#if ENABLE(TOUCH_EVENTS)
|
|
void dispatchEventForTouchAtIndex(EventTarget&, const PlatformTouchEvent&, unsigned, bool isPrimary, WindowProxy&);
|
|
#endif
|
|
|
|
@@ -72,7 +72,7 @@ private:
|
|
struct CapturingData {
|
|
RefPtr<Element> pendingTargetOverride;
|
|
RefPtr<Element> targetOverride;
|
|
-#if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS_FAMILY)
|
|
+#if ENABLE(TOUCH_EVENTS)
|
|
RefPtr<Element> previousTarget;
|
|
#endif
|
|
String pointerType;
|
|
diff --git a/Source/WebCore/page/Screen.cpp b/Source/WebCore/page/Screen.cpp
|
|
index b4f7fe0d15ee81dbc7b2b7c9e7c0e6cc42dc8e55..1a40df0eadea4f508b7227590b9d5386bf257687 100644
|
|
--- a/Source/WebCore/page/Screen.cpp
|
|
+++ b/Source/WebCore/page/Screen.cpp
|
|
@@ -34,6 +34,7 @@
|
|
#include "FloatRect.h"
|
|
#include "Frame.h"
|
|
#include "FrameView.h"
|
|
+#include "Page.h"
|
|
#include "PlatformScreen.h"
|
|
#include "Quirks.h"
|
|
#include "ResourceLoadObserver.h"
|
|
@@ -56,7 +57,7 @@ unsigned Screen::height() const
|
|
return 0;
|
|
if (RuntimeEnabledFeatures::sharedFeatures().webAPIStatisticsEnabled())
|
|
ResourceLoadObserver::shared().logScreenAPIAccessed(*frame->document(), ResourceLoadStatistics::ScreenAPI::Height);
|
|
- long height = static_cast<long>(screenRect(frame->view()).height());
|
|
+ long height = static_cast<long>(frame->page()->screenSize().height());
|
|
return static_cast<unsigned>(height);
|
|
}
|
|
|
|
@@ -67,7 +68,7 @@ unsigned Screen::width() const
|
|
return 0;
|
|
if (RuntimeEnabledFeatures::sharedFeatures().webAPIStatisticsEnabled())
|
|
ResourceLoadObserver::shared().logScreenAPIAccessed(*frame->document(), ResourceLoadStatistics::ScreenAPI::Width);
|
|
- long width = static_cast<long>(screenRect(frame->view()).width());
|
|
+ long width = static_cast<long>(frame->page()->screenSize().width());
|
|
return static_cast<unsigned>(width);
|
|
}
|
|
|
|
diff --git a/Source/WebCore/page/SocketProvider.cpp b/Source/WebCore/page/SocketProvider.cpp
|
|
index 3bec0aef174336939838fb1069fffbcb9f3d5604..566ef3806be3c5ccf1bb951251c2a90dba7071a3 100644
|
|
--- a/Source/WebCore/page/SocketProvider.cpp
|
|
+++ b/Source/WebCore/page/SocketProvider.cpp
|
|
@@ -33,7 +33,7 @@ namespace WebCore {
|
|
|
|
Ref<SocketStreamHandle> SocketProvider::createSocketStreamHandle(const URL& url, SocketStreamHandleClient& client, WebSocketIdentifier, PAL::SessionID sessionID, const String& credentialPartition, const StorageSessionProvider* provider)
|
|
{
|
|
- return SocketStreamHandleImpl::create(url, client, sessionID, credentialPartition, { }, provider);
|
|
+ return SocketStreamHandleImpl::create(url, false, client, sessionID, credentialPartition, { }, provider);
|
|
}
|
|
|
|
RefPtr<ThreadableWebSocketChannel> SocketProvider::createWebSocketChannel(Document&, WebSocketChannelClient&)
|
|
diff --git a/Source/WebCore/page/csp/ContentSecurityPolicy.cpp b/Source/WebCore/page/csp/ContentSecurityPolicy.cpp
|
|
index 37d5c443785f3df52bddb775cb9c1e66e0dd97b6..f2329ad61fd4f4ad006ca89ba2bdc729278dee0d 100644
|
|
--- a/Source/WebCore/page/csp/ContentSecurityPolicy.cpp
|
|
+++ b/Source/WebCore/page/csp/ContentSecurityPolicy.cpp
|
|
@@ -299,6 +299,8 @@ bool ContentSecurityPolicy::protocolMatchesSelf(const URL& url) const
|
|
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))
|
|
+ return true;
|
|
bool isReportOnly = disposition == ContentSecurityPolicy::Disposition::ReportOnly;
|
|
for (auto& policy : m_policies) {
|
|
if (policy->isReportOnly() != isReportOnly)
|
|
@@ -312,6 +314,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))
|
|
+ return true;
|
|
bool isReportOnly = disposition == ContentSecurityPolicy::Disposition::ReportOnly;
|
|
bool isAllowed = true;
|
|
for (auto& policy : m_policies) {
|
|
@@ -328,6 +332,8 @@ bool ContentSecurityPolicy::allPoliciesWithDispositionAllow(Disposition disposit
|
|
template<typename Predicate, typename... Args>
|
|
bool ContentSecurityPolicy::allPoliciesAllow(ViolatedDirectiveCallback&& callback, Predicate&& predicate, Args&&... args) const
|
|
{
|
|
+ if (InspectorInstrumentation::shouldBypassCSP(m_scriptExecutionContext))
|
|
+ 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/ios/FrameIOS.mm b/Source/WebCore/page/ios/FrameIOS.mm
|
|
index 32d32e59b24265286710a5f3f7053e1816ad9e3b..34f7e01b612710a817debb7f8d25d6bd5f0e9e6d 100644
|
|
--- a/Source/WebCore/page/ios/FrameIOS.mm
|
|
+++ b/Source/WebCore/page/ios/FrameIOS.mm
|
|
@@ -225,354 +225,6 @@ CGRect Frame::renderRectForPoint(CGPoint point, bool* isReplaced, float* fontSiz
|
|
return CGRectZero;
|
|
}
|
|
|
|
-void Frame::betterApproximateNode(const IntPoint& testPoint, const NodeQualifier& nodeQualifierFunction, Node*& best, Node* failedNode, IntPoint& bestPoint, IntRect& bestRect, const IntRect& testRect)
|
|
-{
|
|
- IntRect candidateRect;
|
|
- constexpr OptionSet<HitTestRequest::RequestType> hitType { HitTestRequest::ReadOnly, HitTestRequest::Active, HitTestRequest::DisallowUserAgentShadowContent, HitTestRequest::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 Frame::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::RequestType> hitType { HitTestRequest::ReadOnly, HitTestRequest::Active, HitTestRequest::DisallowUserAgentShadowContent, HitTestRequest::AllowVisibleChildFrameContentOnly };
|
|
- hitTestResult = eventHandler().hitTestResultAtPoint(center, hitType);
|
|
- return true;
|
|
-}
|
|
-
|
|
-Node* Frame::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;
|
|
- float ppiFactor = screenPPIFactor();
|
|
-
|
|
- 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 < WTF_ARRAY_LENGTH(testOffsets); n += 2) {
|
|
- IntSize testOffset(testOffsets[n] * searchRadius, testOffsets[n + 1] * searchRadius);
|
|
- IntPoint testPoint = testCenter + testOffset;
|
|
-
|
|
- constexpr OptionSet<HitTestRequest::RequestType> hitType { HitTestRequest::ReadOnly, HitTestRequest::Active, HitTestRequest::DisallowUserAgentShadowContent, HitTestRequest::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 < WTF_ARRAY_LENGTH(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;
|
|
-}
|
|
-
|
|
-Node* Frame::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 (auto shadowRoot = makeRefPtr(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* Frame::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* Frame::nodeRespondingToClickEvents(const FloatPoint& viewportLocation, FloatPoint& adjustedViewportLocation, SecurityOrigin* securityOrigin)
|
|
-{
|
|
- return qualifyingNodeAtViewportLocation(viewportLocation, adjustedViewportLocation, ancestorRespondingToClickEventsNodeQualifier(securityOrigin), ShouldApproximate::Yes);
|
|
-}
|
|
-
|
|
-Node* Frame::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* Frame::nodeRespondingToInteraction(const FloatPoint& viewportLocation, FloatPoint& adjustedViewportLocation)
|
|
-{
|
|
- return qualifyingNodeAtViewportLocation(viewportLocation, adjustedViewportLocation, ancestorRespondingToClickEventsNodeQualifier(), ShouldApproximate::Yes, ShouldFindRootEditableElement::No);
|
|
-}
|
|
-
|
|
-Node* Frame::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->isTextField() || renderer->isTextArea()) && downcast<RenderTextControl>(*renderer).canScroll()) {
|
|
- scrollingAncestor = node;
|
|
- continue;
|
|
- }
|
|
-
|
|
- auto& style = renderer->style();
|
|
-
|
|
- if (renderer->hasOverflowClip()
|
|
- && (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);
|
|
-}
|
|
-
|
|
int Frame::preferredHeight() const
|
|
{
|
|
Document* document = this->document();
|
|
diff --git a/Source/WebCore/platform/Cairo.cmake b/Source/WebCore/platform/Cairo.cmake
|
|
index fc6c5f3cd046269566822c08a482cc3bd6a883c0..083c03903a3111ee2cb6f9882dd2efe146d7dc35 100644
|
|
--- a/Source/WebCore/platform/Cairo.cmake
|
|
+++ b/Source/WebCore/platform/Cairo.cmake
|
|
@@ -17,6 +17,7 @@ list(APPEND WebCore_PRIVATE_FRAMEWORK_HEADERS
|
|
platform/graphics/cairo/ImageBufferCairoGLSurfaceBackend.h
|
|
platform/graphics/cairo/ImageBufferCairoImageSurfaceBackend.h
|
|
platform/graphics/cairo/ImageBufferCairoSurfaceBackend.h
|
|
+ platform/graphics/cairo/ImageBufferUtilitiesCairo.h
|
|
platform/graphics/cairo/PlatformContextCairo.h
|
|
platform/graphics/cairo/RefPtrCairo.h
|
|
)
|
|
diff --git a/Source/WebCore/platform/PlatformKeyboardEvent.h b/Source/WebCore/platform/PlatformKeyboardEvent.h
|
|
index f423a4a1d5399326fc48fe4d4a8a8fb9d4df861e..b4b60162d8b0d34113df052b04a1695d481d266e 100644
|
|
--- a/Source/WebCore/platform/PlatformKeyboardEvent.h
|
|
+++ b/Source/WebCore/platform/PlatformKeyboardEvent.h
|
|
@@ -138,6 +138,7 @@ namespace WebCore {
|
|
static String keyCodeForHardwareKeyCode(unsigned);
|
|
static String keyIdentifierForGdkKeyCode(unsigned);
|
|
static int windowsKeyCodeForGdkKeyCode(unsigned);
|
|
+ static unsigned gdkKeyCodeForWindowsKeyCode(int);
|
|
static String singleCharacterString(unsigned);
|
|
static bool modifiersContainCapsLock(unsigned);
|
|
#endif
|
|
@@ -147,6 +148,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/ScrollableArea.h b/Source/WebCore/platform/ScrollableArea.h
|
|
index 387ad285c20dd8fd5eba27f665eee85183e77c6f..4d44ae6f18064102e13de5221e43042870bade9f 100644
|
|
--- a/Source/WebCore/platform/ScrollableArea.h
|
|
+++ b/Source/WebCore/platform/ScrollableArea.h
|
|
@@ -107,7 +107,7 @@ public:
|
|
void updateScrollSnapState();
|
|
|
|
#if ENABLE(TOUCH_EVENTS)
|
|
- virtual bool handleTouchEvent(const PlatformTouchEvent&);
|
|
+ WEBCORE_EXPORT virtual bool handleTouchEvent(const PlatformTouchEvent&);
|
|
#endif
|
|
|
|
#if PLATFORM(IOS_FAMILY)
|
|
diff --git a/Source/WebCore/platform/graphics/FontCascade.h b/Source/WebCore/platform/graphics/FontCascade.h
|
|
index fd99ed1543a085b25cb91561c053f32b3f1b04a6..cf3d1934e73bdfce82afdbaec8dd54049c18a643 100644
|
|
--- a/Source/WebCore/platform/graphics/FontCascade.h
|
|
+++ b/Source/WebCore/platform/graphics/FontCascade.h
|
|
@@ -279,7 +279,8 @@ private:
|
|
return true;
|
|
if (textRenderingMode == TextRenderingMode::OptimizeSpeed)
|
|
return false;
|
|
-#if PLATFORM(COCOA) || USE(FREETYPE)
|
|
+ // WIN: quick fix for https://bugs.webkit.org/show_bug.cgi?id=201213
|
|
+#if PLATFORM(COCOA) || USE(FREETYPE) || PLATFORM(WIN)
|
|
return true;
|
|
#else
|
|
return false;
|
|
diff --git a/Source/WebCore/platform/graphics/cairo/ImageBufferUtilitiesCairo.cpp b/Source/WebCore/platform/graphics/cairo/ImageBufferUtilitiesCairo.cpp
|
|
index d79728555b7db9b59cb615c55a7a7a6851cb57c8..61d3cc4b488e35ef9e1afa1ce3ac5f5d60ebe9a7 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> data(cairo_surface_t* image, const String& mimeType, 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(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> data(cairo_surface_t* image, const String& mimeType, Optional<double> quality)
|
|
{
|
|
+ if (mimeType == "image/jpeg") {
|
|
+ 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 bc87758878d5163a938af8242c7a6800ea9bd13c..3d0751f8dfe1124bbe054daa2fa0c7552fecab32 100644
|
|
--- a/Source/WebCore/platform/graphics/cg/ImageBufferUtilitiesCG.h
|
|
+++ b/Source/WebCore/platform/graphics/cg/ImageBufferUtilitiesCG.h
|
|
@@ -42,7 +42,7 @@ WEBCORE_EXPORT uint8_t verifyImageBufferIsBigEnough(const void* buffer, size_t b
|
|
CFStringRef jpegUTI();
|
|
RetainPtr<CFStringRef> utiFromImageBufferMIMEType(const String&);
|
|
|
|
-bool encodeImage(CGImageRef, CFStringRef uti, Optional<double> quality, CFMutableDataRef);
|
|
+WEBCORE_EXPORT bool encodeImage(CGImageRef, CFStringRef uti, Optional<double> quality, CFMutableDataRef);
|
|
|
|
String dataURL(CFDataRef, const String& mimeType);
|
|
String dataURL(const ImageData&, const String& mimeType, Optional<double> quality);
|
|
diff --git a/Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGLBase.cpp b/Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGLBase.cpp
|
|
index c4f8b6a1e2907edfa07df0c6eb797873bdd69393..9fd0fc56c8d8cd2fde826bfe96d8355db59616b0 100644
|
|
--- a/Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGLBase.cpp
|
|
+++ b/Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGLBase.cpp
|
|
@@ -27,7 +27,7 @@
|
|
#include "config.h"
|
|
#include "GraphicsContextGLOpenGL.h"
|
|
|
|
-#if ENABLE(GRAPHICS_CONTEXT_GL) && (USE(OPENGL) || (PLATFORM(COCOA) && USE(OPENGL_ES)))
|
|
+#if !PLATFORM(WIN) && ENABLE(GRAPHICS_CONTEXT_GL) && (USE(OPENGL) || (PLATFORM(COCOA) && USE(OPENGL_ES)))
|
|
|
|
#if PLATFORM(IOS_FAMILY)
|
|
#include "GraphicsContextGLOpenGLESIOS.h"
|
|
diff --git a/Source/WebCore/platform/graphics/win/ComplexTextControllerUniscribe.cpp b/Source/WebCore/platform/graphics/win/ComplexTextControllerUniscribe.cpp
|
|
index 774a52a28693bc51dde10a0875ea379afb06fd3c..cd714a7298fe4f5d2c9b580697a5c4cd22d25870 100644
|
|
--- a/Source/WebCore/platform/graphics/win/ComplexTextControllerUniscribe.cpp
|
|
+++ b/Source/WebCore/platform/graphics/win/ComplexTextControllerUniscribe.cpp
|
|
@@ -172,6 +172,33 @@ static Vector<unsigned> stringIndicesFromClusters(const Vector<WORD>& clusters,
|
|
return stringIndices;
|
|
}
|
|
|
|
+static int compactScriptItemsIfNeeded(const UChar* cp, unsigned stringLength, 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().isSystemFont() || font->platformData().hasVariations())
|
|
+ return numItems;
|
|
+
|
|
+ bool allGoodCharacters = true;
|
|
+ for (unsigned i = 0; allGoodCharacters && i < stringLength; ++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(const UChar* cp, unsigned stringLength, unsigned stringLocation, const Font* font)
|
|
{
|
|
if (!font) {
|
|
@@ -201,6 +228,8 @@ void ComplexTextController::collectComplexTextRunsForCharacters(const UChar* cp,
|
|
}
|
|
items.resize(numItems + 1);
|
|
|
|
+ numItems = compactScriptItemsIfNeeded(cp, stringLength, items, numItems, font);
|
|
+
|
|
for (int i = 0; i < numItems; i++) {
|
|
// Determine the string for this item.
|
|
const UChar* str = cp + items[i].iCharPos;
|
|
diff --git a/Source/WebCore/platform/gtk/PlatformKeyboardEventGtk.cpp b/Source/WebCore/platform/gtk/PlatformKeyboardEventGtk.cpp
|
|
index 0516e70973e0078de6ad0216375d34dd9ef51a8d..ffd9a02deb5518e0c8c77b156815c11eb4b16829 100644
|
|
--- a/Source/WebCore/platform/gtk/PlatformKeyboardEventGtk.cpp
|
|
+++ b/Source/WebCore/platform/gtk/PlatformKeyboardEventGtk.cpp
|
|
@@ -37,8 +37,10 @@
|
|
#include "WindowsKeyboardCodes.h"
|
|
#include <gdk/gdk.h>
|
|
#include <gdk/gdkkeysyms.h>
|
|
+#include <wtf/HashMap.h>
|
|
#include <wtf/HexNumber.h>
|
|
#include <wtf/glib/GUniquePtr.h>
|
|
+#include <mutex>
|
|
|
|
namespace WebCore {
|
|
|
|
@@ -1294,6 +1296,246 @@ int PlatformKeyboardEvent::windowsKeyCodeForGdkKeyCode(unsigned keycode)
|
|
|
|
}
|
|
|
|
+static const HashMap<int, unsigned>& gdkToWindowsKeyCodeMap()
|
|
+{
|
|
+ static HashMap<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 HashMap<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/libwpe/PlatformKeyboardEventLibWPE.cpp b/Source/WebCore/platform/libwpe/PlatformKeyboardEventLibWPE.cpp
|
|
index a34dc220bbb9a92b40dfb463e8724e81ac745b2c..8ecedd5dae88469366a619b96960598c1232a32d 100644
|
|
--- a/Source/WebCore/platform/libwpe/PlatformKeyboardEventLibWPE.cpp
|
|
+++ b/Source/WebCore/platform/libwpe/PlatformKeyboardEventLibWPE.cpp
|
|
@@ -30,8 +30,10 @@
|
|
|
|
#include "WindowsKeyboardCodes.h"
|
|
#include <wpe/wpe.h>
|
|
+#include <wtf/HashMap.h>
|
|
#include <wtf/HexNumber.h>
|
|
#include <wtf/text/StringBuilder.h>
|
|
+#include <mutex>
|
|
|
|
namespace WebCore {
|
|
|
|
@@ -1291,6 +1293,246 @@ int PlatformKeyboardEvent::windowsKeyCodeForWPEKeyCode(unsigned keycode)
|
|
return 0;
|
|
}
|
|
|
|
+static const HashMap<int, unsigned>& WPEToWindowsKeyCodeMap()
|
|
+{
|
|
+ static HashMap<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 HashMap<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/network/NetworkStateNotifier.h b/Source/WebCore/platform/network/NetworkStateNotifier.h
|
|
index 87930048f4fd18d6098af7de4da25be532df5931..2bb2afcf9473b0d5d97efbe18dd7b8145bc5f932 100644
|
|
--- a/Source/WebCore/platform/network/NetworkStateNotifier.h
|
|
+++ b/Source/WebCore/platform/network/NetworkStateNotifier.h
|
|
@@ -72,6 +72,7 @@ private:
|
|
#endif
|
|
|
|
Optional<bool> m_isOnLine;
|
|
+ Optional<bool> m_emulatedIsOnLine;
|
|
Vector<WTF::Function<void(bool)>> m_listeners;
|
|
Timer m_updateStateTimer;
|
|
|
|
diff --git a/Source/WebCore/platform/network/cf/SocketStreamHandleImpl.h b/Source/WebCore/platform/network/cf/SocketStreamHandleImpl.h
|
|
index d677280d2b5e7b053a240c155d64bc881f1737bb..1be949e09982b34366d162e6d45ebc51a76dcfb0 100644
|
|
--- a/Source/WebCore/platform/network/cf/SocketStreamHandleImpl.h
|
|
+++ b/Source/WebCore/platform/network/cf/SocketStreamHandleImpl.h
|
|
@@ -47,7 +47,7 @@ class SocketStreamHandleClient;
|
|
|
|
class SocketStreamHandleImpl : public SocketStreamHandle {
|
|
public:
|
|
- static Ref<SocketStreamHandleImpl> create(const URL& url, SocketStreamHandleClient& client, PAL::SessionID sessionID, const String& credentialPartition, SourceApplicationAuditToken&& auditData, const StorageSessionProvider* provider) { return adoptRef(*new SocketStreamHandleImpl(url, client, sessionID, credentialPartition, WTFMove(auditData), provider)); }
|
|
+ static Ref<SocketStreamHandleImpl> create(const URL& url, bool ignoreCertificateErrors, SocketStreamHandleClient& client, PAL::SessionID sessionID, const String& credentialPartition, SourceApplicationAuditToken&& auditData, const StorageSessionProvider* provider) { return adoptRef(*new SocketStreamHandleImpl(url, ignoreCertificateErrors, client, sessionID, credentialPartition, WTFMove(auditData), provider)); }
|
|
|
|
virtual ~SocketStreamHandleImpl();
|
|
|
|
@@ -61,7 +61,7 @@ private:
|
|
Optional<size_t> platformSendInternal(const uint8_t*, size_t);
|
|
bool sendPendingData();
|
|
|
|
- WEBCORE_EXPORT SocketStreamHandleImpl(const URL&, SocketStreamHandleClient&, PAL::SessionID, const String& credentialPartition, SourceApplicationAuditToken&&, const StorageSessionProvider*);
|
|
+ WEBCORE_EXPORT SocketStreamHandleImpl(const URL&, bool ignoreCertificateErrors, SocketStreamHandleClient&, PAL::SessionID, const String& credentialPartition, SourceApplicationAuditToken&&, const StorageSessionProvider*);
|
|
void createStreams();
|
|
void scheduleStreams();
|
|
void chooseProxy();
|
|
@@ -106,6 +106,7 @@ private:
|
|
String m_credentialPartition;
|
|
SourceApplicationAuditToken m_auditData;
|
|
RefPtr<const StorageSessionProvider> m_storageSessionProvider;
|
|
+ bool m_ignoreCertificateErrors { false };
|
|
|
|
StreamBuffer<uint8_t, 1024 * 1024> m_buffer;
|
|
static const unsigned maxBufferSize = 100 * 1024 * 1024;
|
|
diff --git a/Source/WebCore/platform/network/cf/SocketStreamHandleImplCFNet.cpp b/Source/WebCore/platform/network/cf/SocketStreamHandleImplCFNet.cpp
|
|
index 9915f0ceacaf946eb4af2d6b740f7226e344b78d..4382ccde112e3c21892a4dd28fba416a6db90a62 100644
|
|
--- a/Source/WebCore/platform/network/cf/SocketStreamHandleImplCFNet.cpp
|
|
+++ b/Source/WebCore/platform/network/cf/SocketStreamHandleImplCFNet.cpp
|
|
@@ -96,7 +96,7 @@ static inline auto callbacksRunLoopMode()
|
|
#endif
|
|
}
|
|
|
|
-SocketStreamHandleImpl::SocketStreamHandleImpl(const URL& url, SocketStreamHandleClient& client, PAL::SessionID sessionID, const String& credentialPartition, SourceApplicationAuditToken&& auditData, const StorageSessionProvider* provider)
|
|
+SocketStreamHandleImpl::SocketStreamHandleImpl(const URL& url, bool ignoreCertificateErrors, SocketStreamHandleClient& client, PAL::SessionID sessionID, const String& credentialPartition, SourceApplicationAuditToken&& auditData, const StorageSessionProvider* provider)
|
|
: SocketStreamHandle(url, client)
|
|
, m_connectingSubstate(New)
|
|
, m_connectionType(Unknown)
|
|
@@ -104,6 +104,7 @@ SocketStreamHandleImpl::SocketStreamHandleImpl(const URL& url, SocketStreamHandl
|
|
, m_credentialPartition(credentialPartition)
|
|
, m_auditData(WTFMove(auditData))
|
|
, m_storageSessionProvider(provider)
|
|
+ , m_ignoreCertificateErrors(ignoreCertificateErrors)
|
|
{
|
|
LOG(Network, "SocketStreamHandle %p new client %p", this, &m_client);
|
|
|
|
@@ -360,7 +361,7 @@ void SocketStreamHandleImpl::createStreams()
|
|
}
|
|
|
|
if (shouldUseSSL()) {
|
|
- CFBooleanRef validateCertificateChain = DeprecatedGlobalSettings::allowsAnySSLCertificate() ? kCFBooleanFalse : kCFBooleanTrue;
|
|
+ CFBooleanRef validateCertificateChain = m_ignoreCertificateErrors || DeprecatedGlobalSettings::allowsAnySSLCertificate() ? kCFBooleanFalse : kCFBooleanTrue;
|
|
const void* keys[] = {
|
|
kCFStreamSSLPeerName,
|
|
kCFStreamSSLLevel,
|
|
diff --git a/Source/WebCore/platform/network/curl/CookieJarDB.h b/Source/WebCore/platform/network/curl/CookieJarDB.h
|
|
index 7c0ea47ece4ff0d472ce595c91ea1cfa90b25ca7..1c44229a18fe90f6e5e0c0056dddd09acadfe49b 100644
|
|
--- a/Source/WebCore/platform/network/curl/CookieJarDB.h
|
|
+++ b/Source/WebCore/platform/network/curl/CookieJarDB.h
|
|
@@ -72,7 +72,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 1b15af01bcc0eab910fc3b9e8a8d463b7c668519..c11f0b310810fad74eacbd2c41ff16c2507111f1 100644
|
|
--- a/Source/WebCore/platform/network/curl/CurlStream.cpp
|
|
+++ b/Source/WebCore/platform/network/curl/CurlStream.cpp
|
|
@@ -33,7 +33,7 @@
|
|
|
|
namespace WebCore {
|
|
|
|
-CurlStream::CurlStream(CurlStreamScheduler& scheduler, CurlStreamID streamID, URL&& url)
|
|
+CurlStream::CurlStream(CurlStreamScheduler& scheduler, CurlStreamID streamID, bool ignoreCertificateErrors, URL&& url)
|
|
: m_scheduler(scheduler)
|
|
, m_streamID(streamID)
|
|
{
|
|
@@ -45,6 +45,9 @@ CurlStream::CurlStream(CurlStreamScheduler& scheduler, CurlStreamID streamID, UR
|
|
m_curlHandle->setUrl(WTFMove(url));
|
|
|
|
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 313b0173da5cd404a1e3fcad9573b8ff7c3abd4f..020980a0f61d47e8c7929bfaab2f8394d014766d 100644
|
|
--- a/Source/WebCore/platform/network/curl/CurlStream.h
|
|
+++ b/Source/WebCore/platform/network/curl/CurlStream.h
|
|
@@ -50,12 +50,12 @@ public:
|
|
virtual void didFail(CurlStreamID, CURLcode) = 0;
|
|
};
|
|
|
|
- static std::unique_ptr<CurlStream> create(CurlStreamScheduler& scheduler, CurlStreamID streamID, URL&& url)
|
|
+ static std::unique_ptr<CurlStream> create(CurlStreamScheduler& scheduler, CurlStreamID streamID, bool ignoreCertificateErrors, URL&& url)
|
|
{
|
|
- return WTF::makeUnique<CurlStream>(scheduler, streamID, WTFMove(url));
|
|
+ return WTF::makeUnique<CurlStream>(scheduler, streamID, ignoreCertificateErrors, WTFMove(url));
|
|
}
|
|
|
|
- CurlStream(CurlStreamScheduler&, CurlStreamID, URL&&);
|
|
+ CurlStream(CurlStreamScheduler&, CurlStreamID, bool ignoreCertificateErrors, URL&&);
|
|
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 3fb8759984aa31a7d44baa2f69afe2fee461ea4f..bb7ad47477d97fa1eaff5d3da6b9a3705ff1e32f 100644
|
|
--- a/Source/WebCore/platform/network/curl/CurlStreamScheduler.cpp
|
|
+++ b/Source/WebCore/platform/network/curl/CurlStreamScheduler.cpp
|
|
@@ -40,7 +40,7 @@ CurlStreamScheduler::~CurlStreamScheduler()
|
|
ASSERT(isMainThread());
|
|
}
|
|
|
|
-CurlStreamID CurlStreamScheduler::createStream(const URL& url, CurlStream::Client& client)
|
|
+CurlStreamID CurlStreamScheduler::createStream(const URL& url, bool ignoreCertificateErrors, CurlStream::Client& client)
|
|
{
|
|
ASSERT(isMainThread());
|
|
|
|
@@ -51,8 +51,8 @@ CurlStreamID CurlStreamScheduler::createStream(const URL& url, CurlStream::Clien
|
|
auto streamID = m_currentStreamID;
|
|
m_clientList.add(streamID, &client);
|
|
|
|
- callOnWorkerThread([this, streamID, url = url.isolatedCopy()]() mutable {
|
|
- m_streamList.add(streamID, CurlStream::create(*this, streamID, WTFMove(url)));
|
|
+ callOnWorkerThread([this, streamID, ignoreCertificateErrors, url = url.isolatedCopy()]() mutable {
|
|
+ m_streamList.add(streamID, CurlStream::create(*this, streamID, ignoreCertificateErrors, WTFMove(url)));
|
|
});
|
|
|
|
return streamID;
|
|
diff --git a/Source/WebCore/platform/network/curl/CurlStreamScheduler.h b/Source/WebCore/platform/network/curl/CurlStreamScheduler.h
|
|
index 7d881206c9689f433227969c9b7f9ff268bdaaed..2e8118f11f87fa5f32adcedc165aec8220b36d58 100644
|
|
--- a/Source/WebCore/platform/network/curl/CurlStreamScheduler.h
|
|
+++ b/Source/WebCore/platform/network/curl/CurlStreamScheduler.h
|
|
@@ -38,7 +38,7 @@ public:
|
|
CurlStreamScheduler();
|
|
virtual ~CurlStreamScheduler();
|
|
|
|
- CurlStreamID createStream(const URL&, CurlStream::Client&);
|
|
+ CurlStreamID createStream(const URL&, bool ignoreCertificateErrors, CurlStream::Client&);
|
|
void destroyStream(CurlStreamID);
|
|
void send(CurlStreamID, UniqueArray<uint8_t>&&, size_t);
|
|
|
|
diff --git a/Source/WebCore/platform/network/curl/SocketStreamHandleImpl.h b/Source/WebCore/platform/network/curl/SocketStreamHandleImpl.h
|
|
index fad4ef9198118f5e6e5ed7d3c14b99e574593451..a2d59843896f252fccdddbb94c5275eec6300f1b 100644
|
|
--- a/Source/WebCore/platform/network/curl/SocketStreamHandleImpl.h
|
|
+++ b/Source/WebCore/platform/network/curl/SocketStreamHandleImpl.h
|
|
@@ -44,7 +44,7 @@ class StorageSessionProvider;
|
|
|
|
class SocketStreamHandleImpl : public SocketStreamHandle, public CurlStream::Client {
|
|
public:
|
|
- static Ref<SocketStreamHandleImpl> create(const URL& url, SocketStreamHandleClient& client, PAL::SessionID, const String&, SourceApplicationAuditToken&&, const StorageSessionProvider* provider) { return adoptRef(*new SocketStreamHandleImpl(url, client, provider)); }
|
|
+ static Ref<SocketStreamHandleImpl> create(const URL& url, bool ignoreCertificateErrors, SocketStreamHandleClient& client, PAL::SessionID, const String&, SourceApplicationAuditToken&&, const StorageSessionProvider* provider) { return adoptRef(*new SocketStreamHandleImpl(url, ignoreCertificateErrors, client, provider)); }
|
|
|
|
virtual ~SocketStreamHandleImpl();
|
|
|
|
@@ -53,7 +53,7 @@ public:
|
|
WEBCORE_EXPORT void platformClose() final;
|
|
|
|
private:
|
|
- WEBCORE_EXPORT SocketStreamHandleImpl(const URL&, SocketStreamHandleClient&, const StorageSessionProvider*);
|
|
+ WEBCORE_EXPORT SocketStreamHandleImpl(const URL&, bool ignoreCertificateErrors, SocketStreamHandleClient&, const StorageSessionProvider*);
|
|
|
|
size_t bufferedAmount() final;
|
|
Optional<size_t> platformSendInternal(const uint8_t*, size_t);
|
|
diff --git a/Source/WebCore/platform/network/curl/SocketStreamHandleImplCurl.cpp b/Source/WebCore/platform/network/curl/SocketStreamHandleImplCurl.cpp
|
|
index cae8c43d60fcf6a3d69c58a7436516f923d227cb..e6b03f378929abbd4437f8507ea2f6c563edcff7 100644
|
|
--- a/Source/WebCore/platform/network/curl/SocketStreamHandleImplCurl.cpp
|
|
+++ b/Source/WebCore/platform/network/curl/SocketStreamHandleImplCurl.cpp
|
|
@@ -43,7 +43,7 @@
|
|
|
|
namespace WebCore {
|
|
|
|
-SocketStreamHandleImpl::SocketStreamHandleImpl(const URL& url, SocketStreamHandleClient& client, const StorageSessionProvider* provider)
|
|
+SocketStreamHandleImpl::SocketStreamHandleImpl(const URL& url, bool ignoreCertificateErrors, SocketStreamHandleClient& client, const StorageSessionProvider* provider)
|
|
: SocketStreamHandle(url, client)
|
|
, m_storageSessionProvider(provider)
|
|
, m_scheduler(CurlContext::singleton().streamScheduler())
|
|
@@ -52,7 +52,7 @@ SocketStreamHandleImpl::SocketStreamHandleImpl(const URL& url, SocketStreamHandl
|
|
if (m_url.protocolIs("wss") && DeprecatedGlobalSettings::allowsAnySSLCertificate())
|
|
CurlContext::singleton().sslHandle().setIgnoreSSLErrors(true);
|
|
|
|
- m_streamID = m_scheduler.createStream(m_url, *this);
|
|
+ m_streamID = m_scheduler.createStream(m_url, ignoreCertificateErrors, *this);
|
|
}
|
|
|
|
SocketStreamHandleImpl::~SocketStreamHandleImpl()
|
|
diff --git a/Source/WebCore/platform/network/soup/SocketStreamHandleImpl.h b/Source/WebCore/platform/network/soup/SocketStreamHandleImpl.h
|
|
index 3ecf866005da6da9cec7c7930e6a4f93cb39d6e0..d81dc9ac0c433e00ab4ad73e206856098ab9230e 100644
|
|
--- a/Source/WebCore/platform/network/soup/SocketStreamHandleImpl.h
|
|
+++ b/Source/WebCore/platform/network/soup/SocketStreamHandleImpl.h
|
|
@@ -47,7 +47,7 @@ class StorageSessionProvider;
|
|
|
|
class SocketStreamHandleImpl final : public SocketStreamHandle {
|
|
public:
|
|
- static Ref<SocketStreamHandleImpl> create(const URL&, SocketStreamHandleClient&, PAL::SessionID, const String&, SourceApplicationAuditToken&&, const StorageSessionProvider*)
|
|
+ static Ref<SocketStreamHandleImpl> create(const URL&, bool, SocketStreamHandleClient&, PAL::SessionID, const String&, SourceApplicationAuditToken&&, const StorageSessionProvider*)
|
|
{
|
|
RELEASE_ASSERT_NOT_REACHED();
|
|
}
|
|
diff --git a/Source/WebCore/platform/win/KeyEventWin.cpp b/Source/WebCore/platform/win/KeyEventWin.cpp
|
|
index 44737686187a06a92c408ea60b63a48ac8481334..c754a763688b52e7ddd47493296ef9b0c6adc527 100644
|
|
--- a/Source/WebCore/platform/win/KeyEventWin.cpp
|
|
+++ b/Source/WebCore/platform/win/KeyEventWin.cpp
|
|
@@ -239,10 +239,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::RawKeyDown) {
|
|
+ m_text = String();
|
|
+ m_unmodifiedText = String();
|
|
+ } else {
|
|
+ m_keyIdentifier = String();
|
|
+ m_windowsVirtualKeyCode = 0;
|
|
+ }
|
|
}
|
|
|
|
bool PlatformKeyboardEvent::currentCapsLockState()
|
|
diff --git a/Source/WebCore/rendering/RenderTextControl.cpp b/Source/WebCore/rendering/RenderTextControl.cpp
|
|
index 7ac6e023a8cfa1ece6f00f2390743a6225f3229a..aec8586dd04121151df849f631c68e9150c053ce 100644
|
|
--- a/Source/WebCore/rendering/RenderTextControl.cpp
|
|
+++ b/Source/WebCore/rendering/RenderTextControl.cpp
|
|
@@ -217,13 +217,13 @@ void RenderTextControl::layoutExcludedChildren(bool relayoutChildren)
|
|
}
|
|
}
|
|
|
|
-#if PLATFORM(IOS_FAMILY)
|
|
bool RenderTextControl::canScroll() const
|
|
{
|
|
auto innerText = innerTextElement();
|
|
return innerText && innerText->renderer() && innerText->renderer()->hasOverflowClip();
|
|
}
|
|
|
|
+#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 69b193b1ff28bf2d0e58be6ae3152da8d9229a90..9b8327958cbc21e46a5720f558156b00e1c289a8 100644
|
|
--- a/Source/WebCore/rendering/RenderTextControl.h
|
|
+++ b/Source/WebCore/rendering/RenderTextControl.h
|
|
@@ -36,9 +36,9 @@ public:
|
|
|
|
WEBCORE_EXPORT HTMLTextFormControlElement& textFormControlElement() 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/WebKit/NetworkProcess/NetworkProcess.cpp b/Source/WebKit/NetworkProcess/NetworkProcess.cpp
|
|
index 3a139c89100eba218cbfffadc2e3dfa86217f163..b2d71bedddb756e87f97f60c2b7bbe531adfa217 100644
|
|
--- a/Source/WebKit/NetworkProcess/NetworkProcess.cpp
|
|
+++ b/Source/WebKit/NetworkProcess/NetworkProcess.cpp
|
|
@@ -26,7 +26,6 @@
|
|
|
|
#include "config.h"
|
|
#include "NetworkProcess.h"
|
|
-
|
|
#include "ArgumentCoders.h"
|
|
#include "Attachment.h"
|
|
#include "AuthenticationManager.h"
|
|
@@ -551,6 +550,41 @@ void NetworkProcess::destroySession(PAL::SessionID sessionID)
|
|
#endif
|
|
}
|
|
|
|
+void NetworkProcess::getAllCookies(PAL::SessionID sessionID, CompletionHandler<void(Vector<WebCore::Cookie>&&)>&& completionHandler)
|
|
+{
|
|
+ if (auto* networkStorageSession = storageSession(sessionID)) {
|
|
+ completionHandler(networkStorageSession->getAllCookies());
|
|
+ return;
|
|
+ }
|
|
+ completionHandler({ });
|
|
+}
|
|
+
|
|
+void NetworkProcess::setCookies(PAL::SessionID sessionID, Vector<WebCore::Cookie> cookies, CompletionHandler<void(bool)>&& completionHandler) {
|
|
+ if (auto* networkStorageSession = storageSession(sessionID)) {
|
|
+ for (auto cookie : cookies)
|
|
+ networkStorageSession->setCookie(cookie);
|
|
+ completionHandler(true);
|
|
+ return;
|
|
+ }
|
|
+ completionHandler(false);
|
|
+}
|
|
+
|
|
+void NetworkProcess::deleteAllCookies(PAL::SessionID sessionID, CompletionHandler<void(bool)>&& completionHandler)
|
|
+{
|
|
+ if (auto* networkStorageSession = storageSession(sessionID)) {
|
|
+ networkStorageSession->deleteAllCookies();
|
|
+ completionHandler(true);
|
|
+ return;
|
|
+ }
|
|
+ completionHandler(false);
|
|
+}
|
|
+
|
|
+void NetworkProcess::setIgnoreCertificateErrors(PAL::SessionID sessionID, bool ignore)
|
|
+{
|
|
+ if (auto* networkSession = this->networkSession(sessionID))
|
|
+ networkSession->setIgnoreCertificateErrors(ignore);
|
|
+}
|
|
+
|
|
#if ENABLE(RESOURCE_LOAD_STATISTICS)
|
|
void NetworkProcess::dumpResourceLoadStatistics(PAL::SessionID sessionID, CompletionHandler<void(String)>&& completionHandler)
|
|
{
|
|
diff --git a/Source/WebKit/NetworkProcess/NetworkProcess.h b/Source/WebKit/NetworkProcess/NetworkProcess.h
|
|
index d1bfd2045a82227250150d2075e84d7e02de0e38..a03827972e8c3aa264aba3cb90978a14799c173f 100644
|
|
--- a/Source/WebKit/NetworkProcess/NetworkProcess.h
|
|
+++ b/Source/WebKit/NetworkProcess/NetworkProcess.h
|
|
@@ -77,6 +77,7 @@ class SessionID;
|
|
|
|
namespace WebCore {
|
|
class CertificateInfo;
|
|
+struct Cookie;
|
|
class CurlProxySettings;
|
|
class ProtectionSpace;
|
|
class StorageQuotaManager;
|
|
@@ -204,6 +205,11 @@ public:
|
|
|
|
void addWebsiteDataStore(WebsiteDataStoreParameters&&);
|
|
|
|
+ void getAllCookies(PAL::SessionID, CompletionHandler<void(Vector<WebCore::Cookie>&&)>&&);
|
|
+ void setCookies(PAL::SessionID, Vector<WebCore::Cookie>, CompletionHandler<void(bool)>&&);
|
|
+ void deleteAllCookies(PAL::SessionID, CompletionHandler<void(bool)>&&);
|
|
+ void setIgnoreCertificateErrors(PAL::SessionID, bool);
|
|
+
|
|
#if ENABLE(RESOURCE_LOAD_STATISTICS)
|
|
void clearPrevalentResource(PAL::SessionID, const RegistrableDomain&, CompletionHandler<void()>&&);
|
|
void clearUserInteraction(PAL::SessionID, const RegistrableDomain&, CompletionHandler<void()>&&);
|
|
diff --git a/Source/WebKit/NetworkProcess/NetworkProcess.messages.in b/Source/WebKit/NetworkProcess/NetworkProcess.messages.in
|
|
index d0c499283d70a2b8e4da6974b676ead6f601b194..adf20ce785481e2fbf4f7be7e8b6abe4d7dcde34 100644
|
|
--- a/Source/WebKit/NetworkProcess/NetworkProcess.messages.in
|
|
+++ b/Source/WebKit/NetworkProcess/NetworkProcess.messages.in
|
|
@@ -81,6 +81,11 @@ messages -> NetworkProcess LegacyReceiver {
|
|
|
|
PreconnectTo(PAL::SessionID sessionID, WebKit::WebPageProxyIdentifier webPageProxyID, WebCore::PageIdentifier webPageID, URL url, String userAgent, enum:uint8_t WebCore::StoredCredentialsPolicy storedCredentialsPolicy, enum:bool Optional<WebKit::NavigatingToAppBoundDomain> isNavigatingToAppBoundDomain);
|
|
|
|
+ GetAllCookies(PAL::SessionID sessionID) -> (Vector<WebCore::Cookie> cookies) Async
|
|
+ SetCookies(PAL::SessionID sessionID, Vector<WebCore::Cookie> cookies) -> (bool success) Async
|
|
+ DeleteAllCookies(PAL::SessionID sessionID) -> (bool success) Async
|
|
+ SetIgnoreCertificateErrors(PAL::SessionID sessionID, bool ignoreTLSErrors)
|
|
+
|
|
#if ENABLE(RESOURCE_LOAD_STATISTICS)
|
|
ClearPrevalentResource(PAL::SessionID sessionID, WebCore::RegistrableDomain resourceDomain) -> () Async
|
|
ClearUserInteraction(PAL::SessionID sessionID, WebCore::RegistrableDomain resourceDomain) -> () Async
|
|
diff --git a/Source/WebKit/NetworkProcess/NetworkSession.h b/Source/WebKit/NetworkProcess/NetworkSession.h
|
|
index c2d4fc570a5fe9da40210adec93819f2485ef959..9e43931d2734c8699ab18ed151134f216b737b4d 100644
|
|
--- a/Source/WebKit/NetworkProcess/NetworkSession.h
|
|
+++ b/Source/WebKit/NetworkProcess/NetworkSession.h
|
|
@@ -145,6 +145,9 @@ public:
|
|
|
|
bool isStaleWhileRevalidateEnabled() const { return m_isStaleWhileRevalidateEnabled; }
|
|
|
|
+ void setIgnoreCertificateErrors(bool ignore) { m_ignoreCertificateErrors = ignore; }
|
|
+ bool ignoreCertificateErrors() { return m_ignoreCertificateErrors; }
|
|
+
|
|
#if ENABLE(SERVICE_WORKER)
|
|
void addSoftUpdateLoader(std::unique_ptr<ServiceWorkerSoftUpdateLoader>&& loader) { m_softUpdateLoaders.add(WTFMove(loader)); }
|
|
void removeSoftUpdateLoader(ServiceWorkerSoftUpdateLoader* loader) { m_softUpdateLoaders.remove(loader); }
|
|
@@ -177,6 +180,7 @@ protected:
|
|
#endif
|
|
bool m_isStaleWhileRevalidateEnabled { false };
|
|
UniqueRef<AdClickAttributionManager> m_adClickAttribution;
|
|
+ bool m_ignoreCertificateErrors { false };
|
|
|
|
HashSet<Ref<NetworkResourceLoader>> m_keptAliveLoads;
|
|
|
|
diff --git a/Source/WebKit/NetworkProcess/NetworkSocketStream.cpp b/Source/WebKit/NetworkProcess/NetworkSocketStream.cpp
|
|
index 5b489cc538f7c071510106c58f5c094ec9a8e1b8..20d0718eb896bcd9f97fd80572844a5727d84e40 100644
|
|
--- a/Source/WebKit/NetworkProcess/NetworkSocketStream.cpp
|
|
+++ b/Source/WebKit/NetworkProcess/NetworkSocketStream.cpp
|
|
@@ -44,7 +44,7 @@ Ref<NetworkSocketStream> NetworkSocketStream::create(NetworkProcess& networkProc
|
|
NetworkSocketStream::NetworkSocketStream(NetworkProcess& networkProcess, URL&& url, PAL::SessionID sessionID, const String& credentialPartition, WebSocketIdentifier identifier, IPC::Connection& connection, SourceApplicationAuditToken&& auditData)
|
|
: m_identifier(identifier)
|
|
, m_connection(connection)
|
|
- , m_impl(SocketStreamHandleImpl::create(url, *this, sessionID, credentialPartition, WTFMove(auditData), NetworkStorageSessionProvider::create(networkProcess, sessionID).ptr()))
|
|
+ , m_impl(SocketStreamHandleImpl::create(url, networkProcess.networkSession(sessionID)->ignoreCertificateErrors(), *this, sessionID, credentialPartition, WTFMove(auditData), NetworkStorageSessionProvider::create(networkProcess, sessionID).ptr()))
|
|
, m_delayFailTimer(*this, &NetworkSocketStream::sendDelayedFailMessage)
|
|
{
|
|
}
|
|
diff --git a/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm b/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm
|
|
index dfb18b92be6cab7178014e4fad5b1773fe9dcd64..f167baf80bc33da5f1745431391609a2e1db37b5 100644
|
|
--- a/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm
|
|
+++ b/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm
|
|
@@ -661,7 +661,7 @@ static inline void processServerTrustEvaluation(NetworkSessionCocoa& session, Se
|
|
NegotiatedLegacyTLS negotiatedLegacyTLS = NegotiatedLegacyTLS::No;
|
|
|
|
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
|
|
- if (NetworkSessionCocoa::allowsSpecificHTTPSCertificateForHost(challenge))
|
|
+ if (sessionCocoa->ignoreCertificateErrors() || sessionCocoa->allowsSpecificHTTPSCertificateForHost(challenge))
|
|
return completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]);
|
|
|
|
#if HAVE(TLS_PROTOCOL_VERSION_T)
|
|
diff --git a/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.cpp b/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.cpp
|
|
index 27f8ef54e561d6c3e812f8d4dc4cc133634fb4eb..9eb502facc84bec0b1cd5cf27b260091e94d8d11 100644
|
|
--- a/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.cpp
|
|
+++ b/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.cpp
|
|
@@ -26,9 +26,13 @@
|
|
#include "config.h"
|
|
#include "NetworkDataTaskCurl.h"
|
|
|
|
+#include "APIError.h"
|
|
#include "AuthenticationChallengeDisposition.h"
|
|
#include "AuthenticationManager.h"
|
|
+#include "DataReference.h"
|
|
+#include "Download.h"
|
|
#include "NetworkSessionCurl.h"
|
|
+#include "NetworkProcess.h"
|
|
#include <WebCore/AuthenticationChallenge.h>
|
|
#include <WebCore/CookieJar.h>
|
|
#include <WebCore/CurlRequest.h>
|
|
@@ -39,6 +43,8 @@
|
|
#include <WebCore/SameSiteInfo.h>
|
|
#include <WebCore/ShouldRelaxThirdPartyCookieBlocking.h>
|
|
#include <WebCore/SynchronousLoaderClient.h>
|
|
+#include <WebCore/TextEncoding.h>
|
|
+#include <wtf/FileSystem.h>
|
|
|
|
namespace WebKit {
|
|
|
|
@@ -78,6 +84,8 @@ NetworkDataTaskCurl::NetworkDataTaskCurl(NetworkSession& session, NetworkDataTas
|
|
m_curlRequest->setUserPass(m_initialCredential.user(), m_initialCredential.password());
|
|
m_curlRequest->setAuthenticationScheme(ProtectionSpaceAuthenticationSchemeHTTPBasic);
|
|
}
|
|
+ if (m_session->ignoreCertificateErrors())
|
|
+ m_curlRequest->disableServerTrustEvaluation();
|
|
m_curlRequest->setStartTime(m_startTime);
|
|
m_curlRequest->start();
|
|
}
|
|
@@ -179,7 +187,12 @@ void NetworkDataTaskCurl::curlDidReceiveBuffer(CurlRequest&, Ref<SharedBuffer>&&
|
|
auto protectedThis = makeRef(*this);
|
|
if (state() == State::Canceling || state() == State::Completed || (!m_client && !isDownload()))
|
|
return;
|
|
-
|
|
+ if (isDownload()) {
|
|
+ FileSystem::PlatformFileHandle file = FileSystem::openFile(m_pendingDownloadLocation, FileSystem::FileOpenMode::Write);
|
|
+ FileSystem::writeToFile(file, buffer->data(), buffer->size());
|
|
+ FileSystem::closeFile(file);
|
|
+ return;
|
|
+ }
|
|
m_client->didReceiveData(WTFMove(buffer));
|
|
}
|
|
|
|
@@ -188,6 +201,12 @@ void NetworkDataTaskCurl::curlDidComplete(CurlRequest&, NetworkLoadMetrics&& net
|
|
if (state() == State::Canceling || state() == State::Completed || (!m_client && !isDownload()))
|
|
return;
|
|
|
|
+ if (isDownload()) {
|
|
+ auto* download = m_session->networkProcess().downloadManager().download(m_pendingDownloadID);
|
|
+ ASSERT(download);
|
|
+ download->didFinish();
|
|
+ return;
|
|
+ }
|
|
m_client->didCompleteWithError({ }, WTFMove(networkLoadMetrics));
|
|
}
|
|
|
|
@@ -201,6 +220,13 @@ void NetworkDataTaskCurl::curlDidFailWithError(CurlRequest& request, ResourceErr
|
|
return;
|
|
}
|
|
|
|
+ if (isDownload()) {
|
|
+ auto* download = m_session->networkProcess().downloadManager().download(m_pendingDownloadID);
|
|
+ ASSERT(download);
|
|
+ download->didFail(resourceError, IPC::DataReference());
|
|
+ return;
|
|
+ }
|
|
+
|
|
m_client->didCompleteWithError(resourceError);
|
|
}
|
|
|
|
@@ -238,6 +264,18 @@ void NetworkDataTaskCurl::invokeDidReceiveResponse()
|
|
case PolicyAction::Ignore:
|
|
invalidateAndCancel();
|
|
break;
|
|
+ case PolicyAction::Download: {
|
|
+ FileSystem::deleteFile(m_pendingDownloadLocation);
|
|
+ auto& downloadManager = m_session->networkProcess().downloadManager();
|
|
+ auto download = makeUnique<Download>(downloadManager, m_pendingDownloadID, *this, *m_session, suggestedFilename());
|
|
+ auto* downloadPtr = download.get();
|
|
+ downloadManager.dataTaskBecameDownloadTask(m_pendingDownloadID, WTFMove(download));
|
|
+ downloadPtr->didCreateDestination(m_pendingDownloadLocation);
|
|
+
|
|
+ if (m_curlRequest)
|
|
+ m_curlRequest->completeDidReceiveResponse();
|
|
+ break;
|
|
+ }
|
|
default:
|
|
notImplemented();
|
|
break;
|
|
@@ -320,6 +358,8 @@ void NetworkDataTaskCurl::willPerformHTTPRedirection()
|
|
m_curlRequest->setUserPass(m_initialCredential.user(), m_initialCredential.password());
|
|
m_curlRequest->setAuthenticationScheme(ProtectionSpaceAuthenticationSchemeHTTPBasic);
|
|
}
|
|
+ if (m_session->ignoreCertificateErrors())
|
|
+ m_curlRequest->disableServerTrustEvaluation();
|
|
m_curlRequest->setStartTime(m_startTime);
|
|
m_curlRequest->start();
|
|
|
|
@@ -503,4 +543,16 @@ bool NetworkDataTaskCurl::isThirdPartyRequest(const WebCore::ResourceRequest& re
|
|
return !WebCore::areRegistrableDomainsEqual(request.url(), request.firstPartyForCookies());
|
|
}
|
|
|
|
+String NetworkDataTaskCurl::suggestedFilename() const
|
|
+{
|
|
+ if (!m_suggestedFilename.isEmpty())
|
|
+ return m_suggestedFilename;
|
|
+
|
|
+ String suggestedFilename = m_response.suggestedFilename();
|
|
+ if (!suggestedFilename.isEmpty())
|
|
+ return suggestedFilename;
|
|
+
|
|
+ return decodeURLEscapeSequences(m_response.url().lastPathComponent());
|
|
+}
|
|
+
|
|
} // namespace WebKit
|
|
diff --git a/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.h b/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.h
|
|
index 4c120d6830582861432e5e58fba5707206350cd0..3509c62ac2c970fdcf78db2503c0cc4259f56dbd 100644
|
|
--- a/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.h
|
|
+++ b/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.h
|
|
@@ -85,6 +85,7 @@ private:
|
|
|
|
void appendCookieHeader(WebCore::ResourceRequest&);
|
|
void handleCookieHeaders(const WebCore::ResourceRequest&, const WebCore::CurlResponse&);
|
|
+ String suggestedFilename() const override;
|
|
|
|
bool isThirdPartyRequest(const WebCore::ResourceRequest&);
|
|
bool shouldBlockCookies(const WebCore::ResourceRequest&);
|
|
diff --git a/Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.cpp b/Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.cpp
|
|
index c99bcb07366b88ceb0c4f2a8382750f0e2d99b50..8e069a213abfaa4d9be678184eccd293b7f8f94a 100644
|
|
--- a/Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.cpp
|
|
+++ b/Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.cpp
|
|
@@ -444,6 +444,8 @@ bool NetworkDataTaskSoup::tlsConnectionAcceptCertificate(GTlsCertificate* certif
|
|
{
|
|
ASSERT(m_soupRequest);
|
|
URL url = soupURIToURL(soup_request_get_uri(m_soupRequest.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 66ff36eec2db1699a9bc2bce8fe0d5124ce19ed2..cc2bda254ce55d574c36b07dbaf95093c782e3a0 100644
|
|
--- a/Source/WebKit/NetworkProcess/soup/NetworkSessionSoup.cpp
|
|
+++ b/Source/WebKit/NetworkProcess/soup/NetworkSessionSoup.cpp
|
|
@@ -112,6 +112,11 @@ static gboolean webSocketAcceptCertificateCallback(GTlsConnection* connection, G
|
|
return !session->soupNetworkSession().checkTLSErrors(soupURIToURL(soup_message_get_uri(soupMessage)), certificate, errors);
|
|
}
|
|
|
|
+static gboolean webSocketAcceptCertificateCallbackIgnoreTLSErrors(GTlsConnection* connection, GTlsCertificate* certificate, GTlsCertificateFlags errors, NetworkSessionSoup* session)
|
|
+{
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
static void webSocketMessageNetworkEventCallback(SoupMessage* soupMessage, GSocketClientEvent event, GIOStream* connection, NetworkSessionSoup* session)
|
|
{
|
|
if (event != G_SOCKET_CLIENT_TLS_HANDSHAKING)
|
|
@@ -121,6 +126,15 @@ static void webSocketMessageNetworkEventCallback(SoupMessage* soupMessage, GSock
|
|
g_signal_connect(connection, "accept-certificate", G_CALLBACK(webSocketAcceptCertificateCallback), session);
|
|
}
|
|
|
|
+static void webSocketMessageNetworkEventCallbackIgnoreTLSErrors(SoupMessage* soupMessage, GSocketClientEvent event, GIOStream* connection)
|
|
+{
|
|
+ if (event != G_SOCKET_CLIENT_TLS_HANDSHAKING)
|
|
+ return;
|
|
+
|
|
+ g_object_set_data(G_OBJECT(connection), "wk-soup-message", soupMessage);
|
|
+ g_signal_connect(connection, "accept-certificate", G_CALLBACK(webSocketAcceptCertificateCallbackIgnoreTLSErrors), soupMessage);
|
|
+}
|
|
+
|
|
std::unique_ptr<WebSocketTask> NetworkSessionSoup::createWebSocketTask(NetworkSocketChannel& channel, const ResourceRequest& request, const String& protocol)
|
|
{
|
|
GUniquePtr<SoupURI> soupURI = request.createSoupURI();
|
|
@@ -129,8 +143,12 @@ std::unique_ptr<WebSocketTask> NetworkSessionSoup::createWebSocketTask(NetworkSo
|
|
|
|
GRefPtr<SoupMessage> soupMessage = adoptGRef(soup_message_new_from_uri(SOUP_METHOD_GET, soupURI.get()));
|
|
request.updateSoupMessage(soupMessage.get(), blobRegistry());
|
|
- if (request.url().protocolIs("wss"))
|
|
- g_signal_connect(soupMessage.get(), "network-event", G_CALLBACK(webSocketMessageNetworkEventCallback), this);
|
|
+ if (request.url().protocolIs("wss")) {
|
|
+ if (ignoreCertificateErrors())
|
|
+ g_signal_connect(soupMessage.get(), "network-event", G_CALLBACK(webSocketMessageNetworkEventCallbackIgnoreTLSErrors), this);
|
|
+ else
|
|
+ g_signal_connect(soupMessage.get(), "network-event", G_CALLBACK(webSocketMessageNetworkEventCallback), this);
|
|
+ }
|
|
return makeUnique<WebSocketTask>(channel, soupSession(), soupMessage.get(), protocol);
|
|
}
|
|
|
|
diff --git a/Source/WebKit/PlatformGTK.cmake b/Source/WebKit/PlatformGTK.cmake
|
|
index 715d38d76b891489ef95a74e31389b8844ebf102..d86a1c3cdee68b5646a109d9bf56056634c54cb2 100644
|
|
--- a/Source/WebKit/PlatformGTK.cmake
|
|
+++ b/Source/WebKit/PlatformGTK.cmake
|
|
@@ -444,6 +444,9 @@ list(APPEND WebKit_SYSTEM_INCLUDE_DIRECTORIES
|
|
${GSTREAMER_PBUTILS_INCLUDE_DIRS}
|
|
${GTK_INCLUDE_DIRS}
|
|
${LIBSOUP_INCLUDE_DIRS}
|
|
+# Playwright begin
|
|
+ ${LIBVPX_INCLUDE_DIRS}
|
|
+# Playwright end
|
|
)
|
|
|
|
if (USE_WPE_RENDERER)
|
|
@@ -497,9 +500,18 @@ 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 ()
|
|
|
|
+# 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(WebKit2GTK_ENUM_GENERATION_HEADERS ${WebKit2GTK_INSTALLED_HEADERS})
|
|
list(REMOVE_ITEM WebKit2GTK_ENUM_GENERATION_HEADERS ${DERIVED_SOURCES_WEBKIT2GTK_API_DIR}/WebKitEnumTypes.h)
|
|
diff --git a/Source/WebKit/PlatformWPE.cmake b/Source/WebKit/PlatformWPE.cmake
|
|
index a0d83b7d0a54da2e9c9c39b56473743ae48fa9b4..d3b097c89887fb69d374d904691390594c2acd88 100644
|
|
--- a/Source/WebKit/PlatformWPE.cmake
|
|
+++ b/Source/WebKit/PlatformWPE.cmake
|
|
@@ -257,6 +257,7 @@ list(APPEND WebKit_INCLUDE_DIRECTORIES
|
|
"${WEBKIT_DIR}/UIProcess/API/wpe"
|
|
"${WEBKIT_DIR}/UIProcess/CoordinatedGraphics"
|
|
"${WEBKIT_DIR}/UIProcess/geoclue"
|
|
+ "${WEBKIT_DIR}/UIProcess/glib"
|
|
"${WEBKIT_DIR}/UIProcess/gstreamer"
|
|
"${WEBKIT_DIR}/UIProcess/linux"
|
|
"${WEBKIT_DIR}/UIProcess/soup"
|
|
@@ -281,8 +282,17 @@ 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
|
|
Cairo::Cairo
|
|
Freetype::Freetype
|
|
diff --git a/Source/WebKit/PlatformWin.cmake b/Source/WebKit/PlatformWin.cmake
|
|
index 6f057c93c9124a7dd62fab0c82bf1991a426ff0d..b2ade07cb352b29efb6f09c520949a7440cdce9f 100644
|
|
--- a/Source/WebKit/PlatformWin.cmake
|
|
+++ b/Source/WebKit/PlatformWin.cmake
|
|
@@ -59,8 +59,12 @@ list(APPEND WebKit_SOURCES
|
|
|
|
UIProcess/WebsiteData/win/WebsiteDataStoreWin.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
|
|
@@ -117,6 +121,63 @@ list(APPEND WebKit_INCLUDE_DIRECTORIES
|
|
"${WEBKIT_DIR}/win"
|
|
)
|
|
|
|
+# 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"
|
|
+)
|
|
+
|
|
+list(APPEND WebKit_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_win.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/convert.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/convert_argb.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/convert_from.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/convert_from_argb.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/compare_neon.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/compare_neon64.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/rotate.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_common.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/rotate_gcc.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/rotate_neon.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/rotate_neon64.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_neon.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/row_neon64.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/row_win.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/scale.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_common.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/scale_gcc.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/scale_neon.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/scale_neon64.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/scale_win.cc"
|
|
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/video_common.cc"
|
|
+)
|
|
+# Playwright end
|
|
+
|
|
set(WebKitCommonIncludeDirectories ${WebKit_INCLUDE_DIRECTORIES})
|
|
set(WebKitCommonSystemIncludeDirectories ${WebKit_SYSTEM_INCLUDE_DIRECTORIES})
|
|
|
|
@@ -170,6 +231,7 @@ if (${WTF_PLATFORM_WIN_CAIRO})
|
|
OpenSSL::SSL
|
|
mfuuid.lib
|
|
strmiids.lib
|
|
+ ${LIBVPX_CUSTOM_LIBRARY}
|
|
)
|
|
endif ()
|
|
|
|
diff --git a/Source/WebKit/Shared/API/c/wpe/WebKit.h b/Source/WebKit/Shared/API/c/wpe/WebKit.h
|
|
index 898e30b370db8176e886fbbde0cd960e38a64818..74945e06fac0eb14936578de6a599a123364a63a 100644
|
|
--- a/Source/WebKit/Shared/API/c/wpe/WebKit.h
|
|
+++ b/Source/WebKit/Shared/API/c/wpe/WebKit.h
|
|
@@ -78,6 +78,7 @@
|
|
// From Source/WebKit/UIProcess/API/C
|
|
#include <WebKit/WKBackForwardListItemRef.h>
|
|
#include <WebKit/WKBackForwardListRef.h>
|
|
+#include <WebKit/WKBrowserInspector.h>
|
|
#include <WebKit/WKContext.h>
|
|
#include <WebKit/WKContextConfigurationRef.h>
|
|
#include <WebKit/WKCredential.h>
|
|
diff --git a/Source/WebKit/Shared/NativeWebKeyboardEvent.h b/Source/WebKit/Shared/NativeWebKeyboardEvent.h
|
|
index fd2b55f40fdd3d82d6d6947dc33ad31f24f4c1c7..bb1487b1efcbab2fd7ccf79a50eae99ecf4b4cab 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)
|
|
@@ -65,19 +66,35 @@ 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(Type 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<Modifier> 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&, Vector<String>&& commands);
|
|
NativeWebKeyboardEvent(const String&, Optional<Vector<WebCore::CompositionUnderline>>&&, Optional<EditingRange>&&);
|
|
NativeWebKeyboardEvent(Type, const String& text, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, Vector<String>&& commands, bool isKeypad, OptionSet<Modifier>);
|
|
+ NativeWebKeyboardEvent(Type 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<Modifier> 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&, HandledByInputMethod, Optional<Vector<WebCore::CompositionUnderline>>&&, Optional<EditingRange>&&);
|
|
+ NativeWebKeyboardEvent(Type 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<Modifier> modifiers, WallTime timestamp)
|
|
+ : WebKeyboardEvent(type, text, unmodifiedText, key, code, keyIdentifier, windowsVirtualKeyCode, nativeVirtualKeyCode, isAutoRepeat, isKeypad, isSystemKey, modifiers, timestamp)
|
|
+ {
|
|
+ }
|
|
#elif PLATFORM(WIN)
|
|
NativeWebKeyboardEvent(HWND, UINT message, WPARAM, LPARAM, Vector<MSG>&& pendingCharEvents);
|
|
+ NativeWebKeyboardEvent(Type 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<Modifier> 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 5e37f73510f73961d97ce8b42de0e1935a170d9b..7e30ef0830d7d98717b7e0cd3935cc2b1803518f 100644
|
|
--- a/Source/WebKit/Shared/NativeWebMouseEvent.h
|
|
+++ b/Source/WebKit/Shared/NativeWebMouseEvent.h
|
|
@@ -76,6 +76,11 @@ public:
|
|
NativeWebMouseEvent(HWND, UINT message, WPARAM, LPARAM, bool);
|
|
#endif
|
|
|
|
+#if PLATFORM(GTK) || USE(LIBWPE) || PLATFORM(WIN)
|
|
+ NativeWebMouseEvent(Type type, Button button, unsigned short buttons, const WebCore::IntPoint& position, const WebCore::IntPoint& globalPosition, float deltaX, float deltaY, float deltaZ, int clickCount, OptionSet<Modifier> modifiers, WallTime timestamp)
|
|
+ : WebMouseEvent(type, button, buttons, position, globalPosition, deltaX, deltaY, deltaZ, clickCount, modifiers, timestamp) { }
|
|
+#endif
|
|
+
|
|
#if USE(APPKIT)
|
|
NSEvent* nativeEvent() const { return m_nativeEvent.get(); }
|
|
#elif PLATFORM(GTK)
|
|
diff --git a/Source/WebKit/Shared/WebCoreArgumentCoders.cpp b/Source/WebKit/Shared/WebCoreArgumentCoders.cpp
|
|
index e0bbbbc5ba2318bfa8e63196d54eebb890364441..79194a208a2f6fc2fb2f2efae4f3588e50d63240 100644
|
|
--- a/Source/WebKit/Shared/WebCoreArgumentCoders.cpp
|
|
+++ b/Source/WebKit/Shared/WebCoreArgumentCoders.cpp
|
|
@@ -1461,6 +1461,9 @@ void ArgumentCoder<WindowFeatures>::encode(Encoder& encoder, const WindowFeature
|
|
encoder << windowFeatures.resizable;
|
|
encoder << windowFeatures.fullscreen;
|
|
encoder << windowFeatures.dialog;
|
|
+ encoder << windowFeatures.noopener;
|
|
+ encoder << windowFeatures.noreferrer;
|
|
+ encoder << windowFeatures.additionalFeatures;
|
|
}
|
|
|
|
bool ArgumentCoder<WindowFeatures>::decode(Decoder& decoder, WindowFeatures& windowFeatures)
|
|
@@ -1489,6 +1492,12 @@ bool ArgumentCoder<WindowFeatures>::decode(Decoder& decoder, WindowFeatures& win
|
|
return false;
|
|
if (!decoder.decode(windowFeatures.dialog))
|
|
return false;
|
|
+ if (!decoder.decode(windowFeatures.noopener))
|
|
+ return false;
|
|
+ if (!decoder.decode(windowFeatures.noreferrer))
|
|
+ return false;
|
|
+ if (!decoder.decode(windowFeatures.additionalFeatures))
|
|
+ return false;
|
|
return true;
|
|
}
|
|
|
|
diff --git a/Source/WebKit/Shared/WebEvent.h b/Source/WebKit/Shared/WebEvent.h
|
|
index 3ae6504779d3917a79f69f32b58260afeda270b4..72d44c33953cc13bf2ed7c762b4f9a7b88571b56 100644
|
|
--- a/Source/WebKit/Shared/WebEvent.h
|
|
+++ b/Source/WebKit/Shared/WebEvent.h
|
|
@@ -31,6 +31,7 @@
|
|
|
|
#include <wtf/EnumTraits.h>
|
|
#include <wtf/OptionSet.h>
|
|
+#include <wtf/RefCounted.h>
|
|
#include <wtf/WallTime.h>
|
|
#include <wtf/text/WTFString.h>
|
|
|
|
diff --git a/Source/WebKit/Shared/WebKeyboardEvent.cpp b/Source/WebKit/Shared/WebKeyboardEvent.cpp
|
|
index bc4322286484e6afdd49353fae6a8fb3cd5e66f2..7af88c4e93f6a0ea61dd107699c04c0695f7842f 100644
|
|
--- a/Source/WebKit/Shared/WebKeyboardEvent.cpp
|
|
+++ b/Source/WebKit/Shared/WebKeyboardEvent.cpp
|
|
@@ -35,6 +35,7 @@ WebKeyboardEvent::WebKeyboardEvent()
|
|
{
|
|
}
|
|
|
|
+
|
|
#if USE(APPKIT)
|
|
|
|
WebKeyboardEvent::WebKeyboardEvent(Type type, 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>& commands, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<Modifier> modifiers, WallTime timestamp)
|
|
@@ -56,6 +57,24 @@ WebKeyboardEvent::WebKeyboardEvent(Type type, const String& text, const String&
|
|
ASSERT(isKeyboardEventType(type));
|
|
}
|
|
|
|
+WebKeyboardEvent::WebKeyboardEvent(Type 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<Modifier> 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(Type type, const String& text, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool handledByInputMethod, Optional<Vector<WebCore::CompositionUnderline>>&& preeditUnderlines, Optional<EditingRange>&& preeditSelectionRange, Vector<String>&& commands, bool isKeypad, OptionSet<Modifier> modifiers, WallTime timestamp)
|
|
@@ -79,6 +98,24 @@ WebKeyboardEvent::WebKeyboardEvent(Type type, const String& text, const String&
|
|
ASSERT(isKeyboardEventType(type));
|
|
}
|
|
|
|
+WebKeyboardEvent::WebKeyboardEvent(Type 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<Modifier> 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(Type type, 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, OptionSet<Modifier> modifiers, WallTime timestamp)
|
|
@@ -144,6 +181,27 @@ WebKeyboardEvent::WebKeyboardEvent(Type type, const String& text, const String&
|
|
|
|
#endif
|
|
|
|
+#if PLATFORM(WIN) || USE(LIBWPE)
|
|
+
|
|
+WebKeyboardEvent::WebKeyboardEvent(Type 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<Modifier> 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 cb8029dc46dc2531f5cc23409dc6d2f11d5a3b49..a0e673b9680b0013d56920e525f358e333b06b0b 100644
|
|
--- a/Source/WebKit/Shared/WebKeyboardEvent.h
|
|
+++ b/Source/WebKit/Shared/WebKeyboardEvent.h
|
|
@@ -43,14 +43,18 @@ public:
|
|
|
|
#if USE(APPKIT)
|
|
WebKeyboardEvent(Type, 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, OptionSet<Modifier>, WallTime timestamp);
|
|
+ WebKeyboardEvent(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<Modifier>, WallTime timestamp, Vector<WebCore::KeypressCommand>&& commands);
|
|
#elif PLATFORM(GTK)
|
|
WebKeyboardEvent(Type, const String& text, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool handledByInputMethod, Optional<Vector<WebCore::CompositionUnderline>>&&, Optional<EditingRange>&&, Vector<String>&& commands, bool isKeypad, OptionSet<Modifier>, WallTime timestamp);
|
|
+ WebKeyboardEvent(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<Modifier>, WallTime timestamp, Vector<String>&& commands);
|
|
#elif PLATFORM(IOS_FAMILY)
|
|
WebKeyboardEvent(Type, 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, OptionSet<Modifier>, WallTime timestamp);
|
|
#elif USE(LIBWPE)
|
|
WebKeyboardEvent(Type, const String& text, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool handledByInputMethod, Optional<Vector<WebCore::CompositionUnderline>>&&, Optional<EditingRange>&&, bool isKeypad, OptionSet<Modifier>, WallTime timestamp);
|
|
+ WebKeyboardEvent(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<Modifier>, WallTime timestamp);
|
|
#else
|
|
WebKeyboardEvent(Type, 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, OptionSet<Modifier>, WallTime timestamp);
|
|
+ WebKeyboardEvent(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<Modifier>, WallTime timestamp);
|
|
#endif
|
|
|
|
const String& text() const { return m_text; }
|
|
diff --git a/Source/WebKit/Shared/WebPageCreationParameters.cpp b/Source/WebKit/Shared/WebPageCreationParameters.cpp
|
|
index cd46705db0d00962d316badf1862b1480438e156..8667922dbf4f98f002f407f937e4e22e9e36968d 100644
|
|
--- a/Source/WebKit/Shared/WebPageCreationParameters.cpp
|
|
+++ b/Source/WebKit/Shared/WebPageCreationParameters.cpp
|
|
@@ -147,6 +147,8 @@ void WebPageCreationParameters::encode(IPC::Encoder& encoder) const
|
|
encoder << crossOriginAccessControlCheckEnabled;
|
|
encoder << processDisplayName;
|
|
|
|
+ encoder << shouldPauseInInspectorWhenShown;
|
|
+
|
|
encoder << shouldCaptureAudioInUIProcess;
|
|
encoder << shouldCaptureAudioInGPUProcess;
|
|
encoder << shouldCaptureVideoInUIProcess;
|
|
@@ -477,7 +479,10 @@ Optional<WebPageCreationParameters> WebPageCreationParameters::decode(IPC::Decod
|
|
if (!processDisplayName)
|
|
return WTF::nullopt;
|
|
parameters.processDisplayName = WTFMove(*processDisplayName);
|
|
-
|
|
+
|
|
+ if (!decoder.decode(parameters.shouldPauseInInspectorWhenShown))
|
|
+ return WTF::nullopt;
|
|
+
|
|
if (!decoder.decode(parameters.shouldCaptureAudioInUIProcess))
|
|
return WTF::nullopt;
|
|
|
|
diff --git a/Source/WebKit/Shared/WebPageCreationParameters.h b/Source/WebKit/Shared/WebPageCreationParameters.h
|
|
index 723a2b1424a50a9146c4ead4a5419f8eeda94bf7..59bb6298193ec26f38eecf11384ae6b5c895b4bb 100644
|
|
--- a/Source/WebKit/Shared/WebPageCreationParameters.h
|
|
+++ b/Source/WebKit/Shared/WebPageCreationParameters.h
|
|
@@ -236,6 +236,8 @@ struct WebPageCreationParameters {
|
|
|
|
WebCore::ShouldRelaxThirdPartyCookieBlocking shouldRelaxThirdPartyCookieBlocking { WebCore::ShouldRelaxThirdPartyCookieBlocking::No };
|
|
|
|
+ bool shouldPauseInInspectorWhenShown { false };
|
|
+
|
|
#if PLATFORM(GTK)
|
|
String themeName;
|
|
#endif
|
|
diff --git a/Source/WebKit/Shared/gtk/NativeWebKeyboardEventGtk.cpp b/Source/WebKit/Shared/gtk/NativeWebKeyboardEventGtk.cpp
|
|
index c76a9e1f7dae7a31c4048d8f00d849a18ebaff23..1cfd9c7acb69dea69783c42b3f427929509782a4 100644
|
|
--- a/Source/WebKit/Shared/gtk/NativeWebKeyboardEventGtk.cpp
|
|
+++ b/Source/WebKit/Shared/gtk/NativeWebKeyboardEventGtk.cpp
|
|
@@ -50,7 +50,7 @@ NativeWebKeyboardEvent::NativeWebKeyboardEvent(Type type, const String& text, co
|
|
}
|
|
|
|
NativeWebKeyboardEvent::NativeWebKeyboardEvent(const NativeWebKeyboardEvent& event)
|
|
- : WebKeyboardEvent(event.type(), event.text(), event.key(), event.code(), event.keyIdentifier(), event.windowsVirtualKeyCode(), event.nativeVirtualKeyCode(), event.handledByInputMethod(), Optional<Vector<WebCore::CompositionUnderline>>(event.preeditUnderlines()), Optional<EditingRange>(event.preeditSelectionRange()), Vector<String>(event.commands()), event.isKeypad(), event.modifiers(), event.timestamp())
|
|
+ : WebKeyboardEvent(event)
|
|
, m_nativeEvent(event.nativeEvent() ? gdk_event_copy(event.nativeEvent()) : nullptr)
|
|
{
|
|
}
|
|
diff --git a/Source/WebKit/Shared/gtk/NativeWebMouseEventGtk.cpp b/Source/WebKit/Shared/gtk/NativeWebMouseEventGtk.cpp
|
|
index 66fcf27bcdd78e9c4d2b73e1e05830575bc9c05d..656c79494d4224b958ce338c5ebe0f0bfb8d8977 100644
|
|
--- a/Source/WebKit/Shared/gtk/NativeWebMouseEventGtk.cpp
|
|
+++ b/Source/WebKit/Shared/gtk/NativeWebMouseEventGtk.cpp
|
|
@@ -54,7 +54,7 @@ NativeWebMouseEvent::NativeWebMouseEvent(Type type, Button button, unsigned shor
|
|
}
|
|
|
|
NativeWebMouseEvent::NativeWebMouseEvent(const NativeWebMouseEvent& event)
|
|
- : WebMouseEvent(event.type(), event.button(), event.buttons(), event.position(), event.globalPosition(), event.deltaX(), event.deltaY(), event.deltaZ(), event.clickCount(), event.modifiers(), event.timestamp())
|
|
+ : WebMouseEvent(event)
|
|
, m_nativeEvent(event.nativeEvent() ? gdk_event_copy(const_cast<GdkEvent*>(event.nativeEvent())) : nullptr)
|
|
{
|
|
}
|
|
diff --git a/Source/WebKit/Shared/ios/WebPlatformTouchPointIOS.cpp b/Source/WebKit/Shared/ios/WebPlatformTouchPointIOS.cpp
|
|
index 2a9db4f8acafe9d64d5d4ebd9913aa161ea0f4c0..f151ef4e8e6abb5e3044771c235139d48e8aa7cf 100644
|
|
--- a/Source/WebKit/Shared/ios/WebPlatformTouchPointIOS.cpp
|
|
+++ b/Source/WebKit/Shared/ios/WebPlatformTouchPointIOS.cpp
|
|
@@ -26,7 +26,7 @@
|
|
#include "config.h"
|
|
#include "WebTouchEvent.h"
|
|
|
|
-#if ENABLE(TOUCH_EVENTS)
|
|
+#if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS_FAMILY)
|
|
|
|
#include "WebCoreArgumentCoders.h"
|
|
|
|
@@ -79,4 +79,4 @@ Optional<WebPlatformTouchPoint> WebPlatformTouchPoint::decode(IPC::Decoder& deco
|
|
|
|
} // namespace WebKit
|
|
|
|
-#endif // ENABLE(TOUCH_EVENTS)
|
|
+#endif // ENABLE(TOUCH_EVENTS) && PLATFORM(IOS_FAMILY)
|
|
diff --git a/Source/WebKit/Shared/ios/WebTouchEventIOS.cpp b/Source/WebKit/Shared/ios/WebTouchEventIOS.cpp
|
|
index e40a6e172bfd2b75076fd4053da643ebab9eb81f..2516655bbc9e5bc863537a554c5faac0f6fc1a09 100644
|
|
--- a/Source/WebKit/Shared/ios/WebTouchEventIOS.cpp
|
|
+++ b/Source/WebKit/Shared/ios/WebTouchEventIOS.cpp
|
|
@@ -26,7 +26,7 @@
|
|
#include "config.h"
|
|
#include "WebTouchEvent.h"
|
|
|
|
-#if ENABLE(TOUCH_EVENTS)
|
|
+#if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS_FAMILY)
|
|
|
|
#include "ArgumentCoders.h"
|
|
#include "WebCoreArgumentCoders.h"
|
|
@@ -71,4 +71,4 @@ bool WebTouchEvent::decode(IPC::Decoder& decoder, WebTouchEvent& result)
|
|
|
|
} // namespace WebKit
|
|
|
|
-#endif // ENABLE(TOUCH_EVENTS)
|
|
+#endif // ENABLE(TOUCH_EVENTS) && PLATFORM(IOS_FAMILY)
|
|
diff --git a/Source/WebKit/Shared/win/WebEventFactory.cpp b/Source/WebKit/Shared/win/WebEventFactory.cpp
|
|
index 88d53d236cd6d62735f03678a04ca9c198dddacb..b8f8efc57ab00dc5725660c5a8ad56a3e6384de5 100644
|
|
--- a/Source/WebKit/Shared/win/WebEventFactory.cpp
|
|
+++ b/Source/WebKit/Shared/win/WebEventFactory.cpp
|
|
@@ -473,7 +473,7 @@ WebKeyboardEvent WebEventFactory::createWebKeyboardEvent(HWND hwnd, UINT message
|
|
}
|
|
|
|
#if ENABLE(TOUCH_EVENTS)
|
|
-WebTouchEvent WebEventFactory::createWebTouchEvent(const GdkEvent* event, Vector<WebPlatformTouchPoint>&& touchPoints)
|
|
+WebTouchEvent WebEventFactory::createWebTouchEvent()
|
|
{
|
|
return WebTouchEvent();
|
|
}
|
|
diff --git a/Source/WebKit/Sources.txt b/Source/WebKit/Sources.txt
|
|
index bc2c4943aebe5ccaf8b947ed71ae030f4f32d983..8d4dd219630752e80f7fd422d169b87fb7cb433b 100644
|
|
--- a/Source/WebKit/Sources.txt
|
|
+++ b/Source/WebKit/Sources.txt
|
|
@@ -273,16 +273,20 @@ Shared/WebsiteData/WebsiteData.cpp
|
|
|
|
UIProcess/AuxiliaryProcessProxy.cpp
|
|
UIProcess/BackgroundProcessResponsivenessTimer.cpp
|
|
+UIProcess/BrowserInspectorPipe.cpp
|
|
UIProcess/DeviceIdHashSaltStorage.cpp
|
|
UIProcess/DrawingAreaProxy.cpp
|
|
UIProcess/FrameLoadState.cpp
|
|
UIProcess/GeolocationPermissionRequestManagerProxy.cpp
|
|
UIProcess/GeolocationPermissionRequestProxy.cpp
|
|
+UIProcess/InspectorDialogAgent.cpp
|
|
+UIProcess/InspectorPlaywrightAgent.cpp
|
|
UIProcess/LegacyGlobalSettings.cpp
|
|
UIProcess/PageLoadState.cpp
|
|
UIProcess/ProcessAssertion.cpp
|
|
UIProcess/ProcessThrottler.cpp
|
|
UIProcess/ProvisionalPageProxy.cpp
|
|
+UIProcess/RemoteInspectorPipe.cpp
|
|
UIProcess/ResponsivenessTimer.cpp
|
|
UIProcess/SuspendedPageProxy.cpp
|
|
UIProcess/SystemPreviewController.cpp
|
|
@@ -320,6 +324,8 @@ UIProcess/WebOpenPanelResultListenerProxy.cpp
|
|
UIProcess/WebPageDiagnosticLoggingClient.cpp
|
|
UIProcess/WebPageGroup.cpp
|
|
UIProcess/WebPageInjectedBundleClient.cpp
|
|
+UIProcess/WebPageInspectorEmulationAgent.cpp
|
|
+UIProcess/WebPageInspectorInputAgent.cpp
|
|
UIProcess/WebPageProxy.cpp
|
|
UIProcess/WebPasteboardProxy.cpp
|
|
UIProcess/WebPreferences.cpp
|
|
@@ -438,6 +444,9 @@ UIProcess/Inspector/WebPageDebuggable.cpp
|
|
UIProcess/Inspector/WebPageInspectorController.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 77690d0dd5272a05e2a78422218a35b422b5755a..ece57d95f3b608d9e8c6531be8d38ef9f942dd90 100644
|
|
--- a/Source/WebKit/SourcesCocoa.txt
|
|
+++ b/Source/WebKit/SourcesCocoa.txt
|
|
@@ -246,6 +246,7 @@ UIProcess/API/Cocoa/_WKApplicationManifest.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
|
|
@@ -409,6 +410,7 @@ UIProcess/Inspector/ios/WKInspectorHighlightView.mm
|
|
UIProcess/Inspector/ios/WKInspectorNodeSearchGestureRecognizer.mm
|
|
|
|
UIProcess/Inspector/mac/RemoteWebInspectorProxyMac.mm
|
|
+UIProcess/Inspector/mac/ScreencastEncoderMac.mm
|
|
UIProcess/Inspector/mac/WebInspectorProxyMac.mm
|
|
UIProcess/Inspector/mac/WKInspectorViewController.mm
|
|
UIProcess/Inspector/mac/WKInspectorWKWebView.mm
|
|
diff --git a/Source/WebKit/SourcesGTK.txt b/Source/WebKit/SourcesGTK.txt
|
|
index 31dc21754f252d6df56e169e803222a250de8490..94dbac584e99df0b0e80d972cb83669667b0cc88 100644
|
|
--- a/Source/WebKit/SourcesGTK.txt
|
|
+++ b/Source/WebKit/SourcesGTK.txt
|
|
@@ -125,6 +125,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
|
|
@@ -237,6 +238,7 @@ UIProcess/WebsiteData/unix/WebsiteDataStoreUnix.cpp
|
|
|
|
UIProcess/cairo/BackingStoreCairo.cpp @no-unify
|
|
|
|
+UIProcess/glib/InspectorPlaywrightAgentClientGLib.cpp
|
|
UIProcess/glib/WebProcessPoolGLib.cpp
|
|
UIProcess/glib/WebProcessProxyGLib.cpp
|
|
UIProcess/glib/WebsiteDataStoreGLib.cpp @no-unify
|
|
@@ -252,6 +254,7 @@ UIProcess/gtk/ClipboardGtk3.cpp @no-unify
|
|
UIProcess/gtk/ClipboardGtk4.cpp @no-unify
|
|
UIProcess/gtk/GestureController.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
|
|
@@ -262,6 +265,8 @@ UIProcess/gtk/WaylandCompositor.cpp @no-unify
|
|
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 3c299dfd72792cf1b799de6486626c8039ddbc86..c3196cab79ef246cc083d3512957694e42a45e24 100644
|
|
--- a/Source/WebKit/SourcesWPE.txt
|
|
+++ b/Source/WebKit/SourcesWPE.txt
|
|
@@ -117,6 +117,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
|
|
@@ -195,7 +196,7 @@ UIProcess/Automation/wpe/WebAutomationSessionWPE.cpp
|
|
UIProcess/CoordinatedGraphics/DrawingAreaProxyCoordinatedGraphics.cpp
|
|
|
|
UIProcess/geoclue/GeoclueGeolocationProvider.cpp
|
|
-
|
|
+UIProcess/glib/InspectorPlaywrightAgentClientGLib.cpp
|
|
UIProcess/glib/WebProcessPoolGLib.cpp
|
|
UIProcess/glib/WebProcessProxyGLib.cpp
|
|
UIProcess/glib/WebsiteDataStoreGLib.cpp @no-unify
|
|
@@ -217,6 +218,10 @@ UIProcess/linux/MemoryPressureMonitor.cpp
|
|
UIProcess/soup/WebCookieManagerProxySoup.cpp
|
|
UIProcess/soup/WebProcessPoolSoup.cpp
|
|
|
|
+UIProcess/wpe/InspectorTargetProxyWPE.cpp
|
|
+UIProcess/wpe/WebPageInspectorEmulationAgentWPE.cpp
|
|
+UIProcess/wpe/WebPageInspectorInputAgentWPE.cpp
|
|
+
|
|
UIProcess/wpe/WebPageProxyWPE.cpp
|
|
|
|
WebProcess/GPU/media/gstreamer/VideoLayerRemoteGStreamer.cpp
|
|
diff --git a/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.cpp b/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.cpp
|
|
index 18585f61bb6ecabec39ff0c03b862c65856dca24..21bab039d1f6116ebf9c59bc42a695a45f4701e8 100644
|
|
--- a/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.cpp
|
|
+++ b/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.cpp
|
|
@@ -53,6 +53,9 @@ Ref<ProcessPoolConfiguration> ProcessPoolConfiguration::copy()
|
|
copy->m_ignoreSynchronousMessagingTimeoutsForTesting = this->m_ignoreSynchronousMessagingTimeoutsForTesting;
|
|
copy->m_attrStyleEnabled = this->m_attrStyleEnabled;
|
|
copy->m_overrideLanguages = this->m_overrideLanguages;
|
|
+#if PLATFORM(MAC)
|
|
+ copy->m_forceOverlayScrollbars = this->m_forceOverlayScrollbars;
|
|
+#endif
|
|
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 64924902f19811792537a15a32ed4d706daf9670..28906745477d89bb0e7c2b9c3f1523d2d76803d6 100644
|
|
--- a/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.h
|
|
+++ b/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.h
|
|
@@ -98,6 +98,11 @@ public:
|
|
const Vector<WTF::String>& overrideLanguages() const { return m_overrideLanguages; }
|
|
void setOverrideLanguages(Vector<WTF::String>&& languages) { m_overrideLanguages = WTFMove(languages); }
|
|
|
|
+#if PLATFORM(MAC)
|
|
+ bool forceOverlayScrollbars() const { return m_forceOverlayScrollbars; }
|
|
+ void setForceOverlayScrollbars(bool forceOverlayScrollbars) { m_forceOverlayScrollbars = forceOverlayScrollbars; }
|
|
+#endif
|
|
+
|
|
bool alwaysRunsAtBackgroundPriority() const { return m_alwaysRunsAtBackgroundPriority; }
|
|
void setAlwaysRunsAtBackgroundPriority(bool alwaysRunsAtBackgroundPriority) { m_alwaysRunsAtBackgroundPriority = alwaysRunsAtBackgroundPriority; }
|
|
|
|
@@ -157,6 +162,9 @@ private:
|
|
bool m_ignoreSynchronousMessagingTimeoutsForTesting { false };
|
|
bool m_attrStyleEnabled { false };
|
|
Vector<WTF::String> m_overrideLanguages;
|
|
+#if PLATFORM(MAC)
|
|
+ bool m_forceOverlayScrollbars { false };
|
|
+#endif
|
|
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 7b4f93aa426541fdb31ec881770b2f336aee8f8b..8e7a93abcace51dd41aa8e5879e403fe5e5d61a5 100644
|
|
--- a/Source/WebKit/UIProcess/API/APIUIClient.h
|
|
+++ b/Source/WebKit/UIProcess/API/APIUIClient.h
|
|
@@ -93,6 +93,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::WebEvent::Modifier>, Object*) { }
|
|
diff --git a/Source/WebKit/UIProcess/API/C/WKInspector.cpp b/Source/WebKit/UIProcess/API/C/WKInspector.cpp
|
|
index 39327c5c9230591e4f52e4574c416e36687788f0..450033d87fefb743ab7240ce317fae221f91dcf5 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 "WebInspectorProxy.h"
|
|
#include "WebPageProxy.h"
|
|
@@ -130,4 +135,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 c723e798efe385dc6fc8dde1618dcdd7afea5c71..ffffcc97e25bb27c4606bc441a351c2c794c2d1b 100644
|
|
--- a/Source/WebKit/UIProcess/API/C/WKPage.cpp
|
|
+++ b/Source/WebKit/UIProcess/API/C/WKPage.cpp
|
|
@@ -1692,6 +1692,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)
|
|
@@ -1752,6 +1759,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 b6388155cd3036e666110f1925616afd37e868ba..c21275123dc4581f51730a2d27deac37c5d30572 100644
|
|
--- a/Source/WebKit/UIProcess/API/C/WKPageUIClient.h
|
|
+++ b/Source/WebKit/UIProcess/API/C/WKPageUIClient.h
|
|
@@ -90,6 +90,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);
|
|
@@ -1351,6 +1352,7 @@ typedef struct WKPageUIClientV14 {
|
|
|
|
// Version 14.
|
|
WKPageRunWebAuthenticationPanelCallback runWebAuthenticationPanel;
|
|
+ WKPageHandleJavaScriptDialogCallback handleJavaScriptDialog;
|
|
} WKPageUIClientV14;
|
|
|
|
#ifdef __cplusplus
|
|
diff --git a/Source/WebKit/UIProcess/API/Cocoa/WKUIDelegate.h b/Source/WebKit/UIProcess/API/Cocoa/WKUIDelegate.h
|
|
index cad87f3ef2ab93d93a74cec0c34b47c695de6bc6..66145a384638b97ee08516e56e1e86a83713c634 100644
|
|
--- a/Source/WebKit/UIProcess/API/Cocoa/WKUIDelegate.h
|
|
+++ b/Source/WebKit/UIProcess/API/Cocoa/WKUIDelegate.h
|
|
@@ -123,6 +123,13 @@ NS_ASSUME_NONNULL_BEGIN
|
|
*/
|
|
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(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;
|
|
+
|
|
#if TARGET_OS_IPHONE
|
|
|
|
/*! @abstract Allows your app to determine whether or not the given element should show a preview.
|
|
diff --git a/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.h b/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.h
|
|
index 245580d7e15679b82a61c4639850da02d81a4e1e..5fd5c4afbdc167f817b4ae961f446ec44a0ae2c1 100644
|
|
--- a/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.h
|
|
+++ b/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.h
|
|
@@ -24,7 +24,6 @@
|
|
*/
|
|
|
|
#import <WebKit/WKFoundation.h>
|
|
-
|
|
#import <WebKit/WKWebsiteDataRecord.h>
|
|
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@@ -79,6 +78,8 @@ WK_CLASS_AVAILABLE(macos(10.11), ios(9.0))
|
|
/*! @abstract Returns the cookie store representing HTTP cookies in this website data store. */
|
|
@property (nonatomic, readonly) WKHTTPCookieStore *httpCookieStore WK_API_AVAILABLE(macos(10.13), ios(11.0));
|
|
|
|
+- (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 c2db4a04d378f24fdd5e630f15b293bf6be01cab..705cd32ed7f75b67c0938799a42d00b5594eef31 100644
|
|
--- a/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.mm
|
|
+++ b/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.mm
|
|
@@ -45,6 +45,7 @@
|
|
#import <WebCore/Credential.h>
|
|
#import <WebCore/RegistrationDatabase.h>
|
|
#import <WebCore/VersionChecks.h>
|
|
+#import <pal/SessionID.h>
|
|
#import <wtf/BlockPtr.h>
|
|
#import <wtf/URL.h>
|
|
#import <wtf/WeakObjCPtr.h>
|
|
@@ -199,6 +200,11 @@ static WallTime toSystemClockTime(NSDate *date)
|
|
});
|
|
}
|
|
|
|
+- (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..e7143513ea2be8e1cdab5c86a28643fffea626dd
|
|
--- /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));
|
|
+#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 7226cc2cb605d2384b5fdf9210ac731b41610c1e..7883367044356751886f5c1f89250c29fcc58d3a 100644
|
|
--- a/Source/WebKit/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.h
|
|
+++ b/Source/WebKit/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.h
|
|
@@ -62,6 +62,7 @@ WK_CLASS_AVAILABLE(macos(10.10), ios(8.0))
|
|
#endif
|
|
@property (nonatomic) pid_t presentingApplicationPID WK_API_AVAILABLE(macos(10.13), ios(11.0));
|
|
@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 processSwapsOnWindowOpenWithOpener WK_API_AVAILABLE(macos(10.14), ios(12.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 b4c35e8854c61055655aeff2bfb909cdc542839c..11d685c58d7c148430dd664636f5d51e251800c7 100644
|
|
--- a/Source/WebKit/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.mm
|
|
+++ b/Source/WebKit/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.mm
|
|
@@ -231,6 +231,16 @@
|
|
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/_WKRemoteWebInspectorViewController.mm b/Source/WebKit/UIProcess/API/Cocoa/_WKRemoteWebInspectorViewController.mm
|
|
index 66bf24df826daa8e7284248fd1b728cb5ebff343..d40f4f4be2bf76fa300cb54a06e81ff5a1e18d16 100644
|
|
--- a/Source/WebKit/UIProcess/API/Cocoa/_WKRemoteWebInspectorViewController.mm
|
|
+++ b/Source/WebKit/UIProcess/API/Cocoa/_WKRemoteWebInspectorViewController.mm
|
|
@@ -25,6 +25,7 @@
|
|
|
|
#import "config.h"
|
|
#import "_WKRemoteWebInspectorViewController.h"
|
|
+#import "WKWebViewPrivate.h"
|
|
|
|
#if PLATFORM(MAC)
|
|
|
|
diff --git a/Source/WebKit/UIProcess/API/Cocoa/_WKUserStyleSheet.h b/Source/WebKit/UIProcess/API/Cocoa/_WKUserStyleSheet.h
|
|
index 06f8f1f762e89686fc5dc3fc890f13e0b363d333..68363fd83bac76b0f879ae48a54a862d715d685f 100644
|
|
--- a/Source/WebKit/UIProcess/API/Cocoa/_WKUserStyleSheet.h
|
|
+++ b/Source/WebKit/UIProcess/API/Cocoa/_WKUserStyleSheet.h
|
|
@@ -30,6 +30,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
|
@class _WKUserContentWorld;
|
|
@class WKWebView;
|
|
+@class WKContentWorld;
|
|
|
|
typedef NS_ENUM(NSInteger, _WKUserStyleLevel) {
|
|
_WKUserStyleUserLevel,
|
|
diff --git a/Source/WebKit/UIProcess/API/Cocoa/_WKUserStyleSheet.mm b/Source/WebKit/UIProcess/API/Cocoa/_WKUserStyleSheet.mm
|
|
index 0684412b1351f30a5d484f909d7a4b97a71ca426..33daa49f590a614d2122477e4987f58af3b1b8ca 100644
|
|
--- a/Source/WebKit/UIProcess/API/Cocoa/_WKUserStyleSheet.mm
|
|
+++ b/Source/WebKit/UIProcess/API/Cocoa/_WKUserStyleSheet.mm
|
|
@@ -33,6 +33,7 @@
|
|
#import "WebKit2Initialize.h"
|
|
#import "WebPageProxy.h"
|
|
#import "_WKUserContentWorldInternal.h"
|
|
+#import <WebKit/WKContentWorldInternal.h>
|
|
#import <wtf/cocoa/VectorCocoa.h>
|
|
|
|
@implementation _WKUserStyleSheet
|
|
diff --git a/Source/WebKit/UIProcess/API/glib/WebKitBrowserInspector.cpp b/Source/WebKit/UIProcess/API/glib/WebKitBrowserInspector.cpp
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..54529a23f53cebe6f8a96873ca6c2f31f0481ae0
|
|
--- /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>(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 2ceb2b4f49f409bbe6e6810115e36d0c84f83b5d..16d2062b746b80ace6f39d779e9c3b8796b581b1 100644
|
|
--- a/Source/WebKit/UIProcess/API/glib/WebKitUIClient.cpp
|
|
+++ b/Source/WebKit/UIProcess/API/glib/WebKitUIClient.cpp
|
|
@@ -93,6 +93,10 @@ private:
|
|
{
|
|
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 f7faa5880bf02b28157276b60ca100ed38fbf990..aaa967adaa366a72ce5229efb96a01864546a543 100644
|
|
--- a/Source/WebKit/UIProcess/API/glib/WebKitWebContext.cpp
|
|
+++ b/Source/WebKit/UIProcess/API/glib/WebKitWebContext.cpp
|
|
@@ -120,8 +120,8 @@ enum {
|
|
PROP_LOCAL_STORAGE_DIRECTORY,
|
|
#endif
|
|
PROP_WEBSITE_DATA_MANAGER,
|
|
-#if PLATFORM(GTK)
|
|
PROP_PSON_ENABLED,
|
|
+#if PLATFORM(GTK)
|
|
#if !USE(GTK4)
|
|
PROP_USE_SYSYEM_APPEARANCE_FOR_SCROLLBARS
|
|
#endif
|
|
@@ -206,8 +206,8 @@ struct _WebKitWebContextPrivate {
|
|
|
|
RefPtr<WebProcessPool> processPool;
|
|
bool clientsDetached;
|
|
-#if PLATFORM(GTK)
|
|
bool psonEnabled;
|
|
+#if PLATFORM(GTK)
|
|
#if !USE(GTK4)
|
|
bool useSystemAppearanceForScrollbars;
|
|
#endif
|
|
@@ -306,11 +306,9 @@ WEBKIT_DEFINE_TYPE(WebKitWebContext, webkit_web_context, G_TYPE_OBJECT)
|
|
|
|
static const char* injectedBundleDirectory()
|
|
{
|
|
-#if ENABLE(DEVELOPER_MODE)
|
|
const char* bundleDirectory = g_getenv("WEBKIT_INJECTED_BUNDLE_PATH");
|
|
if (bundleDirectory && g_file_test(bundleDirectory, G_FILE_TEST_IS_DIR))
|
|
return bundleDirectory;
|
|
-#endif
|
|
|
|
#if PLATFORM(GTK)
|
|
static const char* injectedBundlePath = LIBDIR G_DIR_SEPARATOR_S "webkit2gtk-" WEBKITGTK_API_VERSION_STRING
|
|
@@ -335,10 +333,10 @@ static void webkitWebContextGetProperty(GObject* object, guint propID, GValue* v
|
|
case PROP_WEBSITE_DATA_MANAGER:
|
|
g_value_set_object(value, webkit_web_context_get_website_data_manager(context));
|
|
break;
|
|
-#if PLATFORM(GTK)
|
|
case PROP_PSON_ENABLED:
|
|
g_value_set_boolean(value, context->priv->psonEnabled);
|
|
break;
|
|
+#if PLATFORM(GTK)
|
|
#if !USE(GTK4)
|
|
case PROP_USE_SYSYEM_APPEARANCE_FOR_SCROLLBARS:
|
|
g_value_set_boolean(value, webkit_web_context_get_use_system_appearance_for_scrollbars(context));
|
|
@@ -365,10 +363,10 @@ static void webkitWebContextSetProperty(GObject* object, guint propID, const GVa
|
|
context->priv->websiteDataManager = manager ? WEBKIT_WEBSITE_DATA_MANAGER(manager) : nullptr;
|
|
break;
|
|
}
|
|
-#if PLATFORM(GTK)
|
|
case PROP_PSON_ENABLED:
|
|
context->priv->psonEnabled = g_value_get_boolean(value);
|
|
break;
|
|
+#if PLATFORM(GTK)
|
|
#if !USE(GTK4)
|
|
case PROP_USE_SYSYEM_APPEARANCE_FOR_SCROLLBARS:
|
|
webkit_web_context_set_use_system_appearance_for_scrollbars(context, g_value_get_boolean(value));
|
|
@@ -380,10 +378,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);
|
|
@@ -391,8 +398,8 @@ static void webkitWebContextConstructed(GObject* object)
|
|
|
|
API::ProcessPoolConfiguration configuration;
|
|
configuration.setInjectedBundlePath(FileSystem::stringFromFileSystemRepresentation(bundleFilename.get()));
|
|
-#if PLATFORM(GTK)
|
|
configuration.setProcessSwapsOnNavigation(priv->psonEnabled);
|
|
+#if PLATFORM(GTK)
|
|
#if !USE(GTK4)
|
|
configuration.setUseSystemAppearanceForScrollbars(priv->useSystemAppearanceForScrollbars);
|
|
#endif
|
|
@@ -429,6 +436,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;
|
|
@@ -501,7 +510,6 @@ static void webkit_web_context_class_init(WebKitWebContextClass* webContextClass
|
|
WEBKIT_TYPE_WEBSITE_DATA_MANAGER,
|
|
static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
|
|
|
|
-#if PLATFORM(GTK)
|
|
/**
|
|
* WebKitWebContext:process-swap-on-cross-site-navigation-enabled:
|
|
*
|
|
@@ -525,6 +533,7 @@ static void webkit_web_context_class_init(WebKitWebContextClass* webContextClass
|
|
FALSE,
|
|
static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
|
|
|
|
+#if PLATFORM(GTK)
|
|
#if !USE(GTK4)
|
|
/**
|
|
* WebKitWebContext:use-system-appearance-for-scrollbars:
|
|
diff --git a/Source/WebKit/UIProcess/API/glib/WebKitWebContextPrivate.h b/Source/WebKit/UIProcess/API/glib/WebKitWebContextPrivate.h
|
|
index 78d1578f94793e9e59a3d4d2b33e79ea8530fa04..493cdadac3873508b3efa3048638e73a13f4c976 100644
|
|
--- a/Source/WebKit/UIProcess/API/glib/WebKitWebContextPrivate.h
|
|
+++ b/Source/WebKit/UIProcess/API/glib/WebKitWebContextPrivate.h
|
|
@@ -45,3 +45,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 3237d2a78442a81f57f52e8f9bb0b454d0a6d11d..4efef8b4032112f84d55f6fa18fdfea5e17bd375 100644
|
|
--- a/Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp
|
|
+++ b/Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp
|
|
@@ -31,6 +31,7 @@
|
|
#include "WebCertificateInfo.h"
|
|
#include "WebContextMenuItem.h"
|
|
#include "WebContextMenuItemData.h"
|
|
+#include "WebPageInspectorController.h"
|
|
#include "WebKitAuthenticationRequestPrivate.h"
|
|
#include "WebKitBackForwardListPrivate.h"
|
|
#include "WebKitContextMenuClient.h"
|
|
@@ -132,6 +133,7 @@ enum {
|
|
CLOSE,
|
|
|
|
SCRIPT_DIALOG,
|
|
+ SCRIPT_DIALOG_HANDLED,
|
|
|
|
DECIDE_POLICY,
|
|
PERMISSION_REQUEST,
|
|
@@ -435,6 +437,9 @@ void WebKitWebViewClient::handleDownloadRequest(WKWPE::View&, DownloadProxy& dow
|
|
|
|
void WebKitWebViewClient::frameDisplayed(WKWPE::View&)
|
|
{
|
|
+ if (RefPtr<cairo_surface_t> surface = adoptRef(webkitWebViewBackendTakeScreenshot(m_webView->priv->backend.get())))
|
|
+ getPage(m_webView).inspectorController().didPaint(surface.get());
|
|
+
|
|
{
|
|
SetForScope<bool> inFrameDisplayedGuard(m_webView->priv->inFrameDisplayed, true);
|
|
for (const auto& callback : m_webView->priv->frameDisplayedCallbacks) {
|
|
@@ -465,6 +470,7 @@ void WebKitWebViewClient::didReceiveUserMessage(WKWPE::View&, UserMessage&& mess
|
|
{
|
|
webkitWebViewDidReceiveUserMessage(m_webView, WTFMove(message), WTFMove(completionHandler));
|
|
}
|
|
+
|
|
#endif
|
|
|
|
static gboolean webkitWebViewLoadFail(WebKitWebView* webView, WebKitLoadEvent, const char* failingURI, GError* error)
|
|
@@ -1592,6 +1598,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
|
|
@@ -2485,6 +2500,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 b9e56fc55fd7dfa821f789264b0c15f9b4c7b412..4138d5b42077f735264ac7a168cce329ebaa89c3 100644
|
|
--- a/Source/WebKit/UIProcess/API/glib/WebKitWebViewPrivate.h
|
|
+++ b/Source/WebKit/UIProcess/API/glib/WebKitWebViewPrivate.h
|
|
@@ -60,6 +60,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/gtk/PageClientImpl.cpp b/Source/WebKit/UIProcess/API/gtk/PageClientImpl.cpp
|
|
index 57139e2d910cf1834d071d482b3967194dd0fda1..3b6ecd1ace15fdaded93b9207446f2810aaf7dbd 100644
|
|
--- a/Source/WebKit/UIProcess/API/gtk/PageClientImpl.cpp
|
|
+++ b/Source/WebKit/UIProcess/API/gtk/PageClientImpl.cpp
|
|
@@ -241,6 +241,8 @@ void PageClientImpl::doneWithKeyEvent(const NativeWebKeyboardEvent& event, bool
|
|
{
|
|
if (wasEventHandled || event.type() != WebEvent::Type::KeyDown || !event.nativeEvent())
|
|
return;
|
|
+ if (!event.nativeEvent())
|
|
+ return;
|
|
|
|
WebKitWebViewBase* webkitWebViewBase = WEBKIT_WEB_VIEW_BASE(m_viewWidget);
|
|
webkitWebViewBaseForwardNextKeyEvent(webkitWebViewBase);
|
|
diff --git a/Source/WebKit/UIProcess/API/gtk/WebKitBrowserInspector.h b/Source/WebKit/UIProcess/API/gtk/WebKitBrowserInspector.h
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..9f1a0173a5641d6f158d815b8f7b9ea66f65c26d
|
|
--- /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(WEBKIT2_COMPILATION)
|
|
+#error "Only <webkit2/webkit2.h> can be included directly."
|
|
+#endif
|
|
+
|
|
+#ifndef WebKitBrowserInspector_h
|
|
+#define WebKitBrowserInspector_h
|
|
+
|
|
+#include <glib-object.h>
|
|
+#include <webkit2/WebKitDefines.h>
|
|
+#include <webkit2/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/WebKitWebViewBase.cpp b/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBase.cpp
|
|
index fbd88dec952ff9da618100d662c81da4feb1b925..50ab14ce6367ed5c0538c043262870c460dbda3c 100644
|
|
--- a/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBase.cpp
|
|
+++ b/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBase.cpp
|
|
@@ -2266,6 +2266,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);
|
|
diff --git a/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBasePrivate.h b/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBasePrivate.h
|
|
index d09aea45d94fb7367ba88fdf8326dea1209d02ce..dac8f3ec62ace87fc82c997feb950733aa59a996 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 "GestureController.h"
|
|
#include "InputMethodState.h"
|
|
@@ -120,3 +121,5 @@ void webkitWebViewBaseDidLosePointerLock(WebKitWebViewBase*);
|
|
void webkitWebViewBaseSetInputMethodContext(WebKitWebViewBase*, WebKitInputMethodContext*);
|
|
WebKitInputMethodContext* webkitWebViewBaseGetInputMethodContext(WebKitWebViewBase*);
|
|
void webkitWebViewBaseSynthesizeCompositionKeyPress(WebKitWebViewBase*, const String& text, Optional<Vector<WebCore::CompositionUnderline>>&&, Optional<WebKit::EditingRange>&&);
|
|
+
|
|
+WebKit::AcceleratedBackingStore* webkitWebViewBaseGetAcceleratedBackingStore(WebKitWebViewBase*);
|
|
diff --git a/Source/WebKit/UIProcess/API/gtk/webkit2.h b/Source/WebKit/UIProcess/API/gtk/webkit2.h
|
|
index c358118360a38c7b462227aa4ab8388bd7942c3e..70bdfbda231b481e8c5ac34fe6d8825f2350d71e 100644
|
|
--- a/Source/WebKit/UIProcess/API/gtk/webkit2.h
|
|
+++ b/Source/WebKit/UIProcess/API/gtk/webkit2.h
|
|
@@ -32,6 +32,7 @@
|
|
#include <webkit2/WebKitAutomationSession.h>
|
|
#include <webkit2/WebKitBackForwardList.h>
|
|
#include <webkit2/WebKitBackForwardListItem.h>
|
|
+#include <webkit2/WebKitBrowserInspector.h>
|
|
#include <webkit2/WebKitContextMenu.h>
|
|
#include <webkit2/WebKitContextMenuActions.h>
|
|
#include <webkit2/WebKitContextMenuItem.h>
|
|
diff --git a/Source/WebKit/UIProcess/API/wpe/PageClientImpl.cpp b/Source/WebKit/UIProcess/API/wpe/PageClientImpl.cpp
|
|
index 2e758227c7274e8a1297c35bfea7ffc2861f6759..160fbce41d7fb868fc8acaab815e7b80593865e6 100644
|
|
--- a/Source/WebKit/UIProcess/API/wpe/PageClientImpl.cpp
|
|
+++ b/Source/WebKit/UIProcess/API/wpe/PageClientImpl.cpp
|
|
@@ -194,7 +194,7 @@ WebCore::IntPoint PageClientImpl::accessibilityScreenToRootView(const WebCore::I
|
|
|
|
WebCore::IntRect PageClientImpl::rootViewToAccessibilityScreen(const WebCore::IntRect& rect)
|
|
{
|
|
- return rootViewToScreen(rect);
|
|
+ return rootViewToScreen(rect);
|
|
}
|
|
|
|
void PageClientImpl::doneWithKeyEvent(const NativeWebKeyboardEvent&, bool)
|
|
diff --git a/Source/WebKit/UIProcess/API/wpe/WebKitBrowserInspector.h b/Source/WebKit/UIProcess/API/wpe/WebKitBrowserInspector.h
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..cb1a540d341b07581ec87b922b7d007ce45ba989
|
|
--- /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(WEBKIT2_COMPILATION)
|
|
+#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 e0fc205b39095cf8aae201a1dcca520461c60de4..872186ad99a7b82f0c61705ff6c5ae4453e5e1d4 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;
|
|
+}
|
|
+
|
|
+cairo_surface_t* 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 6663964d5abac79e123d90e0351590884c66aa72..13ba5e7c3895c6e4efda95f1f90b9baea1c1bf30 100644
|
|
--- a/Source/WebKit/UIProcess/API/wpe/WebKitWebViewBackend.h
|
|
+++ b/Source/WebKit/UIProcess/API/wpe/WebKitWebViewBackend.h
|
|
@@ -27,6 +27,7 @@
|
|
#include <glib-object.h>
|
|
#include <wpe/WebKitDefines.h>
|
|
#include <wpe/wpe.h>
|
|
+#include <cairo.h>
|
|
|
|
G_BEGIN_DECLS
|
|
|
|
@@ -44,6 +45,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 cairo_surface_t* (*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..43690f9ef4969a39084501613bfc00a77fd5df49 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*);
|
|
+
|
|
+cairo_surface_t* webkitWebViewBackendTakeScreenshot(WebKitWebViewBackend*);
|
|
diff --git a/Source/WebKit/UIProcess/API/wpe/docs/wpe-1.0-sections.txt b/Source/WebKit/UIProcess/API/wpe/docs/wpe-1.0-sections.txt
|
|
index a4359531f9923623dec89161f7911f751b18505c..9208ccb61655e1aad6d70d63c6671351f196374f 100644
|
|
--- a/Source/WebKit/UIProcess/API/wpe/docs/wpe-1.0-sections.txt
|
|
+++ b/Source/WebKit/UIProcess/API/wpe/docs/wpe-1.0-sections.txt
|
|
@@ -315,6 +315,8 @@ WEBKIT_TYPE_WEB_VIEW_BACKEND
|
|
WebKitWebViewBackend
|
|
webkit_web_view_backend_get_wpe_backend
|
|
webkit_web_view_backend_new
|
|
+take_screenshot_callback
|
|
+webkit_web_view_backend_set_screenshot_callback
|
|
|
|
<SUBSECTION Private>
|
|
webkit_web_view_backend_get_type
|
|
diff --git a/Source/WebKit/UIProcess/API/wpe/webkit.h b/Source/WebKit/UIProcess/API/wpe/webkit.h
|
|
index 27c680d46428d349b0d1119f12da56ff283a60aa..1980aff7d662a1eea450d2db78b41f12a04f715e 100644
|
|
--- a/Source/WebKit/UIProcess/API/wpe/webkit.h
|
|
+++ b/Source/WebKit/UIProcess/API/wpe/webkit.h
|
|
@@ -32,6 +32,7 @@
|
|
#include <wpe/WebKitAutomationSession.h>
|
|
#include <wpe/WebKitBackForwardList.h>
|
|
#include <wpe/WebKitBackForwardListItem.h>
|
|
+#include <wpe/WebKitBrowserInspector.h>
|
|
#include <wpe/WebKitContextMenu.h>
|
|
#include <wpe/WebKitContextMenuActions.h>
|
|
#include <wpe/WebKitContextMenuItem.h>
|
|
diff --git a/Source/WebKit/UIProcess/BackingStore.h b/Source/WebKit/UIProcess/BackingStore.h
|
|
index fe3c63e61f778762dc2c2080c74ec53fdf8c2e5f..c43a8226c9be702e248f1712e465efa396ee8969 100644
|
|
--- a/Source/WebKit/UIProcess/BackingStore.h
|
|
+++ b/Source/WebKit/UIProcess/BackingStore.h
|
|
@@ -60,6 +60,7 @@ public:
|
|
|
|
#if USE(CAIRO)
|
|
typedef cairo_t* PlatformGraphicsContext;
|
|
+ cairo_surface_t* surface() const;
|
|
#elif USE(DIRECT2D)
|
|
struct DXConnections {
|
|
ID3D11DeviceContext1* immediateContext { nullptr };
|
|
diff --git a/Source/WebKit/UIProcess/BrowserInspectorPipe.cpp b/Source/WebKit/UIProcess/BrowserInspectorPipe.cpp
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..dc8af6fe1c57bcd62d605fd1daa3da13361858bb
|
|
--- /dev/null
|
|
+++ b/Source/WebKit/UIProcess/BrowserInspectorPipe.cpp
|
|
@@ -0,0 +1,57 @@
|
|
+/*
|
|
+ * 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 "RemoteInspectorPipe.h"
|
|
+#include <wtf/NeverDestroyed.h>
|
|
+#include "InspectorPlaywrightAgentClient.h"
|
|
+
|
|
+namespace WebKit {
|
|
+
|
|
+void initializeBrowserInspectorPipe(std::unique_ptr<InspectorPlaywrightAgentClient> client)
|
|
+{
|
|
+ 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/PopUpSOAuthorizationSession.h b/Source/WebKit/UIProcess/Cocoa/SOAuthorization/PopUpSOAuthorizationSession.h
|
|
index 454c61ffdefecc476d1560c7c43f5b5d345f281d..6de7509037b7683ddd403ee247bdf2845ce4e87a 100644
|
|
--- a/Source/WebKit/UIProcess/Cocoa/SOAuthorization/PopUpSOAuthorizationSession.h
|
|
+++ b/Source/WebKit/UIProcess/Cocoa/SOAuthorization/PopUpSOAuthorizationSession.h
|
|
@@ -27,6 +27,8 @@
|
|
|
|
#if HAVE(APP_SSO)
|
|
|
|
+#include <wtf/Forward.h>
|
|
+#include <wtf/CompletionHandler.h>
|
|
#include "SOAuthorizationSession.h"
|
|
#include <wtf/CompletionHandler.h>
|
|
|
|
@@ -39,6 +41,8 @@ class NavigationAction;
|
|
|
|
namespace WebKit {
|
|
|
|
+class WebPageProxy;
|
|
+
|
|
// FSM: Idle => Active => Completed
|
|
class PopUpSOAuthorizationSession final : public SOAuthorizationSession {
|
|
public:
|
|
diff --git a/Source/WebKit/UIProcess/Cocoa/SOAuthorization/PopUpSOAuthorizationSession.mm b/Source/WebKit/UIProcess/Cocoa/SOAuthorization/PopUpSOAuthorizationSession.mm
|
|
index 0f18038de989e69a8432c85b71b6c04e931302b3..82a966779403346aed174dcfcd01a79691956d7b 100644
|
|
--- a/Source/WebKit/UIProcess/Cocoa/SOAuthorization/PopUpSOAuthorizationSession.mm
|
|
+++ b/Source/WebKit/UIProcess/Cocoa/SOAuthorization/PopUpSOAuthorizationSession.mm
|
|
@@ -29,6 +29,7 @@
|
|
#if HAVE(APP_SSO)
|
|
|
|
#import "APINavigationAction.h"
|
|
+#import "WebPageProxy.h"
|
|
#import "WKNavigationDelegatePrivate.h"
|
|
#import "WKUIDelegate.h"
|
|
#import "WKWebViewConfigurationPrivate.h"
|
|
diff --git a/Source/WebKit/UIProcess/Cocoa/UIDelegate.h b/Source/WebKit/UIProcess/Cocoa/UIDelegate.h
|
|
index a49e65397f47572371833c5f75484cee1d3cb8d8..746335c1dfaa0ccb519e8b50a51e35dd89e7772f 100644
|
|
--- a/Source/WebKit/UIProcess/Cocoa/UIDelegate.h
|
|
+++ b/Source/WebKit/UIProcess/Cocoa/UIDelegate.h
|
|
@@ -91,6 +91,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, CompletionHandler<void(bool)>&&) final;
|
|
void decidePolicyForGeolocationPermissionRequest(WebPageProxy&, WebFrameProxy&, const FrameInfoData&, Function<void(bool)>&) final;
|
|
@@ -173,6 +174,7 @@ private:
|
|
bool webViewRunJavaScriptAlertPanelWithMessageInitiatedByFrameCompletionHandler : 1;
|
|
bool webViewRunJavaScriptConfirmPanelWithMessageInitiatedByFrameCompletionHandler : 1;
|
|
bool webViewRunJavaScriptTextInputPanelWithPromptDefaultTextInitiatedByFrameCompletionHandler : 1;
|
|
+ bool webViewHandleJavaScriptDialogValue : 1;
|
|
bool webViewRequestStorageAccessPanelUnderFirstPartyCompletionHandler : 1;
|
|
bool webViewRunBeforeUnloadConfirmPanelWithMessageInitiatedByFrameCompletionHandler : 1;
|
|
bool webViewRequestGeolocationPermissionForFrameDecisionHandler : 1;
|
|
diff --git a/Source/WebKit/UIProcess/Cocoa/UIDelegate.mm b/Source/WebKit/UIProcess/Cocoa/UIDelegate.mm
|
|
index 70ff0dbbdf0e8f88fbceec30b705571c96440910..40e32157fd5e9247e8e162ac9a797f67d8952b46 100644
|
|
--- a/Source/WebKit/UIProcess/Cocoa/UIDelegate.mm
|
|
+++ b/Source/WebKit/UIProcess/Cocoa/UIDelegate.mm
|
|
@@ -102,6 +102,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.webViewRunBeforeUnloadConfirmPanelWithMessageInitiatedByFrameCompletionHandler = [delegate respondsToSelector:@selector(_webView:runBeforeUnloadConfirmPanelWithMessage:initiatedByFrame:completionHandler:)];
|
|
m_delegateMethods.webViewRequestGeolocationPermissionForFrameDecisionHandler = [delegate respondsToSelector:@selector(_webView:requestGeolocationPermissionForFrame:decisionHandler:)];
|
|
@@ -342,6 +343,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 handleJavaScriptDialog:accept value:value];
|
|
+}
|
|
+
|
|
void UIDelegate::UIClient::requestStorageAccessConfirm(WebPageProxy&, WebFrameProxy*, const WebCore::RegistrableDomain& requestingDomain, const WebCore::RegistrableDomain& currentDomain, CompletionHandler<void(bool)>&& completionHandler)
|
|
{
|
|
auto delegate = m_uiDelegate.m_delegate.get();
|
|
diff --git a/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm b/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm
|
|
index cf755226ecb7408cf03d02fedc28e8e22abaa87b..7ece19b982049d9cb8543095df72795133d6599b 100644
|
|
--- a/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm
|
|
+++ b/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm
|
|
@@ -435,7 +435,7 @@ void WebProcessPool::platformInitializeWebProcess(const WebProcessProxy& process
|
|
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)
|
|
@@ -685,8 +685,8 @@ void WebProcessPool::registerNotificationObservers()
|
|
|
|
#if ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
|
|
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));
|
|
}];
|
|
#endif
|
|
|
|
diff --git a/Source/WebKit/UIProcess/Cocoa/WebViewImpl.h b/Source/WebKit/UIProcess/Cocoa/WebViewImpl.h
|
|
index 70084ece22ea8fb1ce6d4d6f4d0e4300d0b46781..11ec3abcf31e2e4b9e0c44bbee0c3f15ff248af0 100644
|
|
--- a/Source/WebKit/UIProcess/Cocoa/WebViewImpl.h
|
|
+++ b/Source/WebKit/UIProcess/Cocoa/WebViewImpl.h
|
|
@@ -491,6 +491,9 @@ public:
|
|
void provideDataForPasteboard(NSPasteboard *, NSString *type);
|
|
NSArray *namesOfPromisedFilesDroppedAtDestination(NSURL *dropDestination);
|
|
|
|
+// Paywright begin
|
|
+ RetainPtr<CGImageRef> takeSnapshotForAutomation();
|
|
+// Paywright end
|
|
RefPtr<ViewSnapshot> takeViewSnapshot();
|
|
void saveBackForwardSnapshotForCurrentItem();
|
|
void saveBackForwardSnapshotForItem(WebBackForwardListItem&);
|
|
diff --git a/Source/WebKit/UIProcess/Cocoa/WebViewImpl.mm b/Source/WebKit/UIProcess/Cocoa/WebViewImpl.mm
|
|
index 43ae7e0a29442007f252acea88b12505a809cc21..28fc130871a3584d95f14e1d667d743d5383c8cc 100644
|
|
--- a/Source/WebKit/UIProcess/Cocoa/WebViewImpl.mm
|
|
+++ b/Source/WebKit/UIProcess/Cocoa/WebViewImpl.mm
|
|
@@ -4511,6 +4511,18 @@ static RetainPtr<CGImageRef> takeWindowSnapshot(CGSWindowID windowID, bool captu
|
|
return adoptCF(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);
|
|
+}
|
|
+// Paywright end
|
|
+
|
|
RefPtr<ViewSnapshot> WebViewImpl::takeViewSnapshot()
|
|
{
|
|
NSWindow *window = [m_view window];
|
|
diff --git a/Source/WebKit/UIProcess/CoordinatedGraphics/DrawingAreaProxyCoordinatedGraphics.cpp b/Source/WebKit/UIProcess/CoordinatedGraphics/DrawingAreaProxyCoordinatedGraphics.cpp
|
|
index 61e3f6050d7f819a479cf511625320e3f6204ee9..58ad051d39fde5955fc68bdfa889600ed2059fb0 100644
|
|
--- a/Source/WebKit/UIProcess/CoordinatedGraphics/DrawingAreaProxyCoordinatedGraphics.cpp
|
|
+++ b/Source/WebKit/UIProcess/CoordinatedGraphics/DrawingAreaProxyCoordinatedGraphics.cpp
|
|
@@ -32,13 +32,16 @@
|
|
#include "DrawingAreaProxyMessages.h"
|
|
#include "LayerTreeContext.h"
|
|
#include "UpdateInfo.h"
|
|
+#include "WebPageInspectorController.h"
|
|
#include "WebPageProxy.h"
|
|
#include "WebPreferences.h"
|
|
#include "WebProcessProxy.h"
|
|
#include <WebCore/PlatformDisplay.h>
|
|
#include <WebCore/Region.h>
|
|
+#include <wtf/Vector.h>
|
|
|
|
#if PLATFORM(GTK)
|
|
+#include "WebKitWebViewBasePrivate.h"
|
|
#include <gtk/gtk.h>
|
|
#endif
|
|
|
|
@@ -51,6 +54,13 @@
|
|
#include <d3d11_1.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;
|
|
|
|
@@ -119,6 +129,10 @@ void DrawingAreaProxyCoordinatedGraphics::paint(BackingStore::PlatformGraphicsCo
|
|
|
|
void DrawingAreaProxyCoordinatedGraphics::sizeDidChange()
|
|
{
|
|
+ for (auto& value : m_callbacks)
|
|
+ value();
|
|
+ m_callbacks.clear();
|
|
+
|
|
#if USE(DIRECT2D)
|
|
m_backingStore = nullptr;
|
|
#endif
|
|
@@ -133,6 +147,11 @@ void DrawingAreaProxyCoordinatedGraphics::deviceScaleFactorDidChange()
|
|
backingStoreStateDidChange(RespondImmediately);
|
|
}
|
|
|
|
+void DrawingAreaProxyCoordinatedGraphics::waitForSizeUpdate(Function<void ()>&& callback)
|
|
+{
|
|
+ m_callbacks.append(WTFMove(callback));
|
|
+}
|
|
+
|
|
void DrawingAreaProxyCoordinatedGraphics::waitForBackingStoreUpdateOnNextPaint()
|
|
{
|
|
m_hasReceivedFirstUpdate = true;
|
|
@@ -238,6 +257,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(m_webPageProxy.viewWidget());
|
|
+ surface = adoptRef(cairo_win32_surface_create(dc));
|
|
+#else
|
|
+ if (isInAcceleratedCompositingMode()) {
|
|
+# if PLATFORM(GTK)
|
|
+ AcceleratedBackingStore* backingStore = webkitWebViewBaseGetAcceleratedBackingStore(WEBKIT_WEB_VIEW_BASE(m_webPageProxy.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;
|
|
+
|
|
+ m_webPageProxy.inspectorController().didPaint(surface.get());
|
|
+}
|
|
+#endif
|
|
+
|
|
#if !PLATFORM(WPE)
|
|
void DrawingAreaProxyCoordinatedGraphics::incorporateUpdate(const UpdateInfo& updateInfo)
|
|
{
|
|
diff --git a/Source/WebKit/UIProcess/CoordinatedGraphics/DrawingAreaProxyCoordinatedGraphics.h b/Source/WebKit/UIProcess/CoordinatedGraphics/DrawingAreaProxyCoordinatedGraphics.h
|
|
index d7695088e7cfc4f638f157338754f9f157489749..f99c2b7c2a2b5fa666aa7db96a124717eee0e922 100644
|
|
--- a/Source/WebKit/UIProcess/CoordinatedGraphics/DrawingAreaProxyCoordinatedGraphics.h
|
|
+++ b/Source/WebKit/UIProcess/CoordinatedGraphics/DrawingAreaProxyCoordinatedGraphics.h
|
|
@@ -30,6 +30,7 @@
|
|
#include "BackingStore.h"
|
|
#include "DrawingAreaProxy.h"
|
|
#include "LayerTreeContext.h"
|
|
+#include <wtf/Function.h>
|
|
#include <wtf/RunLoop.h>
|
|
|
|
namespace WebCore {
|
|
@@ -49,6 +50,10 @@ public:
|
|
|
|
bool isInAcceleratedCompositingMode() const { return !m_layerTreeContext.isEmpty(); }
|
|
const LayerTreeContext& layerTreeContext() const { return m_layerTreeContext; }
|
|
+ void waitForSizeUpdate(Function<void ()>&&);
|
|
+#if !PLATFORM(WPE)
|
|
+ void captureFrame();
|
|
+#endif
|
|
|
|
private:
|
|
// DrawingAreaProxy
|
|
@@ -63,6 +68,9 @@ private:
|
|
void enterAcceleratedCompositingMode(uint64_t backingStoreStateID, const LayerTreeContext&) override;
|
|
void exitAcceleratedCompositingMode(uint64_t backingStoreStateID, const UpdateInfo&) override;
|
|
void updateAcceleratedCompositingMode(uint64_t backingStoreStateID, const LayerTreeContext&) override;
|
|
+#if PLATFORM(WIN)
|
|
+ void didChangeAcceleratedCompositingMode(bool enabled) override;
|
|
+#endif
|
|
|
|
#if !PLATFORM(WPE)
|
|
void incorporateUpdate(const UpdateInfo&);
|
|
@@ -126,12 +134,18 @@ private:
|
|
// For a new Drawing Area don't draw anything until the WebProcess has sent over the first content.
|
|
bool m_hasReceivedFirstUpdate { false };
|
|
|
|
+ Vector<Function<void ()>> m_callbacks;
|
|
+
|
|
#if !PLATFORM(WPE)
|
|
bool m_isBackingStoreDiscardable { true };
|
|
std::unique_ptr<BackingStore> m_backingStore;
|
|
RunLoop::Timer<DrawingAreaProxyCoordinatedGraphics> 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 9d3bc3860931a9f8e744e8155e727a6bca387b51..f7ae34eb674f5f442adbacde8c0f9b202593b405 100644
|
|
--- a/Source/WebKit/UIProcess/Downloads/DownloadProxy.cpp
|
|
+++ b/Source/WebKit/UIProcess/Downloads/DownloadProxy.cpp
|
|
@@ -42,8 +42,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>
|
|
|
|
namespace WebKit {
|
|
using namespace WebCore;
|
|
@@ -56,7 +58,10 @@ DownloadProxy::DownloadProxy(DownloadProxyMap& downloadProxyMap, WebsiteDataStor
|
|
, m_request(resourceRequest)
|
|
, m_originatingPage(makeWeakPtr(originatingPage))
|
|
, m_frameInfo(API::FrameInfo::create(FrameInfoData { frameInfoData }, originatingPage))
|
|
+ , m_uuid(createCanonicalUUIDString())
|
|
{
|
|
+ if (auto* instrumentation = m_dataStore->downloadInstrumentation())
|
|
+ instrumentation->downloadCreated(m_uuid, m_request, frameInfoData, originatingPage);
|
|
}
|
|
|
|
DownloadProxy::~DownloadProxy() = default;
|
|
@@ -139,6 +144,20 @@ void DownloadProxy::didReceiveData(uint64_t bytesWritten, uint64_t totalBytesWri
|
|
|
|
void DownloadProxy::decideDestinationWithSuggestedFilename(const String& suggestedFilename, CompletionHandler<void(String, SandboxExtension::Handle, AllowOverwrite)>&& completionHandler)
|
|
{
|
|
+ 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);
|
|
+ SandboxExtension::createHandle(destination, SandboxExtension::Type::ReadWrite, sandboxExtensionHandle);
|
|
+ }
|
|
+ completionHandler(destination, WTFMove(sandboxExtensionHandle), AllowOverwrite::Yes);
|
|
+ return;
|
|
+ }
|
|
+
|
|
m_client->decideDestinationWithSuggestedFilename(*this, ResourceResponseBase::sanitizeSuggestedFilename(suggestedFilename), [completionHandler = WTFMove(completionHandler)] (AllowOverwrite allowOverwrite, String destination) mutable {
|
|
SandboxExtension::Handle sandboxExtensionHandle;
|
|
if (!destination.isNull())
|
|
@@ -156,6 +175,8 @@ void DownloadProxy::didCreateDestination(const String& path)
|
|
void DownloadProxy::didFinish()
|
|
{
|
|
m_client->didFinish(*this);
|
|
+ if (auto* instrumentation = m_dataStore->downloadInstrumentation())
|
|
+ instrumentation->downloadFinished(m_uuid, String());
|
|
|
|
// This can cause the DownloadProxy object to be deleted.
|
|
m_downloadProxyMap.downloadFinished(*this);
|
|
@@ -174,6 +195,8 @@ void DownloadProxy::didFail(const ResourceError& error, const IPC::DataReference
|
|
m_resumeData = createData(resumeData);
|
|
|
|
m_client->didFail(*this, error);
|
|
+ if (auto* instrumentation = m_dataStore->downloadInstrumentation())
|
|
+ instrumentation->downloadFinished(m_uuid, error.localizedDescription());
|
|
|
|
// This can cause the DownloadProxy object to be deleted.
|
|
m_downloadProxyMap.downloadFinished(*this);
|
|
@@ -184,6 +207,8 @@ void DownloadProxy::didCancel(const IPC::DataReference& resumeData)
|
|
m_resumeData = createData(resumeData);
|
|
|
|
m_client->didCancel(*this);
|
|
+ if (auto* instrumentation = m_dataStore->downloadInstrumentation())
|
|
+ instrumentation->downloadFinished(m_uuid, "canceled"_s);
|
|
|
|
// This can cause the DownloadProxy object to be deleted.
|
|
m_downloadProxyMap.downloadFinished(*this);
|
|
diff --git a/Source/WebKit/UIProcess/Downloads/DownloadProxy.h b/Source/WebKit/UIProcess/Downloads/DownloadProxy.h
|
|
index 3e7408c1ebedea4e7af2d9b9bb1d92095ffc360f..1ae01582255c5d295ce90ee19cb1c5d21082597f 100644
|
|
--- a/Source/WebKit/UIProcess/Downloads/DownloadProxy.h
|
|
+++ b/Source/WebKit/UIProcess/Downloads/DownloadProxy.h
|
|
@@ -134,6 +134,7 @@ private:
|
|
Vector<URL> m_redirectChain;
|
|
bool m_wasUserInitiated { true };
|
|
Ref<API::FrameInfo> m_frameInfo;
|
|
+ String m_uuid;
|
|
};
|
|
|
|
} // namespace WebKit
|
|
diff --git a/Source/WebKit/UIProcess/DrawingAreaProxy.h b/Source/WebKit/UIProcess/DrawingAreaProxy.h
|
|
index 59cdfdafab1d85ea3a5aecb3cd2293e6dfb1eb8d..2c9d8122919bed0b6d7e6f600e5b0c0f9732d1ff 100644
|
|
--- a/Source/WebKit/UIProcess/DrawingAreaProxy.h
|
|
+++ b/Source/WebKit/UIProcess/DrawingAreaProxy.h
|
|
@@ -75,6 +75,7 @@ public:
|
|
|
|
const WebCore::IntSize& size() const { return m_size; }
|
|
bool setSize(const WebCore::IntSize&, const WebCore::IntSize& scrollOffset = { });
|
|
+ void waitForSizeUpdate(Function<void ()>&&);
|
|
|
|
#if USE(COORDINATED_GRAPHICS) || USE(TEXTURE_MAPPER)
|
|
// The timeout we use when waiting for a DidUpdateGeometry message.
|
|
@@ -160,6 +161,9 @@ private:
|
|
virtual void update(uint64_t /* backingStoreStateID */, const UpdateInfo&) { }
|
|
virtual void didUpdateBackingStoreState(uint64_t /* backingStoreStateID */, const UpdateInfo&, const LayerTreeContext&) { }
|
|
virtual void exitAcceleratedCompositingMode(uint64_t /* backingStoreStateID */, const UpdateInfo&) { }
|
|
+#endif
|
|
+#if PLATFORM(WIN)
|
|
+ virtual void didChangeAcceleratedCompositingMode(bool) { }
|
|
#endif
|
|
bool m_startedReceivingMessages { false };
|
|
};
|
|
diff --git a/Source/WebKit/UIProcess/DrawingAreaProxy.messages.in b/Source/WebKit/UIProcess/DrawingAreaProxy.messages.in
|
|
index b0722e7da81e56530deb570b82ed7cfece970362..05ec3e3ea97ba49135a27d7f9b91f14c507d9318 100644
|
|
--- a/Source/WebKit/UIProcess/DrawingAreaProxy.messages.in
|
|
+++ b/Source/WebKit/UIProcess/DrawingAreaProxy.messages.in
|
|
@@ -36,4 +36,7 @@ messages -> DrawingAreaProxy NotRefCounted {
|
|
DidUpdateBackingStoreState(uint64_t backingStoreStateID, WebKit::UpdateInfo updateInfo, WebKit::LayerTreeContext context)
|
|
ExitAcceleratedCompositingMode(uint64_t backingStoreStateID, WebKit::UpdateInfo updateInfo)
|
|
#endif
|
|
+#if PLATFORM(WIN)
|
|
+ DidChangeAcceleratedCompositingMode(bool enabled)
|
|
+#endif
|
|
}
|
|
diff --git a/Source/WebKit/UIProcess/Inspector/Agents/InspectorScreencastAgent.cpp b/Source/WebKit/UIProcess/Inspector/Agents/InspectorScreencastAgent.cpp
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..3873c71090213157a982c0d20316428de098c77b
|
|
--- /dev/null
|
|
+++ b/Source/WebKit/UIProcess/Inspector/Agents/InspectorScreencastAgent.cpp
|
|
@@ -0,0 +1,168 @@
|
|
+/*
|
|
+ * 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 "GenericCallback.h"
|
|
+#include "PageClient.h"
|
|
+#include "ScreencastEncoder.h"
|
|
+#include "WebPageInspectorController.h"
|
|
+#include "WebPageProxy.h"
|
|
+#include "WebsiteDataStore.h"
|
|
+#include <JavaScriptCore/InspectorFrontendDispatchers.h>
|
|
+#include <JavaScriptCore/InspectorFrontendRouter.h>
|
|
+#include <WebCore/NotImplemented.h>
|
|
+#include <wtf/RunLoop.h>
|
|
+#include <wtf/UUID.h>
|
|
+
|
|
+#if USE(CAIRO)
|
|
+#include "DrawingAreaProxyCoordinatedGraphics.h"
|
|
+#include "DrawingAreaProxy.h"
|
|
+#endif
|
|
+
|
|
+namespace WebKit {
|
|
+
|
|
+using namespace Inspector;
|
|
+
|
|
+InspectorScreencastAgent::InspectorScreencastAgent(BackendDispatcher& backendDispatcher, Inspector::FrontendRouter& frontendRouter, WebPageProxy& page)
|
|
+ : InspectorAgentBase("Screencast"_s)
|
|
+ , 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(CAIRO)
|
|
+void InspectorScreencastAgent::didPaint(cairo_surface_t* surface)
|
|
+{
|
|
+ if (m_encoder)
|
|
+ m_encoder->encodeFrame(surface, m_page.drawingArea()->size());
|
|
+}
|
|
+#endif
|
|
+
|
|
+Inspector::Protocol::ErrorStringOr<String /* screencastID */> InspectorScreencastAgent::start(const String& file, int width, int height, Optional<double>&& scale)
|
|
+{
|
|
+ if (m_encoder)
|
|
+ return makeUnexpected("Already recording"_s);
|
|
+
|
|
+ if (width < 10 || width > 10000 || height < 10 || height > 10000)
|
|
+ return makeUnexpected("Invalid size"_s);
|
|
+
|
|
+ if (scale && (*scale <= 0 || *scale > 1))
|
|
+ return makeUnexpected("Unsupported scale"_s);
|
|
+
|
|
+ String errorString;
|
|
+ m_encoder = ScreencastEncoder::create(errorString, file, WebCore::IntSize(width, height), WTFMove(scale));
|
|
+ if (!m_encoder)
|
|
+ return makeUnexpected(errorString);
|
|
+
|
|
+ m_currentScreencastID = createCanonicalUUIDString();
|
|
+
|
|
+#if PLATFORM(MAC)
|
|
+ m_encoder->setOffsetTop(m_page.pageClient().browserToolbarHeight());
|
|
+#endif
|
|
+#if !PLATFORM(WPE)
|
|
+ scheduleFrameEncoding();
|
|
+#endif
|
|
+ // Force at least one frame on WPE.
|
|
+ m_page.forceRepaint(VoidCallback::create([] (CallbackBase::Error) { }));
|
|
+
|
|
+ return { { m_currentScreencastID } };
|
|
+}
|
|
+
|
|
+void InspectorScreencastAgent::stop(Ref<StopCallback>&& 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 !PLATFORM(WPE)
|
|
+void InspectorScreencastAgent::scheduleFrameEncoding()
|
|
+{
|
|
+ if (!m_encoder)
|
|
+ return;
|
|
+
|
|
+ RunLoop::main().dispatchAfter(Seconds(1.0 / 24), [agent = makeWeakPtr(this)]() mutable {
|
|
+ if (!agent)
|
|
+ return;
|
|
+
|
|
+ agent->encodeFrame();
|
|
+ agent->scheduleFrameEncoding();
|
|
+ });
|
|
+}
|
|
+#endif
|
|
+
|
|
+#if PLATFORM(MAC)
|
|
+void InspectorScreencastAgent::encodeFrame()
|
|
+{
|
|
+ if (m_encoder)
|
|
+ m_encoder->encodeFrame(m_page.pageClient().takeSnapshotForAutomation());
|
|
+}
|
|
+#endif
|
|
+
|
|
+#if USE(CAIRO) && !PLATFORM(WPE)
|
|
+void InspectorScreencastAgent::encodeFrame()
|
|
+{
|
|
+ if (!m_encoder)
|
|
+ return;
|
|
+
|
|
+ if (auto* drawingArea = m_page.drawingArea())
|
|
+ static_cast<DrawingAreaProxyCoordinatedGraphics*>(drawingArea)->captureFrame();
|
|
+}
|
|
+#endif
|
|
+
|
|
+} // namespace WebKit
|
|
diff --git a/Source/WebKit/UIProcess/Inspector/Agents/InspectorScreencastAgent.h b/Source/WebKit/UIProcess/Inspector/Agents/InspectorScreencastAgent.h
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..0d4a837cbb0bbba71e32ed083a4c4cfe9b5e4a27
|
|
--- /dev/null
|
|
+++ b/Source/WebKit/UIProcess/Inspector/Agents/InspectorScreencastAgent.h
|
|
@@ -0,0 +1,77 @@
|
|
+/*
|
|
+ * 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 <wtf/Forward.h>
|
|
+#include <wtf/Noncopyable.h>
|
|
+#include <wtf/WeakPtr.h>
|
|
+
|
|
+namespace Inspector {
|
|
+class BackendDispatcher;
|
|
+class FrontendChannel;
|
|
+class FrontendRouter;
|
|
+class ScreencastFrontendDispatcher;
|
|
+}
|
|
+
|
|
+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(CAIRO)
|
|
+ void didPaint(cairo_surface_t*);
|
|
+#endif
|
|
+
|
|
+ Inspector::Protocol::ErrorStringOr<String /* screencastID */> start(const String& file, int width, int height, Optional<double>&& scale) override;
|
|
+ void stop(Ref<StopCallback>&&) override;
|
|
+
|
|
+
|
|
+private:
|
|
+#if !PLATFORM(WPE)
|
|
+ void scheduleFrameEncoding();
|
|
+ void encodeFrame();
|
|
+#endif
|
|
+
|
|
+ Ref<Inspector::ScreencastBackendDispatcher> m_backendDispatcher;
|
|
+ WebPageProxy& m_page;
|
|
+ RefPtr<ScreencastEncoder> m_encoder;
|
|
+ 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..3e9eb9575bb19486ff9d1cefa3dec19a4f804673
|
|
--- /dev/null
|
|
+++ b/Source/WebKit/UIProcess/Inspector/Agents/ScreencastEncoder.cpp
|
|
@@ -0,0 +1,389 @@
|
|
+/*
|
|
+ * 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/RunLoop.h>
|
|
+#include <wtf/UniqueArray.h>
|
|
+#include <wtf/WorkQueue.h>
|
|
+#include <wtf/text/StringConcatenateNumbers.h>
|
|
+
|
|
+#if USE(CAIRO)
|
|
+#include <WebCore/RefPtrCairo.h>
|
|
+#endif
|
|
+
|
|
+using namespace WebCore;
|
|
+
|
|
+namespace WebKit {
|
|
+
|
|
+namespace {
|
|
+// 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(CAIRO)
|
|
+ explicit VPXFrame(RefPtr<cairo_surface_t>&& surface)
|
|
+ : m_surface(WTFMove(surface))
|
|
+ { }
|
|
+#elif PLATFORM(MAC)
|
|
+ VPXFrame(RetainPtr<CGImageRef> windowImage, Optional<double> scale, int offsetTop)
|
|
+ : m_windowImage(WTFMove(windowImage))
|
|
+ , m_scale(scale)
|
|
+ , m_offsetTop(offsetTop)
|
|
+ { }
|
|
+#endif
|
|
+
|
|
+ void setDuration(int duration) { m_duration = duration; }
|
|
+ int duration() const { return m_duration; }
|
|
+
|
|
+ void convertToVpxImage(vpx_image_t* image)
|
|
+ {
|
|
+#if USE(CAIRO)
|
|
+ // 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_scale, 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(CAIRO)
|
|
+ RefPtr<cairo_surface_t> m_surface;
|
|
+#elif PLATFORM(MAC)
|
|
+ RetainPtr<CGImageRef> m_windowImage;
|
|
+ Optional<double> m_scale;
|
|
+ int m_offsetTop { 0 };
|
|
+#endif
|
|
+ int m_duration = 0;
|
|
+};
|
|
+
|
|
+
|
|
+class ScreencastEncoder::VPXCodec {
|
|
+public:
|
|
+ VPXCodec(vpx_codec_ctx_t codec, vpx_codec_enc_cfg_t cfg, FILE* file)
|
|
+ : m_encoderQueue(WorkQueue::create("Screencast encoder"))
|
|
+ , m_codec(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());
|
|
+ // TODO: figure out why simply passing duration doesn't work well.
|
|
+ for (int i = 0; i < frame->duration(); i++)
|
|
+ encodeFrame(m_image.get(), 1);
|
|
+ });
|
|
+ }
|
|
+
|
|
+ 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, 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));
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ bool gotPkts = false;
|
|
+ while ((pkt = vpx_codec_get_cx_data(&m_codec, &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;
|
|
+ }
|
|
+ bool keyframe = (pkt->data.frame.flags & VPX_FRAME_IS_KEY) != 0;
|
|
+ ++m_frameCount;
|
|
+ fprintf(stderr, " #%03d %spts=%" PRId64 " sz=%zd\n", m_frameCount, keyframe ? "[K] " : "", pkt->data.frame.pts, pkt->data.frame.sz);
|
|
+ m_pts += pkt->data.frame.duration;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return gotPkts;
|
|
+ }
|
|
+
|
|
+ void finish()
|
|
+ {
|
|
+ // Flush encoder.
|
|
+ while (encodeFrame(nullptr, 1))
|
|
+ ++m_frameCount;
|
|
+
|
|
+ m_writer->finish();
|
|
+ fclose(m_file);
|
|
+ fprintf(stderr, "ScreencastEncoder::finish %d frames\n", m_frameCount);
|
|
+ }
|
|
+
|
|
+ Ref<WorkQueue> m_encoderQueue;
|
|
+ vpx_codec_ctx_t 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, Optional<double> scale)
|
|
+ : m_vpxCodec(WTFMove(vpxCodec))
|
|
+ , m_size(size)
|
|
+ , m_scale(scale)
|
|
+{
|
|
+ ASSERT(!size.isZero());
|
|
+}
|
|
+
|
|
+ScreencastEncoder::~ScreencastEncoder()
|
|
+{
|
|
+}
|
|
+
|
|
+static constexpr int fps = 24;
|
|
+
|
|
+RefPtr<ScreencastEncoder> ScreencastEncoder::create(String& errorString, const String& filePath, IntSize size, Optional<double> scale)
|
|
+{
|
|
+ vpx_codec_iface_t* codec_interface = vpx_codec_vp8_cx();
|
|
+ if (!codec_interface) {
|
|
+ errorString = "Codec not found.";
|
|
+ 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, 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;
|
|
+ cfg.g_error_resilient = VPX_ERROR_RESILIENT_DEFAULT;
|
|
+
|
|
+ vpx_codec_ctx_t codec;
|
|
+ if (vpx_codec_enc_init(&codec, codec_interface, &cfg, 0)) {
|
|
+ errorString = makeString("Failed to initialize encoder: "_s, vpx_codec_error(&codec));
|
|
+ return nullptr;
|
|
+ }
|
|
+
|
|
+ FILE* file = fopen(filePath.utf8().data(), "wb");
|
|
+ if (!file) {
|
|
+ errorString = makeString("Failed to open file '", filePath, "' for writing: ", strerror(errno));
|
|
+ return nullptr;
|
|
+ }
|
|
+
|
|
+ std::unique_ptr<VPXCodec> vpxCodec(new VPXCodec(codec, cfg, file));
|
|
+ fprintf(stderr, "ScreencastEncoder initialized with: %s\n", vpx_codec_iface_name(codec_interface));
|
|
+ return adoptRef(new ScreencastEncoder(WTFMove(vpxCodec), size, scale));
|
|
+}
|
|
+
|
|
+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;
|
|
+ int duration = 1 + seconds.seconds() * fps; // Duration in timebase units
|
|
+ m_lastFrame->setDuration(duration);
|
|
+ m_vpxCodec->encodeFrameAsync(WTFMove(m_lastFrame));
|
|
+ }
|
|
+ m_lastFrameTimestamp = now;
|
|
+}
|
|
+
|
|
+#if USE(CAIRO)
|
|
+void ScreencastEncoder::encodeFrame(cairo_surface_t* drawingAreaSurface, IntSize size)
|
|
+{
|
|
+ fprintf(stderr, "ScreencastEncoder::encodeFrame\n");
|
|
+ flushLastFrame();
|
|
+ // Note that in WPE drawing area size is updated asynchronously and may differ from acutal
|
|
+ // size of the surface.
|
|
+ if (size.isZero()) {
|
|
+ fprintf(stderr, "Cairo surface size is 0\n");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ // TODO: adjust device scale factor?
|
|
+ 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()));
|
|
+
|
|
+ // TODO: compare to libyuv scale functions?
|
|
+ cairo_matrix_t transform;
|
|
+ if (m_scale) {
|
|
+ cairo_matrix_init_scale(&transform, *m_scale, *m_scale);
|
|
+ cairo_transform(cr.get(), &transform);
|
|
+ } else 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)
|
|
+{
|
|
+ fprintf(stderr, "ScreencastEncoder::encodeFrame\n");
|
|
+ flushLastFrame();
|
|
+
|
|
+ m_lastFrame = makeUnique<VPXFrame>(WTFMove(windowImage), m_scale, m_offsetTop);
|
|
+}
|
|
+#endif
|
|
+
|
|
+void ScreencastEncoder::finish(Function<void()>&& callback)
|
|
+{
|
|
+ if (!m_vpxCodec) {
|
|
+ callback();
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ flushLastFrame();
|
|
+ m_vpxCodec->finishAsync([protectRef = makeRef(*this), callback = WTFMove(callback)] () mutable {
|
|
+ RunLoop::main().dispatch([callback = WTFMove(callback)] {
|
|
+ callback();
|
|
+ });
|
|
+ });
|
|
+}
|
|
+
|
|
+
|
|
+} // namespace WebKit
|
|
diff --git a/Source/WebKit/UIProcess/Inspector/Agents/ScreencastEncoder.h b/Source/WebKit/UIProcess/Inspector/Agents/ScreencastEncoder.h
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..0e2f2d42cf398bee37ab27bda765be978be81f0d
|
|
--- /dev/null
|
|
+++ b/Source/WebKit/UIProcess/Inspector/Agents/ScreencastEncoder.h
|
|
@@ -0,0 +1,79 @@
|
|
+/*
|
|
+ * 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)
|
|
+#include <cairo.h>
|
|
+#endif
|
|
+
|
|
+namespace WebKit {
|
|
+
|
|
+class WebPageProxy;
|
|
+
|
|
+class ScreencastEncoder : public ThreadSafeRefCounted<ScreencastEncoder> {
|
|
+ WTF_MAKE_NONCOPYABLE(ScreencastEncoder);
|
|
+ WTF_MAKE_FAST_ALLOCATED;
|
|
+public:
|
|
+ static RefPtr<ScreencastEncoder> create(String& errorString, const String& filePath, WebCore::IntSize, Optional<double> scale);
|
|
+
|
|
+ class VPXCodec;
|
|
+ ScreencastEncoder(std::unique_ptr<VPXCodec>&&, WebCore::IntSize, Optional<double> scale);
|
|
+ ~ScreencastEncoder();
|
|
+
|
|
+#if USE(CAIRO)
|
|
+ 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, Optional<double> scale, int offsetTop);
|
|
+#endif
|
|
+
|
|
+ std::unique_ptr<VPXCodec> m_vpxCodec;
|
|
+ const WebCore::IntSize m_size;
|
|
+ Optional<double> m_scale;
|
|
+ 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 6928ca2fbfb6939062e3cd14bb7ba6f2fdc87f5f..621b99e233ed5cf504fedbd3ca3209c03bcd611f 100644
|
|
--- a/Source/WebKit/UIProcess/Inspector/InspectorTargetProxy.cpp
|
|
+++ b/Source/WebKit/UIProcess/Inspector/InspectorTargetProxy.cpp
|
|
@@ -27,11 +27,10 @@
|
|
#include "InspectorTargetProxy.h"
|
|
|
|
#include "ProvisionalPageProxy.h"
|
|
-#include "WebFrameProxy.h"
|
|
+#include "WebPageInspectorController.h"
|
|
#include "WebPageInspectorTarget.h"
|
|
#include "WebPageMessages.h"
|
|
#include "WebPageProxy.h"
|
|
-#include "WebProcessProxy.h"
|
|
|
|
namespace WebKit {
|
|
|
|
@@ -39,18 +38,17 @@ using namespace Inspector;
|
|
|
|
std::unique_ptr<InspectorTargetProxy> InspectorTargetProxy::create(WebPageProxy& page, const String& targetId, Inspector::InspectorTargetType type)
|
|
{
|
|
- return makeUnique<InspectorTargetProxy>(page, targetId, type);
|
|
+ return makeUnique<InspectorTargetProxy>(page, nullptr, 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)
|
|
{
|
|
- auto target = InspectorTargetProxy::create(provisionalPage.page(), targetId, type);
|
|
- target->m_provisionalPage = makeWeakPtr(provisionalPage);
|
|
- return target;
|
|
+ return makeUnique<InspectorTargetProxy>(provisionalPage.page(), &provisionalPage, targetId, Inspector::InspectorTargetType::Page);
|
|
}
|
|
|
|
-InspectorTargetProxy::InspectorTargetProxy(WebPageProxy& page, const String& targetId, Inspector::InspectorTargetType type)
|
|
+InspectorTargetProxy::InspectorTargetProxy(WebPageProxy& page, ProvisionalPageProxy* provisionalPage, const String& targetId, Inspector::InspectorTargetType type)
|
|
: m_page(page)
|
|
+ , m_provisionalPage(makeWeakPtr(provisionalPage))
|
|
, m_identifier(targetId)
|
|
, m_type(type)
|
|
{
|
|
@@ -97,6 +95,31 @@ void InspectorTargetProxy::didCommitProvisionalTarget()
|
|
m_provisionalPage = nullptr;
|
|
}
|
|
|
|
+void InspectorTargetProxy::willResume()
|
|
+{
|
|
+ if (m_page.hasRunningProcess())
|
|
+ m_page.send(Messages::WebPage::ResumeInspectorIfPausedInNewWindow());
|
|
+}
|
|
+
|
|
+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 a2239cec8e18850f35f7f88a9c4ebadc62bf4023..79f3ff84327dc075ec96983e04db4b10343b7fae 100644
|
|
--- a/Source/WebKit/UIProcess/Inspector/InspectorTargetProxy.h
|
|
+++ b/Source/WebKit/UIProcess/Inspector/InspectorTargetProxy.h
|
|
@@ -37,13 +37,13 @@ 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_FAST_ALLOCATED;
|
|
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);
|
|
- InspectorTargetProxy(WebPageProxy&, const String& targetId, Inspector::InspectorTargetType);
|
|
+ static std::unique_ptr<InspectorTargetProxy> create(ProvisionalPageProxy&, const String& targetId);
|
|
+ InspectorTargetProxy(WebPageProxy&, ProvisionalPageProxy*, const String& targetId, Inspector::InspectorTargetType);
|
|
~InspectorTargetProxy() = default;
|
|
|
|
Inspector::InspectorTargetType type() const final { return m_type; }
|
|
@@ -55,12 +55,17 @@ 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;
|
|
+
|
|
WebPageProxy& m_page;
|
|
+ WeakPtr<ProvisionalPageProxy> m_provisionalPage;
|
|
String m_identifier;
|
|
Inspector::InspectorTargetType m_type;
|
|
- WeakPtr<ProvisionalPageProxy> m_provisionalPage;
|
|
};
|
|
|
|
} // namespace WebKit
|
|
diff --git a/Source/WebKit/UIProcess/Inspector/WebPageInspectorController.cpp b/Source/WebKit/UIProcess/Inspector/WebPageInspectorController.cpp
|
|
index 1861cff806131196ea49b4f8aca6665beebbf6e8..901c0fdd6bc1bd62b078a07cc9dd3a4c46c2bfd8 100644
|
|
--- a/Source/WebKit/UIProcess/Inspector/WebPageInspectorController.cpp
|
|
+++ b/Source/WebKit/UIProcess/Inspector/WebPageInspectorController.cpp
|
|
@@ -26,12 +26,20 @@
|
|
#include "config.h"
|
|
#include "WebPageInspectorController.h"
|
|
|
|
+#include "APINavigation.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>
|
|
@@ -48,27 +56,108 @@ static String getTargetID(const ProvisionalPageProxy& provisionalPage)
|
|
return WebPageInspectorTarget::toTargetID(provisionalPage.webPageID());
|
|
}
|
|
|
|
+WebPageInspectorControllerObserver* WebPageInspectorController::s_observer = nullptr;
|
|
+
|
|
+void WebPageInspectorController::setObserver(WebPageInspectorControllerObserver* observer)
|
|
+{
|
|
+ s_observer = observer;
|
|
+}
|
|
+
|
|
+WebPageInspectorControllerObserver* WebPageInspectorController::observer() {
|
|
+ return s_observer;
|
|
+}
|
|
+
|
|
WebPageInspectorController::WebPageInspectorController(WebPageProxy& page)
|
|
: m_frontendRouter(FrontendRouter::create())
|
|
, m_backendDispatcher(BackendDispatcher::create(m_frontendRouter.copyRef()))
|
|
, m_page(page)
|
|
{
|
|
- auto targetAgent = makeUnique<InspectorTargetAgent>(m_frontendRouter.get(), m_backendDispatcher.get());
|
|
- m_targetAgent = targetAgent.get();
|
|
- m_agents.append(WTFMove(targetAgent));
|
|
}
|
|
|
|
void WebPageInspectorController::init()
|
|
{
|
|
+ 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_page);
|
|
+ m_emulationAgent = emulationAgent.get();
|
|
+ m_agents.append(WTFMove(emulationAgent));
|
|
+ auto inputAgent = makeUnique<WebPageInspectorInputAgent>(m_backendDispatcher.get(), m_page);
|
|
+ m_inputAgent = inputAgent.get();
|
|
+ m_agents.append(WTFMove(inputAgent));
|
|
+ m_agents.append(makeUnique<InspectorDialogAgent>(m_backendDispatcher.get(), m_frontendRouter.get(), m_page));
|
|
+ auto screencastAgent = makeUnique<InspectorScreencastAgent>(m_backendDispatcher.get(), m_frontendRouter.get(), m_page);
|
|
+ m_screecastAgent = screencastAgent.get();
|
|
+ m_agents.append(WTFMove(screencastAgent));
|
|
+ if (s_observer)
|
|
+ s_observer->didCreateInspectorController(m_page);
|
|
+
|
|
+ // window.open will create page with already running process.
|
|
+ if (!m_page.hasRunningProcess())
|
|
+ return;
|
|
String pageTargetId = WebPageInspectorTarget::toTargetID(m_page.webPageID());
|
|
createInspectorTarget(pageTargetId, Inspector::InspectorTargetType::Page);
|
|
}
|
|
|
|
+void WebPageInspectorController::didFinishAttachingToWebProcess()
|
|
+{
|
|
+ String pageTargetID = WebPageInspectorTarget::toTargetID(m_page.webPageID());
|
|
+ // 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_page.webPageID());
|
|
+ destroyInspectorTarget(pageTargetId);
|
|
+
|
|
disconnectAllFrontends();
|
|
|
|
m_agents.discardValues();
|
|
+
|
|
+ if (s_observer)
|
|
+ s_observer->willDestroyInspectorController(m_page);
|
|
+}
|
|
+
|
|
+bool WebPageInspectorController::pageCrashed(ProcessTerminationReason reason)
|
|
+{
|
|
+ if (reason != ProcessTerminationReason::Crash)
|
|
+ return false;
|
|
+ String targetId = WebPageInspectorTarget::toTargetID(m_page.webPageID());
|
|
+ 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_page, 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();
|
|
}
|
|
|
|
bool WebPageInspectorController::hasLocalFrontend() const
|
|
@@ -82,6 +171,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)
|
|
@@ -100,8 +200,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();
|
|
+ }
|
|
|
|
m_page.didChangeInspectorFrontendCount(m_frontendRouter->frontendCount());
|
|
|
|
@@ -124,6 +226,8 @@ void WebPageInspectorController::disconnectAllFrontends()
|
|
// Disconnect any remaining remote frontends.
|
|
m_frontendRouter->disconnectAllFrontends();
|
|
|
|
+ m_pendingNavigations.clear();
|
|
+
|
|
m_page.didChangeInspectorFrontendCount(m_frontendRouter->frontendCount());
|
|
|
|
#if ENABLE(REMOTE_INSPECTOR)
|
|
@@ -150,6 +254,66 @@ void WebPageInspectorController::setIndicating(bool indicating)
|
|
}
|
|
#endif
|
|
|
|
+#if USE(CAIRO)
|
|
+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_page.loadRequestForInspector(WTFMove(request), frame);
|
|
+ if (!navigation) {
|
|
+ completionHandler("Failed to navigate"_s, 0);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ m_pendingNavigations.set(navigation->navigationID(), WTFMove(completionHandler));
|
|
+}
|
|
+
|
|
+void WebPageInspectorController::didReceivePolicyDecision(WebCore::PolicyAction action, uint64_t 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, 0);
|
|
+ else
|
|
+ completionHandler(String(), navigationID);
|
|
+}
|
|
+
|
|
+void WebPageInspectorController::didDestroyNavigation(uint64_t 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(), 0);
|
|
+}
|
|
+
|
|
+void WebPageInspectorController::didFailProvisionalLoadForFrame(uint64_t navigationID, const WebCore::ResourceError& error)
|
|
+{
|
|
+ if (s_observer)
|
|
+ s_observer->didFailProvisionalLoad(m_page, navigationID, error.localizedDescription());
|
|
+}
|
|
+
|
|
void WebPageInspectorController::createInspectorTarget(const String& targetId, Inspector::InspectorTargetType type)
|
|
{
|
|
addTarget(InspectorTargetProxy::create(m_page, targetId, type));
|
|
@@ -169,6 +333,32 @@ 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::shouldPauseLoading() const
|
|
+{
|
|
+ if (!m_frontendRouter->hasFrontends())
|
|
+ return false;
|
|
+
|
|
+ if (!m_page.isPageOpenedByDOMShowingInitialEmptyDocument())
|
|
+ return false;
|
|
+
|
|
+ auto* target = m_targets.get(WebPageInspectorTarget::toTargetID(m_page.webPageID()));
|
|
+ ASSERT(target);
|
|
+ return target->isPaused();
|
|
+}
|
|
+
|
|
+void WebPageInspectorController::setContinueLoadingCallback(WTF::Function<void()>&& callback)
|
|
+{
|
|
+ auto* target = m_targets.get(WebPageInspectorTarget::toTargetID(m_page.webPageID()));
|
|
+ ASSERT(target);
|
|
+ target->setResumeCallback(WTFMove(callback));
|
|
+}
|
|
+
|
|
bool WebPageInspectorController::shouldPauseLoading(const ProvisionalPageProxy& provisionalPage) const
|
|
{
|
|
if (!m_frontendRouter->hasFrontends())
|
|
@@ -188,7 +378,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)
|
|
@@ -241,4 +431,20 @@ void WebPageInspectorController::addTarget(std::unique_ptr<InspectorTargetProxy>
|
|
m_targets.set(target->identifier(), WTFMove(target));
|
|
}
|
|
|
|
+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_page.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_page.preferences().setUsesBackForwardCache(false);
|
|
+
|
|
+ // Enable popup debugging.
|
|
+ // TODO: allow to set preferences over the inspector protocol or find a better place for this.
|
|
+ m_page.preferences().setJavaScriptCanOpenWindowsAutomatically(true);
|
|
+}
|
|
+
|
|
} // namespace WebKit
|
|
diff --git a/Source/WebKit/UIProcess/Inspector/WebPageInspectorController.h b/Source/WebKit/UIProcess/Inspector/WebPageInspectorController.h
|
|
index f9c26832d3e91e8d747c5c1e0f0d76c34f4c3096..8b73efbba93362d8eebcc3a52158d8b0f6e4c59d 100644
|
|
--- a/Source/WebKit/UIProcess/Inspector/WebPageInspectorController.h
|
|
+++ b/Source/WebKit/UIProcess/Inspector/WebPageInspectorController.h
|
|
@@ -26,17 +26,35 @@
|
|
#pragma once
|
|
|
|
#include "InspectorTargetProxy.h"
|
|
+#include "ProcessTerminationReason.h"
|
|
#include <JavaScriptCore/InspectorAgentRegistry.h>
|
|
#include <JavaScriptCore/InspectorTargetAgent.h>
|
|
#include <WebCore/PageIdentifier.h>
|
|
#include <wtf/Forward.h>
|
|
#include <wtf/Noncopyable.h>
|
|
#include <wtf/text/WTFString.h>
|
|
+#include <wtf/URL.h>
|
|
+
|
|
+#if USE(CAIRO)
|
|
+#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 {
|
|
@@ -44,6 +62,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&, uint64_t navigationID, 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_NONCOPYABLE(WebPageInspectorController);
|
|
WTF_MAKE_FAST_ALLOCATED;
|
|
@@ -51,7 +86,20 @@ public:
|
|
WebPageInspectorController(WebPageProxy&);
|
|
|
|
void init();
|
|
+ void didFinishAttachingToWebProcess();
|
|
+
|
|
+ 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();
|
|
|
|
bool hasLocalFrontend() const;
|
|
|
|
@@ -64,11 +112,25 @@ public:
|
|
#if ENABLE(REMOTE_INSPECTOR)
|
|
void setIndicating(bool);
|
|
#endif
|
|
+#if USE(CAIRO)
|
|
+ void didPaint(cairo_surface_t*);
|
|
+#endif
|
|
+ using NavigationHandler = Function<void(const String&, uint64_t)>;
|
|
+ void navigate(WebCore::ResourceRequest&&, WebFrameProxy*, NavigationHandler&&);
|
|
+ void didReceivePolicyDecision(WebCore::PolicyAction action, uint64_t navigationID);
|
|
+ void didDestroyNavigation(uint64_t navigationID);
|
|
+
|
|
+ void didFailProvisionalLoadForFrame(uint64_t 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 shouldPauseLoading() const;
|
|
+ void setContinueLoadingCallback(WTF::Function<void()>&&);
|
|
+
|
|
bool shouldPauseLoading(const ProvisionalPageProxy&) const;
|
|
void setContinueLoadingCallback(const ProvisionalPageProxy&, WTF::Function<void()>&&);
|
|
|
|
@@ -84,6 +146,7 @@ private:
|
|
void createLazyAgents();
|
|
|
|
void addTarget(std::unique_ptr<InspectorTargetProxy>&&);
|
|
+ void adjustPageSettings();
|
|
|
|
Ref<Inspector::FrontendRouter> m_frontendRouter;
|
|
Ref<Inspector::BackendDispatcher> m_backendDispatcher;
|
|
@@ -92,11 +155,17 @@ private:
|
|
WebPageProxy& m_page;
|
|
|
|
Inspector::InspectorTargetAgent* m_targetAgent { nullptr };
|
|
+ WebPageInspectorEmulationAgent* m_emulationAgent { nullptr };
|
|
+ WebPageInspectorInputAgent* m_inputAgent { nullptr };
|
|
+ InspectorScreencastAgent* m_screecastAgent { nullptr };
|
|
HashMap<String, std::unique_ptr<InspectorTargetProxy>> m_targets;
|
|
|
|
InspectorBrowserAgent* m_enabledBrowserAgent;
|
|
|
|
bool m_didCreateLazyAgents { false };
|
|
+ HashMap<uint64_t, 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..0700f3624b34ab536f4101a12ba5fbd9a81e9a58
|
|
--- /dev/null
|
|
+++ b/Source/WebKit/UIProcess/Inspector/mac/ScreencastEncoderMac.mm
|
|
@@ -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 "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, Optional<double> scale, 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(), kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Little));
|
|
+ double imageWidth = CGImageGetWidth(image);
|
|
+ double imageHeight = CGImageGetHeight(image);
|
|
+ // TODO: exclude controls from original screenshot
|
|
+ double pageHeight = imageHeight - offsetTop;
|
|
+ double ratio = 1;
|
|
+ if (scale) {
|
|
+ ratio = *scale;
|
|
+ } else 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..04d06589d224df007a9a1c3b3ffcf3d56b1744a3
|
|
--- /dev/null
|
|
+++ b/Source/WebKit/UIProcess/InspectorPlaywrightAgent.cpp
|
|
@@ -0,0 +1,882 @@
|
|
+/*
|
|
+ * 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 "APIPageConfiguration.h"
|
|
+#include "FrameInfoData.h"
|
|
+#include "InspectorPlaywrightAgentClient.h"
|
|
+#include "InspectorTargetProxy.h"
|
|
+#include "NetworkProcessMessages.h"
|
|
+#include "NetworkProcessProxy.h"
|
|
+#include "PageClient.h"
|
|
+#include "WebAutomationSession.h"
|
|
+#include "WebGeolocationManagerProxy.h"
|
|
+#include "WebGeolocationPosition.h"
|
|
+#include "WebInspectorUtilities.h"
|
|
+#include "WebPageInspectorController.h"
|
|
+#include "WebPageInspectorTarget.h"
|
|
+#include "WebPageProxy.h"
|
|
+#include "WebProcessPool.h"
|
|
+#include "WebProcessProxy.h"
|
|
+#include <WebCore/FrameIdentifier.h>
|
|
+#include <WebCore/GeolocationPositionData.h>
|
|
+#include <WebCore/InspectorPageAgent.h>
|
|
+#include <WebCore/ProcessIdentifier.h>
|
|
+#include <WebCore/ResourceRequest.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>
|
|
+
|
|
+
|
|
+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;
|
|
+};
|
|
+
|
|
+namespace {
|
|
+
|
|
+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("left=" + String::number(*features.x));
|
|
+ if (features.y)
|
|
+ result->addItem("top=" + String::number(*features.y));
|
|
+ if (features.width)
|
|
+ result->addItem("width=" + String::number(*features.width));
|
|
+ if (features.height)
|
|
+ result->addItem("height=" + String::number(*features.height));
|
|
+ if (features.menuBarVisible)
|
|
+ result->addItem("menubar");
|
|
+ if (features.toolBarVisible)
|
|
+ result->addItem("toolbar");
|
|
+ if (features.statusBarVisible)
|
|
+ result->addItem("status");
|
|
+ if (features.locationBarVisible)
|
|
+ result->addItem("location");
|
|
+ if (features.scrollbarsVisible)
|
|
+ result->addItem("scrollbars");
|
|
+ if (features.resizable)
|
|
+ result->addItem("resizable");
|
|
+ if (features.fullscreen)
|
|
+ result->addItem("fullscreen");
|
|
+ if (features.dialog)
|
|
+ result->addItem("dialog");
|
|
+ if (features.noopener)
|
|
+ result->addItem("noopener");
|
|
+ if (features.noreferrer)
|
|
+ result->addItem("noreferrer");
|
|
+ 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.valueOr(-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()
|
|
+{
|
|
+ ASSERT(m_frontendChannel);
|
|
+
|
|
+ disable();
|
|
+
|
|
+ m_frontendRouter->disconnectFrontend(*m_frontendChannel);
|
|
+ ASSERT(!m_frontendRouter->hasFrontends());
|
|
+
|
|
+ WebPageInspectorController::setObserver(nullptr);
|
|
+ m_frontendChannel = nullptr;
|
|
+}
|
|
+
|
|
+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;
|
|
+ }
|
|
+
|
|
+ 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.process().processPool()))
|
|
+ return;
|
|
+
|
|
+ ASSERT(m_frontendChannel);
|
|
+
|
|
+ String browserContextID = toBrowserContextIDProtocolString(page.sessionID());
|
|
+ String pageProxyID = toPageProxyIDProtocolString(page);
|
|
+ auto* opener = page.configuration().relatedPage();
|
|
+ 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));
|
|
+}
|
|
+
|
|
+void InspectorPlaywrightAgent::willDestroyInspectorController(WebPageProxy& page)
|
|
+{
|
|
+ if (!m_isEnabled)
|
|
+ return;
|
|
+
|
|
+ if (isInspectorProcessPool(page.process().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, uint64_t navigationID, const String& error)
|
|
+{
|
|
+ if (!m_isEnabled)
|
|
+ return;
|
|
+
|
|
+ m_frontendDispatcher->provisionalLoadFailed(
|
|
+ toPageProxyIDProtocolString(page),
|
|
+ String::number(navigationID), 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();
|
|
+ context->dataStore = defaultDataStore;
|
|
+ // 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 (auto& pool : WebProcessPool::allProcessPools()) {
|
|
+ for (auto& process : pool->processes()) {
|
|
+ for (auto* page : process->pages())
|
|
+ didCreateInspectorController(*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(Optional<bool>(), String());
|
|
+ });
|
|
+ for (auto& it : m_browserContexts) {
|
|
+ it.value->dataStore->setDownloadInstrumentation(nullptr);
|
|
+ it.value->pages.clear();
|
|
+ }
|
|
+ m_browserContextDeletions.clear();
|
|
+ return { };
|
|
+}
|
|
+
|
|
+void InspectorPlaywrightAgent::close(Ref<CloseCallback>&& callback)
|
|
+{
|
|
+ Vector<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 (auto* process : WebProcessProxy::allProcessesForInspector()) {
|
|
+ for (auto* page : process->pages())
|
|
+ pages.append(page);
|
|
+ }
|
|
+ for (auto* page : pages)
|
|
+ page->closePage();
|
|
+
|
|
+ if (!WebProcessPool::allProcessPools().size()) {
|
|
+ m_client->closeBrowser();
|
|
+ callback->sendSuccess();
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (!m_defaultContext) {
|
|
+ m_client->closeBrowser();
|
|
+ callback->sendSuccess();
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ m_defaultContext->dataStore->syncLocalStorage([this, callback = WTFMove(callback)] () {
|
|
+ if (!callback->isActive())
|
|
+ return;
|
|
+
|
|
+ if (m_client == nullptr) {
|
|
+ callback->sendFailure("no platform delegate to close browser");
|
|
+ } else {
|
|
+ m_client->closeBrowser();
|
|
+ callback->sendSuccess();
|
|
+ }
|
|
+ });
|
|
+
|
|
+}
|
|
+
|
|
+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);
|
|
+
|
|
+ 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)
|
|
+{
|
|
+ size_t dotPos = frameID.find(".");
|
|
+ if (dotPos == notFound) {
|
|
+ error = "Invalid frame id"_s;
|
|
+ return nullptr;
|
|
+ }
|
|
+
|
|
+ if (!frameID.isAllASCII()) {
|
|
+ error = "Invalid frame id"_s;
|
|
+ return nullptr;
|
|
+ }
|
|
+
|
|
+ String processIDString = frameID.left(dotPos);
|
|
+ uint64_t pid = strtoull(processIDString.ascii().data(), 0, 10);
|
|
+ auto processID = makeObjectIdentifier<WebCore::ProcessIdentifierType>(pid);
|
|
+ WebProcessProxy* process = WebProcessProxy::processForIdentifier(processID);
|
|
+ if (!process) {
|
|
+ error = "Cannot find web process for the frame id"_s;
|
|
+ return nullptr;
|
|
+ }
|
|
+
|
|
+ String frameIDString = frameID.substring(dotPos + 1);
|
|
+ uint64_t frameIDNumber = strtoull(frameIDString.ascii().data(), 0, 10);
|
|
+ auto frameIdentifier = makeObjectIdentifier<WebCore::FrameIdentifierType>(frameIDNumber);
|
|
+ WebFrameProxy* frame = process->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, uint64_t navigationID) {
|
|
+ if (!error.isEmpty()) {
|
|
+ callback->sendFailure(error);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ String navigationIDString;
|
|
+ if (navigationID)
|
|
+ navigationIDString = String::number(navigationID);
|
|
+ callback->sendSuccess(navigationIDString);
|
|
+ });
|
|
+}
|
|
+
|
|
+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 { };
|
|
+}
|
|
+
|
|
+void InspectorPlaywrightAgent::getAllCookies(const String& browserContextID, Ref<GetAllCookiesCallback>&& callback) {
|
|
+ String errorString;
|
|
+ BrowserContext* browserContext = lookupBrowserContext(errorString, browserContextID);
|
|
+ if (!errorString.isEmpty()) {
|
|
+ callback->sendFailure(errorString);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ PAL::SessionID sessionID = browserContext->dataStore->sessionID();
|
|
+ NetworkProcessProxy& networkProcess = browserContext->dataStore->networkProcess();
|
|
+ networkProcess.sendWithAsyncReply(Messages::NetworkProcess::GetAllCookies(sessionID),
|
|
+ [callback = WTFMove(callback)](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));
|
|
+ }, 0);
|
|
+}
|
|
+
|
|
+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;
|
|
+ }
|
|
+
|
|
+ NetworkProcessProxy& networkProcess = browserContext->dataStore->networkProcess();
|
|
+ PAL::SessionID sessionID = browserContext->dataStore->sessionID();
|
|
+
|
|
+ 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");
|
|
+ cookie.value = obj->getString("value");
|
|
+ cookie.domain = obj->getString("domain");
|
|
+ cookie.path = obj->getString("path");
|
|
+ if (!cookie.name || !cookie.value || !cookie.domain || !cookie.path) {
|
|
+ callback->sendFailure("Invalid file payload format"_s);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ Optional<double> expires = obj->getDouble("expires");
|
|
+ if (expires && *expires != -1)
|
|
+ cookie.expires = *expires;
|
|
+ if (Optional<bool> value = obj->getBoolean("httpOnly"))
|
|
+ cookie.httpOnly = *value;
|
|
+ if (Optional<bool> value = obj->getBoolean("secure"))
|
|
+ cookie.secure = *value;
|
|
+ if (Optional<bool> value = obj->getBoolean("session"))
|
|
+ cookie.session = *value;
|
|
+ String sameSite;
|
|
+ if (obj->getString("sameSite", sameSite)) {
|
|
+ if (sameSite == "None")
|
|
+ cookie.sameSite = WebCore::Cookie::SameSitePolicy::None;
|
|
+ if (sameSite == "Lax")
|
|
+ cookie.sameSite = WebCore::Cookie::SameSitePolicy::Lax;
|
|
+ if (sameSite == "Strict")
|
|
+ cookie.sameSite = WebCore::Cookie::SameSitePolicy::Strict;
|
|
+ }
|
|
+ cookies.append(WTFMove(cookie));
|
|
+ }
|
|
+
|
|
+ networkProcess.sendWithAsyncReply(Messages::NetworkProcess::SetCookies(sessionID, WTFMove(cookies)),
|
|
+ [callback = WTFMove(callback)](bool success) {
|
|
+ if (!callback->isActive())
|
|
+ return;
|
|
+
|
|
+ if (success)
|
|
+ callback->sendSuccess();
|
|
+ else
|
|
+ callback->sendFailure("Internal error: no network storage"_s);
|
|
+ callback->sendSuccess();
|
|
+ }, 0);
|
|
+}
|
|
+
|
|
+void InspectorPlaywrightAgent::deleteAllCookies(const String& browserContextID, Ref<DeleteAllCookiesCallback>&& callback) {
|
|
+ String errorString;
|
|
+ BrowserContext* browserContext = lookupBrowserContext(errorString, browserContextID);
|
|
+ if (!errorString.isEmpty()) {
|
|
+ callback->sendFailure(errorString);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ NetworkProcessProxy& networkProcess = browserContext->dataStore->networkProcess();
|
|
+ PAL::SessionID sessionID = browserContext->dataStore->sessionID();
|
|
+ networkProcess.sendWithAsyncReply(Messages::NetworkProcess::DeleteAllCookies(sessionID),
|
|
+ [callback = WTFMove(callback)](bool success) {
|
|
+ if (!callback->isActive())
|
|
+ return;
|
|
+ if (success)
|
|
+ callback->sendSuccess();
|
|
+ else
|
|
+ callback->sendFailure("Internal error: no network storage"_s);
|
|
+ }, 0);
|
|
+}
|
|
+
|
|
+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->dataStore->setLanguagesForAutomation(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);
|
|
+
|
|
+ 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) {
|
|
+ Optional<double> timestamp = geolocation->getDouble("timestamp");
|
|
+ Optional<double> latitude = geolocation->getDouble("latitude");
|
|
+ Optional<double> longitude = geolocation->getDouble("longitude");
|
|
+ Optional<double> accuracy = geolocation->getDouble("accuracy");
|
|
+ if (!timestamp || !latitude || !longitude || !accuracy)
|
|
+ return makeUnexpected("Invalid geolocation format"_s);
|
|
+
|
|
+ auto position = WebGeolocationPosition::create(WebCore::GeolocationPositionData(*timestamp, *latitude, *longitude, *accuracy));
|
|
+ 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)
|
|
+{
|
|
+ if (!m_isEnabled)
|
|
+ return;
|
|
+ String frameID = WebCore::InspectorPageAgent::makeFrameID(page->process().coreProcessIdentifier(), frameInfoData.frameID ? *frameInfoData.frameID : page->mainFrame()->frameID());
|
|
+ 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);
|
|
+}
|
|
+
|
|
+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..0b6cd5c9357c90ac81c0c2d197699855062926af
|
|
--- /dev/null
|
|
+++ b/Source/WebKit/UIProcess/InspectorPlaywrightAgent.h
|
|
@@ -0,0 +1,122 @@
|
|
+/*
|
|
+ * 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 <wtf/HashMap.h>
|
|
+#include <wtf/Forward.h>
|
|
+#include <wtf/Noncopyable.h>
|
|
+
|
|
+namespace Inspector {
|
|
+class BackendDispatcher;
|
|
+class FrontendChannel;
|
|
+class FrontendRouter;
|
|
+class PlaywrightFrontendDispatcher;
|
|
+}
|
|
+
|
|
+namespace PAL {
|
|
+class SessionID;
|
|
+}
|
|
+
|
|
+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&, uint64_t 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;
|
|
+ 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> setIgnoreCertificateErrors(const String& browserContextID, bool ignore) 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;
|
|
+
|
|
+ // DownloadInstrumentation
|
|
+ void downloadCreated(const String& uuid, const WebCore::ResourceRequest&, const FrameInfoData& frameInfoData, WebPageProxy* page) 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);
|
|
+
|
|
+ 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;
|
|
+ HashMap<String, std::unique_ptr<PageProxyChannel>> m_pageProxyChannels;
|
|
+ BrowserContext* m_defaultContext;
|
|
+ HashMap<String, std::unique_ptr<BrowserContext>> m_browserContexts;
|
|
+ HashMap<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..11c8eadafca764aa549cb27c24967e15e6975774
|
|
--- /dev/null
|
|
+++ b/Source/WebKit/UIProcess/InspectorPlaywrightAgentClient.h
|
|
@@ -0,0 +1,66 @@
|
|
+/*
|
|
+ * 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 <wtf/Forward.h>
|
|
+#include <wtf/HashSet.h>
|
|
+#include <wtf/Noncopyable.h>
|
|
+#include <wtf/RefCounted.h>
|
|
+
|
|
+namespace WebKit {
|
|
+
|
|
+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;
|
|
+};
|
|
+
|
|
+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;
|
|
+};
|
|
+
|
|
+} // namespace WebKit
|
|
+
|
|
+#endif // ENABLE(REMOTE_INSPECTOR)
|
|
diff --git a/Source/WebKit/UIProcess/Launcher/win/ProcessLauncherWin.cpp b/Source/WebKit/UIProcess/Launcher/win/ProcessLauncherWin.cpp
|
|
index 7a14cfba15c103a2d4fe263fa49d25af3c396ec2..3ee0e154349661632799057c71f1d1f1551c2d69 100644
|
|
--- a/Source/WebKit/UIProcess/Launcher/win/ProcessLauncherWin.cpp
|
|
+++ b/Source/WebKit/UIProcess/Launcher/win/ProcessLauncherWin.cpp
|
|
@@ -96,8 +96,11 @@ void ProcessLauncher::launchProcess()
|
|
|
|
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 5befc4df2001f87a9a7eeb4d687f13e946d703f3..aee9c052729fd6e8c528459262483a9a1d96fb29 100644
|
|
--- a/Source/WebKit/UIProcess/PageClient.h
|
|
+++ b/Source/WebKit/UIProcess/PageClient.h
|
|
@@ -259,7 +259,7 @@ public:
|
|
virtual void showSafeBrowsingWarning(const SafeBrowsingWarning&, CompletionHandler<void(Variant<ContinueUnsafeLoad, URL>&&)>&& completionHandler) { completionHandler(ContinueUnsafeLoad::Yes); }
|
|
virtual void clearSafeBrowsingWarning() { }
|
|
virtual void clearSafeBrowsingWarningIfForMainFrameNavigation() { }
|
|
-
|
|
+
|
|
#if ENABLE(DRAG_SUPPORT)
|
|
#if PLATFORM(GTK)
|
|
virtual void startDrag(WebCore::SelectionData&&, OptionSet<WebCore::DragOperation>, RefPtr<ShareableBitmap>&& dragImage) = 0;
|
|
@@ -298,6 +298,11 @@ public:
|
|
virtual void selectionDidChange() = 0;
|
|
#endif
|
|
|
|
+// Paywright begin
|
|
+#if PLATFORM(COCOA)
|
|
+ virtual RetainPtr<CGImageRef> takeSnapshotForAutomation() = 0;
|
|
+#endif
|
|
+// Paywright end
|
|
#if PLATFORM(COCOA) || PLATFORM(GTK)
|
|
virtual RefPtr<ViewSnapshot> takeViewSnapshot(Optional<WebCore::IntRect>&&) = 0;
|
|
#endif
|
|
@@ -314,6 +319,7 @@ public:
|
|
virtual WebCore::IntRect rootViewToAccessibilityScreen(const WebCore::IntRect&) = 0;
|
|
#if PLATFORM(MAC)
|
|
virtual WebCore::IntRect rootViewToWindow(const WebCore::IntRect&) = 0;
|
|
+ virtual int browserToolbarHeight() const { return 0; }
|
|
#endif
|
|
#if PLATFORM(IOS_FAMILY)
|
|
virtual void didNotHandleTapAsClick(const WebCore::IntPoint&) = 0;
|
|
@@ -362,7 +368,7 @@ public:
|
|
virtual void setTextIndicator(Ref<WebCore::TextIndicator>, WebCore::TextIndicatorWindowLifetime) = 0;
|
|
virtual void clearTextIndicator(WebCore::TextIndicatorWindowDismissalAnimation) = 0;
|
|
virtual void setTextIndicatorAnimationProgress(float) = 0;
|
|
-
|
|
+
|
|
virtual void didPerformDictionaryLookup(const WebCore::DictionaryPopupInfo&) = 0;
|
|
#endif
|
|
|
|
@@ -493,7 +499,7 @@ public:
|
|
virtual bool hasSafeBrowsingWarning() const { return false; }
|
|
|
|
virtual void setMouseEventPolicy(WebCore::MouseEventPolicy) { }
|
|
-
|
|
+
|
|
#if PLATFORM(MAC)
|
|
virtual void didPerformImmediateActionHitTest(const WebHitTestResultData&, bool contentPreventsDefault, API::Object*) = 0;
|
|
virtual NSObject *immediateActionAnimationControllerForHitTestResult(RefPtr<API::HitTestResult>, uint64_t, RefPtr<API::Object>) = 0;
|
|
diff --git a/Source/WebKit/UIProcess/RemoteInspectorPipe.cpp b/Source/WebKit/UIProcess/RemoteInspectorPipe.cpp
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..9593d0c3cc694309a18ae791a3f6ea0725f9b0cb
|
|
--- /dev/null
|
|
+++ b/Source/WebKit/UIProcess/RemoteInspectorPipe.cpp
|
|
@@ -0,0 +1,221 @@
|
|
+/*
|
|
+ * 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/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
|
|
+
|
|
+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"))
|
|
+ {
|
|
+ }
|
|
+
|
|
+ ~RemoteFrontendChannel() override = default;
|
|
+
|
|
+ ConnectionType connectionType() const override
|
|
+ {
|
|
+ return ConnectionType::Remote;
|
|
+ }
|
|
+
|
|
+ void sendMessageToFrontend(const String& message) override
|
|
+ {
|
|
+ m_senderQueue->dispatch([message = message.isolatedCopy()]() {
|
|
+ WriteBytes(message.ascii().data(), message.length());
|
|
+ WriteBytes("\0", 1);
|
|
+ });
|
|
+ }
|
|
+
|
|
+private:
|
|
+ Ref<WorkQueue> m_senderQueue;
|
|
+};
|
|
+
|
|
+RemoteInspectorPipe::RemoteInspectorPipe(InspectorPlaywrightAgent& playwrightAgent)
|
|
+ : m_playwrightAgent(playwrightAgent)
|
|
+{
|
|
+ // Initialize main loop before creating WorkQueue
|
|
+ WTF::initializeMainThread();
|
|
+ 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", [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)
|
|
+ break;
|
|
+ size_t start = 0;
|
|
+ size_t end = line.size();
|
|
+ line.append(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] {
|
|
+ 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)
|
|
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/WebAuthentication/Mock/MockLocalConnection.h b/Source/WebKit/UIProcess/WebAuthentication/Mock/MockLocalConnection.h
|
|
index ff90d3de4349c9a3385c20c059729b8e22ebe2e5..d5c4f2cd715551ddef6f5af93ada65cbe78ad213 100644
|
|
--- a/Source/WebKit/UIProcess/WebAuthentication/Mock/MockLocalConnection.h
|
|
+++ b/Source/WebKit/UIProcess/WebAuthentication/Mock/MockLocalConnection.h
|
|
@@ -28,6 +28,7 @@
|
|
#if ENABLE(WEB_AUTHN)
|
|
|
|
#include "LocalConnection.h"
|
|
+#include <WebCore/AuthenticatorAssertionResponse.h>
|
|
#include <WebCore/MockWebAuthenticationConfiguration.h>
|
|
|
|
namespace WebKit {
|
|
diff --git a/Source/WebKit/UIProcess/WebContextMenuProxy.h b/Source/WebKit/UIProcess/WebContextMenuProxy.h
|
|
index 2d2c5765c01f2680749a8f193d61fb666a08ab86..4a26ae64fee4c7e57e0336361ad92f9b024b5349 100644
|
|
--- a/Source/WebKit/UIProcess/WebContextMenuProxy.h
|
|
+++ b/Source/WebKit/UIProcess/WebContextMenuProxy.h
|
|
@@ -43,6 +43,7 @@ public:
|
|
virtual ~WebContextMenuProxy();
|
|
|
|
virtual void show();
|
|
+ virtual void hide() {}
|
|
|
|
WebPageProxy* page() const { return m_page.get(); }
|
|
|
|
diff --git a/Source/WebKit/UIProcess/WebGeolocationManagerProxy.cpp b/Source/WebKit/UIProcess/WebGeolocationManagerProxy.cpp
|
|
index 04f3227cd55c992a42cd96a3f25d697aed7965a2..f0d36935f47bab03ea2ec50b705092068ecd3efa 100644
|
|
--- a/Source/WebKit/UIProcess/WebGeolocationManagerProxy.cpp
|
|
+++ b/Source/WebKit/UIProcess/WebGeolocationManagerProxy.cpp
|
|
@@ -128,7 +128,8 @@ void WebGeolocationManagerProxy::startUpdating(IPC::Connection& connection, WebP
|
|
if (!wasUpdating) {
|
|
m_provider->setEnableHighAccuracy(*this, isHighAccuracyEnabled());
|
|
m_provider->startUpdating(*this);
|
|
- } else if (m_lastPosition)
|
|
+ }
|
|
+ if (m_lastPosition)
|
|
connection.send(Messages::WebGeolocationManager::DidChangePosition(m_lastPosition.value()), 0);
|
|
}
|
|
|
|
diff --git a/Source/WebKit/UIProcess/WebPageInspectorEmulationAgent.cpp b/Source/WebKit/UIProcess/WebPageInspectorEmulationAgent.cpp
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..e6e700e846ea091a190b6b1f5c5636fed4389909
|
|
--- /dev/null
|
|
+++ b/Source/WebKit/UIProcess/WebPageInspectorEmulationAgent.cpp
|
|
@@ -0,0 +1,146 @@
|
|
+/*
|
|
+ * 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, double deviceScaleFactor, bool fixedlayout, 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
|
|
+
|
|
+ m_page.setCustomDeviceScaleFactor(deviceScaleFactor);
|
|
+ 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)
|
|
+{
|
|
+ if (!!username && !!password)
|
|
+ m_page.setAuthCredentialsForAutomation(WebCore::Credential(username, password, CredentialPersistencePermanent));
|
|
+ else
|
|
+ m_page.setAuthCredentialsForAutomation(Optional<WebCore::Credential>());
|
|
+ return { };
|
|
+}
|
|
+
|
|
+Inspector::Protocol::ErrorStringOr<void> WebPageInspectorEmulationAgent::setActiveAndFocused(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 { };
|
|
+}
|
|
+
|
|
+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..1353851472668b3e77c19db54f224c0ca151e9d3
|
|
--- /dev/null
|
|
+++ b/Source/WebKit/UIProcess/WebPageInspectorEmulationAgent.h
|
|
@@ -0,0 +1,75 @@
|
|
+/*
|
|
+ * 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, double deviceScaleFactor, bool fixedlayout, Ref<SetDeviceMetricsOverrideCallback>&&) override;
|
|
+ Inspector::Protocol::ErrorStringOr<void> setJavaScriptEnabled(bool enabled) override;
|
|
+ Inspector::Protocol::ErrorStringOr<void> setAuthCredentials(const String&, const String&) override;
|
|
+ Inspector::Protocol::ErrorStringOr<void> setActiveAndFocused(Optional<bool>&&) override;
|
|
+ Inspector::Protocol::ErrorStringOr<void> grantPermissions(const String& origin, Ref<JSON::Array>&& permissions) override;
|
|
+ Inspector::Protocol::ErrorStringOr<void> resetPermissions() 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;
|
|
+ HashMap<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..5c16e0ef1e1593d8a1d26b149d0415136501ac6d
|
|
--- /dev/null
|
|
+++ b/Source/WebKit/UIProcess/WebPageInspectorInputAgent.cpp
|
|
@@ -0,0 +1,277 @@
|
|
+/*
|
|
+ * 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 "NativeWebMouseEvent.h"
|
|
+#include "WebPageProxy.h"
|
|
+#include <wtf/MathExtras.h>
|
|
+#include <wtf/HexNumber.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");
|
|
+ }
|
|
+
|
|
+ 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> {
|
|
+};
|
|
+
|
|
+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_mouseCallbacks->sendSuccess();
|
|
+}
|
|
+
|
|
+void WebPageInspectorInputAgent::didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*)
|
|
+{
|
|
+ m_keyboardCallbacks = makeUnique<KeyboardCallbacks>();
|
|
+ m_mouseCallbacks = makeUnique<MouseCallbacks>();
|
|
+}
|
|
+
|
|
+void WebPageInspectorInputAgent::willDestroyFrontendAndBackend(Inspector::DisconnectReason)
|
|
+{
|
|
+ m_keyboardCallbacks = nullptr;
|
|
+ m_mouseCallbacks = nullptr;
|
|
+}
|
|
+
|
|
+static String keyIdentifierForKey(const String& key)
|
|
+{
|
|
+ if (key.length() == 1)
|
|
+ return makeString("U+", hex(toASCIIUpper(key.characterAt(0)), 4));
|
|
+ if (key == "Delete")
|
|
+ return "U+007F";
|
|
+ if (key == "Backspace")
|
|
+ return "U+0008";
|
|
+ if (key == "ArrowUp")
|
|
+ return "Up";
|
|
+ if (key == "ArrowDown")
|
|
+ return "Down";
|
|
+ if (key == "ArrowLeft")
|
|
+ return "Left";
|
|
+ if (key == "ArrowRight")
|
|
+ return "Right";
|
|
+ if (key == "Tab")
|
|
+ return "U+0009";
|
|
+ if (key == "Pause")
|
|
+ return "Pause";
|
|
+ if (key == "ScrollLock")
|
|
+ return "Scroll";
|
|
+ return key;
|
|
+}
|
|
+
|
|
+void WebPageInspectorInputAgent::dispatchKeyEvent(const String& type, Optional<int>&& modifiers, const String& text, const String& unmodifiedText, const String& code, const String& key, Optional<int>&& windowsVirtualKeyCode, Optional<int>&& nativeVirtualKeyCode, Optional<bool>&& autoRepeat, Optional<bool>&& isKeypad, Optional<bool>&& isSystemKey, RefPtr<JSON::Array>&& commands, Ref<Inspector::InputBackendDispatcherHandler::DispatchKeyEventCallback>&& callback)
|
|
+{
|
|
+ WebKit::WebEvent::Type eventType;
|
|
+ if (type == "keyDown") {
|
|
+ eventType = WebKit::WebEvent::KeyDown;
|
|
+ } else if (type == "keyUp") {
|
|
+ eventType = WebKit::WebEvent::KeyUp;
|
|
+ } else {
|
|
+ callback->sendFailure("Unsupported event type.");
|
|
+ return;
|
|
+ }
|
|
+ OptionSet<WebEvent::Modifier> 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");
|
|
+ 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();
|
|
+
|
|
+ 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, Optional<int>&& modifiers, const String& button, Optional<int>&& buttons, Optional<int>&& clickCount, Optional<int>&& deltaX, Optional<int>&& deltaY, Ref<DispatchMouseEventCallback>&& callback)
|
|
+{
|
|
+ WebEvent::Type eventType = WebEvent::NoType;
|
|
+ if (type == "down")
|
|
+ eventType = WebEvent::MouseDown;
|
|
+ else if (type == "up")
|
|
+ eventType = WebEvent::MouseUp;
|
|
+ else if (type == "move")
|
|
+ eventType = WebEvent::MouseMove;
|
|
+ else {
|
|
+ callback->sendFailure("Unsupported event type");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ OptionSet<WebEvent::Modifier> eventModifiers;
|
|
+ if (modifiers)
|
|
+ eventModifiers = eventModifiers.fromRaw(*modifiers);
|
|
+
|
|
+ WebMouseEvent::Button eventButton = WebMouseEvent::NoButton;
|
|
+ if (!!button) {
|
|
+ if (button == "left")
|
|
+ eventButton = WebMouseEvent::LeftButton;
|
|
+ else if (button == "middle")
|
|
+ eventButton = WebMouseEvent::MiddleButton;
|
|
+ else if (button == "right")
|
|
+ eventButton = WebMouseEvent::RightButton;
|
|
+ else if (button == "none")
|
|
+ eventButton = WebMouseEvent::NoButton;
|
|
+ else {
|
|
+ callback->sendFailure("Unsupported eventButton");
|
|
+ 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();
|
|
+ x = clampToInteger(roundf(x * totalScale));
|
|
+ y = clampToInteger(roundf(y * totalScale));
|
|
+ eventDeltaX = clampToInteger(roundf(eventDeltaX * totalScale));
|
|
+ eventDeltaY = clampToInteger(roundf(eventDeltaY * totalScale));
|
|
+
|
|
+#if PLATFORM(MAC)
|
|
+ platformDispatchMouseEvent(type, x, y, WTFMove(modifiers), button, WTFMove(clickCount));
|
|
+#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, Optional<int>&& modifiers, Ref<DispatchTapEventCallback>&& callback) {
|
|
+ m_page.sendWithAsyncReply(Messages::WebPage::FakeTouchTap(IntPoint(x, y), modifiers ? *modifiers : 0), [callback]() {
|
|
+ callback->sendSuccess();
|
|
+ });
|
|
+}
|
|
+} // namespace WebKit
|
|
diff --git a/Source/WebKit/UIProcess/WebPageInspectorInputAgent.h b/Source/WebKit/UIProcess/WebPageInspectorInputAgent.h
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..05a71c27eae03f2cdf3bcba31a8b108b09b54178
|
|
--- /dev/null
|
|
+++ b/Source/WebKit/UIProcess/WebPageInspectorInputAgent.h
|
|
@@ -0,0 +1,84 @@
|
|
+/*
|
|
+ * 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 <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 didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*) override;
|
|
+ void willDestroyFrontendAndBackend(Inspector::DisconnectReason) override;
|
|
+
|
|
+ // Protocol handler
|
|
+ void dispatchKeyEvent(const String& type, Optional<int>&& modifiers, const String& text, const String& unmodifiedText, const String& code, const String& key, Optional<int>&& windowsVirtualKeyCode, Optional<int>&& nativeVirtualKeyCode, Optional<bool>&& autoRepeat, Optional<bool>&& isKeypad, Optional<bool>&& isSystemKey, RefPtr<JSON::Array>&&, Ref<DispatchKeyEventCallback>&& callback) override;
|
|
+ void dispatchMouseEvent(const String& type, int x, int y, Optional<int>&& modifiers, const String& button, Optional<int>&& buttons, Optional<int>&& clickCount, Optional<int>&& deltaX, Optional<int>&& deltaY, Ref<DispatchMouseEventCallback>&& callback) override;
|
|
+ void dispatchTapEvent(int x, int y, Optional<int>&& modifiers, Ref<DispatchTapEventCallback>&& callback) override;
|
|
+
|
|
+private:
|
|
+ void platformDispatchKeyEvent(WebKeyboardEvent::Type 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<WebEvent::Modifier> modifiers, Vector<String>& commands, WallTime timestamp);
|
|
+#if PLATFORM(WPE)
|
|
+ void platformDispatchMouseEvent(WebMouseEvent::Type type, int x, int y, WebMouseEvent::Button button, OptionSet<WebEvent::Modifier> modifiers);
|
|
+#endif
|
|
+#if PLATFORM(MAC)
|
|
+ void platformDispatchMouseEvent(const String& type, int x, int y, Optional<int>&& modifier, const String& button, Optional<int>&& clickCount);
|
|
+#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;
|
|
+};
|
|
+
|
|
+} // namespace WebKit
|
|
diff --git a/Source/WebKit/UIProcess/WebPageProxy.cpp b/Source/WebKit/UIProcess/WebPageProxy.cpp
|
|
index df4fbf64be7638dafd45c2be9491eff7b3c352bc..75c34574bd43526856613ed3eccf2ad593cd3e84 100644
|
|
--- a/Source/WebKit/UIProcess/WebPageProxy.cpp
|
|
+++ b/Source/WebKit/UIProcess/WebPageProxy.cpp
|
|
@@ -972,6 +972,7 @@ void WebPageProxy::finishAttachingToWebProcess(ProcessLaunchReason reason)
|
|
m_pageLoadState.didSwapWebProcesses();
|
|
if (reason != ProcessLaunchReason::InitialProcess)
|
|
m_drawingArea->waitForBackingStoreUpdateOnNextPaint();
|
|
+ m_inspectorController->didFinishAttachingToWebProcess();
|
|
}
|
|
|
|
void WebPageProxy::didAttachToRunningProcess()
|
|
@@ -1284,6 +1285,21 @@ WebProcessProxy& WebPageProxy::ensureRunningProcess()
|
|
return m_process;
|
|
}
|
|
|
|
+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(ResourceRequest(request), m_backForwardList->currentItem());
|
|
+ LoadParameters loadParameters;
|
|
+ loadParameters.navigationID = navigation->navigationID();
|
|
+ loadParameters.request = WTFMove(request);
|
|
+ loadParameters.shouldOpenExternalURLsPolicy = WebCore::ShouldOpenExternalURLsPolicy::ShouldNotAllow;
|
|
+ loadParameters.shouldTreatAsContinuingLoad = false;
|
|
+ m_process->send(Messages::WebPage::LoadRequestInFrameForInspector(loadParameters, frame->frameID()), m_webPageID);
|
|
+ return navigation;
|
|
+}
|
|
+
|
|
RefPtr<API::Navigation> WebPageProxy::loadRequest(ResourceRequest&& request, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy, API::Object* userData)
|
|
{
|
|
if (m_isClosed)
|
|
@@ -1743,6 +1759,31 @@ void WebPageProxy::setControlledByAutomation(bool controlled)
|
|
websiteDataStore().networkProcess().send(Messages::NetworkProcess::SetSessionIsControlledByAutomation(m_websiteDataStore->sessionID(), m_controlledByAutomation), 0);
|
|
}
|
|
|
|
+void WebPageProxy::setAuthCredentialsForAutomation(Optional<WebCore::Credential>&& credentials)
|
|
+{
|
|
+ m_credentialsForAutomation = WTFMove(credentials);
|
|
+}
|
|
+
|
|
+void WebPageProxy::setPermissionsForAutomation(const HashMap<String, HashSet<String>>& permissions)
|
|
+{
|
|
+ m_permissionsForAutomation = permissions;
|
|
+}
|
|
+
|
|
+void WebPageProxy::setActiveForAutomation(Optional<bool> active) {
|
|
+ m_activeForAutomation = active;
|
|
+ OptionSet<ActivityState::Flag> 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(const String& targetId, Inspector::InspectorTargetType type)
|
|
{
|
|
MESSAGE_CHECK(m_process, !targetId.isEmpty());
|
|
@@ -1882,6 +1923,25 @@ void WebPageProxy::updateActivityState(OptionSet<ActivityState::Flag> flagsToUpd
|
|
{
|
|
bool wasVisible = isViewVisible();
|
|
m_activityState.remove(flagsToUpdate);
|
|
+
|
|
+
|
|
+ if (m_activeForAutomation) {
|
|
+ if (*m_activeForAutomation) {
|
|
+ if (flagsToUpdate & ActivityState::IsFocused)
|
|
+ m_activityState.add(ActivityState::IsFocused);
|
|
+ if (flagsToUpdate & ActivityState::WindowIsActive)
|
|
+ m_activityState.add(ActivityState::WindowIsActive);
|
|
+ if (flagsToUpdate & ActivityState::IsVisible)
|
|
+ m_activityState.add(ActivityState::IsVisible);
|
|
+ if (flagsToUpdate & ActivityState::IsVisibleOrOccluded)
|
|
+ m_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())
|
|
m_activityState.add(ActivityState::IsFocused);
|
|
if (flagsToUpdate & ActivityState::WindowIsActive && pageClient().isViewWindowActive())
|
|
@@ -2860,7 +2920,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)
|
|
const EventNames& names = eventNames();
|
|
for (auto& touchPoint : touchStartEvent.touchPoints()) {
|
|
IntPoint location = touchPoint.location();
|
|
@@ -2893,7 +2953,7 @@ void WebPageProxy::updateTouchEventTracking(const WebTouchEvent& touchStartEvent
|
|
m_touchAndPointerEventTracking.touchStartTracking = TrackingType::Synchronous;
|
|
m_touchAndPointerEventTracking.touchMoveTracking = TrackingType::Synchronous;
|
|
m_touchAndPointerEventTracking.touchEndTracking = TrackingType::Synchronous;
|
|
-#endif // ENABLE(ASYNC_SCROLLING)
|
|
+#endif // ENABLE(ASYNC_SCROLLING) && PLATFORM(IOS_FAMILY)
|
|
}
|
|
|
|
TrackingType WebPageProxy::touchEventTrackingType(const WebTouchEvent& touchStartEvent) const
|
|
@@ -3315,6 +3375,7 @@ void WebPageProxy::receivedNavigationPolicyDecision(PolicyAction policyAction, A
|
|
|
|
void WebPageProxy::receivedPolicyDecision(PolicyAction action, API::Navigation* navigation, RefPtr<API::WebsitePolicies>&& websitePolicies, Ref<PolicyDecisionSender>&& sender, Optional<SandboxExtension::Handle> sandboxExtensionHandle, WillContinueLoadInNewProcess willContinueLoadInNewProcess)
|
|
{
|
|
+ m_inspectorController->didReceivePolicyDecision(action, navigation ? navigation->navigationID() : 0);
|
|
if (!hasRunningProcess()) {
|
|
sender->send(PolicyDecision { sender->identifier(), isNavigatingToAppBoundDomain(), PolicyAction::Ignore, 0, WTF::nullopt, WTF::nullopt });
|
|
return;
|
|
@@ -4011,6 +4072,11 @@ void WebPageProxy::pageScaleFactorDidChange(double scaleFactor)
|
|
m_pageScaleFactor = scaleFactor;
|
|
}
|
|
|
|
+void WebPageProxy::viewScaleFactorDidChange(double scaleFactor)
|
|
+{
|
|
+ m_viewScaleFactor = scaleFactor;
|
|
+}
|
|
+
|
|
void WebPageProxy::pluginScaleFactorDidChange(double pluginScaleFactor)
|
|
{
|
|
m_pluginScaleFactor = pluginScaleFactor;
|
|
@@ -4427,6 +4493,7 @@ void WebPageProxy::didDestroyNavigation(uint64_t navigationID)
|
|
|
|
// FIXME: Message check the navigationID.
|
|
m_navigationState->didDestroyNavigation(navigationID);
|
|
+ m_inspectorController->didDestroyNavigation(navigationID);
|
|
}
|
|
|
|
void WebPageProxy::didStartProvisionalLoadForFrame(FrameIdentifier frameID, FrameInfoData&& frameInfo, ResourceRequest&& request, uint64_t navigationID, URL&& url, URL&& unreachableURL, const UserData& userData)
|
|
@@ -4649,6 +4716,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;
|
|
@@ -5089,7 +5158,14 @@ void WebPageProxy::decidePolicyForNavigationActionAsync(FrameIdentifier frameID,
|
|
NavigationActionData&& navigationActionData, FrameInfoData&& originatingFrameInfo, Optional<WebPageProxyIdentifier> originatingPageID, const WebCore::ResourceRequest& originalRequest, WebCore::ResourceRequest&& request,
|
|
IPC::FormDataReference&& requestBody, WebCore::ResourceResponse&& redirectResponse, const UserData& userData, uint64_t listenerID)
|
|
{
|
|
- decidePolicyForNavigationActionAsyncShared(m_process.copyRef(), m_webPageID, frameID, WTFMove(frameInfo), identifier, navigationID, WTFMove(navigationActionData), WTFMove(originatingFrameInfo), originatingPageID, originalRequest, WTFMove(request), WTFMove(requestBody), WTFMove(redirectResponse), userData, listenerID);
|
|
+ if (m_inspectorController->shouldPauseLoading()) {
|
|
+ m_inspectorController->setContinueLoadingCallback([this, protectedThis = makeRef(*this), frameID, frameInfo = WTFMove(frameInfo), identifier, navigationID, navigationActionData = WTFMove(navigationActionData),
|
|
+ originatingFrameInfo = WTFMove(originatingFrameInfo), originatingPageID, originalRequest, request = WTFMove(request), requestBody = WTFMove(requestBody), redirectResponse = WTFMove(redirectResponse), userData, listenerID] () mutable {
|
|
+ decidePolicyForNavigationActionAsyncShared(m_process.copyRef(), m_webPageID, frameID, WTFMove(frameInfo), identifier, navigationID, WTFMove(navigationActionData), WTFMove(originatingFrameInfo), originatingPageID, originalRequest, WTFMove(request), WTFMove(requestBody), WTFMove(redirectResponse), userData, listenerID);
|
|
+ });
|
|
+ } else {
|
|
+ decidePolicyForNavigationActionAsyncShared(m_process.copyRef(), m_webPageID, frameID, WTFMove(frameInfo), identifier, navigationID, WTFMove(navigationActionData), WTFMove(originatingFrameInfo), originatingPageID, originalRequest, WTFMove(request), WTFMove(requestBody), WTFMove(redirectResponse), userData, listenerID);
|
|
+ }
|
|
}
|
|
|
|
void WebPageProxy::decidePolicyForNavigationActionAsyncShared(Ref<WebProcessProxy>&& process, PageIdentifier webPageID, FrameIdentifier frameID, FrameInfoData&& frameInfo,
|
|
@@ -5606,6 +5682,7 @@ void WebPageProxy::createNewPage(FrameInfoData&& originatingFrameInfoData, WebPa
|
|
auto* originatingPage = m_process->webPage(originatingPageID);
|
|
auto originatingFrameInfo = API::FrameInfo::create(WTFMove(originatingFrameInfoData), originatingPage);
|
|
auto mainFrameURL = m_mainFrame ? m_mainFrame->url() : URL();
|
|
+ m_inspectorController->willCreateNewPage(windowFeatures, request.url());
|
|
auto completionHandler = [this, protectedThis = makeRef(*this), mainFrameURL, request, reply = WTFMove(reply)] (RefPtr<WebPageProxy> newPage) mutable {
|
|
if (!newPage) {
|
|
reply(WTF::nullopt, WTF::nullopt);
|
|
@@ -5635,6 +5712,7 @@ void WebPageProxy::createNewPage(FrameInfoData&& originatingFrameInfoData, WebPa
|
|
void WebPageProxy::showPage()
|
|
{
|
|
m_uiClient->showPage(this);
|
|
+ m_inspectorController->didShowPage();
|
|
}
|
|
|
|
void WebPageProxy::exitFullscreenImmediately()
|
|
@@ -5670,6 +5748,10 @@ void WebPageProxy::closePage()
|
|
if (isClosed())
|
|
return;
|
|
|
|
+#if ENABLE(CONTEXT_MENUS)
|
|
+ if (m_activeContextMenu)
|
|
+ m_activeContextMenu->hide();
|
|
+#endif
|
|
RELEASE_LOG_IF_ALLOWED(Process, "closePage:");
|
|
pageClient().clearAllEditCommands();
|
|
m_uiClient->close(this);
|
|
@@ -5689,6 +5771,8 @@ void WebPageProxy::runJavaScriptAlert(FrameIdentifier frameID, FrameInfoData&& f
|
|
if (auto* automationSession = process().processPool().automationSession())
|
|
automationSession->willShowJavaScriptDialog(*this);
|
|
}
|
|
+ if (m_inspectorDialogAgent)
|
|
+ m_inspectorDialogAgent->javascriptDialogOpening("alert"_s, message);
|
|
m_uiClient->runJavaScriptAlert(*this, message, frame, WTFMove(frameInfo), WTFMove(reply));
|
|
}
|
|
|
|
@@ -5706,6 +5790,8 @@ void WebPageProxy::runJavaScriptConfirm(FrameIdentifier frameID, FrameInfoData&&
|
|
if (auto* automationSession = process().processPool().automationSession())
|
|
automationSession->willShowJavaScriptDialog(*this);
|
|
}
|
|
+ if (m_inspectorDialogAgent)
|
|
+ m_inspectorDialogAgent->javascriptDialogOpening("confirm"_s, message);
|
|
|
|
m_uiClient->runJavaScriptConfirm(*this, message, frame, WTFMove(frameInfo), WTFMove(reply));
|
|
}
|
|
@@ -5724,6 +5810,8 @@ void WebPageProxy::runJavaScriptPrompt(FrameIdentifier frameID, FrameInfoData&&
|
|
if (auto* automationSession = process().processPool().automationSession())
|
|
automationSession->willShowJavaScriptDialog(*this);
|
|
}
|
|
+ if (m_inspectorDialogAgent)
|
|
+ m_inspectorDialogAgent->javascriptDialogOpening("prompt"_s, message, defaultValue);
|
|
|
|
m_uiClient->runJavaScriptPrompt(*this, message, defaultValue, frame, WTFMove(frameInfo), WTFMove(reply));
|
|
}
|
|
@@ -5879,6 +5967,8 @@ void WebPageProxy::runBeforeUnloadConfirmPanel(FrameIdentifier frameID, FrameInf
|
|
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.
|
|
m_process->stopResponsivenessTimer();
|
|
@@ -6994,6 +7084,7 @@ void WebPageProxy::didReceiveEvent(uint32_t opaqueType, bool handled)
|
|
if (auto* automationSession = process().processPool().automationSession())
|
|
automationSession->mouseEventsFlushedForPage(*this);
|
|
didFinishProcessingAllPendingMouseEvents();
|
|
+ m_inspectorController->didProcessAllPendingMouseEvents();
|
|
}
|
|
|
|
break;
|
|
@@ -7020,7 +7111,6 @@ void WebPageProxy::didReceiveEvent(uint32_t opaqueType, bool handled)
|
|
case WebEvent::RawKeyDown:
|
|
case WebEvent::Char: {
|
|
LOG(KeyHandling, "WebPageProxy::didReceiveEvent: %s (queue empty %d)", webKeyboardEventTypeString(type), m_keyEventQueue.isEmpty());
|
|
-
|
|
MESSAGE_CHECK(m_process, !m_keyEventQueue.isEmpty());
|
|
NativeWebKeyboardEvent event = m_keyEventQueue.takeFirst();
|
|
|
|
@@ -7040,7 +7130,6 @@ void WebPageProxy::didReceiveEvent(uint32_t opaqueType, bool handled)
|
|
// The call to doneWithKeyEvent may close this WebPage.
|
|
// Protect against this being destroyed.
|
|
Ref<WebPageProxy> protect(*this);
|
|
-
|
|
pageClient().doneWithKeyEvent(event, handled);
|
|
if (!handled)
|
|
m_uiClient->didNotHandleKeyEvent(this, event);
|
|
@@ -7049,6 +7138,7 @@ void WebPageProxy::didReceiveEvent(uint32_t opaqueType, bool handled)
|
|
if (!canProcessMoreKeyEvents) {
|
|
if (auto* automationSession = process().processPool().automationSession())
|
|
automationSession->keyboardEventsFlushedForPage(*this);
|
|
+ m_inspectorController->didProcessAllPendingKeyboardEvents();
|
|
}
|
|
break;
|
|
}
|
|
@@ -7463,7 +7553,6 @@ static bool shouldReloadAfterProcessTermination(ProcessTerminationReason reason)
|
|
void WebPageProxy::dispatchProcessDidTerminate(ProcessTerminationReason reason)
|
|
{
|
|
RELEASE_LOG_ERROR_IF_ALLOWED(Loading, "dispatchProcessDidTerminate: reason = %d", reason);
|
|
-
|
|
// We notify the client asynchronously because several pages may share the same process
|
|
// and we want to make sure all pages are aware their process has crashed before the
|
|
// the client reacts to the process termination.
|
|
@@ -7471,7 +7560,10 @@ void WebPageProxy::dispatchProcessDidTerminate(ProcessTerminationReason reason)
|
|
if (!weakThis)
|
|
return;
|
|
|
|
- bool handledByClient = false;
|
|
+ bool handledByClient = m_inspectorController->pageCrashed(reason);
|
|
+ if (handledByClient)
|
|
+ return;
|
|
+
|
|
if (m_loaderClient)
|
|
handledByClient = reason != ProcessTerminationReason::RequestedByClient && m_loaderClient->processDidCrash(*this);
|
|
else
|
|
@@ -7740,6 +7832,7 @@ void WebPageProxy::resetStateAfterProcessExited(ProcessTerminationReason termina
|
|
|
|
WebPageCreationParameters WebPageProxy::creationParameters(WebProcessProxy& process, DrawingAreaProxy& drawingArea, RefPtr<API::WebsitePolicies>&& websitePolicies)
|
|
{
|
|
+
|
|
WebPageCreationParameters parameters;
|
|
|
|
parameters.processDisplayName = configuration().processDisplayName();
|
|
@@ -7899,6 +7992,8 @@ WebPageCreationParameters WebPageProxy::creationParameters(WebProcessProxy& proc
|
|
parameters.shouldRelaxThirdPartyCookieBlocking = m_configuration->shouldRelaxThirdPartyCookieBlocking();
|
|
parameters.canUseCredentialStorage = m_canUseCredentialStorage;
|
|
|
|
+ parameters.shouldPauseInInspectorWhenShown = m_inspectorController->shouldPauseLoading();
|
|
+
|
|
#if PLATFORM(GTK)
|
|
parameters.themeName = pageClient().themeName();
|
|
#endif
|
|
@@ -7972,6 +8067,14 @@ void WebPageProxy::gamepadActivity(const Vector<GamepadData>& gamepadDatas, Even
|
|
|
|
void WebPageProxy::didReceiveAuthenticationChallengeProxy(Ref<AuthenticationChallengeProxy>&& authenticationChallenge, NegotiatedLegacyTLS negotiatedLegacyTLS)
|
|
{
|
|
+ if (m_credentialsForAutomation.hasValue()) {
|
|
+ if (m_credentialsForAutomation->isEmpty() || authenticationChallenge->core().previousFailureCount()) {
|
|
+ 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 = makeRef(*this), authenticationChallenge] (bool shouldAllowLegacyTLS) {
|
|
if (shouldAllowLegacyTLS)
|
|
@@ -8057,7 +8160,8 @@ void WebPageProxy::requestGeolocationPermissionForFrame(GeolocationIdentifier ge
|
|
MESSAGE_CHECK(m_process, frame);
|
|
|
|
// FIXME: Geolocation should probably be using toString() as its string representation instead of databaseIdentifier().
|
|
- auto origin = API::SecurityOrigin::create(frameInfo.securityOrigin.securityOrigin());
|
|
+ auto securityOrigin = frameInfo.securityOrigin.securityOrigin();
|
|
+ auto origin = API::SecurityOrigin::create(securityOrigin);
|
|
auto request = m_geolocationPermissionRequestManager.createRequest(geolocationID);
|
|
Function<void(bool)> completionHandler = [request = WTFMove(request)](bool allowed) {
|
|
if (allowed)
|
|
@@ -8066,6 +8170,14 @@ void WebPageProxy::requestGeolocationPermissionForFrame(GeolocationIdentifier ge
|
|
request->deny();
|
|
};
|
|
|
|
+ auto permissions = m_permissionsForAutomation.find(securityOrigin->toString());
|
|
+ if (permissions == m_permissionsForAutomation.end())
|
|
+ permissions = m_permissionsForAutomation.find("*");
|
|
+ if (permissions != m_permissionsForAutomation.end()) {
|
|
+ completionHandler(permissions->value.contains("geolocation"));
|
|
+ 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
|
|
diff --git a/Source/WebKit/UIProcess/WebPageProxy.h b/Source/WebKit/UIProcess/WebPageProxy.h
|
|
index e47cb5e41f39ddb79fd51d751f93aef3dcbc255a..785d2a387e3c8971cf32596d9513d1bec9264ede 100644
|
|
--- a/Source/WebKit/UIProcess/WebPageProxy.h
|
|
+++ b/Source/WebKit/UIProcess/WebPageProxy.h
|
|
@@ -37,6 +37,7 @@
|
|
#include "GeolocationIdentifier.h"
|
|
#include "GeolocationPermissionRequestManagerProxy.h"
|
|
#include "HiddenPageThrottlingAutoIncreasesCounter.h"
|
|
+#include "InspectorDialogAgent.h"
|
|
#include "LayerTreeContext.h"
|
|
#include "MessageSender.h"
|
|
#include "NotificationPermissionRequestManagerProxy.h"
|
|
@@ -506,6 +507,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();
|
|
@@ -577,6 +580,11 @@ public:
|
|
|
|
void setPageLoadStateObserver(std::unique_ptr<PageLoadState::Observer>&&);
|
|
|
|
+ void setAuthCredentialsForAutomation(Optional<WebCore::Credential>&&);
|
|
+ void setPermissionsForAutomation(const HashMap<String, HashSet<String>>&);
|
|
+ void setActiveForAutomation(Optional<bool> active);
|
|
+ void logToStderr(const String& str);
|
|
+
|
|
void initializeWebPage();
|
|
void setDrawingArea(std::unique_ptr<DrawingAreaProxy>&&);
|
|
|
|
@@ -602,6 +610,7 @@ public:
|
|
void closePage();
|
|
|
|
void addPlatformLoadParameters(WebProcessProxy&, LoadParameters&);
|
|
+ RefPtr<API::Navigation> loadRequestForInspector(WebCore::ResourceRequest&&, WebFrameProxy*);
|
|
RefPtr<API::Navigation> loadRequest(WebCore::ResourceRequest&&, WebCore::ShouldOpenExternalURLsPolicy = WebCore::ShouldOpenExternalURLsPolicy::ShouldAllowExternalSchemesButNotAppLinks, API::Object* userData = nullptr);
|
|
RefPtr<API::Navigation> loadFile(const String& fileURL, const String& resourceDirectoryURL, API::Object* userData = nullptr);
|
|
RefPtr<API::Navigation> loadData(const IPC::DataReference&, const String& MIMEType, const String& encoding, const String& baseURL, API::Object* userData = nullptr, WebCore::ShouldOpenExternalURLsPolicy = WebCore::ShouldOpenExternalURLsPolicy::ShouldNotAllow);
|
|
@@ -1100,6 +1109,7 @@ public:
|
|
#endif
|
|
|
|
void pageScaleFactorDidChange(double);
|
|
+ void viewScaleFactorDidChange(double);
|
|
void pluginScaleFactorDidChange(double);
|
|
void pluginZoomFactorDidChange(double);
|
|
|
|
@@ -1416,6 +1426,8 @@ public:
|
|
|
|
#if PLATFORM(COCOA) || PLATFORM(GTK)
|
|
RefPtr<ViewSnapshot> takeViewSnapshot(Optional<WebCore::IntRect>&&);
|
|
+#elif PLATFORM(WPE)
|
|
+ RefPtr<ViewSnapshot> takeViewSnapshot(Optional<WebCore::IntRect>&&) { return nullptr; }
|
|
#endif
|
|
|
|
#if ENABLE(WEB_CRYPTO)
|
|
@@ -2421,6 +2433,7 @@ private:
|
|
String m_overrideContentSecurityPolicy;
|
|
|
|
RefPtr<WebInspectorProxy> m_inspector;
|
|
+ InspectorDialogAgent* m_inspectorDialogAgent { nullptr };
|
|
|
|
#if ENABLE(FULLSCREEN_API)
|
|
std::unique_ptr<WebFullScreenManagerProxy> m_fullScreenManager;
|
|
@@ -2857,6 +2870,9 @@ private:
|
|
RefPtr<API::Object> messageBody;
|
|
};
|
|
Vector<InjectedBundleMessage> m_pendingInjectedBundleMessages;
|
|
+ Optional<WebCore::Credential> m_credentialsForAutomation;
|
|
+ HashMap<String, HashSet<String>> m_permissionsForAutomation;
|
|
+ Optional<bool> m_activeForAutomation;
|
|
|
|
#if PLATFORM(IOS_FAMILY) && ENABLE(DEVICE_ORIENTATION)
|
|
std::unique_ptr<WebDeviceOrientationUpdateProviderProxy> m_webDeviceOrientationUpdateProviderProxy;
|
|
diff --git a/Source/WebKit/UIProcess/WebPageProxy.messages.in b/Source/WebKit/UIProcess/WebPageProxy.messages.in
|
|
index 42145f2c5c04b338ab041fb06d69686c2f579152..07d9076ab5db78c99558d9e6d057928decdb469b 100644
|
|
--- a/Source/WebKit/UIProcess/WebPageProxy.messages.in
|
|
+++ b/Source/WebKit/UIProcess/WebPageProxy.messages.in
|
|
@@ -29,6 +29,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, uint32_t modifiers, WebKit::UserData userData)
|
|
+ LogToStderr(String text)
|
|
|
|
#if ENABLE(NETSCAPE_PLUGIN_API)
|
|
UnavailablePluginButtonClicked(uint32_t pluginUnavailabilityReason, String mimeType, String pluginURLString, String pluginspageAttributeURLString, String frameURLString, String pageURLString)
|
|
@@ -206,6 +207,7 @@ messages -> WebPageProxy {
|
|
#endif
|
|
|
|
PageScaleFactorDidChange(double scaleFactor)
|
|
+ ViewScaleFactorDidChange(double scaleFactor)
|
|
PluginScaleFactorDidChange(double zoomFactor)
|
|
PluginZoomFactorDidChange(double zoomFactor)
|
|
|
|
diff --git a/Source/WebKit/UIProcess/WebProcessPool.cpp b/Source/WebKit/UIProcess/WebProcessPool.cpp
|
|
index 8d987bb66d14340896128d73930f2a1cadd699a6..ceda3697d560f76d451319acb484641e6764dd8b 100644
|
|
--- a/Source/WebKit/UIProcess/WebProcessPool.cpp
|
|
+++ b/Source/WebKit/UIProcess/WebProcessPool.cpp
|
|
@@ -509,6 +509,14 @@ void WebProcessPool::establishWorkerContextConnectionToNetworkProcess(NetworkPro
|
|
|
|
// Arbitrarily choose the first process pool to host the service worker process.
|
|
auto* processPool = processPools()[0];
|
|
+ // Playwright begin
|
|
+ for (auto& process : websiteDataStore->processes()) {
|
|
+ if (process.processPoolIfExists()) {
|
|
+ processPool = process.processPoolIfExists();
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ // Playwright end
|
|
ASSERT(processPool);
|
|
|
|
WebProcessProxy* serviceWorkerProcessProxy { nullptr };
|
|
@@ -745,7 +753,10 @@ void WebProcessPool::initializeNewWebProcess(WebProcessProxy& process, WebsiteDa
|
|
#endif
|
|
|
|
parameters.cacheModel = LegacyGlobalSettings::singleton().cacheModel();
|
|
- parameters.overrideLanguages = configuration().overrideLanguages();
|
|
+ if (websiteDataStore && websiteDataStore->languagesForAutomation().size())
|
|
+ parameters.overrideLanguages = websiteDataStore->languagesForAutomation();
|
|
+ else
|
|
+ parameters.overrideLanguages = configuration().overrideLanguages();
|
|
|
|
parameters.urlSchemesRegisteredAsEmptyDocument = copyToVector(m_schemesToRegisterAsEmptyDocument);
|
|
parameters.urlSchemesRegisteredAsSecure = copyToVector(LegacyGlobalSettings::singleton().schemesToRegisterAsSecure());
|
|
diff --git a/Source/WebKit/UIProcess/WebProcessProxy.cpp b/Source/WebKit/UIProcess/WebProcessProxy.cpp
|
|
index 40c49a99327b1856b0506b443ba8b41a3ab1b70a..3ffc6c0911d2838880049a4e3e4bbd85c6738cf7 100644
|
|
--- a/Source/WebKit/UIProcess/WebProcessProxy.cpp
|
|
+++ b/Source/WebKit/UIProcess/WebProcessProxy.cpp
|
|
@@ -116,6 +116,11 @@ HashMap<ProcessIdentifier, WebProcessProxy*>& WebProcessProxy::allProcesses()
|
|
return map;
|
|
}
|
|
|
|
+Vector<WebProcessProxy*> WebProcessProxy::allProcessesForInspector()
|
|
+{
|
|
+ return copyToVector(allProcesses().values());
|
|
+}
|
|
+
|
|
WebProcessProxy* WebProcessProxy::processForIdentifier(ProcessIdentifier identifier)
|
|
{
|
|
return allProcesses().get(identifier);
|
|
diff --git a/Source/WebKit/UIProcess/WebProcessProxy.h b/Source/WebKit/UIProcess/WebProcessProxy.h
|
|
index 4439f20732ddf1a13bce83453c0927e23ac9bb8e..cbc00cd3c3482154274472f24fbeb2786c47974d 100644
|
|
--- a/Source/WebKit/UIProcess/WebProcessProxy.h
|
|
+++ b/Source/WebKit/UIProcess/WebProcessProxy.h
|
|
@@ -132,6 +132,7 @@ public:
|
|
~WebProcessProxy();
|
|
|
|
static void forWebPagesWithOrigin(PAL::SessionID, const WebCore::SecurityOriginData&, const Function<void(WebPageProxy&)>&);
|
|
+ static Vector<WebProcessProxy*> allProcessesForInspector();
|
|
|
|
WebConnection* webConnection() const { return m_webConnection.get(); }
|
|
|
|
diff --git a/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp b/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp
|
|
index 41191febbc3fbbbf64e6e98ab76f7d0ec5ee14ca..df6d5de947938940aefef7d355858264cd06658a 100644
|
|
--- a/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp
|
|
+++ b/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp
|
|
@@ -2317,6 +2317,17 @@ void WebsiteDataStore::renameOriginInWebsiteData(URL&& oldName, URL&& newName, O
|
|
networkProcess().renameOriginInWebsiteData(m_sessionID, oldName, newName, dataTypes, WTFMove(completionHandler));
|
|
}
|
|
|
|
+void WebsiteDataStore::setLanguagesForAutomation(Vector<String>&& languages)
|
|
+{
|
|
+ m_languagesForAutomation = WTFMove(languages);
|
|
+}
|
|
+
|
|
+void WebsiteDataStore::setDownloadForAutomation(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 ae8e3132c5b6117f81a6f918e9cd353430d1212b..87befc693352c276267c35dbbf55f246b8dfbed9 100644
|
|
--- a/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h
|
|
+++ b/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h
|
|
@@ -92,6 +92,7 @@ enum class CacheModel : uint8_t;
|
|
enum class WebsiteDataFetchOption : uint8_t;
|
|
enum class WebsiteDataType : uint32_t;
|
|
|
|
+struct FrameInfoData;
|
|
struct NetworkProcessConnectionInfo;
|
|
struct WebsiteDataRecord;
|
|
struct WebsiteDataStoreParameters;
|
|
@@ -106,6 +107,16 @@ enum class StorageAccessPromptStatus;
|
|
struct PluginModuleInfo;
|
|
#endif
|
|
|
|
+class WebsiteDataStore;
|
|
+
|
|
+class DownloadInstrumentation {
|
|
+public:
|
|
+ virtual void downloadCreated(const String& uuid, const WebCore::ResourceRequest&, const FrameInfoData& frameInfoData, WebPageProxy* page) = 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 Identified<WebsiteDataStore>, public CanMakeWeakPtr<WebsiteDataStore> {
|
|
public:
|
|
static Ref<WebsiteDataStore> defaultDataStore();
|
|
@@ -276,11 +287,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; }
|
|
#endif
|
|
@@ -333,6 +346,14 @@ public:
|
|
static WTF::String defaultJavaScriptConfigurationDirectory();
|
|
static bool http3Enabled();
|
|
|
|
+ void setLanguagesForAutomation(Vector<String>&&);
|
|
+ Vector<String>& languagesForAutomation() { return m_languagesForAutomation; };
|
|
+ void setDownloadForAutomation(Optional<bool> allow, const String& downloadPath);
|
|
+ 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()>&&);
|
|
|
|
#if ENABLE(APP_BOUND_DOMAINS)
|
|
@@ -417,9 +438,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;
|
|
#endif
|
|
|
|
@@ -445,6 +468,11 @@ private:
|
|
RefPtr<API::HTTPCookieStore> m_cookieStore;
|
|
RefPtr<NetworkProcessProxy> m_networkProcess;
|
|
|
|
+ Vector<String> m_languagesForAutomation;
|
|
+ Optional<bool> m_allowDownloadForAutomation;
|
|
+ String m_downloadPathForAutomation;
|
|
+ DownloadInstrumentation* m_downloadInstrumentation { nullptr };
|
|
+
|
|
#if HAVE(APP_SSO)
|
|
UniqueRef<SOAuthorizationCoordinator> m_soAuthorizationCoordinator;
|
|
#endif
|
|
diff --git a/Source/WebKit/UIProcess/cairo/BackingStoreCairo.cpp b/Source/WebKit/UIProcess/cairo/BackingStoreCairo.cpp
|
|
index dc0a70b8824afdc7ec3dd1f69f4d9b51942924f6..a4e90dc22fb278864c49c0636964e82f3d0d7193 100644
|
|
--- a/Source/WebKit/UIProcess/cairo/BackingStoreCairo.cpp
|
|
+++ b/Source/WebKit/UIProcess/cairo/BackingStoreCairo.cpp
|
|
@@ -27,9 +27,11 @@
|
|
#include "config.h"
|
|
#include "BackingStore.h"
|
|
|
|
+#include "DrawingAreaProxyCoordinatedGraphics.h"
|
|
#include "ShareableBitmap.h"
|
|
#include "UpdateInfo.h"
|
|
#include "WebPageProxy.h"
|
|
+#include "WebPageInspectorController.h"
|
|
#include <WebCore/BackingStoreBackendCairoImpl.h>
|
|
#include <WebCore/CairoUtilities.h>
|
|
#include <WebCore/GraphicsContextImplCairo.h>
|
|
@@ -62,6 +64,13 @@ std::unique_ptr<BackingStoreBackendCairo> BackingStore::createBackend()
|
|
return makeUnique<BackingStoreBackendCairoImpl>(m_size, m_deviceScaleFactor);
|
|
}
|
|
|
|
+cairo_surface_t* BackingStore::surface() const {
|
|
+ if (!m_backend)
|
|
+ return nullptr;
|
|
+
|
|
+ return m_backend->surface();
|
|
+}
|
|
+
|
|
void BackingStore::paint(cairo_t* context, const IntRect& rect)
|
|
{
|
|
ASSERT(m_backend);
|
|
diff --git a/Source/WebKit/UIProcess/geoclue/GeoclueGeolocationProvider.cpp b/Source/WebKit/UIProcess/geoclue/GeoclueGeolocationProvider.cpp
|
|
index 411056d43ea764c42bce0403e6c69ddb8b24b04e..86d4e842699a230ce595088b62a29eabea5b6b90 100644
|
|
--- a/Source/WebKit/UIProcess/geoclue/GeoclueGeolocationProvider.cpp
|
|
+++ b/Source/WebKit/UIProcess/geoclue/GeoclueGeolocationProvider.cpp
|
|
@@ -60,6 +60,8 @@ void GeoclueGeolocationProvider::start(UpdateNotifyFunction&& updateNotifyFuncti
|
|
m_isRunning = true;
|
|
m_cancellable = adoptGRef(g_cancellable_new());
|
|
if (!m_manager) {
|
|
+ g_cancellable_cancel(m_cancellable_start.get());
|
|
+ m_cancellable_start = adoptGRef(g_cancellable_new());
|
|
g_dbus_proxy_new_for_bus(G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, nullptr,
|
|
"org.freedesktop.GeoClue2", "/org/freedesktop/GeoClue2/Manager", "org.freedesktop.GeoClue2.Manager", m_cancellable.get(),
|
|
[](GObject*, GAsyncResult* result, gpointer userData) {
|
|
@@ -91,6 +93,12 @@ void GeoclueGeolocationProvider::stop()
|
|
g_cancellable_cancel(m_cancellable.get());
|
|
m_cancellable = nullptr;
|
|
stopClient();
|
|
+ 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;
|
|
destroyManagerLater();
|
|
}
|
|
|
|
@@ -153,6 +161,8 @@ void GeoclueGeolocationProvider::createClient(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 31d29091985f34a65134a2b0e7cb3ace1dae441d..571ceac8a4b291fa6e91eb8b17065c0aba908ac3 100644
|
|
--- a/Source/WebKit/UIProcess/geoclue/GeoclueGeolocationProvider.h
|
|
+++ b/Source/WebKit/UIProcess/geoclue/GeoclueGeolocationProvider.h
|
|
@@ -71,6 +71,9 @@ private:
|
|
GRefPtr<GDBusProxy> m_manager;
|
|
GRefPtr<GDBusProxy> m_client;
|
|
GRefPtr<GCancellable> m_cancellable;
|
|
+ GRefPtr<GCancellable> m_cancellable_start;
|
|
+ GRefPtr<GCancellable> m_cancellable_setup;
|
|
+ GRefPtr<GCancellable> m_cancellable_create;
|
|
UpdateNotifyFunction m_updateNotifyFunction;
|
|
RunLoop::Timer<GeoclueGeolocationProvider> m_destroyManagerLaterTimer;
|
|
};
|
|
diff --git a/Source/WebKit/UIProcess/glib/InspectorPlaywrightAgentClientGLib.cpp b/Source/WebKit/UIProcess/glib/InspectorPlaywrightAgentClientGLib.cpp
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..09cbc4f3abbeb329c0b396b946b77614a911e8b0
|
|
--- /dev/null
|
|
+++ b/Source/WebKit/UIProcess/glib/InspectorPlaywrightAgentClientGLib.cpp
|
|
@@ -0,0 +1,146 @@
|
|
+/*
|
|
+ * 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 "WebKitBrowserInspectorPrivate.h"
|
|
+#include "WebKitWebContextPrivate.h"
|
|
+#include "WebKitWebsiteDataManagerPrivate.h"
|
|
+#include "WebKitWebViewPrivate.h"
|
|
+#include "WebPageProxy.h"
|
|
+#include <wtf/HashMap.h>
|
|
+#include <wtf/RefPtr.h>
|
|
+#include <wtf/text/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));
|
|
+ }
|
|
+ }
|
|
+ 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";
|
|
+ return nullptr;
|
|
+ }
|
|
+
|
|
+ RefPtr<WebPageProxy> page = webkitBrowserInspectorCreateNewPageInContext(context);
|
|
+ if (page == nullptr) {
|
|
+ error = "Failed to create new page in the context";
|
|
+ return nullptr;
|
|
+ }
|
|
+
|
|
+ if (context == nullptr && sessionID != page->sessionID()) {
|
|
+ ASSERT_NOT_REACHED();
|
|
+ error = " Failed to create new page in default context";
|
|
+ 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());
|
|
+}
|
|
+
|
|
+static PAL::SessionID sessionIDFromContext(WebKitWebContext* context)
|
|
+{
|
|
+ WebKitWebsiteDataManager* data_manager = webkit_web_context_get_website_data_manager(context);
|
|
+ WebsiteDataStore& websiteDataStore = webkitWebsiteDataManagerGetDataStore(data_manager);
|
|
+ return websiteDataStore.sessionID();
|
|
+}
|
|
+
|
|
+std::unique_ptr<BrowserContext> InspectorPlaywrightAgentClientGlib::createBrowserContext(WTF::String& error, const WTF::String& proxyServer, const WTF::String& proxyBypassList)
|
|
+{
|
|
+ GRefPtr<WebKitWebsiteDataManager> data_manager = adoptGRef(webkit_website_data_manager_new_ephemeral());
|
|
+ GRefPtr<WebKitWebContext> context = adoptGRef(WEBKIT_WEB_CONTEXT(g_object_new(WEBKIT_TYPE_WEB_CONTEXT, "website-data-manager", data_manager.get(), "process-swap-on-cross-site-navigation-enabled", true, nullptr)));
|
|
+ if (!context) {
|
|
+ error = "Failed to create GLib ephemeral context";
|
|
+ return nullptr;
|
|
+ }
|
|
+ auto browserContext = std::make_unique<BrowserContext>();
|
|
+ browserContext->processPool = &webkitWebContextGetProcessPool(context.get());
|
|
+ browserContext->dataStore = &webkitWebsiteDataManagerGetDataStore(data_manager.get());
|
|
+ PAL::SessionID sessionID = sessionIDFromContext(context.get());
|
|
+ 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);
|
|
+}
|
|
+
|
|
+} // 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..8006336003a4512b4c63bc8272d4b3507bb63159
|
|
--- /dev/null
|
|
+++ b/Source/WebKit/UIProcess/glib/InspectorPlaywrightAgentClientGLib.h
|
|
@@ -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.
|
|
+ */
|
|
+
|
|
+#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;
|
|
+
|
|
+private:
|
|
+ WebKitWebContext* findContext(WTF::String& error, PAL::SessionID);
|
|
+
|
|
+ HashMap<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 39aeff71fe05354cf63d3b3701d363642d63aca4..32e96cdd0bdbd8c5dcde43fdf60052ac13a226f7 100644
|
|
--- a/Source/WebKit/UIProcess/gtk/AcceleratedBackingStore.h
|
|
+++ b/Source/WebKit/UIProcess/gtk/AcceleratedBackingStore.h
|
|
@@ -28,6 +28,7 @@
|
|
#include <wtf/Noncopyable.h>
|
|
|
|
typedef struct _cairo cairo_t;
|
|
+typedef struct _cairo_surface cairo_surface_t;
|
|
|
|
#if USE(GTK4)
|
|
typedef struct _GdkSnapshot GdkSnapshot;
|
|
@@ -56,6 +57,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 bool makeContextCurrent() { return false; }
|
|
diff --git a/Source/WebKit/UIProcess/gtk/AcceleratedBackingStoreX11.h b/Source/WebKit/UIProcess/gtk/AcceleratedBackingStoreX11.h
|
|
index 054e80bd900cf16d69801e8102ca989ff0563e1d..8245d7ed58008dbb6152e55e619e4331d30ae674 100644
|
|
--- a/Source/WebKit/UIProcess/gtk/AcceleratedBackingStoreX11.h
|
|
+++ b/Source/WebKit/UIProcess/gtk/AcceleratedBackingStoreX11.h
|
|
@@ -52,6 +52,7 @@ private:
|
|
#else
|
|
bool paint(cairo_t*, const WebCore::IntRect&) override;
|
|
#endif
|
|
+ cairo_surface_t* surface() override { return m_surface.get(); }
|
|
|
|
RefPtr<cairo_surface_t> m_surface;
|
|
WebCore::XUniqueDamage m_damage;
|
|
diff --git a/Source/WebKit/UIProcess/gtk/InspectorTargetProxyGtk.cpp b/Source/WebKit/UIProcess/gtk/InspectorTargetProxyGtk.cpp
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..8a86cc348bc210b71bb463dcb3057f575ad7c1d3
|
|
--- /dev/null
|
|
+++ b/Source/WebKit/UIProcess/gtk/InspectorTargetProxyGtk.cpp
|
|
@@ -0,0 +1,44 @@
|
|
+/*
|
|
+ * Copyright (C) 2019 Microsoft Corporation.
|
|
+ *
|
|
+ * Redistribution and use in source and binary forms, with or without
|
|
+ * modification, are permitted provided that the following conditions
|
|
+ * are met:
|
|
+ * 1. Redistributions of source code must retain the above copyright
|
|
+ * notice, this list of conditions and the following disclaimer.
|
|
+ * 2. Redistributions in binary form must reproduce the above copyright
|
|
+ * notice, this list of conditions and the following disclaimer in the
|
|
+ * documentation and/or other materials provided with the distribution.
|
|
+ *
|
|
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
+ */
|
|
+
|
|
+#include "config.h"
|
|
+#include "InspectorTargetProxy.h"
|
|
+
|
|
+#include "WebPageProxy.h"
|
|
+#include <WebCore/GtkUtilities.h>
|
|
+#include <gtk/gtk.h>
|
|
+
|
|
+namespace WebKit {
|
|
+
|
|
+void InspectorTargetProxy::platformActivate(String& error) const
|
|
+{
|
|
+ GtkWidget* parent = gtk_widget_get_toplevel(m_page.viewWidget());
|
|
+ if (WebCore::widgetIsOnscreenToplevelWindow(parent))
|
|
+ gtk_window_present(GTK_WINDOW(parent));
|
|
+ else
|
|
+ error = "The view is not on screen";
|
|
+}
|
|
+
|
|
+} // namespace WebKit
|
|
diff --git a/Source/WebKit/UIProcess/gtk/WebPageInspectorEmulationAgentGtk.cpp b/Source/WebKit/UIProcess/gtk/WebPageInspectorEmulationAgentGtk.cpp
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..e5e25acebabb76a05a77db02a99f1267bd99a3af
|
|
--- /dev/null
|
|
+++ b/Source/WebKit/UIProcess/gtk/WebPageInspectorEmulationAgentGtk.cpp
|
|
@@ -0,0 +1,69 @@
|
|
+/*
|
|
+ * 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 {
|
|
+void WebPageInspectorEmulationAgent::platformSetSize(int width, int height, Function<void (const String& error)>&& callback)
|
|
+{
|
|
+ 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 (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())) {
|
|
+ drawingArea->waitForSizeUpdate([callback = WTFMove(callback)]() {
|
|
+ callback(String());
|
|
+ });
|
|
+ } else {
|
|
+ callback("No backing store for window"_s);
|
|
+ }
|
|
+ gtk_window_resize(GTK_WINDOW(window), width, height);
|
|
+}
|
|
+
|
|
+} // namespace WebKit
|
|
diff --git a/Source/WebKit/UIProcess/gtk/WebPageInspectorInputAgentGtk.cpp b/Source/WebKit/UIProcess/gtk/WebPageInspectorInputAgentGtk.cpp
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..d0f9827544994e450e24e3f7a427c35eeff94d67
|
|
--- /dev/null
|
|
+++ b/Source/WebKit/UIProcess/gtk/WebPageInspectorInputAgentGtk.cpp
|
|
@@ -0,0 +1,105 @@
|
|
+/*
|
|
+ * 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 Vector<String> commandsForKeyEvent(GdkEventType type, unsigned keyVal, unsigned state)
|
|
+{
|
|
+ ASSERT(type == GDK_KEY_PRESS || type == GDK_KEY_RELEASE);
|
|
+
|
|
+ GUniquePtr<GdkEvent> event(gdk_event_new(type));
|
|
+ event->key.keyval = keyVal;
|
|
+ event->key.time = GDK_CURRENT_TIME;
|
|
+ event->key.state = state;
|
|
+ // When synthesizing an event, an invalid hardware_keycode value can cause it to be badly processed by GTK+.
|
|
+ GUniqueOutPtr<GdkKeymapKey> keys;
|
|
+ int keysCount;
|
|
+ if (gdk_keymap_get_entries_for_keyval(gdk_keymap_get_default(), keyVal, &keys.outPtr(), &keysCount) && keysCount)
|
|
+ event->key.hardware_keycode = keys.get()[0].keycode;
|
|
+ return KeyBindingTranslator().commandsForKeyEvent(&event->key);
|
|
+}
|
|
+
|
|
+static unsigned modifiersToEventState(OptionSet<WebEvent::Modifier> modifiers)
|
|
+{
|
|
+ unsigned state = 0;
|
|
+ if (modifiers.contains(WebEvent::Modifier::ControlKey))
|
|
+ state |= GDK_CONTROL_MASK;
|
|
+ if (modifiers.contains(WebEvent::Modifier::ShiftKey))
|
|
+ state |= GDK_SHIFT_MASK;
|
|
+ if (modifiers.contains(WebEvent::Modifier::AltKey))
|
|
+ state |= GDK_META_MASK;
|
|
+ if (modifiers.contains(WebEvent::Modifier::CapsLockKey))
|
|
+ state |= GDK_LOCK_MASK;
|
|
+ return state;
|
|
+}
|
|
+
|
|
+void WebPageInspectorInputAgent::platformDispatchKeyEvent(WebKeyboardEvent::Type 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<WebEvent::Modifier> modifiers, Vector<String>& macCommands, WallTime timestamp)
|
|
+{
|
|
+ Vector<String> commands;
|
|
+ const guint keyVal = WebCore::PlatformKeyboardEvent::gdkKeyCodeForWindowsKeyCode(windowsVirtualKeyCode);
|
|
+ if (keyVal) {
|
|
+ GdkEventType event = GDK_NOTHING;
|
|
+ switch (type)
|
|
+ {
|
|
+ case WebKeyboardEvent::KeyDown:
|
|
+ event = GDK_KEY_PRESS;
|
|
+ break;
|
|
+ case WebKeyboardEvent::KeyUp:
|
|
+ event = GDK_KEY_RELEASE;
|
|
+ break;
|
|
+ default:
|
|
+ fprintf(stderr, "Unsupported event type = %d\n", type);
|
|
+ break;
|
|
+ }
|
|
+ unsigned state = modifiersToEventState(modifiers);
|
|
+ commands = commandsForKeyEvent(event, 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/ios/PageClientImplIOS.mm b/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm
|
|
index b3d1b3891d819d4d1d4f2ac91b2c4951904435b9..54e7e65b4c0a48a9cf8a60cb51122f9095f4bbf7 100644
|
|
--- a/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm
|
|
+++ b/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm
|
|
@@ -436,6 +436,8 @@ IntRect PageClientImpl::rootViewToAccessibilityScreen(const IntRect& rect)
|
|
|
|
void PageClientImpl::doneWithKeyEvent(const NativeWebKeyboardEvent& event, bool eventWasHandled)
|
|
{
|
|
+ if (!event.nativeEvent())
|
|
+ return;
|
|
[m_contentView _didHandleKeyEvent:event.nativeEvent() eventWasHandled:eventWasHandled];
|
|
}
|
|
|
|
diff --git a/Source/WebKit/UIProcess/mac/InspectorPlaywrightAgentClientMac.h b/Source/WebKit/UIProcess/mac/InspectorPlaywrightAgentClientMac.h
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..a16815a6759da61a6a61e3d79058228af887fd7c
|
|
--- /dev/null
|
|
+++ b/Source/WebKit/UIProcess/mac/InspectorPlaywrightAgentClientMac.h
|
|
@@ -0,0 +1,51 @@
|
|
+/*
|
|
+ * 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);
|
|
+ ~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;
|
|
+
|
|
+private:
|
|
+ _WKBrowserInspectorDelegate* delegate_;
|
|
+};
|
|
+
|
|
+
|
|
+} // namespace API
|
|
diff --git a/Source/WebKit/UIProcess/mac/InspectorPlaywrightAgentClientMac.mm b/Source/WebKit/UIProcess/mac/InspectorPlaywrightAgentClientMac.mm
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..8e588f7b8c8c29fb53dd37ea41d46f3d753077fd
|
|
--- /dev/null
|
|
+++ b/Source/WebKit/UIProcess/mac/InspectorPlaywrightAgentClientMac.mm
|
|
@@ -0,0 +1,77 @@
|
|
+/*
|
|
+ * 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 <wtf/RefPtr.h>
|
|
+#import <wtf/text/WTFString.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"
|
|
+
|
|
+namespace WebKit {
|
|
+
|
|
+InspectorPlaywrightAgentClientMac::InspectorPlaywrightAgentClientMac(_WKBrowserInspectorDelegate* delegate)
|
|
+ : delegate_(delegate)
|
|
+{
|
|
+}
|
|
+
|
|
+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()];
|
|
+}
|
|
+
|
|
+} // namespace WebKit
|
|
diff --git a/Source/WebKit/UIProcess/mac/InspectorTargetProxyMac.mm b/Source/WebKit/UIProcess/mac/InspectorTargetProxyMac.mm
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..721826c8c98fc85b68a4f45deaee69c1219a7254
|
|
--- /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 81a2c861c9ad71b83221d9a978e67e7379617a2c..8b070646433218dc41d7ce2fa85f5d8f71be436e 100644
|
|
--- a/Source/WebKit/UIProcess/mac/PageClientImplMac.h
|
|
+++ b/Source/WebKit/UIProcess/mac/PageClientImplMac.h
|
|
@@ -53,6 +53,8 @@ class PageClientImpl final : public PageClientImplCocoa
|
|
#endif
|
|
{
|
|
public:
|
|
+ static void setHeadless(bool headless);
|
|
+
|
|
PageClientImpl(NSView *, WKWebView *);
|
|
virtual ~PageClientImpl();
|
|
|
|
@@ -119,6 +121,7 @@ private:
|
|
WebCore::IntRect rootViewToScreen(const WebCore::IntRect&) override;
|
|
#if PLATFORM(MAC)
|
|
WebCore::IntRect rootViewToWindow(const WebCore::IntRect&) override;
|
|
+ int browserToolbarHeight() const override;
|
|
#endif
|
|
WebCore::IntPoint accessibilityScreenToRootView(const WebCore::IntPoint&) override;
|
|
WebCore::IntRect rootViewToAccessibilityScreen(const WebCore::IntRect&) override;
|
|
@@ -158,6 +161,9 @@ private:
|
|
void updateAcceleratedCompositingMode(const LayerTreeContext&) override;
|
|
void didFirstLayerFlush(const LayerTreeContext&) override;
|
|
|
|
+// Paywright begin
|
|
+ RetainPtr<CGImageRef> takeSnapshotForAutomation() override;
|
|
+// Paywright end
|
|
RefPtr<ViewSnapshot> takeViewSnapshot(Optional<WebCore::IntRect>&&) override;
|
|
void wheelEventWasNotHandledByWebCore(const NativeWebWheelEvent&) override;
|
|
#if ENABLE(MAC_GESTURE_EVENTS)
|
|
@@ -212,6 +218,10 @@ private:
|
|
void beganExitFullScreen(const WebCore::IntRect& initialFrame, const WebCore::IntRect& finalFrame) 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 d9ba4d000b94357287434c750bbae66ca6b1d432..f257f52b169669a112d5d08682deeef9d952c59f 100644
|
|
--- a/Source/WebKit/UIProcess/mac/PageClientImplMac.mm
|
|
+++ b/Source/WebKit/UIProcess/mac/PageClientImplMac.mm
|
|
@@ -80,6 +80,7 @@
|
|
#import <WebCore/TextUndoInsertionMarkupMac.h>
|
|
#import <WebCore/ValidationBubble.h>
|
|
#import <WebCore/WebCoreCALayerExtras.h>
|
|
+#import <WebCore/NotImplemented.h>
|
|
#import <pal/spi/mac/NSApplicationSPI.h>
|
|
#import <wtf/ProcessPrivilege.h>
|
|
#import <wtf/RetainPtr.h>
|
|
@@ -106,6 +107,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)
|
|
@@ -159,6 +167,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);
|
|
@@ -166,6 +177,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)
|
|
@@ -189,6 +203,9 @@ void PageClientImpl::makeFirstResponder()
|
|
|
|
bool PageClientImpl::isViewVisible()
|
|
{
|
|
+ if (_headless)
|
|
+ return true;
|
|
+
|
|
NSView *activeView = this->activeView();
|
|
NSWindow *activeViewWindow = activeWindow();
|
|
|
|
@@ -272,7 +289,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)
|
|
@@ -460,6 +478,15 @@ IntRect PageClientImpl::rootViewToWindow(const WebCore::IntRect& rect)
|
|
return enclosingIntRect(tempRect);
|
|
}
|
|
|
|
+int PageClientImpl::browserToolbarHeight() const
|
|
+{
|
|
+ // There are no controls in headless mode.
|
|
+ if (_headless)
|
|
+ return 0;
|
|
+
|
|
+ return 55;
|
|
+}
|
|
+
|
|
IntPoint PageClientImpl::accessibilityScreenToRootView(const IntPoint& point)
|
|
{
|
|
return screenToRootView(point);
|
|
@@ -472,11 +499,15 @@ IntRect PageClientImpl::rootViewToAccessibilityScreen(const IntRect& rect)
|
|
|
|
void PageClientImpl::doneWithKeyEvent(const NativeWebKeyboardEvent& event, bool eventWasHandled)
|
|
{
|
|
+ if (!event.nativeEvent())
|
|
+ return;
|
|
m_impl->doneWithKeyEvent(event.nativeEvent(), eventWasHandled);
|
|
}
|
|
|
|
RefPtr<WebPopupMenuProxy> PageClientImpl::createPopupMenuProxy(WebPageProxy& page)
|
|
{
|
|
+ if (_headless)
|
|
+ return nullptr;
|
|
return WebPopupMenuProxyMac::create(m_view, page);
|
|
}
|
|
|
|
@@ -596,6 +627,12 @@ CALayer *PageClientImpl::acceleratedCompositingRootLayer() const
|
|
return m_impl->acceleratedCompositingRootLayer();
|
|
}
|
|
|
|
+// Paywright begin
|
|
+RetainPtr<CGImageRef> PageClientImpl::takeSnapshotForAutomation() {
|
|
+ return m_impl->takeSnapshotForAutomation();
|
|
+}
|
|
+// Paywright begin
|
|
+
|
|
RefPtr<ViewSnapshot> PageClientImpl::takeViewSnapshot(Optional<WebCore::IntRect>&&)
|
|
{
|
|
return m_impl->takeViewSnapshot();
|
|
@@ -774,6 +811,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);
|
|
@@ -940,6 +984,9 @@ void PageClientImpl::didRestoreScrollPosition()
|
|
|
|
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/WebContextMenuProxyMac.h b/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.h
|
|
index 0bb07e679f30e7b3682b3736b5372cbbb2d31ec8..cc0740c7d88d11d419cf2ca51cbc00b193531100 100644
|
|
--- a/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.h
|
|
+++ b/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.h
|
|
@@ -62,6 +62,7 @@ private:
|
|
void show() override;
|
|
void showContextMenuWithItems(Vector<Ref<WebContextMenuItem>>&&) override;
|
|
void useContextMenuItems(Vector<Ref<WebContextMenuItem>>&&) override;
|
|
+ void hide() override;
|
|
|
|
void getContextMenuItem(const WebContextMenuItemData&, CompletionHandler<void(NSMenuItem *)>&&);
|
|
void getContextMenuFromItems(const Vector<WebContextMenuItemData>&, CompletionHandler<void(NSMenu *)>&&);
|
|
diff --git a/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.mm b/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.mm
|
|
index 5ad887b13fb41224383e40014b48910cbe2e7dcd..b6a2b93f13bdc6be626bcbb9282ac26da1415049 100644
|
|
--- a/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.mm
|
|
+++ b/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.mm
|
|
@@ -326,6 +326,12 @@ void WebContextMenuProxyMac::getShareMenuItem(CompletionHandler<void(NSMenuItem
|
|
}
|
|
#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..726053d74b9283d734d8699daca0e5e7f8893eca
|
|
--- /dev/null
|
|
+++ b/Source/WebKit/UIProcess/mac/WebPageInspectorInputAgentMac.mm
|
|
@@ -0,0 +1,124 @@
|
|
+/*
|
|
+ * 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 "WebPageInspectorInputAgent.h"
|
|
+#import "WebPageProxy.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, Optional<int>&& optionalModifiers, const String& button, Optional<int>&& optionalClickCount) {
|
|
+ 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)0;
|
|
+ NSEventType dragEventType = (NSEventType)0;
|
|
+ NSEventType upEventType = (NSEventType)0;
|
|
+
|
|
+ if (!button || button == "none") {
|
|
+ downEventType = NSEventTypeMouseMoved;
|
|
+ dragEventType = NSEventTypeMouseMoved;
|
|
+ upEventType = NSEventTypeMouseMoved;
|
|
+ } else if (button == "left") {
|
|
+ downEventType = NSEventTypeLeftMouseDown;
|
|
+ dragEventType = NSEventTypeLeftMouseDragged;
|
|
+ upEventType = NSEventTypeLeftMouseUp;
|
|
+ } else if (button == "middle") {
|
|
+ downEventType = NSEventTypeOtherMouseDown;
|
|
+ dragEventType = NSEventTypeLeftMouseDragged;
|
|
+ upEventType = NSEventTypeOtherMouseUp;
|
|
+ } else if (button == "right") {
|
|
+ downEventType = NSEventTypeRightMouseDown;
|
|
+ upEventType = NSEventTypeRightMouseUp;
|
|
+ }
|
|
+
|
|
+ NSInteger eventNumber = 0;
|
|
+
|
|
+ NSEvent* event = nil;
|
|
+ if (type == "move") {
|
|
+ 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") {
|
|
+ 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") {
|
|
+ event = [NSEvent mouseEventWithType:upEventType location:locationInWindow modifierFlags:modifiers timestamp:timestamp windowNumber:windowNumber context:nil eventNumber:eventNumber clickCount:clickCount pressure:0.0f];
|
|
+ }
|
|
+
|
|
+ if (event) {
|
|
+ NativeWebMouseEvent nativeEvent(event, nil, [window contentView]);
|
|
+ m_page.handleMouseEvent(nativeEvent);
|
|
+ }
|
|
+}
|
|
+
|
|
+void WebPageInspectorInputAgent::platformDispatchKeyEvent(WebKeyboardEvent::Type 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<WebEvent::Modifier> modifiers, Vector<String>& commands, WallTime timestamp)
|
|
+{
|
|
+ Vector<WebCore::KeypressCommand> macCommands;
|
|
+ for (const String& command : commands) {
|
|
+ m_page.registerKeypressCommandName(command);
|
|
+ macCommands.append(WebCore::KeypressCommand(command.utf8().data()));
|
|
+ }
|
|
+ if (text.length() > 0 && macCommands.size() == 0)
|
|
+ macCommands.append(WebCore::KeypressCommand("insertText:", text));
|
|
+ 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/win/InspectorPlaywrightAgentClientWin.cpp b/Source/WebKit/UIProcess/win/InspectorPlaywrightAgentClientWin.cpp
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..dd7fe0604188bb025f361f1c44685e38bbf935ca
|
|
--- /dev/null
|
|
+++ b/Source/WebKit/UIProcess/win/InspectorPlaywrightAgentClientWin.cpp
|
|
@@ -0,0 +1,90 @@
|
|
+/*
|
|
+ * 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));
|
|
+ }
|
|
+ PAL::SessionID sessionID = browserContext->dataStore->sessionID();
|
|
+ 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 3dcd0ec35c92e37239208a8f5d4f461fbeaac3ce..84ba07c57f2abac1bd0ca5d0af2e7366ad036892 100644
|
|
--- a/Source/WebKit/UIProcess/win/WebContextMenuProxyWin.cpp
|
|
+++ b/Source/WebKit/UIProcess/win/WebContextMenuProxyWin.cpp
|
|
@@ -112,5 +112,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 0c80d970c3f9a987faf620081c909f6c7021970d..1467e5481f7417913c0d12a1cb492d02b2a7d1b7 100644
|
|
--- a/Source/WebKit/UIProcess/win/WebContextMenuProxyWin.h
|
|
+++ b/Source/WebKit/UIProcess/win/WebContextMenuProxyWin.h
|
|
@@ -47,6 +47,7 @@ public:
|
|
private:
|
|
WebContextMenuProxyWin(WebPageProxy&, ContextMenuContextData&&, const UserData&);
|
|
void showContextMenuWithItems(Vector<Ref<WebContextMenuItem>>&&) override;
|
|
+ void hide() override;
|
|
|
|
HMENU m_menu;
|
|
};
|
|
diff --git a/Source/WebKit/UIProcess/win/WebPageInspectorEmulationAgentWin.cpp b/Source/WebKit/UIProcess/win/WebPageInspectorEmulationAgentWin.cpp
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..62b841fe1d0de2296e1c61e328cff564f5aa1c0f
|
|
--- /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 = m_page.viewWidget();
|
|
+ HWND windowHwnd = GetAncestor(viewHwnd, GA_ROOT);
|
|
+ RECT viewRect;
|
|
+ RECT windowRect;
|
|
+
|
|
+ if (!windowHwnd || !GetWindowRect(windowHwnd, &windowRect)) {
|
|
+ callback("Could not retrieve window size");
|
|
+ return;
|
|
+ }
|
|
+ if (!GetWindowRect(viewHwnd, &viewRect)) {
|
|
+ callback("Could retrieve view size");
|
|
+ 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");
|
|
+ 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..5cf8a010e9809e6a95741cdb7c2cbeb445ab638b
|
|
--- /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(WebKeyboardEvent::Type 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<WebEvent::Modifier> 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/InspectorTargetProxyWPE.cpp b/Source/WebKit/UIProcess/wpe/InspectorTargetProxyWPE.cpp
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..7453194ca6f032ba86a4c67f5bf12688ab6ec1be
|
|
--- /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/WebPageInspectorEmulationAgentWPE.cpp b/Source/WebKit/UIProcess/wpe/WebPageInspectorEmulationAgentWPE.cpp
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..5dc76aa302cb574307059e66a1b73730efe920da
|
|
--- /dev/null
|
|
+++ b/Source/WebKit/UIProcess/wpe/WebPageInspectorEmulationAgentWPE.cpp
|
|
@@ -0,0 +1,41 @@
|
|
+/*
|
|
+ * 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 "WebPageProxy.h"
|
|
+#include <wpe/wpe.h>
|
|
+
|
|
+namespace WebKit {
|
|
+
|
|
+void WebPageInspectorEmulationAgent::platformSetSize(int width, int height, Function<void (const String& error)>&& callback)
|
|
+{
|
|
+ struct wpe_view_backend* backend = m_page.viewBackend();
|
|
+ wpe_view_backend_dispatch_set_size(backend, width, height);
|
|
+ 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..c3d7cacea987ba2b094d5022c670705ef6ced129
|
|
--- /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(WebKeyboardEvent::Type 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<WebEvent::Modifier> 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/WebKit.xcodeproj/project.pbxproj b/Source/WebKit/WebKit.xcodeproj/project.pbxproj
|
|
index bf1b5aeda03450931bd47cd29f7c4eb25b5834a0..78ee75a76ac16be3f285f589904b4715ae2bdb2d 100644
|
|
--- a/Source/WebKit/WebKit.xcodeproj/project.pbxproj
|
|
+++ b/Source/WebKit/WebKit.xcodeproj/project.pbxproj
|
|
@@ -1781,6 +1781,18 @@
|
|
CEE4AE2B1A5DCF430002F49B /* UIKitSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = CEE4AE2A1A5DCF430002F49B /* UIKitSPI.h */; };
|
|
D3B9484711FF4B6500032B39 /* WebPopupMenu.h in Headers */ = {isa = PBXBuildFile; fileRef = D3B9484311FF4B6500032B39 /* WebPopupMenu.h */; };
|
|
D3B9484911FF4B6500032B39 /* WebSearchPopupMenu.h in Headers */ = {isa = PBXBuildFile; fileRef = D3B9484511FF4B6500032B39 /* WebSearchPopupMenu.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, ); }; };
|
|
DF84CEE4249AA24D009096F6 /* WKPDFHUDView.mm in Sources */ = {isa = PBXBuildFile; fileRef = DF84CEE2249AA21F009096F6 /* WKPDFHUDView.mm */; };
|
|
@@ -1838,6 +1850,9 @@
|
|
E5BEF6822130C48000F31111 /* WebDataListSuggestionsDropdownIOS.h in Headers */ = {isa = PBXBuildFile; fileRef = E5BEF6802130C47F00F31111 /* WebDataListSuggestionsDropdownIOS.h */; };
|
|
E5CB07DC20E1678F0022C183 /* WKFormColorControl.h in Headers */ = {isa = PBXBuildFile; fileRef = E5CB07DA20E1678F0022C183 /* WKFormColorControl.h */; };
|
|
ED82A7F2128C6FAF004477B3 /* WKBundlePageOverlay.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A22F0FF1289FCD90085E74F /* WKBundlePageOverlay.h */; settings = {ATTRIBUTES = (Private, ); }; };
|
|
+ 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, ); }; };
|
|
F42D634122A0EFDF00D2FB3A /* WebAutocorrectionData.h in Headers */ = {isa = PBXBuildFile; fileRef = F42D633F22A0EFD300D2FB3A /* WebAutocorrectionData.h */; };
|
|
F430E9422247335F005FE053 /* WebsiteMetaViewportPolicy.h in Headers */ = {isa = PBXBuildFile; fileRef = F430E941224732A9005FE053 /* WebsiteMetaViewportPolicy.h */; };
|
|
@@ -5269,6 +5284,19 @@
|
|
D3B9484311FF4B6500032B39 /* WebPopupMenu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebPopupMenu.h; sourceTree = "<group>"; };
|
|
D3B9484411FF4B6500032B39 /* WebSearchPopupMenu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebSearchPopupMenu.cpp; sourceTree = "<group>"; };
|
|
D3B9484511FF4B6500032B39 /* WebSearchPopupMenu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebSearchPopupMenu.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>"; };
|
|
@@ -5381,6 +5409,14 @@
|
|
ECA680D31E6904B500731D20 /* ExtraPrivateSymbolsForTAPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExtraPrivateSymbolsForTAPI.h; sourceTree = "<group>"; };
|
|
ECBFC1DB1E6A4D66000300C7 /* ExtraPublicSymbolsForTAPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ExtraPublicSymbolsForTAPI.h; sourceTree = "<group>"; };
|
|
F036978715F4BF0500C3A80E /* WebColorPicker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebColorPicker.cpp; 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>"; };
|
|
F40D1B68220BDC0F00B49A01 /* WebAutocorrectionContext.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = WebAutocorrectionContext.h; path = ios/WebAutocorrectionContext.h; sourceTree = "<group>"; };
|
|
F41056612130699A0092281D /* APIAttachmentCocoa.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = APIAttachmentCocoa.mm; sourceTree = "<group>"; };
|
|
@@ -5479,6 +5515,7 @@
|
|
3766F9EF189A1244003CF19B /* QuartzCore.framework in Frameworks */,
|
|
37694525184FC6B600CDE21F /* Security.framework in Frameworks */,
|
|
37BEC4DD1948FC6A008B4286 /* WebCore.framework in Frameworks */,
|
|
+ F33C7AC7249AD79C0018BE41 /* libwebrtc.dylib in Frameworks */,
|
|
);
|
|
runOnlyForDeploymentPostprocessing = 0;
|
|
};
|
|
@@ -7207,6 +7244,7 @@
|
|
37C4C08318149C2A003688B9 /* Cocoa */ = {
|
|
isa = PBXGroup;
|
|
children = (
|
|
+ D71A94492372290B002C4D9E /* _WKBrowserInspector.h */,
|
|
1A43E826188F38E2009E4D30 /* Deprecated */,
|
|
37A5E01218BBF937000A081E /* _WKActivatedElementInfo.h */,
|
|
37A5E01118BBF937000A081E /* _WKActivatedElementInfo.mm */,
|
|
@@ -8115,6 +8153,7 @@
|
|
isa = PBXGroup;
|
|
children = (
|
|
57A9FF15252C6AEF006A2040 /* libWTF.a */,
|
|
+ F33C7AC6249AD79C0018BE41 /* libwebrtc.dylib */,
|
|
5750F32A2032D4E500389347 /* LocalAuthentication.framework */,
|
|
570DAAB0230273D200E8FC04 /* NearField.framework */,
|
|
);
|
|
@@ -8534,6 +8573,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>";
|
|
@@ -8542,6 +8587,7 @@
|
|
isa = PBXGroup;
|
|
children = (
|
|
A5D3504D1D78F0D2005124A9 /* RemoteWebInspectorProxyMac.mm */,
|
|
+ F3970344249BD4CE003E1A22 /* ScreencastEncoderMac.mm */,
|
|
1CA8B935127C774E00576C2B /* WebInspectorProxyMac.mm */,
|
|
994BADF11F7D77EA00B571E7 /* WKInspectorViewController.h */,
|
|
994BADF21F7D77EB00B571E7 /* WKInspectorViewController.mm */,
|
|
@@ -8969,6 +9015,12 @@
|
|
BC032DC310F438260058C15A /* UIProcess */ = {
|
|
isa = PBXGroup;
|
|
children = (
|
|
+ D76D6887238DBD80008D314B /* InspectorDialogAgent.h */,
|
|
+ D71A944B237239FB002C4D9E /* BrowserInspectorPipe.h */,
|
|
+ D71A943F2371F67E002C4D9E /* WebPageInspectorEmulationAgent.h */,
|
|
+ D71A94402371F67E002C4D9E /* WebPageInspectorInputAgent.h */,
|
|
+ D71A94392370F060002C4D9E /* RemoteInspectorPipe.h */,
|
|
+ D71A94332370E07A002C4D9E /* InspectorPlaywrightAgentClient.h */,
|
|
BC032DC410F4387C0058C15A /* API */,
|
|
512F588D12A8836F00629530 /* Authentication */,
|
|
9955A6E81C79809000EB6A93 /* Automation */,
|
|
@@ -9248,6 +9300,7 @@
|
|
BC0C376610F807660076D7CB /* C */ = {
|
|
isa = PBXGroup;
|
|
children = (
|
|
+ D71A942C2370DF81002C4D9E /* WKBrowserInspector.h */,
|
|
5123CF18133D25E60056F800 /* cg */,
|
|
6EE849C41368D9040038D481 /* mac */,
|
|
BCB63477116BF10600603215 /* WebKit2_C.h */,
|
|
@@ -9843,6 +9896,11 @@
|
|
BCCF085C113F3B7500C650C5 /* mac */ = {
|
|
isa = PBXGroup;
|
|
children = (
|
|
+ D7EB04E62372A73B00F744CE /* InspectorPlaywrightAgentClientMac.mm */,
|
|
+ D71A94302370E025002C4D9E /* InspectorPlaywrightAgentClientMac.h */,
|
|
+ D79902AE236E9404005D6F7E /* WebPageInspectorEmulationAgentMac.mm */,
|
|
+ D79902B0236E9404005D6F7E /* WebPageInspectorInputAgentMac.mm */,
|
|
+ D79902AF236E9404005D6F7E /* InspectorTargetProxyMac.mm */,
|
|
B878B613133428DC006888E9 /* CorrectionPanel.h */,
|
|
B878B614133428DC006888E9 /* CorrectionPanel.mm */,
|
|
C1817362205844A900DFDA65 /* DisplayLink.cpp */,
|
|
@@ -10636,6 +10694,7 @@
|
|
991F492F23A812C60054642B /* _WKInspectorDebuggableInfo.h in Headers */,
|
|
99036AE223A949CF0000B06A /* _WKInspectorDebuggableInfoInternal.h in Headers */,
|
|
9197940C23DBC50300257892 /* _WKInspectorDelegate.h in Headers */,
|
|
+ D71A944A2372290B002C4D9E /* _WKBrowserInspector.h in Headers */,
|
|
5CAFDE472130846A00B1F7E1 /* _WKInspectorInternal.h in Headers */,
|
|
9979CA58237F49F10039EC05 /* _WKInspectorPrivate.h in Headers */,
|
|
99996A9F25004BCC004F7559 /* _WKInspectorPrivateForTesting.h in Headers */,
|
|
@@ -10875,6 +10934,7 @@
|
|
1A14F8E21D74C834006CBEC6 /* FrameInfoData.h in Headers */,
|
|
1AE00D611831792100087DD7 /* FrameLoadState.h in Headers */,
|
|
5C121E842410208D00486F9B /* FrameTreeNodeData.h in Headers */,
|
|
+ F303B849249A8D640031DE5C /* ScreencastEncoder.h in Headers */,
|
|
2D4AF0892044C3C4006C8817 /* FrontBoardServicesSPI.h in Headers */,
|
|
CD78E1151DB7D7ED0014A2DE /* FullscreenClient.h in Headers */,
|
|
CD19D2EA2046406F0017074A /* FullscreenTouchSecheuristic.h in Headers */,
|
|
@@ -10887,6 +10947,7 @@
|
|
BC06F43A12DBCCFB002D78DE /* GeolocationPermissionRequestProxy.h in Headers */,
|
|
2DA944A41884E4F000ED86DB /* GestureTypes.h in Headers */,
|
|
2DA049B8180CCD0A00AAFA9E /* GraphicsLayerCARemote.h in Headers */,
|
|
+ D71A94342370E07A002C4D9E /* InspectorPlaywrightAgentClient.h in Headers */,
|
|
C0CE72AD1247E78D00BC0EC4 /* HandleMessage.h in Headers */,
|
|
1AC75A1B1B3368270056745B /* HangDetectionDisabler.h in Headers */,
|
|
57AC8F50217FEED90055438C /* HidConnection.h in Headers */,
|
|
@@ -11016,8 +11077,10 @@
|
|
413075AC1DE85F370039EC69 /* NetworkRTCMonitor.h in Headers */,
|
|
41DC45961E3D6E2200B11F51 /* NetworkRTCProvider.h in Headers */,
|
|
5C20CBA01BB1ECD800895BB1 /* NetworkSession.h in Headers */,
|
|
+ D71A94422371F67E002C4D9E /* WebPageInspectorEmulationAgent.h in Headers */,
|
|
532159551DBAE7290054AA3C /* NetworkSessionCocoa.h in Headers */,
|
|
417915B92257046F00D6F97E /* NetworkSocketChannel.h in Headers */,
|
|
+ D71A943A2370F061002C4D9E /* RemoteInspectorPipe.h in Headers */,
|
|
570DAAC22303730300E8FC04 /* NfcConnection.h in Headers */,
|
|
570DAAAE23026F5C00E8FC04 /* NfcService.h in Headers */,
|
|
31A2EC5614899C0900810D71 /* NotificationPermissionRequest.h in Headers */,
|
|
@@ -11100,6 +11163,7 @@
|
|
CD2865EE2255562000606AC7 /* ProcessTaskStateObserver.h in Headers */,
|
|
463FD4821EB94EC000A2982C /* ProcessTerminationReason.h in Headers */,
|
|
86E67A251910B9D100004AB7 /* ProcessThrottler.h in Headers */,
|
|
+ D71A944C237239FB002C4D9E /* BrowserInspectorPipe.h in Headers */,
|
|
83048AE61ACA45DC0082C832 /* ProcessThrottlerClient.h in Headers */,
|
|
A1E688701F6E2BAB007006A6 /* QuarantineSPI.h in Headers */,
|
|
1A0C227E2451130A00ED614D /* QuickLookThumbnailingSoftLink.h in Headers */,
|
|
@@ -11395,6 +11459,7 @@
|
|
A543E30D215C8A9000279CD9 /* WebPageInspectorTargetController.h in Headers */,
|
|
A543E307215AD13700279CD9 /* WebPageInspectorTargetFrontendChannel.h in Headers */,
|
|
C0CE72A11247E71D00BC0EC4 /* WebPageMessages.h in Headers */,
|
|
+ F3867F0A24607D4E008F0F31 /* InspectorScreencastAgent.h in Headers */,
|
|
2D5C9D0619C81D8F00B3C5C1 /* WebPageOverlay.h in Headers */,
|
|
46C392292316EC4D008EED9B /* WebPageProxyIdentifier.h in Headers */,
|
|
BCBD3915125BB1A800D2C29F /* WebPageProxyMessages.h in Headers */,
|
|
@@ -11523,6 +11588,7 @@
|
|
BCD25F1711D6BDE100169B0E /* WKBundleFrame.h in Headers */,
|
|
BCF049E611FE20F600F86A58 /* WKBundleFramePrivate.h in Headers */,
|
|
BC49862F124D18C100D834E1 /* WKBundleHitTestResult.h in Headers */,
|
|
+ D71A94432371F67E002C4D9E /* WebPageInspectorInputAgent.h in Headers */,
|
|
BC204EF211C83EC8008F3375 /* WKBundleInitialize.h in Headers */,
|
|
65B86F1E12F11DE300B7DD8A /* WKBundleInspector.h in Headers */,
|
|
1A8B66B41BC45B010082DF77 /* WKBundleMac.h in Headers */,
|
|
@@ -11575,6 +11641,7 @@
|
|
5C795D71229F3757003FF1C4 /* WKContextMenuElementInfoPrivate.h in Headers */,
|
|
51A555F6128C6C47009ABCEC /* WKContextMenuItem.h in Headers */,
|
|
51A55601128C6D92009ABCEC /* WKContextMenuItemTypes.h in Headers */,
|
|
+ D76D6888238DBD81008D314B /* InspectorDialogAgent.h in Headers */,
|
|
A1EA02381DABFF7E0096021F /* WKContextMenuListener.h in Headers */,
|
|
BCC938E11180DE440085E5FE /* WKContextPrivate.h in Headers */,
|
|
9FB5F395169E6A80002C25BF /* WKContextPrivateMac.h in Headers */,
|
|
@@ -11723,6 +11790,7 @@
|
|
1AB8A1F818400BB800E9AE69 /* WKPageContextMenuClient.h in Headers */,
|
|
8372DB251A674C8F00C697C5 /* WKPageDiagnosticLoggingClient.h in Headers */,
|
|
1AB8A1F418400B8F00E9AE69 /* WKPageFindClient.h in Headers */,
|
|
+ D71A94322370E025002C4D9E /* InspectorPlaywrightAgentClientMac.h in Headers */,
|
|
1AB8A1F618400B9D00E9AE69 /* WKPageFindMatchesClient.h in Headers */,
|
|
1AB8A1F018400B0000E9AE69 /* WKPageFormClient.h in Headers */,
|
|
BC7B633712A45ABA00D174A4 /* WKPageGroup.h in Headers */,
|
|
@@ -12815,6 +12883,7 @@
|
|
C1A152D724E5A29A00978C8B /* HandleXPCEndpointMessages.mm in Sources */,
|
|
2749F6442146561B008380BF /* InjectedBundleNodeHandle.cpp in Sources */,
|
|
2749F6452146561E008380BF /* InjectedBundleRangeHandle.cpp in Sources */,
|
|
+ D79902B2236E9404005D6F7E /* InspectorTargetProxyMac.mm in Sources */,
|
|
2D913441212CF9F000128AFD /* JSNPMethod.cpp in Sources */,
|
|
2D913442212CF9F000128AFD /* JSNPObject.cpp in Sources */,
|
|
C14D37FE24ACE086007FF014 /* LaunchServicesDatabaseManager.mm in Sources */,
|
|
@@ -12828,6 +12897,7 @@
|
|
2D92A781212B6A7100F493FD /* MessageReceiverMap.cpp in Sources */,
|
|
2D92A782212B6A7100F493FD /* MessageSender.cpp in Sources */,
|
|
2D92A77A212B6A6100F493FD /* Module.cpp in Sources */,
|
|
+ D79902B1236E9404005D6F7E /* WebPageInspectorEmulationAgentMac.mm in Sources */,
|
|
57B826452304F14000B72EB0 /* NearFieldSoftLink.mm in Sources */,
|
|
2D913443212CF9F000128AFD /* NetscapeBrowserFuncs.cpp in Sources */,
|
|
2D913444212CF9F000128AFD /* NetscapePlugin.cpp in Sources */,
|
|
@@ -12851,6 +12921,7 @@
|
|
1A2D8439127F65D5001EB962 /* NPObjectMessageReceiverMessageReceiver.cpp in Sources */,
|
|
2D92A792212B6AD400F493FD /* NPObjectProxy.cpp in Sources */,
|
|
2D92A793212B6AD400F493FD /* NPRemoteObjectMap.cpp in Sources */,
|
|
+ D7EB04E72372A73B00F744CE /* InspectorPlaywrightAgentClientMac.mm in Sources */,
|
|
2D913447212CF9F000128AFD /* NPRuntimeObjectMap.cpp in Sources */,
|
|
2D913448212CF9F000128AFD /* NPRuntimeUtilities.cpp in Sources */,
|
|
2D92A794212B6AD400F493FD /* NPVariantData.cpp in Sources */,
|
|
@@ -13136,6 +13207,7 @@
|
|
2D92A78C212B6AB100F493FD /* WebMouseEvent.cpp in Sources */,
|
|
31BA924D148831260062EDB5 /* WebNotificationManagerMessageReceiver.cpp in Sources */,
|
|
2DF6FE52212E110900469030 /* WebPage.cpp in Sources */,
|
|
+ D79902B3236E9404005D6F7E /* WebPageInspectorInputAgentMac.mm in Sources */,
|
|
C0CE72A01247E71D00BC0EC4 /* WebPageMessageReceiver.cpp in Sources */,
|
|
BCBD3914125BB1A800D2C29F /* WebPageProxyMessageReceiver.cpp in Sources */,
|
|
7CE9CE101FA0767A000177DE /* WebPageUpdatePreferences.cpp in Sources */,
|
|
diff --git a/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp b/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp
|
|
index 69dea7493e2683c5417ebc9fa647b687ea710b83..427c4ddd5c3b6743ff686790e9076700e3705c3a 100644
|
|
--- a/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp
|
|
+++ b/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp
|
|
@@ -223,6 +223,11 @@ void WebLoaderStrategy::scheduleLoad(ResourceLoader& resourceLoader, CachedResou
|
|
}
|
|
#endif
|
|
|
|
+ if (m_emulateOfflineState) {
|
|
+ scheduleInternallyFailedLoad(resourceLoader);
|
|
+ return;
|
|
+ }
|
|
+
|
|
if (!tryLoadingUsingURLSchemeHandler(resourceLoader, trackingParameters)) {
|
|
WEBLOADERSTRATEGY_RELEASE_LOG_IF_ALLOWED("scheduleLoad: URL will be scheduled with the NetworkProcess");
|
|
|
|
@@ -770,7 +775,7 @@ void WebLoaderStrategy::didFinishPreconnection(uint64_t preconnectionIdentifier,
|
|
|
|
bool WebLoaderStrategy::isOnLine() const
|
|
{
|
|
- return m_isOnLine;
|
|
+ return m_emulateOfflineState ? false : m_isOnLine;
|
|
}
|
|
|
|
void WebLoaderStrategy::addOnlineStateChangeListener(Function<void(bool)>&& listener)
|
|
@@ -790,6 +795,11 @@ void WebLoaderStrategy::isResourceLoadFinished(CachedResource& resource, Complet
|
|
|
|
void WebLoaderStrategy::setOnLineState(bool isOnLine)
|
|
{
|
|
+ if (m_emulateOfflineState) {
|
|
+ m_isOnLine = isOnLine;
|
|
+ return;
|
|
+ }
|
|
+
|
|
if (m_isOnLine == isOnLine)
|
|
return;
|
|
|
|
@@ -798,6 +808,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 9d9884183ec93daeb3ab63218960172a050e0ffb..65ae20cbeaf74d4954590b76ae63a4b2a9c1b506 100644
|
|
--- a/Source/WebKit/WebProcess/Network/WebLoaderStrategy.h
|
|
+++ b/Source/WebKit/WebProcess/Network/WebLoaderStrategy.h
|
|
@@ -88,6 +88,7 @@ public:
|
|
bool isOnLine() const final;
|
|
void addOnlineStateChangeListener(Function<void(bool)>&&) final;
|
|
void setOnLineState(bool);
|
|
+ void setEmulateOfflineState(bool) final;
|
|
|
|
static uint64_t generateLoadIdentifier();
|
|
|
|
@@ -130,6 +131,7 @@ private:
|
|
HashMap<unsigned long, PreconnectCompletionHandler> m_preconnectCompletionHandlers;
|
|
Vector<Function<void(bool)>> m_onlineStateChangeListeners;
|
|
bool m_isOnLine { true };
|
|
+ bool m_emulateOfflineState { false };
|
|
};
|
|
|
|
} // namespace WebKit
|
|
diff --git a/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp b/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp
|
|
index 76c0d1fc8aa090dde462cb21e24a234f100acfe1..31a997a0945e5430d33e13b9171e209c058e280c 100644
|
|
--- a/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp
|
|
+++ b/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp
|
|
@@ -386,6 +386,8 @@ void WebChromeClient::setResizable(bool resizable)
|
|
|
|
void WebChromeClient::addMessageToConsole(MessageSource source, MessageLevel level, const String& message, unsigned lineNumber, unsigned columnNumber, const String& sourceID)
|
|
{
|
|
+ if (level == MessageLevel::Error)
|
|
+ m_page.send(Messages::WebPageProxy::LogToStderr(message));
|
|
// Notify the bundle client.
|
|
m_page.injectedBundleUIClient().willAddMessageToConsole(&m_page, source, level, message, lineNumber, columnNumber, sourceID);
|
|
}
|
|
@@ -805,6 +807,13 @@ std::unique_ptr<DateTimeChooser> WebChromeClient::createDateTimeChooser(DateTime
|
|
|
|
#endif
|
|
|
|
+#if ENABLE(ORIENTATION_EVENTS) && !PLATFORM(IOS_FAMILY)
|
|
+int WebChromeClient::deviceOrientation() const {
|
|
+ // Only overrides are supported for non-iOS platforms.
|
|
+ return 0;
|
|
+}
|
|
+#endif
|
|
+
|
|
void WebChromeClient::runOpenPanel(Frame& frame, FileChooser& fileChooser)
|
|
{
|
|
if (m_page.activeOpenPanelResultListener())
|
|
diff --git a/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp b/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp
|
|
index 1b9a3a9acd53066475a37d00e92058e8d8cb28b4..5c59cba07f51ff34e8def6a874f5d383af543a53 100644
|
|
--- a/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp
|
|
+++ b/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp
|
|
@@ -1557,13 +1557,6 @@ void WebFrameLoaderClient::transitionToCommittedForNewPage()
|
|
if (webPage->scrollPinningBehavior() != DoNotPin)
|
|
view->setScrollPinningBehavior(webPage->scrollPinningBehavior());
|
|
|
|
-#if USE(COORDINATED_GRAPHICS)
|
|
- if (shouldUseFixedLayout) {
|
|
- view->setDelegatesScrolling(shouldUseFixedLayout);
|
|
- view->setPaintsEntireContents(shouldUseFixedLayout);
|
|
- return;
|
|
- }
|
|
-#endif
|
|
}
|
|
|
|
void WebFrameLoaderClient::didRestoreFromBackForwardCache()
|
|
diff --git a/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/DrawingAreaCoordinatedGraphics.cpp b/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/DrawingAreaCoordinatedGraphics.cpp
|
|
index 4f1a1ff1e4476cd8b272eb14100015943296eb19..427e0d55577716eaaa53eafe0acdbf27698baf27 100644
|
|
--- a/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/DrawingAreaCoordinatedGraphics.cpp
|
|
+++ b/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/DrawingAreaCoordinatedGraphics.cpp
|
|
@@ -37,6 +37,7 @@
|
|
#include "WebPreferencesKeys.h"
|
|
#include <WebCore/Frame.h>
|
|
#include <WebCore/GraphicsContext.h>
|
|
+#include <WebCore/InspectorController.h>
|
|
#include <WebCore/Page.h>
|
|
#include <WebCore/PageOverlayController.h>
|
|
#include <WebCore/Settings.h>
|
|
@@ -122,6 +123,16 @@ void DrawingAreaCoordinatedGraphics::scroll(const IntRect& scrollRect, const Int
|
|
ASSERT(m_scrollRect.isEmpty());
|
|
ASSERT(m_scrollOffset.isEmpty());
|
|
ASSERT(m_dirtyRegion.isEmpty());
|
|
+// Playwright begin
|
|
+#if !PLATFORM(WIN)
|
|
+ if (m_webPage.mainFrameView() && m_webPage.mainFrameView()->useFixedLayout()) {
|
|
+ IntRect visibleRect;
|
|
+ visibleRect.move(-scrollDelta.width(), -scrollDelta.height());
|
|
+ m_layerTreeHost->scrollNonCompositedContents(visibleRect);
|
|
+ return;
|
|
+ }
|
|
+#endif
|
|
+// Playwright end
|
|
m_layerTreeHost->scrollNonCompositedContents(scrollRect);
|
|
return;
|
|
}
|
|
@@ -247,6 +258,7 @@ void DrawingAreaCoordinatedGraphics::updatePreferences(const WebPreferencesStore
|
|
settings.setAcceleratedCompositingEnabled(false);
|
|
}
|
|
#endif
|
|
+
|
|
settings.setForceCompositingMode(store.getBoolValueForKey(WebPreferencesKey::forceCompositingModeKey()));
|
|
// Fixed position elements need to be composited and create stacking contexts
|
|
// in order to be scrolled by the ScrollingCoordinator.
|
|
@@ -616,6 +628,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::exitAcceleratedCompositingMode()
|
|
@@ -665,6 +682,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(m_backingStoreStateID, updateInfo));
|
|
}
|
|
+// Playwright begin
|
|
+#if PLATFORM(WIN)
|
|
+ didChangeAcceleratedCompositingMode(false);
|
|
+#endif
|
|
+// Playwright end
|
|
}
|
|
|
|
void DrawingAreaCoordinatedGraphics::scheduleDisplay()
|
|
diff --git a/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/LayerTreeHost.cpp b/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/LayerTreeHost.cpp
|
|
index 8685e23d0d468601c459954775fe6f565b0ce7ac..f9d49292837bf390b81eadeaebe2d4d599bc236c 100644
|
|
--- a/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/LayerTreeHost.cpp
|
|
+++ b/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/LayerTreeHost.cpp
|
|
@@ -166,8 +166,16 @@ void LayerTreeHost::setViewOverlayRootLayer(GraphicsLayer* viewOverlayRootLayer)
|
|
void LayerTreeHost::scrollNonCompositedContents(const IntRect& rect)
|
|
{
|
|
auto* frameView = m_webPage.mainFrameView();
|
|
+
|
|
+// Playwright begin
|
|
+#if PLATFORM(WIN)
|
|
if (!frameView || !frameView->delegatesScrolling())
|
|
+ return
|
|
+#else
|
|
+ if (!frameView)
|
|
return;
|
|
+#endif
|
|
+// Playwright end
|
|
|
|
m_viewportController.didScroll(rect.location());
|
|
if (m_isDiscardable)
|
|
diff --git a/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/LayerTreeHostTextureMapper.cpp b/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/LayerTreeHostTextureMapper.cpp
|
|
index 28e2c6d10fa08265d8edb7449565ee527f9826ed..044e7a5a9f3fb74fbfb7cdae33df4439d1b2938a 100644
|
|
--- a/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/LayerTreeHostTextureMapper.cpp
|
|
+++ b/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/LayerTreeHostTextureMapper.cpp
|
|
@@ -29,6 +29,7 @@
|
|
|
|
#if USE(GRAPHICS_LAYER_TEXTURE_MAPPER)
|
|
|
|
+#include "DrawingArea.h"
|
|
#include "WebPage.h"
|
|
#include <GLES2/gl2.h>
|
|
#include <WebCore/Document.h>
|
|
diff --git a/Source/WebKit/WebProcess/WebPage/DrawingArea.cpp b/Source/WebKit/WebProcess/WebPage/DrawingArea.cpp
|
|
index 97429e9769d2accf3d99949e2f6ca8a4e8acece9..eda4008b60b4f28958e246ae9aea773b4407769e 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 "WebPage.h"
|
|
#include "WebPageCreationParameters.h"
|
|
#include "WebProcess.h"
|
|
@@ -89,6 +90,13 @@ RefPtr<WebCore::DisplayRefreshMonitor> DrawingArea::createDisplayRefreshMonitor(
|
|
}
|
|
#endif
|
|
|
|
+#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 e1c230af001c04e9ad5c525a31b5c912e2eac3bd..9c1a2473fe463830718412f62506a14ceff63e10 100644
|
|
--- a/Source/WebKit/WebProcess/WebPage/DrawingArea.h
|
|
+++ b/Source/WebKit/WebProcess/WebPage/DrawingArea.h
|
|
@@ -143,6 +143,9 @@ public:
|
|
virtual void didChangeViewportAttributes(WebCore::ViewportAttributes&&) = 0;
|
|
virtual void deviceOrPageScaleFactorChanged() = 0;
|
|
#endif
|
|
+#if PLATFORM(WIN)
|
|
+ void didChangeAcceleratedCompositingMode(bool enabled);
|
|
+#endif
|
|
|
|
virtual void adoptLayersFromDrawingArea(DrawingArea&) { }
|
|
virtual void adoptDisplayRefreshMonitorsFromDrawingArea(DrawingArea&) { }
|
|
diff --git a/Source/WebKit/WebProcess/WebPage/WebDocumentLoader.cpp b/Source/WebKit/WebProcess/WebPage/WebDocumentLoader.cpp
|
|
index b2d54a627b94583bda3518c4e7c3364481b605a4..d407e32b6a7b8b27925c49391e86d42c9b3dfa8b 100644
|
|
--- a/Source/WebKit/WebProcess/WebPage/WebDocumentLoader.cpp
|
|
+++ b/Source/WebKit/WebProcess/WebPage/WebDocumentLoader.cpp
|
|
@@ -47,6 +47,14 @@ void WebDocumentLoader::detachFromFrame()
|
|
DocumentLoader::detachFromFrame();
|
|
}
|
|
|
|
+void WebDocumentLoader::replacedByFragmentNavigation(Frame& frame)
|
|
+{
|
|
+ ASSERT(!this->frame());
|
|
+ // Notify WebPageProxy that the navigation has been converted into same page navigation.
|
|
+ if (m_navigationID)
|
|
+ WebFrame::fromCoreFrame(frame)->documentLoaderDetached(m_navigationID);
|
|
+}
|
|
+
|
|
void WebDocumentLoader::setNavigationID(uint64_t navigationID)
|
|
{
|
|
ASSERT(navigationID);
|
|
diff --git a/Source/WebKit/WebProcess/WebPage/WebDocumentLoader.h b/Source/WebKit/WebProcess/WebPage/WebDocumentLoader.h
|
|
index f127d64d005ab7b93875591b94a5899205e91579..df0de26e4dc449a0fbf93e7037444df4e5365822 100644
|
|
--- a/Source/WebKit/WebProcess/WebPage/WebDocumentLoader.h
|
|
+++ b/Source/WebKit/WebProcess/WebPage/WebDocumentLoader.h
|
|
@@ -43,7 +43,10 @@ public:
|
|
private:
|
|
WebDocumentLoader(const WebCore::ResourceRequest&, const WebCore::SubstituteData&);
|
|
|
|
+ uint64_t loaderIDForInspector() override { return navigationID(); }
|
|
+
|
|
void detachFromFrame() override;
|
|
+ void replacedByFragmentNavigation(WebCore::Frame&) override;
|
|
|
|
uint64_t m_navigationID;
|
|
};
|
|
diff --git a/Source/WebKit/WebProcess/WebPage/WebPage.cpp b/Source/WebKit/WebProcess/WebPage/WebPage.cpp
|
|
index 260a0e2acb4be9ea7b3d0f3abcfd0602f51472b5..cd998b7005dc9cc3ba79a201ce40b2c7b272b8ac 100644
|
|
--- a/Source/WebKit/WebProcess/WebPage/WebPage.cpp
|
|
+++ b/Source/WebKit/WebProcess/WebPage/WebPage.cpp
|
|
@@ -799,6 +799,9 @@ WebPage::WebPage(PageIdentifier pageID, WebPageCreationParameters&& parameters)
|
|
|
|
m_page->setCanUseCredentialStorage(parameters.canUseCredentialStorage);
|
|
|
|
+ if (parameters.shouldPauseInInspectorWhenShown)
|
|
+ m_page->inspectorController().pauseWhenShown();
|
|
+
|
|
updateThrottleState();
|
|
}
|
|
|
|
@@ -1572,6 +1575,22 @@ void WebPage::platformDidReceiveLoadParameters(const LoadParameters& loadParamet
|
|
}
|
|
#endif
|
|
|
|
+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->coreFrame(), loadParameters.request };
|
|
+ frame->coreFrame()->loader().load(WTFMove(frameLoadRequest));
|
|
+ ASSERT(!m_pendingFrameNavigationID);
|
|
+}
|
|
+
|
|
void WebPage::loadRequest(LoadParameters&& loadParameters)
|
|
{
|
|
#if ENABLE(APP_BOUND_DOMAINS)
|
|
@@ -1782,17 +1801,13 @@ void WebPage::setSize(const WebCore::IntSize& viewSize)
|
|
view->resize(viewSize);
|
|
m_drawingArea->setNeedsDisplay();
|
|
|
|
-#if USE(COORDINATED_GRAPHICS)
|
|
if (view->useFixedLayout())
|
|
sendViewportAttributesChanged(m_page->viewportArguments());
|
|
-#endif
|
|
}
|
|
|
|
-#if USE(COORDINATED_GRAPHICS)
|
|
void WebPage::sendViewportAttributesChanged(const ViewportArguments& viewportArguments)
|
|
{
|
|
- FrameView* view = m_page->mainFrame().view();
|
|
- ASSERT(view && view->useFixedLayout());
|
|
+ ASSERT(m_page->mainFrame().view() && m_page->mainFrame().view()->useFixedLayout());
|
|
|
|
// Viewport properties have no impact on zero sized fixed viewports.
|
|
if (m_viewSize.isEmpty())
|
|
@@ -1809,20 +1824,18 @@ void WebPage::sendViewportAttributesChanged(const ViewportArguments& viewportArg
|
|
|
|
ViewportAttributes attr = computeViewportAttributes(viewportArguments, minimumLayoutFallbackWidth, deviceWidth, deviceHeight, 1, m_viewSize);
|
|
|
|
- // If no layout was done yet set contentFixedOrigin to (0,0).
|
|
- IntPoint contentFixedOrigin = view->didFirstLayout() ? view->fixedVisibleContentRect().location() : IntPoint();
|
|
-
|
|
- // Put the width and height to the viewport width and height. In css units however.
|
|
- // Use FloatSize to avoid truncated values during scale.
|
|
- FloatSize contentFixedSize = m_viewSize;
|
|
-
|
|
- contentFixedSize.scale(1 / attr.initialScale);
|
|
- view->setFixedVisibleContentRect(IntRect(contentFixedOrigin, roundedIntSize(contentFixedSize)));
|
|
+#if ENABLE(CSS_DEVICE_ADAPTATION)
|
|
+ FrameView* view = m_page->mainFrame().view();
|
|
+ // CSS viewport descriptors might be applied to already affected viewport size
|
|
+ // if the page enables/disables stylesheets, so need to keep initial viewport size.
|
|
+ view->setInitialViewportSize(roundedIntSize(m_viewSize));
|
|
+#endif
|
|
|
|
attr.initialScale = m_page->viewportArguments().zoom; // Resets auto (-1) if no value was set by user.
|
|
|
|
// This also takes care of the relayout.
|
|
setFixedLayoutSize(roundedIntSize(attr.layoutSize));
|
|
+ scaleView(deviceWidth / attr.layoutSize.width());
|
|
|
|
#if USE(COORDINATED_GRAPHICS)
|
|
m_drawingArea->didChangeViewportAttributes(WTFMove(attr));
|
|
@@ -1830,7 +1843,6 @@ void WebPage::sendViewportAttributesChanged(const ViewportArguments& viewportArg
|
|
send(Messages::WebPageProxy::DidChangeViewportProperties(attr));
|
|
#endif
|
|
}
|
|
-#endif
|
|
|
|
void WebPage::scrollMainFrameIfNotAtMaxScrollPosition(const IntSize& scrollOffset)
|
|
{
|
|
@@ -2129,6 +2141,7 @@ void WebPage::scaleView(double scale)
|
|
}
|
|
|
|
m_page->setViewScaleFactor(scale);
|
|
+ send(Messages::WebPageProxy::ViewScaleFactorDidChange(scale));
|
|
scalePage(pageScale, scrollPositionAtNewScale);
|
|
}
|
|
|
|
@@ -2233,17 +2246,13 @@ void WebPage::viewportPropertiesDidChange(const ViewportArguments& viewportArgum
|
|
viewportConfigurationChanged();
|
|
#endif
|
|
|
|
-#if USE(COORDINATED_GRAPHICS)
|
|
FrameView* view = m_page->mainFrame().view();
|
|
if (view && view->useFixedLayout())
|
|
sendViewportAttributesChanged(viewportArguments);
|
|
+#if USE(COORDINATED_GRAPHICS)
|
|
else
|
|
m_drawingArea->didChangeViewportAttributes(ViewportAttributes());
|
|
#endif
|
|
-
|
|
-#if !PLATFORM(IOS_FAMILY) && !USE(COORDINATED_GRAPHICS)
|
|
- UNUSED_PARAM(viewportArguments);
|
|
-#endif
|
|
}
|
|
|
|
void WebPage::listenForLayoutMilestones(OptionSet<WebCore::LayoutMilestone> milestones)
|
|
@@ -3070,6 +3079,104 @@ void WebPage::touchEvent(const WebTouchEvent& touchEvent)
|
|
|
|
send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(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<WebEvent::Modifier> eventModifiers;
|
|
+ eventModifiers = eventModifiers.fromRaw(modifiers);
|
|
+
|
|
+ {
|
|
+ Vector<WebPlatformTouchPoint> touchPoints;
|
|
+ WebPlatformTouchPoint::TouchPointState state = WebPlatformTouchPoint::TouchPointState::TouchPressed;
|
|
+ touchPoints.append(WebPlatformTouchPoint(id, state, screenPosition, position, radius, rotationAngle, force));
|
|
+
|
|
+ WebTouchEvent touchEvent(WebEvent::TouchStart, WTFMove(touchPoints), eventModifiers, WallTime::now());
|
|
+
|
|
+ CurrentEvent currentEvent(touchEvent);
|
|
+ handled = handleTouchEvent(touchEvent, m_page.get());
|
|
+ }
|
|
+ {
|
|
+ Vector<WebPlatformTouchPoint> touchPoints;
|
|
+ WebPlatformTouchPoint::TouchPointState state = WebPlatformTouchPoint::TouchPointState::TouchReleased;
|
|
+ touchPoints.append(WebPlatformTouchPoint(id, state, screenPosition, position, radius, rotationAngle, force));
|
|
+
|
|
+ WebTouchEvent touchEvent(WebEvent::TouchEnd, WTFMove(touchPoints), eventModifiers, WallTime::now());
|
|
+
|
|
+ CurrentEvent currentEvent(touchEvent);
|
|
+ handled = handleTouchEvent(touchEvent, m_page.get()) || handled;
|
|
+ }
|
|
+ if (!handled) {
|
|
+ FloatPoint adjustedPoint;
|
|
+ Node* nodeRespondingToClick = m_page->mainFrame().nodeRespondingToClickEvents(position, adjustedPoint);
|
|
+ Frame* frameRespondingToClick = nodeRespondingToClick ? nodeRespondingToClick->document().frame() : nullptr;
|
|
+ IntPoint adjustedIntPoint = roundedIntPoint(adjustedPoint);
|
|
+ if (!frameRespondingToClick) {
|
|
+ completionHandler();
|
|
+ return;
|
|
+ }
|
|
+ bool shiftKey = eventModifiers.contains(WebEvent::Modifier::ShiftKey);
|
|
+ bool ctrlKey = eventModifiers.contains(WebEvent::Modifier::ControlKey);
|
|
+ bool altKey = eventModifiers.contains(WebEvent::Modifier::AltKey);
|
|
+ bool metaKey = eventModifiers.contains(WebEvent::Modifier::MetaKey);
|
|
+ double force = 0.0;
|
|
+ SyntheticClickType syntheticClickType = SyntheticClickType::OneFingerTap;
|
|
+
|
|
+ m_page->mainFrame().eventHandler().mouseMoved(PlatformMouseEvent(
|
|
+ adjustedIntPoint,
|
|
+ adjustedIntPoint,
|
|
+ MouseButton::NoButton,
|
|
+ PlatformEvent::Type::MouseMoved,
|
|
+ 0,
|
|
+ shiftKey,
|
|
+ ctrlKey,
|
|
+ altKey,
|
|
+ metaKey,
|
|
+ WallTime::now(),
|
|
+ force,
|
|
+ syntheticClickType
|
|
+ ));
|
|
+ m_page->mainFrame().eventHandler().handleMousePressEvent(PlatformMouseEvent(
|
|
+ adjustedIntPoint,
|
|
+ adjustedIntPoint,
|
|
+ MouseButton::LeftButton,
|
|
+ PlatformEvent::Type::MousePressed,
|
|
+ 1,
|
|
+ shiftKey,
|
|
+ ctrlKey,
|
|
+ altKey,
|
|
+ metaKey,
|
|
+ WallTime::now(),
|
|
+ force,
|
|
+ syntheticClickType
|
|
+ ));
|
|
+ m_page->mainFrame().eventHandler().handleMouseReleaseEvent(PlatformMouseEvent(
|
|
+ adjustedIntPoint,
|
|
+ adjustedIntPoint,
|
|
+ MouseButton::LeftButton,
|
|
+ PlatformEvent::Type::MouseReleased,
|
|
+ 1,
|
|
+ shiftKey,
|
|
+ ctrlKey,
|
|
+ altKey,
|
|
+ metaKey,
|
|
+ WallTime::now(),
|
|
+ force,
|
|
+ syntheticClickType
|
|
+ ));
|
|
+ }
|
|
+ completionHandler();
|
|
+}
|
|
#endif
|
|
|
|
void WebPage::cancelPointer(WebCore::PointerID pointerId, const WebCore::IntPoint& documentPoint)
|
|
@@ -3146,6 +3253,11 @@ void WebPage::sendMessageToTargetBackend(const String& targetId, const String& m
|
|
m_inspectorTargetController->sendMessageToTargetBackend(targetId, message);
|
|
}
|
|
|
|
+void WebPage::resumeInspectorIfPausedInNewWindow()
|
|
+{
|
|
+ m_page->inspectorController().resumeIfPausedInNewWindow();
|
|
+}
|
|
+
|
|
void WebPage::insertNewlineInQuotedContent()
|
|
{
|
|
Frame& frame = m_page->focusController().focusedOrMainFrame();
|
|
@@ -3381,6 +3493,7 @@ void WebPage::didCompletePageTransition()
|
|
void WebPage::show()
|
|
{
|
|
send(Messages::WebPageProxy::ShowPage());
|
|
+ m_page->inspectorController().didShowNewWindow();
|
|
}
|
|
|
|
void WebPage::setIsTakingSnapshotsForApplicationSuspension(bool isTakingSnapshotsForApplicationSuspension)
|
|
@@ -6486,6 +6599,9 @@ Ref<DocumentLoader> WebPage::createDocumentLoader(Frame& frame, const ResourceRe
|
|
WebsitePoliciesData::applyToDocumentLoader(WTFMove(*m_pendingWebsitePolicies), documentLoader);
|
|
m_pendingWebsitePolicies = WTF::nullopt;
|
|
}
|
|
+ } else if (m_pendingFrameNavigationID) {
|
|
+ documentLoader->setNavigationID(m_pendingFrameNavigationID);
|
|
+ m_pendingFrameNavigationID = 0;
|
|
}
|
|
|
|
return documentLoader;
|
|
diff --git a/Source/WebKit/WebProcess/WebPage/WebPage.h b/Source/WebKit/WebProcess/WebPage/WebPage.h
|
|
index 1ff35fb0936a5c7716aa4c012d26e073b4478e95..7c038bbac087d37a268b8057d0c1eab98cc72604 100644
|
|
--- a/Source/WebKit/WebProcess/WebPage/WebPage.h
|
|
+++ b/Source/WebKit/WebProcess/WebPage/WebPage.h
|
|
@@ -1186,6 +1186,7 @@ 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 insertNewlineInQuotedContent();
|
|
|
|
@@ -1464,6 +1465,7 @@ private:
|
|
// Actions
|
|
void tryClose(CompletionHandler<void(bool)>&&);
|
|
void platformDidReceiveLoadParameters(const LoadParameters&);
|
|
+ void loadRequestInFrameForInspector(LoadParameters&&, WebCore::FrameIdentifier);
|
|
void loadRequest(LoadParameters&&);
|
|
NO_RETURN void loadRequestWaitingForProcessLaunch(LoadParameters&&, URL&&, WebPageProxyIdentifier, bool);
|
|
void loadData(LoadParameters&&);
|
|
@@ -1499,6 +1501,7 @@ private:
|
|
void updatePotentialTapSecurityOrigin(const WebTouchEvent&, bool wasHandled);
|
|
#elif ENABLE(TOUCH_EVENTS)
|
|
void touchEvent(const WebTouchEvent&);
|
|
+ void fakeTouchTap(const WebCore::IntPoint& position, uint8_t modifiers, CompletionHandler<void()>&& completionHandler);
|
|
#endif
|
|
|
|
void cancelPointer(WebCore::PointerID, const WebCore::IntPoint&);
|
|
@@ -1616,9 +1619,7 @@ private:
|
|
void countStringMatches(const String&, OptionSet<FindOptions>, uint32_t maxMatchCount);
|
|
void replaceMatches(const Vector<uint32_t>& matchIndices, const String& replacementText, bool selectionOnly, CallbackID);
|
|
|
|
-#if USE(COORDINATED_GRAPHICS)
|
|
void sendViewportAttributesChanged(const WebCore::ViewportArguments&);
|
|
-#endif
|
|
|
|
void didChangeSelectedIndexForActivePopupMenu(int32_t newIndex);
|
|
void setTextForActivePopupMenu(int32_t index);
|
|
@@ -2095,6 +2096,7 @@ private:
|
|
UserActivity m_userActivity;
|
|
|
|
uint64_t m_pendingNavigationID { 0 };
|
|
+ uint64_t m_pendingFrameNavigationID { 0 };
|
|
Optional<WebsitePoliciesData> m_pendingWebsitePolicies;
|
|
|
|
bool m_mainFrameProgressCompleted { false };
|
|
diff --git a/Source/WebKit/WebProcess/WebPage/WebPage.messages.in b/Source/WebKit/WebProcess/WebPage/WebPage.messages.in
|
|
index 0c9d967b6cd644551eae73a389d626ab671ccaab..5056a7e199f7fb1b9629b94fe96a9f86f379718e 100644
|
|
--- a/Source/WebKit/WebProcess/WebPage/WebPage.messages.in
|
|
+++ b/Source/WebKit/WebProcess/WebPage/WebPage.messages.in
|
|
@@ -132,6 +132,7 @@ GenerateSyntheticEditingCommand(enum:uint8_t WebKit::SyntheticEditingCommandType
|
|
ConnectInspector(String targetId, Inspector::FrontendChannel::ConnectionType connectionType)
|
|
DisconnectInspector(String targetId)
|
|
SendMessageToTargetBackend(String targetId, String message)
|
|
+ ResumeInspectorIfPausedInNewWindow();
|
|
|
|
#if ENABLE(REMOTE_INSPECTOR)
|
|
SetIndicating(bool indicating);
|
|
@@ -143,6 +144,7 @@ GenerateSyntheticEditingCommand(enum:uint8_t WebKit::SyntheticEditingCommandType
|
|
#endif
|
|
#if !ENABLE(IOS_TOUCH_EVENTS) && ENABLE(TOUCH_EVENTS)
|
|
TouchEvent(WebKit::WebTouchEvent event)
|
|
+ FakeTouchTap(WebCore::IntPoint position, uint8_t modifiers) -> () Async
|
|
#endif
|
|
|
|
CancelPointer(WebCore::PointerID pointerId, WebCore::IntPoint documentPoint)
|
|
@@ -177,6 +179,7 @@ GenerateSyntheticEditingCommand(enum:uint8_t WebKit::SyntheticEditingCommandType
|
|
LoadURLInFrame(URL url, String referrer, WebCore::FrameIdentifier frameID)
|
|
LoadDataInFrame(IPC::DataReference data, String MIMEType, String encodingName, URL baseURL, WebCore::FrameIdentifier frameID)
|
|
LoadRequest(struct WebKit::LoadParameters loadParameters)
|
|
+ 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)
|
|
LoadAlternateHTML(struct WebKit::LoadParameters loadParameters)
|
|
diff --git a/Source/WebKit/WebProcess/WebProcess.cpp b/Source/WebKit/WebProcess/WebProcess.cpp
|
|
index 59e07b0801aff970dfc6a3ae54103fd9f75a0fdb..c3e58bf3ec665b4f218067c1fd7f0307af6c6efb 100644
|
|
--- a/Source/WebKit/WebProcess/WebProcess.cpp
|
|
+++ b/Source/WebKit/WebProcess/WebProcess.cpp
|
|
@@ -81,6 +81,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>
|
|
@@ -292,6 +293,8 @@ void WebProcess::initializeProcess(const AuxiliaryProcessInitializationParameter
|
|
|
|
platformInitializeProcess(parameters);
|
|
updateCPULimit();
|
|
+
|
|
+ Inspector::IdentifiersFactory::initializeWithProcessID(parameters.processIdentifier->toUInt64());
|
|
}
|
|
|
|
void WebProcess::initializeConnection(IPC::Connection* connection)
|
|
diff --git a/Source/WebKit/WebProcess/win/WebProcessMainWin.cpp b/Source/WebKit/WebProcess/win/WebProcessMainWin.cpp
|
|
index 89bc159df35910abe133c68d71057cdfe1995cbb..aba8e9110a3ec4c59e9888b148e1e908d477cbe4 100644
|
|
--- a/Source/WebKit/WebProcess/win/WebProcessMainWin.cpp
|
|
+++ b/Source/WebKit/WebProcess/win/WebProcessMainWin.cpp
|
|
@@ -42,7 +42,9 @@ public:
|
|
bool platformInitialize() override
|
|
{
|
|
if (SetProcessDpiAwarenessContextPtr())
|
|
- SetProcessDpiAwarenessContextPtr()(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
|
|
+ // Playwright begin
|
|
+ SetProcessDpiAwarenessContextPtr()(DPI_AWARENESS_CONTEXT_UNAWARE);
|
|
+ // Playwright end
|
|
else
|
|
SetProcessDPIAware();
|
|
return true;
|
|
diff --git a/Source/WebKitLegacy/mac/WebView/WebHTMLView.mm b/Source/WebKitLegacy/mac/WebView/WebHTMLView.mm
|
|
index ee6481f3860a7a7b51a11078e4338d705cfdab61..bfca888466b946f921f96e379a84ca99104cf248 100644
|
|
--- a/Source/WebKitLegacy/mac/WebView/WebHTMLView.mm
|
|
+++ b/Source/WebKitLegacy/mac/WebView/WebHTMLView.mm
|
|
@@ -4227,7 +4227,7 @@ static BOOL currentScrollIsBlit(NSView *clipView)
|
|
_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 aa087a5b4a0caa6a219b086a6021b3e0a9586fc0..930daec24f7b5d98f6c2aa20f24ccd94967acd10 100644
|
|
--- a/Source/WebKitLegacy/mac/WebView/WebView.mm
|
|
+++ b/Source/WebKitLegacy/mac/WebView/WebView.mm
|
|
@@ -4188,7 +4188,7 @@ IGNORE_WARNINGS_END
|
|
}
|
|
#endif // PLATFORM(IOS_FAMILY)
|
|
|
|
-#if ENABLE(TOUCH_EVENTS)
|
|
+#if ENABLE(IOS_TOUCH_EVENTS)
|
|
|
|
- (NSArray *)_touchEventRegions
|
|
{
|
|
@@ -4230,7 +4230,7 @@ IGNORE_WARNINGS_END
|
|
}).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 74f0c9e8c76d6271bc619955198f01787a6e86b1..12024d6622ffebb3046711f67b8dbcd6239ac6ce 100644
|
|
--- a/Source/cmake/OptionsGTK.cmake
|
|
+++ b/Source/cmake/OptionsGTK.cmake
|
|
@@ -6,6 +6,8 @@ WEBKIT_OPTION_DEFINE(USE_GTK4 "Whether to enable usage of GTK4 instead of GTK3."
|
|
|
|
SET_PROJECT_VERSION(2 31 0)
|
|
|
|
+set(ENABLE_WEBKIT_LEGACY OFF)
|
|
+
|
|
if (USE_GTK4)
|
|
set(WEBKITGTK_API_VERSION 5.0)
|
|
set(GTK_MINIMUM_VERSION 3.98.5)
|
|
@@ -55,6 +57,10 @@ find_package(EGL)
|
|
find_package(OpenGL)
|
|
find_package(OpenGLES2)
|
|
|
|
+# Playwright begin
|
|
+find_package(LibVPX REQUIRED)
|
|
+# Playwright end
|
|
+
|
|
include(GStreamerDefinitions)
|
|
|
|
SET_AND_EXPOSE_TO_BUILD(USE_ATK TRUE)
|
|
@@ -194,6 +200,13 @@ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_SHAREABLE_RESOURCE PUBLIC ON)
|
|
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEB_API_STATISTICS PRIVATE ON)
|
|
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEB_RTC PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
|
|
|
|
+# Playwright
|
|
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_APPLICATION_MANIFEST PRIVATE ON)
|
|
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_CSS_TRAILING_WORD PRIVATE ON)
|
|
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_CURSOR_VISIBILITY PRIVATE ON)
|
|
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_DOWNLOAD_ATTRIBUTE PRIVATE ON)
|
|
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_LEGACY_CSS_VENDOR_PREFIXES PRIVATE ON)
|
|
+
|
|
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 6466bda63785bb6cf6a2ca95355cc121ad952c32..d9288dfc8ab70fc65a1da44d3ad8d08a6c3098ce 100644
|
|
--- a/Source/cmake/OptionsWPE.cmake
|
|
+++ b/Source/cmake/OptionsWPE.cmake
|
|
@@ -3,6 +3,7 @@ include(VersioningUtils)
|
|
|
|
SET_PROJECT_VERSION(2 31 0)
|
|
set(WPE_API_VERSION 1.0)
|
|
+set(ENABLE_WEBKIT_LEGACY OFF)
|
|
|
|
CALCULATE_LIBRARY_VERSIONS_FROM_LIBTOOL_TRIPLE(WEBKIT 15 0 12)
|
|
|
|
@@ -80,13 +81,21 @@ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEBGL2 PRIVATE OFF)
|
|
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEB_RTC PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
|
|
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEBXR PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
|
|
|
|
+# Playwright
|
|
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_APPLICATION_MANIFEST PRIVATE ON)
|
|
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_CSS_TRAILING_WORD 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_DOWNLOAD_ATTRIBUTE PRIVATE ON)
|
|
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_LEGACY_CSS_VENDOR_PREFIXES PRIVATE ON)
|
|
+
|
|
# 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 any other WebKit ports.
|
|
WEBKIT_OPTION_DEFINE(ENABLE_GTKDOC "Whether or not to use generate gtkdoc." PUBLIC OFF)
|
|
WEBKIT_OPTION_DEFINE(USE_OPENJPEG "Whether to enable support for JPEG2000 images." PUBLIC ON)
|
|
WEBKIT_OPTION_DEFINE(USE_WOFF2 "Whether to enable support for WOFF2 Web Fonts." PUBLIC ON)
|
|
-WEBKIT_OPTION_DEFINE(ENABLE_WPE_QT_API "Whether to enable support for the Qt5/QML plugin" PUBLIC ${ENABLE_DEVELOPER_MODE})
|
|
+WEBKIT_OPTION_DEFINE(ENABLE_WPE_QT_API "Whether to enable support for the Qt5/QML plugin" PUBLIC OFF)
|
|
WEBKIT_OPTION_DEFINE(USE_SYSTEMD "Whether to enable journald logging" PUBLIC ON)
|
|
|
|
# Private options specific to the WPE port.
|
|
diff --git a/Source/cmake/OptionsWin.cmake b/Source/cmake/OptionsWin.cmake
|
|
index 3b1b8d555570c7405e36d724d508729dc900720f..7dbc3cd7d88434e1521c43ee57947752158172dd 100644
|
|
--- a/Source/cmake/OptionsWin.cmake
|
|
+++ b/Source/cmake/OptionsWin.cmake
|
|
@@ -7,8 +7,9 @@ add_definitions(-D_WINDOWS -DWINVER=0x601 -D_WIN32_WINNT=0x601)
|
|
add_definitions(-DNOMINMAX)
|
|
add_definitions(-DUNICODE -D_UNICODE)
|
|
|
|
+set(ENABLE_WEBKIT_LEGACY OFF)
|
|
+
|
|
if ((NOT DEFINED ENABLE_WEBKIT_LEGACY) OR ENABLE_WEBKIT_LEGACY)
|
|
- set(ENABLE_WEBKIT_LEGACY ON)
|
|
set(ENABLE_WEBKIT OFF)
|
|
endif ()
|
|
|
|
@@ -88,6 +89,13 @@ if (${WTF_PLATFORM_WIN_CAIRO})
|
|
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEBDRIVER PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
|
|
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEB_CRYPTO PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
|
|
|
|
+ # Playwright
|
|
+ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_CSS_CONIC_GRADIENTS PRIVATE ON)
|
|
+ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_CSS_TRAILING_WORD PRIVATE ON)
|
|
+ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_DARK_MODE_CSS PRIVATE ON)
|
|
+ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_DOWNLOAD_ATTRIBUTE PRIVATE ON)
|
|
+ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_TOUCH_EVENTS PRIVATE ON)
|
|
+
|
|
# FIXME: Implement plugin process on Modern WebKit. https://bugs.webkit.org/show_bug.cgi?id=185313
|
|
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_NETSCAPE_PLUGIN_API PRIVATE OFF)
|
|
else ()
|
|
diff --git a/Source/cmake/OptionsWinCairo.cmake b/Source/cmake/OptionsWinCairo.cmake
|
|
index bc7059b8640dc89efaa7bba164f41aaac4f658a0..49601573cd49e176866c7f13ae0bcb76bf8b6503 100644
|
|
--- a/Source/cmake/OptionsWinCairo.cmake
|
|
+++ b/Source/cmake/OptionsWinCairo.cmake
|
|
@@ -32,15 +32,36 @@ if (OpenJPEG_FOUND)
|
|
endif ()
|
|
|
|
find_package(WOFF2 1.0.2 COMPONENTS dec)
|
|
-if (WOFF2_FOUND)
|
|
- SET_AND_EXPOSE_TO_BUILD(USE_WOFF2 ON)
|
|
-endif ()
|
|
+SET_AND_EXPOSE_TO_BUILD(USE_WOFF2 ON)
|
|
|
|
find_package(WebP COMPONENTS demux)
|
|
if (WebP_FOUND)
|
|
SET_AND_EXPOSE_TO_BUILD(USE_WEBP ON)
|
|
endif ()
|
|
|
|
+# Playwright begin
|
|
+if (NOT LIBVPX_PACKAGE_PATH)
|
|
+ set(LIBVPX_PACKAGE_PATH "C:\\vcpkg\\packages\\libvpx_x64-windows")
|
|
+endif()
|
|
+file(TO_CMAKE_PATH "${LIBVPX_PACKAGE_PATH}" LIBVPX_PACKAGE_PATH)
|
|
+message(STATUS "Using LIBVPX_PACKAGE_PATH = ${LIBVPX_PACKAGE_PATH}")
|
|
+
|
|
+find_library(LIBVPX_CUSTOM_LIBRARY vpxmd.lib
|
|
+ HINTS ${LIBVPX_PACKAGE_PATH}/lib
|
|
+ REQIRED
|
|
+ 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
|
|
+
|
|
# TODO: Add a check for HAVE_RSA_PSS for support of CryptoAlgorithmRSA_PSS
|
|
# https://bugs.webkit.org/show_bug.cgi?id=206635
|
|
|
|
diff --git a/Tools/MiniBrowser/gtk/BrowserTab.c b/Tools/MiniBrowser/gtk/BrowserTab.c
|
|
index 3845eabba3e964f9e11bb0ffcb8726fd4ea96fc4..2e0e3929907d4760eb681c743984d4c83273880d 100644
|
|
--- a/Tools/MiniBrowser/gtk/BrowserTab.c
|
|
+++ b/Tools/MiniBrowser/gtk/BrowserTab.c
|
|
@@ -160,6 +160,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);
|
|
@@ -623,6 +628,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);
|
|
@@ -668,6 +674,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 90f29c8732d3269f9ff2c0e5707a1e8361cbcc10..81ab85819e78f293353d8ed853a7f48e87c13bf1 100644
|
|
--- a/Tools/MiniBrowser/gtk/BrowserWindow.c
|
|
+++ b/Tools/MiniBrowser/gtk/BrowserWindow.c
|
|
@@ -1335,6 +1335,12 @@ static gboolean browserWindowDeleteEvent(GtkWidget *widget, GdkEventAny* event)
|
|
}
|
|
#endif
|
|
|
|
+static void zeroPreferredSize(GtkWidget* widget, gint* minimumSize, gint* naturalSize)
|
|
+{
|
|
+ *minimumSize = 10;
|
|
+ *naturalSize = 10;
|
|
+}
|
|
+
|
|
static void browser_window_class_init(BrowserWindowClass *klass)
|
|
{
|
|
GObjectClass *gobjectClass = G_OBJECT_CLASS(klass);
|
|
@@ -1348,6 +1354,14 @@ static void browser_window_class_init(BrowserWindowClass *klass)
|
|
GtkWidgetClass *widgetClass = GTK_WIDGET_CLASS(klass);
|
|
widgetClass->delete_event = browserWindowDeleteEvent;
|
|
#endif
|
|
+
|
|
+// Playwrigth begin
|
|
+ // Override preferred (which is minimum :-) size to 0 so that we can
|
|
+ // emulate arbitrary resolution.
|
|
+ GtkWidgetClass* browserWidgetClass = GTK_WIDGET_CLASS(klass);
|
|
+ browserWidgetClass->get_preferred_width = zeroPreferredSize;
|
|
+ browserWidgetClass->get_preferred_height = zeroPreferredSize;
|
|
+// Playwrigth end
|
|
}
|
|
|
|
/* Public API. */
|
|
diff --git a/Tools/MiniBrowser/gtk/BrowserWindow.h b/Tools/MiniBrowser/gtk/BrowserWindow.h
|
|
index 62629b4c1c25ae82bd797b39bbf9de0331f8eed2..5de7900a29b0e629f1ac404bbb0dc5b4e605294d 100644
|
|
--- a/Tools/MiniBrowser/gtk/BrowserWindow.h
|
|
+++ b/Tools/MiniBrowser/gtk/BrowserWindow.h
|
|
@@ -37,7 +37,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 dc53db0c258b0401e0a2dca43e0380f1074ce024..1eed53ed934952e921a69c9f62bcd34f380f9935 100644
|
|
--- a/Tools/MiniBrowser/gtk/main.c
|
|
+++ b/Tools/MiniBrowser/gtk/main.c
|
|
@@ -52,7 +52,12 @@ static const char *cookiesPolicy;
|
|
static const char *proxy;
|
|
static gboolean darkMode;
|
|
static gboolean enableITP;
|
|
+static gboolean inspectorPipe;
|
|
+static gboolean headless;
|
|
+static gboolean noStartupWindow;
|
|
+static const char *userDataDir;
|
|
static gboolean printVersion;
|
|
+static GtkApplication *browserApplication = NULL;
|
|
|
|
typedef enum {
|
|
MINI_BROWSER_ERROR_INVALID_ABOUT_PATH
|
|
@@ -144,6 +149,10 @@ static const GOptionEntry commandLineOptions[] =
|
|
{ "content-filter", 0, 0, G_OPTION_ARG_FILENAME, &contentFilter, "JSON with content filtering rules", "FILE" },
|
|
{ "enable-itp", 0, 0, G_OPTION_ARG_NONE, &enableITP, "Enable Intelligent Tracking Prevention (ITP)", NULL },
|
|
{ "version", 'v', 0, G_OPTION_ARG_NONE, &printVersion, "Print the WebKitGTK version", NULL },
|
|
+ { "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 }
|
|
};
|
|
@@ -584,6 +593,48 @@ static void filterSavedCallback(WebKitUserContentFilterStore *store, GAsyncResul
|
|
g_main_loop_quit(data->mainLoop);
|
|
}
|
|
|
|
+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,
|
|
+ "is-ephemeral", webkit_web_context_is_ephemeral(context),
|
|
+ "is-controlled-by-automation", TRUE,
|
|
+ NULL));
|
|
+ GtkWidget *newWindow = browser_window_new(NULL, context);
|
|
+ gtk_window_set_application(GTK_WINDOW(newWindow), browserApplication);
|
|
+ browser_window_append_view(BROWSER_WINDOW(newWindow), newWebView);
|
|
+ gtk_widget_grab_focus(GTK_WIDGET(newWebView));
|
|
+ gtk_widget_show(GTK_WIDGET(newWindow));
|
|
+ webkit_web_view_load_uri(newWebView, "about:blank");
|
|
+ return newWebView;
|
|
+}
|
|
+
|
|
+static void quitBroserApplication(WebKitBrowserInspector* browser_inspector)
|
|
+{
|
|
+ g_application_release(G_APPLICATION(browserApplication));
|
|
+}
|
|
+
|
|
+static void keepApplicationAliveUntilQuit(GApplication *application)
|
|
+{
|
|
+ // Reference the application, it will be released in quitBroserApplication.
|
|
+ g_application_hold(application);
|
|
+ WebKitBrowserInspector* browserInspector = webkit_browser_inspector_get_default();
|
|
+ g_signal_connect(browserInspector, "quit-application", G_CALLBACK(quitBroserApplication), NULL);
|
|
+}
|
|
+
|
|
+static void configureBrowserInspectorPipe()
|
|
+{
|
|
+ WebKitBrowserInspector* browserInspector = webkit_browser_inspector_get_default();
|
|
+ g_signal_connect(browserInspector, "create-new-page", G_CALLBACK(createNewPage), NULL);
|
|
+
|
|
+ webkit_browser_inspector_initialize_pipe(proxy, ignoreHosts);
|
|
+}
|
|
+
|
|
static void startup(GApplication *application)
|
|
{
|
|
const char *actionAccels[] = {
|
|
@@ -614,10 +665,22 @@ static void startup(GApplication *application)
|
|
|
|
static void activate(GApplication *application, WebKitSettings *webkitSettings)
|
|
{
|
|
+ if (inspectorPipe)
|
|
+ configureBrowserInspectorPipe();
|
|
+
|
|
+ if (noStartupWindow) {
|
|
+ keepApplicationAliveUntilQuit(application);
|
|
+ g_clear_object(&webkitSettings);
|
|
+ return;
|
|
+ }
|
|
+
|
|
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_STRING, "MiniBrowser", NULL);
|
|
char *cacheDirectory = g_build_filename(g_get_user_cache_dir(), "webkitgtk-" WEBKITGTK_API_VERSION_STRING, "MiniBrowser", NULL);
|
|
manager = webkit_website_data_manager_new("base-data-directory", dataDirectory, "base-cache-directory", cacheDirectory, NULL);
|
|
@@ -641,6 +704,7 @@ static void activate(GApplication *application, WebKitSettings *webkitSettings)
|
|
"use-system-appearance-for-scrollbars", FALSE,
|
|
#endif
|
|
NULL);
|
|
+ persistentWebContext = webContext;
|
|
g_object_unref(manager);
|
|
|
|
if (cookiesPolicy) {
|
|
@@ -716,9 +780,7 @@ static void activate(GApplication *application, WebKitSettings *webkitSettings)
|
|
WebKitWebView *webView = createBrowserTab(mainWindow, webkitSettings, userContentManager, defaultWebsitePolicies);
|
|
if (!i)
|
|
firstTab = GTK_WIDGET(webView);
|
|
- 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);
|
|
@@ -791,9 +853,11 @@ int main(int argc, char *argv[])
|
|
}
|
|
|
|
GtkApplication *application = gtk_application_new(NULL, G_APPLICATION_FLAGS_NONE);
|
|
+ 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);
|
|
|
|
return 0;
|
|
diff --git a/Tools/MiniBrowser/wpe/main.cpp b/Tools/MiniBrowser/wpe/main.cpp
|
|
index 2ab04ce061cffbfcbbc4e64c6683996b672abbce..2d105be12aa764a538132c8a7cf19b4ea8ec5099 100644
|
|
--- a/Tools/MiniBrowser/wpe/main.cpp
|
|
+++ b/Tools/MiniBrowser/wpe/main.cpp
|
|
@@ -40,6 +40,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;
|
|
@@ -63,6 +66,9 @@ static const GOptionEntry commandLineOptions[] =
|
|
{ "bg-color", 0, 0, G_OPTION_ARG_STRING, &bgColor, "Window background color. Default: white", "COLOR" },
|
|
{ "enable-itp", 0, 0, G_OPTION_ARG_NONE, &enableITP, "Enable Intelligent Tracking Prevention (ITP)", 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 }
|
|
};
|
|
@@ -147,13 +153,34 @@ static void filterSavedCallback(WebKitUserContentFilterStore *store, GAsyncResul
|
|
g_main_loop_quit(data->mainLoop);
|
|
}
|
|
|
|
+static gboolean webViewLoadFailed()
|
|
+{
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
static void webViewClose(WebKitWebView* webView, gpointer)
|
|
{
|
|
// Hash table key delete func takes care of unref'ing the view
|
|
g_hash_table_remove(openViews, webView);
|
|
}
|
|
|
|
-static WebKitWebView* createWebView(WebKitWebView* webView, WebKitNavigationAction*, gpointer)
|
|
+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 WebKitWebView* createWebView(WebKitWebView* webView, WebKitNavigationAction*, gpointer);
|
|
+
|
|
+static WebKitWebView* createWebViewImpl(WebKitWebView* webView, WebKitWebContext *webContext)
|
|
{
|
|
auto backend = createViewBackend(1280, 720);
|
|
struct wpe_view_backend* wpeBackend = backend->backend();
|
|
@@ -165,17 +192,66 @@ static WebKitWebView* createWebView(WebKitWebView* webView, WebKitNavigationActi
|
|
delete static_cast<WPEToolingBackends::ViewBackend*>(data);
|
|
}, backend.release());
|
|
|
|
- auto* newWebView = webkit_web_view_new_with_related_view(viewBackend, webView);
|
|
- webkit_web_view_set_settings(newWebView, webkit_web_view_get_settings(webView));
|
|
+// 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_new_with_related_view(viewBackend, webView);
|
|
+ } else {
|
|
+ newWebView = WEBKIT_WEB_VIEW(g_object_new(WEBKIT_TYPE_WEB_VIEW,
|
|
+ "backend", viewBackend,
|
|
+ "web-context", webContext,
|
|
+ nullptr));
|
|
+ }
|
|
|
|
g_signal_connect(newWebView, "create", G_CALLBACK(createWebView), nullptr);
|
|
g_signal_connect(newWebView, "close", G_CALLBACK(webViewClose), nullptr);
|
|
|
|
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, "create", G_CALLBACK(createWebView), nullptr);
|
|
return newWebView;
|
|
}
|
|
|
|
+static WebKitWebView* createWebView(WebKitWebView* webView, WebKitNavigationAction*, gpointer)
|
|
+{
|
|
+ return createWebViewImpl(webView, nullptr);
|
|
+}
|
|
+
|
|
+static WebKitWebContext *persistentWebContext = NULL;
|
|
+
|
|
+static WebKitWebView* createNewPage(WebKitBrowserInspector*, WebKitWebContext *webContext)
|
|
+{
|
|
+ if (!webContext)
|
|
+ webContext = persistentWebContext;
|
|
+ WebKitWebView* webView = createWebViewImpl(nullptr, webContext);
|
|
+ webkit_web_view_load_uri(webView, "about:blank");
|
|
+ return webView;
|
|
+}
|
|
+
|
|
+static void quitBroserApplication(WebKitBrowserInspector* browser_inspector, gpointer data)
|
|
+{
|
|
+ GMainLoop* mainLoop = static_cast<GMainLoop*>(data);
|
|
+ g_main_loop_quit(mainLoop);
|
|
+}
|
|
+
|
|
+static void configureBrowserInspector(GMainLoop* mainLoop)
|
|
+{
|
|
+ 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), mainLoop);
|
|
+ webkit_browser_inspector_initialize_pipe(proxy, ignoreHosts);
|
|
+}
|
|
+
|
|
int main(int argc, char *argv[])
|
|
{
|
|
#if ENABLE_DEVELOPER_MODE
|
|
@@ -207,6 +283,16 @@ int main(int argc, char *argv[])
|
|
}
|
|
|
|
auto* loop = g_main_loop_new(nullptr, FALSE);
|
|
+ if (inspectorPipe)
|
|
+ configureBrowserInspector(loop);
|
|
+
|
|
+ openViews = g_hash_table_new_full(nullptr, nullptr, g_object_unref, nullptr);
|
|
+
|
|
+ if (noStartupWindow) {
|
|
+ g_main_loop_run(loop);
|
|
+ g_main_loop_unref(loop);
|
|
+ return 0;
|
|
+ }
|
|
|
|
auto backend = createViewBackend(1280, 720);
|
|
struct wpe_view_backend* wpeBackend = backend->backend();
|
|
@@ -216,7 +302,15 @@ int main(int argc, char *argv[])
|
|
return 1;
|
|
}
|
|
|
|
- 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) {
|
|
@@ -228,7 +322,8 @@ int main(int argc, char *argv[])
|
|
if (ignoreTLSErrors)
|
|
webkit_website_data_manager_set_tls_errors_policy(manager, WEBKIT_TLS_ERRORS_POLICY_IGNORE);
|
|
|
|
- auto* webContext = webkit_web_context_new_with_website_data_manager(manager);
|
|
+ WebKitWebContext *webContext = WEBKIT_WEB_CONTEXT(g_object_new(WEBKIT_TYPE_WEB_CONTEXT, "website-data-manager", manager, "process-swap-on-cross-site-navigation-enabled", TRUE, NULL));
|
|
+ persistentWebContext = webContext;
|
|
g_object_unref(manager);
|
|
|
|
if (cookiesPolicy) {
|
|
@@ -287,7 +382,14 @@ int main(int argc, char *argv[])
|
|
auto* viewBackend = webkit_web_view_backend_new(wpeBackend, [](gpointer data) {
|
|
delete static_cast<WPEToolingBackends::ViewBackend*>(data);
|
|
}, backend.release());
|
|
-
|
|
+// 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,
|
|
@@ -304,8 +406,6 @@ int main(int argc, char *argv[])
|
|
backendPtr->setAccessibleChild(ATK_OBJECT(accessible));
|
|
#endif
|
|
|
|
- openViews = g_hash_table_new_full(nullptr, nullptr, g_object_unref, nullptr);
|
|
-
|
|
webkit_web_context_set_automation_allowed(webContext, automationMode);
|
|
g_signal_connect(webContext, "automation-started", G_CALLBACK(automationStartedCallback), webView);
|
|
g_signal_connect(webView, "permission-request", G_CALLBACK(decidePermissionRequest), nullptr);
|
|
@@ -318,16 +418,9 @@ int main(int argc, char *argv[])
|
|
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");
|
|
@@ -337,8 +430,7 @@ int main(int argc, char *argv[])
|
|
g_hash_table_destroy(openViews);
|
|
|
|
|
|
- if (privateMode || automationMode)
|
|
- g_object_unref(webContext);
|
|
+ g_object_unref(webContext);
|
|
g_main_loop_unref(loop);
|
|
|
|
return 0;
|
|
diff --git a/Tools/PlatformWin.cmake b/Tools/PlatformWin.cmake
|
|
index ef4407cfc114e602d98ed81724da504f453e258f..448dd483715162baba484f756fbcc1d72de4ba0c 100644
|
|
--- a/Tools/PlatformWin.cmake
|
|
+++ b/Tools/PlatformWin.cmake
|
|
@@ -12,4 +12,5 @@ endif ()
|
|
|
|
if (ENABLE_WEBKIT)
|
|
add_subdirectory(WebKitTestRunner)
|
|
+ add_subdirectory(Playwright/win)
|
|
endif ()
|
|
diff --git a/Tools/Scripts/build-webkit b/Tools/Scripts/build-webkit
|
|
index 9a25452ae45f7437252b87336b7f6042db7613d5..acbf64c242a843dc1056d8be22fcb623403f54ab 100755
|
|
--- a/Tools/Scripts/build-webkit
|
|
+++ b/Tools/Scripts/build-webkit
|
|
@@ -247,7 +247,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/TestController.cpp b/Tools/WebKitTestRunner/TestController.cpp
|
|
index 58c2c095fc032366c48600954dd172b9f6834a0a..d26f7bbf216866b548cefda9775caeea093cb5f7 100644
|
|
--- a/Tools/WebKitTestRunner/TestController.cpp
|
|
+++ b/Tools/WebKitTestRunner/TestController.cpp
|
|
@@ -730,7 +730,8 @@ void TestController::createWebViewWithOptions(const TestOptions& options)
|
|
0, // didResignInputElementStrongPasswordAppearance
|
|
0, // requestStorageAccessConfirm
|
|
shouldAllowDeviceOrientationAndMotionAccess,
|
|
- runWebAuthenticationPanel
|
|
+ runWebAuthenticationPanel,
|
|
+ 0 // handleJavaScriptDialog
|
|
};
|
|
WKPageSetPageUIClient(m_mainWebView->page(), &pageUIClient.base);
|
|
|
|
diff --git a/Tools/WebKitTestRunner/mac/EventSenderProxy.mm b/Tools/WebKitTestRunner/mac/EventSenderProxy.mm
|
|
index 10272884084d2c10208cfa0714f1b10c5efc0a0b..fca38337665e206b40fc3f620c408b249d696701 100644
|
|
--- a/Tools/WebKitTestRunner/mac/EventSenderProxy.mm
|
|
+++ b/Tools/WebKitTestRunner/mac/EventSenderProxy.mm
|
|
@@ -873,4 +873,51 @@ void EventSenderProxy::mouseScrollByWithWheelAndMomentumPhases(int x, int y, int
|
|
}
|
|
}
|
|
|
|
+#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/win/DLLLauncher/DLLLauncherMain.cpp b/Tools/win/DLLLauncher/DLLLauncherMain.cpp
|
|
index 39238ac08dbcab92fb1d053928938a96f154c9b1..64bc9f1458254322dca9005b5e2d2b19bb901386 100644
|
|
--- a/Tools/win/DLLLauncher/DLLLauncherMain.cpp
|
|
+++ b/Tools/win/DLLLauncher/DLLLauncherMain.cpp
|
|
@@ -96,11 +96,9 @@ static bool prependPath(const wstring& directoryToPrepend)
|
|
static int fatalError(const wstring& programName, const wstring& message)
|
|
{
|
|
wstring caption = programName + L" can't open.";
|
|
-#if USE_CONSOLE_ENTRY_POINT
|
|
+// Playwright begin
|
|
fwprintf(stderr, L"%s\n%s\n", caption.c_str(), message.c_str());
|
|
-#else
|
|
- ::MessageBoxW(0, message.c_str(), caption.c_str(), MB_ICONERROR);
|
|
-#endif
|
|
+// Playwright end
|
|
return 1;
|
|
}
|
|
|
|
diff --git a/Tools/wpe/backends/HeadlessViewBackend.cpp b/Tools/wpe/backends/HeadlessViewBackend.cpp
|
|
index c09b6f39f894943f11b7a453428fab7d6f6e68fb..bc21acb648562ee0380811599b08f7d26c3e706a 100644
|
|
--- a/Tools/wpe/backends/HeadlessViewBackend.cpp
|
|
+++ b/Tools/wpe/backends/HeadlessViewBackend.cpp
|
|
@@ -145,27 +145,24 @@ void HeadlessViewBackend::updateSnapshot(struct wpe_fdo_shm_exported_buffer* exp
|
|
return;
|
|
}
|
|
|
|
- uint32_t bufferStride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, m_width);
|
|
- uint8_t* buffer = new uint8_t[bufferStride * m_height];
|
|
- memset(buffer, 0, bufferStride * m_height);
|
|
+ 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;
|
|
+ }
|
|
|
|
+ uint32_t bufferStride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width);
|
|
+ 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);
|
|
}
|
|
|
|
@@ -173,7 +170,7 @@ void HeadlessViewBackend::updateSnapshot(struct wpe_fdo_shm_exported_buffer* exp
|
|
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,
|