Yury Semikhatsky 2a01d0c83c
browser(webkit): build Playwright.app in workspace mode (#15161)
WebKit switched to workspace builds by default upstream in c67ee46115 and Playwright.app project (forked from MiniBrowser.app xcode project) was not a part of the workspace. This PR:

* Adds Tools/Playwright project to the WebKit workspace;
* Adds WebKit.framework to the list of dependencies of Playwright.app (I managed to successfully build without this modification but decided to added to be on the safe side as that was done upstream too);
* Removes `--no-use-workspace` in order to use workspace build mode which is the default upstream.

Pretty-diff: 75f1e79447
2022-06-28 12:30:01 -07:00

23148 lines
1001 KiB
Diff

diff --git a/Source/JavaScriptCore/CMakeLists.txt b/Source/JavaScriptCore/CMakeLists.txt
index 0aa6bbc263dcefd52c5660a3c16a517116b2482d..73a0bfbd99e77e4a00f590a4c206b2cf808e7e90 100644
--- a/Source/JavaScriptCore/CMakeLists.txt
+++ b/Source/JavaScriptCore/CMakeLists.txt
@@ -1354,22 +1354,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 0fd5ff880ac1add676c385722decd3a74468d78d..03eae0d873add089da986df79b762ebdd2acc8f4 100644
--- a/Source/JavaScriptCore/DerivedSources.make
+++ b/Source/JavaScriptCore/DerivedSources.make
@@ -290,22 +290,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 d28bffd30f21910bb63f515efc6fa9c7749825a4..498ea4b88e0befb9b526c188e079bb5b9882b374 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()->getOwnPropertyNames(&object, globalObject, propertyNames, DontEnumPropertiesMode::Exclude);
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 18b6dab3b9df38d781c5c767f76a29d8d18dbe02..0f3a341056f429ff282abcab22be4843c60f546c 100644
--- a/Source/JavaScriptCore/inspector/IdentifiersFactory.cpp
+++ b/Source/JavaScriptCore/inspector/IdentifiersFactory.cpp
@@ -32,14 +32,21 @@
namespace Inspector {
namespace {
+static uint64_t s_processID = 0;
static unsigned long s_lastUsedIdentifier = 0;
}
static String addPrefixToIdentifier(unsigned long identifier)
{
- return makeString("0.", identifier);
+ return makeString(s_processID, ".", identifier);
}
+void IdentifiersFactory::initializeWithProcessID(uint64_t processID) {
+ ASSERT(!s_processID);
+ s_processID = processID;
+}
+
+
String IdentifiersFactory::createIdentifier()
{
return addPrefixToIdentifier(++s_lastUsedIdentifier);
diff --git a/Source/JavaScriptCore/inspector/IdentifiersFactory.h b/Source/JavaScriptCore/inspector/IdentifiersFactory.h
index 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 8b290faebc1865519b0e7c514f497585dfc0bbda..53c68bca057c85c94201ef8e9870f0cb9e4cef6f 100644
--- a/Source/JavaScriptCore/inspector/InjectedScript.cpp
+++ b/Source/JavaScriptCore/inspector/InjectedScript.cpp
@@ -91,7 +91,7 @@ void InjectedScript::awaitPromise(const String& promiseObjectId, bool returnByVa
makeAsyncCall(function, WTFMove(callback));
}
-void InjectedScript::callFunctionOn(Protocol::ErrorString& errorString, const String& objectId, const String& expression, const String& arguments, bool returnByValue, bool generatePreview, RefPtr<Protocol::Runtime::RemoteObject>& result, std::optional<bool>& wasThrown)
+void InjectedScript::callFunctionOn(const String& objectId, const String& expression, const String& arguments, bool returnByValue, bool generatePreview, bool awaitPromise, AsyncCallCallback&& callback)
{
Deprecated::ScriptFunctionCall function(injectedScriptObject(), "callFunctionOn"_s, inspectorEnvironment()->functionCallHandler());
function.appendArgument(objectId);
@@ -99,10 +99,8 @@ void InjectedScript::callFunctionOn(Protocol::ErrorString& errorString, const St
function.appendArgument(arguments);
function.appendArgument(returnByValue);
function.appendArgument(generatePreview);
-
- std::optional<int> savedResultIndex;
- makeEvalCall(errorString, function, result, wasThrown, savedResultIndex);
- ASSERT(!savedResultIndex);
+ function.appendArgument(awaitPromise);
+ makeAsyncCall(function, WTFMove(callback));
}
void InjectedScript::evaluateOnCallFrame(Protocol::ErrorString& errorString, JSC::JSValue callFrames, const String& callFrameId, const String& expression, const String& objectGroup, bool includeCommandLineAPI, bool returnByValue, bool generatePreview, bool saveResult, RefPtr<Protocol::Runtime::RemoteObject>& result, std::optional<bool>& wasThrown, std::optional<int>& savedResultIndex)
@@ -289,6 +287,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/InjectedScript.h b/Source/JavaScriptCore/inspector/InjectedScript.h
index e6b24967273095ae424ac9b3fe5e081ee8999ab7..9f7b72259ab79504b8bfcc24d35abe70d7372065 100644
--- a/Source/JavaScriptCore/inspector/InjectedScript.h
+++ b/Source/JavaScriptCore/inspector/InjectedScript.h
@@ -64,7 +64,7 @@ public:
void evaluate(Protocol::ErrorString&, const String& expression, const String& objectGroup, bool includeCommandLineAPI, bool returnByValue, bool generatePreview, bool saveResult, RefPtr<Protocol::Runtime::RemoteObject>& result, std::optional<bool>& wasThrown, std::optional<int>& savedResultIndex);
void awaitPromise(const String& promiseObjectId, bool returnByValue, bool generatePreview, bool saveResult, AsyncCallCallback&&);
void evaluateOnCallFrame(Protocol::ErrorString&, JSC::JSValue callFrames, const String& callFrameId, const String& expression, const String& objectGroup, bool includeCommandLineAPI, bool returnByValue, bool generatePreview, bool saveResult, RefPtr<Protocol::Runtime::RemoteObject>& result, std::optional<bool>& wasThrown, std::optional<int>& savedResultIndex);
- void callFunctionOn(Protocol::ErrorString&, const String& objectId, const String& expression, const String& arguments, bool returnByValue, bool generatePreview, RefPtr<Protocol::Runtime::RemoteObject>& result, std::optional<bool>& wasThrown);
+ void callFunctionOn(const String& objectId, const String& expression, const String& arguments, bool returnByValue, bool generatePreview, bool awaitPromise, AsyncCallCallback&&);
void getFunctionDetails(Protocol::ErrorString&, const String& functionId, RefPtr<Protocol::Debugger::FunctionDetails>& result);
void functionDetails(Protocol::ErrorString&, JSC::JSValue, RefPtr<Protocol::Debugger::FunctionDetails>& result);
void getPreview(Protocol::ErrorString&, const String& objectId, RefPtr<Protocol::Runtime::ObjectPreview>& result);
diff --git a/Source/JavaScriptCore/inspector/InjectedScriptSource.js b/Source/JavaScriptCore/inspector/InjectedScriptSource.js
index 0080366628c66a5be04024aa560e0d812c27884a..9c325c085feddd42920dce3c71fd60703b670e3f 100644
--- a/Source/JavaScriptCore/inspector/InjectedScriptSource.js
+++ b/Source/JavaScriptCore/inspector/InjectedScriptSource.js
@@ -166,7 +166,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;
}
@@ -201,14 +201,16 @@ let InjectedScript = class InjectedScript
return this._evaluateAndWrap(callFrame.evaluateWithScopeExtension, callFrame, expression, objectGroup, isEvalOnCallFrame, includeCommandLineAPI, returnByValue, generatePreview, saveResult);
}
- callFunctionOn(objectId, expression, args, returnByValue, generatePreview)
+ callFunctionOn(objectId, expression, args, returnByValue, generatePreview, awaitPromise, callback)
{
let parsedObjectId = this._parseObjectId(objectId);
let object = this._objectForId(parsedObjectId);
let objectGroupName = this._idToObjectGroupName[parsedObjectId.id];
- if (!isDefined(object))
- return "Could not find object with given id";
+ if (!isDefined(object)) {
+ callback(this._createThrownValue("Could not find object with given id", objectGroupName));
+ return ;
+ }
let resolvedArgs = @createArrayWithoutPrototype();
if (args) {
@@ -217,22 +219,37 @@ let InjectedScript = class InjectedScript
try {
resolvedArgs[i] = this._resolveCallArgument(callArgs[i]);
} catch (e) {
- return @String(e);
+ callback(this._createThrownValue(e, objectGroupName));
+ return;
}
}
}
try {
let func = InjectedScriptHost.evaluate("(" + expression + ")");
- if (typeof func !== "function")
- return "Given expression does not evaluate to a function";
-
- return @createObjectWithoutPrototype(
- "wasThrown", false,
- "result", RemoteObject.create(func.@apply(object, resolvedArgs), objectGroupName, returnByValue, generatePreview),
- );
+ if (typeof func !== "function") {
+ callback(this._createThrownValue("Given expression does not evaluate to a function", objectGroupName));
+ return;
+ }
+ let result = func.apply(object, resolvedArgs);
+ if (awaitPromise && isDefined(result) && (InjectedScriptHost.internalConstructorName(result) === 'Promise')) {
+ result.then(value => {
+ callback({
+ wasThrown: false,
+ result: RemoteObject.create(value, objectGroupName, returnByValue, generatePreview),
+ });
+ }, reason => {
+ callback(this._createThrownValue(reason, objectGroupName));
+ });
+ } else {
+ callback({
+ wasThrown: false,
+ result: RemoteObject.create(result, objectGroupName, returnByValue, generatePreview)
+ });
+ }
} catch (e) {
- return this._createThrownValue(e, objectGroupName);
+ callback(this._createThrownValue(e, objectGroupName));
+ return;
}
}
diff --git a/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.cpp b/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.cpp
index 1088a6a8f2965e17e52d7ba1d1142b9ed697ad3f..a928811c56eaac0ea5a9a350093cb69e7b3ad59d 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 scopedRequestId(m_currentRequestId, requestId);
diff --git a/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.h b/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.h
index 37c4f9833d4981b47bcd8debd4a79109254641a2..1c82cc9783618234bef7024d91821ce509912526 100644
--- a/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.h
+++ b/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.h
@@ -83,7 +83,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..653842a82ed7a7be8603c9ef88ff48d1cda421be 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"_s; }
+ virtual void close(String& error, bool /* runBeforeUnload */) { error = "Target cannot be closed"_s; }
private:
+ virtual void willResume() { }
+
WTF::Function<void()> m_resumeCallback;
bool m_isPaused { false };
};
diff --git a/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.cpp b/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.cpp
index 6e976621186326be53aedeeda618a441d7bea6a6..ab46b5e2d1688ab538ebac0f5b908dc5a49a365a 100644
--- a/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.cpp
+++ b/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.cpp
@@ -177,41 +177,38 @@ void InspectorRuntimeAgent::awaitPromise(const Protocol::Runtime::RemoteObjectId
});
}
-Protocol::ErrorStringOr<std::tuple<Ref<Protocol::Runtime::RemoteObject>, std::optional<bool> /* wasThrown */>> InspectorRuntimeAgent::callFunctionOn(const Protocol::Runtime::RemoteObjectId& objectId, const String& functionDeclaration, RefPtr<JSON::Array>&& arguments, std::optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& emulateUserGesture)
+void InspectorRuntimeAgent::callFunctionOn(const Protocol::Runtime::RemoteObjectId& objectId, const String& functionDeclaration, RefPtr<JSON::Array>&& arguments, std::optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& emulateUserGesture, std::optional<bool>&& awaitPromise, Ref<CallFunctionOnCallback>&& callback)
{
InjectedScript injectedScript = m_injectedScriptManager.injectedScriptForObjectId(objectId);
- if (injectedScript.hasNoValue())
- return makeUnexpected("Missing injected script for given objectId"_s);
+ if (injectedScript.hasNoValue()) {
+ callback->sendFailure("Missing injected script for given objectId"_s);
+ return;
+ }
- return callFunctionOn(injectedScript, objectId, functionDeclaration, WTFMove(arguments), WTFMove(doNotPauseOnExceptionsAndMuteConsole), WTFMove(returnByValue), WTFMove(generatePreview), WTFMove(emulateUserGesture));
+ callFunctionOn(injectedScript, objectId, functionDeclaration, WTFMove(arguments), WTFMove(doNotPauseOnExceptionsAndMuteConsole), WTFMove(returnByValue), WTFMove(generatePreview), WTFMove(emulateUserGesture), WTFMove(awaitPromise), WTFMove(callback));
}
-Protocol::ErrorStringOr<std::tuple<Ref<Protocol::Runtime::RemoteObject>, std::optional<bool> /* wasThrown */>> InspectorRuntimeAgent::callFunctionOn(InjectedScript& injectedScript, const Protocol::Runtime::RemoteObjectId& objectId, const String& functionDeclaration, RefPtr<JSON::Array>&& arguments, std::optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& /* emulateUserGesture */)
+void InspectorRuntimeAgent::callFunctionOn(InjectedScript& injectedScript, const Protocol::Runtime::RemoteObjectId& objectId, const String& functionDeclaration, RefPtr<JSON::Array>&& arguments, std::optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& /* emulateUserGesture */, std::optional<bool>&& awaitPromise, Ref<CallFunctionOnCallback>&& callback)
{
ASSERT(!injectedScript.hasNoValue());
-
- Protocol::ErrorString errorString;
-
- RefPtr<Protocol::Runtime::RemoteObject> result;
- std::optional<bool> wasThrown;
-
+
JSC::Debugger::TemporarilyDisableExceptionBreakpoints temporarilyDisableExceptionBreakpoints(m_debugger);
-
+
bool pauseAndMute = doNotPauseOnExceptionsAndMuteConsole.value_or(false);
if (pauseAndMute) {
temporarilyDisableExceptionBreakpoints.replace();
muteConsole();
}
-
- injectedScript.callFunctionOn(errorString, objectId, functionDeclaration, arguments ? arguments->toJSONString() : nullString(), returnByValue.value_or(false), generatePreview.value_or(false), result, wasThrown);
+
+ injectedScript.callFunctionOn(objectId, functionDeclaration, arguments ? arguments->toJSONString() : nullString(), returnByValue.value_or(false), generatePreview.value_or(false), awaitPromise.value_or(false), [callback=WTFMove(callback)] (Protocol::ErrorString& errorString, RefPtr<Protocol::Runtime::RemoteObject>&& result, std::optional<bool>&& wasThrown, std::optional<int>&&) {
+ if (!result)
+ callback->sendFailure(errorString);
+ else
+ callback->sendSuccess(result.releaseNonNull(), WTFMove(wasThrown));
+ });
if (pauseAndMute)
unmuteConsole();
-
- if (!result)
- return makeUnexpected(errorString);
-
- return { { result.releaseNonNull(), WTFMove(wasThrown) } };
}
Protocol::ErrorStringOr<Ref<Protocol::Runtime::ObjectPreview>> InspectorRuntimeAgent::getPreview(const Protocol::Runtime::RemoteObjectId& objectId)
diff --git a/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.h b/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.h
index 1db64831b835df816130be4e7d42b7b213625656..5c3488200ab2df6dfc914ff780f05eba7ffd92a2 100644
--- a/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.h
+++ b/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.h
@@ -62,7 +62,7 @@ public:
Protocol::ErrorStringOr<std::tuple<Protocol::Runtime::SyntaxErrorType, String /* message */, RefPtr<Protocol::Runtime::ErrorRange>>> parse(const String& expression) final;
Protocol::ErrorStringOr<std::tuple<Ref<Protocol::Runtime::RemoteObject>, std::optional<bool> /* wasThrown */, std::optional<int> /* savedResultIndex */>> evaluate(const String& expression, const String& objectGroup, std::optional<bool>&& includeCommandLineAPI, std::optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, std::optional<Protocol::Runtime::ExecutionContextId>&&, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& saveResult, std::optional<bool>&& emulateUserGesture) override;
void awaitPromise(const Protocol::Runtime::RemoteObjectId&, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& saveResult, Ref<AwaitPromiseCallback>&&) final;
- Protocol::ErrorStringOr<std::tuple<Ref<Protocol::Runtime::RemoteObject>, std::optional<bool> /* wasThrown */>> callFunctionOn(const Protocol::Runtime::RemoteObjectId&, const String& functionDeclaration, RefPtr<JSON::Array>&& arguments, std::optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& emulateUserGesture) override;
+ void callFunctionOn(const Protocol::Runtime::RemoteObjectId&, const String& functionDeclaration, RefPtr<JSON::Array>&& arguments, std::optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& emulateUserGesture, std::optional<bool>&& awaitPromise, Ref<CallFunctionOnCallback>&&) override;
Protocol::ErrorStringOr<void> releaseObject(const Protocol::Runtime::RemoteObjectId&) final;
Protocol::ErrorStringOr<Ref<Protocol::Runtime::ObjectPreview>> getPreview(const Protocol::Runtime::RemoteObjectId&) final;
Protocol::ErrorStringOr<std::tuple<Ref<JSON::ArrayOf<Protocol::Runtime::PropertyDescriptor>>, RefPtr<JSON::ArrayOf<Protocol::Runtime::InternalPropertyDescriptor>>>> getProperties(const Protocol::Runtime::RemoteObjectId&, std::optional<bool>&& ownProperties, std::optional<int>&& fetchStart, std::optional<int>&& fetchCount, std::optional<bool>&& generatePreview) final;
@@ -82,7 +82,7 @@ protected:
InspectorRuntimeAgent(AgentContext&);
Protocol::ErrorStringOr<std::tuple<Ref<Protocol::Runtime::RemoteObject>, std::optional<bool> /* wasThrown */, std::optional<int> /* savedResultIndex */>> evaluate(InjectedScript&, const String& expression, const String& objectGroup, std::optional<bool>&& includeCommandLineAPI, std::optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& saveResult, std::optional<bool>&& emulateUserGesture);
- Protocol::ErrorStringOr<std::tuple<Ref<Protocol::Runtime::RemoteObject>, std::optional<bool> /* wasThrown */>> callFunctionOn(InjectedScript&, const Protocol::Runtime::RemoteObjectId&, const String& functionDeclaration, RefPtr<JSON::Array>&& arguments, std::optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& emulateUserGesture);
+ void callFunctionOn(InjectedScript&, const Protocol::Runtime::RemoteObjectId&, const String& functionDeclaration, RefPtr<JSON::Array>&& arguments, std::optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& emulateUserGesture, std::optional<bool>&& awaitPromise, Ref<CallFunctionOnCallback>&&);
InjectedScriptManager& injectedScriptManager() { return m_injectedScriptManager; }
diff --git a/Source/JavaScriptCore/inspector/agents/InspectorTargetAgent.cpp b/Source/JavaScriptCore/inspector/agents/InspectorTargetAgent.cpp
index 508eb02ec95c52408384a1e2b77648afd426dd9d..93d6757e170272cda8c346bf51578d2b5f8aafaa 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, std::optional<bool>&& runBeforeUnload)
+{
+ InspectorTarget* target = m_targets.get(targetId);
+ if (!target)
+ return makeUnexpected("Missing target for given targetId"_s);
+
+ String errorString;
+ target->close(errorString, runBeforeUnload && *runBeforeUnload);
+ if (!errorString.isEmpty())
+ return makeUnexpected(errorString);
+
+ return { };
+}
+
void InspectorTargetAgent::sendMessageFromTargetToFrontend(const String& targetId, const String& message)
{
ASSERT_WITH_MESSAGE(m_targets.get(targetId), "Sending a message from an untracked target to the frontend.");
@@ -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)
diff --git a/Source/JavaScriptCore/inspector/agents/InspectorTargetAgent.h b/Source/JavaScriptCore/inspector/agents/InspectorTargetAgent.h
index e81573fd0fffaaf6fd2af36635c78fcdf8608c69..c8cde6cfcde9612624f12e21bd9fa56b426bec7f 100644
--- a/Source/JavaScriptCore/inspector/agents/InspectorTargetAgent.h
+++ b/Source/JavaScriptCore/inspector/agents/InspectorTargetAgent.h
@@ -50,15 +50,20 @@ public:
Protocol::ErrorStringOr<void> setPauseOnStart(bool) final;
Protocol::ErrorStringOr<void> resume(const String& targetId) final;
Protocol::ErrorStringOr<void> sendMessageToTarget(const String& targetId, const String& message) final;
+ Protocol::ErrorStringOr<void> activate(const String& targetId) override;
+ Protocol::ErrorStringOr<void> close(const String& targetId, std::optional<bool>&& runBeforeUnload) override;
// Target lifecycle.
void targetCreated(InspectorTarget&);
void targetDestroyed(InspectorTarget&);
+ void targetCrashed(InspectorTarget&);
void didCommitProvisionalTarget(const String& oldTargetID, const String& committedTargetID);
// 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 8de3ac227ca561a647ce78bb610d712378e20352..e999d1ac814a2ad9fbceca25e9fa56cea137e928 100644
--- a/Source/JavaScriptCore/inspector/protocol/DOM.json
+++ b/Source/JavaScriptCore/inspector/protocol/DOM.json
@@ -80,6 +80,16 @@
{ "name": "value", "type": "string", "description": "The value that is resolved to with this data binding relationship." }
]
},
+ {
+ "id": "Rect",
+ "type": "object",
+ "properties": [
+ { "name": "x", "type": "integer", "description": "X coordinate" },
+ { "name": "y", "type": "integer", "description": "Y coordinate" },
+ { "name": "width", "type": "integer", "description": "Rectangle width" },
+ { "name": "height", "type": "integer", "description": "Rectangle height" }
+ ]
+ },
{
"id": "EventListener",
"type": "object",
@@ -177,6 +187,16 @@
{ "name": "pseudoId", "$ref": "CSS.PseudoId", "optional": true }
],
"description": "An object referencing a node and a pseudo-element, primarily used to identify an animation effect target."
+ },
+ {
+ "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": [
@@ -559,7 +579,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": [
@@ -626,6 +648,46 @@
"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" }, "optional": true, "description": "Files to set" },
+ { "name": "paths", "type": "array", "items": { "type": "string" }, "optional": true, "description": "File paths 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..347a01b3fdd1a8277cb4104558e8bbfa63539374
--- /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": "fixedLayout", "type": "boolean" },
+ { "name": "deviceScaleFactor", "type": "number", "optional": true }
+ ]
+ },
+ {
+ "name": "setJavaScriptEnabled",
+ "description": "Allows to disable script execution for the page.",
+ "parameters": [
+ { "name": "enabled", "type": "boolean" }
+ ]
+ },
+ {
+ "name": "setAuthCredentials",
+ "description": "Credentials to use during HTTP authentication.",
+ "parameters": [
+ { "name": "username", "type": "string", "optional": true },
+ { "name": "password", "type": "string", "optional": true }
+ ]
+ },
+ {
+ "name": "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..b9ab57a2b5739ed997231399b4bd4042a0cb0935
--- /dev/null
+++ b/Source/JavaScriptCore/inspector/protocol/Input.json
@@ -0,0 +1,223 @@
+{
+ "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": "dispatchWheelEvent",
+ "description": "Dispatches a wheel event to the page.",
+ "async": true,
+ "parameters": [
+ {
+ "name": "x",
+ "description": "X coordinate of the event relative to the main frame's viewport in CSS pixels.",
+ "type": "integer"
+ },
+ {
+ "name": "y",
+ "description": "Y coordinate of the event relative to the main frame's viewport in CSS pixels. 0 refers to\nthe top of the viewport and Y increases as it proceeds towards the bottom of the viewport.",
+ "type": "integer"
+ },
+ {
+ "name": "modifiers",
+ "description": "Bit field representing pressed modifier keys. Alt=1, Ctrl=2, Meta/Command=4, Shift=8\n(default: 0).",
+ "optional": true,
+ "type": "integer"
+ },
+ {
+ "name": "deltaX",
+ "description": "X delta in CSS pixels for mouse wheel event (default: 0).",
+ "optional": true,
+ "type": "integer"
+ },
+ {
+ "name": "deltaY",
+ "description": "Y delta in CSS pixels for mouse wheel event (default: 0).",
+ "optional": true,
+ "type": "integer"
+ }
+ ]
+ },
+ {
+ "name": "dispatchTapEvent",
+ "description": "Dispatches a tap event to the page.",
+ "async": true,
+ "parameters": [
+ {
+ "name": "x",
+ "description": "X coordinate of the event relative to the main frame's viewport in CSS pixels.",
+ "type": "integer"
+ },
+ {
+ "name": "y",
+ "description": "Y coordinate of the event relative to the main frame's viewport in CSS pixels. 0 refers to\nthe top of the viewport and Y increases as it proceeds towards the bottom of the viewport.",
+ "type": "integer"
+ },
+ {
+ "name": "modifiers",
+ "description": "Bit field representing pressed modifier keys. Alt=1, Ctrl=2, Meta/Command=4, Shift=8\n(default: 0).",
+ "optional": true,
+ "type": "integer"
+ }
+ ]
+ }
+ ]
+}
diff --git a/Source/JavaScriptCore/inspector/protocol/Network.json b/Source/JavaScriptCore/inspector/protocol/Network.json
index 464e6312ef88000b6987a45479d4d3cda65eb6a5..6114c4bb0d19f532aeea0359fc74a13f00559434 100644
--- a/Source/JavaScriptCore/inspector/protocol/Network.json
+++ b/Source/JavaScriptCore/inspector/protocol/Network.json
@@ -343,6 +343,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 1c97ad011c5ec183a5866bb98319badd5ec9442f..658937fdc58425b9a164d9bc368a9e61ed836918 100644
--- a/Source/JavaScriptCore/inspector/protocol/Page.json
+++ b/Source/JavaScriptCore/inspector/protocol/Page.json
@@ -21,7 +21,14 @@
"ShowDebugBorders",
"ShowRepaintCounter",
"WebRTCEncryptionEnabled",
- "WebSecurityEnabled"
+ "WebSecurityEnabled",
+ "DeviceOrientationEventEnabled",
+ "SpeechRecognitionEnabled",
+ "PointerLockEnabled",
+ "NotificationsEnabled",
+ "FullScreenEnabled",
+ "InputTypeMonthEnabled",
+ "InputTypeWeekEnabled"
]
},
{
@@ -49,6 +56,12 @@
"enum": ["Light", "Dark"],
"description": "Page appearance name."
},
+ {
+ "id": "ReducedMotion",
+ "type": "string",
+ "enum": ["Reduce", "NoPreference"],
+ "description": "Page reduced-motion media query override."
+ },
{
"id": "Frame",
"type": "object",
@@ -112,6 +125,51 @@
{ "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."}
+ ]
+ },
+ {
+ "id": "Insets",
+ "type": "object",
+ "properties": [
+ { "name": "top", "type": "number" },
+ { "name": "right", "type": "number" },
+ { "name": "bottom", "type": "number" },
+ { "name": "left", "type": "number" }
+ ]
}
],
"commands": [
@@ -131,6 +189,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.",
@@ -147,6 +213,14 @@
{ "name": "value", "type": "string", "optional": true, "description": "Value to override the user agent with. If this value is not provided, the override is removed. Overrides are removed when Web Inspector closes/disconnects." }
]
},
+ {
+ "name": "overridePlatform",
+ "description": "Override's the navigator.platform of the inspected page",
+ "targetTypes": ["page"],
+ "parameters": [
+ { "name": "value", "type": "string", "optional": true, "description": "Value to override the platform with. If this value is not provided, the override is removed. Overrides are removed when Web Inspector closes/disconnects." }
+ ]
+ },
{
"name": "overrideSetting",
"description": "Allows the frontend to override the inspected page's settings.",
@@ -204,7 +278,8 @@
"name": "setBootstrapScript",
"targetTypes": ["page"],
"parameters": [
- { "name": "source", "type": "string", "optional": true, "description": "If `source` is provided (and not empty), it will be injected into all future global objects as soon as they're created. Omitting `source` will stop this from happening." }
+ { "name": "source", "type": "string", "optional": true, "description": "If `source` is provided (and not empty), it will be injected into all future global objects as soon as they're created. Omitting `source` will stop this from happening." },
+ { "name": "worldName", "type": "string", "optional": true, "description": "Isolated world name to evaluate the script in. If not specified main world will be used." }
]
},
{
@@ -270,6 +345,28 @@
{ "name": "appearance", "$ref": "Appearance", "optional": true }
]
},
+ {
+ "name": "setForcedReducedMotion",
+ "description": "Forces the reduced-motion media query for the page.",
+ "targetTypes": ["page"],
+ "parameters": [
+ { "name": "reducedMotion", "$ref": "ReducedMotion", "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.",
@@ -290,7 +387,8 @@
{ "name": "y", "type": "integer", "description": "Y coordinate" },
{ "name": "width", "type": "integer", "description": "Rectangle width" },
{ "name": "height", "type": "integer", "description": "Rectangle height" },
- { "name": "coordinateSystem", "$ref": "CoordinateSystem", "description": "Indicates the coordinate system of the supplied rectangle." }
+ { "name": "coordinateSystem", "$ref": "CoordinateSystem", "description": "Indicates the coordinate system of the supplied rectangle." },
+ { "name": "omitDeviceScaleFactor", "type": "boolean", "optional": true, "description": "By default, screenshot is inflated by device scale factor to avoid blurry image. This flag disables it." }
],
"returns": [
{ "name": "dataURL", "type": "string", "description": "Base64-encoded image data (PNG)." }
@@ -308,12 +406,92 @@
{
"name": "setScreenSizeOverride",
"description": "Overrides screen size exposed to DOM and used in media queries for testing with provided values.",
- "condition": "!(defined(WTF_PLATFORM_COCOA) && WTF_PLATFORM_COCOA)",
"targetTypes": ["page"],
"parameters": [
{ "name": "width", "type": "integer", "description": "Screen width", "optional": true },
{ "name": "height", "type": "integer", "description": "Screen height", "optional": true }
]
+ },
+ {
+ "name": "insertText",
+ "description": "Insert text into the current selection of the page.",
+ "parameters": [
+ { "name": "text", "type": "string", "description": "Text to insert." }
+ ]
+ },
+ {
+ "name": "setComposition",
+ "description": "Set the current IME composition.",
+ "parameters": [
+ { "name": "text", "type": "string" },
+ { "name": "selectionStart", "type": "integer" },
+ { "name": "selectionLength", "type": "integer" },
+ { "name": "replacementStart", "type": "integer", "optional": true },
+ { "name": "replacementLength", "type": "integer", "optional": true }
+ ]
+ },
+ {
+ "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": "setOrientationOverride",
+ "description": "Overrides window.orientation with provided value.",
+ "parameters": [
+ { "name": "angle", "type": "integer", "optional": true }
+ ]
+ },
+ {
+ "name": "setVisibleContentRects",
+ "targetTypes": ["page"],
+ "parameters": [
+ { "name": "unobscuredContentRect", "$ref": "DOM.Rect", "optional": true },
+ { "name": "contentInsets", "$ref": "Insets", "optional": true },
+ { "name": "obscuredInsets", "$ref": "Insets", "optional": true },
+ { "name": "unobscuredInsets", "$ref": "Insets", "optional": true }
+ ]
+ },
+ {
+ "name": "updateScrollingState",
+ "description": "Ensures that the scroll regions are up to date."
}
],
"events": [
@@ -321,14 +499,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." }
]
},
{
@@ -338,6 +518,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.",
@@ -377,6 +565,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.",
@@ -385,6 +589,42 @@
"parameters": [
{ "name": "appearance", "$ref": "Appearance", "description": "Name of the appearance that is active (not considering any forced appearance.)" }
]
+ },
+ {
+ "name": "willCheckNavigationPolicy",
+ "description": "Fired when page is about to check policy for newly triggered navigation.",
+ "parameters": [
+ {
+ "name": "frameId",
+ "description": "Id of the frame.",
+ "$ref": "Network.FrameId"
+ }
+ ]
+ },
+ {
+ "name": "didCheckNavigationPolicy",
+ "description": "Fired when page has received navigation policy decision.",
+ "parameters": [
+ {
+ "name": "frameId",
+ "description": "Id of the frame.",
+ "$ref": "Network.FrameId"
+ },
+ {
+ "name": "cancel",
+ "description": "True if the navigation will not continue in this frame.",
+ "type": "boolean",
+ "optional": true
+ }
+ ]
+ },
+ {
+ "name": "fileChooserOpened",
+ "description": "Fired when the page shows file chooser for it's <input type=file>.",
+ "parameters": [
+ { "name": "frameId", "$ref": "Network.FrameId", "description": "Frame where file chooser is opened." },
+ { "name": "element", "$ref": "Runtime.RemoteObject", "description": "Input element." }
+ ]
}
]
}
diff --git a/Source/JavaScriptCore/inspector/protocol/Playwright.json b/Source/JavaScriptCore/inspector/protocol/Playwright.json
new file mode 100644
index 0000000000000000000000000000000000000000..91bdeadaeb77d223cd4dc47b8bb90850d54a9056
--- /dev/null
+++ b/Source/JavaScriptCore/inspector/protocol/Playwright.json
@@ -0,0 +1,277 @@
+{
+ "domain": "Playwright",
+ "availability": ["web"],
+ "types": [
+ {
+ "id": "ContextID",
+ "type": "string",
+ "description": "Id of Browser context."
+ },
+ {
+ "id": "PageProxyID",
+ "type": "string",
+ "description": "Id of WebPageProxy."
+ },
+ {
+ "id": "CookieSameSitePolicy",
+ "type": "string",
+ "enum": ["None", "Lax", "Strict"],
+ "description": "Same-Site policy of a cookie."
+ },
+ {
+ "id": "Cookie",
+ "type": "object",
+ "description": "Cookie object",
+ "properties": [
+ { "name": "name", "type": "string", "description": "Cookie name." },
+ { "name": "value", "type": "string", "description": "Cookie value." },
+ { "name": "domain", "type": "string", "description": "Cookie domain." },
+ { "name": "path", "type": "string", "description": "Cookie path." },
+ { "name": "expires", "type": "number", "description": "Cookie expires." },
+ { "name": "httpOnly", "type": "boolean", "description": "True if cookie is http-only." },
+ { "name": "secure", "type": "boolean", "description": "True if cookie is secure." },
+ { "name": "session", "type": "boolean", "description": "True if cookie is session cookie." },
+ { "name": "sameSite", "$ref": "CookieSameSitePolicy", "description": "Cookie Same-Site policy." }
+ ]
+ },
+ {
+ "id": "SetCookieParam",
+ "type": "object",
+ "description": "Cookie object",
+ "properties": [
+ { "name": "name", "type": "string", "description": "Cookie name." },
+ { "name": "value", "type": "string", "description": "Cookie value." },
+ { "name": "domain", "type": "string", "description": "Cookie domain." },
+ { "name": "path", "type": "string", "description": "Cookie path." },
+ { "name": "expires", "type": "number", "optional": true, "description": "Cookie expires." },
+ { "name": "httpOnly", "type": "boolean", "optional": true, "description": "True if cookie is http-only." },
+ { "name": "secure", "type": "boolean", "optional": true, "description": "True if cookie is secure." },
+ { "name": "session", "type": "boolean", "optional": true, "description": "True if cookie is session cookie." },
+ { "name": "sameSite", "$ref": "CookieSameSitePolicy", "optional": true, "description": "Cookie Same-Site policy." }
+ ]
+ },
+ {
+ "id": "NameValue",
+ "type": "object",
+ "description": "Name-value pair",
+ "properties": [
+ { "name": "name", "type": "string" },
+ { "name": "value", "type": "string" }
+ ]
+ },
+ {
+ "id": "OriginStorage",
+ "type": "object",
+ "description": "Origin object",
+ "properties": [
+ { "name": "origin", "type": "string", "description": "Origin." },
+ { "name": "items", "type": "array", "items": { "$ref": "NameValue" }, "description": "Storage entries." }
+ ]
+ },
+ {
+ "id": "Geolocation",
+ "type": "object",
+ "description": "Geolocation",
+ "properties": [
+ { "name": "timestamp", "type": "number", "description": "Mock latitude" },
+ { "name": "latitude", "type": "number", "description": "Mock latitude" },
+ { "name": "longitude", "type": "number", "description": "Mock longitude" },
+ { "name": "accuracy", "type": "number", "description": "Mock accuracy" }
+ ]
+ }
+ ],
+ "commands": [
+ {
+ "name": "enable"
+ },
+ {
+ "name": "disable"
+ },
+ {
+ "name": "close",
+ "async": true,
+ "description": "Close browser."
+ },
+ {
+ "name": "createContext",
+ "description": "Creates new ephemeral browser context.",
+ "parameters": [
+ { "name": "proxyServer", "type": "string", "optional": true, "description": "Proxy server, similar to the one passed to --proxy-server" },
+ { "name": "proxyBypassList", "type": "string", "optional": true, "description": "Proxy bypass list, similar to the one passed to --proxy-bypass-list" }
+ ],
+ "returns": [
+ { "name": "browserContextId", "$ref": "ContextID", "description": "Unique identifier of the context." }
+ ]
+ },
+ {
+ "name": "deleteContext",
+ "async": true,
+ "description": "Deletes browser context previously created with createContect. The command will automatically close all pages that use the context.",
+ "parameters": [
+ { "name": "browserContextId", "$ref": "ContextID", "description": "Identifier of the context to delete." }
+ ]
+ },
+ {
+ "name": "createPage",
+ "parameters": [
+ { "name": "browserContextId", "$ref": "ContextID", "optional": true, "description": "JSON Inspector Protocol message (command) to be dispatched on the backend." }
+ ],
+ "returns": [
+ { "name": "pageProxyId", "$ref": "PageProxyID", "description": "Unique identifier of the page proxy." }
+ ]
+ },
+ {
+ "name": "navigate",
+ "async": true,
+ "description": "Navigates current page to the given URL.",
+ "parameters": [
+ { "name": "url", "type": "string", "description": "URL to navigate the page to." },
+ { "name": "pageProxyId", "$ref": "PageProxyID", "description": "Unique identifier of the page proxy." },
+ { "name": "frameId", "$ref": "Network.FrameId", "optional": true, "description": "Id of the frame to navigate."},
+ { "name": "referrer", "type": "string", "optional": true, "description": "Referrer URL." }
+ ],
+ "returns": [
+ { "name": "loaderId", "$ref": "Network.LoaderId", "optional": true, "description": "Identifier of the loader associated with the navigation." }
+ ]
+ },
+ {
+ "name": "grantFileReadAccess",
+ "description": "Grants read access for the specified files to the web process of the page.",
+ "parameters": [
+ { "name": "pageProxyId", "$ref": "PageProxyID", "description": "Unique identifier of the page proxy." },
+ { "name": "paths", "type": "array", "items": { "type": "string" }, "description": "Id of the frame to navigate."}
+ ]
+ },
+ {
+ "name": "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." }
+ ]
+ },
+ {
+ "name": "cancelDownload",
+ "parameters": [
+ { "name": "uuid", "type": "string" }
+ ],
+ "description": "Cancels a current running download."
+ }
+ ],
+ "events": [
+ {
+ "name": "pageProxyCreated",
+ "parameters": [
+ { "name": "browserContextId", "$ref": "ContextID", "description": "Unique identifier of the context." },
+ { "name": "pageProxyId", "$ref": "PageProxyID" },
+ { "name": "openerId", "$ref": "PageProxyID", "optional": true, "description": "Unique identifier of the opening page. Only set for pages created by window.open()." }
+ ]
+ },
+ {
+ "name": "pageProxyDestroyed",
+ "parameters": [
+ { "name": "pageProxyId", "$ref": "PageProxyID" }
+ ]
+ },
+ {
+ "name": "provisionalLoadFailed",
+ "description": "Fired when provisional load fails.",
+ "parameters": [
+ { "name": "pageProxyId", "$ref": "PageProxyID", "description": "Unique identifier of the page proxy." },
+ { "name": "loaderId", "$ref": "Network.LoaderId", "description": "Identifier of the loader associated with the navigation." },
+ { "name": "error", "type": "string", "description": "Localized error string." }
+ ]
+ },
+ {
+ "name": "windowOpen",
+ "description": "Fired when page opens a new window.",
+ "parameters": [
+ { "name": "pageProxyId", "$ref": "PageProxyID", "description": "Unique identifier of the page proxy." },
+ { "name": "url", "type": "string" },
+ { "name": "windowFeatures", "type": "array", "items": { "type": "string" } }
+ ]
+ },
+ {
+ "name": "downloadCreated",
+ "parameters": [
+ { "name": "pageProxyId", "$ref": "PageProxyID", "description": "Unique identifier of the page proxy." },
+ { "name": "frameId", "$ref": "Network.FrameId", "description": "Unique identifier of the originating frame." },
+ { "name": "uuid", "type": "string" },
+ { "name": "url", "type": "string" }
+ ]
+ },
+ {
+ "name": "downloadFilenameSuggested",
+ "parameters": [
+ { "name": "uuid", "type": "string" },
+ { "name": "suggestedFilename", "type": "string" }
+ ]
+ },
+ {
+ "name": "downloadFinished",
+ "parameters": [
+ { "name": "uuid", "type": "string" },
+ { "name": "error", "type": "string" }
+ ]
+ },
+ {
+ "name": "screencastFinished",
+ "parameters": [
+ { "name": "screencastId", "$ref": "Screencast.ScreencastId", "description": "Unique identifier of the screencast." }
+ ]
+ }
+ ]
+}
diff --git a/Source/JavaScriptCore/inspector/protocol/Runtime.json b/Source/JavaScriptCore/inspector/protocol/Runtime.json
index 274b01596d490fb81b48cf89bf668e0634e8b423..d08a9ddd745c748767ba8055907daa7beeffc219 100644
--- a/Source/JavaScriptCore/inspector/protocol/Runtime.json
+++ b/Source/JavaScriptCore/inspector/protocol/Runtime.json
@@ -261,12 +261,14 @@
{ "name": "doNotPauseOnExceptionsAndMuteConsole", "type": "boolean", "optional": true, "description": "Specifies whether function call should stop on exceptions and mute console. Overrides setPauseOnException state." },
{ "name": "returnByValue", "type": "boolean", "optional": true, "description": "Whether the result is expected to be a JSON object which should be sent by value." },
{ "name": "generatePreview", "type": "boolean", "optional": true, "description": "Whether preview should be generated for the result." },
- { "name": "emulateUserGesture", "type": "boolean", "optional": true, "description": "Whether the expression should be considered to be in a user gesture or not." }
+ { "name": "emulateUserGesture", "type": "boolean", "optional": true, "description": "Whether the expression should be considered to be in a user gesture or not." },
+ { "name": "awaitPromise", "type": "boolean", "optional": true, "description": "Whether to automatically await returned promise." }
],
"returns": [
{ "name": "result", "$ref": "RemoteObject", "description": "Call result." },
{ "name": "wasThrown", "type": "boolean", "optional": true, "description": "True if the result was thrown during the evaluation." }
- ]
+ ],
+ "async": true
},
{
"name": "getPreview",
diff --git a/Source/JavaScriptCore/inspector/protocol/Screencast.json b/Source/JavaScriptCore/inspector/protocol/Screencast.json
new file mode 100644
index 0000000000000000000000000000000000000000..73a4e53ced3acc41316bb8d4c787306d3f28a27e
--- /dev/null
+++ b/Source/JavaScriptCore/inspector/protocol/Screencast.json
@@ -0,0 +1,64 @@
+{
+ "domain": "Screencast",
+ "availability": ["web"],
+ "types": [
+ {
+ "id": "ScreencastId",
+ "type": "string",
+ "description": "Unique identifier of the screencast."
+ }
+ ],
+ "commands": [
+ {
+ "name": "startVideo",
+ "description": "Starts recoring video to speified file.",
+ "parameters": [
+ { "name": "file", "type": "string", "description": "Output file location." },
+ { "name": "width", "type": "integer" },
+ { "name": "height", "type": "integer" },
+ { "name": "toolbarHeight", "type": "integer" }
+ ],
+ "returns": [
+ { "name": "screencastId", "$ref": "ScreencastId", "description": "Unique identifier of the screencast." }
+ ]
+ },
+ {
+ "name": "stopVideo",
+ "async": true,
+ "description": "Stops recoding video. Returns after the file has been closed."
+ },
+ {
+ "name": "startScreencast",
+ "description": "Starts screencast.",
+ "parameters": [
+ { "name": "width", "type": "integer" },
+ { "name": "height", "type": "integer" },
+ { "name": "toolbarHeight", "type": "integer" },
+ { "name": "quality", "type": "integer" }
+ ],
+ "returns": [
+ { "name": "generation", "type": "integer", "description": "Screencast session generation." }
+ ]
+ },
+ {
+ "name": "stopScreencast",
+ "description": "Stops screencast."
+ },
+ {
+ "name": "screencastFrameAck",
+ "parameters": [
+ { "name": "generation", "type": "integer", "description": "Screencast session generation" }
+ ]
+ }
+ ],
+ "events": [
+ {
+ "name": "screencastFrame",
+ "parameters": [
+ { "name": "data", "type": "string", "description": "Base64 data" },
+ { "name": "deviceWidth", "type": "integer" },
+ { "name": "deviceHeight", "type": "integer" }
+ ]
+ }
+ ]
+}
diff --git a/Source/JavaScriptCore/inspector/protocol/Target.json b/Source/JavaScriptCore/inspector/protocol/Target.json
index 52920cded24a9c6b0ef6fb4e518664955db4f9fa..bbbabc4e7259088b9404e8cc07eecd6f45077da0 100644
--- a/Source/JavaScriptCore/inspector/protocol/Target.json
+++ b/Source/JavaScriptCore/inspector/protocol/Target.json
@@ -10,7 +10,7 @@
"properties": [
{ "name": "targetId", "type": "string", "description": "Unique identifier for the target." },
{ "name": "type", "type": "string", "enum": ["page", "service-worker", "worker"] },
- { "name": "isProvisional", "type": "boolean", "optional": true, "description": "Whether this is a provisional page target." },
+ { "name": "isProvisional", "type": "boolean", "optional": true, "description": "True value indicates that this is a provisional page target i.e. Such target may be created when current page starts cross-origin navigation. Eventually each provisional target is either committed and swaps with the current target or gets destroyed, e.g. in case of load request failure." },
{ "name": "isPaused", "type": "boolean", "optional": true, "description": "Whether the target is paused on start and has to be explicitely resumed by inspector." }
]
}
@@ -37,6 +37,21 @@
{ "name": "targetId", "type": "string" },
{ "name": "message", "type": "string", "description": "JSON Inspector Protocol message (command) to be dispatched on the backend." }
]
+ },
+ {
+ "name": "activate",
+ "description": "Reveals the target on screen.",
+ "parameters": [
+ { "name": "targetId", "type": "string" }
+ ]
+ },
+ {
+ "name": "close",
+ "description": "Closes the target.",
+ "parameters": [
+ { "name": "targetId", "type": "string" },
+ { "name": "runBeforeUnload", "type": "boolean", "optional": true }
+ ]
}
],
"events": [
@@ -49,7 +64,8 @@
{
"name": "targetDestroyed",
"parameters": [
- { "name": "targetId", "type": "string" }
+ { "name": "targetId", "type": "string" },
+ { "name": "crashed", "type": "boolean" }
]
},
{
diff --git a/Source/JavaScriptCore/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/ThirdParty/libwebrtc/CMakeLists.txt b/Source/ThirdParty/libwebrtc/CMakeLists.txt
index 0d42c17c6a85b2a9f6af319431332f7f8a709188..8899c8e85b11db81d1da14c7f27814883f75da50 100644
--- a/Source/ThirdParty/libwebrtc/CMakeLists.txt
+++ b/Source/ThirdParty/libwebrtc/CMakeLists.txt
@@ -398,6 +398,11 @@ set(webrtc_SOURCES
Source/third_party/boringssl/src/ssl/tls13_server.cc
Source/third_party/boringssl/src/ssl/tls_method.cc
Source/third_party/boringssl/src/ssl/tls_record.cc
+# Playwright begin
+ Source/third_party/libwebm/mkvmuxer/mkvmuxer.cc
+ Source/third_party/libwebm/mkvmuxer/mkvmuxerutil.cc
+ Source/third_party/libwebm/mkvmuxer/mkvwriter.cc
+# Playwright end
Source/third_party/libyuv/source/compare_common.cc
Source/third_party/libyuv/source/compare_gcc.cc
Source/third_party/libyuv/source/convert.cc
@@ -1857,6 +1862,10 @@ set(webrtc_INCLUDE_DIRECTORIES PRIVATE
Source/third_party/libsrtp/config
Source/third_party/libsrtp/crypto/include
Source/third_party/libsrtp/include
+# Playwright begin
+ Source/third_party/libwebm
+ Source/third_party/libvpx/source/libvpx
+# 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 4157c0a95fa332ac85a295814fda2fb61f3da434..6edd90d2c5fc3b16d19f4d73edacf8b3c776bb9e 100644
--- a/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.mac.exp
+++ b/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.mac.exp
@@ -338,3 +338,23 @@ __ZN6webrtc32createPixelBufferFromFrameBufferERNS_16VideoFrameBufferERKNSt3__18f
__ZN6webrtc25CreateTaskQueueGcdFactoryEv
__ZN6webrtc27CreatePeerConnectionFactoryEPN3rtc6ThreadES2_S2_NS0_13scoped_refptrINS_17AudioDeviceModuleEEENS3_INS_19AudioEncoderFactoryEEENS3_INS_19AudioDecoderFactoryEEENSt3__110unique_ptrINS_19VideoEncoderFactoryENSA_14default_deleteISC_EEEENSB_INS_19VideoDecoderFactoryENSD_ISG_EEEENS3_INS_10AudioMixerEEENS3_INS_15AudioProcessingEEEPNS_19AudioFrameProcessorENSB_INS_16TaskQueueFactoryENSD_ISP_EEEE
__ZN6webrtc16convertBGRAToYUVEP10__CVBufferS1_
+__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 64433d3d2a0be3d9b83bde060700af8ce57a0b9d..14e35310c06a3add1cbe951287706be705761580 100644
--- a/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.xcconfig
+++ b/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.xcconfig
@@ -50,7 +50,7 @@ DYLIB_INSTALL_NAME_BASE_WK_RELOCATABLE_FRAMEWORKS_ = $(NORMAL_WEBCORE_FRAMEWORKS
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/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/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_PREFIX = $(WK_LIBRARY_HEADERS_FOLDER_PATH);
INSTALL_PUBLIC_HEADER_PREFIX = $(INSTALL_PATH_PREFIX)$(PUBLIC_HEADERS_FOLDER_PREFIX);
diff --git a/Source/ThirdParty/libwebrtc/libwebrtc.xcodeproj/project.pbxproj b/Source/ThirdParty/libwebrtc/libwebrtc.xcodeproj/project.pbxproj
index e4b94b59216277aae01696e6d4846abf8f287dce..8cbe085788ba582ee4615faef20769b6d0eaea03 100644
--- a/Source/ThirdParty/libwebrtc/libwebrtc.xcodeproj/project.pbxproj
+++ b/Source/ThirdParty/libwebrtc/libwebrtc.xcodeproj/project.pbxproj
@@ -6,6 +6,20 @@
objectVersion = 52;
objects = {
+/* Begin PBXAggregateTarget section */
+ F31720AC27FE215900EEE407 /* Copy libvpx headers */ = {
+ isa = PBXAggregateTarget;
+ buildConfigurationList = F31720B027FE215900EEE407 /* Build configuration list for PBXAggregateTarget "Copy libvpx headers" */;
+ buildPhases = (
+ F31720B127FE216400EEE407 /* ShellScript */,
+ );
+ dependencies = (
+ );
+ name = "Copy libvpx headers";
+ productName = "Copy libvpx headers";
+ };
+/* End PBXAggregateTarget section */
+
/* Begin PBXBuildFile section */
410091CF242CFD6500C5EDA2 /* internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 41A391FA1EFC493000C4516A /* internal.h */; };
410091D2242CFF6F00C5EDA2 /* gcm_nohw.c in Sources */ = {isa = PBXBuildFile; fileRef = 410091D0242CFD8200C5EDA2 /* gcm_nohw.c */; };
@@ -4529,6 +4543,9 @@
DDF30D9127C5C725006A526F /* receive_side_congestion_controller.h in Headers */ = {isa = PBXBuildFile; fileRef = DDF30D9027C5C725006A526F /* receive_side_congestion_controller.h */; };
DDF30D9527C5C756006A526F /* bwe_defines.h in Headers */ = {isa = PBXBuildFile; fileRef = DDF30D9327C5C756006A526F /* bwe_defines.h */; };
DDF30D9627C5C756006A526F /* remote_bitrate_estimator.h in Headers */ = {isa = PBXBuildFile; fileRef = DDF30D9427C5C756006A526F /* remote_bitrate_estimator.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 */
@@ -4779,6 +4796,13 @@
remoteGlobalIDString = DDF30D0527C5C003006A526F;
remoteInfo = absl;
};
+ F31720B327FE273100EEE407 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = FB39D0701200ED9200088E69 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = F31720AC27FE215900EEE407;
+ remoteInfo = "Copy libvpx headers";
+ };
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
@@ -9558,6 +9582,9 @@
DDF30D9027C5C725006A526F /* receive_side_congestion_controller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = receive_side_congestion_controller.h; sourceTree = "<group>"; };
DDF30D9327C5C756006A526F /* bwe_defines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bwe_defines.h; sourceTree = "<group>"; };
DDF30D9427C5C756006A526F /* remote_bitrate_estimator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = remote_bitrate_estimator.h; 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 */
@@ -16876,6 +16903,7 @@
isa = PBXGroup;
children = (
CDFD2F9224C4B2F90048DAC3 /* common */,
+ F3B7819524C7CC1300FCB122 /* mkvmuxer */,
CDEBB19224C0191800ADBD44 /* webm_parser */,
);
path = libwebm;
@@ -17343,6 +17371,16 @@
path = include;
sourceTree = "<group>";
};
+ F3B7819524C7CC1300FCB122 /* mkvmuxer */ = {
+ isa = PBXGroup;
+ children = (
+ F3B7819724C7CC5200FCB122 /* mkvmuxer.cc */,
+ F3B7819624C7CC5100FCB122 /* mkvmuxerutil.cc */,
+ F3B7819824C7CC5200FCB122 /* mkvwriter.cc */,
+ );
+ name = mkvmuxer;
+ sourceTree = "<group>";
+ };
FB39D06E1200ED9200088E69 = {
isa = PBXGroup;
children = (
@@ -20024,6 +20062,7 @@
DDF30CFA27C5A98F006A526F /* PBXBuildRule */,
);
dependencies = (
+ F31720B427FE273100EEE407 /* PBXTargetDependency */,
DD2E76E827C6B69A00F2A74C /* PBXTargetDependency */,
CDEBB4CC24C01AB400ADBD44 /* PBXTargetDependency */,
411ED040212E0811004320BA /* PBXTargetDependency */,
@@ -20084,6 +20123,7 @@
41F77D15215BE45E00E72967 /* yasm */,
CDEBB11824C0187400ADBD44 /* webm */,
DDF30D0527C5C003006A526F /* absl */,
+ F31720AC27FE215900EEE407 /* Copy libvpx headers */,
);
};
/* End PBXProject section */
@@ -20217,6 +20257,23 @@
shellPath = /bin/sh;
shellScript = "[ \"${WK_USE_NEW_BUILD_SYSTEM}\" = YES ] && exit 0\nxcodebuild -project \"${PROJECT_FILE_PATH}\" -target \"${TARGET_NAME}\" installhdrs SYMROOT=\"${TARGET_TEMP_DIR}/LegacyNestHeaders-build\" DSTROOT=\"${BUILT_PRODUCTS_DIR}\" SDKROOT=\"${SDKROOT}\" -UseNewBuildSystem=YES\n";
};
+ F31720B127FE216400EEE407 /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputFileListPaths = (
+ );
+ inputPaths = (
+ );
+ outputFileListPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "PRIVATE_HEADERS_FOLDER_PATH=usr/local/include\n\nif [[ \"${DEPLOYMENT_LOCATION}\" == \"NO\" ]]; then\n PRIVATE_HEADERS_PATH=\"${TARGET_BUILD_DIR%/}/${PRIVATE_HEADERS_FOLDER_PATH}\"\nelse\n PRIVATE_HEADERS_PATH=\"${DSTROOT}${INSTALL_PATH_PREFIX%/}/${PRIVATE_HEADERS_FOLDER_PATH}\"\nfi;\n\necho \"#### PRIVATE_HEADERS_PATH = ${PRIVATE_HEADERS_PATH}\"\necho\n\nmkdir -p \"${PRIVATE_HEADERS_PATH}\"\n\nrsync -av --no-owner --no-group --prune-empty-dirs --exclude \".svn\" --exclude \"usr\" --include \"*/\" --include \"*.h\" --exclude \"*\" \"${SRCROOT}/Source/third_party/libyuv/include/\" \"${PRIVATE_HEADERS_PATH}\"\n\nrsync -av --no-owner --no-group --prune-empty-dirs --exclude \".svn\" --exclude \"usr\" --exclude \"src\" --exclude \"internal\" --include \"*/\" --include \"*.h\" --exclude \"*\" \"${SRCROOT}/Source/third_party/libvpx/source/libvpx/vpx\" \"${PRIVATE_HEADERS_PATH}\"\n\nrsync -av --no-owner --no-group --prune-empty-dirs --exclude \".svn\" --exclude \"usr\" --include \"*/\" --include \"*.h\" --exclude \"*\" \"${SRCROOT}/Source/third_party/libwebm/\" \"${PRIVATE_HEADERS_PATH}\"\n\n";
+ };
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
@@ -21787,6 +21844,9 @@
417953DB216983910028266B /* metrics.cc in Sources */,
5CDD865E1E43B8B500621E92 /* min_max_operations.c in Sources */,
4189395B242A71F5007FDC41 /* min_video_bitrate_experiment.cc in Sources */,
+ F3B7819A24C7CC5200FCB122 /* mkvmuxer.cc in Sources */,
+ F3B7819924C7CC5200FCB122 /* mkvmuxerutil.cc in Sources */,
+ F3B7819B24C7CC5200FCB122 /* mkvwriter.cc in Sources */,
4131C387234B957D0028A615 /* moving_average.cc in Sources */,
41FCBB1521B1F7AA00A5DF27 /* moving_average.cc in Sources */,
5CD286101E6A64C90094FDC8 /* moving_max.cc in Sources */,
@@ -22471,6 +22531,11 @@
target = DDF30D0527C5C003006A526F /* absl */;
targetProxy = DD2E76E727C6B69A00F2A74C /* PBXContainerItemProxy */;
};
+ F31720B427FE273100EEE407 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = F31720AC27FE215900EEE407 /* Copy libvpx headers */;
+ targetProxy = F31720B327FE273100EEE407 /* PBXContainerItemProxy */;
+ };
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
@@ -22719,6 +22784,27 @@
};
name = Production;
};
+ F31720AD27FE215900EEE407 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Debug;
+ };
+ F31720AE27FE215900EEE407 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Release;
+ };
+ F31720AF27FE215900EEE407 /* Production */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Production;
+ };
FB39D0711200ED9200088E69 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 5D7C59C71208C68B001C873E /* DebugRelease.xcconfig */;
@@ -22851,6 +22937,16 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Production;
};
+ F31720B027FE215900EEE407 /* Build configuration list for PBXAggregateTarget "Copy libvpx headers" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ F31720AD27FE215900EEE407 /* Debug */,
+ F31720AE27FE215900EEE407 /* Release */,
+ F31720AF27FE215900EEE407 /* Production */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Production;
+ };
FB39D0731200ED9200088E69 /* Build configuration list for PBXProject "libwebrtc" */ = {
isa = XCConfigurationList;
buildConfigurations = (
diff --git a/Source/WTF/Scripts/Preferences/WebPreferences.yaml b/Source/WTF/Scripts/Preferences/WebPreferences.yaml
index d5570255afc5eb0f43b5bcb9a621355daf360db6..82d4528e0716740d15b3ddc5c407e3bebd2cb056 100644
--- a/Source/WTF/Scripts/Preferences/WebPreferences.yaml
+++ b/Source/WTF/Scripts/Preferences/WebPreferences.yaml
@@ -977,7 +977,7 @@ InspectorStartsAttached:
exposed: [ WebKit ]
defaultValue:
WebKit:
- default: true
+ default: false
InspectorWindowFrame:
type: String
@@ -1736,6 +1736,17 @@ PluginsEnabled:
WebCore:
default: false
+PointerLockEnabled:
+ type: bool
+ condition: ENABLE(POINTER_LOCK)
+ defaultValue:
+ WebKitLegacy:
+ default: true
+ WebKit:
+ default: true
+ WebCore:
+ default: true
+
PrivateClickMeasurementEnabled:
type: bool
humanReadableName: "Private Click Measurement"
diff --git a/Source/WTF/Scripts/Preferences/WebPreferencesExperimental.yaml b/Source/WTF/Scripts/Preferences/WebPreferencesExperimental.yaml
index c66d797dffc804037a114c098ca24f09e2fde705..da2cf33e17d7d4a9c3055eda162e74cb7972f371 100644
--- a/Source/WTF/Scripts/Preferences/WebPreferencesExperimental.yaml
+++ b/Source/WTF/Scripts/Preferences/WebPreferencesExperimental.yaml
@@ -503,7 +503,7 @@ CrossOriginOpenerPolicyEnabled:
WebKitLegacy:
default: false
WebKit:
- default: true
+ default: false
WebCore:
default: false
@@ -880,9 +880,9 @@ MaskWebGLStringsEnabled:
WebKitLegacy:
default: true
WebKit:
- default: true
+ default: false
WebCore:
- default: true
+ default: false
# FIXME: This is on by default in WebKit2. Perhaps we should consider turning it on for WebKitLegacy as well.
MediaCapabilitiesExtensionsEnabled:
@@ -1390,7 +1390,7 @@ SpeechRecognitionEnabled:
WebKitLegacy:
default: false
WebKit:
- "HAVE(SPEECHRECOGNIZER) && ENABLE(MEDIA_STREAM)": true
+ "ENABLE(MEDIA_STREAM)": true
default: false
WebCore:
default: false
@@ -1505,6 +1505,7 @@ UseGPUProcessForDisplayCapture:
WebKit:
default: false
+# Playwright: force-disable on Windows
UseGPUProcessForWebGLEnabled:
type: bool
humanReadableName: "GPU Process: WebGL"
@@ -1515,7 +1516,7 @@ UseGPUProcessForWebGLEnabled:
defaultValue:
WebKit:
"ENABLE(GPU_PROCESS_BY_DEFAULT) && PLATFORM(IOS_FAMILY) && !HAVE(UIKIT_WEBKIT_INTERNALS)": true
- "PLATFORM(WIN)": true
+ "PLATFORM(WIN)": false
default: false
UserGesturePromisePropagationEnabled:
diff --git a/Source/WTF/Scripts/Preferences/WebPreferencesInternal.yaml b/Source/WTF/Scripts/Preferences/WebPreferencesInternal.yaml
index 03e44cf23a5f2a02d34a5c45b4061b2468628d0b..781a061f018f97b47e6da586b6d933c0dace5952 100644
--- a/Source/WTF/Scripts/Preferences/WebPreferencesInternal.yaml
+++ b/Source/WTF/Scripts/Preferences/WebPreferencesInternal.yaml
@@ -918,6 +918,7 @@ UseCGDisplayListsForDOMRendering:
WebKit:
default: true
+# Playwright: force-disable on Windows
UseGPUProcessForCanvasRenderingEnabled:
type: bool
humanReadableName: "GPU Process: Canvas Rendering"
@@ -928,7 +929,7 @@ UseGPUProcessForCanvasRenderingEnabled:
defaultValue:
WebKit:
"ENABLE(GPU_PROCESS_BY_DEFAULT)": true
- "PLATFORM(WIN)": true
+ "PLATFORM(WIN)": false
default: false
UseGPUProcessForMediaEnabled:
diff --git a/Source/WTF/wtf/PlatformEnable.h b/Source/WTF/wtf/PlatformEnable.h
index 5ad56f9bc9b46939b719a2a8bcfe5196286fc22f..b9e2ca132f66c60dce682c857356147b7442846b 100644
--- a/Source/WTF/wtf/PlatformEnable.h
+++ b/Source/WTF/wtf/PlatformEnable.h
@@ -416,7 +416,7 @@
#endif
#if !defined(ENABLE_ORIENTATION_EVENTS)
-#define ENABLE_ORIENTATION_EVENTS 0
+#define ENABLE_ORIENTATION_EVENTS 1
#endif
#if OS(WINDOWS)
@@ -477,7 +477,7 @@
#endif
#if !defined(ENABLE_TOUCH_EVENTS)
-#define ENABLE_TOUCH_EVENTS 0
+#define ENABLE_TOUCH_EVENTS 1
#endif
#if !defined(ENABLE_TOUCH_ACTION_REGIONS)
diff --git a/Source/WTF/wtf/PlatformEnableCocoa.h b/Source/WTF/wtf/PlatformEnableCocoa.h
index cea074e8b58caa50312bdf52760cf504f446da05..24d7fd9ba4e84125f4294292b062c8a385f4283b 100644
--- a/Source/WTF/wtf/PlatformEnableCocoa.h
+++ b/Source/WTF/wtf/PlatformEnableCocoa.h
@@ -247,7 +247,7 @@
#define ENABLE_DATA_DETECTION 1
#endif
-#if !defined(ENABLE_DEVICE_ORIENTATION) && !PLATFORM(MAC) && !PLATFORM(MACCATALYST)
+#if !defined(ENABLE_DEVICE_ORIENTATION) && !PLATFORM(MACCATALYST)
#define ENABLE_DEVICE_ORIENTATION 1
#endif
diff --git a/Source/WTF/wtf/PlatformGTK.cmake b/Source/WTF/wtf/PlatformGTK.cmake
index bb01bfeeac63f854fa656ec6b8d262fafc4c9df5..f8376ea8aada69d2e53734ba8fd234c2455c2b09 100644
--- a/Source/WTF/wtf/PlatformGTK.cmake
+++ b/Source/WTF/wtf/PlatformGTK.cmake
@@ -79,6 +79,7 @@ list(APPEND WTF_LIBRARIES
${GLIB_LIBRARIES}
Threads::Threads
ZLIB::ZLIB
+ stdc++fs
)
if (Journald_FOUND)
diff --git a/Source/WTF/wtf/PlatformHave.h b/Source/WTF/wtf/PlatformHave.h
index 3b5da4aa52fd0777291db0d5c2884559620bce9f..bfdfbb11bf86a4ccb3cfc1af7c9d583272eaebea 100644
--- a/Source/WTF/wtf/PlatformHave.h
+++ b/Source/WTF/wtf/PlatformHave.h
@@ -426,7 +426,7 @@
#define HAVE_FOUNDATION_WITH_SAME_SITE_COOKIE_SUPPORT 1
#endif
-#if PLATFORM(MAC) || PLATFORM(IOS) || PLATFORM(MACCATALYST) || PLATFORM(GTK) || PLATFORM(WPE)
+#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/WTF/wtf/PlatformWPE.cmake b/Source/WTF/wtf/PlatformWPE.cmake
index 09d4af604a835c7c6be1e43c249565bd1053aff4..0d6112342480454ce41a6b56dd925e1d41880e0b 100644
--- a/Source/WTF/wtf/PlatformWPE.cmake
+++ b/Source/WTF/wtf/PlatformWPE.cmake
@@ -52,6 +52,7 @@ list(APPEND WTF_LIBRARIES
${GLIB_LIBRARIES}
Threads::Threads
ZLIB::ZLIB
+ stdc++fs
)
if (Journald_FOUND)
diff --git a/Source/WebCore/DerivedSources.make b/Source/WebCore/DerivedSources.make
index 6163832ab099365f4a93e0c3ac22608492940e20..423d9ce211cce63e4cfb68ba3d0056a99f7c5009 100644
--- a/Source/WebCore/DerivedSources.make
+++ b/Source/WebCore/DerivedSources.make
@@ -979,6 +979,10 @@ JS_BINDING_IDLS := \
$(WebCore)/dom/Slotable.idl \
$(WebCore)/dom/StaticRange.idl \
$(WebCore)/dom/StringCallback.idl \
+ $(WebCore)/dom/Document+Touch.idl \
+ $(WebCore)/dom/Touch.idl \
+ $(WebCore)/dom/TouchEvent.idl \
+ $(WebCore)/dom/TouchList.idl \
$(WebCore)/dom/Text.idl \
$(WebCore)/dom/TextDecoder.idl \
$(WebCore)/dom/TextDecoderStream.idl \
@@ -1527,9 +1531,6 @@ JS_BINDING_IDLS := \
ADDITIONAL_BINDING_IDLS = \
DocumentTouch.idl \
GestureEvent.idl \
- Touch.idl \
- TouchEvent.idl \
- TouchList.idl \
#
vpath %.in $(WEBKITADDITIONS_HEADER_SEARCH_PATHS)
diff --git a/Source/WebCore/Modules/geolocation/Geolocation.cpp b/Source/WebCore/Modules/geolocation/Geolocation.cpp
index a0f3a2f50826db31cf7d6c133e4dfc47bac27528..a09ba013dc815b3f14f67ce799c2edb4bf77134b 100644
--- a/Source/WebCore/Modules/geolocation/Geolocation.cpp
+++ b/Source/WebCore/Modules/geolocation/Geolocation.cpp
@@ -371,8 +371,9 @@ bool Geolocation::shouldBlockGeolocationRequests()
bool isSecure = SecurityOrigin::isSecure(document()->url()) || document()->isSecureContext();
bool hasMixedContent = !document()->foundMixedContent().isEmpty();
bool isLocalOrigin = securityOrigin()->isLocal();
+ bool isPotentiallyTrustworthy = securityOrigin()->isPotentiallyTrustworthy();
if (document()->canAccessResource(ScriptExecutionContext::ResourceType::Geolocation) != ScriptExecutionContext::HasResourceAccess::No) {
- if (isLocalOrigin || (isSecure && !hasMixedContent) || isRequestFromIBooks())
+ if (isLocalOrigin || isPotentiallyTrustworthy || (isSecure && !hasMixedContent) || isRequestFromIBooks())
return false;
}
diff --git a/Source/WebCore/Modules/speech/cocoa/WebSpeechRecognizerTask.mm b/Source/WebCore/Modules/speech/cocoa/WebSpeechRecognizerTask.mm
index a941d76a4f748718df1e3cff2a6c5e0827f48891..f62db5a27ac0e4c12430e7d19e60c83d768ace22 100644
--- a/Source/WebCore/Modules/speech/cocoa/WebSpeechRecognizerTask.mm
+++ b/Source/WebCore/Modules/speech/cocoa/WebSpeechRecognizerTask.mm
@@ -198,6 +198,7 @@ NS_ASSUME_NONNULL_BEGIN
- (void)speechRecognizer:(SFSpeechRecognizer *)speechRecognizer availabilityDidChange:(BOOL)available
{
+ UNUSED_PARAM(speechRecognizer);
ASSERT(isMainThread());
if (available || !_task)
@@ -211,6 +212,7 @@ NS_ASSUME_NONNULL_BEGIN
- (void)speechRecognitionTask:(SFSpeechRecognitionTask *)task didHypothesizeTranscription:(SFTranscription *)transcription
{
+ UNUSED_PARAM(task);
ASSERT(isMainThread());
[self sendSpeechStartIfNeeded];
@@ -219,6 +221,7 @@ NS_ASSUME_NONNULL_BEGIN
- (void)speechRecognitionTask:(SFSpeechRecognitionTask *)task didFinishRecognition:(SFSpeechRecognitionResult *)recognitionResult
{
+ UNUSED_PARAM(task);
ASSERT(isMainThread());
[self callbackWithTranscriptions:recognitionResult.transcriptions isFinal:YES];
@@ -230,6 +233,7 @@ NS_ASSUME_NONNULL_BEGIN
- (void)speechRecognitionTaskWasCancelled:(SFSpeechRecognitionTask *)task
{
+ UNUSED_PARAM(task);
ASSERT(isMainThread());
[self sendSpeechEndIfNeeded];
diff --git a/Source/WebCore/PlatformWPE.cmake b/Source/WebCore/PlatformWPE.cmake
index 9604d21ceb51ab8d20a337c8dbe52c4059043d2c..86a9eec09c4ac457bdd4567eeab570210c1beec3 100644
--- a/Source/WebCore/PlatformWPE.cmake
+++ b/Source/WebCore/PlatformWPE.cmake
@@ -49,6 +49,7 @@ list(APPEND WebCore_PRIVATE_FRAMEWORK_HEADERS
platform/graphics/wayland/PlatformDisplayWayland.h
platform/graphics/wayland/WlUniquePtr.h
+ platform/wpe/SelectionData.h
)
set(CSS_VALUE_PLATFORM_DEFINES "HAVE_OS_DARK_MODE_SUPPORT=1")
diff --git a/Source/WebCore/SourcesCocoa.txt b/Source/WebCore/SourcesCocoa.txt
index 0c77d35ce6fe7ea21a48bb4c900fcd6954aa6112..2494f912e5b5245b6f023a6ec0c3256f5af39c4d 100644
--- a/Source/WebCore/SourcesCocoa.txt
+++ b/Source/WebCore/SourcesCocoa.txt
@@ -638,3 +638,9 @@ platform/graphics/angle/GraphicsContextGLANGLE.cpp @no-unify
platform/graphics/cocoa/ANGLEUtilitiesCocoa.cpp @no-unify
platform/graphics/cocoa/GraphicsContextGLCocoa.mm @no-unify
platform/graphics/cv/GraphicsContextGLCVCocoa.cpp @no-unify
+
+// Playwright begin
+JSTouch.cpp
+JSTouchEvent.cpp
+JSTouchList.cpp
+// Playwright end
diff --git a/Source/WebCore/SourcesGTK.txt b/Source/WebCore/SourcesGTK.txt
index 3c998999a8d2bd7063c6212cea68837c224476cd..9bdcd851df22e2aa179063a95fa69f6f29e54517 100644
--- a/Source/WebCore/SourcesGTK.txt
+++ b/Source/WebCore/SourcesGTK.txt
@@ -37,6 +37,9 @@ accessibility/atspi/AccessibilityObjectValueAtspi.cpp
accessibility/atspi/AccessibilityRootAtspi.cpp
accessibility/atspi/AXObjectCacheAtspi.cpp
+accessibility/empty/AXObjectCacheEmpty.cpp
+accessibility/empty/AccessibilityObjectEmpty.cpp
+
editing/atspi/FrameSelectionAtspi.cpp
editing/gtk/EditorGtk.cpp
@@ -135,3 +138,10 @@ platform/xdg/MIMETypeRegistryXdg.cpp
rendering/RenderThemeAdwaita.cpp
rendering/RenderThemeGtk.cpp
+
+// Playwright: begin.
+JSSpeechSynthesisErrorCode.cpp
+JSSpeechSynthesisErrorEvent.cpp
+JSSpeechSynthesisErrorEventInit.cpp
+JSSpeechSynthesisEventInit.cpp
+// Playwright: end.
diff --git a/Source/WebCore/SourcesWPE.txt b/Source/WebCore/SourcesWPE.txt
index 6ae23004c411842a59c2389d631127b9ce848773..eb60c694acc9a2f2f03503527ca8e9de406ca73d 100644
--- a/Source/WebCore/SourcesWPE.txt
+++ b/Source/WebCore/SourcesWPE.txt
@@ -37,11 +37,16 @@ accessibility/atspi/AccessibilityObjectValueAtspi.cpp
accessibility/atspi/AccessibilityRootAtspi.cpp
accessibility/atspi/AXObjectCacheAtspi.cpp
+accessibility/empty/AXObjectCacheEmpty.cpp
+accessibility/empty/AccessibilityObjectEmpty.cpp
+
editing/atspi/FrameSelectionAtspi.cpp
editing/libwpe/EditorLibWPE.cpp
loader/soup/ResourceLoaderSoup.cpp
+page/wpe/DragControllerWPE.cpp
+
page/linux/ResourceUsageOverlayLinux.cpp
page/linux/ResourceUsageThreadLinux.cpp
@@ -90,8 +95,19 @@ platform/text/LocaleICU.cpp
platform/unix/LoggingUnix.cpp
+platform/wpe/DragDataWPE.cpp
+platform/wpe/DragImageWPE.cpp
platform/wpe/PlatformScreenWPE.cpp
platform/xdg/MIMETypeRegistryXdg.cpp
rendering/RenderThemeAdwaita.cpp
+
+platform/wpe/SelectionData.cpp
+
+// Playwright: begin.
+JSSpeechSynthesisErrorCode.cpp
+JSSpeechSynthesisErrorEvent.cpp
+JSSpeechSynthesisErrorEventInit.cpp
+JSSpeechSynthesisEventInit.cpp
+// Playwright: end.
diff --git a/Source/WebCore/WebCore.order b/Source/WebCore/WebCore.order
index 82f617e0d496ee71ffc2f2ce4c00ddc0e640f0de..ad47858a0ba283ed44a486dbee29c10a54e97403 100644
--- a/Source/WebCore/WebCore.order
+++ b/Source/WebCore/WebCore.order
@@ -3090,7 +3090,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 630a1ea8a7d808221de8b7b0277f99ed7d854e0f..0ea6fc22e491195744ad4b95481e378278c83bb4 100644
--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj
+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj
@@ -5557,6 +5557,13 @@
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 */; };
+ 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, ); }; };
@@ -17952,6 +17959,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>"; };
@@ -24648,6 +24663,11 @@
BC4A5324256055590028C592 /* TextDirectionSubmenuInclusionBehavior.h */,
2D4F96F11A1ECC240098BF88 /* TextIndicator.cpp */,
2D4F96F21A1ECC240098BF88 /* TextIndicator.h */,
+ F050E16923AD660C0011CE47 /* Touch.cpp */,
+ F050E16F23AD669E0011CE47 /* TouchEvent.cpp */,
+ F050E17023AD669F0011CE47 /* TouchEvent.h */,
+ F050E16C23AD66630011CE47 /* TouchList.cpp */,
+ F050E16B23AD66620011CE47 /* TouchList.h */,
F48570A42644C76D00C05F71 /* TranslationContextMenuInfo.h */,
F4E1965F21F26E4E00285078 /* UndoItem.cpp */,
2ECDBAD521D8906300F00ECD /* UndoItem.h */,
@@ -30465,6 +30485,8 @@
29E4D8DF16B0940F00C84704 /* PlatformSpeechSynthesizer.h */,
1AD8F81A11CAB9E900E93E54 /* PlatformStrategies.cpp */,
1AD8F81911CAB9E900E93E54 /* PlatformStrategies.h */,
+ F050E16623AC9C070011CE47 /* PlatformTouchEvent.h */,
+ F050E17623AD70C40011CE47 /* PlatformTouchPoint.h */,
0FD7C21D23CE41E30096D102 /* PlatformWheelEvent.cpp */,
935C476A09AC4D4F00A6AAB4 /* PlatformWheelEvent.h */,
BCBB8AB513F1AFB000734DF0 /* PODInterval.h */,
@@ -32776,6 +32798,7 @@
AD6E71AB1668899D00320C13 /* DocumentSharedObjectPool.h */,
6BDB5DC1227BD3B800919770 /* DocumentStorageAccess.cpp */,
6BDB5DC0227BD3B800919770 /* DocumentStorageAccess.h */,
+ F050E17323AD6A800011CE47 /* DocumentTouch.cpp */,
7CE7FA5B1EF882300060C9D6 /* DocumentTouch.cpp */,
7CE7FA591EF882300060C9D6 /* DocumentTouch.h */,
A8185F3209765765005826D9 /* DocumentType.cpp */,
@@ -37071,6 +37094,8 @@
1AD8F81B11CAB9E900E93E54 /* PlatformStrategies.h in Headers */,
0F7D07331884C56C00B4AF86 /* PlatformTextTrack.h in Headers */,
074E82BB18A69F0E007EF54C /* PlatformTimeRanges.h in Headers */,
+ F050E16823AC9C080011CE47 /* PlatformTouchEvent.h in Headers */,
+ F050E17823AD70C50011CE47 /* PlatformTouchPoint.h in Headers */,
CDD08ABD277E542600EA3755 /* PlatformTrackConfiguration.h in Headers */,
CD1F9B022700323D00617EB6 /* PlatformVideoColorPrimaries.h in Headers */,
CD1F9B01270020B700617EB6 /* PlatformVideoColorSpace.h in Headers */,
@@ -38215,6 +38240,7 @@
0F54DD081881D5F5003EEDBB /* Touch.h in Headers */,
71B7EE0D21B5C6870031C1EF /* TouchAction.h in Headers */,
0F54DD091881D5F5003EEDBB /* TouchEvent.h in Headers */,
+ F050E16D23AD66630011CE47 /* TouchList.h in Headers */,
0F54DD0A1881D5F5003EEDBB /* TouchList.h in Headers */,
070334D71459FFD5008D8D45 /* TrackBase.h in Headers */,
BE88E0C21715CE2600658D98 /* TrackListBase.h in Headers */,
@@ -39173,6 +39199,7 @@
1ABA76CA11D20E50004C201C /* CSSPropertyNames.cpp in Sources */,
2D22830323A8470700364B7E /* CursorMac.mm in Sources */,
5CBD59592280E926002B22AA /* CustomHeaderFields.cpp in Sources */,
+ F050E17423AD6A800011CE47 /* DocumentTouch.cpp in Sources */,
7CE6CBFD187F394900D46BF5 /* FormatConverter.cpp in Sources */,
5130F2F624AEA60A00E1D0A0 /* GameControllerSoftLink.mm in Sources */,
51A4BB0A1954D61600FA5C2E /* Gamepad.cpp in Sources */,
@@ -39249,6 +39276,9 @@
C1692DD223D23ABD006E88F7 /* SystemBattery.mm in Sources */,
CE88EE262414467B007F29C2 /* TextAlternativeWithRange.mm in Sources */,
51DF6D800B92A18E00C2DC85 /* ThreadCheck.mm in Sources */,
+ F050E16A23AD660C0011CE47 /* Touch.cpp in Sources */,
+ F050E17123AD669F0011CE47 /* TouchEvent.cpp in Sources */,
+ F050E16E23AD66630011CE47 /* TouchList.cpp in Sources */,
538EC8031F96AF81004D22A8 /* UnifiedSource1-mm.mm in Sources */,
538EC8021F96AF81004D22A8 /* UnifiedSource1.cpp in Sources */,
538EC8051F96AF81004D22A8 /* UnifiedSource2-mm.mm in Sources */,
diff --git a/Source/WebCore/accessibility/AccessibilityObject.cpp b/Source/WebCore/accessibility/AccessibilityObject.cpp
index 1a0e3cec9998259c910ebb8f27a795b60ca1e6c8..577d9a4deef3910595b6af591280d9f56acb7166 100644
--- a/Source/WebCore/accessibility/AccessibilityObject.cpp
+++ b/Source/WebCore/accessibility/AccessibilityObject.cpp
@@ -61,6 +61,7 @@
#include "HTMLParserIdioms.h"
#include "HTMLTextAreaElement.h"
#include "HitTestResult.h"
+#include "InspectorInstrumentation.h"
#include "LocalizedStrings.h"
#include "MathMLNames.h"
#include "NodeList.h"
@@ -3734,9 +3735,14 @@ AccessibilityObjectInclusion AccessibilityObject::defaultObjectInclusion() const
if (roleValue() == AccessibilityRole::ApplicationDialog)
return AccessibilityObjectInclusion::IncludeObject;
- return accessibilityPlatformIncludesObject();
+ AccessibilityObjectInclusion platformBehavior = accessibilityPlatformIncludesObject();
+ if (platformBehavior != AccessibilityObjectInclusion::DefaultBehavior) {
+ if (auto* page = this->page())
+ InspectorInstrumentation::maybeOverrideDefaultObjectInclusion(*page, platformBehavior);
+ }
+ return platformBehavior;
}
-
+
bool AccessibilityObject::accessibilityIsIgnored() const
{
AXComputedObjectAttributeCache* attributeCache = nullptr;
diff --git a/Source/WebCore/accessibility/AccessibilityObjectInterface.h b/Source/WebCore/accessibility/AccessibilityObjectInterface.h
index 609f212740dfedc8e3cf50881ef7ebece3f42b40..1b2be343cfd1d2a1581d165693ca554a5810374c 100644
--- a/Source/WebCore/accessibility/AccessibilityObjectInterface.h
+++ b/Source/WebCore/accessibility/AccessibilityObjectInterface.h
@@ -57,7 +57,7 @@ typedef const struct __AXTextMarkerRange* AXTextMarkerRangeRef;
#elif USE(ATSPI)
typedef WebCore::AccessibilityObjectAtspi AccessibilityObjectWrapper;
#else
-class AccessibilityObjectWrapper;
+class AccessibilityObjectWrapper : public RefCounted<AccessibilityObjectWrapper> {};
#endif
namespace PAL {
@@ -1553,6 +1553,8 @@ private:
COMPtr<AccessibilityObjectWrapper> m_wrapper;
#elif USE(ATSPI)
RefPtr<AccessibilityObjectAtspi> m_wrapper;
+#else
+ RefPtr<AccessibilityObjectWrapper> m_wrapper;
#endif
virtual void detachPlatformWrapper(AccessibilityDetachmentType) = 0;
};
diff --git a/Source/WebCore/accessibility/empty/AXObjectCacheEmpty.cpp b/Source/WebCore/accessibility/empty/AXObjectCacheEmpty.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0233d1046f7074c11e9a3bab50f8fe8c5af7d95a
--- /dev/null
+++ b/Source/WebCore/accessibility/empty/AXObjectCacheEmpty.cpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 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"
+
+#if ENABLE(ACCESSIBILITY) && !USE(ATK) && !USE(ATSPI)
+
+#include "AXObjectCache.h"
+
+namespace WebCore {
+
+void AXObjectCache::detachWrapper(AXCoreObject* obj, AccessibilityDetachmentType) { }
+void AXObjectCache::attachWrapper(AXCoreObject*) { }
+void AXObjectCache::handleScrolledToAnchor(const Node* anchorNode) { }
+void AXObjectCache::postPlatformNotification(AXCoreObject* obj, AXNotification notification) { }
+void AXObjectCache::nodeTextChangePlatformNotification(AccessibilityObject*, AXTextChange, unsigned, const String&){ }
+void AXObjectCache::frameLoadingEventPlatformNotification(AccessibilityObject* obj, AXLoadingEvent notification) { }
+void AXObjectCache::platformHandleFocusedUIElementChanged(Node*, Node* newFocusedNode) { }
+void AXObjectCache::platformPerformDeferredCacheUpdate() { }
+
+} // namespace WebCore
+
+#endif // ENABLE(ACCESSIBILITY)
diff --git a/Source/WebCore/accessibility/empty/AccessibilityObjectEmpty.cpp b/Source/WebCore/accessibility/empty/AccessibilityObjectEmpty.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..dd2d8452302999e4a89b0bc18e842645c939247d
--- /dev/null
+++ b/Source/WebCore/accessibility/empty/AccessibilityObjectEmpty.cpp
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 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"
+
+#if ENABLE(ACCESSIBILITY) && !USE(ATK) && !USE(ATSPI)
+
+#include "AccessibilityObject.h"
+
+namespace WebCore {
+
+bool AccessibilityObject::accessibilityIgnoreAttachment() const { return true; }
+AccessibilityObjectInclusion AccessibilityObject::accessibilityPlatformIncludesObject() const { return AccessibilityObjectInclusion::DefaultBehavior; }
+void AccessibilityObject::detachPlatformWrapper(AccessibilityDetachmentType) { }
+
+} // namespace WebCore
+
+#endif // ENABLE(ACCESSIBILITY) && !USE(ATK) && !USE(ATSPI)
diff --git a/Source/WebCore/bindings/js/WebCoreBuiltinNames.h b/Source/WebCore/bindings/js/WebCoreBuiltinNames.h
index 8a81d9d56d0184e9d1ebabf2ec00e2d6aba2aa60..7790111683bcf27b9683159752a6a4e9e8e15ed6 100644
--- a/Source/WebCore/bindings/js/WebCoreBuiltinNames.h
+++ b/Source/WebCore/bindings/js/WebCoreBuiltinNames.h
@@ -151,6 +151,8 @@ namespace WebCore {
macro(DataTransferItem) \
macro(DataTransferItemList) \
macro(DelayNode) \
+ macro(DeviceMotionEvent) \
+ macro(DeviceOrientationEvent) \
macro(DocumentTimeline) \
macro(DynamicsCompressorNode) \
macro(ExtendableEvent) \
diff --git a/Source/WebCore/css/MediaQueryEvaluator.cpp b/Source/WebCore/css/MediaQueryEvaluator.cpp
index 01d312c38e8e273099cf8d9b187ac704300f4c34..62570e7024cebae99b9d2eef711e70d867c7602f 100644
--- a/Source/WebCore/css/MediaQueryEvaluator.cpp
+++ b/Source/WebCore/css/MediaQueryEvaluator.cpp
@@ -856,7 +856,11 @@ static bool prefersContrastEvaluate(CSSValue* value, const CSSToLengthConversion
static bool prefersReducedMotionEvaluate(CSSValue* value, const CSSToLengthConversionData&, Frame& frame, MediaFeaturePrefix)
{
bool userPrefersReducedMotion = false;
-
+
+ std::optional<bool> reducedMotionOverride = frame.page()->useReducedMotionOverride();
+ if (reducedMotionOverride)
+ userPrefersReducedMotion = reducedMotionOverride.value();
+ else {
switch (frame.settings().forcedPrefersReducedMotionAccessibilityValue()) {
case ForcedAccessibilityValue::On:
userPrefersReducedMotion = true;
@@ -869,6 +873,7 @@ static bool prefersReducedMotionEvaluate(CSSValue* value, const CSSToLengthConve
#endif
break;
}
+ }
if (!value)
return userPrefersReducedMotion;
diff --git a/Source/WebCore/dom/DataTransfer.cpp b/Source/WebCore/dom/DataTransfer.cpp
index 1fd7ac8377fe0b502f396998b1675460542bd823..7452bfd809b3e5f5c489cf254ad1321eaec084dc 100644
--- a/Source/WebCore/dom/DataTransfer.cpp
+++ b/Source/WebCore/dom/DataTransfer.cpp
@@ -496,6 +496,14 @@ Ref<DataTransfer> DataTransfer::createForDrag(const Document& document)
return adoptRef(*new DataTransfer(StoreMode::ReadWrite, Pasteboard::createForDragAndDrop(PagePasteboardContext::create(document.pageID())), Type::DragAndDropData));
}
+#if PLATFORM(MAC)
+Ref<DataTransfer> DataTransfer::createForDrag(const Document& document, const String& pasteboardName)
+{
+ return adoptRef(*new DataTransfer(StoreMode::ReadWrite, makeUnique<Pasteboard>(PagePasteboardContext::create(document.pageID()), pasteboardName), Type::DragAndDropData));
+}
+#endif
+
+
Ref<DataTransfer> DataTransfer::createForDragStartEvent(const Document& document)
{
auto dataTransfer = adoptRef(*new DataTransfer(StoreMode::ReadWrite, makeUnique<StaticPasteboard>(), Type::DragAndDropData));
diff --git a/Source/WebCore/dom/DataTransfer.h b/Source/WebCore/dom/DataTransfer.h
index fbcdea3855b8a42ab5f69ba06839b78857abb1f1..a5686a98b117836df7656d4360056be8ef2a2878 100644
--- a/Source/WebCore/dom/DataTransfer.h
+++ b/Source/WebCore/dom/DataTransfer.h
@@ -90,6 +90,9 @@ public:
#if ENABLE(DRAG_SUPPORT)
static Ref<DataTransfer> createForDrag(const Document&);
+#if PLATFORM(MAC)
+ static Ref<DataTransfer> createForDrag(const Document&, const String& pasteboardName);
+#endif
static Ref<DataTransfer> createForDragStartEvent(const Document&);
static Ref<DataTransfer> createForDrop(const Document&, std::unique_ptr<Pasteboard>&&, OptionSet<DragOperation>, bool draggingFiles);
static Ref<DataTransfer> createForUpdatingDropTarget(const Document&, std::unique_ptr<Pasteboard>&&, OptionSet<DragOperation>, bool draggingFiles);
diff --git a/Source/WebCore/dom/DeviceMotionEvent.idl b/Source/WebCore/dom/DeviceMotionEvent.idl
index ea39a33a6250b4d10b20802f98aa9a5d57e63a7b..300a763508d311fd7b34cb3df3cc93080bb52930 100644
--- a/Source/WebCore/dom/DeviceMotionEvent.idl
+++ b/Source/WebCore/dom/DeviceMotionEvent.idl
@@ -25,6 +25,7 @@
[
Conditional=DEVICE_ORIENTATION,
+ EnabledBySetting=DeviceOrientationEventEnabled,
Exposed=Window
] interface DeviceMotionEvent : Event {
readonly attribute Acceleration? acceleration;
diff --git a/Source/WebCore/dom/DeviceOrientationEvent.idl b/Source/WebCore/dom/DeviceOrientationEvent.idl
index 9043052540b13d8120fb641de6337af46c3b36ef..a0f89e64b64640d2d4dbc14734868c4d4b03fc6f 100644
--- a/Source/WebCore/dom/DeviceOrientationEvent.idl
+++ b/Source/WebCore/dom/DeviceOrientationEvent.idl
@@ -25,6 +25,7 @@
[
Conditional=DEVICE_ORIENTATION,
+ EnabledBySetting=DeviceOrientationEventEnabled,
Exposed=Window
] interface DeviceOrientationEvent : Event {
readonly attribute unrestricted double? alpha;
diff --git a/Source/WebCore/dom/Document+PointerLock.idl b/Source/WebCore/dom/Document+PointerLock.idl
index 898027004b8553cac8130541026af70ffb5ee073..883d6a7df7a164625037cd8cee95c8fe4312b9e8 100644
--- a/Source/WebCore/dom/Document+PointerLock.idl
+++ b/Source/WebCore/dom/Document+PointerLock.idl
@@ -25,6 +25,7 @@
// https://w3c.github.io/pointerlock/#extensions-to-the-document-interface
[
+ EnabledBySetting=PointerLockEnabled,
Conditional=POINTER_LOCK
] partial interface Document {
[NotEnumerable] attribute EventHandler onpointerlockchange; // FIXME: Should be enumerable.
diff --git a/Source/WebCore/dom/DocumentOrShadowRoot+PointerLock.idl b/Source/WebCore/dom/DocumentOrShadowRoot+PointerLock.idl
index 9b8dbfc15ce078702321abcd6c0e636df7a60510..2956f7098e87af10ab8f5584b456ce9a6d432a20 100644
--- a/Source/WebCore/dom/DocumentOrShadowRoot+PointerLock.idl
+++ b/Source/WebCore/dom/DocumentOrShadowRoot+PointerLock.idl
@@ -25,6 +25,7 @@
// https://w3c.github.io/pointerlock/#extensions-to-the-documentorshadowroot-mixin
[
+ EnabledBySetting=PointerLockEnabled,
Conditional=POINTER_LOCK
] partial interface mixin DocumentOrShadowRoot {
readonly attribute Element? pointerLockElement;
diff --git a/Source/WebCore/dom/Element+PointerLock.idl b/Source/WebCore/dom/Element+PointerLock.idl
index f27718c1e2b8cd0a8075e556d4cdba7d9ae8fc54..2b61721594e5435845f3151e0de345e90eafc9ea 100644
--- a/Source/WebCore/dom/Element+PointerLock.idl
+++ b/Source/WebCore/dom/Element+PointerLock.idl
@@ -24,6 +24,7 @@
*/
[
+ EnabledBySetting=PointerLockEnabled,
Conditional=POINTER_LOCK
] partial interface Element {
undefined requestPointerLock();
diff --git a/Source/WebCore/dom/PointerEvent.cpp b/Source/WebCore/dom/PointerEvent.cpp
index 4433bc1c4a055d0a8386fd01e7e9d44b99425516..a8a43743370f3a00bed40a206ae98a5cc50bc7c7 100644
--- a/Source/WebCore/dom/PointerEvent.cpp
+++ b/Source/WebCore/dom/PointerEvent.cpp
@@ -114,4 +114,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 AtomString& 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(touchPointerEventType())
+ , 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 7542bab569d49879f0eb460520738b3da37116f6..17c92229cc596bc80a718911b74737d3575137e1 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 {
@@ -81,7 +83,7 @@ public:
static Ref<PointerEvent> create(const AtomString& type, short button, const MouseEvent&, PointerID, const String& pointerType);
static Ref<PointerEvent> create(const AtomString& 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 AtomString& type, const PlatformTouchEvent&, unsigned touchIndex, bool isPrimary, Ref<WindowProxy>&&);
#endif
@@ -121,7 +123,7 @@ private:
PointerEvent(const AtomString&, Init&&);
PointerEvent(const AtomString& type, short button, const MouseEvent&, PointerID, const String& pointerType);
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/editing/libwpe/EditorLibWPE.cpp b/Source/WebCore/editing/libwpe/EditorLibWPE.cpp
index b8a3148b067373dadfb43975473a18caeb266d51..504172cd327b38ffbd103259e86d374752ee3474 100644
--- a/Source/WebCore/editing/libwpe/EditorLibWPE.cpp
+++ b/Source/WebCore/editing/libwpe/EditorLibWPE.cpp
@@ -34,6 +34,7 @@
#include "NotImplemented.h"
#include "Pasteboard.h"
#include "Settings.h"
+#include "WebContentReader.h"
#include "markup.h"
namespace WebCore {
@@ -99,6 +100,14 @@ void Editor::platformPasteFont()
{
}
+RefPtr<DocumentFragment> Editor::webContentFromPasteboard(Pasteboard& pasteboard, const SimpleRange& context, bool allowPlainText, bool& chosePlainText)
+{
+ WebContentReader reader(*m_document.frame(), context, allowPlainText);
+ pasteboard.read(reader);
+ chosePlainText = reader.madeFragmentFromPlainText;
+ return WTFMove(reader.fragment);
+}
+
} // namespace WebCore
#endif // USE(LIBWPE)
diff --git a/Source/WebCore/html/FileInputType.cpp b/Source/WebCore/html/FileInputType.cpp
index e739d217b780fc475c78762f0b04b96f57fa7df1..2d8479d1695fc6239c9f55ab29371d5d10a62a5f 100644
--- a/Source/WebCore/html/FileInputType.cpp
+++ b/Source/WebCore/html/FileInputType.cpp
@@ -37,6 +37,7 @@
#include "HTMLNames.h"
#include "Icon.h"
#include "InputTypeNames.h"
+#include "InspectorInstrumentation.h"
#include "LocalizedStrings.h"
#include "MIMETypeRegistry.h"
#include "RenderFileUploadControl.h"
@@ -200,6 +201,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 23b330d6d57226dd0e3e2d19117520097f6baf7f..45531ee0561e8783f245f05f27cd51c175c52b70 100644
--- a/Source/WebCore/inspector/InspectorController.cpp
+++ b/Source/WebCore/inspector/InspectorController.cpp
@@ -285,6 +285,8 @@ void InspectorController::disconnectFrontend(FrontendChannel& frontendChannel)
// Unplug all instrumentations since they aren't needed now.
InspectorInstrumentation::unregisterInstrumentingAgents(m_instrumentingAgents.get());
+
+ m_pauseWhenShown = false;
}
m_inspectorClient->frontendCountChanged(m_frontendRouter->frontendCount());
@@ -304,6 +306,8 @@ void InspectorController::disconnectAllFrontends()
// The frontend should call setInspectorFrontendClient(nullptr) under closeWindow().
ASSERT(!m_inspectorFrontendClient);
+ m_pauseWhenShown = false;
+
if (!m_frontendRouter->hasFrontends())
return;
@@ -392,8 +396,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);
}
@@ -534,4 +538,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 4d5a3859ec6a46d07d45c80a3b5870ee2ef13d36..75eb55a024a6ae3892a4fedc535bf6a647cc3bc7 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();
+
// Testing support.
WEBCORE_EXPORT bool isUnderTest() const;
void setIsUnderTest(bool isUnderTest) { m_isUnderTest = isUnderTest; }
@@ -154,6 +158,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 1dcecd878be6ea8bcfee6765f9d38eec9afa51f5..38e224ae0abeee1987412fa2ee04b380a2dcc3cb 100644
--- a/Source/WebCore/inspector/InspectorInstrumentation.cpp
+++ b/Source/WebCore/inspector/InspectorInstrumentation.cpp
@@ -572,6 +572,13 @@ void InspectorInstrumentation::applyUserAgentOverrideImpl(InstrumentingAgents& i
pageAgent->applyUserAgentOverride(userAgent);
}
+void InspectorInstrumentation::applyPlatformOverrideImpl(InstrumentingAgents& instrumentingAgents, String& platform)
+{
+ if (auto* pageAgent = instrumentingAgents.enabledPageAgent())
+ pageAgent->applyPlatformOverride(platform);
+}
+
+
void InspectorInstrumentation::applyEmulatedMediaImpl(InstrumentingAgents& instrumentingAgents, String& media)
{
if (auto* pageAgent = instrumentingAgents.enabledPageAgent())
@@ -651,6 +658,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())
@@ -683,20 +696,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)
@@ -777,12 +787,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()) {
@@ -819,6 +823,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)
{
@@ -1301,6 +1311,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::willCheckNavigationPolicyImpl(InstrumentingAgents& instrumentingAgents, Frame& frame)
+{
+ if (InspectorPageAgent* pageAgent = instrumentingAgents.enabledPageAgent())
+ pageAgent->willCheckNavigationPolicy(frame);
+}
+
+void InspectorInstrumentation::didCheckNavigationPolicyImpl(InstrumentingAgents& instrumentingAgents, Frame& frame, bool cancel)
+{
+ if (InspectorPageAgent* pageAgent = instrumentingAgents.enabledPageAgent())
+ pageAgent->didCheckNavigationPolicy(frame, cancel);
+}
+
InstrumentingAgents& InspectorInstrumentation::instrumentingAgents(WorkerOrWorkletGlobalScope& globalScope)
{
return globalScope.inspectorController().m_instrumentingAgents;
@@ -1312,6 +1352,13 @@ InstrumentingAgents& InspectorInstrumentation::instrumentingAgents(Page& page)
return page.inspectorController().m_instrumentingAgents.get();
}
+void InspectorInstrumentation::maybeOverrideDefaultObjectInclusion(Page& page, AccessibilityObjectInclusion& inclusion) {
+ if (InspectorPageAgent* pageAgent = instrumentingAgents(page).enabledPageAgent()) {
+ if (pageAgent->doingAccessibilitySnapshot())
+ inclusion = AccessibilityObjectInclusion::DefaultBehavior;
+ }
+}
+
InstrumentingAgents* InspectorInstrumentation::instrumentingAgents(ScriptExecutionContext& context)
{
if (is<Document>(context))
diff --git a/Source/WebCore/inspector/InspectorInstrumentation.h b/Source/WebCore/inspector/InspectorInstrumentation.h
index 4b44709392749f24351f86ea97535b5eeee086b9..f4546646d1dcff84fafd740f36155f93ab755c3f 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 "CanvasBase.h"
#include "CanvasRenderingContext.h"
@@ -45,6 +46,7 @@
#include "HitTestResult.h"
#include "InspectorInstrumentationPublic.h"
#include "Page.h"
+#include "ResourceError.h"
#include "ResourceLoader.h"
#include "ResourceLoaderIdentifier.h"
#include "StorageArea.h"
@@ -77,6 +79,7 @@ class DOMWrapperWorld;
class Document;
class DocumentLoader;
class EventListener;
+class HTMLInputElement;
class HTTPHeaderMap;
class InspectorTimelineAgent;
class InstrumentingAgents;
@@ -189,6 +192,7 @@ public:
static void didRecalculateStyle(Document&);
static void didScheduleStyleRecalculation(Document&);
static void applyUserAgentOverride(Frame&, String&);
+ static void applyPlatformOverride(Frame&, String&);
static void applyEmulatedMedia(Frame&, String&);
static void flexibleBoxRendererBeganLayout(const RenderObject&);
@@ -201,6 +205,7 @@ public:
static void didReceiveData(Frame*, ResourceLoaderIdentifier, const SharedBuffer*, int encodedDataLength);
static void didFinishLoading(Frame*, DocumentLoader*, ResourceLoaderIdentifier, const NetworkLoadMetrics&, ResourceLoader*);
static void didFailLoading(Frame*, DocumentLoader*, ResourceLoaderIdentifier, const ResourceError&);
+ static void didReceiveMainResourceError(Frame&, const ResourceError&);
static void willSendRequest(WorkerOrWorkletGlobalScope&, ResourceLoaderIdentifier, ResourceRequest&);
static void didReceiveResourceResponse(WorkerOrWorkletGlobalScope&, ResourceLoaderIdentifier, const ResourceResponse&);
@@ -227,11 +232,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
@@ -318,6 +323,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 willCheckNavigationPolicy(Frame&);
+ static void didCheckNavigationPolicy(Frame&, bool cancel);
+
static void frontendCreated();
static void frontendDeleted();
static bool hasFrontends() { return InspectorInstrumentationPublic::hasFrontends(); }
@@ -334,6 +345,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&);
@@ -411,6 +424,7 @@ private:
static void didRecalculateStyleImpl(InstrumentingAgents&);
static void didScheduleStyleRecalculationImpl(InstrumentingAgents&, Document&);
static void applyUserAgentOverrideImpl(InstrumentingAgents&, String&);
+ static void applyPlatformOverrideImpl(InstrumentingAgents&, String&);
static void applyEmulatedMediaImpl(InstrumentingAgents&, String&);
static void flexibleBoxRendererBeganLayoutImpl(InstrumentingAgents&, const RenderObject&);
@@ -425,6 +439,7 @@ private:
static void didReceiveDataImpl(InstrumentingAgents&, ResourceLoaderIdentifier, const SharedBuffer*, int encodedDataLength);
static void didFinishLoadingImpl(InstrumentingAgents&, ResourceLoaderIdentifier, DocumentLoader*, const NetworkLoadMetrics&, ResourceLoader*);
static void didFailLoadingImpl(InstrumentingAgents&, ResourceLoaderIdentifier, DocumentLoader*, const ResourceError&);
+ static void didReceiveMainResourceErrorImpl(InstrumentingAgents&, Frame&, const ResourceError&);
static void willLoadXHRSynchronouslyImpl(InstrumentingAgents&);
static void didLoadXHRSynchronouslyImpl(InstrumentingAgents&);
static void scriptImportedImpl(InstrumentingAgents&, ResourceLoaderIdentifier, const String& sourceString);
@@ -435,11 +450,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
@@ -521,6 +536,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 willCheckNavigationPolicyImpl(InstrumentingAgents&, Frame&);
+ static void didCheckNavigationPolicyImpl(InstrumentingAgents&, Frame&, bool cancel);
+
static InstrumentingAgents& instrumentingAgents(Page&);
static InstrumentingAgents& instrumentingAgents(WorkerOrWorkletGlobalScope&);
@@ -1039,6 +1060,13 @@ inline void InspectorInstrumentation::applyUserAgentOverride(Frame& frame, Strin
applyUserAgentOverrideImpl(*agents, userAgent);
}
+inline void InspectorInstrumentation::applyPlatformOverride(Frame& frame, String& platform)
+{
+ FAST_RETURN_IF_NO_FRONTENDS(void());
+ if (auto* agents = instrumentingAgents(frame))
+ applyPlatformOverrideImpl(*agents, platform);
+}
+
inline void InspectorInstrumentation::applyEmulatedMedia(Frame& frame, String& media)
{
FAST_RETURN_IF_NO_FRONTENDS(void());
@@ -1141,6 +1169,13 @@ inline void InspectorInstrumentation::didFailLoading(WorkerOrWorkletGlobalScope&
didFailLoadingImpl(instrumentingAgents(globalScope), identifier, nullptr, error);
}
+inline void InspectorInstrumentation::didReceiveMainResourceError(Frame& frame, const ResourceError& error)
+{
+ FAST_RETURN_IF_NO_FRONTENDS(void());
+ if (auto* agents = instrumentingAgents(frame))
+ didReceiveMainResourceErrorImpl(*agents, frame, error);
+}
+
inline void InspectorInstrumentation::continueAfterXFrameOptionsDenied(Frame& frame, ResourceLoaderIdentifier identifier, DocumentLoader& loader, const ResourceResponse& response)
{
// Treat the same as didReceiveResponse.
@@ -1231,13 +1266,6 @@ inline void InspectorInstrumentation::frameDocumentUpdated(Frame& frame)
frameDocumentUpdatedImpl(*agents, frame);
}
-inline void InspectorInstrumentation::loaderDetachedFromFrame(Frame& frame, DocumentLoader& loader)
-{
- FAST_RETURN_IF_NO_FRONTENDS(void());
- if (auto* agents = instrumentingAgents(frame))
- loaderDetachedFromFrameImpl(*agents, loader);
-}
-
inline void InspectorInstrumentation::frameStartedLoading(Frame& frame)
{
FAST_RETURN_IF_NO_FRONTENDS(void());
@@ -1266,6 +1294,13 @@ inline void InspectorInstrumentation::frameClearedScheduledNavigation(Frame& fra
frameClearedScheduledNavigationImpl(*agents, frame);
}
+inline void InspectorInstrumentation::didNavigateWithinPage(Frame& frame)
+{
+ FAST_RETURN_IF_NO_FRONTENDS(void());
+ if (auto* agents = instrumentingAgents(frame))
+ didNavigateWithinPageImpl(*agents, frame);
+}
+
#if ENABLE(DARK_MODE_CSS) || HAVE(OS_DARK_MODE_SUPPORT)
inline void InspectorInstrumentation::defaultAppearanceDidChange(Page& page, bool useDarkAppearance)
{
@@ -1696,6 +1731,42 @@ inline void InspectorInstrumentation::renderLayerDestroyed(Page* page, const Ren
renderLayerDestroyedImpl(*agents, renderLayer);
}
+inline void InspectorInstrumentation::runOpenPanel(Frame* frame, HTMLInputElement* element, bool* intercept)
+{
+ FAST_RETURN_IF_NO_FRONTENDS(void());
+ if (auto* agents = instrumentingAgents(*frame))
+ runOpenPanelImpl(*agents, element, intercept);
+}
+
+inline void InspectorInstrumentation::frameAttached(Frame* frame)
+{
+ FAST_RETURN_IF_NO_FRONTENDS(void());
+ if (auto* agents = instrumentingAgents(frame))
+ frameAttachedImpl(*agents, *frame);
+}
+
+inline bool InspectorInstrumentation::shouldBypassCSP(ScriptExecutionContext* context)
+{
+ FAST_RETURN_IF_NO_FRONTENDS(false);
+ if (auto* agents = instrumentingAgents(context))
+ return shouldBypassCSPImpl(*agents);
+ return false;
+}
+
+inline void InspectorInstrumentation::willCheckNavigationPolicy(Frame& frame)
+{
+ FAST_RETURN_IF_NO_FRONTENDS(void());
+ if (auto* agents = instrumentingAgents(frame))
+ willCheckNavigationPolicyImpl(*agents, frame);
+}
+
+inline void InspectorInstrumentation::didCheckNavigationPolicy(Frame& frame, bool cancel)
+{
+ FAST_RETURN_IF_NO_FRONTENDS(void());
+ if (auto* agents = instrumentingAgents(frame))
+ didCheckNavigationPolicyImpl(*agents, frame, cancel);
+}
+
inline InstrumentingAgents* InspectorInstrumentation::instrumentingAgents(ScriptExecutionContext* context)
{
return context ? instrumentingAgents(*context) : nullptr;
diff --git a/Source/WebCore/inspector/UserGestureEmulationScope.h b/Source/WebCore/inspector/UserGestureEmulationScope.h
index 07103c35e0a9193a010a85cf2ea8017b2ad59212..338d158be5a6f35adc6817dc94d6084b8bc593c5 100644
--- a/Source/WebCore/inspector/UserGestureEmulationScope.h
+++ b/Source/WebCore/inspector/UserGestureEmulationScope.h
@@ -37,6 +37,7 @@ namespace WebCore {
class ChromeClient;
class Document;
class Page;
+class Document;
class UserGestureEmulationScope {
WTF_MAKE_NONCOPYABLE(UserGestureEmulationScope);
diff --git a/Source/WebCore/inspector/agents/InspectorDOMAgent.cpp b/Source/WebCore/inspector/agents/InspectorDOMAgent.cpp
index 19b82d5098da96d66489c84c5309fc7225b8a725..188b193b1cf67f2cd4cf35ad2313de57bd703670 100644
--- a/Source/WebCore/inspector/agents/InspectorDOMAgent.cpp
+++ b/Source/WebCore/inspector/agents/InspectorDOMAgent.cpp
@@ -62,12 +62,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"
@@ -95,12 +99,14 @@
#include "Pasteboard.h"
#include "PseudoElement.h"
#include "RenderGrid.h"
+#include "RenderLayer.h"
#include "RenderObject.h"
#include "RenderStyle.h"
#include "RenderStyleConstants.h"
#include "ScriptController.h"
#include "SelectorChecker.h"
#include "ShadowRoot.h"
+#include "SharedBuffer.h"
#include "StaticNodeList.h"
#include "StyleProperties.h"
#include "StyleResolver.h"
@@ -134,7 +140,8 @@ using namespace HTMLNames;
static const size_t maxTextSize = 10000;
static const UChar ellipsisUChar[] = { 0x2026, 0 };
-static std::optional<Color> parseColor(RefPtr<JSON::Object>&& colorObject)
+// static
+std::optional<Color> InspectorDOMAgent::parseColor(RefPtr<JSON::Object>&& colorObject)
{
if (!colorObject)
return std::nullopt;
@@ -153,7 +160,7 @@ static std::optional<Color> parseColor(RefPtr<JSON::Object>&& colorObject)
static Color parseConfigColor(const String& fieldName, JSON::Object& configObject)
{
- return parseColor(configObject.getObject(fieldName)).value_or(Color::transparentBlack);
+ return InspectorDOMAgent::parseColor(configObject.getObject(fieldName)).value_or(Color::transparentBlack);
}
static bool parseQuad(Ref<JSON::Array>&& quadArray, FloatQuad* quad)
@@ -451,6 +458,20 @@ Node* InspectorDOMAgent::assertNode(Protocol::ErrorString& errorString, Protocol
return node;
}
+Node* InspectorDOMAgent::assertNode(Protocol::ErrorString& errorString, std::optional<Protocol::DOM::NodeId>&& nodeId, const String& objectId)
+{
+ Node* node = nullptr;
+ if (nodeId) {
+ node = assertNode(errorString, *nodeId);
+ } else if (!!objectId) {
+ node = nodeForObjectId(objectId);
+ if (!node)
+ errorString = "Missing node for given objectId"_s;
+ } else
+ errorString = "Either nodeId or objectId must be specified"_s;
+ return node;
+}
+
Document* InspectorDOMAgent::assertDocument(Protocol::ErrorString& errorString, Protocol::DOM::NodeId nodeId)
{
Node* node = assertNode(errorString, nodeId);
@@ -1442,16 +1463,7 @@ Protocol::ErrorStringOr<void> InspectorDOMAgent::highlightSelector(Ref<JSON::Obj
Protocol::ErrorStringOr<void> InspectorDOMAgent::highlightNode(Ref<JSON::Object>&& highlightInspectorObject, std::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);
@@ -1689,15 +1701,136 @@ 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) {
+ std::optional<double> x = rect->getDouble("x"_s);
+ std::optional<double> y = rect->getDouble("y"_s);
+ std::optional<double> width = rect->getDouble("width"_s);
+ std::optional<double> height = rect->getDouble("height"_s);
+ if (!x || !y || !width || !height)
+ return makeUnexpected("Malformed rect"_s);
+
+ absoluteBounds.setX(absoluteBounds.x() + LayoutUnit(*x));
+ absoluteBounds.setY(absoluteBounds.y() + LayoutUnit(*y));
+ absoluteBounds.setWidth(LayoutUnit(std::max(*width, 1.0)));
+ absoluteBounds.setHeight(LayoutUnit(std::max(*height, 1.0)));
+ }
+ ScrollAlignment alignment = ScrollAlignment::alignCenterIfNeeded;
+ alignment.m_enableLegacyHorizontalVisibilityThreshold = false; // Disable RenderLayer minium horizontal scroll threshold.
+ renderer->scrollRectToVisible(absoluteBounds, insideFixed, { SelectionRevealMode::Reveal, alignment, alignment, ShouldAllowCrossOriginScrolling::Yes, ScrollBehavior::Instant });
+ return { };
+}
+
+Protocol::ErrorStringOr<Ref<JSON::ArrayOf<Protocol::DOM::Quad>>> InspectorDOMAgent::getContentQuads(const String& objectId)
+{
+ Node* node = nodeForObjectId(objectId);
+ if (!node)
+ return makeUnexpected("Node not found"_s);
+
+ 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(std::optional<Inspector::Protocol::DOM::NodeId>&& nodeId, const String& objectId, std::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);
@@ -2952,7 +3085,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, std::optional<int>&& contextId)
{
Document* document = &node->document();
if (auto* templateHost = document->templateDocumentHost())
@@ -2961,12 +3094,18 @@ RefPtr<Protocol::Runtime::RemoteObject> InspectorDOMAgent::resolveNode(Node* nod
if (!frame)
return nullptr;
- auto& globalObject = mainWorldGlobalObject(*frame);
- auto injectedScript = m_injectedScriptManager.injectedScriptFor(&globalObject);
+ InjectedScript injectedScript;
+ if (contextId) {
+ injectedScript = m_injectedScriptManager.injectedScriptForId(*contextId);
+ } else {
+ auto& globalObject = mainWorldGlobalObject(*frame);
+ injectedScript = m_injectedScriptManager.injectedScriptFor(&globalObject);
+ }
+
if (injectedScript.hasNoValue())
return nullptr;
- return injectedScript.wrapObject(nodeAsScriptValue(globalObject, node), objectGroup);
+ return injectedScript.wrapObject(nodeAsScriptValue(*injectedScript.globalObject(), node), objectGroup);
}
Node* InspectorDOMAgent::scriptValueAsNode(JSC::JSValue value)
@@ -2989,4 +3128,57 @@ Protocol::ErrorStringOr<void> InspectorDOMAgent::setAllowEditingUserAgentShadowT
return { };
}
+Protocol::ErrorStringOr<void> InspectorDOMAgent::setInputFiles(const String& objectId, RefPtr<JSON::Array>&& files, RefPtr<JSON::Array>&& paths) {
+ 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"_s)
+ return makeUnexpected("Not an input node"_s);
+
+ if (!(bool(files) ^ bool(paths)))
+ return makeUnexpected("Exactly one of files and paths should be specified"_s);
+
+ HTMLInputElement* element = static_cast<HTMLInputElement*>(node);
+ Vector<Ref<File>> fileObjects;
+ if (files) {
+ for (unsigned i = 0; i < files->length(); ++i) {
+ RefPtr<JSON::Value> item = files->get(i);
+ RefPtr<JSON::Object> obj = item->asObject();
+ if (!obj)
+ return makeUnexpected("Invalid file payload format"_s);
+
+ String name;
+ String type;
+ String data;
+ if (!obj->getString("name"_s, name) || !obj->getString("type"_s, type) || !obj->getString("data"_s, data))
+ return makeUnexpected("Invalid file payload format"_s);
+
+ std::optional<Vector<uint8_t>> buffer = base64Decode(data);
+ if (!buffer)
+ return makeUnexpected("Unable to decode given content"_s);
+
+ ScriptExecutionContext* context = element->scriptExecutionContext();
+ fileObjects.append(File::create(context, Blob::create(context, WTFMove(*buffer), type), name));
+ }
+ } else {
+ for (unsigned i = 0; i < paths->length(); ++i) {
+ RefPtr<JSON::Value> item = paths->get(i);
+ String path = item->asString();
+ if (path.isEmpty())
+ return makeUnexpected("Invalid file path"_s);
+
+ ScriptExecutionContext* context = element->scriptExecutionContext();
+ fileObjects.append(File::create(context, path));
+ }
+ }
+ 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 262829afb3c7151464de876368db47bf733e7f2e..fdcc8c44f3d24f13003b3eed3f2af79c9746896f 100644
--- a/Source/WebCore/inspector/agents/InspectorDOMAgent.h
+++ b/Source/WebCore/inspector/agents/InspectorDOMAgent.h
@@ -57,6 +57,7 @@ namespace WebCore {
class AXCoreObject;
class CharacterData;
+class Color;
class DOMEditor;
class Document;
class Element;
@@ -89,6 +90,7 @@ public:
static String toErrorString(Exception&&);
static String documentURLString(Document*);
+ static std::optional<Color> parseColor(RefPtr<JSON::Object>&&);
// We represent embedded doms as a part of the same hierarchy. Hence we treat children of frame owners differently.
// We also skip whitespace text nodes conditionally. Following methods encapsulate these specifics.
@@ -132,7 +134,7 @@ public:
Inspector::Protocol::ErrorStringOr<std::tuple<String /* searchId */, int /* resultCount */>> performSearch(const String& query, RefPtr<JSON::Array>&& nodeIds, std::optional<bool>&& caseSensitive);
Inspector::Protocol::ErrorStringOr<Ref<JSON::ArrayOf<Inspector::Protocol::DOM::NodeId>>> getSearchResults(const String& searchId, int fromIndex, int toIndex);
Inspector::Protocol::ErrorStringOr<void> discardSearchResults(const String& searchId);
- Inspector::Protocol::ErrorStringOr<Ref<Inspector::Protocol::Runtime::RemoteObject>> resolveNode(Inspector::Protocol::DOM::NodeId, const String& objectGroup);
+ Inspector::Protocol::ErrorStringOr<Ref<Inspector::Protocol::Runtime::RemoteObject>> resolveNode(std::optional<Inspector::Protocol::DOM::NodeId>&& nodeId, const String& objectId, std::optional<int>&& contextId, const String& objectGroup);
Inspector::Protocol::ErrorStringOr<Ref<JSON::ArrayOf<String>>> getAttributes(Inspector::Protocol::DOM::NodeId);
#if PLATFORM(IOS_FAMILY)
Inspector::Protocol::ErrorStringOr<void> setInspectModeEnabled(bool, RefPtr<JSON::Object>&& highlightConfig);
@@ -159,6 +161,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, RefPtr<JSON::Array>&& files, RefPtr<JSON::Array>&& paths);
// InspectorInstrumentation
Inspector::Protocol::DOM::NodeId identifierForNode(Node&);
@@ -200,7 +206,7 @@ public:
Node* nodeForId(Inspector::Protocol::DOM::NodeId);
Inspector::Protocol::DOM::NodeId boundNodeId(const Node*);
- RefPtr<Inspector::Protocol::Runtime::RemoteObject> resolveNode(Node*, const String& objectGroup);
+ RefPtr<Inspector::Protocol::Runtime::RemoteObject> resolveNode(Node*, const String& objectGroup, std::optional<int>&& contextId);
bool handleMousePress();
void mouseDidMoveOverElement(const HitTestResult&, unsigned modifierFlags);
void inspect(Node*);
@@ -212,12 +218,15 @@ public:
void reset();
Node* assertNode(Inspector::Protocol::ErrorString&, Inspector::Protocol::DOM::NodeId);
+ Node* assertNode(Inspector::Protocol::ErrorString&, std::optional<Inspector::Protocol::DOM::NodeId>&& nodeId, const String& objectId);
Element* assertElement(Inspector::Protocol::ErrorString&, Inspector::Protocol::DOM::NodeId);
Document* assertDocument(Inspector::Protocol::ErrorString&, Inspector::Protocol::DOM::NodeId);
RefPtr<JSC::Breakpoint> breakpointForEventListener(EventTarget&, const AtomString& eventType, EventListener&, bool capture);
Inspector::Protocol::DOM::EventListenerId idForEventListener(EventTarget&, const AtomString& eventType, EventListener&, bool capture);
+ Node* nodeForObjectId(const Inspector::Protocol::Runtime::RemoteObjectId&);
+
private:
#if ENABLE(VIDEO)
void mediaMetricsTimerFired();
@@ -246,7 +255,6 @@ private:
void processAccessibilityChildren(AXCoreObject&, JSON::ArrayOf<Inspector::Protocol::DOM::NodeId>&);
Node* nodeForPath(const String& path);
- Node* nodeForObjectId(const Inspector::Protocol::Runtime::RemoteObjectId&);
void discardBindings();
diff --git a/Source/WebCore/inspector/agents/InspectorNetworkAgent.cpp b/Source/WebCore/inspector/agents/InspectorNetworkAgent.cpp
index 921a2ea05ea6a21751c4f80f41df48d2a9b21462..c36e22d1c5e6594ba46af90e6dbaf3dbb35bae46 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"
@@ -58,6 +59,7 @@
#include "MIMETypeRegistry.h"
#include "MemoryCache.h"
#include "NetworkResourcesData.h"
+#include "NetworkStateNotifier.h"
#include "Page.h"
#include "PlatformStrategies.h"
#include "ProgressTracker.h"
@@ -335,8 +337,8 @@ static Ref<Protocol::Network::Request> buildObjectForResourceRequest(const Resou
.release();
if (request.httpBody() && !request.httpBody()->isEmpty()) {
- auto bytes = request.httpBody()->flatten();
- requestObject->setPostData(String::fromUTF8WithLatin1Fallback(bytes.data(), bytes.size()));
+ Vector<uint8_t> bytes = request.httpBody()->flatten();
+ requestObject->setPostData(base64EncodeToString(bytes));
}
if (resourceLoader) {
@@ -389,6 +391,8 @@ RefPtr<Protocol::Network::Response> InspectorNetworkAgent::buildObjectForResourc
.setSource(responseSource(response.source()))
.release();
+ responseObject->setRequestHeaders(buildObjectForHeaders(response.m_httpRequestHeaderFields));
+
if (resourceLoader) {
auto* metrics = response.deprecatedNetworkLoadMetricsOrNull();
responseObject->setTiming(buildObjectForTiming(metrics ? *metrics : NetworkLoadMetrics::emptyMetrics(), *resourceLoader));
@@ -950,6 +954,7 @@ void InspectorNetworkAgent::continuePendingResponses()
Protocol::ErrorStringOr<void> InspectorNetworkAgent::setExtraHTTPHeaders(Ref<JSON::Object>&& headers)
{
+ m_extraRequestHeaders.clear();
for (auto& entry : headers.get()) {
auto stringValue = entry.value->asString();
if (!!stringValue)
@@ -1230,6 +1235,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));
@@ -1329,14 +1337,23 @@ Protocol::ErrorStringOr<void> InspectorNetworkAgent::interceptRequestWithRespons
response.setHTTPStatusCode(status);
response.setHTTPStatusText(AtomString { statusText });
HTTPHeaderMap explicitHeaders;
+ String setCookieValue;
for (auto& header : headers.get()) {
auto headerValue = header.value->asString();
- if (!!headerValue)
+ if (equalIgnoringASCIICase(header.key, "Set-Cookie"_s))
+ setCookieValue = headerValue;
+ else if (!!headerValue)
explicitHeaders.add(header.key, headerValue);
+
}
response.setHTTPHeaderFields(WTFMove(explicitHeaders));
response.setHTTPHeaderField(HTTPHeaderName::ContentType, response.mimeType());
- loader->didReceiveResponse(response, [loader, buffer = data.releaseNonNull()]() {
+
+ auto* frame = loader->frame();
+ if (!setCookieValue.isEmpty() && frame && frame->page())
+ frame->page()->cookieJar().setCookieFromResponse(*loader.get(), setCookieValue);
+
+ loader->didReceiveResponse(response, [loader, buffer = data.releaseNonNull()]() mutable {
if (loader->reachedTerminalState())
return;
@@ -1384,6 +1401,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/"_s)
diff --git a/Source/WebCore/inspector/agents/InspectorNetworkAgent.h b/Source/WebCore/inspector/agents/InspectorNetworkAgent.h
index 7f3f2986e0d48cb9927d2042211e336b94e05253..8fba37e07c7b723cecd1bf74bb28015966cd775c 100644
--- a/Source/WebCore/inspector/agents/InspectorNetworkAgent.h
+++ b/Source/WebCore/inspector/agents/InspectorNetworkAgent.h
@@ -34,6 +34,8 @@
#include "InspectorInstrumentation.h"
#include "InspectorPageAgent.h"
#include "InspectorWebAgentBase.h"
+#include "ResourceError.h"
+#include "SharedBuffer.h"
#include "WebSocket.h"
#include <JavaScriptCore/InspectorBackendDispatchers.h>
#include <JavaScriptCore/InspectorFrontendDispatchers.h>
@@ -98,6 +100,7 @@ public:
Inspector::Protocol::ErrorStringOr<void> interceptWithResponse(const Inspector::Protocol::Network::RequestId&, const String& content, bool base64Encoded, const String& mimeType, std::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 a6e415a9bf47e0f4c98b9f375b3195df287fe67b..c30bc2a8972cb58fa433ae4004afdc31c4197c9e 100644
--- a/Source/WebCore/inspector/agents/InspectorPageAgent.cpp
+++ b/Source/WebCore/inspector/agents/InspectorPageAgent.cpp
@@ -32,20 +32,28 @@
#include "config.h"
#include "InspectorPageAgent.h"
+#include "AXObjectCache.h"
+#include "BackForwardController.h"
#include "CachedResource.h"
#include "CachedResourceLoader.h"
+#include "CompositionHighlight.h"
#include "Cookie.h"
#include "CookieJar.h"
+#include "CustomHeaderFields.h"
#include "DOMWrapperWorld.h"
#include "DocumentInlines.h"
#include "DocumentLoader.h"
+#include "Editor.h"
#include "ElementInlines.h"
+#include "FocusController.h"
#include "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"
@@ -56,19 +64,29 @@
#include "MIMETypeRegistry.h"
#include "MemoryCache.h"
#include "Page.h"
+#include "PageRuntimeAgent.h"
#include "RenderObject.h"
#include "RenderTheme.h"
+#include "RuntimeEnabledFeatures.h"
+#include "SimpleRange.h"
#include "ScriptController.h"
#include "ScriptSourceCode.h"
#include "SecurityOrigin.h"
#include "Settings.h"
#include "StyleScope.h"
#include <pal/text/TextEncoding.h>
+#include "TextIterator.h"
+#include "TypingCommand.h"
#include "UserGestureIndicator.h"
#include <JavaScriptCore/ContentSearchUtilities.h>
#include <JavaScriptCore/IdentifiersFactory.h>
+#include <JavaScriptCore/InjectedScriptManager.h>
#include <JavaScriptCore/RegularExpression.h>
+#include <wtf/DateMath.h>
#include <wtf/ListHashSet.h>
+#include <wtf/NeverDestroyed.h>
+#include <wtf/Ref.h>
+#include <wtf/RefPtr.h>
#include <wtf/Stopwatch.h>
#include <wtf/text/Base64.h>
#include <wtf/text/StringBuilder.h>
@@ -81,11 +99,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 uint8_t* buffer, unsigned size, const String& textEncodingName, String* result)
{
if (buffer) {
@@ -326,6 +348,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)
{
@@ -357,12 +380,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)
@@ -411,6 +442,22 @@ Protocol::ErrorStringOr<void> InspectorPageAgent::reload(std::optional<bool>&& i
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)
{
Frame& frame = m_inspectedPage.mainFrame();
@@ -432,6 +479,13 @@ Protocol::ErrorStringOr<void> InspectorPageAgent::overrideUserAgent(const String
return { };
}
+Protocol::ErrorStringOr<void> InspectorPageAgent::overridePlatform(const String& value)
+{
+ m_platformOverride = value;
+
+ return { };
+}
+
Protocol::ErrorStringOr<void> InspectorPageAgent::overrideSetting(Protocol::Page::Setting setting, std::optional<bool>&& value)
{
auto& inspectedPageSettings = m_inspectedPage.settings();
@@ -445,6 +499,12 @@ Protocol::ErrorStringOr<void> InspectorPageAgent::overrideSetting(Protocol::Page
inspectedPageSettings.setAuthorAndUserStylesEnabledInspectorOverride(value);
return { };
+#if ENABLE(DEVICE_ORIENTATION)
+ case Protocol::Page::Setting::DeviceOrientationEventEnabled:
+ inspectedPageSettings.setDeviceOrientationEventEnabled(value.value_or(false));
+ return { };
+#endif
+
case Protocol::Page::Setting::ICECandidateFilteringEnabled:
inspectedPageSettings.setICECandidateFilteringEnabledInspectorOverride(value);
return { };
@@ -470,6 +530,36 @@ Protocol::ErrorStringOr<void> InspectorPageAgent::overrideSetting(Protocol::Page
inspectedPageSettings.setNeedsSiteSpecificQuirksInspectorOverride(value);
return { };
+#if ENABLE(NOTIFICATIONS)
+ case Protocol::Page::Setting::NotificationsEnabled:
+ inspectedPageSettings.setNotificationsEnabled(value.value_or(false));
+ return { };
+#endif
+
+#if ENABLE(FULLSCREEN_API)
+ case Protocol::Page::Setting::FullScreenEnabled:
+ inspectedPageSettings.setFullScreenEnabled(value.value_or(false));
+ return { };
+#endif
+
+#if ENABLE(INPUT_TYPE_MONTH)
+ case Protocol::Page::Setting::InputTypeMonthEnabled:
+ inspectedPageSettings.setInputTypeMonthEnabled(value.value_or(false));
+ return { };
+#endif
+
+#if ENABLE(INPUT_TYPE_WEEK)
+ case Protocol::Page::Setting::InputTypeWeekEnabled:
+ inspectedPageSettings.setInputTypeWeekEnabled(value.value_or(false));
+ return { };
+#endif
+
+#if ENABLE(POINTER_LOCK)
+ case Protocol::Page::Setting::PointerLockEnabled:
+ inspectedPageSettings.setPointerLockEnabled(value.value_or(false));
+ return { };
+#endif
+
case Protocol::Page::Setting::ScriptEnabled:
inspectedPageSettings.setScriptEnabledInspectorOverride(value);
return { };
@@ -482,6 +572,12 @@ Protocol::ErrorStringOr<void> InspectorPageAgent::overrideSetting(Protocol::Page
inspectedPageSettings.setShowRepaintCounterInspectorOverride(value);
return { };
+#if ENABLE(MEDIA_STREAM)
+ case Protocol::Page::Setting::SpeechRecognitionEnabled:
+ inspectedPageSettings.setSpeechRecognitionEnabled(value.value_or(false));
+ return { };
+#endif
+
case Protocol::Page::Setting::WebRTCEncryptionEnabled:
inspectedPageSettings.setWebRTCEncryptionEnabledInspectorOverride(value);
return { };
@@ -702,9 +798,13 @@ Protocol::ErrorStringOr<std::tuple<String, bool /* base64Encoded */>> InspectorP
return { { content, base64Encoded } };
}
-Protocol::ErrorStringOr<void> InspectorPageAgent::setBootstrapScript(const String& source)
+Protocol::ErrorStringOr<void> InspectorPageAgent::setBootstrapScript(const String& source, const String& worldName)
{
- m_bootstrapScript = source;
+ String key = worldName.isNull() ? emptyString() : worldName;
+ if (source.isEmpty())
+ m_worldNameToBootstrapScript.remove(key);
+ else
+ m_worldNameToBootstrapScript.set(key, source);
return { };
}
@@ -807,15 +907,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)
@@ -823,13 +924,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)
@@ -841,20 +952,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)
@@ -865,11 +974,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));
@@ -890,6 +994,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)
{
@@ -899,13 +1009,22 @@ void InspectorPageAgent::defaultAppearanceDidChange(bool useDarkAppearance)
void InspectorPageAgent::didClearWindowObjectInWorld(Frame& frame, DOMWrapperWorld& world)
{
- if (&world != &mainThreadNormalWorld())
+ if (m_worldNameToBootstrapScript.isEmpty())
return;
- if (m_bootstrapScript.isEmpty())
+ if (world.name().isEmpty() && &world != &mainThreadNormalWorld())
+ return;
+
+ String worldName = world.name();
+ // Null string cannot be used as a key.
+ if (worldName.isNull())
+ worldName = emptyString();
+
+ if (!m_worldNameToBootstrapScript.contains(worldName))
return;
- frame.script().evaluateIgnoringException(ScriptSourceCode(m_bootstrapScript, URL { "web-inspector://bootstrap.js"_str }));
+ String bootstrapScript = m_worldNameToBootstrapScript.get(worldName);
+ frame.script().evaluateInWorldIgnoringException(ScriptSourceCode(bootstrapScript, URL { "web-inspector://bootstrap.js"_str }), world);
}
void InspectorPageAgent::didPaint(RenderObject& renderer, const LayoutRect& rect)
@@ -949,6 +1068,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& globalObject = mainWorldGlobalObject(*frame);
+ auto injectedScript = m_injectedScriptManager.injectedScriptFor(&globalObject);
+ if (injectedScript.hasNoValue())
+ return;
+
+ auto object = injectedScript.wrapObject(InspectorDOMAgent::nodeAsScriptValue(globalObject, element), WTF::String());
+ if (!object)
+ return;
+
+ m_frontendDispatcher->fileChooserOpened(frameId(frame), object.releaseNonNull());
+}
+
+void InspectorPageAgent::frameAttached(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::willCheckNavigationPolicy(Frame& frame)
+{
+ m_frontendDispatcher->willCheckNavigationPolicy(frameId(&frame));
+}
+
+void InspectorPageAgent::didCheckNavigationPolicy(Frame& frame, bool cancel)
+{
+ m_frontendDispatcher->didCheckNavigationPolicy(frameId(&frame), cancel);
+}
+
Ref<Protocol::Page::Frame> InspectorPageAgent::buildObjectForFrame(Frame* frame)
{
ASSERT_ARG(frame, frame);
@@ -1062,6 +1227,12 @@ void InspectorPageAgent::applyUserAgentOverride(String& userAgent)
userAgent = m_userAgentOverride;
}
+void InspectorPageAgent::applyPlatformOverride(String& platform)
+{
+ if (!m_platformOverride.isEmpty())
+ platform = m_platformOverride;
+}
+
void InspectorPageAgent::applyEmulatedMedia(String& media)
{
if (!m_emulatedMedia.isEmpty())
@@ -1085,11 +1256,13 @@ Protocol::ErrorStringOr<String> InspectorPageAgent::snapshotNode(Protocol::DOM::
return snapshot->toDataURL("image/png"_s, std::nullopt, PreserveResolution::Yes);
}
-Protocol::ErrorStringOr<String> InspectorPageAgent::snapshotRect(int x, int y, int width, int height, Protocol::Page::CoordinateSystem coordinateSystem)
+Protocol::ErrorStringOr<String> InspectorPageAgent::snapshotRect(int x, int y, int width, int height, Protocol::Page::CoordinateSystem coordinateSystem, std::optional<bool>&& omitDeviceScaleFactor)
{
SnapshotOptions options { { }, PixelFormat::BGRA8, DestinationColorSpace::SRGB() };
if (coordinateSystem == Protocol::Page::CoordinateSystem::Viewport)
options.flags.add(SnapshotFlags::InViewCoordinates);
+ if (omitDeviceScaleFactor.has_value() && *omitDeviceScaleFactor)
+ options.flags.add(SnapshotFlags::OmitDeviceScaleFactor);
IntRect rectangle(x, y, width, height);
auto snapshot = snapshotFrameRect(m_inspectedPage.mainFrame(), rectangle, WTFMove(options));
@@ -1100,6 +1273,47 @@ Protocol::ErrorStringOr<String> InspectorPageAgent::snapshotRect(int x, int y, i
return snapshot->toDataURL("image/png"_s, std::nullopt, PreserveResolution::Yes);
}
+Protocol::ErrorStringOr<void> InspectorPageAgent::setForcedReducedMotion(std::optional<Protocol::Page::ReducedMotion>&& reducedMotion)
+{
+ if (!reducedMotion) {
+ m_inspectedPage.setUseReducedMotionOverride(std::nullopt);
+ return { };
+ }
+
+ switch (*reducedMotion) {
+ case Protocol::Page::ReducedMotion::Reduce:
+ m_inspectedPage.setUseReducedMotionOverride(true);
+ return { };
+ case Protocol::Page::ReducedMotion::NoPreference:
+ m_inspectedPage.setUseReducedMotionOverride(false);
+ return { };
+ }
+
+ ASSERT_NOT_REACHED();
+ return { };
+}
+
+Protocol::ErrorStringOr<void> InspectorPageAgent::setTimeZone(const String& timeZone)
+{
+ bool success = WTF::setTimeZoneOverride(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()
{
@@ -1112,7 +1326,6 @@ Protocol::ErrorStringOr<String> InspectorPageAgent::archive()
}
#endif
-#if !PLATFORM(COCOA)
Protocol::ErrorStringOr<void> InspectorPageAgent::setScreenSizeOverride(std::optional<int>&& width, std::optional<int>&& height)
{
if (width.has_value() != height.has_value())
@@ -1127,6 +1340,630 @@ Protocol::ErrorStringOr<void> InspectorPageAgent::setScreenSizeOverride(std::opt
m_inspectedPage.mainFrame().setOverrideScreenSize(FloatSize(width.value_or(0), height.value_or(0)));
return { };
}
+
+Protocol::ErrorStringOr<void> InspectorPageAgent::insertText(const String& text)
+{
+ UserGestureIndicator indicator { ProcessingUserGesture };
+ Frame& frame = m_inspectedPage.focusController().focusedOrMainFrame();
+
+ if (frame.editor().hasComposition()) {
+ frame.editor().confirmComposition(text);
+ } else {
+ Document* focusedDocument = frame.document();
+ TypingCommand::insertText(*focusedDocument, text, 0);
+ }
+ return { };
+}
+
+Protocol::ErrorStringOr<void> InspectorPageAgent::setComposition(const String& text, int selectionStart, int selectionLength, std::optional<int>&& replacementStart, std::optional<int>&& replacementLength)
+{
+ Frame& frame = m_inspectedPage.focusController().focusedOrMainFrame();
+
+ UserGestureIndicator indicator { ProcessingUserGesture };
+
+ if (!frame.selection().selection().isContentEditable())
+ return { };
+ if (replacementStart) {
+ WebCore::CharacterRange range { static_cast<uint64_t>(*replacementStart), replacementLength ? static_cast<uint64_t>(*replacementLength) : 0 };
+ auto* element = frame.selection().rootEditableElementOrDocumentElement();
+ if (element)
+ frame.selection().setSelection(VisibleSelection(resolveCharacterRange(makeRangeSelectingNodeContents(*element), range)));
+ }
+ frame.editor().setComposition(text, { }, { }, static_cast<uint64_t>(selectionStart), selectionStart + selectionLength);
+ 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"_s;
+ case AccessibilityRole::Application:
+ return "Application"_s;
+ case AccessibilityRole::ApplicationAlert:
+ return "ApplicationAlert"_s;
+ case AccessibilityRole::ApplicationAlertDialog:
+ return "ApplicationAlertDialog"_s;
+ case AccessibilityRole::ApplicationDialog:
+ return "ApplicationDialog"_s;
+ case AccessibilityRole::ApplicationGroup:
+ return "ApplicationGroup"_s;
+ case AccessibilityRole::ApplicationLog:
+ return "ApplicationLog"_s;
+ case AccessibilityRole::ApplicationMarquee:
+ return "ApplicationMarquee"_s;
+ case AccessibilityRole::ApplicationStatus:
+ return "ApplicationStatus"_s;
+ case AccessibilityRole::ApplicationTextGroup:
+ return "ApplicationTextGroup"_s;
+ case AccessibilityRole::ApplicationTimer:
+ return "ApplicationTimer"_s;
+ case AccessibilityRole::Audio:
+ return "Audio"_s;
+ case AccessibilityRole::Blockquote:
+ return "Blockquote"_s;
+ case AccessibilityRole::Browser:
+ return "Browser"_s;
+ case AccessibilityRole::BusyIndicator:
+ return "BusyIndicator"_s;
+ case AccessibilityRole::Button:
+ return "Button"_s;
+ case AccessibilityRole::Canvas:
+ return "Canvas"_s;
+ case AccessibilityRole::Caption:
+ return "Caption"_s;
+ case AccessibilityRole::Cell:
+ return "Cell"_s;
+ case AccessibilityRole::CheckBox:
+ return "CheckBox"_s;
+ case AccessibilityRole::ColorWell:
+ return "ColorWell"_s;
+ case AccessibilityRole::Column:
+ return "Column"_s;
+ case AccessibilityRole::ColumnHeader:
+ return "ColumnHeader"_s;
+ case AccessibilityRole::ComboBox:
+ return "ComboBox"_s;
+ case AccessibilityRole::Definition:
+ return "Definition"_s;
+ case AccessibilityRole::Deletion:
+ return "Deletion"_s;
+ case AccessibilityRole::DescriptionList:
+ return "DescriptionList"_s;
+ case AccessibilityRole::DescriptionListTerm:
+ return "DescriptionListTerm"_s;
+ case AccessibilityRole::DescriptionListDetail:
+ return "DescriptionListDetail"_s;
+ case AccessibilityRole::Details:
+ return "Details"_s;
+ case AccessibilityRole::Directory:
+ return "Directory"_s;
+ case AccessibilityRole::DisclosureTriangle:
+ return "DisclosureTriangle"_s;
+ case AccessibilityRole::Div:
+ return "Div"_s;
+ case AccessibilityRole::Document:
+ return "Document"_s;
+ case AccessibilityRole::DocumentArticle:
+ return "DocumentArticle"_s;
+ case AccessibilityRole::DocumentMath:
+ return "DocumentMath"_s;
+ case AccessibilityRole::DocumentNote:
+ return "DocumentNote"_s;
+ case AccessibilityRole::Drawer:
+ return "Drawer"_s;
+ case AccessibilityRole::EditableText:
+ return "EditableText"_s;
+ case AccessibilityRole::Feed:
+ return "Feed"_s;
+ case AccessibilityRole::Figure:
+ return "Figure"_s;
+ case AccessibilityRole::Footer:
+ return "Footer"_s;
+ case AccessibilityRole::Footnote:
+ return "Footnote"_s;
+ case AccessibilityRole::Form:
+ return "Form"_s;
+ case AccessibilityRole::GraphicsDocument:
+ return "GraphicsDocument"_s;
+ case AccessibilityRole::GraphicsObject:
+ return "GraphicsObject"_s;
+ case AccessibilityRole::GraphicsSymbol:
+ return "GraphicsSymbol"_s;
+ case AccessibilityRole::Grid:
+ return "Grid"_s;
+ case AccessibilityRole::GridCell:
+ return "GridCell"_s;
+ case AccessibilityRole::Group:
+ return "Group"_s;
+ case AccessibilityRole::GrowArea:
+ return "GrowArea"_s;
+ case AccessibilityRole::Heading:
+ return "Heading"_s;
+ case AccessibilityRole::HelpTag:
+ return "HelpTag"_s;
+ case AccessibilityRole::HorizontalRule:
+ return "HorizontalRule"_s;
+ case AccessibilityRole::Ignored:
+ return "Ignored"_s;
+ case AccessibilityRole::Inline:
+ return "Inline"_s;
+ case AccessibilityRole::Image:
+ return "Image"_s;
+ case AccessibilityRole::ImageMap:
+ return "ImageMap"_s;
+ case AccessibilityRole::ImageMapLink:
+ return "ImageMapLink"_s;
+ case AccessibilityRole::Incrementor:
+ return "Incrementor"_s;
+ case AccessibilityRole::Insertion:
+ return "Insertion"_s;
+ case AccessibilityRole::Label:
+ return "Label"_s;
+ case AccessibilityRole::LandmarkBanner:
+ return "LandmarkBanner"_s;
+ case AccessibilityRole::LandmarkComplementary:
+ return "LandmarkComplementary"_s;
+ case AccessibilityRole::LandmarkContentInfo:
+ return "LandmarkContentInfo"_s;
+ case AccessibilityRole::LandmarkDocRegion:
+ return "LandmarkDocRegion"_s;
+ case AccessibilityRole::LandmarkMain:
+ return "LandmarkMain"_s;
+ case AccessibilityRole::LandmarkNavigation:
+ return "LandmarkNavigation"_s;
+ case AccessibilityRole::LandmarkRegion:
+ return "LandmarkRegion"_s;
+ case AccessibilityRole::LandmarkSearch:
+ return "LandmarkSearch"_s;
+ case AccessibilityRole::Legend:
+ return "Legend"_s;
+ case AccessibilityRole::Link:
+ return "Link"_s;
+ case AccessibilityRole::List:
+ return "List"_s;
+ case AccessibilityRole::ListBox:
+ return "ListBox"_s;
+ case AccessibilityRole::ListBoxOption:
+ return "ListBoxOption"_s;
+ case AccessibilityRole::ListItem:
+ return "ListItem"_s;
+ case AccessibilityRole::ListMarker:
+ return "ListMarker"_s;
+ case AccessibilityRole::Mark:
+ return "Mark"_s;
+ case AccessibilityRole::MathElement:
+ return "MathElement"_s;
+ case AccessibilityRole::Matte:
+ return "Matte"_s;
+ case AccessibilityRole::Menu:
+ return "Menu"_s;
+ case AccessibilityRole::MenuBar:
+ return "MenuBar"_s;
+ case AccessibilityRole::MenuButton:
+ return "MenuButton"_s;
+ case AccessibilityRole::MenuItem:
+ return "MenuItem"_s;
+ case AccessibilityRole::MenuItemCheckbox:
+ return "MenuItemCheckbox"_s;
+ case AccessibilityRole::MenuItemRadio:
+ return "MenuItemRadio"_s;
+ case AccessibilityRole::MenuListPopup:
+ return "MenuListPopup"_s;
+ case AccessibilityRole::MenuListOption:
+ return "MenuListOption"_s;
+ case AccessibilityRole::Meter:
+ return "Meter"_s;
+ case AccessibilityRole::Model:
+ return "Model"_s;
+ case AccessibilityRole::Outline:
+ return "Outline"_s;
+ case AccessibilityRole::Paragraph:
+ return "Paragraph"_s;
+ case AccessibilityRole::PopUpButton:
+ return "PopUpButton"_s;
+ case AccessibilityRole::Pre:
+ return "Pre"_s;
+ case AccessibilityRole::Presentational:
+ return "Presentational"_s;
+ case AccessibilityRole::ProgressIndicator:
+ return "ProgressIndicator"_s;
+ case AccessibilityRole::RadioButton:
+ return "RadioButton"_s;
+ case AccessibilityRole::RadioGroup:
+ return "RadioGroup"_s;
+ case AccessibilityRole::RowHeader:
+ return "RowHeader"_s;
+ case AccessibilityRole::Row:
+ return "Row"_s;
+ case AccessibilityRole::RowGroup:
+ return "RowGroup"_s;
+ case AccessibilityRole::RubyBase:
+ return "RubyBase"_s;
+ case AccessibilityRole::RubyBlock:
+ return "RubyBlock"_s;
+ case AccessibilityRole::RubyInline:
+ return "RubyInline"_s;
+ case AccessibilityRole::RubyRun:
+ return "RubyRun"_s;
+ case AccessibilityRole::RubyText:
+ return "RubyText"_s;
+ case AccessibilityRole::Ruler:
+ return "Ruler"_s;
+ case AccessibilityRole::RulerMarker:
+ return "RulerMarker"_s;
+ case AccessibilityRole::ScrollArea:
+ return "ScrollArea"_s;
+ case AccessibilityRole::ScrollBar:
+ return "ScrollBar"_s;
+ case AccessibilityRole::SearchField:
+ return "SearchField"_s;
+ case AccessibilityRole::Sheet:
+ return "Sheet"_s;
+ case AccessibilityRole::Slider:
+ return "Slider"_s;
+ case AccessibilityRole::SliderThumb:
+ return "SliderThumb"_s;
+ case AccessibilityRole::SpinButton:
+ return "SpinButton"_s;
+ case AccessibilityRole::SpinButtonPart:
+ return "SpinButtonPart"_s;
+ case AccessibilityRole::SplitGroup:
+ return "SplitGroup"_s;
+ case AccessibilityRole::Splitter:
+ return "Splitter"_s;
+ case AccessibilityRole::StaticText:
+ return "StaticText"_s;
+ case AccessibilityRole::Subscript:
+ return "Subscript"_s;
+ case AccessibilityRole::Summary:
+ return "Summary"_s;
+ case AccessibilityRole::Superscript:
+ return "Superscript"_s;
+ case AccessibilityRole::Switch:
+ return "Switch"_s;
+ case AccessibilityRole::SystemWide:
+ return "SystemWide"_s;
+ case AccessibilityRole::SVGRoot:
+ return "SVGRoot"_s;
+ case AccessibilityRole::SVGText:
+ return "SVGText"_s;
+ case AccessibilityRole::SVGTSpan:
+ return "SVGTSpan"_s;
+ case AccessibilityRole::SVGTextPath:
+ return "SVGTextPath"_s;
+ case AccessibilityRole::TabGroup:
+ return "TabGroup"_s;
+ case AccessibilityRole::TabList:
+ return "TabList"_s;
+ case AccessibilityRole::TabPanel:
+ return "TabPanel"_s;
+ case AccessibilityRole::Tab:
+ return "Tab"_s;
+ case AccessibilityRole::Table:
+ return "Table"_s;
+ case AccessibilityRole::TableHeaderContainer:
+ return "TableHeaderContainer"_s;
+ case AccessibilityRole::TextArea:
+ return "TextArea"_s;
+ case AccessibilityRole::TextGroup:
+ return "TextGroup"_s;
+ case AccessibilityRole::Term:
+ return "Term"_s;
+ case AccessibilityRole::Time:
+ return "Time"_s;
+ case AccessibilityRole::Tree:
+ return "Tree"_s;
+ case AccessibilityRole::TreeGrid:
+ return "TreeGrid"_s;
+ case AccessibilityRole::TreeItem:
+ return "TreeItem"_s;
+ case AccessibilityRole::TextField:
+ return "TextField"_s;
+ case AccessibilityRole::ToggleButton:
+ return "ToggleButton"_s;
+ case AccessibilityRole::Toolbar:
+ return "Toolbar"_s;
+ case AccessibilityRole::Unknown:
+ return "Unknown"_s;
+ case AccessibilityRole::UserInterfaceTooltip:
+ return "UserInterfaceTooltip"_s;
+ case AccessibilityRole::ValueIndicator:
+ return "ValueIndicator"_s;
+ case AccessibilityRole::Video:
+ return "Video"_s;
+ case AccessibilityRole::WebApplication:
+ return "WebApplication"_s;
+ case AccessibilityRole::WebArea:
+ return "WebArea"_s;
+ case AccessibilityRole::WebCoreLink:
+ return "WebCoreLink"_s;
+ case AccessibilityRole::Window:
+ return "Window"_s;
+ };
+ return "Unknown"_s;
+}
+
+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"_s) {
+ if (invalidValue == "grammar"_s)
+ axNode->setInvalid(Inspector::Protocol::Page::AXNode::Invalid::Grammar);
+ else if (invalidValue == "spelling"_s)
+ axNode->setInvalid(Inspector::Protocol::Page::AXNode::Invalid::Spelling);
+ else // Future versions of ARIA may allow additional truthy values. Ex. format, order, or size.
+ axNode->setInvalid(Inspector::Protocol::Page::AXNode::Invalid::True);
+ }
+ switch (axObject->orientation()) {
+ case AccessibilityOrientation::Undefined:
+ break;
+ case AccessibilityOrientation::Vertical:
+ axNode->setOrientation("vertical"_s);
+ break;
+ case AccessibilityOrientation::Horizontal:
+ axNode->setOrientation("horizontal"_s);
+ break;
+ }
+
+ if (axObject->isKeyboardFocusable())
+ axNode->setFocusable(axObject->isKeyboardFocusable());
+
+ if (nodeToFind && axObject->node() == nodeToFind)
+ axNode->setFound(true);
+
+ if (!axObject->children().isEmpty()) {
+ Ref<JSON::ArrayOf<Inspector::Protocol::Page::AXNode>> children = JSON::ArrayOf<Inspector::Protocol::Page::AXNode>::create();
+ for (auto& childObject : axObject->children())
+ children->addItem(snapshotForAXObject(childObject, 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();
+ RefPtr document = 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(RefPtr { axObject }, node);
+ m_doingAccessibilitySnapshot = false;
+ return axNode;
+}
+
+Protocol::ErrorStringOr<void> InspectorPageAgent::setInterceptFileChooserDialog(bool enabled)
+{
+ m_interceptFileChooserDialog = enabled;
+ return { };
+}
+
+Protocol::ErrorStringOr<void> InspectorPageAgent::setDefaultBackgroundColorOverride(RefPtr<JSON::Object>&& color)
+{
+ FrameView* view = m_inspectedPage.mainFrame().view();
+ if (!view)
+ return makeUnexpected("Internal error: No frame view to set color two"_s);
+
+ if (!color) {
+ view->updateBackgroundRecursively(std::optional<Color>());
+ return { };
+ }
+
+ view->updateBackgroundRecursively(InspectorDOMAgent::parseColor(WTFMove(color)));
+ return { };
+}
+
+Protocol::ErrorStringOr<void> InspectorPageAgent::createUserWorld(const String& name)
+{
+ if (createdUserWorlds().contains(name))
+ return makeUnexpected("World with the given name already exists"_s);
+
+ Ref<DOMWrapperWorld> world = ScriptController::createWorld(name, ScriptController::WorldType::User);
+ ensureUserWorldsExistInAllFrames({world.ptr()});
+ createdUserWorlds().set(name, WTFMove(world));
+ return { };
+}
+
+void InspectorPageAgent::ensureUserWorldsExistInAllFrames(const Vector<DOMWrapperWorld*>& worlds)
+{
+ for (Frame* frame = &m_inspectedPage.mainFrame(); frame; frame = frame->tree().traverseNext()) {
+ 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::setOrientationOverride(std::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
+}
+
+static std::optional<FloatBoxExtent> parseInsets(RefPtr<JSON::Object>&& insets)
+{
+ std::optional<double> top = insets->getDouble("top"_s);
+ std::optional<double> right = insets->getDouble("right"_s);
+ std::optional<double> bottom = insets->getDouble("bottom"_s);
+ std::optional<double> left = insets->getDouble("left"_s);
+ if (top && right && bottom && left)
+ return FloatBoxExtent(static_cast<float>(*top), static_cast<float>(*right), static_cast<float>(*bottom), static_cast<float>(*left));
+ return std::optional<FloatBoxExtent>();
+}
+
+static std::optional<FloatRect> parseRect(RefPtr<JSON::Object>&& insets)
+{
+ std::optional<double> x = insets->getDouble("x"_s);
+ std::optional<double> y = insets->getDouble("y"_s);
+ std::optional<double> width = insets->getDouble("width"_s);
+ std::optional<double> height = insets->getDouble("height"_s);
+ if (x && y && width && height)
+ return FloatRect(static_cast<float>(*x), static_cast<float>(*y), static_cast<float>(*width), static_cast<float>(*height));
+ return std::optional<FloatRect>();
+}
+
+Protocol::ErrorStringOr<void> InspectorPageAgent::setVisibleContentRects(RefPtr<JSON::Object>&& unobscuredContentRect, RefPtr<JSON::Object>&& contentInsets, RefPtr<JSON::Object>&& obscuredInsets, RefPtr<JSON::Object>&& unobscuredInsets)
+{
+ FrameView* view = m_inspectedPage.mainFrame().view();
+ if (!view)
+ return makeUnexpected("Internal error: No frame view to set content rects for"_s);
+
+ if (unobscuredContentRect) {
+ std::optional<FloatRect> ucr = parseRect(WTFMove(unobscuredContentRect));
+ if (!ucr)
+ return makeUnexpected("Invalid unobscured content rect"_s);
+
+ view->setUnobscuredContentSize(FloatSize(ucr->width(), ucr->height()));
+ }
+
+ if (contentInsets) {
+ std::optional<FloatBoxExtent> ci = parseInsets(WTFMove(contentInsets));
+ if (!ci)
+ return makeUnexpected("Invalid content insets"_s);
+
+ m_inspectedPage.setContentInsets(*ci);
+ }
+
+ if (obscuredInsets) {
+ std::optional<FloatBoxExtent> oi = parseInsets(WTFMove(obscuredInsets));
+ if (!oi)
+ return makeUnexpected("Invalid obscured insets"_s);
+
+ m_inspectedPage.setObscuredInsets(*oi);
+ }
+
+ if (unobscuredInsets) {
+ std::optional<FloatBoxExtent> ui = parseInsets(WTFMove(unobscuredInsets));
+ if (!ui)
+ return makeUnexpected("Invalid unobscured insets"_s);
+
+ m_inspectedPage.setUnobscuredSafeAreaInsets(*ui);
+ }
+ return {};
+}
+
+Protocol::ErrorStringOr<void> InspectorPageAgent::updateScrollingState()
+{
+ auto* scrollingCoordinator = m_inspectedPage.scrollingCoordinator();
+ if (!scrollingCoordinator)
+ return {};
+ scrollingCoordinator->commitTreeStateIfNeeded();
+ return {};
+}
} // namespace WebCore
diff --git a/Source/WebCore/inspector/agents/InspectorPageAgent.h b/Source/WebCore/inspector/agents/InspectorPageAgent.h
index 6d94ad131257d8d7cdb05898fd3f42e0c72766bf..6a85dba5cac19bf0adc93e0015ad223a2c60b5ad 100644
--- a/Source/WebCore/inspector/agents/InspectorPageAgent.h
+++ b/Source/WebCore/inspector/agents/InspectorPageAgent.h
@@ -32,19 +32,26 @@
#pragma once
#include "CachedResource.h"
+#include "FrameIdentifier.h"
#include "InspectorWebAgentBase.h"
#include "LayoutRect.h"
+#include "ProcessIdentifier.h"
#include <JavaScriptCore/InspectorBackendDispatchers.h>
#include <JavaScriptCore/InspectorFrontendDispatchers.h>
#include <wtf/RobinHoodHashMap.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;
@@ -76,6 +83,7 @@ public:
OtherResource,
};
+ WEBCORE_EXPORT static String makeFrameID(ProcessIdentifier processID, FrameIdentifier frameID);
static bool sharedBufferContent(RefPtr<FragmentedSharedBuffer>&&, 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);
@@ -96,15 +104,18 @@ public:
Inspector::Protocol::ErrorStringOr<void> enable();
Inspector::Protocol::ErrorStringOr<void> disable();
Inspector::Protocol::ErrorStringOr<void> reload(std::optional<bool>&& ignoreCache, std::optional<bool>&& revalidateAllResources);
+ Inspector::Protocol::ErrorStringOr<void> goBack();
+ Inspector::Protocol::ErrorStringOr<void> goForward();
Inspector::Protocol::ErrorStringOr<void> navigate(const String& url);
Inspector::Protocol::ErrorStringOr<void> overrideUserAgent(const String&);
+ Inspector::Protocol::ErrorStringOr<void> overridePlatform(const String&);
Inspector::Protocol::ErrorStringOr<void> overrideSetting(Inspector::Protocol::Page::Setting, std::optional<bool>&& value);
Inspector::Protocol::ErrorStringOr<Ref<JSON::ArrayOf<Inspector::Protocol::Page::Cookie>>> getCookies();
Inspector::Protocol::ErrorStringOr<void> setCookie(Ref<JSON::Object>&&);
Inspector::Protocol::ErrorStringOr<void> deleteCookie(const String& cookieName, const String& url);
Inspector::Protocol::ErrorStringOr<Ref<Inspector::Protocol::Page::FrameResourceTree>> getResourceTree();
Inspector::Protocol::ErrorStringOr<std::tuple<String, bool /* base64Encoded */>> getResourceContent(const Inspector::Protocol::Network::FrameId&, const String& url);
- Inspector::Protocol::ErrorStringOr<void> setBootstrapScript(const String& source);
+ Inspector::Protocol::ErrorStringOr<void> setBootstrapScript(const String& source, const String& worldName);
Inspector::Protocol::ErrorStringOr<Ref<JSON::ArrayOf<Inspector::Protocol::GenericTypes::SearchMatch>>> searchInResource(const Inspector::Protocol::Network::FrameId&, const String& url, const String& query, std::optional<bool>&& caseSensitive, std::optional<bool>&& isRegex, const Inspector::Protocol::Network::RequestId&);
Inspector::Protocol::ErrorStringOr<Ref<JSON::ArrayOf<Inspector::Protocol::Page::SearchResult>>> searchInResources(const String&, std::optional<bool>&& caseSensitive, std::optional<bool>&& isRegex);
#if !PLATFORM(IOS_FAMILY)
@@ -115,35 +126,55 @@ public:
#if ENABLE(DARK_MODE_CSS) || HAVE(OS_DARK_MODE_SUPPORT)
Inspector::Protocol::ErrorStringOr<void> setForcedAppearance(std::optional<Inspector::Protocol::Page::Appearance>&&);
#endif
+ Inspector::Protocol::ErrorStringOr<void> setForcedReducedMotion(std::optional<Inspector::Protocol::Page::ReducedMotion>&&);
+ Inspector::Protocol::ErrorStringOr<void> setTimeZone(const String&);
+ Inspector::Protocol::ErrorStringOr<void> setTouchEmulationEnabled(bool);
Inspector::Protocol::ErrorStringOr<String> snapshotNode(Inspector::Protocol::DOM::NodeId);
- Inspector::Protocol::ErrorStringOr<String> snapshotRect(int x, int y, int width, int height, Inspector::Protocol::Page::CoordinateSystem);
+ Inspector::Protocol::ErrorStringOr<String> snapshotRect(int x, int y, int width, int height, Inspector::Protocol::Page::CoordinateSystem, std::optional<bool>&& omitDeviceScaleFactor);
#if ENABLE(WEB_ARCHIVE) && USE(CF)
Inspector::Protocol::ErrorStringOr<String> archive();
#endif
-#if !PLATFORM(COCOA)
Inspector::Protocol::ErrorStringOr<void> setScreenSizeOverride(std::optional<int>&& width, std::optional<int>&& height);
-#endif
+
+ Inspector::Protocol::ErrorStringOr<void> insertText(const String& text);
+ Inspector::Protocol::ErrorStringOr<void> setComposition(const String& text, int selectionStart, int selectionLength, std::optional<int>&& replacementStart, std::optional<int>&& replacementLength);
+ 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> setOrientationOverride(std::optional<int>&& angle);
+ Inspector::Protocol::ErrorStringOr<void> setVisibleContentRects(RefPtr<JSON::Object>&& unobscuredContentRect, RefPtr<JSON::Object>&& contentInsets, RefPtr<JSON::Object>&& obscuredInsets, RefPtr<JSON::Object>&& unobscuredInsets);
+ Inspector::Protocol::ErrorStringOr<void> updateScrollingState();
// 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
void applyUserAgentOverride(String&);
+ void applyPlatformOverride(String&);
void applyEmulatedMedia(String&);
void didClearWindowObjectInWorld(Frame&, DOMWrapperWorld&);
void didPaint(RenderObject&, const LayoutRect&);
void didLayout();
void didScroll();
void didRecalculateStyle();
+ void runOpenPanel(HTMLInputElement* element, bool* intercept);
+ void frameAttached(Frame&);
+ bool shouldBypassCSP();
+ void willCheckNavigationPolicy(Frame&);
+ void didCheckNavigationPolicy(Frame&, bool cancel);
+ bool doingAccessibilitySnapshot() const { return m_doingAccessibilitySnapshot; };
Frame* frameForId(const Inspector::Protocol::Network::FrameId&);
WEBCORE_EXPORT String frameId(Frame*);
@@ -152,6 +183,7 @@ public:
private:
double timestamp();
+ void ensureUserWorldsExistInAllFrames(const Vector<DOMWrapperWorld*>&);
static bool mainResourceContent(Frame*, bool withBase64Encode, String* result);
static bool dataContent(const uint8_t* data, unsigned size, const String& textEncodingName, bool withBase64Encode, String* result);
@@ -163,18 +195,20 @@ private:
RefPtr<Inspector::PageBackendDispatcher> m_backendDispatcher;
Page& m_inspectedPage;
+ Inspector::InjectedScriptManager& m_injectedScriptManager;
InspectorClient* m_client { nullptr };
InspectorOverlay* m_overlay { nullptr };
- // FIXME: Make a WeakHashMap and use it for m_frameToIdentifier and m_loaderToIdentifier.
- HashMap<Frame*, String> m_frameToIdentifier;
MemoryCompactRobinHoodHashMap<String, WeakPtr<Frame>> m_identifierToFrame;
- HashMap<DocumentLoader*, String> m_loaderToIdentifier;
+ HashMap<String, String> m_worldNameToBootstrapScript;
String m_userAgentOverride;
+ String m_platformOverride;
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 fe1cc2dbb9863cd4480476d2e21a5a229dc8a0e8..35dd7ca4cabe0d0ec76d44e260870a99becaa128 100644
--- a/Source/WebCore/inspector/agents/InspectorWorkerAgent.cpp
+++ b/Source/WebCore/inspector/agents/InspectorWorkerAgent.cpp
@@ -168,7 +168,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 31ca79d6410560456c89a5be62560fc33e082cee..4a1e4dbc2ff3c13761014ae614ebf4b7199dbdcd 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 "JSDOMWindowCustom.h"
#include "JSExecState.h"
#include "Page.h"
@@ -74,7 +75,9 @@ Protocol::ErrorStringOr<std::tuple<Ref<Protocol::Runtime::RemoteObject>, std::op
if (injectedScript.hasNoValue())
return makeUnexpected("Missing injected script for given callFrameId"_s);
- UserGestureEmulationScope userGestureScope(m_inspectedPage, emulateUserGesture.value_or(false), dynamicDowncast<Document>(executionContext(injectedScript.globalObject())));
+ JSC::JSGlobalObject* globalObject = injectedScript.globalObject();
+ Document* document = globalObject ? activeDOMWindow(*globalObject).document() : nullptr;
+ UserGestureEmulationScope userGestureScope(m_inspectedPage, emulateUserGesture.value_or(false), document);
return WebDebuggerAgent::evaluateOnCallFrame(injectedScript, 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 5e7a1214da060ba3a168cf21b22e6c398c0e07f7..ef38546315e7e88f09738b18d44a0268a009307c 100644
--- a/Source/WebCore/inspector/agents/page/PageRuntimeAgent.cpp
+++ b/Source/WebCore/inspector/agents/page/PageRuntimeAgent.cpp
@@ -35,6 +35,7 @@
#include "DOMWrapperWorld.h"
#include "Document.h"
#include "Frame.h"
+#include "FrameLoader.h"
#include "InspectorPageAgent.h"
#include "InstrumentingAgents.h"
#include "JSDOMWindowCustom.h"
@@ -42,6 +43,7 @@
#include "Page.h"
#include "PageConsoleClient.h"
#include "ScriptController.h"
+#include "ScriptSourceCode.h"
#include "SecurityOrigin.h"
#include "UserGestureEmulationScope.h"
#include <JavaScriptCore/InjectedScript.h>
@@ -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.
+ mainWorldGlobalObject(frame);
+ }
+}
+
InjectedScript PageRuntimeAgent::injectedScriptForEval(Protocol::ErrorString& errorString, std::optional<Protocol::Runtime::ExecutionContextId>&& executionContextId)
{
if (!executionContextId) {
@@ -196,18 +207,24 @@ Protocol::ErrorStringOr<std::tuple<Ref<Protocol::Runtime::RemoteObject>, std::op
if (injectedScript.hasNoValue())
return makeUnexpected(errorString);
- UserGestureEmulationScope userGestureScope(m_inspectedPage, emulateUserGesture.value_or(false), dynamicDowncast<Document>(executionContext(injectedScript.globalObject())));
+ JSC::JSGlobalObject* globalObject = injectedScript.globalObject();
+ Document* document = globalObject ? activeDOMWindow(*globalObject).document() : nullptr;
+ UserGestureEmulationScope userGestureScope(m_inspectedPage, emulateUserGesture.value_or(false), document);
return InspectorRuntimeAgent::evaluate(injectedScript, expression, objectGroup, WTFMove(includeCommandLineAPI), WTFMove(doNotPauseOnExceptionsAndMuteConsole), WTFMove(returnByValue), WTFMove(generatePreview), WTFMove(saveResult), WTFMove(emulateUserGesture));
}
-Protocol::ErrorStringOr<std::tuple<Ref<Protocol::Runtime::RemoteObject>, std::optional<bool> /* wasThrown */>> PageRuntimeAgent::callFunctionOn(const Protocol::Runtime::RemoteObjectId& objectId, const String& expression, RefPtr<JSON::Array>&& optionalArguments, std::optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& emulateUserGesture)
+void PageRuntimeAgent::callFunctionOn(const Protocol::Runtime::RemoteObjectId& objectId, const String& expression, RefPtr<JSON::Array>&& optionalArguments, std::optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& emulateUserGesture, std::optional<bool>&& awaitPromise, Ref<CallFunctionOnCallback>&& callback)
{
auto injectedScript = injectedScriptManager().injectedScriptForObjectId(objectId);
- if (injectedScript.hasNoValue())
- return makeUnexpected("Missing injected script for given objectId"_s);
+ if (injectedScript.hasNoValue()) {
+ callback->sendFailure("Missing injected script for given objectId"_s);
+ return;
+ }
- UserGestureEmulationScope userGestureScope(m_inspectedPage, emulateUserGesture.value_or(false), dynamicDowncast<Document>(executionContext(injectedScript.globalObject())));
- return InspectorRuntimeAgent::callFunctionOn(injectedScript, objectId, expression, WTFMove(optionalArguments), WTFMove(doNotPauseOnExceptionsAndMuteConsole), WTFMove(returnByValue), WTFMove(generatePreview), WTFMove(emulateUserGesture));
+ JSC::JSGlobalObject* globalObject = injectedScript.globalObject();
+ Document* document = globalObject ? activeDOMWindow(*globalObject).document() : nullptr;
+ UserGestureEmulationScope userGestureScope(m_inspectedPage, emulateUserGesture.value_or(false), document);
+ return InspectorRuntimeAgent::callFunctionOn(objectId, expression, WTFMove(optionalArguments), WTFMove(doNotPauseOnExceptionsAndMuteConsole), WTFMove(returnByValue), WTFMove(generatePreview), WTFMove(emulateUserGesture), WTFMove(awaitPromise), WTFMove(callback));
}
} // namespace WebCore
diff --git a/Source/WebCore/inspector/agents/page/PageRuntimeAgent.h b/Source/WebCore/inspector/agents/page/PageRuntimeAgent.h
index 6aba3a2c6e8bbb7a0bca4f07824cf4de8ce36f8e..537e3b34d6405e412bf0e2350909c9afda06bed8 100644
--- a/Source/WebCore/inspector/agents/page/PageRuntimeAgent.h
+++ b/Source/WebCore/inspector/agents/page/PageRuntimeAgent.h
@@ -54,25 +54,25 @@ public:
~PageRuntimeAgent();
// RuntimeBackendDispatcherHandler
- Inspector::Protocol::ErrorStringOr<void> enable();
- Inspector::Protocol::ErrorStringOr<void> disable();
- Inspector::Protocol::ErrorStringOr<std::tuple<Ref<Inspector::Protocol::Runtime::RemoteObject>, std::optional<bool> /* wasThrown */, std::optional<int> /* savedResultIndex */>> evaluate(const String& expression, const String& objectGroup, std::optional<bool>&& includeCommandLineAPI, std::optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, std::optional<Inspector::Protocol::Runtime::ExecutionContextId>&&, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& saveResult, std::optional<bool>&& emulateUserGesture);
- Inspector::Protocol::ErrorStringOr<std::tuple<Ref<Inspector::Protocol::Runtime::RemoteObject>, std::optional<bool> /* wasThrown */>> callFunctionOn(const Inspector::Protocol::Runtime::RemoteObjectId&, const String& expression, RefPtr<JSON::Array>&& arguments, std::optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& emulateUserGesture);
+ Inspector::Protocol::ErrorStringOr<void> enable() override;
+ Inspector::Protocol::ErrorStringOr<void> disable() override;
+ Inspector::Protocol::ErrorStringOr<std::tuple<Ref<Inspector::Protocol::Runtime::RemoteObject>, std::optional<bool> /* wasThrown */, std::optional<int> /* savedResultIndex */>> evaluate(const String& expression, const String& objectGroup, std::optional<bool>&& includeCommandLineAPI, std::optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, std::optional<Inspector::Protocol::Runtime::ExecutionContextId>&&, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& saveResult, std::optional<bool>&& emulateUserGesture) override;
+ void callFunctionOn(const Inspector::Protocol::Runtime::RemoteObjectId&, const String& functionDeclaration, RefPtr<JSON::Array>&& arguments, std::optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& emulateUserGesture, std::optional<bool>&& awaitPromise, Ref<CallFunctionOnCallback>&&) override;
// InspectorInstrumentation
void frameNavigated(Frame&);
void didClearWindowObjectInWorld(Frame&, DOMWrapperWorld&);
+ void didReceiveMainResourceError(Frame&);
private:
- Inspector::InjectedScript injectedScriptForEval(Inspector::Protocol::ErrorString&, std::optional<Inspector::Protocol::Runtime::ExecutionContextId>&&);
- void muteConsole();
- void unmuteConsole();
+ Inspector::InjectedScript injectedScriptForEval(Inspector::Protocol::ErrorString&, std::optional<Inspector::Protocol::Runtime::ExecutionContextId>&&) override;
+ void muteConsole() override;
+ void unmuteConsole() override;
void reportExecutionContextCreation();
void notifyContextCreated(const Inspector::Protocol::Network::FrameId&, JSC::JSGlobalObject*, const DOMWrapperWorld&, SecurityOrigin* = nullptr);
std::unique_ptr<Inspector::RuntimeFrontendDispatcher> m_frontendDispatcher;
RefPtr<Inspector::RuntimeBackendDispatcher> m_backendDispatcher;
-
InstrumentingAgents& m_instrumentingAgents;
Page& m_inspectedPage;
diff --git a/Source/WebCore/loader/CookieJar.h b/Source/WebCore/loader/CookieJar.h
index 21e33e46bdb1af8434527747e3c308cbe53f60f0..c17c4de17f439c04d27caa532771934cb2f62abd 100644
--- a/Source/WebCore/loader/CookieJar.h
+++ b/Source/WebCore/loader/CookieJar.h
@@ -43,6 +43,7 @@ struct CookieRequestHeaderFieldProxy;
class NetworkStorageSession;
class StorageSessionProvider;
struct SameSiteInfo;
+class ResourceLoader;
class WEBCORE_EXPORT CookieJar : public RefCounted<CookieJar> {
public:
@@ -66,6 +67,9 @@ public:
virtual void clearCache() { }
virtual void clearCacheForHost(const String&) { }
+ // Playwright.
+ virtual void setCookieFromResponse(ResourceLoader&, const String&) { }
+
virtual ~CookieJar();
protected:
static SameSiteInfo sameSiteInfo(const Document&, IsForDOMCookieAccess = IsForDOMCookieAccess::No);
diff --git a/Source/WebCore/loader/DocumentLoader.cpp b/Source/WebCore/loader/DocumentLoader.cpp
index 7aa1cd888e1bee6e9a6e326f68a71ffc008a728a..85de870ae44f6ec4efc4d4e7e770c79a446031e7 100644
--- a/Source/WebCore/loader/DocumentLoader.cpp
+++ b/Source/WebCore/loader/DocumentLoader.cpp
@@ -1507,8 +1507,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 50de786a5483597989439209ebd16b5b4e8a2924..59198323a3e72b92e95f73c15a43dc6d8e967765 100644
--- a/Source/WebCore/loader/DocumentLoader.h
+++ b/Source/WebCore/loader/DocumentLoader.h
@@ -181,9 +181,13 @@ public:
WEBCORE_EXPORT virtual void detachFromFrame();
+ virtual void replacedByFragmentNavigation(Frame&) { }
+
WEBCORE_EXPORT FrameLoader* frameLoader() const;
WEBCORE_EXPORT SubresourceLoader* mainResourceLoader() const;
WEBCORE_EXPORT RefPtr<FragmentedSharedBuffer> 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 e350042d03e78ad19cb5ea642b29025b5ba75e76..d1049c1b4b5e73da2beefd5d15179c129b9dbbd9 100644
--- a/Source/WebCore/loader/FrameLoader.cpp
+++ b/Source/WebCore/loader/FrameLoader.cpp
@@ -1173,6 +1173,7 @@ void FrameLoader::loadInSameDocument(URL url, RefPtr<SerializedScriptValue> stat
}
m_client->dispatchDidNavigateWithinPage();
+ InspectorInstrumentation::didNavigateWithinPage(m_frame);
m_frame.document()->statePopped(stateObject ? stateObject.releaseNonNull() : SerializedScriptValue::nullValue());
m_client->dispatchDidPopStateWithinPage();
@@ -1609,6 +1610,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 };
@@ -1638,7 +1641,9 @@ void FrameLoader::loadWithDocumentLoader(DocumentLoader* loader, FrameLoadType t
}
RELEASE_ASSERT(!isBackForwardLoadType(policyChecker().loadType()) || history().provisionalItem());
+ InspectorInstrumentation::willCheckNavigationPolicy(m_frame);
policyChecker().checkNavigationPolicy(ResourceRequest(loader->request()), ResourceResponse { } /* redirectResponse */, loader, WTFMove(formState), [this, protectedFrame = Ref { m_frame }, allowNavigationToInvalidURL, completionHandler = completionHandlerCaller.release()] (const ResourceRequest& request, WeakPtr<FormState>&& formState, NavigationPolicyDecision navigationPolicyDecision) mutable {
+ InspectorInstrumentation::didCheckNavigationPolicy(m_frame, navigationPolicyDecision != NavigationPolicyDecision::ContinueLoad);
continueLoadAfterNavigationPolicy(request, formState.get(), navigationPolicyDecision, allowNavigationToInvalidURL);
completionHandler();
}, PolicyDecisionMode::Asynchronous);
@@ -2806,12 +2811,17 @@ String FrameLoader::userAgent(const URL& url) const
String FrameLoader::navigatorPlatform() const
{
+ String platform;
+
if (auto* documentLoader = m_frame.mainFrame().loader().activeDocumentLoader()) {
auto& customNavigatorPlatform = documentLoader->customNavigatorPlatform();
if (!customNavigatorPlatform.isEmpty())
- return customNavigatorPlatform;
+ platform = customNavigatorPlatform;
}
- return String();
+
+ InspectorInstrumentation::applyPlatformOverride(m_frame, platform);
+
+ return platform;
}
void FrameLoader::dispatchOnloadEvents()
@@ -3218,6 +3228,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)
@@ -3988,9 +4000,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)
@@ -3999,13 +4008,13 @@ void FrameLoader::dispatchDidClearWindowObjectsInAllWorlds()
void FrameLoader::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld& world)
{
- if (!m_frame.script().canExecuteScripts(NotAboutToExecuteScript) || !m_frame.windowProxy().existingJSWindowProxy(world))
- return;
+ if (m_frame.windowProxy().existingJSWindowProxy(world)) {
+ if (m_frame.script().canExecuteScripts(NotAboutToExecuteScript))
+ m_client->dispatchDidClearWindowObjectInWorld(world);
- 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 29d2e3f46140aaa51160e6a28562f370e371eb21..676ddc9369050c19454fbf5faffac2b27e0fad41 100644
--- a/Source/WebCore/loader/LoaderStrategy.h
+++ b/Source/WebCore/loader/LoaderStrategy.h
@@ -86,6 +86,7 @@ public:
virtual bool isOnLine() const = 0;
virtual void addOnlineStateChangeListener(Function<void(bool)>&&) = 0;
+ virtual void setEmulateOfflineState(bool) {};
virtual bool shouldPerformSecurityChecks() const { return false; }
virtual bool havePerformedSecurityChecks(const ResourceResponse&) const { return false; }
diff --git a/Source/WebCore/loader/PolicyChecker.cpp b/Source/WebCore/loader/PolicyChecker.cpp
index 61edc972ce354589380535f8c02a39b902d626aa..5eb8f591778112b22205fd910dff18b9ddb46a92 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 "ThreadableBlobRegistry.h"
#include <wtf/CompletionHandler.h>
diff --git a/Source/WebCore/loader/ProgressTracker.cpp b/Source/WebCore/loader/ProgressTracker.cpp
index a2c6d72b5ba0f04a49ca6dc710ef6fa5e0125c33..759b0d34b7db839027063a1b6ce8fb0f7ee2acd4 100644
--- a/Source/WebCore/loader/ProgressTracker.cpp
+++ b/Source/WebCore/loader/ProgressTracker.cpp
@@ -160,6 +160,8 @@ void ProgressTracker::progressCompleted(Frame& frame)
if (!m_numProgressTrackedFrames || m_originatingProgressFrame == &frame)
finalProgressComplete();
+ InspectorInstrumentation::frameStoppedLoading(frame);
+
m_client->didChangeEstimatedProgress();
}
@@ -186,8 +188,6 @@ void ProgressTracker::finalProgressComplete()
m_client->progressFinished(*frame);
m_page.progressFinished(*frame);
frame->loader().loadProgressingStatusChanged();
-
- InspectorInstrumentation::frameStoppedLoading(*frame);
}
void ProgressTracker::incrementProgress(ResourceLoaderIdentifier identifier, const ResourceResponse& response)
diff --git a/Source/WebCore/page/ChromeClient.h b/Source/WebCore/page/ChromeClient.h
index 81a36fc8222e4345aa3474056e164757f8fe94ed..23be7d3bb2a8679227b7876599eafc2f685c51df 100644
--- a/Source/WebCore/page/ChromeClient.h
+++ b/Source/WebCore/page/ChromeClient.h
@@ -320,7 +320,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 85998d7f632cf588c444446045140f91740f0f5e..b3d139b1a80110e27ef867bf481c1a29e3bdba7b 100644
--- a/Source/WebCore/page/EventHandler.cpp
+++ b/Source/WebCore/page/EventHandler.cpp
@@ -142,6 +142,7 @@
#if ENABLE(TOUCH_EVENTS) && !ENABLE(IOS_TOUCH_EVENTS)
#include "PlatformTouchEvent.h"
+#include "PointerCaptureController.h"
#endif
#if ENABLE(MAC_GESTURE_EVENTS)
@@ -807,9 +808,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;
@@ -849,8 +848,6 @@ VisiblePosition EventHandler::selectionExtentRespectingEditingBoundary(const Vis
return adjustedTarget->renderer()->positionForPoint(LayoutPoint(selectionEndPoint), nullptr);
}
-#if ENABLE(DRAG_SUPPORT)
-
#if !PLATFORM(IOS_FAMILY)
bool EventHandler::supportsSelectionUpdatesOnMouseDrag() const
@@ -872,8 +869,10 @@ bool EventHandler::handleMouseDraggedEvent(const MouseEventWithHitTestResults& e
Ref<Frame> protectedFrame(m_frame);
+#if ENABLE(DRAG_SUPPORT)
if (handleDrag(event, checkDragHysteresis))
return true;
+#endif
RefPtr targetNode = event.targetNode();
if (event.event().button() != LeftButton || !targetNode)
@@ -894,7 +893,9 @@ bool EventHandler::handleMouseDraggedEvent(const MouseEventWithHitTestResults& e
ASSERT(mouseDownMayStartSelect() || m_mouseDownMayStartAutoscroll);
#endif
+#if ENABLE(DRAG_SUPPORT)
m_mouseDownMayStartDrag = false;
+#endif
if (m_mouseDownMayStartAutoscroll && !panScrollInProgress()) {
m_autoscrollController->startAutoscrollForSelection(renderer);
@@ -911,6 +912,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
@@ -942,6 +945,8 @@ bool EventHandler::eventMayStartDrag(const PlatformMouseEvent& event) const
return targetElement && page->dragController().draggableElement(&m_frame, targetElement.get(), result.roundedPointInInnerNodeFrame(), state);
}
+#endif // ENABLE(DRAG_SUPPORT)
+
void EventHandler::updateSelectionForMouseDrag()
{
if (!supportsSelectionUpdatesOnMouseDrag())
@@ -1036,7 +1041,6 @@ void EventHandler::updateSelectionForMouseDrag(const HitTestResult& hitTestResul
if (oldSelection != newSelection && ImageOverlay::isOverlayText(newSelection.start().containerNode()) && ImageOverlay::isOverlayText(newSelection.end().containerNode()))
invalidateClick();
}
-#endif // ENABLE(DRAG_SUPPORT)
void EventHandler::lostMouseCapture()
{
@@ -1084,9 +1088,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;
@@ -2054,10 +2056,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;
}
@@ -4145,7 +4145,14 @@ bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event, CheckDr
if (!m_frame.document())
return false;
- dragState().dataTransfer = DataTransfer::createForDrag(*m_frame.document());
+#if PLATFORM(MAC)
+ auto* page = m_frame.page();
+ if (page && !page->overrideDragPasteboardName().isEmpty())
+ dragState().dataTransfer = DataTransfer::createForDrag(*m_frame.document(), page->overrideDragPasteboardName());
+ else
+#endif
+ dragState().dataTransfer = DataTransfer::createForDrag(*m_frame.document());
+
auto hasNonDefaultPasteboardData = HasNonDefaultPasteboardData::No;
if (dragState().shouldDispatchEvents) {
@@ -4542,7 +4549,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());
@@ -4669,6 +4677,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 dcefd2a8a88719f101df3de79bb296ac236e4d88..b29280bff9acbc8df2f9c5035be931eb70e86265 100644
--- a/Source/WebCore/page/EventHandler.h
+++ b/Source/WebCore/page/EventHandler.h
@@ -136,9 +136,7 @@ public:
WEBCORE_EXPORT VisiblePosition selectionExtentRespectingEditingBoundary(const VisibleSelection&, const LayoutPoint&, Node*);
-#if ENABLE(DRAG_SUPPORT)
void updateSelectionForMouseDrag();
-#endif
#if ENABLE(PAN_SCROLLING)
void didPanScrollStart();
@@ -387,10 +385,8 @@ private:
bool startKeyboardScrolling(KeyboardEvent&);
void stopKeyboardScrolling();
-#if ENABLE(DRAG_SUPPORT)
bool handleMouseDraggedEvent(const MouseEventWithHitTestResults&, CheckDragHysteresis = ShouldCheckDragHysteresis);
bool shouldAllowMouseDownToStartDrag() const;
-#endif
WEBCORE_EXPORT bool handleMouseReleaseEvent(const MouseEventWithHitTestResults&);
@@ -490,10 +486,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.
@@ -501,9 +495,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);
@@ -595,8 +590,8 @@ private:
Timer m_autoHideCursorTimer;
#endif
-#if ENABLE(DRAG_SUPPORT)
LayoutPoint m_dragStartPosition;
+#if ENABLE(DRAG_SUPPORT)
RefPtr<Element> m_dragTarget;
bool m_mouseDownMayStartDrag { false };
bool m_dragMayStartSelectionInstead { false };
diff --git a/Source/WebCore/page/Frame.cpp b/Source/WebCore/page/Frame.cpp
index 0d953e1e6242b0d41a8ee54996f7c0be309dca24..b38a18645821fa0e3245a29df4ec6fdcb3ff9909 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 "DocumentTimelinesController.h"
#include "DocumentType.h"
@@ -73,6 +74,7 @@
#include "NavigationScheduler.h"
#include "Navigator.h"
#include "NodeList.h"
+#include "NodeRenderStyle.h"
#include "NodeTraversal.h"
#include "Page.h"
#include "ProcessWarming.h"
@@ -191,6 +193,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)
@@ -374,7 +377,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)
@@ -1171,6 +1174,362 @@ DataDetectionResultsStorage& Frame::dataDetectionResults()
#endif
+#if !PLATFORM(IOS_FAMILY)
+
+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::Type> hitType { HitTestRequest::Type::ReadOnly, HitTestRequest::Type::Active, HitTestRequest::Type::DisallowUserAgentShadowContent, HitTestRequest::Type::AllowVisibleChildFrameContentOnly };
+ auto* candidate = nodeQualifierFunction(eventHandler().hitTestResultAtPoint(testPoint, hitType), failedNode, &candidateRect);
+
+ // Bail if we have no candidate, or the candidate is already equal to our current best node,
+ // or our candidate is the avoidedNode and there is a current best node.
+ if (!candidate || candidate == best)
+ return;
+
+ // The document should never be considered the best alternative.
+ if (candidate->isDocumentNode())
+ return;
+
+ if (best) {
+ IntRect bestIntersect = intersection(testRect, bestRect);
+ IntRect candidateIntersect = intersection(testRect, candidateRect);
+ // if the candidate intersection is smaller than the current best intersection, bail.
+ if (candidateIntersect.width() * candidateIntersect.height() <= bestIntersect.width() * bestIntersect.height())
+ return;
+ }
+
+ // At this point we either don't have a previous best, or our current candidate has a better intersection.
+ best = candidate;
+ bestPoint = testPoint;
+ bestRect = candidateRect;
+}
+
+bool 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::Type> hitType { HitTestRequest::Type::ReadOnly, HitTestRequest::Type::Active, HitTestRequest::Type::DisallowUserAgentShadowContent, HitTestRequest::Type::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::Type> hitType { HitTestRequest::Type::ReadOnly, HitTestRequest::Type::Active, HitTestRequest::Type::DisallowUserAgentShadowContent, HitTestRequest::Type::AllowChildFrameContent };
+ auto candidateInfo = eventHandler().hitTestResultAtPoint(testPoint, hitType);
+ Node* candidateNode = nodeQualifierFunction(candidateInfo, 0, 0);
+ if (candidateNode && candidateNode->isDescendantOf(originalApproximateNode)) {
+ approximateNode = candidateNode;
+ bestPoint = testPoint;
+ break;
+ }
+ }
+ } else if (!approximateNode && shouldApproximate == ShouldApproximate::Yes) {
+ // Grab the closest parent element of our failed candidate node.
+ Node* candidate = candidateInfo.innerNode();
+ Node* failedNode = candidate;
+
+ while (candidate && !candidate->isElementNode())
+ candidate = candidate->parentInComposedTree();
+
+ if (candidate)
+ failedNode = candidate;
+
+ // The center point was tested earlier.
+ const float testOffsets[] = {
+ -.3f, -.3f,
+ +.3f, -.3f,
+ -.3f, +.3f,
+ +.3f, +.3f,
+ -.6f, -.6f,
+ +.6f, -.6f,
+ -.6f, +.6f,
+ +.6f, +.6f,
+ -1.f, 0,
+ +1.f, 0,
+ 0, +1.f,
+ 0, -1.f,
+ };
+ IntRect bestFrame;
+ IntRect testRect(testCenter, IntSize());
+ testRect.inflate(searchRadius);
+ int currentTestRadius = 0;
+ for (unsigned n = 0; n < 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 (RefPtr shadowRoot = element.shadowRoot()) {
+ if (shadowRoot->delegatesFocus()) {
+ for (auto& node : composedTreeDescendants(element)) {
+ if (is<Element>(node) && downcast<Element>(node).isMouseFocusable())
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+static bool nodeWillRespondToMouseEvents(Node& node)
+{
+ return node.willRespondToMouseClickEvents() || node.willRespondToMouseMoveEvents() || nodeIsMouseFocusable(node);
+}
+
+Node* 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->hasNonVisibleOverflow()
+ && (style.overflowY() == Overflow::Auto || style.overflowY() == Overflow::Scroll
+ || style.overflowX() == Overflow::Auto || style.overflowX() == Overflow::Scroll)) {
+ scrollingAncestor = node;
+ }
+ }
+
+ return scrollingAncestor;
+ };
+
+ FloatPoint adjustedViewportLocation;
+ return qualifyingNodeAtViewportLocation(viewportLocation, adjustedViewportLocation, WTFMove(ancestorRespondingToScrollWheelEvents), ShouldApproximate::No);
+}
+
+#endif // !PLATFORM(IOS_FAMILY)
+
} // namespace WebCore
#undef FRAME_RELEASE_LOG_ERROR
diff --git a/Source/WebCore/page/Frame.h b/Source/WebCore/page/Frame.h
index 856ff374f367332ca5ab10a46bff825b8bcb159b..24bbbcd6b51a9ae27c72a0810c97678afb6b018c 100644
--- a/Source/WebCore/page/Frame.h
+++ b/Source/WebCore/page/Frame.h
@@ -113,8 +113,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)>;
// FIXME: Rename Frame to LocalFrame and AbstractFrame to Frame.
class Frame final : public AbstractFrame {
@@ -220,10 +220,6 @@ public:
WEBCORE_EXPORT DataDetectionResultsStorage& dataDetectionResults();
#endif
-#if PLATFORM(IOS_FAMILY)
- const ViewportArguments& viewportArguments() const;
- WEBCORE_EXPORT void setViewportArguments(const ViewportArguments&);
-
WEBCORE_EXPORT Node* deepestNodeAtLocation(const FloatPoint& viewportLocation);
WEBCORE_EXPORT Node* nodeRespondingToClickEvents(const FloatPoint& viewportLocation, FloatPoint& adjustedViewportLocation, SecurityOrigin* = nullptr);
WEBCORE_EXPORT Node* nodeRespondingToDoubleClickEvent(const FloatPoint& viewportLocation, FloatPoint& adjustedViewportLocation);
@@ -231,6 +227,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;
@@ -298,6 +298,7 @@ public:
WEBCORE_EXPORT FloatSize screenSize() const;
void setOverrideScreenSize(FloatSize&&);
+ bool hasScreenSizeOverride() const { return !m_overrideScreenSize.isEmpty(); }
void selfOnlyRef();
void selfOnlyDeref();
@@ -336,7 +337,6 @@ private:
#if ENABLE(DATA_DETECTION)
std::unique_ptr<DataDetectionResultsStorage> m_dataDetectionResults;
#endif
-#if PLATFORM(IOS_FAMILY)
void betterApproximateNode(const IntPoint& testPoint, const NodeQualifier&, Node*& best, Node* failedNode, IntPoint& bestPoint, IntRect& bestRect, const IntRect& testRect);
bool hitTestResultAtViewportLocation(const FloatPoint& viewportLocation, HitTestResult&, IntPoint& center);
@@ -344,6 +344,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 4e524dcb9f03fcc0e50919b16448be6b0421b5da..b566f02589bac9c3259a63db94a3108bbcbff554 100644
--- a/Source/WebCore/page/FrameSnapshotting.cpp
+++ b/Source/WebCore/page/FrameSnapshotting.cpp
@@ -107,7 +107,7 @@ RefPtr<ImageBuffer> snapshotFrameRectWithClip(Frame& frame, const IntRect& image
// Other paint behaviors are set by paintContentsForSnapshot.
frame.view()->setPaintBehavior(paintBehavior);
- float scaleFactor = frame.page()->deviceScaleFactor();
+ float scaleFactor = options.flags.contains(SnapshotFlags::OmitDeviceScaleFactor) ? 1 : frame.page()->deviceScaleFactor();
if (frame.page()->delegatesScaling())
scaleFactor *= frame.page()->pageScaleFactor();
@@ -122,7 +122,13 @@ RefPtr<ImageBuffer> snapshotFrameRectWithClip(Frame& frame, const IntRect& image
if (!buffer)
return nullptr;
+#if !PLATFORM(MAC)
+ buffer->context().scale(scaleFactor);
+#endif
+
buffer->context().translate(-imageRect.location());
+ if (coordinateSpace != FrameView::ViewCoordinates)
+ buffer->context().scale(1 / frame.page()->pageScaleFactor());
if (!clipRects.isEmpty()) {
Path clipPath;
@@ -131,7 +137,10 @@ RefPtr<ImageBuffer> snapshotFrameRectWithClip(Frame& frame, const IntRect& image
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/FrameSnapshotting.h b/Source/WebCore/page/FrameSnapshotting.h
index bb1bc2ffd02177718a77c5534e66bed55232e660..1eaff1702c30b337d4a8f5a804a9a4b134e1b111 100644
--- a/Source/WebCore/page/FrameSnapshotting.h
+++ b/Source/WebCore/page/FrameSnapshotting.h
@@ -44,7 +44,7 @@ class IntRect;
class ImageBuffer;
class Node;
-enum class SnapshotFlags : uint8_t {
+enum class SnapshotFlags : uint16_t {
ExcludeSelectionHighlighting = 1 << 0,
PaintSelectionOnly = 1 << 1,
InViewCoordinates = 1 << 2,
@@ -53,6 +53,7 @@ enum class SnapshotFlags : uint8_t {
PaintEverythingExcludingSelection = 1 << 5,
PaintWithIntegralScaleFactor = 1 << 6,
Shareable = 1 << 7,
+ OmitDeviceScaleFactor = 1 << 8,
};
struct SnapshotOptions {
diff --git a/Source/WebCore/page/History.cpp b/Source/WebCore/page/History.cpp
index a782c3be51ca113a52482c5a10583c8fa64724ef..1d82dff81be5c5492efb3bfe77d2f259c2f2b5db 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 93c354f511f13e018dfb3a9f0a60f5738fb5ee55..860c2372779c91c0a6299f396c748f6d149c64e0 100644
--- a/Source/WebCore/page/Page.cpp
+++ b/Source/WebCore/page/Page.cpp
@@ -485,6 +485,37 @@ void Page::setOverrideViewportArguments(const std::optional<ViewportArguments>&
document->updateViewportArguments();
}
+FloatSize Page::screenSize()
+{
+ return m_overrideScreenSize.value_or(screenRect(mainFrame().view()).size());
+}
+
+void Page::setOverrideScreenSize(std::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.value_or(chrome().client().deviceOrientation());
+}
+
+void Page::setOverrideOrientation(std::optional<int> orientation)
+{
+ if (orientation == m_overrideOrientation)
+ return;
+
+ m_overrideOrientation = orientation;
+ mainFrame().orientationChanged();
+}
+#endif
+
ScrollingCoordinator* Page::scrollingCoordinator()
{
if (!m_scrollingCoordinator && m_settings->scrollingCoordinatorEnabled()) {
@@ -1354,10 +1385,6 @@ void Page::didCommitLoad()
m_isEditableRegionEnabled = false;
#endif
-#if HAVE(OS_DARK_MODE_SUPPORT)
- setUseDarkAppearanceOverride(std::nullopt);
-#endif
-
resetSeenPlugins();
resetSeenMediaEngines();
@@ -3406,6 +3433,16 @@ void Page::setUseDarkAppearanceOverride(std::optional<bool> valueOverride)
#endif
}
+void Page::setUseReducedMotionOverride(std::optional<bool> valueOverride)
+{
+ if (valueOverride == m_useReducedMotionOverride)
+ return;
+
+ m_useReducedMotionOverride = valueOverride;
+
+ appearanceDidChange();
+}
+
void Page::setFullscreenInsets(const FloatBoxExtent& insets)
{
if (insets == m_fullscreenInsets)
diff --git a/Source/WebCore/page/Page.h b/Source/WebCore/page/Page.h
index 3166d7463afcbd48dd08bb0d20ed047bd7ac0f54..6dd15d9fb0c0887bae8bafff9a52967c9e543310 100644
--- a/Source/WebCore/page/Page.h
+++ b/Source/WebCore/page/Page.h
@@ -281,6 +281,9 @@ public:
const std::optional<ViewportArguments>& overrideViewportArguments() const { return m_overrideViewportArguments; }
WEBCORE_EXPORT void setOverrideViewportArguments(const std::optional<ViewportArguments>&);
+ WEBCORE_EXPORT FloatSize screenSize();
+ void setOverrideScreenSize(std::optional<FloatSize> size);
+
static void refreshPlugins(bool reload);
WEBCORE_EXPORT PluginData& pluginData();
void clearPluginData();
@@ -331,6 +334,10 @@ public:
DragCaretController& dragCaretController() const { return *m_dragCaretController; }
#if ENABLE(DRAG_SUPPORT)
DragController& dragController() const { return *m_dragController; }
+#if PLATFORM(MAC)
+ void setDragPasteboardName(const String& pasteboardName) { m_overrideDragPasteboardName = pasteboardName; }
+ const String& overrideDragPasteboardName() { return m_overrideDragPasteboardName; }
+#endif
#endif
FocusController& focusController() const { return *m_focusController; }
#if ENABLE(CONTEXT_MENUS)
@@ -498,6 +505,8 @@ public:
WEBCORE_EXPORT void effectiveAppearanceDidChange(bool useDarkAppearance, bool useElevatedUserInterfaceLevel);
bool defaultUseDarkAppearance() const { return m_useDarkAppearance; }
void setUseDarkAppearanceOverride(std::optional<bool>);
+ std::optional<bool> useReducedMotionOverride() const { return m_useReducedMotionOverride; }
+ void setUseReducedMotionOverride(std::optional<bool>);
#if ENABLE(TEXT_AUTOSIZING)
float textAutosizingWidth() const { return m_textAutosizingWidth; }
@@ -905,6 +914,11 @@ public:
bool shouldBuildInteractionRegions() const;
#endif
+#if ENABLE(ORIENTATION_EVENTS)
+ int orientation() const;
+ void setOverrideOrientation(std::optional<int>);
+#endif
+
#if ENABLE(DEVICE_ORIENTATION) && PLATFORM(IOS_FAMILY)
DeviceOrientationUpdateProvider* deviceOrientationUpdateProvider() const { return m_deviceOrientationUpdateProvider.get(); }
#endif
@@ -1023,6 +1037,9 @@ private:
#if ENABLE(DRAG_SUPPORT)
const std::unique_ptr<DragController> m_dragController;
+#if PLATFORM(MAC)
+ String m_overrideDragPasteboardName;
+#endif
#endif
const std::unique_ptr<FocusController> m_focusController;
#if ENABLE(CONTEXT_MENUS)
@@ -1102,6 +1119,7 @@ private:
bool m_useElevatedUserInterfaceLevel { false };
bool m_useDarkAppearance { false };
std::optional<bool> m_useDarkAppearanceOverride;
+ std::optional<bool> m_useReducedMotionOverride;
#if ENABLE(TEXT_AUTOSIZING)
float m_textAutosizingWidth { 0 };
@@ -1279,6 +1297,11 @@ private:
#endif
std::optional<ViewportArguments> m_overrideViewportArguments;
+ std::optional<FloatSize> m_overrideScreenSize;
+
+#if ENABLE(ORIENTATION_EVENTS)
+ std::optional<int> m_overrideOrientation;
+#endif
#if ENABLE(DEVICE_ORIENTATION) && PLATFORM(IOS_FAMILY)
RefPtr<DeviceOrientationUpdateProvider> m_deviceOrientationUpdateProvider;
diff --git a/Source/WebCore/page/PointerCaptureController.cpp b/Source/WebCore/page/PointerCaptureController.cpp
index 88c3ca9610ca27e2bfa8d548597170b990990897..21de65f197804a31bbc0bf1a1098579c5dc2bfd7 100644
--- a/Source/WebCore/page/PointerCaptureController.cpp
+++ b/Source/WebCore/page/PointerCaptureController.cpp
@@ -195,7 +195,7 @@ bool PointerCaptureController::preventsCompatibilityMouseEventsForIdentifier(Poi
return capturingData && capturingData->preventsCompatibilityMouseEvents;
}
-#if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS_FAMILY)
+#if ENABLE(TOUCH_EVENTS)
static bool hierarchyHasCapturingEventListeners(Element* target, const AtomString& eventName)
{
for (RefPtr<ContainerNode> currentNode = target; currentNode; currentNode = currentNode->parentInComposedTree()) {
@@ -476,7 +476,7 @@ void PointerCaptureController::cancelPointer(PointerID pointerId, const IntPoint
capturingData->pendingTargetOverride = nullptr;
capturingData->state = CapturingData::State::Cancelled;
-#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 8c911ca663507b61640a4e29245dabe79573c420..08cdd2bfea9f5ac19c8cc39dc80032e140828ca4 100644
--- a/Source/WebCore/page/PointerCaptureController.h
+++ b/Source/WebCore/page/PointerCaptureController.h
@@ -57,7 +57,7 @@ public:
RefPtr<PointerEvent> pointerEventForMouseEvent(const MouseEvent&, PointerID, const String& pointerType);
-#if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS_FAMILY)
+#if ENABLE(TOUCH_EVENTS)
void dispatchEventForTouchAtIndex(EventTarget&, const PlatformTouchEvent&, unsigned, bool isPrimary, WindowProxy&);
#endif
@@ -77,7 +77,7 @@ private:
RefPtr<Element> pendingTargetOverride;
RefPtr<Element> targetOverride;
-#if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS_FAMILY)
+#if ENABLE(TOUCH_EVENTS)
RefPtr<Element> previousTarget;
#endif
bool hasAnyElement() const {
diff --git a/Source/WebCore/page/RuntimeEnabledFeatures.cpp b/Source/WebCore/page/RuntimeEnabledFeatures.cpp
index 897d2a009752a4030659a88e8b16382e00ac2316..08bb3344c59a0462668762815473659ff005d363 100644
--- a/Source/WebCore/page/RuntimeEnabledFeatures.cpp
+++ b/Source/WebCore/page/RuntimeEnabledFeatures.cpp
@@ -61,7 +61,11 @@ RuntimeEnabledFeatures& RuntimeEnabledFeatures::sharedFeatures()
#if ENABLE(TOUCH_EVENTS)
bool RuntimeEnabledFeatures::touchEventsEnabled() const
{
- return m_touchEventsEnabled.value_or(screenHasTouchDevice());
+ return m_touchEventsEnabled.value_or(platformScreenHasTouchDevice());
+}
+bool RuntimeEnabledFeatures::isTouchPrimaryInputDevice() const
+{
+ return m_touchEventsEnabled.value_or(platformScreenIsTouchPrimaryInputDevice());
}
#endif
diff --git a/Source/WebCore/page/RuntimeEnabledFeatures.h b/Source/WebCore/page/RuntimeEnabledFeatures.h
index 687407911c5af4b3f5aca3b42c85a14f585a49d0..fc883c029e29277149b575b191f333ecdcc694fc 100644
--- a/Source/WebCore/page/RuntimeEnabledFeatures.h
+++ b/Source/WebCore/page/RuntimeEnabledFeatures.h
@@ -174,6 +174,7 @@ public:
void setMouseEventsSimulationEnabled(bool isEnabled) { m_mouseEventsSimulationEnabled = isEnabled; }
bool touchEventsEnabled() const;
void setTouchEventsEnabled(bool isEnabled) { m_touchEventsEnabled = isEnabled; }
+ bool isTouchPrimaryInputDevice() const;
#endif
bool pageAtRuleSupportEnabled() const { return m_pageAtRuleSupportEnabled; }
diff --git a/Source/WebCore/page/Screen.cpp b/Source/WebCore/page/Screen.cpp
index 7ac11c8289347e3a2f3e7316cf9e32932b9544ed..764b2d4fe36ac2e5588bd22595424ac11d42acd0 100644
--- a/Source/WebCore/page/Screen.cpp
+++ b/Source/WebCore/page/Screen.cpp
@@ -102,6 +102,8 @@ int Screen::availLeft() const
return 0;
if (RuntimeEnabledFeatures::sharedFeatures().webAPIStatisticsEnabled())
ResourceLoadObserver::shared().logScreenAPIAccessed(*frame->document(), ResourceLoadStatistics::ScreenAPI::AvailLeft);
+ if (frame->hasScreenSizeOverride())
+ return 0;
return static_cast<int>(screenAvailableRect(frame->view()).x());
}
@@ -112,6 +114,8 @@ int Screen::availTop() const
return 0;
if (RuntimeEnabledFeatures::sharedFeatures().webAPIStatisticsEnabled())
ResourceLoadObserver::shared().logScreenAPIAccessed(*frame->document(), ResourceLoadStatistics::ScreenAPI::AvailTop);
+ if (frame->hasScreenSizeOverride())
+ return 0;
return static_cast<int>(screenAvailableRect(frame->view()).y());
}
@@ -122,6 +126,8 @@ unsigned Screen::availHeight() const
return 0;
if (RuntimeEnabledFeatures::sharedFeatures().webAPIStatisticsEnabled())
ResourceLoadObserver::shared().logScreenAPIAccessed(*frame->document(), ResourceLoadStatistics::ScreenAPI::AvailHeight);
+ if (frame->hasScreenSizeOverride())
+ return static_cast<unsigned>(frame->screenSize().height());
return static_cast<unsigned>(screenAvailableRect(frame->view()).height());
}
@@ -132,6 +138,8 @@ unsigned Screen::availWidth() const
return 0;
if (RuntimeEnabledFeatures::sharedFeatures().webAPIStatisticsEnabled())
ResourceLoadObserver::shared().logScreenAPIAccessed(*frame->document(), ResourceLoadStatistics::ScreenAPI::AvailWidth);
+ if (frame->hasScreenSizeOverride())
+ return static_cast<unsigned>(frame->screenSize().width());
return static_cast<unsigned>(screenAvailableRect(frame->view()).width());
}
diff --git a/Source/WebCore/page/csp/ContentSecurityPolicy.cpp b/Source/WebCore/page/csp/ContentSecurityPolicy.cpp
index 882c974316404ffb3f35640922c7b032a60f8152..b76888b2d241f77b29276523fb3b1d49e52214b7 100644
--- a/Source/WebCore/page/csp/ContentSecurityPolicy.cpp
+++ b/Source/WebCore/page/csp/ContentSecurityPolicy.cpp
@@ -298,6 +298,8 @@ bool ContentSecurityPolicy::allowContentSecurityPolicySourceStarToMatchAnyProtoc
template<typename Predicate, typename... Args>
typename std::enable_if<!std::is_convertible<Predicate, ContentSecurityPolicy::ViolatedDirectiveCallback>::value, bool>::type ContentSecurityPolicy::allPoliciesWithDispositionAllow(Disposition disposition, Predicate&& predicate, Args&&... args) const
{
+ if (InspectorInstrumentation::shouldBypassCSP(m_scriptExecutionContext))
+ return true;
bool isReportOnly = disposition == ContentSecurityPolicy::Disposition::ReportOnly;
for (auto& policy : m_policies) {
if (policy->isReportOnly() != isReportOnly)
@@ -311,6 +313,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) {
@@ -327,6 +331,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/wpe/DragControllerWPE.cpp b/Source/WebCore/page/wpe/DragControllerWPE.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2549355fc55ca55d2b6917dbfd05999f0e5607b3
--- /dev/null
+++ b/Source/WebCore/page/wpe/DragControllerWPE.cpp
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2007-20 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "DragController.h"
+
+#include "DataTransfer.h"
+#include "Document.h"
+#include "DragData.h"
+#include "Editor.h"
+#include "Element.h"
+#include "Frame.h"
+#include "FrameDestructionObserverInlines.h"
+#include "Pasteboard.h"
+#include "markup.h"
+
+namespace WebCore {
+
+// FIXME: These values are straight out of DragControllerMac, so probably have
+// little correlation with Gdk standards...
+const int DragController::MaxOriginalImageArea = 1500 * 1500;
+const int DragController::DragIconRightInset = 7;
+const int DragController::DragIconBottomInset = 3;
+
+const float DragController::DragImageAlpha = 0.75f;
+
+bool DragController::isCopyKeyDown(const DragData& dragData)
+{
+ return dragData.flags().contains(DragApplicationFlags::IsCopyKeyDown);
+}
+
+std::optional<DragOperation> DragController::dragOperation(const DragData& dragData)
+{
+ // FIXME: This logic is incomplete
+ if (dragData.containsURL())
+ return DragOperation::Copy;
+
+ return std::nullopt;
+}
+
+const IntSize& DragController::maxDragImageSize()
+{
+ static const IntSize maxDragImageSize(200, 200);
+ return maxDragImageSize;
+}
+
+void DragController::cleanupAfterSystemDrag()
+{
+}
+
+void DragController::declareAndWriteDragImage(DataTransfer& dataTransfer, Element& element, const URL& url, const String& label)
+{
+ Frame* frame = element.document().frame();
+ ASSERT(frame);
+ frame->editor().writeImageToPasteboard(dataTransfer.pasteboard(), element, url, label);
+}
+
+}
diff --git a/Source/WebCore/platform/Cairo.cmake b/Source/WebCore/platform/Cairo.cmake
index 1fb0e9d5cee3b3df4ee1e96eb8d75016ad687fc5..497bd34cc97e2d20c9d6982a8d92d852451743cd 100644
--- a/Source/WebCore/platform/Cairo.cmake
+++ b/Source/WebCore/platform/Cairo.cmake
@@ -16,6 +16,7 @@ list(APPEND WebCore_PRIVATE_FRAMEWORK_HEADERS
platform/graphics/cairo/ImageBufferCairoBackend.h
platform/graphics/cairo/ImageBufferCairoImageSurfaceBackend.h
platform/graphics/cairo/ImageBufferCairoSurfaceBackend.h
+ platform/graphics/cairo/ImageBufferUtilitiesCairo.h
platform/graphics/cairo/RefPtrCairo.h
)
diff --git a/Source/WebCore/platform/DragData.h b/Source/WebCore/platform/DragData.h
index 6600dfa7b189e15fab7fb796f66ef1a79dcd22f3..4c0bc485ca92614efca23a5a2da871b77d5285d3 100644
--- a/Source/WebCore/platform/DragData.h
+++ b/Source/WebCore/platform/DragData.h
@@ -48,7 +48,7 @@ typedef void* DragDataRef;
#elif PLATFORM(WIN)
typedef struct IDataObject* DragDataRef;
-#elif PLATFORM(GTK)
+#elif PLATFORM(GTK) || PLATFORM(WPE)
namespace WebCore {
class SelectionData;
}
diff --git a/Source/WebCore/platform/DragImage.cpp b/Source/WebCore/platform/DragImage.cpp
index 9e97dd5f689e6a1a90c9069445dc3f4b8c45e840..cc3ddc3e6d656a91c5ed58e050483d37e36d015a 100644
--- a/Source/WebCore/platform/DragImage.cpp
+++ b/Source/WebCore/platform/DragImage.cpp
@@ -279,7 +279,7 @@ DragImage::~DragImage()
deleteDragImage(m_dragImageRef);
}
-#if !PLATFORM(COCOA) && !PLATFORM(GTK) && !PLATFORM(WIN)
+#if !PLATFORM(COCOA) && !PLATFORM(GTK) && !PLATFORM(WIN) && !PLATFORM(WPE)
IntSize dragImageSize(DragImageRef)
{
diff --git a/Source/WebCore/platform/Pasteboard.h b/Source/WebCore/platform/Pasteboard.h
index 6c8bff431b593b2443e411381f634e417f71cf06..c48473c936e9f7d997db8006770ae1488e1b2a1f 100644
--- a/Source/WebCore/platform/Pasteboard.h
+++ b/Source/WebCore/platform/Pasteboard.h
@@ -44,7 +44,7 @@ OBJC_CLASS NSString;
OBJC_CLASS NSArray;
#endif
-#if PLATFORM(GTK)
+#if PLATFORM(GTK) || PLATFORM(WPE)
#include "SelectionData.h"
#endif
@@ -92,16 +92,12 @@ struct PasteboardWebContent {
Vector<String> clientTypes;
Vector<RefPtr<SharedBuffer>> clientData;
#endif
-#if PLATFORM(GTK)
+#if PLATFORM(GTK) || PLATFORM(WPE)
String contentOrigin;
bool canSmartCopyOrDelete;
String text;
String markup;
#endif
-#if USE(LIBWPE)
- String text;
- String markup;
-#endif
};
struct PasteboardURL {
@@ -110,7 +106,7 @@ struct PasteboardURL {
#if PLATFORM(MAC)
String userVisibleForm;
#endif
-#if PLATFORM(GTK)
+#if PLATFORM(GTK) || PLATFORM(WPE)
String markup;
#endif
};
@@ -200,6 +196,11 @@ public:
#endif
#endif
+#if PLATFORM(WPE) && ENABLE(DRAG_SUPPORT)
+ explicit Pasteboard(std::unique_ptr<PasteboardContext>&&, SelectionData&);
+ explicit Pasteboard(std::unique_ptr<PasteboardContext>&&, SelectionData&&);
+#endif
+
#if PLATFORM(WIN)
explicit Pasteboard(std::unique_ptr<PasteboardContext>&&, IDataObject*);
explicit Pasteboard(std::unique_ptr<PasteboardContext>&&, WCDataObject*);
@@ -266,6 +267,12 @@ public:
static std::unique_ptr<Pasteboard> createForGlobalSelection(std::unique_ptr<PasteboardContext>&&);
#endif
+#if PLATFORM(WPE)
+ const SelectionData& selectionData() const {
+ return *m_selectionData;
+ }
+#endif
+
#if PLATFORM(IOS_FAMILY)
explicit Pasteboard(std::unique_ptr<PasteboardContext>&&, int64_t changeCount);
explicit Pasteboard(std::unique_ptr<PasteboardContext>&&, const String& pasteboardName);
@@ -300,6 +307,7 @@ public:
COMPtr<IDataObject> dataObject() const { return m_dataObject; }
void setExternalDataObject(IDataObject*);
const DragDataMap& dragDataMap() const { return m_dragDataMap; }
+ WEBCORE_EXPORT DragDataMap createDragDataMap();
void writeURLToWritableDataObject(const URL&, const String&);
COMPtr<WCDataObject> writableDataObject() const { return m_writableDataObject; }
void writeImageToDataObject(Element&, const URL&); // FIXME: Layering violation.
@@ -351,6 +359,10 @@ private:
String m_name;
#endif
+#if PLATFORM(WPE)
+ std::optional<SelectionData> m_selectionData;
+#endif
+
#if PLATFORM(COCOA)
String m_pasteboardName;
int64_t m_changeCount;
@@ -366,6 +378,7 @@ private:
COMPtr<IDataObject> m_dataObject;
COMPtr<WCDataObject> m_writableDataObject;
DragDataMap m_dragDataMap;
+ bool m_forDrag = false;
#endif
};
diff --git a/Source/WebCore/platform/PlatformKeyboardEvent.h b/Source/WebCore/platform/PlatformKeyboardEvent.h
index 1d3edd9585338828c7074fd8389e437c16c42d92..0f4b5b074f6c95919a09567bd1338577c0930627 100644
--- a/Source/WebCore/platform/PlatformKeyboardEvent.h
+++ b/Source/WebCore/platform/PlatformKeyboardEvent.h
@@ -134,6 +134,7 @@ namespace WebCore {
static String keyCodeForHardwareKeyCode(unsigned);
static String keyIdentifierForGdkKeyCode(unsigned);
static int windowsKeyCodeForGdkKeyCode(unsigned);
+ static unsigned gdkKeyCodeForWindowsKeyCode(int);
static String singleCharacterString(unsigned);
static bool modifiersContainCapsLock(unsigned);
#endif
@@ -143,6 +144,7 @@ namespace WebCore {
static String keyCodeForHardwareKeyCode(unsigned);
static String keyIdentifierForWPEKeyCode(unsigned);
static int windowsKeyCodeForWPEKeyCode(unsigned);
+ static unsigned WPEKeyCodeForWindowsKeyCode(int);
static String singleCharacterString(unsigned);
#endif
diff --git a/Source/WebCore/platform/PlatformScreen.cpp b/Source/WebCore/platform/PlatformScreen.cpp
index ba50b688ab6d0bae5d199fa0bac4b7e2004baf81..0b83a798b00835635a95a0db22173de094ba4035 100644
--- a/Source/WebCore/platform/PlatformScreen.cpp
+++ b/Source/WebCore/platform/PlatformScreen.cpp
@@ -25,6 +25,7 @@
#include "config.h"
#include "PlatformScreen.h"
+#include "RuntimeEnabledFeatures.h"
#if PLATFORM(COCOA)
@@ -72,3 +73,16 @@ const ScreenData* screenData(PlatformDisplayID screenDisplayID)
} // namespace WebCore
#endif // PLATFORM(COCOA)
+
+#if ENABLE(TOUCH_EVENTS)
+namespace WebCore {
+
+bool screenHasTouchDevice() {
+ return RuntimeEnabledFeatures::sharedFeatures().touchEventsEnabled();
+}
+bool screenIsTouchPrimaryInputDevice() {
+ return RuntimeEnabledFeatures::sharedFeatures().isTouchPrimaryInputDevice();
+}
+
+} // namespace WebCore
+#endif
diff --git a/Source/WebCore/platform/PlatformScreen.h b/Source/WebCore/platform/PlatformScreen.h
index 44799e0b2a93cbcf25f4315d62a3d95896c02f3d..29277223448a0936a16f975970ab60d739b000cd 100644
--- a/Source/WebCore/platform/PlatformScreen.h
+++ b/Source/WebCore/platform/PlatformScreen.h
@@ -151,12 +151,14 @@ WEBCORE_EXPORT float screenScaleFactor(UIScreen * = nullptr);
#endif
#if ENABLE(TOUCH_EVENTS)
-#if PLATFORM(GTK) || PLATFORM(WPE)
WEBCORE_EXPORT bool screenHasTouchDevice();
WEBCORE_EXPORT bool screenIsTouchPrimaryInputDevice();
+#if PLATFORM(GTK) || PLATFORM(WPE)
+bool platformScreenHasTouchDevice();
+bool platformScreenIsTouchPrimaryInputDevice();
#else
-constexpr bool screenHasTouchDevice() { return true; }
-constexpr bool screenIsTouchPrimaryInputDevice() { return true; }
+constexpr bool platformScreenHasTouchDevice() { return true; }
+constexpr bool platformScreenIsTouchPrimaryInputDevice() { return true; }
#endif
#endif
diff --git a/Source/WebCore/platform/ScrollableArea.h b/Source/WebCore/platform/ScrollableArea.h
index 78a23f64c6bd7bdfe37c41b77dc5682e868f6233..fff6c69423d9709e8142c6549db5d798a7a71ae6 100644
--- a/Source/WebCore/platform/ScrollableArea.h
+++ b/Source/WebCore/platform/ScrollableArea.h
@@ -102,7 +102,7 @@ public:
void stopKeyboardScrollAnimation();
#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/SourcesGLib.txt b/Source/WebCore/platform/SourcesGLib.txt
index 53f48ba8ad99364680457daf4dcbae632360be12..8825859d561113f14ba6ef8d860c5202d2fbd253 100644
--- a/Source/WebCore/platform/SourcesGLib.txt
+++ b/Source/WebCore/platform/SourcesGLib.txt
@@ -33,6 +33,7 @@ platform/glib/LowPowerModeNotifierGLib.cpp
platform/glib/RemoteCommandListenerGLib.cpp
platform/glib/SharedBufferGlib.cpp
platform/glib/UserAgentGLib.cpp
+platform/glib/PlatformSpeechSynthesizerGLib.cpp
platform/network/glib/DNSResolveQueueGLib.cpp
platform/network/glib/NetworkStateNotifierGLib.cpp
diff --git a/Source/WebCore/platform/glib/PlatformSpeechSynthesizerGLib.cpp b/Source/WebCore/platform/glib/PlatformSpeechSynthesizerGLib.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f0c3a183e5bc44bdfa4201e0db2067b41bf51580
--- /dev/null
+++ b/Source/WebCore/platform/glib/PlatformSpeechSynthesizerGLib.cpp
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+#import "PlatformSpeechSynthesizer.h"
+
+#if ENABLE(SPEECH_SYNTHESIS)
+
+namespace WebCore {
+
+PlatformSpeechSynthesizer::PlatformSpeechSynthesizer(PlatformSpeechSynthesizerClient* client)
+ : m_speechSynthesizerClient(client)
+{
+}
+
+PlatformSpeechSynthesizer::~PlatformSpeechSynthesizer()
+{
+}
+
+void PlatformSpeechSynthesizer::initializeVoiceList()
+{
+}
+
+void PlatformSpeechSynthesizer::pause()
+{
+}
+
+void PlatformSpeechSynthesizer::resume()
+{
+}
+
+void PlatformSpeechSynthesizer::speak(RefPtr<PlatformSpeechSynthesisUtterance>&& utterance)
+{
+}
+
+void PlatformSpeechSynthesizer::cancel()
+{
+}
+
+void PlatformSpeechSynthesizer::resetState()
+{
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(SPEECH_SYNTHESIS)
diff --git a/Source/WebCore/platform/graphics/FontCascade.h b/Source/WebCore/platform/graphics/FontCascade.h
index b9f5a43f03f9708014d5f9fbf043b16357f4878e..58ab030548916e850d9fa1c28f97e5f596bf41bf 100644
--- a/Source/WebCore/platform/graphics/FontCascade.h
+++ b/Source/WebCore/platform/graphics/FontCascade.h
@@ -308,7 +308,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 fab94e0ac0f4ab8f7d7decec53adb1f3ac7a6e07..56193e30522a6fe87e1a7bf01beeae9b9fdb5fbf 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, std::optional<double>)
+static Vector<uint8_t> encodeJpeg(cairo_surface_t* image, int quality)
+{
+ if (cairo_surface_get_type(image) != CAIRO_SURFACE_TYPE_IMAGE) {
+ fprintf(stderr, "Unexpected cairo surface type: %d\n", cairo_surface_get_type(image));
+ return { };
+ }
+
+ if (cairo_image_surface_get_format(image) != CAIRO_FORMAT_ARGB32) {
+ fprintf(stderr, "Unexpected surface image format: %d\n", cairo_image_surface_get_format(image));
+ return { };
+ }
+
+ struct jpeg_compress_struct info;
+ struct jpeg_error_mgr error;
+ info.err = jpeg_std_error(&error);
+ jpeg_create_compress(&info);
+
+ unsigned char* bufferPtr = nullptr;
+ unsigned long bufferSize;
+ jpeg_mem_dest(&info, &bufferPtr, &bufferSize);
+ info.image_width = cairo_image_surface_get_width(image);
+ info.image_height = cairo_image_surface_get_height(image);
+
+#ifndef LIBJPEG_TURBO_VERSION
+ COMPILE_ASSERT(false, only_libjpeg_turbo_is_supported);
+#endif
+
+#if CPU(LITTLE_ENDIAN)
+ info.in_color_space = JCS_EXT_BGRA;
+#else
+ info.in_color_space = JCS_EXT_ARGB;
+#endif
+ // # of color components in input image
+ info.input_components = 4;
+
+ jpeg_set_defaults(&info);
+ jpeg_set_quality(&info, quality, true);
+
+ jpeg_start_compress(&info, true);
+
+ while (info.next_scanline < info.image_height)
+ {
+ JSAMPROW row = cairo_image_surface_get_data(image) + (info.next_scanline * cairo_image_surface_get_stride(image));
+ if (jpeg_write_scanlines(&info, &row, 1) != 1) {
+ fprintf(stderr, "JPEG library failed to encode line\n");
+ break;
+ }
+ }
+
+ jpeg_finish_compress(&info);
+ jpeg_destroy_compress(&info);
+
+ Vector<uint8_t> output;
+ output.append(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, std::optional<double> quality)
{
+ if (mimeType == "image/jpeg"_s) {
+ int qualityPercent = 100;
+ if (quality)
+ qualityPercent = static_cast<int>(*quality * 100.0 + 0.5);
+ return encodeJpeg(image, qualityPercent);
+ }
+
Vector<uint8_t> encodedImage;
if (!image || !encodeImage(image, mimeType, &encodedImage))
return { };
diff --git a/Source/WebCore/platform/graphics/cg/ImageBufferUtilitiesCG.h b/Source/WebCore/platform/graphics/cg/ImageBufferUtilitiesCG.h
index 8677d106bf2d0f53044b47fba0e6736efcd3aeb6..9b28f9d917536d2c2699f613adf296bbdd965969 100644
--- a/Source/WebCore/platform/graphics/cg/ImageBufferUtilitiesCG.h
+++ b/Source/WebCore/platform/graphics/cg/ImageBufferUtilitiesCG.h
@@ -36,10 +36,10 @@ class PixelBuffer;
WEBCORE_EXPORT uint8_t verifyImageBufferIsBigEnough(const void* buffer, size_t bufferSize);
-CFStringRef jpegUTI();
+WEBCORE_EXPORT CFStringRef jpegUTI();
WEBCORE_EXPORT RetainPtr<CFStringRef> utiFromImageBufferMIMEType(const String&);
-Vector<uint8_t> data(CGImageRef, CFStringRef destinationUTI, std::optional<double> quality);
+WEBCORE_EXPORT Vector<uint8_t> data(CGImageRef, CFStringRef destinationUTI, std::optional<double> quality);
Vector<uint8_t> data(const PixelBuffer&, const String& mimeType, std::optional<double> quality);
WEBCORE_EXPORT String dataURL(CGImageRef, CFStringRef destinationUTI, const String& mimeType, std::optional<double> quality);
diff --git a/Source/WebCore/platform/graphics/filters/software/FEComponentTransferSoftwareApplier.h b/Source/WebCore/platform/graphics/filters/software/FEComponentTransferSoftwareApplier.h
index b60f9a64bacc8282860da6de299b75aeb295b9b5..55bd017c03c6478ca334bd5ef164160fef5d5302 100644
--- a/Source/WebCore/platform/graphics/filters/software/FEComponentTransferSoftwareApplier.h
+++ b/Source/WebCore/platform/graphics/filters/software/FEComponentTransferSoftwareApplier.h
@@ -23,6 +23,7 @@
#pragma once
#include "FilterEffectApplier.h"
+#include "PixelBuffer.h"
namespace WebCore {
diff --git a/Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGLBase.cpp b/Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGLBase.cpp
index ce40cc903f98688cbd2da28c0f0ed6660ce38b52..808e5e68f6abafc3a200f6c2d7cd12c9f34be473 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(WEBGL) && USE(OPENGL)
+#if !PLATFORM(WIN) && ENABLE(WEBGL) && USE(OPENGL)
#include "ByteArrayPixelBuffer.h"
#include "ExtensionsGLOpenGL.h"
diff --git a/Source/WebCore/platform/graphics/win/ComplexTextControllerUniscribe.cpp b/Source/WebCore/platform/graphics/win/ComplexTextControllerUniscribe.cpp
index 6d6820fc22f9a7102bbdad6c4b5e3e7e9645f66c..f44797b8c197bf1b3daaa9b59dad2a8e250c4791 100644
--- a/Source/WebCore/platform/graphics/win/ComplexTextControllerUniscribe.cpp
+++ b/Source/WebCore/platform/graphics/win/ComplexTextControllerUniscribe.cpp
@@ -170,6 +170,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) {
@@ -199,6 +226,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 dd5fb8634277baea92be6ecaf6d2fbc7ce7ee9f0..9aa9e4d923d487cd4003e7396ebe61c7df51057d 100644
--- a/Source/WebCore/platform/gtk/PlatformKeyboardEventGtk.cpp
+++ b/Source/WebCore/platform/gtk/PlatformKeyboardEventGtk.cpp
@@ -37,8 +37,10 @@
#include <gdk/gdk.h>
#include <gdk/gdkkeysyms.h>
#include <pal/text/TextEncoding.h>
+#include <wtf/HashMap.h>
#include <wtf/HexNumber.h>
#include <wtf/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/gtk/PlatformScreenGtk.cpp b/Source/WebCore/platform/gtk/PlatformScreenGtk.cpp
index 80958ba565a877224d0ed37e4e4057b4be0dde24..eca42bf5181bc4a95efca9c9c3f5ce0f987fea43 100644
--- a/Source/WebCore/platform/gtk/PlatformScreenGtk.cpp
+++ b/Source/WebCore/platform/gtk/PlatformScreenGtk.cpp
@@ -224,7 +224,7 @@ bool screenSupportsExtendedColor(Widget*)
}
#if ENABLE(TOUCH_EVENTS)
-bool screenHasTouchDevice()
+bool platformScreenHasTouchDevice()
{
auto* display = gdk_display_get_default();
if (!display)
@@ -234,7 +234,7 @@ bool screenHasTouchDevice()
return seat ? gdk_seat_get_capabilities(seat) & GDK_SEAT_CAPABILITY_TOUCH : true;
}
-bool screenIsTouchPrimaryInputDevice()
+bool platformScreenIsTouchPrimaryInputDevice()
{
auto* display = gdk_display_get_default();
if (!display)
diff --git a/Source/WebCore/platform/libwpe/PasteboardLibWPE.cpp b/Source/WebCore/platform/libwpe/PasteboardLibWPE.cpp
index ae439e30f1fb239d18e1164e8896dfb272c75673..c004d77c162f87701278fa1ada9200b92a8e7838 100644
--- a/Source/WebCore/platform/libwpe/PasteboardLibWPE.cpp
+++ b/Source/WebCore/platform/libwpe/PasteboardLibWPE.cpp
@@ -32,6 +32,10 @@
#include "PasteboardStrategy.h"
#include "PlatformStrategies.h"
+#if ENABLE(DRAG_SUPPORT)
+#include "DragData.h"
+#endif
+
namespace WebCore {
std::unique_ptr<Pasteboard> Pasteboard::createForCopyAndPaste(std::unique_ptr<PasteboardContext>&& context)
@@ -73,6 +77,16 @@ String Pasteboard::readOrigin()
String Pasteboard::readString(const String& type)
{
+ if (m_selectionData) {
+ if (type == "text/plain"_s)
+ return m_selectionData->text();;
+ if (type == "text/html"_s)
+ return m_selectionData->markup();
+ if (type == "Files"_s || type == "text/uri-list"_s)
+ return m_selectionData->uriList();
+ return { };
+ }
+
return platformStrategies()->pasteboardStrategy()->readStringFromPasteboard(0, type, name(), context());
}
@@ -84,6 +98,15 @@ String Pasteboard::readStringInCustomData(const String&)
void Pasteboard::writeString(const String& type, const String& text)
{
+ if (m_selectionData) {
+ if (type == "Files"_s || type == "text/uri-list"_s)
+ m_selectionData->setURIList(text);
+ else if (type == "text/html"_s)
+ m_selectionData->setMarkup(text);
+ else if (type == "text/plain"_s)
+ m_selectionData->setText(text);
+ return;
+ }
platformStrategies()->pasteboardStrategy()->writeToPasteboard(type, text);
}
@@ -111,7 +134,12 @@ void Pasteboard::read(PasteboardFileReader&, std::optional<size_t>)
void Pasteboard::write(const PasteboardURL& url)
{
- platformStrategies()->pasteboardStrategy()->writeToPasteboard("text/plain;charset=utf-8"_s, url.url.string());
+ if (m_selectionData) {
+ m_selectionData->clearAll();
+ m_selectionData->setURL(url.url, url.title);
+ } else {
+ platformStrategies()->pasteboardStrategy()->writeToPasteboard("text/plain;charset=utf-8"_s, url.url.string());
+ }
}
void Pasteboard::writeTrustworthyWebURLsPboardType(const PasteboardURL&)
@@ -119,8 +147,16 @@ void Pasteboard::writeTrustworthyWebURLsPboardType(const PasteboardURL&)
notImplemented();
}
-void Pasteboard::write(const PasteboardImage&)
+void Pasteboard::write(const PasteboardImage& pasteboardImage)
{
+ if (m_selectionData) {
+ m_selectionData->clearAll();
+ if (!pasteboardImage.url.url.isEmpty()) {
+ m_selectionData->setURL(pasteboardImage.url.url, pasteboardImage.url.title);
+ m_selectionData->setMarkup(pasteboardImage.url.markup);
+ }
+ m_selectionData->setImage(pasteboardImage.image.get());
+ }
}
void Pasteboard::write(const PasteboardBuffer&)
@@ -129,7 +165,14 @@ void Pasteboard::write(const PasteboardBuffer&)
void Pasteboard::write(const PasteboardWebContent& content)
{
- platformStrategies()->pasteboardStrategy()->writeToPasteboard(content);
+ if (m_selectionData) {
+ m_selectionData->clearAll();
+ m_selectionData->setText(content.text);
+ m_selectionData->setMarkup(content.markup);
+ m_selectionData->setCanSmartReplace(content.canSmartCopyOrDelete);
+ } else {
+ platformStrategies()->pasteboardStrategy()->writeToPasteboard(content);
+ }
}
Pasteboard::FileContentState Pasteboard::fileContentState()
@@ -160,6 +203,35 @@ void Pasteboard::write(const Color&)
{
}
+#if ENABLE(DRAG_SUPPORT)
+
+Pasteboard::Pasteboard(std::unique_ptr<PasteboardContext>&& context, SelectionData&& selectionData)
+ : m_context(WTFMove(context))
+ , m_selectionData(WTFMove(selectionData))
+{
+}
+
+Pasteboard::Pasteboard(std::unique_ptr<PasteboardContext>&& context, SelectionData& selectionData)
+ : m_context(WTFMove(context))
+ , m_selectionData(selectionData)
+{
+}
+
+std::unique_ptr<Pasteboard> Pasteboard::createForDragAndDrop(std::unique_ptr<PasteboardContext>&& context)
+{
+ return makeUnique<Pasteboard>(WTFMove(context), SelectionData());
+}
+
+std::unique_ptr<Pasteboard> Pasteboard::create(const DragData& dragData)
+{
+ RELEASE_ASSERT(dragData.platformData());
+ return makeUnique<Pasteboard>(dragData.createPasteboardContext(), *dragData.platformData());
+}
+void Pasteboard::setDragImage(DragImage, const IntPoint&)
+{
+}
+#endif
+
} // namespace WebCore
#endif // USE(LIBWPE)
diff --git a/Source/WebCore/platform/libwpe/PlatformKeyboardEventLibWPE.cpp b/Source/WebCore/platform/libwpe/PlatformKeyboardEventLibWPE.cpp
index a724f126f8f389d46ba5c1a941eef76fdc59c94c..aa40f6c3ee81213074639cce1d18eb21c6e204f4 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/HTTPHeaderMap.cpp b/Source/WebCore/platform/network/HTTPHeaderMap.cpp
index f169677e661510b225b899c79b68d040179a097a..420e101c7bb7a49b5c644076a8a2ffab2282d758 100644
--- a/Source/WebCore/platform/network/HTTPHeaderMap.cpp
+++ b/Source/WebCore/platform/network/HTTPHeaderMap.cpp
@@ -229,8 +229,11 @@ void HTTPHeaderMap::add(HTTPHeaderName name, const String& value)
auto index = m_commonHeaders.findIf([&](auto& header) {
return header.key == name;
});
+ // Align with Chromium and Firefox, but just for SetCookies where it is critical:
+ // https://bit.ly/2HCa0iq
+ String separator = name == HTTPHeaderName::SetCookie ? "\n "_s : ", "_s;
if (index != notFound)
- m_commonHeaders[index].value = makeString(m_commonHeaders[index].value, ", ", value);
+ m_commonHeaders[index].value = makeString(m_commonHeaders[index].value, separator, value);
else
m_commonHeaders.append(CommonHeader { name, value });
}
diff --git a/Source/WebCore/platform/network/NetworkStorageSession.h b/Source/WebCore/platform/network/NetworkStorageSession.h
index cad5fdc361c1ae84f56e0c8cba754ede9b70450f..64ba38b5a05202ae2ec5ec4d244177a7b169e569 100644
--- a/Source/WebCore/platform/network/NetworkStorageSession.h
+++ b/Source/WebCore/platform/network/NetworkStorageSession.h
@@ -156,6 +156,8 @@ public:
NetworkingContext* context() const;
#endif
+ WEBCORE_EXPORT void setCookiesFromResponse(const URL& firstParty, const SameSiteInfo&, const URL&, const String& setCookieValue);
+
WEBCORE_EXPORT HTTPCookieAcceptPolicy cookieAcceptPolicy() const;
WEBCORE_EXPORT void setCookie(const Cookie&);
WEBCORE_EXPORT void setCookies(const Vector<Cookie>&, const URL&, const URL& mainDocumentURL);
diff --git a/Source/WebCore/platform/network/ResourceResponseBase.h b/Source/WebCore/platform/network/ResourceResponseBase.h
index cd8cde01d0bbb527983cee06f1759ff35bea2f9a..c87610f9a3386d518b3cf8529a42d61dbac200b1 100644
--- a/Source/WebCore/platform/network/ResourceResponseBase.h
+++ b/Source/WebCore/platform/network/ResourceResponseBase.h
@@ -224,6 +224,8 @@ public:
WEBCORE_EXPORT static ResourceResponse dataURLResponse(const URL&, const DataURLDecoder::Result&);
+ HTTPHeaderMap m_httpRequestHeaderFields;
+
protected:
enum InitLevel {
Uninitialized,
@@ -303,6 +305,7 @@ void ResourceResponseBase::encode(Encoder& encoder) const
encoder << m_httpStatusText;
encoder << m_httpVersion;
encoder << m_httpHeaderFields;
+ encoder << m_httpRequestHeaderFields;
// We don't want to put the networkLoadMetrics info
// into the disk cache, because we will never use the old info.
@@ -375,6 +378,12 @@ bool ResourceResponseBase::decode(Decoder& decoder, ResourceResponseBase& respon
return false;
response.m_httpHeaderFields = WTFMove(*httpHeaderFields);
+ std::optional<HTTPHeaderMap> httpRequestHeaderFields;
+ decoder >> httpRequestHeaderFields;
+ if (!httpRequestHeaderFields)
+ return false;
+ response.m_httpRequestHeaderFields = WTFMove(*httpRequestHeaderFields);
+
// The networkLoadMetrics info is only send over IPC and not stored in disk cache.
if constexpr (Decoder::isIPCDecoder) {
std::optional<Box<NetworkLoadMetrics>> networkLoadMetrics;
diff --git a/Source/WebCore/platform/network/cocoa/NetworkStorageSessionCocoa.mm b/Source/WebCore/platform/network/cocoa/NetworkStorageSessionCocoa.mm
index a32a938cceed433559c00e15c72f6a47465ec575..1759e5d76989670705100cb3427a79b5ce35b761 100644
--- a/Source/WebCore/platform/network/cocoa/NetworkStorageSessionCocoa.mm
+++ b/Source/WebCore/platform/network/cocoa/NetworkStorageSessionCocoa.mm
@@ -479,6 +479,22 @@ void NetworkStorageSession::setCookiesFromDOM(const URL& firstParty, const SameS
END_BLOCK_OBJC_EXCEPTIONS
}
+void NetworkStorageSession::setCookiesFromResponse(const URL& firstParty, const SameSiteInfo& sameSiteInfo, const URL& url, const String& setCookieValue)
+{
+ Vector<String> cookieValues = setCookieValue.split('\n');
+ size_t count = cookieValues.size();
+ auto* cookies = [NSMutableArray arrayWithCapacity:count];
+ for (const auto& cookieValue : cookieValues) {
+ NSString* cookieString = (NSString *)cookieValue;
+ NSString* cookieKey = @"Set-Cookie";
+ NSDictionary* headers = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObject:cookieString] forKeys:[NSArray arrayWithObject:cookieKey]];
+ NSArray<NSHTTPCookie*>* parsedCookies = [NSHTTPCookie cookiesWithResponseHeaderFields:headers forURL:(NSURL *)url];
+ [cookies addObject:parsedCookies[0]];
+ }
+ NSURL *cookieURL = url;
+ setHTTPCookiesForURL(cookieStorage().get(), cookies, cookieURL, firstParty, sameSiteInfo);
+}
+
static NSHTTPCookieAcceptPolicy httpCookieAcceptPolicy(CFHTTPCookieStorageRef cookieStorage)
{
ASSERT(hasProcessPrivilege(ProcessPrivilege::CanAccessRawCookies));
diff --git a/Source/WebCore/platform/network/curl/CookieJarDB.h b/Source/WebCore/platform/network/curl/CookieJarDB.h
index dd0553966d670c398bb352730905def8a0a3f289..0622f8a2d217365cfa4ceb1b4cab58b898835f92 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 7a7aa8371394ab6a66a66392cef306daeafe6811..44dd345cb40cc887343ce36ff29fb5ffc5a1ed9e 100644
--- a/Source/WebCore/platform/network/curl/CurlStream.cpp
+++ b/Source/WebCore/platform/network/curl/CurlStream.cpp
@@ -34,7 +34,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)
{
@@ -46,6 +46,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 e8a32c26461b4308ea227c6df8c972439905d0bc..5da1a95615b04fca8402f53ecd7f05a006640372 100644
--- a/Source/WebCore/platform/network/curl/CurlStream.h
+++ b/Source/WebCore/platform/network/curl/CurlStream.h
@@ -51,12 +51,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 makeUnique<CurlStream>(scheduler, streamID, WTFMove(url));
+ return 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 d94ff4f9169a6c0b5adb9719f5506d0fb80e6f89..3f955607764d028807d150619bf7f49e08bc3e7e 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 0c39c90aac884fca48849388acc1b42bad16d620..dd8e50686c348b46d5ae92fd67a31eb0cbdb014f 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/NetworkStorageSessionCurl.cpp b/Source/WebCore/platform/network/curl/NetworkStorageSessionCurl.cpp
index 1b93415110a77d443d951890095c31fdadf889e9..b7682f0a2539b1a98c23e5391ec255f169768b32 100644
--- a/Source/WebCore/platform/network/curl/NetworkStorageSessionCurl.cpp
+++ b/Source/WebCore/platform/network/curl/NetworkStorageSessionCurl.cpp
@@ -118,6 +118,12 @@ void NetworkStorageSession::setCookieAcceptPolicy(CookieAcceptPolicy policy) con
cookieDatabase().setAcceptPolicy(policy);
}
+void NetworkStorageSession::setCookiesFromResponse(const URL& firstParty, const SameSiteInfo&, const URL& url, const String& setCookieValue)
+{
+ for (auto& cookieString : setCookieValue.split('\n'))
+ cookieDatabase().setCookie(firstParty, url, cookieString, CookieJarDB::Source::Network);
+}
+
HTTPCookieAcceptPolicy NetworkStorageSession::cookieAcceptPolicy() const
{
switch (cookieDatabase().acceptPolicy()) {
diff --git a/Source/WebCore/platform/network/curl/SocketStreamHandleImpl.h b/Source/WebCore/platform/network/curl/SocketStreamHandleImpl.h
index 950cd1b1ac6800212e8192b5cb53e69b34409111..58b1f55543f1bdcfc8e6b19b06633c0c4c45095a 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, bool) { return adoptRef(*new SocketStreamHandleImpl(url, client, provider)); }
+ static Ref<SocketStreamHandleImpl> create(const URL& url, SocketStreamHandleClient& client, PAL::SessionID, const String&, SourceApplicationAuditToken&&, const StorageSessionProvider* provider, bool ignoreCertificateErrors) { 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;
std::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 e106d2e9c4bdf2f099c34d61270ab1ab12e1b1bc..d1ffe11e4fc2a0bece55c4a70f4d1eef28c4dadb 100644
--- a/Source/WebCore/platform/network/curl/SocketStreamHandleImplCurl.cpp
+++ b/Source/WebCore/platform/network/curl/SocketStreamHandleImplCurl.cpp
@@ -44,7 +44,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())
@@ -53,7 +53,7 @@ SocketStreamHandleImpl::SocketStreamHandleImpl(const URL& url, SocketStreamHandl
if (m_url.protocolIs("wss"_s) && 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/NetworkStorageSessionSoup.cpp b/Source/WebCore/platform/network/soup/NetworkStorageSessionSoup.cpp
index 1c91f93595ab4362409762530880878e3804c2b8..8848c9d880f341d4a0de089ff0ddc1d0fdde5ea4 100644
--- a/Source/WebCore/platform/network/soup/NetworkStorageSessionSoup.cpp
+++ b/Source/WebCore/platform/network/soup/NetworkStorageSessionSoup.cpp
@@ -410,6 +410,30 @@ void NetworkStorageSession::setCookie(const Cookie& cookie)
soup_cookie_jar_add_cookie(cookieStorage(), cookie.toSoupCookie());
}
+void NetworkStorageSession::setCookiesFromResponse(const URL& firstParty, const SameSiteInfo&, const URL& url, const String& setCookieValue)
+{
+ auto origin = urlToSoupURI(url);
+ if (!origin)
+ return;
+
+ auto firstPartyURI = urlToSoupURI(firstParty);
+ if (!firstPartyURI)
+ return;
+
+ for (auto& cookieString : setCookieValue.split('\n')) {
+ GUniquePtr<SoupCookie> cookie(soup_cookie_parse(cookieString.utf8().data(), origin.get()));
+
+ if (!cookie)
+ continue;
+
+#if SOUP_CHECK_VERSION(2, 67, 1)
+ soup_cookie_jar_add_cookie_full(cookieStorage(), cookie.release(), origin.get(), firstPartyURI.get());
+#else
+ soup_cookie_jar_add_cookie_with_first_party(cookieStorage(), firstPartyURI.get(), cookie.release());
+#endif
+ }
+}
+
void NetworkStorageSession::deleteCookie(const Cookie& cookie, CompletionHandler<void()>&& completionHandler)
{
GUniquePtr<SoupCookie> targetCookie(cookie.toSoupCookie());
diff --git a/Source/WebCore/platform/win/ClipboardUtilitiesWin.cpp b/Source/WebCore/platform/win/ClipboardUtilitiesWin.cpp
index fdde3ee4f109b35c5b6766450a5aa3fd56619199..6d960bee81c15d0415c04616bb7715390a9a83e6 100644
--- a/Source/WebCore/platform/win/ClipboardUtilitiesWin.cpp
+++ b/Source/WebCore/platform/win/ClipboardUtilitiesWin.cpp
@@ -39,6 +39,7 @@
#include <wtf/text/StringBuilder.h>
#include <wtf/text/win/WCharStringExtras.h>
#include <wtf/unicode/CharacterNames.h>
+#include "Pasteboard.h"
namespace WebCore {
@@ -690,7 +691,10 @@ template<typename T> void getStringData(IDataObject* data, FORMATETC* format, Ve
STGMEDIUM store;
if (FAILED(data->GetData(format, &store)))
return;
- dataStrings.append(String(static_cast<T*>(GlobalLock(store.hGlobal)), ::GlobalSize(store.hGlobal) / sizeof(T)));
+ // The string here should be null terminated, but it could come from another app so lets lock it
+ // to the size to prevent an overflow.
+ String rawString = String(static_cast<T*>(GlobalLock(store.hGlobal)), ::GlobalSize(store.hGlobal) / sizeof(T));
+ dataStrings.append(String::fromUTF8(rawString.utf8().data()));
GlobalUnlock(store.hGlobal);
ReleaseStgMedium(&store);
}
diff --git a/Source/WebCore/platform/win/ClipboardUtilitiesWin.h b/Source/WebCore/platform/win/ClipboardUtilitiesWin.h
index c50799b63e05adbe32bae3535d786c7d268f980f..9cf1cc7ec4eaae22947f80ba272dfae272167bd6 100644
--- a/Source/WebCore/platform/win/ClipboardUtilitiesWin.h
+++ b/Source/WebCore/platform/win/ClipboardUtilitiesWin.h
@@ -34,6 +34,7 @@ namespace WebCore {
class Document;
class DocumentFragment;
+class Pasteboard;
HGLOBAL createGlobalData(const String&);
HGLOBAL createGlobalData(const Vector<char>&);
diff --git a/Source/WebCore/platform/win/DragDataWin.cpp b/Source/WebCore/platform/win/DragDataWin.cpp
index 207572d157ba2173c045e01da8f9b83b034c047e..6590bd36b23bdcbc947b191d2c011414655dfd68 100644
--- a/Source/WebCore/platform/win/DragDataWin.cpp
+++ b/Source/WebCore/platform/win/DragDataWin.cpp
@@ -48,6 +48,7 @@ DragData::DragData(const DragDataMap& data, const IntPoint& clientPosition, cons
, m_applicationFlags(flags)
, m_pageID(pageID)
, m_dragDataMap(data)
+ , m_dragDestinationActionMask(anyDragDestinationAction())
{
}
diff --git a/Source/WebCore/platform/win/KeyEventWin.cpp b/Source/WebCore/platform/win/KeyEventWin.cpp
index 05a0d1256a136982507b732c7852bbece201b513..f2c00eca40fbf3a88780610228f60ba6f8c1f441 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/platform/win/PasteboardWin.cpp b/Source/WebCore/platform/win/PasteboardWin.cpp
index 5e64d73381ec823978295aed1c40401ce54f0aa9..a34378d865208ddce94b829a6add7d1064f27a5d 100644
--- a/Source/WebCore/platform/win/PasteboardWin.cpp
+++ b/Source/WebCore/platform/win/PasteboardWin.cpp
@@ -1129,7 +1129,21 @@ void Pasteboard::writeCustomData(const Vector<PasteboardCustomData>& data)
}
clear();
+ if (m_dataObject) {
+ const auto& customData = data.first();
+ customData.forEachPlatformString([&](auto& type, auto& string) {
+ writeString(type, string);
+ });
+ if (customData.hasSameOriginCustomData() || !customData.origin().isEmpty()) {
+ customData.forEachCustomString([&](auto& type, auto& string) {
+ writeString(type, string);
+ });
+ }
+ return;
+ }
+
+ // this is the real real clipboard. Prbaobly need to be doing drag data stuff.
if (::OpenClipboard(m_owner)) {
const auto& customData = data.first();
customData.forEachPlatformStringOrBuffer([](auto& type, auto& stringOrBuffer) {
@@ -1168,4 +1182,25 @@ void Pasteboard::write(const Color&)
{
}
+DragDataMap Pasteboard::createDragDataMap() {
+ DragDataMap dragDataMap;
+ auto dragObject = dataObject();
+ if (!dragObject)
+ return dragDataMap;
+ // Enumerate clipboard content and load it in the map.
+ COMPtr<IEnumFORMATETC> itr;
+
+ if (FAILED(dragObject->EnumFormatEtc(DATADIR_GET, &itr)) || !itr)
+ return dragDataMap;
+
+ FORMATETC dataFormat;
+ while (itr->Next(1, &dataFormat, 0) == S_OK) {
+ Vector<String> dataStrings;
+ getClipboardData(dragObject.get(), &dataFormat, dataStrings);
+ if (!dataStrings.isEmpty())
+ dragDataMap.set(dataFormat.cfFormat, dataStrings);
+ }
+ return dragDataMap;
+}
+
} // namespace WebCore
diff --git a/Source/WebCore/platform/win/ScrollbarThemeWin.cpp b/Source/WebCore/platform/win/ScrollbarThemeWin.cpp
index e89ec9d83d8abc141938716f24eaba061a085af3..6005d02b9bf20ef2cbf9382fdf50c863952c8db5 100644
--- a/Source/WebCore/platform/win/ScrollbarThemeWin.cpp
+++ b/Source/WebCore/platform/win/ScrollbarThemeWin.cpp
@@ -114,8 +114,7 @@ static int scrollbarThicknessInPixels()
int ScrollbarThemeWin::scrollbarThickness(ScrollbarControlSize, ScrollbarExpansionState)
{
- float inverseScaleFactor = 1.0f / deviceScaleFactorForWindow(0);
- return clampTo<int>(inverseScaleFactor * scrollbarThicknessInPixels());
+ return 0;
}
void ScrollbarThemeWin::themeChanged()
diff --git a/Source/WebCore/platform/wpe/DragDataWPE.cpp b/Source/WebCore/platform/wpe/DragDataWPE.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..07fb260a5203167fdf94a552949394bb73ca8c61
--- /dev/null
+++ b/Source/WebCore/platform/wpe/DragDataWPE.cpp
@@ -0,0 +1,87 @@
+/*
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "DragData.h"
+#include "SelectionData.h"
+
+namespace WebCore {
+
+bool DragData::canSmartReplace() const
+{
+ return false;
+}
+
+bool DragData::containsColor() const
+{
+ return false;
+}
+
+bool DragData::containsFiles() const
+{
+ return m_platformDragData->hasFilenames();
+}
+
+unsigned DragData::numberOfFiles() const
+{
+ return m_platformDragData->filenames().size();
+}
+
+Vector<String> DragData::asFilenames() const
+{
+ return m_platformDragData->filenames();
+}
+
+bool DragData::containsPlainText() const
+{
+ return m_platformDragData->hasText();
+}
+
+String DragData::asPlainText() const
+{
+ return m_platformDragData->text();
+}
+
+Color DragData::asColor() const
+{
+ return Color();
+}
+
+bool DragData::containsCompatibleContent(DraggingPurpose) const
+{
+ return containsPlainText() || containsURL() || containsColor() || containsFiles();
+}
+
+bool DragData::containsURL(FilenameConversionPolicy filenamePolicy) const
+{
+ return !asURL(filenamePolicy).isEmpty();
+}
+
+String DragData::asURL(FilenameConversionPolicy filenamePolicy, String* title) const
+{
+ if (!m_platformDragData->hasURL())
+ return String();
+ if (filenamePolicy != ConvertFilenames) {
+ if (m_platformDragData->url().isLocalFile())
+ return { };
+ }
+
+ if (title)
+ *title = m_platformDragData->urlLabel();
+ return m_platformDragData->url().string();
+}
+
+}
diff --git a/Source/WebCore/platform/wpe/DragImageWPE.cpp b/Source/WebCore/platform/wpe/DragImageWPE.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e77e6db7a93a9dfcaad3866eb445edf4ebfe33b5
--- /dev/null
+++ b/Source/WebCore/platform/wpe/DragImageWPE.cpp
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2010,2017 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "DragImage.h"
+#include "NotImplemented.h"
+
+#include "Image.h"
+
+namespace WebCore {
+
+IntSize dragImageSize(DragImageRef)
+{
+ notImplemented();
+ return { 0, 0 };
+}
+
+void deleteDragImage(DragImageRef)
+{
+ notImplemented();
+}
+
+DragImageRef scaleDragImage(DragImageRef, FloatSize)
+{
+ notImplemented();
+ return nullptr;
+}
+
+DragImageRef dissolveDragImageToFraction(DragImageRef image, float)
+{
+ notImplemented();
+ return image;
+}
+
+DragImageRef createDragImageFromImage(Image* image, ImageOrientation)
+{
+ return image->nativeImageForCurrentFrame()->platformImage();
+}
+
+
+DragImageRef createDragImageIconForCachedImageFilename(const String&)
+{
+ notImplemented();
+ return nullptr;
+}
+
+DragImageRef createDragImageForLink(Element&, URL&, const String&, TextIndicatorData&, FontRenderingMode, float)
+{
+ notImplemented();
+ return nullptr;
+}
+
+DragImageRef createDragImageForColor(const Color&, const FloatRect&, float, Path&)
+{
+ return nullptr;
+}
+
+}
diff --git a/Source/WebCore/platform/wpe/PlatformScreenWPE.cpp b/Source/WebCore/platform/wpe/PlatformScreenWPE.cpp
index bbdd1ce76241d933ada9c43fabae4912cbfa64e1..e6ae01a77350c519b203f6ed2910f63871b9b829 100644
--- a/Source/WebCore/platform/wpe/PlatformScreenWPE.cpp
+++ b/Source/WebCore/platform/wpe/PlatformScreenWPE.cpp
@@ -93,12 +93,12 @@ bool screenSupportsExtendedColor(Widget*)
}
#if ENABLE(TOUCH_EVENTS)
-bool screenHasTouchDevice()
+bool platformScreenHasTouchDevice()
{
return true;
}
-bool screenIsTouchPrimaryInputDevice()
+bool platformScreenIsTouchPrimaryInputDevice()
{
return true;
}
diff --git a/Source/WebCore/platform/wpe/SelectionData.cpp b/Source/WebCore/platform/wpe/SelectionData.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2a461c25464ec787513369527743671d34f56709
--- /dev/null
+++ b/Source/WebCore/platform/wpe/SelectionData.cpp
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2009, Martin Robinson
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "SelectionData.h"
+
+#include <wtf/glib/GUniquePtr.h>
+#include <wtf/text/CString.h>
+#include <wtf/text/StringBuilder.h>
+
+namespace WebCore {
+
+static void replaceNonBreakingSpaceWithSpace(String& str)
+{
+ static const UChar NonBreakingSpaceCharacter = 0xA0;
+ static const UChar SpaceCharacter = ' ';
+ str = makeStringByReplacingAll(str, NonBreakingSpaceCharacter, SpaceCharacter);
+}
+
+void SelectionData::setText(const String& newText)
+{
+ m_text = newText;
+ replaceNonBreakingSpaceWithSpace(m_text);
+}
+
+void SelectionData::setURIList(const String& uriListString)
+{
+ m_uriList = uriListString;
+
+ // This code is originally from: platform/chromium/ChromiumDataObject.cpp.
+ // FIXME: We should make this code cross-platform eventually.
+
+ // Line separator is \r\n per RFC 2483 - however, for compatibility
+ // reasons we also allow just \n here.
+
+ // Process the input and copy the first valid URL into the url member.
+ // In case no URLs can be found, subsequent calls to getData("URL")
+ // will get an empty string. This is in line with the HTML5 spec (see
+ // "The DragEvent and DataTransfer interfaces"). Also extract all filenames
+ // from the URI list.
+ bool setURL = hasURL();
+ for (auto& line : uriListString.split('\n')) {
+ line = line.stripWhiteSpace();
+ if (line.isEmpty())
+ continue;
+ if (line[0] == '#')
+ continue;
+
+ URL url = URL(URL(), line);
+ if (url.isValid()) {
+ if (!setURL) {
+ m_url = url;
+ setURL = true;
+ }
+
+ GUniqueOutPtr<GError> error;
+ GUniquePtr<gchar> filename(g_filename_from_uri(line.utf8().data(), 0, &error.outPtr()));
+ if (!error && filename)
+ m_filenames.append(String::fromUTF8(filename.get()));
+ }
+ }
+}
+
+void SelectionData::setURL(const URL& url, const String& label)
+{
+ m_url = url;
+ if (m_uriList.isEmpty())
+ m_uriList = url.string();
+
+ if (!hasText())
+ setText(url.string());
+
+ if (hasMarkup())
+ return;
+
+ String actualLabel(label);
+ if (actualLabel.isEmpty())
+ actualLabel = url.string();
+
+ StringBuilder markup;
+ markup.append("<a href=\"");
+ markup.append(url.string());
+ markup.append("\">");
+ GUniquePtr<gchar> escaped(g_markup_escape_text(actualLabel.utf8().data(), -1));
+ markup.append(String::fromUTF8(escaped.get()));
+ markup.append("</a>");
+ setMarkup(markup.toString());
+}
+
+const String& SelectionData::urlLabel() const
+{
+ if (hasText())
+ return text();
+
+ if (hasURL())
+ return url().string();
+
+ return emptyString();
+}
+
+void SelectionData::clearAllExceptFilenames()
+{
+ clearText();
+ clearMarkup();
+ clearURIList();
+ clearURL();
+ clearImage();
+ clearCustomData();
+
+ m_canSmartReplace = false;
+}
+
+void SelectionData::clearAll()
+{
+ clearAllExceptFilenames();
+ m_filenames.clear();
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/wpe/SelectionData.h b/Source/WebCore/platform/wpe/SelectionData.h
new file mode 100644
index 0000000000000000000000000000000000000000..cf2b51f6f02837a1106f4d999f2f130e2580986a
--- /dev/null
+++ b/Source/WebCore/platform/wpe/SelectionData.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2009, Martin Robinson
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#pragma once
+
+#include "Image.h"
+#include "SharedBuffer.h"
+#include <wtf/HashMap.h>
+#include <wtf/URL.h>
+#include <wtf/text/StringHash.h>
+
+namespace WebCore {
+
+class SelectionData {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ void setText(const String&);
+ const String& text() const { return m_text; }
+ bool hasText() const { return !m_text.isEmpty(); }
+ void clearText() { m_text = emptyString(); }
+
+ void setMarkup(const String& newMarkup) { m_markup = newMarkup; }
+ const String& markup() const { return m_markup; }
+ bool hasMarkup() const { return !m_markup.isEmpty(); }
+ void clearMarkup() { m_markup = emptyString(); }
+
+ void setURL(const URL&, const String&);
+ const URL& url() const { return m_url; }
+ const String& urlLabel() const;
+ bool hasURL() const { return !m_url.isEmpty() && m_url.isValid(); }
+ void clearURL() { m_url = URL(); }
+
+ void setURIList(const String&);
+ const String& uriList() const { return m_uriList; }
+ const Vector<String>& filenames() const { return m_filenames; }
+ bool hasURIList() const { return !m_uriList.isEmpty(); }
+ bool hasFilenames() const { return !m_filenames.isEmpty(); }
+ void clearURIList() { m_uriList = emptyString(); }
+
+ void setImage(Image* newImage) { m_image = newImage; }
+ Image* image() const { return m_image.get(); }
+ bool hasImage() const { return m_image; }
+ void clearImage() { m_image = nullptr; }
+
+ void setCanSmartReplace(bool canSmartReplace) { m_canSmartReplace = canSmartReplace; }
+ bool canSmartReplace() const { return m_canSmartReplace; }
+
+ void setCustomData(Ref<SharedBuffer>&& buffer) { m_customData = WTFMove(buffer); }
+ SharedBuffer* customData() const { return m_customData.get(); }
+ bool hasCustomData() const { return !!m_customData; }
+ void clearCustomData() { m_customData = nullptr; }
+
+ void clearAll();
+ void clearAllExceptFilenames();
+
+private:
+ String m_text;
+ String m_markup;
+ URL m_url;
+ String m_uriList;
+ Vector<String> m_filenames;
+ RefPtr<Image> m_image;
+ bool m_canSmartReplace { false };
+ RefPtr<SharedBuffer> m_customData;
+};
+
+} // namespace WebCore
diff --git a/Source/WebCore/rendering/RenderTextControl.cpp b/Source/WebCore/rendering/RenderTextControl.cpp
index fcd984f4ec4646da9cc9920f9447b1ce0e96456d..8fea25dbf3cd74992dd2f3b8907c691f3fe2e6a8 100644
--- a/Source/WebCore/rendering/RenderTextControl.cpp
+++ b/Source/WebCore/rendering/RenderTextControl.cpp
@@ -212,13 +212,13 @@ void RenderTextControl::layoutExcludedChildren(bool relayoutChildren)
}
}
-#if PLATFORM(IOS_FAMILY)
bool RenderTextControl::canScroll() const
{
auto innerText = innerTextElement();
return innerText && innerText->renderer() && innerText->renderer()->hasNonVisibleOverflow();
}
+#if PLATFORM(IOS_FAMILY)
int RenderTextControl::innerLineHeight() const
{
auto innerText = innerTextElement();
diff --git a/Source/WebCore/rendering/RenderTextControl.h b/Source/WebCore/rendering/RenderTextControl.h
index fac9402820702989bf72ed2425678bfb82bd6523..40b5a6441d22714fd370ce1a7c2f534e6e7510f5 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/Cookies/WebCookieManager.messages.in b/Source/WebKit/NetworkProcess/Cookies/WebCookieManager.messages.in
index 2081154f90fac8f7b9f7c6061cf5dc6da1af44b5..e7c6071a6f2e05e76e0fd1cb4661ebd32a5bb3fd 100644
--- a/Source/WebKit/NetworkProcess/Cookies/WebCookieManager.messages.in
+++ b/Source/WebKit/NetworkProcess/Cookies/WebCookieManager.messages.in
@@ -26,13 +26,13 @@
messages -> WebCookieManager NotRefCounted {
void GetHostnamesWithCookies(PAL::SessionID sessionID) -> (Vector<String> hostnames)
void DeleteCookiesForHostnames(PAL::SessionID sessionID, Vector<String> hostnames) -> ()
- void DeleteAllCookies(PAL::SessionID sessionID) -> ()
void SetCookie(PAL::SessionID sessionID, Vector<WebCore::Cookie> cookie) -> ()
void SetCookies(PAL::SessionID sessionID, Vector<WebCore::Cookie> cookies, URL url, URL mainDocumentURL) -> ()
void GetAllCookies(PAL::SessionID sessionID) -> (Vector<WebCore::Cookie> cookies)
void GetCookies(PAL::SessionID sessionID, URL url) -> (Vector<WebCore::Cookie> cookies)
void DeleteCookie(PAL::SessionID sessionID, struct WebCore::Cookie cookie) -> ()
+ void DeleteAllCookies(PAL::SessionID sessionID) -> ()
void DeleteAllCookiesModifiedSince(PAL::SessionID sessionID, WallTime time) -> ()
void SetHTTPCookieAcceptPolicy(enum:uint8_t WebCore::HTTPCookieAcceptPolicy policy) -> ()
diff --git a/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp b/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp
index 24e9d0eecb5730ad96c625b114b9c7360adcac52..e0b0218bbf37222fc581d19d6ec3f688445aa9c5 100644
--- a/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp
+++ b/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp
@@ -83,6 +83,11 @@
#include <WebCore/SameSiteInfo.h>
#include <WebCore/SecurityPolicy.h>
+#if PLATFORM(COCOA)
+#include "NetworkDataTaskCocoa.h"
+#include "NetworkSessionCocoa.h"
+#endif
+
#if ENABLE(APPLE_PAY_REMOTE_UI)
#include "WebPaymentCoordinatorProxyMessages.h"
#endif
@@ -486,6 +491,10 @@ void NetworkConnectionToWebProcess::createSocketStream(URL&& url, String cachePa
if (auto* session = networkSession())
acceptInsecureCertificates = session->shouldAcceptInsecureCertificatesForWebSockets();
#endif
+ if (auto* session = networkSession()) {
+ if (session->ignoreCertificateErrors())
+ acceptInsecureCertificates = true;
+ }
m_networkSocketStreams.add(identifier, NetworkSocketStream::create(m_networkProcess.get(), WTFMove(url), m_sessionID, cachePartition, identifier, m_connection, WTFMove(token), acceptInsecureCertificates));
}
@@ -1030,6 +1039,14 @@ void NetworkConnectionToWebProcess::clearPageSpecificData(PageIdentifier pageID)
#endif
}
+void NetworkConnectionToWebProcess::setCookieFromResponse(const URL& firstParty, const SameSiteInfo& sameSiteInfo, const URL& url, const String& setCookieValue)
+{
+ auto* networkStorageSession = storageSession();
+ if (!networkStorageSession)
+ return;
+ networkStorageSession->setCookiesFromResponse(firstParty, sameSiteInfo, url, setCookieValue);
+}
+
#if ENABLE(INTELLIGENT_TRACKING_PREVENTION)
void NetworkConnectionToWebProcess::removeStorageAccessForFrame(FrameIdentifier frameID, PageIdentifier pageID)
{
diff --git a/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h b/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h
index 35deb0171bee03d36acd1abad195e9450a54d6fc..90c118158c336763c98132abdded326d9339d8ff 100644
--- a/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h
+++ b/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h
@@ -312,6 +312,8 @@ private:
void clearPageSpecificData(WebCore::PageIdentifier);
+ void setCookieFromResponse(const URL& firstParty, const WebCore::SameSiteInfo&, const URL& url, const String& setCookieValue);
+
#if ENABLE(INTELLIGENT_TRACKING_PREVENTION)
void removeStorageAccessForFrame(WebCore::FrameIdentifier, WebCore::PageIdentifier);
diff --git a/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.messages.in b/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.messages.in
index 77597632a0e3f5dbac4ed45312c401496cf2387d..c3861e47242b15234101ca02a83f2766c8220de2 100644
--- a/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.messages.in
+++ b/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.messages.in
@@ -66,6 +66,8 @@ messages -> NetworkConnectionToWebProcess LegacyReceiver {
ClearPageSpecificData(WebCore::PageIdentifier pageID);
+ SetCookieFromResponse(URL firstParty, struct WebCore::SameSiteInfo sameSiteInfo, URL url, String setCookieValue);
+
#if ENABLE(INTELLIGENT_TRACKING_PREVENTION)
RemoveStorageAccessForFrame(WebCore::FrameIdentifier frameID, WebCore::PageIdentifier pageID);
LogUserInteraction(WebCore::RegistrableDomain domain)
diff --git a/Source/WebKit/NetworkProcess/NetworkProcess.cpp b/Source/WebKit/NetworkProcess/NetworkProcess.cpp
index db42197e01c6e835b41455610ea396ea26920243..1ebb695020d4e8ed8739a288e02241142395140e 100644
--- a/Source/WebKit/NetworkProcess/NetworkProcess.cpp
+++ b/Source/WebKit/NetworkProcess/NetworkProcess.cpp
@@ -530,6 +530,12 @@ void NetworkProcess::destroySession(PAL::SessionID sessionID)
m_sessionsControlledByAutomation.remove(sessionID);
}
+void NetworkProcess::setIgnoreCertificateErrors(PAL::SessionID sessionID, bool ignore)
+{
+ if (auto* networkSession = this->networkSession(sessionID))
+ networkSession->setIgnoreCertificateErrors(ignore);
+}
+
#if ENABLE(INTELLIGENT_TRACKING_PREVENTION)
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 c0d5646aa8964318a999f9a107c493855b2cee7d..35a225a2527732d4d483e07313eac6b7ec4dec86 100644
--- a/Source/WebKit/NetworkProcess/NetworkProcess.h
+++ b/Source/WebKit/NetworkProcess/NetworkProcess.h
@@ -36,6 +36,7 @@
#include "QuotaIncreaseRequestIdentifier.h"
#include "RTCDataChannelRemoteManagerProxy.h"
#include "SandboxExtension.h"
+#include "StorageNamespaceIdentifier.h"
#include "WebPageProxyIdentifier.h"
#include "WebResourceLoadStatisticsStore.h"
#include "WebsiteData.h"
@@ -82,6 +83,7 @@ class SessionID;
namespace WebCore {
class CertificateInfo;
+struct Cookie;
class CurlProxySettings;
class ProtectionSpace;
class NetworkStorageSession;
@@ -201,6 +203,8 @@ public:
void addWebsiteDataStore(WebsiteDataStoreParameters&&);
+ void setIgnoreCertificateErrors(PAL::SessionID, bool);
+
#if ENABLE(INTELLIGENT_TRACKING_PREVENTION)
void clearPrevalentResource(PAL::SessionID, RegistrableDomain&&, CompletionHandler<void()>&&);
void clearUserInteraction(PAL::SessionID, RegistrableDomain&&, CompletionHandler<void()>&&);
diff --git a/Source/WebKit/NetworkProcess/NetworkProcess.messages.in b/Source/WebKit/NetworkProcess/NetworkProcess.messages.in
index 34334c3b4fdf491271702fd46b0676e01a34f1e4..7ce428cb543a07ac2559d56de7484e02772f6cb9 100644
--- a/Source/WebKit/NetworkProcess/NetworkProcess.messages.in
+++ b/Source/WebKit/NetworkProcess/NetworkProcess.messages.in
@@ -77,6 +77,8 @@ 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 std::optional<WebKit::NavigatingToAppBoundDomain> isNavigatingToAppBoundDomain, enum:bool WebKit::LastNavigationWasAppInitiated lastNavigationWasAppInitiated);
+ SetIgnoreCertificateErrors(PAL::SessionID sessionID, bool ignoreTLSErrors)
+
#if ENABLE(INTELLIGENT_TRACKING_PREVENTION)
ClearPrevalentResource(PAL::SessionID sessionID, WebCore::RegistrableDomain resourceDomain) -> ()
ClearUserInteraction(PAL::SessionID sessionID, WebCore::RegistrableDomain resourceDomain) -> ()
diff --git a/Source/WebKit/NetworkProcess/NetworkSession.h b/Source/WebKit/NetworkProcess/NetworkSession.h
index 11b3fc7c4267ef9e412d7d48bb6cfbe70b2bdfeb..af1fb6660696cf9c91d319670d5542727ae3ac18 100644
--- a/Source/WebKit/NetworkProcess/NetworkSession.h
+++ b/Source/WebKit/NetworkProcess/NetworkSession.h
@@ -192,6 +192,9 @@ public:
void lowMemoryHandler(WTF::Critical);
+ 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); }
@@ -273,6 +276,7 @@ protected:
bool m_privateClickMeasurementDebugModeEnabled { false };
std::optional<WebCore::PrivateClickMeasurement> m_ephemeralMeasurement;
bool m_isRunningEphemeralMeasurementTest { false };
+ bool m_ignoreCertificateErrors { false };
HashSet<Ref<NetworkResourceLoader>> m_keptAliveLoads;
diff --git a/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm b/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm
index 1dc6df3e1145332a0aeb902c0f5d7d5d727593be..230d268489a52391f7d4f336d22311e35c9f8278 100644
--- a/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm
+++ b/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm
@@ -720,7 +720,7 @@ void NetworkSessionCocoa::setClientAuditToken(const WebCore::AuthenticationChall
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
sessionCocoa->setClientAuditToken(challenge);
- if (NetworkSessionCocoa::allowsSpecificHTTPSCertificateForHost(challenge))
+ if (sessionCocoa->ignoreCertificateErrors() || sessionCocoa->allowsSpecificHTTPSCertificateForHost(challenge))
return completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]);
NSURLSessionTaskTransactionMetrics *metrics = task._incompleteTaskMetrics.transactionMetrics.lastObject;
@@ -964,6 +964,13 @@ ALLOW_DEPRECATED_DECLARATIONS_END
resourceResponse.setDeprecatedNetworkLoadMetrics(WebCore::copyTimingData(taskMetrics, networkDataTask->networkLoadMetrics()));
+ __block WebCore::HTTPHeaderMap requestHeaders;
+ NSURLSessionTaskTransactionMetrics *m = dataTask._incompleteTaskMetrics.transactionMetrics.lastObject;
+ [m.request.allHTTPHeaderFields enumerateKeysAndObjectsUsingBlock:^(NSString *name, NSString *value, BOOL *) {
+ requestHeaders.set(String(name), String(value));
+ }];
+ resourceResponse.m_httpRequestHeaderFields = WTFMove(requestHeaders);
+
networkDataTask->didReceiveResponse(WTFMove(resourceResponse), negotiatedLegacyTLS, privateRelayed, [completionHandler = makeBlockPtr(completionHandler), taskIdentifier](WebCore::PolicyAction policyAction) {
#if !LOG_DISABLED
LOG(NetworkSession, "%llu didReceiveResponse completionHandler (%d)", taskIdentifier, policyAction);
diff --git a/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.cpp b/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.cpp
index d1fac29ff7fb628b8994642eb9b7a35cad9ad37f..5f2068c1d6deff4792d974714d75b204958e9a42 100644
--- a/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.cpp
+++ b/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.cpp
@@ -84,6 +84,8 @@ NetworkDataTaskCurl::NetworkDataTaskCurl(NetworkSession& session, NetworkDataTas
m_curlRequest->setUserPass(m_initialCredential.user(), m_initialCredential.password());
m_curlRequest->setAuthenticationScheme(ProtectionSpace::AuthenticationScheme::HTTPBasic);
}
+ if (m_session->ignoreCertificateErrors())
+ m_curlRequest->disableServerTrustEvaluation();
m_curlRequest->start();
}
@@ -160,6 +162,7 @@ void NetworkDataTaskCurl::curlDidReceiveResponse(CurlRequest& request, CurlRespo
m_response = ResourceResponse(receivedResponse);
m_response.setCertificateInfo(WTFMove(receivedResponse.certificateInfo));
m_response.setDeprecatedNetworkLoadMetrics(Box<NetworkLoadMetrics>::create(WTFMove(receivedResponse.networkLoadMetrics)));
+ m_response.m_httpRequestHeaderFields = request.resourceRequest().httpHeaderFields();
handleCookieHeaders(request.resourceRequest(), receivedResponse);
@@ -386,6 +389,8 @@ void NetworkDataTaskCurl::willPerformHTTPRedirection()
m_curlRequest->setUserPass(m_initialCredential.user(), m_initialCredential.password());
m_curlRequest->setAuthenticationScheme(ProtectionSpace::AuthenticationScheme::HTTPBasic);
}
+ if (m_session->ignoreCertificateErrors())
+ m_curlRequest->disableServerTrustEvaluation();
m_curlRequest->start();
if (m_state != State::Suspended) {
diff --git a/Source/WebKit/NetworkProcess/curl/NetworkSessionCurl.cpp b/Source/WebKit/NetworkProcess/curl/NetworkSessionCurl.cpp
index 892d1b2541e218047c33e88a207aa56e36b7e6bc..04bf128418cce29926d53c1af682485f4162ba03 100644
--- a/Source/WebKit/NetworkProcess/curl/NetworkSessionCurl.cpp
+++ b/Source/WebKit/NetworkProcess/curl/NetworkSessionCurl.cpp
@@ -61,7 +61,7 @@ NetworkSessionCurl::~NetworkSessionCurl()
std::unique_ptr<WebSocketTask> NetworkSessionCurl::createWebSocketTask(WebPageProxyIdentifier, NetworkSocketChannel& channel, const WebCore::ResourceRequest& request, const String& protocol, const WebCore::ClientOrigin&, bool)
{
- return makeUnique<WebSocketTask>(channel, request, protocol);
+ return makeUnique<WebSocketTask>(channel, request, protocol, ignoreCertificateErrors());
}
} // namespace WebKit
diff --git a/Source/WebKit/NetworkProcess/curl/WebSocketTaskCurl.cpp b/Source/WebKit/NetworkProcess/curl/WebSocketTaskCurl.cpp
index 2c14f606108b1942a5a84ddc833055bea95a37d3..d14839aef6cfca76c3f385651bc3ef3c5af951b2 100644
--- a/Source/WebKit/NetworkProcess/curl/WebSocketTaskCurl.cpp
+++ b/Source/WebKit/NetworkProcess/curl/WebSocketTaskCurl.cpp
@@ -33,7 +33,7 @@
namespace WebKit {
-WebSocketTask::WebSocketTask(NetworkSocketChannel& channel, const WebCore::ResourceRequest& request, const String& protocol)
+WebSocketTask::WebSocketTask(NetworkSocketChannel& channel, const WebCore::ResourceRequest& request, const String& protocol, bool ignoreCertificateErrors)
: m_channel(channel)
, m_request(request.isolatedCopy())
, m_protocol(protocol)
@@ -42,7 +42,7 @@ WebSocketTask::WebSocketTask(NetworkSocketChannel& channel, const WebCore::Resou
if (request.url().protocolIs("wss"_s) && WebCore::DeprecatedGlobalSettings::allowsAnySSLCertificate())
WebCore::CurlContext::singleton().sslHandle().setIgnoreSSLErrors(true);
- m_streamID = m_scheduler.createStream(request.url(), *this);
+ m_streamID = m_scheduler.createStream(request.url(), ignoreCertificateErrors, *this);
m_channel.didSendHandshakeRequest(WebCore::ResourceRequest(m_request));
}
diff --git a/Source/WebKit/NetworkProcess/curl/WebSocketTaskCurl.h b/Source/WebKit/NetworkProcess/curl/WebSocketTaskCurl.h
index 2027a4b929fda90b34f46bf563846ca8d4553829..34bfbb236d5f16c8bb34920a2bb01c048d63ab5f 100644
--- a/Source/WebKit/NetworkProcess/curl/WebSocketTaskCurl.h
+++ b/Source/WebKit/NetworkProcess/curl/WebSocketTaskCurl.h
@@ -45,7 +45,7 @@ struct SessionSet;
class WebSocketTask : public CanMakeWeakPtr<WebSocketTask>, public WebCore::CurlStream::Client {
WTF_MAKE_FAST_ALLOCATED;
public:
- WebSocketTask(NetworkSocketChannel&, const WebCore::ResourceRequest&, const String& protocol);
+ WebSocketTask(NetworkSocketChannel&, const WebCore::ResourceRequest&, const String& protocol, bool ignoreCertificateErrors);
~WebSocketTask();
void sendString(const IPC::DataReference&, CompletionHandler<void()>&&);
diff --git a/Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.cpp b/Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.cpp
index fb70fe2e30abc45508eac1ff7b6fa5b576c22917..6d6404a9fdacf1f5c5f108b860e0e577856b6bf3 100644
--- a/Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.cpp
+++ b/Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.cpp
@@ -494,6 +494,8 @@ void NetworkDataTaskSoup::didSendRequest(GRefPtr<GInputStream>&& inputStream)
m_networkLoadMetrics.failsTAOCheck = !passesTimingAllowOriginCheck(m_response, *origin);
}
+ auto& additionalMetrics = additionalNetworkLoadMetricsForWebInspector();
+ m_response.m_httpRequestHeaderFields = additionalMetrics.requestHeaders;
dispatchDidReceiveResponse();
}
@@ -591,6 +593,8 @@ bool NetworkDataTaskSoup::acceptCertificate(GTlsCertificate* certificate, GTlsCe
{
ASSERT(m_soupMessage);
URL url = soupURIToURL(soup_message_get_uri(m_soupMessage.get()));
+ if (m_session->ignoreCertificateErrors())
+ return true;
auto error = static_cast<NetworkSessionSoup&>(*m_session).soupNetworkSession().checkTLSErrors(url, certificate, tlsErrors);
if (!error)
return true;
diff --git a/Source/WebKit/NetworkProcess/soup/NetworkSessionSoup.cpp b/Source/WebKit/NetworkProcess/soup/NetworkSessionSoup.cpp
index ddb157400854dd30878a15879cd3b8c2c13f436f..9e952998a139b84ccb80f7e756343e4b1a49efcc 100644
--- a/Source/WebKit/NetworkProcess/soup/NetworkSessionSoup.cpp
+++ b/Source/WebKit/NetworkProcess/soup/NetworkSessionSoup.cpp
@@ -109,6 +109,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)
@@ -119,6 +124,15 @@ static void webSocketMessageNetworkEventCallback(SoupMessage* soupMessage, GSock
}
#endif
+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(WebPageProxyIdentifier, NetworkSocketChannel& channel, const ResourceRequest& request, const String& protocol, const ClientOrigin&, bool)
{
GRefPtr<SoupMessage> soupMessage = request.createSoupMessage(blobRegistry());
@@ -127,14 +141,21 @@ std::unique_ptr<WebSocketTask> NetworkSessionSoup::createWebSocketTask(WebPagePr
if (request.url().protocolIs("wss"_s)) {
#if USE(SOUP2)
- g_signal_connect(soupMessage.get(), "network-event", G_CALLBACK(webSocketMessageNetworkEventCallback), this);
+ 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);
#else
- g_signal_connect(soupMessage.get(), "accept-certificate", G_CALLBACK(+[](SoupMessage* message, GTlsCertificate* certificate, GTlsCertificateFlags errors, NetworkSessionSoup* session) -> gboolean {
- if (DeprecatedGlobalSettings::allowsAnySSLCertificate())
- return TRUE;
-
- return !session->soupNetworkSession().checkTLSErrors(soup_message_get_uri(message), certificate, errors);
- }), this);
+ if (ignoreCertificateErrors()) {
+ g_signal_connect(soupMessage.get(), "accept-certificate", G_CALLBACK(webSocketAcceptCertificateCallbackIgnoreTLSErrors), this);
+ } else {
+ g_signal_connect(soupMessage.get(), "accept-certificate", G_CALLBACK(+[](SoupMessage* message, GTlsCertificate* certificate, GTlsCertificateFlags errors, NetworkSessionSoup* session) -> gboolean {
+ if (DeprecatedGlobalSettings::allowsAnySSLCertificate())
+ return TRUE;
+
+ return !session->soupNetworkSession().checkTLSErrors(soup_message_get_uri(message), certificate, errors);
+ }), this);
+ }
#endif
}
return makeUnique<WebSocketTask>(channel, request, soupSession(), soupMessage.get(), protocol);
diff --git a/Source/WebKit/PlatformGTK.cmake b/Source/WebKit/PlatformGTK.cmake
index c8b445abe3f464e8d327642e80ac900b565f93d3..b1792226c39d05ec9961581a00b58a92da615b73 100644
--- a/Source/WebKit/PlatformGTK.cmake
+++ b/Source/WebKit/PlatformGTK.cmake
@@ -488,6 +488,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)
@@ -541,6 +544,9 @@ if (USE_LIBWEBRTC)
list(APPEND WebKit_SYSTEM_INCLUDE_DIRECTORIES
"${THIRDPARTY_DIR}/libwebrtc/Source/"
"${THIRDPARTY_DIR}/libwebrtc/Source/webrtc"
+# Playwright begin
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/include"
+# Playwright end
)
endif ()
@@ -555,6 +561,12 @@ if (ENABLE_MEDIA_STREAM)
)
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 ${WebKit2Gtk_DERIVED_SOURCES_DIR}/webkit/WebKitEnumTypes.h)
diff --git a/Source/WebKit/PlatformWPE.cmake b/Source/WebKit/PlatformWPE.cmake
index 8126927e398ac903e7c3a7200cdb67894a8c4ed7..7dc4ee3c07733ab2c7a39c57499408fba81eed19 100644
--- a/Source/WebKit/PlatformWPE.cmake
+++ b/Source/WebKit/PlatformWPE.cmake
@@ -197,6 +197,7 @@ set(WPE_API_INSTALLED_HEADERS
${WEBKIT_DIR}/UIProcess/API/wpe/WebKitOptionMenuItem.h
${WEBKIT_DIR}/UIProcess/API/wpe/WebKitPermissionRequest.h
${WEBKIT_DIR}/UIProcess/API/wpe/WebKitPlugin.h
+ ${WEBKIT_DIR}/UIProcess/API/wpe/WebKitPointerLockPermissionRequest.h
${WEBKIT_DIR}/UIProcess/API/wpe/WebKitPolicyDecision.h
${WEBKIT_DIR}/UIProcess/API/wpe/WebKitRectangle.h
${WEBKIT_DIR}/UIProcess/API/wpe/WebKitResponsePolicyDecision.h
@@ -325,6 +326,7 @@ list(APPEND WebKit_INCLUDE_DIRECTORIES
"${WEBKIT_DIR}/UIProcess/CoordinatedGraphics"
"${WEBKIT_DIR}/UIProcess/Inspector/glib"
"${WEBKIT_DIR}/UIProcess/geoclue"
+ "${WEBKIT_DIR}/UIProcess/glib"
"${WEBKIT_DIR}/UIProcess/gstreamer"
"${WEBKIT_DIR}/UIProcess/linux"
"${WEBKIT_DIR}/UIProcess/soup"
@@ -346,8 +348,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 feb39b35c1bd873c646da76aa762e40680f96533..9188b2fd6561727504fb5f14185d00d245cc98cf 100644
--- a/Source/WebKit/PlatformWin.cmake
+++ b/Source/WebKit/PlatformWin.cmake
@@ -64,8 +64,12 @@ list(APPEND WebKit_SOURCES
UIProcess/wc/DrawingAreaProxyWC.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
@@ -84,6 +88,7 @@ list(APPEND WebKit_SOURCES
WebProcess/MediaCache/WebMediaKeyStorageManager.cpp
WebProcess/WebCoreSupport/win/WebPopupMenuWin.cpp
+ WebProcess/WebCoreSupport/win/WebDragClientWin.cpp
WebProcess/WebPage/AcceleratedSurface.cpp
@@ -137,6 +142,72 @@ list(APPEND WebKit_MESSAGES_IN_FILES
GPUProcess/graphics/wc/RemoteWCLayerTreeHost
)
+# 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_mmi.cc"
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/compare_msa.cc"
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/compare_neon64.cc"
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/compare_neon.cc"
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/compare_win.cc"
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/convert_argb.cc"
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/convert.cc"
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/convert_from_argb.cc"
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/convert_from.cc"
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/convert_jpeg.cc"
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/convert_to_argb.cc"
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/convert_to_i420.cc"
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/cpu_id.cc"
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/mjpeg_decoder.cc"
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/mjpeg_validate.cc"
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/planar_functions.cc"
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/rotate_any.cc"
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/rotate_argb.cc"
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/rotate.cc"
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/rotate_common.cc"
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/rotate_gcc.cc"
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/rotate_mmi.cc"
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/rotate_msa.cc"
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/rotate_neon64.cc"
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/rotate_neon.cc"
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/rotate_win.cc"
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/row_any.cc"
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/row_common.cc"
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/row_gcc.cc"
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/row_mmi.cc"
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/row_msa.cc"
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/row_neon64.cc"
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/row_neon.cc"
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/row_win.cc"
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/scale_any.cc"
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/scale_argb.cc"
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/scale.cc"
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/scale_common.cc"
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/scale_gcc.cc"
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/scale_mmi.cc"
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/scale_msa.cc"
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/scale_neon64.cc"
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/scale_neon.cc"
+ "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/scale_uv.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})
@@ -197,6 +268,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 caf67e1dece5b727e43eba780e70814f8fdb0f63..740150d2589d6e16a516daa3bf6ef899ac538c99 100644
--- a/Source/WebKit/Shared/API/c/wpe/WebKit.h
+++ b/Source/WebKit/Shared/API/c/wpe/WebKit.h
@@ -77,6 +77,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 ee8cac1c980039c4a36de5501ab7f135e710d06b..deae2be9e720ff76186ecea89920dfc39c4f186a 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&, std::optional<Vector<WebCore::CompositionUnderline>>&&, std::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, std::optional<Vector<WebCore::CompositionUnderline>>&&, std::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 fef57e34be6ed7592187c3e1fd73c989bf79da1a..e35612e9b88877627802df18e9084e7f4022e629 100644
--- a/Source/WebKit/Shared/NativeWebMouseEvent.h
+++ b/Source/WebKit/Shared/NativeWebMouseEvent.h
@@ -78,6 +78,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/NativeWebWheelEvent.h b/Source/WebKit/Shared/NativeWebWheelEvent.h
index f2f3979fcac9dfd97d0e0ead600fe35eb8defd40..ac91412e1a96bdf521b1890a66e465dc54293d31 100644
--- a/Source/WebKit/Shared/NativeWebWheelEvent.h
+++ b/Source/WebKit/Shared/NativeWebWheelEvent.h
@@ -67,7 +67,8 @@ public:
#elif PLATFORM(WIN)
NativeWebWheelEvent(HWND, UINT message, WPARAM, LPARAM);
#endif
-
+ NativeWebWheelEvent(const WebWheelEvent & webWheelEvent)
+ : WebWheelEvent(webWheelEvent) { }
#if USE(APPKIT)
NSEvent* nativeEvent() const { return m_nativeEvent.get(); }
#elif PLATFORM(GTK)
diff --git a/Source/WebKit/Shared/WebCoreArgumentCoders.cpp b/Source/WebKit/Shared/WebCoreArgumentCoders.cpp
index 99ffa8b82f520c65d42bd102a9f7f2a26e68bd87..023bddefda4145020e96970888f0436dd1c1db21 100644
--- a/Source/WebKit/Shared/WebCoreArgumentCoders.cpp
+++ b/Source/WebKit/Shared/WebCoreArgumentCoders.cpp
@@ -123,6 +123,10 @@
#include <WebCore/TextRecognitionResult.h>
#endif
+#if PLATFORM(WPE)
+#include "ArgumentCodersWPE.h"
+#endif
+
// FIXME: Seems like we could use std::tuple to cut down the code below a lot!
namespace IPC {
@@ -1303,6 +1307,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)
@@ -1331,6 +1338,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;
}
@@ -1344,6 +1357,11 @@ void ArgumentCoder<DragData>::encode(Encoder& encoder, const DragData& dragData)
#if PLATFORM(COCOA)
encoder << dragData.pasteboardName();
encoder << dragData.fileNames();
+#endif
+#if PLATFORM(WIN)
+ DragData dragDataCopy = dragData;
+ HashMap<unsigned int, Vector<String>> hash = dragDataCopy.dragDataMap();
+ encoder << hash;
#endif
encoder << dragData.dragDestinationActionMask();
encoder << dragData.pageID();
@@ -1367,9 +1385,16 @@ bool ArgumentCoder<DragData>::decode(Decoder& decoder, DragData& dragData)
if (!decoder.decode(applicationFlags))
return false;
+#if PLATFORM(WIN)
+ DragDataMap dragDataMap;
+ if (!decoder.decode(dragDataMap))
+ return false;
+#else
String pasteboardName;
- Vector<String> fileNames;
+#endif
+
#if PLATFORM(COCOA)
+ Vector<String> fileNames;
if (!decoder.decode(pasteboardName))
return false;
@@ -1385,8 +1410,14 @@ bool ArgumentCoder<DragData>::decode(Decoder& decoder, DragData& dragData)
if (!decoder.decode(pageID))
return false;
+#if PLATFORM(WIN)
+ dragData = DragData(dragDataMap, clientPosition, globalPosition, draggingSourceOperationMask, applicationFlags, pageID);
+#else
dragData = DragData(pasteboardName, clientPosition, globalPosition, draggingSourceOperationMask, applicationFlags, dragDestinationActionMask, pageID);
+#endif
+#if PLATFORM(COCOA)
dragData.setFileNames(fileNames);
+#endif
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 3679736973ebc06771c7d94591909688f28a70b4..8df0a8e223551e2ee73e816adcb3b31153c54eb5 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, std::optional<Vector<WebCore::CompositionUnderline>>&& preeditUnderlines, std::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)
@@ -142,6 +179,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 1817691d3e12ddec8169248c791826cc13b057e3..cdc90eda23ed5ba20ee78a02c0dd632be4bc615a 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, std::optional<Vector<WebCore::CompositionUnderline>>&&, std::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, std::optional<Vector<WebCore::CompositionUnderline>>&&, std::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/WebMouseEvent.h b/Source/WebKit/Shared/WebMouseEvent.h
index cf2adc382b3f59890c43a54b6c28bab2c4a965c6..998e96ec8c997bd1b51434c77e73e9420f5ebaa7 100644
--- a/Source/WebKit/Shared/WebMouseEvent.h
+++ b/Source/WebKit/Shared/WebMouseEvent.h
@@ -62,6 +62,7 @@ public:
Button button() const { return static_cast<Button>(m_button); }
unsigned short buttons() const { return m_buttons; }
+ void playwrightSetButtons(unsigned short buttons) { m_buttons = buttons; }
const WebCore::IntPoint& position() const { return m_position; } // Relative to the view.
const WebCore::IntPoint& globalPosition() const { return m_globalPosition; }
float deltaX() const { return m_deltaX; }
diff --git a/Source/WebKit/Shared/WebPageCreationParameters.cpp b/Source/WebKit/Shared/WebPageCreationParameters.cpp
index a09735f21a6e29f42cdb4689a76e6f515656fc24..4239e03c964470a2afa6e6f1c1153c603cc1d008 100644
--- a/Source/WebKit/Shared/WebPageCreationParameters.cpp
+++ b/Source/WebKit/Shared/WebPageCreationParameters.cpp
@@ -155,6 +155,8 @@ void WebPageCreationParameters::encode(IPC::Encoder& encoder) const
encoder << crossOriginAccessControlCheckEnabled;
encoder << processDisplayName;
+ encoder << shouldPauseInInspectorWhenShown;
+
encoder << shouldCaptureAudioInUIProcess;
encoder << shouldCaptureAudioInGPUProcess;
encoder << shouldCaptureVideoInUIProcess;
@@ -533,7 +535,10 @@ std::optional<WebPageCreationParameters> WebPageCreationParameters::decode(IPC::
if (!processDisplayName)
return std::nullopt;
parameters.processDisplayName = WTFMove(*processDisplayName);
-
+
+ if (!decoder.decode(parameters.shouldPauseInInspectorWhenShown))
+ return std::nullopt;
+
if (!decoder.decode(parameters.shouldCaptureAudioInUIProcess))
return std::nullopt;
diff --git a/Source/WebKit/Shared/WebPageCreationParameters.h b/Source/WebKit/Shared/WebPageCreationParameters.h
index a3bf148e49a919fb3e326564936ca9aa725b0222..543f1a4d6fa571eb025b90d27a39aea9d591f0f9 100644
--- a/Source/WebKit/Shared/WebPageCreationParameters.h
+++ b/Source/WebKit/Shared/WebPageCreationParameters.h
@@ -254,6 +254,8 @@ struct WebPageCreationParameters {
bool httpsUpgradeEnabled { true };
+ bool shouldPauseInInspectorWhenShown { false };
+
#if PLATFORM(IOS)
bool allowsDeprecatedSynchronousXMLHttpRequestDuringUnload { false };
#endif
diff --git a/Source/WebKit/Shared/gtk/NativeWebKeyboardEventGtk.cpp b/Source/WebKit/Shared/gtk/NativeWebKeyboardEventGtk.cpp
index c204637774ee803eac42a34cde79aa556f143b82..345f5b08179e3dd239725bed06e48b46bc718336 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(), std::optional<Vector<WebCore::CompositionUnderline>>(event.preeditUnderlines()), std::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 ebf179e3f11c3e05e2354d36b1a68c4c3b965403..c00ea8a5ebe6f1d7fa987cac003dc3a281cfb386 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(), 0, NoTap, event.isTouchEvent(), event.pointerId(), event.pointerType())
+ : 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 03e118154f6bb5b704b4ecb83d3d9543f8c5a5fa..9725caaac6ee65a96ea324ddbb4e1a3785bbc028 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 @@ std::optional<WebPlatformTouchPoint> WebPlatformTouchPoint::decode(IPC::Decoder&
} // 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/libwpe/ArgumentCodersWPE.cpp b/Source/WebKit/Shared/libwpe/ArgumentCodersWPE.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..85842bcbac87cb4964c8b144f549a512034fb392
--- /dev/null
+++ b/Source/WebKit/Shared/libwpe/ArgumentCodersWPE.cpp
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2011 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ArgumentCodersWPE.h"
+
+#include "DataReference.h"
+#include "ShareableBitmap.h"
+#include "WebCoreArgumentCoders.h"
+#include <WebCore/GraphicsContext.h>
+#include <WebCore/Image.h>
+#include <WebCore/SelectionData.h>
+
+namespace IPC {
+using namespace WebCore;
+using namespace WebKit;
+
+static void encodeImage(Encoder& encoder, Image& image)
+{
+ RefPtr<ShareableBitmap> bitmap = ShareableBitmap::create(IntSize(image.size()), { });
+ bitmap->createGraphicsContext()->drawImage(image, IntPoint());
+
+ ShareableBitmap::Handle handle;
+ bitmap->createHandle(handle);
+
+ encoder << handle;
+}
+
+static WARN_UNUSED_RETURN bool decodeImage(Decoder& decoder, RefPtr<Image>& image)
+{
+ ShareableBitmap::Handle handle;
+ if (!decoder.decode(handle))
+ return false;
+
+ RefPtr<ShareableBitmap> bitmap = ShareableBitmap::create(handle);
+ if (!bitmap)
+ return false;
+ image = bitmap->createImage();
+ if (!image)
+ return false;
+ return true;
+}
+
+void ArgumentCoder<SelectionData>::encode(Encoder& encoder, const SelectionData& selection)
+{
+ bool hasText = selection.hasText();
+ encoder << hasText;
+ if (hasText)
+ encoder << selection.text();
+ bool hasMarkup = selection.hasMarkup();
+ encoder << hasMarkup;
+ if (hasMarkup)
+ encoder << selection.markup();
+
+ bool hasURL = selection.hasURL();
+ encoder << hasURL;
+ if (hasURL)
+ encoder << selection.url().string();
+
+ bool hasURIList = selection.hasURIList();
+ encoder << hasURIList;
+ if (hasURIList)
+ encoder << selection.uriList();
+
+ bool hasImage = selection.hasImage();
+ encoder << hasImage;
+ if (hasImage)
+ encodeImage(encoder, *selection.image());
+
+ bool hasCustomData = selection.hasCustomData();
+ encoder << hasCustomData;
+ if (hasCustomData)
+ encoder << RefPtr<SharedBuffer>(selection.customData());
+
+ bool canSmartReplace = selection.canSmartReplace();
+ encoder << canSmartReplace;
+}
+
+std::optional<SelectionData> ArgumentCoder<SelectionData>::decode(Decoder& decoder)
+{
+ SelectionData selection;
+
+ bool hasText;
+ if (!decoder.decode(hasText))
+ return std::nullopt;
+ if (hasText) {
+ String text;
+ if (!decoder.decode(text))
+ return std::nullopt;
+ selection.setText(text);
+ }
+
+ bool hasMarkup;
+ if (!decoder.decode(hasMarkup))
+ return std::nullopt;
+ if (hasMarkup) {
+ String markup;
+ if (!decoder.decode(markup))
+ return std::nullopt;
+ selection.setMarkup(markup);
+ }
+
+ bool hasURL;
+ if (!decoder.decode(hasURL))
+ return std::nullopt;
+ if (hasURL) {
+ String url;
+ if (!decoder.decode(url))
+ return std::nullopt;
+ selection.setURL(URL(URL(), url), String());
+ }
+
+ bool hasURIList;
+ if (!decoder.decode(hasURIList))
+ return std::nullopt;
+ if (hasURIList) {
+ String uriList;
+ if (!decoder.decode(uriList))
+ return std::nullopt;
+ selection.setURIList(uriList);
+ }
+
+ bool hasImage;
+ if (!decoder.decode(hasImage))
+ return std::nullopt;
+ if (hasImage) {
+ RefPtr<Image> image;
+ if (!decodeImage(decoder, image))
+ return std::nullopt;
+ selection.setImage(image.get());
+ }
+
+ bool hasCustomData;
+ if (!decoder.decode(hasCustomData))
+ return std::nullopt;
+ if (hasCustomData) {
+ RefPtr<SharedBuffer> buffer;
+ if (!decoder.decode(buffer))
+ return std::nullopt;
+ selection.setCustomData(Ref<SharedBuffer>(*buffer));
+ }
+
+ bool canSmartReplace;
+ if (!decoder.decode(canSmartReplace))
+ return std::nullopt;
+ selection.setCanSmartReplace(canSmartReplace);
+
+ return selection;
+}
+
+}
diff --git a/Source/WebKit/Shared/libwpe/ArgumentCodersWPE.h b/Source/WebKit/Shared/libwpe/ArgumentCodersWPE.h
new file mode 100644
index 0000000000000000000000000000000000000000..789a0d7cf69704c8f665a9ed79348fbcbc1301c4
--- /dev/null
+++ b/Source/WebKit/Shared/libwpe/ArgumentCodersWPE.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2011 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "ArgumentCoders.h"
+
+namespace WebCore {
+class SelectionData;
+}
+
+namespace IPC {
+
+template<> struct ArgumentCoder<WebCore::SelectionData> {
+ static void encode(Encoder&, const WebCore::SelectionData&);
+ static std::optional<WebCore::SelectionData> decode(Decoder&);
+};
+
+} // namespace IPC
diff --git a/Source/WebKit/Shared/win/WebEventFactory.cpp b/Source/WebKit/Shared/win/WebEventFactory.cpp
index 90df093a49c09dc670dfea55077c77d889dd1c1b..6ffd51532e29b941b8dc10f545b7f5b81e9407b4 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 176db7b86ea45229243298e6e1817ee5940d72c3..9b52cae9b11e75cd2a30a1774a2626923afab8f8 100644
--- a/Source/WebKit/Sources.txt
+++ b/Source/WebKit/Sources.txt
@@ -398,11 +398,14 @@ Shared/XR/XRDeviceProxy.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/MediaKeySystemPermissionRequestManagerProxy.cpp
UIProcess/MediaKeySystemPermissionRequestProxy.cpp
@@ -411,6 +414,7 @@ UIProcess/PageLoadState.cpp
UIProcess/ProcessAssertion.cpp
UIProcess/ProcessThrottler.cpp
UIProcess/ProvisionalPageProxy.cpp
+UIProcess/RemoteInspectorPipe.cpp
UIProcess/ResponsivenessTimer.cpp
UIProcess/SpeechRecognitionRemoteRealtimeMediaSource.cpp
UIProcess/SpeechRecognitionRemoteRealtimeMediaSourceManager.cpp
@@ -452,6 +456,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
@@ -575,7 +581,11 @@ UIProcess/Inspector/WebInspectorUtilities.cpp
UIProcess/Inspector/WebPageDebuggable.cpp
UIProcess/Inspector/WebPageInspectorController.cpp
+UIProcess/Inspector/Agents/CairoJpegEncoder.cpp
UIProcess/Inspector/Agents/InspectorBrowserAgent.cpp
+UIProcess/Inspector/Agents/InspectorScreencastAgent.cpp
+UIProcess/Inspector/Agents/ScreencastEncoder.cpp
+UIProcess/Inspector/Agents/WebMFileWriter.cpp
UIProcess/Media/AudioSessionRoutingArbitratorProxy.cpp
UIProcess/Media/MediaUsageManager.cpp
diff --git a/Source/WebKit/SourcesCocoa.txt b/Source/WebKit/SourcesCocoa.txt
index 14bb808bb4d659faaca9df623a2ed3213dccf3ee..e36d2ea060310a90a73a0f8af7d96040152122ac 100644
--- a/Source/WebKit/SourcesCocoa.txt
+++ b/Source/WebKit/SourcesCocoa.txt
@@ -279,6 +279,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
@@ -456,6 +457,7 @@ UIProcess/Inspector/ios/WKInspectorHighlightView.mm
UIProcess/Inspector/ios/WKInspectorNodeSearchGestureRecognizer.mm
UIProcess/Inspector/mac/RemoteWebInspectorUIProxyMac.mm
+UIProcess/Inspector/mac/ScreencastEncoderMac.mm
UIProcess/Inspector/mac/WebInspectorUIProxyMac.mm
UIProcess/Inspector/mac/WKInspectorResourceURLSchemeHandler.mm
UIProcess/Inspector/mac/WKInspectorViewController.mm
diff --git a/Source/WebKit/SourcesGTK.txt b/Source/WebKit/SourcesGTK.txt
index c8d48a081abcb7cdb6ce4f7229e4ac64e5ecefbc..428636b072e631bdf02833720bd806cb8bbca3ed 100644
--- a/Source/WebKit/SourcesGTK.txt
+++ b/Source/WebKit/SourcesGTK.txt
@@ -129,6 +129,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
@@ -248,6 +249,7 @@ UIProcess/WebsiteData/unix/WebsiteDataStoreUnix.cpp
UIProcess/cairo/BackingStoreCairo.cpp @no-unify
+UIProcess/glib/InspectorPlaywrightAgentClientGLib.cpp
UIProcess/glib/WebPageProxyGLib.cpp
UIProcess/glib/WebProcessPoolGLib.cpp
UIProcess/glib/WebProcessProxyGLib.cpp
@@ -265,6 +267,7 @@ UIProcess/gtk/ClipboardGtk4.cpp @no-unify
UIProcess/gtk/WebDateTimePickerGtk.cpp
UIProcess/gtk/GtkSettingsManager.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
@@ -277,6 +280,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 24962250ca5c823c8679a94455bfb303b01e72c0..9783d5f1bb82aa307c1cfdf6ca4861abb8f653e0 100644
--- a/Source/WebKit/SourcesWPE.txt
+++ b/Source/WebKit/SourcesWPE.txt
@@ -87,6 +87,7 @@ Shared/glib/ProcessExecutablePathGLib.cpp
Shared/glib/UserMessage.cpp
Shared/glib/WebContextMenuItemGlib.cpp
+Shared/libwpe/ArgumentCodersWPE.cpp
Shared/libwpe/NativeWebKeyboardEventLibWPE.cpp
Shared/libwpe/NativeWebMouseEventLibWPE.cpp
Shared/libwpe/NativeWebTouchEventLibWPE.cpp
@@ -122,6 +123,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
@@ -156,6 +158,7 @@ UIProcess/API/glib/WebKitOptionMenu.cpp @no-unify
UIProcess/API/glib/WebKitOptionMenuItem.cpp @no-unify
UIProcess/API/glib/WebKitPermissionRequest.cpp @no-unify
UIProcess/API/glib/WebKitPlugin.cpp @no-unify
+UIProcess/API/glib/WebKitPointerLockPermissionRequest.cpp @no-unify
UIProcess/API/glib/WebKitPolicyDecision.cpp @no-unify
UIProcess/API/glib/WebKitPrivate.cpp @no-unify
UIProcess/API/glib/WebKitProtocolHandler.cpp @no-unify
@@ -190,6 +193,7 @@ UIProcess/API/wpe/InputMethodFilterWPE.cpp @no-unify
UIProcess/API/wpe/PageClientImpl.cpp @no-unify
UIProcess/API/wpe/TouchGestureController.cpp @no-unify
UIProcess/API/wpe/WebKitColor.cpp @no-unify
+UIProcess/API/wpe/WebKitDataListSuggestionsDropdown.cpp @no-unify
UIProcess/API/wpe/WebKitInputMethodContextWPE.cpp @no-unify
UIProcess/API/wpe/WebKitPopupMenu.cpp @no-unify
UIProcess/API/wpe/WebKitRectangle.cpp @no-unify
@@ -206,6 +210,7 @@ UIProcess/CoordinatedGraphics/DrawingAreaProxyCoordinatedGraphics.cpp
UIProcess/geoclue/GeoclueGeolocationProvider.cpp
+UIProcess/glib/InspectorPlaywrightAgentClientGLib.cpp
UIProcess/glib/WebPageProxyGLib.cpp
UIProcess/glib/WebProcessPoolGLib.cpp
UIProcess/glib/WebProcessProxyGLib.cpp
@@ -231,6 +236,11 @@ UIProcess/linux/MemoryPressureMonitor.cpp
UIProcess/soup/WebProcessPoolSoup.cpp
+UIProcess/wpe/InspectorTargetProxyWPE.cpp
+UIProcess/wpe/WebColorPickerWPE.cpp
+UIProcess/wpe/WebDateTimePickerWPE.cpp
+UIProcess/wpe/WebPageInspectorEmulationAgentWPE.cpp
+UIProcess/wpe/WebPageInspectorInputAgentWPE.cpp
UIProcess/wpe/WebPageProxyWPE.cpp
WebProcess/GPU/graphics/gbm/RemoteGraphicsContextGLProxyGBM.cpp
@@ -261,6 +271,8 @@ WebProcess/WebCoreSupport/glib/WebEditorClientGLib.cpp
WebProcess/WebCoreSupport/soup/WebFrameNetworkingContext.cpp
+WebProcess/WebCoreSupport/wpe/WebDragClientWPE.cpp
+
WebProcess/WebCoreSupport/wpe/WebEditorClientWPE.cpp
WebProcess/WebPage/AcceleratedSurface.cpp
diff --git a/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.cpp b/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.cpp
index a16fe13c08576194ec8c43e9dae62a20566904be..f1bc17b878c3103475fa371e05f53cce3a27cff1 100644
--- a/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.cpp
+++ b/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.cpp
@@ -54,6 +54,9 @@ Ref<ProcessPoolConfiguration> ProcessPoolConfiguration::copy()
copy->m_attrStyleEnabled = this->m_attrStyleEnabled;
copy->m_shouldThrowExceptionForGlobalConstantRedeclaration = this->m_shouldThrowExceptionForGlobalConstantRedeclaration;
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 490c7181fe91a9cc050b84a8bf24471db075354b..e4e31e2e06fea50ef760650faada7a46e582fd63 100644
--- a/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.h
+++ b/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.h
@@ -102,6 +102,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; }
@@ -178,6 +183,9 @@ private:
bool m_attrStyleEnabled { false };
bool m_shouldThrowExceptionForGlobalConstantRedeclaration { true };
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 4e48757e4d41547798c74f0b16734d6aa71992e5..2188b93b42c2364347c04ab2be3d3e7b279e1710 100644
--- a/Source/WebKit/UIProcess/API/APIUIClient.h
+++ b/Source/WebKit/UIProcess/API/APIUIClient.h
@@ -106,6 +106,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 e1465edd29caf3109c17d44bb3c88aaba98cfbb5..32d569d3240c583334b8b6512407430fd448ae75 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 "WebInspectorUIProxy.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 2d2ca701c9092613f96c7ab102fe2a2f224d8e65..2358414be2644a4157723a8b0f69ba47d78a19d0 100644
--- a/Source/WebKit/UIProcess/API/C/WKPage.cpp
+++ b/Source/WebKit/UIProcess/API/C/WKPage.cpp
@@ -1762,6 +1762,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)
@@ -1791,6 +1798,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 63323ea918dcddf512dadfff52dd5e60326e6ab8..63acaadcdb0d4a80b543db2728f3657cd4ed6f5f 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);
@@ -1355,6 +1356,7 @@ typedef struct WKPageUIClientV14 {
// Version 14.
WKPageRunWebAuthenticationPanelCallback runWebAuthenticationPanel;
+ WKPageHandleJavaScriptDialogCallback handleJavaScriptDialog;
} WKPageUIClientV14;
typedef struct WKPageUIClientV15 {
@@ -1462,6 +1464,7 @@ typedef struct WKPageUIClientV15 {
// Version 14.
WKPageRunWebAuthenticationPanelCallback runWebAuthenticationPanel;
+ WKPageHandleJavaScriptDialogCallback handleJavaScriptDialog;
// Version 15.
WKPageDecidePolicyForSpeechRecognitionPermissionRequestCallback decidePolicyForSpeechRecognitionPermissionRequest;
@@ -1573,6 +1576,7 @@ typedef struct WKPageUIClientV16 {
// Version 14.
WKPageRunWebAuthenticationPanelCallback runWebAuthenticationPanel;
+ WKPageHandleJavaScriptDialogCallback handleJavaScriptDialog;
// Version 15.
WKPageDecidePolicyForSpeechRecognitionPermissionRequestCallback decidePolicyForSpeechRecognitionPermissionRequest;
@@ -1687,6 +1691,7 @@ typedef struct WKPageUIClientV17 {
// Version 14.
WKPageRunWebAuthenticationPanelCallback runWebAuthenticationPanel;
+ WKPageHandleJavaScriptDialogCallback handleJavaScriptDialog;
// Version 15.
WKPageDecidePolicyForSpeechRecognitionPermissionRequestCallback decidePolicyForSpeechRecognitionPermissionRequest;
@@ -1803,6 +1808,7 @@ typedef struct WKPageUIClientV18 {
// Version 14.
WKPageRunWebAuthenticationPanelCallback runWebAuthenticationPanel;
+ WKPageHandleJavaScriptDialogCallback handleJavaScriptDialog;
// Version 15.
WKPageDecidePolicyForSpeechRecognitionPermissionRequestCallback decidePolicyForSpeechRecognitionPermissionRequest;
diff --git a/Source/WebKit/UIProcess/API/Cocoa/WKUIDelegate.h b/Source/WebKit/UIProcess/API/Cocoa/WKUIDelegate.h
index 82003ea11098fa60e7ac7e2cdd29ea86154c7ccb..b0ebb2874de88f8e11c515d973b4e2cea160304a 100644
--- a/Source/WebKit/UIProcess/API/Cocoa/WKUIDelegate.h
+++ b/Source/WebKit/UIProcess/API/Cocoa/WKUIDelegate.h
@@ -135,6 +135,12 @@ typedef NS_ENUM(NSInteger, WKMediaCaptureType) {
*/
- (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;
/*! @abstract A delegate to request permission for microphone audio and camera video access.
@param webView The web view invoking the delegate method.
diff --git a/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.h b/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.h
index afa925f36c29db9c23921298dead9cce737500d6..42d396342acdb6d39830f611df0ee40ea6ec879e 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 b8bf936e2eb8ca4dc0f445099dfb899395950bdb..30a2af76de0daac450c7afbb8a2dfe8116147b11 100644
--- a/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.mm
+++ b/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.mm
@@ -47,6 +47,7 @@
#import "_WKResourceLoadStatisticsThirdPartyInternal.h"
#import "_WKWebsiteDataStoreConfigurationInternal.h"
#import "_WKWebsiteDataStoreDelegate.h"
+#import <pal/SessionID.h>
#import <WebCore/Credential.h>
#import <WebCore/RegistrationDatabase.h>
#import <WebCore/ServiceWorkerClientData.h>
@@ -234,6 +235,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/_WKDownload.mm b/Source/WebKit/UIProcess/API/Cocoa/_WKDownload.mm
index f585618b83609aa3664cc248ee1aa56ed35221a5..96bfd6a709a4ca6bc5a76abc5d98323ef8a5bf07 100644
--- a/Source/WebKit/UIProcess/API/Cocoa/_WKDownload.mm
+++ b/Source/WebKit/UIProcess/API/Cocoa/_WKDownload.mm
@@ -32,6 +32,7 @@
#import "WKFrameInfoInternal.h"
#import "WKNSData.h"
#import "WKWebViewInternal.h"
+#import <wtf/cocoa/VectorCocoa.h>
#import <wtf/WeakObjCPtr.h>
#import <wtf/cocoa/VectorCocoa.h>
diff --git a/Source/WebKit/UIProcess/API/Cocoa/_WKDownloadInternal.h b/Source/WebKit/UIProcess/API/Cocoa/_WKDownloadInternal.h
index b1c6e033c8a86353f96161482d92c227d7946201..64e592705c97d2d78668aa532f271ddf83ed4c9a 100644
--- a/Source/WebKit/UIProcess/API/Cocoa/_WKDownloadInternal.h
+++ b/Source/WebKit/UIProcess/API/Cocoa/_WKDownloadInternal.h
@@ -24,6 +24,7 @@
*/
#import "_WKDownload.h"
+#import "WKObject.h"
#import "WKObject.h"
#import <wtf/RetainPtr.h>
diff --git a/Source/WebKit/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.h b/Source/WebKit/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.h
index 5b5d106b46392ed95bc7bc6df74c9b43ad07627b..846b2bbbc19b17fa4a2b8d14751b7c5c44beb902 100644
--- a/Source/WebKit/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.h
+++ b/Source/WebKit/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.h
@@ -67,6 +67,7 @@ WK_CLASS_AVAILABLE(macos(10.10), ios(8.0))
@property (nonatomic) pid_t presentingApplicationPID WK_API_AVAILABLE(macos(10.13), ios(11.0));
@property (nonatomic) audit_token_t presentingApplicationProcessToken WK_API_AVAILABLE(macos(10.13), ios(11.3));
@property (nonatomic) BOOL processSwapsOnNavigation WK_API_AVAILABLE(macos(10.14), ios(12.0));
+@property (nonatomic) BOOL forceOverlayScrollbars WK_API_AVAILABLE(macos(10.14));
@property (nonatomic) BOOL alwaysKeepAndReuseSwappedProcesses WK_API_AVAILABLE(macos(10.14), ios(12.0));
@property (nonatomic) BOOL processSwapsOnWindowOpenWithOpener WK_API_AVAILABLE(macos(10.14), ios(12.0));
@property (nonatomic) BOOL processSwapsOnNavigationWithinSameNonHTTPFamilyProtocol WK_API_AVAILABLE(macos(12.0), ios(15.0));
diff --git a/Source/WebKit/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.mm b/Source/WebKit/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.mm
index 2e235bb880c638a0e74256b6d66cb0244ea0a3f1..3471eebb47e860f7c2071d0e7f2691c9f0a6355d 100644
--- a/Source/WebKit/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.mm
+++ b/Source/WebKit/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.mm
@@ -257,6 +257,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 37fc2ad398dfb9a821b381308e901d194dfea05a..17bd960aa28eec80ed78878a76f32a45d238ab04 100644
--- a/Source/WebKit/UIProcess/API/Cocoa/_WKRemoteWebInspectorViewController.mm
+++ b/Source/WebKit/UIProcess/API/Cocoa/_WKRemoteWebInspectorViewController.mm
@@ -24,6 +24,7 @@
*/
#import "config.h"
+#import "WKWebViewPrivate.h"
#import "_WKRemoteWebInspectorViewControllerInternal.h"
#if PLATFORM(MAC)
diff --git a/Source/WebKit/UIProcess/API/Cocoa/_WKUserStyleSheet.h b/Source/WebKit/UIProcess/API/Cocoa/_WKUserStyleSheet.h
index 4974e14214e2bb3e982325b885bab33e54f83998..cacdf8c71fab248d38d2faf03f7affdcfed1ef62 100644
--- a/Source/WebKit/UIProcess/API/Cocoa/_WKUserStyleSheet.h
+++ b/Source/WebKit/UIProcess/API/Cocoa/_WKUserStyleSheet.h
@@ -31,6 +31,7 @@ NS_ASSUME_NONNULL_BEGIN
@class _WKUserContentWorld;
@class WKContentWorld;
@class WKWebView;
+@class WKContentWorld;
typedef NS_ENUM(NSInteger, _WKUserStyleLevel) {
_WKUserStyleUserLevel,
diff --git a/Source/WebKit/UIProcess/API/Cocoa/_WKUserStyleSheet.mm b/Source/WebKit/UIProcess/API/Cocoa/_WKUserStyleSheet.mm
index 1e827013c603ae8bd43d798170deb98fc3153852..2075bc78069bde530ec237c0b761773c10013948 100644
--- a/Source/WebKit/UIProcess/API/Cocoa/_WKUserStyleSheet.mm
+++ b/Source/WebKit/UIProcess/API/Cocoa/_WKUserStyleSheet.mm
@@ -35,6 +35,7 @@
#import "WebPageProxy.h"
#import "_WKUserContentWorldInternal.h"
#import <WebCore/WebCoreObjCExtras.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..575245fc1f279a75f7e74c26652cf772a2fc95b7
--- /dev/null
+++ b/Source/WebKit/UIProcess/API/glib/WebKitBrowserInspector.cpp
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2019 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebKitBrowserInspector.h"
+
+#include "BrowserInspectorPipe.h"
+#include "InspectorPlaywrightAgentClientGLib.h"
+#include "WebKitBrowserInspectorPrivate.h"
+#include "WebKitWebViewPrivate.h"
+#include <wtf/glib/GRefPtr.h>
+#include <wtf/glib/WTFGType.h>
+
+/**
+ * SECTION: WebKitBrowserInspector
+ * @Short_description: Access to the WebKit browser inspector
+ * @Title: WebKitBrowserInspector
+ *
+ * The WebKit Browser Inspector is an experimental API that provides
+ * access to the inspector via the remote debugging protocol. The protocol
+ * allows to create ephemeral contexts and create pages in them and then
+ * manipulate them using the inspector commands. This may be useful for
+ * the browser automation or remote debugging.
+ *
+ * Currently the protocol can be exposed to the parent process via a unix
+ * pipe.
+ */
+
+enum {
+ CREATE_NEW_PAGE,
+ QUIT_APPLICATION,
+
+ LAST_SIGNAL
+};
+
+struct _WebKitBrowserInspectorPrivate {
+ int unused { 0 };
+};
+
+WEBKIT_DEFINE_TYPE(WebKitBrowserInspector, webkit_browser_inspector, G_TYPE_OBJECT)
+
+static guint signals[LAST_SIGNAL] = { 0, };
+
+static void webkit_browser_inspector_class_init(WebKitBrowserInspectorClass* findClass)
+{
+ GObjectClass* gObjectClass = G_OBJECT_CLASS(findClass);
+
+ /**
+ * WebKitBrowserInspector::create-new-page:
+ * @inspector: the #WebKitBrowserInspector on which the signal is emitted
+ *
+ * Emitted when the inspector is requested to create a new page in the provided
+ * #WebKitWebContext.
+ *
+ * This signal is emitted when inspector receives 'Browser.createPage' command
+ * from its remote client. If the signal is not handled the command will fail.
+ *
+ * Returns: %WebKitWebView that contains created page.
+ */
+ signals[CREATE_NEW_PAGE] = g_signal_new(
+ "create-new-page",
+ G_TYPE_FROM_CLASS(gObjectClass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(WebKitBrowserInspectorClass, create_new_page),
+ nullptr, nullptr,
+ g_cclosure_marshal_generic,
+#if PLATFORM(GTK)
+ GTK_TYPE_WIDGET,
+#else
+ WEBKIT_TYPE_WEB_VIEW,
+#endif
+ 1,
+ WEBKIT_TYPE_WEB_CONTEXT);
+
+ /**
+ * WebKitBrowserInspector::quit-application:
+ * @inspector: the #WebKitBrowserInspector on which the signal is emitted
+ *
+ * Emitted when the inspector is requested to close the browser application.
+ *
+ * This signal is emitted when inspector receives 'Browser.close' command
+ * from its remote client. If the signal is not handled the command will fail.
+ */
+ signals[QUIT_APPLICATION] = g_signal_new(
+ "quit-application",
+ G_TYPE_FROM_CLASS(gObjectClass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(WebKitBrowserInspectorClass, quit_application),
+ nullptr, nullptr,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+WebKit::WebPageProxy* webkitBrowserInspectorCreateNewPageInContext(WebKitWebContext* context)
+{
+ WebKitWebView* newWebView;
+ g_signal_emit(webkit_browser_inspector_get_default(), signals[CREATE_NEW_PAGE], 0, context, &newWebView);
+ if (!newWebView)
+ return nullptr;
+ return &webkitWebViewGetPage(newWebView);
+}
+
+void webkitBrowserInspectorQuitApplication()
+{
+ g_signal_emit(webkit_browser_inspector_get_default(), signals[QUIT_APPLICATION], 0, NULL);
+}
+
+static gpointer createWebKitBrowserInspector(gpointer)
+{
+ static GRefPtr<WebKitBrowserInspector> browserInspector = adoptGRef(WEBKIT_BROWSER_INSPECTOR(g_object_new(WEBKIT_TYPE_BROWSER_INSPECTOR, nullptr)));
+ return browserInspector.get();
+}
+
+/**
+ * webkit_browser_inspector_get_default:
+ *
+ * Gets the default instance of the browser inspector.
+ *
+ * Returns: (transfer none): a #WebKitBrowserInspector
+ */
+WebKitBrowserInspector* webkit_browser_inspector_get_default(void)
+{
+ static GOnce onceInit = G_ONCE_INIT;
+ return WEBKIT_BROWSER_INSPECTOR(g_once(&onceInit, createWebKitBrowserInspector, 0));
+}
+
+/**
+ * webkit_browser_inspector_initialize_pipe:
+ *
+ * Creates browser inspector and configures pipe handler to communicate with
+ * the parent process.
+ */
+void webkit_browser_inspector_initialize_pipe(const char* defaultProxyURI, const char* const* ignoreHosts)
+{
+ WebKit::initializeBrowserInspectorPipe(makeUnique<WebKit::InspectorPlaywrightAgentClientGlib>(String::fromUTF8(defaultProxyURI), ignoreHosts));
+}
diff --git a/Source/WebKit/UIProcess/API/glib/WebKitBrowserInspectorPrivate.h b/Source/WebKit/UIProcess/API/glib/WebKitBrowserInspectorPrivate.h
new file mode 100644
index 0000000000000000000000000000000000000000..e0b1da48465c850f541532ed961d1b778bea6028
--- /dev/null
+++ b/Source/WebKit/UIProcess/API/glib/WebKitBrowserInspectorPrivate.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2019 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "WebKitBrowserInspector.h"
+#include "WebPageProxy.h"
+
+WebKit::WebPageProxy* webkitBrowserInspectorCreateNewPageInContext(WebKitWebContext*);
+void webkitBrowserInspectorQuitApplication();
diff --git a/Source/WebKit/UIProcess/API/glib/WebKitUIClient.cpp b/Source/WebKit/UIProcess/API/glib/WebKitUIClient.cpp
index 64c90f9f25fc44911e819ab94fa973bf0b82a0e4..8d8c739fb903b71f7881801cb41901f241709b2a 100644
--- a/Source/WebKit/UIProcess/API/glib/WebKitUIClient.cpp
+++ b/Source/WebKit/UIProcess/API/glib/WebKitUIClient.cpp
@@ -98,6 +98,10 @@ private:
page.makeViewBlankIfUnpaintedSinceLastLoadCommit();
webkitWebViewRunJavaScriptPrompt(m_webView, message.utf8(), defaultValue.utf8(), WTFMove(completionHandler));
}
+ void handleJavaScriptDialog(WebPageProxy&, bool accept, const String& value) final
+ {
+ webkitWebViewHandleJavaScriptDialog(m_webView, accept, value);
+ }
bool canRunBeforeUnloadConfirmPanel() const final { return true; }
diff --git a/Source/WebKit/UIProcess/API/glib/WebKitWebContext.cpp b/Source/WebKit/UIProcess/API/glib/WebKitWebContext.cpp
index 3c6482c9fa52135d6aa0ceee148a02c02c4b080c..97860d7823c9f6367f2ead31735b1eeed8b1c9bb 100644
--- a/Source/WebKit/UIProcess/API/glib/WebKitWebContext.cpp
+++ b/Source/WebKit/UIProcess/API/glib/WebKitWebContext.cpp
@@ -404,10 +404,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);
@@ -460,6 +469,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;
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 b3f5f45aeb30c1019dfa6470edd6e8cecb717ba8..ebfb314c82bdc1ef844870a7b5d0d6071db0dd81 100644
--- a/Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp
+++ b/Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp
@@ -32,6 +32,7 @@
#include "WebCertificateInfo.h"
#include "WebContextMenuItem.h"
#include "WebContextMenuItemData.h"
+#include "WebPageInspectorController.h"
#include "WebKitAuthenticationRequestPrivate.h"
#include "WebKitBackForwardListPrivate.h"
#include "WebKitContextMenuClient.h"
@@ -51,6 +52,7 @@
#include "WebKitJavascriptResultPrivate.h"
#include "WebKitNavigationClient.h"
#include "WebKitNotificationPrivate.h"
+#include "WebKitPointerLockPermissionRequest.h"
#include "WebKitPrivate.h"
#include "WebKitResponsePolicyDecision.h"
#include "WebKitScriptDialogPrivate.h"
@@ -85,7 +87,6 @@
#if PLATFORM(GTK)
#include "WebKitInputMethodContextImplGtk.h"
-#include "WebKitPointerLockPermissionRequest.h"
#include "WebKitPrintOperationPrivate.h"
#include "WebKitWebInspectorPrivate.h"
#include "WebKitWebViewBasePrivate.h"
@@ -133,6 +134,7 @@ enum {
CLOSE,
SCRIPT_DIALOG,
+ SCRIPT_DIALOG_HANDLED,
DECIDE_POLICY,
PERMISSION_REQUEST,
@@ -471,6 +473,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 inFrameDisplayedGuard(m_webView->priv->inFrameDisplayed, true);
for (const auto& callback : m_webView->priv->frameDisplayedCallbacks) {
@@ -501,6 +506,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)
@@ -552,7 +558,7 @@ static gboolean webkitWebViewDecidePolicy(WebKitWebView*, WebKitPolicyDecision*
static gboolean webkitWebViewPermissionRequest(WebKitWebView*, WebKitPermissionRequest* request)
{
-#if ENABLE(POINTER_LOCK)
+#if ENABLE(POINTER_LOCK) && PLATFORM(GTK)
if (WEBKIT_IS_POINTER_LOCK_PERMISSION_REQUEST(request)) {
webkit_permission_request_allow(request);
return TRUE;
@@ -1784,6 +1790,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
@@ -2616,6 +2631,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 fbab1afe9ca09f5e6a6793f5065f08fc76bfedaf..23f66f4da6229d88271e4b732414088b7cc0397e 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 5a44624f8d2fc8fb7f8871c97c8ffd3cd73c3b5e..39751c87230dee3e800b8c1c8a54fbe86efc5b3f 100644
--- a/Source/WebKit/UIProcess/API/gtk/PageClientImpl.cpp
+++ b/Source/WebKit/UIProcess/API/gtk/PageClientImpl.cpp
@@ -252,6 +252,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 54293e7e4c923eafb2459c243cc9a3913e970e3f..f7a16a553798b0608371cb9a4aade2c0ccb00114 100644
--- a/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBase.cpp
+++ b/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBase.cpp
@@ -2558,6 +2558,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 b60e10c4fb1c6c867579b58661a6e3f017ba81b0..3f8ec4479449e9cc1e3b2503ba2e3e352e329d84 100644
--- a/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBasePrivate.h
+++ b/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBasePrivate.h
@@ -27,6 +27,7 @@
#pragma once
+#include "AcceleratedBackingStore.h"
#include "APIPageConfiguration.h"
#include "InputMethodState.h"
#include "SameDocumentNavigationType.h"
@@ -122,3 +123,5 @@ void webkitWebViewBaseSynthesizeWheelEvent(WebKitWebViewBase*, const GdkEvent*,
void webkitWebViewBaseMakeBlank(WebKitWebViewBase*, bool);
void webkitWebViewBasePageGrabbedTouch(WebKitWebViewBase*);
void webkitWebViewBaseSetShouldNotifyFocusEvents(WebKitWebViewBase*, bool);
+
+WebKit::AcceleratedBackingStore* webkitWebViewBaseGetAcceleratedBackingStore(WebKitWebViewBase*);
diff --git a/Source/WebKit/UIProcess/API/gtk/webkit2.h b/Source/WebKit/UIProcess/API/gtk/webkit2.h
index 5cd9524252a97d4ea64dfeb22e5a47b55f36c887..45da62b4ffe54d5cfd680dd40cabd6f45bc993a6 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/WebKitColorChooserRequest.h>
#include <webkit2/WebKitContextMenu.h>
#include <webkit2/WebKitContextMenuActions.h>
diff --git a/Source/WebKit/UIProcess/API/wpe/PageClientImpl.cpp b/Source/WebKit/UIProcess/API/wpe/PageClientImpl.cpp
index cfe3689f22c6659ceab3950e40b686e9b97b4254..d2de92105afecd8e1a5ffb6de16965aad74c71a0 100644
--- a/Source/WebKit/UIProcess/API/wpe/PageClientImpl.cpp
+++ b/Source/WebKit/UIProcess/API/wpe/PageClientImpl.cpp
@@ -32,8 +32,11 @@
#include "NativeWebWheelEvent.h"
#include "TouchGestureController.h"
#include "WPEView.h"
+#include "WebColorPickerWPE.h"
+#include "WebDateTimePickerWPE.h"
#include "WebContextMenuProxy.h"
#include "WebContextMenuProxyWPE.h"
+#include "WebKitDataListSuggestionsDropdown.h"
#include "WebKitPopupMenu.h"
#include <WebCore/ActivityState.h>
#include <WebCore/DOMPasteAccess.h>
@@ -194,7 +197,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)
@@ -447,4 +450,23 @@ void PageClientImpl::selectionDidChange()
m_view.selectionDidChange();
}
+#if ENABLE(DATALIST_ELEMENT)
+RefPtr<WebKit::WebDataListSuggestionsDropdown> PageClientImpl::createDataListSuggestionsDropdown(WebKit::WebPageProxy& page)
+{
+ return WebKitDataListSuggestionsDropdown::create(page);
+}
+#endif
+
+RefPtr<WebColorPicker> PageClientImpl::createColorPicker(WebPageProxy* page, const WebCore::Color& color, const WebCore::IntRect& rect, Vector<WebCore::Color>&&)
+{
+ return WebColorPickerWPE::create(*page, color, rect);
+}
+
+#if ENABLE(DATE_AND_TIME_INPUT_TYPES)
+RefPtr<WebDateTimePicker> PageClientImpl::createDateTimePicker(WebPageProxy& page)
+{
+ return WebDateTimePickerWPE::create(page);
+}
+#endif
+
} // namespace WebKit
diff --git a/Source/WebKit/UIProcess/API/wpe/PageClientImpl.h b/Source/WebKit/UIProcess/API/wpe/PageClientImpl.h
index 7c08a13e10c75677452b74f52be2b447a5edaa13..56cf11581d453e8234f0957828083ee7c9bce8a6 100644
--- a/Source/WebKit/UIProcess/API/wpe/PageClientImpl.h
+++ b/Source/WebKit/UIProcess/API/wpe/PageClientImpl.h
@@ -167,6 +167,17 @@ private:
void selectionDidChange() override;
+#if ENABLE(DATALIST_ELEMENT)
+ RefPtr<WebKit::WebDataListSuggestionsDropdown> createDataListSuggestionsDropdown(WebKit::WebPageProxy& page) override;
+#endif
+
+#if ENABLE(INPUT_TYPE_COLOR)
+ RefPtr<WebColorPicker> createColorPicker(WebPageProxy*, const WebCore::Color& initialColor, const WebCore::IntRect&, Vector<WebCore::Color>&&) override;
+#endif
+#if ENABLE(DATE_AND_TIME_INPUT_TYPES)
+ RefPtr<WebDateTimePicker> createDateTimePicker(WebPageProxy&) override;
+#endif
+
WKWPE::View& m_view;
};
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/WebKitDataListSuggestionsDropdown.cpp b/Source/WebKit/UIProcess/API/wpe/WebKitDataListSuggestionsDropdown.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..afafef2b7fb433e006b1763e653e200bc80edcbd
--- /dev/null
+++ b/Source/WebKit/UIProcess/API/wpe/WebKitDataListSuggestionsDropdown.cpp
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2019 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebKitDataListSuggestionsDropdown.h"
+
+#if ENABLE(DATALIST_ELEMENT)
+
+#include "WebPageProxy.h"
+
+namespace WebKit {
+
+WebKitDataListSuggestionsDropdown::WebKitDataListSuggestionsDropdown(WebPageProxy& page)
+ : WebDataListSuggestionsDropdown(page)
+{
+}
+
+WebKitDataListSuggestionsDropdown::~WebKitDataListSuggestionsDropdown()
+{
+}
+
+void WebKitDataListSuggestionsDropdown::show(WebCore::DataListSuggestionInformation&& information)
+{
+}
+
+void WebKitDataListSuggestionsDropdown::handleKeydownWithIdentifier(const String& key)
+{
+}
+
+void WebKitDataListSuggestionsDropdown::close()
+{
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(DATALIST_ELEMENT)
diff --git a/Source/WebKit/UIProcess/API/wpe/WebKitDataListSuggestionsDropdown.h b/Source/WebKit/UIProcess/API/wpe/WebKitDataListSuggestionsDropdown.h
new file mode 100644
index 0000000000000000000000000000000000000000..0a099832c3dd959f456fcae49a1d62a9477d2758
--- /dev/null
+++ b/Source/WebKit/UIProcess/API/wpe/WebKitDataListSuggestionsDropdown.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2019 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(DATALIST_ELEMENT)
+
+#include "WebDataListSuggestionsDropdown.h"
+
+namespace WebKit {
+
+class WebPageProxy;
+
+class WebKitDataListSuggestionsDropdown final : public WebDataListSuggestionsDropdown {
+public:
+ static Ref<WebKitDataListSuggestionsDropdown> create(WebPageProxy& page)
+ {
+ return adoptRef(*new WebKitDataListSuggestionsDropdown(page));
+ }
+
+ ~WebKitDataListSuggestionsDropdown();
+
+private:
+ WebKitDataListSuggestionsDropdown(WebPageProxy&);
+
+ void show(WebCore::DataListSuggestionInformation&&) final;
+ void handleKeydownWithIdentifier(const String&) final;
+ void close() final;
+};
+
+} // namespace WebKit
+
+#endif // ENABLE(DATALIST_ELEMENT)
diff --git a/Source/WebKit/UIProcess/API/wpe/WebKitPointerLockPermissionRequest.h b/Source/WebKit/UIProcess/API/wpe/WebKitPointerLockPermissionRequest.h
new file mode 100644
index 0000000000000000000000000000000000000000..a47e7eeb15094655c87d41ad0de7973306121184
--- /dev/null
+++ b/Source/WebKit/UIProcess/API/wpe/WebKitPointerLockPermissionRequest.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2019 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION)
+#error "Only <webkit2/webkit2.h> can be included directly."
+#endif
+
+#ifndef WebKitPointerLockPermissionRequest_h
+#define WebKitPointerLockPermissionRequest_h
+
+#include <glib-object.h>
+#include <wpe/WebKitDefines.h>
+
+G_BEGIN_DECLS
+
+#define WEBKIT_TYPE_POINTER_LOCK_PERMISSION_REQUEST (webkit_pointer_lock_permission_request_get_type())
+#define WEBKIT_POINTER_LOCK_PERMISSION_REQUEST(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_POINTER_LOCK_PERMISSION_REQUEST, WebKitPointerLockPermissionRequest))
+#define WEBKIT_POINTER_LOCK_PERMISSION_REQUEST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WEBKIT_TYPE_POINTER_LOCK_PERMISSION_REQUEST, WebKitPointerLockPermissionRequestClass))
+#define WEBKIT_IS_POINTER_LOCK_PERMISSION_REQUEST(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_POINTER_LOCK_PERMISSION_REQUEST))
+#define WEBKIT_IS_POINTER_LOCK_PERMISSION_REQUEST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_POINTER_LOCK_PERMISSION_REQUEST))
+#define WEBKIT_POINTER_LOCK_PERMISSION_REQUEST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_POINTER_LOCK_PERMISSION_REQUEST, WebKitPointerLockPermissionRequestClass))
+
+typedef struct _WebKitPointerLockPermissionRequest WebKitPointerLockPermissionRequest;
+typedef struct _WebKitPointerLockPermissionRequestClass WebKitPointerLockPermissionRequestClass;
+typedef struct _WebKitPointerLockPermissionRequestPrivate WebKitPointerLockPermissionRequestPrivate;
+
+struct _WebKitPointerLockPermissionRequest {
+ GObject parent;
+
+ /*< private >*/
+ WebKitPointerLockPermissionRequestPrivate *priv;
+};
+
+struct _WebKitPointerLockPermissionRequestClass {
+ GObjectClass parent_class;
+
+ void (*_webkit_reserved0) (void);
+ void (*_webkit_reserved1) (void);
+ void (*_webkit_reserved2) (void);
+ void (*_webkit_reserved3) (void);
+};
+
+WEBKIT_API GType
+webkit_pointer_lock_permission_request_get_type (void);
+
+G_END_DECLS
+
+#endif
diff --git a/Source/WebKit/UIProcess/API/wpe/WebKitWebViewBackend.cpp b/Source/WebKit/UIProcess/API/wpe/WebKitWebViewBackend.cpp
index 763bda5b29304f7ed7133c0a8158e6c8b94c5ea1..ff5d01438e44ce6785a2aa70fc5423ba74e7101c 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/webkit.h b/Source/WebKit/UIProcess/API/wpe/webkit.h
index c2221efc00618c2ec4d20a88c59840767bd52ff5..71f1cd7e07c705a7c830ff5c4f7d7f981bb363f2 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 d3a707a6b440421565144a56e586fa2723fe41c3..6e2492539efdf476452873f069bdaa34163f4a30 100644
--- a/Source/WebKit/UIProcess/BackingStore.h
+++ b/Source/WebKit/UIProcess/BackingStore.h
@@ -51,6 +51,7 @@ public:
#if USE(CAIRO)
typedef cairo_t* PlatformGraphicsContext;
+ cairo_surface_t* surface() const;
#endif
void paint(PlatformGraphicsContext, const WebCore::IntRect&);
diff --git a/Source/WebKit/UIProcess/BrowserInspectorPipe.cpp b/Source/WebKit/UIProcess/BrowserInspectorPipe.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..cfb57a48ce387b79613b757e2eb4de2c378aac30
--- /dev/null
+++ b/Source/WebKit/UIProcess/BrowserInspectorPipe.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2019 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "BrowserInspectorPipe.h"
+
+#if ENABLE(REMOTE_INSPECTOR)
+
+#include "InspectorPlaywrightAgent.h"
+#include "InspectorPlaywrightAgentClient.h"
+#include "RemoteInspectorPipe.h"
+#include "WebKit2Initialize.h"
+#include <wtf/NeverDestroyed.h>
+
+namespace WebKit {
+
+void initializeBrowserInspectorPipe(std::unique_ptr<InspectorPlaywrightAgentClient> client)
+{
+ // Initialize main loop before creating inspecor agent and pipe queues.
+ WebKit::InitializeWebKit2();
+
+ class BrowserInspectorPipe {
+ public:
+ BrowserInspectorPipe(std::unique_ptr<InspectorPlaywrightAgentClient> client)
+ : m_playwrightAgent(std::move(client))
+ , m_remoteInspectorPipe(m_playwrightAgent)
+ {
+ }
+
+ InspectorPlaywrightAgent m_playwrightAgent;
+ RemoteInspectorPipe m_remoteInspectorPipe;
+ };
+
+ static NeverDestroyed<BrowserInspectorPipe> pipe(std::move(client));
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(REMOTE_INSPECTOR)
diff --git a/Source/WebKit/UIProcess/BrowserInspectorPipe.h b/Source/WebKit/UIProcess/BrowserInspectorPipe.h
new file mode 100644
index 0000000000000000000000000000000000000000..cd66887de171cda7d15a8e4dc6dbff63665dc619
--- /dev/null
+++ b/Source/WebKit/UIProcess/BrowserInspectorPipe.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2019 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(REMOTE_INSPECTOR)
+
+namespace WebKit {
+
+class InspectorPlaywrightAgentClient;
+
+void initializeBrowserInspectorPipe(std::unique_ptr<InspectorPlaywrightAgentClient> client);
+
+} // namespace WebKit
+
+#endif // ENABLE(REMOTE_INSPECTOR)
diff --git a/Source/WebKit/UIProcess/Cocoa/AutomationClient.mm b/Source/WebKit/UIProcess/Cocoa/AutomationClient.mm
index 30860712f58b2a8d48cef5da4e6f03345f2921ba..e715496c24529689784ba4d481d23441ab68cf1e 100644
--- a/Source/WebKit/UIProcess/Cocoa/AutomationClient.mm
+++ b/Source/WebKit/UIProcess/Cocoa/AutomationClient.mm
@@ -35,6 +35,7 @@
#import <wtf/RunLoop.h>
#import <wtf/spi/cf/CFBundleSPI.h>
#import <wtf/text/WTFString.h>
+#import <wtf/RunLoop.h>
using namespace Inspector;
diff --git a/Source/WebKit/UIProcess/Cocoa/ModalContainerControlClassifier.mm b/Source/WebKit/UIProcess/Cocoa/ModalContainerControlClassifier.mm
index 9edf4e2ca81f85f4cf8827932964e5fc352af99e..2eb7b0a327f517b7975cc0cab100a3818d44635e 100644
--- a/Source/WebKit/UIProcess/Cocoa/ModalContainerControlClassifier.mm
+++ b/Source/WebKit/UIProcess/Cocoa/ModalContainerControlClassifier.mm
@@ -36,6 +36,11 @@
#import <pal/cocoa/CoreMLSoftLink.h>
#import <pal/cocoa/NaturalLanguageSoftLink.h>
+#include <wtf/CrossThreadCopier.h>
+#include <wtf/CompletionHandler.h>
+
+#include <wtf/RunLoop.h>
+
static NSString *const classifierInputFeatureKey = @"text";
static NSString *const classifierOutputFeatureKey = @"label";
diff --git a/Source/WebKit/UIProcess/Cocoa/SOAuthorization/PopUpSOAuthorizationSession.h b/Source/WebKit/UIProcess/Cocoa/SOAuthorization/PopUpSOAuthorizationSession.h
index 454c61ffdefecc476d1560c7c43f5b5d345f281d..59f93c79167d3d392b46ff5243494b02af073550 100644
--- a/Source/WebKit/UIProcess/Cocoa/SOAuthorization/PopUpSOAuthorizationSession.h
+++ b/Source/WebKit/UIProcess/Cocoa/SOAuthorization/PopUpSOAuthorizationSession.h
@@ -29,6 +29,7 @@
#include "SOAuthorizationSession.h"
#include <wtf/CompletionHandler.h>
+#include <wtf/Forward.h>
OBJC_CLASS WKSOSecretDelegate;
OBJC_CLASS WKWebView;
@@ -39,6 +40,8 @@ class NavigationAction;
namespace WebKit {
+class WebPageProxy;
+
// FSM: Idle => Active => Completed
class PopUpSOAuthorizationSession final : public SOAuthorizationSession {
public:
diff --git a/Source/WebKit/UIProcess/Cocoa/UIDelegate.h b/Source/WebKit/UIProcess/Cocoa/UIDelegate.h
index 20b08ac2df75f589bbbe29e2f924c92f33cf2242..2aaa37a18eb31ade4ff8d7fb8b85fee612bb47f1 100644
--- a/Source/WebKit/UIProcess/Cocoa/UIDelegate.h
+++ b/Source/WebKit/UIProcess/Cocoa/UIDelegate.h
@@ -95,6 +95,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;
@@ -198,6 +199,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 be5ac6eefad0e4b6f3c02bb5c60765dbfb7eb1ff..dfc01d10998ec98d0affd93c4f17653586c1444b 100644
--- a/Source/WebKit/UIProcess/Cocoa/UIDelegate.mm
+++ b/Source/WebKit/UIProcess/Cocoa/UIDelegate.mm
@@ -111,6 +111,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.webViewRequestGeolocationPermissionForOriginDecisionHandler = [delegate respondsToSelector:@selector(_webView:requestGeolocationPermissionForOrigin:initiatedByFrame:decisionHandler:)];
@@ -411,6 +412,15 @@ void UIDelegate::UIClient::runJavaScriptPrompt(WebPageProxy& page, const WTF::St
}).get()];
}
+void UIDelegate::UIClient::handleJavaScriptDialog(WebKit::WebPageProxy&, bool accept, const WTF::String& value) {
+ if (!m_uiDelegate->m_delegateMethods.webViewHandleJavaScriptDialogValue)
+ return;
+ auto delegate = m_uiDelegate->m_delegate.get();
+ if (!delegate)
+ return;
+ [delegate webView:m_uiDelegate->m_webView.get().get() handleJavaScriptDialog:accept value:value];
+}
+
void UIDelegate::UIClient::requestStorageAccessConfirm(WebPageProxy& webPageProxy, WebFrameProxy*, const WebCore::RegistrableDomain& requestingDomain, const WebCore::RegistrableDomain& currentDomain, CompletionHandler<void(bool)>&& completionHandler)
{
if (!m_uiDelegate)
diff --git a/Source/WebKit/UIProcess/Cocoa/WebPageProxyCocoa.mm b/Source/WebKit/UIProcess/Cocoa/WebPageProxyCocoa.mm
index 6f380789014dc0f6ffa648055760370ff22391a9..f6e6d4054b5c75af0effd8e8b36a3d2c5941b212 100644
--- a/Source/WebKit/UIProcess/Cocoa/WebPageProxyCocoa.mm
+++ b/Source/WebKit/UIProcess/Cocoa/WebPageProxyCocoa.mm
@@ -37,6 +37,7 @@
#import "LoadParameters.h"
#import "ModalContainerControlClassifier.h"
#import "PageClient.h"
+#import "PasteboardTypes.h"
#import "PlaybackSessionManagerProxy.h"
#import "QuickLookThumbnailLoader.h"
#import "SafeBrowsingSPI.h"
@@ -252,9 +253,66 @@ bool WebPageProxy::scrollingUpdatesDisabledForTesting()
void WebPageProxy::startDrag(const DragItem& dragItem, const ShareableBitmap::Handle& dragImageHandle)
{
+ if (m_interceptDrags) {
+ NSPasteboard *pasteboard = [NSPasteboard pasteboardWithName: m_overrideDragPasteboardName];
+
+ m_dragSelectionData = String([pasteboard name]);
+ grantAccessToCurrentPasteboardData(String([pasteboard name]));
+ m_dragSourceOperationMask = WebCore::anyDragOperation();
+
+ if (auto& info = dragItem.promisedAttachmentInfo) {
+ auto attachment = attachmentForIdentifier(info.attachmentIdentifier);
+ if (!attachment) {
+ dragCancelled();
+ return;
+ }
+ NSString *utiType = attachment->utiType();
+ if (!utiType.length) {
+ dragCancelled();
+ return;
+ }
+
+ ASSERT(info.additionalTypes.size() == info.additionalData.size());
+ if (info.additionalTypes.size() == info.additionalData.size()) {
+ for (size_t index = 0; index < info.additionalTypes.size(); ++index) {
+ auto nsData = info.additionalData[index]->createNSData();
+ [pasteboard setData:nsData.get() forType:info.additionalTypes[index]];
+ }
+ }
+ } else {
+ [pasteboard setString:@"" forType:PasteboardTypes::WebDummyPboardType];
+ }
+ didStartDrag();
+ return;
+ }
+
pageClient().startDrag(dragItem, dragImageHandle);
}
+void WebPageProxy::releaseInspectorDragPasteboard() {
+ if (!!m_dragSelectionData)
+ m_dragSelectionData = std::nullopt;
+ if (!m_overrideDragPasteboardName.isEmpty()) {
+ NSPasteboard *pasteboard = [NSPasteboard pasteboardWithUniqueName];
+ [pasteboard releaseGlobally];
+ m_overrideDragPasteboardName = ""_s;
+ }
+}
+
+
+void WebPageProxy::setInterceptDrags(bool shouldIntercept) {
+ m_interceptDrags = shouldIntercept;
+ if (m_interceptDrags) {
+ if (m_overrideDragPasteboardName.isEmpty()) {
+ NSPasteboard *pasteboard = [NSPasteboard pasteboardWithUniqueName];
+ m_overrideDragPasteboardName = String([pasteboard name]);
+ }
+ send(Messages::WebPage::SetDragPasteboardName(m_overrideDragPasteboardName));
+ } else {
+ send(Messages::WebPage::SetDragPasteboardName(""_s));
+ }
+}
+
// FIXME: Move these functions to WebPageProxyIOS.mm.
#if PLATFORM(IOS_FAMILY)
diff --git a/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm b/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm
index 67c9da2a619319ee4ad11c226654579e411a14c0..3566f0ca4acbcae4d28b4ed0d52c66effa68055d 100644
--- a/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm
+++ b/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm
@@ -364,7 +364,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)
@@ -629,8 +629,8 @@ void WebProcessPool::registerNotificationObservers()
}];
m_scrollerStyleNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:NSPreferredScrollerStyleDidChangeNotification object:nil queue:[NSOperationQueue currentQueue] usingBlock:^(NSNotification *notification) {
- auto scrollbarStyle = [NSScroller preferredScrollerStyle];
- sendToAllProcesses(Messages::WebProcess::ScrollerStylePreferenceChanged(scrollbarStyle));
+ bool useOverlayScrollbars = m_configuration->forceOverlayScrollbars() || ([NSScroller preferredScrollerStyle] == NSScrollerStyleOverlay);
+ sendToAllProcesses(Messages::WebProcess::ScrollerStylePreferenceChanged(useOverlayScrollbars));
}];
m_activationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:NSApplicationDidBecomeActiveNotification object:NSApp queue:[NSOperationQueue currentQueue] usingBlock:^(NSNotification *notification) {
diff --git a/Source/WebKit/UIProcess/Cocoa/WebViewImpl.h b/Source/WebKit/UIProcess/Cocoa/WebViewImpl.h
index 1234f6f1344764cdb086ba6b9d05680d23dff34b..a04ecc1d18e5787624af5a86637064484881c3ff 100644
--- a/Source/WebKit/UIProcess/Cocoa/WebViewImpl.h
+++ b/Source/WebKit/UIProcess/Cocoa/WebViewImpl.h
@@ -507,6 +507,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 a5d05fe4ae7fb4eeef125cb5ddcf96208de84066..518f11059640b1e61c57d0fc7622e7579f71c607 100644
--- a/Source/WebKit/UIProcess/Cocoa/WebViewImpl.mm
+++ b/Source/WebKit/UIProcess/Cocoa/WebViewImpl.mm
@@ -2776,6 +2776,11 @@ WebCore::DestinationColorSpace WebViewImpl::colorSpace()
if (!m_colorSpace)
m_colorSpace = [NSColorSpace sRGBColorSpace];
}
+ // Playwright begin
+ // window.colorSpace is sometimes null on popup windows in headless mode
+ if (!m_colorSpace)
+ return WebCore::DestinationColorSpace::SRGB();
+ // Playwright end
ASSERT(m_colorSpace);
return WebCore::DestinationColorSpace { [m_colorSpace CGColorSpace] };
@@ -4775,6 +4780,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 32c82b899b301c957c5632c09e0ae321cf64e961..71cabafb96edd24d63f21f7fcc0a841cf8e72deb 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
@@ -46,6 +49,13 @@
#include <wtf/glib/RunLoopSourcePriority.h>
#endif
+#if PLATFORM(WIN)
+#include <cairo-win32.h>
+#include <windows.h>
+#include <WebCore/HWndDC.h>
+#include <WebCore/RefPtrCairo.h>
+#endif
+
namespace WebKit {
using namespace WebCore;
@@ -114,6 +124,10 @@ void DrawingAreaProxyCoordinatedGraphics::paint(BackingStore::PlatformGraphicsCo
void DrawingAreaProxyCoordinatedGraphics::sizeDidChange()
{
+ for (auto& value : m_callbacks)
+ value();
+ m_callbacks.clear();
+
backingStoreStateDidChange(RespondImmediately);
}
@@ -122,6 +136,11 @@ void DrawingAreaProxyCoordinatedGraphics::deviceScaleFactorDidChange()
backingStoreStateDidChange(RespondImmediately);
}
+void DrawingAreaProxyCoordinatedGraphics::waitForSizeUpdate(Function<void ()>&& callback)
+{
+ m_callbacks.append(WTFMove(callback));
+}
+
void DrawingAreaProxyCoordinatedGraphics::waitForBackingStoreUpdateOnNextPaint()
{
m_hasReceivedFirstUpdate = true;
@@ -244,6 +263,45 @@ void DrawingAreaProxyCoordinatedGraphics::targetRefreshRateDidChange(unsigned ra
send(Messages::DrawingArea::TargetRefreshRateDidChange(rate));
}
+#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 f3dfe6614bad532c49995cf7afc5f6818a469ca6..78971e7296e5395079590fdf491b1ba1781b216f 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
@@ -69,6 +74,9 @@ private:
void exitAcceleratedCompositingMode(uint64_t backingStoreStateID, const UpdateInfo&) override;
void updateAcceleratedCompositingMode(uint64_t backingStoreStateID, const LayerTreeContext&) override;
void targetRefreshRateDidChange(unsigned) override;
+#if PLATFORM(WIN)
+ void didChangeAcceleratedCompositingMode(bool enabled) override;
+#endif
#if !PLATFORM(WPE)
void incorporateUpdate(const UpdateInfo&);
@@ -132,12 +140,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 447320824dcb6f91eedc15f469f5fc57ce68703f..7f8b2a0ee2c5985e86ef888c6ebc709ec8fc2647 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>
#if PLATFORM(MAC)
#include <pal/spi/mac/QuarantineSPI.h>
@@ -60,7 +62,10 @@ DownloadProxy::DownloadProxy(DownloadProxyMap& downloadProxyMap, WebsiteDataStor
, m_request(resourceRequest)
, m_originatingPage(originatingPage)
, m_frameInfo(API::FrameInfo::create(FrameInfoData { frameInfoData }, originatingPage))
+ , m_uuid(createVersion4UUIDString())
{
+ if (auto* instrumentation = m_dataStore->downloadInstrumentation())
+ instrumentation->downloadCreated(m_uuid, m_request, frameInfoData, originatingPage, this);
}
DownloadProxy::~DownloadProxy()
@@ -79,9 +84,12 @@ static RefPtr<API::Data> createData(const IPC::DataReference& data)
void DownloadProxy::cancel(CompletionHandler<void(API::Data*)>&& completionHandler)
{
if (m_dataStore) {
- m_dataStore->networkProcess().sendWithAsyncReply(Messages::NetworkProcess::CancelDownload(m_downloadID), [this, protectedThis = Ref { *this }, completionHandler = WTFMove(completionHandler)] (const IPC::DataReference& resumeData) mutable {
+ auto* instrumentation = m_dataStore->downloadInstrumentation();
+ m_dataStore->networkProcess().sendWithAsyncReply(Messages::NetworkProcess::CancelDownload(m_downloadID), [this, protectedThis = Ref { *this }, completionHandler = WTFMove(completionHandler), instrumentation] (const IPC::DataReference& resumeData) mutable {
m_legacyResumeData = createData(resumeData);
completionHandler(m_legacyResumeData.get());
+ if (instrumentation)
+ instrumentation->downloadFinished(m_uuid, "canceled"_s);
m_downloadProxyMap.downloadFinished(*this);
});
} else
@@ -167,6 +175,21 @@ void DownloadProxy::decideDestinationWithSuggestedFilename(const WebCore::Resour
suggestedFilename = m_suggestedFilename;
suggestedFilename = MIMETypeRegistry::appendFileExtensionIfNecessary(suggestedFilename, response.mimeType());
+ if (auto* instrumentation = m_dataStore->downloadInstrumentation())
+ instrumentation->downloadFilenameSuggested(m_uuid, suggestedFilename);
+
+ if (m_dataStore->allowDownloadForAutomation()) {
+ SandboxExtension::Handle sandboxExtensionHandle;
+ String destination;
+ if (*m_dataStore->allowDownloadForAutomation()) {
+ destination = FileSystem::pathByAppendingComponent(m_dataStore->downloadPathForAutomation(), m_uuid);
+ if (auto handle = SandboxExtension::createHandle(destination, SandboxExtension::Type::ReadWrite))
+ sandboxExtensionHandle = WTFMove(*handle);
+ }
+ completionHandler(destination, WTFMove(sandboxExtensionHandle), AllowOverwrite::Yes);
+ return;
+ }
+
m_client->decideDestinationWithSuggestedFilename(*this, response, ResourceResponseBase::sanitizeSuggestedFilename(suggestedFilename), [this, protectedThis = Ref { *this }, completionHandler = WTFMove(completionHandler)] (AllowOverwrite allowOverwrite, String destination) mutable {
SandboxExtension::Handle sandboxExtensionHandle;
if (!destination.isNull()) {
@@ -215,6 +238,8 @@ void DownloadProxy::didFinish()
updateQuarantinePropertiesIfPossible();
#endif
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);
@@ -225,6 +250,8 @@ void DownloadProxy::didFail(const ResourceError& error, const IPC::DataReference
m_legacyResumeData = createData(resumeData);
m_client->didFail(*this, error, m_legacyResumeData.get());
+ if (auto* instrumentation = m_dataStore->downloadInstrumentation())
+ instrumentation->downloadFinished(m_uuid, error.localizedDescription());
// This can cause the DownloadProxy object to be deleted.
m_downloadProxyMap.downloadFinished(*this);
diff --git a/Source/WebKit/UIProcess/Downloads/DownloadProxy.h b/Source/WebKit/UIProcess/Downloads/DownloadProxy.h
index 26c569d3cf475e6d4320f2388e43d77014caad86..79eebdc32a322b902ed9ada16a2084c0f214049a 100644
--- a/Source/WebKit/UIProcess/Downloads/DownloadProxy.h
+++ b/Source/WebKit/UIProcess/Downloads/DownloadProxy.h
@@ -149,6 +149,7 @@ private:
#if PLATFORM(COCOA)
RetainPtr<NSProgress> m_progress;
#endif
+ String m_uuid;
};
} // namespace WebKit
diff --git a/Source/WebKit/UIProcess/DrawingAreaProxy.h b/Source/WebKit/UIProcess/DrawingAreaProxy.h
index 21dd04d3fb314a0a96ccad8191edde3ada5de326..5a2ac57e9bcedd650996161112441d9598c036ee 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.
@@ -162,6 +163,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/CairoJpegEncoder.cpp b/Source/WebKit/UIProcess/Inspector/Agents/CairoJpegEncoder.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9426d9eed59f433eac62b8eb6a16139b84079949
--- /dev/null
+++ b/Source/WebKit/UIProcess/Inspector/Agents/CairoJpegEncoder.cpp
@@ -0,0 +1,244 @@
+/* Copyright 2018 Bernhard R. Fischer, 4096R/8E24F29D <bf@abenteuerland.at>
+ *
+ * This file is part of Cairo_JPG.
+ *
+ * Cairo_JPG is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Cairo_JPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Cairo_JPG. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+/*! \file cairo_jpg.c
+ * This file contains two functions for reading and writing JPEG files from
+ * and to Cairo image surfaces. It uses the functions from the libjpeg.
+ * Most of the code is directly derived from the online example at
+ * http://libjpeg-turbo.virtualgl.org/Documentation/Documentation
+ *
+ * All prototypes are defined in cairo_jpg.h All functions and their parameters
+ * and return values are described below directly at the functions. You may
+ * also have a look at the preprocessor macros defined below.
+ *
+ * To compile this code you need to have installed the packages libcairo2-dev
+ * and libjpeg-dev. Compile with the following to create an object file to link
+ * with your code:
+ * gcc -std=c99 -Wall -c `pkg-config cairo libjpeg --cflags --libs` cairo_jpg.c
+ * Use the following command to include the main() function and create an
+ * executable for testing of this code:
+ * gcc -std=c99 -Wall -o cairo_jpg -DCAIRO_JPEG_MAIN `pkg-config cairo libjpeg --cflags --libs` cairo_jpg.c
+ *
+ * @author Bernhard R. Fischer, 4096R/8E24F29D bf@abenteuerland.at
+ * @version 2020/01/18
+ * @license LGPL3.
+ */
+
+#if USE(CAIRO)
+
+#include "CairoJpegEncoder.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <cairo.h>
+extern "C" {
+#include "jpeglib.h"
+}
+
+/*! Macro to activate main() function. This is only used for testing. Comment
+ * it out (#undef) if you link this file to your own program.
+ */
+//#define CAIRO_JPEG_MAIN
+//
+/*! Define this to use an alternate implementation of
+ * cairo_image_surface_create_from_jpeg() which fstat(3)s the file before
+ * reading (see below). For huge files this /may/ be slightly faster.
+ */
+#undef CAIRO_JPEG_USE_FSTAT
+
+/*! This is the read block size for the stream reader
+ * cairo_image_surface_create_from_jpeg_stream().
+ */
+#ifdef USE_CAIRO_READ_FUNC_LEN_T
+#define CAIRO_JPEG_IO_BLOCK_SIZE 4096
+#else
+/*! Block size has to be one if cairo_read_func_t is in use because of the lack
+ * to detect EOF (truncated reads).
+ */
+#define CAIRO_JPEG_IO_BLOCK_SIZE 1
+/*! In case of original cairo_read_func_t is used fstat() should be used for
+ * performance reasons (see CAIRO_JPEG_USE_FSTAT above).
+ */
+#define CAIRO_JPEG_USE_FSTAT
+#endif
+
+/*! Define this to test jpeg creation with non-image surfaces. This is only for
+ * testing and is to be used together with CAIRO_JPEG_MAIN.
+ */
+#undef CAIRO_JPEG_TEST_SIMILAR
+#if defined(CAIRO_JPEG_TEST_SIMILAR) && defined(CAIRO_JPEG_MAIN)
+#include <cairo-pdf.h>
+#endif
+
+
+#ifndef LIBJPEG_TURBO_VERSION
+/*! This function makes a covnersion for "odd" pixel sizes which typically is a
+ * conversion from a 3-byte to a 4-byte (or more) pixel size or vice versa.
+ * The conversion is done from the source buffer src to the destination buffer
+ * dst. The caller MUST ensure that src and dst have the correct memory size.
+ * This is dw * num for dst and sw * num for src. src and dst may point to the
+ * same memory address.
+ * @param dst Pointer to destination buffer.
+ * @param dw Pixel width (in bytes) of pixels in destination buffer, dw >= 3.
+ * @param src Pointer to source buffer.
+ * @param sw Pixel width (in bytes) of pixels in source buffer, sw >= 3.
+ * @param num Number of pixels to convert, num >= 1;
+ */
+static void pix_conv(unsigned char *dst, int dw, const unsigned char *src, int sw, int num)
+{
+ int si, di;
+
+ // safety check
+ if (dw < 3 || sw < 3 || dst == NULL || src == NULL)
+ return;
+
+ num--;
+ for (si = num * sw, di = num * dw; si >= 0; si -= sw, di -= dw)
+ {
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ dst[di + 2] = src[si ];
+ dst[di + 1] = src[si + 1];
+ dst[di + 0] = src[si + 2];
+#else
+ // FIXME: This is untested, it may be wrong.
+ dst[di - 3] = src[si - 3];
+ dst[di - 2] = src[si - 2];
+ dst[di - 1] = src[si - 1];
+#endif
+ }
+}
+#endif
+
+
+/*! This function creates a JPEG file in memory from a Cairo image surface.
+ * @param sfc Pointer to a Cairo surface. It should be an image surface of
+ * either CAIRO_FORMAT_ARGB32 or CAIRO_FORMAT_RGB24. Other formats are
+ * converted to CAIRO_FORMAT_RGB24 before compression.
+ * Please note that this may give unexpected results because JPEG does not
+ * support transparency. Thus, default background color is used to replace
+ * transparent regions. The default background color is black if not specified
+ * explicitly. Thus converting e.g. PDF surfaces without having any specific
+ * background color set will apear with black background and not white as you
+ * might expect. In such cases it is suggested to manually convert the surface
+ * to RGB24 before calling this function.
+ * @param data Pointer to a memory pointer. This parameter receives a pointer
+ * to the memory area where the final JPEG data is found in memory. This
+ * function reserves the memory properly and it has to be freed by the caller
+ * with free(3).
+ * @param len Pointer to a variable of type size_t which will receive the final
+ * lenght of the memory buffer.
+ * @param quality Compression quality, 0-100.
+ * @return On success the function returns CAIRO_STATUS_SUCCESS. In case of
+ * error CAIRO_STATUS_INVALID_FORMAT is returned.
+ */
+cairo_status_t cairo_image_surface_write_to_jpeg_mem(cairo_surface_t *sfc, unsigned char **data, size_t *len, int quality)
+{
+ struct jpeg_compress_struct cinfo;
+ struct jpeg_error_mgr jerr;
+ JSAMPROW row_pointer[1];
+ cairo_surface_t *other = NULL;
+
+ // check valid input format (must be IMAGE_SURFACE && (ARGB32 || RGB24))
+ if (cairo_surface_get_type(sfc) != CAIRO_SURFACE_TYPE_IMAGE ||
+ (cairo_image_surface_get_format(sfc) != CAIRO_FORMAT_ARGB32 &&
+ cairo_image_surface_get_format(sfc) != CAIRO_FORMAT_RGB24))
+ {
+ // create a similar surface with a proper format if supplied input format
+ // does not fulfill the requirements
+ double x1, y1, x2, y2;
+ other = sfc;
+ cairo_t *ctx = cairo_create(other);
+ // get extents of original surface
+ cairo_clip_extents(ctx, &x1, &y1, &x2, &y2);
+ cairo_destroy(ctx);
+
+ // create new image surface
+ sfc = cairo_surface_create_similar_image(other, CAIRO_FORMAT_RGB24, x2 - x1, y2 - y1);
+ if (cairo_surface_status(sfc) != CAIRO_STATUS_SUCCESS)
+ return CAIRO_STATUS_INVALID_FORMAT;
+
+ // paint original surface to new surface
+ ctx = cairo_create(sfc);
+ cairo_set_source_surface(ctx, other, 0, 0);
+ cairo_paint(ctx);
+ cairo_destroy(ctx);
+ }
+
+ // finish queued drawing operations
+ cairo_surface_flush(sfc);
+
+ // init jpeg compression structures
+ cinfo.err = jpeg_std_error(&jerr);
+ jpeg_create_compress(&cinfo);
+
+ // set compression parameters
+ unsigned long targetSize;
+ jpeg_mem_dest(&cinfo, data, &targetSize);
+
+ cinfo.image_width = cairo_image_surface_get_width(sfc);
+ cinfo.image_height = cairo_image_surface_get_height(sfc);
+#ifdef LIBJPEG_TURBO_VERSION
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ //cinfo.in_color_space = JCS_EXT_BGRX;
+ cinfo.in_color_space = cairo_image_surface_get_format(sfc) == CAIRO_FORMAT_ARGB32 ? JCS_EXT_BGRA : JCS_EXT_BGRX;
+#else
+ //cinfo.in_color_space = JCS_EXT_XRGB;
+ cinfo.in_color_space = cairo_image_surface_get_format(sfc) == CAIRO_FORMAT_ARGB32 ? JCS_EXT_ARGB : JCS_EXT_XRGB;
+#endif
+ cinfo.input_components = 4;
+#else
+ cinfo.in_color_space = JCS_RGB;
+ cinfo.input_components = 3;
+#endif
+ jpeg_set_defaults(&cinfo);
+ jpeg_set_quality(&cinfo, quality, TRUE);
+
+ // start compressor
+ jpeg_start_compress(&cinfo, TRUE);
+
+ // loop over all lines and compress
+ while (cinfo.next_scanline < cinfo.image_height)
+ {
+#ifdef LIBJPEG_TURBO_VERSION
+ row_pointer[0] = cairo_image_surface_get_data(sfc) + (cinfo.next_scanline
+ * cairo_image_surface_get_stride(sfc));
+#else
+ unsigned char row_buf[3 * cinfo.image_width];
+ pix_conv(row_buf, 3, cairo_image_surface_get_data(sfc) +
+ (cinfo.next_scanline * cairo_image_surface_get_stride(sfc)), 4, cinfo.image_width);
+ row_pointer[0] = row_buf;
+#endif
+ (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
+ }
+
+ // finalize and close everything
+ jpeg_finish_compress(&cinfo);
+ jpeg_destroy_compress(&cinfo);
+
+ // destroy temporary image surface (if available)
+ if (other != NULL)
+ cairo_surface_destroy(sfc);
+
+ *len = targetSize;
+ return CAIRO_STATUS_SUCCESS;
+}
+
+#endif
diff --git a/Source/WebKit/UIProcess/Inspector/Agents/CairoJpegEncoder.h b/Source/WebKit/UIProcess/Inspector/Agents/CairoJpegEncoder.h
new file mode 100644
index 0000000000000000000000000000000000000000..4ec8b96bbbddf8a7b042f53a8068754a384fc7ad
--- /dev/null
+++ b/Source/WebKit/UIProcess/Inspector/Agents/CairoJpegEncoder.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) Microsoft. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <cairo.h>
+
+cairo_status_t cairo_image_surface_write_to_jpeg_mem(cairo_surface_t *sfc, unsigned char **data, size_t *len, int quality);
diff --git a/Source/WebKit/UIProcess/Inspector/Agents/InspectorScreencastAgent.cpp b/Source/WebKit/UIProcess/Inspector/Agents/InspectorScreencastAgent.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..dcd6d6283cfce4be647846514736c16dadb95263
--- /dev/null
+++ b/Source/WebKit/UIProcess/Inspector/Agents/InspectorScreencastAgent.cpp
@@ -0,0 +1,304 @@
+/*
+ * 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 <pal/crypto/CryptoDigest.h>
+#include <JavaScriptCore/InspectorFrontendRouter.h>
+#include <WebCore/NotImplemented.h>
+#include <wtf/RunLoop.h>
+#include <wtf/UUID.h>
+#include <wtf/text/Base64.h>
+
+#if USE(CAIRO)
+#include "CairoJpegEncoder.h"
+#include "DrawingAreaProxyCoordinatedGraphics.h"
+#include "DrawingAreaProxy.h"
+#endif
+
+#if PLATFORM(MAC)
+#include <WebCore/ImageBufferUtilitiesCG.h>
+#endif
+
+namespace WebKit {
+
+const int kMaxFramesInFlight = 1;
+
+using namespace Inspector;
+
+InspectorScreencastAgent::InspectorScreencastAgent(BackendDispatcher& backendDispatcher, Inspector::FrontendRouter& frontendRouter, WebPageProxy& page)
+ : InspectorAgentBase("Screencast"_s)
+ , m_frontendDispatcher(makeUnique<ScreencastFrontendDispatcher>(frontendRouter))
+ , m_backendDispatcher(ScreencastBackendDispatcher::create(backendDispatcher, this))
+ , m_page(page)
+{
+}
+
+InspectorScreencastAgent::~InspectorScreencastAgent()
+{
+}
+
+void InspectorScreencastAgent::didCreateFrontendAndBackend(FrontendRouter*, BackendDispatcher*)
+{
+}
+
+void InspectorScreencastAgent::willDestroyFrontendAndBackend(DisconnectReason)
+{
+ if (!m_encoder)
+ return;
+
+ // The agent may be destroyed when the callback is invoked.
+ m_encoder->finish([sessionID = m_page.websiteDataStore().sessionID(), screencastID = WTFMove(m_currentScreencastID)] {
+ if (WebPageInspectorController::observer())
+ WebPageInspectorController::observer()->didFinishScreencast(sessionID, screencastID);
+ });
+
+ m_encoder = nullptr;
+}
+
+#if USE(CAIRO)
+void InspectorScreencastAgent::didPaint(cairo_surface_t* surface)
+{
+#if PLATFORM(WPE)
+ // Get actual image size (in device pixels).
+ WebCore::IntSize displaySize(cairo_image_surface_get_width(surface), cairo_image_surface_get_height(surface));
+
+ WebCore::IntSize drawingAreaSize = m_page.drawingArea()->size();
+ drawingAreaSize.scale(m_page.deviceScaleFactor());
+ if (drawingAreaSize != displaySize) {
+ return;
+ }
+
+#else
+ WebCore::IntSize displaySize = m_page.drawingArea()->size();
+#endif
+ if (m_encoder)
+ m_encoder->encodeFrame(surface, displaySize);
+ if (m_screencast) {
+
+ {
+ // Do not send the same frame over and over.
+ unsigned char *data = cairo_image_surface_get_data(surface);
+ int stride = cairo_image_surface_get_stride(surface);
+ int height = cairo_image_surface_get_height(surface);
+ auto cryptoDigest = PAL::CryptoDigest::create(PAL::CryptoDigest::Algorithm::SHA_1);
+ cryptoDigest->addBytes(data, stride * height);
+ auto digest = cryptoDigest->computeHash();
+ if (m_lastFrameDigest == digest)
+ return;
+ m_lastFrameDigest = digest;
+ }
+
+ if (m_screencastFramesInFlight > kMaxFramesInFlight)
+ return;
+ // Scale image to fit width / height
+ double scale = std::min(m_screencastWidth / displaySize.width(), m_screencastHeight / displaySize.height());
+ RefPtr<cairo_surface_t> scaledSurface;
+ if (scale < 1) {
+ WebCore::IntSize scaledSize = displaySize;
+ scaledSize.scale(scale);
+ cairo_matrix_t transform;
+ cairo_matrix_init_scale(&transform, scale, scale);
+ scaledSurface = adoptRef(cairo_image_surface_create(CAIRO_FORMAT_ARGB32, scaledSize.width(), scaledSize.height()));
+ RefPtr<cairo_t> cr = adoptRef(cairo_create(scaledSurface.get()));
+ cairo_transform(cr.get(), &transform);
+ cairo_set_source_surface(cr.get(), surface, 0, 0);
+ cairo_paint(cr.get());
+ surface = scaledSurface.get();
+ }
+ unsigned char *data = nullptr;
+ size_t len = 0;
+ cairo_image_surface_write_to_jpeg_mem(surface, &data, &len, m_screencastQuality);
+ String result = base64EncodeToString(data, len);
+ ++m_screencastFramesInFlight;
+ m_frontendDispatcher->screencastFrame(result, displaySize.width(), displaySize.height());
+ }
+}
+#endif
+
+Inspector::Protocol::ErrorStringOr<String /* screencastID */> InspectorScreencastAgent::startVideo(const String& file, int width, int height, int toolbarHeight)
+{
+ if (m_encoder)
+ return makeUnexpected("Already recording"_s);
+
+ if (width < 10 || width > 10000 || height < 10 || height > 10000)
+ return makeUnexpected("Invalid size"_s);
+
+ String errorString;
+ m_encoder = ScreencastEncoder::create(errorString, file, WebCore::IntSize(width, height));
+ if (!m_encoder)
+ return makeUnexpected(errorString);
+
+ m_currentScreencastID = createVersion4UUIDString();
+
+#if PLATFORM(MAC)
+ m_encoder->setOffsetTop(toolbarHeight);
+#endif
+
+ kickFramesStarted();
+ return { { m_currentScreencastID } };
+}
+
+void InspectorScreencastAgent::stopVideo(Ref<StopVideoCallback>&& callback)
+{
+ if (!m_encoder) {
+ callback->sendFailure("Not recording"_s);
+ return;
+ }
+
+ // The agent may be destroyed when the callback is invoked.
+ m_encoder->finish([sessionID = m_page.websiteDataStore().sessionID(), screencastID = WTFMove(m_currentScreencastID), callback = WTFMove(callback)] {
+ if (WebPageInspectorController::observer())
+ WebPageInspectorController::observer()->didFinishScreencast(sessionID, screencastID);
+ callback->sendSuccess();
+ });
+ m_encoder = nullptr;
+ if (!m_screencast)
+ m_framesAreGoing = false;
+}
+
+Inspector::Protocol::ErrorStringOr<int /* generation */> InspectorScreencastAgent::startScreencast(int width, int height, int toolbarHeight, int quality)
+{
+ if (m_screencast)
+ return makeUnexpected("Already screencasting"_s);
+ m_screencast = true;
+ m_screencastWidth = width;
+ m_screencastHeight = height;
+ m_screencastQuality = quality;
+ m_screencastToolbarHeight = toolbarHeight;
+ m_screencastFramesInFlight = 0;
+ ++m_screencastGeneration;
+ kickFramesStarted();
+ return m_screencastGeneration;
+}
+
+Inspector::Protocol::ErrorStringOr<void> InspectorScreencastAgent::screencastFrameAck(int generation)
+{
+ if (m_screencastGeneration != generation)
+ return { };
+ --m_screencastFramesInFlight;
+ return { };
+}
+
+Inspector::Protocol::ErrorStringOr<void> InspectorScreencastAgent::stopScreencast()
+{
+ if (!m_screencast)
+ return makeUnexpected("Not screencasting"_s);
+ m_screencast = false;
+ if (!m_encoder)
+ m_framesAreGoing = false;
+ return { };
+}
+
+void InspectorScreencastAgent::kickFramesStarted()
+{
+ if (!m_framesAreGoing) {
+ m_framesAreGoing = true;
+#if !PLATFORM(WPE)
+ scheduleFrameEncoding();
+#endif
+ }
+ m_page.forceRepaint([] { });
+}
+
+#if !PLATFORM(WPE)
+void InspectorScreencastAgent::scheduleFrameEncoding()
+{
+ if (!m_encoder && !m_screencast)
+ return;
+
+ RunLoop::main().dispatchAfter(Seconds(1.0 / ScreencastEncoder::fps), [agent = WeakPtr { this }]() mutable {
+ if (!agent)
+ return;
+
+ agent->encodeFrame();
+ agent->scheduleFrameEncoding();
+ });
+}
+#endif
+
+#if PLATFORM(MAC)
+void InspectorScreencastAgent::encodeFrame()
+{
+ if (!m_encoder && !m_screencast)
+ return;
+ RetainPtr<CGImageRef> imageRef = m_page.pageClient().takeSnapshotForAutomation();
+ if (m_screencast && m_screencastFramesInFlight <= kMaxFramesInFlight) {
+ CGImage* imagePtr = imageRef.get();
+ WebCore::IntSize imageSize(CGImageGetWidth(imagePtr), CGImageGetHeight(imagePtr));
+ WebCore::IntSize displaySize = imageSize;
+ displaySize.contract(0, m_screencastToolbarHeight);
+ double scale = std::min(m_screencastWidth / displaySize.width(), m_screencastHeight / displaySize.height());
+ RetainPtr<CGImageRef> transformedImageRef;
+ if (scale < 1 || m_screencastToolbarHeight) {
+ WebCore::IntSize screencastSize = displaySize;
+ WebCore::IntSize scaledImageSize = imageSize;
+ if (scale < 1) {
+ screencastSize.scale(scale);
+ scaledImageSize.scale(scale);
+ }
+ auto colorSpace = adoptCF(CGColorSpaceCreateDeviceRGB());
+ auto context = adoptCF(CGBitmapContextCreate(nullptr, screencastSize.width(), screencastSize.height(), 8, 4 * screencastSize.width(), colorSpace.get(), (CGBitmapInfo)kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host));
+ CGContextDrawImage(context.get(), CGRectMake(0, 0, scaledImageSize.width(), scaledImageSize.height()), imagePtr);
+ transformedImageRef = adoptCF(CGBitmapContextCreateImage(context.get()));
+ imagePtr = transformedImageRef.get();
+ }
+ auto data = WebCore::data(imagePtr, WebCore::jpegUTI(), m_screencastQuality * 0.1);
+
+ // Do not send the same frame over and over.
+ auto cryptoDigest = PAL::CryptoDigest::create(PAL::CryptoDigest::Algorithm::SHA_1);
+ cryptoDigest->addBytes(data.data(), data.size());
+ auto digest = cryptoDigest->computeHash();
+ if (m_lastFrameDigest != digest) {
+ String base64Data = base64EncodeToString(data);
+ ++m_screencastFramesInFlight;
+ m_frontendDispatcher->screencastFrame(base64Data, displaySize.width(), displaySize.height());
+ m_lastFrameDigest = digest;
+ }
+ }
+ if (m_encoder)
+ m_encoder->encodeFrame(WTFMove(imageRef));
+}
+#endif
+
+#if USE(CAIRO) && !PLATFORM(WPE)
+void InspectorScreencastAgent::encodeFrame()
+{
+ if (!m_encoder && !m_screencast)
+ 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..d28dde452275f18739e3b1c8d709185c9bf0f40e
--- /dev/null
+++ b/Source/WebKit/UIProcess/Inspector/Agents/InspectorScreencastAgent.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2020 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <JavaScriptCore/InspectorAgentBase.h>
+#include <JavaScriptCore/InspectorBackendDispatchers.h>
+#include <JavaScriptCore/InspectorFrontendDispatchers.h>
+
+#if USE(CAIRO)
+#include <cairo.h>
+#endif
+
+#include <wtf/Forward.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/WeakPtr.h>
+
+namespace Inspector {
+class BackendDispatcher;
+class FrontendChannel;
+class FrontendRouter;
+class ScreencastFrontendDispatcher;
+}
+
+namespace WebKit {
+
+class 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 */> startVideo(const String& file, int width, int height, int toolbarHeight) override;
+ void stopVideo(Ref<StopVideoCallback>&&) override;
+
+ Inspector::Protocol::ErrorStringOr<int /* generation */> startScreencast(int width, int height, int toolbarHeight, int quality) override;
+ Inspector::Protocol::ErrorStringOr<void> screencastFrameAck(int generation) override;
+ Inspector::Protocol::ErrorStringOr<void> stopScreencast() override;
+
+private:
+#if !PLATFORM(WPE)
+ void scheduleFrameEncoding();
+ void encodeFrame();
+#endif
+
+ void kickFramesStarted();
+
+ std::unique_ptr<Inspector::ScreencastFrontendDispatcher> m_frontendDispatcher;
+ Ref<Inspector::ScreencastBackendDispatcher> m_backendDispatcher;
+ WebPageProxy& m_page;
+ Vector<uint8_t> m_lastFrameDigest;
+ RefPtr<ScreencastEncoder> m_encoder;
+ bool m_screencast = false;
+ bool m_framesAreGoing = false;
+ double m_screencastWidth = 0;
+ double m_screencastHeight = 0;
+ int m_screencastQuality = 0;
+ int m_screencastToolbarHeight = 0;
+ int m_screencastGeneration = 0;
+ int m_screencastFramesInFlight = 0;
+ String m_currentScreencastID;
+};
+
+} // namespace WebKit
diff --git a/Source/WebKit/UIProcess/Inspector/Agents/ScreencastEncoder.cpp b/Source/WebKit/UIProcess/Inspector/Agents/ScreencastEncoder.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..489fb9a4a98de71526a6c3d6746e8b7192bac9b8
--- /dev/null
+++ b/Source/WebKit/UIProcess/Inspector/Agents/ScreencastEncoder.cpp
@@ -0,0 +1,379 @@
+/*
+ * 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 {
+
+// Number of timebase unints per one frame.
+constexpr int timeScale = 1000;
+
+// Defines the dimension of a macro block. This is used to compute the active
+// map for the encoder.
+const int kMacroBlockSize = 16;
+
+void createImage(unsigned int width, unsigned int height,
+ std::unique_ptr<vpx_image_t>& out_image,
+ std::unique_ptr<uint8_t[]>& out_image_buffer) {
+ std::unique_ptr<vpx_image_t> image(new vpx_image_t());
+ memset(image.get(), 0, sizeof(vpx_image_t));
+
+ // libvpx seems to require both to be assigned.
+ image->d_w = width;
+ image->w = width;
+ image->d_h = height;
+ image->h = height;
+
+ // I420
+ image->fmt = VPX_IMG_FMT_YV12;
+ image->x_chroma_shift = 1;
+ image->y_chroma_shift = 1;
+
+ // libyuv's fast-path requires 16-byte aligned pointers and strides, so pad
+ // the Y, U and V planes' strides to multiples of 16 bytes.
+ const int y_stride = ((image->w - 1) & ~15) + 16;
+ const int uv_unaligned_stride = y_stride >> image->x_chroma_shift;
+ const int uv_stride = ((uv_unaligned_stride - 1) & ~15) + 16;
+
+ // libvpx accesses the source image in macro blocks, and will over-read
+ // if the image is not padded out to the next macroblock: crbug.com/119633.
+ // Pad the Y, U and V planes' height out to compensate.
+ // Assuming macroblocks are 16x16, aligning the planes' strides above also
+ // macroblock aligned them.
+ static_assert(kMacroBlockSize == 16, "macroblock_size_not_16");
+ const int y_rows = ((image->h - 1) & ~(kMacroBlockSize-1)) + kMacroBlockSize;
+ const int uv_rows = y_rows >> image->y_chroma_shift;
+
+ // Allocate a YUV buffer large enough for the aligned data & padding.
+ const int buffer_size = y_stride * y_rows + 2*uv_stride * uv_rows;
+ std::unique_ptr<uint8_t[]> image_buffer(new uint8_t[buffer_size]);
+
+ // Reset image value to 128 so we just need to fill in the y plane.
+ memset(image_buffer.get(), 128, buffer_size);
+
+ // Fill in the information for |image_|.
+ unsigned char* uchar_buffer =
+ reinterpret_cast<unsigned char*>(image_buffer.get());
+ image->planes[0] = uchar_buffer;
+ image->planes[1] = image->planes[0] + y_stride * y_rows;
+ image->planes[2] = image->planes[1] + uv_stride * uv_rows;
+ image->stride[0] = y_stride;
+ image->stride[1] = uv_stride;
+ image->stride[2] = uv_stride;
+
+ out_image = std::move(image);
+ out_image_buffer = std::move(image_buffer);
+}
+
+} // namespace
+
+class ScreencastEncoder::VPXFrame {
+ WTF_MAKE_NONCOPYABLE(VPXFrame);
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+#if USE(CAIRO)
+ explicit VPXFrame(RefPtr<cairo_surface_t>&& surface)
+ : m_surface(WTFMove(surface))
+ { }
+#elif PLATFORM(MAC)
+ VPXFrame(RetainPtr<CGImageRef> windowImage, int offsetTop)
+ : m_windowImage(WTFMove(windowImage))
+ , m_offsetTop(offsetTop)
+ { }
+#endif
+
+ void setDuration(Seconds duration) { m_duration = duration; }
+ Seconds duration() const { return m_duration; }
+
+ void convertToVpxImage(vpx_image_t* image)
+ {
+#if USE(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_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;
+ int m_offsetTop { 0 };
+#endif
+ Seconds m_duration;
+};
+
+
+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());
+ double frameCount = frame->duration().seconds() * fps;
+ // For long duration repeat frame at 1 fps to ensure last frame duration is short enough.
+ // TODO: figure out why simply passing duration doesn't work well.
+ for (;frameCount > 1.5; frameCount -= 1) {
+ encodeFrame(m_image.get(), timeScale);
+ }
+ encodeFrame(m_image.get(), std::max<int>(1, frameCount * timeScale));
+ });
+ }
+
+ void finishAsync(Function<void()>&& callback)
+ {
+ m_encoderQueue->dispatch([this, callback = WTFMove(callback)] {
+ finish();
+ callback();
+ });
+ }
+
+private:
+ bool encodeFrame(vpx_image_t *img, int duration)
+ {
+ vpx_codec_iter_t iter = nullptr;
+ const vpx_codec_cx_pkt_t *pkt = nullptr;
+ int flags = 0;
+ const vpx_codec_err_t res = vpx_codec_encode(&m_codec, 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;
+ }
+ ++m_frameCount;
+ m_pts += pkt->data.frame.duration;
+ }
+ }
+
+ return gotPkts;
+ }
+
+ void finish()
+ {
+ // Flush encoder.
+ while (encodeFrame(nullptr, 1))
+ ++m_frameCount;
+
+ m_writer->finish();
+ fclose(m_file);
+ }
+
+ Ref<WorkQueue> m_encoderQueue;
+ 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)
+ : m_vpxCodec(WTFMove(vpxCodec))
+ , m_size(size)
+{
+ ASSERT(!size.isZero());
+}
+
+ScreencastEncoder::~ScreencastEncoder()
+{
+}
+
+RefPtr<ScreencastEncoder> ScreencastEncoder::create(String& errorString, const String& filePath, IntSize size)
+{
+ vpx_codec_iface_t* codec_interface = vpx_codec_vp8_cx();
+ if (!codec_interface) {
+ errorString = "Codec not found."_s;
+ return nullptr;
+ }
+
+ if (size.width() <= 0 || size.height() <= 0 || (size.width() % 2) != 0 || (size.height() % 2) != 0) {
+ errorString = makeString("Invalid frame size: "_s, size.width(), "x"_s, size.height());
+ return nullptr;
+ }
+
+ vpx_codec_enc_cfg_t cfg;
+ memset(&cfg, 0, sizeof(cfg));
+ vpx_codec_err_t error = vpx_codec_enc_config_default(codec_interface, &cfg, 0);
+ if (error) {
+ errorString = makeString("Failed to get default codec config: "_s, vpx_codec_err_to_string(error));
+ return nullptr;
+ }
+
+ cfg.g_w = size.width();
+ cfg.g_h = size.height();
+ cfg.g_timebase.num = 1;
+ cfg.g_timebase.den = fps * timeScale;
+ cfg.g_error_resilient = VPX_ERROR_RESILIENT_DEFAULT;
+
+ 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));
+ return adoptRef(new ScreencastEncoder(WTFMove(vpxCodec), size));
+}
+
+void ScreencastEncoder::flushLastFrame()
+{
+ MonotonicTime now = MonotonicTime::now();
+ if (m_lastFrameTimestamp) {
+ // If previous frame encoding failed for some rason leave the timestampt intact.
+ if (!m_lastFrame)
+ return;
+
+ Seconds seconds = now - m_lastFrameTimestamp;
+ m_lastFrame->setDuration(seconds);
+ m_vpxCodec->encodeFrameAsync(WTFMove(m_lastFrame));
+ }
+ m_lastFrameTimestamp = now;
+}
+
+#if USE(CAIRO)
+void ScreencastEncoder::encodeFrame(cairo_surface_t* drawingAreaSurface, IntSize size)
+{
+ flushLastFrame();
+ // Note that in WPE drawing area size is updated asynchronously and may differ from acutal
+ // size of the surface.
+ if (size.isZero()) {
+ return;
+ }
+
+ RefPtr<cairo_surface_t> surface = adoptRef(cairo_image_surface_create(CAIRO_FORMAT_ARGB32, m_size.width(), m_size.height()));
+ {
+ RefPtr<cairo_t> cr = adoptRef(cairo_create(surface.get()));
+
+ cairo_matrix_t transform;
+ if (size.width() > m_size.width() || size.height() > m_size.height()) {
+ // If no scale is specified shrink to fit the frame.
+ double scale = std::min(static_cast<double>(m_size.width()) / size.width(),
+ static_cast<double>(m_size.height()) / size.height());
+ cairo_matrix_init_scale(&transform, scale, scale);
+ cairo_transform(cr.get(), &transform);
+ }
+
+ // Record top left part of the drawing area that fits into the frame.
+ cairo_set_source_surface(cr.get(), drawingAreaSurface, 0, 0);
+ cairo_paint(cr.get());
+ }
+ cairo_surface_flush(surface.get());
+
+ m_lastFrame = makeUnique<VPXFrame>(WTFMove(surface));
+}
+#elif PLATFORM(MAC)
+void ScreencastEncoder::encodeFrame(RetainPtr<CGImageRef>&& windowImage)
+{
+ flushLastFrame();
+
+ m_lastFrame = makeUnique<VPXFrame>(WTFMove(windowImage), m_offsetTop);
+}
+#endif
+
+void ScreencastEncoder::finish(Function<void()>&& callback)
+{
+ if (!m_vpxCodec) {
+ callback();
+ return;
+ }
+
+ flushLastFrame();
+ m_vpxCodec->finishAsync([protectRef = Ref { *this }, callback = WTFMove(callback)] () mutable {
+ RunLoop::main().dispatch([callback = WTFMove(callback)] {
+ callback();
+ });
+ });
+}
+
+
+} // namespace WebKit
diff --git a/Source/WebKit/UIProcess/Inspector/Agents/ScreencastEncoder.h b/Source/WebKit/UIProcess/Inspector/Agents/ScreencastEncoder.h
new file mode 100644
index 0000000000000000000000000000000000000000..36df6131950ca95f74dc191628376fc589dbcb33
--- /dev/null
+++ b/Source/WebKit/UIProcess/Inspector/Agents/ScreencastEncoder.h
@@ -0,0 +1,80 @@
+/*
+ * 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 constexpr int fps = 25;
+
+ static RefPtr<ScreencastEncoder> create(String& errorString, const String& filePath, WebCore::IntSize);
+
+ class VPXCodec;
+ ScreencastEncoder(std::unique_ptr<VPXCodec>&&, WebCore::IntSize);
+ ~ScreencastEncoder();
+
+#if USE(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, int offsetTop);
+#endif
+
+ std::unique_ptr<VPXCodec> m_vpxCodec;
+ const WebCore::IntSize m_size;
+ MonotonicTime m_lastFrameTimestamp;
+ class VPXFrame;
+ std::unique_ptr<VPXFrame> m_lastFrame;
+#if PLATFORM(MAC)
+ int m_offsetTop { 0 };
+#endif
+};
+
+} // namespace WebKit
diff --git a/Source/WebKit/UIProcess/Inspector/Agents/WebMFileWriter.cpp b/Source/WebKit/UIProcess/Inspector/Agents/WebMFileWriter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9b269b356e206f0252245a1497adb0d05128c9b4
--- /dev/null
+++ b/Source/WebKit/UIProcess/Inspector/Agents/WebMFileWriter.cpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2014 The WebM project authors. All Rights Reserved.
+ * Copyright (C) 2020 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebMFileWriter.h"
+
+#include <string>
+#include "mkvmuxer/mkvmuxerutil.h"
+
+namespace WebKit {
+
+WebMFileWriter::WebMFileWriter(FILE* file, vpx_codec_enc_cfg_t* cfg)
+ : m_cfg(cfg)
+ , m_writer(new mkvmuxer::MkvWriter(file))
+ , m_segment(new mkvmuxer::Segment()) {
+ m_segment->Init(m_writer.get());
+ m_segment->set_mode(mkvmuxer::Segment::kFile);
+ m_segment->OutputCues(true);
+
+ mkvmuxer::SegmentInfo* info = m_segment->GetSegmentInfo();
+ std::string version = "Playwright " + std::string(vpx_codec_version_str());
+ info->set_writing_app(version.c_str());
+
+ // Add vp8 track.
+ m_videoTrackId = m_segment->AddVideoTrack(
+ static_cast<int>(m_cfg->g_w), static_cast<int>(m_cfg->g_h), 0);
+ if (!m_videoTrackId) {
+ fprintf(stderr, "Failed to add video track\n");
+ }
+}
+
+WebMFileWriter::~WebMFileWriter() {}
+
+bool WebMFileWriter::writeFrame(const vpx_codec_cx_pkt_t* pkt) {
+ int64_t pts_ns = pkt->data.frame.pts * 1000000000ll * m_cfg->g_timebase.num /
+ m_cfg->g_timebase.den;
+ return m_segment->AddFrame(static_cast<uint8_t*>(pkt->data.frame.buf),
+ pkt->data.frame.sz, m_videoTrackId, pts_ns,
+ pkt->data.frame.flags & VPX_FRAME_IS_KEY);
+}
+
+void WebMFileWriter::finish() {
+ m_segment->Finalize();
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit/UIProcess/Inspector/Agents/WebMFileWriter.h b/Source/WebKit/UIProcess/Inspector/Agents/WebMFileWriter.h
new file mode 100644
index 0000000000000000000000000000000000000000..e2ce910f3fd7f587add552275b7e7176cf8b2723
--- /dev/null
+++ b/Source/WebKit/UIProcess/Inspector/Agents/WebMFileWriter.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2020 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <memory>
+#include <stdio.h>
+#include <stdlib.h>
+#include "vpx/vpx_encoder.h"
+
+#include "mkvmuxer/mkvmuxer.h"
+#include "mkvmuxer/mkvwriter.h"
+
+namespace WebKit {
+
+class WebMFileWriter {
+public:
+ WebMFileWriter(FILE*, vpx_codec_enc_cfg_t* cfg);
+ ~WebMFileWriter();
+
+ bool writeFrame(const vpx_codec_cx_pkt_t* pkt);
+ void finish();
+
+private:
+ vpx_codec_enc_cfg_t* m_cfg = nullptr;
+ std::unique_ptr<mkvmuxer::MkvWriter> m_writer;
+ std::unique_ptr<mkvmuxer::Segment> m_segment;
+ uint64_t m_videoTrackId = 0;
+};
+
+} // namespace WebKit
diff --git a/Source/WebKit/UIProcess/Inspector/Cocoa/InspectorExtensionDelegate.h b/Source/WebKit/UIProcess/Inspector/Cocoa/InspectorExtensionDelegate.h
index 0f83f41855bf996b5846e677934a202851941d54..cf4afbd2cccf4607dd8d6e6d7983b03c1c044d42 100644
--- a/Source/WebKit/UIProcess/Inspector/Cocoa/InspectorExtensionDelegate.h
+++ b/Source/WebKit/UIProcess/Inspector/Cocoa/InspectorExtensionDelegate.h
@@ -29,6 +29,7 @@
#import "APIInspectorExtensionClient.h"
#import "WKFoundation.h"
+#import <WebCore/FrameIdentifier.h>
#import <wtf/WeakObjCPtr.h>
@class _WKInspectorExtension;
diff --git a/Source/WebKit/UIProcess/Inspector/InspectorTargetProxy.cpp b/Source/WebKit/UIProcess/Inspector/InspectorTargetProxy.cpp
index cfcacce0122bb03fa47fd8580cfbedfb2ad37d48..5619cbd7e4e842be0d8e2db2c64a7e0028838808 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 = 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(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 ed4e6f30b8c35966075573dccee801daceec865e..81e10124a8a745727fc25316345cda01201a5dba 100644
--- a/Source/WebKit/UIProcess/Inspector/WebPageInspectorController.cpp
+++ b/Source/WebKit/UIProcess/Inspector/WebPageInspectorController.cpp
@@ -26,13 +26,21 @@
#include "config.h"
#include "WebPageInspectorController.h"
+#include "APINavigation.h"
#include "APIUIClient.h"
#include "InspectorBrowserAgent.h"
+#include "InspectorDialogAgent.h"
+#include "InspectorScreencastAgent.h"
#include "ProvisionalPageProxy.h"
#include "WebFrameProxy.h"
#include "WebPageInspectorAgentBase.h"
+#include "WebPageInspectorEmulationAgent.h"
+#include "WebPageInspectorInputAgent.h"
#include "WebPageInspectorTarget.h"
#include "WebPageProxy.h"
+#include "WebPreferences.h"
+#include <WebCore/ResourceError.h>
+#include <WebCore/WindowFeatures.h>
#include <JavaScriptCore/InspectorAgentBase.h>
#include <JavaScriptCore/InspectorBackendDispatcher.h>
#include <JavaScriptCore/InspectorBackendDispatchers.h>
@@ -49,27 +57,114 @@ 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& inspectedPage)
: m_frontendRouter(FrontendRouter::create())
, m_backendDispatcher(BackendDispatcher::create(m_frontendRouter.copyRef()))
, m_inspectedPage(inspectedPage)
{
- auto targetAgent = makeUnique<InspectorTargetAgent>(m_frontendRouter.get(), m_backendDispatcher.get());
- m_targetAgent = targetAgent.get();
- m_agents.append(WTFMove(targetAgent));
}
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_inspectedPage);
+ m_emulationAgent = emulationAgent.get();
+ m_agents.append(WTFMove(emulationAgent));
+ auto inputAgent = makeUnique<WebPageInspectorInputAgent>(m_backendDispatcher.get(), m_inspectedPage);
+ m_inputAgent = inputAgent.get();
+ m_agents.append(WTFMove(inputAgent));
+ m_agents.append(makeUnique<InspectorDialogAgent>(m_backendDispatcher.get(), m_frontendRouter.get(), m_inspectedPage));
+ auto screencastAgent = makeUnique<InspectorScreencastAgent>(m_backendDispatcher.get(), m_frontendRouter.get(), m_inspectedPage);
+ m_screecastAgent = screencastAgent.get();
+ m_agents.append(WTFMove(screencastAgent));
+ if (s_observer)
+ s_observer->didCreateInspectorController(m_inspectedPage);
+
+ // window.open will create page with already running process.
+ if (!m_inspectedPage.hasRunningProcess())
+ return;
String pageTargetId = WebPageInspectorTarget::toTargetID(m_inspectedPage.webPageID());
createInspectorTarget(pageTargetId, Inspector::InspectorTargetType::Page);
}
+void WebPageInspectorController::didFinishAttachingToWebProcess()
+{
+ String pageTargetID = WebPageInspectorTarget::toTargetID(m_inspectedPage.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_inspectedPage.webPageID());
+ destroyInspectorTarget(pageTargetId);
+
disconnectAllFrontends();
m_agents.discardValues();
+
+ if (s_observer)
+ s_observer->willDestroyInspectorController(m_inspectedPage);
+}
+
+bool WebPageInspectorController::pageCrashed(ProcessTerminationReason reason)
+{
+ if (reason != ProcessTerminationReason::Crash)
+ return false;
+ String targetId = WebPageInspectorTarget::toTargetID(m_inspectedPage.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_inspectedPage, features, url);
+}
+
+void WebPageInspectorController::didShowPage()
+{
+ if (m_frontendRouter->hasFrontends())
+ m_emulationAgent->didShowPage();
+}
+
+void WebPageInspectorController::didProcessAllPendingKeyboardEvents()
+{
+ if (m_frontendRouter->hasFrontends())
+ m_inputAgent->didProcessAllPendingKeyboardEvents();
+}
+
+void WebPageInspectorController::didProcessAllPendingMouseEvents()
+{
+ if (m_frontendRouter->hasFrontends())
+ m_inputAgent->didProcessAllPendingMouseEvents();
+}
+
+void WebPageInspectorController::didProcessAllPendingWheelEvents()
+{
+ if (m_frontendRouter->hasFrontends())
+ m_inputAgent->didProcessAllPendingWheelEvents();
}
bool WebPageInspectorController::hasLocalFrontend() const
@@ -83,6 +178,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)
@@ -101,8 +207,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_inspectedPage.didChangeInspectorFrontendCount(m_frontendRouter->frontendCount());
@@ -125,6 +233,8 @@ void WebPageInspectorController::disconnectAllFrontends()
// Disconnect any remaining remote frontends.
m_frontendRouter->disconnectAllFrontends();
+ m_pendingNavigations.clear();
+
m_inspectedPage.didChangeInspectorFrontendCount(m_frontendRouter->frontendCount());
#if ENABLE(REMOTE_INSPECTOR)
@@ -151,6 +261,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_inspectedPage.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_inspectedPage, navigationID, error.localizedDescription());
+}
+
void WebPageInspectorController::createInspectorTarget(const String& targetId, Inspector::InspectorTargetType type)
{
addTarget(InspectorTargetProxy::create(m_inspectedPage, targetId, type));
@@ -170,6 +340,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_inspectedPage.isPageOpenedByDOMShowingInitialEmptyDocument())
+ return false;
+
+ auto* target = m_targets.get(WebPageInspectorTarget::toTargetID(m_inspectedPage.webPageID()));
+ ASSERT(target);
+ return target->isPaused();
+}
+
+void WebPageInspectorController::setContinueLoadingCallback(WTF::Function<void()>&& callback)
+{
+ auto* target = m_targets.get(WebPageInspectorTarget::toTargetID(m_inspectedPage.webPageID()));
+ ASSERT(target);
+ target->setResumeCallback(WTFMove(callback));
+}
+
bool WebPageInspectorController::shouldPauseLoading(const ProvisionalPageProxy& provisionalPage) const
{
if (!m_frontendRouter->hasFrontends())
@@ -189,7 +385,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)
@@ -267,4 +463,27 @@ void WebPageInspectorController::browserExtensionsDisabled(HashSet<String>&& ext
m_enabledBrowserAgent->extensionsDisabled(WTFMove(extensionIDs));
}
+void WebPageInspectorController::adjustPageSettings()
+{
+ // Set this to true as otherwise updating any preferences will override its
+ // value in the Web Process to false (and InspectorController sets it locally
+ // to true when frontend is connected).
+ m_inspectedPage.preferences().setDeveloperExtrasEnabled(true);
+
+ // Navigation to cached pages doesn't fire some of the events (e.g. execution context created)
+ // that inspector depends on. So we disable the cache when front-end connects.
+ m_inspectedPage.preferences().setUsesBackForwardCache(false);
+
+ // Enable popup debugging.
+ // TODO: allow to set preferences over the inspector protocol or find a better place for this.
+ m_inspectedPage.preferences().setJavaScriptCanOpenWindowsAutomatically(true);
+
+ // Enable media stream.
+ if (!m_inspectedPage.preferences().mediaStreamEnabled()) {
+ m_inspectedPage.preferences().setMediaDevicesEnabled(true);
+ m_inspectedPage.preferences().setMediaStreamEnabled(true);
+ m_inspectedPage.preferences().setPeerConnectionEnabled(true);
+ }
+}
+
} // namespace WebKit
diff --git a/Source/WebKit/UIProcess/Inspector/WebPageInspectorController.h b/Source/WebKit/UIProcess/Inspector/WebPageInspectorController.h
index 8c1339345d451874502b271f6aa2eca3fa0d3faf..1f8f5e74c86b61c1c5a16ac33d48afdd0e59a2e9 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,21 @@ 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();
+ void didProcessAllPendingWheelEvents();
bool hasLocalFrontend() const;
@@ -64,11 +113,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()>&&);
@@ -87,6 +150,7 @@ private:
void createLazyAgents();
void addTarget(std::unique_ptr<InspectorTargetProxy>&&);
+ void adjustPageSettings();
Ref<Inspector::FrontendRouter> m_frontendRouter;
Ref<Inspector::BackendDispatcher> m_backendDispatcher;
@@ -95,11 +159,17 @@ private:
WebPageProxy& m_inspectedPage;
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..6a04ee480bc3a8270a7de20b1cd0da718242b4c1
--- /dev/null
+++ b/Source/WebKit/UIProcess/Inspector/mac/ScreencastEncoderMac.mm
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2020 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ScreencastEncoder.h"
+
+#include <algorithm>
+#include <CoreGraphics/CoreGraphics.h>
+#include <wtf/RetainPtr.h>
+
+namespace WebKit {
+
+void ScreencastEncoder::imageToARGB(CGImageRef image, uint8_t* argb_data, int width, int height, int offsetTop)
+{
+ size_t bitsPerComponent = 8;
+ size_t bytesPerPixel = 4;
+ size_t bytesPerRow = bytesPerPixel * width;
+ RetainPtr<CGColorSpaceRef> colorSpace = adoptCF(CGColorSpaceCreateDeviceRGB());
+ RetainPtr<CGContextRef> context = adoptCF(CGBitmapContextCreate(argb_data, width, height, bitsPerComponent, bytesPerRow, colorSpace.get(), (CGBitmapInfo)kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Little));
+ double imageWidth = CGImageGetWidth(image);
+ double imageHeight = CGImageGetHeight(image);
+ double pageHeight = imageHeight - offsetTop;
+ double ratio = 1;
+ if (imageWidth > width || pageHeight > height) {
+ ratio = std::min(width / imageWidth, height / pageHeight);
+ }
+ imageWidth *= ratio;
+ imageHeight *= ratio;
+ pageHeight *= ratio;
+ CGContextDrawImage(context.get(), CGRectMake(0, height - pageHeight, imageWidth, imageHeight), image);
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit/UIProcess/InspectorDialogAgent.cpp b/Source/WebKit/UIProcess/InspectorDialogAgent.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..663f92f0df76042cf6385b056f8a917d688259f9
--- /dev/null
+++ b/Source/WebKit/UIProcess/InspectorDialogAgent.cpp
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2019 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "InspectorDialogAgent.h"
+
+#include "APINavigation.h"
+#include "APIUIClient.h"
+#include "WebPageProxy.h"
+#include <JavaScriptCore/InspectorFrontendRouter.h>
+
+
+namespace WebKit {
+
+using namespace Inspector;
+
+InspectorDialogAgent::InspectorDialogAgent(Inspector::BackendDispatcher& backendDispatcher, Inspector::FrontendRouter& frontendRouter, WebPageProxy& page)
+ : InspectorAgentBase("Dialog"_s)
+ , m_frontendDispatcher(makeUnique<DialogFrontendDispatcher>(frontendRouter))
+ , m_backendDispatcher(DialogBackendDispatcher::create(backendDispatcher, this))
+ , m_page(page)
+{
+}
+
+InspectorDialogAgent::~InspectorDialogAgent()
+{
+ disable();
+}
+
+void InspectorDialogAgent::didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*)
+{
+}
+
+void InspectorDialogAgent::willDestroyFrontendAndBackend(Inspector::DisconnectReason)
+{
+}
+
+Inspector::Protocol::ErrorStringOr<void> InspectorDialogAgent::enable()
+{
+ if (m_page.inspectorDialogAgent())
+ return makeUnexpected("Dialog domain is already enabled."_s);
+
+ m_page.setInspectorDialogAgent(this);
+ return { };
+}
+
+Inspector::Protocol::ErrorStringOr<void> InspectorDialogAgent::disable()
+{
+ if (m_page.inspectorDialogAgent() != this)
+ return { };
+
+ m_page.setInspectorDialogAgent(nullptr);
+ return { };
+}
+
+Inspector::Protocol::ErrorStringOr<void> InspectorDialogAgent::handleJavaScriptDialog(bool accept, const String& value)
+{
+ m_page.uiClient().handleJavaScriptDialog(m_page, accept, value);
+ return { };
+}
+
+void InspectorDialogAgent::javascriptDialogOpening(const String& type, const String& message, const String& defaultValue) {
+ m_frontendDispatcher->javascriptDialogOpening(type, message, defaultValue);
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit/UIProcess/InspectorDialogAgent.h b/Source/WebKit/UIProcess/InspectorDialogAgent.h
new file mode 100644
index 0000000000000000000000000000000000000000..d0e11ed81a6257c011df23d5870da7403f8e9fe4
--- /dev/null
+++ b/Source/WebKit/UIProcess/InspectorDialogAgent.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2019 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "WebEvent.h"
+
+#include <JavaScriptCore/InspectorAgentBase.h>
+#include <JavaScriptCore/InspectorBackendDispatchers.h>
+#include <JavaScriptCore/InspectorFrontendDispatchers.h>
+
+#include <wtf/Forward.h>
+#include <wtf/Noncopyable.h>
+
+namespace Inspector {
+class FrontendChannel;
+class FrontendRouter;
+}
+
+namespace WebKit {
+
+class NativeWebKeyboardEvent;
+class WebPageProxy;
+
+class InspectorDialogAgent : public Inspector::InspectorAgentBase, public Inspector::DialogBackendDispatcherHandler {
+ WTF_MAKE_NONCOPYABLE(InspectorDialogAgent);
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ InspectorDialogAgent(Inspector::BackendDispatcher& backendDispatcher, Inspector::FrontendRouter& frontendRouter, WebPageProxy& page);
+ ~InspectorDialogAgent() override;
+
+ void didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*) override;
+ void willDestroyFrontendAndBackend(Inspector::DisconnectReason) override;
+
+ Inspector::Protocol::ErrorStringOr<void> enable() override;
+ Inspector::Protocol::ErrorStringOr<void> disable() override;
+ Inspector::Protocol::ErrorStringOr<void> handleJavaScriptDialog(bool accept, const String& promptText) override;
+
+ void javascriptDialogOpening(const String& type, const String& message, const String& defaultValue = String());
+
+private:
+ void platformHandleJavaScriptDialog(bool accept, const String* promptText);
+ std::unique_ptr<Inspector::DialogFrontendDispatcher> m_frontendDispatcher;
+ Ref<Inspector::DialogBackendDispatcher> m_backendDispatcher;
+ WebPageProxy& m_page;
+};
+
+} // namespace WebKit
diff --git a/Source/WebKit/UIProcess/InspectorPlaywrightAgent.cpp b/Source/WebKit/UIProcess/InspectorPlaywrightAgent.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d9f566a6cce6433c2cfbb25fd6793f65a4ec1f23
--- /dev/null
+++ b/Source/WebKit/UIProcess/InspectorPlaywrightAgent.cpp
@@ -0,0 +1,956 @@
+/*
+ * Copyright (C) 2019 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "InspectorPlaywrightAgent.h"
+
+#if ENABLE(REMOTE_INSPECTOR)
+
+#include "APIGeolocationProvider.h"
+#include "APIHTTPCookieStore.h"
+#include "APIPageConfiguration.h"
+#include "FrameInfoData.h"
+#include "InspectorPlaywrightAgentClient.h"
+#include "InspectorTargetProxy.h"
+#include "NetworkProcessMessages.h"
+#include "NetworkProcessProxy.h"
+#include "PageClient.h"
+#include "SandboxExtension.h"
+#include "StorageNamespaceIdentifier.h"
+#include "WebAutomationSession.h"
+#include "WebGeolocationManagerProxy.h"
+#include "WebGeolocationPosition.h"
+#include "WebInspectorUtilities.h"
+#include "WebPageGroup.h"
+#include "WebPageInspectorController.h"
+#include "WebPageInspectorTarget.h"
+#include "WebPageMessages.h"
+#include "WebPageProxy.h"
+#include "WebProcessPool.h"
+#include "WebProcessProxy.h"
+#include "WebsiteDataRecord.h"
+#include <WebCore/FrameIdentifier.h>
+#include <WebCore/GeolocationPositionData.h>
+#include <WebCore/InspectorPageAgent.h>
+#include <WebCore/ProcessIdentifier.h>
+#include <WebCore/ResourceRequest.h>
+#include <WebCore/SecurityOriginData.h>
+#include <WebCore/WindowFeatures.h>
+#include <JavaScriptCore/InspectorBackendDispatcher.h>
+#include <JavaScriptCore/InspectorFrontendChannel.h>
+#include <JavaScriptCore/InspectorFrontendRouter.h>
+#include <pal/SessionID.h>
+#include <stdlib.h>
+#include <wtf/HashMap.h>
+#include <wtf/HashSet.h>
+#include <wtf/HexNumber.h>
+#include <wtf/URL.h>
+
+
+using namespace Inspector;
+
+namespace WebKit {
+
+class InspectorPlaywrightAgent::PageProxyChannel : public FrontendChannel {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ PageProxyChannel(FrontendChannel& frontendChannel, String browserContextID, String pageProxyID, WebPageProxy& page)
+ : m_browserContextID(browserContextID)
+ , m_pageProxyID(pageProxyID)
+ , m_frontendChannel(frontendChannel)
+ , m_page(page)
+ {
+ }
+
+ ~PageProxyChannel() override = default;
+
+ void dispatchMessageFromFrontend(const String& message)
+ {
+ m_page.inspectorController().dispatchMessageFromFrontend(message);
+ }
+
+ WebPageProxy& page() { return m_page; }
+
+ void disconnect()
+ {
+ m_page.inspectorController().disconnectFrontend(*this);
+ }
+
+private:
+ ConnectionType connectionType() const override { return m_frontendChannel.connectionType(); }
+ void sendMessageToFrontend(const String& message) override
+ {
+ m_frontendChannel.sendMessageToFrontend(addTabIdToMessage(message));
+ }
+
+ String addTabIdToMessage(const String& message) {
+ RefPtr<JSON::Value> parsedMessage = JSON::Value::parseJSON(message);
+ if (!parsedMessage)
+ return message;
+
+ RefPtr<JSON::Object> messageObject = parsedMessage->asObject();
+ if (!messageObject)
+ return message;
+
+ messageObject->setString("browserContextId"_s, m_browserContextID);
+ messageObject->setString("pageProxyId"_s, m_pageProxyID);
+ return messageObject->toJSONString();
+ }
+
+ String m_browserContextID;
+ String m_pageProxyID;
+ FrontendChannel& m_frontendChannel;
+ WebPageProxy& m_page;
+};
+
+class OverridenGeolocationProvider final : public API::GeolocationProvider, public CanMakeWeakPtr<OverridenGeolocationProvider> {
+ WTF_MAKE_NONCOPYABLE(OverridenGeolocationProvider);
+public:
+ OverridenGeolocationProvider()
+ : m_position(WebGeolocationPosition::create(WebCore::GeolocationPositionData()))
+ {
+ }
+
+ void setPosition(const Ref<WebGeolocationPosition>& position) {
+ m_position = position;
+ }
+
+private:
+ void startUpdating(WebGeolocationManagerProxy& proxy) override
+ {
+ proxy.providerDidChangePosition(&m_position.get());
+ }
+
+ void stopUpdating(WebGeolocationManagerProxy&) override
+ {
+ }
+
+ void setEnableHighAccuracy(WebGeolocationManagerProxy&, bool enabled) override
+ {
+ }
+
+ Ref<WebGeolocationPosition> m_position;
+};
+
+namespace {
+
+void setGeolocationProvider(BrowserContext* browserContext) {
+ auto provider = makeUnique<OverridenGeolocationProvider>();
+ browserContext->geolocationProvider = *provider;
+ auto* geoManager = browserContext->processPool->supplement<WebGeolocationManagerProxy>();
+ geoManager->setProvider(WTFMove(provider));
+}
+
+String toBrowserContextIDProtocolString(const PAL::SessionID& sessionID)
+{
+ StringBuilder builder;
+ builder.append(hex(sessionID.toUInt64(), 16));
+ return builder.toString();
+}
+
+String toPageProxyIDProtocolString(const WebPageProxy& page)
+{
+ return makeString(page.identifier().toUInt64());
+}
+
+
+static Ref<JSON::ArrayOf<String>> getEnabledWindowFeatures(const WebCore::WindowFeatures& features) {
+ auto result = JSON::ArrayOf<String>::create();
+ if (features.x)
+ result->addItem("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"_s);
+ if (features.toolBarVisible)
+ result->addItem("toolbar"_s);
+ if (features.statusBarVisible)
+ result->addItem("status"_s);
+ if (features.locationBarVisible)
+ result->addItem("location"_s);
+ if (features.scrollbarsVisible)
+ result->addItem("scrollbars"_s);
+ if (features.resizable)
+ result->addItem("resizable"_s);
+ if (features.fullscreen)
+ result->addItem("fullscreen"_s);
+ if (features.dialog)
+ result->addItem("dialog"_s);
+ if (features.noopener)
+ result->addItem("noopener"_s);
+ if (features.noreferrer)
+ result->addItem("noreferrer"_s);
+ for (const auto& additionalFeature : features.additionalFeatures)
+ result->addItem(additionalFeature);
+ return result;
+}
+
+Inspector::Protocol::Playwright::CookieSameSitePolicy cookieSameSitePolicy(WebCore::Cookie::SameSitePolicy policy)
+{
+ switch (policy) {
+ case WebCore::Cookie::SameSitePolicy::None:
+ return Inspector::Protocol::Playwright::CookieSameSitePolicy::None;
+ case WebCore::Cookie::SameSitePolicy::Lax:
+ return Inspector::Protocol::Playwright::CookieSameSitePolicy::Lax;
+ case WebCore::Cookie::SameSitePolicy::Strict:
+ return Inspector::Protocol::Playwright::CookieSameSitePolicy::Strict;
+ }
+ ASSERT_NOT_REACHED();
+ return Inspector::Protocol::Playwright::CookieSameSitePolicy::None;
+}
+
+Ref<Inspector::Protocol::Playwright::Cookie> buildObjectForCookie(const WebCore::Cookie& cookie)
+{
+ return Inspector::Protocol::Playwright::Cookie::create()
+ .setName(cookie.name)
+ .setValue(cookie.value)
+ .setDomain(cookie.domain)
+ .setPath(cookie.path)
+ .setExpires(cookie.expires.value_or(-1))
+ .setHttpOnly(cookie.httpOnly)
+ .setSecure(cookie.secure)
+ .setSession(cookie.session)
+ .setSameSite(cookieSameSitePolicy(cookie.sameSite))
+ .release();
+}
+
+} // namespace
+
+BrowserContext::BrowserContext() = default;
+
+BrowserContext::~BrowserContext() = default;
+
+class InspectorPlaywrightAgent::BrowserContextDeletion {
+ WTF_MAKE_NONCOPYABLE(BrowserContextDeletion);
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ BrowserContextDeletion(std::unique_ptr<BrowserContext>&& context, size_t numberOfPages, Ref<DeleteContextCallback>&& callback)
+ : m_browserContext(WTFMove(context))
+ , m_numberOfPages(numberOfPages)
+ , m_callback(WTFMove(callback)) { }
+
+ void didDestroyPage(const WebPageProxy& page)
+ {
+ ASSERT(m_browserContext->dataStore->sessionID() == page.sessionID());
+ // Check if new pages have been created during the context destruction and
+ // close all of them if necessary.
+ if (m_numberOfPages == 1) {
+ auto pages = m_browserContext->pages;
+ size_t numberOfPages = pages.size();
+ if (numberOfPages > 1) {
+ m_numberOfPages = numberOfPages;
+ for (auto* existingPage : pages) {
+ if (existingPage != &page)
+ existingPage->closePage();
+ }
+ }
+ }
+ --m_numberOfPages;
+ if (m_numberOfPages)
+ return;
+ m_callback->sendSuccess();
+ }
+
+ bool isFinished() const { return !m_numberOfPages; }
+
+ BrowserContext* context() const { return m_browserContext.get(); }
+
+private:
+ std::unique_ptr<BrowserContext> m_browserContext;
+ size_t m_numberOfPages;
+ Ref<DeleteContextCallback> m_callback;
+};
+
+
+InspectorPlaywrightAgent::InspectorPlaywrightAgent(std::unique_ptr<InspectorPlaywrightAgentClient> client)
+ : m_frontendChannel(nullptr)
+ , m_frontendRouter(FrontendRouter::create())
+ , m_backendDispatcher(BackendDispatcher::create(m_frontendRouter.copyRef()))
+ , m_client(std::move(client))
+ , m_frontendDispatcher(makeUnique<PlaywrightFrontendDispatcher>(m_frontendRouter))
+ , m_playwrightDispatcher(PlaywrightBackendDispatcher::create(m_backendDispatcher.get(), this))
+{
+}
+
+InspectorPlaywrightAgent::~InspectorPlaywrightAgent()
+{
+ if (m_frontendChannel)
+ disconnectFrontend();
+}
+
+void InspectorPlaywrightAgent::connectFrontend(FrontendChannel& frontendChannel)
+{
+ ASSERT(!m_frontendChannel);
+ m_frontendChannel = &frontendChannel;
+ WebPageInspectorController::setObserver(this);
+
+ m_frontendRouter->connectFrontend(frontendChannel);
+}
+
+void InspectorPlaywrightAgent::disconnectFrontend()
+{
+ if (!m_frontendChannel)
+ return;
+
+ disable();
+
+ m_frontendRouter->disconnectFrontend(*m_frontendChannel);
+ ASSERT(!m_frontendRouter->hasFrontends());
+
+ WebPageInspectorController::setObserver(nullptr);
+ m_frontendChannel = nullptr;
+
+ closeImpl([](String error){});
+}
+
+void InspectorPlaywrightAgent::dispatchMessageFromFrontend(const String& message)
+{
+ m_backendDispatcher->dispatch(message, [&](const RefPtr<JSON::Object>& messageObject) {
+ RefPtr<JSON::Value> idValue;
+ if (!messageObject->getValue("id"_s, idValue))
+ return BackendDispatcher::InterceptionResult::Continue;
+ RefPtr<JSON::Value> pageProxyIDValue;
+ if (!messageObject->getValue("pageProxyId"_s, pageProxyIDValue))
+ return BackendDispatcher::InterceptionResult::Continue;
+
+ String pageProxyID;
+ if (!pageProxyIDValue->asString(pageProxyID)) {
+ m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidRequest, "The type of 'pageProxyId' must be string"_s);
+ m_backendDispatcher->sendPendingErrors();
+ return BackendDispatcher::InterceptionResult::Intercepted;
+ }
+
+ if (auto pageProxyChannel = m_pageProxyChannels.get(pageProxyID)) {
+ pageProxyChannel->dispatchMessageFromFrontend(message);
+ return BackendDispatcher::InterceptionResult::Intercepted;
+ }
+
+ std::optional<int> requestId = idValue->asInteger();
+ if (!requestId) {
+ m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidRequest, "The type of 'id' must be number"_s);
+ m_backendDispatcher->sendPendingErrors();
+ return BackendDispatcher::InterceptionResult::Intercepted;
+ }
+
+ m_backendDispatcher->reportProtocolError(*requestId, BackendDispatcher::InvalidParams, "Cannot find page proxy with provided 'pageProxyId'"_s);
+ m_backendDispatcher->sendPendingErrors();
+ return BackendDispatcher::InterceptionResult::Intercepted;
+ });
+}
+
+void InspectorPlaywrightAgent::didCreateInspectorController(WebPageProxy& page)
+{
+ if (!m_isEnabled)
+ return;
+
+ if (isInspectorProcessPool(page.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().ptr();
+ context->dataStore = defaultDataStore;
+ setGeolocationProvider(context.get());
+ // Add default context to the map so that we can easily find it for
+ // created/deleted pages.
+ PAL::SessionID sessionID = context->dataStore->sessionID();
+ m_browserContexts.set(toBrowserContextIDProtocolString(sessionID), WTFMove(context));
+ }
+
+ WebsiteDataStore::forEachWebsiteDataStore([this] (WebsiteDataStore& dataStore) {
+ dataStore.setDownloadInstrumentation(this);
+ });
+ for (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(std::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)
+{
+ closeImpl([callback = WTFMove(callback)] (String error) {
+ if (!callback->isActive())
+ return;
+ if (error.isNull())
+ callback->sendSuccess();
+ else
+ callback->sendFailure(error);
+ });
+}
+
+void InspectorPlaywrightAgent::closeImpl(Function<void(String)>&& callback)
+{
+ Vector<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 (!m_defaultContext) {
+ m_client->closeBrowser();
+ callback(String());
+ return;
+ }
+
+ m_defaultContext->dataStore->syncLocalStorage([this, callback = WTFMove(callback)] () {
+ if (m_client == nullptr) {
+ callback("no platform delegate to close browser"_s);
+ } else {
+ m_client->closeBrowser();
+ callback(String());
+ }
+ });
+
+}
+
+Inspector::Protocol::ErrorStringOr<String /* browserContextID */> InspectorPlaywrightAgent::createContext(const String& proxyServer, const String& proxyBypassList)
+{
+ String errorString;
+ std::unique_ptr<BrowserContext> browserContext = m_client->createBrowserContext(errorString, proxyServer, proxyBypassList);
+ if (!browserContext)
+ return makeUnexpected(errorString);
+
+ // Ensure network process.
+ browserContext->dataStore->networkProcess();
+ browserContext->dataStore->setDownloadInstrumentation(this);
+ setGeolocationProvider(browserContext.get());
+ PAL::SessionID sessionID = browserContext->dataStore->sessionID();
+ String browserContextID = toBrowserContextIDProtocolString(sessionID);
+ m_browserContexts.set(browserContextID, WTFMove(browserContext));
+ return browserContextID;
+}
+
+void InspectorPlaywrightAgent::deleteContext(const String& browserContextID, Ref<DeleteContextCallback>&& callback)
+{
+ String errorString;
+ BrowserContext* browserContext = lookupBrowserContext(errorString, browserContextID);
+ if (!lookupBrowserContext(errorString, browserContextID)) {
+ callback->sendFailure(errorString);
+ return;
+ }
+
+ if (browserContext == m_defaultContext) {
+ callback->sendFailure("Cannot delete default context"_s);
+ return;
+ }
+
+ auto pages = browserContext->pages;
+ PAL::SessionID sessionID = browserContext->dataStore->sessionID();
+ auto contextHolder = m_browserContexts.take(browserContextID);
+ if (pages.isEmpty()) {
+ callback->sendSuccess();
+ } else {
+ m_browserContextDeletions.set(browserContextID, makeUnique<BrowserContextDeletion>(WTFMove(contextHolder), pages.size(), WTFMove(callback)));
+ for (auto* page : pages)
+ page->closePage();
+ }
+ m_client->deleteBrowserContext(errorString, sessionID);
+}
+
+Inspector::Protocol::ErrorStringOr<String /* pageProxyID */> InspectorPlaywrightAgent::createPage(const String& browserContextID)
+{
+ String errorString;
+ BrowserContext* browserContext = lookupBrowserContext(errorString, browserContextID);
+ if (!browserContext)
+ return makeUnexpected(errorString);
+
+ RefPtr<WebPageProxy> page = m_client->createPage(errorString, *browserContext);
+ if (!page)
+ return makeUnexpected(errorString);
+
+ return toPageProxyIDProtocolString(*page);
+}
+
+WebFrameProxy* InspectorPlaywrightAgent::frameForID(const String& frameID, String& error)
+{
+ size_t dotPos = frameID.find("."_s);
+ 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::grantFileReadAccess(const String& pageProxyID, Ref<JSON::Array>&& paths)
+{
+#if ENABLE(SANDBOX_EXTENSIONS)
+ auto* pageProxyChannel = m_pageProxyChannels.get(pageProxyID);
+ if (!pageProxyChannel)
+ return makeUnexpected("Unknown pageProxyID"_s);
+
+ Vector<String> files;
+ for (const auto& value : paths.get()) {
+ String path;
+ if (!value->asString(path))
+ return makeUnexpected("Filr path must be a string"_s);
+
+ files.append(path);
+ }
+
+ auto sandboxExtensionHandles = SandboxExtension::createReadOnlyHandlesForFiles("InspectorPlaywrightAgent::grantFileReadAccess"_s, files);
+ pageProxyChannel->page().send(Messages::WebPage::ExtendSandboxForFilesFromOpenPanel(WTFMove(sandboxExtensionHandles)));
+#endif
+ return { };
+}
+
+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;
+ }
+
+ browserContext->dataStore->cookieStore().cookies(
+ [callback = WTFMove(callback)](const Vector<WebCore::Cookie>& allCookies) {
+ if (!callback->isActive())
+ return;
+ auto cookies = JSON::ArrayOf<Inspector::Protocol::Playwright::Cookie>::create();
+ for (const auto& cookie : allCookies)
+ cookies->addItem(buildObjectForCookie(cookie));
+ callback->sendSuccess(WTFMove(cookies));
+ });
+}
+
+void InspectorPlaywrightAgent::setCookies(const String& browserContextID, Ref<JSON::Array>&& in_cookies, Ref<SetCookiesCallback>&& callback) {
+ String errorString;
+ BrowserContext* browserContext = lookupBrowserContext(errorString, browserContextID);
+ if (!errorString.isEmpty()) {
+ callback->sendFailure(errorString);
+ return;
+ }
+
+ Vector<WebCore::Cookie> cookies;
+ for (unsigned i = 0; i < in_cookies->length(); ++i) {
+ RefPtr<JSON::Value> item = in_cookies->get(i);
+ RefPtr<JSON::Object> obj = item->asObject();
+ if (!obj) {
+ callback->sendFailure("Invalid cookie payload format"_s);
+ return;
+ }
+
+ WebCore::Cookie cookie;
+ cookie.name = obj->getString("name"_s);
+ cookie.value = obj->getString("value"_s);
+ cookie.domain = obj->getString("domain"_s);
+ cookie.path = obj->getString("path"_s);
+ if (!cookie.name || !cookie.value || !cookie.domain || !cookie.path) {
+ callback->sendFailure("Invalid file payload format"_s);
+ return;
+ }
+
+ std::optional<double> expires = obj->getDouble("expires"_s);
+ if (expires && *expires != -1)
+ cookie.expires = *expires;
+ if (std::optional<bool> value = obj->getBoolean("httpOnly"_s))
+ cookie.httpOnly = *value;
+ if (std::optional<bool> value = obj->getBoolean("secure"_s))
+ cookie.secure = *value;
+ if (std::optional<bool> value = obj->getBoolean("session"_s))
+ cookie.session = *value;
+ String sameSite;
+ if (obj->getString("sameSite"_s, sameSite)) {
+ if (sameSite == "None"_s)
+ cookie.sameSite = WebCore::Cookie::SameSitePolicy::None;
+ if (sameSite == "Lax"_s)
+ cookie.sameSite = WebCore::Cookie::SameSitePolicy::Lax;
+ if (sameSite == "Strict"_s)
+ cookie.sameSite = WebCore::Cookie::SameSitePolicy::Strict;
+ }
+ cookies.append(WTFMove(cookie));
+ }
+
+ browserContext->dataStore->cookieStore().setCookies(WTFMove(cookies),
+ [callback = WTFMove(callback)]() {
+ if (!callback->isActive())
+ return;
+ callback->sendSuccess();
+ });
+}
+
+void InspectorPlaywrightAgent::deleteAllCookies(const String& browserContextID, Ref<DeleteAllCookiesCallback>&& callback) {
+ String errorString;
+ BrowserContext* browserContext = lookupBrowserContext(errorString, browserContextID);
+ if (!errorString.isEmpty()) {
+ callback->sendFailure(errorString);
+ return;
+ }
+
+ browserContext->dataStore->cookieStore().deleteAllCookies(
+ [callback = WTFMove(callback)]() {
+ if (!callback->isActive())
+ return;
+ callback->sendSuccess();
+ });
+}
+
+Inspector::Protocol::ErrorStringOr<void> InspectorPlaywrightAgent::setLanguages(Ref<JSON::Array>&& languages, const String& browserContextID)
+{
+ String errorString;
+ BrowserContext* browserContext = lookupBrowserContext(errorString, browserContextID);
+ if (!errorString.isEmpty())
+ return makeUnexpected(errorString);
+
+ Vector<String> items;
+ for (const auto& value : languages.get()) {
+ String language;
+ if (!value->asString(language))
+ return makeUnexpected("Language must be a string"_s);
+
+ items.append(language);
+ }
+
+ browserContext->processPool->configuration().setOverrideLanguages(WTFMove(items));
+ return { };
+}
+
+Inspector::Protocol::ErrorStringOr<void> InspectorPlaywrightAgent::setDownloadBehavior(const String& behavior, const String& downloadPath, const String& browserContextID)
+{
+ String errorString;
+ BrowserContext* browserContext = lookupBrowserContext(errorString, browserContextID);
+ if (!errorString.isEmpty())
+ return makeUnexpected(errorString);
+
+ std::optional<bool> allow;
+ if (behavior == "allow"_s)
+ allow = true;
+ if (behavior == "deny"_s)
+ allow = false;
+ browserContext->dataStore->setDownloadForAutomation(allow, downloadPath);
+ return { };
+}
+
+Inspector::Protocol::ErrorStringOr<void> InspectorPlaywrightAgent::setGeolocationOverride(const String& browserContextID, RefPtr<JSON::Object>&& geolocation)
+{
+ String errorString;
+ BrowserContext* browserContext = lookupBrowserContext(errorString, browserContextID);
+ if (!errorString.isEmpty())
+ return makeUnexpected(errorString);
+
+ auto* geoManager = browserContext->processPool->supplement<WebGeolocationManagerProxy>();
+ if (!geoManager)
+ return makeUnexpected("Internal error: geolocation manager is not available."_s);
+
+ if (geolocation) {
+ std::optional<double> timestamp = geolocation->getDouble("timestamp"_s);
+ std::optional<double> latitude = geolocation->getDouble("latitude"_s);
+ std::optional<double> longitude = geolocation->getDouble("longitude"_s);
+ std::optional<double> accuracy = geolocation->getDouble("accuracy"_s);
+ if (!timestamp || !latitude || !longitude || !accuracy)
+ return makeUnexpected("Invalid geolocation format"_s);
+
+ auto position = WebGeolocationPosition::create(WebCore::GeolocationPositionData(*timestamp, *latitude, *longitude, *accuracy));
+ if (!browserContext->geolocationProvider)
+ return makeUnexpected("Internal error: geolocation provider has been destroyed."_s);
+ browserContext->geolocationProvider->setPosition(position);
+ geoManager->providerDidChangePosition(&position.get());
+ } else {
+ geoManager->providerDidFailToDeterminePosition("Position unavailable"_s);
+ }
+ return { };
+}
+
+void InspectorPlaywrightAgent::downloadCreated(const String& uuid, const WebCore::ResourceRequest& request, const FrameInfoData& frameInfoData, WebPageProxy* page, RefPtr<DownloadProxy> download)
+{
+ if (!m_isEnabled)
+ return;
+ String frameID = WebCore::InspectorPageAgent::makeFrameID(page->process().coreProcessIdentifier(), frameInfoData.frameID ? *frameInfoData.frameID : page->mainFrame()->frameID());
+ m_downloads.set(uuid, download);
+ m_frontendDispatcher->downloadCreated(
+ toPageProxyIDProtocolString(*page),
+ frameID,
+ uuid, request.url().string());
+}
+
+void InspectorPlaywrightAgent::downloadFilenameSuggested(const String& uuid, const String& suggestedFilename)
+{
+ if (!m_isEnabled)
+ return;
+ m_frontendDispatcher->downloadFilenameSuggested(uuid, suggestedFilename);
+}
+
+void InspectorPlaywrightAgent::downloadFinished(const String& uuid, const String& error)
+{
+ if (!m_isEnabled)
+ return;
+ m_frontendDispatcher->downloadFinished(uuid, error);
+ m_downloads.remove(uuid);
+}
+
+Inspector::Protocol::ErrorStringOr<void> InspectorPlaywrightAgent::cancelDownload(const String& uuid)
+{
+ if (!m_isEnabled)
+ return { };
+ auto download = m_downloads.get(uuid);
+ if (!download)
+ return { };
+ download->cancel([] (auto*) {});
+ return { };
+}
+
+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..8522b4942343d9a6f2473ea9a133d1ff5267e8ed
--- /dev/null
+++ b/Source/WebKit/UIProcess/InspectorPlaywrightAgent.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2019 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(REMOTE_INSPECTOR)
+
+#include "InspectorPlaywrightAgentClient.h"
+#include <JavaScriptCore/InspectorBackendDispatchers.h>
+#include "WebPageInspectorController.h"
+#include "WebProcessPool.h"
+#include "DownloadProxy.h"
+#include <wtf/HashMap.h>
+#include <wtf/Forward.h>
+#include <wtf/Noncopyable.h>
+
+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> grantFileReadAccess(const String& pageProxyID, Ref<JSON::Array>&& paths) 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;
+ Inspector::Protocol::ErrorStringOr<void> cancelDownload(const String& uuid) override;
+
+ // DownloadInstrumentation
+ void downloadCreated(const String& uuid, const WebCore::ResourceRequest&, const FrameInfoData& frameInfoData, WebPageProxy* page, RefPtr<DownloadProxy> download) override;
+ void downloadFilenameSuggested(const String& uuid, const String& suggestedFilename) override;
+ void downloadFinished(const String& uuid, const String& error) override;
+
+ BrowserContext* getExistingBrowserContext(const String& browserContextID);
+ BrowserContext* lookupBrowserContext(Inspector::ErrorString&, const String& browserContextID);
+ WebFrameProxy* frameForID(const String& frameID, String& error);
+ void closeImpl(Function<void(String)>&&);
+
+ Inspector::FrontendChannel* m_frontendChannel { nullptr };
+ Ref<Inspector::FrontendRouter> m_frontendRouter;
+ Ref<Inspector::BackendDispatcher> m_backendDispatcher;
+ std::unique_ptr<InspectorPlaywrightAgentClient> m_client;
+ std::unique_ptr<Inspector::PlaywrightFrontendDispatcher> m_frontendDispatcher;
+ Ref<Inspector::PlaywrightBackendDispatcher> m_playwrightDispatcher;
+ HashMap<String, std::unique_ptr<PageProxyChannel>> m_pageProxyChannels;
+ BrowserContext* m_defaultContext;
+ HashMap<String, RefPtr<DownloadProxy>> m_downloads;
+ 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..c9f2d7ec888e819a49cb898803432013f6270c2a
--- /dev/null
+++ b/Source/WebKit/UIProcess/InspectorPlaywrightAgentClient.h
@@ -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.
+ */
+
+#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>
+#include <wtf/WeakPtr.h>
+
+namespace WebKit {
+
+class OverridenGeolocationProvider;
+class WebsiteDataStore;
+class WebPageProxy;
+class WebProcessPool;
+
+class BrowserContext {
+ WTF_MAKE_NONCOPYABLE(BrowserContext);
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ BrowserContext();
+ ~BrowserContext();
+
+ RefPtr<WebsiteDataStore> dataStore;
+ RefPtr<WebProcessPool> processPool;
+ HashSet<WebPageProxy*> pages;
+ WeakPtr<OverridenGeolocationProvider> geolocationProvider;
+};
+
+class InspectorPlaywrightAgentClient {
+public:
+ virtual ~InspectorPlaywrightAgentClient() = default;
+ virtual RefPtr<WebKit::WebPageProxy> createPage(WTF::String& error, const BrowserContext& context) = 0;
+ virtual void closeBrowser() = 0;
+ virtual std::unique_ptr<BrowserContext> createBrowserContext(WTF::String& error, const WTF::String& proxyServer, const WTF::String& proxyBypassList) = 0;
+ virtual void deleteBrowserContext(WTF::String& error, PAL::SessionID) = 0;
+};
+
+} // 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 ffc917d8bcabc32cd5db24fcc454d743b59763dc..e6d36eaf5bca4f19de66fe5640102037d8637c0d 100644
--- a/Source/WebKit/UIProcess/PageClient.h
+++ b/Source/WebKit/UIProcess/PageClient.h
@@ -321,6 +321,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(std::optional<WebCore::IntRect>&&) = 0;
#endif
diff --git a/Source/WebKit/UIProcess/ProvisionalPageProxy.cpp b/Source/WebKit/UIProcess/ProvisionalPageProxy.cpp
index f85e2a653d0dff83a2970b0a05e75459830a5c21..f64097fc38ef2a3630d7625a4a7ea678ed12fdaf 100644
--- a/Source/WebKit/UIProcess/ProvisionalPageProxy.cpp
+++ b/Source/WebKit/UIProcess/ProvisionalPageProxy.cpp
@@ -635,3 +635,5 @@ bool ProvisionalPageProxy::sendMessage(UniqueRef<IPC::Encoder>&& encoder, Option
}
} // namespace WebKit
+
+#undef MESSAGE_CHECK
diff --git a/Source/WebKit/UIProcess/RemoteInspectorPipe.cpp b/Source/WebKit/UIProcess/RemoteInspectorPipe.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..dd8b28e692dca4078eb710b2a97e61716126a4cb
--- /dev/null
+++ b/Source/WebKit/UIProcess/RemoteInspectorPipe.cpp
@@ -0,0 +1,224 @@
+/*
+ * 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)
+{
+ 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) {
+ RunLoop::main().dispatch([this] {
+ if (!m_terminated)
+ m_playwrightAgent.disconnectFrontend();
+ });
+ 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 = WTFMove(message)] {
+ if (!m_terminated)
+ m_playwrightAgent.dispatchMessageFromFrontend(message);
+ });
+ }
+ ++end;
+ start = end;
+ }
+ if (start != 0 && start < line.size())
+ memmove(line.data(), line.data() + start, line.size() - start);
+ line.shrink(line.size() - start);
+ }
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(REMOTE_INSPECTOR)
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 684b9616573761123fbcc0d94be29de519ecced6..51ff18323ece0ee15c87d63a1d6fd604377ee968 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 72443b5a8da3abba60042c09d4b2c9d42acf9221..bcf13bc87801d5fcfa7f8178a8adf8fc4a50bb44 100644
--- a/Source/WebKit/UIProcess/WebContextMenuProxy.h
+++ b/Source/WebKit/UIProcess/WebContextMenuProxy.h
@@ -33,6 +33,7 @@
#include <wtf/RefCounted.h>
#include <wtf/WeakPtr.h>
+OBJC_CLASS NSArray;
OBJC_CLASS NSMenu;
namespace WebKit {
@@ -45,6 +46,7 @@ public:
virtual ~WebContextMenuProxy();
virtual void show();
+ virtual void hide() {}
WebPageProxy* page() const { return m_page.get(); }
diff --git a/Source/WebKit/UIProcess/WebPageInspectorEmulationAgent.cpp b/Source/WebKit/UIProcess/WebPageInspectorEmulationAgent.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ae45b4212bdb3f6a004cc80a1d91146b540f86f5
--- /dev/null
+++ b/Source/WebKit/UIProcess/WebPageInspectorEmulationAgent.cpp
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2019 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebPageInspectorEmulationAgent.h"
+
+#include "APIPageConfiguration.h"
+#include "WebPageProxy.h"
+#include "WebPreferences.h"
+#include "PageClient.h"
+#include <JavaScriptCore/InspectorFrontendRouter.h>
+#include <WebCore/Credential.h>
+
+
+namespace WebKit {
+
+using namespace Inspector;
+
+WebPageInspectorEmulationAgent::WebPageInspectorEmulationAgent(BackendDispatcher& backendDispatcher, WebPageProxy& page)
+ : InspectorAgentBase("Emulation"_s)
+ , m_backendDispatcher(EmulationBackendDispatcher::create(backendDispatcher, this))
+ , m_page(page)
+{
+}
+
+WebPageInspectorEmulationAgent::~WebPageInspectorEmulationAgent()
+{
+}
+
+void WebPageInspectorEmulationAgent::didCreateFrontendAndBackend(FrontendRouter*, BackendDispatcher*)
+{
+}
+
+void WebPageInspectorEmulationAgent::willDestroyFrontendAndBackend(DisconnectReason)
+{
+ m_commandsToRunWhenShown.clear();
+}
+
+void WebPageInspectorEmulationAgent::setDeviceMetricsOverride(int width, int height, bool fixedlayout, std::optional<double>&& deviceScaleFactor, Ref<SetDeviceMetricsOverrideCallback>&& callback)
+{
+#if PLATFORM(GTK)
+ // On gtk, fixed layout doesn't work with compositing enabled
+ // FIXME: This turns off compositing forever, even if fixedLayout is disabled.
+ if (fixedlayout) {
+ auto copy = m_page.preferences().copy();
+ copy->setAcceleratedCompositingEnabled(false);
+ m_page.setPreferences(copy);
+ }
+#endif
+
+ if (deviceScaleFactor)
+ m_page.setCustomDeviceScaleFactor(deviceScaleFactor.value());
+ m_page.setUseFixedLayout(fixedlayout);
+ if (!m_page.pageClient().isViewVisible() && m_page.configuration().relatedPage()) {
+ m_commandsToRunWhenShown.append([this, width, height, callback = WTFMove(callback)]() mutable {
+ setSize(width, height, WTFMove(callback));
+ });
+ } else {
+ setSize(width, height, WTFMove(callback));
+ }
+}
+
+void WebPageInspectorEmulationAgent::setSize(int width, int height, Ref<SetDeviceMetricsOverrideCallback>&& callback)
+{
+ platformSetSize(width, height, [callback = WTFMove(callback)](const String& error) {
+ if (error.isEmpty())
+ callback->sendSuccess();
+ else
+ callback->sendFailure(error);
+ });
+}
+
+Inspector::Protocol::ErrorStringOr<void> WebPageInspectorEmulationAgent::setJavaScriptEnabled(bool enabled)
+{
+ auto copy = m_page.preferences().copy();
+ copy->setJavaScriptEnabled(enabled);
+ m_page.setPreferences(copy);
+ return { };
+}
+
+Inspector::Protocol::ErrorStringOr<void> WebPageInspectorEmulationAgent::setAuthCredentials(const String& username, const String& password)
+{
+ if (!!username && !!password)
+ m_page.setAuthCredentialsForAutomation(WebCore::Credential(username, password, CredentialPersistencePermanent));
+ else
+ m_page.setAuthCredentialsForAutomation(std::optional<WebCore::Credential>());
+ return { };
+}
+
+Inspector::Protocol::ErrorStringOr<void> WebPageInspectorEmulationAgent::setActiveAndFocused(std::optional<bool>&& active)
+{
+ m_page.setActiveForAutomation(WTFMove(active));
+ return { };
+}
+
+Inspector::Protocol::ErrorStringOr<void> WebPageInspectorEmulationAgent::grantPermissions(const String& origin, Ref<JSON::Array>&& values)
+{
+ HashSet<String> set;
+ for (const auto& value : values.get()) {
+ String name;
+ if (!value->asString(name))
+ return makeUnexpected("Permission must be a string"_s);
+
+ set.add(name);
+ }
+ m_permissions.set(origin, WTFMove(set));
+ m_page.setPermissionsForAutomation(m_permissions);
+ return { };
+}
+
+Inspector::Protocol::ErrorStringOr<void> WebPageInspectorEmulationAgent::resetPermissions()
+{
+ m_permissions.clear();
+ m_page.setPermissionsForAutomation(m_permissions);
+ return { };
+}
+
+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..b3bb4880a866ee6132b8b26acf8dad81afe14d85
--- /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, bool fixedlayout, std::optional<double>&& deviceScaleFactor, Ref<SetDeviceMetricsOverrideCallback>&&) override;
+ Inspector::Protocol::ErrorStringOr<void> setJavaScriptEnabled(bool enabled) override;
+ Inspector::Protocol::ErrorStringOr<void> setAuthCredentials(const String&, const String&) override;
+ Inspector::Protocol::ErrorStringOr<void> setActiveAndFocused(std::optional<bool>&&) override;
+ Inspector::Protocol::ErrorStringOr<void> grantPermissions(const String& origin, Ref<JSON::Array>&& permissions) override;
+ Inspector::Protocol::ErrorStringOr<void> resetPermissions() override;
+
+ 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..ac30c5f2308932d0074e59acf8093750f5eab9db
--- /dev/null
+++ b/Source/WebKit/UIProcess/WebPageInspectorInputAgent.cpp
@@ -0,0 +1,332 @@
+/*
+ * 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 "NativeWebWheelEvent.h"
+#include "WebWheelEvent.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"_s);
+ }
+
+ void append(Ref<T>&& callback)
+ {
+ m_callbacks.append(WTFMove(callback));
+ }
+
+ void sendSuccess()
+ {
+ for (const auto& callback : m_callbacks)
+ callback->sendSuccess();
+ m_callbacks.clear();
+ }
+
+private:
+ Vector<Ref<T>> m_callbacks;
+};
+
+} // namespace
+
+class WebPageInspectorInputAgent::KeyboardCallbacks : public CallbackList<Inspector::InputBackendDispatcherHandler::DispatchKeyEventCallback> {
+};
+
+class WebPageInspectorInputAgent::MouseCallbacks : public CallbackList<Inspector::InputBackendDispatcherHandler::DispatchMouseEventCallback> {
+};
+
+class WebPageInspectorInputAgent::WheelCallbacks : public CallbackList<Inspector::InputBackendDispatcherHandler::DispatchWheelEventCallback> {
+};
+
+WebPageInspectorInputAgent::WebPageInspectorInputAgent(Inspector::BackendDispatcher& backendDispatcher, WebPageProxy& page)
+ : InspectorAgentBase("Input"_s)
+ , m_backendDispatcher(InputBackendDispatcher::create(backendDispatcher, this))
+ , m_page(page)
+{
+}
+
+WebPageInspectorInputAgent::~WebPageInspectorInputAgent() = default;
+
+void WebPageInspectorInputAgent::didProcessAllPendingKeyboardEvents()
+{
+ m_keyboardCallbacks->sendSuccess();
+}
+
+void WebPageInspectorInputAgent::didProcessAllPendingMouseEvents()
+{
+ m_page.setInterceptDrags(false);
+ m_mouseCallbacks->sendSuccess();
+}
+
+void WebPageInspectorInputAgent::didProcessAllPendingWheelEvents()
+{
+ m_wheelCallbacks->sendSuccess();
+}
+
+void WebPageInspectorInputAgent::didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*)
+{
+ m_keyboardCallbacks = makeUnique<KeyboardCallbacks>();
+ m_mouseCallbacks = makeUnique<MouseCallbacks>();
+ m_wheelCallbacks = makeUnique<WheelCallbacks>();
+}
+
+void WebPageInspectorInputAgent::willDestroyFrontendAndBackend(Inspector::DisconnectReason)
+{
+ m_keyboardCallbacks = nullptr;
+ m_mouseCallbacks = nullptr;
+ m_wheelCallbacks = nullptr;
+}
+
+static String keyIdentifierForKey(const String& key)
+{
+ if (key.length() == 1)
+ return makeString("U+", hex(toASCIIUpper(key.characterAt(0)), 4));
+ if (key == "Delete"_s)
+ return "U+007F"_s;
+ if (key == "Backspace"_s)
+ return "U+0008"_s;
+ if (key == "ArrowUp"_s)
+ return "Up"_s;
+ if (key == "ArrowDown"_s)
+ return "Down"_s;
+ if (key == "ArrowLeft"_s)
+ return "Left"_s;
+ if (key == "ArrowRight"_s)
+ return "Right"_s;
+ if (key == "Tab"_s)
+ return "U+0009"_s;
+ if (key == "Pause"_s)
+ return "Pause"_s;
+ if (key == "ScrollLock"_s)
+ return "Scroll"_s;
+ return key;
+}
+
+void WebPageInspectorInputAgent::dispatchKeyEvent(const String& type, std::optional<int>&& modifiers, const String& text, const String& unmodifiedText, const String& code, const String& key, std::optional<int>&& windowsVirtualKeyCode, std::optional<int>&& nativeVirtualKeyCode, std::optional<bool>&& autoRepeat, std::optional<bool>&& isKeypad, std::optional<bool>&& isSystemKey, RefPtr<JSON::Array>&& commands, Ref<Inspector::InputBackendDispatcherHandler::DispatchKeyEventCallback>&& callback)
+{
+ WebKit::WebEvent::Type eventType;
+ if (type == "keyDown"_s) {
+ eventType = WebKit::WebEvent::KeyDown;
+ } else if (type == "keyUp"_s) {
+ eventType = WebKit::WebEvent::KeyUp;
+ } else {
+ callback->sendFailure("Unsupported event type."_s);
+ 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"_s);
+ return;
+ }
+ eventCommands.append(command);
+ }
+ }
+
+ String keyIdentifier = keyIdentifierForKey(key);
+
+ bool eventIsAutoRepeat = false;
+ if (autoRepeat)
+ eventIsAutoRepeat = *autoRepeat;
+ bool eventIsKeypad = false;
+ if (isKeypad)
+ eventIsKeypad = *isKeypad;
+ bool eventIsSystemKey = false;
+ if (isSystemKey)
+ eventIsSystemKey = *isSystemKey;
+ WallTime timestamp = WallTime::now();
+
+ // cancel any active drag on Escape
+ if (eventType == WebKit::WebEvent::KeyDown && key == "Escape"_s && m_page.cancelDragIfNeeded()) {
+ callback->sendSuccess();
+ return;
+ }
+
+ m_keyboardCallbacks->append(WTFMove(callback));
+ platformDispatchKeyEvent(
+ eventType,
+ text,
+ unmodifiedText,
+ key,
+ code,
+ keyIdentifier,
+ eventWindowsVirtualKeyCode,
+ eventNativeVirtualKeyCode,
+ eventIsAutoRepeat,
+ eventIsKeypad,
+ eventIsSystemKey,
+ eventModifiers,
+ eventCommands,
+ timestamp);
+}
+
+void WebPageInspectorInputAgent::dispatchMouseEvent(const String& type, int x, int y, std::optional<int>&& modifiers, const String& button, std::optional<int>&& buttons, std::optional<int>&& clickCount, std::optional<int>&& deltaX, std::optional<int>&& deltaY, Ref<DispatchMouseEventCallback>&& callback)
+{
+ WebEvent::Type eventType = WebEvent::NoType;
+ if (type == "down"_s)
+ eventType = WebEvent::MouseDown;
+ else if (type == "up"_s)
+ eventType = WebEvent::MouseUp;
+ else if (type == "move"_s)
+ eventType = WebEvent::MouseMove;
+ else {
+ callback->sendFailure("Unsupported event type"_s);
+ return;
+ }
+
+ OptionSet<WebEvent::Modifier> eventModifiers;
+ if (modifiers)
+ eventModifiers = eventModifiers.fromRaw(*modifiers);
+
+ WebMouseEvent::Button eventButton = WebMouseEvent::NoButton;
+ if (!!button) {
+ if (button == "left"_s)
+ eventButton = WebMouseEvent::LeftButton;
+ else if (button == "middle"_s)
+ eventButton = WebMouseEvent::MiddleButton;
+ else if (button == "right"_s)
+ eventButton = WebMouseEvent::RightButton;
+ else if (button == "none"_s)
+ eventButton = WebMouseEvent::NoButton;
+ else {
+ callback->sendFailure("Unsupported eventButton"_s);
+ return;
+ }
+ }
+
+ unsigned short eventButtons = 0;
+ if (buttons)
+ eventButtons = *buttons;
+
+ int eventClickCount = 0;
+ if (clickCount)
+ eventClickCount = *clickCount;
+ int eventDeltaX = 0;
+ if (deltaX)
+ eventDeltaX = *deltaX;
+ int eventDeltaY = 0;
+ if (deltaY)
+ eventDeltaY = *deltaY;
+ m_mouseCallbacks->append(WTFMove(callback));
+
+ // Convert css coordinates to view coordinates (dip).
+ double totalScale = m_page.pageScaleFactor() * m_page.viewScaleFactor();
+ x = clampToInteger(roundf(x * totalScale));
+ y = clampToInteger(roundf(y * totalScale));
+ eventDeltaX = clampToInteger(roundf(eventDeltaX * totalScale));
+ eventDeltaY = clampToInteger(roundf(eventDeltaY * totalScale));
+
+ // We intercept any drags generated by this mouse event
+ // to prevent them from creating actual drags in the host
+ // operating system. This is turned off in the callback.
+ m_page.setInterceptDrags(true);
+#if PLATFORM(MAC)
+ ASSERT_UNUSED(eventType, 1);
+ ASSERT_UNUSED(eventButton, 1);
+ ASSERT_UNUSED(eventClickCount, 1);
+ platformDispatchMouseEvent(type, x, y, WTFMove(modifiers), button, WTFMove(clickCount), eventButtons);
+#elif PLATFORM(GTK) || PLATFORM(WPE) || PLATFORM(WIN)
+ WallTime timestamp = WallTime::now();
+ NativeWebMouseEvent event(
+ eventType,
+ eventButton,
+ eventButtons,
+ {x, y},
+ WebCore::IntPoint(),
+ eventDeltaX,
+ eventDeltaY,
+ 0,
+ eventClickCount,
+ eventModifiers,
+ timestamp);
+ m_page.handleMouseEvent(event);
+#endif
+}
+
+void WebPageInspectorInputAgent::dispatchTapEvent(int x, int y, std::optional<int>&& modifiers, Ref<DispatchTapEventCallback>&& callback) {
+ m_page.sendWithAsyncReply(Messages::WebPage::FakeTouchTap(WebCore::IntPoint(x, y), modifiers ? *modifiers : 0), [callback]() {
+ callback->sendSuccess();
+ });
+}
+
+void WebPageInspectorInputAgent::dispatchWheelEvent(int x, int y, std::optional<int>&& modifiers, std::optional<int>&& deltaX, std::optional<int>&& deltaY, Ref<DispatchWheelEventCallback>&& callback)
+{
+ OptionSet<WebEvent::Modifier> eventModifiers;
+ if (modifiers)
+ eventModifiers = eventModifiers.fromRaw(*modifiers);
+
+ float eventDeltaX = 0.0f;
+ if (deltaX)
+ eventDeltaX = *deltaX;
+ float eventDeltaY = 0.0f;
+ if (deltaY)
+ eventDeltaY = *deltaY;
+ m_wheelCallbacks->append(WTFMove(callback));
+
+ // Convert css coordinates to view coordinates (dip).
+ double totalScale = m_page.pageScaleFactor() * m_page.viewScaleFactor();
+ x = clampToInteger(roundf(x * totalScale));
+ y = clampToInteger(roundf(y * totalScale));
+
+ WallTime timestamp = WallTime::now();
+ WebCore::FloatSize delta = {-eventDeltaX, -eventDeltaY};
+ WebCore::FloatSize wheelTicks = delta;
+ wheelTicks.scale(1.0f / WebCore::Scrollbar::pixelsPerLineStep());
+ WebWheelEvent webEvent(WebEvent::Wheel, {x, y}, {x, y}, delta, wheelTicks, WebWheelEvent::ScrollByPixelWheelEvent, eventModifiers, timestamp);
+ NativeWebWheelEvent event(webEvent);
+ m_page.handleWheelEvent(event);
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit/UIProcess/WebPageInspectorInputAgent.h b/Source/WebKit/UIProcess/WebPageInspectorInputAgent.h
new file mode 100644
index 0000000000000000000000000000000000000000..48c9ccc420c1b4ae3259e1d5ba17fd8fbea24b96
--- /dev/null
+++ b/Source/WebKit/UIProcess/WebPageInspectorInputAgent.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2019 Microsoft Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "WebEvent.h"
+#include "WebKeyboardEvent.h"
+#include "WebMouseEvent.h"
+#include <JavaScriptCore/InspectorAgentBase.h>
+#include <JavaScriptCore/InspectorBackendDispatchers.h>
+#include <wtf/Forward.h>
+#include <wtf/Noncopyable.h>
+
+namespace Inspector {
+class BackendDispatcher;
+class FrontendChannel;
+class FrontendRouter;
+}
+
+namespace WebKit {
+
+class NativeWebKeyboardEvent;
+class WebPageProxy;
+
+class WebPageInspectorInputAgent : public Inspector::InspectorAgentBase, public Inspector::InputBackendDispatcherHandler {
+ WTF_MAKE_NONCOPYABLE(WebPageInspectorInputAgent);
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ WebPageInspectorInputAgent(Inspector::BackendDispatcher& backendDispatcher, WebPageProxy& page);
+ ~WebPageInspectorInputAgent() override;
+
+ void didProcessAllPendingKeyboardEvents();
+ void didProcessAllPendingMouseEvents();
+ void didProcessAllPendingWheelEvents();
+
+ void didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*) override;
+ void willDestroyFrontendAndBackend(Inspector::DisconnectReason) override;
+
+ // Protocol handler
+ void dispatchKeyEvent(const String& type, std::optional<int>&& modifiers, const String& text, const String& unmodifiedText, const String& code, const String& key, std::optional<int>&& windowsVirtualKeyCode, std::optional<int>&& nativeVirtualKeyCode, std::optional<bool>&& autoRepeat, std::optional<bool>&& isKeypad, std::optional<bool>&& isSystemKey, RefPtr<JSON::Array>&&, Ref<DispatchKeyEventCallback>&& callback) override;
+ void dispatchMouseEvent(const String& type, int x, int y, std::optional<int>&& modifiers, const String& button, std::optional<int>&& buttons, std::optional<int>&& clickCount, std::optional<int>&& deltaX, std::optional<int>&& deltaY, Ref<DispatchMouseEventCallback>&& callback) override;
+ void dispatchTapEvent(int x, int y, std::optional<int>&& modifiers, Ref<DispatchTapEventCallback>&& callback) override;
+ void dispatchWheelEvent(int x, int y, std::optional<int>&& modifiers, std::optional<int>&& deltaX, std::optional<int>&& deltaY, Ref<DispatchWheelEventCallback>&& 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(MAC)
+ void platformDispatchMouseEvent(const String& type, int x, int y, std::optional<int>&& modifier, const String& button, std::optional<int>&& clickCount, unsigned short buttons);
+#endif
+
+ Ref<Inspector::InputBackendDispatcher> m_backendDispatcher;
+ WebPageProxy& m_page;
+ // Keep track of currently active modifiers across multiple keystrokes.
+ // Most platforms do not track current modifiers from synthesized events.
+ unsigned m_currentModifiers { 0 };
+ class KeyboardCallbacks;
+ std::unique_ptr<KeyboardCallbacks> m_keyboardCallbacks;
+ class MouseCallbacks;
+ std::unique_ptr<MouseCallbacks> m_mouseCallbacks;
+ class WheelCallbacks;
+ std::unique_ptr<WheelCallbacks> m_wheelCallbacks;
+};
+
+} // namespace WebKit
diff --git a/Source/WebKit/UIProcess/WebPageProxy.cpp b/Source/WebKit/UIProcess/WebPageProxy.cpp
index 4ae22f73c56835b751ab51c5cc1099b7ba79f9ca..d1a1b358633416af389e0ad45b633049db6ab80a 100644
--- a/Source/WebKit/UIProcess/WebPageProxy.cpp
+++ b/Source/WebKit/UIProcess/WebPageProxy.cpp
@@ -247,6 +247,9 @@
#if PLATFORM(GTK)
#include "GtkSettingsManager.h"
+#endif
+
+#if PLATFORM(GTK) || PLATFORM(WPE)
#include <WebCore/SelectionData.h>
#endif
@@ -629,6 +632,10 @@ WebPageProxy::~WebPageProxy()
if (m_preferences->mediaSessionCoordinatorEnabled())
GroupActivitiesSessionNotifier::sharedNotifier().removeWebPage(*this);
#endif
+
+#if PLATFORM(COCOA)
+ releaseInspectorDragPasteboard();
+#endif
}
void WebPageProxy::addAllMessageReceivers()
@@ -1045,6 +1052,7 @@ void WebPageProxy::finishAttachingToWebProcess(ProcessLaunchReason reason)
m_pageLoadState.didSwapWebProcesses();
if (reason != ProcessLaunchReason::InitialProcess)
m_drawingArea->waitForBackingStoreUpdateOnNextPaint();
+ m_inspectorController->didFinishAttachingToWebProcess();
}
void WebPageProxy::didAttachToRunningProcess()
@@ -1398,6 +1406,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 = ShouldTreatAsContinuingLoad::No;
+ 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)
@@ -1951,6 +1974,31 @@ void WebPageProxy::setControlledByAutomation(bool controlled)
websiteDataStore().networkProcess().send(Messages::NetworkProcess::SetSessionIsControlledByAutomation(m_websiteDataStore->sessionID(), m_controlledByAutomation), 0);
}
+void WebPageProxy::setAuthCredentialsForAutomation(std::optional<WebCore::Credential>&& credentials)
+{
+ m_credentialsForAutomation = WTFMove(credentials);
+}
+
+void WebPageProxy::setPermissionsForAutomation(const HashMap<String, HashSet<String>>& permissions)
+{
+ m_permissionsForAutomation = permissions;
+}
+
+void WebPageProxy::setActiveForAutomation(std::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());
@@ -2143,6 +2191,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())
@@ -2762,6 +2829,8 @@ void WebPageProxy::performDragControllerAction(DragControllerAction action, Drag
{
if (!hasRunningProcess())
return;
+ if (action == DragControllerAction::Entered || action == DragControllerAction::Updated)
+ m_dragEventsQueued++;
#if PLATFORM(GTK)
UNUSED_PARAM(dragStorageName);
UNUSED_PARAM(sandboxExtensionHandle);
@@ -2772,6 +2841,8 @@ void WebPageProxy::performDragControllerAction(DragControllerAction action, Drag
m_process->assumeReadAccessToBaseURL(*this, url);
ASSERT(dragData.platformData());
+#endif
+#if PLATFORM(GTK) || PLATFORM(WPE)
send(Messages::WebPage::PerformDragControllerAction(action, dragData.clientPosition(), dragData.globalPosition(), dragData.draggingSourceOperationMask(), *dragData.platformData(), dragData.flags()));
#else
send(Messages::WebPage::PerformDragControllerAction(action, dragData, sandboxExtensionHandle, sandboxExtensionsForUpload));
@@ -2787,18 +2858,41 @@ void WebPageProxy::didPerformDragControllerAction(std::optional<WebCore::DragOpe
m_currentDragCaretEditableElementRect = editableElementRect;
setDragCaretRect(insertionRect);
pageClient().didPerformDragControllerAction();
+ m_dragEventsQueued--;
+ if (m_dragEventsQueued == 0 && m_mouseEventQueue.isEmpty())
+ m_inspectorController->didProcessAllPendingMouseEvents();
+
}
-#if PLATFORM(GTK)
+#if PLATFORM(GTK) || PLATFORM(WPE)
void WebPageProxy::startDrag(SelectionData&& selectionData, OptionSet<WebCore::DragOperation> dragOperationMask, const ShareableBitmap::Handle& dragImageHandle, IntPoint&& dragImageHotspot)
{
- RefPtr<ShareableBitmap> dragImage = !dragImageHandle.isNull() ? ShareableBitmap::create(dragImageHandle) : nullptr;
- pageClient().startDrag(WTFMove(selectionData), dragOperationMask, WTFMove(dragImage), WTFMove(dragImageHotspot));
+ if (m_interceptDrags) {
+ m_dragSelectionData = WTFMove(selectionData);
+ m_dragSourceOperationMask = dragOperationMask;
+ } else {
+#if PLATFORM(GTK)
+ RefPtr<ShareableBitmap> dragImage = !dragImageHandle.isNull() ? ShareableBitmap::create(dragImageHandle) : nullptr;
+ pageClient().startDrag(WTFMove(selectionData), dragOperationMask, WTFMove(dragImage), WTFMove(dragImageHotspot));
+#endif
+ }
+
+ didStartDrag();
+}
+#endif
+#if PLATFORM(WIN) && ENABLE(DRAG_SUPPORT)
+void WebPageProxy::startDrag(WebCore::DragDataMap&& dragDataMap)
+{
+ if (m_interceptDrags) {
+ m_dragSelectionData = WTFMove(dragDataMap);
+ m_dragSourceOperationMask = WebCore::anyDragOperation();
+ }
didStartDrag();
}
#endif
+
void WebPageProxy::dragEnded(const IntPoint& clientPosition, const IntPoint& globalPosition, OptionSet<WebCore::DragOperation> dragOperationMask)
{
if (!hasRunningProcess())
@@ -2807,6 +2901,24 @@ void WebPageProxy::dragEnded(const IntPoint& clientPosition, const IntPoint& glo
setDragCaretRect({ });
}
+bool WebPageProxy::cancelDragIfNeeded() {
+ if (!m_dragSelectionData)
+ return false;
+ m_dragSelectionData = std::nullopt;
+#if PLATFORM(COCOA)
+ releaseInspectorDragPasteboard();
+#endif
+
+ dragEnded(m_lastMousePositionForDrag, IntPoint(), m_dragSourceOperationMask);
+ return true;
+}
+
+#if !PLATFORM(COCOA)
+void WebPageProxy::setInterceptDrags(bool shouldIntercept) {
+ m_interceptDrags = shouldIntercept;
+}
+#endif
+
void WebPageProxy::didPerformDragOperation(bool handled)
{
pageClient().didPerformDragOperation(handled);
@@ -2819,8 +2931,18 @@ void WebPageProxy::didStartDrag()
discardQueuedMouseEvents();
send(Messages::WebPage::DidStartDrag());
+
+ if (m_interceptDrags) {
+#if PLATFORM(WIN) || PLATFORM(COCOA)
+ DragData dragData(*m_dragSelectionData, m_lastMousePositionForDrag, WebCore::IntPoint(), m_dragSourceOperationMask);
+#else
+ DragData dragData(&*m_dragSelectionData, m_lastMousePositionForDrag, WebCore::IntPoint(), m_dragSourceOperationMask);
+#endif
+ dragEntered(dragData);
+ dragUpdated(dragData);
+ }
}
-
+
void WebPageProxy::dragCancelled()
{
if (hasRunningProcess())
@@ -2925,16 +3047,38 @@ void WebPageProxy::processNextQueuedMouseEvent()
m_process->startResponsivenessTimer();
}
- std::optional<Vector<SandboxExtension::Handle>> sandboxExtensions;
+ m_lastMousePositionForDrag = event.position();
+ if (!m_dragSelectionData) {
+ std::optional<Vector<SandboxExtension::Handle>> sandboxExtensions;
#if PLATFORM(MAC)
- bool eventMayStartDrag = !m_currentDragOperation && eventType == WebEvent::MouseMove && event.button() != WebMouseEvent::Button::NoButton;
- if (eventMayStartDrag)
- sandboxExtensions = SandboxExtension::createHandlesForMachLookup({ "com.apple.iconservices"_s, "com.apple.iconservices.store"_s }, process().auditToken(), SandboxExtension::MachBootstrapOptions::EnableMachBootstrap);
+ bool eventMayStartDrag = !m_currentDragOperation && eventType == WebEvent::MouseMove && event.button() != WebMouseEvent::Button::NoButton;
+ if (eventMayStartDrag)
+ sandboxExtensions = SandboxExtension::createHandlesForMachLookup({ "com.apple.iconservices"_s, "com.apple.iconservices.store"_s }, process().auditToken(), SandboxExtension::MachBootstrapOptions::EnableMachBootstrap);
+#endif
+
+ LOG(MouseHandling, "UIProcess: sent mouse event %s (queue size %zu)", webMouseEventTypeString(eventType), m_mouseEventQueue.size());
+ send(Messages::WebPage::MouseEvent(event, sandboxExtensions));
+ } else {
+#if PLATFORM(WIN) || PLATFORM(COCOA)
+ DragData dragData(*m_dragSelectionData, event.position(), event.globalPosition(), m_dragSourceOperationMask);
+#else
+ DragData dragData(&*m_dragSelectionData, event.position(), event.globalPosition(), m_dragSourceOperationMask);
#endif
+ if (eventType == WebEvent::MouseMove) {
+ dragUpdated(dragData);
+ } else if (eventType == WebEvent::MouseUp) {
+ if (m_currentDragOperation && m_dragSourceOperationMask.containsAny(m_currentDragOperation.value())) {
+ SandboxExtension::Handle sandboxExtensionHandle;
+ Vector<SandboxExtension::Handle> sandboxExtensionsForUpload;
- LOG(MouseHandling, "UIProcess: sent mouse event %s (queue size %zu)", webMouseEventTypeString(eventType), m_mouseEventQueue.size());
- send(Messages::WebPage::MouseEvent(event, sandboxExtensions));
+ performDragOperation(dragData, ""_s, WTFMove(sandboxExtensionHandle), WTFMove(sandboxExtensionsForUpload));
+ }
+ m_dragSelectionData = std::nullopt;
+ dragEnded(event.position(), event.globalPosition(), m_dragSourceOperationMask);
+ }
+ didReceiveEvent(eventType, true);
+ }
}
void WebPageProxy::doAfterProcessingAllPendingMouseEvents(WTF::Function<void ()>&& action)
@@ -3098,7 +3242,7 @@ static TrackingType mergeTrackingTypes(TrackingType a, TrackingType b)
void WebPageProxy::updateTouchEventTracking(const WebTouchEvent& touchStartEvent)
{
-#if ENABLE(ASYNC_SCROLLING) && PLATFORM(COCOA)
+#if ENABLE(ASYNC_SCROLLING) && PLATFORM(IOS_FAMILY)
for (auto& touchPoint : touchStartEvent.touchPoints()) {
IntPoint location = touchPoint.location();
auto updateTrackingType = [this, location](TrackingType& trackingType, EventTrackingRegions::EventType eventType) {
@@ -3130,7 +3274,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
@@ -3519,6 +3663,8 @@ void WebPageProxy::receivedNavigationPolicyDecision(PolicyAction policyAction, A
policyAction = PolicyAction::Download;
if (policyAction != PolicyAction::Use || !frame.isMainFrame() || !navigation) {
+ if (policyAction == PolicyAction::Download && navigation)
+ m_decidePolicyForResponseRequest = navigation->currentRequest();
receivedPolicyDecision(policyAction, navigation, navigation->websitePolicies(), WTFMove(navigationAction), WTFMove(sender));
return;
}
@@ -3589,6 +3735,7 @@ void WebPageProxy::receivedNavigationPolicyDecision(PolicyAction policyAction, A
void WebPageProxy::receivedPolicyDecision(PolicyAction action, API::Navigation* navigation, RefPtr<API::WebsitePolicies>&& websitePolicies, std::variant<Ref<API::NavigationResponse>, Ref<API::NavigationAction>>&& navigationActionOrResponse, Ref<PolicyDecisionSender>&& sender, WillContinueLoadInNewProcess willContinueLoadInNewProcess, std::optional<SandboxExtension::Handle> sandboxExtensionHandle)
{
+ m_inspectorController->didReceivePolicyDecision(action, navigation ? navigation->navigationID() : 0);
if (!hasRunningProcess()) {
sender->send(PolicyDecision { sender->identifier(), isNavigatingToAppBoundDomain(), PolicyAction::Ignore, 0, std::nullopt, std::nullopt });
return;
@@ -4363,6 +4510,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;
@@ -4764,6 +4916,7 @@ void WebPageProxy::didDestroyNavigation(uint64_t navigationID)
return;
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)
@@ -4989,6 +5142,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;
@@ -5468,7 +5623,14 @@ void WebPageProxy::decidePolicyForNavigationActionAsync(FrameIdentifier frameID,
NavigationActionData&& navigationActionData, FrameInfoData&& originatingFrameInfo, std::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 = Ref { *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,
@@ -6058,6 +6220,7 @@ void WebPageProxy::createNewPage(FrameInfoData&& originatingFrameInfoData, WebPa
if (originatingPage)
openerAppInitiatedState = originatingPage->lastNavigationWasAppInitiated();
+ m_inspectorController->willCreateNewPage(windowFeatures, request.url());
auto completionHandler = [this, protectedThis = Ref { *this }, mainFrameURL, request, reply = WTFMove(reply), privateClickMeasurement = navigationActionData.privateClickMeasurement, openerAppInitiatedState = WTFMove(openerAppInitiatedState)] (RefPtr<WebPageProxy> newPage) mutable {
if (!newPage) {
reply(std::nullopt, std::nullopt);
@@ -6104,6 +6267,7 @@ void WebPageProxy::createNewPage(FrameInfoData&& originatingFrameInfoData, WebPa
void WebPageProxy::showPage()
{
m_uiClient->showPage(this);
+ m_inspectorController->didShowPage();
}
void WebPageProxy::exitFullscreenImmediately()
@@ -6163,6 +6327,10 @@ void WebPageProxy::closePage()
if (isClosed())
return;
+#if ENABLE(CONTEXT_MENUS)
+ if (m_activeContextMenu)
+ m_activeContextMenu->hide();
+#endif
WEBPAGEPROXY_RELEASE_LOG(Process, "closePage:");
pageClient().clearAllEditCommands();
m_uiClient->close(this);
@@ -6199,6 +6367,8 @@ void WebPageProxy::runJavaScriptAlert(FrameIdentifier frameID, FrameInfoData&& f
}
runModalJavaScriptDialog(WTFMove(frame), WTFMove(frameInfo), message, [reply = WTFMove(reply)](WebPageProxy& page, WebFrameProxy* frame, FrameInfoData&& frameInfo, const String& message, CompletionHandler<void()>&& completion) mutable {
+ if (page.m_inspectorDialogAgent)
+ page.m_inspectorDialogAgent->javascriptDialogOpening("alert"_s, message);
page.m_uiClient->runJavaScriptAlert(page, message, frame, WTFMove(frameInfo), [reply = WTFMove(reply), completion = WTFMove(completion)]() mutable {
reply();
completion();
@@ -6220,6 +6390,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);
runModalJavaScriptDialog(WTFMove(frame), WTFMove(frameInfo), message, [reply = WTFMove(reply)](WebPageProxy& page, WebFrameProxy* frame, FrameInfoData&& frameInfo, const String& message, CompletionHandler<void()>&& completion) mutable {
page.m_uiClient->runJavaScriptConfirm(page, message, frame, WTFMove(frameInfo), [reply = WTFMove(reply), completion = WTFMove(completion)](bool result) mutable {
@@ -6243,6 +6415,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);
runModalJavaScriptDialog(WTFMove(frame), WTFMove(frameInfo), message, [reply = WTFMove(reply), defaultValue](WebPageProxy& page, WebFrameProxy* frame, FrameInfoData&& frameInfo, const String& message, CompletionHandler<void()>&& completion) mutable {
page.m_uiClient->runJavaScriptPrompt(page, message, defaultValue, frame, WTFMove(frameInfo), [reply = WTFMove(reply), completion = WTFMove(completion)](auto& result) mutable {
@@ -6370,6 +6544,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();
@@ -7637,6 +7813,8 @@ void WebPageProxy::didReceiveEvent(uint32_t opaqueType, bool handled)
if (auto* automationSession = process().processPool().automationSession())
automationSession->mouseEventsFlushedForPage(*this);
didFinishProcessingAllPendingMouseEvents();
+ if (m_dragEventsQueued == 0)
+ m_inspectorController->didProcessAllPendingMouseEvents();
}
break;
}
@@ -7651,10 +7829,13 @@ void WebPageProxy::didReceiveEvent(uint32_t opaqueType, bool handled)
pageClient().wheelEventWasNotHandledByWebCore(oldestProcessedEvent);
}
- if (auto eventToSend = wheelEventCoalescer().nextEventToDispatch())
+ if (auto eventToSend = wheelEventCoalescer().nextEventToDispatch()) {
sendWheelEvent(*eventToSend);
- else if (auto* automationSession = process().processPool().automationSession())
- automationSession->wheelEventsFlushedForPage(*this);
+ } else {
+ if (auto* automationSession = process().processPool().automationSession())
+ automationSession->wheelEventsFlushedForPage(*this);
+ m_inspectorController->didProcessAllPendingWheelEvents();
+ }
break;
}
@@ -7663,7 +7844,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());
auto event = m_keyEventQueue.takeFirst();
MESSAGE_CHECK(m_process, type == event.type());
@@ -7682,7 +7862,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);
@@ -7691,6 +7870,7 @@ void WebPageProxy::didReceiveEvent(uint32_t opaqueType, bool handled)
if (!canProcessMoreKeyEvents) {
if (auto* automationSession = process().processPool().automationSession())
automationSession->keyboardEventsFlushedForPage(*this);
+ m_inspectorController->didProcessAllPendingKeyboardEvents();
}
break;
}
@@ -8024,7 +8204,10 @@ void WebPageProxy::dispatchProcessDidTerminate(ProcessTerminationReason reason)
{
WEBPAGEPROXY_RELEASE_LOG_ERROR(Loading, "dispatchProcessDidTerminate: reason=%{public}s", processTerminationReasonToString(reason));
- bool handledByClient = false;
+ bool handledByClient = m_inspectorController->pageCrashed(reason);
+ if (handledByClient)
+ return;
+
if (m_loaderClient)
handledByClient = reason != ProcessTerminationReason::RequestedByClient && m_loaderClient->processDidCrash(*this);
else
@@ -8358,6 +8541,7 @@ static Span<const ASCIILiteral> gpuMachServices()
WebPageCreationParameters WebPageProxy::creationParameters(WebProcessProxy& process, DrawingAreaProxy& drawingArea, RefPtr<API::WebsitePolicies>&& websitePolicies)
{
+
WebPageCreationParameters parameters;
parameters.processDisplayName = configuration().processDisplayName();
@@ -8550,6 +8734,8 @@ WebPageCreationParameters WebPageProxy::creationParameters(WebProcessProxy& proc
parameters.httpsUpgradeEnabled = preferences().upgradeKnownHostsToHTTPSEnabled() ? m_configuration->httpsUpgradeEnabled() : false;
+ parameters.shouldPauseInInspectorWhenShown = m_inspectorController->shouldPauseLoading();
+
#if PLATFORM(IOS)
// FIXME: This is also being passed over the to WebProcess via the PreferencesStore.
parameters.allowsDeprecatedSynchronousXMLHttpRequestDuringUnload = allowsDeprecatedSynchronousXMLHttpRequestDuringUnload();
@@ -8622,6 +8808,14 @@ void WebPageProxy::gamepadActivity(const Vector<GamepadData>& gamepadDatas, Even
void WebPageProxy::didReceiveAuthenticationChallengeProxy(Ref<AuthenticationChallengeProxy>&& authenticationChallenge, NegotiatedLegacyTLS negotiatedLegacyTLS)
{
+ if (m_credentialsForAutomation.has_value()) {
+ 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 = Ref { *this }, authenticationChallenge] (bool shouldAllowLegacyTLS) {
if (shouldAllowLegacyTLS)
@@ -8715,6 +8909,15 @@ void WebPageProxy::requestGeolocationPermissionForFrame(GeolocationIdentifier ge
request->deny();
};
+ auto securityOrigin = frameInfo.securityOrigin.securityOrigin();
+ auto permissions = m_permissionsForAutomation.find(securityOrigin->toString());
+ if (permissions == m_permissionsForAutomation.end())
+ permissions = m_permissionsForAutomation.find("*"_s);
+ if (permissions != m_permissionsForAutomation.end()) {
+ completionHandler(permissions->value.contains("geolocation"_s));
+ 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 4c44adebde38491bb7015ef9a90fcb910c323eab..d52644e5efc6095b277c5365dfd9f2388b4d2bbb 100644
--- a/Source/WebKit/UIProcess/WebPageProxy.h
+++ b/Source/WebKit/UIProcess/WebPageProxy.h
@@ -39,6 +39,7 @@
#include "GeolocationPermissionRequestManagerProxy.h"
#include "HiddenPageThrottlingAutoIncreasesCounter.h"
#include "IdentifierTypes.h"
+#include "InspectorDialogAgent.h"
#include "LayerTreeContext.h"
#include "MediaKeySystemPermissionRequestManagerProxy.h"
#include "MediaPlaybackState.h"
@@ -148,8 +149,11 @@
#include "EndowmentStateTracker.h"
#endif
+OBJC_CLASS NSPasteboard;
+
#if ENABLE(DRAG_SUPPORT)
#include <WebCore/DragActions.h>
+#include <WebCore/DragData.h>
#endif
#if ENABLE(TOUCH_EVENTS)
@@ -171,6 +175,14 @@
#include "ArgumentCodersGtk.h"
#endif
+#if PLATFORM(WPE)
+#include "ArgumentCodersWPE.h"
+#endif
+
+#if PLATFORM(GTK) || PLATFORM(WPE)
+#include <WebCore/SelectionData.h>
+#endif
+
#if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS_FAMILY)
#include <WebCore/MediaPlaybackTargetPicker.h>
#include <WebCore/WebMediaSessionManagerClient.h>
@@ -249,6 +261,7 @@ class AuthenticationChallenge;
class CertificateInfo;
class Cursor;
class DragData;
+typedef HashMap<unsigned, Vector<String>> DragDataMap;
class FloatRect;
class FontAttributeChanges;
class FontChanges;
@@ -256,7 +269,6 @@ class GraphicsLayer;
class IntSize;
class ProtectionSpace;
class RunLoopObserver;
-class SelectionData;
class SharedBuffer;
class SpeechRecognitionRequest;
class TextIndicator;
@@ -542,6 +554,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();
@@ -652,6 +666,11 @@ public:
void setPageLoadStateObserver(std::unique_ptr<PageLoadState::Observer>&&);
+ void setAuthCredentialsForAutomation(std::optional<WebCore::Credential>&&);
+ void setPermissionsForAutomation(const HashMap<String, HashSet<String>>&);
+ void setActiveForAutomation(std::optional<bool> active);
+ void logToStderr(const String& str);
+
void initializeWebPage();
void setDrawingArea(std::unique_ptr<DrawingAreaProxy>&&);
@@ -679,6 +698,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, bool isAppInitiated = true, 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);
@@ -1214,6 +1234,7 @@ public:
#endif
void pageScaleFactorDidChange(double);
+ void viewScaleFactorDidChange(double);
void pluginScaleFactorDidChange(double);
void pluginZoomFactorDidChange(double);
@@ -1301,14 +1322,20 @@ public:
void didStartDrag();
void dragCancelled();
void setDragCaretRect(const WebCore::IntRect&);
+ void setInterceptDrags(bool shouldIntercept);
+ bool cancelDragIfNeeded();
#if PLATFORM(COCOA)
void startDrag(const WebCore::DragItem&, const ShareableBitmap::Handle& dragImageHandle);
void setPromisedDataForImage(const String& pasteboardName, const SharedMemory::IPCHandle& imageHandle, const String& filename, const String& extension,
const String& title, const String& url, const String& visibleURL, const SharedMemory::IPCHandle& archiveHandle, const String& originIdentifier);
+ void releaseInspectorDragPasteboard();
#endif
-#if PLATFORM(GTK)
+#if PLATFORM(GTK) || PLATFORM(WPE)
void startDrag(WebCore::SelectionData&&, OptionSet<WebCore::DragOperation>, const ShareableBitmap::Handle& dragImage, WebCore::IntPoint&& dragImageHotspot);
#endif
+#if PLATFORM(WIN)
+ void startDrag(WebCore::DragDataMap&& dragDataMap);
+#endif
#endif
void processDidBecomeUnresponsive();
@@ -1559,6 +1586,8 @@ public:
#if PLATFORM(COCOA) || PLATFORM(GTK)
RefPtr<ViewSnapshot> takeViewSnapshot(std::optional<WebCore::IntRect>&&);
+#elif PLATFORM(WPE)
+ RefPtr<ViewSnapshot> takeViewSnapshot(std::optional<WebCore::IntRect>&&) { return nullptr; }
#endif
#if ENABLE(WEB_CRYPTO)
@@ -2735,6 +2764,7 @@ private:
String m_overrideContentSecurityPolicy;
RefPtr<WebInspectorUIProxy> m_inspector;
+ InspectorDialogAgent* m_inspectorDialogAgent { nullptr };
#if PLATFORM(COCOA)
WeakObjCPtr<WKWebView> m_cocoaView;
@@ -3004,6 +3034,20 @@ private:
unsigned m_currentDragNumberOfFilesToBeAccepted { 0 };
WebCore::IntRect m_currentDragCaretRect;
WebCore::IntRect m_currentDragCaretEditableElementRect;
+ bool m_interceptDrags { false };
+ OptionSet<WebCore::DragOperation> m_dragSourceOperationMask;
+ WebCore::IntPoint m_lastMousePositionForDrag;
+ int m_dragEventsQueued = 0;
+#if PLATFORM(COCOA)
+ std::optional<String> m_dragSelectionData;
+ String m_overrideDragPasteboardName;
+#endif
+#if PLATFORM(GTK) || PLATFORM(WPE)
+ std::optional<WebCore::SelectionData> m_dragSelectionData;
+#endif
+#if PLATFORM(WIN)
+ std::optional<WebCore::DragDataMap> m_dragSelectionData;
+#endif
#endif
PageLoadState m_pageLoadState;
@@ -3216,6 +3260,9 @@ private:
RefPtr<API::Object> messageBody;
};
Vector<InjectedBundleMessage> m_pendingInjectedBundleMessages;
+ std::optional<WebCore::Credential> m_credentialsForAutomation;
+ HashMap<String, HashSet<String>> m_permissionsForAutomation;
+ std::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 bc758641100c9ab2bb70c878f7a10a6db198cf01..fa3764f7c417363a0da953552fb9b6ff45c4d8f2 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(WEBGL)
WebGLPolicyForURL(URL url) -> (enum:uint8_t WebCore::WebGLLoadPolicy loadPolicy) Synchronous
@@ -175,6 +176,7 @@ messages -> WebPageProxy {
#endif
PageScaleFactorDidChange(double scaleFactor)
+ ViewScaleFactorDidChange(double scaleFactor)
PluginScaleFactorDidChange(double zoomFactor)
PluginZoomFactorDidChange(double zoomFactor)
@@ -303,10 +305,12 @@ messages -> WebPageProxy {
StartDrag(struct WebCore::DragItem dragItem, WebKit::ShareableBitmap::Handle dragImage)
SetPromisedDataForImage(String pasteboardName, WebKit::SharedMemory::IPCHandle imageHandle, String filename, String extension, String title, String url, String visibleURL, WebKit::SharedMemory::IPCHandle archiveHandle, String originIdentifier)
#endif
-#if PLATFORM(GTK) && ENABLE(DRAG_SUPPORT)
+#if (PLATFORM(GTK) || PLATFORM(WPE)) && ENABLE(DRAG_SUPPORT)
StartDrag(WebCore::SelectionData selectionData, OptionSet<WebCore::DragOperation> dragOperationMask, WebKit::ShareableBitmap::Handle dragImage, WebCore::IntPoint dragImageHotspot)
#endif
-
+#if PLATFORM(WIN) && ENABLE(DRAG_SUPPORT)
+ StartDrag(HashMap<unsigned, Vector<String>> dragDataMap)
+#endif
#if ENABLE(DRAG_SUPPORT)
DidPerformDragOperation(bool handled)
#endif
diff --git a/Source/WebKit/UIProcess/WebProcessPool.cpp b/Source/WebKit/UIProcess/WebProcessPool.cpp
index abc6cbd41160f202bffd5b3c6854388151c59812..3d2229909eec35dc9ba88312e5c81068c46fe519 100644
--- a/Source/WebKit/UIProcess/WebProcessPool.cpp
+++ b/Source/WebKit/UIProcess/WebProcessPool.cpp
@@ -534,6 +534,14 @@ void WebProcessPool::establishRemoteWorkerContextConnectionToNetworkProcess(Remo
RefPtr<WebProcessProxy> requestingProcess = requestingProcessIdentifier ? WebProcessProxy::processForIdentifier(*requestingProcessIdentifier) : nullptr;
WebProcessPool* processPool = requestingProcess ? &requestingProcess->processPool() : processPools()[0];
+ // Playwright begin
+ for (auto& process : websiteDataStore->processes()) {
+ if (process.processPoolIfExists()) {
+ processPool = process.processPoolIfExists();
+ break;
+ }
+ }
+ // Playwright end
ASSERT(processPool);
WebProcessProxy* remoteWorkerProcessProxy { nullptr };
diff --git a/Source/WebKit/UIProcess/WebProcessProxy.cpp b/Source/WebKit/UIProcess/WebProcessProxy.cpp
index e3bca858c06e2e4d2f078fcc7c683ffc18a58b3b..b8c2f10c98d150f547eee9249270395c5f08be75 100644
--- a/Source/WebKit/UIProcess/WebProcessProxy.cpp
+++ b/Source/WebKit/UIProcess/WebProcessProxy.cpp
@@ -147,6 +147,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 4e99baca3b593cf8071b5982fb872e0c6dcf1830..570921d07003475219ba1e1920f1323e3d062fa2 100644
--- a/Source/WebKit/UIProcess/WebProcessProxy.h
+++ b/Source/WebKit/UIProcess/WebProcessProxy.h
@@ -146,6 +146,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 e08988ab685895adcbbe581fe49ef2c751253d2c..303025f95770382059b18cb7f36ed1199bb18b91 100644
--- a/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp
+++ b/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp
@@ -2002,6 +2002,12 @@ void WebsiteDataStore::originDirectoryForTesting(URL&& origin, URL&& topOrigin,
networkProcess().websiteDataOriginDirectoryForTesting(m_sessionID, WTFMove(origin), WTFMove(topOrigin), type, WTFMove(completionHandler));
}
+void WebsiteDataStore::setDownloadForAutomation(std::optional<bool> allow, const String& downloadPath)
+{
+ m_allowDownloadForAutomation = allow;
+ m_downloadPathForAutomation = downloadPath;
+}
+
#if ENABLE(APP_BOUND_DOMAINS)
void WebsiteDataStore::hasAppBoundSession(CompletionHandler<void(bool)>&& completionHandler) const
{
diff --git a/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h b/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h
index 22ad4ca93d1e4645d838178a12a5eab30167f573..f20741ec7f9b7a09e86c045783176584d587f3ff 100644
--- a/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h
+++ b/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h
@@ -88,6 +88,7 @@ class SecKeyProxyStore;
class DeviceIdHashSaltStorage;
class NetworkProcessProxy;
class SOAuthorizationCoordinator;
+class DownloadProxy;
class VirtualAuthenticatorManager;
class WebPageProxy;
class WebProcessPool;
@@ -97,6 +98,7 @@ enum class CacheModel : uint8_t;
enum class WebsiteDataFetchOption : uint8_t;
enum class WebsiteDataType : uint32_t;
+struct FrameInfoData;
struct NetworkProcessConnectionInfo;
struct WebsiteDataRecord;
struct WebsiteDataStoreParameters;
@@ -107,6 +109,14 @@ enum class StorageAccessStatus : uint8_t;
enum class StorageAccessPromptStatus;
#endif
+class DownloadInstrumentation {
+public:
+ virtual void downloadCreated(const String& uuid, const WebCore::ResourceRequest&, const FrameInfoData& frameInfoData, WebPageProxy* page, RefPtr<DownloadProxy> download) = 0;
+ virtual void downloadFilenameSuggested(const String& uuid, const String& suggestedFilename) = 0;
+ virtual void downloadFinished(const String& uuid, const String& error) = 0;
+ virtual ~DownloadInstrumentation() = default;
+};
+
class WebsiteDataStore : public API::ObjectImpl<API::Object::Type::WebsiteDataStore>, public Identified<WebsiteDataStore>, public CanMakeWeakPtr<WebsiteDataStore> {
public:
static Ref<WebsiteDataStore> defaultDataStore();
@@ -294,11 +304,13 @@ public:
const WebCore::CurlProxySettings& networkProxySettings() const { return m_proxySettings; }
#endif
-#if USE(SOUP)
+#if USE(SOUP) || PLATFORM(COCOA) || PLATFORM(WIN)
void setPersistentCredentialStorageEnabled(bool);
bool persistentCredentialStorageEnabled() const { return m_persistentCredentialStorageEnabled && isPersistent(); }
void setIgnoreTLSErrors(bool);
bool ignoreTLSErrors() const { return m_ignoreTLSErrors; }
+#endif
+#if USE(SOUP)
void setNetworkProxySettings(WebCore::SoupNetworkProxySettings&&);
const WebCore::SoupNetworkProxySettings& networkProxySettings() const { return m_networkProxySettings; }
void setCookiePersistentStorage(const String&, SoupCookiePersistentStorageType);
@@ -362,6 +374,12 @@ public:
static constexpr uint64_t defaultPerOriginQuota() { return 1000 * MB; }
static bool defaultShouldUseCustomStoragePaths();
+ void setDownloadForAutomation(std::optional<bool> allow, const String& downloadPath);
+ std::optional<bool> allowDownloadForAutomation() { return m_allowDownloadForAutomation; };
+ String downloadPathForAutomation() { return m_downloadPathForAutomation; };
+ void setDownloadInstrumentation(DownloadInstrumentation* instrumentation) { m_downloadInstrumentation = instrumentation; };
+ DownloadInstrumentation* downloadInstrumentation() { return m_downloadInstrumentation; };
+
void resetQuota(CompletionHandler<void()>&&);
void clearStorage(CompletionHandler<void()>&&);
@@ -456,9 +474,11 @@ private:
WebCore::CurlProxySettings m_proxySettings;
#endif
-#if USE(SOUP)
+#if USE(SOUP) || PLATFORM(COCOA) || PLATFORM(WIN)
bool m_persistentCredentialStorageEnabled { true };
bool m_ignoreTLSErrors { true };
+#endif
+#if USE(SOUP)
WebCore::SoupNetworkProxySettings m_networkProxySettings;
String m_cookiePersistentStoragePath;
SoupCookiePersistentStorageType m_cookiePersistentStorageType { SoupCookiePersistentStorageType::SQLite };
@@ -486,6 +506,10 @@ private:
RefPtr<API::HTTPCookieStore> m_cookieStore;
RefPtr<NetworkProcessProxy> m_networkProcess;
+ std::optional<bool> m_allowDownloadForAutomation;
+ String m_downloadPathForAutomation;
+ DownloadInstrumentation* m_downloadInstrumentation { nullptr };
+
#if HAVE(APP_SSO)
std::unique_ptr<SOAuthorizationCoordinator> m_soAuthorizationCoordinator;
#endif
diff --git a/Source/WebKit/UIProcess/cairo/BackingStoreCairo.cpp b/Source/WebKit/UIProcess/cairo/BackingStoreCairo.cpp
index 0b2fc0019ffa2c05383dc4b4e480b4d380aa9fd5..79773452d246f3bcdf42122a3bf8f67685e45fdc 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/GraphicsContextCairo.h>
@@ -61,6 +63,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 692a45a48fa027f9221338d74f5351bef4baf00f..db8c761c71cc7009be66255c2668de4eff36dee0 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 b5e48e6c61a8a3f4b40b84112c4010101c4d5f41..46747b1d78bfe0270178609867c0d710807fa668 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..20a7cd2c65be39b3bcab356f6eee0b82d084c6bf
--- /dev/null
+++ b/Source/WebKit/UIProcess/glib/InspectorPlaywrightAgentClientGLib.cpp
@@ -0,0 +1,152 @@
+/*
+ * 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));
+ }
+ }
+ ignoreHosts.append(nullptr);
+ return parseRawProxySettings(proxyServer, ignoreHosts.data());
+}
+
+InspectorPlaywrightAgentClientGlib::InspectorPlaywrightAgentClientGlib(const WTF::String& proxyURI, const char* const* ignoreHosts)
+ : m_proxySettings(parseRawProxySettings(proxyURI, ignoreHosts))
+{
+}
+
+RefPtr<WebPageProxy> InspectorPlaywrightAgentClientGlib::createPage(WTF::String& error, const BrowserContext& browserContext)
+{
+ auto sessionID = browserContext.dataStore->sessionID();
+ WebKitWebContext* context = m_idToContext.get(sessionID);
+ if (!context && !browserContext.dataStore->isPersistent()) {
+ ASSERT_NOT_REACHED();
+ error = "Context with provided id not found"_s;
+ return nullptr;
+ }
+
+ RefPtr<WebPageProxy> page = webkitBrowserInspectorCreateNewPageInContext(context);
+ if (page == nullptr) {
+ error = "Failed to create new page in the context"_s;
+ return nullptr;
+ }
+
+ if (context == nullptr && sessionID != page->sessionID()) {
+ ASSERT_NOT_REACHED();
+ error = " Failed to create new page in default context"_s;
+ return nullptr;
+ }
+
+ return page;
+}
+
+void InspectorPlaywrightAgentClientGlib::closeBrowser()
+{
+ m_idToContext.clear();
+ webkitBrowserInspectorQuitApplication();
+ if (webkitWebContextExistingCount() > 1)
+ fprintf(stderr, "LEAK: %d contexts are still alive when closing browser\n", webkitWebContextExistingCount());
+}
+
+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(),
+ // WPE has PSON enabled by default and doesn't have such parameter.
+#if PLATFORM(GTK)
+ "process-swap-on-cross-site-navigation-enabled", true,
+#endif
+ nullptr)));
+ if (!context) {
+ error = "Failed to create GLib ephemeral context"_s;
+ 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/glib/WebPageProxyGLib.cpp b/Source/WebKit/UIProcess/glib/WebPageProxyGLib.cpp
index 521df7840ab6d376c25130e87ea500942398c8b6..da198916beb0d0b46661f5209db3967ba5f9f776 100644
--- a/Source/WebKit/UIProcess/glib/WebPageProxyGLib.cpp
+++ b/Source/WebKit/UIProcess/glib/WebPageProxyGLib.cpp
@@ -57,4 +57,34 @@ void WebPageProxy::loadRecentSearches(const String&, CompletionHandler<void(Vect
completionHandler({ });
}
+#if ENABLE(SPEECH_SYNTHESIS)
+void WebPageProxy::didStartSpeaking(WebCore::PlatformSpeechSynthesisUtterance&)
+{
+}
+
+void WebPageProxy::didFinishSpeaking(WebCore::PlatformSpeechSynthesisUtterance&)
+{
+}
+
+void WebPageProxy::didPauseSpeaking(WebCore::PlatformSpeechSynthesisUtterance&)
+{
+}
+
+void WebPageProxy::didResumeSpeaking(WebCore::PlatformSpeechSynthesisUtterance&)
+{
+}
+
+void WebPageProxy::speakingErrorOccurred(WebCore::PlatformSpeechSynthesisUtterance&)
+{
+}
+
+void WebPageProxy::boundaryEventOccurred(WebCore::PlatformSpeechSynthesisUtterance&, WebCore::SpeechBoundary speechBoundary, unsigned charIndex, unsigned charLength)
+{
+}
+
+void WebPageProxy::voicesDidChange()
+{
+}
+#endif // ENABLE(SPEECH_SYNTHESIS)
+
}
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..f5f811ced4eafef530d101c4e397fe2780ac3071
--- /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"_s;
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit/UIProcess/gtk/WebDateTimePickerGtk.cpp b/Source/WebKit/UIProcess/gtk/WebDateTimePickerGtk.cpp
index 6029857cfcd6c4fea14de28243f1955138a62844..8a1bda8f2637670cf88baca998cbff09157d2a6f 100644
--- a/Source/WebKit/UIProcess/gtk/WebDateTimePickerGtk.cpp
+++ b/Source/WebKit/UIProcess/gtk/WebDateTimePickerGtk.cpp
@@ -34,6 +34,8 @@
#include <wtf/SetForScope.h>
#include <wtf/glib/GRefPtr.h>
+using namespace WebCore;
+
namespace WebKit {
Ref<WebDateTimePickerGtk> WebDateTimePickerGtk::create(WebPageProxy& page)
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 8739382008f49e3dc58e3a7a73bb2432081b7726..bf9d909afbd09db070ea381ba3bfcfb04b54c28e 100644
--- a/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm
+++ b/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm
@@ -439,6 +439,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 4d795740f062bf59e99b1ee2098dc56d101d5561..540dc56fb31ac77f07f0c979650fc20fa5d1e00b 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();
@@ -165,6 +167,9 @@ private:
void updateAcceleratedCompositingMode(const LayerTreeContext&) override;
void didFirstLayerFlush(const LayerTreeContext&) override;
+// Paywright begin
+ RetainPtr<CGImageRef> takeSnapshotForAutomation() override;
+// Paywright end
RefPtr<ViewSnapshot> takeViewSnapshot(std::optional<WebCore::IntRect>&&) override;
void wheelEventWasNotHandledByWebCore(const NativeWebWheelEvent&) override;
#if ENABLE(MAC_GESTURE_EVENTS)
@@ -216,6 +221,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 496290a54e38ca2931f579fa14e04e6cc3cb747e..5ce3691dcac88c29a33f004a3894e69a8197add2 100644
--- a/Source/WebKit/UIProcess/mac/PageClientImplMac.mm
+++ b/Source/WebKit/UIProcess/mac/PageClientImplMac.mm
@@ -81,6 +81,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>
@@ -107,6 +108,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)
@@ -160,6 +168,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);
@@ -167,6 +178,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)
@@ -190,6 +204,9 @@ void PageClientImpl::makeFirstResponder()
bool PageClientImpl::isViewVisible()
{
+ if (_headless)
+ return true;
+
NSView *activeView = this->activeView();
NSWindow *activeViewWindow = activeWindow();
@@ -273,7 +290,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)
@@ -479,6 +497,8 @@ IntRect PageClientImpl::rootViewToAccessibilityScreen(const IntRect& rect)
void PageClientImpl::doneWithKeyEvent(const NativeWebKeyboardEvent& event, bool eventWasHandled)
{
+ if (!event.nativeEvent())
+ return;
m_impl->doneWithKeyEvent(event.nativeEvent(), eventWasHandled);
}
@@ -498,6 +518,8 @@ void PageClientImpl::computeHasVisualSearchResults(const URL& imageURL, Shareabl
RefPtr<WebPopupMenuProxy> PageClientImpl::createPopupMenuProxy(WebPageProxy& page)
{
+ if (_headless)
+ return nullptr;
return WebPopupMenuProxyMac::create(m_view, page);
}
@@ -629,6 +651,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(std::optional<WebCore::IntRect>&&)
{
return m_impl->takeViewSnapshot();
@@ -796,6 +824,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);
@@ -973,6 +1008,9 @@ void PageClientImpl::requestScrollToRect(const WebCore::FloatRect& targetRect, c
bool PageClientImpl::windowIsFrontWindowUnderMouse(const NativeWebMouseEvent& event)
{
+ // Simulated event.
+ if (!event.nativeEvent())
+ return false;
return m_impl->windowIsFrontWindowUnderMouse(event.nativeEvent());
}
diff --git a/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.h b/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.h
index 29b621bd947974bf0d84552bfe502f497f0a1301..986988431e717aff12ed8b3a78bf454394208d99 100644
--- a/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.h
+++ b/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.h
@@ -68,6 +68,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 ceeea741690315d1c1254f67fd3d6aaf6e7a2f5d..c1c60a1926a1f5b103277feff0223edd305569aa 100644
--- a/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.mm
+++ b/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.mm
@@ -465,6 +465,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..a68a52bd912d8d34b4f8ad505c2f8890735321d1
--- /dev/null
+++ b/Source/WebKit/UIProcess/mac/WebPageInspectorInputAgentMac.mm
@@ -0,0 +1,125 @@
+/*
+ * 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, std::optional<int>&& optionalModifiers, const String& button, std::optional<int>&& optionalClickCount, unsigned short buttons) {
+ IntPoint locationInWindow(x, y);
+
+ NSEventModifierFlags modifiers = 0;
+ if (optionalModifiers) {
+ int inputModifiers = *optionalModifiers;
+ if (inputModifiers & 1)
+ modifiers |= NSEventModifierFlagShift;
+ if (inputModifiers & 2)
+ modifiers |= NSEventModifierFlagControl;
+ if (inputModifiers & 4)
+ modifiers |= NSEventModifierFlagOption;
+ if (inputModifiers & 8)
+ modifiers |= NSEventModifierFlagCommand;
+ }
+ int clickCount = optionalClickCount ? *optionalClickCount : 0;
+
+ NSTimeInterval timestamp = [NSDate timeIntervalSinceReferenceDate];
+ NSWindow *window = m_page.platformWindow();
+ NSInteger windowNumber = window.windowNumber;
+
+ NSEventType downEventType = (NSEventType)0;
+ NSEventType dragEventType = (NSEventType)0;
+ NSEventType upEventType = (NSEventType)0;
+
+ if (!button || button == "none"_s) {
+ downEventType = NSEventTypeMouseMoved;
+ dragEventType = NSEventTypeMouseMoved;
+ upEventType = NSEventTypeMouseMoved;
+ } else if (button == "left"_s) {
+ downEventType = NSEventTypeLeftMouseDown;
+ dragEventType = NSEventTypeLeftMouseDragged;
+ upEventType = NSEventTypeLeftMouseUp;
+ } else if (button == "middle"_s) {
+ downEventType = NSEventTypeOtherMouseDown;
+ dragEventType = NSEventTypeLeftMouseDragged;
+ upEventType = NSEventTypeOtherMouseUp;
+ } else if (button == "right"_s) {
+ downEventType = NSEventTypeRightMouseDown;
+ upEventType = NSEventTypeRightMouseUp;
+ }
+
+ NSInteger eventNumber = 0;
+
+ NSEvent* event = nil;
+ if (type == "move"_s) {
+ event = [NSEvent mouseEventWithType:dragEventType location:locationInWindow modifierFlags:modifiers timestamp:timestamp windowNumber:windowNumber context:nil eventNumber:eventNumber clickCount:clickCount pressure:0.0f];
+ } else if (type == "down"_s) {
+ event = [NSEvent mouseEventWithType:downEventType location:locationInWindow modifierFlags:modifiers timestamp:timestamp windowNumber:windowNumber context:nil eventNumber:eventNumber clickCount:clickCount pressure:WebCore::ForceAtClick];
+ } else if (type == "up"_s) {
+ event = [NSEvent mouseEventWithType:upEventType location:locationInWindow modifierFlags:modifiers timestamp:timestamp windowNumber:windowNumber context:nil eventNumber:eventNumber clickCount:clickCount pressure:0.0f];
+ }
+
+ if (event) {
+ NativeWebMouseEvent nativeEvent(event, nil, [window contentView]);
+ nativeEvent.playwrightSetButtons(buttons);
+ 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));
+ }
+ if (text.length() > 0 && macCommands.size() == 0)
+ macCommands.append(WebCore::KeypressCommand("insertText:"_s, 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..0f95bc9549b3a00f9b976b4fe9140ea8e61a3513
--- /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"_s);
+ return;
+ }
+ if (!GetWindowRect(viewHwnd, &viewRect)) {
+ callback("Could retrieve view size"_s);
+ return;
+ }
+
+ width += windowRect.right - windowRect.left - viewRect.right + viewRect.left;
+ height += windowRect.bottom - windowRect.top - viewRect.bottom + viewRect.top;
+
+ if (!SetWindowPos(windowHwnd, 0, 0, 0, width, height, SWP_NOCOPYBITS | SWP_NOSENDCHANGING | SWP_NOMOVE)) {
+ callback("Could not resize window"_s);
+ return;
+ }
+ callback(String());
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit/UIProcess/win/WebPageInspectorInputAgentWin.cpp b/Source/WebKit/UIProcess/win/WebPageInspectorInputAgentWin.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..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/WebColorPickerWPE.cpp b/Source/WebKit/UIProcess/wpe/WebColorPickerWPE.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2433afca5cdbac71d11ae1fce223766091b5c843
--- /dev/null
+++ b/Source/WebKit/UIProcess/wpe/WebColorPickerWPE.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2015 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebColorPickerWPE.h"
+
+#if ENABLE(INPUT_TYPE_COLOR)
+
+#include "WebPageProxy.h"
+
+namespace WebKit {
+using namespace WebCore;
+
+Ref<WebColorPickerWPE> WebColorPickerWPE::create(WebPageProxy& page, const Color& initialColor, const IntRect& rect)
+{
+ return adoptRef(*new WebColorPickerWPE(page, initialColor, rect));
+}
+
+WebColorPickerWPE::WebColorPickerWPE(WebPageProxy& page, const Color& initialColor, const IntRect&)
+ : WebColorPicker(&page)
+{
+}
+
+WebColorPickerWPE::~WebColorPickerWPE()
+{
+ endPicker();
+}
+
+void WebColorPickerWPE::endPicker()
+{
+}
+
+void WebColorPickerWPE::showColorPicker(const Color& color)
+{
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(INPUT_TYPE_COLOR)
diff --git a/Source/WebKit/UIProcess/wpe/WebColorPickerWPE.h b/Source/WebKit/UIProcess/wpe/WebColorPickerWPE.h
new file mode 100644
index 0000000000000000000000000000000000000000..7edc93b3873dd42a7f877626551ec994395baae9
--- /dev/null
+++ b/Source/WebKit/UIProcess/wpe/WebColorPickerWPE.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2015 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WebColorPickerWPE_h
+#define WebColorPickerWPE_h
+
+#if ENABLE(INPUT_TYPE_COLOR)
+
+#include "WebColorPicker.h"
+
+typedef struct _GtkColorChooser GtkColorChooser;
+
+namespace WebCore {
+class Color;
+class IntRect;
+}
+
+namespace WebKit {
+
+class WebColorPickerWPE : public WebColorPicker {
+public:
+ static Ref<WebColorPickerWPE> create(WebPageProxy&, const WebCore::Color&, const WebCore::IntRect&);
+ virtual ~WebColorPickerWPE();
+
+ void endPicker() override;
+ void showColorPicker(const WebCore::Color&) override;
+
+protected:
+ WebColorPickerWPE(WebPageProxy&, const WebCore::Color&, const WebCore::IntRect&);
+};
+
+} // namespace WebKit
+
+#endif // ENABLE(INPUT_TYPE_COLOR)
+#endif // WebColorPickerWPE_h
diff --git a/Source/WebKit/UIProcess/wpe/WebDateTimePickerWPE.cpp b/Source/WebKit/UIProcess/wpe/WebDateTimePickerWPE.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a44463faf011fbab08f87bb7007a5e71c2a73758
--- /dev/null
+++ b/Source/WebKit/UIProcess/wpe/WebDateTimePickerWPE.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ * Copyright (C) 2021 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebDateTimePickerWPE.h"
+
+#if ENABLE(DATE_AND_TIME_INPUT_TYPES)
+
+using namespace WebCore;
+
+namespace WebKit {
+
+Ref<WebDateTimePickerWPE> WebDateTimePickerWPE::create(WebPageProxy& page)
+{
+ return adoptRef(*new WebDateTimePickerWPE(page));
+}
+
+WebDateTimePickerWPE::~WebDateTimePickerWPE()
+{
+}
+
+WebDateTimePickerWPE::WebDateTimePickerWPE(WebPageProxy& page)
+ : WebDateTimePicker(page)
+{
+}
+
+void WebDateTimePickerWPE::showDateTimePicker(WebCore::DateTimeChooserParameters&& params)
+{
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(DATE_AND_TIME_INPUT_TYPES)
diff --git a/Source/WebKit/UIProcess/wpe/WebDateTimePickerWPE.h b/Source/WebKit/UIProcess/wpe/WebDateTimePickerWPE.h
new file mode 100644
index 0000000000000000000000000000000000000000..0c0e3fce33b06ee72c4c29d2a4abe9644f4cc895
--- /dev/null
+++ b/Source/WebKit/UIProcess/wpe/WebDateTimePickerWPE.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ * Copyright (C) 2021 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(DATE_AND_TIME_INPUT_TYPES)
+
+#include "WebDateTimePicker.h"
+#include <WebCore/DateComponents.h>
+#include <WebCore/DateTimeChooserParameters.h>
+
+namespace WebKit {
+
+class WebDateTimePickerWPE final : public WebDateTimePicker {
+public:
+ static Ref<WebDateTimePickerWPE> create(WebPageProxy&);
+ ~WebDateTimePickerWPE();
+
+private:
+ WebDateTimePickerWPE(WebPageProxy&);
+
+ void showDateTimePicker(WebCore::DateTimeChooserParameters&&) final;
+};
+
+} // namespace WebKit
+
+#endif // ENABLE(DATE_AND_TIME_INPUT_TYPES)
diff --git a/Source/WebKit/UIProcess/wpe/WebPageInspectorEmulationAgentWPE.cpp b/Source/WebKit/UIProcess/wpe/WebPageInspectorEmulationAgentWPE.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..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 5d66ff9892f76589aa9e7154029a8cf0886b8e7f..1e779df73c5bbbfa42aafccf2a00efcef6afe84d 100644
--- a/Source/WebKit/WebKit.xcodeproj/project.pbxproj
+++ b/Source/WebKit/WebKit.xcodeproj/project.pbxproj
@@ -1243,6 +1243,7 @@
5CABDC8722C40FED001EDE8E /* APIMessageListener.h in Headers */ = {isa = PBXBuildFile; fileRef = 5CABDC8322C40FA7001EDE8E /* APIMessageListener.h */; };
5CADDE05215046BD0067D309 /* WKWebProcess.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C74300E21500492004BFA17 /* WKWebProcess.h */; settings = {ATTRIBUTES = (Private, ); }; };
5CAECB6627465AE400AB78D0 /* UnifiedSource115.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5CAECB5E27465AE300AB78D0 /* UnifiedSource115.cpp */; };
+ BF2C49ED7AD83CB7BC93CC92 /* UnifiedSource116.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1D7178FBC4EDB168CDB0B04D /* UnifiedSource116.cpp */; };
5CAF7AA726F93AB00003F19E /* adattributiond.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5CAF7AA526F93A950003F19E /* adattributiond.cpp */; };
5CAFDE452130846300B1F7E1 /* _WKInspector.h in Headers */ = {isa = PBXBuildFile; fileRef = 5CAFDE422130843500B1F7E1 /* _WKInspector.h */; settings = {ATTRIBUTES = (Private, ); }; };
5CAFDE472130846A00B1F7E1 /* _WKInspectorInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 5CAFDE442130843600B1F7E1 /* _WKInspectorInternal.h */; };
@@ -2220,6 +2221,18 @@
DF0C5F28252ECB8E00D921DB /* WKDownload.h in Headers */ = {isa = PBXBuildFile; fileRef = DF0C5F24252ECB8D00D921DB /* WKDownload.h */; settings = {ATTRIBUTES = (Public, ); }; };
DF0C5F2A252ECB8E00D921DB /* WKDownloadDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = DF0C5F26252ECB8E00D921DB /* WKDownloadDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; };
DF0C5F2B252ED44000D921DB /* WKDownloadInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = DF0C5F25252ECB8E00D921DB /* WKDownloadInternal.h */; };
+ D71A94322370E025002C4D9E /* InspectorPlaywrightAgentClientMac.h in Headers */ = {isa = PBXBuildFile; fileRef = D71A94302370E025002C4D9E /* InspectorPlaywrightAgentClientMac.h */; };
+ D71A94342370E07A002C4D9E /* InspectorPlaywrightAgentClient.h in Headers */ = {isa = PBXBuildFile; fileRef = D71A94332370E07A002C4D9E /* InspectorPlaywrightAgentClient.h */; };
+ D71A943A2370F061002C4D9E /* RemoteInspectorPipe.h in Headers */ = {isa = PBXBuildFile; fileRef = D71A94392370F060002C4D9E /* RemoteInspectorPipe.h */; };
+ D71A94422371F67E002C4D9E /* WebPageInspectorEmulationAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = D71A943F2371F67E002C4D9E /* WebPageInspectorEmulationAgent.h */; };
+ D71A94432371F67E002C4D9E /* WebPageInspectorInputAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = D71A94402371F67E002C4D9E /* WebPageInspectorInputAgent.h */; };
+ D71A944A2372290B002C4D9E /* _WKBrowserInspector.h in Headers */ = {isa = PBXBuildFile; fileRef = D71A94492372290B002C4D9E /* _WKBrowserInspector.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ D71A944C237239FB002C4D9E /* BrowserInspectorPipe.h in Headers */ = {isa = PBXBuildFile; fileRef = D71A944B237239FB002C4D9E /* BrowserInspectorPipe.h */; };
+ D76D6888238DBD81008D314B /* InspectorDialogAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = D76D6887238DBD80008D314B /* InspectorDialogAgent.h */; };
+ D79902B1236E9404005D6F7E /* WebPageInspectorEmulationAgentMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = D79902AE236E9404005D6F7E /* WebPageInspectorEmulationAgentMac.mm */; };
+ D79902B2236E9404005D6F7E /* InspectorTargetProxyMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = D79902AF236E9404005D6F7E /* InspectorTargetProxyMac.mm */; };
+ D79902B3236E9404005D6F7E /* WebPageInspectorInputAgentMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = D79902B0236E9404005D6F7E /* WebPageInspectorInputAgentMac.mm */; };
+ D7EB04E72372A73B00F744CE /* InspectorPlaywrightAgentClientMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = D7EB04E62372A73B00F744CE /* InspectorPlaywrightAgentClientMac.mm */; };
DF462E0F23F22F5500EFF35F /* WKHTTPCookieStorePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = DF462E0E23F22F5300EFF35F /* WKHTTPCookieStorePrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
DF462E1223F338BE00EFF35F /* WKContentWorldPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = DF462E1123F338AD00EFF35F /* WKContentWorldPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
DF84CEE4249AA24D009096F6 /* WKPDFHUDView.mm in Sources */ = {isa = PBXBuildFile; fileRef = DF84CEE2249AA21F009096F6 /* WKPDFHUDView.mm */; };
@@ -2282,6 +2295,8 @@
E5BEF6822130C48000F31111 /* WebDataListSuggestionsDropdownIOS.h in Headers */ = {isa = PBXBuildFile; fileRef = E5BEF6802130C47F00F31111 /* WebDataListSuggestionsDropdownIOS.h */; };
E5CB07DC20E1678F0022C183 /* WKFormColorControl.h in Headers */ = {isa = PBXBuildFile; fileRef = E5CB07DA20E1678F0022C183 /* WKFormColorControl.h */; };
E5CBA76427A318E100DF7858 /* UnifiedSource120.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5CBA75F27A3187800DF7858 /* UnifiedSource120.cpp */; };
+ E5CBA77427A318E100DF7858 /* UnifiedSource121.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5CBA76F27A3187800DF7858 /* UnifiedSource121.cpp */; };
+ E5CBA78427A318E100DF7858 /* UnifiedSource122.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5CBA77F27A3187800DF7858 /* UnifiedSource122.cpp */; };
E5CBA76527A318E100DF7858 /* UnifiedSource118.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5CBA76127A3187900DF7858 /* UnifiedSource118.cpp */; };
E5CBA76627A318E100DF7858 /* UnifiedSource116.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5CBA76327A3187B00DF7858 /* UnifiedSource116.cpp */; };
E5CBA76727A318E100DF7858 /* UnifiedSource119.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5CBA76027A3187900DF7858 /* UnifiedSource119.cpp */; };
@@ -2298,6 +2313,9 @@
EBA8D3B627A5E33F00CB7900 /* MockPushServiceConnection.mm in Sources */ = {isa = PBXBuildFile; fileRef = EBA8D3B027A5E33F00CB7900 /* MockPushServiceConnection.mm */; };
EBA8D3B727A5E33F00CB7900 /* PushServiceConnection.mm in Sources */ = {isa = PBXBuildFile; fileRef = EBA8D3B127A5E33F00CB7900 /* PushServiceConnection.mm */; };
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, ); }; };
F4299507270E234D0032298B /* StreamMessageReceiver.h in Headers */ = {isa = PBXBuildFile; fileRef = F4299506270E234C0032298B /* StreamMessageReceiver.h */; };
F42D634122A0EFDF00D2FB3A /* WebAutocorrectionData.h in Headers */ = {isa = PBXBuildFile; fileRef = F42D633F22A0EFD300D2FB3A /* WebAutocorrectionData.h */; };
@@ -5262,6 +5280,7 @@
5CABDC8522C40FCC001EDE8E /* WKMessageListener.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKMessageListener.h; sourceTree = "<group>"; };
5CADDE0D2151AA010067D309 /* AuthenticationChallengeDisposition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AuthenticationChallengeDisposition.h; sourceTree = "<group>"; };
5CAECB5E27465AE300AB78D0 /* UnifiedSource115.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = UnifiedSource115.cpp; path = "DerivedSources/WebKit/unified-sources/UnifiedSource115.cpp"; sourceTree = BUILT_PRODUCTS_DIR; };
+ 1D7178FBC4EDB168CDB0B04D /* UnifiedSource116.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = UnifiedSource116.cpp; path = "DerivedSources/WebKit/unified-sources/UnifiedSource116.cpp"; sourceTree = BUILT_PRODUCTS_DIR; };
5CAF7AA426F93A750003F19E /* adattributiond */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = adattributiond; sourceTree = BUILT_PRODUCTS_DIR; };
5CAF7AA526F93A950003F19E /* adattributiond.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = adattributiond.cpp; sourceTree = "<group>"; };
5CAF7AA626F93AA50003F19E /* adattributiond.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = adattributiond.xcconfig; sourceTree = "<group>"; };
@@ -6973,6 +6992,19 @@
DF0C5F24252ECB8D00D921DB /* WKDownload.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKDownload.h; sourceTree = "<group>"; };
DF0C5F25252ECB8E00D921DB /* WKDownloadInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKDownloadInternal.h; sourceTree = "<group>"; };
DF0C5F26252ECB8E00D921DB /* WKDownloadDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKDownloadDelegate.h; sourceTree = "<group>"; };
+ D71A942C2370DF81002C4D9E /* WKBrowserInspector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKBrowserInspector.h; sourceTree = "<group>"; };
+ D71A94302370E025002C4D9E /* InspectorPlaywrightAgentClientMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorPlaywrightAgentClientMac.h; sourceTree = "<group>"; };
+ D71A94332370E07A002C4D9E /* InspectorPlaywrightAgentClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorPlaywrightAgentClient.h; sourceTree = "<group>"; };
+ D71A94392370F060002C4D9E /* RemoteInspectorPipe.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RemoteInspectorPipe.h; sourceTree = "<group>"; };
+ D71A943F2371F67E002C4D9E /* WebPageInspectorEmulationAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebPageInspectorEmulationAgent.h; sourceTree = "<group>"; };
+ D71A94402371F67E002C4D9E /* WebPageInspectorInputAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebPageInspectorInputAgent.h; sourceTree = "<group>"; };
+ D71A94492372290B002C4D9E /* _WKBrowserInspector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _WKBrowserInspector.h; sourceTree = "<group>"; };
+ D71A944B237239FB002C4D9E /* BrowserInspectorPipe.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BrowserInspectorPipe.h; sourceTree = "<group>"; };
+ D76D6887238DBD80008D314B /* InspectorDialogAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorDialogAgent.h; sourceTree = "<group>"; };
+ D79902AE236E9404005D6F7E /* WebPageInspectorEmulationAgentMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebPageInspectorEmulationAgentMac.mm; sourceTree = "<group>"; };
+ D79902AF236E9404005D6F7E /* InspectorTargetProxyMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = InspectorTargetProxyMac.mm; sourceTree = "<group>"; };
+ D79902B0236E9404005D6F7E /* WebPageInspectorInputAgentMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebPageInspectorInputAgentMac.mm; sourceTree = "<group>"; };
+ D7EB04E62372A73B00F744CE /* InspectorPlaywrightAgentClientMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = InspectorPlaywrightAgentClientMac.mm; sourceTree = "<group>"; };
DF462E0E23F22F5300EFF35F /* WKHTTPCookieStorePrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKHTTPCookieStorePrivate.h; sourceTree = "<group>"; };
DF462E1123F338AD00EFF35F /* WKContentWorldPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKContentWorldPrivate.h; sourceTree = "<group>"; };
DF58C6311371AC5800F9A37C /* NativeWebWheelEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NativeWebWheelEvent.h; sourceTree = "<group>"; };
@@ -7102,6 +7134,8 @@
E5CB07DA20E1678F0022C183 /* WKFormColorControl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = WKFormColorControl.h; path = ios/forms/WKFormColorControl.h; sourceTree = "<group>"; };
E5CB07DB20E1678F0022C183 /* WKFormColorControl.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = WKFormColorControl.mm; path = ios/forms/WKFormColorControl.mm; sourceTree = "<group>"; };
E5CBA75F27A3187800DF7858 /* UnifiedSource120.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = UnifiedSource120.cpp; path = "DerivedSources/WebKit/unified-sources/UnifiedSource120.cpp"; sourceTree = BUILT_PRODUCTS_DIR; };
+ E5CBA76F27A3187800DF7858 /* UnifiedSource121.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = UnifiedSource121.cpp; path = "DerivedSources/WebKit/unified-sources/UnifiedSource121.cpp"; sourceTree = BUILT_PRODUCTS_DIR; };
+ E5CBA77F27A3187800DF7858 /* UnifiedSource122.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = UnifiedSource122.cpp; path = "DerivedSources/WebKit/unified-sources/UnifiedSource122.cpp"; sourceTree = BUILT_PRODUCTS_DIR; };
E5CBA76027A3187900DF7858 /* UnifiedSource119.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = UnifiedSource119.cpp; path = "DerivedSources/WebKit/unified-sources/UnifiedSource119.cpp"; sourceTree = BUILT_PRODUCTS_DIR; };
E5CBA76127A3187900DF7858 /* UnifiedSource118.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = UnifiedSource118.cpp; path = "DerivedSources/WebKit/unified-sources/UnifiedSource118.cpp"; sourceTree = BUILT_PRODUCTS_DIR; };
E5CBA76227A3187900DF7858 /* UnifiedSource117.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = UnifiedSource117.cpp; path = "DerivedSources/WebKit/unified-sources/UnifiedSource117.cpp"; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -7123,6 +7157,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>"; };
@@ -7256,6 +7298,7 @@
files = (
3766F9EE189A1241003CF19B /* JavaScriptCore.framework in Frameworks */,
3766F9F1189A1254003CF19B /* libicucore.dylib in Frameworks */,
+ F33C7AC7249AD79C0018BE41 /* libwebrtc.dylib in Frameworks */,
3766F9EF189A1244003CF19B /* QuartzCore.framework in Frameworks */,
37694525184FC6B600CDE21F /* Security.framework in Frameworks */,
37BEC4DD1948FC6A008B4286 /* WebCore.framework in Frameworks */,
@@ -9400,6 +9443,7 @@
99788ACA1F421DCA00C08000 /* _WKAutomationSessionConfiguration.mm */,
990D28A81C6404B000986977 /* _WKAutomationSessionDelegate.h */,
990D28AF1C65203900986977 /* _WKAutomationSessionInternal.h */,
+ D71A94492372290B002C4D9E /* _WKBrowserInspector.h */,
5C4609E222430E4C009943C2 /* _WKContentRuleListAction.h */,
5C4609E322430E4D009943C2 /* _WKContentRuleListAction.mm */,
5C4609E422430E4D009943C2 /* _WKContentRuleListActionInternal.h */,
@@ -10490,6 +10534,7 @@
E34B110C27C46BC6006D2F2E /* libWebCoreTestShim.dylib */,
E34B110F27C46D09006D2F2E /* libWebCoreTestSupport.dylib */,
DDE992F4278D06D900F60D26 /* libWebKitAdditions.a */,
+ F33C7AC6249AD79C0018BE41 /* libwebrtc.dylib */,
57A9FF15252C6AEF006A2040 /* libWTF.a */,
5750F32A2032D4E500389347 /* LocalAuthentication.framework */,
570DAAB0230273D200E8FC04 /* NearField.framework */,
@@ -11017,6 +11062,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>";
@@ -11025,6 +11076,7 @@
isa = PBXGroup;
children = (
A5D3504D1D78F0D2005124A9 /* RemoteWebInspectorUIProxyMac.mm */,
+ F3970344249BD4CE003E1A22 /* ScreencastEncoderMac.mm */,
1CA8B935127C774E00576C2B /* WebInspectorUIProxyMac.mm */,
99A7ACE326012919006D57FD /* WKInspectorResourceURLSchemeHandler.h */,
99A7ACE42601291A006D57FD /* WKInspectorResourceURLSchemeHandler.mm */,
@@ -11568,6 +11620,7 @@
E1513C65166EABB200149FCB /* AuxiliaryProcessProxy.h */,
46A2B6061E5675A200C3DEDA /* BackgroundProcessResponsivenessTimer.cpp */,
46A2B6071E5675A200C3DEDA /* BackgroundProcessResponsivenessTimer.h */,
+ D71A944B237239FB002C4D9E /* BrowserInspectorPipe.h */,
4659F25E275FF6B200BBB369 /* CaptivePortalModeObserver.h */,
07297F9C1C1711EA003F0735 /* DeviceIdHashSaltStorage.cpp */,
07297F9D1C17BBEA223F0735 /* DeviceIdHashSaltStorage.h */,
@@ -11585,6 +11638,8 @@
2DD5A72A1EBF09A7009BA597 /* HiddenPageThrottlingAutoIncreasesCounter.h */,
839A2F2F1E2067390039057E /* HighPerformanceGraphicsUsageSampler.cpp */,
839A2F301E2067390039057E /* HighPerformanceGraphicsUsageSampler.h */,
+ D76D6887238DBD80008D314B /* InspectorDialogAgent.h */,
+ D71A94332370E07A002C4D9E /* InspectorPlaywrightAgentClient.h */,
5CEABA2B2333251400797797 /* LegacyGlobalSettings.cpp */,
5CEABA2A2333247700797797 /* LegacyGlobalSettings.h */,
31607F3819627002009B87DA /* LegacySessionStateCoding.h */,
@@ -11614,6 +11669,7 @@
1A0C227D2451130A00ED614D /* QuickLookThumbnailingSoftLink.mm */,
1AEE57232409F142002005D6 /* QuickLookThumbnailLoader.h */,
1AEE57242409F142002005D6 /* QuickLookThumbnailLoader.mm */,
+ D71A94392370F060002C4D9E /* RemoteInspectorPipe.h */,
BC111B08112F5E3C00337BAB /* ResponsivenessTimer.cpp */,
1A30066C1110F4F70031937C /* ResponsivenessTimer.h */,
5CA98549210BEB5A0057EB6B /* SafeBrowsingWarning.h */,
@@ -11714,6 +11770,8 @@
BC7B6204129A0A6700D174A4 /* WebPageGroup.h */,
2D9EA3101A96D9EB002D2807 /* WebPageInjectedBundleClient.cpp */,
2D9EA30E1A96CBFF002D2807 /* WebPageInjectedBundleClient.h */,
+ D71A943F2371F67E002C4D9E /* WebPageInspectorEmulationAgent.h */,
+ D71A94402371F67E002C4D9E /* WebPageInspectorInputAgent.h */,
BC111B0B112F5E4F00337BAB /* WebPageProxy.cpp */,
BC032DCB10F4389F0058C15A /* WebPageProxy.h */,
BCBD38FA125BAB9A00D2C29F /* WebPageProxy.messages.in */,
@@ -11866,6 +11924,7 @@
BC646C1911DD399F006455B0 /* WKBackForwardListItemRef.h */,
BC646C1611DD399F006455B0 /* WKBackForwardListRef.cpp */,
BC646C1711DD399F006455B0 /* WKBackForwardListRef.h */,
+ D71A942C2370DF81002C4D9E /* WKBrowserInspector.h */,
BCB9E24A1120E15C00A137E0 /* WKContext.cpp */,
BCB9E2491120E15C00A137E0 /* WKContext.h */,
1AE52F9319201F6B00A1FA37 /* WKContextConfigurationRef.cpp */,
@@ -12449,6 +12508,9 @@
C18173602058424700DFDA65 /* DisplayLink.h */,
31ABA79C215AF9E000C90E31 /* HighPerformanceGPUManager.h */,
31ABA79D215AF9E000C90E31 /* HighPerformanceGPUManager.mm */,
+ D71A94302370E025002C4D9E /* InspectorPlaywrightAgentClientMac.h */,
+ D7EB04E62372A73B00F744CE /* InspectorPlaywrightAgentClientMac.mm */,
+ D79902AF236E9404005D6F7E /* InspectorTargetProxyMac.mm */,
1AFDE65B1954E8D500C48FFA /* LegacySessionStateCoding.cpp */,
0FCB4E5818BBE3D9000FCFC9 /* PageClientImplMac.h */,
0FCB4E5918BBE3D9000FCFC9 /* PageClientImplMac.mm */,
@@ -12475,6 +12537,8 @@
E568B92120A3AC6A00E3C856 /* WebDataListSuggestionsDropdownMac.mm */,
E55CD20124D09F1F0042DB9C /* WebDateTimePickerMac.h */,
E55CD20224D09F1F0042DB9C /* WebDateTimePickerMac.mm */,
+ D79902AE236E9404005D6F7E /* WebPageInspectorEmulationAgentMac.mm */,
+ D79902B0236E9404005D6F7E /* WebPageInspectorInputAgentMac.mm */,
BC857E8512B71EBB00EDEB2E /* WebPageProxyMac.mm */,
BC5750951268F3C6006F0F12 /* WebPopupMenuProxyMac.h */,
BC5750961268F3C6006F0F12 /* WebPopupMenuProxyMac.mm */,
@@ -13659,6 +13723,7 @@
99788ACB1F421DDA00C08000 /* _WKAutomationSessionConfiguration.h in Headers */,
990D28AC1C6420CF00986977 /* _WKAutomationSessionDelegate.h in Headers */,
990D28B11C65208D00986977 /* _WKAutomationSessionInternal.h in Headers */,
+ D71A944A2372290B002C4D9E /* _WKBrowserInspector.h in Headers */,
5C4609E7224317B4009943C2 /* _WKContentRuleListAction.h in Headers */,
5C4609E8224317BB009943C2 /* _WKContentRuleListActionInternal.h in Headers */,
1A5704F81BE01FF400874AF1 /* _WKContextMenuElementInfo.h in Headers */,
@@ -13907,6 +13972,7 @@
E170876C16D6CA6900F99226 /* BlobRegistryProxy.h in Headers */,
4F601432155C5AA2001FBDE0 /* BlockingResponseMap.h in Headers */,
1A5705111BE410E600874AF1 /* BlockSPI.h in Headers */,
+ D71A944C237239FB002C4D9E /* BrowserInspectorPipe.h in Headers */,
BC3065FA1259344E00E71278 /* CacheModel.h in Headers */,
41897ED81F415D8A0016FA42 /* CacheStorageEngine.h in Headers */,
41FABD2A1F4DE001006A6C97 /* CacheStorageEngineCache.h in Headers */,
@@ -14172,7 +14238,11 @@
2DD45ADE1E5F8972006C355F /* InputViewUpdateDeferrer.h in Headers */,
CE550E152283752200D28791 /* InsertTextOptions.h in Headers */,
9197940523DBC4BB00257892 /* InspectorBrowserAgent.h in Headers */,
+ D76D6888238DBD81008D314B /* InspectorDialogAgent.h in Headers */,
996B2B9D25E257FF00719379 /* InspectorExtensionDelegate.h in Headers */,
+ D71A94342370E07A002C4D9E /* InspectorPlaywrightAgentClient.h in Headers */,
+ D71A94322370E025002C4D9E /* InspectorPlaywrightAgentClientMac.h in Headers */,
+ F3867F0A24607D4E008F0F31 /* InspectorScreencastAgent.h in Headers */,
A5E391FD2183C1F800C8FB31 /* InspectorTargetProxy.h in Headers */,
51E9049C27BCB9D400929E7E /* InstallCoordinationSPI.h in Headers */,
C5BCE5DF1C50766A00CDE3FA /* InteractionInformationAtPosition.h in Headers */,
@@ -14390,6 +14460,7 @@
CDAC20CA23FC2F750021DEE3 /* RemoteCDMInstanceSession.h in Headers */,
CDAC20C923FC2F750021DEE3 /* RemoteCDMInstanceSessionIdentifier.h in Headers */,
F451C0FE2703B263002BA03B /* RemoteDisplayListRecorderProxy.h in Headers */,
+ D71A943A2370F061002C4D9E /* RemoteInspectorPipe.h in Headers */,
2D47B56D1810714E003A3AEE /* RemoteLayerBackingStore.h in Headers */,
2DDF731518E95060004F5A66 /* RemoteLayerBackingStoreCollection.h in Headers */,
1AB16AEA164B3A8800290D62 /* RemoteLayerTreeContext.h in Headers */,
@@ -14448,6 +14519,7 @@
E1E552C516AE065F004ED653 /* SandboxInitializationParameters.h in Headers */,
E36FF00327F36FBD004BE21A /* SandboxStateVariables.h in Headers */,
7BAB111025DD02B3008FC479 /* ScopedActiveMessageReceiveQueue.h in Headers */,
+ F303B849249A8D640031DE5C /* ScreencastEncoder.h in Headers */,
E4D54D0421F1D72D007E3C36 /* ScrollingTreeFrameScrollingNodeRemoteIOS.h in Headers */,
0F931C1C18C5711900DBA7C3 /* ScrollingTreeOverflowScrollingNodeIOS.h in Headers */,
0F931C1C18C5711900DBB8D4 /* ScrollingTreeScrollingNodeDelegateIOS.h in Headers */,
@@ -14796,6 +14868,8 @@
2D9EA30F1A96CBFF002D2807 /* WebPageInjectedBundleClient.h in Headers */,
9197940823DBC4CB00257892 /* WebPageInspectorAgentBase.h in Headers */,
A513F5402154A5D700662841 /* WebPageInspectorController.h in Headers */,
+ D71A94422371F67E002C4D9E /* WebPageInspectorEmulationAgent.h in Headers */,
+ D71A94432371F67E002C4D9E /* WebPageInspectorInputAgent.h in Headers */,
A543E30C215C8A8D00279CD9 /* WebPageInspectorTarget.h in Headers */,
A543E30D215C8A9000279CD9 /* WebPageInspectorTargetController.h in Headers */,
A543E307215AD13700279CD9 /* WebPageInspectorTargetFrontendChannel.h in Headers */,
@@ -16725,6 +16799,8 @@
51E9049727BCB3D900929E7E /* ICAppBundle.mm in Sources */,
2749F6442146561B008380BF /* InjectedBundleNodeHandle.cpp in Sources */,
2749F6452146561E008380BF /* InjectedBundleRangeHandle.cpp in Sources */,
+ D7EB04E72372A73B00F744CE /* InspectorPlaywrightAgentClientMac.mm in Sources */,
+ D79902B2236E9404005D6F7E /* InspectorTargetProxyMac.mm in Sources */,
C14D37FE24ACE086007FF014 /* LaunchServicesDatabaseManager.mm in Sources */,
C1710CF724AA643200D7C112 /* LaunchServicesDatabaseObserver.mm in Sources */,
2984F588164BA095004BC0C6 /* LegacyCustomProtocolManagerMessageReceiver.cpp in Sources */,
@@ -17059,6 +17135,8 @@
E3816B3D27E2463A005EAFC0 /* WebMockContentFilterManager.cpp in Sources */,
31BA924D148831260062EDB5 /* WebNotificationManagerMessageReceiver.cpp in Sources */,
2DF6FE52212E110900469030 /* WebPage.cpp in Sources */,
+ D79902B1236E9404005D6F7E /* WebPageInspectorEmulationAgentMac.mm 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 70d709b11ae2e39a413c495aacdbcc9657b4f476..c0048cf470dd99507a447fbdeb9ec66c2d13deda 100644
--- a/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp
+++ b/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp
@@ -232,6 +232,11 @@ void WebLoaderStrategy::scheduleLoad(ResourceLoader& resourceLoader, CachedResou
}
#endif
+ if (m_emulateOfflineState) {
+ scheduleInternallyFailedLoad(resourceLoader);
+ return;
+ }
+
#if ENABLE(PDFJS)
if (tryLoadingUsingPDFJSHandler(resourceLoader, trackingParameters))
return;
@@ -314,7 +319,8 @@ static void addParametersShared(const Frame* frame, NetworkResourceLoadParameter
}
}
-void WebLoaderStrategy::scheduleLoadFromNetworkProcess(ResourceLoader& resourceLoader, const ResourceRequest& request, const WebResourceLoader::TrackingParameters& trackingParameters, bool shouldClearReferrerOnHTTPSToHTTPRedirect, Seconds maximumBufferingTime)
+// static
+bool WebLoaderStrategy::fillParametersForNetworkProcessLoad(ResourceLoader& resourceLoader, const ResourceRequest& request, const WebResourceLoader::TrackingParameters& trackingParameters, bool shouldClearReferrerOnHTTPSToHTTPRedirect, Seconds maximumBufferingTime, NetworkResourceLoadParameters& loadParameters)
{
auto identifier = resourceLoader.identifier();
ASSERT(identifier);
@@ -330,7 +336,7 @@ void WebLoaderStrategy::scheduleLoadFromNetworkProcess(ResourceLoader& resourceL
RunLoop::main().dispatch([resourceLoader = Ref { resourceLoader }, error = blockedError(request)] {
resourceLoader->didFail(error);
});
- return;
+ return false;
}
}
@@ -340,7 +346,6 @@ void WebLoaderStrategy::scheduleLoadFromNetworkProcess(ResourceLoader& resourceL
LOG(NetworkScheduling, "(WebProcess) WebLoaderStrategy::scheduleLoad, url '%s' will be scheduled with the NetworkProcess with priority %d, storedCredentialsPolicy %i", resourceLoader.url().string().latin1().data(), static_cast<int>(resourceLoader.request().priority()), (int)storedCredentialsPolicy);
- NetworkResourceLoadParameters loadParameters;
loadParameters.identifier = identifier;
loadParameters.webPageProxyID = trackingParameters.webPageProxyID;
loadParameters.webPageID = trackingParameters.pageID;
@@ -425,14 +430,11 @@ void WebLoaderStrategy::scheduleLoadFromNetworkProcess(ResourceLoader& resourceL
if (loadParameters.options.mode != FetchOptions::Mode::Navigate) {
ASSERT(loadParameters.sourceOrigin);
- if (!loadParameters.sourceOrigin) {
- WEBLOADERSTRATEGY_RELEASE_LOG_ERROR("scheduleLoad: no sourceOrigin (priority=%d)", static_cast<int>(resourceLoader.request().priority()));
- scheduleInternallyFailedLoad(resourceLoader);
- return;
- }
+ if (!loadParameters.sourceOrigin)
+ return false;
}
- loadParameters.shouldRestrictHTTPResponseAccess = shouldPerformSecurityChecks();
+ loadParameters.shouldRestrictHTTPResponseAccess = RuntimeEnabledFeatures::sharedFeatures().restrictedHTTPResponseAccess();
loadParameters.isMainFrameNavigation = resourceLoader.frame() && resourceLoader.frame()->isMainFrame() && resourceLoader.options().mode == FetchOptions::Mode::Navigate;
if (loadParameters.isMainFrameNavigation && document)
@@ -464,6 +466,17 @@ void WebLoaderStrategy::scheduleLoadFromNetworkProcess(ResourceLoader& resourceL
}
ASSERT((loadParameters.webPageID && loadParameters.webFrameID) || loadParameters.clientCredentialPolicy == ClientCredentialPolicy::CannotAskClientForCredentials);
+ return true;
+}
+
+void WebLoaderStrategy::scheduleLoadFromNetworkProcess(ResourceLoader& resourceLoader, const ResourceRequest& request, const WebResourceLoader::TrackingParameters& trackingParameters, bool shouldClearReferrerOnHTTPSToHTTPRedirect, Seconds maximumBufferingTime)
+{
+ NetworkResourceLoadParameters loadParameters;
+ if (!fillParametersForNetworkProcessLoad(resourceLoader, request, trackingParameters, shouldClearReferrerOnHTTPSToHTTPRedirect, maximumBufferingTime, loadParameters)) {
+ WEBLOADERSTRATEGY_RELEASE_LOG_ERROR("scheduleLoad: no sourceOrigin (priority=%d)", static_cast<int>(resourceLoader.request().priority()));
+ scheduleInternallyFailedLoad(resourceLoader);
+ return;
+ }
std::optional<NetworkResourceLoadIdentifier> existingNetworkResourceLoadIdentifierToResume;
if (loadParameters.isMainFrameNavigation)
@@ -478,7 +491,7 @@ void WebLoaderStrategy::scheduleLoadFromNetworkProcess(ResourceLoader& resourceL
}
auto loader = WebResourceLoader::create(resourceLoader, trackingParameters);
- m_webResourceLoaders.set(identifier, WTFMove(loader));
+ m_webResourceLoaders.set(resourceLoader.identifier(), WTFMove(loader));
}
void WebLoaderStrategy::scheduleInternallyFailedLoad(WebCore::ResourceLoader& resourceLoader)
@@ -885,7 +898,7 @@ void WebLoaderStrategy::didFinishPreconnection(WebCore::ResourceLoaderIdentifier
bool WebLoaderStrategy::isOnLine() const
{
- return m_isOnLine;
+ return m_emulateOfflineState ? false : m_isOnLine;
}
void WebLoaderStrategy::addOnlineStateChangeListener(Function<void(bool)>&& listener)
@@ -905,6 +918,11 @@ void WebLoaderStrategy::isResourceLoadFinished(CachedResource& resource, Complet
void WebLoaderStrategy::setOnLineState(bool isOnLine)
{
+ if (m_emulateOfflineState) {
+ m_isOnLine = isOnLine;
+ return;
+ }
+
if (m_isOnLine == isOnLine)
return;
@@ -913,6 +931,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 cfa563b7d34056c9375d4382ff42d55dab3daa14..baf0bdc4f441721d085ff86bd152a7ccb638d21c 100644
--- a/Source/WebKit/WebProcess/Network/WebLoaderStrategy.h
+++ b/Source/WebKit/WebProcess/Network/WebLoaderStrategy.h
@@ -41,6 +41,7 @@ struct FetchOptions;
namespace WebKit {
class NetworkProcessConnection;
+class NetworkResourceLoadParameters;
class WebFrame;
class WebPage;
class WebURLSchemeTaskProxy;
@@ -88,6 +89,9 @@ public:
bool isOnLine() const final;
void addOnlineStateChangeListener(Function<void(bool)>&&) final;
void setOnLineState(bool);
+ void setEmulateOfflineState(bool) final;
+
+ static bool fillParametersForNetworkProcessLoad(WebCore::ResourceLoader&, const WebCore::ResourceRequest&, const WebResourceLoader::TrackingParameters&, bool shouldClearReferrerOnHTTPSToHTTPRedirect, Seconds maximumBufferingTime, NetworkResourceLoadParameters&);
void setExistingNetworkResourceLoadIdentifierToResume(std::optional<NetworkResourceLoadIdentifier> existingNetworkResourceLoadIdentifierToResume) { m_existingNetworkResourceLoadIdentifierToResume = existingNetworkResourceLoadIdentifierToResume; }
@@ -140,6 +144,7 @@ private:
Vector<Function<void(bool)>> m_onlineStateChangeListeners;
std::optional<NetworkResourceLoadIdentifier> m_existingNetworkResourceLoadIdentifierToResume;
bool m_isOnLine { true };
+ bool m_emulateOfflineState { false };
};
} // namespace WebKit
diff --git a/Source/WebKit/WebProcess/Network/WebResourceLoader.cpp b/Source/WebKit/WebProcess/Network/WebResourceLoader.cpp
index 529ad5482554d07bd7bedbf3d48dc9f76e323c7c..b66401713b40e607f646414b90d6bf87c7e14d60 100644
--- a/Source/WebKit/WebProcess/Network/WebResourceLoader.cpp
+++ b/Source/WebKit/WebProcess/Network/WebResourceLoader.cpp
@@ -197,9 +197,6 @@ void WebResourceLoader::didReceiveResponse(ResourceResponse&& response, PrivateR
}
m_coreLoader->didReceiveResponse(inspectorResponse, [this, protectedThis = WTFMove(protectedThis), interceptedRequestIdentifier, policyDecisionCompletionHandler = WTFMove(policyDecisionCompletionHandler), overrideData = WTFMove(overrideData)]() mutable {
- if (policyDecisionCompletionHandler)
- policyDecisionCompletionHandler();
-
if (!m_coreLoader || !m_coreLoader->identifier()) {
m_interceptController.continueResponse(interceptedRequestIdentifier);
return;
@@ -217,6 +214,8 @@ void WebResourceLoader::didReceiveResponse(ResourceResponse&& response, PrivateR
}
});
});
+ if (policyDecisionCompletionHandler)
+ policyDecisionCompletionHandler();
return;
}
diff --git a/Source/WebKit/WebProcess/Notifications/NotificationPermissionRequestManager.cpp b/Source/WebKit/WebProcess/Notifications/NotificationPermissionRequestManager.cpp
index e00c722c2be5d505243d45f46001839d4eb8a977..33c0832cde6c292230397a13e70d90fb5984302d 100644
--- a/Source/WebKit/WebProcess/Notifications/NotificationPermissionRequestManager.cpp
+++ b/Source/WebKit/WebProcess/Notifications/NotificationPermissionRequestManager.cpp
@@ -88,7 +88,7 @@ void NotificationPermissionRequestManager::startRequest(const SecurityOriginData
m_page->sendWithAsyncReply(Messages::WebPageProxy::RequestNotificationPermission(securityOrigin.toString()), [this, protectedThis = Ref { *this }, securityOrigin, permissionHandler = WTFMove(permissionHandler)](bool allowed) mutable {
- auto innerPermissionHandler = [this, protectedThis = Ref { *this }, securityOrigin, permissionHandler = WTFMove(permissionHandler)] (bool allowed) mutable {
+ auto innerPermissionHandler = [this, protectedThis, securityOrigin, permissionHandler = WTFMove(permissionHandler)] (bool allowed) mutable {
WebProcess::singleton().supplement<WebNotificationManager>()->didUpdateNotificationDecision(securityOrigin.toString(), allowed);
auto permissionHandlers = m_requestsPerOrigin.take(securityOrigin);
diff --git a/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp b/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp
index ceb0deefec78e10d4ea64aff2b0c5cdadf313d61..f8b71b76a52e8d970fd3a7600df157e90f18d049 100644
--- a/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp
+++ b/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp
@@ -415,6 +415,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);
}
@@ -823,6 +825,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/WebDragClient.cpp b/Source/WebKit/WebProcess/WebCoreSupport/WebDragClient.cpp
index 2eb0886f13ed035a53b8eaa60605de4dfe53fbe3..c46393209cb4f80704bbc9268fad4371347d5b30 100644
--- a/Source/WebKit/WebProcess/WebCoreSupport/WebDragClient.cpp
+++ b/Source/WebKit/WebProcess/WebCoreSupport/WebDragClient.cpp
@@ -29,6 +29,13 @@
#if ENABLE(DRAG_SUPPORT)
#include "WebPage.h"
+#include <WebCore/DataTransfer.h>
+#include <WebCore/Pasteboard.h>
+#include "ShareableBitmap.h"
+
+#if PLATFORM(WPE)
+#include "ArgumentCodersWPE.h"
+#endif
namespace WebKit {
using namespace WebCore;
@@ -50,7 +57,7 @@ OptionSet<DragSourceAction> WebDragClient::dragSourceActionMaskForPoint(const In
return m_page->allowedDragSourceActions();
}
-#if !PLATFORM(COCOA) && !PLATFORM(GTK)
+#if !PLATFORM(COCOA) && !PLATFORM(GTK) && !PLATFORM(WPE) && !PLATFORM(WIN)
void WebDragClient::startDrag(DragItem, DataTransfer&, Frame&)
{
}
diff --git a/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp b/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp
index 1592d5cdb478aa77c5f4991dc79b11301851c5c0..e91a8e3ef026b34ca57fb2a0a529f51e9b8bfc21 100644
--- a/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp
+++ b/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp
@@ -1612,13 +1612,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/WebCoreSupport/mac/WebDragClientMac.mm b/Source/WebKit/WebProcess/WebCoreSupport/mac/WebDragClientMac.mm
index f8f925e1d72b6b64a9c5530073b0dc0ad675a4da..fefe472498045a872b344fb3ad73d736c5e7f2f3 100644
--- a/Source/WebKit/WebProcess/WebCoreSupport/mac/WebDragClientMac.mm
+++ b/Source/WebKit/WebProcess/WebCoreSupport/mac/WebDragClientMac.mm
@@ -126,7 +126,8 @@ static WebCore::CachedImage* cachedImage(Element& element)
void WebDragClient::declareAndWriteDragImage(const String& pasteboardName, Element& element, const URL& url, const String& label, Frame*)
{
- ASSERT(pasteboardName == String(NSPasteboardNameDrag));
+ if (pasteboardName != String(NSPasteboardNameDrag))
+ return;
WebCore::CachedImage* image = cachedImage(element);
diff --git a/Source/WebKit/WebProcess/WebCoreSupport/win/WebDragClientWin.cpp b/Source/WebKit/WebProcess/WebCoreSupport/win/WebDragClientWin.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2606914d22e85affd9b2f71c361c9db3a14da4f3
--- /dev/null
+++ b/Source/WebKit/WebProcess/WebCoreSupport/win/WebDragClientWin.cpp
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2011 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebDragClient.h"
+
+#if ENABLE(DRAG_SUPPORT)
+
+//#include "ArgumentCodersWPE.h"
+#include "ShareableBitmap.h"
+#include "WebPage.h"
+#include "WebPageProxyMessages.h"
+#include <WebCore/DataTransfer.h>
+#include <WebCore/DragData.h>
+#include <WebCore/Pasteboard.h>
+#include <wtf/win/GDIObject.h>
+#include <WebCore/Frame.h>
+
+//#include <WebCore/SelectionData.h>
+
+namespace WebKit {
+using namespace WebCore;
+
+void WebDragClient::didConcludeEditDrag()
+{
+}
+
+void WebDragClient::startDrag(DragItem, DataTransfer& dataTransfer, Frame& frame)
+{
+ m_page->willStartDrag();
+ m_page->send(Messages::WebPageProxy::StartDrag(dataTransfer.pasteboard().createDragDataMap()));
+}
+
+}; // namespace WebKit.
+
+#endif // ENABLE(DRAG_SUPPORT)
diff --git a/Source/WebKit/WebProcess/WebCoreSupport/wpe/WebDragClientWPE.cpp b/Source/WebKit/WebProcess/WebCoreSupport/wpe/WebDragClientWPE.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6d1dab390782a6c88d387bc94a36ecf07397902f
--- /dev/null
+++ b/Source/WebKit/WebProcess/WebCoreSupport/wpe/WebDragClientWPE.cpp
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2011 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebDragClient.h"
+
+#if ENABLE(DRAG_SUPPORT)
+
+#include "ArgumentCodersWPE.h"
+#include "ShareableBitmap.h"
+#include "WebPage.h"
+#include "WebPageProxyMessages.h"
+#include <WebCore/DataTransfer.h>
+#include <WebCore/DragData.h>
+#include <WebCore/Pasteboard.h>
+#include <WebCore/SelectionData.h>
+
+namespace WebKit {
+using namespace WebCore;
+
+void WebDragClient::didConcludeEditDrag()
+{
+}
+
+void WebDragClient::startDrag(DragItem, DataTransfer& dataTransfer, Frame&)
+{
+ m_page->willStartDrag();
+
+ ShareableBitmap::Handle handle;
+ m_page->send(Messages::WebPageProxy::StartDrag(dataTransfer.pasteboard().selectionData(), dataTransfer.sourceOperationMask(), handle, dataTransfer.dragLocation()));
+}
+
+}; // namespace WebKit.
+
+#endif // ENABLE(DRAG_SUPPORT)
diff --git a/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/DrawingAreaCoordinatedGraphics.cpp b/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/DrawingAreaCoordinatedGraphics.cpp
index 6bc7442b28ed5ee475d603975bee65cf32df39f4..21fb325d26bfe3819c62e9ad181c6c02c0490fb4 100644
--- a/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/DrawingAreaCoordinatedGraphics.cpp
+++ b/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/DrawingAreaCoordinatedGraphics.cpp
@@ -38,6 +38,7 @@
#include <WebCore/Frame.h>
#include <WebCore/FrameView.h>
#include <WebCore/GraphicsContext.h>
+#include <WebCore/InspectorController.h>
#include <WebCore/Page.h>
#include <WebCore/PageOverlayController.h>
#include <WebCore/Region.h>
@@ -116,6 +117,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 = IntRect(m_layerTreeHost->viewportController().visibleContentsRect());
+ visibleRect.move(-scrollDelta.width(), -scrollDelta.height());
+ m_layerTreeHost->scrollNonCompositedContents(visibleRect);
+ return;
+ }
+#endif
+// Playwright end
m_layerTreeHost->scrollNonCompositedContents(scrollRect);
return;
}
@@ -248,6 +259,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.
@@ -670,6 +682,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()
@@ -719,6 +736,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 60d596ec08c0b3550a328ae715e180ae3669676b..be272bed2f5cf15d3b5b195ab5e7a90a9b33db34 100644
--- a/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/LayerTreeHost.cpp
+++ b/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/LayerTreeHost.cpp
@@ -183,8 +183,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)
@@ -318,6 +326,10 @@ void LayerTreeHost::didChangeViewport()
if (!view->useFixedLayout())
view->notifyScrollPositionChanged(m_lastScrollPosition);
+// Playwright begin
+ else
+ m_viewportController.didScroll(m_lastScrollPosition);
+// Playwright end
}
if (m_lastPageScaleFactor != pageScale) {
diff --git a/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/LayerTreeHost.h b/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/LayerTreeHost.h
index 293c2e5de26e3612217e7f44ea43dfd589cc657e..659558a1e666cd099800c5291d06acbe5ac101e3 100644
--- a/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/LayerTreeHost.h
+++ b/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/LayerTreeHost.h
@@ -105,6 +105,13 @@ public:
void adjustTransientZoom(double, WebCore::FloatPoint);
void commitTransientZoom(double, WebCore::FloatPoint);
#endif
+
+// Playwright begin
+#if USE(COORDINATED_GRAPHICS)
+ const SimpleViewportController& viewportController() const { return m_viewportController; }
+#endif
+// Playwright end
+
private:
#if USE(COORDINATED_GRAPHICS)
void layerFlushTimerFired();
diff --git a/Source/WebKit/WebProcess/WebPage/DrawingArea.cpp b/Source/WebKit/WebProcess/WebPage/DrawingArea.cpp
index db2e5d686e6ffff8f5299903c4d42fb3a64607ac..8a4d23bdebe6a7b2f7dea87517de8f0cea62093d 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"
@@ -94,6 +95,13 @@ void DrawingArea::tryMarkLayersVolatile(CompletionHandler<void(bool)>&& completi
completionFunction(true);
}
+#if PLATFORM(WIN)
+void DrawingArea::didChangeAcceleratedCompositingMode(bool enabled)
+{
+ send(Messages::DrawingAreaProxy::DidChangeAcceleratedCompositingMode(enabled));
+}
+#endif
+
void DrawingArea::removeMessageReceiverIfNeeded()
{
if (m_hasRemovedMessageReceiver)
diff --git a/Source/WebKit/WebProcess/WebPage/DrawingArea.h b/Source/WebKit/WebProcess/WebPage/DrawingArea.h
index 3f6b9304dd08fbcc1fba7086163c753f0ad50785..165f22b4c3043cff7c9fbfb70fdc56f141b6bd6c 100644
--- a/Source/WebKit/WebProcess/WebPage/DrawingArea.h
+++ b/Source/WebKit/WebProcess/WebPage/DrawingArea.h
@@ -148,6 +148,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/WebCookieJar.cpp b/Source/WebKit/WebProcess/WebPage/WebCookieJar.cpp
index 51afcf721a21c6b073b84f55dbceba45909e2000..233a6b023d27cd7d4b3579e8d006d34edc4ea91f 100644
--- a/Source/WebKit/WebProcess/WebPage/WebCookieJar.cpp
+++ b/Source/WebKit/WebProcess/WebPage/WebCookieJar.cpp
@@ -38,6 +38,7 @@
#include <WebCore/FrameDestructionObserverInlines.h>
#include <WebCore/FrameLoader.h>
#include <WebCore/FrameLoaderClient.h>
+#include <WebCore/ResourceLoader.h>
#include <WebCore/Settings.h>
#include <WebCore/StorageSessionProvider.h>
@@ -256,4 +257,10 @@ void WebCookieJar::deleteCookie(const WebCore::Document& document, const URL& ur
WebProcess::singleton().ensureNetworkProcessConnection().connection().sendWithAsyncReply(Messages::NetworkConnectionToWebProcess::DeleteCookie(url, cookieName), WTFMove(completionHandler));
}
+void WebCookieJar::setCookieFromResponse(ResourceLoader& loader, const String& setCookieValue)
+{
+ const auto& request = loader.request();
+ WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::NetworkConnectionToWebProcess::SetCookieFromResponse(request.firstPartyForCookies(), SameSiteInfo::create(request), request.url(), setCookieValue), 0);
+}
+
} // namespace WebKit
diff --git a/Source/WebKit/WebProcess/WebPage/WebCookieJar.h b/Source/WebKit/WebProcess/WebPage/WebCookieJar.h
index 4dca404d993dbcbafeac3cf175b45201db3857f8..9d1025bd52589de93f00139791f924b85a8c30ca 100644
--- a/Source/WebKit/WebProcess/WebPage/WebCookieJar.h
+++ b/Source/WebKit/WebProcess/WebPage/WebCookieJar.h
@@ -52,6 +52,8 @@ public:
void cookiesDeleted(const String& host, const Vector<WebCore::Cookie>&);
void allCookiesDeleted();
+ void setCookieFromResponse(WebCore::ResourceLoader&, const String& setCookieValue);
+
private:
WebCookieJar();
diff --git a/Source/WebKit/WebProcess/WebPage/WebDocumentLoader.cpp b/Source/WebKit/WebProcess/WebPage/WebDocumentLoader.cpp
index 16f522fe281f8174b254b0a18626ace238229fd8..86e9489334107fbeb10df041f04eadc4bfb05657 100644
--- a/Source/WebKit/WebProcess/WebPage/WebDocumentLoader.cpp
+++ b/Source/WebKit/WebProcess/WebPage/WebDocumentLoader.cpp
@@ -49,6 +49,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 00ac534ccd395f447bba91996e299e93602d735a..e62107b8b50cd36da712892e18414b1015b9e479 100644
--- a/Source/WebKit/WebProcess/WebPage/WebPage.cpp
+++ b/Source/WebKit/WebProcess/WebPage/WebPage.cpp
@@ -934,6 +934,9 @@ WebPage::WebPage(PageIdentifier pageID, WebPageCreationParameters&& parameters)
CFPreferencesGetAppIntegerValue(CFSTR("key"), CFSTR("com.apple.WebKit.WebContent.BlockIOKitInWebContentSandbox"), nullptr);
#endif
+ if (parameters.shouldPauseInInspectorWhenShown)
+ m_page->inspectorController().pauseWhenShown();
+
updateThrottleState();
}
@@ -1708,6 +1711,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)
{
WEBPAGE_RELEASE_LOG(Loading, "loadRequest: navigationID=%" PRIu64 ", shouldTreatAsContinuingLoad=%u, lastNavigationWasAppInitiated=%d, existingNetworkResourceLoadIdentifierToResume=%" PRIu64, loadParameters.navigationID, static_cast<unsigned>(loadParameters.shouldTreatAsContinuingLoad), loadParameters.request.isAppInitiated(), valueOrDefault(loadParameters.existingNetworkResourceLoadIdentifierToResume).toUInt64());
@@ -1980,17 +1999,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())
@@ -2007,20 +2022,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));
@@ -2028,7 +2041,6 @@ void WebPage::sendViewportAttributesChanged(const ViewportArguments& viewportArg
send(Messages::WebPageProxy::DidChangeViewportProperties(attr));
#endif
}
-#endif
void WebPage::scrollMainFrameIfNotAtMaxScrollPosition(const IntSize& scrollOffset)
{
@@ -2313,6 +2325,7 @@ void WebPage::scaleView(double scale)
}
m_page->setViewScaleFactor(scale);
+ send(Messages::WebPageProxy::ViewScaleFactorDidChange(scale));
scalePage(pageScale, scrollPositionAtNewScale);
}
@@ -2492,17 +2505,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)
@@ -3416,6 +3425,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)
@@ -3492,6 +3599,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()
{
Ref frame = CheckedRef(m_page->focusController())->focusedOrMainFrame();
@@ -3732,6 +3844,7 @@ void WebPage::didCompletePageTransition()
void WebPage::show()
{
send(Messages::WebPageProxy::ShowPage());
+ m_page->inspectorController().didShowNewWindow();
}
void WebPage::setIsTakingSnapshotsForApplicationSuspension(bool isTakingSnapshotsForApplicationSuspension)
@@ -4591,7 +4704,7 @@ NotificationPermissionRequestManager* WebPage::notificationPermissionRequestMana
#if ENABLE(DRAG_SUPPORT)
-#if PLATFORM(GTK)
+#if PLATFORM(GTK) || PLATFORM(WPE)
void WebPage::performDragControllerAction(DragControllerAction action, const IntPoint& clientPosition, const IntPoint& globalPosition, OptionSet<DragOperation> draggingSourceOperationMask, SelectionData&& selectionData, OptionSet<DragApplicationFlags> flags)
{
if (!m_page) {
@@ -7001,6 +7114,9 @@ Ref<DocumentLoader> WebPage::createDocumentLoader(Frame& frame, const ResourceRe
WebsitePoliciesData::applyToDocumentLoader(WTFMove(*m_pendingWebsitePolicies), documentLoader);
m_pendingWebsitePolicies = std::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 483d6a87cb493adedbe1cb4a470676b60351fa8e..0e4ad272f59d8999bc0ca5be37ef5f08fb7dd77b 100644
--- a/Source/WebKit/WebProcess/WebPage/WebPage.h
+++ b/Source/WebKit/WebProcess/WebPage/WebPage.h
@@ -117,6 +117,10 @@
#include "WebPrintOperationGtk.h"
#endif
+#if PLATFORM(WPE)
+#include "ArgumentCodersWPE.h"
+#endif
+
#if PLATFORM(GTK) || PLATFORM(WPE)
#include "InputMethodState.h"
#endif
@@ -1014,11 +1018,11 @@ public:
void clearSelection();
void restoreSelectionInFocusedEditableElement();
-#if ENABLE(DRAG_SUPPORT) && PLATFORM(GTK)
+#if ENABLE(DRAG_SUPPORT) && (PLATFORM(GTK) || PLATFORM(WPE))
void performDragControllerAction(DragControllerAction, const WebCore::IntPoint& clientPosition, const WebCore::IntPoint& globalPosition, OptionSet<WebCore::DragOperation> draggingSourceOperationMask, WebCore::SelectionData&&, OptionSet<WebCore::DragApplicationFlags>);
#endif
-#if ENABLE(DRAG_SUPPORT) && !PLATFORM(GTK)
+#if ENABLE(DRAG_SUPPORT) && !PLATFORM(GTK) && !PLATFORM(WPE)
void performDragControllerAction(DragControllerAction, const WebCore::DragData&, SandboxExtension::Handle&&, Vector<SandboxExtension::Handle>&&);
#endif
@@ -1032,6 +1036,9 @@ public:
void didStartDrag();
void dragCancelled();
OptionSet<WebCore::DragSourceAction> allowedDragSourceActions() const { return m_allowedDragSourceActions; }
+#if PLATFORM(MAC)
+ void setDragPasteboardName(const String& pasteboardName) { m_page->setDragPasteboardName(pasteboardName); }
+#endif
#endif
void beginPrinting(WebCore::FrameIdentifier, const PrintInfo&);
@@ -1266,6 +1273,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();
@@ -1656,6 +1664,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&&);
@@ -1693,6 +1702,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&);
@@ -1836,9 +1846,7 @@ private:
void requestRectForFoundTextRange(const WebFoundTextRange&, CompletionHandler<void(WebCore::FloatRect)>&&);
-#if USE(COORDINATED_GRAPHICS)
void sendViewportAttributesChanged(const WebCore::ViewportArguments&);
-#endif
void didChangeSelectedIndexForActivePopupMenu(int32_t newIndex);
void setTextForActivePopupMenu(int32_t index);
@@ -2381,6 +2389,7 @@ private:
UserActivity m_userActivity;
uint64_t m_pendingNavigationID { 0 };
+ uint64_t m_pendingFrameNavigationID { 0 };
std::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 ba168de76718bb7b4aef2f56f5e66b1494b50126..78b3e10a9a764a0a50dabeb690c7941430cbe7fd 100644
--- a/Source/WebKit/WebProcess/WebPage/WebPage.messages.in
+++ b/Source/WebKit/WebProcess/WebPage/WebPage.messages.in
@@ -139,6 +139,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);
@@ -150,6 +151,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)
@@ -179,6 +181,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)
LoadSimulatedRequestAndResponse(struct WebKit::LoadParameters loadParameters, WebCore::ResourceResponse simulatedResponse)
@@ -343,10 +346,10 @@ GenerateSyntheticEditingCommand(enum:uint8_t WebKit::SyntheticEditingCommandType
AddMIMETypeWithCustomContentProvider(String mimeType)
# Drag and drop.
-#if PLATFORM(GTK) && ENABLE(DRAG_SUPPORT)
+#if (PLATFORM(GTK) || PLATFORM(WPE)) && ENABLE(DRAG_SUPPORT)
PerformDragControllerAction(enum:uint8_t WebKit::DragControllerAction action, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, OptionSet<WebCore::DragOperation> draggingSourceOperationMask, WebCore::SelectionData selection, OptionSet<WebCore::DragApplicationFlags> flags)
#endif
-#if !PLATFORM(GTK) && ENABLE(DRAG_SUPPORT)
+#if !PLATFORM(GTK) && !PLATFORM(WPE) && ENABLE(DRAG_SUPPORT)
PerformDragControllerAction(enum:uint8_t WebKit::DragControllerAction action, WebCore::DragData dragData, WebKit::SandboxExtension::Handle sandboxExtensionHandle, Vector<WebKit::SandboxExtension::Handle> sandboxExtensionsForUpload)
#endif
#if ENABLE(DRAG_SUPPORT)
@@ -355,6 +358,10 @@ GenerateSyntheticEditingCommand(enum:uint8_t WebKit::SyntheticEditingCommandType
DragCancelled()
#endif
+#if PLATFORM(MAC) && ENABLE(DRAG_SUPPORT)
+ SetDragPasteboardName(String pasteboardName)
+#endif
+
#if PLATFORM(IOS_FAMILY) && ENABLE(DRAG_SUPPORT)
RequestDragStart(WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, OptionSet<WebCore::DragSourceAction> allowedActionsMask)
RequestAdditionalItemsForDragSession(WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, OptionSet<WebCore::DragSourceAction> allowedActionsMask)
diff --git a/Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm b/Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm
index fdaca3bcda306311602556e63e7fe3581ce60136..2138b53e7f8c9e1b600b9ae9f3ed56521d61c248 100644
--- a/Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm
+++ b/Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm
@@ -801,21 +801,37 @@ String WebPage::platformUserAgent(const URL&) const
bool WebPage::hoverSupportedByPrimaryPointingDevice() const
{
+#if ENABLE(TOUCH_EVENTS)
+ return !screenIsTouchPrimaryInputDevice();
+#else
return true;
+#endif
}
bool WebPage::hoverSupportedByAnyAvailablePointingDevice() const
{
+#if ENABLE(TOUCH_EVENTS)
+ return !screenHasTouchDevice();
+#else
return true;
+#endif
}
std::optional<PointerCharacteristics> WebPage::pointerCharacteristicsOfPrimaryPointingDevice() const
{
+#if ENABLE(TOUCH_EVENTS)
+ if (screenIsTouchPrimaryInputDevice())
+ return PointerCharacteristics::Coarse;
+#endif
return PointerCharacteristics::Fine;
}
OptionSet<PointerCharacteristics> WebPage::pointerCharacteristicsOfAllAvailablePointingDevices() const
{
+#if ENABLE(TOUCH_EVENTS)
+ if (screenHasTouchDevice())
+ return PointerCharacteristics::Coarse;
+#endif
return PointerCharacteristics::Fine;
}
diff --git a/Source/WebKit/WebProcess/WebPage/win/WebPageWin.cpp b/Source/WebKit/WebProcess/WebPage/win/WebPageWin.cpp
index c77ff78cd3cd9627d1ae7b930c81457094645200..88746359159a76b169b7e6dcbee4fb34db5f246a 100644
--- a/Source/WebKit/WebProcess/WebPage/win/WebPageWin.cpp
+++ b/Source/WebKit/WebProcess/WebPage/win/WebPageWin.cpp
@@ -43,6 +43,7 @@
#include <WebCore/NotImplemented.h>
#include <WebCore/Page.h>
#include <WebCore/PlatformKeyboardEvent.h>
+#include <WebCore/PlatformScreen.h>
#include <WebCore/PointerCharacteristics.h>
#include <WebCore/Settings.h>
#include <WebCore/SharedBuffer.h>
@@ -118,21 +119,37 @@ String WebPage::platformUserAgent(const URL&) const
bool WebPage::hoverSupportedByPrimaryPointingDevice() const
{
+#if ENABLE(TOUCH_EVENTS)
+ return !screenIsTouchPrimaryInputDevice();
+#else
return true;
+#endif
}
bool WebPage::hoverSupportedByAnyAvailablePointingDevice() const
{
+#if ENABLE(TOUCH_EVENTS)
+ return !screenHasTouchDevice();
+#else
return true;
+#endif
}
std::optional<PointerCharacteristics> WebPage::pointerCharacteristicsOfPrimaryPointingDevice() const
{
+#if ENABLE(TOUCH_EVENTS)
+ if (screenIsTouchPrimaryInputDevice())
+ return PointerCharacteristics::Coarse;
+#endif
return PointerCharacteristics::Fine;
}
OptionSet<PointerCharacteristics> WebPage::pointerCharacteristicsOfAllAvailablePointingDevices() const
{
+#if ENABLE(TOUCH_EVENTS)
+ if (screenHasTouchDevice())
+ return PointerCharacteristics::Coarse;
+#endif
return PointerCharacteristics::Fine;
}
diff --git a/Source/WebKit/WebProcess/WebProcess.cpp b/Source/WebKit/WebProcess/WebProcess.cpp
index 490ee90b7ffb3dffcbcf2fb0213987d5262ad8c3..71d74c0adbf63c0581404010e7b76a4d3a7801c7 100644
--- a/Source/WebKit/WebProcess/WebProcess.cpp
+++ b/Source/WebKit/WebProcess/WebProcess.cpp
@@ -92,6 +92,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>
@@ -368,6 +369,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 8987c3964a9308f2454759de7f8972215a3ae416..bcac0afeb94ed8123d1f9fb0b932c8497d157b49 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 44ef0c4d102fb1022205f41919442fe5ab703522..9ddc4fc93aa4b798b2f8edecaf87ee740ec48a10 100644
--- a/Source/WebKitLegacy/mac/WebView/WebHTMLView.mm
+++ b/Source/WebKitLegacy/mac/WebView/WebHTMLView.mm
@@ -4189,7 +4189,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 59cecf9242ab834dadc904ef295365e1476f47f9..ca4cc96e62df62e92c22c3535f5972cc1fdc4cba 100644
--- a/Source/WebKitLegacy/mac/WebView/WebView.mm
+++ b/Source/WebKitLegacy/mac/WebView/WebView.mm
@@ -4039,7 +4039,7 @@ IGNORE_WARNINGS_END
}
#endif // PLATFORM(IOS_FAMILY)
-#if ENABLE(TOUCH_EVENTS)
+#if ENABLE(IOS_TOUCH_EVENTS)
- (NSArray *)_touchEventRegions
{
@@ -4081,7 +4081,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 337ac4df65636502a2b20a323c24033027536247..d44db8d54f0c8a4d840c6d970591a9f0a8c850cf 100644
--- a/Source/cmake/OptionsGTK.cmake
+++ b/Source/cmake/OptionsGTK.cmake
@@ -11,8 +11,13 @@ if (${CMAKE_VERSION} VERSION_LESS "3.20" AND NOT ${CMAKE_GENERATOR} STREQUAL "Ni
message(FATAL_ERROR "Building with Makefiles requires CMake 3.20 or newer. Either enable Ninja by passing -GNinja, or upgrade CMake.")
endif ()
+set(ENABLE_WEBKIT_LEGACY OFF)
+
set(USER_AGENT_BRANDING "" CACHE STRING "Branding to add to user agent string")
+set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
+set(THREADS_PREFER_PTHREAD_FLAG TRUE)
+
find_package(Cairo 1.14.0 REQUIRED)
find_package(Fontconfig 2.8.0 REQUIRED)
find_package(Freetype 2.4.2 REQUIRED)
@@ -32,6 +37,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_CAIRO TRUE)
@@ -65,16 +74,16 @@ WEBKIT_OPTION_DEFINE(ENABLE_QUARTZ_TARGET "Whether to enable support for the Qua
WEBKIT_OPTION_DEFINE(ENABLE_WAYLAND_TARGET "Whether to enable support for the Wayland windowing target." PUBLIC ON)
WEBKIT_OPTION_DEFINE(ENABLE_X11_TARGET "Whether to enable support for the X11 windowing target." PUBLIC ON)
WEBKIT_OPTION_DEFINE(USE_ANGLE_WEBGL "Whether to use ANGLE as WebGL backend." PUBLIC OFF)
-WEBKIT_OPTION_DEFINE(USE_AVIF "Whether to enable support for AVIF images." PUBLIC ${ENABLE_EXPERIMENTAL_FEATURES})
+WEBKIT_OPTION_DEFINE(USE_AVIF "Whether to enable support for AVIF images." PUBLIC OFF)
WEBKIT_OPTION_DEFINE(USE_GTK4 "Whether to enable usage of GTK4 instead of GTK3." PUBLIC OFF)
-WEBKIT_OPTION_DEFINE(USE_JPEGXL "Whether to enable support for JPEG-XL images." PUBLIC ${ENABLE_EXPERIMENTAL_FEATURES})
+WEBKIT_OPTION_DEFINE(USE_JPEGXL "Whether to enable support for JPEG-XL images." PUBLIC OFF)
WEBKIT_OPTION_DEFINE(USE_LCMS "Whether to enable support for image color management using libcms2." PUBLIC ON)
WEBKIT_OPTION_DEFINE(USE_LIBHYPHEN "Whether to enable the default automatic hyphenation implementation." PUBLIC ON)
WEBKIT_OPTION_DEFINE(USE_LIBNOTIFY "Whether to enable the default web notification implementation." PUBLIC ON)
WEBKIT_OPTION_DEFINE(USE_LIBSECRET "Whether to enable the persistent credential storage using libsecret." PUBLIC ON)
WEBKIT_OPTION_DEFINE(USE_OPENGL_OR_ES "Whether to use OpenGL or ES." PUBLIC ON)
WEBKIT_OPTION_DEFINE(USE_OPENJPEG "Whether to enable support for JPEG2000 images." PUBLIC ON)
-WEBKIT_OPTION_DEFINE(USE_SOUP2 "Whether to enable usage of Soup 2 instead of Soup 3." PUBLIC OFF)
+WEBKIT_OPTION_DEFINE(USE_SOUP2 "Whether to enable usage of Soup 2 instead of Soup 3." PUBLIC ON)
WEBKIT_OPTION_DEFINE(USE_WOFF2 "Whether to enable support for WOFF2 Web Fonts." PUBLIC ON)
WEBKIT_OPTION_DEFINE(USE_WPE_RENDERER "Whether to enable WPE rendering" PUBLIC ON)
@@ -124,7 +133,7 @@ endif ()
# without approval from a GTK reviewer. There must be strong reason to support
# changing the value of the option.
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_DRAG_SUPPORT PUBLIC ON)
-WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_GAMEPAD PUBLIC ON)
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_GAMEPAD PUBLIC OFF)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MINIBROWSER PUBLIC ON)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_PDFJS PUBLIC ON)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_SPELLCHECK PUBLIC ON)
@@ -158,10 +167,10 @@ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_INPUT_TYPE_WEEK PRIVATE ON)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_INTELLIGENT_TRACKING_PREVENTION PRIVATE ON)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_LAYER_BASED_SVG_ENGINE PRIVATE ON)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_LAYOUT_FORMATTING_CONTEXT PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
-WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_RECORDER PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_RECORDER PRIVATE OFF)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_SESSION PRIVATE ON)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_SESSION_PLAYLIST PRIVATE OFF)
-WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_STREAM PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_STREAM PRIVATE ON)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MHTML PRIVATE ON)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MODERN_MEDIA_CONTROLS PRIVATE ON)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_CONTROLS_CONTEXT_MENUS PRIVATE ON)
@@ -171,7 +180,7 @@ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_NETWORK_CACHE_SPECULATIVE_REVALIDATION P
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_NETWORK_CACHE_STALE_WHILE_REVALIDATE PRIVATE ON)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_OFFSCREEN_CANVAS PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_OFFSCREEN_CANVAS_IN_WORKERS PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
-WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_THUNDER PRIVATE ${ENABLE_DEVELOPER_MODE})
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_THUNDER PRIVATE OFF)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_PERIODIC_MEMORY_MONITOR PRIVATE ON)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_POINTER_LOCK PRIVATE ON)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_SERVICE_WORKER PRIVATE ON)
@@ -179,6 +188,15 @@ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_SHAREABLE_RESOURCE PRIVATE 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_CURSOR_VISIBILITY PRIVATE ON)
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_DOWNLOAD_ATTRIBUTE PRIVATE ON)
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_DEVICE_ORIENTATION PRIVATE ON)
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_GAMEPAD PRIVATE ON)
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_SPEECH_SYNTHESIS PRIVATE ON)
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_POINTER_LOCK PRIVATE ON)
+
include(GStreamerDependencies)
# Finalize the value for all options. Do not attempt to use an option before
@@ -280,7 +298,8 @@ if (NOT EXISTS "${TOOLS_DIR}/glib/apply-build-revision-to-files.py")
set(BUILD_REVISION "tarball")
endif ()
-SET_AND_EXPOSE_TO_BUILD(USE_ATSPI ${ENABLE_ACCESSIBILITY})
+SET_AND_EXPOSE_TO_BUILD(USE_ATSPI FALSE)
+
SET_AND_EXPOSE_TO_BUILD(HAVE_GTK_UNIX_PRINTING ${GTK_UNIX_PRINT_FOUND})
SET_AND_EXPOSE_TO_BUILD(HAVE_OS_DARK_MODE_SUPPORT 1)
diff --git a/Source/cmake/OptionsWPE.cmake b/Source/cmake/OptionsWPE.cmake
index 1e87cb5c724113c1e35ac00b23589d08504f7dda..ad6dbfa38182b6107f63b192c8cf9df3db6e6b28 100644
--- a/Source/cmake/OptionsWPE.cmake
+++ b/Source/cmake/OptionsWPE.cmake
@@ -9,8 +9,13 @@ if (${CMAKE_VERSION} VERSION_LESS "3.20" AND NOT ${CMAKE_GENERATOR} STREQUAL "Ni
message(FATAL_ERROR "Building with Makefiles requires CMake 3.20 or newer. Either enable Ninja by passing -GNinja, or upgrade CMake.")
endif ()
+set(ENABLE_WEBKIT_LEGACY OFF)
+
set(USER_AGENT_BRANDING "" CACHE STRING "Branding to add to user agent string")
+set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
+set(THREADS_PREFER_PTHREAD_FLAG TRUE)
+
find_package(Cairo 1.14.0 REQUIRED)
find_package(Fontconfig 2.8.0 REQUIRED)
find_package(Freetype 2.4.2 REQUIRED)
@@ -63,10 +68,10 @@ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_INTELLIGENT_TRACKING_PREVENTION PRIVATE
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_LAYER_BASED_SVG_ENGINE PRIVATE ON)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_LAYOUT_FORMATTING_CONTEXT PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_CONTROLS_CONTEXT_MENUS PRIVATE ON)
-WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_RECORDER PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_RECORDER PRIVATE OFF)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_SESSION PRIVATE ON)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_SESSION_PLAYLIST PRIVATE OFF)
-WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_STREAM PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_STREAM PRIVATE ON)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MHTML PRIVATE ON)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MODERN_MEDIA_CONTROLS PRIVATE ON)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_NETSCAPE_PLUGIN_API PRIVATE OFF)
@@ -77,24 +82,42 @@ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_OFFSCREEN_CANVAS_IN_WORKERS PRIVATE ${EN
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_PERIODIC_MEMORY_MONITOR PRIVATE ON)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_SERVICE_WORKER PRIVATE ON)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_SHAREABLE_RESOURCE PRIVATE ON)
-WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_THUNDER PRIVATE ${ENABLE_DEVELOPER_MODE})
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_THUNDER PRIVATE OFF)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_TOUCH_EVENTS PRIVATE ON)
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_CURSOR_VISIBILITY PRIVATE ON)
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_DARK_MODE_CSS PRIVATE ON)
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_DATALIST_ELEMENT PRIVATE ON)
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_DOWNLOAD_ATTRIBUTE PRIVATE ON)
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_DRAG_SUPPORT PRIVATE ON)
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_DEVICE_ORIENTATION PRIVATE ON)
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_GAMEPAD PRIVATE ON)
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_INPUT_TYPE_COLOR PRIVATE ON)
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_INPUT_TYPE_DATE PRIVATE ON)
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_INPUT_TYPE_DATETIMELOCAL PRIVATE ON)
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_INPUT_TYPE_MONTH PRIVATE ON)
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_INPUT_TYPE_TIME PRIVATE ON)
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_INPUT_TYPE_WEEK PRIVATE ON)
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_SPEECH_SYNTHESIS PRIVATE ON)
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_POINTER_LOCK 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 other WebKit ports.
WEBKIT_OPTION_DEFINE(ENABLE_DOCUMENTATION "Whether to generate documentation." PUBLIC ON)
WEBKIT_OPTION_DEFINE(ENABLE_INTROSPECTION "Whether to enable GObject introspection." PUBLIC ON)
WEBKIT_OPTION_DEFINE(ENABLE_JOURNALD_LOG "Whether to enable journald logging" 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_ANGLE_WEBGL "Whether to use ANGLE as WebGL backend." PUBLIC OFF)
-WEBKIT_OPTION_DEFINE(USE_AVIF "Whether to enable support for AVIF images." PUBLIC ${ENABLE_EXPERIMENTAL_FEATURES})
-WEBKIT_OPTION_DEFINE(USE_JPEGXL "Whether to enable support for JPEG-XL images." PUBLIC ${ENABLE_EXPERIMENTAL_FEATURES})
+WEBKIT_OPTION_DEFINE(USE_AVIF "Whether to enable support for AVIF images." PUBLIC OFF)
+WEBKIT_OPTION_DEFINE(USE_JPEGXL "Whether to enable support for JPEG-XL images." PUBLIC OFF)
WEBKIT_OPTION_DEFINE(USE_LCMS "Whether to enable support for image color management using libcms2." PUBLIC ON)
WEBKIT_OPTION_DEFINE(USE_OPENJPEG "Whether to enable support for JPEG2000 images." PUBLIC ON)
-WEBKIT_OPTION_DEFINE(USE_SOUP2 "Whether to enable usage of Soup 2 instead of Soup 3." PUBLIC OFF)
+WEBKIT_OPTION_DEFINE(USE_SOUP2 "Whether to enable usage of Soup 2 instead of Soup 3." PUBLIC ON)
WEBKIT_OPTION_DEFINE(USE_WOFF2 "Whether to enable support for WOFF2 Web Fonts." PUBLIC ON)
# Private options specific to the WPE port.
@@ -301,7 +324,7 @@ if (NOT EXISTS "${TOOLS_DIR}/glib/apply-build-revision-to-files.py")
endif ()
SET_AND_EXPOSE_TO_BUILD(HAVE_ACCESSIBILITY ${ENABLE_ACCESSIBILITY})
-SET_AND_EXPOSE_TO_BUILD(USE_ATSPI ${ENABLE_ACCESSIBILITY})
+SET_AND_EXPOSE_TO_BUILD(USE_ATSPI FALSE)
SET_AND_EXPOSE_TO_BUILD(USE_CAIRO TRUE)
SET_AND_EXPOSE_TO_BUILD(USE_EGL TRUE)
SET_AND_EXPOSE_TO_BUILD(USE_GCRYPT TRUE)
diff --git a/Source/cmake/OptionsWin.cmake b/Source/cmake/OptionsWin.cmake
index dfc46c968213532914e88e1c65e3f3852f29c2a1..4ae88adbba3f5b37d009aabaaf89652ee1f9d88a 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 ()
@@ -26,11 +27,9 @@ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_CSS_BOX_DECORATION_BREAK PUBLIC ON)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_CSS_SELECTORS_LEVEL4 PUBLIC ON)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_CURSOR_VISIBILITY PUBLIC ON)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_DATALIST_ELEMENT PUBLIC OFF)
-WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_DEVICE_ORIENTATION PUBLIC OFF)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_DRAG_SUPPORT PUBLIC ON)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_FTL_JIT PUBLIC OFF)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_FULLSCREEN_API PUBLIC ON)
-WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_GAMEPAD PUBLIC OFF)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_GEOLOCATION PUBLIC ON)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_INPUT_TYPE_COLOR PUBLIC OFF)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_INPUT_TYPE_DATE PUBLIC OFF)
@@ -46,7 +45,6 @@ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_CONTROLS_SCRIPT PUBLIC ON)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_SOURCE PUBLIC OFF)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_STATISTICS PUBLIC ON)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MOUSE_CURSOR_SCALE PUBLIC ON)
-WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_NOTIFICATIONS PUBLIC OFF)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_VIDEO PUBLIC ON)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEBASSEMBLY PRIVATE OFF)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEB_AUDIO PUBLIC OFF)
@@ -90,6 +88,16 @@ if (${WTF_PLATFORM_WIN_CAIRO})
# No support planned
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_FTPDIR PRIVATE OFF)
+ # Playwright
+ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_CSS_CONIC_GRADIENTS PRIVATE ON)
+ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_DARK_MODE_CSS PRIVATE ON)
+ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_DEVICE_ORIENTATION PRIVATE ON)
+ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_DOWNLOAD_ATTRIBUTE PRIVATE ON)
+ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_GAMEPAD PRIVATE ON)
+ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_NOTIFICATIONS PRIVATE ON)
+ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_POINTER_LOCK PRIVATE ON)
+ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_TOUCH_EVENTS PRIVATE ON)
+
# 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 62b4bc6e91b180abe8ca0f749ce76bf1aba98d4d..23216d79747d514c53e965618d5bf7ade8beb659 100644
--- a/Source/cmake/OptionsWinCairo.cmake
+++ b/Source/cmake/OptionsWinCairo.cmake
@@ -37,20 +37,42 @@ 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
+
set(USE_ANGLE_EGL ON)
set(USE_ANGLE_WEBGL ON)
SET_AND_EXPOSE_TO_BUILD(USE_ANGLE ON)
SET_AND_EXPOSE_TO_BUILD(USE_CAIRO ON)
+SET_AND_EXPOSE_TO_BUILD(USE_CF ON)
SET_AND_EXPOSE_TO_BUILD(USE_CURL ON)
SET_AND_EXPOSE_TO_BUILD(USE_GRAPHICS_LAYER_TEXTURE_MAPPER ON)
SET_AND_EXPOSE_TO_BUILD(USE_GRAPHICS_LAYER_WC ON)
@@ -67,11 +89,7 @@ SET_AND_EXPOSE_TO_BUILD(ENABLE_DEVELOPER_MODE ${DEVELOPER_MODE})
SET_AND_EXPOSE_TO_BUILD(HAVE_OS_DARK_MODE_SUPPORT 1)
-# CoreFoundation is required when building WebKitLegacy
-if (ENABLE_WEBKIT_LEGACY)
- SET_AND_EXPOSE_TO_BUILD(USE_CF ON)
- set(COREFOUNDATION_LIBRARY CFlite)
-endif ()
+set(COREFOUNDATION_LIBRARY CFlite)
add_definitions(-DWTF_PLATFORM_WIN_CAIRO=1)
add_definitions(-DNOCRYPT)
diff --git a/Tools/MiniBrowser/gtk/BrowserTab.c b/Tools/MiniBrowser/gtk/BrowserTab.c
index 1c84f30b2ea96dd0c168918f9d63773b8e2548a3..55603437900a65de7bef70563c9ec0399c5f563c 100644
--- a/Tools/MiniBrowser/gtk/BrowserTab.c
+++ b/Tools/MiniBrowser/gtk/BrowserTab.c
@@ -161,6 +161,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);
@@ -708,6 +713,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);
@@ -758,6 +764,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 881609c9fe8f2b5ed6158a5972438c14fd650cf5..566568382a2983a8a823cf0a0cf2634a9848d607 100644
--- a/Tools/MiniBrowser/gtk/BrowserWindow.c
+++ b/Tools/MiniBrowser/gtk/BrowserWindow.c
@@ -70,7 +70,7 @@ struct _BrowserWindowClass {
GtkApplicationWindowClass parent;
};
-static const char *defaultWindowTitle = "WebKitGTK MiniBrowser";
+static const char *defaultWindowTitle = "🎭 Playwright";
static const gdouble minimumZoomLevel = 0.5;
static const gdouble maximumZoomLevel = 3;
static const gdouble defaultZoomLevel = 1;
@@ -154,13 +154,11 @@ static void webViewURIChanged(WebKitWebView *webView, GParamSpec *pspec, Browser
static void webViewTitleChanged(WebKitWebView *webView, GParamSpec *pspec, BrowserWindow *window)
{
const char *title = webkit_web_view_get_title(webView);
+ char *privateTitle = NULL;
if (!title)
title = defaultWindowTitle;
- char *privateTitle = NULL;
- if (webkit_web_view_is_controlled_by_automation(webView))
- privateTitle = g_strdup_printf("[Automation] %s", title);
- else if (webkit_web_view_is_ephemeral(webView))
- privateTitle = g_strdup_printf("[Private] %s", title);
+ else
+ privateTitle = g_strdup_printf("🎭 Playwright: %s", title);
gtk_window_set_title(GTK_WINDOW(window), privateTitle ? privateTitle : title);
g_free(privateTitle);
}
@@ -493,8 +491,12 @@ static gboolean webViewDecidePolicy(WebKitWebView *webView, WebKitPolicyDecision
return FALSE;
WebKitNavigationAction *navigationAction = webkit_navigation_policy_decision_get_navigation_action(WEBKIT_NAVIGATION_POLICY_DECISION(decision));
- if (webkit_navigation_action_get_navigation_type(navigationAction) != WEBKIT_NAVIGATION_TYPE_LINK_CLICKED
- || webkit_navigation_action_get_mouse_button(navigationAction) != GDK_BUTTON_MIDDLE)
+ if (webkit_navigation_action_get_navigation_type(navigationAction) != WEBKIT_NAVIGATION_TYPE_LINK_CLICKED)
+ return FALSE;
+
+ guint modifiers = webkit_navigation_action_get_modifiers(navigationAction);
+ if (webkit_navigation_action_get_mouse_button(navigationAction) != GDK_BUTTON_MIDDLE &&
+ (webkit_navigation_action_get_mouse_button(navigationAction) != GDK_BUTTON_PRIMARY || (modifiers & (GDK_CONTROL_MASK | GDK_SHIFT_MASK)) == 0))
return FALSE;
/* Multiple tabs are not allowed in editor mode. */
@@ -1445,6 +1447,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);
@@ -1458,6 +1466,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 c3beeba577d32dc32ea5f0fb80cd46ebe118bb34..ed7714a20ab2869d188aa1d30cee49f69e68db86 100644
--- a/Tools/MiniBrowser/gtk/main.c
+++ b/Tools/MiniBrowser/gtk/main.c
@@ -61,7 +61,12 @@ static gboolean enableITP;
static gboolean enableSandbox;
static gboolean exitAfterLoad;
static gboolean webProcessCrashed;
+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
@@ -156,6 +161,10 @@ static const GOptionEntry commandLineOptions[] =
{ "exit-after-load", 0, 0, G_OPTION_ARG_NONE, &exitAfterLoad, "Quit the browser after the load finishes", NULL },
{ "time-zone", 't', 0, G_OPTION_ARG_STRING, &timeZone, "Set time zone", "TIMEZONE" },
{ "version", 'v', 0, G_OPTION_ARG_NONE, &printVersion, "Print the WebKitGTK version", NULL },
+ { "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 }
};
@@ -624,6 +633,57 @@ static void filterSavedCallback(WebKitUserContentFilterStore *store, GAsyncResul
g_main_loop_quit(data->mainLoop);
}
+static WebKitSettings* createPlaywrightSettings() {
+ WebKitSettings* webkitSettings = webkit_settings_new();
+ // Playwright: revert to the default state before https://github.com/WebKit/WebKit/commit/a73a25b9ea9229987c8fa7b2e092e6324cb17913
+ webkit_settings_set_hardware_acceleration_policy(webkitSettings, WEBKIT_HARDWARE_ACCELERATION_POLICY_NEVER);
+ webkit_settings_set_hardware_acceleration_policy(webkitSettings, WEBKIT_HARDWARE_ACCELERATION_POLICY_ON_DEMAND);
+ return webkitSettings;
+}
+
+static WebKitWebContext *persistentWebContext = NULL;
+
+static WebKitWebView *createNewPage(WebKitBrowserInspector *browser_inspector, WebKitWebContext *context)
+{
+ if (context == NULL)
+ context = persistentWebContext;
+
+ WebKitWebView *newWebView = WEBKIT_WEB_VIEW(g_object_new(WEBKIT_TYPE_WEB_VIEW,
+ "web-context", context,
+ "settings", createPlaywrightSettings(),
+ "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[] = {
@@ -654,10 +714,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);
@@ -682,6 +754,7 @@ static void activate(GApplication *application, WebKitSettings *webkitSettings)
#endif
"time-zone-override", timeZone,
NULL);
+ persistentWebContext = webContext;
g_object_unref(manager);
if (enableSandbox)
@@ -763,9 +836,7 @@ static void activate(GApplication *application, WebKitSettings *webkitSettings)
if (exitAfterLoad)
exitAfterWebViewLoadFinishes(webView, application);
}
- gchar *url = argumentToURL(uriArguments[i]);
- webkit_web_view_load_uri(webView, url);
- g_free(url);
+ webkit_web_view_load_uri(webView, uriArguments[i]);
}
} else {
WebKitWebView *webView = createBrowserTab(mainWindow, webkitSettings, userContentManager, defaultWebsitePolicies);
@@ -812,7 +883,7 @@ int main(int argc, char *argv[])
g_option_context_add_group(context, gst_init_get_option_group());
#endif
- WebKitSettings *webkitSettings = webkit_settings_new();
+ WebKitSettings *webkitSettings = createPlaywrightSettings();
webkit_settings_set_enable_developer_extras(webkitSettings, TRUE);
webkit_settings_set_enable_webgl(webkitSettings, TRUE);
webkit_settings_set_enable_media_stream(webkitSettings, TRUE);
@@ -844,9 +915,11 @@ int main(int argc, char *argv[])
}
GtkApplication *application = gtk_application_new("org.webkitgtk.MiniBrowser", G_APPLICATION_NON_UNIQUE);
+ browserApplication = application;
g_signal_connect(application, "startup", G_CALLBACK(startup), NULL);
g_signal_connect(application, "activate", G_CALLBACK(activate), webkitSettings);
g_application_run(G_APPLICATION(application), 0, NULL);
+ browserApplication = NULL;
g_object_unref(application);
return exitAfterLoad && webProcessCrashed ? 1 : 0;
diff --git a/Tools/MiniBrowser/wpe/main.cpp b/Tools/MiniBrowser/wpe/main.cpp
index 38fd6896339c7ca66e5f31ff6ad93cc0f330f7e5..f154e7e7da2f03f4a34e6e329ad5f38a33690b57 100644
--- a/Tools/MiniBrowser/wpe/main.cpp
+++ b/Tools/MiniBrowser/wpe/main.cpp
@@ -45,6 +45,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;
@@ -70,6 +73,9 @@ static const GOptionEntry commandLineOptions[] =
{ "enable-itp", 0, 0, G_OPTION_ARG_NONE, &enableITP, "Enable Intelligent Tracking Prevention (ITP)", nullptr },
{ "time-zone", 't', 0, G_OPTION_ARG_STRING, &timeZone, "Set time zone", "TIMEZONE" },
{ "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 }
};
@@ -154,13 +160,36 @@ 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 gboolean webViewDecidePolicy(WebKitWebView *webView, WebKitPolicyDecision *decision, WebKitPolicyDecisionType decisionType, gpointer);
+
+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();
@@ -172,17 +201,88 @@ 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, "decide-policy", G_CALLBACK(webViewDecidePolicy), nullptr);
return newWebView;
}
+static WebKitWebView* createWebView(WebKitWebView* webView, WebKitNavigationAction*, gpointer)
+{
+ return createWebViewImpl(webView, nullptr);
+}
+
+static gboolean webViewDecidePolicy(WebKitWebView *webView, WebKitPolicyDecision *decision, WebKitPolicyDecisionType decisionType, gpointer)
+{
+ if (decisionType != WEBKIT_POLICY_DECISION_TYPE_NAVIGATION_ACTION)
+ return FALSE;
+
+ WebKitNavigationAction *navigationAction = webkit_navigation_policy_decision_get_navigation_action(WEBKIT_NAVIGATION_POLICY_DECISION(decision));
+ if (webkit_navigation_action_get_navigation_type(navigationAction) != WEBKIT_NAVIGATION_TYPE_LINK_CLICKED)
+ return FALSE;
+
+ guint modifiers = webkit_navigation_action_get_modifiers(navigationAction);
+ if (webkit_navigation_action_get_mouse_button(navigationAction) != 2 /* GDK_BUTTON_MIDDLE */ &&
+ (webkit_navigation_action_get_mouse_button(navigationAction) != 1 /* GDK_BUTTON_PRIMARY */ || (modifiers & (wpe_input_keyboard_modifier_control | wpe_input_keyboard_modifier_shift)) == 0))
+ return FALSE;
+
+ /* Open a new tab if link clicked with the middle button, shift+click or ctrl+click. */
+ WebKitWebView* newWebView = createWebViewImpl(nullptr, webkit_web_view_get_context(webView));
+ webkit_web_view_load_request(newWebView, webkit_navigation_action_get_request(navigationAction));
+
+ webkit_policy_decision_ignore(decision);
+ return TRUE;
+}
+
+static WebKitWebContext *persistentWebContext = NULL;
+
+static WebKitWebView* createNewPage(WebKitBrowserInspector*, WebKitWebContext *webContext)
+{
+ if (!webContext)
+ webContext = persistentWebContext;
+ WebKitWebView* webView = createWebViewImpl(nullptr, webContext);
+ 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
@@ -218,6 +318,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();
@@ -227,7 +337,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) {
@@ -240,6 +358,7 @@ int main(int argc, char *argv[])
webkit_website_data_manager_set_tls_errors_policy(manager, WEBKIT_TLS_ERRORS_POLICY_IGNORE);
auto* webContext = WEBKIT_WEB_CONTEXT(g_object_new(WEBKIT_TYPE_WEB_CONTEXT, "website-data-manager", manager, "time-zone-override", timeZone, nullptr));
+ persistentWebContext = webContext;
g_object_unref(manager);
if (cookiesPolicy) {
@@ -298,7 +417,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,
@@ -315,8 +441,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);
@@ -329,16 +453,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");
@@ -348,8 +465,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 b4e8c0496caa9912bf9b7e0d9a8db03161b70e7c..12954131704cb3a3b8ccfe15c60c3919067d72a9 100755
--- a/Tools/Scripts/build-webkit
+++ b/Tools/Scripts/build-webkit
@@ -256,7 +256,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/InjectedBundle/empty/AccessibilityControllerEmpty.cpp b/Tools/WebKitTestRunner/InjectedBundle/empty/AccessibilityControllerEmpty.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3618075f10824beb0bc6cd8070772ab88f4e51c8
--- /dev/null
+++ b/Tools/WebKitTestRunner/InjectedBundle/empty/AccessibilityControllerEmpty.cpp
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2022 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"
+
+#if !USE(ATSPI) && !USE(ATK)
+
+#include "AccessibilityController.h"
+#include "AccessibilityUIElement.h"
+#include <WebCore/NotImplemented.h>
+
+namespace WTR {
+
+void AccessibilityController::resetToConsistentState()
+{
+ notImplemented();
+}
+
+RefPtr<AccessibilityUIElement> AccessibilityController::accessibleElementById(JSStringRef id)
+{
+ notImplemented();
+ return nullptr;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityController::platformName()
+{
+ notImplemented();
+ return nullptr;
+}
+
+void AccessibilityController::injectAccessibilityPreference(JSStringRef domain, JSStringRef key, JSStringRef value)
+{
+ notImplemented();
+}
+
+Ref<AccessibilityUIElement> AccessibilityController::rootElement()
+{
+ notImplemented();
+ return AccessibilityUIElement::create(nullptr);
+}
+
+RefPtr<AccessibilityUIElement> AccessibilityController::focusedElement()
+{
+ notImplemented();
+ return nullptr;
+}
+
+bool AccessibilityController::addNotificationListener(JSValueRef)
+{
+ notImplemented();
+ return false;
+}
+
+bool AccessibilityController::removeNotificationListener()
+{
+ notImplemented();
+ return false;
+}
+
+} // namespace WTR
+
+#endif // USE(ATSPI)
diff --git a/Tools/WebKitTestRunner/InjectedBundle/empty/AccessibilityUIElementEmpty.cpp b/Tools/WebKitTestRunner/InjectedBundle/empty/AccessibilityUIElementEmpty.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..fb739f862252dcdda61aa08e8e4861f8ba06d76c
--- /dev/null
+++ b/Tools/WebKitTestRunner/InjectedBundle/empty/AccessibilityUIElementEmpty.cpp
@@ -0,0 +1,1044 @@
+/*
+ * Copyright (C) 2022 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 "AccessibilityUIElement.h"
+
+#if !USE(ATSPI) && !USE(ATK)
+
+#include <WebCore/NotImplemented.h>
+
+namespace WTR {
+
+AccessibilityUIElement::AccessibilityUIElement(PlatformUIElement)
+{
+ notImplemented();
+}
+
+AccessibilityUIElement::AccessibilityUIElement(const AccessibilityUIElement&)
+{
+ notImplemented();
+}
+
+AccessibilityUIElement::~AccessibilityUIElement()
+{
+ notImplemented();
+}
+
+bool AccessibilityUIElement::isEqual(AccessibilityUIElement*)
+{
+ notImplemented();
+ return false;
+}
+
+void AccessibilityUIElement::getChildren(Vector<RefPtr<AccessibilityUIElement>>&)
+{
+ notImplemented();
+}
+
+void AccessibilityUIElement::getChildrenWithRange(Vector<RefPtr<AccessibilityUIElement>>&, unsigned, unsigned)
+{
+ notImplemented();
+}
+
+int AccessibilityUIElement::childrenCount()
+{
+ notImplemented();
+ return 0;
+}
+
+RefPtr<AccessibilityUIElement> AccessibilityUIElement::elementAtPoint(int, int)
+{
+ notImplemented();
+ return nullptr;
+}
+
+unsigned AccessibilityUIElement::indexOfChild(AccessibilityUIElement*)
+{
+ notImplemented();
+ return 0;
+}
+
+
+RefPtr<AccessibilityUIElement> AccessibilityUIElement::childAtIndex(unsigned)
+{
+ notImplemented();
+ return nullptr;
+}
+
+RefPtr<AccessibilityUIElement> AccessibilityUIElement::linkedUIElementAtIndex(unsigned)
+{
+ notImplemented();
+ return nullptr;
+}
+
+RefPtr<AccessibilityUIElement> AccessibilityUIElement::ariaOwnsElementAtIndex(unsigned)
+{
+ notImplemented();
+ return nullptr;
+}
+
+RefPtr<AccessibilityUIElement> AccessibilityUIElement::ariaFlowToElementAtIndex(unsigned)
+{
+ notImplemented();
+ return nullptr;
+}
+
+RefPtr<AccessibilityUIElement> AccessibilityUIElement::ariaControlsElementAtIndex(unsigned)
+{
+ notImplemented();
+ return nullptr;
+}
+
+RefPtr<AccessibilityUIElement> AccessibilityUIElement::disclosedRowAtIndex(unsigned)
+{
+ notImplemented();
+ return nullptr;
+}
+
+RefPtr<AccessibilityUIElement> AccessibilityUIElement::rowAtIndex(unsigned)
+{
+ notImplemented();
+ return nullptr;
+}
+
+RefPtr<AccessibilityUIElement> AccessibilityUIElement::selectedChildAtIndex(unsigned) const
+{
+ notImplemented();
+ return nullptr;
+}
+
+unsigned AccessibilityUIElement::selectedChildrenCount() const
+{
+ notImplemented();
+ return 0;
+}
+
+RefPtr<AccessibilityUIElement> AccessibilityUIElement::selectedRowAtIndex(unsigned)
+{
+ notImplemented();
+ return nullptr;
+}
+
+RefPtr<AccessibilityUIElement> AccessibilityUIElement::titleUIElement()
+{
+ notImplemented();
+ return nullptr;
+}
+
+RefPtr<AccessibilityUIElement> AccessibilityUIElement::parentElement()
+{
+ notImplemented();
+ return nullptr;
+}
+
+RefPtr<AccessibilityUIElement> AccessibilityUIElement::disclosedByRow()
+{
+ notImplemented();
+ return nullptr;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfLinkedUIElements()
+{
+ notImplemented();
+ return nullptr;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfDocumentLinks()
+{
+ notImplemented();
+ return nullptr;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfChildren()
+{
+ notImplemented();
+ return nullptr;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::allAttributes()
+{
+ notImplemented();
+ return nullptr;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::stringAttributeValue(JSStringRef)
+{
+ notImplemented();
+ return nullptr;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::currentStateValue() const
+{
+ notImplemented();
+ return nullptr;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::stringDescriptionOfAttributeValue(JSStringRef)
+{
+ notImplemented();
+ return nullptr;
+}
+
+double AccessibilityUIElement::numberAttributeValue(JSStringRef attribute)
+{
+ notImplemented();
+ return 0;
+}
+
+JSValueRef AccessibilityUIElement::uiElementArrayAttributeValue(JSStringRef attribute) const
+{
+ notImplemented();
+ return nullptr;
+}
+
+JSValueRef AccessibilityUIElement::rowHeaders() const
+{
+ notImplemented();
+ return nullptr;
+}
+
+JSValueRef AccessibilityUIElement::columnHeaders() const
+{
+ notImplemented();
+ return nullptr;
+}
+
+RefPtr<AccessibilityUIElement> AccessibilityUIElement::uiElementAttributeValue(JSStringRef attribute) const
+{
+ notImplemented();
+ return nullptr;
+}
+
+bool AccessibilityUIElement::boolAttributeValue(JSStringRef attribute)
+{
+ notImplemented();
+ return false;
+}
+
+bool AccessibilityUIElement::isAttributeSettable(JSStringRef attribute)
+{
+ notImplemented();
+ return false;
+}
+
+bool AccessibilityUIElement::isAttributeSupported(JSStringRef attribute)
+{
+ notImplemented();
+ return false;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::parameterizedAttributeNames()
+{
+ notImplemented();
+ return nullptr;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::role()
+{
+ notImplemented();
+ return nullptr;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::subrole()
+{
+ notImplemented();
+ return nullptr;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::roleDescription()
+{
+ notImplemented();
+ return nullptr;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::computedRoleString()
+{
+ notImplemented();
+ return nullptr;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::title()
+{
+ notImplemented();
+ return nullptr;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::description()
+{
+ notImplemented();
+ return nullptr;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::orientation() const
+{
+ notImplemented();
+ return nullptr;
+}
+
+bool AccessibilityUIElement::isAtomicLiveRegion() const
+{
+ notImplemented();
+ return false;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::liveRegionRelevant() const
+{
+ notImplemented();
+ return nullptr;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::liveRegionStatus() const
+{
+ notImplemented();
+ return nullptr;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::stringValue()
+{
+ notImplemented();
+ return nullptr;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::language()
+{
+ notImplemented();
+ return nullptr;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::helpText() const
+{
+ notImplemented();
+ return nullptr;
+}
+
+double AccessibilityUIElement::x()
+{
+ notImplemented();
+ return 0;
+}
+
+double AccessibilityUIElement::y()
+{
+ notImplemented();
+ return 0;
+}
+
+double AccessibilityUIElement::width()
+{
+ notImplemented();
+ return 0;
+}
+
+double AccessibilityUIElement::height()
+{
+ notImplemented();
+ return 0;
+}
+
+double AccessibilityUIElement::clickPointX()
+{
+ notImplemented();
+ return 0;
+}
+
+double AccessibilityUIElement::clickPointY()
+{
+ notImplemented();
+ return 0;
+}
+
+double AccessibilityUIElement::intValue() const
+{
+ notImplemented();
+ return 0;
+}
+
+double AccessibilityUIElement::minValue()
+{
+ notImplemented();
+ return 0;
+}
+
+double AccessibilityUIElement::maxValue()
+{
+ notImplemented();
+ return 0;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::valueDescription()
+{
+ notImplemented();
+ return nullptr;
+}
+
+int AccessibilityUIElement::insertionPointLineNumber()
+{
+ notImplemented();
+ return 0;
+}
+
+bool AccessibilityUIElement::isPressActionSupported()
+{
+ notImplemented();
+ return false;
+}
+
+bool AccessibilityUIElement::isIncrementActionSupported()
+{
+ notImplemented();
+ return false;
+}
+
+bool AccessibilityUIElement::isDecrementActionSupported()
+{
+ notImplemented();
+ return false;
+}
+
+bool AccessibilityUIElement::isBusy() const
+{
+ notImplemented();
+ return false;
+}
+
+bool AccessibilityUIElement::isEnabled()
+{
+ notImplemented();
+ return false;
+}
+
+bool AccessibilityUIElement::isRequired() const
+{
+ notImplemented();
+ return false;
+}
+
+bool AccessibilityUIElement::isFocused() const
+{
+ notImplemented();
+ return false;
+}
+
+bool AccessibilityUIElement::isSelected() const
+{
+ notImplemented();
+ return false;
+}
+
+bool AccessibilityUIElement::isSelectedOptionActive() const
+{
+ notImplemented();
+ return false;
+}
+
+bool AccessibilityUIElement::isExpanded() const
+{
+ notImplemented();
+ return false;
+}
+
+bool AccessibilityUIElement::isChecked() const
+{
+ notImplemented();
+ return false;
+}
+
+bool AccessibilityUIElement::isIndeterminate() const
+{
+ notImplemented();
+ return false;
+}
+
+int AccessibilityUIElement::hierarchicalLevel() const
+{
+ notImplemented();
+ return 0;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::speakAs()
+{
+ notImplemented();
+ return nullptr;
+}
+
+bool AccessibilityUIElement::ariaIsGrabbed() const
+{
+ notImplemented();
+ return false;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::ariaDropEffects() const
+{
+ notImplemented();
+ return nullptr;
+}
+
+int AccessibilityUIElement::lineForIndex(int)
+{
+ notImplemented();
+ return 0;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::rangeForLine(int)
+{
+ notImplemented();
+ return nullptr;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::rangeForPosition(int, int)
+{
+ notImplemented();
+ return nullptr;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::boundsForRange(unsigned, unsigned)
+{
+ notImplemented();
+ return nullptr;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::stringForRange(unsigned, unsigned)
+{
+ notImplemented();
+ return nullptr;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::attributedStringForRange(unsigned, unsigned)
+{
+ notImplemented();
+ return nullptr;
+}
+
+bool AccessibilityUIElement::attributedStringRangeIsMisspelled(unsigned, unsigned)
+{
+ notImplemented();
+ return false;
+}
+
+unsigned AccessibilityUIElement::uiElementCountForSearchPredicate(JSContextRef, AccessibilityUIElement*, bool, JSValueRef, JSStringRef, bool, bool)
+{
+ notImplemented();
+ return 0;
+}
+
+RefPtr<AccessibilityUIElement> AccessibilityUIElement::uiElementForSearchPredicate(JSContextRef, AccessibilityUIElement*, bool, JSValueRef, JSStringRef, bool, bool)
+{
+ notImplemented();
+ return nullptr;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::selectTextWithCriteria(JSContextRef, JSStringRef, JSValueRef, JSStringRef, JSStringRef)
+{
+ notImplemented();
+ return nullptr;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfColumnHeaders()
+{
+ notImplemented();
+ return nullptr;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfRowHeaders()
+{
+ notImplemented();
+ return nullptr;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfColumns()
+{
+ notImplemented();
+ return nullptr;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfRows()
+{
+ notImplemented();
+ return nullptr;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfVisibleCells()
+{
+ notImplemented();
+ return nullptr;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfHeader()
+{
+ notImplemented();
+ return nullptr;
+}
+
+int AccessibilityUIElement::rowCount()
+{
+ notImplemented();
+ return 0;
+}
+
+int AccessibilityUIElement::columnCount()
+{
+ notImplemented();
+ return 0;
+}
+
+int AccessibilityUIElement::indexInTable()
+{
+ notImplemented();
+ return 0;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::rowIndexRange()
+{
+ notImplemented();
+ return nullptr;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::columnIndexRange()
+{
+ notImplemented();
+ return nullptr;
+}
+
+RefPtr<AccessibilityUIElement> AccessibilityUIElement::cellForColumnAndRow(unsigned, unsigned)
+{
+ notImplemented();
+ return nullptr;
+}
+
+RefPtr<AccessibilityUIElement> AccessibilityUIElement::horizontalScrollbar() const
+{
+ notImplemented();
+ return nullptr;
+}
+
+RefPtr<AccessibilityUIElement> AccessibilityUIElement::verticalScrollbar() const
+{
+ notImplemented();
+ return nullptr;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::selectedTextRange()
+{
+ notImplemented();
+ return nullptr;
+}
+
+bool AccessibilityUIElement::setSelectedTextRange(unsigned, unsigned)
+{
+ notImplemented();
+ return false;
+}
+
+void AccessibilityUIElement::increment()
+{
+ notImplemented();
+}
+
+void AccessibilityUIElement::decrement()
+{
+ notImplemented();
+}
+
+void AccessibilityUIElement::showMenu()
+{
+ notImplemented();
+}
+
+void AccessibilityUIElement::press()
+{
+ notImplemented();
+}
+
+void AccessibilityUIElement::setSelectedChild(AccessibilityUIElement* element) const
+{
+ notImplemented();
+}
+
+void AccessibilityUIElement::setSelectedChildAtIndex(unsigned index) const
+{
+ notImplemented();
+}
+
+void AccessibilityUIElement::removeSelectionAtIndex(unsigned index) const
+{
+ notImplemented();
+}
+
+void AccessibilityUIElement::clearSelectedChildren() const
+{
+ notImplemented();
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::accessibilityValue() const
+{
+ notImplemented();
+ return nullptr;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::documentEncoding()
+{
+ notImplemented();
+ return nullptr;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::documentURI()
+{
+ notImplemented();
+ return nullptr;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::url()
+{
+ notImplemented();
+ return nullptr;
+}
+
+bool AccessibilityUIElement::addNotificationListener(JSValueRef functionCallback)
+{
+ notImplemented();
+ return false;
+}
+
+bool AccessibilityUIElement::removeNotificationListener()
+{
+ notImplemented();
+ return false;
+}
+
+bool AccessibilityUIElement::isFocusable() const
+{
+ notImplemented();
+ return false;
+}
+
+bool AccessibilityUIElement::isSelectable() const
+{
+ notImplemented();
+ return false;
+}
+
+bool AccessibilityUIElement::isMultiSelectable() const
+{
+ notImplemented();
+ return false;
+}
+
+bool AccessibilityUIElement::isVisible() const
+{
+ notImplemented();
+ return false;
+}
+
+bool AccessibilityUIElement::isOffScreen() const
+{
+ notImplemented();
+ return false;
+}
+
+bool AccessibilityUIElement::isCollapsed() const
+{
+ notImplemented();
+ return false;
+}
+
+bool AccessibilityUIElement::isIgnored() const
+{
+ notImplemented();
+ return false;
+}
+
+bool AccessibilityUIElement::isSingleLine() const
+{
+ notImplemented();
+ return false;
+}
+
+bool AccessibilityUIElement::isMultiLine() const
+{
+ notImplemented();
+ return false;
+}
+
+bool AccessibilityUIElement::hasPopup() const
+{
+ notImplemented();
+ return false;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::popupValue() const
+{
+ notImplemented();
+ return nullptr;
+}
+
+void AccessibilityUIElement::takeFocus()
+{
+ notImplemented();
+}
+
+void AccessibilityUIElement::takeSelection()
+{
+ notImplemented();
+}
+
+void AccessibilityUIElement::addSelection()
+{
+ notImplemented();
+}
+
+void AccessibilityUIElement::removeSelection()
+{
+ notImplemented();
+}
+
+RefPtr<AccessibilityTextMarkerRange> AccessibilityUIElement::lineTextMarkerRangeForTextMarker(AccessibilityTextMarker*)
+{
+ notImplemented();
+ return nullptr;
+}
+
+RefPtr<AccessibilityTextMarkerRange> AccessibilityUIElement::textMarkerRangeForElement(AccessibilityUIElement*)
+{
+ notImplemented();
+ return nullptr;
+}
+
+int AccessibilityUIElement::textMarkerRangeLength(AccessibilityTextMarkerRange*)
+{
+ notImplemented();
+ return 0;
+}
+
+RefPtr<AccessibilityTextMarker> AccessibilityUIElement::previousTextMarker(AccessibilityTextMarker*)
+{
+ notImplemented();
+ return nullptr;
+}
+
+RefPtr<AccessibilityTextMarker> AccessibilityUIElement::nextTextMarker(AccessibilityTextMarker*)
+{
+ notImplemented();
+ return nullptr;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::rectsForTextMarkerRange(AccessibilityTextMarkerRange*, JSStringRef)
+{
+ notImplemented();
+ return nullptr;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::stringForTextMarkerRange(AccessibilityTextMarkerRange*)
+{
+ notImplemented();
+ return nullptr;
+}
+
+RefPtr<AccessibilityTextMarkerRange> AccessibilityUIElement::textMarkerRangeForMarkers(AccessibilityTextMarker*, AccessibilityTextMarker*)
+{
+ notImplemented();
+ return nullptr;
+}
+
+RefPtr<AccessibilityTextMarker> AccessibilityUIElement::startTextMarkerForTextMarkerRange(AccessibilityTextMarkerRange*)
+{
+ notImplemented();
+ return nullptr;
+}
+
+RefPtr<AccessibilityTextMarker> AccessibilityUIElement::endTextMarkerForTextMarkerRange(AccessibilityTextMarkerRange*)
+{
+ notImplemented();
+ return nullptr;
+}
+
+RefPtr<AccessibilityTextMarker> AccessibilityUIElement::endTextMarkerForBounds(int, int, int, int)
+{
+ notImplemented();
+ return nullptr;
+}
+
+RefPtr<AccessibilityTextMarker> AccessibilityUIElement::startTextMarkerForBounds(int, int, int, int)
+{
+ notImplemented();
+ return nullptr;
+}
+
+RefPtr<AccessibilityTextMarker> AccessibilityUIElement::textMarkerForPoint(int, int)
+{
+ notImplemented();
+ return nullptr;
+}
+
+RefPtr<AccessibilityUIElement> AccessibilityUIElement::accessibilityElementForTextMarker(AccessibilityTextMarker*)
+{
+ notImplemented();
+ return nullptr;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::attributedStringForTextMarkerRange(AccessibilityTextMarkerRange*)
+{
+ notImplemented();
+ return nullptr;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::attributedStringForTextMarkerRangeWithOptions(AccessibilityTextMarkerRange*, bool)
+{
+ notImplemented();
+ return nullptr;
+}
+
+bool AccessibilityUIElement::attributedStringForTextMarkerRangeContainsAttribute(JSStringRef, AccessibilityTextMarkerRange*)
+{
+ notImplemented();
+ return false;
+}
+
+int AccessibilityUIElement::indexForTextMarker(AccessibilityTextMarker*)
+{
+ notImplemented();
+ return 0;
+}
+
+bool AccessibilityUIElement::isTextMarkerValid(AccessibilityTextMarker*)
+{
+ notImplemented();
+ return false;
+}
+
+RefPtr<AccessibilityTextMarker> AccessibilityUIElement::textMarkerForIndex(int)
+{
+ notImplemented();
+ return nullptr;
+}
+
+RefPtr<AccessibilityTextMarker> AccessibilityUIElement::startTextMarker()
+{
+ notImplemented();
+ return nullptr;
+}
+
+RefPtr<AccessibilityTextMarker> AccessibilityUIElement::endTextMarker()
+{
+ notImplemented();
+ return nullptr;
+}
+
+bool AccessibilityUIElement::setSelectedTextMarkerRange(AccessibilityTextMarkerRange*)
+{
+ notImplemented();
+ return false;
+}
+
+void AccessibilityUIElement::scrollToMakeVisible()
+{
+ notImplemented();
+}
+
+void AccessibilityUIElement::scrollToGlobalPoint(int, int)
+{
+ notImplemented();
+}
+
+void AccessibilityUIElement::scrollToMakeVisibleWithSubFocus(int, int, int, int)
+{
+ notImplemented();
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::supportedActions() const
+{
+ notImplemented();
+ return nullptr;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::pathDescription() const
+{
+ notImplemented();
+ return nullptr;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::mathPostscriptsDescription() const
+{
+ notImplemented();
+ return nullptr;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::mathPrescriptsDescription() const
+{
+ notImplemented();
+ return nullptr;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::classList() const
+{
+ notImplemented();
+ return nullptr;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::characterAtOffset(int)
+{
+ notImplemented();
+ return nullptr;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::wordAtOffset(int)
+{
+ notImplemented();
+ return nullptr;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::lineAtOffset(int)
+{
+ notImplemented();
+ return nullptr;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::sentenceAtOffset(int)
+{
+ notImplemented();
+ return nullptr;
+}
+
+bool AccessibilityUIElement::replaceTextInRange(JSStringRef, int, int)
+{
+ notImplemented();
+ return false;
+}
+
+bool AccessibilityUIElement::insertText(JSStringRef)
+{
+ notImplemented();
+ return false;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::domIdentifier() const
+{
+ notImplemented();
+ return nullptr;
+}
+
+} // namespace WTF
+
+#endif // !USE(ATSPI) && !USE(ATK)
diff --git a/Tools/WebKitTestRunner/PlatformGTK.cmake b/Tools/WebKitTestRunner/PlatformGTK.cmake
index 8e434fbb2d6c04528922d50b3e1dd36bf945557e..35231da4eb73a9d99e004b3e1d649fc9fa30ec6f 100644
--- a/Tools/WebKitTestRunner/PlatformGTK.cmake
+++ b/Tools/WebKitTestRunner/PlatformGTK.cmake
@@ -25,6 +25,7 @@ list(APPEND WebKitTestRunner_LIBRARIES
${GLIB_LIBRARIES}
Cairo::Cairo
GTK::GTK
+ stdc++fs
)
list(APPEND WebKitTestRunnerInjectedBundle_LIBRARIES
@@ -38,6 +39,9 @@ list(APPEND WebKitTestRunnerInjectedBundle_SOURCES
InjectedBundle/atspi/AccessibilityNotificationHandler.cpp
InjectedBundle/atspi/AccessibilityUIElementAtspi.cpp
+ InjectedBundle/empty/AccessibilityControllerEmpty.cpp
+ InjectedBundle/empty/AccessibilityUIElementEmpty.cpp
+
InjectedBundle/gtk/ActivateFontsGtk.cpp
InjectedBundle/gtk/InjectedBundleGtk.cpp
InjectedBundle/gtk/InjectedBundleUtilities.cpp
diff --git a/Tools/WebKitTestRunner/PlatformWPE.cmake b/Tools/WebKitTestRunner/PlatformWPE.cmake
index 4f3640a8b93897d69604ee8ba38cd07561720ad2..00b657a8a585d104afc346dc1126fb718564be3e 100644
--- a/Tools/WebKitTestRunner/PlatformWPE.cmake
+++ b/Tools/WebKitTestRunner/PlatformWPE.cmake
@@ -30,6 +30,7 @@ list(APPEND WebKitTestRunner_LIBRARIES
${WPEBACKEND_FDO_LIBRARIES}
Cairo::Cairo
WebKit::WPEToolingBackends
+ stdc++fs
)
list(APPEND WebKitTestRunnerInjectedBundle_LIBRARIES
@@ -43,6 +44,9 @@ list(APPEND WebKitTestRunnerInjectedBundle_SOURCES
InjectedBundle/atspi/AccessibilityNotificationHandler.cpp
InjectedBundle/atspi/AccessibilityUIElementAtspi.cpp
+ InjectedBundle/empty/AccessibilityControllerEmpty.cpp
+ InjectedBundle/empty/AccessibilityUIElementEmpty.cpp
+
InjectedBundle/wpe/ActivateFontsWPE.cpp
InjectedBundle/wpe/InjectedBundleWPE.cpp
InjectedBundle/wpe/TestRunnerWPE.cpp
diff --git a/Tools/WebKitTestRunner/TestController.cpp b/Tools/WebKitTestRunner/TestController.cpp
index 0ca9c821eda81adfdeab20e652e3b5003eefa423..9e64e6f9d94726ac63d5edfbf7c6f1871b6aa6c8 100644
--- a/Tools/WebKitTestRunner/TestController.cpp
+++ b/Tools/WebKitTestRunner/TestController.cpp
@@ -874,6 +874,7 @@ void TestController::createWebViewWithOptions(const TestOptions& options)
0, // requestStorageAccessConfirm
shouldAllowDeviceOrientationAndMotionAccess,
runWebAuthenticationPanel,
+ 0, // handleJavaScriptDialog
decidePolicyForSpeechRecognitionPermissionRequest,
decidePolicyForMediaKeySystemPermissionRequest,
nullptr, // requestWebAuthenticationNoGesture
diff --git a/Tools/WebKitTestRunner/mac/EventSenderProxy.mm b/Tools/WebKitTestRunner/mac/EventSenderProxy.mm
index b0a503013185f29feeca47e4313b27e349973c02..ee1f87780a99b2b626b1ada984d6310975076019 100644
--- a/Tools/WebKitTestRunner/mac/EventSenderProxy.mm
+++ b/Tools/WebKitTestRunner/mac/EventSenderProxy.mm
@@ -896,4 +896,51 @@ void EventSenderProxy::scaleGestureEnd(double scale)
#endif // ENABLE(MAC_GESTURE_EVENTS)
+#if ENABLE(TOUCH_EVENTS)
+void EventSenderProxy::addTouchPoint(int, int)
+{
+}
+
+void EventSenderProxy::updateTouchPoint(int, int, int)
+{
+}
+
+void EventSenderProxy::touchStart()
+{
+}
+
+void EventSenderProxy::touchMove()
+{
+}
+
+void EventSenderProxy::touchEnd()
+{
+}
+
+void EventSenderProxy::touchCancel()
+{
+}
+
+void EventSenderProxy::clearTouchPoints()
+{
+}
+
+void EventSenderProxy::releaseTouchPoint(int)
+{
+}
+
+void EventSenderProxy::cancelTouchPoint(int)
+{
+}
+
+void EventSenderProxy::setTouchPointRadius(int, int)
+{
+}
+
+void EventSenderProxy::setTouchModifier(WKEventModifiers, bool)
+{
+}
+#endif // ENABLE(TOUCH_EVENTS)
+
+
} // namespace WTR
diff --git a/Tools/glib/dependencies/apt b/Tools/glib/dependencies/apt
index dbf1d28ab1e501e26af3a188465267e3b1d521a6..23df2162e3eb12b4e974100d966d5cab67dd071c 100644
--- a/Tools/glib/dependencies/apt
+++ b/Tools/glib/dependencies/apt
@@ -56,9 +56,11 @@ PACKAGES=(
libwayland-dev
libwebp-dev
libwoff-dev
+ libxcb-glx0-dev
libxslt1-dev
ninja-build
patch
+ patchelf
ruby
# These are dependencies necessary for running tests.
diff --git a/Tools/gtk/jhbuild.modules b/Tools/gtk/jhbuild.modules
index 3eb911ba48eca35de2de9ee671cb577a0a96ec27..916b45a541486e59380d66b524a004a77d955ed8 100644
--- a/Tools/gtk/jhbuild.modules
+++ b/Tools/gtk/jhbuild.modules
@@ -295,28 +295,28 @@
</autotools>
<meson id="atk" mesonargs="-Dintrospection=false">
- <branch module="/sources/atk/2.34/atk-${version}.tar.xz" version="2.34.1"
+ <branch module="/sources/atk/2.38/atk-${version}.tar.xz" version="2.38.0"
repo="download.gnome.org"
- hash="sha256:d4f0e3b3d21265fcf2bc371e117da51c42ede1a71f6db1c834e6976bb20997cb"/>
+ hash="sha256:ac4de2a4ef4bd5665052952fe169657e65e895c5057dffb3c2a810f6191a0c36"/>
<dependencies>
<dep package="glib"/>
</dependencies>
</meson>
<meson id="at-spi2-core" mesonargs="-Dintrospection=no -Dx11=no">
- <branch module="/sources/at-spi2-core/2.34/at-spi2-core-${version}.tar.xz" version="2.34.0"
+ <branch module="/sources/at-spi2-core/2.44/at-spi2-core-${version}.tar.xz" version="2.44.1"
repo="download.gnome.org"
- hash="sha256:d629cdbd674e539f8912028512af583990938c7b49e25184c126b00121ef11c6">
+ hash="sha256:4beb23270ba6cf7caf20b597354d75194d89afb69d2efcf15f4271688ba6f746">
</branch>
<dependencies>
<dep package="glib"/>
</dependencies>
</meson>
- <meson id="at-spi2-atk" mesonargs="-Dintrospection=no">
- <branch module="/sources/at-spi2-atk/2.34/at-spi2-atk-${version}.tar.xz" version="2.34.0"
+ <meson id="at-spi2-atk" mesonargs="">
+ <branch module="/sources/at-spi2-atk/2.38/at-spi2-atk-${version}.tar.xz" version="2.38.0"
repo="download.gnome.org"
- hash="sha256:3a9a7e96a1eb549529e60a42201dd78ccce413d9c1706e16351cc5288e064500">
+ hash="sha256:cfa008a5af822b36ae6287f18182c40c91dd699c55faa38605881ed175ca464f">
</branch>
<dependencies>
<dep package="glib"/>
diff --git a/Tools/jhbuild/jhbuild-minimal.modules b/Tools/jhbuild/jhbuild-minimal.modules
index a08c829f49b43d494a09c40f71606735c172b6a5..49403c27d67b40e5ae0fb4cf294d835cfdaf37c6 100644
--- a/Tools/jhbuild/jhbuild-minimal.modules
+++ b/Tools/jhbuild/jhbuild-minimal.modules
@@ -22,7 +22,6 @@
<dep package="wpebackend-fdo"/>
<dep package="icu"/>
<dep package="libsoup"/>
- <dep package="openxr"/>
<dep package="libvpx"/>
<dep package="glib"/>
<dep package="glib-networking"/>
@@ -135,13 +134,13 @@
hash="sha256:4fe0a4bed6b4c3ae7249d341031c27b32f8d9e0ffb5337d71cbcec7160362cf7"/>
</meson>
- <!-- meson 0.50.1 required to build libsoup 2.69 -->
+ <!-- meson 0.56.2+ required to build atk 2.38 -->
<distutils id="meson" python3="1">
<branch repo="github-tarball"
- version="0.50.1"
+ version="0.61.5"
module="mesonbuild/meson/releases/download/${version}/meson-${version}.tar.gz"
checkoutdir="meson-${version}"
- hash="sha256:f68f56d60c80a77df8fc08fa1016bc5831605d4717b622c96212573271e14ecc"/>
+ hash="sha256:5e9a0d65c1a51936362b9686d1c5e9e184a6fd245d57e7269750ce50c20f5d9a"/>
</distutils>
<!-- OpenXR required for WebXR support -->
@@ -175,21 +174,34 @@
</branch>
</meson>
- <meson id="glib-networking"
- mesonargs="-Dgnutls=disabled -Dopenssl=enabled">
- <dependencies>
- <dep package="glib"/>
- </dependencies>
- <branch module="/sources/glib-networking/2.70/glib-networking-${version}.tar.xz" version="2.70.0"
- repo="download.gnome.org"
- hash="sha256:66b408e7afa86c582fe38963db56133869ab4b57d34e48ec56aba621940d6f35"/>
- </meson>
+ <if condition-set="use_openssl_backend">
+ <meson id="glib-networking"
+ mesonargs="-Dgnutls=disabled -Dopenssl=enabled">
+ <dependencies>
+ <dep package="glib"/>
+ </dependencies>
+ <branch module="/sources/glib-networking/2.70/glib-networking-${version}.tar.xz" version="2.70.0"
+ repo="download.gnome.org"
+ hash="sha256:66b408e7afa86c582fe38963db56133869ab4b57d34e48ec56aba621940d6f35"/>
+ </meson>
+ </if>
+
+ <if condition-unset="use_openssl_backend">
+ <meson id="glib-networking">
+ <dependencies>
+ <dep package="glib"/>
+ </dependencies>
+ <branch module="/sources/glib-networking/2.70/glib-networking-${version}.tar.xz" version="2.70.0"
+ repo="download.gnome.org"
+ hash="sha256:66b408e7afa86c582fe38963db56133869ab4b57d34e48ec56aba621940d6f35"/>
+ </meson>
+ </if>
<!-- atk needed to build with A11y support -->
<meson id="atk" mesonargs="-Dintrospection=false">
- <branch module="/sources/atk/2.34/atk-${version}.tar.xz" version="2.34.1"
+ <branch module="/sources/atk/2.38/atk-${version}.tar.xz" version="2.38.0"
repo="download.gnome.org"
- hash="sha256:d4f0e3b3d21265fcf2bc371e117da51c42ede1a71f6db1c834e6976bb20997cb"/>
+ hash="sha256:ac4de2a4ef4bd5665052952fe169657e65e895c5057dffb3c2a810f6191a0c36"/>
<dependencies>
<dep package="glib"/>
</dependencies>
@@ -197,9 +209,9 @@
<!-- at-spi2-core needed to build with A11y support -->
<meson id="at-spi2-core" mesonargs="-Dintrospection=no -Dx11=no">
- <branch module="/sources/at-spi2-core/2.34/at-spi2-core-${version}.tar.xz" version="2.34.0"
+ <branch module="/sources/at-spi2-core/2.44/at-spi2-core-${version}.tar.xz" version="2.44.1"
repo="download.gnome.org"
- hash="sha256:d629cdbd674e539f8912028512af583990938c7b49e25184c126b00121ef11c6">
+ hash="sha256:4beb23270ba6cf7caf20b597354d75194d89afb69d2efcf15f4271688ba6f746">
</branch>
<dependencies>
<dep package="glib"/>
@@ -207,10 +219,10 @@
</meson>
<!-- at-spi2-atk needed to build with A11y support -->
- <meson id="at-spi2-atk" mesonargs="-Dintrospection=no">
- <branch module="/sources/at-spi2-atk/2.34/at-spi2-atk-${version}.tar.xz" version="2.34.0"
+ <meson id="at-spi2-atk" mesonargs="">
+ <branch module="/sources/at-spi2-atk/2.38/at-spi2-atk-${version}.tar.xz" version="2.38.0"
repo="download.gnome.org"
- hash="sha256:3a9a7e96a1eb549529e60a42201dd78ccce413d9c1706e16351cc5288e064500">
+ hash="sha256:cfa008a5af822b36ae6287f18182c40c91dd699c55faa38605881ed175ca464f">
</branch>
<dependencies>
<dep package="glib"/>
diff --git a/Tools/jhbuild/jhbuildrc_common.py b/Tools/jhbuild/jhbuildrc_common.py
index 814abef097120d8f0b99ce7b05a43dc014597248..d691310642588977ee12f5f74d90735f19725143 100644
--- a/Tools/jhbuild/jhbuildrc_common.py
+++ b/Tools/jhbuild/jhbuildrc_common.py
@@ -19,7 +19,7 @@ import multiprocessing
import sys
import os
import platform
-
+import re
script_dir = None
@@ -35,6 +35,24 @@ def top_level_path(*args):
return os.path.join(*((os.path.join(os.path.dirname(__file__), '..', '..'),) + args))
+def gnutls_version():
+ ret = {}
+ gnutls = "/usr/include/gnutls/gnutls.h"
+ with open(gnutls) as fd:
+ for l in fd.readlines():
+ m = re.match(r'#define\s+GNUTLS_VERSION_([A-Z]+)\s+(\d+)', l)
+ if m:
+ key, value = m.group(1), m.group(2)
+ ret[key.lower()] = int(value)
+ fd.close()
+ return ret
+
+
+def use_openssl_backend():
+ v = gnutls_version()
+ return v["major"] <= 3 and v["minor"] <= 6 and v["patch"] < 13
+
+
def init(jhbuildrc_globals, jhbuild_platform):
__tools_directory = os.path.join(os.path.dirname(__file__), "../", jhbuild_platform)
@@ -100,3 +118,7 @@ def init(jhbuildrc_globals, jhbuild_platform):
jhbuild_enable_thunder = os.environ['JHBUILD_ENABLE_THUNDER'].lower()
if jhbuild_enable_thunder == 'yes' or jhbuild_enable_thunder == '1' or jhbuild_enable_thunder == 'true':
jhbuildrc_globals['conditions'].add('Thunder')
+
+ if use_openssl_backend():
+ jhbuildrc_globals['conditions'].add('use_openssl_backend')
+
diff --git a/Tools/win/DLLLauncher/DLLLauncherMain.cpp b/Tools/win/DLLLauncher/DLLLauncherMain.cpp
index 52605867b9302d1afcc56c5e9b0c54acf0827900..6edf24ab60249241ba2969531ef55f4b495dce9e 100644
--- a/Tools/win/DLLLauncher/DLLLauncherMain.cpp
+++ b/Tools/win/DLLLauncher/DLLLauncherMain.cpp
@@ -99,11 +99,9 @@ static bool prependPath(const std::wstring& directoryToPrepend)
static int fatalError(const std::wstring& programName, const std::wstring& message)
{
std::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 f648e718b51dcc4afe433c812956ea8960232b3c..b849dd178d0d463c0a8afff9bfe0b7aacb74fa67 100644
--- a/Tools/wpe/backends/HeadlessViewBackend.cpp
+++ b/Tools/wpe/backends/HeadlessViewBackend.cpp
@@ -52,3 +52,4 @@ void HeadlessViewBackend::dispatchFullscreenEvent()
#endif
} // namespace WPEToolingBackends
+
diff --git a/Tools/wpe/backends/fdo/HeadlessViewBackendFdo.cpp b/Tools/wpe/backends/fdo/HeadlessViewBackendFdo.cpp
index 4b3d262528d33800ac46e4e9fc342b11f2744979..39d72bd2c04e79b94a5c7634b6abc9b227d5c148 100644
--- a/Tools/wpe/backends/fdo/HeadlessViewBackendFdo.cpp
+++ b/Tools/wpe/backends/fdo/HeadlessViewBackendFdo.cpp
@@ -149,27 +149,25 @@ void HeadlessViewBackend::updateSnapshot(PlatformBuffer exportedBuffer)
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);
}
@@ -177,7 +175,7 @@ void HeadlessViewBackend::updateSnapshot(PlatformBuffer exportedBuffer)
cairo_surface_destroy(m_snapshot);
m_snapshot = cairo_image_surface_create_for_data(buffer, CAIRO_FORMAT_ARGB32,
- m_width, m_height, cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, m_width));
+ width, height, cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width));
static cairo_user_data_key_t bufferKey;
cairo_surface_set_user_data(m_snapshot, &bufferKey, buffer,
diff --git a/Tools/wpe/jhbuild.modules b/Tools/wpe/jhbuild.modules
index 8b8ba5b934075fe53e231a418db17ddcf7ba92aa..08aba0aa37ffbbd5878befe05e2950ab5350ea3c 100644
--- a/Tools/wpe/jhbuild.modules
+++ b/Tools/wpe/jhbuild.modules
@@ -276,28 +276,28 @@
</autotools>
<meson id="atk" mesonargs="-Dintrospection=false">
- <branch module="/sources/atk/2.34/atk-${version}.tar.xz" version="2.34.1"
+ <branch module="/sources/atk/2.38/atk-${version}.tar.xz" version="2.38.0"
repo="download.gnome.org"
- hash="sha256:d4f0e3b3d21265fcf2bc371e117da51c42ede1a71f6db1c834e6976bb20997cb"/>
+ hash="sha256:ac4de2a4ef4bd5665052952fe169657e65e895c5057dffb3c2a810f6191a0c36"/>
<dependencies>
<dep package="glib"/>
</dependencies>
</meson>
<meson id="at-spi2-core" mesonargs="-Dintrospection=no -Dx11=no">
- <branch module="/sources/at-spi2-core/2.34/at-spi2-core-${version}.tar.xz" version="2.34.0"
+ <branch module="/sources/at-spi2-core/2.44/at-spi2-core-${version}.tar.xz" version="2.44.1"
repo="download.gnome.org"
- hash="sha256:d629cdbd674e539f8912028512af583990938c7b49e25184c126b00121ef11c6">
+ hash="sha256:4beb23270ba6cf7caf20b597354d75194d89afb69d2efcf15f4271688ba6f746">
</branch>
<dependencies>
<dep package="glib"/>
</dependencies>
</meson>
- <meson id="at-spi2-atk" mesonargs="-Dintrospection=no">
- <branch module="/sources/at-spi2-atk/2.34/at-spi2-atk-${version}.tar.xz" version="2.34.0"
+ <meson id="at-spi2-atk" mesonargs="">
+ <branch module="/sources/at-spi2-atk/2.38/at-spi2-atk-${version}.tar.xz" version="2.38.0"
repo="download.gnome.org"
- hash="sha256:3a9a7e96a1eb549529e60a42201dd78ccce413d9c1706e16351cc5288e064500">
+ hash="sha256:cfa008a5af822b36ae6287f18182c40c91dd699c55faa38605881ed175ca464f">
</branch>
<dependencies>
<dep package="glib"/>
diff --git a/WebKit.xcworkspace/contents.xcworkspacedata b/WebKit.xcworkspace/contents.xcworkspacedata
index 8660306662de6faabab78662034958811e3e4a67..979c470d97950007ad990564eba18de965c295b2 100644
--- a/WebKit.xcworkspace/contents.xcworkspacedata
+++ b/WebKit.xcworkspace/contents.xcworkspacedata
@@ -1,6 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
+ <FileRef
+ location = "group:Tools/Playwright/Playwright.xcodeproj">
+ </FileRef>
<FileRef
location = "group:Source/bmalloc/bmalloc.xcodeproj">
</FileRef>
diff --git a/WebKit.xcworkspace/xcshareddata/xcschemes/All Modules.xcscheme b/WebKit.xcworkspace/xcshareddata/xcschemes/All Modules.xcscheme
index 0a7672a9d18fead0f7c0b451683835beff4f94a1..87ccc0e4fcb4a386165392fe8df6acade41b755e 100644
--- a/WebKit.xcworkspace/xcshareddata/xcschemes/All Modules.xcscheme
+++ b/WebKit.xcworkspace/xcshareddata/xcschemes/All Modules.xcscheme
@@ -188,6 +188,20 @@
ReferencedContainer = "container:Tools/MiniBrowser/MiniBrowser.xcodeproj">
</BuildableReference>
</BuildActionEntry>
+ <BuildActionEntry
+ buildForTesting = "YES"
+ buildForRunning = "YES"
+ buildForProfiling = "YES"
+ buildForArchiving = "YES"
+ buildForAnalyzing = "YES">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "8D1107260486CEB800E47091"
+ BuildableName = "Playwright.app"
+ BlueprintName = "Playwright"
+ ReferencedContainer = "container:Tools/Playwright/Playwright.xcodeproj">
+ </BuildableReference>
+ </BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"