16767 lines
		
	
	
		
			743 KiB
		
	
	
	
		
			Diff
		
	
	
	
			
		
		
	
	
			16767 lines
		
	
	
		
			743 KiB
		
	
	
	
		
			Diff
		
	
	
	
diff --git a/Source/JavaScriptCore/CMakeLists.txt b/Source/JavaScriptCore/CMakeLists.txt
 | 
						||
index f7c6662f7fe56709f45094c073f55c5081ca887e..606faf1918b3a80211d4aea9797a98a5596dcc10 100644
 | 
						||
--- a/Source/JavaScriptCore/CMakeLists.txt
 | 
						||
+++ b/Source/JavaScriptCore/CMakeLists.txt
 | 
						||
@@ -1154,18 +1154,22 @@ 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/Browser.json
 | 
						||
+    ${JAVASCRIPTCORE_DIR}/inspector/protocol/Emulation.json
 | 
						||
     ${JAVASCRIPTCORE_DIR}/inspector/protocol/GenericTypes.json
 | 
						||
     ${JAVASCRIPTCORE_DIR}/inspector/protocol/Heap.json
 | 
						||
+    ${JAVASCRIPTCORE_DIR}/inspector/protocol/Input.json
 | 
						||
     ${JAVASCRIPTCORE_DIR}/inspector/protocol/Inspector.json
 | 
						||
     ${JAVASCRIPTCORE_DIR}/inspector/protocol/LayerTree.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
 | 
						||
diff --git a/Source/JavaScriptCore/DerivedSources.make b/Source/JavaScriptCore/DerivedSources.make
 | 
						||
index e9d804d9e8be5c345ef47219e0e996d319bbf907..9a73a9d88e1b2825458d40d33500d23c67d4d08b 100644
 | 
						||
--- a/Source/JavaScriptCore/DerivedSources.make
 | 
						||
+++ b/Source/JavaScriptCore/DerivedSources.make
 | 
						||
@@ -244,18 +244,22 @@ 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/Browser.json \
 | 
						||
+    $(JavaScriptCore)/inspector/protocol/Emulation.json \
 | 
						||
     $(JavaScriptCore)/inspector/protocol/GenericTypes.json \
 | 
						||
     $(JavaScriptCore)/inspector/protocol/Heap.json \
 | 
						||
+    $(JavaScriptCore)/inspector/protocol/Input.json \
 | 
						||
     $(JavaScriptCore)/inspector/protocol/Inspector.json \
 | 
						||
     $(JavaScriptCore)/inspector/protocol/LayerTree.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 \
 | 
						||
diff --git a/Source/JavaScriptCore/bindings/ScriptValue.cpp b/Source/JavaScriptCore/bindings/ScriptValue.cpp
 | 
						||
index dece6ac51e3a85b1e094e405effc6203887ddfd4..9bf7519d894eceb06b40d754c4fb7940399eba84 100644
 | 
						||
--- a/Source/JavaScriptCore/bindings/ScriptValue.cpp
 | 
						||
+++ b/Source/JavaScriptCore/bindings/ScriptValue.cpp
 | 
						||
@@ -81,7 +81,10 @@ static RefPtr<JSON::Value> jsToInspectorValue(JSGlobalObject* globalObject, JSVa
 | 
						||
         PropertyNameArray propertyNames(vm, PropertyNameMode::Strings, PrivateSymbolMode::Exclude);
 | 
						||
         object.methodTable(vm)->getOwnPropertyNames(&object, globalObject, propertyNames, EnumerationMode());
 | 
						||
         for (auto& name : propertyNames) {
 | 
						||
-            auto inspectorValue = jsToInspectorValue(globalObject, object.get(globalObject, name), maxDepth);
 | 
						||
+            JSValue childValue = object.get(globalObject, name);
 | 
						||
+            if (childValue.isUndefined())
 | 
						||
+                continue;
 | 
						||
+            auto inspectorValue = jsToInspectorValue(globalObject, childValue, maxDepth);
 | 
						||
             if (!inspectorValue)
 | 
						||
                 return nullptr;
 | 
						||
             inspectorObject->setValue(name.string(), WTFMove(inspectorValue));
 | 
						||
diff --git a/Source/JavaScriptCore/inspector/IdentifiersFactory.cpp b/Source/JavaScriptCore/inspector/IdentifiersFactory.cpp
 | 
						||
index 95cd87b01b15cb8667e57bc5bb51a71f06bc3760..0481fa93227f297be9d9cf000c5a72235956a390 100644
 | 
						||
--- a/Source/JavaScriptCore/inspector/IdentifiersFactory.cpp
 | 
						||
+++ b/Source/JavaScriptCore/inspector/IdentifiersFactory.cpp
 | 
						||
@@ -30,14 +30,21 @@
 | 
						||
 namespace Inspector {
 | 
						||
 
 | 
						||
 namespace {
 | 
						||
+static uint64_t s_processID = 0;
 | 
						||
 static long s_lastUsedIdentifier = 0;
 | 
						||
 }
 | 
						||
 
 | 
						||
 static String addPrefixToIdentifier(const String& identifier)
 | 
						||
 {
 | 
						||
-    return makeString("0.", identifier);
 | 
						||
+    return makeString(s_processID, ".", identifier);
 | 
						||
 }
 | 
						||
 
 | 
						||
+void IdentifiersFactory::initializeWithProcessID(uint64_t processID) {
 | 
						||
+    ASSERT(!s_processID);
 | 
						||
+    s_processID = processID;
 | 
						||
+}
 | 
						||
+
 | 
						||
+
 | 
						||
 String IdentifiersFactory::createIdentifier()
 | 
						||
 {
 | 
						||
     return addPrefixToIdentifier(String::number(++s_lastUsedIdentifier));
 | 
						||
diff --git a/Source/JavaScriptCore/inspector/IdentifiersFactory.h b/Source/JavaScriptCore/inspector/IdentifiersFactory.h
 | 
						||
index eb25aedee4cd9ebe007e06c2515b37ee095b06f4..badf6559595c8377db1089ca3c25008e1be2c8f1 100644
 | 
						||
--- a/Source/JavaScriptCore/inspector/IdentifiersFactory.h
 | 
						||
+++ b/Source/JavaScriptCore/inspector/IdentifiersFactory.h
 | 
						||
@@ -31,6 +31,7 @@ namespace Inspector {
 | 
						||
 
 | 
						||
 class JS_EXPORT_PRIVATE IdentifiersFactory {
 | 
						||
 public:
 | 
						||
+    static void initializeWithProcessID(uint64_t);
 | 
						||
     static String createIdentifier();
 | 
						||
     static String requestId(unsigned long identifier);
 | 
						||
 };
 | 
						||
diff --git a/Source/JavaScriptCore/inspector/InjectedScript.cpp b/Source/JavaScriptCore/inspector/InjectedScript.cpp
 | 
						||
index cc849f051fa40518a9d1a03429bc2b4dbcfb3102..11b05346f6098fa23f51ba9abc1af0e0e60a626c 100644
 | 
						||
--- a/Source/JavaScriptCore/inspector/InjectedScript.cpp
 | 
						||
+++ b/Source/JavaScriptCore/inspector/InjectedScript.cpp
 | 
						||
@@ -287,9 +287,13 @@ 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;
 | 
						||
 
 | 
						||
     RefPtr<JSON::Object> resultObject;
 | 
						||
-    bool castSucceeded = toInspectorValue(globalObject(), callResult.value())->asObject(resultObject);
 | 
						||
+    bool castSucceeded = toInspectorValue(globalObject(), callResultValue)->asObject(resultObject);
 | 
						||
     ASSERT_UNUSED(castSucceeded, castSucceeded);
 | 
						||
 
 | 
						||
     return BindingTraits<Protocol::Runtime::RemoteObject>::runtimeCast(resultObject);
 | 
						||
diff --git a/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.cpp b/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.cpp
 | 
						||
index 038cb646d31706905deff8935040d63c0afd00f9..2fca7b043f15a8cce3819cc827912fb719a345db 100644
 | 
						||
--- a/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.cpp
 | 
						||
+++ b/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.cpp
 | 
						||
@@ -102,7 +102,7 @@ void BackendDispatcher::registerDispatcherForDomain(const String& domain, Supple
 | 
						||
     m_dispatchers.set(domain, dispatcher);
 | 
						||
 }
 | 
						||
 
 | 
						||
-void BackendDispatcher::dispatch(const String& message)
 | 
						||
+BackendDispatcher::DispatchResult BackendDispatcher::dispatch(const String& message, Mode mode, Interceptor&& interceptor)
 | 
						||
 {
 | 
						||
     Ref<BackendDispatcher> protect(*this);
 | 
						||
 
 | 
						||
@@ -120,29 +120,32 @@ void BackendDispatcher::dispatch(const String& message)
 | 
						||
         if (!JSON::Value::parseJSON(message, parsedMessage)) {
 | 
						||
             reportProtocolError(ParseError, "Message must be in JSON format"_s);
 | 
						||
             sendPendingErrors();
 | 
						||
-            return;
 | 
						||
+            return DispatchResult::Finished;
 | 
						||
         }
 | 
						||
 
 | 
						||
         if (!parsedMessage->asObject(messageObject)) {
 | 
						||
             reportProtocolError(InvalidRequest, "Message must be a JSONified object"_s);
 | 
						||
             sendPendingErrors();
 | 
						||
-            return;
 | 
						||
+            return DispatchResult::Finished;
 | 
						||
         }
 | 
						||
 
 | 
						||
         RefPtr<JSON::Value> requestIdValue;
 | 
						||
         if (!messageObject->getValue("id"_s, requestIdValue)) {
 | 
						||
             reportProtocolError(InvalidRequest, "'id' property was not found"_s);
 | 
						||
             sendPendingErrors();
 | 
						||
-            return;
 | 
						||
+            return DispatchResult::Finished;
 | 
						||
         }
 | 
						||
 
 | 
						||
         if (!requestIdValue->asInteger(requestId)) {
 | 
						||
             reportProtocolError(InvalidRequest, "The type of 'id' property must be integer"_s);
 | 
						||
             sendPendingErrors();
 | 
						||
-            return;
 | 
						||
+            return DispatchResult::Finished;
 | 
						||
         }
 | 
						||
     }
 | 
						||
 
 | 
						||
+    if (interceptor && interceptor(messageObject) == DispatchResult::Finished)
 | 
						||
+        return DispatchResult::Finished;
 | 
						||
+
 | 
						||
     {
 | 
						||
         // We could be called re-entrantly from a nested run loop, so restore the previous id.
 | 
						||
         SetForScope<Optional<long>> scopedRequestId(m_currentRequestId, requestId);
 | 
						||
@@ -151,29 +154,31 @@ void BackendDispatcher::dispatch(const String& message)
 | 
						||
         if (!messageObject->getValue("method"_s, methodValue)) {
 | 
						||
             reportProtocolError(InvalidRequest, "'method' property wasn't found"_s);
 | 
						||
             sendPendingErrors();
 | 
						||
-            return;
 | 
						||
+            return DispatchResult::Finished;
 | 
						||
         }
 | 
						||
 
 | 
						||
         String methodString;
 | 
						||
         if (!methodValue->asString(methodString)) {
 | 
						||
             reportProtocolError(InvalidRequest, "The type of 'method' property must be string"_s);
 | 
						||
             sendPendingErrors();
 | 
						||
-            return;
 | 
						||
+            return DispatchResult::Finished;
 | 
						||
         }
 | 
						||
 
 | 
						||
         Vector<String> domainAndMethod = methodString.splitAllowingEmptyEntries('.');
 | 
						||
         if (domainAndMethod.size() != 2 || !domainAndMethod[0].length() || !domainAndMethod[1].length()) {
 | 
						||
             reportProtocolError(InvalidRequest, "The 'method' property was formatted incorrectly. It should be 'Domain.method'"_s);
 | 
						||
             sendPendingErrors();
 | 
						||
-            return;
 | 
						||
+            return DispatchResult::Finished;
 | 
						||
         }
 | 
						||
 
 | 
						||
         String domain = domainAndMethod[0];
 | 
						||
         SupplementalBackendDispatcher* domainDispatcher = m_dispatchers.get(domain);
 | 
						||
         if (!domainDispatcher) {
 | 
						||
+            if (mode == Mode::ContinueIfDomainIsMissing)
 | 
						||
+                return DispatchResult::Continue;
 | 
						||
             reportProtocolError(MethodNotFound, "'" + domain + "' domain was not found");
 | 
						||
             sendPendingErrors();
 | 
						||
-            return;
 | 
						||
+            return DispatchResult::Finished;
 | 
						||
         }
 | 
						||
 
 | 
						||
         String method = domainAndMethod[1];
 | 
						||
@@ -182,6 +187,7 @@ void BackendDispatcher::dispatch(const String& message)
 | 
						||
         if (m_protocolErrors.size())
 | 
						||
             sendPendingErrors();
 | 
						||
     }
 | 
						||
+    return DispatchResult::Finished;
 | 
						||
 }
 | 
						||
 
 | 
						||
 // FIXME: remove this function when legacy InspectorObject symbols are no longer needed <http://webkit.org/b/179847>.
 | 
						||
diff --git a/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.h b/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.h
 | 
						||
index 95d9d81188e735e8f1b70cc0deee2682cb6714f0..4c67ce34302f74e0d07f64ae53a4eaf18df6669a 100644
 | 
						||
--- a/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.h
 | 
						||
+++ b/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.h
 | 
						||
@@ -82,7 +82,11 @@ public:
 | 
						||
     };
 | 
						||
 
 | 
						||
     void registerDispatcherForDomain(const String& domain, SupplementalBackendDispatcher*);
 | 
						||
-    void dispatch(const String& message);
 | 
						||
+
 | 
						||
+    enum class DispatchResult { Finished, Continue };
 | 
						||
+    enum class Mode { FailIfDomainIsMissing, ContinueIfDomainIsMissing };
 | 
						||
+    using Interceptor = WTF::Function<DispatchResult(const RefPtr<JSON::Object>&)>;
 | 
						||
+    DispatchResult dispatch(const String& message, Mode mode = Mode::FailIfDomainIsMissing, Interceptor&& interceptor = Interceptor());
 | 
						||
 
 | 
						||
     // Note that 'unused' is a workaround so the compiler can pick the right sendResponse based on arity.
 | 
						||
     // When <http://webkit.org/b/179847> is fixed or this class is renamed for the JSON::Object case,
 | 
						||
diff --git a/Source/JavaScriptCore/inspector/InspectorFrontendRouter.cpp b/Source/JavaScriptCore/inspector/InspectorFrontendRouter.cpp
 | 
						||
index d408d364f1986983161f9d44efbc8bc6f6898676..1375ce9990f0c63d7e6f33ee62930051d6cd44cb 100644
 | 
						||
--- a/Source/JavaScriptCore/inspector/InspectorFrontendRouter.cpp
 | 
						||
+++ b/Source/JavaScriptCore/inspector/InspectorFrontendRouter.cpp
 | 
						||
@@ -49,7 +49,7 @@ void FrontendRouter::connectFrontend(FrontendChannel& connection)
 | 
						||
 void FrontendRouter::disconnectFrontend(FrontendChannel& connection)
 | 
						||
 {
 | 
						||
     if (!m_connections.contains(&connection)) {
 | 
						||
-        ASSERT_NOT_REACHED();
 | 
						||
+        ASSERT(m_connections.isEmpty());
 | 
						||
         return;
 | 
						||
     }
 | 
						||
 
 | 
						||
diff --git a/Source/JavaScriptCore/inspector/InspectorTarget.cpp b/Source/JavaScriptCore/inspector/InspectorTarget.cpp
 | 
						||
index 0cc2127c9c12c2d82dea9550bad73f4ffb99ba24..8ca65cc042d435cbc0e05dcc5c5dfc958eb24f5a 100644
 | 
						||
--- a/Source/JavaScriptCore/inspector/InspectorTarget.cpp
 | 
						||
+++ b/Source/JavaScriptCore/inspector/InspectorTarget.cpp
 | 
						||
@@ -44,6 +44,8 @@ void InspectorTarget::resume()
 | 
						||
     ASSERT(m_isPaused);
 | 
						||
     m_isPaused = false;
 | 
						||
 
 | 
						||
+    willResume();
 | 
						||
+
 | 
						||
     if (m_resumeCallback) {
 | 
						||
         m_resumeCallback();
 | 
						||
         m_resumeCallback = nullptr;
 | 
						||
@@ -52,7 +54,6 @@ void InspectorTarget::resume()
 | 
						||
 
 | 
						||
 void InspectorTarget::setResumeCallback(WTF::Function<void()>&& callback)
 | 
						||
 {
 | 
						||
-    ASSERT(!m_resumeCallback);
 | 
						||
     m_resumeCallback = WTFMove(callback);
 | 
						||
 }
 | 
						||
 
 | 
						||
diff --git a/Source/JavaScriptCore/inspector/InspectorTarget.h b/Source/JavaScriptCore/inspector/InspectorTarget.h
 | 
						||
index 4b95964db4d902b4b7f4b0b4c40afea51654ff2f..966a5927702b65edb343369decafda7fc83eaec7 100644
 | 
						||
--- a/Source/JavaScriptCore/inspector/InspectorTarget.h
 | 
						||
+++ b/Source/JavaScriptCore/inspector/InspectorTarget.h
 | 
						||
@@ -56,8 +56,12 @@ public:
 | 
						||
     virtual void connect(FrontendChannel::ConnectionType) = 0;
 | 
						||
     virtual void disconnect() = 0;
 | 
						||
     virtual void sendMessageToTargetBackend(const String&) = 0;
 | 
						||
+    virtual void activate(String& error) { error = "Target cannot be activated"; }
 | 
						||
+    virtual void close(String& error, bool /* runBeforeUnload */) { error = "Target cannot be closed"; }
 | 
						||
 
 | 
						||
 private:
 | 
						||
+    virtual void willResume() { }
 | 
						||
+
 | 
						||
     WTF::Function<void()> m_resumeCallback;
 | 
						||
     bool m_isPaused { false };
 | 
						||
 };
 | 
						||
diff --git a/Source/JavaScriptCore/inspector/agents/InspectorTargetAgent.cpp b/Source/JavaScriptCore/inspector/agents/InspectorTargetAgent.cpp
 | 
						||
index 8fcb5a1e55750d325a84824d86c49cfe6fb04268..ed2525df326bfe649793701a112eefa30952e375 100644
 | 
						||
--- a/Source/JavaScriptCore/inspector/agents/InspectorTargetAgent.cpp
 | 
						||
+++ b/Source/JavaScriptCore/inspector/agents/InspectorTargetAgent.cpp
 | 
						||
@@ -87,6 +87,28 @@ void InspectorTargetAgent::sendMessageToTarget(ErrorString& errorString, const S
 | 
						||
     target->sendMessageToTargetBackend(message);
 | 
						||
 }
 | 
						||
 
 | 
						||
+void InspectorTargetAgent::activate(ErrorString& errorString, const String& targetId)
 | 
						||
+{
 | 
						||
+    InspectorTarget* target = m_targets.get(targetId);
 | 
						||
+    if (!target) {
 | 
						||
+        errorString = "Missing target for given targetId"_s;
 | 
						||
+        return;
 | 
						||
+    }
 | 
						||
+
 | 
						||
+    target->activate(errorString);
 | 
						||
+}
 | 
						||
+
 | 
						||
+void InspectorTargetAgent::close(ErrorString& errorString, const String& targetId, const bool* runBeforeUnload)
 | 
						||
+{
 | 
						||
+    InspectorTarget* target = m_targets.get(targetId);
 | 
						||
+    if (!target) {
 | 
						||
+        errorString = "Missing target for given targetId"_s;
 | 
						||
+        return;
 | 
						||
+    }
 | 
						||
+
 | 
						||
+    target->close(errorString, runBeforeUnload && *runBeforeUnload);
 | 
						||
+}
 | 
						||
+
 | 
						||
 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 +166,17 @@ void InspectorTargetAgent::targetDestroyed(InspectorTarget& target)
 | 
						||
     if (!m_isConnected)
 | 
						||
         return;
 | 
						||
 
 | 
						||
-    m_frontendDispatcher->targetDestroyed(target.identifier());
 | 
						||
+    m_frontendDispatcher->targetDestroyed(target.identifier(), false);
 | 
						||
+}
 | 
						||
+
 | 
						||
+void InspectorTargetAgent::targetCrashed(InspectorTarget& target)
 | 
						||
+{
 | 
						||
+    m_targets.remove(target.identifier());
 | 
						||
+
 | 
						||
+    if (!m_isConnected)
 | 
						||
+        return;
 | 
						||
+
 | 
						||
+    m_frontendDispatcher->targetDestroyed(target.identifier(), true);
 | 
						||
 }
 | 
						||
 
 | 
						||
 void InspectorTargetAgent::didCommitProvisionalTarget(const String& oldTargetID, const String& committedTargetID)
 | 
						||
@@ -159,6 +191,18 @@ void InspectorTargetAgent::didCommitProvisionalTarget(const String& oldTargetID,
 | 
						||
     m_frontendDispatcher->didCommitProvisionalTarget(oldTargetID, committedTargetID);
 | 
						||
 }
 | 
						||
 
 | 
						||
+void InspectorTargetAgent::ensureConnected(const String& targetID)
 | 
						||
+{
 | 
						||
+    if (!m_isConnected)
 | 
						||
+        return;
 | 
						||
+
 | 
						||
+    auto* target = m_targets.get(targetID);
 | 
						||
+    if (!target)
 | 
						||
+        return;
 | 
						||
+
 | 
						||
+    target->connect(connectionType());
 | 
						||
+}
 | 
						||
+
 | 
						||
 FrontendChannel::ConnectionType InspectorTargetAgent::connectionType() const
 | 
						||
 {
 | 
						||
     return m_router.hasLocalFrontend() ? Inspector::FrontendChannel::ConnectionType::Local : Inspector::FrontendChannel::ConnectionType::Remote;
 | 
						||
diff --git a/Source/JavaScriptCore/inspector/agents/InspectorTargetAgent.h b/Source/JavaScriptCore/inspector/agents/InspectorTargetAgent.h
 | 
						||
index 1eb7abb2fa21d7a8ec0833160f53e5c523ec4317..7709bcc2ec69aab0589ca1b954db1fb241bb583b 100644
 | 
						||
--- a/Source/JavaScriptCore/inspector/agents/InspectorTargetAgent.h
 | 
						||
+++ b/Source/JavaScriptCore/inspector/agents/InspectorTargetAgent.h
 | 
						||
@@ -52,15 +52,21 @@ public:
 | 
						||
     void setPauseOnStart(ErrorString&, bool pauseOnStart) override;
 | 
						||
     void resume(ErrorString&, const String& targetId) override;
 | 
						||
     void sendMessageToTarget(ErrorString&, const String& targetId, const String& message) final;
 | 
						||
+    void activate(ErrorString&, const String& targetId) override;
 | 
						||
+    void close(ErrorString&, const String& targetId, const bool* runBeforeUnload) override;
 | 
						||
 
 | 
						||
     // Target lifecycle.
 | 
						||
     void targetCreated(InspectorTarget&);
 | 
						||
     void targetDestroyed(InspectorTarget&);
 | 
						||
+    void targetCrashed(InspectorTarget&);
 | 
						||
     void didCommitProvisionalTarget(const String& oldTargetID, const String& committedTargetID);
 | 
						||
+    void ensureConnected(const String& targetID);
 | 
						||
 
 | 
						||
     // Target messages.
 | 
						||
     void sendMessageFromTargetToFrontend(const String& targetId, const String& message);
 | 
						||
 
 | 
						||
+    bool isConnected() { return m_isConnected; }
 | 
						||
+
 | 
						||
 private:
 | 
						||
     // FrontendChannel
 | 
						||
     FrontendChannel::ConnectionType connectionType() const;
 | 
						||
diff --git a/Source/JavaScriptCore/inspector/protocol/DOM.json b/Source/JavaScriptCore/inspector/protocol/DOM.json
 | 
						||
index 38cb48bedf2b168149ff79423b7fafc1e63ce8b3..e3d044934f5a0dc2331534439daa53116019548f 100644
 | 
						||
--- a/Source/JavaScriptCore/inspector/protocol/DOM.json
 | 
						||
+++ b/Source/JavaScriptCore/inspector/protocol/DOM.json
 | 
						||
@@ -79,6 +79,16 @@
 | 
						||
                 { "name": "value", "type": "string", "description": "The value that is resolved to with this data binding relationship." }
 | 
						||
             ]
 | 
						||
         },
 | 
						||
+        {
 | 
						||
+          "id": "Rect",
 | 
						||
+          "type": "object",
 | 
						||
+          "properties": [
 | 
						||
+            { "name": "x", "type": "integer", "description": "X coordinate" },
 | 
						||
+            { "name": "y", "type": "integer", "description": "Y coordinate" },
 | 
						||
+            { "name": "width", "type": "integer", "description": "Rectangle width" },
 | 
						||
+            { "name": "height", "type": "integer", "description": "Rectangle height" }
 | 
						||
+      ]
 | 
						||
+        },
 | 
						||
         {
 | 
						||
             "id": "EventListener",
 | 
						||
             "type": "object",
 | 
						||
@@ -167,6 +177,16 @@
 | 
						||
                 { "name": "borderColor", "$ref": "RGBAColor", "optional": true, "description": "The border highlight fill color (default: transparent)." },
 | 
						||
                 { "name": "marginColor", "$ref": "RGBAColor", "optional": true, "description": "The margin highlight fill color (default: transparent)." }
 | 
						||
             ]
 | 
						||
+        },
 | 
						||
+        {
 | 
						||
+            "id": "FilePayload",
 | 
						||
+            "type": "object",
 | 
						||
+            "description": "Data to construct File object.",
 | 
						||
+            "properties": [
 | 
						||
+                { "name": "name", "type": "string", "description": "File name." },
 | 
						||
+                { "name": "type", "type": "string", "description": "File type." },
 | 
						||
+                { "name": "data", "type": "string", "description": "Base64-encoded file data." }
 | 
						||
+            ]
 | 
						||
         }
 | 
						||
     ],
 | 
						||
     "commands": [
 | 
						||
@@ -481,7 +501,9 @@
 | 
						||
             "name": "resolveNode",
 | 
						||
             "description": "Resolves JavaScript node object for given node id.",
 | 
						||
             "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": [
 | 
						||
@@ -542,6 +564,45 @@
 | 
						||
             "parameters": [
 | 
						||
                 { "name": "allow", "type": "boolean" }
 | 
						||
             ]
 | 
						||
+        },
 | 
						||
+        {
 | 
						||
+            "name": "describeNode",
 | 
						||
+            "description": "Returns node description.",
 | 
						||
+            "parameters": [
 | 
						||
+                { "name": "objectId", "$ref": "Runtime.RemoteObjectId", "description": "JavaScript object id of the node wrapper." }
 | 
						||
+            ],
 | 
						||
+            "returns": [
 | 
						||
+                { "name": "contentFrameId", "$ref": "Network.FrameId", "optional": true, "description": "Frame ID for frame owner elements." },
 | 
						||
+                { "name": "ownerFrameId", "$ref": "Network.FrameId", "optional": true, "description": "ID of the owning frame element." }
 | 
						||
+            ]
 | 
						||
+        },
 | 
						||
+        {
 | 
						||
+          "name": "scrollIntoViewIfNeeded",
 | 
						||
+          "description": "Scrolls the given rect into view if not already in the viewport.",
 | 
						||
+          "parameters": [
 | 
						||
+              { "name": "objectId", "$ref": "Runtime.RemoteObjectId", "description": "JavaScript object id of the node wrapper." },
 | 
						||
+              { "name": "rect", "$ref": "Rect", "optional": true, "description": "Rect relative to the node's border box, in CSS pixels." }
 | 
						||
+          ]
 | 
						||
+        },
 | 
						||
+        {
 | 
						||
+            "name": "getContentQuads",
 | 
						||
+            "description": "Returns quads that describe node position on the page. This method\nmight return multiple quads for inline nodes.",
 | 
						||
+            "parameters": [
 | 
						||
+                { "name": "objectId", "$ref": "Runtime.RemoteObjectId", "description": "JavaScript object id of the node wrapper." }
 | 
						||
+            ],
 | 
						||
+            "returns": [
 | 
						||
+                {
 | 
						||
+                    "name": "quads", "type": "array", "items": { "$ref": "Quad" }, "description": "Quads that describe node layout relative to viewport."
 | 
						||
+                }
 | 
						||
+            ]
 | 
						||
+        },
 | 
						||
+        {
 | 
						||
+            "name": "setInputFiles",
 | 
						||
+            "description": "Sets input files for given <input type=file>",
 | 
						||
+            "parameters": [
 | 
						||
+                { "name": "objectId", "$ref": "Runtime.RemoteObjectId", "description": "Input element handle." },
 | 
						||
+                { "name": "files", "type": "array", "items": { "$ref": "FilePayload" }, "description": "Files to set" }
 | 
						||
+            ]
 | 
						||
         }
 | 
						||
     ],
 | 
						||
     "events": [
 | 
						||
diff --git a/Source/JavaScriptCore/inspector/protocol/Dialog.json b/Source/JavaScriptCore/inspector/protocol/Dialog.json
 | 
						||
new file mode 100644
 | 
						||
index 0000000000000000000000000000000000000000..79edea03fed4e9be5da96e1275e182a479cb7a0a
 | 
						||
--- /dev/null
 | 
						||
+++ b/Source/JavaScriptCore/inspector/protocol/Dialog.json
 | 
						||
@@ -0,0 +1,36 @@
 | 
						||
+{
 | 
						||
+    "domain": "Dialog",
 | 
						||
+    "description": "Actions and events related to alert boxes.",
 | 
						||
+    "availability": ["web"],
 | 
						||
+    "types": [
 | 
						||
+    ],
 | 
						||
+    "commands": [
 | 
						||
+        {
 | 
						||
+            "name": "enable",
 | 
						||
+            "description": "Enables dialog domain notifications."
 | 
						||
+        },
 | 
						||
+        {
 | 
						||
+            "name": "disable",
 | 
						||
+            "description": "Disables dialog domain notifications."
 | 
						||
+        },
 | 
						||
+        {
 | 
						||
+            "name": "handleJavaScriptDialog",
 | 
						||
+            "description": "Accepts or dismisses a JavaScript initiated dialog (alert, confirm, prompt, or onbeforeunload).",
 | 
						||
+            "parameters": [
 | 
						||
+                { "name": "accept", "type": "boolean", "description": "Whether to accept or dismiss the dialog."},
 | 
						||
+                { "name": "promptText", "optional": true, "type": "string", "description": "The text to enter into the dialog prompt before accepting. Used only if this is a prompt dialog."}
 | 
						||
+            ]
 | 
						||
+        }
 | 
						||
+    ],
 | 
						||
+    "events": [
 | 
						||
+        {
 | 
						||
+            "name": "javascriptDialogOpening",
 | 
						||
+            "description": "Fired when a JavaScript initiated dialog (alert, confirm, prompt, or onbeforeunload) is about to open.",
 | 
						||
+            "parameters": [
 | 
						||
+                { "name": "type", "type": "string", "description": "Dialog type."},
 | 
						||
+                { "name": "message", "type": "string", "description": "Message that will be displayed by the dialog."},
 | 
						||
+                { "name": "defaultPrompt", "optional": true, "type": "string", "description": "Default dialog prompt."}
 | 
						||
+            ]
 | 
						||
+        }
 | 
						||
+    ]
 | 
						||
+}
 | 
						||
diff --git a/Source/JavaScriptCore/inspector/protocol/Emulation.json b/Source/JavaScriptCore/inspector/protocol/Emulation.json
 | 
						||
new file mode 100644
 | 
						||
index 0000000000000000000000000000000000000000..552e5dd60fa53fada79f8d6e333f52bc10a2bead
 | 
						||
--- /dev/null
 | 
						||
+++ b/Source/JavaScriptCore/inspector/protocol/Emulation.json
 | 
						||
@@ -0,0 +1,39 @@
 | 
						||
+{
 | 
						||
+    "domain": "Emulation",
 | 
						||
+    "availability": ["web"],
 | 
						||
+    "commands": [
 | 
						||
+        {
 | 
						||
+            "name": "setDeviceMetricsOverride",
 | 
						||
+            "description": "Overrides device metrics with provided values.",
 | 
						||
+            "async": true,
 | 
						||
+            "parameters": [
 | 
						||
+                { "name": "width", "type": "integer" },
 | 
						||
+                { "name": "height", "type": "integer" },
 | 
						||
+                { "name": "deviceScaleFactor", "type": "number" },
 | 
						||
+                { "name": "fixedLayout", "type": "boolean" }
 | 
						||
+            ]
 | 
						||
+        },
 | 
						||
+        {
 | 
						||
+            "name": "setJavaScriptEnabled",
 | 
						||
+            "description": "Allows to disable script execution for the page.",
 | 
						||
+            "parameters": [
 | 
						||
+                { "name": "enabled", "type": "boolean" }
 | 
						||
+            ]
 | 
						||
+        },
 | 
						||
+        {
 | 
						||
+            "name": "setAuthCredentials",
 | 
						||
+            "description": "Credentials to use during HTTP authentication.",
 | 
						||
+            "parameters": [
 | 
						||
+                { "name": "username", "type": "string", "optional": true },
 | 
						||
+                { "name": "password", "type": "string", "optional": true }
 | 
						||
+            ]
 | 
						||
+        },
 | 
						||
+        {
 | 
						||
+            "name": "setActiveAndFocused",
 | 
						||
+            "description": "Makes page focused for test.",
 | 
						||
+            "parameters": [
 | 
						||
+                { "name": "active", "type": "boolean", "optional": true }
 | 
						||
+            ]
 | 
						||
+        }
 | 
						||
+    ]
 | 
						||
+}
 | 
						||
diff --git a/Source/JavaScriptCore/inspector/protocol/Input.json b/Source/JavaScriptCore/inspector/protocol/Input.json
 | 
						||
new file mode 100644
 | 
						||
index 0000000000000000000000000000000000000000..34909cce9f6d8d7c74be4c96e40f80cadb2f931d
 | 
						||
--- /dev/null
 | 
						||
+++ b/Source/JavaScriptCore/inspector/protocol/Input.json
 | 
						||
@@ -0,0 +1,165 @@
 | 
						||
+{
 | 
						||
+    "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"
 | 
						||
+                }
 | 
						||
+            ]
 | 
						||
+        }
 | 
						||
+    ]
 | 
						||
+}
 | 
						||
diff --git a/Source/JavaScriptCore/inspector/protocol/Network.json b/Source/JavaScriptCore/inspector/protocol/Network.json
 | 
						||
index 777a54166ed6664561b3f8249a6abb4ac59d0480..e738f34f65fa8137a16bf7b66bc237b85b2f5208 100644
 | 
						||
--- a/Source/JavaScriptCore/inspector/protocol/Network.json
 | 
						||
+++ b/Source/JavaScriptCore/inspector/protocol/Network.json
 | 
						||
@@ -231,7 +231,8 @@
 | 
						||
             "name": "setInterceptionEnabled",
 | 
						||
             "description": "Enable interception of network requests.",
 | 
						||
             "parameters": [
 | 
						||
-                { "name": "enabled", "type": "boolean" }
 | 
						||
+                { "name": "enabled", "type": "boolean" },
 | 
						||
+                { "name": "interceptRequests", "type": "boolean", "optional": true }
 | 
						||
             ]
 | 
						||
         },
 | 
						||
         {
 | 
						||
@@ -258,7 +259,18 @@
 | 
						||
             "name": "interceptContinue",
 | 
						||
             "description": "Continue an interception with no modifications.",
 | 
						||
             "parameters": [
 | 
						||
-                { "name": "requestId", "$ref": "RequestId", "description": "Identifier for the intercepted Network request or response to continue." }
 | 
						||
+                { "name": "requestId", "$ref": "RequestId", "description": "Identifier for the intercepted Network request or response to continue." },
 | 
						||
+                { "name": "method", "type": "string", "optional": true,"description": "HTTP request method." },
 | 
						||
+                { "name": "headers", "$ref": "Headers", "optional": true, "description": "HTTP response headers. Pass through original values if unmodified." },
 | 
						||
+                { "name": "postData", "type": "string", "optional": true, "description": "HTTP POST request data." }
 | 
						||
+            ]
 | 
						||
+        },
 | 
						||
+        {
 | 
						||
+            "name": "interceptAsError",
 | 
						||
+            "description": "Abort the intercepted request with given reason.",
 | 
						||
+            "parameters": [
 | 
						||
+                { "name": "requestId", "$ref": "RequestId", "description": "Identifier for the intercepted Network request." },
 | 
						||
+                { "name": "reason", "type": "string", "description": "Deliver error reason for the request." }
 | 
						||
             ]
 | 
						||
         },
 | 
						||
         {
 | 
						||
@@ -266,13 +278,20 @@
 | 
						||
             "description": "Provide response content for an intercepted response.",
 | 
						||
             "parameters": [
 | 
						||
                 { "name": "requestId", "$ref": "RequestId", "description": "Identifier for the intercepted Network response to modify." },
 | 
						||
-                { "name": "content", "type": "string" },
 | 
						||
-                { "name": "base64Encoded", "type": "boolean", "description": "True, if content was sent as base64." },
 | 
						||
+                { "name": "content", "type": "string", "optional": true },
 | 
						||
+                { "name": "base64Encoded", "type": "boolean", "optional": true, "description": "True, if content was sent as base64." },
 | 
						||
                 { "name": "mimeType", "type": "string", "optional": true, "description": "MIME Type for the data." },
 | 
						||
                 { "name": "status", "type": "integer", "optional": true, "description": "HTTP response status code. Pass through original values if unmodified." },
 | 
						||
                 { "name": "statusText", "type": "string", "optional": true, "description": "HTTP response status text. Pass through original values if unmodified." },
 | 
						||
                 { "name": "headers", "$ref": "Headers", "optional": true, "description": "HTTP response headers. Pass through original values if unmodified." }
 | 
						||
             ]
 | 
						||
+        },
 | 
						||
+        {
 | 
						||
+            "name": "setEmulateOfflineState",
 | 
						||
+            "description": "Emulate offline state overriding the actual state.",
 | 
						||
+            "parameters": [
 | 
						||
+                { "name": "offline", "type": "boolean", "description": "True to emulate offline." }
 | 
						||
+            ]
 | 
						||
         }
 | 
						||
     ],
 | 
						||
     "events": [
 | 
						||
@@ -356,6 +375,14 @@
 | 
						||
                 { "name": "response", "$ref": "Response", "description": "Original response content that would proceed if this is continued." }
 | 
						||
             ]
 | 
						||
         },
 | 
						||
+        {
 | 
						||
+            "name": "requestIntercepted",
 | 
						||
+            "description": "Fired when HTTP request has been intercepted. The frontend must response with <code>Network.interceptContinue</code> or <code>Network.interceptWithRespons</code>` to continue this response.",
 | 
						||
+            "parameters": [
 | 
						||
+                { "name": "requestId", "$ref": "RequestId", "description": "Identifier for this intercepted network. Corresponds with an earlier <code>Network.requestWillBeSent</code>." },
 | 
						||
+                { "name": "request", "$ref": "Request", "description": "Original request content that would proceed if this is continued." }
 | 
						||
+            ]
 | 
						||
+        },
 | 
						||
         {
 | 
						||
             "name": "webSocketWillSendHandshakeRequest",
 | 
						||
             "description": "Fired when WebSocket is about to initiate handshake.",
 | 
						||
diff --git a/Source/JavaScriptCore/inspector/protocol/Page.json b/Source/JavaScriptCore/inspector/protocol/Page.json
 | 
						||
index a8fc5332ac92424b00a3dec62152fd3c5f28544e..6aa07fd2ee4e0dff43b151d1cee7497f4aa0505b 100644
 | 
						||
--- a/Source/JavaScriptCore/inspector/protocol/Page.json
 | 
						||
+++ b/Source/JavaScriptCore/inspector/protocol/Page.json
 | 
						||
@@ -110,6 +110,41 @@
 | 
						||
                 { "name": "session", "type": "boolean", "description": "True in case of session cookie." },
 | 
						||
                 { "name": "sameSite", "$ref": "CookieSameSitePolicy", "description": "Cookie Same-Site policy." }
 | 
						||
             ]
 | 
						||
+        },
 | 
						||
+        {
 | 
						||
+            "id": "AXNode",
 | 
						||
+            "type": "object",
 | 
						||
+            "description": "Accessibility Node",
 | 
						||
+            "properties": [
 | 
						||
+                { "name": "role", "type": "string", "description": "The role."},
 | 
						||
+                { "name": "name", "type": "string","optional": true, "description": "A human readable name for the node."},
 | 
						||
+                { "name": "value", "type": "any", "optional": true, "description": "The current value of the node."},
 | 
						||
+                { "name": "description", "type": "string", "optional": true, "description": "An additional human readable description of the node."},
 | 
						||
+                { "name": "keyshortcuts", "type": "string", "optional": true, "description": "Keyboard shortcuts associated with this node."},
 | 
						||
+                { "name": "roledescription", "type": "string", "optional": true, "description": "A human readable alternative to the role."},
 | 
						||
+                { "name": "valuetext", "type": "string", "optional": true, "description": "A description of the current value."},
 | 
						||
+                { "name": "disabled", "type": "boolean", "optional": true, "description": "Whether the node is disabled."},
 | 
						||
+                { "name": "expanded", "type": "boolean", "optional": true, "description": "Whether the node is expanded or collapsed."},
 | 
						||
+                { "name": "focused", "type": "boolean", "optional": true, "description": "Whether the node is focused."},
 | 
						||
+                { "name": "modal", "type": "boolean", "optional": true, "description": "Whether the node is modal."},
 | 
						||
+                { "name": "multiline", "type": "boolean", "optional": true, "description": "Whether the node text input supports multiline."},
 | 
						||
+                { "name": "multiselectable", "type": "boolean", "optional": true, "description": "Whether more than one child can be selected."},
 | 
						||
+                { "name": "readonly", "type": "boolean", "optional": true, "description": "Whether the node is read only."},
 | 
						||
+                { "name": "required", "type": "boolean", "optional": true, "description": "Whether the node is required."},
 | 
						||
+                { "name": "selected", "type": "boolean", "optional": true, "description": "Whether the node is selected in its parent node."},
 | 
						||
+                { "name": "checked", "type": "string", "optional": true, "enum": ["true", "false", "mixed"], "description": "Whether the checkbox is checked, or \"mixed\"."},
 | 
						||
+                { "name": "pressed", "type": "string", "optional": true, "enum": ["true", "false", "mixed"], "description": "Whether the toggle button is checked, or \"mixed\"."},
 | 
						||
+                { "name": "level", "type": "integer", "optional": true, "description": "The level of a heading."},
 | 
						||
+                { "name": "valuemin", "type": "number", "optional": true, "description": "The minimum value in a node."},
 | 
						||
+                { "name": "valuemax", "type": "number", "optional": true, "description": "The maximum value in a node."},
 | 
						||
+                { "name": "autocomplete", "type": "string", "optional": true, "description": "What kind of autocomplete is supported by a control."},
 | 
						||
+                { "name": "haspopup", "type": "string", "optional": true, "description": "What kind of popup is currently being shown for a node."},
 | 
						||
+                { "name": "invalid", "type": "string", "optional": true, "enum": ["true", "false", "grammar", "spelling"], "description": "Whether and in what way this node's value is invalid."},
 | 
						||
+                { "name": "orientation", "type": "string", "optional": true, "description": "Whether the node is oriented horizontally or vertically."},
 | 
						||
+                { "name": "focusable", "type": "boolean", "optional": true, "description": "Whether the node is focusable."},
 | 
						||
+                { "name": "children", "type": "array", "optional": true, "items": { "$ref": "AXNode"}, "description": "Child AXNodes of this node, if any."},
 | 
						||
+                { "name": "found", "type": "boolean", "optional": true, "description": "True if this AXNode corresponds with the ObjectId passed into acessibilitySnapshot."}
 | 
						||
+            ]
 | 
						||
         }
 | 
						||
     ],
 | 
						||
     "commands": [
 | 
						||
@@ -129,11 +164,21 @@
 | 
						||
                 { "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.",
 | 
						||
             "parameters": [
 | 
						||
-                { "name": "url", "type": "string", "description": "URL to navigate the page to." }
 | 
						||
+                { "name": "url", "type": "string", "description": "URL to navigate the page to." },
 | 
						||
+                { "name": "frameId", "$ref": "Network.FrameId", "optional": true, "description": "Id of the frame to navigate."},
 | 
						||
+                { "name": "referrer", "type": "string", "optional": true, "description": "Referrer URL." }
 | 
						||
             ]
 | 
						||
         },
 | 
						||
         {
 | 
						||
@@ -246,6 +291,20 @@
 | 
						||
                 { "name": "appearance", "$ref": "Appearance", "description": "Appearance name to force. Empty string disables the override." }
 | 
						||
             ]
 | 
						||
         },
 | 
						||
+        {
 | 
						||
+            "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.",
 | 
						||
@@ -276,19 +335,78 @@
 | 
						||
             "returns": [
 | 
						||
                 { "name": "data", "type": "string", "description": "Base64-encoded web archive." }
 | 
						||
             ]
 | 
						||
+        },
 | 
						||
+        {
 | 
						||
+            "name": "insertText",
 | 
						||
+            "description": "Insert text into the current selection of the page.",
 | 
						||
+            "parameters": [
 | 
						||
+                { "name": "text", "type": "string", "description": "Text to insert." }
 | 
						||
+            ]
 | 
						||
+        },
 | 
						||
+        {
 | 
						||
+            "name": "accessibilitySnapshot",
 | 
						||
+            "description": "Serializes and returns all of the accessibility nodes of the page.",
 | 
						||
+            "parameters": [
 | 
						||
+                { "name": "objectId", "type": "string", "optional": true, "description": "Object Id of a node to find in the accessibility tree."}
 | 
						||
+            ],
 | 
						||
+            "returns": [
 | 
						||
+                { "name": "axNode", "$ref": "AXNode", "description": "The root AXNode."}
 | 
						||
+            ]
 | 
						||
+        },
 | 
						||
+        {
 | 
						||
+            "name": "setInterceptFileChooserDialog",
 | 
						||
+            "description": "Intercepts file chooser dialog",
 | 
						||
+            "parameters": [
 | 
						||
+                { "name": "enabled", "type": "boolean", "description": "True to enable." }
 | 
						||
+            ]
 | 
						||
+        },
 | 
						||
+        {
 | 
						||
+            "name": "setDefaultBackgroundColorOverride",
 | 
						||
+            "description": "Sets or clears an override of the default background color of the frame. This override is used if the content does not specify one.",
 | 
						||
+            "parameters": [
 | 
						||
+                { "name": "color", "$ref": "DOM.RGBAColor", "optional": true, "description": "RGBA of the default background color. If not specified, any existing override will be cleared." }
 | 
						||
+            ]
 | 
						||
+        },
 | 
						||
+        {
 | 
						||
+            "name": "createUserWorld",
 | 
						||
+            "description": "Creates an user world for every loaded frame.",
 | 
						||
+            "parameters": [
 | 
						||
+                { "name": "name", "type": "string", "description": "Isolated world name, will be used as an execution context name." }
 | 
						||
+            ]
 | 
						||
+        },
 | 
						||
+        {
 | 
						||
+            "name": "setBypassCSP",
 | 
						||
+            "description": "Enable page Content Security Policy by-passing.",
 | 
						||
+            "parameters": [
 | 
						||
+                { "name": "enabled", "type": "boolean", "description": "Whether to bypass page CSP." }
 | 
						||
+            ]
 | 
						||
+        },
 | 
						||
+        {
 | 
						||
+            "name": "crash",
 | 
						||
+            "description": "Crashes the page process"
 | 
						||
+        },
 | 
						||
+        {
 | 
						||
+            "name": "setScreenSizeOverride",
 | 
						||
+            "description": "Overrides screen size with provided values.",
 | 
						||
+            "parameters": [
 | 
						||
+                { "name": "width", "type": "integer" },
 | 
						||
+                { "name": "height", "type": "integer" }
 | 
						||
+            ]
 | 
						||
         }
 | 
						||
     ],
 | 
						||
     "events": [
 | 
						||
         {
 | 
						||
             "name": "domContentEventFired",
 | 
						||
             "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",
 | 
						||
             "parameters": [
 | 
						||
-                { "name": "timestamp", "type": "number" }
 | 
						||
+              { "name": "timestamp", "type": "number" },
 | 
						||
+              { "name": "frameId", "$ref": "Network.FrameId", "description": "Id of the frame that has fired load event." }
 | 
						||
             ]
 | 
						||
         },
 | 
						||
         {
 | 
						||
@@ -298,6 +416,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.",
 | 
						||
@@ -334,12 +460,36 @@
 | 
						||
                 { "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.",
 | 
						||
             "parameters": [
 | 
						||
                 { "name": "appearance", "$ref": "Appearance", "description": "Name of the appearance that is active (not considering any forced appearance.)" }
 | 
						||
             ]
 | 
						||
+        },
 | 
						||
+        {
 | 
						||
+            "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..cb021782b238f318f4b09c6f99699a8e184c1d75
 | 
						||
--- /dev/null
 | 
						||
+++ b/Source/JavaScriptCore/inspector/protocol/Playwright.json
 | 
						||
@@ -0,0 +1,220 @@
 | 
						||
+{
 | 
						||
+    "domain": "Playwright",
 | 
						||
+    "availability": ["web"],
 | 
						||
+    "types": [
 | 
						||
+        {
 | 
						||
+            "id": "ContextID",
 | 
						||
+            "type": "string",
 | 
						||
+            "description": "Id of Browser context."
 | 
						||
+        },
 | 
						||
+        {
 | 
						||
+            "id": "PageProxyID",
 | 
						||
+            "type": "string",
 | 
						||
+            "description": "Id of WebPageProxy."
 | 
						||
+        },
 | 
						||
+        {
 | 
						||
+            "id": "PageProxyInfo",
 | 
						||
+            "type": "object",
 | 
						||
+            "description": "Tab info object",
 | 
						||
+            "properties": [
 | 
						||
+                { "name": "pageProxyId", "$ref": "PageProxyID" },
 | 
						||
+                { "name": "browserContextId", "$ref": "ContextID", "description": "Unique identifier of the context." },
 | 
						||
+                { "name": "openerId", "$ref": "PageProxyID", "optional": true, "description": "Unique identifier of the opening page. Only set for pages created by window.open()." }
 | 
						||
+            ]
 | 
						||
+        },
 | 
						||
+        {
 | 
						||
+            "id": "CookieSameSitePolicy",
 | 
						||
+            "type": "string",
 | 
						||
+            "enum": ["None", "Lax", "Strict"],
 | 
						||
+            "description": "Same-Site policy of a cookie."
 | 
						||
+        },
 | 
						||
+        {
 | 
						||
+            "id": "Cookie",
 | 
						||
+            "type": "object",
 | 
						||
+            "description": "Cookie object",
 | 
						||
+            "properties": [
 | 
						||
+                { "name": "name", "type": "string", "description": "Cookie name." },
 | 
						||
+                { "name": "value", "type": "string", "description": "Cookie value." },
 | 
						||
+                { "name": "domain", "type": "string", "description": "Cookie domain." },
 | 
						||
+                { "name": "path", "type": "string", "description": "Cookie path." },
 | 
						||
+                { "name": "expires", "type": "number", "description": "Cookie expires." },
 | 
						||
+                { "name": "httpOnly", "type": "boolean", "description": "True if cookie is http-only." },
 | 
						||
+                { "name": "secure", "type": "boolean", "description": "True if cookie is secure." },
 | 
						||
+                { "name": "session", "type": "boolean", "description": "True if cookie is session cookie." },
 | 
						||
+                { "name": "sameSite", "$ref": "CookieSameSitePolicy", "description": "Cookie Same-Site policy." }
 | 
						||
+            ]
 | 
						||
+        },
 | 
						||
+        {
 | 
						||
+            "id": "SetCookieParam",
 | 
						||
+            "type": "object",
 | 
						||
+            "description": "Cookie object",
 | 
						||
+            "properties": [
 | 
						||
+                { "name": "name", "type": "string", "description": "Cookie name." },
 | 
						||
+                { "name": "value", "type": "string", "description": "Cookie value." },
 | 
						||
+                { "name": "domain", "type": "string", "description": "Cookie domain." },
 | 
						||
+                { "name": "path", "type": "string", "description": "Cookie path." },
 | 
						||
+                { "name": "expires", "type": "number", "optional": true, "description": "Cookie expires." },
 | 
						||
+                { "name": "httpOnly", "type": "boolean", "optional": true, "description": "True if cookie is http-only." },
 | 
						||
+                { "name": "secure", "type": "boolean", "optional": true, "description": "True if cookie is secure." },
 | 
						||
+                { "name": "session", "type": "boolean", "optional": true, "description": "True if cookie is session cookie." },
 | 
						||
+                { "name": "sameSite", "$ref": "CookieSameSitePolicy", "optional": true, "description": "Cookie Same-Site policy." }
 | 
						||
+            ]
 | 
						||
+        },
 | 
						||
+        {
 | 
						||
+            "id": "Geolocation",
 | 
						||
+            "type": "object",
 | 
						||
+            "description": "Geolocation",
 | 
						||
+            "properties": [
 | 
						||
+                { "name": "timestamp", "type": "number", "description": "Mock latitude" },
 | 
						||
+                { "name": "latitude", "type": "number", "description": "Mock latitude" },
 | 
						||
+                { "name": "longitude", "type": "number", "description": "Mock longitude" },
 | 
						||
+                { "name": "accuracy", "type": "number", "description": "Mock accuracy" }
 | 
						||
+            ]
 | 
						||
+        }
 | 
						||
+    ],
 | 
						||
+    "commands": [
 | 
						||
+        {
 | 
						||
+            "name": "close",
 | 
						||
+            "async": true,
 | 
						||
+            "description": "Close browser."
 | 
						||
+        },
 | 
						||
+        {
 | 
						||
+            "name": "createContext",
 | 
						||
+            "description": "Creates new ephemeral browser context.",
 | 
						||
+            "returns": [
 | 
						||
+                { "name": "browserContextId", "$ref": "ContextID", "description": "Unique identifier of the context." }
 | 
						||
+            ]
 | 
						||
+        },
 | 
						||
+        {
 | 
						||
+            "name": "deleteContext",
 | 
						||
+            "async": true,
 | 
						||
+            "description": "Deletes browser context previously created with createContect. The command will automatically close all pages that use the context.",
 | 
						||
+            "parameters": [
 | 
						||
+                { "name": "browserContextId", "$ref": "ContextID", "description": "Identifier of the context to delete." }
 | 
						||
+            ]
 | 
						||
+        },
 | 
						||
+        {
 | 
						||
+            "name": "createPage",
 | 
						||
+            "parameters": [
 | 
						||
+                { "name": "browserContextId", "$ref": "ContextID", "optional": true, "description": "JSON Inspector Protocol message (command) to be dispatched on the backend." }
 | 
						||
+            ],
 | 
						||
+            "returns": [
 | 
						||
+                { "name": "pageProxyId", "$ref": "PageProxyID", "description": "Unique identifier of the page proxy." }
 | 
						||
+            ]
 | 
						||
+        },
 | 
						||
+        {
 | 
						||
+            "name": "navigate",
 | 
						||
+            "async": true,
 | 
						||
+            "description": "Navigates current page to the given URL.",
 | 
						||
+            "parameters": [
 | 
						||
+                { "name": "url", "type": "string", "description": "URL to navigate the page to." },
 | 
						||
+                { "name": "pageProxyId", "$ref": "PageProxyID", "description": "Unique identifier of the page proxy." },
 | 
						||
+                { "name": "frameId", "$ref": "Network.FrameId", "optional": true, "description": "Id of the frame to navigate."},
 | 
						||
+                { "name": "referrer", "type": "string", "optional": true, "description": "Referrer URL." }
 | 
						||
+            ],
 | 
						||
+            "returns": [
 | 
						||
+                { "name": "loaderId", "$ref": "Network.LoaderId", "optional": true, "description": "Identifier of the loader associated with the navigation." }
 | 
						||
+            ]
 | 
						||
+        },
 | 
						||
+        {
 | 
						||
+            "name": "setIgnoreCertificateErrors",
 | 
						||
+            "description": "Change whether all certificate errors should be ignored.",
 | 
						||
+            "parameters": [
 | 
						||
+                { "name": "browserContextId", "$ref": "ContextID", "optional": true, "description": "Browser context id." },
 | 
						||
+                { "name": "ignore", "type": "boolean" }
 | 
						||
+            ]
 | 
						||
+        },
 | 
						||
+        {
 | 
						||
+            "name": "getAllCookies",
 | 
						||
+            "description": "Returns all cookies in the given browser context.",
 | 
						||
+            "async": true,
 | 
						||
+            "parameters": [
 | 
						||
+                { "name": "browserContextId", "$ref": "ContextID", "optional": true, "description": "Browser context id." }
 | 
						||
+            ],
 | 
						||
+            "returns": [
 | 
						||
+                { "name": "cookies", "type": "array", "items": { "$ref": "Cookie" }, "description": "Cookies." }
 | 
						||
+            ]
 | 
						||
+        },
 | 
						||
+        {
 | 
						||
+            "name": "setCookies",
 | 
						||
+            "description": "Sets cookies in the given browser context.",
 | 
						||
+            "async": true,
 | 
						||
+            "parameters": [
 | 
						||
+                { "name": "browserContextId", "$ref": "ContextID", "optional": true, "description": "Browser context id." },
 | 
						||
+                { "name": "cookies", "type": "array", "items": { "$ref": "SetCookieParam" }, "description": "Cookies." }
 | 
						||
+            ]
 | 
						||
+        },
 | 
						||
+        {
 | 
						||
+            "name": "deleteAllCookies",
 | 
						||
+            "description": "Deletes cookies in the given browser context.",
 | 
						||
+            "async": true,
 | 
						||
+            "parameters": [
 | 
						||
+                { "name": "browserContextId", "$ref": "ContextID", "optional": true, "description": "Browser context id." }
 | 
						||
+            ]
 | 
						||
+        },
 | 
						||
+        {
 | 
						||
+            "name": "setGeolocationOverride",
 | 
						||
+            "parameters": [
 | 
						||
+                { "name": "browserContextId", "$ref": "ContextID", "optional": true, "description": "Browser context id." },
 | 
						||
+                { "name": "geolocation", "$ref": "Geolocation", "optional": true, "description": "Geolocation to set, if missing emulates position unavailable." }
 | 
						||
+            ],
 | 
						||
+            "description": "Overrides the geolocation position or error."
 | 
						||
+        },
 | 
						||
+        {
 | 
						||
+            "name": "grantPermissions",
 | 
						||
+            "parameters": [
 | 
						||
+                { "name": "browserContextId", "$ref": "ContextID", "optional": true, "description": "Browser context id." },
 | 
						||
+                { "name": "origin", "type": "string" },
 | 
						||
+                { "name": "permissions", "type": "array", "items": { "type": "string" } }
 | 
						||
+            ],
 | 
						||
+            "description": "Overrides the permissions."
 | 
						||
+        },
 | 
						||
+        {
 | 
						||
+            "name": "resetPermissions",
 | 
						||
+            "parameters": [
 | 
						||
+                { "name": "browserContextId", "$ref": "ContextID", "optional": true, "description": "Browser context id." }
 | 
						||
+            ],
 | 
						||
+            "description": "Clears permission overrides."
 | 
						||
+        },
 | 
						||
+        {
 | 
						||
+            "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." }
 | 
						||
+            ]
 | 
						||
+        }
 | 
						||
+    ],
 | 
						||
+    "events": [
 | 
						||
+        {
 | 
						||
+            "name": "pageProxyCreated",
 | 
						||
+            "parameters": [
 | 
						||
+                { "name": "pageProxyInfo", "$ref": "PageProxyInfo" }
 | 
						||
+            ]
 | 
						||
+        },
 | 
						||
+        {
 | 
						||
+            "name": "pageProxyDestroyed",
 | 
						||
+            "parameters": [
 | 
						||
+                { "name": "pageProxyId", "$ref": "PageProxyID" }
 | 
						||
+            ]
 | 
						||
+        },
 | 
						||
+        {
 | 
						||
+            "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": "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." }
 | 
						||
+            ]
 | 
						||
+        }
 | 
						||
+    ]
 | 
						||
+}
 | 
						||
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 9e2bee913d37c79fedbb918176a43022b84fa45b..ad8926d773144114dad3842fa0fe239155a15d9e 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",
 | 
						||
@@ -32,7 +32,8 @@
 | 
						||
             "name": "workerCreated",
 | 
						||
             "parameters": [
 | 
						||
                 { "name": "workerId", "type": "string" },
 | 
						||
-                { "name": "url", "type": "string" }
 | 
						||
+                { "name": "url", "type": "string" },
 | 
						||
+                { "name": "frameId", "$ref": "Network.FrameId", "description": "Id of the frame this worker belongs to." }
 | 
						||
             ]
 | 
						||
         },
 | 
						||
         {
 | 
						||
diff --git a/Source/JavaScriptCore/runtime/DateConversion.cpp b/Source/JavaScriptCore/runtime/DateConversion.cpp
 | 
						||
index 955756ba405f400970610f9a68c7ed42a67cb015..1520c0a1475a90de2795e4ccd8919c1bb1384066 100644
 | 
						||
--- a/Source/JavaScriptCore/runtime/DateConversion.cpp
 | 
						||
+++ b/Source/JavaScriptCore/runtime/DateConversion.cpp
 | 
						||
@@ -100,17 +100,23 @@ String formatDateTime(const GregorianDateTime& t, DateTimeFormat format, bool as
 | 
						||
             appendNumber<2>(builder, offset / 60);
 | 
						||
             appendNumber<2>(builder, offset % 60);
 | 
						||
 
 | 
						||
-#if OS(WINDOWS)
 | 
						||
-            TIME_ZONE_INFORMATION timeZoneInformation;
 | 
						||
-            GetTimeZoneInformation(&timeZoneInformation);
 | 
						||
-            const WCHAR* winTimeZoneName = t.isDST() ? timeZoneInformation.DaylightName : timeZoneInformation.StandardName;
 | 
						||
-            String timeZoneName(winTimeZoneName);
 | 
						||
+            String timeZoneName;
 | 
						||
+            if (!WTF::timeZoneDisplayNameForAutomation().isEmpty()) {
 | 
						||
+                timeZoneName = WTF::timeZoneDisplayNameForAutomation();
 | 
						||
+            } else {
 | 
						||
+ #if OS(WINDOWS)
 | 
						||
+                TIME_ZONE_INFORMATION timeZoneInformation;
 | 
						||
+                GetTimeZoneInformation(&timeZoneInformation);
 | 
						||
+                const WCHAR* winTimeZoneName = t.isDST() ? timeZoneInformation.DaylightName : timeZoneInformation.StandardName;
 | 
						||
+                timeZoneName = String(winTimeZoneName);
 | 
						||
 #else
 | 
						||
-            struct tm gtm = t;
 | 
						||
-            char timeZoneName[70];
 | 
						||
-            strftime(timeZoneName, sizeof(timeZoneName), "%Z", >m);
 | 
						||
+                struct tm gtm = t;
 | 
						||
+                char tzName[70];
 | 
						||
+                strftime(tzName, sizeof(tzName), "%Z", >m);
 | 
						||
+                timeZoneName = String(tzName);
 | 
						||
 #endif
 | 
						||
-            if (timeZoneName[0]) {
 | 
						||
+            }
 | 
						||
+            if (!timeZoneName.isEmpty()) {
 | 
						||
                 builder.appendLiteral(" (");
 | 
						||
                 builder.append(timeZoneName);
 | 
						||
                 builder.append(')');
 | 
						||
diff --git a/Source/JavaScriptCore/runtime/IntlDateTimeFormat.cpp b/Source/JavaScriptCore/runtime/IntlDateTimeFormat.cpp
 | 
						||
index 9817a45ea2f3a22844ed3e56816cff94eb051423..67f7459a556ed22740fbfcd2b1b7b530d34d5bb5 100644
 | 
						||
--- a/Source/JavaScriptCore/runtime/IntlDateTimeFormat.cpp
 | 
						||
+++ b/Source/JavaScriptCore/runtime/IntlDateTimeFormat.cpp
 | 
						||
@@ -39,6 +39,7 @@
 | 
						||
 #include <unicode/ucal.h>
 | 
						||
 #include <unicode/udatpg.h>
 | 
						||
 #include <unicode/uenum.h>
 | 
						||
+#include <wtf/DateMath.h>
 | 
						||
 #include <wtf/text/StringBuilder.h>
 | 
						||
 
 | 
						||
 #if JSC_ICU_HAS_UFIELDPOSITER
 | 
						||
@@ -113,6 +114,10 @@ void IntlDateTimeFormat::setBoundFormat(VM& vm, JSBoundFunction* format)
 | 
						||
 
 | 
						||
 static String defaultTimeZone()
 | 
						||
 {
 | 
						||
+    String tz = WTF::timeZoneForAutomation();
 | 
						||
+    if (!tz.isEmpty())
 | 
						||
+        return tz;
 | 
						||
+
 | 
						||
     // 6.4.3 DefaultTimeZone () (ECMA-402 2.0)
 | 
						||
     // The DefaultTimeZone abstract operation returns a String value representing the valid (6.4.1) and canonicalized (6.4.2) time zone name for the host environment’s current time zone.
 | 
						||
 
 | 
						||
diff --git a/Source/WTF/wtf/DateMath.cpp b/Source/WTF/wtf/DateMath.cpp
 | 
						||
index 1999737341553001d5246b8190e9ea11d615a158..540ed892bca8110f8013477da7bd9b459a17e60d 100644
 | 
						||
--- a/Source/WTF/wtf/DateMath.cpp
 | 
						||
+++ b/Source/WTF/wtf/DateMath.cpp
 | 
						||
@@ -77,11 +77,16 @@
 | 
						||
 #include <limits>
 | 
						||
 #include <stdint.h>
 | 
						||
 #include <time.h>
 | 
						||
+#include <unicode/ucal.h>
 | 
						||
 #include <wtf/Assertions.h>
 | 
						||
 #include <wtf/ASCIICType.h>
 | 
						||
+#include <wtf/Language.h>
 | 
						||
 #include <wtf/MathExtras.h>
 | 
						||
+#include <wtf/NeverDestroyed.h>
 | 
						||
 #include <wtf/StdLibExtras.h>
 | 
						||
+#include <wtf/ThreadSpecific.h>
 | 
						||
 #include <wtf/text/StringBuilder.h>
 | 
						||
+#include <wtf/unicode/UTF8Conversion.h>
 | 
						||
 
 | 
						||
 #if OS(WINDOWS)
 | 
						||
 #include <windows.h>
 | 
						||
@@ -107,6 +112,18 @@ template<unsigned length> inline bool startsWithLettersIgnoringASCIICase(const c
 | 
						||
     return equalLettersIgnoringASCIICase(string, lowercaseLetters, length - 1);
 | 
						||
 }
 | 
						||
 
 | 
						||
+struct TimeZoneForAutomation {
 | 
						||
+    UCalendar* cal;
 | 
						||
+    String id;
 | 
						||
+    String displayName;
 | 
						||
+};
 | 
						||
+
 | 
						||
+static TimeZoneForAutomation& innerTimeZoneForAutomation()
 | 
						||
+{
 | 
						||
+    static NeverDestroyed<WTF::ThreadSpecific<TimeZoneForAutomation>> timeZoneForAutomation;
 | 
						||
+    return *timeZoneForAutomation.get();
 | 
						||
+}
 | 
						||
+
 | 
						||
 /* Constants */
 | 
						||
 
 | 
						||
 const char* const weekdayName[7] = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
 | 
						||
@@ -333,6 +350,14 @@ static double calculateDSTOffset(time_t localTime, double utcOffset)
 | 
						||
 // Returns combined offset in millisecond (UTC + DST).
 | 
						||
 LocalTimeOffset calculateLocalTimeOffset(double ms, TimeType inputTimeType)
 | 
						||
 {
 | 
						||
+    TimeZoneForAutomation& tz = innerTimeZoneForAutomation();
 | 
						||
+    if (tz.cal) {
 | 
						||
+        UErrorCode status = U_ZERO_ERROR;
 | 
						||
+        ucal_setMillis(tz.cal, ms, &status);
 | 
						||
+        int32_t offset = ucal_get(tz.cal, UCAL_ZONE_OFFSET, &status);
 | 
						||
+        int32_t dstOffset = ucal_get(tz.cal, UCAL_DST_OFFSET, &status);
 | 
						||
+        return LocalTimeOffset(dstOffset, offset + dstOffset);
 | 
						||
+    }
 | 
						||
 #if HAVE(TM_GMTOFF)
 | 
						||
     double localToUTCTimeOffset = inputTimeType == LocalTime ? calculateUTCOffset() : 0;
 | 
						||
 #else
 | 
						||
@@ -1034,4 +1059,65 @@ String makeRFC2822DateString(unsigned dayOfWeek, unsigned day, unsigned month, u
 | 
						||
     return stringBuilder.toString();
 | 
						||
 }
 | 
						||
 
 | 
						||
+bool setTimeZoneForAutomation(const String& timeZone)
 | 
						||
+{
 | 
						||
+    innerTimeZoneForAutomation().displayName = String();
 | 
						||
+    if (innerTimeZoneForAutomation().cal) {
 | 
						||
+        ucal_close(innerTimeZoneForAutomation().cal);
 | 
						||
+        innerTimeZoneForAutomation().cal = nullptr;
 | 
						||
+    }
 | 
						||
+    if (timeZone.isEmpty()) {
 | 
						||
+        innerTimeZoneForAutomation().id = String();
 | 
						||
+        return true;
 | 
						||
+    }
 | 
						||
+
 | 
						||
+    // Timezone is ascii.
 | 
						||
+    Vector<UChar> buffer(timeZone.length());
 | 
						||
+    UChar* bufferStart = buffer.data();
 | 
						||
+    CString ctz = timeZone.utf8();
 | 
						||
+    if (!Unicode::convertUTF8ToUTF16(ctz.data(), ctz.data() + ctz.length(), &bufferStart, bufferStart + timeZone.length()))
 | 
						||
+        return false;
 | 
						||
+
 | 
						||
+    Vector<UChar, 32> canonicalBuffer(32);
 | 
						||
+    UErrorCode status = U_ZERO_ERROR;
 | 
						||
+    auto canonicalLength = ucal_getCanonicalTimeZoneID(buffer.data(), buffer.size(), canonicalBuffer.data(), canonicalBuffer.size(), nullptr, &status);
 | 
						||
+    if (status == U_BUFFER_OVERFLOW_ERROR) {
 | 
						||
+        status = U_ZERO_ERROR;
 | 
						||
+        canonicalBuffer.grow(canonicalLength);
 | 
						||
+        ucal_getCanonicalTimeZoneID(buffer.data(), buffer.size(), canonicalBuffer.data(), canonicalLength, nullptr, &status);
 | 
						||
+    }
 | 
						||
+    if (!U_SUCCESS(status))
 | 
						||
+        return false;
 | 
						||
+
 | 
						||
+    UCalendar* cal = ucal_open(canonicalBuffer.data(), canonicalLength, nullptr, UCAL_TRADITIONAL, &status);
 | 
						||
+    if (!U_SUCCESS(status))
 | 
						||
+        return false;
 | 
						||
+
 | 
						||
+    Vector<UChar, 32> displayNameBuffer(32);
 | 
						||
+    auto displayNameLength = ucal_getTimeZoneDisplayName(cal, UCAL_STANDARD, defaultLanguage().utf8().data(), displayNameBuffer.data(), displayNameBuffer.size(), &status);
 | 
						||
+    if (status == U_BUFFER_OVERFLOW_ERROR) {
 | 
						||
+        status = U_ZERO_ERROR;
 | 
						||
+        displayNameBuffer.grow(displayNameLength);
 | 
						||
+        ucal_getTimeZoneDisplayName(cal, UCAL_STANDARD, defaultLanguage().utf8().data(), displayNameBuffer.data(), displayNameLength, &status);
 | 
						||
+    }
 | 
						||
+    if (!U_SUCCESS(status))
 | 
						||
+        return false;
 | 
						||
+
 | 
						||
+    TimeZoneForAutomation& tzfa = innerTimeZoneForAutomation();
 | 
						||
+    tzfa.cal = cal;
 | 
						||
+    tzfa.id = String(canonicalBuffer.data(), canonicalLength);
 | 
						||
+    tzfa.displayName = String(displayNameBuffer.data(), displayNameLength);
 | 
						||
+    return true;
 | 
						||
+}
 | 
						||
+
 | 
						||
+String timeZoneForAutomation()
 | 
						||
+{
 | 
						||
+    return innerTimeZoneForAutomation().id;
 | 
						||
+}
 | 
						||
+
 | 
						||
+String timeZoneDisplayNameForAutomation()
 | 
						||
+{
 | 
						||
+    return innerTimeZoneForAutomation().displayName;
 | 
						||
+}
 | 
						||
+
 | 
						||
 } // namespace WTF
 | 
						||
diff --git a/Source/WTF/wtf/DateMath.h b/Source/WTF/wtf/DateMath.h
 | 
						||
index 602f89a49d454cc5e5acd030024227d49d98c61f..41811e65bd0f15b443fb90d37ee4d0a21780a518 100644
 | 
						||
--- a/Source/WTF/wtf/DateMath.h
 | 
						||
+++ b/Source/WTF/wtf/DateMath.h
 | 
						||
@@ -389,6 +389,10 @@ inline int dayInMonthFromDayInYear(int dayInYear, bool leapYear)
 | 
						||
     return d - step;
 | 
						||
 }
 | 
						||
 
 | 
						||
+WTF_EXPORT_PRIVATE bool setTimeZoneForAutomation(const String& timeZone);
 | 
						||
+WTF_EXPORT_PRIVATE String timeZoneForAutomation();
 | 
						||
+WTF_EXPORT_PRIVATE String timeZoneDisplayNameForAutomation();
 | 
						||
+
 | 
						||
 // Returns combined offset in millisecond (UTC + DST).
 | 
						||
 WTF_EXPORT_PRIVATE LocalTimeOffset calculateLocalTimeOffset(double utcInMilliseconds, TimeType = UTCTime);
 | 
						||
 
 | 
						||
diff --git a/Source/WTF/wtf/PlatformHave.h b/Source/WTF/wtf/PlatformHave.h
 | 
						||
index 44004c2e0da3c19384459f5b305f6c6e8fe5d6ac..15478b41e06a7aff27ca9a25ab3afcffdc317608 100644
 | 
						||
--- a/Source/WTF/wtf/PlatformHave.h
 | 
						||
+++ b/Source/WTF/wtf/PlatformHave.h
 | 
						||
@@ -379,7 +379,7 @@
 | 
						||
 #define HAVE_NSHTTPCOOKIESTORAGE__INITWITHIDENTIFIER_WITH_INACCURATE_NULLABILITY 1
 | 
						||
 #endif
 | 
						||
 
 | 
						||
-#if (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101400) || PLATFORM(IOS) || PLATFORM(MACCATALYST)
 | 
						||
+#if (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101400) || PLATFORM(IOS) || PLATFORM(MACCATALYST) || PLATFORM(GTK) || PLATFORM(WPE) || PLATFORM(WIN)
 | 
						||
 #define HAVE_OS_DARK_MODE_SUPPORT 1
 | 
						||
 #endif
 | 
						||
 
 | 
						||
diff --git a/Source/WebCore/Modules/geolocation/Geolocation.cpp b/Source/WebCore/Modules/geolocation/Geolocation.cpp
 | 
						||
index 6d5be9a591a272cd67d6e9d097b30505bdf8ae5e..8f67ba28c380e844c8e4191ee704466559d88f97 100644
 | 
						||
--- a/Source/WebCore/Modules/geolocation/Geolocation.cpp
 | 
						||
+++ b/Source/WebCore/Modules/geolocation/Geolocation.cpp
 | 
						||
@@ -356,8 +356,9 @@ bool Geolocation::shouldBlockGeolocationRequests()
 | 
						||
     bool isSecure = SecurityOrigin::isSecure(document()->url());
 | 
						||
     bool hasMixedContent = !document()->foundMixedContent().isEmpty();
 | 
						||
     bool isLocalOrigin = securityOrigin()->isLocal();
 | 
						||
+    bool isPotentiallyTrustworthy = securityOrigin()->isPotentiallyTrustworthy();
 | 
						||
     if (securityOrigin()->canRequestGeolocation()) {
 | 
						||
-        if (isLocalOrigin || (isSecure && !hasMixedContent) || isRequestFromIBooks())
 | 
						||
+        if (isLocalOrigin || isPotentiallyTrustworthy || (isSecure && !hasMixedContent) || isRequestFromIBooks())
 | 
						||
             return false;
 | 
						||
     }
 | 
						||
     
 | 
						||
diff --git a/Source/WebCore/SourcesCocoa.txt b/Source/WebCore/SourcesCocoa.txt
 | 
						||
index c80b21a94fc00b0a619b44ef35470e63d86e72f1..3d72a82e755de4bf92895ad499788d5ff459168b 100644
 | 
						||
--- a/Source/WebCore/SourcesCocoa.txt
 | 
						||
+++ b/Source/WebCore/SourcesCocoa.txt
 | 
						||
@@ -649,7 +649,7 @@ WHLSLStandardLibraryFunctionMap.cpp
 | 
						||
 
 | 
						||
 #endif
 | 
						||
 
 | 
						||
-#if ENABLE_IOS_TOUCH_EVENTS
 | 
						||
+#if ENABLE_TOUCH_EVENTS
 | 
						||
 
 | 
						||
     JSTouch.cpp
 | 
						||
     JSTouchEvent.cpp
 | 
						||
diff --git a/Source/WebCore/WebCore.order b/Source/WebCore/WebCore.order
 | 
						||
index 34f1a72596fb89c8b647fff3348cca3d959c014c..ab6e42c4da2a8a77f66ce532a3a12bb9ee991207 100644
 | 
						||
--- a/Source/WebCore/WebCore.order
 | 
						||
+++ b/Source/WebCore/WebCore.order
 | 
						||
@@ -3094,7 +3094,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 6d625ee04539635a97fe0d9b21a6b2d970ef2ddf..5d27dbb03899a0ef914452436b6c2a2149d3f708 100644
 | 
						||
--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj
 | 
						||
+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj
 | 
						||
@@ -4972,6 +4972,14 @@
 | 
						||
 		EDE3A5000C7A430600956A37 /* ColorMac.h in Headers */ = {isa = PBXBuildFile; fileRef = EDE3A4FF0C7A430600956A37 /* ColorMac.h */; settings = {ATTRIBUTES = (Private, ); }; };
 | 
						||
 		EDEC98030AED7E170059137F /* WebCorePrefix.h in Headers */ = {isa = PBXBuildFile; fileRef = EDEC98020AED7E170059137F /* WebCorePrefix.h */; };
 | 
						||
 		EFCC6C8F20FE914400A2321B /* CanvasActivityRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = EFCC6C8D20FE914000A2321B /* CanvasActivityRecord.h */; settings = {ATTRIBUTES = (Private, ); }; };
 | 
						||
+		F050E16823AC9C080011CE47 /* PlatformTouchEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = F050E16623AC9C070011CE47 /* PlatformTouchEvent.h */; settings = {ATTRIBUTES = (Private, ); }; };
 | 
						||
+		F050E16A23AD660C0011CE47 /* Touch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F050E16923AD660C0011CE47 /* Touch.cpp */; };
 | 
						||
+		F050E16D23AD66630011CE47 /* TouchList.h in Headers */ = {isa = PBXBuildFile; fileRef = F050E16B23AD66620011CE47 /* TouchList.h */; settings = {ATTRIBUTES = (Private, ); }; };
 | 
						||
+		F050E16E23AD66630011CE47 /* TouchList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F050E16C23AD66630011CE47 /* TouchList.cpp */; };
 | 
						||
+		F050E17123AD669F0011CE47 /* TouchEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F050E16F23AD669E0011CE47 /* TouchEvent.cpp */; };
 | 
						||
+		F050E17223AD669F0011CE47 /* TouchEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = F050E17023AD669F0011CE47 /* TouchEvent.h */; settings = {ATTRIBUTES = (Private, ); }; };
 | 
						||
+		F050E17423AD6A800011CE47 /* DocumentTouch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F050E17323AD6A800011CE47 /* DocumentTouch.cpp */; };
 | 
						||
+		F050E17823AD70C50011CE47 /* PlatformTouchPoint.h in Headers */ = {isa = PBXBuildFile; fileRef = F050E17623AD70C40011CE47 /* PlatformTouchPoint.h */; settings = {ATTRIBUTES = (Private, ); }; };
 | 
						||
 		F12171F516A8CED2000053CA /* WebVTTElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F12171F316A8BC63000053CA /* WebVTTElement.cpp */; };
 | 
						||
 		F12171F616A8CF0B000053CA /* WebVTTElement.h in Headers */ = {isa = PBXBuildFile; fileRef = F12171F416A8BC63000053CA /* WebVTTElement.h */; };
 | 
						||
 		F32BDCD92363AACA0073B6AE /* UserGestureEmulationScope.h in Headers */ = {isa = PBXBuildFile; fileRef = F32BDCD72363AACA0073B6AE /* UserGestureEmulationScope.h */; };
 | 
						||
@@ -15456,6 +15464,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>"; };
 | 
						||
@@ -20694,7 +20710,12 @@
 | 
						||
 				2D2E34A921A4E191004598B5 /* EditableImageReference.h */,
 | 
						||
 				1AF326770D78B9440068F0C4 /* EditorClient.h */,
 | 
						||
 				93C09A800B064F00005ABD4D /* EventHandler.cpp */,
 | 
						||
+				F050E16F23AD669E0011CE47 /* TouchEvent.cpp */,
 | 
						||
+				F050E17023AD669F0011CE47 /* TouchEvent.h */,
 | 
						||
 				93C09A520B064DB3005ABD4D /* EventHandler.h */,
 | 
						||
+				F050E16923AD660C0011CE47 /* Touch.cpp */,
 | 
						||
+				F050E16C23AD66630011CE47 /* TouchList.cpp */,
 | 
						||
+				F050E16B23AD66620011CE47 /* TouchList.h */,
 | 
						||
 				E0FEF371B27C53EAC1C1FBEE /* EventSource.cpp */,
 | 
						||
 				E0FEF371B17C53EAC1C1FBEE /* EventSource.h */,
 | 
						||
 				E0FEF371B07C53EAC1C1FBEE /* EventSource.idl */,
 | 
						||
@@ -25934,7 +25955,9 @@
 | 
						||
 				1A2E6E560CC551E0004A2062 /* sql */,
 | 
						||
 				B2C3D9EC0D006C1D00EF6F26 /* text */,
 | 
						||
 				DFDB912CF8E88A6DA1AD264F /* AbortableTaskQueue.h */,
 | 
						||
+				F050E16623AC9C070011CE47 /* PlatformTouchEvent.h */,
 | 
						||
 				49AE2D94134EE5F90072920A /* CalculationValue.cpp */,
 | 
						||
+				F050E17623AD70C40011CE47 /* PlatformTouchPoint.h */,
 | 
						||
 				49AE2D95134EE5F90072920A /* CalculationValue.h */,
 | 
						||
 				C330A22113EC196B0000B45B /* ColorChooser.h */,
 | 
						||
 				C37CDEBC149EF2030042090D /* ColorChooserClient.h */,
 | 
						||
@@ -28162,6 +28185,7 @@
 | 
						||
 				BCCFBAE70B5152ED0001F1D7 /* DocumentParser.h */,
 | 
						||
 				AD6E71AA1668899D00320C13 /* DocumentSharedObjectPool.cpp */,
 | 
						||
 				AD6E71AB1668899D00320C13 /* DocumentSharedObjectPool.h */,
 | 
						||
+				F050E17323AD6A800011CE47 /* DocumentTouch.cpp */,
 | 
						||
 				6BDB5DC1227BD3B800919770 /* DocumentStorageAccess.cpp */,
 | 
						||
 				6BDB5DC0227BD3B800919770 /* DocumentStorageAccess.h */,
 | 
						||
 				6BDB5DC5227CA0EB00919770 /* DocumentStorageAccess.idl */,
 | 
						||
@@ -29046,6 +29070,7 @@
 | 
						||
 				93C4F6EB1108F9A50099D0DB /* AccessibilityScrollbar.h in Headers */,
 | 
						||
 				29489FC712C00F0300D83F0F /* AccessibilityScrollView.h in Headers */,
 | 
						||
 				0709FC4E1025DEE30059CDBA /* AccessibilitySlider.h in Headers */,
 | 
						||
+				F050E16D23AD66630011CE47 /* TouchList.h in Headers */,
 | 
						||
 				29D7BCFA1444AF7D0070619C /* AccessibilitySpinButton.h in Headers */,
 | 
						||
 				69A6CBAD1C6BE42C00B836E9 /* AccessibilitySVGElement.h in Headers */,
 | 
						||
 				AAC08CF315F941FD00F1E188 /* AccessibilitySVGRoot.h in Headers */,
 | 
						||
@@ -30908,6 +30933,7 @@
 | 
						||
 				6E4ABCD5138EA0B70071D291 /* JSHTMLUnknownElement.h in Headers */,
 | 
						||
 				E44614170CD6826900FADA75 /* JSHTMLVideoElement.h in Headers */,
 | 
						||
 				81BE20D311F4BC3200915DFA /* JSIDBCursor.h in Headers */,
 | 
						||
+				F050E17823AD70C50011CE47 /* PlatformTouchPoint.h in Headers */,
 | 
						||
 				7C3D8EF01E0B21430023B084 /* JSIDBCursorDirection.h in Headers */,
 | 
						||
 				C585A68311D4FB08004C3E4B /* JSIDBDatabase.h in Headers */,
 | 
						||
 				C585A69711D4FB13004C3E4B /* JSIDBFactory.h in Headers */,
 | 
						||
@@ -32821,9 +32847,11 @@
 | 
						||
 				A7DBF8DE1276919C006B6008 /* TextCheckingHelper.h in Headers */,
 | 
						||
 				B2C3DA3A0D006C1D00EF6F26 /* TextCodec.h in Headers */,
 | 
						||
 				26E98A10130A9FCA008EB7B2 /* TextCodecASCIIFastPath.h in Headers */,
 | 
						||
+				F050E16823AC9C080011CE47 /* PlatformTouchEvent.h in Headers */,
 | 
						||
 				B2C3DA3C0D006C1D00EF6F26 /* TextCodecICU.h in Headers */,
 | 
						||
 				B2C3DA3E0D006C1D00EF6F26 /* TextCodecLatin1.h in Headers */,
 | 
						||
 				57EF5E601D20C83900171E60 /* TextCodecReplacement.h in Headers */,
 | 
						||
+				F050E17223AD669F0011CE47 /* TouchEvent.h in Headers */,
 | 
						||
 				B2C3DA400D006C1D00EF6F26 /* TextCodecUserDefined.h in Headers */,
 | 
						||
 				B2C3DA420D006C1D00EF6F26 /* TextCodecUTF16.h in Headers */,
 | 
						||
 				9343CB8212F25E510033C5EE /* TextCodecUTF8.h in Headers */,
 | 
						||
@@ -33707,6 +33735,7 @@
 | 
						||
 				CDDE02ED18B3ED6D00CF7FF1 /* CDMSessionAVFoundationObjC.mm in Sources */,
 | 
						||
 				CDDE02F018B5651300CF7FF1 /* CDMSessionAVStreamSession.mm in Sources */,
 | 
						||
 				CDE5959D1BF2757100A1CBE8 /* CDMSessionMediaSourceAVFObjC.mm in Sources */,
 | 
						||
+				F050E17123AD669F0011CE47 /* TouchEvent.cpp in Sources */,
 | 
						||
 				A14090FB1AA51E1D0091191A /* ContentFilterUnblockHandlerCocoa.mm in Sources */,
 | 
						||
 				07AFF4231EFB144900B545B3 /* CoreAudioCaptureSourceIOS.mm in Sources */,
 | 
						||
 				46C696CC1E7205FC00597937 /* CPUMonitor.cpp in Sources */,
 | 
						||
@@ -33781,6 +33810,7 @@
 | 
						||
 				51058ADF1D67C229009A538C /* MockGamepad.cpp in Sources */,
 | 
						||
 				51058AE11D67C229009A538C /* MockGamepadProvider.cpp in Sources */,
 | 
						||
 				CDF2B0121820540600F2B424 /* MockMediaPlayerMediaSource.cpp in Sources */,
 | 
						||
+				F050E17423AD6A800011CE47 /* DocumentTouch.cpp in Sources */,
 | 
						||
 				CDF2B0141820540600F2B424 /* MockMediaSourcePrivate.cpp in Sources */,
 | 
						||
 				CDF2B0161820540700F2B424 /* MockSourceBufferPrivate.cpp in Sources */,
 | 
						||
 				2D9BF7421DBFDC27007A7D99 /* NavigatorEME.cpp in Sources */,
 | 
						||
@@ -33867,6 +33897,7 @@
 | 
						||
 				538EC8881F993F9C004D22A8 /* UnifiedSource23.cpp in Sources */,
 | 
						||
 				DE5F85801FA1ABF4006DB63A /* UnifiedSource24-mm.mm in Sources */,
 | 
						||
 				538EC8891F993F9D004D22A8 /* UnifiedSource24.cpp in Sources */,
 | 
						||
+				F050E16E23AD66630011CE47 /* TouchList.cpp in Sources */,
 | 
						||
 				DE5F85811FA1ABF4006DB63A /* UnifiedSource25-mm.mm in Sources */,
 | 
						||
 				538EC88A1F993F9D004D22A8 /* UnifiedSource25.cpp in Sources */,
 | 
						||
 				DE5F85821FA1ABF4006DB63A /* UnifiedSource26-mm.mm in Sources */,
 | 
						||
@@ -34399,6 +34430,7 @@
 | 
						||
 				2D8B92F1203D13E1009C868F /* UnifiedSource516.cpp in Sources */,
 | 
						||
 				2D8B92F2203D13E1009C868F /* UnifiedSource517.cpp in Sources */,
 | 
						||
 				2D8B92F3203D13E1009C868F /* UnifiedSource518.cpp in Sources */,
 | 
						||
+				F050E16A23AD660C0011CE47 /* Touch.cpp in Sources */,
 | 
						||
 				2D8B92F4203D13E1009C868F /* UnifiedSource519.cpp in Sources */,
 | 
						||
 				2D8B92F5203D13E1009C868F /* UnifiedSource520.cpp in Sources */,
 | 
						||
 				2D8B92F6203D13E1009C868F /* UnifiedSource521.cpp in Sources */,
 | 
						||
diff --git a/Source/WebCore/css/MediaQueryEvaluator.cpp b/Source/WebCore/css/MediaQueryEvaluator.cpp
 | 
						||
index 2ac163067f2e00a595c425a91fc3a55617baf689..0f492b539ed56f7f963fdf5a72ab75f8f7ea89ab 100644
 | 
						||
--- a/Source/WebCore/css/MediaQueryEvaluator.cpp
 | 
						||
+++ b/Source/WebCore/css/MediaQueryEvaluator.cpp
 | 
						||
@@ -387,7 +387,7 @@ static bool deviceAspectRatioEvaluate(CSSValue* value, const CSSToLengthConversi
 | 
						||
     if (!value)
 | 
						||
         return true;
 | 
						||
 
 | 
						||
-    auto size = screenRect(frame.mainFrame().view()).size();
 | 
						||
+    auto size = frame.page()->screenSize();
 | 
						||
     bool result = compareAspectRatioValue(value, size.width(), size.height(), op);
 | 
						||
     LOG_WITH_STREAM(MediaQueries, stream << "  deviceAspectRatioEvaluate: " << op << " " << aspectRatioValueAsString(value) << " actual screen size " << size << ": " << result);
 | 
						||
     return result;
 | 
						||
@@ -505,7 +505,7 @@ static bool deviceHeightEvaluate(CSSValue* value, const CSSToLengthConversionDat
 | 
						||
     if (!value)
 | 
						||
         return true;
 | 
						||
     int length;
 | 
						||
-    auto height = screenRect(frame.mainFrame().view()).height();
 | 
						||
+    auto height = frame.page()->screenSize().height();
 | 
						||
     if (!computeLength(value, !frame.document()->inQuirksMode(), conversionData, length))
 | 
						||
         return false;
 | 
						||
 
 | 
						||
@@ -520,8 +520,10 @@ static bool deviceWidthEvaluate(CSSValue* value, const CSSToLengthConversionData
 | 
						||
     // assume if we have a device, assume non-zero
 | 
						||
     if (!value)
 | 
						||
         return true;
 | 
						||
+    if (!frame.mainFrame().view())
 | 
						||
+        return false;
 | 
						||
     int length;
 | 
						||
-    auto width = screenRect(frame.mainFrame().view()).width();
 | 
						||
+    auto width = frame.page()->screenSize().width();
 | 
						||
     if (!computeLength(value, !frame.document()->inQuirksMode(), conversionData, length))
 | 
						||
         return false;
 | 
						||
 
 | 
						||
diff --git a/Source/WebCore/dom/UserGestureIndicator.cpp b/Source/WebCore/dom/UserGestureIndicator.cpp
 | 
						||
index dfec93b644f72a51bad0bebf396da61c57f6e428..353833a7614a55566862c196bafc598a475536a1 100644
 | 
						||
--- a/Source/WebCore/dom/UserGestureIndicator.cpp
 | 
						||
+++ b/Source/WebCore/dom/UserGestureIndicator.cpp
 | 
						||
@@ -56,8 +56,7 @@ UserGestureIndicator::UserGestureIndicator(Optional<ProcessingUserGestureState>
 | 
						||
 
 | 
						||
     if (state)
 | 
						||
         currentToken() = UserGestureToken::create(state.value(), gestureType);
 | 
						||
-
 | 
						||
-    if (document && currentToken()->processingUserGesture() && state) {
 | 
						||
+    if (document && state && currentToken()->processingUserGesture()) {
 | 
						||
         document->updateLastHandledUserGestureTimestamp(currentToken()->startTime());
 | 
						||
         if (processInteractionStyle == ProcessInteractionStyle::Immediate)
 | 
						||
             ResourceLoadObserver::shared().logUserInteractionWithReducedTimeResolution(document->topDocument());
 | 
						||
diff --git a/Source/WebCore/html/FileInputType.cpp b/Source/WebCore/html/FileInputType.cpp
 | 
						||
index 4e41fd3f807e8f34bfef3f63f0ba6119a619821e..1f7be602cb2134f8867bf95afe0c9337bce57055 100644
 | 
						||
--- a/Source/WebCore/html/FileInputType.cpp
 | 
						||
+++ b/Source/WebCore/html/FileInputType.cpp
 | 
						||
@@ -36,6 +36,7 @@
 | 
						||
 #include "HTMLNames.h"
 | 
						||
 #include "Icon.h"
 | 
						||
 #include "InputTypeNames.h"
 | 
						||
+#include "InspectorInstrumentation.h"
 | 
						||
 #include "LocalizedStrings.h"
 | 
						||
 #include "RenderFileUploadControl.h"
 | 
						||
 #include "RuntimeEnabledFeatures.h"
 | 
						||
@@ -205,6 +206,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 7d50ddc7a38a3723e4ee7d66ca97c8acb37c726a..7ee70c6dd4bb84012a682ed648dc3c0cbd8ad211 100644
 | 
						||
--- a/Source/WebCore/inspector/InspectorController.cpp
 | 
						||
+++ b/Source/WebCore/inspector/InspectorController.cpp
 | 
						||
@@ -510,4 +510,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 cd4497c9cdf7e3dc7fe89ffdbf188d47f2aaa00d..8cadb40ac6cd04fa3921866a6c4d3142518cb0c3 100644
 | 
						||
--- a/Source/WebCore/inspector/InspectorController.h
 | 
						||
+++ b/Source/WebCore/inspector/InspectorController.h
 | 
						||
@@ -100,6 +100,10 @@ public:
 | 
						||
     WEBCORE_EXPORT void willComposite(Frame&);
 | 
						||
     WEBCORE_EXPORT void didComposite(Frame&);
 | 
						||
 
 | 
						||
+    WEBCORE_EXPORT void pauseWhenShown();
 | 
						||
+    WEBCORE_EXPORT void resumeIfPausedInNewWindow();
 | 
						||
+    WEBCORE_EXPORT void didShowNewWindow();
 | 
						||
+
 | 
						||
     bool isUnderTest() const { return m_isUnderTest; }
 | 
						||
     void setIsUnderTest(bool isUnderTest) { m_isUnderTest = isUnderTest; }
 | 
						||
     WEBCORE_EXPORT void evaluateForTestInFrontend(const String& script);
 | 
						||
@@ -149,6 +153,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 3dc7b494d6656a91c7dd9c68e1c9eaf789666d01..54ff59eaec197fdd12248cd4542b91db2b5bb83a 100644
 | 
						||
--- a/Source/WebCore/inspector/InspectorInstrumentation.cpp
 | 
						||
+++ b/Source/WebCore/inspector/InspectorInstrumentation.cpp
 | 
						||
@@ -621,6 +621,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.pageRuntimeAgent())
 | 
						||
+        pageRuntimeAgent->didReceiveMainResourceError(frame);
 | 
						||
+}
 | 
						||
+
 | 
						||
 void InspectorInstrumentation::willLoadXHRSynchronouslyImpl(InstrumentingAgents& instrumentingAgents)
 | 
						||
 {
 | 
						||
     if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent())
 | 
						||
@@ -653,20 +659,17 @@ void InspectorInstrumentation::didReceiveScriptResponseImpl(InstrumentingAgents&
 | 
						||
 
 | 
						||
 void InspectorInstrumentation::domContentLoadedEventFiredImpl(InstrumentingAgents& instrumentingAgents, Frame& frame)
 | 
						||
 {
 | 
						||
-    if (!frame.isMainFrame())
 | 
						||
-        return;
 | 
						||
-
 | 
						||
     if (InspectorPageAgent* pageAgent = instrumentingAgents.inspectorPageAgent())
 | 
						||
-        pageAgent->domContentEventFired();
 | 
						||
+        pageAgent->domContentEventFired(frame);
 | 
						||
 }
 | 
						||
 
 | 
						||
 void InspectorInstrumentation::loadEventFiredImpl(InstrumentingAgents& instrumentingAgents, Frame* frame)
 | 
						||
 {
 | 
						||
-    if (!frame || !frame->isMainFrame())
 | 
						||
+    if (!frame)
 | 
						||
         return;
 | 
						||
 
 | 
						||
     if (InspectorPageAgent* pageAgent = instrumentingAgents.inspectorPageAgent())
 | 
						||
-        pageAgent->loadEventFired();
 | 
						||
+        pageAgent->loadEventFired(*frame);
 | 
						||
 }
 | 
						||
 
 | 
						||
 void InspectorInstrumentation::frameDetachedFromParentImpl(InstrumentingAgents& instrumentingAgents, Frame& frame)
 | 
						||
@@ -744,12 +747,6 @@ void InspectorInstrumentation::frameDocumentUpdatedImpl(InstrumentingAgents& ins
 | 
						||
         pageDOMDebuggerAgent->frameDocumentUpdated(frame);
 | 
						||
 }
 | 
						||
 
 | 
						||
-void InspectorInstrumentation::loaderDetachedFromFrameImpl(InstrumentingAgents& instrumentingAgents, DocumentLoader& loader)
 | 
						||
-{
 | 
						||
-    if (InspectorPageAgent* inspectorPageAgent = instrumentingAgents.inspectorPageAgent())
 | 
						||
-        inspectorPageAgent->loaderDetachedFromFrame(loader);
 | 
						||
-}
 | 
						||
-
 | 
						||
 void InspectorInstrumentation::frameStartedLoadingImpl(InstrumentingAgents& instrumentingAgents, Frame& frame)
 | 
						||
 {
 | 
						||
     if (frame.isMainFrame()) {
 | 
						||
@@ -786,6 +783,12 @@ void InspectorInstrumentation::frameClearedScheduledNavigationImpl(Instrumenting
 | 
						||
         inspectorPageAgent->frameClearedScheduledNavigation(frame);
 | 
						||
 }
 | 
						||
 
 | 
						||
+void InspectorInstrumentation::didNavigateWithinPageImpl(InstrumentingAgents& instrumentingAgents, Frame& frame)
 | 
						||
+{
 | 
						||
+    if (InspectorPageAgent* inspectorPageAgent = instrumentingAgents.inspectorPageAgent())
 | 
						||
+        inspectorPageAgent->didNavigateWithinPage(frame);
 | 
						||
+}
 | 
						||
+
 | 
						||
 void InspectorInstrumentation::defaultAppearanceDidChangeImpl(InstrumentingAgents& instrumentingAgents, bool useDarkAppearance)
 | 
						||
 {
 | 
						||
     if (InspectorPageAgent* inspectorPageAgent = instrumentingAgents.inspectorPageAgent())
 | 
						||
@@ -1288,6 +1291,31 @@ void InspectorInstrumentation::renderLayerDestroyedImpl(InstrumentingAgents& ins
 | 
						||
         layerTreeAgent->renderLayerDestroyed(renderLayer);
 | 
						||
 }
 | 
						||
 
 | 
						||
+void InspectorInstrumentation::runOpenPanelImpl(InstrumentingAgents& instrumentingAgents, HTMLInputElement* element, bool* intercept)
 | 
						||
+{
 | 
						||
+    if (InspectorPageAgent* pageAgent = instrumentingAgents.inspectorPageAgent())
 | 
						||
+        pageAgent->runOpenPanel(element, intercept);
 | 
						||
+}
 | 
						||
+
 | 
						||
+void InspectorInstrumentation::frameAttachedImpl(InstrumentingAgents& instrumentingAgents, Frame& frame) {
 | 
						||
+    if (InspectorPageAgent* pageAgent = instrumentingAgents.inspectorPageAgent())
 | 
						||
+        pageAgent->frameAttached(frame);
 | 
						||
+}
 | 
						||
+
 | 
						||
+bool InspectorInstrumentation::shouldBypassCSPImpl(InstrumentingAgents& instrumentingAgents)
 | 
						||
+{
 | 
						||
+    if (InspectorPageAgent* pageAgent = instrumentingAgents.inspectorPageAgent())
 | 
						||
+        return pageAgent->shouldBypassCSP();
 | 
						||
+    return false;
 | 
						||
+}
 | 
						||
+
 | 
						||
+bool InspectorInstrumentation::interceptRequestImpl(InstrumentingAgents& instrumentingAgents, ResourceLoader& loader, Function<void(bool handled)>&& handler)
 | 
						||
+{
 | 
						||
+    if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent())
 | 
						||
+        return networkAgent->interceptRequest(loader, WTFMove(handler));
 | 
						||
+    return false;
 | 
						||
+}
 | 
						||
+
 | 
						||
 InstrumentingAgents& InspectorInstrumentation::instrumentingAgentsForWorkerGlobalScope(WorkerGlobalScope& workerGlobalScope)
 | 
						||
 {
 | 
						||
     return workerGlobalScope.inspectorController().m_instrumentingAgents;
 | 
						||
diff --git a/Source/WebCore/inspector/InspectorInstrumentation.h b/Source/WebCore/inspector/InspectorInstrumentation.h
 | 
						||
index b246eaa559a75265c890dfa47d01d311c186a403..57460008e1925fe15ea37d1eee194836afed8370 100644
 | 
						||
--- a/Source/WebCore/inspector/InspectorInstrumentation.h
 | 
						||
+++ b/Source/WebCore/inspector/InspectorInstrumentation.h
 | 
						||
@@ -45,11 +45,13 @@
 | 
						||
 #include "HitTestResult.h"
 | 
						||
 #include "InspectorInstrumentationPublic.h"
 | 
						||
 #include "Page.h"
 | 
						||
+#include "ResourceLoader.h"
 | 
						||
 #include "StorageArea.h"
 | 
						||
 #include "WebAnimation.h"
 | 
						||
 #include <JavaScriptCore/ConsoleMessage.h>
 | 
						||
 #include <initializer_list>
 | 
						||
 #include <wtf/CompletionHandler.h>
 | 
						||
+#include <wtf/Function.h>
 | 
						||
 #include <wtf/MemoryPressureHandler.h>
 | 
						||
 #include <wtf/RefPtr.h>
 | 
						||
 
 | 
						||
@@ -77,6 +79,7 @@ class DOMWrapperWorld;
 | 
						||
 class Document;
 | 
						||
 class DocumentLoader;
 | 
						||
 class EventListener;
 | 
						||
+class HTMLInputElement;
 | 
						||
 class HTTPHeaderMap;
 | 
						||
 class InspectorTimelineAgent;
 | 
						||
 class InstrumentingAgents;
 | 
						||
@@ -197,6 +200,7 @@ public:
 | 
						||
     static void didReceiveData(Frame*, unsigned long identifier, const char* data, int dataLength, int encodedDataLength);
 | 
						||
     static void didFinishLoading(Frame*, DocumentLoader*, unsigned long identifier, const NetworkLoadMetrics&, ResourceLoader*);
 | 
						||
     static void didFailLoading(Frame*, DocumentLoader*, unsigned long identifier, const ResourceError&);
 | 
						||
+    static void didReceiveMainResourceError(Frame&, const ResourceError&);
 | 
						||
 
 | 
						||
     static void willSendRequest(WorkerGlobalScope&, unsigned long identifier, ResourceRequest&);
 | 
						||
     static void didReceiveResourceResponse(WorkerGlobalScope&, unsigned long identifier, const ResourceResponse&);
 | 
						||
@@ -223,11 +227,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&);
 | 
						||
     static void defaultAppearanceDidChange(Page&, bool useDarkAppearance);
 | 
						||
     static void willDestroyCachedResource(CachedResource&);
 | 
						||
 
 | 
						||
@@ -317,6 +321,11 @@ 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 bool interceptRequest(ResourceLoader&, Function<void(bool handled)>&&);
 | 
						||
+
 | 
						||
     static void frontendCreated();
 | 
						||
     static void frontendDeleted();
 | 
						||
     static bool hasFrontends() { return InspectorInstrumentationPublic::hasFrontends(); }
 | 
						||
@@ -417,6 +426,7 @@ private:
 | 
						||
     static void didReceiveDataImpl(InstrumentingAgents&, unsigned long identifier, const char* data, int dataLength, int encodedDataLength);
 | 
						||
     static void didFinishLoadingImpl(InstrumentingAgents&, unsigned long identifier, DocumentLoader*, const NetworkLoadMetrics&, ResourceLoader*);
 | 
						||
     static void didFailLoadingImpl(InstrumentingAgents&, unsigned long identifier, DocumentLoader*, const ResourceError&);
 | 
						||
+    static void didReceiveMainResourceErrorImpl(InstrumentingAgents&, Frame&, const ResourceError&);
 | 
						||
     static void willLoadXHRSynchronouslyImpl(InstrumentingAgents&);
 | 
						||
     static void didLoadXHRSynchronouslyImpl(InstrumentingAgents&);
 | 
						||
     static void scriptImportedImpl(InstrumentingAgents&, unsigned long identifier, const String& sourceString);
 | 
						||
@@ -427,11 +437,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&);
 | 
						||
     static void defaultAppearanceDidChangeImpl(InstrumentingAgents&, bool useDarkAppearance);
 | 
						||
     static void willDestroyCachedResourceImpl(CachedResource&);
 | 
						||
 
 | 
						||
@@ -517,6 +527,11 @@ 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 bool interceptRequestImpl(InstrumentingAgents&, ResourceLoader&, Function<void(bool handled)>&&);
 | 
						||
+
 | 
						||
     static InstrumentingAgents& instrumentingAgentsForPage(Page&);
 | 
						||
     static InstrumentingAgents& instrumentingAgentsForWorkerGlobalScope(WorkerGlobalScope&);
 | 
						||
 
 | 
						||
@@ -1097,6 +1112,13 @@ inline void InspectorInstrumentation::didFailLoading(Frame* frame, DocumentLoade
 | 
						||
         didFailLoadingImpl(*instrumentingAgents, identifier, loader, error);
 | 
						||
 }
 | 
						||
 
 | 
						||
+inline void InspectorInstrumentation::didReceiveMainResourceError(Frame& frame, const ResourceError& error)
 | 
						||
+{
 | 
						||
+    FAST_RETURN_IF_NO_FRONTENDS(void());
 | 
						||
+    if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame))
 | 
						||
+        didReceiveMainResourceErrorImpl(*instrumentingAgents, frame, error);
 | 
						||
+}
 | 
						||
+
 | 
						||
 inline void InspectorInstrumentation::didFailLoading(WorkerGlobalScope& workerGlobalScope, unsigned long identifier, const ResourceError& error)
 | 
						||
 {
 | 
						||
     didFailLoadingImpl(instrumentingAgentsForWorkerGlobalScope(workerGlobalScope), identifier, nullptr, error);
 | 
						||
@@ -1192,13 +1214,6 @@ inline void InspectorInstrumentation::frameDocumentUpdated(Frame& frame)
 | 
						||
         frameDocumentUpdatedImpl(*instrumentingAgents, frame);
 | 
						||
 }
 | 
						||
 
 | 
						||
-inline void InspectorInstrumentation::loaderDetachedFromFrame(Frame& frame, DocumentLoader& loader)
 | 
						||
-{
 | 
						||
-    FAST_RETURN_IF_NO_FRONTENDS(void());
 | 
						||
-    if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame))
 | 
						||
-        loaderDetachedFromFrameImpl(*instrumentingAgents, loader);
 | 
						||
-}
 | 
						||
-
 | 
						||
 inline void InspectorInstrumentation::frameStartedLoading(Frame& frame)
 | 
						||
 {
 | 
						||
     FAST_RETURN_IF_NO_FRONTENDS(void());
 | 
						||
@@ -1227,6 +1242,13 @@ inline void InspectorInstrumentation::frameClearedScheduledNavigation(Frame& fra
 | 
						||
         frameClearedScheduledNavigationImpl(*instrumentingAgents, frame);
 | 
						||
 }
 | 
						||
 
 | 
						||
+inline void InspectorInstrumentation::didNavigateWithinPage(Frame& frame)
 | 
						||
+{
 | 
						||
+    FAST_RETURN_IF_NO_FRONTENDS(void());
 | 
						||
+    if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame))
 | 
						||
+        didNavigateWithinPageImpl(*instrumentingAgents, frame);
 | 
						||
+}
 | 
						||
+
 | 
						||
 inline void InspectorInstrumentation::defaultAppearanceDidChange(Page& page, bool useDarkAppearance)
 | 
						||
 {
 | 
						||
     FAST_RETURN_IF_NO_FRONTENDS(void());
 | 
						||
@@ -1677,6 +1699,36 @@ inline void InspectorInstrumentation::renderLayerDestroyed(Page* page, const Ren
 | 
						||
         renderLayerDestroyedImpl(*instrumentingAgents, renderLayer);
 | 
						||
 }
 | 
						||
 
 | 
						||
+inline void InspectorInstrumentation::runOpenPanel(Frame* frame, HTMLInputElement* element, bool* intercept)
 | 
						||
+{
 | 
						||
+    FAST_RETURN_IF_NO_FRONTENDS(void());
 | 
						||
+    if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(*frame))
 | 
						||
+        runOpenPanelImpl(*instrumentingAgents, element, intercept);
 | 
						||
+}
 | 
						||
+
 | 
						||
+inline void InspectorInstrumentation::frameAttached(Frame* frame)
 | 
						||
+{
 | 
						||
+    FAST_RETURN_IF_NO_FRONTENDS(void());
 | 
						||
+    if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame))
 | 
						||
+        frameAttachedImpl(*instrumentingAgents, *frame);
 | 
						||
+}
 | 
						||
+
 | 
						||
+inline bool InspectorInstrumentation::shouldBypassCSP(ScriptExecutionContext* context)
 | 
						||
+{
 | 
						||
+    FAST_RETURN_IF_NO_FRONTENDS(false);
 | 
						||
+    if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForContext(context))
 | 
						||
+        return shouldBypassCSPImpl(*instrumentingAgents);
 | 
						||
+    return false;
 | 
						||
+}
 | 
						||
+
 | 
						||
+inline bool InspectorInstrumentation::interceptRequest(ResourceLoader& loader, Function<void(bool handled)>&& handler)
 | 
						||
+{
 | 
						||
+    FAST_RETURN_IF_NO_FRONTENDS(false);
 | 
						||
+    if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(loader.frame()))
 | 
						||
+        return interceptRequestImpl(*instrumentingAgents, loader, WTFMove(handler));
 | 
						||
+    return false;
 | 
						||
+}
 | 
						||
+
 | 
						||
 inline InstrumentingAgents* InspectorInstrumentation::instrumentingAgentsForContext(ScriptExecutionContext* context)
 | 
						||
 {
 | 
						||
     return context ? instrumentingAgentsForContext(*context) : nullptr;
 | 
						||
diff --git a/Source/WebCore/inspector/InspectorInstrumentationWebKit.cpp b/Source/WebCore/inspector/InspectorInstrumentationWebKit.cpp
 | 
						||
index 954aaf121a9fa507d83bc10ae37de1f128f7dcfc..9f16be3dbcf4857742ec2ab131e2b2f962a2a47c 100644
 | 
						||
--- a/Source/WebCore/inspector/InspectorInstrumentationWebKit.cpp
 | 
						||
+++ b/Source/WebCore/inspector/InspectorInstrumentationWebKit.cpp
 | 
						||
@@ -30,6 +30,11 @@
 | 
						||
 
 | 
						||
 namespace WebCore {
 | 
						||
 
 | 
						||
+bool InspectorInstrumentationWebKit::interceptRequestInternal(ResourceLoader& loader, Function<void(bool handled)>&& handler)
 | 
						||
+{
 | 
						||
+    return InspectorInstrumentation::interceptRequest(loader, WTFMove(handler));
 | 
						||
+}
 | 
						||
+
 | 
						||
 bool InspectorInstrumentationWebKit::shouldInterceptResponseInternal(const Frame& frame, const ResourceResponse& response)
 | 
						||
 {
 | 
						||
     return InspectorInstrumentation::shouldInterceptResponse(frame, response);
 | 
						||
diff --git a/Source/WebCore/inspector/InspectorInstrumentationWebKit.h b/Source/WebCore/inspector/InspectorInstrumentationWebKit.h
 | 
						||
index b67e89b80b4e7a8586cac81ade5d58a1bcb0d431..c468bc0981d1fb13272b28095f9f7584840b5861 100644
 | 
						||
--- a/Source/WebCore/inspector/InspectorInstrumentationWebKit.h
 | 
						||
+++ b/Source/WebCore/inspector/InspectorInstrumentationWebKit.h
 | 
						||
@@ -27,6 +27,7 @@
 | 
						||
 
 | 
						||
 #include "InspectorInstrumentationPublic.h"
 | 
						||
 #include <wtf/CompletionHandler.h>
 | 
						||
+#include <wtf/Function.h>
 | 
						||
 
 | 
						||
 namespace WebCore {
 | 
						||
 
 | 
						||
@@ -36,14 +37,22 @@ class SharedBuffer;
 | 
						||
 
 | 
						||
 class WEBCORE_EXPORT InspectorInstrumentationWebKit {
 | 
						||
 public:
 | 
						||
+    static bool interceptRequest(ResourceLoader&, Function<void(bool handled)>&&);
 | 
						||
     static bool shouldInterceptResponse(const Frame*, const ResourceResponse&);
 | 
						||
     static void interceptResponse(const Frame*, const ResourceResponse&, unsigned long identifier, CompletionHandler<void(const ResourceResponse&, RefPtr<SharedBuffer>)>&&);
 | 
						||
 
 | 
						||
 private:
 | 
						||
+    static bool interceptRequestInternal(ResourceLoader&, Function<void(bool handled)>&&);
 | 
						||
     static bool shouldInterceptResponseInternal(const Frame&, const ResourceResponse&);
 | 
						||
     static void interceptResponseInternal(const Frame&, const ResourceResponse&, unsigned long identifier, CompletionHandler<void(const ResourceResponse&, RefPtr<SharedBuffer>)>&&);
 | 
						||
 };
 | 
						||
 
 | 
						||
+inline bool InspectorInstrumentationWebKit::interceptRequest(ResourceLoader& loader, Function<void(bool handled)>&& handler)
 | 
						||
+{
 | 
						||
+    FAST_RETURN_IF_NO_FRONTENDS(false);
 | 
						||
+    return interceptRequestInternal(loader, WTFMove(handler));
 | 
						||
+}
 | 
						||
+
 | 
						||
 inline bool InspectorInstrumentationWebKit::shouldInterceptResponse(const Frame* frame, const ResourceResponse& response)
 | 
						||
 {
 | 
						||
     FAST_RETURN_IF_NO_FRONTENDS(false);
 | 
						||
diff --git a/Source/WebCore/inspector/agents/InspectorDOMAgent.cpp b/Source/WebCore/inspector/agents/InspectorDOMAgent.cpp
 | 
						||
index d2ca5bbe109aaad182bae185c4d52d8aaecda84d..4fa24557c5a86a967e8d13579e75ce50d72947a4 100644
 | 
						||
--- a/Source/WebCore/inspector/agents/InspectorDOMAgent.cpp
 | 
						||
+++ b/Source/WebCore/inspector/agents/InspectorDOMAgent.cpp
 | 
						||
@@ -61,12 +61,16 @@
 | 
						||
 #include "Event.h"
 | 
						||
 #include "EventListener.h"
 | 
						||
 #include "EventNames.h"
 | 
						||
+#include "File.h"
 | 
						||
+#include "FileList.h"
 | 
						||
 #include "Frame.h"
 | 
						||
 #include "FrameTree.h"
 | 
						||
 #include "FrameView.h"
 | 
						||
 #include "FullscreenManager.h"
 | 
						||
+#include "FloatQuad.h"
 | 
						||
 #include "HTMLElement.h"
 | 
						||
 #include "HTMLFrameOwnerElement.h"
 | 
						||
+#include "HTMLInputElement.h"
 | 
						||
 #include "HTMLMediaElement.h"
 | 
						||
 #include "HTMLNames.h"
 | 
						||
 #include "HTMLParserIdioms.h"
 | 
						||
@@ -93,11 +97,14 @@
 | 
						||
 #include "Page.h"
 | 
						||
 #include "Pasteboard.h"
 | 
						||
 #include "PseudoElement.h"
 | 
						||
+#include "RenderLayer.h"
 | 
						||
+#include "RenderObject.h"
 | 
						||
 #include "RenderStyle.h"
 | 
						||
 #include "RenderStyleConstants.h"
 | 
						||
 #include "ScriptState.h"
 | 
						||
 #include "SelectorChecker.h"
 | 
						||
 #include "ShadowRoot.h"
 | 
						||
+#include "SharedBuffer.h"
 | 
						||
 #include "StaticNodeList.h"
 | 
						||
 #include "StyleProperties.h"
 | 
						||
 #include "StyleResolver.h"
 | 
						||
@@ -128,7 +135,8 @@ using namespace HTMLNames;
 | 
						||
 static const size_t maxTextSize = 10000;
 | 
						||
 static const UChar ellipsisUChar[] = { 0x2026, 0 };
 | 
						||
 
 | 
						||
-static Color parseColor(const JSON::Object* colorObject)
 | 
						||
+// static
 | 
						||
+Color InspectorDOMAgent::parseColor(const JSON::Object* colorObject)
 | 
						||
 {
 | 
						||
     if (!colorObject)
 | 
						||
         return Color::transparent;
 | 
						||
@@ -157,7 +165,7 @@ static Color parseConfigColor(const String& fieldName, const JSON::Object* confi
 | 
						||
     RefPtr<JSON::Object> colorObject;
 | 
						||
     configObject->getObject(fieldName, colorObject);
 | 
						||
 
 | 
						||
-    return parseColor(colorObject.get());
 | 
						||
+    return InspectorDOMAgent::parseColor(colorObject.get());
 | 
						||
 }
 | 
						||
 
 | 
						||
 static bool parseQuad(const JSON::Array& quadArray, FloatQuad* quad)
 | 
						||
@@ -438,6 +446,20 @@ Node* InspectorDOMAgent::assertNode(ErrorString& errorString, int nodeId)
 | 
						||
     return node;
 | 
						||
 }
 | 
						||
 
 | 
						||
+Node* InspectorDOMAgent::assertNode(ErrorString& errorString, const int* 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(ErrorString& errorString, int nodeId)
 | 
						||
 {
 | 
						||
     Node* node = assertNode(errorString, nodeId);
 | 
						||
@@ -1329,16 +1351,7 @@ void InspectorDOMAgent::highlightSelector(ErrorString& errorString, const JSON::
 | 
						||
 
 | 
						||
 void InspectorDOMAgent::highlightNode(ErrorString& errorString, const JSON::Object& highlightInspectorObject, const int* 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;
 | 
						||
-
 | 
						||
+    Node* node = assertNode(errorString, nodeId, objectId);
 | 
						||
     if (!node)
 | 
						||
         return;
 | 
						||
 
 | 
						||
@@ -1486,18 +1499,147 @@ void InspectorDOMAgent::setInspectedNode(ErrorString& errorString, int nodeId)
 | 
						||
     m_suppressEventListenerChangedEvent = false;
 | 
						||
 }
 | 
						||
 
 | 
						||
-void InspectorDOMAgent::resolveNode(ErrorString& errorString, int nodeId, const String* objectGroup, RefPtr<Inspector::Protocol::Runtime::RemoteObject>& result)
 | 
						||
+static FloatPoint contentsToRootView(FrameView& containingView, const FloatPoint& point)
 | 
						||
 {
 | 
						||
-    String objectGroupName = objectGroup ? *objectGroup : emptyString();
 | 
						||
-    Node* node = assertNode(errorString, nodeId);
 | 
						||
+    return containingView.convertToRootView(point - toFloatSize(containingView.documentScrollPositionRelativeToViewOrigin()));
 | 
						||
+}
 | 
						||
+
 | 
						||
+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 RefPtr<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 RefPtr<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;
 | 
						||
+}
 | 
						||
+
 | 
						||
+void InspectorDOMAgent::describeNode(ErrorString& errorString, const String& objectId, Optional<String>& contentFrameId, Optional<String>& ownerFrameId)
 | 
						||
+{
 | 
						||
+    Node* node = nodeForObjectId(objectId);
 | 
						||
+    if (!node) {
 | 
						||
+        errorString = "Node not found"_s;
 | 
						||
+        return;
 | 
						||
+    }
 | 
						||
+
 | 
						||
+    auto* pageAgent = m_instrumentingAgents.inspectorPageAgent();
 | 
						||
+    if (!pageAgent) {
 | 
						||
+        errorString = "Page agent must be enabled"_s;
 | 
						||
+        return;
 | 
						||
+    }
 | 
						||
+
 | 
						||
+    String frameId = pageAgent->frameId(node->document().frame());
 | 
						||
+    if (!frameId.isEmpty())
 | 
						||
+        ownerFrameId = frameId;
 | 
						||
+
 | 
						||
+    if (is<HTMLFrameOwnerElement>(*node)) {
 | 
						||
+        const auto& frameOwner = downcast<HTMLFrameOwnerElement>(*node);
 | 
						||
+        String frameId = pageAgent->frameId(frameOwner.contentFrame());
 | 
						||
+        if (!frameId.isEmpty())
 | 
						||
+            contentFrameId = frameId;
 | 
						||
+    }
 | 
						||
+}
 | 
						||
+
 | 
						||
+void InspectorDOMAgent::scrollIntoViewIfNeeded(ErrorString& errorString, const String& objectId, const JSON::Object* rect)
 | 
						||
+{
 | 
						||
+    Node* node = nodeForObjectId(objectId);
 | 
						||
+    if (!node) {
 | 
						||
+        errorString = "Node not found"_s;
 | 
						||
+        return;
 | 
						||
+    }
 | 
						||
+    node->document().updateLayoutIgnorePendingStylesheets();
 | 
						||
+    if (!node->isConnected()) {
 | 
						||
+        errorString = "Node is detached from document"_s;
 | 
						||
+        return;
 | 
						||
+    }
 | 
						||
+    RenderObject* renderer = node->renderer();
 | 
						||
+    if (!renderer) {
 | 
						||
+        errorString = "Node does not have a layout object"_s;
 | 
						||
+        return;
 | 
						||
+    }
 | 
						||
+    bool insideFixed;
 | 
						||
+    LayoutRect absoluteBounds = renderer->absoluteBoundingBoxRect(true, &insideFixed);
 | 
						||
+    if (rect) {
 | 
						||
+        double x = 0.0;
 | 
						||
+        double y = 0.0;
 | 
						||
+        double width = 0.0;
 | 
						||
+        double height = 0.0;
 | 
						||
+        if (!rect->getDouble("x", x) || !rect->getDouble("y", y) || !rect->getDouble("width", width) || !rect->getDouble("height", height)) {
 | 
						||
+            errorString = "Malformed rect"_s;
 | 
						||
+            return;
 | 
						||
+        }
 | 
						||
+        absoluteBounds.setX(absoluteBounds.x() + LayoutUnit(x));
 | 
						||
+        absoluteBounds.setY(absoluteBounds.y() + LayoutUnit(y));
 | 
						||
+        absoluteBounds.setWidth(LayoutUnit(std::max(width, 1.0)));
 | 
						||
+        absoluteBounds.setHeight(LayoutUnit(std::max(height, 1.0)));
 | 
						||
+    }
 | 
						||
+    // Note: we should use ScrollAlignment::alignCenterIfNotVisible, but
 | 
						||
+    // RenderLayer insists on no horizontal scroll if enough of the rect is visible.
 | 
						||
+    ScrollAlignment alignment = ScrollAlignment::alignCenterAlways;
 | 
						||
+    renderer->scrollRectToVisible(absoluteBounds, insideFixed, { SelectionRevealMode::Reveal, alignment, alignment, ShouldAllowCrossOriginScrolling::Yes });
 | 
						||
+}
 | 
						||
+
 | 
						||
+void InspectorDOMAgent::getContentQuads(ErrorString& errorString, const String& objectId, RefPtr<JSON::ArrayOf<Inspector::Protocol::DOM::Quad>>& contentQuads)
 | 
						||
+{
 | 
						||
+    Node* node = nodeForObjectId(objectId);
 | 
						||
+    if (!node) {
 | 
						||
+        errorString = "Node not found"_s;
 | 
						||
+        return;
 | 
						||
+    }
 | 
						||
+    RenderObject* renderer = node->renderer();
 | 
						||
+    if (!renderer) {
 | 
						||
+        errorString = "Node doesn't have renderer"_s;
 | 
						||
+        return;
 | 
						||
+    }
 | 
						||
+
 | 
						||
+    // Ensure quads are up to date.
 | 
						||
+    renderer->document().updateLayoutIgnorePendingStylesheets();
 | 
						||
+
 | 
						||
+    Frame* containingFrame = renderer->document().frame();
 | 
						||
+    FrameView* containingView = containingFrame ? containingFrame->view() : nullptr;
 | 
						||
+    if (!containingView) {
 | 
						||
+        errorString = "Internal error: no containing view"_s;
 | 
						||
+        return;
 | 
						||
+    }
 | 
						||
+    Vector<FloatQuad> quads;
 | 
						||
+    renderer->absoluteQuads(quads);
 | 
						||
+    for (auto& quad : quads)
 | 
						||
+        frameQuadToViewport(*containingView, quad, m_inspectedPage.pageScaleFactor());
 | 
						||
+    contentQuads = buildArrayOfQuads(quads);
 | 
						||
+}
 | 
						||
+
 | 
						||
+void InspectorDOMAgent::resolveNode(ErrorString& errorString, const int* nodeId, const String* objectId, const int* contextId, const String* objectGroup, RefPtr<Inspector::Protocol::Runtime::RemoteObject>& result)
 | 
						||
+{
 | 
						||
+    Node* node = assertNode(errorString, nodeId, objectId);
 | 
						||
     if (!node)
 | 
						||
         return;
 | 
						||
-    RefPtr<Inspector::Protocol::Runtime::RemoteObject> object = resolveNode(node, objectGroupName);
 | 
						||
-    if (!object) {
 | 
						||
+    String objectGroupName = objectGroup ? *objectGroup : emptyString();
 | 
						||
+    result = resolveNode(node, objectGroupName, contextId);
 | 
						||
+    if (!result) {
 | 
						||
         errorString = "Missing injected script for given nodeId"_s;
 | 
						||
         return;
 | 
						||
     }
 | 
						||
-    result = object;
 | 
						||
 }
 | 
						||
 
 | 
						||
 void InspectorDOMAgent::getAttributes(ErrorString& errorString, int nodeId, RefPtr<JSON::ArrayOf<String>>& result)
 | 
						||
@@ -2662,7 +2804,7 @@ void InspectorDOMAgent::pushNodeByPathToFrontend(ErrorString& errorString, const
 | 
						||
         errorString = "Missing node for given path"_s;
 | 
						||
 }
 | 
						||
 
 | 
						||
-RefPtr<Inspector::Protocol::Runtime::RemoteObject> InspectorDOMAgent::resolveNode(Node* node, const String& objectGroup)
 | 
						||
+RefPtr<Inspector::Protocol::Runtime::RemoteObject> InspectorDOMAgent::resolveNode(Node* node, const String& objectGroup, const int* contextId)
 | 
						||
 {
 | 
						||
     Document* document = &node->document();
 | 
						||
     if (auto* templateHost = document->templateDocumentHost())
 | 
						||
@@ -2671,12 +2813,16 @@ RefPtr<Inspector::Protocol::Runtime::RemoteObject> InspectorDOMAgent::resolveNod
 | 
						||
     if (!frame)
 | 
						||
         return nullptr;
 | 
						||
 
 | 
						||
-    auto& state = *mainWorldExecState(frame);
 | 
						||
-    auto injectedScript = m_injectedScriptManager.injectedScriptFor(&state);
 | 
						||
+    InjectedScript injectedScript;
 | 
						||
+    if (contextId) {
 | 
						||
+        injectedScript = m_injectedScriptManager.injectedScriptForId(*contextId);
 | 
						||
+    } else {
 | 
						||
+        injectedScript = m_injectedScriptManager.injectedScriptFor(mainWorldExecState(frame));
 | 
						||
+    }
 | 
						||
     if (injectedScript.hasNoValue())
 | 
						||
         return nullptr;
 | 
						||
 
 | 
						||
-    return injectedScript.wrapObject(nodeAsScriptValue(state, node), objectGroup);
 | 
						||
+    return injectedScript.wrapObject(nodeAsScriptValue(*injectedScript.globalObject(), node), objectGroup);
 | 
						||
 }
 | 
						||
 
 | 
						||
 Node* InspectorDOMAgent::scriptValueAsNode(JSC::JSValue value)
 | 
						||
@@ -2697,4 +2843,46 @@ void InspectorDOMAgent::setAllowEditingUserAgentShadowTrees(ErrorString&, bool a
 | 
						||
     m_allowEditingUserAgentShadowTrees = allow;
 | 
						||
 }
 | 
						||
 
 | 
						||
+void InspectorDOMAgent::setInputFiles(ErrorString& errorString, const String& objectId, const JSON::Array& files) {
 | 
						||
+    InjectedScript injectedScript = m_injectedScriptManager.injectedScriptForObjectId(objectId);
 | 
						||
+    if (injectedScript.hasNoValue()) {
 | 
						||
+        errorString = "Can not find element's context for given id"_s;
 | 
						||
+        return;
 | 
						||
+    }
 | 
						||
+    Node* node = scriptValueAsNode(injectedScript.findObjectById(objectId));
 | 
						||
+    if (!node) {
 | 
						||
+        errorString = "Can not find element for given id"_s;
 | 
						||
+        return;
 | 
						||
+    }
 | 
						||
+    if (node->nodeType() != Node::ELEMENT_NODE || node->nodeName() != "INPUT") {
 | 
						||
+        errorString = "Not an input node"_s;
 | 
						||
+        return;
 | 
						||
+    }
 | 
						||
+    HTMLInputElement* element = static_cast<HTMLInputElement*>(node);
 | 
						||
+    Vector<Ref<File>> fileObjects;
 | 
						||
+    for (unsigned i = 0; i < files.length(); ++i) {
 | 
						||
+        RefPtr<JSON::Value> item = files.get(i);
 | 
						||
+        RefPtr<JSON::Object> obj;
 | 
						||
+        if (!item->asObject(obj)) {
 | 
						||
+            errorString = "Invalid file payload format"_s;
 | 
						||
+            return;
 | 
						||
+        }
 | 
						||
+        String name;
 | 
						||
+        String type;
 | 
						||
+        String data;
 | 
						||
+        if (!obj->getString("name", name) || !obj->getString("type", type) || !obj->getString("data", data)) {
 | 
						||
+            errorString = "Invalid file payload format"_s;
 | 
						||
+            return;
 | 
						||
+        }
 | 
						||
+        Vector<uint8_t> buffer;
 | 
						||
+        if (!base64Decode(data, buffer)) {
 | 
						||
+            errorString = "Unable to decode given content"_s;
 | 
						||
+            return;
 | 
						||
+        }
 | 
						||
+        fileObjects.append(File::create(Blob::create(SharedBuffer::create(WTFMove(buffer)), type), name));
 | 
						||
+    }
 | 
						||
+    RefPtr<FileList> fileList = FileList::create(WTFMove(fileObjects));
 | 
						||
+    element->setFiles(WTFMove(fileList));
 | 
						||
+}
 | 
						||
+
 | 
						||
 } // namespace WebCore
 | 
						||
diff --git a/Source/WebCore/inspector/agents/InspectorDOMAgent.h b/Source/WebCore/inspector/agents/InspectorDOMAgent.h
 | 
						||
index 7df0e83eb53d75c41c554f1401235ba21719414c..ae6f961a7b7fe63ece60e34210bf333bedef2eee 100644
 | 
						||
--- a/Source/WebCore/inspector/agents/InspectorDOMAgent.h
 | 
						||
+++ b/Source/WebCore/inspector/agents/InspectorDOMAgent.h
 | 
						||
@@ -54,6 +54,7 @@ namespace WebCore {
 | 
						||
 
 | 
						||
 class AXCoreObject;
 | 
						||
 class CharacterData;
 | 
						||
+class Color;
 | 
						||
 class DOMEditor;
 | 
						||
 class Document;
 | 
						||
 class Element;
 | 
						||
@@ -88,6 +89,7 @@ public:
 | 
						||
     static String toErrorString(Exception&&);
 | 
						||
 
 | 
						||
     static String documentURLString(Document*);
 | 
						||
+    static Color parseColor(const 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.
 | 
						||
@@ -129,7 +131,7 @@ public:
 | 
						||
     void performSearch(ErrorString&, const String& query, const JSON::Array* nodeIds, const bool* caseSensitive, String* searchId, int* resultCount) override;
 | 
						||
     void getSearchResults(ErrorString&, const String& searchId, int fromIndex, int toIndex, RefPtr<JSON::ArrayOf<int>>&) override;
 | 
						||
     void discardSearchResults(ErrorString&, const String& searchId) override;
 | 
						||
-    void resolveNode(ErrorString&, int nodeId, const String* objectGroup, RefPtr<Inspector::Protocol::Runtime::RemoteObject>& result) override;
 | 
						||
+    void resolveNode(ErrorString&, const int* nodeId, const String* objectId, const int* contextId, const String* objectGroup, RefPtr<Inspector::Protocol::Runtime::RemoteObject>& result) override;
 | 
						||
     void getAttributes(ErrorString&, int nodeId, RefPtr<JSON::ArrayOf<String>>& result) override;
 | 
						||
     void setInspectModeEnabled(ErrorString&, bool enabled, const JSON::Object* highlightConfig, const bool* showRulers) override;
 | 
						||
     void requestNode(ErrorString&, const String& objectId, int* nodeId) override;
 | 
						||
@@ -148,6 +150,10 @@ public:
 | 
						||
     void focus(ErrorString&, int nodeId) override;
 | 
						||
     void setInspectedNode(ErrorString&, int nodeId) override;
 | 
						||
     void setAllowEditingUserAgentShadowTrees(ErrorString&, bool allow) final;
 | 
						||
+    void describeNode(ErrorString&, const String& objectId, Optional<String>& contentFrameId, Optional<String>& ownerFrameId) override;
 | 
						||
+    void scrollIntoViewIfNeeded(ErrorString&, const String& objectId, const JSON::Object* rect) override;
 | 
						||
+    void getContentQuads(ErrorString&, const String& objectId, RefPtr<JSON::ArrayOf<Inspector::Protocol::DOM::Quad>>&) override;
 | 
						||
+    void setInputFiles(ErrorString&, const String& objectId, const JSON::Array& files) override;
 | 
						||
 
 | 
						||
     // InspectorInstrumentation
 | 
						||
     int identifierForNode(Node&);
 | 
						||
@@ -185,7 +191,7 @@ public:
 | 
						||
     Node* nodeForId(int nodeId);
 | 
						||
     int boundNodeId(const Node*);
 | 
						||
 
 | 
						||
-    RefPtr<Inspector::Protocol::Runtime::RemoteObject> resolveNode(Node*, const String& objectGroup);
 | 
						||
+    RefPtr<Inspector::Protocol::Runtime::RemoteObject> resolveNode(Node*, const String& objectGroup, const int* contextId);
 | 
						||
     bool handleMousePress();
 | 
						||
     void mouseDidMoveOverElement(const HitTestResult&, unsigned modifierFlags);
 | 
						||
     void inspect(Node*);
 | 
						||
@@ -196,12 +202,15 @@ public:
 | 
						||
     void reset();
 | 
						||
 
 | 
						||
     Node* assertNode(ErrorString&, int nodeId);
 | 
						||
+    Node* assertNode(ErrorString&, const int* nodeId, const String* objectId);
 | 
						||
     Element* assertElement(ErrorString&, int nodeId);
 | 
						||
     Document* assertDocument(ErrorString&, int nodeId);
 | 
						||
 
 | 
						||
     bool hasBreakpointForEventListener(EventTarget&, const AtomString& eventType, EventListener&, bool capture);
 | 
						||
     int idForEventListener(EventTarget&, const AtomString& eventType, EventListener&, bool capture);
 | 
						||
 
 | 
						||
+    Node* nodeForObjectId(const String& objectId);
 | 
						||
+
 | 
						||
 private:
 | 
						||
 #if ENABLE(VIDEO)
 | 
						||
     void mediaMetricsTimerFired();
 | 
						||
@@ -228,9 +237,8 @@ private:
 | 
						||
     Ref<Inspector::Protocol::DOM::EventListener> buildObjectForEventListener(const RegisteredEventListener&, int identifier, EventTarget&, const AtomString& eventType, bool disabled, bool hasBreakpoint);
 | 
						||
     RefPtr<Inspector::Protocol::DOM::AccessibilityProperties> buildObjectForAccessibilityProperties(Node*);
 | 
						||
     void processAccessibilityChildren(AXCoreObject&, JSON::ArrayOf<int>&);
 | 
						||
-    
 | 
						||
+
 | 
						||
     Node* nodeForPath(const String& path);
 | 
						||
-    Node* nodeForObjectId(const String& objectId);
 | 
						||
 
 | 
						||
     void discardBindings();
 | 
						||
 
 | 
						||
diff --git a/Source/WebCore/inspector/agents/InspectorDOMStorageAgent.h b/Source/WebCore/inspector/agents/InspectorDOMStorageAgent.h
 | 
						||
index b578660fbb3ce176e4e0aeb5a22021dc880e47f0..a7c968bc9f88c7d26e1887bb53106b4af2464753 100644
 | 
						||
--- a/Source/WebCore/inspector/agents/InspectorDOMStorageAgent.h
 | 
						||
+++ b/Source/WebCore/inspector/agents/InspectorDOMStorageAgent.h
 | 
						||
@@ -40,6 +40,7 @@ class DOMStorageFrontendDispatcher;
 | 
						||
 
 | 
						||
 namespace WebCore {
 | 
						||
 
 | 
						||
+class Color;
 | 
						||
 class Frame;
 | 
						||
 class Page;
 | 
						||
 class SecurityOrigin;
 | 
						||
diff --git a/Source/WebCore/inspector/agents/InspectorNetworkAgent.cpp b/Source/WebCore/inspector/agents/InspectorNetworkAgent.cpp
 | 
						||
index ee9edb30dd7b3461c4d491dfaf7929011d498bc9..71b51b0261494112b23800fe02f5e31bb90769bb 100644
 | 
						||
--- a/Source/WebCore/inspector/agents/InspectorNetworkAgent.cpp
 | 
						||
+++ b/Source/WebCore/inspector/agents/InspectorNetworkAgent.cpp
 | 
						||
@@ -44,6 +44,7 @@
 | 
						||
 #include "DocumentLoader.h"
 | 
						||
 #include "DocumentThreadableLoader.h"
 | 
						||
 #include "Frame.h"
 | 
						||
+#include "FormData.h"
 | 
						||
 #include "FrameLoader.h"
 | 
						||
 #include "HTTPHeaderMap.h"
 | 
						||
 #include "HTTPHeaderNames.h"
 | 
						||
@@ -56,6 +57,7 @@
 | 
						||
 #include "MIMETypeRegistry.h"
 | 
						||
 #include "MemoryCache.h"
 | 
						||
 #include "NetworkResourcesData.h"
 | 
						||
+#include "NetworkStateNotifier.h"
 | 
						||
 #include "Page.h"
 | 
						||
 #include "PlatformStrategies.h"
 | 
						||
 #include "ProgressTracker.h"
 | 
						||
@@ -99,6 +101,11 @@ using namespace Inspector;
 | 
						||
 
 | 
						||
 namespace {
 | 
						||
 
 | 
						||
+String inspectorInitiatorPrefix()
 | 
						||
+{
 | 
						||
+    return "InspectorPageAgent.navigate referrer:"_s;
 | 
						||
+}
 | 
						||
+
 | 
						||
 class InspectorThreadableLoaderClient final : public ThreadableLoaderClient {
 | 
						||
     WTF_MAKE_NONCOPYABLE(InspectorThreadableLoaderClient);
 | 
						||
 public:
 | 
						||
@@ -453,6 +460,13 @@ void InspectorNetworkAgent::willSendRequest(unsigned long identifier, DocumentLo
 | 
						||
     for (auto& entry : m_extraRequestHeaders)
 | 
						||
         request.setHTTPHeaderField(entry.key, entry.value);
 | 
						||
 
 | 
						||
+    if (request.initiatorIdentifier().startsWith(inspectorInitiatorPrefix())) {
 | 
						||
+        String referrer = request.initiatorIdentifier().substring(inspectorInitiatorPrefix().length());
 | 
						||
+        if (!referrer.isEmpty())
 | 
						||
+            request.setHTTPReferrer(referrer);
 | 
						||
+        request.setInitiatorIdentifier(String());
 | 
						||
+    }
 | 
						||
+
 | 
						||
     auto protocolResourceType = InspectorPageAgent::resourceTypeJSON(type);
 | 
						||
 
 | 
						||
     Document* document = loader && loader->frame() ? loader->frame()->document() : nullptr;
 | 
						||
@@ -841,6 +855,7 @@ void InspectorNetworkAgent::disable(ErrorString&)
 | 
						||
     m_resourcesData->clear();
 | 
						||
     m_extraRequestHeaders.clear();
 | 
						||
 
 | 
						||
+    continuePendingRequests();
 | 
						||
     continuePendingResponses();
 | 
						||
 
 | 
						||
     setResourceCachingDisabled(false);
 | 
						||
@@ -864,6 +879,16 @@ bool InspectorNetworkAgent::shouldIntercept(URL url)
 | 
						||
     return false;
 | 
						||
 }
 | 
						||
 
 | 
						||
+void InspectorNetworkAgent::continuePendingRequests()
 | 
						||
+{
 | 
						||
+    for (auto& pendingRequest : m_pendingInterceptRequests.values()) {
 | 
						||
+        ResourceLoader* loader = pendingRequest->m_loader.get();
 | 
						||
+        if (loader->identifier())
 | 
						||
+            pendingRequest->m_callback(false);
 | 
						||
+    }
 | 
						||
+    m_pendingInterceptRequests.clear();
 | 
						||
+}
 | 
						||
+
 | 
						||
 void InspectorNetworkAgent::continuePendingResponses()
 | 
						||
 {
 | 
						||
     for (auto& pendingInterceptResponse : m_pendingInterceptResponses.values())
 | 
						||
@@ -1020,17 +1045,15 @@ void InspectorNetworkAgent::resolveWebSocket(ErrorString& errorString, const Str
 | 
						||
     result = injectedScript.wrapObject(webSocketAsScriptValue(state, webSocket), objectGroupName);
 | 
						||
 }
 | 
						||
 
 | 
						||
-void InspectorNetworkAgent::setInterceptionEnabled(ErrorString& errorString, bool enabled)
 | 
						||
+void InspectorNetworkAgent::setInterceptionEnabled(ErrorString&, bool enabled, const bool* interceptRequests)
 | 
						||
 {
 | 
						||
-    if (m_interceptionEnabled == enabled) {
 | 
						||
-        errorString = m_interceptionEnabled ? "Interception already enabled"_s : "Interception already disabled"_s;
 | 
						||
-        return;
 | 
						||
-    }
 | 
						||
-
 | 
						||
     m_interceptionEnabled = enabled;
 | 
						||
+    m_interceptRequests = interceptRequests && *interceptRequests;
 | 
						||
 
 | 
						||
     if (!m_interceptionEnabled)
 | 
						||
         continuePendingResponses();
 | 
						||
+    if (!m_interceptionEnabled || !m_interceptRequests)
 | 
						||
+        continuePendingRequests();
 | 
						||
 }
 | 
						||
 
 | 
						||
 void InspectorNetworkAgent::addInterception(ErrorString& errorString, const String& url, const bool* optionalCaseSensitive, const bool* optionalIsRegex, const String* networkStageString)
 | 
						||
@@ -1112,19 +1135,128 @@ void InspectorNetworkAgent::interceptResponse(const ResourceResponse& response,
 | 
						||
     m_frontendDispatcher->responseIntercepted(requestId, buildObjectForResourceResponse(response, nullptr));
 | 
						||
 }
 | 
						||
 
 | 
						||
-void InspectorNetworkAgent::interceptContinue(ErrorString& errorString, const String& requestId)
 | 
						||
-{
 | 
						||
+bool InspectorNetworkAgent::interceptRequest(ResourceLoader& loader, Function<void(bool handled)>&& handler) {
 | 
						||
+    if (!m_interceptionEnabled || !m_interceptRequests)
 | 
						||
+        return false;
 | 
						||
+    String requestId = IdentifiersFactory::requestId(loader.identifier());
 | 
						||
+    auto pendingRequest = makeUnique<PendingInterceptRequest>();
 | 
						||
+    pendingRequest->m_loader = &loader;
 | 
						||
+    pendingRequest->m_callback = WTFMove(handler);
 | 
						||
+    m_pendingInterceptRequests.set(requestId, WTFMove(pendingRequest));
 | 
						||
+    m_frontendDispatcher->requestIntercepted(requestId, buildObjectForResourceRequest(loader.request()));
 | 
						||
+    return true;
 | 
						||
+}
 | 
						||
+
 | 
						||
+void InspectorNetworkAgent::interceptContinue(ErrorString& errorString, const String& requestId, const String* method, const JSON::Object* headers, const String* postData)
 | 
						||
+{
 | 
						||
+    auto pendingRequest = m_pendingInterceptRequests.take(requestId);
 | 
						||
+    if (pendingRequest) {
 | 
						||
+        ResourceLoader* loader = pendingRequest->m_loader.get();
 | 
						||
+        if (!loader->identifier()) {
 | 
						||
+            // Do not throw upon continue of canceled requests.
 | 
						||
+            return;
 | 
						||
+        }
 | 
						||
+        // Safe to const cast at this point, we are only adjusting the method / headers / post.
 | 
						||
+        ResourceRequest* request = const_cast<ResourceRequest*>(&loader->request());
 | 
						||
+        if (method)
 | 
						||
+            request->setHTTPMethod(*method);
 | 
						||
+        if (headers) {
 | 
						||
+            HTTPHeaderMap explicitHeaders;
 | 
						||
+            for (auto& header : *headers) {
 | 
						||
+                String headerValue;
 | 
						||
+                if (header.value->asString(headerValue))
 | 
						||
+                    explicitHeaders.add(header.key, headerValue);
 | 
						||
+            }
 | 
						||
+            request->setHTTPHeaderFields(WTFMove(explicitHeaders));
 | 
						||
+        }
 | 
						||
+        if (postData) {
 | 
						||
+            Vector<uint8_t> buffer;
 | 
						||
+            if (!base64Decode(*postData, buffer)) {
 | 
						||
+                errorString = "Unable to decode given postData"_s;
 | 
						||
+                return;
 | 
						||
+            }
 | 
						||
+            Ref<FormData> data = FormData::create(buffer);
 | 
						||
+            request->setHTTPBody(WTFMove(data));
 | 
						||
+        }
 | 
						||
+        pendingRequest->m_callback(false);
 | 
						||
+        return;
 | 
						||
+    }
 | 
						||
+
 | 
						||
     auto pendingInterceptResponse = m_pendingInterceptResponses.take(requestId);
 | 
						||
-    if (!pendingInterceptResponse) {
 | 
						||
-        errorString = "Missing pending intercept response for given requestId"_s;
 | 
						||
+    if (pendingInterceptResponse) {
 | 
						||
+        pendingInterceptResponse->respondWithOriginalResponse();
 | 
						||
         return;
 | 
						||
     }
 | 
						||
 
 | 
						||
-    pendingInterceptResponse->respondWithOriginalResponse();
 | 
						||
+    errorString = "Missing pending intercept response for given requestId"_s;
 | 
						||
 }
 | 
						||
 
 | 
						||
-void InspectorNetworkAgent::interceptWithResponse(ErrorString& errorString, const String& requestId, const String& content, bool base64Encoded, const String* mimeType, const int* status, const String* statusText, const JSON::Object* headers)
 | 
						||
+void InspectorNetworkAgent::interceptAsError(ErrorString& errorString, const String& requestId, const String& reason)
 | 
						||
 {
 | 
						||
+    auto pendingRequest = m_pendingInterceptRequests.take(requestId);
 | 
						||
+    if (pendingRequest) {
 | 
						||
+        ResourceLoader* loader = pendingRequest->m_loader.get();
 | 
						||
+        if (!loader->identifier()) {
 | 
						||
+            errorString = "Unable to abort request, it has already been processed"_s;
 | 
						||
+            return;
 | 
						||
+        }
 | 
						||
+        ResourceError error(errorDomainWebKitInternal, 0, loader->url(), "Request intercepted"_s, ResourceError::Type::General);
 | 
						||
+        if (reason == "AccessControl")
 | 
						||
+            error = ResourceError(errorDomainWebKitInternal, 0, loader->url(), "Access denied"_s, ResourceError::Type::AccessControl);
 | 
						||
+        else if (reason == "Cancellation")
 | 
						||
+            error = ResourceError(errorDomainWebKitInternal, 0, loader->url(), "Request canceled"_s, ResourceError::Type::Cancellation);
 | 
						||
+        else if (reason == "Timeout")
 | 
						||
+            error = ResourceError(errorDomainWebKitInternal, 0, loader->url(), "Request timed out"_s, ResourceError::Type::Timeout);
 | 
						||
+        loader->didFail(error);
 | 
						||
+        pendingRequest->m_callback(true);
 | 
						||
+        return;
 | 
						||
+    }
 | 
						||
+
 | 
						||
+    errorString = "Missing pending intercept response for given requestId"_s;
 | 
						||
+}
 | 
						||
+
 | 
						||
+void InspectorNetworkAgent::interceptWithResponse(ErrorString& errorString, const String& requestId, const String* content, const bool* base64Encoded, const String* mimeType, const int* status, const String* statusText, const JSON::Object* headers)
 | 
						||
+{
 | 
						||
+    auto pendingRequest = m_pendingInterceptRequests.take(requestId);
 | 
						||
+    if (pendingRequest && status && statusText && mimeType && headers) {
 | 
						||
+        RefPtr<ResourceLoader> loader = pendingRequest->m_loader.get();
 | 
						||
+        if (!loader->identifier()) {
 | 
						||
+            errorString = "Unable to fulfill request, it has already been processed"_s;
 | 
						||
+            return;
 | 
						||
+        }
 | 
						||
+        RefPtr<SharedBuffer> data;
 | 
						||
+        if (base64Encoded && *base64Encoded && content) {
 | 
						||
+            Vector<uint8_t> buffer;
 | 
						||
+            if (!base64Decode(*content, buffer)) {
 | 
						||
+                errorString = "Unable to decode given content"_s;
 | 
						||
+                return;
 | 
						||
+            }
 | 
						||
+            data = SharedBuffer::create(WTFMove(buffer));
 | 
						||
+        } else if (content) {
 | 
						||
+            data = SharedBuffer::create(content->utf8().data(), content->utf8().length());
 | 
						||
+        }
 | 
						||
+
 | 
						||
+        ResourceResponse response(pendingRequest->m_loader->url(), *mimeType, data->size(), String());
 | 
						||
+        response.setSource(ResourceResponse::Source::InspectorOverride);
 | 
						||
+        response.setHTTPStatusCode(*status);
 | 
						||
+        response.setHTTPStatusText(*statusText);
 | 
						||
+        HTTPHeaderMap explicitHeaders;
 | 
						||
+        for (auto& header : *headers) {
 | 
						||
+            String headerValue;
 | 
						||
+            if (header.value->asString(headerValue))
 | 
						||
+                explicitHeaders.add(header.key, headerValue);
 | 
						||
+        }
 | 
						||
+        response.setHTTPHeaderFields(WTFMove(explicitHeaders));
 | 
						||
+        response.setHTTPHeaderField(HTTPHeaderName::ContentType, response.mimeType());
 | 
						||
+        loader->didReceiveResponse(response, [loader, data = data.releaseNonNull()]() mutable {
 | 
						||
+            if (data->size())
 | 
						||
+                loader->didReceiveBuffer(WTFMove(data), data->size(), DataPayloadWholeResource);
 | 
						||
+            loader->didFinishLoading(NetworkLoadMetrics());
 | 
						||
+        });
 | 
						||
+        pendingRequest->m_callback(true);
 | 
						||
+        return;
 | 
						||
+    }
 | 
						||
+
 | 
						||
     auto pendingInterceptResponse = m_pendingInterceptResponses.take(requestId);
 | 
						||
     if (!pendingInterceptResponse) {
 | 
						||
         errorString = "Missing pending intercept response for given requestId"_s;
 | 
						||
@@ -1152,20 +1284,26 @@ void InspectorNetworkAgent::interceptWithResponse(ErrorString& errorString, cons
 | 
						||
     }
 | 
						||
 
 | 
						||
     RefPtr<SharedBuffer> overrideData;
 | 
						||
-    if (base64Encoded) {
 | 
						||
+    if (base64Encoded && *base64Encoded && content) {
 | 
						||
         Vector<uint8_t> buffer;
 | 
						||
-        if (!base64Decode(content, buffer)) {
 | 
						||
+        if (!base64Decode(*content, buffer)) {
 | 
						||
             errorString = "Unable to decode given content"_s;
 | 
						||
             pendingInterceptResponse->respondWithOriginalResponse();
 | 
						||
             return;
 | 
						||
         }
 | 
						||
         overrideData = SharedBuffer::create(WTFMove(buffer));
 | 
						||
-    } else
 | 
						||
-        overrideData = SharedBuffer::create(content.utf8().data(), content.utf8().length());
 | 
						||
+    } else if (content) {
 | 
						||
+        overrideData = SharedBuffer::create(content->utf8().data(), content->utf8().length());
 | 
						||
+    }
 | 
						||
 
 | 
						||
     pendingInterceptResponse->respond(overrideResponse, overrideData);
 | 
						||
 }
 | 
						||
 
 | 
						||
+void InspectorNetworkAgent::setEmulateOfflineState(ErrorString&, bool offline)
 | 
						||
+{
 | 
						||
+    platformStrategies()->loaderStrategy()->setEmulateOfflineState(offline);
 | 
						||
+}
 | 
						||
+
 | 
						||
 bool InspectorNetworkAgent::shouldTreatAsText(const String& mimeType)
 | 
						||
 {
 | 
						||
     return startsWithLettersIgnoringASCIICase(mimeType, "text/")
 | 
						||
@@ -1295,6 +1433,11 @@ void InspectorNetworkAgent::searchInRequest(ErrorString& errorString, const Stri
 | 
						||
     results = ContentSearchUtilities::searchInTextByLines(resourceData->content(), query, caseSensitive, isRegex);
 | 
						||
 }
 | 
						||
 
 | 
						||
+String InspectorNetworkAgent::createInitiatorIdentifierForInspectorNavigation(const String& referrer)
 | 
						||
+{
 | 
						||
+    return inspectorInitiatorPrefix() + referrer;
 | 
						||
+}
 | 
						||
+
 | 
						||
 void InspectorNetworkAgent::mainFrameNavigated(DocumentLoader& loader)
 | 
						||
 {
 | 
						||
     m_resourcesData->clear(loaderIdentifier(&loader));
 | 
						||
diff --git a/Source/WebCore/inspector/agents/InspectorNetworkAgent.h b/Source/WebCore/inspector/agents/InspectorNetworkAgent.h
 | 
						||
index b038a1879c043aa17dae97425693f29be42e3258..d60716b837663004675ffd90bceede4c3a6e98c6 100644
 | 
						||
--- a/Source/WebCore/inspector/agents/InspectorNetworkAgent.h
 | 
						||
+++ b/Source/WebCore/inspector/agents/InspectorNetworkAgent.h
 | 
						||
@@ -87,11 +87,13 @@ public:
 | 
						||
     void loadResource(const String& frameId, const String& url, Ref<LoadResourceCallback>&&) final;
 | 
						||
     void getSerializedCertificate(ErrorString&, const String& requestId, String* serializedCertificate) final;
 | 
						||
     void resolveWebSocket(ErrorString&, const String& requestId, const String* objectGroup, RefPtr<Inspector::Protocol::Runtime::RemoteObject>&) final;
 | 
						||
-    void setInterceptionEnabled(ErrorString&, bool enabled) final;
 | 
						||
+    void setInterceptionEnabled(ErrorString&, bool enabled, const bool* interceptRequests) final;
 | 
						||
     void addInterception(ErrorString&, const String& url, const bool* caseSensitive, const bool* isRegex, const String* networkStageString) final;
 | 
						||
     void removeInterception(ErrorString&, const String& url, const bool* caseSensitive, const bool* isRegex, const String* networkStageString) final;
 | 
						||
-    void interceptContinue(ErrorString&, const String& requestId) final;
 | 
						||
-    void interceptWithResponse(ErrorString&, const String& requestId, const String& content, bool base64Encoded, const String* mimeType, const int* status, const String* statusText, const JSON::Object* headers) final;
 | 
						||
+    void interceptContinue(ErrorString&, const String& requestId, const String* method, const JSON::Object* headers, const String* postData) final;
 | 
						||
+    void interceptAsError(ErrorString&, const String& requestId, const String& reason) final;
 | 
						||
+    void interceptWithResponse(ErrorString&, const String& requestId, const String* content, const bool* base64Encoded, const String* mimeType, const int* status, const String* statusText, const JSON::Object* headers) final;
 | 
						||
+    void setEmulateOfflineState(ErrorString&, bool offline) final;
 | 
						||
 
 | 
						||
     // InspectorInstrumentation
 | 
						||
     void willRecalculateStyle();
 | 
						||
@@ -121,10 +123,13 @@ public:
 | 
						||
     bool willInterceptRequest(const ResourceRequest&);
 | 
						||
     bool shouldInterceptResponse(const ResourceResponse&);
 | 
						||
     void interceptResponse(const ResourceResponse&, unsigned long identifier, CompletionHandler<void(const ResourceResponse&, RefPtr<SharedBuffer>)>&&);
 | 
						||
+    bool interceptRequest(ResourceLoader& loader, Function<void(bool handled)>&&);
 | 
						||
 
 | 
						||
     void searchOtherRequests(const JSC::Yarr::RegularExpression&, RefPtr<JSON::ArrayOf<Inspector::Protocol::Page::SearchResult>>&);
 | 
						||
     void searchInRequest(ErrorString&, const String& requestId, const String& query, bool caseSensitive, bool isRegex, RefPtr<JSON::ArrayOf<Inspector::Protocol::GenericTypes::SearchMatch>>&);
 | 
						||
 
 | 
						||
+    static String createInitiatorIdentifierForInspectorNavigation(const String& referrer);
 | 
						||
+
 | 
						||
 protected:
 | 
						||
     InspectorNetworkAgent(WebAgentContext&);
 | 
						||
 
 | 
						||
@@ -141,6 +146,7 @@ private:
 | 
						||
     void willSendRequest(unsigned long identifier, DocumentLoader*, ResourceRequest&, const ResourceResponse& redirectResponse, InspectorPageAgent::ResourceType);
 | 
						||
 
 | 
						||
     bool shouldIntercept(URL);
 | 
						||
+    void continuePendingRequests();
 | 
						||
     void continuePendingResponses();
 | 
						||
 
 | 
						||
     WebSocket* webSocketForRequestId(const String& requestId);
 | 
						||
@@ -191,6 +197,15 @@ private:
 | 
						||
         bool m_responded { false };
 | 
						||
     };
 | 
						||
 
 | 
						||
+    class PendingInterceptRequest {
 | 
						||
+        WTF_MAKE_NONCOPYABLE(PendingInterceptRequest);
 | 
						||
+        WTF_MAKE_FAST_ALLOCATED;
 | 
						||
+    public:
 | 
						||
+        PendingInterceptRequest() = default;
 | 
						||
+        RefPtr<ResourceLoader> m_loader;
 | 
						||
+        CompletionHandler<void(bool handled)> m_callback;
 | 
						||
+    };
 | 
						||
+
 | 
						||
     std::unique_ptr<Inspector::NetworkFrontendDispatcher> m_frontendDispatcher;
 | 
						||
     RefPtr<Inspector::NetworkBackendDispatcher> m_backendDispatcher;
 | 
						||
     Inspector::InjectedScriptManager& m_injectedScriptManager;
 | 
						||
@@ -214,6 +229,7 @@ private:
 | 
						||
     };
 | 
						||
     Vector<Intercept> m_intercepts;
 | 
						||
     HashMap<String, std::unique_ptr<PendingInterceptResponse>> m_pendingInterceptResponses;
 | 
						||
+    HashMap<String, std::unique_ptr<PendingInterceptRequest>> m_pendingInterceptRequests;
 | 
						||
 
 | 
						||
     // FIXME: InspectorNetworkAgent should not be aware of style recalculation.
 | 
						||
     RefPtr<Inspector::Protocol::Network::Initiator> m_styleRecalculationInitiator;
 | 
						||
@@ -222,6 +238,7 @@ private:
 | 
						||
     bool m_enabled { false };
 | 
						||
     bool m_loadingXHRSynchronously { false };
 | 
						||
     bool m_interceptionEnabled { false };
 | 
						||
+    bool m_interceptRequests { false };
 | 
						||
 };
 | 
						||
 
 | 
						||
 } // namespace WebCore
 | 
						||
diff --git a/Source/WebCore/inspector/agents/InspectorPageAgent.cpp b/Source/WebCore/inspector/agents/InspectorPageAgent.cpp
 | 
						||
index 44a7da37f588d38e3070e967cdc23a9fd9dad203..bf760c64150ea04e82c979df2fabf73a3fbd7733 100644
 | 
						||
--- a/Source/WebCore/inspector/agents/InspectorPageAgent.cpp
 | 
						||
+++ b/Source/WebCore/inspector/agents/InspectorPageAgent.cpp
 | 
						||
@@ -32,6 +32,8 @@
 | 
						||
 #include "config.h"
 | 
						||
 #include "InspectorPageAgent.h"
 | 
						||
 
 | 
						||
+#include "AXObjectCache.h"
 | 
						||
+#include "BackForwardController.h"
 | 
						||
 #include "CachedResource.h"
 | 
						||
 #include "CachedResourceLoader.h"
 | 
						||
 #include "Cookie.h"
 | 
						||
@@ -40,12 +42,15 @@
 | 
						||
 #include "DOMWrapperWorld.h"
 | 
						||
 #include "Document.h"
 | 
						||
 #include "DocumentLoader.h"
 | 
						||
+#include "FocusController.h"
 | 
						||
 #include "Frame.h"
 | 
						||
 #include "FrameLoadRequest.h"
 | 
						||
 #include "FrameLoader.h"
 | 
						||
+#include "FrameLoaderClient.h"
 | 
						||
 #include "FrameSnapshotting.h"
 | 
						||
 #include "FrameView.h"
 | 
						||
 #include "HTMLFrameOwnerElement.h"
 | 
						||
+#include "HTMLInputElement.h"
 | 
						||
 #include "HTMLNames.h"
 | 
						||
 #include "ImageBuffer.h"
 | 
						||
 #include "InspectorClient.h"
 | 
						||
@@ -56,19 +61,29 @@
 | 
						||
 #include "MIMETypeRegistry.h"
 | 
						||
 #include "MemoryCache.h"
 | 
						||
 #include "Page.h"
 | 
						||
+#include "PageRuntimeAgent.h"
 | 
						||
 #include "RenderObject.h"
 | 
						||
 #include "RenderTheme.h"
 | 
						||
+#include "RuntimeEnabledFeatures.h"
 | 
						||
 #include "ScriptController.h"
 | 
						||
 #include "ScriptSourceCode.h"
 | 
						||
+#include "ScriptState.h"
 | 
						||
 #include "SecurityOrigin.h"
 | 
						||
 #include "Settings.h"
 | 
						||
 #include "StyleScope.h"
 | 
						||
 #include "TextEncoding.h"
 | 
						||
+#include "TypingCommand.h"
 | 
						||
 #include "UserGestureIndicator.h"
 | 
						||
 #include <JavaScriptCore/ContentSearchUtilities.h>
 | 
						||
 #include <JavaScriptCore/IdentifiersFactory.h>
 | 
						||
+#include <JavaScriptCore/InjectedScriptManager.h>
 | 
						||
 #include <JavaScriptCore/RegularExpression.h>
 | 
						||
+#include <platform/ProcessIdentifier.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,7 +96,6 @@
 | 
						||
 #include "LegacyWebArchive.h"
 | 
						||
 #endif
 | 
						||
 
 | 
						||
-
 | 
						||
 namespace WebCore {
 | 
						||
 
 | 
						||
 using namespace Inspector;
 | 
						||
@@ -100,6 +114,11 @@ using namespace Inspector;
 | 
						||
     macro(WebRTCEncryptionEnabled) \
 | 
						||
     macro(WebSecurityEnabled)
 | 
						||
 
 | 
						||
+static HashMap<String, Ref<DOMWrapperWorld>>& createdUserWorlds() {
 | 
						||
+    static NeverDestroyed<HashMap<String, Ref<DOMWrapperWorld>>> nameToWorld;
 | 
						||
+    return nameToWorld;
 | 
						||
+}
 | 
						||
+
 | 
						||
 static bool decodeBuffer(const char* buffer, unsigned size, const String& textEncodingName, String* result)
 | 
						||
 {
 | 
						||
     if (buffer) {
 | 
						||
@@ -340,6 +359,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)
 | 
						||
 {
 | 
						||
@@ -373,11 +393,20 @@ void InspectorPageAgent::enable(ErrorString& errorString)
 | 
						||
 #if HAVE(OS_DARK_MODE_SUPPORT)
 | 
						||
     defaultAppearanceDidChange(m_inspectedPage.defaultUseDarkAppearance());
 | 
						||
 #endif
 | 
						||
+
 | 
						||
+    if (!createdUserWorlds().isEmpty()) {
 | 
						||
+        Vector<DOMWrapperWorld*> worlds;
 | 
						||
+        for (const auto& world : createdUserWorlds().values())
 | 
						||
+            worlds.append(world.ptr());
 | 
						||
+        ensureUserWorldsExistInAllFrames(worlds);
 | 
						||
+    }
 | 
						||
 }
 | 
						||
 
 | 
						||
 void InspectorPageAgent::disable(ErrorString&)
 | 
						||
 {
 | 
						||
     m_instrumentingAgents.setInspectorPageAgent(nullptr);
 | 
						||
+    m_interceptFileChooserDialog = false;
 | 
						||
+    m_bypassCSP = false;
 | 
						||
 
 | 
						||
     ErrorString unused;
 | 
						||
     setShowPaintRects(unused, false);
 | 
						||
@@ -415,14 +444,35 @@ void InspectorPageAgent::reload(ErrorString&, const bool* optionalReloadFromOrig
 | 
						||
     m_inspectedPage.mainFrame().loader().reload(reloadOptions);
 | 
						||
 }
 | 
						||
 
 | 
						||
-void InspectorPageAgent::navigate(ErrorString&, const String& url)
 | 
						||
+void InspectorPageAgent::goBack(ErrorString& errorString)
 | 
						||
+{
 | 
						||
+    if (!m_inspectedPage.backForward().goBack())
 | 
						||
+        errorString = "Failed to go back"_s;
 | 
						||
+}
 | 
						||
+
 | 
						||
+void InspectorPageAgent::goForward(ErrorString& errorString)
 | 
						||
+{
 | 
						||
+    if (!m_inspectedPage.backForward().goForward())
 | 
						||
+        errorString = "Failed to go forward"_s;
 | 
						||
+}
 | 
						||
+
 | 
						||
+void InspectorPageAgent::navigate(ErrorString& errorString, const String& url, const String* frameId, const String* referrer)
 | 
						||
 {
 | 
						||
     UserGestureIndicator indicator { ProcessingUserGesture };
 | 
						||
-    Frame& frame = m_inspectedPage.mainFrame();
 | 
						||
+    Frame* frame = frameId ? assertFrame(errorString, *frameId) : &m_inspectedPage.mainFrame();
 | 
						||
+    if (!frame)
 | 
						||
+        return;
 | 
						||
+
 | 
						||
+    ResourceRequest resourceRequest { frame->document()->completeURL(url) };
 | 
						||
+    if (!resourceRequest.url().isValid()) {
 | 
						||
+        errorString = "Cannot navigate to invalid URL"_s;
 | 
						||
+        return;
 | 
						||
+    }
 | 
						||
 
 | 
						||
-    ResourceRequest resourceRequest { frame.document()->completeURL(url) };
 | 
						||
-    FrameLoadRequest frameLoadRequest { *frame.document(), frame.document()->securityOrigin(), WTFMove(resourceRequest), "_self"_s, LockHistory::No, LockBackForwardList::No, ReferrerPolicy::EmptyString, AllowNavigationToInvalidURL::No, NewFrameOpenerPolicy::Allow, ShouldOpenExternalURLsPolicy::ShouldNotAllow, InitiatedByMainFrame::Unknown };
 | 
						||
-    frame.loader().changeLocation(WTFMove(frameLoadRequest));
 | 
						||
+    if (referrer)
 | 
						||
+        resourceRequest.setInitiatorIdentifier(InspectorNetworkAgent::createInitiatorIdentifierForInspectorNavigation(*referrer));
 | 
						||
+    FrameLoadRequest frameLoadRequest { *frame->document(), frame->document()->securityOrigin(), WTFMove(resourceRequest), "_self"_s, LockHistory::No, LockBackForwardList::No, ReferrerPolicy::EmptyString, AllowNavigationToInvalidURL::No, NewFrameOpenerPolicy::Allow, ShouldOpenExternalURLsPolicy::ShouldNotAllow, InitiatedByMainFrame::Unknown };
 | 
						||
+    frame->loader().changeLocation(WTFMove(frameLoadRequest));
 | 
						||
 }
 | 
						||
 
 | 
						||
 void InspectorPageAgent::overrideUserAgent(ErrorString&, const String* value)
 | 
						||
@@ -683,15 +733,16 @@ void InspectorPageAgent::setShowPaintRects(ErrorString&, bool show)
 | 
						||
     m_overlay->setShowPaintRects(show);
 | 
						||
 }
 | 
						||
 
 | 
						||
-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)
 | 
						||
@@ -699,13 +750,18 @@ void InspectorPageAgent::frameNavigated(Frame& frame)
 | 
						||
     m_frontendDispatcher->frameNavigated(buildObjectForFrame(&frame));
 | 
						||
 }
 | 
						||
 
 | 
						||
+static String globalIDForFrame(Frame& frame)
 | 
						||
+{
 | 
						||
+    return makeString(Process::identifier().toUInt64(), ".", frame.loader().client().frameID()->toUInt64());
 | 
						||
+}
 | 
						||
+
 | 
						||
 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 String& frameId)
 | 
						||
@@ -717,20 +773,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(ErrorString& errorString, const String& frameId)
 | 
						||
@@ -741,11 +795,6 @@ Frame* InspectorPageAgent::assertFrame(ErrorString& errorString, const String& f
 | 
						||
     return frame;
 | 
						||
 }
 | 
						||
 
 | 
						||
-void InspectorPageAgent::loaderDetachedFromFrame(DocumentLoader& loader)
 | 
						||
-{
 | 
						||
-    m_loaderToIdentifier.remove(&loader);
 | 
						||
-}
 | 
						||
-
 | 
						||
 void InspectorPageAgent::frameStartedLoading(Frame& frame)
 | 
						||
 {
 | 
						||
     m_frontendDispatcher->frameStartedLoading(frameId(&frame));
 | 
						||
@@ -766,6 +815,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);
 | 
						||
+}
 | 
						||
+
 | 
						||
 void InspectorPageAgent::defaultAppearanceDidChange(bool useDarkAppearance)
 | 
						||
 {
 | 
						||
     m_frontendDispatcher->defaultAppearanceDidChange(useDarkAppearance ? Inspector::Protocol::Page::Appearance::Dark : Inspector::Protocol::Page::Appearance::Light);
 | 
						||
@@ -823,6 +878,38 @@ void InspectorPageAgent::didRecalculateStyle()
 | 
						||
     m_overlay->update();
 | 
						||
 }
 | 
						||
 
 | 
						||
+void InspectorPageAgent::runOpenPanel(HTMLInputElement* element, bool* intercept)
 | 
						||
+{
 | 
						||
+    if (m_interceptFileChooserDialog) {
 | 
						||
+        *intercept = true;
 | 
						||
+    } else {
 | 
						||
+        return;
 | 
						||
+    }
 | 
						||
+    Document& document = element->document();
 | 
						||
+    auto* frame =  document.frame();
 | 
						||
+    if (!frame)
 | 
						||
+        return;
 | 
						||
+
 | 
						||
+    auto& state = *mainWorldExecState(frame);
 | 
						||
+    auto injectedScript = m_injectedScriptManager.injectedScriptFor(&state);
 | 
						||
+    if (injectedScript.hasNoValue())
 | 
						||
+        return;
 | 
						||
+
 | 
						||
+    m_frontendDispatcher->fileChooserOpened(frameId(frame), injectedScript.wrapObject(InspectorDOMAgent::nodeAsScriptValue(state, element), WTF::String()));
 | 
						||
+}
 | 
						||
+
 | 
						||
+void InspectorPageAgent::frameAttached(Frame& frame)
 | 
						||
+{
 | 
						||
+    Frame* parent = frame.tree().parent();
 | 
						||
+    String parentFrameId = frameId(parent);
 | 
						||
+    m_frontendDispatcher->frameAttached(frameId(&frame), parent ? &parentFrameId : nullptr);
 | 
						||
+}
 | 
						||
+
 | 
						||
+bool InspectorPageAgent::shouldBypassCSP()
 | 
						||
+{
 | 
						||
+    return m_bypassCSP;
 | 
						||
+}
 | 
						||
+
 | 
						||
 Ref<Inspector::Protocol::Page::Frame> InspectorPageAgent::buildObjectForFrame(Frame* frame)
 | 
						||
 {
 | 
						||
     ASSERT_ARG(frame, frame);
 | 
						||
@@ -966,6 +1053,29 @@ void InspectorPageAgent::snapshotRect(ErrorString& errorString, int x, int y, in
 | 
						||
     *outDataURL = snapshot->toDataURL("image/png"_s, WTF::nullopt, PreserveResolution::Yes);
 | 
						||
 }
 | 
						||
 
 | 
						||
+void InspectorPageAgent::setTimeZone(ErrorString& errorString, const String* timeZone)
 | 
						||
+{
 | 
						||
+    if (!timeZone) {
 | 
						||
+        WTF::setTimeZoneForAutomation(String());
 | 
						||
+        return;
 | 
						||
+    }
 | 
						||
+    bool success = WTF::setTimeZoneForAutomation(*timeZone);
 | 
						||
+    if (!success)
 | 
						||
+        errorString = "Invalid time zone " + *timeZone;
 | 
						||
+}
 | 
						||
+
 | 
						||
+void InspectorPageAgent::setTouchEmulationEnabled(ErrorString& errorString, bool enabled)
 | 
						||
+{
 | 
						||
+#if ENABLE(TOUCH_EVENTS)
 | 
						||
+    RuntimeEnabledFeatures::sharedFeatures().setTouchEventsEnabled(enabled);
 | 
						||
+    UNUSED_PARAM(errorString);
 | 
						||
+#else
 | 
						||
+    UNUSED_PARAM(enabled);
 | 
						||
+    errorString = "Not supported"_s;
 | 
						||
+#endif
 | 
						||
+}
 | 
						||
+
 | 
						||
+
 | 
						||
 void InspectorPageAgent::archive(ErrorString& errorString, String* data)
 | 
						||
 {
 | 
						||
 #if ENABLE(WEB_ARCHIVE) && USE(CF)
 | 
						||
@@ -983,4 +1093,529 @@ void InspectorPageAgent::archive(ErrorString& errorString, String* data)
 | 
						||
 #endif
 | 
						||
 }
 | 
						||
 
 | 
						||
+void InspectorPageAgent::insertText(ErrorString&, const String& text)
 | 
						||
+{
 | 
						||
+    UserGestureIndicator indicator { ProcessingUserGesture };
 | 
						||
+    Document* focusedDocument = m_inspectedPage.focusController().focusedOrMainFrame().document();
 | 
						||
+    TypingCommand::insertText(*focusedDocument, text, 0);
 | 
						||
+}
 | 
						||
+
 | 
						||
+static String roleFromObject(RefPtr<AXCoreObject> axObject)
 | 
						||
+{
 | 
						||
+    String computedRoleString = axObject->computedRoleString();
 | 
						||
+    if (!computedRoleString.isEmpty())
 | 
						||
+        return computedRoleString;
 | 
						||
+    AccessibilityRole role = axObject->roleValue();
 | 
						||
+    switch(role) {
 | 
						||
+        case AccessibilityRole::Annotation:
 | 
						||
+            return "Annotation";
 | 
						||
+        case AccessibilityRole::Application:
 | 
						||
+            return "Application";
 | 
						||
+        case AccessibilityRole::ApplicationAlert:
 | 
						||
+            return "ApplicationAlert";
 | 
						||
+        case AccessibilityRole::ApplicationAlertDialog:
 | 
						||
+            return "ApplicationAlertDialog";
 | 
						||
+        case AccessibilityRole::ApplicationDialog:
 | 
						||
+            return "ApplicationDialog";
 | 
						||
+        case AccessibilityRole::ApplicationGroup:
 | 
						||
+            return "ApplicationGroup";
 | 
						||
+        case AccessibilityRole::ApplicationLog:
 | 
						||
+            return "ApplicationLog";
 | 
						||
+        case AccessibilityRole::ApplicationMarquee:
 | 
						||
+            return "ApplicationMarquee";
 | 
						||
+        case AccessibilityRole::ApplicationStatus:
 | 
						||
+            return "ApplicationStatus";
 | 
						||
+        case AccessibilityRole::ApplicationTextGroup:
 | 
						||
+            return "ApplicationTextGroup";
 | 
						||
+        case AccessibilityRole::ApplicationTimer:
 | 
						||
+            return "ApplicationTimer";
 | 
						||
+        case AccessibilityRole::Audio:
 | 
						||
+            return "Audio";
 | 
						||
+        case AccessibilityRole::Blockquote:
 | 
						||
+            return "Blockquote";
 | 
						||
+        case AccessibilityRole::Browser:
 | 
						||
+            return "Browser";
 | 
						||
+        case AccessibilityRole::BusyIndicator:
 | 
						||
+            return "BusyIndicator";
 | 
						||
+        case AccessibilityRole::Button:
 | 
						||
+            return "Button";
 | 
						||
+        case AccessibilityRole::Canvas:
 | 
						||
+            return "Canvas";
 | 
						||
+        case AccessibilityRole::Caption:
 | 
						||
+            return "Caption";
 | 
						||
+        case AccessibilityRole::Cell:
 | 
						||
+            return "Cell";
 | 
						||
+        case AccessibilityRole::CheckBox:
 | 
						||
+            return "CheckBox";
 | 
						||
+        case AccessibilityRole::ColorWell:
 | 
						||
+            return "ColorWell";
 | 
						||
+        case AccessibilityRole::Column:
 | 
						||
+            return "Column";
 | 
						||
+        case AccessibilityRole::ColumnHeader:
 | 
						||
+            return "ColumnHeader";
 | 
						||
+        case AccessibilityRole::ComboBox:
 | 
						||
+            return "ComboBox";
 | 
						||
+        case AccessibilityRole::Definition:
 | 
						||
+            return "Definition";
 | 
						||
+        case AccessibilityRole::Deletion:
 | 
						||
+            return "Deletion";
 | 
						||
+        case AccessibilityRole::DescriptionList:
 | 
						||
+            return "DescriptionList";
 | 
						||
+        case AccessibilityRole::DescriptionListTerm:
 | 
						||
+            return "DescriptionListTerm";
 | 
						||
+        case AccessibilityRole::DescriptionListDetail:
 | 
						||
+            return "DescriptionListDetail";
 | 
						||
+        case AccessibilityRole::Details:
 | 
						||
+            return "Details";
 | 
						||
+        case AccessibilityRole::Directory:
 | 
						||
+            return "Directory";
 | 
						||
+        case AccessibilityRole::DisclosureTriangle:
 | 
						||
+            return "DisclosureTriangle";
 | 
						||
+        case AccessibilityRole::Div:
 | 
						||
+            return "Div";
 | 
						||
+        case AccessibilityRole::Document:
 | 
						||
+            return "Document";
 | 
						||
+        case AccessibilityRole::DocumentArticle:
 | 
						||
+            return "DocumentArticle";
 | 
						||
+        case AccessibilityRole::DocumentMath:
 | 
						||
+            return "DocumentMath";
 | 
						||
+        case AccessibilityRole::DocumentNote:
 | 
						||
+            return "DocumentNote";
 | 
						||
+        case AccessibilityRole::Drawer:
 | 
						||
+            return "Drawer";
 | 
						||
+        case AccessibilityRole::EditableText:
 | 
						||
+            return "EditableText";
 | 
						||
+        case AccessibilityRole::Feed:
 | 
						||
+            return "Feed";
 | 
						||
+        case AccessibilityRole::Figure:
 | 
						||
+            return "Figure";
 | 
						||
+        case AccessibilityRole::Footer:
 | 
						||
+            return "Footer";
 | 
						||
+        case AccessibilityRole::Footnote:
 | 
						||
+            return "Footnote";
 | 
						||
+        case AccessibilityRole::Form:
 | 
						||
+            return "Form";
 | 
						||
+        case AccessibilityRole::GraphicsDocument:
 | 
						||
+            return "GraphicsDocument";
 | 
						||
+        case AccessibilityRole::GraphicsObject:
 | 
						||
+            return "GraphicsObject";
 | 
						||
+        case AccessibilityRole::GraphicsSymbol:
 | 
						||
+            return "GraphicsSymbol";
 | 
						||
+        case AccessibilityRole::Grid:
 | 
						||
+            return "Grid";
 | 
						||
+        case AccessibilityRole::GridCell:
 | 
						||
+            return "GridCell";
 | 
						||
+        case AccessibilityRole::Group:
 | 
						||
+            return "Group";
 | 
						||
+        case AccessibilityRole::GrowArea:
 | 
						||
+            return "GrowArea";
 | 
						||
+        case AccessibilityRole::Heading:
 | 
						||
+            return "Heading";
 | 
						||
+        case AccessibilityRole::HelpTag:
 | 
						||
+            return "HelpTag";
 | 
						||
+        case AccessibilityRole::HorizontalRule:
 | 
						||
+            return "HorizontalRule";
 | 
						||
+        case AccessibilityRole::Ignored:
 | 
						||
+            return "Ignored";
 | 
						||
+        case AccessibilityRole::Inline:
 | 
						||
+            return "Inline";
 | 
						||
+        case AccessibilityRole::Image:
 | 
						||
+            return "Image";
 | 
						||
+        case AccessibilityRole::ImageMap:
 | 
						||
+            return "ImageMap";
 | 
						||
+        case AccessibilityRole::ImageMapLink:
 | 
						||
+            return "ImageMapLink";
 | 
						||
+        case AccessibilityRole::Incrementor:
 | 
						||
+            return "Incrementor";
 | 
						||
+        case AccessibilityRole::Insertion:
 | 
						||
+            return "Insertion";
 | 
						||
+        case AccessibilityRole::Label:
 | 
						||
+            return "Label";
 | 
						||
+        case AccessibilityRole::LandmarkBanner:
 | 
						||
+            return "LandmarkBanner";
 | 
						||
+        case AccessibilityRole::LandmarkComplementary:
 | 
						||
+            return "LandmarkComplementary";
 | 
						||
+        case AccessibilityRole::LandmarkContentInfo:
 | 
						||
+            return "LandmarkContentInfo";
 | 
						||
+        case AccessibilityRole::LandmarkDocRegion:
 | 
						||
+            return "LandmarkDocRegion";
 | 
						||
+        case AccessibilityRole::LandmarkMain:
 | 
						||
+            return "LandmarkMain";
 | 
						||
+        case AccessibilityRole::LandmarkNavigation:
 | 
						||
+            return "LandmarkNavigation";
 | 
						||
+        case AccessibilityRole::LandmarkRegion:
 | 
						||
+            return "LandmarkRegion";
 | 
						||
+        case AccessibilityRole::LandmarkSearch:
 | 
						||
+            return "LandmarkSearch";
 | 
						||
+        case AccessibilityRole::Legend:
 | 
						||
+            return "Legend";
 | 
						||
+        case AccessibilityRole::Link:
 | 
						||
+            return "Link";
 | 
						||
+        case AccessibilityRole::List:
 | 
						||
+            return "List";
 | 
						||
+        case AccessibilityRole::ListBox:
 | 
						||
+            return "ListBox";
 | 
						||
+        case AccessibilityRole::ListBoxOption:
 | 
						||
+            return "ListBoxOption";
 | 
						||
+        case AccessibilityRole::ListItem:
 | 
						||
+            return "ListItem";
 | 
						||
+        case AccessibilityRole::ListMarker:
 | 
						||
+            return "ListMarker";
 | 
						||
+        case AccessibilityRole::Mark:
 | 
						||
+            return "Mark";
 | 
						||
+        case AccessibilityRole::MathElement:
 | 
						||
+            return "MathElement";
 | 
						||
+        case AccessibilityRole::Matte:
 | 
						||
+            return "Matte";
 | 
						||
+        case AccessibilityRole::Menu:
 | 
						||
+            return "Menu";
 | 
						||
+        case AccessibilityRole::MenuBar:
 | 
						||
+            return "MenuBar";
 | 
						||
+        case AccessibilityRole::MenuButton:
 | 
						||
+            return "MenuButton";
 | 
						||
+        case AccessibilityRole::MenuItem:
 | 
						||
+            return "MenuItem";
 | 
						||
+        case AccessibilityRole::MenuItemCheckbox:
 | 
						||
+            return "MenuItemCheckbox";
 | 
						||
+        case AccessibilityRole::MenuItemRadio:
 | 
						||
+            return "MenuItemRadio";
 | 
						||
+        case AccessibilityRole::MenuListPopup:
 | 
						||
+            return "MenuListPopup";
 | 
						||
+        case AccessibilityRole::MenuListOption:
 | 
						||
+            return "MenuListOption";
 | 
						||
+        case AccessibilityRole::Meter:
 | 
						||
+            return "Meter";
 | 
						||
+        case AccessibilityRole::Outline:
 | 
						||
+            return "Outline";
 | 
						||
+        case AccessibilityRole::Paragraph:
 | 
						||
+            return "Paragraph";
 | 
						||
+        case AccessibilityRole::PopUpButton:
 | 
						||
+            return "PopUpButton";
 | 
						||
+        case AccessibilityRole::Pre:
 | 
						||
+            return "Pre";
 | 
						||
+        case AccessibilityRole::Presentational:
 | 
						||
+            return "Presentational";
 | 
						||
+        case AccessibilityRole::ProgressIndicator:
 | 
						||
+            return "ProgressIndicator";
 | 
						||
+        case AccessibilityRole::RadioButton:
 | 
						||
+            return "RadioButton";
 | 
						||
+        case AccessibilityRole::RadioGroup:
 | 
						||
+            return "RadioGroup";
 | 
						||
+        case AccessibilityRole::RowHeader:
 | 
						||
+            return "RowHeader";
 | 
						||
+        case AccessibilityRole::Row:
 | 
						||
+            return "Row";
 | 
						||
+        case AccessibilityRole::RowGroup:
 | 
						||
+            return "RowGroup";
 | 
						||
+        case AccessibilityRole::RubyBase:
 | 
						||
+            return "RubyBase";
 | 
						||
+        case AccessibilityRole::RubyBlock:
 | 
						||
+            return "RubyBlock";
 | 
						||
+        case AccessibilityRole::RubyInline:
 | 
						||
+            return "RubyInline";
 | 
						||
+        case AccessibilityRole::RubyRun:
 | 
						||
+            return "RubyRun";
 | 
						||
+        case AccessibilityRole::RubyText:
 | 
						||
+            return "RubyText";
 | 
						||
+        case AccessibilityRole::Ruler:
 | 
						||
+            return "Ruler";
 | 
						||
+        case AccessibilityRole::RulerMarker:
 | 
						||
+            return "RulerMarker";
 | 
						||
+        case AccessibilityRole::ScrollArea:
 | 
						||
+            return "ScrollArea";
 | 
						||
+        case AccessibilityRole::ScrollBar:
 | 
						||
+            return "ScrollBar";
 | 
						||
+        case AccessibilityRole::SearchField:
 | 
						||
+            return "SearchField";
 | 
						||
+        case AccessibilityRole::Sheet:
 | 
						||
+            return "Sheet";
 | 
						||
+        case AccessibilityRole::Slider:
 | 
						||
+            return "Slider";
 | 
						||
+        case AccessibilityRole::SliderThumb:
 | 
						||
+            return "SliderThumb";
 | 
						||
+        case AccessibilityRole::SpinButton:
 | 
						||
+            return "SpinButton";
 | 
						||
+        case AccessibilityRole::SpinButtonPart:
 | 
						||
+            return "SpinButtonPart";
 | 
						||
+        case AccessibilityRole::SplitGroup:
 | 
						||
+            return "SplitGroup";
 | 
						||
+        case AccessibilityRole::Splitter:
 | 
						||
+            return "Splitter";
 | 
						||
+        case AccessibilityRole::StaticText:
 | 
						||
+            return "StaticText";
 | 
						||
+        case AccessibilityRole::Subscript:
 | 
						||
+            return "Subscript";
 | 
						||
+        case AccessibilityRole::Summary:
 | 
						||
+            return "Summary";
 | 
						||
+        case AccessibilityRole::Superscript:
 | 
						||
+            return "Superscript";
 | 
						||
+        case AccessibilityRole::Switch:
 | 
						||
+            return "Switch";
 | 
						||
+        case AccessibilityRole::SystemWide:
 | 
						||
+            return "SystemWide";
 | 
						||
+        case AccessibilityRole::SVGRoot:
 | 
						||
+            return "SVGRoot";
 | 
						||
+        case AccessibilityRole::SVGText:
 | 
						||
+            return "SVGText";
 | 
						||
+        case AccessibilityRole::SVGTSpan:
 | 
						||
+            return "SVGTSpan";
 | 
						||
+        case AccessibilityRole::SVGTextPath:
 | 
						||
+            return "SVGTextPath";
 | 
						||
+        case AccessibilityRole::TabGroup:
 | 
						||
+            return "TabGroup";
 | 
						||
+        case AccessibilityRole::TabList:
 | 
						||
+            return "TabList";
 | 
						||
+        case AccessibilityRole::TabPanel:
 | 
						||
+            return "TabPanel";
 | 
						||
+        case AccessibilityRole::Tab:
 | 
						||
+            return "Tab";
 | 
						||
+        case AccessibilityRole::Table:
 | 
						||
+            return "Table";
 | 
						||
+        case AccessibilityRole::TableHeaderContainer:
 | 
						||
+            return "TableHeaderContainer";
 | 
						||
+        case AccessibilityRole::TextArea:
 | 
						||
+            return "TextArea";
 | 
						||
+        case AccessibilityRole::TextGroup:
 | 
						||
+            return "TextGroup";
 | 
						||
+        case AccessibilityRole::Term:
 | 
						||
+            return "Term";
 | 
						||
+        case AccessibilityRole::Time:
 | 
						||
+            return "Time";
 | 
						||
+        case AccessibilityRole::Tree:
 | 
						||
+            return "Tree";
 | 
						||
+        case AccessibilityRole::TreeGrid:
 | 
						||
+            return "TreeGrid";
 | 
						||
+        case AccessibilityRole::TreeItem:
 | 
						||
+            return "TreeItem";
 | 
						||
+        case AccessibilityRole::TextField:
 | 
						||
+            return "TextField";
 | 
						||
+        case AccessibilityRole::ToggleButton:
 | 
						||
+            return "ToggleButton";
 | 
						||
+        case AccessibilityRole::Toolbar:
 | 
						||
+            return "Toolbar";
 | 
						||
+        case AccessibilityRole::Unknown:
 | 
						||
+            return "Unknown";
 | 
						||
+        case AccessibilityRole::UserInterfaceTooltip:
 | 
						||
+            return "UserInterfaceTooltip";
 | 
						||
+        case AccessibilityRole::ValueIndicator:
 | 
						||
+            return "ValueIndicator";
 | 
						||
+        case AccessibilityRole::Video:
 | 
						||
+            return "Video";
 | 
						||
+        case AccessibilityRole::WebApplication:
 | 
						||
+            return "WebApplication";
 | 
						||
+        case AccessibilityRole::WebArea:
 | 
						||
+            return "WebArea";
 | 
						||
+        case AccessibilityRole::WebCoreLink:
 | 
						||
+            return "WebCoreLink";
 | 
						||
+        case AccessibilityRole::Window:
 | 
						||
+            return "Window";
 | 
						||
+    };
 | 
						||
+    return "Unknown";
 | 
						||
+}
 | 
						||
+
 | 
						||
+static RefPtr<Inspector::Protocol::Page::AXNode> snapshotForAXObject(RefPtr<AXCoreObject> axObject, Node* nodeToFind)
 | 
						||
+{
 | 
						||
+    auto axNode = Inspector::Protocol::Page::AXNode::create()
 | 
						||
+        .setRole(roleFromObject(axObject))
 | 
						||
+        .release();
 | 
						||
+
 | 
						||
+    if (!axObject->computedLabel().isEmpty())
 | 
						||
+        axNode->setName(axObject->computedLabel());
 | 
						||
+    if (!axObject->stringValue().isEmpty())
 | 
						||
+        axNode->setValue(JSON::Value::create(axObject->stringValue()));
 | 
						||
+    if (!axObject->accessibilityDescription().isEmpty())
 | 
						||
+        axNode->setDescription(axObject->accessibilityDescription());
 | 
						||
+    if (!axObject->keyShortcutsValue().isEmpty())
 | 
						||
+        axNode->setKeyshortcuts(axObject->keyShortcutsValue());
 | 
						||
+    if (!axObject->valueDescription().isEmpty())
 | 
						||
+        axNode->setValuetext(axObject->valueDescription());
 | 
						||
+    if (!axObject->roleDescription().isEmpty())
 | 
						||
+        axNode->setRoledescription(axObject->roleDescription());
 | 
						||
+    if (!axObject->isEnabled())
 | 
						||
+        axNode->setDisabled(!axObject->isEnabled());
 | 
						||
+    if (axObject->supportsExpanded())
 | 
						||
+        axNode->setExpanded(axObject->isExpanded());
 | 
						||
+    if (axObject->isFocused())
 | 
						||
+        axNode->setFocused(axObject->isFocused());
 | 
						||
+    if (axObject->isModalNode())
 | 
						||
+        axNode->setModal(axObject->isModalNode());
 | 
						||
+    bool multiline = axObject->ariaIsMultiline() || axObject->roleValue() == AccessibilityRole::TextArea;
 | 
						||
+    if (multiline)
 | 
						||
+        axNode->setMultiline(multiline);
 | 
						||
+    if (axObject->isMultiSelectable())
 | 
						||
+        axNode->setMultiselectable(axObject->isMultiSelectable());
 | 
						||
+    if (axObject->supportsReadOnly() && !axObject->canSetValueAttribute() && axObject->isEnabled())
 | 
						||
+        axNode->setReadonly(true);
 | 
						||
+    if (axObject->supportsRequiredAttribute())
 | 
						||
+        axNode->setRequired(axObject->isRequired());
 | 
						||
+    if (axObject->isSelected())
 | 
						||
+        axNode->setSelected(axObject->isSelected());
 | 
						||
+    if (axObject->supportsChecked()) {
 | 
						||
+        AccessibilityButtonState checkedState = axObject->checkboxOrRadioValue();
 | 
						||
+        switch (checkedState) {
 | 
						||
+            case AccessibilityButtonState::On:
 | 
						||
+                axNode->setChecked(Inspector::Protocol::Page::AXNode::Checked::True);
 | 
						||
+                break;
 | 
						||
+            case AccessibilityButtonState::Off:
 | 
						||
+                axNode->setChecked(Inspector::Protocol::Page::AXNode::Checked::False);
 | 
						||
+                break;
 | 
						||
+            case AccessibilityButtonState::Mixed:
 | 
						||
+                axNode->setChecked(Inspector::Protocol::Page::AXNode::Checked::Mixed);
 | 
						||
+                break;
 | 
						||
+        }
 | 
						||
+    }
 | 
						||
+    if (axObject->supportsPressed()) {
 | 
						||
+        AccessibilityButtonState checkedState = axObject->checkboxOrRadioValue();
 | 
						||
+        switch (checkedState) {
 | 
						||
+            case AccessibilityButtonState::On:
 | 
						||
+                axNode->setPressed(Inspector::Protocol::Page::AXNode::Pressed::True);
 | 
						||
+                break;
 | 
						||
+            case AccessibilityButtonState::Off:
 | 
						||
+                axNode->setPressed(Inspector::Protocol::Page::AXNode::Pressed::False);
 | 
						||
+                break;
 | 
						||
+            case AccessibilityButtonState::Mixed:
 | 
						||
+                axNode->setPressed(Inspector::Protocol::Page::AXNode::Pressed::Mixed);
 | 
						||
+                break;
 | 
						||
+        }
 | 
						||
+    }
 | 
						||
+    unsigned level = axObject->hierarchicalLevel() ? axObject->hierarchicalLevel() : axObject->headingLevel();
 | 
						||
+    if (level)
 | 
						||
+        axNode->setLevel(level);
 | 
						||
+    if (axObject->minValueForRange() != 0)
 | 
						||
+        axNode->setValuemin(axObject->minValueForRange());
 | 
						||
+    if (axObject->maxValueForRange() != 0)
 | 
						||
+        axNode->setValuemax(axObject->maxValueForRange());
 | 
						||
+    if (axObject->supportsAutoComplete())
 | 
						||
+        axNode->setAutocomplete(axObject->autoCompleteValue());
 | 
						||
+    if (axObject->hasPopup())
 | 
						||
+        axNode->setHaspopup(axObject->popupValue());
 | 
						||
+
 | 
						||
+    String invalidValue = axObject->invalidStatus();
 | 
						||
+    if (invalidValue != "false") {
 | 
						||
+        if (invalidValue == "grammar")
 | 
						||
+            axNode->setInvalid(Inspector::Protocol::Page::AXNode::Invalid::Grammar);
 | 
						||
+        else if (invalidValue == "spelling")
 | 
						||
+            axNode->setInvalid(Inspector::Protocol::Page::AXNode::Invalid::Spelling);
 | 
						||
+        else // Future versions of ARIA may allow additional truthy values. Ex. format, order, or size.
 | 
						||
+            axNode->setInvalid(Inspector::Protocol::Page::AXNode::Invalid::True);
 | 
						||
+    }
 | 
						||
+    switch (axObject->orientation()) {
 | 
						||
+        case AccessibilityOrientation::Undefined:
 | 
						||
+            break;
 | 
						||
+        case AccessibilityOrientation::Vertical:
 | 
						||
+            axNode->setOrientation("vertical"_s);
 | 
						||
+            break;
 | 
						||
+        case AccessibilityOrientation::Horizontal:
 | 
						||
+            axNode->setOrientation("horizontal"_s);
 | 
						||
+            break;
 | 
						||
+    }
 | 
						||
+
 | 
						||
+    if (axObject->isKeyboardFocusable())
 | 
						||
+        axNode->setFocusable(axObject->isKeyboardFocusable());
 | 
						||
+
 | 
						||
+    if (nodeToFind && axObject->node() == nodeToFind)
 | 
						||
+        axNode->setFound(true);
 | 
						||
+
 | 
						||
+    if (axObject->hasChildren()) {
 | 
						||
+        RefPtr<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(children);
 | 
						||
+    }
 | 
						||
+    return axNode;
 | 
						||
+}
 | 
						||
+
 | 
						||
+
 | 
						||
+void InspectorPageAgent::accessibilitySnapshot(ErrorString& errorString, const String* objectId, RefPtr<Inspector::Protocol::Page::AXNode>& out_axNode)
 | 
						||
+{
 | 
						||
+    if (!WebCore::AXObjectCache::accessibilityEnabled())
 | 
						||
+        WebCore::AXObjectCache::enableAccessibility();
 | 
						||
+    auto document = makeRefPtr(m_inspectedPage.mainFrame().document());
 | 
						||
+    if (!document) {
 | 
						||
+        errorString = "No document for main frame"_s;
 | 
						||
+        return;
 | 
						||
+    }
 | 
						||
+    AXObjectCache* axObjectCache = document->axObjectCache();
 | 
						||
+    if (!axObjectCache) {
 | 
						||
+        errorString = "No AXObjectCache for main document"_s;
 | 
						||
+        return;
 | 
						||
+    }
 | 
						||
+    AXCoreObject* axObject = axObjectCache->rootObject();
 | 
						||
+    if (!axObject) {
 | 
						||
+        errorString = "No AXObject for main document"_s;
 | 
						||
+        return;
 | 
						||
+    }
 | 
						||
+
 | 
						||
+    Node* node = nullptr;
 | 
						||
+    if (objectId) {
 | 
						||
+        InspectorDOMAgent* domAgent = m_instrumentingAgents.inspectorDOMAgent();
 | 
						||
+        ASSERT(domAgent);
 | 
						||
+        node = domAgent->nodeForObjectId(*objectId);
 | 
						||
+        if (!node) {
 | 
						||
+            errorString = "No Node for objectId"_s;
 | 
						||
+            return;
 | 
						||
+        }
 | 
						||
+    }
 | 
						||
+
 | 
						||
+    out_axNode = snapshotForAXObject(makeRefPtr(axObject), node);
 | 
						||
+}
 | 
						||
+
 | 
						||
+void InspectorPageAgent::setInterceptFileChooserDialog(ErrorString&, bool enabled)
 | 
						||
+{
 | 
						||
+    m_interceptFileChooserDialog = enabled;
 | 
						||
+}
 | 
						||
+
 | 
						||
+void InspectorPageAgent::setDefaultBackgroundColorOverride(ErrorString& errorString, const JSON::Object* color)
 | 
						||
+{
 | 
						||
+    FrameView* view = m_inspectedPage.mainFrame().view();
 | 
						||
+    if (!view) {
 | 
						||
+        errorString = "Internal error: No frame view to set color two"_s;
 | 
						||
+        return;
 | 
						||
+    }
 | 
						||
+    if (!color) {
 | 
						||
+        view->updateBackgroundRecursively(Optional<Color>());
 | 
						||
+        return;
 | 
						||
+    }
 | 
						||
+    view->updateBackgroundRecursively(InspectorDOMAgent::parseColor(color));
 | 
						||
+}
 | 
						||
+
 | 
						||
+void InspectorPageAgent::createUserWorld(ErrorString& errorString, const String& name)
 | 
						||
+{
 | 
						||
+    if (createdUserWorlds().contains(name)) {
 | 
						||
+        errorString = "World with the given name already exists"_s;
 | 
						||
+        return;
 | 
						||
+    }
 | 
						||
+
 | 
						||
+    Ref<DOMWrapperWorld> world = ScriptController::createWorld(name, ScriptController::WorldType::User);
 | 
						||
+    ensureUserWorldsExistInAllFrames({world.ptr()});
 | 
						||
+    createdUserWorlds().set(name, WTFMove(world));
 | 
						||
+}
 | 
						||
+
 | 
						||
+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();
 | 
						||
+    }
 | 
						||
+}
 | 
						||
+
 | 
						||
+void InspectorPageAgent::setBypassCSP(ErrorString&, bool enabled)
 | 
						||
+{
 | 
						||
+    m_bypassCSP = enabled;
 | 
						||
+}
 | 
						||
+
 | 
						||
+void InspectorPageAgent::crash(ErrorString&)
 | 
						||
+{
 | 
						||
+    CRASH();
 | 
						||
+}
 | 
						||
+
 | 
						||
+void InspectorPageAgent::setScreenSizeOverride(ErrorString&, int width, int height)
 | 
						||
+{
 | 
						||
+    Optional<FloatSize> size;
 | 
						||
+    if (width && height)
 | 
						||
+        size = FloatSize(width, height);
 | 
						||
+    m_inspectedPage.setOverrideScreenSize(size);
 | 
						||
+}
 | 
						||
+
 | 
						||
+
 | 
						||
 } // namespace WebCore
 | 
						||
diff --git a/Source/WebCore/inspector/agents/InspectorPageAgent.h b/Source/WebCore/inspector/agents/InspectorPageAgent.h
 | 
						||
index 110173dbbfe819226b6c4caa0f65a5dee8c39f2b..f59486b7e1635ceaa67f3fe5968e8e0e42a023b9 100644
 | 
						||
--- a/Source/WebCore/inspector/agents/InspectorPageAgent.h
 | 
						||
+++ b/Source/WebCore/inspector/agents/InspectorPageAgent.h
 | 
						||
@@ -40,11 +40,16 @@
 | 
						||
 #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;
 | 
						||
@@ -97,7 +102,9 @@ public:
 | 
						||
     void enable(ErrorString&) override;
 | 
						||
     void disable(ErrorString&) override;
 | 
						||
     void reload(ErrorString&, const bool* optionalReloadFromOrigin, const bool* optionalRevalidateAllResources) override;
 | 
						||
-    void navigate(ErrorString&, const String& url) override;
 | 
						||
+    void goBack(ErrorString&) override;
 | 
						||
+    void goForward(ErrorString&) override;
 | 
						||
+    void navigate(ErrorString&, const String& url, const String* frameId, const String* referrer) override;
 | 
						||
     void overrideUserAgent(ErrorString&, const String* value) override;
 | 
						||
     void overrideSetting(ErrorString&, const String& setting, const bool* value) override;
 | 
						||
     void getCookies(ErrorString&, RefPtr<JSON::ArrayOf<Inspector::Protocol::Page::Cookie>>& cookies) override;
 | 
						||
@@ -111,20 +118,30 @@ public:
 | 
						||
     void setShowPaintRects(ErrorString&, bool show) override;
 | 
						||
     void setEmulatedMedia(ErrorString&, const String&) override;
 | 
						||
     void setForcedAppearance(ErrorString&, const String&) override;
 | 
						||
+    void setTimeZone(ErrorString&, const String*) override;
 | 
						||
+    void setTouchEmulationEnabled(ErrorString&, bool) override;
 | 
						||
     void snapshotNode(ErrorString&, int nodeId, String* outDataURL) override;
 | 
						||
-    void snapshotRect(ErrorString&, int x, int y, int width, int height, const String& coordinateSystem, String* outDataURL) override;
 | 
						||
+    void snapshotRect(ErrorString&, int x, int y, int width,  int height, const String& coordinateSystem, String* outDataURL) override;
 | 
						||
     void archive(ErrorString&, String* data) override;
 | 
						||
+    void insertText(ErrorString&, const String& text) override;
 | 
						||
+    void accessibilitySnapshot(ErrorString&, const String* objectId, RefPtr<Inspector::Protocol::Page::AXNode>& out_axNode) override;
 | 
						||
+    void setInterceptFileChooserDialog(ErrorString&, bool enabled) override;
 | 
						||
+    void setDefaultBackgroundColorOverride(ErrorString&, const JSON::Object*) override;
 | 
						||
+    void createUserWorld(ErrorString&, const String&) override;
 | 
						||
+    void setBypassCSP(ErrorString&, bool) override;
 | 
						||
+    void crash(ErrorString&) override;
 | 
						||
+    void setScreenSizeOverride(ErrorString&, int width, int height) override;
 | 
						||
 
 | 
						||
     // 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&);
 | 
						||
     void defaultAppearanceDidChange(bool useDarkAppearance);
 | 
						||
     void applyUserAgentOverride(String&);
 | 
						||
     void applyEmulatedMedia(String&);
 | 
						||
@@ -133,6 +150,9 @@ public:
 | 
						||
     void didLayout();
 | 
						||
     void didScroll();
 | 
						||
     void didRecalculateStyle();
 | 
						||
+    void runOpenPanel(HTMLInputElement* element, bool* intercept);
 | 
						||
+    void frameAttached(Frame&);
 | 
						||
+    bool shouldBypassCSP();
 | 
						||
 
 | 
						||
     Frame* frameForId(const String& frameId);
 | 
						||
     WEBCORE_EXPORT String frameId(Frame*);
 | 
						||
@@ -141,6 +161,7 @@ public:
 | 
						||
 
 | 
						||
 private:
 | 
						||
     double timestamp();
 | 
						||
+    void ensureUserWorldsExistInAllFrames(const Vector<DOMWrapperWorld*>&);
 | 
						||
 
 | 
						||
     static bool mainResourceContent(Frame*, bool withBase64Encode, String* result);
 | 
						||
     static bool dataContent(const char* data, unsigned size, const String& textEncodingName, bool withBase64Encode, String* result);
 | 
						||
@@ -152,18 +173,19 @@ private:
 | 
						||
     RefPtr<Inspector::PageBackendDispatcher> m_backendDispatcher;
 | 
						||
 
 | 
						||
     Page& m_inspectedPage;
 | 
						||
+    Inspector::InjectedScriptManager& m_injectedScriptManager;
 | 
						||
     InspectorClient* m_client { nullptr };
 | 
						||
     InspectorOverlay* m_overlay { nullptr };
 | 
						||
 
 | 
						||
-    HashMap<Frame*, String> m_frameToIdentifier;
 | 
						||
     HashMap<String, Frame*> m_identifierToFrame;
 | 
						||
-    HashMap<DocumentLoader*, String> m_loaderToIdentifier;
 | 
						||
     String m_userAgentOverride;
 | 
						||
     String m_emulatedMedia;
 | 
						||
     String m_forcedAppearance;
 | 
						||
     String m_bootstrapScript;
 | 
						||
     bool m_isFirstLayoutAfterOnLoad { false };
 | 
						||
     bool m_showPaintRects { false };
 | 
						||
+    bool m_interceptFileChooserDialog { false };
 | 
						||
+    bool m_bypassCSP { false };
 | 
						||
 };
 | 
						||
 
 | 
						||
 } // namespace WebCore
 | 
						||
diff --git a/Source/WebCore/inspector/agents/InspectorWorkerAgent.cpp b/Source/WebCore/inspector/agents/InspectorWorkerAgent.cpp
 | 
						||
index 5b7d17a424be41789f73e795736defb8fdf4ed1b..ee571acbf3a4c34cd7039ddd04febe36164a7346 100644
 | 
						||
--- a/Source/WebCore/inspector/agents/InspectorWorkerAgent.cpp
 | 
						||
+++ b/Source/WebCore/inspector/agents/InspectorWorkerAgent.cpp
 | 
						||
@@ -160,7 +160,11 @@ void InspectorWorkerAgent::connectToWorkerInspectorProxy(WorkerInspectorProxy* p
 | 
						||
 
 | 
						||
     m_connectedProxies.set(proxy->identifier(), proxy);
 | 
						||
 
 | 
						||
-    m_frontendDispatcher->workerCreated(proxy->identifier(), proxy->url());
 | 
						||
+    ASSERT(is<Document>(proxy->scriptExecutionContext()));
 | 
						||
+    Document& document = downcast<Document>(*proxy->scriptExecutionContext());
 | 
						||
+    auto* pageAgent = m_instrumentingAgents.inspectorPageAgent();
 | 
						||
+    m_frontendDispatcher->workerCreated(proxy->identifier(), proxy->url(),
 | 
						||
+        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 cc0b0526f19f806ce621521d0771cc5f30d43840..6b54fa315ac22af78f2bf1befef204ca48308200 100644
 | 
						||
--- a/Source/WebCore/inspector/agents/page/PageDebuggerAgent.cpp
 | 
						||
+++ b/Source/WebCore/inspector/agents/page/PageDebuggerAgent.cpp
 | 
						||
@@ -38,6 +38,7 @@
 | 
						||
 #include "Frame.h"
 | 
						||
 #include "InspectorPageAgent.h"
 | 
						||
 #include "InstrumentingAgents.h"
 | 
						||
+#include "JSDOMWindowBase.h"
 | 
						||
 #include "Page.h"
 | 
						||
 #include "PageConsoleClient.h"
 | 
						||
 #include "PageScriptDebugServer.h"
 | 
						||
@@ -70,8 +71,11 @@ bool PageDebuggerAgent::enabled() const
 | 
						||
 
 | 
						||
 void PageDebuggerAgent::evaluateOnCallFrame(ErrorString& errorString, const String& callFrameId, const String& expression, const String* objectGroup, const bool* includeCommandLineAPI, const bool* doNotPauseOnExceptionsAndMuteConsole, const bool* returnByValue, const bool* generatePreview, const bool* saveResult, const bool* emulateUserGesture, RefPtr<Protocol::Runtime::RemoteObject>& result, Optional<bool>& wasThrown, Optional<int>& savedResultIndex)
 | 
						||
 {
 | 
						||
+    InjectedScript injectedScript = injectedScriptManager().injectedScriptForObjectId(callFrameId);
 | 
						||
+    JSC::JSGlobalObject* globalObject = injectedScript.globalObject();
 | 
						||
+    Document* document = globalObject ? activeDOMWindow(*globalObject).document() : nullptr;
 | 
						||
     auto shouldEmulateUserGesture = emulateUserGesture && *emulateUserGesture;
 | 
						||
-    UserGestureEmulationScope userGestureScope(m_inspectedPage, shouldEmulateUserGesture);
 | 
						||
+    UserGestureEmulationScope userGestureScope(m_inspectedPage, shouldEmulateUserGesture, document);
 | 
						||
 
 | 
						||
     WebDebuggerAgent::evaluateOnCallFrame(errorString, callFrameId, expression, objectGroup, includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole, returnByValue, generatePreview, saveResult, emulateUserGesture, result, wasThrown, savedResultIndex);
 | 
						||
 }
 | 
						||
diff --git a/Source/WebCore/inspector/agents/page/PageRuntimeAgent.cpp b/Source/WebCore/inspector/agents/page/PageRuntimeAgent.cpp
 | 
						||
index 63336051bb0050d6a55eb5543b0349eb964bbb7a..eecfb5a50196c6d9ca353e9b7aedbd4d6feb690c 100644
 | 
						||
--- a/Source/WebCore/inspector/agents/page/PageRuntimeAgent.cpp
 | 
						||
+++ b/Source/WebCore/inspector/agents/page/PageRuntimeAgent.cpp
 | 
						||
@@ -35,12 +35,14 @@
 | 
						||
 #include "DOMWrapperWorld.h"
 | 
						||
 #include "Document.h"
 | 
						||
 #include "Frame.h"
 | 
						||
+#include "FrameLoader.h"
 | 
						||
 #include "InspectorPageAgent.h"
 | 
						||
 #include "InstrumentingAgents.h"
 | 
						||
 #include "JSDOMWindowBase.h"
 | 
						||
 #include "Page.h"
 | 
						||
 #include "PageConsoleClient.h"
 | 
						||
 #include "ScriptController.h"
 | 
						||
+#include "ScriptSourceCode.h"
 | 
						||
 #include "ScriptState.h"
 | 
						||
 #include "SecurityOrigin.h"
 | 
						||
 #include "UserGestureEmulationScope.h"
 | 
						||
@@ -106,6 +108,15 @@ void PageRuntimeAgent::didClearWindowObjectInWorld(Frame& frame, DOMWrapperWorld
 | 
						||
     notifyContextCreated(pageAgent->frameId(&frame), frame.script().globalObject(world), world);
 | 
						||
 }
 | 
						||
 
 | 
						||
+void PageRuntimeAgent::didReceiveMainResourceError(Frame& frame)
 | 
						||
+{
 | 
						||
+    if (frame.loader().stateMachine().isDisplayingInitialEmptyDocument()) {
 | 
						||
+        // Ensure execution context is created for the empty docment to make
 | 
						||
+        // it usable in case loading failed.
 | 
						||
+        mainWorldExecState(&frame);
 | 
						||
+    }
 | 
						||
+}
 | 
						||
+
 | 
						||
 InjectedScript PageRuntimeAgent::injectedScriptForEval(ErrorString& errorString, const int* executionContextId)
 | 
						||
 {
 | 
						||
     if (!executionContextId) {
 | 
						||
@@ -194,13 +205,21 @@ void PageRuntimeAgent::notifyContextCreated(const String& frameId, JSC::JSGlobal
 | 
						||
 
 | 
						||
 void PageRuntimeAgent::evaluate(ErrorString& errorString, const String& expression, const String* objectGroup, const bool* includeCommandLineAPI, const bool* doNotPauseOnExceptionsAndMuteConsole, const int* executionContextId, const bool* returnByValue, const bool* generatePreview, const bool* saveResult, const bool* emulateUserGesture, RefPtr<Inspector::Protocol::Runtime::RemoteObject>& result, Optional<bool>& wasThrown, Optional<int>& savedResultIndex)
 | 
						||
 {
 | 
						||
-    UserGestureEmulationScope userGestureScope(m_inspectedPage, asBool(emulateUserGesture));
 | 
						||
+    InjectedScript injectedScript = injectedScriptForEval(errorString, executionContextId);
 | 
						||
+    if (!errorString.isEmpty())
 | 
						||
+        return;
 | 
						||
+    JSC::JSGlobalObject* globalObject = injectedScript.globalObject();
 | 
						||
+    Document* document = globalObject ? activeDOMWindow(*globalObject).document() : nullptr;
 | 
						||
+    UserGestureEmulationScope userGestureScope(m_inspectedPage, asBool(emulateUserGesture), document);
 | 
						||
     InspectorRuntimeAgent::evaluate(errorString, expression, objectGroup, includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole, executionContextId, returnByValue, generatePreview, saveResult, emulateUserGesture, result, wasThrown, savedResultIndex);
 | 
						||
 }
 | 
						||
 
 | 
						||
 void PageRuntimeAgent::callFunctionOn(ErrorString& errorString, const String& objectId, const String& expression, const JSON::Array* optionalArguments, const bool* doNotPauseOnExceptionsAndMuteConsole, const bool* returnByValue, const bool* generatePreview, const bool* emulateUserGesture, RefPtr<Inspector::Protocol::Runtime::RemoteObject>& result, Optional<bool>& wasThrown)
 | 
						||
 {
 | 
						||
-    UserGestureEmulationScope userGestureScope(m_inspectedPage, asBool(emulateUserGesture));
 | 
						||
+    InjectedScript injectedScript = injectedScriptManager().injectedScriptForObjectId(objectId);
 | 
						||
+    JSC::JSGlobalObject* globalObject = injectedScript.globalObject();
 | 
						||
+    Document* document = globalObject ? activeDOMWindow(*globalObject).document() : nullptr;
 | 
						||
+    UserGestureEmulationScope userGestureScope(m_inspectedPage, asBool(emulateUserGesture), document);
 | 
						||
     InspectorRuntimeAgent::callFunctionOn(errorString, objectId, expression, optionalArguments, doNotPauseOnExceptionsAndMuteConsole, returnByValue, generatePreview, emulateUserGesture, result, wasThrown);
 | 
						||
 }
 | 
						||
 
 | 
						||
diff --git a/Source/WebCore/inspector/agents/page/PageRuntimeAgent.h b/Source/WebCore/inspector/agents/page/PageRuntimeAgent.h
 | 
						||
index 2af3739b7fe7c16faa7d8d2797ce6d010215398d..80bfde6120874e16fb173f707fd0bd8a3e5067a0 100644
 | 
						||
--- a/Source/WebCore/inspector/agents/page/PageRuntimeAgent.h
 | 
						||
+++ b/Source/WebCore/inspector/agents/page/PageRuntimeAgent.h
 | 
						||
@@ -63,6 +63,7 @@ public:
 | 
						||
     // InspectorInstrumentation
 | 
						||
     void frameNavigated(Frame&);
 | 
						||
     void didClearWindowObjectInWorld(Frame&, DOMWrapperWorld&);
 | 
						||
+    void didReceiveMainResourceError(Frame&);
 | 
						||
 
 | 
						||
 private:
 | 
						||
     Inspector::InjectedScript injectedScriptForEval(ErrorString&, const int* executionContextId) override;
 | 
						||
@@ -73,7 +74,6 @@ private:
 | 
						||
 
 | 
						||
     std::unique_ptr<Inspector::RuntimeFrontendDispatcher> m_frontendDispatcher;
 | 
						||
     RefPtr<Inspector::RuntimeBackendDispatcher> m_backendDispatcher;
 | 
						||
-
 | 
						||
     InstrumentingAgents& m_instrumentingAgents;
 | 
						||
 
 | 
						||
     Page& m_inspectedPage;
 | 
						||
diff --git a/Source/WebCore/inspector/agents/page/UserGestureEmulationScope.cpp b/Source/WebCore/inspector/agents/page/UserGestureEmulationScope.cpp
 | 
						||
index 633bce6e8f3c0785632eb7f26d172f6016b3efd9..14f531504bb2b96646d1a48092a0b132b0510f55 100644
 | 
						||
--- a/Source/WebCore/inspector/agents/page/UserGestureEmulationScope.cpp
 | 
						||
+++ b/Source/WebCore/inspector/agents/page/UserGestureEmulationScope.cpp
 | 
						||
@@ -39,9 +39,9 @@
 | 
						||
 
 | 
						||
 namespace WebCore {
 | 
						||
 
 | 
						||
-UserGestureEmulationScope::UserGestureEmulationScope(Page& inspectedPage, bool emulateUserGesture)
 | 
						||
+UserGestureEmulationScope::UserGestureEmulationScope(Page& inspectedPage, bool emulateUserGesture, Document* document)
 | 
						||
     : m_pageChromeClient(inspectedPage.chrome().client())
 | 
						||
-    , m_gestureIndicator(emulateUserGesture ? Optional<ProcessingUserGestureState>(ProcessingUserGesture) : WTF::nullopt)
 | 
						||
+    , m_gestureIndicator(emulateUserGesture ? Optional<ProcessingUserGestureState>(ProcessingUserGesture) : WTF::nullopt, document)
 | 
						||
     , m_emulateUserGesture(emulateUserGesture)
 | 
						||
     , m_userWasInteracting(false)
 | 
						||
 {
 | 
						||
diff --git a/Source/WebCore/inspector/agents/page/UserGestureEmulationScope.h b/Source/WebCore/inspector/agents/page/UserGestureEmulationScope.h
 | 
						||
index b94ed78ad3dbea19543c1fd54653f0481e52fb7c..6341c7ff7ef53577f33c19ecad1b8bfbd674d051 100644
 | 
						||
--- a/Source/WebCore/inspector/agents/page/UserGestureEmulationScope.h
 | 
						||
+++ b/Source/WebCore/inspector/agents/page/UserGestureEmulationScope.h
 | 
						||
@@ -38,11 +38,12 @@ namespace WebCore {
 | 
						||
 
 | 
						||
 class ChromeClient;
 | 
						||
 class Page;
 | 
						||
+class Document;
 | 
						||
 
 | 
						||
 class UserGestureEmulationScope {
 | 
						||
     WTF_MAKE_NONCOPYABLE(UserGestureEmulationScope);
 | 
						||
 public:
 | 
						||
-    UserGestureEmulationScope(Page& inspectedPage, bool emulateUserGesture);
 | 
						||
+    UserGestureEmulationScope(Page& inspectedPage, bool emulateUserGesture, Document* document);
 | 
						||
     ~UserGestureEmulationScope();
 | 
						||
 
 | 
						||
 private:
 | 
						||
diff --git a/Source/WebCore/loader/DocumentLoader.cpp b/Source/WebCore/loader/DocumentLoader.cpp
 | 
						||
index 1511f5a7d4b038e7a8d2ddc4ae3e5060486fd794..80c08e8065c27724e8130fb7b2b164dbbc018937 100644
 | 
						||
--- a/Source/WebCore/loader/DocumentLoader.cpp
 | 
						||
+++ b/Source/WebCore/loader/DocumentLoader.cpp
 | 
						||
@@ -1289,8 +1289,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 d6a3d0acd246de70cb485880a04b38941c832f65..61c8d5478f5eefccf88532bebf69b94d97e8a88c 100644
 | 
						||
--- a/Source/WebCore/loader/DocumentLoader.h
 | 
						||
+++ b/Source/WebCore/loader/DocumentLoader.h
 | 
						||
@@ -163,9 +163,13 @@ public:
 | 
						||
 
 | 
						||
     WEBCORE_EXPORT virtual void detachFromFrame();
 | 
						||
 
 | 
						||
+    virtual void replacedByFragmentNavigation(Frame&) { }
 | 
						||
+
 | 
						||
     WEBCORE_EXPORT FrameLoader* frameLoader() const;
 | 
						||
     WEBCORE_EXPORT SubresourceLoader* mainResourceLoader() const;
 | 
						||
     WEBCORE_EXPORT RefPtr<SharedBuffer> mainResourceData() const;
 | 
						||
+
 | 
						||
+    virtual uint64_t loaderIDForInspector() { return 0; }
 | 
						||
     
 | 
						||
     DocumentWriter& writer() const { return m_writer; }
 | 
						||
 
 | 
						||
diff --git a/Source/WebCore/loader/FrameLoader.cpp b/Source/WebCore/loader/FrameLoader.cpp
 | 
						||
index 0f4a5283f5a3ef22d7e4203e660acf41f2545f19..9b3b2cf7df8310012bcc341abd40266d317e0cd4 100644
 | 
						||
--- a/Source/WebCore/loader/FrameLoader.cpp
 | 
						||
+++ b/Source/WebCore/loader/FrameLoader.cpp
 | 
						||
@@ -1183,6 +1183,7 @@ void FrameLoader::loadInSameDocument(const URL& url, SerializedScriptValue* stat
 | 
						||
     }
 | 
						||
 
 | 
						||
     m_client.dispatchDidNavigateWithinPage();
 | 
						||
+    InspectorInstrumentation::didNavigateWithinPage(m_frame);
 | 
						||
 
 | 
						||
     m_frame.document()->statePopped(stateObject ? Ref<SerializedScriptValue> { *stateObject } : SerializedScriptValue::nullValue());
 | 
						||
     m_client.dispatchDidPopStateWithinPage();
 | 
						||
@@ -1369,6 +1370,8 @@ void FrameLoader::loadURL(FrameLoadRequest&& frameLoadRequest, const String& ref
 | 
						||
 
 | 
						||
     ASSERT(newLoadType != FrameLoadType::Same);
 | 
						||
 
 | 
						||
+    request.setInitiatorIdentifier(frameLoadRequest.resourceRequest().initiatorIdentifier());
 | 
						||
+
 | 
						||
     // The search for a target frame is done earlier in the case of form submission.
 | 
						||
     Frame* targetFrame = isFormSubmission ? nullptr : findFrameForNavigation(effectiveFrameName);
 | 
						||
     if (targetFrame && targetFrame != &m_frame) {
 | 
						||
@@ -1501,6 +1504,7 @@ void FrameLoader::load(FrameLoadRequest&& request)
 | 
						||
 
 | 
						||
 void FrameLoader::loadWithNavigationAction(const ResourceRequest& request, NavigationAction&& action, LockHistory lockHistory, FrameLoadType type, RefPtr<FormState>&& formState, AllowNavigationToInvalidURL allowNavigationToInvalidURL, const String& downloadAttribute, CompletionHandler<void()>&& completionHandler)
 | 
						||
 {
 | 
						||
+    InspectorInstrumentation::frameScheduledNavigation(m_frame, Seconds(0));
 | 
						||
     FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "loadWithNavigationAction: frame load started");
 | 
						||
 
 | 
						||
     Ref<DocumentLoader> loader = m_client.createDocumentLoader(request, defaultSubstituteDataForURL(request.url()));
 | 
						||
@@ -1603,6 +1607,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 };
 | 
						||
 
 | 
						||
@@ -3196,6 +3202,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)
 | 
						||
@@ -3958,9 +3966,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)
 | 
						||
@@ -3969,13 +3974,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 579d9038f317d45d27c84a27e3f21cff0ae8fddf..9dc41a6ff78b85e229927409b309e01adce2f27a 100644
 | 
						||
--- a/Source/WebCore/loader/LoaderStrategy.h
 | 
						||
+++ b/Source/WebCore/loader/LoaderStrategy.h
 | 
						||
@@ -80,6 +80,7 @@ public:
 | 
						||
 
 | 
						||
     virtual bool isOnLine() const = 0;
 | 
						||
     virtual void addOnlineStateChangeListener(WTF::Function<void(bool)>&&) = 0;
 | 
						||
+    virtual void setEmulateOfflineState(bool) {};
 | 
						||
 
 | 
						||
     virtual bool shouldPerformSecurityChecks() const { return false; }
 | 
						||
     virtual bool havePerformedSecurityChecks(const ResourceResponse&) const { return false; }
 | 
						||
diff --git a/Source/WebCore/loader/ProgressTracker.cpp b/Source/WebCore/loader/ProgressTracker.cpp
 | 
						||
index e24fded2225f1c1918f454017566717e20484eab..30e4b7a986418c4b4f6c799b858b608206e22bb5 100644
 | 
						||
--- a/Source/WebCore/loader/ProgressTracker.cpp
 | 
						||
+++ b/Source/WebCore/loader/ProgressTracker.cpp
 | 
						||
@@ -154,6 +154,8 @@ void ProgressTracker::progressCompleted(Frame& frame)
 | 
						||
     if (!m_numProgressTrackedFrames || m_originatingProgressFrame == &frame)
 | 
						||
         finalProgressComplete();
 | 
						||
 
 | 
						||
+    InspectorInstrumentation::frameStoppedLoading(frame);
 | 
						||
+
 | 
						||
     m_client->didChangeEstimatedProgress();
 | 
						||
 }
 | 
						||
 
 | 
						||
@@ -179,8 +181,6 @@ void ProgressTracker::finalProgressComplete()
 | 
						||
     frame->loader().client().setMainFrameDocumentReady(true);
 | 
						||
     m_client->progressFinished(*frame);
 | 
						||
     frame->loader().loadProgressingStatusChanged();
 | 
						||
-
 | 
						||
-    InspectorInstrumentation::frameStoppedLoading(*frame);
 | 
						||
 }
 | 
						||
 
 | 
						||
 void ProgressTracker::incrementProgress(unsigned long identifier, const ResourceResponse& response)
 | 
						||
diff --git a/Source/WebCore/page/EventHandler.cpp b/Source/WebCore/page/EventHandler.cpp
 | 
						||
index fb61b6fd24b34a91e71b0064615b6a22675a5515..30d793a10b9689e55495db9e5e986735e2c025f8 100644
 | 
						||
--- a/Source/WebCore/page/EventHandler.cpp
 | 
						||
+++ b/Source/WebCore/page/EventHandler.cpp
 | 
						||
@@ -809,9 +809,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;
 | 
						||
@@ -850,8 +848,6 @@ VisiblePosition EventHandler::selectionExtentRespectingEditingBoundary(const Vis
 | 
						||
     return targetNode->renderer()->positionForPoint(LayoutPoint(selectionEndPoint), nullptr);
 | 
						||
 }
 | 
						||
 
 | 
						||
-#if ENABLE(DRAG_SUPPORT)
 | 
						||
-
 | 
						||
 #if !PLATFORM(IOS_FAMILY)
 | 
						||
 
 | 
						||
 bool EventHandler::supportsSelectionUpdatesOnMouseDrag() const
 | 
						||
@@ -873,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
 | 
						||
 
 | 
						||
     Node* targetNode = event.targetNode();
 | 
						||
     if (event.event().button() != LeftButton || !targetNode)
 | 
						||
@@ -895,7 +893,9 @@ bool EventHandler::handleMouseDraggedEvent(const MouseEventWithHitTestResults& e
 | 
						||
     ASSERT(m_mouseDownMayStartSelect || m_mouseDownMayStartAutoscroll);
 | 
						||
 #endif
 | 
						||
 
 | 
						||
+#if ENABLE(DRAG_SUPPORT)
 | 
						||
     m_mouseDownMayStartDrag = false;
 | 
						||
+#endif
 | 
						||
 
 | 
						||
     if (m_mouseDownMayStartAutoscroll && !panScrollInProgress()) {
 | 
						||
         m_autoscrollController->startAutoscrollForSelection(renderer);
 | 
						||
@@ -912,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
 | 
						||
@@ -943,6 +945,8 @@ bool EventHandler::eventMayStartDrag(const PlatformMouseEvent& event) const
 | 
						||
     return targetElement && page->dragController().draggableElement(&m_frame, targetElement, result.roundedPointInInnerNodeFrame(), state);
 | 
						||
 }
 | 
						||
 
 | 
						||
+#endif // ENABLE(DRAG_SUPPORT)
 | 
						||
+
 | 
						||
 void EventHandler::updateSelectionForMouseDrag()
 | 
						||
 {
 | 
						||
     if (!supportsSelectionUpdatesOnMouseDrag())
 | 
						||
@@ -1034,7 +1038,6 @@ void EventHandler::updateSelectionForMouseDrag(const HitTestResult& hitTestResul
 | 
						||
     m_frame.selection().setSelectionByMouseIfDifferent(newSelection, m_frame.selection().granularity(),
 | 
						||
         FrameSelection::AdjustEndpointsAtBidiBoundary);
 | 
						||
 }
 | 
						||
-#endif // ENABLE(DRAG_SUPPORT)
 | 
						||
 
 | 
						||
 void EventHandler::lostMouseCapture()
 | 
						||
 {
 | 
						||
@@ -1082,9 +1085,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;
 | 
						||
@@ -2039,10 +2040,8 @@ bool EventHandler::handleMouseMoveEvent(const PlatformMouseEvent& platformMouseE
 | 
						||
         return true;
 | 
						||
     
 | 
						||
     swallowEvent = !dispatchMouseEvent(eventNames().mousemoveEvent, mouseEvent.targetNode(), false, 0, platformMouseEvent, true);
 | 
						||
-#if ENABLE(DRAG_SUPPORT)
 | 
						||
     if (!swallowEvent)
 | 
						||
         swallowEvent = handleMouseDraggedEvent(mouseEvent);
 | 
						||
-#endif
 | 
						||
 
 | 
						||
     return swallowEvent;
 | 
						||
 }
 | 
						||
diff --git a/Source/WebCore/page/EventHandler.h b/Source/WebCore/page/EventHandler.h
 | 
						||
index b19f13f229355dc5957d32c2d0ebf9a3990759d7..786a37d815f0972649064a14f05f73ce113da877 100644
 | 
						||
--- a/Source/WebCore/page/EventHandler.h
 | 
						||
+++ b/Source/WebCore/page/EventHandler.h
 | 
						||
@@ -132,9 +132,7 @@ public:
 | 
						||
 
 | 
						||
     WEBCORE_EXPORT VisiblePosition selectionExtentRespectingEditingBoundary(const VisibleSelection&, const LayoutPoint&, Node*);
 | 
						||
 
 | 
						||
-#if ENABLE(DRAG_SUPPORT)
 | 
						||
     void updateSelectionForMouseDrag();
 | 
						||
-#endif
 | 
						||
 
 | 
						||
 #if ENABLE(PAN_SCROLLING)
 | 
						||
     void didPanScrollStart();
 | 
						||
@@ -364,10 +362,8 @@ private:
 | 
						||
     bool handleMousePressEventDoubleClick(const MouseEventWithHitTestResults&);
 | 
						||
     bool handleMousePressEventTripleClick(const MouseEventWithHitTestResults&);
 | 
						||
 
 | 
						||
-#if ENABLE(DRAG_SUPPORT)
 | 
						||
     bool handleMouseDraggedEvent(const MouseEventWithHitTestResults&, CheckDragHysteresis = ShouldCheckDragHysteresis);
 | 
						||
     bool shouldAllowMouseDownToStartDrag() const;
 | 
						||
-#endif
 | 
						||
 
 | 
						||
     WEBCORE_EXPORT bool handleMouseReleaseEvent(const MouseEventWithHitTestResults&);
 | 
						||
 
 | 
						||
@@ -454,10 +450,8 @@ private:
 | 
						||
     void defaultTabEventHandler(KeyboardEvent&);
 | 
						||
     void defaultArrowEventHandler(FocusDirection, KeyboardEvent&);
 | 
						||
 
 | 
						||
-#if ENABLE(DRAG_SUPPORT)
 | 
						||
     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.
 | 
						||
@@ -465,9 +459,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);
 | 
						||
     
 | 
						||
@@ -517,10 +512,7 @@ private:
 | 
						||
     enum SelectionInitiationState { HaveNotStartedSelection, PlacedCaret, ExtendedSelection };
 | 
						||
     SelectionInitiationState m_selectionInitiationState { HaveNotStartedSelection };
 | 
						||
 
 | 
						||
-#if ENABLE(DRAG_SUPPORT)
 | 
						||
     LayoutPoint m_dragStartPosition;
 | 
						||
-#endif
 | 
						||
-
 | 
						||
     Timer m_hoverTimer;
 | 
						||
     Timer m_cursorUpdateTimer;
 | 
						||
 
 | 
						||
diff --git a/Source/WebCore/page/Frame.cpp b/Source/WebCore/page/Frame.cpp
 | 
						||
index bc741bc1e585095b2e31636fe4a6502c1a2518e7..87608f42473dd009d691ad4eefa0960c7b24c11d 100644
 | 
						||
--- a/Source/WebCore/page/Frame.cpp
 | 
						||
+++ b/Source/WebCore/page/Frame.cpp
 | 
						||
@@ -180,6 +180,7 @@ Frame::Frame(Page& page, HTMLFrameOwnerElement* ownerElement, FrameLoaderClient&
 | 
						||
 void Frame::init()
 | 
						||
 {
 | 
						||
     m_loader->init();
 | 
						||
+    InspectorInstrumentation::frameAttached(this);
 | 
						||
 }
 | 
						||
 
 | 
						||
 Ref<Frame> Frame::create(Page* page, HTMLFrameOwnerElement* ownerElement, FrameLoaderClient* client)
 | 
						||
diff --git a/Source/WebCore/page/FrameSnapshotting.cpp b/Source/WebCore/page/FrameSnapshotting.cpp
 | 
						||
index 73587787f88a6ad4e4baffb0beb0b87e7782916f..7e7a984207d6005bdb116784f981b487c8c16846 100644
 | 
						||
--- a/Source/WebCore/page/FrameSnapshotting.cpp
 | 
						||
+++ b/Source/WebCore/page/FrameSnapshotting.cpp
 | 
						||
@@ -115,6 +115,8 @@ std::unique_ptr<ImageBuffer> snapshotFrameRectWithClip(Frame& frame, const IntRe
 | 
						||
     if (!buffer)
 | 
						||
         return nullptr;
 | 
						||
     buffer->context().translate(-imageRect.x(), -imageRect.y());
 | 
						||
+    if (coordinateSpace != FrameView::ViewCoordinates)
 | 
						||
+      buffer->context().scale(1 / frame.page()->pageScaleFactor());
 | 
						||
 
 | 
						||
     if (!clipRects.isEmpty()) {
 | 
						||
         Path clipPath;
 | 
						||
@@ -123,7 +125,10 @@ std::unique_ptr<ImageBuffer> snapshotFrameRectWithClip(Frame& frame, const IntRe
 | 
						||
         buffer->context().clipPath(clipPath);
 | 
						||
     }
 | 
						||
 
 | 
						||
-    frame.view()->paintContentsForSnapshot(buffer->context(), imageRect, shouldIncludeSelection, coordinateSpace);
 | 
						||
+    FloatRect fr = imageRect;
 | 
						||
+    if (coordinateSpace != FrameView::ViewCoordinates)
 | 
						||
+      fr.scale(frame.page()->pageScaleFactor());
 | 
						||
+    frame.view()->paintContentsForSnapshot(buffer->context(), enclosingIntRect(fr), shouldIncludeSelection, coordinateSpace);
 | 
						||
     return buffer;
 | 
						||
 }
 | 
						||
 
 | 
						||
diff --git a/Source/WebCore/page/FrameView.cpp b/Source/WebCore/page/FrameView.cpp
 | 
						||
index 5c0dab84e00b3786e05474c989c5839da15aa1eb..87378c01a02a6d6d02bfc71eb707490ebd68d3a4 100644
 | 
						||
--- a/Source/WebCore/page/FrameView.cpp
 | 
						||
+++ b/Source/WebCore/page/FrameView.cpp
 | 
						||
@@ -2991,7 +2991,7 @@ void FrameView::setBaseBackgroundColor(const Color& backgroundColor)
 | 
						||
 
 | 
						||
 void FrameView::updateBackgroundRecursively(const Optional<Color>& backgroundColor)
 | 
						||
 {
 | 
						||
-#if HAVE(OS_DARK_MODE_SUPPORT)
 | 
						||
+#if HAVE(OS_DARK_MODE_SUPPORT) && (defined(WTF_PLATFORM_MAC) && WTF_PLATFORM_MAC) || (defined(WTF_PLATFORM_IOS_FAMILY) && WTF_PLATFORM_IOS_FAMILY)
 | 
						||
     Color baseBackgroundColor = backgroundColor.valueOr(RenderTheme::singleton().systemColor(CSSValueAppleSystemControlBackground, styleColorOptions()));
 | 
						||
 #else
 | 
						||
     Color baseBackgroundColor = backgroundColor.valueOr(Color::white);
 | 
						||
diff --git a/Source/WebCore/page/History.cpp b/Source/WebCore/page/History.cpp
 | 
						||
index 9c58b06f4c471130ce4815f11d14cb78f81b49a0..3d624733c36f09518b12095d91e67a2ae67879e2 100644
 | 
						||
--- a/Source/WebCore/page/History.cpp
 | 
						||
+++ b/Source/WebCore/page/History.cpp
 | 
						||
@@ -259,6 +259,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 a383a1cb022e80bf69fce5446c5a934b2c3c649d..316b895e8690d3286a4416f3d9d5a7a318ff5921 100644
 | 
						||
--- a/Source/WebCore/page/Page.cpp
 | 
						||
+++ b/Source/WebCore/page/Page.cpp
 | 
						||
@@ -86,6 +86,7 @@
 | 
						||
 #include "PerformanceLoggingClient.h"
 | 
						||
 #include "PerformanceMonitor.h"
 | 
						||
 #include "PlatformMediaSessionManager.h"
 | 
						||
+#include "PlatformScreen.h"
 | 
						||
 #include "PlatformStrategies.h"
 | 
						||
 #include "PlugInClient.h"
 | 
						||
 #include "PluginData.h"
 | 
						||
@@ -419,6 +420,21 @@ void Page::setOverrideViewportArguments(const Optional<ViewportArguments>& viewp
 | 
						||
         document->updateViewportArguments();
 | 
						||
 }
 | 
						||
 
 | 
						||
+FloatSize Page::screenSize()
 | 
						||
+{
 | 
						||
+    return m_overrideScreenSize.valueOr(screenRect(mainFrame().view()).size());
 | 
						||
+}
 | 
						||
+
 | 
						||
+void Page::setOverrideScreenSize(Optional<FloatSize> size)
 | 
						||
+{
 | 
						||
+    if (size == m_overrideScreenSize)
 | 
						||
+        return;
 | 
						||
+
 | 
						||
+    m_overrideScreenSize = size;
 | 
						||
+    if (auto* document = mainFrame().document())
 | 
						||
+        document->updateViewportArguments();
 | 
						||
+}
 | 
						||
+
 | 
						||
 ScrollingCoordinator* Page::scrollingCoordinator()
 | 
						||
 {
 | 
						||
     if (!m_scrollingCoordinator && m_settings->scrollingCoordinatorEnabled()) {
 | 
						||
diff --git a/Source/WebCore/page/Page.h b/Source/WebCore/page/Page.h
 | 
						||
index 81ee655c282bd96656e15eb1f390382a8a368f15..79763e7895c4fa774f8498a599a2ef876ccbe228 100644
 | 
						||
--- a/Source/WebCore/page/Page.h
 | 
						||
+++ b/Source/WebCore/page/Page.h
 | 
						||
@@ -186,6 +186,9 @@ public:
 | 
						||
     const Optional<ViewportArguments>& overrideViewportArguments() const { return m_overrideViewportArguments; }
 | 
						||
     WEBCORE_EXPORT void setOverrideViewportArguments(const Optional<ViewportArguments>&);
 | 
						||
 
 | 
						||
+    WEBCORE_EXPORT FloatSize screenSize();
 | 
						||
+    WEBCORE_EXPORT void setOverrideScreenSize(Optional<FloatSize> size);
 | 
						||
+
 | 
						||
     static void refreshPlugins(bool reload);
 | 
						||
     WEBCORE_EXPORT PluginData& pluginData();
 | 
						||
     void clearPluginData();
 | 
						||
@@ -994,6 +997,7 @@ private:
 | 
						||
 #endif
 | 
						||
 
 | 
						||
     Optional<ViewportArguments> m_overrideViewportArguments;
 | 
						||
+    Optional<FloatSize> m_overrideScreenSize;
 | 
						||
 
 | 
						||
 #if ENABLE(DEVICE_ORIENTATION) && PLATFORM(IOS_FAMILY)
 | 
						||
     RefPtr<DeviceOrientationUpdateProvider> m_deviceOrientationUpdateProvider;
 | 
						||
diff --git a/Source/WebCore/page/Screen.cpp b/Source/WebCore/page/Screen.cpp
 | 
						||
index a9d228ca404918860c40651994db78a1e76db5ca..1fc3c345308dfed8384d1c02334f2030e879383d 100644
 | 
						||
--- a/Source/WebCore/page/Screen.cpp
 | 
						||
+++ b/Source/WebCore/page/Screen.cpp
 | 
						||
@@ -32,6 +32,7 @@
 | 
						||
 #include "FloatRect.h"
 | 
						||
 #include "Frame.h"
 | 
						||
 #include "FrameView.h"
 | 
						||
+#include "Page.h"
 | 
						||
 #include "PlatformScreen.h"
 | 
						||
 #include "ResourceLoadObserver.h"
 | 
						||
 #include "RuntimeEnabledFeatures.h"
 | 
						||
@@ -53,7 +54,7 @@ unsigned Screen::height() const
 | 
						||
         return 0;
 | 
						||
     if (RuntimeEnabledFeatures::sharedFeatures().webAPIStatisticsEnabled())
 | 
						||
         ResourceLoadObserver::shared().logScreenAPIAccessed(*frame->document(), ResourceLoadStatistics::ScreenAPI::Height);
 | 
						||
-    long height = static_cast<long>(screenRect(frame->view()).height());
 | 
						||
+    long height = static_cast<long>(frame->page()->screenSize().height());
 | 
						||
     return static_cast<unsigned>(height);
 | 
						||
 }
 | 
						||
 
 | 
						||
@@ -64,7 +65,7 @@ unsigned Screen::width() const
 | 
						||
         return 0;
 | 
						||
     if (RuntimeEnabledFeatures::sharedFeatures().webAPIStatisticsEnabled())
 | 
						||
         ResourceLoadObserver::shared().logScreenAPIAccessed(*frame->document(), ResourceLoadStatistics::ScreenAPI::Width);
 | 
						||
-    long width = static_cast<long>(screenRect(frame->view()).width());
 | 
						||
+    long width = static_cast<long>(frame->page()->screenSize().width());
 | 
						||
     return static_cast<unsigned>(width);
 | 
						||
 }
 | 
						||
 
 | 
						||
diff --git a/Source/WebCore/page/csp/ContentSecurityPolicy.cpp b/Source/WebCore/page/csp/ContentSecurityPolicy.cpp
 | 
						||
index ad6f5209c52e0842d93be267f8f5e99551dfe07c..0fcf4fe9877ba8a89a8dfb321e120f7954c6f69b 100644
 | 
						||
--- a/Source/WebCore/page/csp/ContentSecurityPolicy.cpp
 | 
						||
+++ b/Source/WebCore/page/csp/ContentSecurityPolicy.cpp
 | 
						||
@@ -298,6 +298,8 @@ bool ContentSecurityPolicy::protocolMatchesSelf(const URL& url) const
 | 
						||
 template<typename Predicate, typename... Args>
 | 
						||
 typename std::enable_if<!std::is_convertible<Predicate, ContentSecurityPolicy::ViolatedDirectiveCallback>::value, bool>::type ContentSecurityPolicy::allPoliciesWithDispositionAllow(Disposition disposition, Predicate&& predicate, Args&&... args) const
 | 
						||
 {
 | 
						||
+    if (InspectorInstrumentation::shouldBypassCSP(m_scriptExecutionContext))
 | 
						||
+        return true;
 | 
						||
     bool isReportOnly = disposition == ContentSecurityPolicy::Disposition::ReportOnly;
 | 
						||
     for (auto& policy : m_policies) {
 | 
						||
         if (policy->isReportOnly() != isReportOnly)
 | 
						||
@@ -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/platform/PlatformKeyboardEvent.h b/Source/WebCore/platform/PlatformKeyboardEvent.h
 | 
						||
index f423a4a1d5399326fc48fe4d4a8a8fb9d4df861e..b4b60162d8b0d34113df052b04a1695d481d266e 100644
 | 
						||
--- a/Source/WebCore/platform/PlatformKeyboardEvent.h
 | 
						||
+++ b/Source/WebCore/platform/PlatformKeyboardEvent.h
 | 
						||
@@ -138,6 +138,7 @@ namespace WebCore {
 | 
						||
         static String keyCodeForHardwareKeyCode(unsigned);
 | 
						||
         static String keyIdentifierForGdkKeyCode(unsigned);
 | 
						||
         static int windowsKeyCodeForGdkKeyCode(unsigned);
 | 
						||
+        static unsigned gdkKeyCodeForWindowsKeyCode(int);
 | 
						||
         static String singleCharacterString(unsigned);
 | 
						||
         static bool modifiersContainCapsLock(unsigned);
 | 
						||
 #endif
 | 
						||
@@ -147,6 +148,7 @@ namespace WebCore {
 | 
						||
         static String keyCodeForHardwareKeyCode(unsigned);
 | 
						||
         static String keyIdentifierForWPEKeyCode(unsigned);
 | 
						||
         static int windowsKeyCodeForWPEKeyCode(unsigned);
 | 
						||
+        static unsigned WPEKeyCodeForWindowsKeyCode(int);
 | 
						||
         static String singleCharacterString(unsigned);
 | 
						||
 #endif
 | 
						||
 
 | 
						||
diff --git a/Source/WebCore/platform/ScrollableArea.h b/Source/WebCore/platform/ScrollableArea.h
 | 
						||
index fdddf2f9beb7e0b28f072cb121d1ee117bf00969..6c6acba2e5795319b60bd3031f37d8872d5a2011 100644
 | 
						||
--- a/Source/WebCore/platform/ScrollableArea.h
 | 
						||
+++ b/Source/WebCore/platform/ScrollableArea.h
 | 
						||
@@ -103,7 +103,7 @@ public:
 | 
						||
     void updateScrollSnapState();
 | 
						||
 
 | 
						||
 #if ENABLE(TOUCH_EVENTS)
 | 
						||
-    virtual bool handleTouchEvent(const PlatformTouchEvent&);
 | 
						||
+    WEBCORE_EXPORT virtual bool handleTouchEvent(const PlatformTouchEvent&);
 | 
						||
 #endif
 | 
						||
 
 | 
						||
 #if PLATFORM(IOS_FAMILY)
 | 
						||
diff --git a/Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGLBase.cpp b/Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGLBase.cpp
 | 
						||
index 3cc3dc9012e8ff409141dd43808b71264c8cd337..e44eca80b5a7f0ac8360d39d78ec7097d5296dc3 100644
 | 
						||
--- a/Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGLBase.cpp
 | 
						||
+++ b/Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGLBase.cpp
 | 
						||
@@ -27,7 +27,7 @@
 | 
						||
 #include "config.h"
 | 
						||
 #include "GraphicsContextGLOpenGL.h"
 | 
						||
 
 | 
						||
-#if ENABLE(GRAPHICS_CONTEXT_GL) && (USE(OPENGL) || (PLATFORM(COCOA) && USE(OPENGL_ES)))
 | 
						||
+#if !PLATFORM(WIN) && ENABLE(GRAPHICS_CONTEXT_GL) && (USE(OPENGL) || (PLATFORM(COCOA) && USE(OPENGL_ES)))
 | 
						||
 
 | 
						||
 #if PLATFORM(IOS_FAMILY)
 | 
						||
 #include "GraphicsContextGLOpenGLESIOS.h"
 | 
						||
diff --git a/Source/WebCore/platform/gtk/PlatformKeyboardEventGtk.cpp b/Source/WebCore/platform/gtk/PlatformKeyboardEventGtk.cpp
 | 
						||
index 269008b9053c8d8b6787cf22f13b44b46dace333..d3ba16947bc8964a7cfe746cabbf99d32a673cef 100644
 | 
						||
--- a/Source/WebCore/platform/gtk/PlatformKeyboardEventGtk.cpp
 | 
						||
+++ b/Source/WebCore/platform/gtk/PlatformKeyboardEventGtk.cpp
 | 
						||
@@ -36,8 +36,10 @@
 | 
						||
 #include "WindowsKeyboardCodes.h"
 | 
						||
 #include <gdk/gdk.h>
 | 
						||
 #include <gdk/gdkkeysyms.h>
 | 
						||
+#include <wtf/HashMap.h>
 | 
						||
 #include <wtf/HexNumber.h>
 | 
						||
 #include <wtf/glib/GUniquePtr.h>
 | 
						||
+#include <mutex>
 | 
						||
 
 | 
						||
 namespace WebCore {
 | 
						||
 
 | 
						||
@@ -1293,6 +1295,246 @@ int PlatformKeyboardEvent::windowsKeyCodeForGdkKeyCode(unsigned keycode)
 | 
						||
 
 | 
						||
 }
 | 
						||
 
 | 
						||
+static const HashMap<int, unsigned>& gdkToWindowsKeyCodeMap()
 | 
						||
+{
 | 
						||
+    static HashMap<int, unsigned>* result;
 | 
						||
+    static std::once_flag once;
 | 
						||
+    std::call_once(
 | 
						||
+        once,
 | 
						||
+        [] {
 | 
						||
+            const unsigned gdkKeyCodes[] = {
 | 
						||
+                GDK_KEY_Cancel,
 | 
						||
+                // FIXME: non-keypad keys should take precedence, so we skip GDK_KEY_KP_*
 | 
						||
+                // GDK_KEY_KP_0,
 | 
						||
+                // GDK_KEY_KP_1,
 | 
						||
+                // GDK_KEY_KP_2,
 | 
						||
+                // GDK_KEY_KP_3,
 | 
						||
+                // GDK_KEY_KP_4,
 | 
						||
+                // GDK_KEY_KP_5,
 | 
						||
+                // GDK_KEY_KP_6,
 | 
						||
+                // GDK_KEY_KP_7,
 | 
						||
+                // GDK_KEY_KP_8,
 | 
						||
+                // GDK_KEY_KP_9,
 | 
						||
+                // GDK_KEY_KP_Multiply,
 | 
						||
+                // GDK_KEY_KP_Add,
 | 
						||
+                // GDK_KEY_KP_Subtract,
 | 
						||
+                // GDK_KEY_KP_Decimal,
 | 
						||
+                // GDK_KEY_KP_Divide,
 | 
						||
+                // GDK_KEY_KP_Page_Up,
 | 
						||
+                // GDK_KEY_KP_Page_Down,
 | 
						||
+                // GDK_KEY_KP_End,
 | 
						||
+                // GDK_KEY_KP_Home,
 | 
						||
+                // GDK_KEY_KP_Left,
 | 
						||
+                // GDK_KEY_KP_Up,
 | 
						||
+                // GDK_KEY_KP_Right,
 | 
						||
+                // GDK_KEY_KP_Down,
 | 
						||
+                GDK_KEY_BackSpace,
 | 
						||
+                // GDK_KEY_ISO_Left_Tab,
 | 
						||
+                // GDK_KEY_3270_BackTab,
 | 
						||
+                GDK_KEY_Tab,
 | 
						||
+                GDK_KEY_Clear,
 | 
						||
+                // GDK_KEY_ISO_Enter,
 | 
						||
+                // GDK_KEY_KP_Enter,
 | 
						||
+                GDK_KEY_Return,
 | 
						||
+                GDK_KEY_Menu,
 | 
						||
+                GDK_KEY_Pause,
 | 
						||
+                GDK_KEY_AudioPause,
 | 
						||
+                GDK_KEY_Caps_Lock,
 | 
						||
+                GDK_KEY_Kana_Lock,
 | 
						||
+                GDK_KEY_Kana_Shift,
 | 
						||
+                GDK_KEY_Hangul,
 | 
						||
+                GDK_KEY_Hangul_Hanja,
 | 
						||
+                GDK_KEY_Kanji,
 | 
						||
+                GDK_KEY_Escape,
 | 
						||
+                GDK_KEY_space,
 | 
						||
+                GDK_KEY_Page_Up,
 | 
						||
+                GDK_KEY_Page_Down,
 | 
						||
+                GDK_KEY_End,
 | 
						||
+                GDK_KEY_Home,
 | 
						||
+                GDK_KEY_Left,
 | 
						||
+                GDK_KEY_Up,
 | 
						||
+                GDK_KEY_Right,
 | 
						||
+                GDK_KEY_Down,
 | 
						||
+                GDK_KEY_Select,
 | 
						||
+                GDK_KEY_Print,
 | 
						||
+                GDK_KEY_Execute,
 | 
						||
+                GDK_KEY_Insert,
 | 
						||
+                GDK_KEY_KP_Insert,
 | 
						||
+                GDK_KEY_Delete,
 | 
						||
+                GDK_KEY_KP_Delete,
 | 
						||
+                GDK_KEY_Help,
 | 
						||
+                GDK_KEY_0,
 | 
						||
+                GDK_KEY_parenright,
 | 
						||
+                GDK_KEY_1,
 | 
						||
+                GDK_KEY_exclam,
 | 
						||
+                GDK_KEY_2,
 | 
						||
+                GDK_KEY_at,
 | 
						||
+                GDK_KEY_3,
 | 
						||
+                GDK_KEY_numbersign,
 | 
						||
+                GDK_KEY_4,
 | 
						||
+                GDK_KEY_dollar,
 | 
						||
+                GDK_KEY_5,
 | 
						||
+                GDK_KEY_percent,
 | 
						||
+                GDK_KEY_6,
 | 
						||
+                GDK_KEY_asciicircum,
 | 
						||
+                GDK_KEY_7,
 | 
						||
+                GDK_KEY_ampersand,
 | 
						||
+                GDK_KEY_8,
 | 
						||
+                GDK_KEY_asterisk,
 | 
						||
+                GDK_KEY_9,
 | 
						||
+                GDK_KEY_parenleft,
 | 
						||
+                GDK_KEY_a,
 | 
						||
+                GDK_KEY_A,
 | 
						||
+                GDK_KEY_b,
 | 
						||
+                GDK_KEY_B,
 | 
						||
+                GDK_KEY_c,
 | 
						||
+                GDK_KEY_C,
 | 
						||
+                GDK_KEY_d,
 | 
						||
+                GDK_KEY_D,
 | 
						||
+                GDK_KEY_e,
 | 
						||
+                GDK_KEY_E,
 | 
						||
+                GDK_KEY_f,
 | 
						||
+                GDK_KEY_F,
 | 
						||
+                GDK_KEY_g,
 | 
						||
+                GDK_KEY_G,
 | 
						||
+                GDK_KEY_h,
 | 
						||
+                GDK_KEY_H,
 | 
						||
+                GDK_KEY_i,
 | 
						||
+                GDK_KEY_I,
 | 
						||
+                GDK_KEY_j,
 | 
						||
+                GDK_KEY_J,
 | 
						||
+                GDK_KEY_k,
 | 
						||
+                GDK_KEY_K,
 | 
						||
+                GDK_KEY_l,
 | 
						||
+                GDK_KEY_L,
 | 
						||
+                GDK_KEY_m,
 | 
						||
+                GDK_KEY_M,
 | 
						||
+                GDK_KEY_n,
 | 
						||
+                GDK_KEY_N,
 | 
						||
+                GDK_KEY_o,
 | 
						||
+                GDK_KEY_O,
 | 
						||
+                GDK_KEY_p,
 | 
						||
+                GDK_KEY_P,
 | 
						||
+                GDK_KEY_q,
 | 
						||
+                GDK_KEY_Q,
 | 
						||
+                GDK_KEY_r,
 | 
						||
+                GDK_KEY_R,
 | 
						||
+                GDK_KEY_s,
 | 
						||
+                GDK_KEY_S,
 | 
						||
+                GDK_KEY_t,
 | 
						||
+                GDK_KEY_T,
 | 
						||
+                GDK_KEY_u,
 | 
						||
+                GDK_KEY_U,
 | 
						||
+                GDK_KEY_v,
 | 
						||
+                GDK_KEY_V,
 | 
						||
+                GDK_KEY_w,
 | 
						||
+                GDK_KEY_W,
 | 
						||
+                GDK_KEY_x,
 | 
						||
+                GDK_KEY_X,
 | 
						||
+                GDK_KEY_y,
 | 
						||
+                GDK_KEY_Y,
 | 
						||
+                GDK_KEY_z,
 | 
						||
+                GDK_KEY_Z,
 | 
						||
+                GDK_KEY_Meta_L,
 | 
						||
+                GDK_KEY_Meta_R,
 | 
						||
+                GDK_KEY_Sleep,
 | 
						||
+                GDK_KEY_Num_Lock,
 | 
						||
+                GDK_KEY_Scroll_Lock,
 | 
						||
+                GDK_KEY_Shift_L,
 | 
						||
+                GDK_KEY_Shift_R,
 | 
						||
+                GDK_KEY_Control_L,
 | 
						||
+                GDK_KEY_Control_R,
 | 
						||
+                GDK_KEY_Alt_L,
 | 
						||
+                GDK_KEY_Alt_R,
 | 
						||
+                GDK_KEY_Back,
 | 
						||
+                GDK_KEY_Forward,
 | 
						||
+                GDK_KEY_Refresh,
 | 
						||
+                GDK_KEY_Stop,
 | 
						||
+                GDK_KEY_Search,
 | 
						||
+                GDK_KEY_Favorites,
 | 
						||
+                GDK_KEY_HomePage,
 | 
						||
+                GDK_KEY_AudioMute,
 | 
						||
+                GDK_KEY_AudioLowerVolume,
 | 
						||
+                GDK_KEY_AudioRaiseVolume,
 | 
						||
+                GDK_KEY_AudioNext,
 | 
						||
+                GDK_KEY_AudioPrev,
 | 
						||
+                GDK_KEY_AudioStop,
 | 
						||
+                GDK_KEY_AudioMedia,
 | 
						||
+                GDK_KEY_semicolon,
 | 
						||
+                GDK_KEY_colon,
 | 
						||
+                GDK_KEY_plus,
 | 
						||
+                GDK_KEY_equal,
 | 
						||
+                GDK_KEY_comma,
 | 
						||
+                GDK_KEY_less,
 | 
						||
+                GDK_KEY_minus,
 | 
						||
+                GDK_KEY_underscore,
 | 
						||
+                GDK_KEY_period,
 | 
						||
+                GDK_KEY_greater,
 | 
						||
+                GDK_KEY_slash,
 | 
						||
+                GDK_KEY_question,
 | 
						||
+                GDK_KEY_asciitilde,
 | 
						||
+                GDK_KEY_quoteleft,
 | 
						||
+                GDK_KEY_bracketleft,
 | 
						||
+                GDK_KEY_braceleft,
 | 
						||
+                GDK_KEY_backslash,
 | 
						||
+                GDK_KEY_bar,
 | 
						||
+                GDK_KEY_bracketright,
 | 
						||
+                GDK_KEY_braceright,
 | 
						||
+                GDK_KEY_quoteright,
 | 
						||
+                GDK_KEY_quotedbl,
 | 
						||
+                GDK_KEY_AudioRewind,
 | 
						||
+                GDK_KEY_AudioForward,
 | 
						||
+                GDK_KEY_AudioPlay,
 | 
						||
+                GDK_KEY_F1,
 | 
						||
+                GDK_KEY_F2,
 | 
						||
+                GDK_KEY_F3,
 | 
						||
+                GDK_KEY_F4,
 | 
						||
+                GDK_KEY_F5,
 | 
						||
+                GDK_KEY_F6,
 | 
						||
+                GDK_KEY_F7,
 | 
						||
+                GDK_KEY_F8,
 | 
						||
+                GDK_KEY_F9,
 | 
						||
+                GDK_KEY_F10,
 | 
						||
+                GDK_KEY_F11,
 | 
						||
+                GDK_KEY_F12,
 | 
						||
+                GDK_KEY_F13,
 | 
						||
+                GDK_KEY_F14,
 | 
						||
+                GDK_KEY_F15,
 | 
						||
+                GDK_KEY_F16,
 | 
						||
+                GDK_KEY_F17,
 | 
						||
+                GDK_KEY_F18,
 | 
						||
+                GDK_KEY_F19,
 | 
						||
+                GDK_KEY_F20,
 | 
						||
+                GDK_KEY_F21,
 | 
						||
+                GDK_KEY_F22,
 | 
						||
+                GDK_KEY_F23,
 | 
						||
+                GDK_KEY_F24,
 | 
						||
+                GDK_KEY_VoidSymbol,
 | 
						||
+                GDK_KEY_Red,
 | 
						||
+                GDK_KEY_Green,
 | 
						||
+                GDK_KEY_Yellow,
 | 
						||
+                GDK_KEY_Blue,
 | 
						||
+                GDK_KEY_PowerOff,
 | 
						||
+                GDK_KEY_AudioRecord,
 | 
						||
+                GDK_KEY_Display,
 | 
						||
+                GDK_KEY_Subtitle,
 | 
						||
+                GDK_KEY_Video
 | 
						||
+            };
 | 
						||
+            result = new HashMap<int, unsigned>();
 | 
						||
+            for (unsigned gdkKeyCode : gdkKeyCodes) {
 | 
						||
+                int winKeyCode = PlatformKeyboardEvent::windowsKeyCodeForGdkKeyCode(gdkKeyCode);
 | 
						||
+                // If several gdk key codes map to the same win key code first one is used.
 | 
						||
+                result->add(winKeyCode, gdkKeyCode);
 | 
						||
+            }
 | 
						||
+        });
 | 
						||
+    return *result;
 | 
						||
+}
 | 
						||
+
 | 
						||
+unsigned PlatformKeyboardEvent::gdkKeyCodeForWindowsKeyCode(int keycode)
 | 
						||
+{
 | 
						||
+    return gdkToWindowsKeyCodeMap().get(keycode);
 | 
						||
+}
 | 
						||
+
 | 
						||
 String PlatformKeyboardEvent::singleCharacterString(unsigned val)
 | 
						||
 {
 | 
						||
     switch (val) {
 | 
						||
diff --git a/Source/WebCore/platform/libwpe/PlatformKeyboardEventLibWPE.cpp b/Source/WebCore/platform/libwpe/PlatformKeyboardEventLibWPE.cpp
 | 
						||
index a34dc220bbb9a92b40dfb463e8724e81ac745b2c..8ecedd5dae88469366a619b96960598c1232a32d 100644
 | 
						||
--- a/Source/WebCore/platform/libwpe/PlatformKeyboardEventLibWPE.cpp
 | 
						||
+++ b/Source/WebCore/platform/libwpe/PlatformKeyboardEventLibWPE.cpp
 | 
						||
@@ -30,8 +30,10 @@
 | 
						||
 
 | 
						||
 #include "WindowsKeyboardCodes.h"
 | 
						||
 #include <wpe/wpe.h>
 | 
						||
+#include <wtf/HashMap.h>
 | 
						||
 #include <wtf/HexNumber.h>
 | 
						||
 #include <wtf/text/StringBuilder.h>
 | 
						||
+#include <mutex>
 | 
						||
 
 | 
						||
 namespace WebCore {
 | 
						||
 
 | 
						||
@@ -1291,6 +1293,246 @@ int PlatformKeyboardEvent::windowsKeyCodeForWPEKeyCode(unsigned keycode)
 | 
						||
     return 0;
 | 
						||
 }
 | 
						||
 
 | 
						||
+static const HashMap<int, unsigned>& WPEToWindowsKeyCodeMap()
 | 
						||
+{
 | 
						||
+    static HashMap<int, unsigned>* result;
 | 
						||
+    static std::once_flag once;
 | 
						||
+    std::call_once(
 | 
						||
+        once,
 | 
						||
+        [] {
 | 
						||
+            const unsigned WPEKeyCodes[] = {
 | 
						||
+                WPE_KEY_Cancel,
 | 
						||
+                // FIXME: non-keypad keys should take precedence, so we skip WPE_KEY_KP_*
 | 
						||
+                // WPE_KEY_KP_0,
 | 
						||
+                // WPE_KEY_KP_1,
 | 
						||
+                // WPE_KEY_KP_2,
 | 
						||
+                // WPE_KEY_KP_3,
 | 
						||
+                // WPE_KEY_KP_4,
 | 
						||
+                // WPE_KEY_KP_5,
 | 
						||
+                // WPE_KEY_KP_6,
 | 
						||
+                // WPE_KEY_KP_7,
 | 
						||
+                // WPE_KEY_KP_8,
 | 
						||
+                // WPE_KEY_KP_9,
 | 
						||
+                // WPE_KEY_KP_Multiply,
 | 
						||
+                // WPE_KEY_KP_Add,
 | 
						||
+                // WPE_KEY_KP_Subtract,
 | 
						||
+                // WPE_KEY_KP_Decimal,
 | 
						||
+                // WPE_KEY_KP_Divide,
 | 
						||
+                // WPE_KEY_KP_Page_Up,
 | 
						||
+                // WPE_KEY_KP_Page_Down,
 | 
						||
+                // WPE_KEY_KP_End,
 | 
						||
+                // WPE_KEY_KP_Home,
 | 
						||
+                // WPE_KEY_KP_Left,
 | 
						||
+                // WPE_KEY_KP_Up,
 | 
						||
+                // WPE_KEY_KP_Right,
 | 
						||
+                // WPE_KEY_KP_Down,
 | 
						||
+                WPE_KEY_BackSpace,
 | 
						||
+                // WPE_KEY_ISO_Left_Tab,
 | 
						||
+                // WPE_KEY_3270_BackTab,
 | 
						||
+                WPE_KEY_Tab,
 | 
						||
+                WPE_KEY_Clear,
 | 
						||
+                // WPE_KEY_ISO_Enter,
 | 
						||
+                // WPE_KEY_KP_Enter,
 | 
						||
+                WPE_KEY_Return,
 | 
						||
+                WPE_KEY_Menu,
 | 
						||
+                WPE_KEY_Pause,
 | 
						||
+                WPE_KEY_AudioPause,
 | 
						||
+                WPE_KEY_Caps_Lock,
 | 
						||
+                WPE_KEY_Kana_Lock,
 | 
						||
+                WPE_KEY_Kana_Shift,
 | 
						||
+                WPE_KEY_Hangul,
 | 
						||
+                WPE_KEY_Hangul_Hanja,
 | 
						||
+                WPE_KEY_Kanji,
 | 
						||
+                WPE_KEY_Escape,
 | 
						||
+                WPE_KEY_space,
 | 
						||
+                WPE_KEY_Page_Up,
 | 
						||
+                WPE_KEY_Page_Down,
 | 
						||
+                WPE_KEY_End,
 | 
						||
+                WPE_KEY_Home,
 | 
						||
+                WPE_KEY_Left,
 | 
						||
+                WPE_KEY_Up,
 | 
						||
+                WPE_KEY_Right,
 | 
						||
+                WPE_KEY_Down,
 | 
						||
+                WPE_KEY_Select,
 | 
						||
+                WPE_KEY_Print,
 | 
						||
+                WPE_KEY_Execute,
 | 
						||
+                WPE_KEY_Insert,
 | 
						||
+                WPE_KEY_KP_Insert,
 | 
						||
+                WPE_KEY_Delete,
 | 
						||
+                WPE_KEY_KP_Delete,
 | 
						||
+                WPE_KEY_Help,
 | 
						||
+                WPE_KEY_0,
 | 
						||
+                WPE_KEY_parenright,
 | 
						||
+                WPE_KEY_1,
 | 
						||
+                WPE_KEY_exclam,
 | 
						||
+                WPE_KEY_2,
 | 
						||
+                WPE_KEY_at,
 | 
						||
+                WPE_KEY_3,
 | 
						||
+                WPE_KEY_numbersign,
 | 
						||
+                WPE_KEY_4,
 | 
						||
+                WPE_KEY_dollar,
 | 
						||
+                WPE_KEY_5,
 | 
						||
+                WPE_KEY_percent,
 | 
						||
+                WPE_KEY_6,
 | 
						||
+                WPE_KEY_asciicircum,
 | 
						||
+                WPE_KEY_7,
 | 
						||
+                WPE_KEY_ampersand,
 | 
						||
+                WPE_KEY_8,
 | 
						||
+                WPE_KEY_asterisk,
 | 
						||
+                WPE_KEY_9,
 | 
						||
+                WPE_KEY_parenleft,
 | 
						||
+                WPE_KEY_a,
 | 
						||
+                WPE_KEY_A,
 | 
						||
+                WPE_KEY_b,
 | 
						||
+                WPE_KEY_B,
 | 
						||
+                WPE_KEY_c,
 | 
						||
+                WPE_KEY_C,
 | 
						||
+                WPE_KEY_d,
 | 
						||
+                WPE_KEY_D,
 | 
						||
+                WPE_KEY_e,
 | 
						||
+                WPE_KEY_E,
 | 
						||
+                WPE_KEY_f,
 | 
						||
+                WPE_KEY_F,
 | 
						||
+                WPE_KEY_g,
 | 
						||
+                WPE_KEY_G,
 | 
						||
+                WPE_KEY_h,
 | 
						||
+                WPE_KEY_H,
 | 
						||
+                WPE_KEY_i,
 | 
						||
+                WPE_KEY_I,
 | 
						||
+                WPE_KEY_j,
 | 
						||
+                WPE_KEY_J,
 | 
						||
+                WPE_KEY_k,
 | 
						||
+                WPE_KEY_K,
 | 
						||
+                WPE_KEY_l,
 | 
						||
+                WPE_KEY_L,
 | 
						||
+                WPE_KEY_m,
 | 
						||
+                WPE_KEY_M,
 | 
						||
+                WPE_KEY_n,
 | 
						||
+                WPE_KEY_N,
 | 
						||
+                WPE_KEY_o,
 | 
						||
+                WPE_KEY_O,
 | 
						||
+                WPE_KEY_p,
 | 
						||
+                WPE_KEY_P,
 | 
						||
+                WPE_KEY_q,
 | 
						||
+                WPE_KEY_Q,
 | 
						||
+                WPE_KEY_r,
 | 
						||
+                WPE_KEY_R,
 | 
						||
+                WPE_KEY_s,
 | 
						||
+                WPE_KEY_S,
 | 
						||
+                WPE_KEY_t,
 | 
						||
+                WPE_KEY_T,
 | 
						||
+                WPE_KEY_u,
 | 
						||
+                WPE_KEY_U,
 | 
						||
+                WPE_KEY_v,
 | 
						||
+                WPE_KEY_V,
 | 
						||
+                WPE_KEY_w,
 | 
						||
+                WPE_KEY_W,
 | 
						||
+                WPE_KEY_x,
 | 
						||
+                WPE_KEY_X,
 | 
						||
+                WPE_KEY_y,
 | 
						||
+                WPE_KEY_Y,
 | 
						||
+                WPE_KEY_z,
 | 
						||
+                WPE_KEY_Z,
 | 
						||
+                WPE_KEY_Meta_L,
 | 
						||
+                WPE_KEY_Meta_R,
 | 
						||
+                WPE_KEY_Sleep,
 | 
						||
+                WPE_KEY_Num_Lock,
 | 
						||
+                WPE_KEY_Scroll_Lock,
 | 
						||
+                WPE_KEY_Shift_L,
 | 
						||
+                WPE_KEY_Shift_R,
 | 
						||
+                WPE_KEY_Control_L,
 | 
						||
+                WPE_KEY_Control_R,
 | 
						||
+                WPE_KEY_Alt_L,
 | 
						||
+                WPE_KEY_Alt_R,
 | 
						||
+                WPE_KEY_Back,
 | 
						||
+                WPE_KEY_Forward,
 | 
						||
+                WPE_KEY_Refresh,
 | 
						||
+                WPE_KEY_Stop,
 | 
						||
+                WPE_KEY_Search,
 | 
						||
+                WPE_KEY_Favorites,
 | 
						||
+                WPE_KEY_HomePage,
 | 
						||
+                WPE_KEY_AudioMute,
 | 
						||
+                WPE_KEY_AudioLowerVolume,
 | 
						||
+                WPE_KEY_AudioRaiseVolume,
 | 
						||
+                WPE_KEY_AudioNext,
 | 
						||
+                WPE_KEY_AudioPrev,
 | 
						||
+                WPE_KEY_AudioStop,
 | 
						||
+                WPE_KEY_AudioMedia,
 | 
						||
+                WPE_KEY_semicolon,
 | 
						||
+                WPE_KEY_colon,
 | 
						||
+                WPE_KEY_plus,
 | 
						||
+                WPE_KEY_equal,
 | 
						||
+                WPE_KEY_comma,
 | 
						||
+                WPE_KEY_less,
 | 
						||
+                WPE_KEY_minus,
 | 
						||
+                WPE_KEY_underscore,
 | 
						||
+                WPE_KEY_period,
 | 
						||
+                WPE_KEY_greater,
 | 
						||
+                WPE_KEY_slash,
 | 
						||
+                WPE_KEY_question,
 | 
						||
+                WPE_KEY_asciitilde,
 | 
						||
+                WPE_KEY_quoteleft,
 | 
						||
+                WPE_KEY_bracketleft,
 | 
						||
+                WPE_KEY_braceleft,
 | 
						||
+                WPE_KEY_backslash,
 | 
						||
+                WPE_KEY_bar,
 | 
						||
+                WPE_KEY_bracketright,
 | 
						||
+                WPE_KEY_braceright,
 | 
						||
+                WPE_KEY_quoteright,
 | 
						||
+                WPE_KEY_quotedbl,
 | 
						||
+                WPE_KEY_AudioRewind,
 | 
						||
+                WPE_KEY_AudioForward,
 | 
						||
+                WPE_KEY_AudioPlay,
 | 
						||
+                WPE_KEY_F1,
 | 
						||
+                WPE_KEY_F2,
 | 
						||
+                WPE_KEY_F3,
 | 
						||
+                WPE_KEY_F4,
 | 
						||
+                WPE_KEY_F5,
 | 
						||
+                WPE_KEY_F6,
 | 
						||
+                WPE_KEY_F7,
 | 
						||
+                WPE_KEY_F8,
 | 
						||
+                WPE_KEY_F9,
 | 
						||
+                WPE_KEY_F10,
 | 
						||
+                WPE_KEY_F11,
 | 
						||
+                WPE_KEY_F12,
 | 
						||
+                WPE_KEY_F13,
 | 
						||
+                WPE_KEY_F14,
 | 
						||
+                WPE_KEY_F15,
 | 
						||
+                WPE_KEY_F16,
 | 
						||
+                WPE_KEY_F17,
 | 
						||
+                WPE_KEY_F18,
 | 
						||
+                WPE_KEY_F19,
 | 
						||
+                WPE_KEY_F20,
 | 
						||
+                WPE_KEY_F21,
 | 
						||
+                WPE_KEY_F22,
 | 
						||
+                WPE_KEY_F23,
 | 
						||
+                WPE_KEY_F24,
 | 
						||
+                WPE_KEY_VoidSymbol,
 | 
						||
+                WPE_KEY_Red,
 | 
						||
+                WPE_KEY_Green,
 | 
						||
+                WPE_KEY_Yellow,
 | 
						||
+                WPE_KEY_Blue,
 | 
						||
+                WPE_KEY_PowerOff,
 | 
						||
+                WPE_KEY_AudioRecord,
 | 
						||
+                WPE_KEY_Display,
 | 
						||
+                WPE_KEY_Subtitle,
 | 
						||
+                WPE_KEY_Video
 | 
						||
+            };
 | 
						||
+            result = new HashMap<int, unsigned>();
 | 
						||
+            for (unsigned WPEKeyCode : WPEKeyCodes) {
 | 
						||
+                int winKeyCode = PlatformKeyboardEvent::windowsKeyCodeForWPEKeyCode(WPEKeyCode);
 | 
						||
+                // If several gdk key codes map to the same win key code first one is used.
 | 
						||
+                result->add(winKeyCode, WPEKeyCode);
 | 
						||
+            }
 | 
						||
+        });
 | 
						||
+    return *result;
 | 
						||
+}
 | 
						||
+
 | 
						||
+unsigned PlatformKeyboardEvent::WPEKeyCodeForWindowsKeyCode(int keycode)
 | 
						||
+{
 | 
						||
+    return WPEToWindowsKeyCodeMap().get(keycode);
 | 
						||
+}
 | 
						||
+
 | 
						||
 String PlatformKeyboardEvent::singleCharacterString(unsigned val)
 | 
						||
 {
 | 
						||
     switch (val) {
 | 
						||
diff --git a/Source/WebCore/platform/network/NetworkStateNotifier.h b/Source/WebCore/platform/network/NetworkStateNotifier.h
 | 
						||
index 87930048f4fd18d6098af7de4da25be532df5931..2bb2afcf9473b0d5d97efbe18dd7b8145bc5f932 100644
 | 
						||
--- a/Source/WebCore/platform/network/NetworkStateNotifier.h
 | 
						||
+++ b/Source/WebCore/platform/network/NetworkStateNotifier.h
 | 
						||
@@ -72,6 +72,7 @@ private:
 | 
						||
 #endif
 | 
						||
 
 | 
						||
     Optional<bool> m_isOnLine;
 | 
						||
+    Optional<bool> m_emulatedIsOnLine;
 | 
						||
     Vector<WTF::Function<void(bool)>> m_listeners;
 | 
						||
     Timer m_updateStateTimer;
 | 
						||
 
 | 
						||
diff --git a/Source/WebCore/platform/network/curl/CookieJarDB.cpp b/Source/WebCore/platform/network/curl/CookieJarDB.cpp
 | 
						||
index 02b0f63388332ff47ca96f962a0a0a413336006e..29f80ea769a72cb4b7b93c11073c337174c83701 100644
 | 
						||
--- a/Source/WebCore/platform/network/curl/CookieJarDB.cpp
 | 
						||
+++ b/Source/WebCore/platform/network/curl/CookieJarDB.cpp
 | 
						||
@@ -30,11 +30,13 @@
 | 
						||
 #include "PublicSuffix.h"
 | 
						||
 #include "RegistrableDomain.h"
 | 
						||
 #include "SQLiteFileSystem.h"
 | 
						||
+#include <wtf/DateMath.h>
 | 
						||
 #include <wtf/FileSystem.h>
 | 
						||
 #include <wtf/MonotonicTime.h>
 | 
						||
 #include <wtf/Optional.h>
 | 
						||
 #include <wtf/URL.h>
 | 
						||
 #include <wtf/Vector.h>
 | 
						||
+#include <wtf/WallTime.h>
 | 
						||
 #include <wtf/text/StringConcatenateNumbers.h>
 | 
						||
 
 | 
						||
 namespace WebCore {
 | 
						||
@@ -377,7 +379,7 @@ Optional<Vector<Cookie>> CookieJarDB::searchCookies(const URL& firstParty, const
 | 
						||
 
 | 
						||
     const String sql =
 | 
						||
         "SELECT name, value, domain, path, expires, httponly, secure, session FROM Cookie WHERE "\
 | 
						||
-        "(NOT ((session = 0) AND (datetime(expires, 'unixepoch') < datetime('now')))) "\
 | 
						||
+        "(NOT ((session = 0) AND (expires < ?)))"
 | 
						||
         "AND (httponly = COALESCE(NULLIF(?, -1), httponly)) "\
 | 
						||
         "AND (secure = COALESCE(NULLIF(?, -1), secure)) "\
 | 
						||
         "AND (session = COALESCE(NULLIF(?, -1), session)) "\
 | 
						||
@@ -389,15 +391,16 @@ Optional<Vector<Cookie>> CookieJarDB::searchCookies(const URL& firstParty, const
 | 
						||
         return WTF::nullopt;
 | 
						||
 
 | 
						||
     pstmt->prepare();
 | 
						||
-    pstmt->bindInt(1, httpOnly ? *httpOnly : -1);
 | 
						||
-    pstmt->bindInt(2, secure ? *secure : -1);
 | 
						||
-    pstmt->bindInt(3, session ? *session : -1);
 | 
						||
-    pstmt->bindText(4, requestHost);
 | 
						||
+    pstmt->bindInt64(1, WallTime::now().secondsSinceEpoch().milliseconds());
 | 
						||
+    pstmt->bindInt(2, httpOnly ? *httpOnly : -1);
 | 
						||
+    pstmt->bindInt(3, secure ? *secure : -1);
 | 
						||
+    pstmt->bindInt(4, session ? *session : -1);
 | 
						||
+    pstmt->bindText(5, requestHost);
 | 
						||
 
 | 
						||
     if (CookieUtil::isIPAddress(requestHost) || !requestHost.contains('.') || registrableDomain.isEmpty())
 | 
						||
-        pstmt->bindNull(5);
 | 
						||
+        pstmt->bindNull(6);
 | 
						||
     else
 | 
						||
-        pstmt->bindText(5, String("*.") + registrableDomain.string());
 | 
						||
+        pstmt->bindText(6, String("*.") + registrableDomain.string());
 | 
						||
 
 | 
						||
     if (!pstmt)
 | 
						||
         return WTF::nullopt;
 | 
						||
@@ -413,7 +416,7 @@ Optional<Vector<Cookie>> CookieJarDB::searchCookies(const URL& firstParty, const
 | 
						||
         String cookieValue = pstmt->getColumnText(1);
 | 
						||
         String cookieDomain = pstmt->getColumnText(2).convertToASCIILowercase();
 | 
						||
         String cookiePath = pstmt->getColumnText(3);
 | 
						||
-        double cookieExpires = (double)pstmt->getColumnInt64(4) * 1000;
 | 
						||
+        double cookieExpires = (double)pstmt->getColumnInt64(4);
 | 
						||
         bool cookieHttpOnly = (pstmt->getColumnInt(5) == 1);
 | 
						||
         bool cookieSecure = (pstmt->getColumnInt(6) == 1);
 | 
						||
         bool cookieSession = (pstmt->getColumnInt(7) == 1);
 | 
						||
@@ -434,7 +437,8 @@ Optional<Vector<Cookie>> CookieJarDB::searchCookies(const URL& firstParty, const
 | 
						||
         cookie.value = cookieValue;
 | 
						||
         cookie.domain = cookieDomain;
 | 
						||
         cookie.path = cookiePath;
 | 
						||
-        cookie.expires = cookieExpires;
 | 
						||
+        if (cookieExpires)
 | 
						||
+          cookie.expires = cookieExpires;
 | 
						||
         cookie.httpOnly = cookieHttpOnly;
 | 
						||
         cookie.secure = cookieSecure;
 | 
						||
         cookie.session = cookieSession;
 | 
						||
@@ -461,7 +465,9 @@ Vector<Cookie> CookieJarDB::getAllCookies()
 | 
						||
         cookie.value = pstmt->getColumnText(1);
 | 
						||
         cookie.domain = pstmt->getColumnText(2).convertToASCIILowercase();
 | 
						||
         cookie.path = pstmt->getColumnText(3);
 | 
						||
-        cookie.expires = (double)pstmt->getColumnInt64(4) * 1000;
 | 
						||
+        double cookieExpires = (double)pstmt->getColumnInt64(4);
 | 
						||
+        if (cookieExpires)
 | 
						||
+          cookie.expires = cookieExpires;
 | 
						||
         cookie.httpOnly = (pstmt->getColumnInt(5) == 1);
 | 
						||
         cookie.secure = (pstmt->getColumnInt(6) == 1);
 | 
						||
         cookie.session = (pstmt->getColumnInt(7) == 1);
 | 
						||
@@ -505,7 +511,7 @@ bool CookieJarDB::canAcceptCookie(const Cookie& cookie, const URL& firstParty, c
 | 
						||
 bool CookieJarDB::setCookie(const Cookie& cookie)
 | 
						||
 {
 | 
						||
     auto expires = cookie.expires.valueOr(0.0);
 | 
						||
-    if (!cookie.session && MonotonicTime::fromRawSeconds(expires) <= MonotonicTime::now())
 | 
						||
+    if (!cookie.session && MonotonicTime::fromRawSeconds(expires / WTF::msPerSecond) <= MonotonicTime::now())
 | 
						||
         return deleteCookieInternal(cookie.name, cookie.domain, cookie.path);
 | 
						||
 
 | 
						||
     auto& statement = preparedStatement(SET_COOKIE_SQL);
 | 
						||
diff --git a/Source/WebCore/platform/network/curl/CookieUtil.cpp b/Source/WebCore/platform/network/curl/CookieUtil.cpp
 | 
						||
index 5d8cefd130891eb042d3b04e2b6f846e3881b7e4..d3cf6e67132fb7c52ef1a03188af0916f1688118 100644
 | 
						||
--- a/Source/WebCore/platform/network/curl/CookieUtil.cpp
 | 
						||
+++ b/Source/WebCore/platform/network/curl/CookieUtil.cpp
 | 
						||
@@ -31,6 +31,7 @@
 | 
						||
 
 | 
						||
 #include <wtf/DateMath.h>
 | 
						||
 #include <wtf/Optional.h>
 | 
						||
+#include <wtf/WallTime.h>
 | 
						||
 #include <wtf/text/WTFString.h>
 | 
						||
 
 | 
						||
 /* This is the maximum line length we accept for a cookie line. RFC 2109
 | 
						||
@@ -79,13 +80,13 @@ bool domainMatch(const String& cookieDomain, const String& host)
 | 
						||
     return false;
 | 
						||
 }
 | 
						||
 
 | 
						||
-static Optional<double> parseExpires(const char* expires)
 | 
						||
+static Optional<double> parseExpiresMS(const char* expires)
 | 
						||
 {
 | 
						||
     double tmp = WTF::parseDateFromNullTerminatedCharacters(expires);
 | 
						||
     if (isnan(tmp))
 | 
						||
         return { };
 | 
						||
 
 | 
						||
-    return Optional<double> {tmp / WTF::msPerSecond};
 | 
						||
+    return Optional<double> {tmp};
 | 
						||
 }
 | 
						||
 
 | 
						||
 static void parseCookieAttributes(const String& attribute, bool& hasMaxAge, Cookie& result)
 | 
						||
@@ -117,9 +118,9 @@ static void parseCookieAttributes(const String& attribute, bool& hasMaxAge, Cook
 | 
						||
 
 | 
						||
     } else if (equalIgnoringASCIICase(attributeName, "max-age")) {
 | 
						||
         bool ok;
 | 
						||
-        time_t expiryTime = time(0) + attributeValue.toInt64(&ok);
 | 
						||
+        double maxAgeSeconds = attributeValue.toInt64(&ok);
 | 
						||
         if (ok) {
 | 
						||
-            result.expires = (double)expiryTime;
 | 
						||
+            result.expires = (WallTime::now().secondsSinceEpoch().value() + maxAgeSeconds) * WTF::msPerSecond;
 | 
						||
             result.session = false;
 | 
						||
 
 | 
						||
             // If there is a max-age attribute as well as an expires attribute
 | 
						||
@@ -127,7 +128,7 @@ static void parseCookieAttributes(const String& attribute, bool& hasMaxAge, Cook
 | 
						||
             hasMaxAge = true;
 | 
						||
         }
 | 
						||
     } else if (equalIgnoringASCIICase(attributeName, "expires") && !hasMaxAge) {
 | 
						||
-        if (auto expiryTime = parseExpires(attributeValue.utf8().data())) {
 | 
						||
+        if (auto expiryTime = parseExpiresMS(attributeValue.utf8().data())) {
 | 
						||
             result.expires = expiryTime.value();
 | 
						||
             result.session = false;
 | 
						||
         }
 | 
						||
diff --git a/Source/WebCore/platform/win/KeyEventWin.cpp b/Source/WebCore/platform/win/KeyEventWin.cpp
 | 
						||
index 44737686187a06a92c408ea60b63a48ac8481334..c754a763688b52e7ddd47493296ef9b0c6adc527 100644
 | 
						||
--- a/Source/WebCore/platform/win/KeyEventWin.cpp
 | 
						||
+++ b/Source/WebCore/platform/win/KeyEventWin.cpp
 | 
						||
@@ -239,10 +239,16 @@ PlatformKeyboardEvent::PlatformKeyboardEvent(HWND, WPARAM code, LPARAM keyData,
 | 
						||
 {
 | 
						||
 }
 | 
						||
 
 | 
						||
-void PlatformKeyboardEvent::disambiguateKeyDownEvent(Type, bool)
 | 
						||
+void PlatformKeyboardEvent::disambiguateKeyDownEvent(Type type, bool backwardsCompatibility)
 | 
						||
 {
 | 
						||
-    // No KeyDown events on Windows to disambiguate.
 | 
						||
-    ASSERT_NOT_REACHED();
 | 
						||
+    m_type = type;
 | 
						||
+    if (type == PlatformEvent::RawKeyDown) {
 | 
						||
+        m_text = String();
 | 
						||
+        m_unmodifiedText = String();
 | 
						||
+    } else {
 | 
						||
+        m_keyIdentifier = String();
 | 
						||
+        m_windowsVirtualKeyCode = 0;
 | 
						||
+    }
 | 
						||
 }
 | 
						||
 
 | 
						||
 bool PlatformKeyboardEvent::currentCapsLockState()
 | 
						||
diff --git a/Source/WebKit/NetworkProcess/NetworkProcess.cpp b/Source/WebKit/NetworkProcess/NetworkProcess.cpp
 | 
						||
index 09bc42cb53114d089c3794ae7b00503655a4499d..1bdb584c7f5f1867088c775cb6518d620ab295a0 100644
 | 
						||
--- a/Source/WebKit/NetworkProcess/NetworkProcess.cpp
 | 
						||
+++ b/Source/WebKit/NetworkProcess/NetworkProcess.cpp
 | 
						||
@@ -26,7 +26,6 @@
 | 
						||
 
 | 
						||
 #include "config.h"
 | 
						||
 #include "NetworkProcess.h"
 | 
						||
-
 | 
						||
 #include "ArgumentCoders.h"
 | 
						||
 #include "Attachment.h"
 | 
						||
 #include "AuthenticationManager.h"
 | 
						||
@@ -594,6 +593,35 @@ void NetworkProcess::destroySession(PAL::SessionID sessionID)
 | 
						||
     m_storageManagerSet->remove(sessionID);
 | 
						||
 }
 | 
						||
 
 | 
						||
+void NetworkProcess::getAllCookies(PAL::SessionID sessionID, CompletionHandler<void(Vector<WebCore::Cookie>&&)>&& completionHandler)
 | 
						||
+{
 | 
						||
+    if (auto* networkStorageSession = storageSession(sessionID)) {
 | 
						||
+        completionHandler(networkStorageSession->getAllCookies());
 | 
						||
+        return;
 | 
						||
+    }
 | 
						||
+    completionHandler({ });
 | 
						||
+}
 | 
						||
+
 | 
						||
+void NetworkProcess::setCookies(PAL::SessionID sessionID, Vector<WebCore::Cookie> cookies, CompletionHandler<void(bool)>&& completionHandler) {
 | 
						||
+    if (auto* networkStorageSession = storageSession(sessionID)) {
 | 
						||
+        for (auto cookie : cookies)
 | 
						||
+            networkStorageSession->setCookie(cookie);
 | 
						||
+        completionHandler(true);
 | 
						||
+        return;
 | 
						||
+    }
 | 
						||
+    completionHandler(false);
 | 
						||
+}
 | 
						||
+
 | 
						||
+void NetworkProcess::deleteAllCookies(PAL::SessionID sessionID, CompletionHandler<void(bool)>&& completionHandler)
 | 
						||
+{
 | 
						||
+    if (auto* networkStorageSession = storageSession(sessionID)) {
 | 
						||
+        networkStorageSession->deleteAllCookies();
 | 
						||
+        completionHandler(true);
 | 
						||
+        return;
 | 
						||
+    }
 | 
						||
+    completionHandler(false);
 | 
						||
+}
 | 
						||
+
 | 
						||
 #if ENABLE(RESOURCE_LOAD_STATISTICS)
 | 
						||
 void NetworkProcess::dumpResourceLoadStatistics(PAL::SessionID sessionID, CompletionHandler<void(String)>&& completionHandler)
 | 
						||
 {
 | 
						||
diff --git a/Source/WebKit/NetworkProcess/NetworkProcess.h b/Source/WebKit/NetworkProcess/NetworkProcess.h
 | 
						||
index 769595855829302a1bed9596412813f333572f18..1a11997c2723666ae7c193ac4e79af9a3632cdb1 100644
 | 
						||
--- a/Source/WebKit/NetworkProcess/NetworkProcess.h
 | 
						||
+++ b/Source/WebKit/NetworkProcess/NetworkProcess.h
 | 
						||
@@ -74,6 +74,7 @@ class SessionID;
 | 
						||
 
 | 
						||
 namespace WebCore {
 | 
						||
 class CertificateInfo;
 | 
						||
+struct Cookie;
 | 
						||
 class CurlProxySettings;
 | 
						||
 class DownloadID;
 | 
						||
 class ProtectionSpace;
 | 
						||
@@ -202,6 +203,10 @@ public:
 | 
						||
 
 | 
						||
     void addWebsiteDataStore(WebsiteDataStoreParameters&&);
 | 
						||
 
 | 
						||
+    void getAllCookies(PAL::SessionID, CompletionHandler<void(Vector<WebCore::Cookie>&&)>&&);
 | 
						||
+    void setCookies(PAL::SessionID, Vector<WebCore::Cookie>, CompletionHandler<void(bool)>&&);
 | 
						||
+    void deleteAllCookies(PAL::SessionID, CompletionHandler<void(bool)>&&);
 | 
						||
+
 | 
						||
 #if ENABLE(RESOURCE_LOAD_STATISTICS)
 | 
						||
     void clearPrevalentResource(PAL::SessionID, const RegistrableDomain&, CompletionHandler<void()>&&);
 | 
						||
     void clearUserInteraction(PAL::SessionID, const RegistrableDomain&, CompletionHandler<void()>&&);
 | 
						||
@@ -309,6 +314,7 @@ public:
 | 
						||
 
 | 
						||
 #if PLATFORM(COCOA)
 | 
						||
     NetworkHTTPSUpgradeChecker& networkHTTPSUpgradeChecker();
 | 
						||
+    bool ignoreTLSErrors() const { return m_ignoreTLSErrors; }
 | 
						||
 #endif
 | 
						||
 
 | 
						||
     const String& uiProcessBundleIdentifier() const { return m_uiProcessBundleIdentifier; }
 | 
						||
@@ -422,8 +428,10 @@ private:
 | 
						||
     void syncAllCookies();
 | 
						||
     void didSyncAllCookies();
 | 
						||
 
 | 
						||
-#if USE(SOUP)
 | 
						||
+#if PLATFORM(COCOA) || USE(CURL) || USE(SOUP)
 | 
						||
     void setIgnoreTLSErrors(bool);
 | 
						||
+#endif
 | 
						||
+#if USE(SOUP)
 | 
						||
     void userPreferredLanguagesChanged(const Vector<String>&);
 | 
						||
     void setNetworkProxySettings(const WebCore::SoupNetworkProxySettings&);
 | 
						||
 #endif
 | 
						||
@@ -570,6 +578,7 @@ private:
 | 
						||
 
 | 
						||
 #if PLATFORM(COCOA)
 | 
						||
     std::unique_ptr<NetworkHTTPSUpgradeChecker> m_networkHTTPSUpgradeChecker;
 | 
						||
+    bool m_ignoreTLSErrors { false };
 | 
						||
 #endif
 | 
						||
 
 | 
						||
 #if ENABLE(RESOURCE_LOAD_STATISTICS)
 | 
						||
diff --git a/Source/WebKit/NetworkProcess/NetworkProcess.messages.in b/Source/WebKit/NetworkProcess/NetworkProcess.messages.in
 | 
						||
index ebebaddfbd2e036dd02f4efbf99645613eb28206..81057e5bbfaa5b61e3e93ce781476a7953444aff 100644
 | 
						||
--- a/Source/WebKit/NetworkProcess/NetworkProcess.messages.in
 | 
						||
+++ b/Source/WebKit/NetworkProcess/NetworkProcess.messages.in
 | 
						||
@@ -27,8 +27,10 @@ messages -> NetworkProcess LegacyReceiver {
 | 
						||
     # Creates a connection for communication with a WebProcess
 | 
						||
     CreateNetworkConnectionToWebProcess(WebCore::ProcessIdentifier processIdentifier, PAL::SessionID sessionID) -> (Optional<IPC::Attachment> connectionIdentifier, enum:uint8_t WebCore::HTTPCookieAcceptPolicy cookieAcceptPolicy) Async
 | 
						||
 
 | 
						||
-#if USE(SOUP)
 | 
						||
+#if USE(SOUP) || PLATFORM(COCOA) || USE(CURL)
 | 
						||
     SetIgnoreTLSErrors(bool ignoreTLSErrors)
 | 
						||
+#endif
 | 
						||
+#if USE(SOUP)
 | 
						||
     UserPreferredLanguagesChanged(Vector<String> languages)
 | 
						||
     SetNetworkProxySettings(struct WebCore::SoupNetworkProxySettings settings)
 | 
						||
     PrefetchDNS(String hostname)
 | 
						||
@@ -82,6 +84,10 @@ messages -> NetworkProcess LegacyReceiver {
 | 
						||
 
 | 
						||
     PreconnectTo(PAL::SessionID sessionID, URL url, String userAgent, enum:uint8_t WebCore::StoredCredentialsPolicy storedCredentialsPolicy);
 | 
						||
 
 | 
						||
+    GetAllCookies(PAL::SessionID sessionID) -> (Vector<WebCore::Cookie> cookies) Async
 | 
						||
+    SetCookies(PAL::SessionID sessionID, Vector<WebCore::Cookie> cookies) -> (bool success) Async
 | 
						||
+    DeleteAllCookies(PAL::SessionID sessionID) -> (bool success) Async
 | 
						||
+
 | 
						||
 #if ENABLE(RESOURCE_LOAD_STATISTICS)
 | 
						||
     ClearPrevalentResource(PAL::SessionID sessionID, WebCore::RegistrableDomain resourceDomain) -> () Async
 | 
						||
     ClearUserInteraction(PAL::SessionID sessionID, WebCore::RegistrableDomain resourceDomain) -> () Async
 | 
						||
diff --git a/Source/WebKit/NetworkProcess/NetworkProcessCreationParameters.h b/Source/WebKit/NetworkProcess/NetworkProcessCreationParameters.h
 | 
						||
index bdc2cae74892db1b0a26d22afbe2a4bb7a6c0ab0..7c45a71befbcd531e724a816d606f81fe6061a2f 100644
 | 
						||
--- a/Source/WebKit/NetworkProcess/NetworkProcessCreationParameters.h
 | 
						||
+++ b/Source/WebKit/NetworkProcess/NetworkProcessCreationParameters.h
 | 
						||
@@ -74,9 +74,9 @@ struct NetworkProcessCreationParameters {
 | 
						||
 
 | 
						||
     WebsiteDataStoreParameters defaultDataStoreParameters;
 | 
						||
     
 | 
						||
+    bool ignoreTLSErrors { false };
 | 
						||
 #if USE(SOUP)
 | 
						||
     WebCore::HTTPCookieAcceptPolicy cookieAcceptPolicy { WebCore::HTTPCookieAcceptPolicy::AlwaysAccept };
 | 
						||
-    bool ignoreTLSErrors { false };
 | 
						||
     Vector<String> languages;
 | 
						||
     WebCore::SoupNetworkProxySettings proxySettings;
 | 
						||
 #endif
 | 
						||
diff --git a/Source/WebKit/NetworkProcess/cocoa/NetworkProcessCocoa.mm b/Source/WebKit/NetworkProcess/cocoa/NetworkProcessCocoa.mm
 | 
						||
index 6416bcfe97bf44a231f0691c5ce97fba791df526..58aa3dd33f2f96c045a2b725e74c3da2a4a6ce80 100644
 | 
						||
--- a/Source/WebKit/NetworkProcess/cocoa/NetworkProcessCocoa.mm
 | 
						||
+++ b/Source/WebKit/NetworkProcess/cocoa/NetworkProcessCocoa.mm
 | 
						||
@@ -89,6 +89,8 @@ void NetworkProcess::platformInitializeNetworkProcessCocoa(const NetworkProcessC
 | 
						||
 #endif
 | 
						||
 #endif
 | 
						||
 
 | 
						||
+    setIgnoreTLSErrors(parameters.ignoreTLSErrors);
 | 
						||
+
 | 
						||
     _CFNetworkSetATSContext(parameters.networkATSContext.get());
 | 
						||
 
 | 
						||
     m_uiProcessBundleIdentifier = parameters.uiProcessBundleIdentifier;
 | 
						||
@@ -209,6 +211,7 @@ void NetworkProcess::syncAllCookies()
 | 
						||
     });
 | 
						||
 }
 | 
						||
 
 | 
						||
+
 | 
						||
 #if HAVE(FOUNDATION_WITH_SAVE_COOKIES_WITH_COMPLETION_HANDLER)
 | 
						||
 static void saveCookies(NSHTTPCookieStorage *cookieStorage, CompletionHandler<void()>&& completionHandler)
 | 
						||
 {
 | 
						||
@@ -239,6 +242,11 @@ void NetworkProcess::platformSyncAllCookies(CompletionHandler<void()>&& completi
 | 
						||
     ALLOW_DEPRECATED_DECLARATIONS_END
 | 
						||
 }
 | 
						||
 
 | 
						||
+void NetworkProcess::setIgnoreTLSErrors(bool ignoreTLSErrors)
 | 
						||
+{
 | 
						||
+    m_ignoreTLSErrors = ignoreTLSErrors;
 | 
						||
+}
 | 
						||
+
 | 
						||
 void NetworkProcess::platformPrepareToSuspend(CompletionHandler<void()>&& completionHandler)
 | 
						||
 {
 | 
						||
     completionHandler();
 | 
						||
diff --git a/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.h b/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.h
 | 
						||
index 198aaacb4847c934191a5df8e6b69c1f3e565647..16cebf540b396a73527da35c51b2f247c7ef0aba 100644
 | 
						||
--- a/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.h
 | 
						||
+++ b/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.h
 | 
						||
@@ -77,7 +77,7 @@ public:
 | 
						||
     const String& dataConnectionServiceType() const;
 | 
						||
 #endif
 | 
						||
 
 | 
						||
-    static bool allowsSpecificHTTPSCertificateForHost(const WebCore::AuthenticationChallenge&);
 | 
						||
+    bool allowsSpecificHTTPSCertificateForHost(const WebCore::AuthenticationChallenge&);
 | 
						||
 
 | 
						||
     void continueDidReceiveChallenge(SessionWrapper&, const WebCore::AuthenticationChallenge&, NegotiatedLegacyTLS, NetworkDataTaskCocoa::TaskIdentifier, NetworkDataTaskCocoa*, CompletionHandler<void(WebKit::AuthenticationChallengeDisposition, const WebCore::Credential&)>&&);
 | 
						||
 
 | 
						||
diff --git a/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm b/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm
 | 
						||
index 4e5c72ff0ac5bc3b419bb5e57e0dbb71ee01f9bd..84f38cc73841ac7760e75af66376e2390471f80d 100644
 | 
						||
--- a/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm
 | 
						||
+++ b/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm
 | 
						||
@@ -653,7 +653,7 @@ static inline void processServerTrustEvaluation(NetworkSessionCocoa& session, Se
 | 
						||
     NegotiatedLegacyTLS negotiatedLegacyTLS = NegotiatedLegacyTLS::No;
 | 
						||
 
 | 
						||
     if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
 | 
						||
-        if (NetworkSessionCocoa::allowsSpecificHTTPSCertificateForHost(challenge))
 | 
						||
+        if (sessionCocoa->allowsSpecificHTTPSCertificateForHost(challenge))
 | 
						||
             return completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]);
 | 
						||
 
 | 
						||
 #if HAVE(TLS_PROTOCOL_VERSION_T)
 | 
						||
@@ -1379,6 +1379,9 @@ static bool certificatesMatch(SecTrustRef trust1, SecTrustRef trust2)
 | 
						||
 
 | 
						||
 bool NetworkSessionCocoa::allowsSpecificHTTPSCertificateForHost(const WebCore::AuthenticationChallenge& challenge)
 | 
						||
 {
 | 
						||
+    if (networkProcess().ignoreTLSErrors())
 | 
						||
+        return true;
 | 
						||
+
 | 
						||
     const String& host = challenge.protectionSpace().host();
 | 
						||
     NSArray *certificates = [NSURLRequest allowsSpecificHTTPSCertificateForHost:host];
 | 
						||
     if (!certificates)
 | 
						||
diff --git a/Source/WebKit/NetworkProcess/curl/NetworkProcessCurl.cpp b/Source/WebKit/NetworkProcess/curl/NetworkProcessCurl.cpp
 | 
						||
index 5be170266f45b8bf72ef56b10087cb59bb56dba9..24f8885a0054c1a64cb7deebb00bb4421c56a858 100644
 | 
						||
--- a/Source/WebKit/NetworkProcess/curl/NetworkProcessCurl.cpp
 | 
						||
+++ b/Source/WebKit/NetworkProcess/curl/NetworkProcessCurl.cpp
 | 
						||
@@ -94,4 +94,9 @@ void NetworkProcess::setNetworkProxySettings(PAL::SessionID sessionID, WebCore::
 | 
						||
         ASSERT_NOT_REACHED();
 | 
						||
 }
 | 
						||
 
 | 
						||
+void NetworkProcess::setIgnoreTLSErrors(bool ignoreTLSErrors)
 | 
						||
+{
 | 
						||
+    CurlContext::singleton().sslHandle().setIgnoreSSLErrors(ignoreTLSErrors);
 | 
						||
+}
 | 
						||
+
 | 
						||
 } // namespace WebKit
 | 
						||
diff --git a/Source/WebKit/PlatformWPE.cmake b/Source/WebKit/PlatformWPE.cmake
 | 
						||
index 963518a05c4ad1a4690048341104022504e04651..e6800b106c40fec6cd80415498a6bddfee1c17ac 100644
 | 
						||
--- a/Source/WebKit/PlatformWPE.cmake
 | 
						||
+++ b/Source/WebKit/PlatformWPE.cmake
 | 
						||
@@ -249,6 +249,7 @@ list(APPEND WebKit_INCLUDE_DIRECTORIES
 | 
						||
     "${WEBKIT_DIR}/UIProcess/API/wpe"
 | 
						||
     "${WEBKIT_DIR}/UIProcess/CoordinatedGraphics"
 | 
						||
     "${WEBKIT_DIR}/UIProcess/geoclue"
 | 
						||
+    "${WEBKIT_DIR}/UIProcess/glib"
 | 
						||
     "${WEBKIT_DIR}/UIProcess/gstreamer"
 | 
						||
     "${WEBKIT_DIR}/UIProcess/linux"
 | 
						||
     "${WEBKIT_DIR}/UIProcess/soup"
 | 
						||
diff --git a/Source/WebKit/PlatformWin.cmake b/Source/WebKit/PlatformWin.cmake
 | 
						||
index 75a9c8d7678dad39dc4b5254427da518ef5928f1..e1de3540157681c4cc0404736b9604e7dd74e9bc 100644
 | 
						||
--- a/Source/WebKit/PlatformWin.cmake
 | 
						||
+++ b/Source/WebKit/PlatformWin.cmake
 | 
						||
@@ -56,8 +56,12 @@ list(APPEND WebKit_SOURCES
 | 
						||
 
 | 
						||
     UIProcess/WebsiteData/win/WebsiteDataStoreWin.cpp
 | 
						||
 
 | 
						||
+    UIProcess/win/InspectorTargetProxyWin.cpp
 | 
						||
+    UIProcess/win/InspectorPlaywrightAgentClientWin.cpp
 | 
						||
     UIProcess/win/PageClientImpl.cpp
 | 
						||
     UIProcess/win/WebContextMenuProxyWin.cpp
 | 
						||
+    UIProcess/win/WebPageInspectorEmulationAgentWin.cpp
 | 
						||
+    UIProcess/win/WebPageInspectorInputAgentWin.cpp
 | 
						||
     UIProcess/win/WebPageProxyWin.cpp
 | 
						||
     UIProcess/win/WebPopupMenuProxyWin.cpp
 | 
						||
     UIProcess/win/WebProcessPoolWin.cpp
 | 
						||
diff --git a/Source/WebKit/Shared/API/c/wpe/WebKit.h b/Source/WebKit/Shared/API/c/wpe/WebKit.h
 | 
						||
index 898e30b370db8176e886fbbde0cd960e38a64818..74945e06fac0eb14936578de6a599a123364a63a 100644
 | 
						||
--- a/Source/WebKit/Shared/API/c/wpe/WebKit.h
 | 
						||
+++ b/Source/WebKit/Shared/API/c/wpe/WebKit.h
 | 
						||
@@ -78,6 +78,7 @@
 | 
						||
 // From Source/WebKit/UIProcess/API/C
 | 
						||
 #include <WebKit/WKBackForwardListItemRef.h>
 | 
						||
 #include <WebKit/WKBackForwardListRef.h>
 | 
						||
+#include <WebKit/WKBrowserInspector.h>
 | 
						||
 #include <WebKit/WKContext.h>
 | 
						||
 #include <WebKit/WKContextConfigurationRef.h>
 | 
						||
 #include <WebKit/WKCredential.h>
 | 
						||
diff --git a/Source/WebKit/Shared/NativeWebKeyboardEvent.h b/Source/WebKit/Shared/NativeWebKeyboardEvent.h
 | 
						||
index f08c19fb95ec8c8cca8f4ca2aa4049885637febf..c09e35e1b4fbf95b31f8d890bf09231055e4373a 100644
 | 
						||
--- a/Source/WebKit/Shared/NativeWebKeyboardEvent.h
 | 
						||
+++ b/Source/WebKit/Shared/NativeWebKeyboardEvent.h
 | 
						||
@@ -34,6 +34,7 @@
 | 
						||
 #if USE(APPKIT)
 | 
						||
 #include <wtf/RetainPtr.h>
 | 
						||
 OBJC_CLASS NSView;
 | 
						||
+OBJC_CLASS NSEvent;
 | 
						||
 
 | 
						||
 namespace WebCore {
 | 
						||
 struct CompositionUnderline;
 | 
						||
@@ -67,18 +68,34 @@ 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&);
 | 
						||
     enum class HandledByInputMethod : bool { No, Yes };
 | 
						||
     NativeWebKeyboardEvent(GdkEvent*, const String&, HandledByInputMethod, Optional<Vector<WebCore::CompositionUnderline>>&&, Optional<EditingRange>&&, Vector<String>&& commands);
 | 
						||
+    NativeWebKeyboardEvent(Type type, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<Modifier> modifiers, WallTime timestamp, Vector<String>&& commands)
 | 
						||
+        : WebKeyboardEvent(type, text, unmodifiedText, key, code, keyIdentifier, windowsVirtualKeyCode, nativeVirtualKeyCode, isAutoRepeat, isKeypad, isSystemKey, modifiers, timestamp, WTFMove(commands))
 | 
						||
+    {
 | 
						||
+    }
 | 
						||
 #elif PLATFORM(IOS_FAMILY)
 | 
						||
     enum class HandledByInputMethod : bool { No, Yes };
 | 
						||
     NativeWebKeyboardEvent(::WebEvent *, HandledByInputMethod);
 | 
						||
 #elif USE(LIBWPE)
 | 
						||
     enum class HandledByInputMethod : bool { No, Yes };
 | 
						||
     NativeWebKeyboardEvent(struct wpe_input_keyboard_event*, const String&, HandledByInputMethod, Optional<Vector<WebCore::CompositionUnderline>>&&, Optional<EditingRange>&&);
 | 
						||
+    NativeWebKeyboardEvent(Type type, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<Modifier> modifiers, WallTime timestamp)
 | 
						||
+        : WebKeyboardEvent(type, text, unmodifiedText, key, code, keyIdentifier, windowsVirtualKeyCode, nativeVirtualKeyCode, isAutoRepeat, isKeypad, isSystemKey, modifiers, timestamp)
 | 
						||
+    {
 | 
						||
+    }
 | 
						||
 #elif PLATFORM(WIN)
 | 
						||
     NativeWebKeyboardEvent(HWND, UINT message, WPARAM, LPARAM, Vector<MSG>&& pendingCharEvents);
 | 
						||
+    NativeWebKeyboardEvent(Type type, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<Modifier> modifiers, WallTime timestamp)
 | 
						||
+        : WebKeyboardEvent(type, text, unmodifiedText, key, code, keyIdentifier, windowsVirtualKeyCode, nativeVirtualKeyCode, isAutoRepeat, isKeypad, isSystemKey, modifiers, timestamp)
 | 
						||
+    {
 | 
						||
+    }
 | 
						||
 #endif
 | 
						||
 
 | 
						||
 #if USE(APPKIT)
 | 
						||
diff --git a/Source/WebKit/Shared/NativeWebMouseEvent.h b/Source/WebKit/Shared/NativeWebMouseEvent.h
 | 
						||
index 0fa557e9faa34ba81a7a4f7da5e32f30cbfad5d2..4f06afeb895fb1231d87e4304a4b588cd326944c 100644
 | 
						||
--- a/Source/WebKit/Shared/NativeWebMouseEvent.h
 | 
						||
+++ b/Source/WebKit/Shared/NativeWebMouseEvent.h
 | 
						||
@@ -70,6 +70,11 @@ public:
 | 
						||
     NativeWebMouseEvent(HWND, UINT message, WPARAM, LPARAM, bool);
 | 
						||
 #endif
 | 
						||
 
 | 
						||
+#if PLATFORM(GTK) || USE(LIBWPE) || PLATFORM(WIN)
 | 
						||
+    NativeWebMouseEvent(Type type, Button button, unsigned short buttons, const WebCore::IntPoint& position, const WebCore::IntPoint& globalPosition, float deltaX, float deltaY, float deltaZ, int clickCount, OptionSet<Modifier> modifiers, WallTime timestamp)
 | 
						||
+       : WebMouseEvent(type, button, buttons, position, globalPosition, deltaX, deltaY, deltaZ, clickCount, modifiers, timestamp) { }
 | 
						||
+#endif
 | 
						||
+
 | 
						||
 #if USE(APPKIT)
 | 
						||
     NSEvent* nativeEvent() const { return m_nativeEvent.get(); }
 | 
						||
 #elif PLATFORM(GTK)
 | 
						||
diff --git a/Source/WebKit/Shared/WebCoreArgumentCoders.cpp b/Source/WebKit/Shared/WebCoreArgumentCoders.cpp
 | 
						||
index 3ceb4c77e59084229a40593986db3ece0a1a78dc..fb91b3d7d979a16fcc695ae4f8d40532539d82ad 100644
 | 
						||
--- a/Source/WebKit/Shared/WebCoreArgumentCoders.cpp
 | 
						||
+++ b/Source/WebKit/Shared/WebCoreArgumentCoders.cpp
 | 
						||
@@ -1459,6 +1459,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)
 | 
						||
@@ -1487,6 +1490,12 @@ bool ArgumentCoder<WindowFeatures>::decode(Decoder& decoder, WindowFeatures& win
 | 
						||
         return false;
 | 
						||
     if (!decoder.decode(windowFeatures.dialog))
 | 
						||
         return false;
 | 
						||
+    if (!decoder.decode(windowFeatures.noopener))
 | 
						||
+        return false;
 | 
						||
+    if (!decoder.decode(windowFeatures.noreferrer))
 | 
						||
+        return false;
 | 
						||
+    if (!decoder.decode(windowFeatures.additionalFeatures))
 | 
						||
+        return false;
 | 
						||
     return true;
 | 
						||
 }
 | 
						||
 
 | 
						||
diff --git a/Source/WebKit/Shared/WebEvent.h b/Source/WebKit/Shared/WebEvent.h
 | 
						||
index 224ef51567fdf5eb7321a3411faccd283b5b2813..7c102952d5821486f0c6a0af0b8d3286ace96b93 100644
 | 
						||
--- a/Source/WebKit/Shared/WebEvent.h
 | 
						||
+++ b/Source/WebKit/Shared/WebEvent.h
 | 
						||
@@ -37,6 +37,7 @@
 | 
						||
 #include <WebCore/IntSize.h>
 | 
						||
 #include <WebCore/KeypressCommand.h>
 | 
						||
 #include <wtf/OptionSet.h>
 | 
						||
+#include <wtf/RefCounted.h>
 | 
						||
 #include <wtf/WallTime.h>
 | 
						||
 #include <wtf/text/WTFString.h>
 | 
						||
 
 | 
						||
@@ -252,14 +253,18 @@ public:
 | 
						||
 
 | 
						||
 #if USE(APPKIT)
 | 
						||
     WebKeyboardEvent(Type, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, int macCharCode, bool handledByInputMethod, const Vector<WebCore::KeypressCommand>&, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<Modifier>, WallTime timestamp);
 | 
						||
+    WebKeyboardEvent(Type, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<Modifier>, WallTime timestamp, Vector<WebCore::KeypressCommand>&& commands);
 | 
						||
 #elif PLATFORM(GTK)
 | 
						||
     WebKeyboardEvent(Type, const String& text, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool handledByInputMethod, Optional<Vector<WebCore::CompositionUnderline>>&&, Optional<EditingRange>&&, Vector<String>&& commands, bool isKeypad, OptionSet<Modifier>, WallTime timestamp);
 | 
						||
+    WebKeyboardEvent(Type, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<Modifier>, WallTime timestamp, Vector<String>&& commands);
 | 
						||
 #elif PLATFORM(IOS_FAMILY)
 | 
						||
     WebKeyboardEvent(Type, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, int macCharCode, bool handledByInputMethod, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<Modifier>, WallTime timestamp);
 | 
						||
 #elif USE(LIBWPE)
 | 
						||
     WebKeyboardEvent(Type, const String& text, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool handledByInputMethod, Optional<Vector<WebCore::CompositionUnderline>>&&, Optional<EditingRange>&&, bool isKeypad, OptionSet<Modifier>, WallTime timestamp);
 | 
						||
+    WebKeyboardEvent(Type, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<Modifier>, WallTime timestamp);
 | 
						||
 #else
 | 
						||
     WebKeyboardEvent(Type, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, int macCharCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<Modifier>, WallTime timestamp);
 | 
						||
+    WebKeyboardEvent(Type, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<Modifier>, WallTime timestamp);
 | 
						||
 #endif
 | 
						||
 
 | 
						||
     const String& text() const { return m_text; }
 | 
						||
@@ -301,7 +306,7 @@ private:
 | 
						||
     int32_t m_nativeVirtualKeyCode;
 | 
						||
     int32_t m_macCharCode;
 | 
						||
 #if USE(APPKIT) || USE(UIKIT_KEYBOARD_ADDITIONS) || PLATFORM(GTK) || USE(LIBWPE)
 | 
						||
-    bool m_handledByInputMethod;
 | 
						||
+    bool m_handledByInputMethod = false;
 | 
						||
 #endif
 | 
						||
 #if PLATFORM(GTK) || USE(LIBWPE)
 | 
						||
     Optional<Vector<WebCore::CompositionUnderline>> m_preeditUnderlines;
 | 
						||
diff --git a/Source/WebKit/Shared/WebKeyboardEvent.cpp b/Source/WebKit/Shared/WebKeyboardEvent.cpp
 | 
						||
index cccb560418f32fad40587ac083b95f398eb1399d..f6b0aee44e5f12055dd14ad0636d780d2d4ece5d 100644
 | 
						||
--- a/Source/WebKit/Shared/WebKeyboardEvent.cpp
 | 
						||
+++ b/Source/WebKit/Shared/WebKeyboardEvent.cpp
 | 
						||
@@ -35,6 +35,7 @@ WebKeyboardEvent::WebKeyboardEvent()
 | 
						||
 {
 | 
						||
 }
 | 
						||
 
 | 
						||
+
 | 
						||
 #if USE(APPKIT)
 | 
						||
 
 | 
						||
 WebKeyboardEvent::WebKeyboardEvent(Type type, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, int macCharCode, bool handledByInputMethod, const Vector<WebCore::KeypressCommand>& commands, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<Modifier> modifiers, WallTime timestamp)
 | 
						||
@@ -56,6 +57,24 @@ WebKeyboardEvent::WebKeyboardEvent(Type type, const String& text, const String&
 | 
						||
     ASSERT(isKeyboardEventType(type));
 | 
						||
 }
 | 
						||
 
 | 
						||
+WebKeyboardEvent::WebKeyboardEvent(Type type, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<Modifier> modifiers, WallTime timestamp, Vector<WebCore::KeypressCommand>&& commands)
 | 
						||
+    : WebEvent(type, modifiers, timestamp)
 | 
						||
+    , m_text(text)
 | 
						||
+    , m_unmodifiedText(text)
 | 
						||
+    , m_key(key)
 | 
						||
+    , m_code(code)
 | 
						||
+    , m_keyIdentifier(keyIdentifier)
 | 
						||
+    , m_windowsVirtualKeyCode(windowsVirtualKeyCode)
 | 
						||
+    , m_nativeVirtualKeyCode(nativeVirtualKeyCode)
 | 
						||
+    , m_macCharCode(0)
 | 
						||
+    , m_commands(WTFMove(commands))
 | 
						||
+    , m_isAutoRepeat(isAutoRepeat)
 | 
						||
+    , m_isKeypad(isKeypad)
 | 
						||
+    , m_isSystemKey(isSystemKey)
 | 
						||
+{
 | 
						||
+    ASSERT(isKeyboardEventType(type));
 | 
						||
+}
 | 
						||
+
 | 
						||
 #elif PLATFORM(GTK)
 | 
						||
 
 | 
						||
 WebKeyboardEvent::WebKeyboardEvent(Type type, const String& text, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool handledByInputMethod, Optional<Vector<WebCore::CompositionUnderline>>&& preeditUnderlines, Optional<EditingRange>&& preeditSelectionRange, Vector<String>&& commands, bool isKeypad, OptionSet<Modifier> modifiers, WallTime timestamp)
 | 
						||
@@ -79,6 +98,24 @@ WebKeyboardEvent::WebKeyboardEvent(Type type, const String& text, const String&
 | 
						||
     ASSERT(isKeyboardEventType(type));
 | 
						||
 }
 | 
						||
 
 | 
						||
+WebKeyboardEvent::WebKeyboardEvent(Type type, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<Modifier> modifiers, WallTime timestamp, Vector<String>&& commands)
 | 
						||
+    : WebEvent(type, modifiers, timestamp)
 | 
						||
+    , m_text(text)
 | 
						||
+    , m_unmodifiedText(text)
 | 
						||
+    , m_key(key)
 | 
						||
+    , m_code(code)
 | 
						||
+    , m_keyIdentifier(keyIdentifier)
 | 
						||
+    , m_windowsVirtualKeyCode(windowsVirtualKeyCode)
 | 
						||
+    , m_nativeVirtualKeyCode(nativeVirtualKeyCode)
 | 
						||
+    , m_macCharCode(0)
 | 
						||
+    , m_commands(WTFMove(commands))
 | 
						||
+    , m_isAutoRepeat(isAutoRepeat)
 | 
						||
+    , m_isKeypad(isKeypad)
 | 
						||
+    , m_isSystemKey(isSystemKey)
 | 
						||
+{
 | 
						||
+    ASSERT(isKeyboardEventType(type));
 | 
						||
+}
 | 
						||
+
 | 
						||
 #elif PLATFORM(IOS_FAMILY)
 | 
						||
 
 | 
						||
 WebKeyboardEvent::WebKeyboardEvent(Type type, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, int macCharCode, bool handledByInputMethod, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<Modifier> modifiers, WallTime timestamp)
 | 
						||
@@ -144,6 +181,27 @@ WebKeyboardEvent::WebKeyboardEvent(Type type, const String& text, const String&
 | 
						||
 
 | 
						||
 #endif
 | 
						||
 
 | 
						||
+#if PLATFORM(WIN) || USE(LIBWPE)
 | 
						||
+
 | 
						||
+WebKeyboardEvent::WebKeyboardEvent(Type type, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<Modifier> modifiers, WallTime timestamp)
 | 
						||
+    : WebEvent(type, modifiers, timestamp)
 | 
						||
+    , m_text(text)
 | 
						||
+    , m_unmodifiedText(text)
 | 
						||
+    , m_key(key)
 | 
						||
+    , m_code(code)
 | 
						||
+    , m_keyIdentifier(keyIdentifier)
 | 
						||
+    , m_windowsVirtualKeyCode(windowsVirtualKeyCode)
 | 
						||
+    , m_nativeVirtualKeyCode(nativeVirtualKeyCode)
 | 
						||
+    , m_macCharCode(0)
 | 
						||
+    , m_isAutoRepeat(isAutoRepeat)
 | 
						||
+    , m_isKeypad(isKeypad)
 | 
						||
+    , m_isSystemKey(isSystemKey)
 | 
						||
+{
 | 
						||
+    ASSERT(isKeyboardEventType(type));
 | 
						||
+}
 | 
						||
+
 | 
						||
+#endif
 | 
						||
+
 | 
						||
 WebKeyboardEvent::~WebKeyboardEvent()
 | 
						||
 {
 | 
						||
 }
 | 
						||
diff --git a/Source/WebKit/Shared/WebPageCreationParameters.cpp b/Source/WebKit/Shared/WebPageCreationParameters.cpp
 | 
						||
index 724c16e50433debb240d9be13be9a5f0579baa43..ae6824657c76c0627bec3bfd037cf2cf48871e82 100644
 | 
						||
--- a/Source/WebKit/Shared/WebPageCreationParameters.cpp
 | 
						||
+++ b/Source/WebKit/Shared/WebPageCreationParameters.cpp
 | 
						||
@@ -149,6 +149,8 @@ void WebPageCreationParameters::encode(IPC::Encoder& encoder) const
 | 
						||
     encoder << shouldRenderCanvasInGPUProcess;
 | 
						||
     encoder << needsInAppBrowserPrivacyQuirks;
 | 
						||
 
 | 
						||
+    encoder << shouldPauseInInspectorWhenShown;
 | 
						||
+
 | 
						||
 #if PLATFORM(GTK)
 | 
						||
     encoder << themeName;
 | 
						||
 #endif
 | 
						||
@@ -478,6 +480,9 @@ Optional<WebPageCreationParameters> WebPageCreationParameters::decode(IPC::Decod
 | 
						||
     if (!decoder.decode(parameters.needsInAppBrowserPrivacyQuirks))
 | 
						||
         return WTF::nullopt;
 | 
						||
     
 | 
						||
+    if (!decoder.decode(parameters.shouldPauseInInspectorWhenShown))
 | 
						||
+        return WTF::nullopt;
 | 
						||
+
 | 
						||
 #if PLATFORM(GTK)
 | 
						||
     if (!decoder.decode(parameters.themeName))
 | 
						||
         return WTF::nullopt;
 | 
						||
diff --git a/Source/WebKit/Shared/WebPageCreationParameters.h b/Source/WebKit/Shared/WebPageCreationParameters.h
 | 
						||
index e8b9fa886cc37d688d1c88584635b212945b0e91..5cb8d7bbc7b24ef5bc2160b2b0d780827bb66b29 100644
 | 
						||
--- a/Source/WebKit/Shared/WebPageCreationParameters.h
 | 
						||
+++ b/Source/WebKit/Shared/WebPageCreationParameters.h
 | 
						||
@@ -220,6 +220,8 @@ struct WebPageCreationParameters {
 | 
						||
     bool shouldRenderCanvasInGPUProcess { false };
 | 
						||
     bool needsInAppBrowserPrivacyQuirks { false };
 | 
						||
 
 | 
						||
+    bool shouldPauseInInspectorWhenShown { false };
 | 
						||
+
 | 
						||
 #if PLATFORM(GTK)
 | 
						||
     String themeName;
 | 
						||
 #endif
 | 
						||
diff --git a/Source/WebKit/Shared/gtk/NativeWebKeyboardEventGtk.cpp b/Source/WebKit/Shared/gtk/NativeWebKeyboardEventGtk.cpp
 | 
						||
index 2357f3d58415fae78e48b0f8a25bddad85c786bf..f3941a74922f5a0a3bf59a11cd4c42fbfd33d0af 100644
 | 
						||
--- a/Source/WebKit/Shared/gtk/NativeWebKeyboardEventGtk.cpp
 | 
						||
+++ b/Source/WebKit/Shared/gtk/NativeWebKeyboardEventGtk.cpp
 | 
						||
@@ -40,7 +40,7 @@ NativeWebKeyboardEvent::NativeWebKeyboardEvent(GdkEvent* event, const String& te
 | 
						||
 }
 | 
						||
 
 | 
						||
 NativeWebKeyboardEvent::NativeWebKeyboardEvent(const NativeWebKeyboardEvent& event)
 | 
						||
-    : WebKeyboardEvent(WebEventFactory::createWebKeyboardEvent(event.nativeEvent(), event.text(), event.handledByInputMethod(), Optional<Vector<WebCore::CompositionUnderline>>(event.preeditUnderlines()), Optional<EditingRange>(event.preeditSelectionRange()), Vector<String>(event.commands())))
 | 
						||
+    : WebKeyboardEvent(event)
 | 
						||
     , m_nativeEvent(gdk_event_copy(event.nativeEvent()))
 | 
						||
 {
 | 
						||
 }
 | 
						||
diff --git a/Source/WebKit/Shared/gtk/NativeWebMouseEventGtk.cpp b/Source/WebKit/Shared/gtk/NativeWebMouseEventGtk.cpp
 | 
						||
index 58e37fe3827cdb08d36ef0c85b8d4a968dee001a..429d245ea99fdee1b598a5caf51de8ce4b47fb02 100644
 | 
						||
--- a/Source/WebKit/Shared/gtk/NativeWebMouseEventGtk.cpp
 | 
						||
+++ b/Source/WebKit/Shared/gtk/NativeWebMouseEventGtk.cpp
 | 
						||
@@ -38,8 +38,8 @@ NativeWebMouseEvent::NativeWebMouseEvent(GdkEvent* event, int eventClickCount, O
 | 
						||
 }
 | 
						||
 
 | 
						||
 NativeWebMouseEvent::NativeWebMouseEvent(const NativeWebMouseEvent& event)
 | 
						||
-    : WebMouseEvent(WebEventFactory::createWebMouseEvent(event.nativeEvent(), event.clickCount(), WebCore::IntPoint(event.deltaX(), event.deltaY())))
 | 
						||
-    , m_nativeEvent(gdk_event_copy(event.nativeEvent()))
 | 
						||
+    : WebMouseEvent(event)
 | 
						||
+    , m_nativeEvent(event.nativeEvent() ? gdk_event_copy(event.nativeEvent()) : nullptr)
 | 
						||
 {
 | 
						||
 }
 | 
						||
 
 | 
						||
diff --git a/Source/WebKit/Shared/ios/WebPlatformTouchPointIOS.cpp b/Source/WebKit/Shared/ios/WebPlatformTouchPointIOS.cpp
 | 
						||
index 7b5eb372880d8662544334cd4697276d543de45b..ba06ecbb2cf5088a4c8c0824b50cb7797605dc57 100644
 | 
						||
--- a/Source/WebKit/Shared/ios/WebPlatformTouchPointIOS.cpp
 | 
						||
+++ b/Source/WebKit/Shared/ios/WebPlatformTouchPointIOS.cpp
 | 
						||
@@ -26,7 +26,7 @@
 | 
						||
 #include "config.h"
 | 
						||
 #include "WebEvent.h"
 | 
						||
 
 | 
						||
-#if ENABLE(TOUCH_EVENTS)
 | 
						||
+#if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS_FAMILY)
 | 
						||
 
 | 
						||
 #include "WebCoreArgumentCoders.h"
 | 
						||
 
 | 
						||
@@ -79,4 +79,4 @@ Optional<WebPlatformTouchPoint> WebPlatformTouchPoint::decode(IPC::Decoder& deco
 | 
						||
 
 | 
						||
 } // namespace WebKit
 | 
						||
 
 | 
						||
-#endif // ENABLE(TOUCH_EVENTS)
 | 
						||
+#endif // ENABLE(TOUCH_EVENTS) && PLATFORM(IOS_FAMILY)
 | 
						||
diff --git a/Source/WebKit/Shared/ios/WebTouchEventIOS.cpp b/Source/WebKit/Shared/ios/WebTouchEventIOS.cpp
 | 
						||
index 45a56eb3b0fda13c3b78d57594a0092e4e1866f6..5e29e15813be6abe82790e6a98d3947e7a6fae44 100644
 | 
						||
--- a/Source/WebKit/Shared/ios/WebTouchEventIOS.cpp
 | 
						||
+++ b/Source/WebKit/Shared/ios/WebTouchEventIOS.cpp
 | 
						||
@@ -26,7 +26,7 @@
 | 
						||
 #include "config.h"
 | 
						||
 #include "WebEvent.h"
 | 
						||
 
 | 
						||
-#if ENABLE(TOUCH_EVENTS)
 | 
						||
+#if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS_FAMILY)
 | 
						||
 
 | 
						||
 #include "ArgumentCoders.h"
 | 
						||
 #include "WebCoreArgumentCoders.h"
 | 
						||
@@ -71,4 +71,4 @@ bool WebTouchEvent::decode(IPC::Decoder& decoder, WebTouchEvent& result)
 | 
						||
 
 | 
						||
 } // namespace WebKit
 | 
						||
 
 | 
						||
-#endif // ENABLE(TOUCH_EVENTS)
 | 
						||
+#endif // ENABLE(TOUCH_EVENTS) && PLATFORM(IOS_FAMILY)
 | 
						||
diff --git a/Source/WebKit/Shared/win/WebEventFactory.cpp b/Source/WebKit/Shared/win/WebEventFactory.cpp
 | 
						||
index 88d53d236cd6d62735f03678a04ca9c198dddacb..b8f8efc57ab00dc5725660c5a8ad56a3e6384de5 100644
 | 
						||
--- a/Source/WebKit/Shared/win/WebEventFactory.cpp
 | 
						||
+++ b/Source/WebKit/Shared/win/WebEventFactory.cpp
 | 
						||
@@ -473,7 +473,7 @@ WebKeyboardEvent WebEventFactory::createWebKeyboardEvent(HWND hwnd, UINT message
 | 
						||
 }
 | 
						||
 
 | 
						||
 #if ENABLE(TOUCH_EVENTS)
 | 
						||
-WebTouchEvent WebEventFactory::createWebTouchEvent(const GdkEvent* event, Vector<WebPlatformTouchPoint>&& touchPoints)
 | 
						||
+WebTouchEvent WebEventFactory::createWebTouchEvent()
 | 
						||
 {
 | 
						||
     return WebTouchEvent();
 | 
						||
 }
 | 
						||
diff --git a/Source/WebKit/Sources.txt b/Source/WebKit/Sources.txt
 | 
						||
index c3e3874d1480228a09b53ad3edda66fb33edc2f2..18d7a8e5459eefb94e8862d94129204389fb8623 100644
 | 
						||
--- a/Source/WebKit/Sources.txt
 | 
						||
+++ b/Source/WebKit/Sources.txt
 | 
						||
@@ -276,16 +276,21 @@ Shared/WebsiteData/WebsiteData.cpp
 | 
						||
 
 | 
						||
 UIProcess/AuxiliaryProcessProxy.cpp
 | 
						||
 UIProcess/BackgroundProcessResponsivenessTimer.cpp
 | 
						||
+UIProcess/BrowserInspectorController.cpp
 | 
						||
+UIProcess/BrowserInspectorPipe.cpp
 | 
						||
 UIProcess/DeviceIdHashSaltStorage.cpp
 | 
						||
 UIProcess/DrawingAreaProxy.cpp
 | 
						||
 UIProcess/FrameLoadState.cpp
 | 
						||
 UIProcess/GeolocationPermissionRequestManagerProxy.cpp
 | 
						||
 UIProcess/GeolocationPermissionRequestProxy.cpp
 | 
						||
+UIProcess/InspectorDialogAgent.cpp
 | 
						||
+UIProcess/InspectorPlaywrightAgent.cpp
 | 
						||
 UIProcess/LegacyGlobalSettings.cpp
 | 
						||
 UIProcess/PageLoadState.cpp
 | 
						||
 UIProcess/ProcessAssertion.cpp
 | 
						||
 UIProcess/ProcessThrottler.cpp
 | 
						||
 UIProcess/ProvisionalPageProxy.cpp
 | 
						||
+UIProcess/RemoteInspectorPipe.cpp
 | 
						||
 UIProcess/ResponsivenessTimer.cpp
 | 
						||
 UIProcess/StatisticsRequest.cpp
 | 
						||
 UIProcess/SuspendedPageProxy.cpp
 | 
						||
@@ -323,6 +328,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
 | 
						||
diff --git a/Source/WebKit/SourcesCocoa.txt b/Source/WebKit/SourcesCocoa.txt
 | 
						||
index a124cdca7849248a5039fb74da4541c18857f97e..f9d49d81f3383685daaf5a9d748925217cd3115e 100644
 | 
						||
--- a/Source/WebKit/SourcesCocoa.txt
 | 
						||
+++ b/Source/WebKit/SourcesCocoa.txt
 | 
						||
@@ -249,6 +249,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
 | 
						||
diff --git a/Source/WebKit/SourcesGTK.txt b/Source/WebKit/SourcesGTK.txt
 | 
						||
index eba34614fe0fdcee53c1edc4e940c41bbd24027c..17b592801937088d73ecd8842c48d55f57f0d8d2 100644
 | 
						||
--- a/Source/WebKit/SourcesGTK.txt
 | 
						||
+++ b/Source/WebKit/SourcesGTK.txt
 | 
						||
@@ -130,6 +130,7 @@ UIProcess/API/glib/WebKitAuthenticationRequest.cpp @no-unify
 | 
						||
 UIProcess/API/glib/WebKitAutomationSession.cpp @no-unify
 | 
						||
 UIProcess/API/glib/WebKitBackForwardList.cpp @no-unify
 | 
						||
 UIProcess/API/glib/WebKitBackForwardListItem.cpp @no-unify
 | 
						||
+UIProcess/API/glib/WebKitBrowserInspector.cpp @no-unify
 | 
						||
 UIProcess/API/glib/WebKitContextMenuClient.cpp @no-unify
 | 
						||
 UIProcess/API/glib/WebKitCookieManager.cpp @no-unify
 | 
						||
 UIProcess/API/glib/WebKitCredential.cpp @no-unify
 | 
						||
@@ -237,6 +238,7 @@ UIProcess/WebsiteData/unix/WebsiteDataStoreUnix.cpp
 | 
						||
 
 | 
						||
 UIProcess/cairo/BackingStoreCairo.cpp @no-unify
 | 
						||
 
 | 
						||
+UIProcess/glib/InspectorPlaywrightAgentClientGLib.cpp
 | 
						||
 UIProcess/glib/WebProcessPoolGLib.cpp
 | 
						||
 UIProcess/glib/WebProcessProxyGLib.cpp
 | 
						||
 UIProcess/glib/WebsiteDataStoreGLib.cpp @no-unify
 | 
						||
@@ -250,6 +252,7 @@ UIProcess/gtk/AcceleratedBackingStoreX11.cpp @no-unify
 | 
						||
 UIProcess/gtk/DragAndDropHandler.cpp
 | 
						||
 UIProcess/gtk/GestureController.cpp
 | 
						||
 UIProcess/gtk/HardwareAccelerationManager.cpp
 | 
						||
+UIProcess/gtk/InspectorTargetProxyGtk.cpp
 | 
						||
 UIProcess/gtk/KeyBindingTranslator.cpp
 | 
						||
 UIProcess/gtk/PointerLockManager.cpp @no-unify
 | 
						||
 UIProcess/gtk/PointerLockManagerWayland.cpp @no-unify
 | 
						||
@@ -261,6 +264,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 69a52e17a4a8932b5dfc5edfa72b922c18d43082..bc332745c8905414f1c8079c036dadf73902fde4 100644
 | 
						||
--- a/Source/WebKit/SourcesWPE.txt
 | 
						||
+++ b/Source/WebKit/SourcesWPE.txt
 | 
						||
@@ -118,6 +118,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
 | 
						||
@@ -193,7 +194,7 @@ UIProcess/Automation/wpe/WebAutomationSessionWPE.cpp
 | 
						||
 UIProcess/CoordinatedGraphics/DrawingAreaProxyCoordinatedGraphics.cpp
 | 
						||
 
 | 
						||
 UIProcess/geoclue/GeoclueGeolocationProvider.cpp
 | 
						||
-
 | 
						||
+UIProcess/glib/InspectorPlaywrightAgentClientGLib.cpp
 | 
						||
 UIProcess/glib/WebProcessPoolGLib.cpp
 | 
						||
 UIProcess/glib/WebProcessProxyGLib.cpp
 | 
						||
 UIProcess/glib/WebsiteDataStoreGLib.cpp @no-unify
 | 
						||
@@ -220,6 +221,10 @@ UIProcess/soup/WebProcessPoolSoup.cpp
 | 
						||
 
 | 
						||
 UIProcess/wpe/WebPageProxyWPE.cpp
 | 
						||
 
 | 
						||
+UIProcess/wpe/InspectorTargetProxyWPE.cpp
 | 
						||
+UIProcess/wpe/WebPageInspectorEmulationAgentWPE.cpp
 | 
						||
+UIProcess/wpe/WebPageInspectorInputAgentWPE.cpp
 | 
						||
+
 | 
						||
 WebProcess/InjectedBundle/API/glib/DOM/DOMObjectCache.cpp @no-unify
 | 
						||
 WebProcess/InjectedBundle/API/glib/DOM/WebKitDOMDocument.cpp @no-unify
 | 
						||
 WebProcess/InjectedBundle/API/glib/DOM/WebKitDOMElement.cpp @no-unify
 | 
						||
diff --git a/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.cpp b/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.cpp
 | 
						||
index 72ccef564d1854290de793921e1f092804a6bec6..2ae46d68a1c7454e02800e87ba7eade58713b9e1 100644
 | 
						||
--- a/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.cpp
 | 
						||
+++ b/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.cpp
 | 
						||
@@ -53,6 +53,9 @@ Ref<ProcessPoolConfiguration> ProcessPoolConfiguration::copy()
 | 
						||
     copy->m_ignoreSynchronousMessagingTimeoutsForTesting = this->m_ignoreSynchronousMessagingTimeoutsForTesting;
 | 
						||
     copy->m_attrStyleEnabled = this->m_attrStyleEnabled;
 | 
						||
     copy->m_overrideLanguages = this->m_overrideLanguages;
 | 
						||
+#if PLATFORM(MAC)
 | 
						||
+    copy->m_forceOverlayScrollbars = this->m_forceOverlayScrollbars;
 | 
						||
+#endif
 | 
						||
     copy->m_alwaysRunsAtBackgroundPriority = this->m_alwaysRunsAtBackgroundPriority;
 | 
						||
     copy->m_shouldTakeUIBackgroundAssertion = this->m_shouldTakeUIBackgroundAssertion;
 | 
						||
     copy->m_shouldCaptureDisplayInUIProcess = this->m_shouldCaptureDisplayInUIProcess;
 | 
						||
diff --git a/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.h b/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.h
 | 
						||
index 2a7e318e14f5cd4d136756ce31eb3a16f14055df..2657b4524eb49b76dc2c136837f2d2f5b2806434 100644
 | 
						||
--- a/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.h
 | 
						||
+++ b/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.h
 | 
						||
@@ -98,6 +98,11 @@ public:
 | 
						||
     const Vector<WTF::String>& overrideLanguages() const { return m_overrideLanguages; }
 | 
						||
     void setOverrideLanguages(Vector<WTF::String>&& languages) { m_overrideLanguages = WTFMove(languages); }
 | 
						||
     
 | 
						||
+#if PLATFORM(MAC)
 | 
						||
+    bool forceOverlayScrollbars() const { return m_forceOverlayScrollbars; }
 | 
						||
+    void setForceOverlayScrollbars(bool forceOverlayScrollbars) { m_forceOverlayScrollbars = forceOverlayScrollbars; }
 | 
						||
+#endif
 | 
						||
+
 | 
						||
     bool alwaysRunsAtBackgroundPriority() const { return m_alwaysRunsAtBackgroundPriority; }
 | 
						||
     void setAlwaysRunsAtBackgroundPriority(bool alwaysRunsAtBackgroundPriority) { m_alwaysRunsAtBackgroundPriority = alwaysRunsAtBackgroundPriority; }
 | 
						||
 
 | 
						||
@@ -141,6 +146,9 @@ private:
 | 
						||
     bool m_ignoreSynchronousMessagingTimeoutsForTesting { false };
 | 
						||
     bool m_attrStyleEnabled { false };
 | 
						||
     Vector<WTF::String> m_overrideLanguages;
 | 
						||
+#if PLATFORM(MAC)
 | 
						||
+    bool m_forceOverlayScrollbars { false };
 | 
						||
+#endif
 | 
						||
     bool m_alwaysRunsAtBackgroundPriority { false };
 | 
						||
     bool m_shouldTakeUIBackgroundAssertion { true };
 | 
						||
     bool m_shouldCaptureDisplayInUIProcess { DEFAULT_CAPTURE_DISPLAY_IN_UI_PROCESS };
 | 
						||
diff --git a/Source/WebKit/UIProcess/API/APIUIClient.h b/Source/WebKit/UIProcess/API/APIUIClient.h
 | 
						||
index 9066b62ac2e964220fbd6cdd68be8e973b99ddd6..06193f0b01207b30dd3c7c97db32bfeeda41f247 100644
 | 
						||
--- a/Source/WebKit/UIProcess/API/APIUIClient.h
 | 
						||
+++ b/Source/WebKit/UIProcess/API/APIUIClient.h
 | 
						||
@@ -97,6 +97,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/WKContext.cpp b/Source/WebKit/UIProcess/API/C/WKContext.cpp
 | 
						||
index 743cb854e28f51a0399d6fd1589e767fa3494f25..a6667051636cef88fb9dacc928cde16ba5215266 100644
 | 
						||
--- a/Source/WebKit/UIProcess/API/C/WKContext.cpp
 | 
						||
+++ b/Source/WebKit/UIProcess/API/C/WKContext.cpp
 | 
						||
@@ -436,6 +436,11 @@ WKWebsiteDataStoreRef WKContextGetWebsiteDataStore(WKContextRef)
 | 
						||
     return WKWebsiteDataStoreGetDefaultDataStore();
 | 
						||
 }
 | 
						||
 
 | 
						||
+void WKContextSetPrimaryDataStore(WKContextRef contextRef, WKWebsiteDataStoreRef dataStoreRef)
 | 
						||
+{
 | 
						||
+    WebKit::toImpl(contextRef)->setPrimaryDataStore(*WebKit::toImpl(dataStoreRef));
 | 
						||
+}
 | 
						||
+
 | 
						||
 WKApplicationCacheManagerRef WKContextGetApplicationCacheManager(WKContextRef context)
 | 
						||
 {
 | 
						||
     return reinterpret_cast<WKApplicationCacheManagerRef>(WKWebsiteDataStoreGetDefaultDataStore());
 | 
						||
diff --git a/Source/WebKit/UIProcess/API/C/WKContext.h b/Source/WebKit/UIProcess/API/C/WKContext.h
 | 
						||
index 08f54ff5057f8d04e26adfe2c0e3a472647935e7..8f3ae0f0346514cec926ea7babff40c22fd4097a 100644
 | 
						||
--- a/Source/WebKit/UIProcess/API/C/WKContext.h
 | 
						||
+++ b/Source/WebKit/UIProcess/API/C/WKContext.h
 | 
						||
@@ -168,6 +168,7 @@ WK_EXPORT void WKContextStartMemorySampler(WKContextRef context, WKDoubleRef int
 | 
						||
 WK_EXPORT void WKContextStopMemorySampler(WKContextRef context);
 | 
						||
 
 | 
						||
 WK_EXPORT WKWebsiteDataStoreRef WKContextGetWebsiteDataStore(WKContextRef context) WK_C_API_DEPRECATED_WITH_REPLACEMENT(WKWebsiteDataStoreGetDefaultDataStore);
 | 
						||
+WK_EXPORT void WKContextSetPrimaryDataStore(WKContextRef context, WKWebsiteDataStoreRef dataStore);
 | 
						||
 
 | 
						||
 WK_EXPORT WKApplicationCacheManagerRef WKContextGetApplicationCacheManager(WKContextRef context) WK_C_API_DEPRECATED_WITH_REPLACEMENT(WKWebsiteDataStoreGetDefaultDataStore);
 | 
						||
 WK_EXPORT WKCookieManagerRef WKContextGetCookieManager(WKContextRef context) WK_C_API_DEPRECATED;
 | 
						||
diff --git a/Source/WebKit/UIProcess/API/C/WKInspector.cpp b/Source/WebKit/UIProcess/API/C/WKInspector.cpp
 | 
						||
index 39327c5c9230591e4f52e4574c416e36687788f0..269dc87a6ab35481d2b45bea86fff893a9bddfb2 100644
 | 
						||
--- a/Source/WebKit/UIProcess/API/C/WKInspector.cpp
 | 
						||
+++ b/Source/WebKit/UIProcess/API/C/WKInspector.cpp
 | 
						||
@@ -28,6 +28,11 @@
 | 
						||
 
 | 
						||
 #if !PLATFORM(IOS_FAMILY)
 | 
						||
 
 | 
						||
+#if PLATFORM(WIN)
 | 
						||
+#include "BrowserInspectorPipe.h"
 | 
						||
+#include "InspectorPlaywrightAgentClientWin.h"
 | 
						||
+#endif
 | 
						||
+
 | 
						||
 #include "WKAPICast.h"
 | 
						||
 #include "WebInspectorProxy.h"
 | 
						||
 #include "WebPageProxy.h"
 | 
						||
@@ -130,4 +135,11 @@ void WKInspectorToggleElementSelection(WKInspectorRef inspectorRef)
 | 
						||
     toImpl(inspectorRef)->toggleElementSelection();
 | 
						||
 }
 | 
						||
 
 | 
						||
+void WKInspectorInitializeRemoteInspectorPipe(CreatePageCallback createPage, QuitCallback quit)
 | 
						||
+{
 | 
						||
+#if PLATFORM(WIN)
 | 
						||
+    initializeBrowserInspectorPipe(makeUnique<InspectorPlaywrightAgentClientWin>(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..1f707641766b51e3bddcdde0c49ee8cfcd83db0b 100644
 | 
						||
--- a/Source/WebKit/UIProcess/API/C/WKInspector.h
 | 
						||
+++ b/Source/WebKit/UIProcess/API/C/WKInspector.h
 | 
						||
@@ -66,6 +66,9 @@ WK_EXPORT void WKInspectorTogglePageProfiling(WKInspectorRef inspector);
 | 
						||
 WK_EXPORT bool WKInspectorIsElementSelectionActive(WKInspectorRef inspector);
 | 
						||
 WK_EXPORT void WKInspectorToggleElementSelection(WKInspectorRef inspector);
 | 
						||
 
 | 
						||
+typedef WKPageRef (*CreatePageCallback)(WKPageConfigurationRef configuration);
 | 
						||
+typedef void (*QuitCallback)();
 | 
						||
+WK_EXPORT void WKInspectorInitializeRemoteInspectorPipe(CreatePageCallback, QuitCallback);
 | 
						||
 #ifdef __cplusplus
 | 
						||
 }
 | 
						||
 #endif
 | 
						||
diff --git a/Source/WebKit/UIProcess/API/C/WKPage.cpp b/Source/WebKit/UIProcess/API/C/WKPage.cpp
 | 
						||
index 8432ce01af2c43154416f65f035352006c103527..19e9fb021793cc5aebe855d50c9be29c582e915c 100644
 | 
						||
--- a/Source/WebKit/UIProcess/API/C/WKPage.cpp
 | 
						||
+++ b/Source/WebKit/UIProcess/API/C/WKPage.cpp
 | 
						||
@@ -1678,6 +1678,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)
 | 
						||
@@ -1738,6 +1745,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 1d2febfba8833912f72216aa53c8c20090ee2d8b..1b2c3d84b15b12f1a187c0b7622db43cbbcd5996 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);
 | 
						||
@@ -1352,6 +1353,7 @@ typedef struct WKPageUIClientV14 {
 | 
						||
 
 | 
						||
     // Version 14.
 | 
						||
     WKPageRunWebAuthenticationPanelCallback                             runWebAuthenticationPanel;
 | 
						||
+    WKPageHandleJavaScriptDialogCallback                                handleJavaScriptDialog;
 | 
						||
 } WKPageUIClientV14;
 | 
						||
 
 | 
						||
 #ifdef __cplusplus
 | 
						||
diff --git a/Source/WebKit/UIProcess/API/Cocoa/WKProcessPool.mm b/Source/WebKit/UIProcess/API/Cocoa/WKProcessPool.mm
 | 
						||
index 032584571cb63dbe6b49a7953f6e8d6d7e83e375..766b1e0456a490eb60eeef01c8edd8577ab3fe1a 100644
 | 
						||
--- a/Source/WebKit/UIProcess/API/Cocoa/WKProcessPool.mm
 | 
						||
+++ b/Source/WebKit/UIProcess/API/Cocoa/WKProcessPool.mm
 | 
						||
@@ -47,6 +47,7 @@
 | 
						||
 #import "_WKDownloadDelegate.h"
 | 
						||
 #import "_WKDownloadInternal.h"
 | 
						||
 #import "_WKProcessPoolConfigurationInternal.h"
 | 
						||
+#import "_WKWebsiteDataStoreInternal.h"
 | 
						||
 #import <WebCore/CertificateInfo.h>
 | 
						||
 #import <WebCore/HTTPCookieAcceptPolicyCocoa.h>
 | 
						||
 #import <WebCore/PluginData.h>
 | 
						||
@@ -84,6 +85,18 @@ static WKProcessPool *sharedProcessPool;
 | 
						||
     return self;
 | 
						||
 }
 | 
						||
 
 | 
						||
+- (instancetype)_initWithConfiguration:(_WKProcessPoolConfiguration *)configuration AndDataStore:(WKWebsiteDataStore*)dataStore
 | 
						||
+{
 | 
						||
+    if (!(self = [super init]))
 | 
						||
+        return nil;
 | 
						||
+
 | 
						||
+    API::Object::constructInWrapper<WebKit::WebProcessPool>(self, *configuration->_processPoolConfiguration);
 | 
						||
+    _processPool->setPrimaryDataStore(*dataStore->_websiteDataStore);
 | 
						||
+
 | 
						||
+    return self;
 | 
						||
+}
 | 
						||
+
 | 
						||
+
 | 
						||
 - (instancetype)init
 | 
						||
 {
 | 
						||
     return [self _initWithConfiguration:adoptNS([[_WKProcessPoolConfiguration alloc] init]).get()];
 | 
						||
diff --git a/Source/WebKit/UIProcess/API/Cocoa/WKProcessPoolPrivate.h b/Source/WebKit/UIProcess/API/Cocoa/WKProcessPoolPrivate.h
 | 
						||
index cc0f99cf9b1fb80dfd023c2200c66d87d494d6c4..96713376932923a342d0c973216c96925d18dbf0 100644
 | 
						||
--- a/Source/WebKit/UIProcess/API/Cocoa/WKProcessPoolPrivate.h
 | 
						||
+++ b/Source/WebKit/UIProcess/API/Cocoa/WKProcessPoolPrivate.h
 | 
						||
@@ -37,6 +37,7 @@
 | 
						||
 
 | 
						||
 @interface WKProcessPool ()
 | 
						||
 - (instancetype)_initWithConfiguration:(_WKProcessPoolConfiguration *)configuration __attribute__((objc_method_family(init))) NS_DESIGNATED_INITIALIZER;
 | 
						||
+- (instancetype)_initWithConfiguration:(_WKProcessPoolConfiguration *)configuration AndDataStore:(WKWebsiteDataStore *)dataStore __attribute__((objc_method_family(init))) NS_DESIGNATED_INITIALIZER;
 | 
						||
 @end
 | 
						||
 
 | 
						||
 @interface WKProcessPool (WKPrivate)
 | 
						||
diff --git a/Source/WebKit/UIProcess/API/Cocoa/WKUIDelegate.h b/Source/WebKit/UIProcess/API/Cocoa/WKUIDelegate.h
 | 
						||
index cad87f3ef2ab93d93a74cec0c34b47c695de6bc6..66145a384638b97ee08516e56e1e86a83713c634 100644
 | 
						||
--- a/Source/WebKit/UIProcess/API/Cocoa/WKUIDelegate.h
 | 
						||
+++ b/Source/WebKit/UIProcess/API/Cocoa/WKUIDelegate.h
 | 
						||
@@ -123,6 +123,13 @@ NS_ASSUME_NONNULL_BEGIN
 | 
						||
  */
 | 
						||
 - (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable result))completionHandler;
 | 
						||
 
 | 
						||
+/*! @abstract Handle a JavaScript dialog.
 | 
						||
+ @param webView The web view invoking the delegate method.
 | 
						||
+ @param accept Whether to accept the dialog.
 | 
						||
+ @param value Value to use for prompt dialog.
 | 
						||
+ */
 | 
						||
+- (void)webView:(WKWebView *)webView handleJavaScriptDialog:(BOOL)accept value:(nullable NSString *)value;
 | 
						||
+
 | 
						||
 #if TARGET_OS_IPHONE
 | 
						||
 
 | 
						||
 /*! @abstract Allows your app to determine whether or not the given element should show a preview.
 | 
						||
diff --git a/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.h b/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.h
 | 
						||
index 726c4972aa0b32e0dc602e0ab2d71f6ae8ef93ae..c67f408797724cb6d68ed441c0ef1cccd33ca1e0 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
 | 
						||
@@ -78,6 +77,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 ed2e5ef682164ae5d52c4a3bfc3d2c8d5d58763a..d00941dda15e35c4b812583a0f3b00dc3123f0d9 100644
 | 
						||
--- a/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.mm
 | 
						||
+++ b/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.mm
 | 
						||
@@ -44,6 +44,7 @@
 | 
						||
 #import "_WKWebsiteDataStoreDelegate.h"
 | 
						||
 #import <WebCore/Credential.h>
 | 
						||
 #import <WebCore/RegistrationDatabase.h>
 | 
						||
+#import <pal/SessionID.h>
 | 
						||
 #import <wtf/BlockPtr.h>
 | 
						||
 #import <wtf/URL.h>
 | 
						||
 #import <wtf/WeakObjCPtr.h>
 | 
						||
@@ -184,6 +185,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..b64d1a6d54ec15a99164294706543cee626d1050
 | 
						||
--- /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;
 | 
						||
+- (void)deleteBrowserContext:(uint64_t)sessionID;
 | 
						||
+- (void)quit;
 | 
						||
+@end
 | 
						||
+
 | 
						||
+WK_CLASS_AVAILABLE(macos(10.14.0))
 | 
						||
+@interface _WKBrowserInspector : NSObject
 | 
						||
++ (void)initializeRemoteInspectorPipe:(id<_WKBrowserInspectorDelegate>)delegate headless:(BOOL)headless;
 | 
						||
+@end
 | 
						||
+
 | 
						||
+
 | 
						||
+NS_ASSUME_NONNULL_END
 | 
						||
+
 | 
						||
diff --git a/Source/WebKit/UIProcess/API/Cocoa/_WKBrowserInspector.mm b/Source/WebKit/UIProcess/API/Cocoa/_WKBrowserInspector.mm
 | 
						||
new file mode 100644
 | 
						||
index 0000000000000000000000000000000000000000..e7143513ea2be8e1cdab5c86a28643fffea626dd
 | 
						||
--- /dev/null
 | 
						||
+++ b/Source/WebKit/UIProcess/API/Cocoa/_WKBrowserInspector.mm
 | 
						||
@@ -0,0 +1,60 @@
 | 
						||
+/*
 | 
						||
+ * Copyright (C) 2019 Microsoft Corporation.
 | 
						||
+ *
 | 
						||
+ * Redistribution and use in source and binary forms, with or without
 | 
						||
+ * modification, are permitted provided that the following conditions
 | 
						||
+ * are met:
 | 
						||
+ * 1. Redistributions of source code must retain the above copyright
 | 
						||
+ *    notice, this list of conditions and the following disclaimer.
 | 
						||
+ * 2. Redistributions in binary form must reproduce the above copyright
 | 
						||
+ *    notice, this list of conditions and the following disclaimer in the
 | 
						||
+ *    documentation and/or other materials provided with the distribution.
 | 
						||
+ *
 | 
						||
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
						||
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
						||
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
						||
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | 
						||
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | 
						||
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
						||
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | 
						||
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | 
						||
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
						||
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
						||
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
						||
+ */
 | 
						||
+
 | 
						||
+#include "config.h"
 | 
						||
+#include "_WKBrowserInspector.h"
 | 
						||
+
 | 
						||
+#include "BrowserInspectorPipe.h"
 | 
						||
+#include "InspectorPlaywrightAgentClientMac.h"
 | 
						||
+#include "PageClientImplMac.h"
 | 
						||
+#include "WebKit2Initialize.h"
 | 
						||
+
 | 
						||
+#import "WKWebView.h"
 | 
						||
+
 | 
						||
+using namespace WebKit;
 | 
						||
+
 | 
						||
+@implementation _WKBrowserInspector
 | 
						||
+
 | 
						||
++ (void)initializeRemoteInspectorPipe:(id<_WKBrowserInspectorDelegate>)delegate headless:(BOOL)headless
 | 
						||
+{
 | 
						||
+#if ENABLE(REMOTE_INSPECTOR)
 | 
						||
+    InitializeWebKit2();
 | 
						||
+    PageClientImpl::setHeadless(headless);
 | 
						||
+    initializeBrowserInspectorPipe(makeUnique<InspectorPlaywrightAgentClientMac>(delegate));
 | 
						||
+#endif
 | 
						||
+}
 | 
						||
+
 | 
						||
+@end
 | 
						||
+
 | 
						||
+@implementation _WKBrowserContext
 | 
						||
+- (void)dealloc
 | 
						||
+{
 | 
						||
+    [_dataStore release];
 | 
						||
+    [_processPool release];
 | 
						||
+    _dataStore = nil;
 | 
						||
+    _processPool = nil;
 | 
						||
+    [super dealloc];
 | 
						||
+}
 | 
						||
+@end
 | 
						||
diff --git a/Source/WebKit/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.h b/Source/WebKit/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.h
 | 
						||
index 04922b10809ed4754279184a42169defa5f01ec8..a40edf790cded9f05943aa226db1e1e7e7211cb6 100644
 | 
						||
--- a/Source/WebKit/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.h
 | 
						||
+++ b/Source/WebKit/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.h
 | 
						||
@@ -62,6 +62,7 @@ WK_CLASS_AVAILABLE(macos(10.10), ios(8.0))
 | 
						||
 #endif
 | 
						||
 @property (nonatomic) pid_t presentingApplicationPID WK_API_AVAILABLE(macos(10.13), ios(11.0));
 | 
						||
 @property (nonatomic) BOOL processSwapsOnNavigation WK_API_AVAILABLE(macos(10.14), ios(12.0));
 | 
						||
+@property (nonatomic) BOOL forceOverlayScrollbars WK_API_AVAILABLE(macos(10.14));
 | 
						||
 @property (nonatomic) BOOL alwaysKeepAndReuseSwappedProcesses WK_API_AVAILABLE(macos(10.14), ios(12.0));
 | 
						||
 @property (nonatomic) BOOL processSwapsOnWindowOpenWithOpener WK_API_AVAILABLE(macos(10.14), ios(12.0));
 | 
						||
 @property (nonatomic) BOOL prewarmsProcessesAutomatically WK_API_AVAILABLE(macos(10.14.4), ios(12.2));
 | 
						||
diff --git a/Source/WebKit/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.mm b/Source/WebKit/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.mm
 | 
						||
index 18dae1c505a2d068740d559cf0ad31ea172c7c07..cb58f6df7a99867b149be670fcd76ba76a90be59 100644
 | 
						||
--- a/Source/WebKit/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.mm
 | 
						||
+++ b/Source/WebKit/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.mm
 | 
						||
@@ -261,6 +261,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 2bdb8b9e7256f22096ebaa5d51959aa52389ca0a..2141d9d17497861a6c711f99306de10992a93ce8 100644
 | 
						||
--- a/Source/WebKit/UIProcess/API/Cocoa/_WKRemoteWebInspectorViewController.mm
 | 
						||
+++ b/Source/WebKit/UIProcess/API/Cocoa/_WKRemoteWebInspectorViewController.mm
 | 
						||
@@ -25,6 +25,7 @@
 | 
						||
 
 | 
						||
 #import "config.h"
 | 
						||
 #import "_WKRemoteWebInspectorViewController.h"
 | 
						||
+#import "WKWebViewPrivate.h"
 | 
						||
 
 | 
						||
 #if PLATFORM(MAC)
 | 
						||
 
 | 
						||
diff --git a/Source/WebKit/UIProcess/API/glib/WebKitBrowserInspector.cpp b/Source/WebKit/UIProcess/API/glib/WebKitBrowserInspector.cpp
 | 
						||
new file mode 100644
 | 
						||
index 0000000000000000000000000000000000000000..1884526cd6ce7d436af6596ab3a45b103031dba1
 | 
						||
--- /dev/null
 | 
						||
+++ b/Source/WebKit/UIProcess/API/glib/WebKitBrowserInspector.cpp
 | 
						||
@@ -0,0 +1,136 @@
 | 
						||
+/*
 | 
						||
+ * 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,
 | 
						||
+
 | 
						||
+    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 signla 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);
 | 
						||
+}
 | 
						||
+
 | 
						||
+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);
 | 
						||
+}
 | 
						||
+
 | 
						||
+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(GMainLoop* mainLoop)
 | 
						||
+{
 | 
						||
+#if ENABLE(REMOTE_INSPECTOR)
 | 
						||
+    WebKit::initializeBrowserInspectorPipe(makeUnique<WebKit::InspectorPlaywrightAgentClientGlib>(mainLoop));
 | 
						||
+#endif
 | 
						||
+}
 | 
						||
diff --git a/Source/WebKit/UIProcess/API/glib/WebKitBrowserInspectorPrivate.h b/Source/WebKit/UIProcess/API/glib/WebKitBrowserInspectorPrivate.h
 | 
						||
new file mode 100644
 | 
						||
index 0000000000000000000000000000000000000000..1bff4e694f19264d1be418198b7921780e4f8309
 | 
						||
--- /dev/null
 | 
						||
+++ b/Source/WebKit/UIProcess/API/glib/WebKitBrowserInspectorPrivate.h
 | 
						||
@@ -0,0 +1,31 @@
 | 
						||
+/*
 | 
						||
+ * 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*);
 | 
						||
diff --git a/Source/WebKit/UIProcess/API/glib/WebKitUIClient.cpp b/Source/WebKit/UIProcess/API/glib/WebKitUIClient.cpp
 | 
						||
index ec20db91bf75ad3968fac93893f2f4bd3cd0ffae..8e82a209cd515a6290564bb9fdf3aa7049c44981 100644
 | 
						||
--- a/Source/WebKit/UIProcess/API/glib/WebKitUIClient.cpp
 | 
						||
+++ b/Source/WebKit/UIProcess/API/glib/WebKitUIClient.cpp
 | 
						||
@@ -64,7 +64,8 @@ private:
 | 
						||
     void createNewPage(WebPageProxy& page, WebCore::WindowFeatures&& windowFeatures, Ref<API::NavigationAction>&& apiNavigationAction, CompletionHandler<void(RefPtr<WebPageProxy>&&)>&& completionHandler) final
 | 
						||
     {
 | 
						||
         WebKitNavigationAction navigationAction(WTFMove(apiNavigationAction));
 | 
						||
-        completionHandler(webkitWebViewCreateNewPage(m_webView, windowFeatures, &navigationAction));
 | 
						||
+        WebPageProxy* newPage = webkitWebViewCreateNewPage(m_webView, windowFeatures, &navigationAction);
 | 
						||
+        completionHandler(adoptRef(newPage));
 | 
						||
     }
 | 
						||
 
 | 
						||
     void showPage(WebPageProxy*) final
 | 
						||
@@ -91,6 +92,10 @@ private:
 | 
						||
     {
 | 
						||
         webkitWebViewRunJavaScriptPrompt(m_webView, message.utf8(), defaultValue.utf8(), WTFMove(completionHandler));
 | 
						||
     }
 | 
						||
+    void handleJavaScriptDialog(WebPageProxy&, bool accept, const String& value) final
 | 
						||
+    {
 | 
						||
+        webkitWebViewHandleJavaScriptDialog(m_webView, accept, value);
 | 
						||
+    }
 | 
						||
 
 | 
						||
     bool canRunBeforeUnloadConfirmPanel() const final { return true; }
 | 
						||
 
 | 
						||
diff --git a/Source/WebKit/UIProcess/API/glib/WebKitWebContext.cpp b/Source/WebKit/UIProcess/API/glib/WebKitWebContext.cpp
 | 
						||
index 33a9b7d5ad060f275dcf7156a8cff3f37644e736..128a5c75807848de10aed628618fc7d149a42792 100644
 | 
						||
--- a/Source/WebKit/UIProcess/API/glib/WebKitWebContext.cpp
 | 
						||
+++ b/Source/WebKit/UIProcess/API/glib/WebKitWebContext.cpp
 | 
						||
@@ -119,9 +119,7 @@ enum {
 | 
						||
     PROP_LOCAL_STORAGE_DIRECTORY,
 | 
						||
 #endif
 | 
						||
     PROP_WEBSITE_DATA_MANAGER,
 | 
						||
-#if PLATFORM(GTK)
 | 
						||
     PROP_PSON_ENABLED
 | 
						||
-#endif
 | 
						||
 };
 | 
						||
 
 | 
						||
 enum {
 | 
						||
@@ -202,9 +200,7 @@ struct _WebKitWebContextPrivate {
 | 
						||
 
 | 
						||
     RefPtr<WebProcessPool> processPool;
 | 
						||
     bool clientsDetached;
 | 
						||
-#if PLATFORM(GTK)
 | 
						||
     bool psonEnabled;
 | 
						||
-#endif
 | 
						||
 
 | 
						||
     GRefPtr<WebKitFaviconDatabase> faviconDatabase;
 | 
						||
     GRefPtr<WebKitSecurityManager> securityManager;
 | 
						||
@@ -329,11 +325,9 @@ static void webkitWebContextGetProperty(GObject* object, guint propID, GValue* v
 | 
						||
     case PROP_WEBSITE_DATA_MANAGER:
 | 
						||
         g_value_set_object(value, webkit_web_context_get_website_data_manager(context));
 | 
						||
         break;
 | 
						||
-#if PLATFORM(GTK)
 | 
						||
     case PROP_PSON_ENABLED:
 | 
						||
         g_value_set_boolean(value, context->priv->psonEnabled);
 | 
						||
         break;
 | 
						||
-#endif
 | 
						||
     default:
 | 
						||
         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propID, paramSpec);
 | 
						||
     }
 | 
						||
@@ -354,11 +348,9 @@ static void webkitWebContextSetProperty(GObject* object, guint propID, const GVa
 | 
						||
         context->priv->websiteDataManager = manager ? WEBKIT_WEBSITE_DATA_MANAGER(manager) : nullptr;
 | 
						||
         break;
 | 
						||
     }
 | 
						||
-#if PLATFORM(GTK)
 | 
						||
     case PROP_PSON_ENABLED:
 | 
						||
         context->priv->psonEnabled = g_value_get_boolean(value);
 | 
						||
         break;
 | 
						||
-#endif
 | 
						||
     default:
 | 
						||
         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propID, paramSpec);
 | 
						||
     }
 | 
						||
@@ -375,9 +367,7 @@ static void webkitWebContextConstructed(GObject* object)
 | 
						||
 
 | 
						||
     API::ProcessPoolConfiguration configuration;
 | 
						||
     configuration.setInjectedBundlePath(FileSystem::stringFromFileSystemRepresentation(bundleFilename.get()));
 | 
						||
-#if PLATFORM(GTK)
 | 
						||
     configuration.setProcessSwapsOnNavigation(priv->psonEnabled);
 | 
						||
-#endif
 | 
						||
 
 | 
						||
     if (!priv->websiteDataManager)
 | 
						||
         priv->websiteDataManager = adoptGRef(webkit_website_data_manager_new("local-storage-directory", priv->localStorageDirectory.data(), nullptr));
 | 
						||
@@ -385,6 +375,11 @@ static void webkitWebContextConstructed(GObject* object)
 | 
						||
     if (!webkit_website_data_manager_is_ephemeral(priv->websiteDataManager.get()))
 | 
						||
         WebKit::LegacyGlobalSettings::singleton().setHSTSStorageDirectory(FileSystem::stringFromFileSystemRepresentation(webkit_website_data_manager_get_hsts_cache_directory(priv->websiteDataManager.get())));
 | 
						||
 
 | 
						||
+    const gchar *singleprocess = g_getenv("MINIBROWSER_SINGLEPROCESS");
 | 
						||
+    if (singleprocess && *singleprocess) {
 | 
						||
+        // processModel is not set at this point, force single process.
 | 
						||
+        configuration.setUsesSingleWebProcess(true);
 | 
						||
+    }
 | 
						||
     priv->processPool = WebProcessPool::create(configuration);
 | 
						||
     priv->processPool->setPrimaryDataStore(webkitWebsiteDataManagerGetDataStore(priv->websiteDataManager.get()));
 | 
						||
     priv->processPool->setUserMessageHandler([webContext](UserMessage&& message, CompletionHandler<void(UserMessage&&)>&& completionHandler) {
 | 
						||
@@ -496,7 +491,6 @@ static void webkit_web_context_class_init(WebKitWebContextClass* webContextClass
 | 
						||
             WEBKIT_TYPE_WEBSITE_DATA_MANAGER,
 | 
						||
             static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
 | 
						||
 
 | 
						||
-#if PLATFORM(GTK)
 | 
						||
     /**
 | 
						||
      * WebKitWebContext:process-swap-on-cross-site-navigation-enabled:
 | 
						||
      *
 | 
						||
@@ -519,7 +513,6 @@ static void webkit_web_context_class_init(WebKitWebContextClass* webContextClass
 | 
						||
             _("Whether swap Web processes on cross-site navigations is enabled"),
 | 
						||
             FALSE,
 | 
						||
             static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
 | 
						||
-#endif
 | 
						||
 
 | 
						||
     /**
 | 
						||
      * WebKitWebContext::download-started:
 | 
						||
diff --git a/Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp b/Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp
 | 
						||
index a4aa7c9d75345dc8053c010b01ecd7ff7330eea9..db2f436ad2fb9a90e5e6c0a96e76e726af71ac63 100644
 | 
						||
--- a/Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp
 | 
						||
+++ b/Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp
 | 
						||
@@ -131,6 +131,7 @@ enum {
 | 
						||
     CLOSE,
 | 
						||
 
 | 
						||
     SCRIPT_DIALOG,
 | 
						||
+    SCRIPT_DIALOG_HANDLED,
 | 
						||
 
 | 
						||
     DECIDE_POLICY,
 | 
						||
     PERMISSION_REQUEST,
 | 
						||
@@ -1536,6 +1537,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
 | 
						||
@@ -2417,6 +2427,20 @@ 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;
 | 
						||
+    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 5ab7574c9378f52db87ce75157627c04e9b2e962..5322d725238f5989c04b045615a2de8163329fdf 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 a68a30983f609d925b45ee16fbe34110b6cabe95..533f45fe6810509b8a0e1823087011a86510770a 100644
 | 
						||
--- a/Source/WebKit/UIProcess/API/gtk/PageClientImpl.cpp
 | 
						||
+++ b/Source/WebKit/UIProcess/API/gtk/PageClientImpl.cpp
 | 
						||
@@ -230,6 +230,8 @@ void PageClientImpl::doneWithKeyEvent(const NativeWebKeyboardEvent& event, bool
 | 
						||
 {
 | 
						||
     if (wasEventHandled)
 | 
						||
         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..a51cfebc270ca5a91cd94645eeeb005ba9a67caf
 | 
						||
--- /dev/null
 | 
						||
+++ b/Source/WebKit/UIProcess/API/gtk/WebKitBrowserInspector.h
 | 
						||
@@ -0,0 +1,79 @@
 | 
						||
+/*
 | 
						||
+ * 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);
 | 
						||
+
 | 
						||
+    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              (GMainLoop*);
 | 
						||
+
 | 
						||
+G_END_DECLS
 | 
						||
+
 | 
						||
+#endif
 | 
						||
diff --git a/Source/WebKit/UIProcess/API/gtk/webkit2.h b/Source/WebKit/UIProcess/API/gtk/webkit2.h
 | 
						||
index 930b17b6629e04d0dfa2222bbc3217877c6e1812..395462e5f01c195231e9296d1204167cded99ad3 100644
 | 
						||
--- a/Source/WebKit/UIProcess/API/gtk/webkit2.h
 | 
						||
+++ b/Source/WebKit/UIProcess/API/gtk/webkit2.h
 | 
						||
@@ -32,6 +32,7 @@
 | 
						||
 #include <webkit2/WebKitAutomationSession.h>
 | 
						||
 #include <webkit2/WebKitBackForwardList.h>
 | 
						||
 #include <webkit2/WebKitBackForwardListItem.h>
 | 
						||
+#include <webkit2/WebKitBrowserInspector.h>
 | 
						||
 #include <webkit2/WebKitContextMenu.h>
 | 
						||
 #include <webkit2/WebKitContextMenuActions.h>
 | 
						||
 #include <webkit2/WebKitContextMenuItem.h>
 | 
						||
diff --git a/Source/WebKit/UIProcess/API/wpe/WebKitBrowserInspector.h b/Source/WebKit/UIProcess/API/wpe/WebKitBrowserInspector.h
 | 
						||
new file mode 100644
 | 
						||
index 0000000000000000000000000000000000000000..6dffa4fa10a9a64f778a0a77c760c2e76b2f9968
 | 
						||
--- /dev/null
 | 
						||
+++ b/Source/WebKit/UIProcess/API/wpe/WebKitBrowserInspector.h
 | 
						||
@@ -0,0 +1,79 @@
 | 
						||
+/*
 | 
						||
+ * 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);
 | 
						||
+
 | 
						||
+    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              (GMainLoop*);
 | 
						||
+
 | 
						||
+G_END_DECLS
 | 
						||
+
 | 
						||
+#endif
 | 
						||
diff --git a/Source/WebKit/UIProcess/API/wpe/WebKitScriptDialogWPE.cpp b/Source/WebKit/UIProcess/API/wpe/WebKitScriptDialogWPE.cpp
 | 
						||
index 3ad6e613657557045ec07ce4bcdb3eea0d1e7dae..a53a4aa01bd692ba34bacb9f663c335cfd3821a7 100644
 | 
						||
--- a/Source/WebKit/UIProcess/API/wpe/WebKitScriptDialogWPE.cpp
 | 
						||
+++ b/Source/WebKit/UIProcess/API/wpe/WebKitScriptDialogWPE.cpp
 | 
						||
@@ -22,14 +22,26 @@
 | 
						||
 
 | 
						||
 #include "WebKitScriptDialogPrivate.h"
 | 
						||
 
 | 
						||
-void webkitScriptDialogAccept(WebKitScriptDialog*)
 | 
						||
+void webkitScriptDialogAccept(WebKitScriptDialog* dialog)
 | 
						||
 {
 | 
						||
+    if (!dialog->completionHandler)
 | 
						||
+        return;
 | 
						||
+    auto completionHandler = std::exchange(dialog->completionHandler, nullptr);
 | 
						||
+    completionHandler(true, String());
 | 
						||
 }
 | 
						||
 
 | 
						||
-void webkitScriptDialogDismiss(WebKitScriptDialog*)
 | 
						||
+void webkitScriptDialogDismiss(WebKitScriptDialog* dialog)
 | 
						||
 {
 | 
						||
+    if (!dialog->completionHandler)
 | 
						||
+        return;
 | 
						||
+    auto completionHandler = std::exchange(dialog->completionHandler, nullptr);
 | 
						||
+    completionHandler(false, String());
 | 
						||
 }
 | 
						||
 
 | 
						||
-void webkitScriptDialogSetUserInput(WebKitScriptDialog*, const String&)
 | 
						||
+void webkitScriptDialogSetUserInput(WebKitScriptDialog* dialog, const String& value)
 | 
						||
 {
 | 
						||
+    if (!dialog->completionHandler)
 | 
						||
+        return;
 | 
						||
+    auto completionHandler = std::exchange(dialog->completionHandler, nullptr);
 | 
						||
+    completionHandler(true, value);
 | 
						||
 }
 | 
						||
diff --git a/Source/WebKit/UIProcess/API/wpe/webkit.h b/Source/WebKit/UIProcess/API/wpe/webkit.h
 | 
						||
index 02e258253e47fbf6594c20f743d0faeac8a4eefe..e051fdf396dc65717def6b36168b5538e3cb2f4d 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/BrowserInspectorController.cpp b/Source/WebKit/UIProcess/BrowserInspectorController.cpp
 | 
						||
new file mode 100644
 | 
						||
index 0000000000000000000000000000000000000000..300be76e7926ac5eb435ab62df1a973f04520327
 | 
						||
--- /dev/null
 | 
						||
+++ b/Source/WebKit/UIProcess/BrowserInspectorController.cpp
 | 
						||
@@ -0,0 +1,244 @@
 | 
						||
+/*
 | 
						||
+ * 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 "BrowserInspectorController.h"
 | 
						||
+
 | 
						||
+#if ENABLE(REMOTE_INSPECTOR)
 | 
						||
+
 | 
						||
+#include "InspectorPlaywrightAgent.h"
 | 
						||
+#include "InspectorPlaywrightAgentClient.h"
 | 
						||
+#include "WebPageInspectorController.h"
 | 
						||
+#include "WebPageProxy.h"
 | 
						||
+#include "WebProcessPool.h"
 | 
						||
+#include "WebProcessProxy.h"
 | 
						||
+#include <JavaScriptCore/InspectorBackendDispatcher.h>
 | 
						||
+#include <JavaScriptCore/InspectorBackendDispatchers.h>
 | 
						||
+#include <JavaScriptCore/InspectorFrontendChannel.h>
 | 
						||
+#include <JavaScriptCore/InspectorFrontendRouter.h>
 | 
						||
+#include <JavaScriptCore/InspectorTarget.h>
 | 
						||
+#include <WebCore/WindowFeatures.h>
 | 
						||
+#include <wtf/Ref.h>
 | 
						||
+#include <wtf/RefPtr.h>
 | 
						||
+
 | 
						||
+using namespace Inspector;
 | 
						||
+
 | 
						||
+namespace WebKit {
 | 
						||
+
 | 
						||
+static Vector<WebPageProxy*> allPages()
 | 
						||
+{
 | 
						||
+    ASSERT(isMainThread());
 | 
						||
+    Vector<WebPageProxy*> result;
 | 
						||
+    for (WebProcessPool* pool : WebProcessPool::allProcessPools()) {
 | 
						||
+        for (auto& process : pool->processes()) {
 | 
						||
+            result.appendRange(process->pages().begin(), process->pages().end());
 | 
						||
+        }
 | 
						||
+    }
 | 
						||
+    return result;
 | 
						||
+}
 | 
						||
+
 | 
						||
+class BrowserInspectorController::PageProxyChannel : public FrontendChannel {
 | 
						||
+    WTF_MAKE_FAST_ALLOCATED;
 | 
						||
+public:
 | 
						||
+    PageProxyChannel(FrontendChannel& frontendChannel, String pageProxyID, WebPageProxy& page)
 | 
						||
+        : 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;
 | 
						||
+        if (!JSON::Value::parseJSON(message, parsedMessage))
 | 
						||
+            return message;
 | 
						||
+
 | 
						||
+        RefPtr<JSON::Object> messageObject;
 | 
						||
+        if (!parsedMessage->asObject(messageObject))
 | 
						||
+            return message;
 | 
						||
+
 | 
						||
+        messageObject->setString("pageProxyId"_s, m_pageProxyID);
 | 
						||
+        return messageObject->toJSONString();
 | 
						||
+    }
 | 
						||
+
 | 
						||
+    String m_pageProxyID;
 | 
						||
+    FrontendChannel& m_frontendChannel;
 | 
						||
+    WebPageProxy& m_page;
 | 
						||
+};
 | 
						||
+
 | 
						||
+BrowserInspectorController::BrowserInspectorController(std::unique_ptr<InspectorPlaywrightAgentClient> client)
 | 
						||
+    : m_frontendChannel(nullptr)
 | 
						||
+    , m_frontendRouter(FrontendRouter::create())
 | 
						||
+    , m_backendDispatcher(BackendDispatcher::create(m_frontendRouter.copyRef()))
 | 
						||
+    , m_browserAgentClient(std::move(client))
 | 
						||
+{
 | 
						||
+    PageProxyIDMap* map = this;
 | 
						||
+    auto browserAgent = makeUnique<InspectorPlaywrightAgent>(m_frontendRouter, m_backendDispatcher, m_browserAgentClient.get(), *map);
 | 
						||
+    m_browserAgent = browserAgent.get();
 | 
						||
+    m_agents.append(WTFMove(browserAgent));
 | 
						||
+}
 | 
						||
+
 | 
						||
+BrowserInspectorController::~BrowserInspectorController()
 | 
						||
+{
 | 
						||
+    if (m_frontendChannel)
 | 
						||
+        disconnectFrontend();
 | 
						||
+}
 | 
						||
+
 | 
						||
+void BrowserInspectorController::connectFrontend(FrontendChannel& frontendChannel)
 | 
						||
+{
 | 
						||
+    ASSERT(!m_frontendChannel);
 | 
						||
+    m_frontendChannel = &frontendChannel;
 | 
						||
+    WebPageInspectorController::setObserver(this);
 | 
						||
+
 | 
						||
+    bool connectingFirstFrontend = !m_frontendRouter->hasFrontends();
 | 
						||
+    m_frontendRouter->connectFrontend(frontendChannel);
 | 
						||
+    if (connectingFirstFrontend)
 | 
						||
+        m_agents.didCreateFrontendAndBackend(&m_frontendRouter.get(), &m_backendDispatcher.get());
 | 
						||
+
 | 
						||
+    connectToAllPages();
 | 
						||
+}
 | 
						||
+
 | 
						||
+void BrowserInspectorController::disconnectFrontend()
 | 
						||
+{
 | 
						||
+    ASSERT(m_frontendChannel);
 | 
						||
+    disconnectFromAllPages();
 | 
						||
+
 | 
						||
+    m_frontendRouter->disconnectFrontend(*m_frontendChannel);
 | 
						||
+    if (!m_frontendRouter->hasFrontends())
 | 
						||
+        m_agents.willDestroyFrontendAndBackend(DisconnectReason::InspectorDestroyed);
 | 
						||
+
 | 
						||
+    WebPageInspectorController::setObserver(nullptr);
 | 
						||
+    m_frontendChannel = nullptr;
 | 
						||
+}
 | 
						||
+
 | 
						||
+void BrowserInspectorController::dispatchMessageFromFrontend(const String& message)
 | 
						||
+{
 | 
						||
+    m_backendDispatcher->dispatch(message, BackendDispatcher::Mode::FailIfDomainIsMissing, [&](const RefPtr<JSON::Object>& messageObject) {
 | 
						||
+        RefPtr<JSON::Value> pageProxyIDValue;
 | 
						||
+        if (!messageObject->getValue("pageProxyId"_s, pageProxyIDValue))
 | 
						||
+            return BackendDispatcher::DispatchResult::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::DispatchResult::Finished;
 | 
						||
+        }
 | 
						||
+
 | 
						||
+
 | 
						||
+        if (auto pageProxyChannel = m_pageProxyChannels.get(pageProxyID)) {
 | 
						||
+            pageProxyChannel->dispatchMessageFromFrontend(message);
 | 
						||
+            return BackendDispatcher::DispatchResult::Finished;
 | 
						||
+        }
 | 
						||
+
 | 
						||
+        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidRequest, "Cannot find page proxy with provided 'pageProxyId'"_s);
 | 
						||
+        m_backendDispatcher->sendPendingErrors();
 | 
						||
+        return BackendDispatcher::DispatchResult::Finished;
 | 
						||
+    });
 | 
						||
+}
 | 
						||
+
 | 
						||
+void BrowserInspectorController::connectToAllPages()
 | 
						||
+{
 | 
						||
+    for (auto* page : allPages())
 | 
						||
+        connectToPage(*page);
 | 
						||
+}
 | 
						||
+
 | 
						||
+void BrowserInspectorController::disconnectFromAllPages()
 | 
						||
+{
 | 
						||
+    for (auto it = m_pageProxyChannels.begin(); it != m_pageProxyChannels.end(); ++it)
 | 
						||
+        it->value->disconnect();
 | 
						||
+    m_pageProxyChannels.clear();
 | 
						||
+}
 | 
						||
+
 | 
						||
+void BrowserInspectorController::connectToPage(WebPageProxy& page)
 | 
						||
+{
 | 
						||
+    String pageProxyID = InspectorPlaywrightAgent::toPageProxyIDProtocolString(page);
 | 
						||
+    auto pageProxyChannel = makeUnique<PageProxyChannel>(*m_frontendChannel, pageProxyID, page);
 | 
						||
+    page.inspectorController().connectFrontend(*pageProxyChannel);
 | 
						||
+    // Always pause new targets if controlled remotely.
 | 
						||
+    page.inspectorController().setPauseOnStart(true);
 | 
						||
+    m_pageProxyChannels.set(pageProxyID, WTFMove(pageProxyChannel));
 | 
						||
+}
 | 
						||
+
 | 
						||
+void BrowserInspectorController::didCreateInspectorController(WebPageProxy& page)
 | 
						||
+{
 | 
						||
+    ASSERT(m_frontendChannel);
 | 
						||
+    // Auto-connect to all new pages.
 | 
						||
+    connectToPage(page);
 | 
						||
+    m_browserAgent->didCreateWebPageProxy(page);
 | 
						||
+}
 | 
						||
+
 | 
						||
+void BrowserInspectorController::willDestroyInspectorController(WebPageProxy& page)
 | 
						||
+{
 | 
						||
+    m_browserAgent->willDestroyWebPageProxy(page);
 | 
						||
+
 | 
						||
+    String pageProxyID = InspectorPlaywrightAgent::toPageProxyIDProtocolString(page);
 | 
						||
+    auto it = m_pageProxyChannels.find(pageProxyID);
 | 
						||
+    ASSERT(it != m_pageProxyChannels.end());
 | 
						||
+    it->value->disconnect();
 | 
						||
+    m_pageProxyChannels.remove(it);
 | 
						||
+}
 | 
						||
+
 | 
						||
+void BrowserInspectorController::didFailProvisionalLoad(WebPageProxy& page, uint64_t navigationID, const String& error)
 | 
						||
+{
 | 
						||
+    m_browserAgent->didFailProvisionalLoad(page, navigationID, error);
 | 
						||
+}
 | 
						||
+
 | 
						||
+void BrowserInspectorController::willCreateNewPage(WebPageProxy& page, const WebCore::WindowFeatures& features, const URL& url)
 | 
						||
+{
 | 
						||
+    m_browserAgent->willCreateNewPage(page, features, url);
 | 
						||
+}
 | 
						||
+
 | 
						||
+WebPageProxy* BrowserInspectorController::findPageProxy(const String& pageProxyID)
 | 
						||
+{
 | 
						||
+    if (auto* pageProxyChannel = m_pageProxyChannels.get(pageProxyID))
 | 
						||
+        return &pageProxyChannel->page();
 | 
						||
+
 | 
						||
+    return nullptr;
 | 
						||
+}
 | 
						||
+
 | 
						||
+} // namespace WebKit
 | 
						||
+
 | 
						||
+#endif // ENABLE(REMOTE_INSPECTOR)
 | 
						||
diff --git a/Source/WebKit/UIProcess/BrowserInspectorController.h b/Source/WebKit/UIProcess/BrowserInspectorController.h
 | 
						||
new file mode 100644
 | 
						||
index 0000000000000000000000000000000000000000..b8e7b1c9f301c99baf62dc52ad4591b0376f00b3
 | 
						||
--- /dev/null
 | 
						||
+++ b/Source/WebKit/UIProcess/BrowserInspectorController.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
 | 
						||
+
 | 
						||
+#if ENABLE(REMOTE_INSPECTOR)
 | 
						||
+
 | 
						||
+#include "InspectorPlaywrightAgent.h"
 | 
						||
+#include "WebPageInspectorController.h"
 | 
						||
+#include <JavaScriptCore/InspectorAgentRegistry.h>
 | 
						||
+#include <wtf/Forward.h>
 | 
						||
+#include <wtf/Noncopyable.h>
 | 
						||
+
 | 
						||
+namespace Inspector {
 | 
						||
+class BackendDispatcher;
 | 
						||
+class FrontendChannel;
 | 
						||
+class FrontendRouter;
 | 
						||
+}
 | 
						||
+
 | 
						||
+namespace WebKit {
 | 
						||
+
 | 
						||
+class InspectorPlaywrightAgent;
 | 
						||
+class InspectorPlaywrightAgentClient;
 | 
						||
+
 | 
						||
+class BrowserInspectorController : private WebPageInspectorControllerObserver, private PageProxyIDMap {
 | 
						||
+    WTF_MAKE_NONCOPYABLE(BrowserInspectorController);
 | 
						||
+    WTF_MAKE_FAST_ALLOCATED;
 | 
						||
+public:
 | 
						||
+    BrowserInspectorController(std::unique_ptr<InspectorPlaywrightAgentClient> client);
 | 
						||
+    ~BrowserInspectorController();
 | 
						||
+
 | 
						||
+    void connectFrontend(Inspector::FrontendChannel&);
 | 
						||
+    void disconnectFrontend();
 | 
						||
+    void dispatchMessageFromFrontend(const String& message);
 | 
						||
+
 | 
						||
+private:
 | 
						||
+    class TargetHandler;
 | 
						||
+    class PageProxyChannel;
 | 
						||
+
 | 
						||
+    // 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;
 | 
						||
+
 | 
						||
+    // PageProxyIDMap
 | 
						||
+    WebPageProxy* findPageProxy(const String& pageProxyID) override;
 | 
						||
+
 | 
						||
+    void connectToAllPages();
 | 
						||
+    void disconnectFromAllPages();
 | 
						||
+    void connectToPage(WebPageProxy&);
 | 
						||
+
 | 
						||
+    Inspector::FrontendChannel* m_frontendChannel { nullptr };
 | 
						||
+    Ref<Inspector::FrontendRouter> m_frontendRouter;
 | 
						||
+    Ref<Inspector::BackendDispatcher> m_backendDispatcher;
 | 
						||
+    std::unique_ptr<InspectorPlaywrightAgentClient> m_browserAgentClient;
 | 
						||
+    Inspector::AgentRegistry m_agents;
 | 
						||
+    InspectorPlaywrightAgent* m_browserAgent { nullptr };
 | 
						||
+    HashMap<String, std::unique_ptr<PageProxyChannel>> m_pageProxyChannels;
 | 
						||
+};
 | 
						||
+
 | 
						||
+} // namespace WebKit
 | 
						||
+
 | 
						||
+#endif // ENABLE(REMOTE_INSPECTOR)
 | 
						||
diff --git a/Source/WebKit/UIProcess/BrowserInspectorPipe.cpp b/Source/WebKit/UIProcess/BrowserInspectorPipe.cpp
 | 
						||
new file mode 100644
 | 
						||
index 0000000000000000000000000000000000000000..e07123453ecab2611ff4918cec37ee6e744a23a6
 | 
						||
--- /dev/null
 | 
						||
+++ b/Source/WebKit/UIProcess/BrowserInspectorPipe.cpp
 | 
						||
@@ -0,0 +1,57 @@
 | 
						||
+/*
 | 
						||
+ * Copyright (C) 2019 Microsoft Corporation.
 | 
						||
+ *
 | 
						||
+ * Redistribution and use in source and binary forms, with or without
 | 
						||
+ * modification, are permitted provided that the following conditions
 | 
						||
+ * are met:
 | 
						||
+ * 1. Redistributions of source code must retain the above copyright
 | 
						||
+ *    notice, this list of conditions and the following disclaimer.
 | 
						||
+ * 2. Redistributions in binary form must reproduce the above copyright
 | 
						||
+ *    notice, this list of conditions and the following disclaimer in the
 | 
						||
+ *    documentation and/or other materials provided with the distribution.
 | 
						||
+ *
 | 
						||
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
						||
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
						||
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
						||
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | 
						||
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | 
						||
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
						||
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | 
						||
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | 
						||
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
						||
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
						||
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
						||
+ */
 | 
						||
+
 | 
						||
+#include "config.h"
 | 
						||
+#include "BrowserInspectorPipe.h"
 | 
						||
+
 | 
						||
+#if ENABLE(REMOTE_INSPECTOR)
 | 
						||
+
 | 
						||
+#include "BrowserInspectorController.h"
 | 
						||
+#include "RemoteInspectorPipe.h"
 | 
						||
+#include <wtf/NeverDestroyed.h>
 | 
						||
+#include "InspectorPlaywrightAgentClient.h"
 | 
						||
+
 | 
						||
+namespace WebKit {
 | 
						||
+
 | 
						||
+void initializeBrowserInspectorPipe(std::unique_ptr<InspectorPlaywrightAgentClient> client)
 | 
						||
+{
 | 
						||
+    class BrowserInspectorPipe {
 | 
						||
+    public:
 | 
						||
+        BrowserInspectorPipe(std::unique_ptr<InspectorPlaywrightAgentClient> client)
 | 
						||
+            : m_browserInspectorController(std::move(client))
 | 
						||
+            , m_remoteInspectorPipe(m_browserInspectorController)
 | 
						||
+        {
 | 
						||
+        }
 | 
						||
+
 | 
						||
+        BrowserInspectorController m_browserInspectorController;
 | 
						||
+        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/PageClientImplCocoa.mm b/Source/WebKit/UIProcess/Cocoa/PageClientImplCocoa.mm
 | 
						||
index 40949c2f409cd42dca616c29649852ff222f2af5..b56ff05f55263e00bdccfda75249a767e965fe82 100644
 | 
						||
--- a/Source/WebKit/UIProcess/Cocoa/PageClientImplCocoa.mm
 | 
						||
+++ b/Source/WebKit/UIProcess/Cocoa/PageClientImplCocoa.mm
 | 
						||
@@ -40,7 +40,7 @@ namespace WebKit {
 | 
						||
 PageClientImplCocoa::PageClientImplCocoa(WKWebView *webView)
 | 
						||
     : m_webView { webView }
 | 
						||
 #if USE(DICTATION_ALTERNATIVES)
 | 
						||
-    , m_alternativeTextUIController { makeUnique<AlternativeTextUIController>() }
 | 
						||
+    , m_alternativeTextUIController { makeUnique<WebCore::AlternativeTextUIController>() }
 | 
						||
 #endif
 | 
						||
 {
 | 
						||
 }
 | 
						||
diff --git a/Source/WebKit/UIProcess/Cocoa/SOAuthorization/PopUpSOAuthorizationSession.h b/Source/WebKit/UIProcess/Cocoa/SOAuthorization/PopUpSOAuthorizationSession.h
 | 
						||
index 454c61ffdefecc476d1560c7c43f5b5d345f281d..6de7509037b7683ddd403ee247bdf2845ce4e87a 100644
 | 
						||
--- a/Source/WebKit/UIProcess/Cocoa/SOAuthorization/PopUpSOAuthorizationSession.h
 | 
						||
+++ b/Source/WebKit/UIProcess/Cocoa/SOAuthorization/PopUpSOAuthorizationSession.h
 | 
						||
@@ -27,6 +27,8 @@
 | 
						||
 
 | 
						||
 #if HAVE(APP_SSO)
 | 
						||
 
 | 
						||
+#include <wtf/Forward.h>
 | 
						||
+#include <wtf/CompletionHandler.h>
 | 
						||
 #include "SOAuthorizationSession.h"
 | 
						||
 #include <wtf/CompletionHandler.h>
 | 
						||
 
 | 
						||
@@ -39,6 +41,8 @@ class NavigationAction;
 | 
						||
 
 | 
						||
 namespace WebKit {
 | 
						||
 
 | 
						||
+class WebPageProxy;
 | 
						||
+
 | 
						||
 // FSM: Idle => Active => Completed
 | 
						||
 class PopUpSOAuthorizationSession final : public SOAuthorizationSession {
 | 
						||
 public:
 | 
						||
diff --git a/Source/WebKit/UIProcess/Cocoa/SOAuthorization/PopUpSOAuthorizationSession.mm b/Source/WebKit/UIProcess/Cocoa/SOAuthorization/PopUpSOAuthorizationSession.mm
 | 
						||
index 0f18038de989e69a8432c85b71b6c04e931302b3..82a966779403346aed174dcfcd01a79691956d7b 100644
 | 
						||
--- a/Source/WebKit/UIProcess/Cocoa/SOAuthorization/PopUpSOAuthorizationSession.mm
 | 
						||
+++ b/Source/WebKit/UIProcess/Cocoa/SOAuthorization/PopUpSOAuthorizationSession.mm
 | 
						||
@@ -29,6 +29,7 @@
 | 
						||
 #if HAVE(APP_SSO)
 | 
						||
 
 | 
						||
 #import "APINavigationAction.h"
 | 
						||
+#import "WebPageProxy.h"
 | 
						||
 #import "WKNavigationDelegatePrivate.h"
 | 
						||
 #import "WKUIDelegate.h"
 | 
						||
 #import "WKWebViewConfigurationPrivate.h"
 | 
						||
diff --git a/Source/WebKit/UIProcess/Cocoa/UIDelegate.h b/Source/WebKit/UIProcess/Cocoa/UIDelegate.h
 | 
						||
index ecf6a5c2dce317eb58f77f33f57010fdabdf87ed..c6a1125dc1b8c06fe752ec5ca86239dfeac3c3d6 100644
 | 
						||
--- a/Source/WebKit/UIProcess/Cocoa/UIDelegate.h
 | 
						||
+++ b/Source/WebKit/UIProcess/Cocoa/UIDelegate.h
 | 
						||
@@ -91,6 +91,7 @@ private:
 | 
						||
         void runJavaScriptAlert(WebPageProxy&, const WTF::String&, WebFrameProxy*, FrameInfoData&&, Function<void()>&& completionHandler) final;
 | 
						||
         void runJavaScriptConfirm(WebPageProxy&, const WTF::String&, WebFrameProxy*, FrameInfoData&&, Function<void(bool)>&& completionHandler) final;
 | 
						||
         void runJavaScriptPrompt(WebPageProxy&, const WTF::String&, const WTF::String&, WebFrameProxy*, FrameInfoData&&, Function<void(const WTF::String&)>&&) final;
 | 
						||
+        void handleJavaScriptDialog(WebKit::WebPageProxy&, bool accept, const WTF::String&) final;
 | 
						||
         void presentStorageAccessConfirmDialog(const WTF::String& requestingDomain, const WTF::String& currentDomain, CompletionHandler<void(bool)>&&);
 | 
						||
         void requestStorageAccessConfirm(WebPageProxy&, WebFrameProxy*, const WebCore::RegistrableDomain& requestingDomain, const WebCore::RegistrableDomain& currentDomain, CompletionHandler<void(bool)>&&) final;
 | 
						||
         void decidePolicyForGeolocationPermissionRequest(WebPageProxy&, WebFrameProxy&, const FrameInfoData&, Function<void(bool)>&) final;
 | 
						||
@@ -170,6 +171,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 c562fac4fb66635b63e51f6a43a4879c357f4f73..931be3735d0f46c19afd1024ab6ee0400055c09d 100644
 | 
						||
--- a/Source/WebKit/UIProcess/Cocoa/UIDelegate.mm
 | 
						||
+++ b/Source/WebKit/UIProcess/Cocoa/UIDelegate.mm
 | 
						||
@@ -102,6 +102,7 @@ void UIDelegate::setDelegate(id <WKUIDelegate> delegate)
 | 
						||
     m_delegateMethods.webViewRunJavaScriptAlertPanelWithMessageInitiatedByFrameCompletionHandler = [delegate respondsToSelector:@selector(webView:runJavaScriptAlertPanelWithMessage:initiatedByFrame:completionHandler:)];
 | 
						||
     m_delegateMethods.webViewRunJavaScriptConfirmPanelWithMessageInitiatedByFrameCompletionHandler = [delegate respondsToSelector:@selector(webView:runJavaScriptConfirmPanelWithMessage:initiatedByFrame:completionHandler:)];
 | 
						||
     m_delegateMethods.webViewRunJavaScriptTextInputPanelWithPromptDefaultTextInitiatedByFrameCompletionHandler = [delegate respondsToSelector:@selector(webView:runJavaScriptTextInputPanelWithPrompt:defaultText:initiatedByFrame:completionHandler:)];
 | 
						||
+    m_delegateMethods.webViewHandleJavaScriptDialogValue = [delegate respondsToSelector:@selector(webView:handleJavaScriptDialog:value:)];
 | 
						||
     m_delegateMethods.webViewRequestStorageAccessPanelUnderFirstPartyCompletionHandler = [delegate respondsToSelector:@selector(_webView:requestStorageAccessPanelForDomain:underCurrentDomain:completionHandler:)];
 | 
						||
     m_delegateMethods.webViewRunBeforeUnloadConfirmPanelWithMessageInitiatedByFrameCompletionHandler = [delegate respondsToSelector:@selector(_webView:runBeforeUnloadConfirmPanelWithMessage:initiatedByFrame:completionHandler:)];
 | 
						||
     m_delegateMethods.webViewRequestGeolocationPermissionForFrameDecisionHandler = [delegate respondsToSelector:@selector(_webView:requestGeolocationPermissionForFrame:decisionHandler:)];
 | 
						||
@@ -338,6 +339,15 @@ void UIDelegate::UIClient::runJavaScriptPrompt(WebPageProxy& page, const WTF::St
 | 
						||
     }).get()];
 | 
						||
 }
 | 
						||
 
 | 
						||
+void UIDelegate::UIClient::handleJavaScriptDialog(WebKit::WebPageProxy&, bool accept, const WTF::String& value) {
 | 
						||
+    if (!m_uiDelegate.m_delegateMethods.webViewHandleJavaScriptDialogValue)
 | 
						||
+        return;
 | 
						||
+    auto delegate = m_uiDelegate.m_delegate.get();
 | 
						||
+    if (!delegate)
 | 
						||
+        return;
 | 
						||
+    [delegate webView:m_uiDelegate.m_webView handleJavaScriptDialog:accept value:value];
 | 
						||
+}
 | 
						||
+
 | 
						||
 void UIDelegate::UIClient::requestStorageAccessConfirm(WebPageProxy&, WebFrameProxy*, const WebCore::RegistrableDomain& requestingDomain, const WebCore::RegistrableDomain& currentDomain, CompletionHandler<void(bool)>&& completionHandler)
 | 
						||
 {
 | 
						||
     auto delegate = m_uiDelegate.m_delegate.get();
 | 
						||
diff --git a/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm b/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm
 | 
						||
index e8baa21f6b46266fc7a39b150037f377a3107e9d..cbb9f97e9c774a51f66436459dd4dfe5d558fffb 100644
 | 
						||
--- a/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm
 | 
						||
+++ b/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm
 | 
						||
@@ -138,6 +138,13 @@ static void registerUserDefaultsIfNeeded()
 | 
						||
     [[NSUserDefaults standardUserDefaults] registerDefaults:registrationDictionary];
 | 
						||
 }
 | 
						||
 
 | 
						||
+void WebProcessPool::setIgnoreTLSErrors(bool ignoreTLSErrors)
 | 
						||
+{
 | 
						||
+    m_ignoreTLSErrors = ignoreTLSErrors;
 | 
						||
+    if (m_networkProcess)
 | 
						||
+        m_networkProcess->send(Messages::NetworkProcess::SetIgnoreTLSErrors(m_ignoreTLSErrors), 0);
 | 
						||
+}
 | 
						||
+
 | 
						||
 void WebProcessPool::updateProcessSuppressionState()
 | 
						||
 {
 | 
						||
     if (m_networkProcess)
 | 
						||
@@ -365,7 +372,7 @@ void WebProcessPool::platformInitializeWebProcess(const WebProcessProxy& process
 | 
						||
 #if PLATFORM(MAC)
 | 
						||
     auto screenProperties = WebCore::collectScreenProperties();
 | 
						||
     parameters.screenProperties = WTFMove(screenProperties);
 | 
						||
-    parameters.useOverlayScrollbars = ([NSScroller preferredScrollerStyle] == NSScrollerStyleOverlay);
 | 
						||
+    parameters.useOverlayScrollbars = m_configuration->forceOverlayScrollbars() || ([NSScroller preferredScrollerStyle] == NSScrollerStyleOverlay);
 | 
						||
 #endif
 | 
						||
     
 | 
						||
 #if PLATFORM(IOS)
 | 
						||
@@ -482,6 +489,8 @@ void WebProcessPool::platformInitializeNetworkProcess(NetworkProcessCreationPara
 | 
						||
         }
 | 
						||
     }
 | 
						||
 
 | 
						||
+    parameters.ignoreTLSErrors = m_ignoreTLSErrors;
 | 
						||
+
 | 
						||
     parameters.networkATSContext = adoptCF(_CFNetworkCopyATSContext());
 | 
						||
 
 | 
						||
     parameters.shouldSuppressMemoryPressureHandler = [defaults boolForKey:WebKitSuppressMemoryPressureHandlerDefaultsKey];
 | 
						||
@@ -642,8 +651,8 @@ void WebProcessPool::registerNotificationObservers()
 | 
						||
 
 | 
						||
 #if ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
 | 
						||
     m_scrollerStyleNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:NSPreferredScrollerStyleDidChangeNotification object:nil queue:[NSOperationQueue currentQueue] usingBlock:^(NSNotification *notification) {
 | 
						||
-        auto scrollbarStyle = [NSScroller preferredScrollerStyle];
 | 
						||
-        sendToAllProcesses(Messages::WebProcess::ScrollerStylePreferenceChanged(scrollbarStyle));
 | 
						||
+        bool useOverlayScrollbars = m_configuration->forceOverlayScrollbars() || ([NSScroller preferredScrollerStyle] == NSScrollerStyleOverlay);
 | 
						||
+        sendToAllProcesses(Messages::WebProcess::ScrollerStylePreferenceChanged(useOverlayScrollbars));
 | 
						||
     }];
 | 
						||
 #endif
 | 
						||
 
 | 
						||
diff --git a/Source/WebKit/UIProcess/CoordinatedGraphics/DrawingAreaProxyCoordinatedGraphics.cpp b/Source/WebKit/UIProcess/CoordinatedGraphics/DrawingAreaProxyCoordinatedGraphics.cpp
 | 
						||
index 6bbd1cabd27ae2847648a8c2edcf9acfcd556ff5..38d101b9a96986e40f6e9f0261fa429a3d516e2e 100644
 | 
						||
--- a/Source/WebKit/UIProcess/CoordinatedGraphics/DrawingAreaProxyCoordinatedGraphics.cpp
 | 
						||
+++ b/Source/WebKit/UIProcess/CoordinatedGraphics/DrawingAreaProxyCoordinatedGraphics.cpp
 | 
						||
@@ -37,6 +37,7 @@
 | 
						||
 #include "WebProcessProxy.h"
 | 
						||
 #include <WebCore/PlatformDisplay.h>
 | 
						||
 #include <WebCore/Region.h>
 | 
						||
+#include <wtf/Vector.h>
 | 
						||
 
 | 
						||
 #if PLATFORM(GTK)
 | 
						||
 #include <gtk/gtk.h>
 | 
						||
@@ -119,6 +120,10 @@ void DrawingAreaProxyCoordinatedGraphics::paint(BackingStore::PlatformGraphicsCo
 | 
						||
 
 | 
						||
 void DrawingAreaProxyCoordinatedGraphics::sizeDidChange()
 | 
						||
 {
 | 
						||
+    for (auto& value : m_callbacks)
 | 
						||
+        value();
 | 
						||
+    m_callbacks.clear();
 | 
						||
+
 | 
						||
 #if USE(DIRECT2D)
 | 
						||
     m_backingStore = nullptr;
 | 
						||
 #endif
 | 
						||
@@ -133,6 +138,11 @@ void DrawingAreaProxyCoordinatedGraphics::deviceScaleFactorDidChange()
 | 
						||
     backingStoreStateDidChange(RespondImmediately);
 | 
						||
 }
 | 
						||
 
 | 
						||
+void DrawingAreaProxyCoordinatedGraphics::waitForSizeUpdate(Function<void ()>&& callback)
 | 
						||
+{
 | 
						||
+    m_callbacks.append(WTFMove(callback));
 | 
						||
+}
 | 
						||
+
 | 
						||
 void DrawingAreaProxyCoordinatedGraphics::waitForBackingStoreUpdateOnNextPaint()
 | 
						||
 {
 | 
						||
     m_hasReceivedFirstUpdate = true;
 | 
						||
diff --git a/Source/WebKit/UIProcess/CoordinatedGraphics/DrawingAreaProxyCoordinatedGraphics.h b/Source/WebKit/UIProcess/CoordinatedGraphics/DrawingAreaProxyCoordinatedGraphics.h
 | 
						||
index d7695088e7cfc4f638f157338754f9f157489749..ba114d47ac079661702e44f19853398f5c1d6b55 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/HashMap.h>
 | 
						||
 #include <wtf/RunLoop.h>
 | 
						||
 
 | 
						||
 namespace WebCore {
 | 
						||
@@ -49,6 +50,7 @@ public:
 | 
						||
 
 | 
						||
     bool isInAcceleratedCompositingMode() const { return !m_layerTreeContext.isEmpty(); }
 | 
						||
     const LayerTreeContext& layerTreeContext() const { return m_layerTreeContext; }
 | 
						||
+    void waitForSizeUpdate(Function<void ()>&&);
 | 
						||
 
 | 
						||
 private:
 | 
						||
     // DrawingAreaProxy
 | 
						||
@@ -126,6 +128,8 @@ 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;
 | 
						||
diff --git a/Source/WebKit/UIProcess/DrawingAreaProxy.h b/Source/WebKit/UIProcess/DrawingAreaProxy.h
 | 
						||
index 4896c404bc8b25d69360de7d1c509383282b2317..14bdebf732e929ea367c961f9d0bec85202bbae3 100644
 | 
						||
--- a/Source/WebKit/UIProcess/DrawingAreaProxy.h
 | 
						||
+++ b/Source/WebKit/UIProcess/DrawingAreaProxy.h
 | 
						||
@@ -70,6 +70,7 @@ public:
 | 
						||
 
 | 
						||
     const WebCore::IntSize& size() const { return m_size; }
 | 
						||
     bool setSize(const WebCore::IntSize&, const WebCore::IntSize& scrollOffset = { });
 | 
						||
+    void waitForSizeUpdate(Function<void ()>&&);
 | 
						||
 
 | 
						||
     // The timeout we use when waiting for a DidUpdateGeometry message.
 | 
						||
     static constexpr Seconds didUpdateBackingStoreStateTimeout() { return Seconds::fromMilliseconds(500); }
 | 
						||
diff --git a/Source/WebKit/UIProcess/Inspector/InspectorTargetProxy.cpp b/Source/WebKit/UIProcess/Inspector/InspectorTargetProxy.cpp
 | 
						||
index 6928ca2fbfb6939062e3cd14bb7ba6f2fdc87f5f..c4645302296540a408aa88dabb64fd5e9a04f3f7 100644
 | 
						||
--- a/Source/WebKit/UIProcess/Inspector/InspectorTargetProxy.cpp
 | 
						||
+++ b/Source/WebKit/UIProcess/Inspector/InspectorTargetProxy.cpp
 | 
						||
@@ -27,11 +27,10 @@
 | 
						||
 #include "InspectorTargetProxy.h"
 | 
						||
 
 | 
						||
 #include "ProvisionalPageProxy.h"
 | 
						||
-#include "WebFrameProxy.h"
 | 
						||
+#include "WebPageInspectorController.h"
 | 
						||
 #include "WebPageInspectorTarget.h"
 | 
						||
 #include "WebPageMessages.h"
 | 
						||
 #include "WebPageProxy.h"
 | 
						||
-#include "WebProcessProxy.h"
 | 
						||
 
 | 
						||
 namespace WebKit {
 | 
						||
 
 | 
						||
@@ -39,18 +38,17 @@ using namespace Inspector;
 | 
						||
 
 | 
						||
 std::unique_ptr<InspectorTargetProxy> InspectorTargetProxy::create(WebPageProxy& page, const String& targetId, Inspector::InspectorTargetType type)
 | 
						||
 {
 | 
						||
-    return makeUnique<InspectorTargetProxy>(page, targetId, type);
 | 
						||
+    return makeUnique<InspectorTargetProxy>(page, nullptr, targetId, type);
 | 
						||
 }
 | 
						||
 
 | 
						||
-std::unique_ptr<InspectorTargetProxy> InspectorTargetProxy::create(ProvisionalPageProxy& provisionalPage, const String& targetId, Inspector::InspectorTargetType type)
 | 
						||
+std::unique_ptr<InspectorTargetProxy> InspectorTargetProxy::create(ProvisionalPageProxy& provisionalPage, const String& targetId)
 | 
						||
 {
 | 
						||
-    auto target = InspectorTargetProxy::create(provisionalPage.page(), targetId, type);
 | 
						||
-    target->m_provisionalPage = makeWeakPtr(provisionalPage);
 | 
						||
-    return target;
 | 
						||
+    return makeUnique<InspectorTargetProxy>(provisionalPage.page(), &provisionalPage, targetId, Inspector::InspectorTargetType::Page);
 | 
						||
 }
 | 
						||
 
 | 
						||
-InspectorTargetProxy::InspectorTargetProxy(WebPageProxy& page, const String& targetId, Inspector::InspectorTargetType type)
 | 
						||
+InspectorTargetProxy::InspectorTargetProxy(WebPageProxy& page, ProvisionalPageProxy* provisionalPage, const String& targetId, Inspector::InspectorTargetType type)
 | 
						||
     : m_page(page)
 | 
						||
+    , m_provisionalPage(makeWeakPtr(provisionalPage))
 | 
						||
     , m_identifier(targetId)
 | 
						||
     , m_type(type)
 | 
						||
 {
 | 
						||
@@ -83,6 +81,9 @@ void InspectorTargetProxy::disconnect()
 | 
						||
 
 | 
						||
 void InspectorTargetProxy::sendMessageToTargetBackend(const String& message)
 | 
						||
 {
 | 
						||
+    if (m_page.inspectorController().dispatchMessageToTargetBackend(message))
 | 
						||
+        return;
 | 
						||
+
 | 
						||
     if (m_provisionalPage) {
 | 
						||
         m_provisionalPage->send(Messages::WebPage::SendMessageToTargetBackend(identifier(), message));
 | 
						||
         return;
 | 
						||
@@ -97,6 +98,31 @@ void InspectorTargetProxy::didCommitProvisionalTarget()
 | 
						||
     m_provisionalPage = nullptr;
 | 
						||
 }
 | 
						||
 
 | 
						||
+void InspectorTargetProxy::willResume()
 | 
						||
+{
 | 
						||
+    if (m_page.hasRunningProcess())
 | 
						||
+        m_page.send(Messages::WebPage::ResumeInspectorIfPausedInNewWindow());
 | 
						||
+}
 | 
						||
+
 | 
						||
+void InspectorTargetProxy::activate(String& error)
 | 
						||
+{
 | 
						||
+    if (m_type != Inspector::InspectorTargetType::Page)
 | 
						||
+        return InspectorTarget::activate(error);
 | 
						||
+
 | 
						||
+    platformActivate(error);
 | 
						||
+}
 | 
						||
+
 | 
						||
+void InspectorTargetProxy::close(String& error, bool runBeforeUnload)
 | 
						||
+{
 | 
						||
+    if (m_type != Inspector::InspectorTargetType::Page)
 | 
						||
+        return InspectorTarget::close(error, runBeforeUnload);
 | 
						||
+
 | 
						||
+    if (runBeforeUnload)
 | 
						||
+        m_page.tryClose();
 | 
						||
+    else
 | 
						||
+        m_page.closePage();
 | 
						||
+}
 | 
						||
+
 | 
						||
 bool InspectorTargetProxy::isProvisional() const
 | 
						||
 {
 | 
						||
     return !!m_provisionalPage;
 | 
						||
diff --git a/Source/WebKit/UIProcess/Inspector/InspectorTargetProxy.h b/Source/WebKit/UIProcess/Inspector/InspectorTargetProxy.h
 | 
						||
index a2239cec8e18850f35f7f88a9c4ebadc62bf4023..79f3ff84327dc075ec96983e04db4b10343b7fae 100644
 | 
						||
--- a/Source/WebKit/UIProcess/Inspector/InspectorTargetProxy.h
 | 
						||
+++ b/Source/WebKit/UIProcess/Inspector/InspectorTargetProxy.h
 | 
						||
@@ -37,13 +37,13 @@ class WebPageProxy;
 | 
						||
 // NOTE: This UIProcess side InspectorTarget doesn't care about the frontend channel, since
 | 
						||
 // any target -> frontend messages will be routed to the WebPageProxy with a targetId.
 | 
						||
 
 | 
						||
-class InspectorTargetProxy final : public Inspector::InspectorTarget {
 | 
						||
+class InspectorTargetProxy : public Inspector::InspectorTarget {
 | 
						||
     WTF_MAKE_FAST_ALLOCATED;
 | 
						||
     WTF_MAKE_NONCOPYABLE(InspectorTargetProxy);
 | 
						||
 public:
 | 
						||
     static std::unique_ptr<InspectorTargetProxy> create(WebPageProxy&, const String& targetId, Inspector::InspectorTargetType);
 | 
						||
-    static std::unique_ptr<InspectorTargetProxy> create(ProvisionalPageProxy&, const String& targetId, Inspector::InspectorTargetType);
 | 
						||
-    InspectorTargetProxy(WebPageProxy&, const String& targetId, Inspector::InspectorTargetType);
 | 
						||
+    static std::unique_ptr<InspectorTargetProxy> create(ProvisionalPageProxy&, const String& targetId);
 | 
						||
+    InspectorTargetProxy(WebPageProxy&, ProvisionalPageProxy*, const String& targetId, Inspector::InspectorTargetType);
 | 
						||
     ~InspectorTargetProxy() = default;
 | 
						||
 
 | 
						||
     Inspector::InspectorTargetType type() const final { return m_type; }
 | 
						||
@@ -55,12 +55,17 @@ public:
 | 
						||
     void connect(Inspector::FrontendChannel::ConnectionType) override;
 | 
						||
     void disconnect() override;
 | 
						||
     void sendMessageToTargetBackend(const String&) override;
 | 
						||
+    void activate(String& error) override;
 | 
						||
+    void close(String& error, bool runBeforeUnload) override;
 | 
						||
 
 | 
						||
 private:
 | 
						||
+    void willResume() override;
 | 
						||
+    void platformActivate(String& error) const;
 | 
						||
+
 | 
						||
     WebPageProxy& m_page;
 | 
						||
+    WeakPtr<ProvisionalPageProxy> m_provisionalPage;
 | 
						||
     String m_identifier;
 | 
						||
     Inspector::InspectorTargetType m_type;
 | 
						||
-    WeakPtr<ProvisionalPageProxy> m_provisionalPage;
 | 
						||
 };
 | 
						||
 
 | 
						||
 } // namespace WebKit
 | 
						||
diff --git a/Source/WebKit/UIProcess/Inspector/WebPageInspectorController.cpp b/Source/WebKit/UIProcess/Inspector/WebPageInspectorController.cpp
 | 
						||
index 1861cff806131196ea49b4f8aca6665beebbf6e8..e1bade3da38ad2c1faa8bffcae623eb167b3232a 100644
 | 
						||
--- a/Source/WebKit/UIProcess/Inspector/WebPageInspectorController.cpp
 | 
						||
+++ b/Source/WebKit/UIProcess/Inspector/WebPageInspectorController.cpp
 | 
						||
@@ -26,12 +26,19 @@
 | 
						||
 #include "config.h"
 | 
						||
 #include "WebPageInspectorController.h"
 | 
						||
 
 | 
						||
+#include "APINavigation.h"
 | 
						||
 #include "InspectorBrowserAgent.h"
 | 
						||
+#include "InspectorDialogAgent.h"
 | 
						||
 #include "ProvisionalPageProxy.h"
 | 
						||
 #include "WebFrameProxy.h"
 | 
						||
 #include "WebPageInspectorAgentBase.h"
 | 
						||
+#include "WebPageInspectorEmulationAgent.h"
 | 
						||
+#include "WebPageInspectorInputAgent.h"
 | 
						||
 #include "WebPageInspectorTarget.h"
 | 
						||
 #include "WebPageProxy.h"
 | 
						||
+#include "WebPreferences.h"
 | 
						||
+#include <WebCore/ResourceError.h>
 | 
						||
+#include <WebCore/WindowFeatures.h>
 | 
						||
 #include <JavaScriptCore/InspectorAgentBase.h>
 | 
						||
 #include <JavaScriptCore/InspectorBackendDispatcher.h>
 | 
						||
 #include <JavaScriptCore/InspectorBackendDispatchers.h>
 | 
						||
@@ -48,27 +55,102 @@ static String getTargetID(const ProvisionalPageProxy& provisionalPage)
 | 
						||
     return WebPageInspectorTarget::toTargetID(provisionalPage.webPageID());
 | 
						||
 }
 | 
						||
 
 | 
						||
+WebPageInspectorControllerObserver* WebPageInspectorController::s_observer = nullptr;
 | 
						||
+
 | 
						||
+void WebPageInspectorController::setObserver(WebPageInspectorControllerObserver* observer)
 | 
						||
+{
 | 
						||
+    s_observer = observer;
 | 
						||
+}
 | 
						||
+
 | 
						||
 WebPageInspectorController::WebPageInspectorController(WebPageProxy& page)
 | 
						||
     : m_frontendRouter(FrontendRouter::create())
 | 
						||
     , m_backendDispatcher(BackendDispatcher::create(m_frontendRouter.copyRef()))
 | 
						||
     , m_page(page)
 | 
						||
 {
 | 
						||
-    auto targetAgent = makeUnique<InspectorTargetAgent>(m_frontendRouter.get(), m_backendDispatcher.get());
 | 
						||
-    m_targetAgent = targetAgent.get();
 | 
						||
-    m_agents.append(WTFMove(targetAgent));
 | 
						||
 }
 | 
						||
 
 | 
						||
 void WebPageInspectorController::init()
 | 
						||
 {
 | 
						||
+    auto targetAgent = makeUnique<InspectorTargetAgent>(m_frontendRouter.get(), m_backendDispatcher.get());
 | 
						||
+    m_targetAgent = targetAgent.get();
 | 
						||
+    m_agents.append(WTFMove(targetAgent));
 | 
						||
+    auto emulationAgent = makeUnique<WebPageInspectorEmulationAgent>(m_backendDispatcher.get(), m_page);
 | 
						||
+    m_emulationAgent = emulationAgent.get();
 | 
						||
+    m_agents.append(WTFMove(emulationAgent));
 | 
						||
+    auto inputAgent = makeUnique<WebPageInspectorInputAgent>(m_backendDispatcher.get(), m_page);
 | 
						||
+    m_inputAgent = inputAgent.get();
 | 
						||
+    m_agents.append(WTFMove(inputAgent));
 | 
						||
+    m_agents.append(makeUnique<InspectorDialogAgent>(m_backendDispatcher.get(), m_frontendRouter.get(), m_page));
 | 
						||
+
 | 
						||
+    if (s_observer)
 | 
						||
+        s_observer->didCreateInspectorController(m_page);
 | 
						||
+
 | 
						||
+    // window.open will create page with already running process.
 | 
						||
+    if (!m_page.hasRunningProcess())
 | 
						||
+        return;
 | 
						||
     String pageTargetId = WebPageInspectorTarget::toTargetID(m_page.webPageID());
 | 
						||
     createInspectorTarget(pageTargetId, Inspector::InspectorTargetType::Page);
 | 
						||
 }
 | 
						||
 
 | 
						||
+void WebPageInspectorController::didFinishAttachingToWebProcess()
 | 
						||
+{
 | 
						||
+    String pageTargetID = WebPageInspectorTarget::toTargetID(m_page.webPageID());
 | 
						||
+    // Create target only after attaching to a Web Process first time. Before that
 | 
						||
+    // we cannot event establish frontend connection.
 | 
						||
+    if (m_targets.contains(pageTargetID))
 | 
						||
+        return;
 | 
						||
+    createInspectorTarget(pageTargetID, Inspector::InspectorTargetType::Page);
 | 
						||
+}
 | 
						||
+
 | 
						||
 void WebPageInspectorController::pageClosed()
 | 
						||
 {
 | 
						||
+    String pageTargetId = WebPageInspectorTarget::toTargetID(m_page.webPageID());
 | 
						||
+    destroyInspectorTarget(pageTargetId);
 | 
						||
+
 | 
						||
     disconnectAllFrontends();
 | 
						||
 
 | 
						||
     m_agents.discardValues();
 | 
						||
+
 | 
						||
+    if (s_observer)
 | 
						||
+        s_observer->willDestroyInspectorController(m_page);
 | 
						||
+}
 | 
						||
+
 | 
						||
+bool WebPageInspectorController::pageCrashed(ProcessTerminationReason reason)
 | 
						||
+{
 | 
						||
+    if (reason != ProcessTerminationReason::Crash)
 | 
						||
+        return false;
 | 
						||
+    String targetId = WebPageInspectorTarget::toTargetID(m_page.webPageID());
 | 
						||
+    auto it = m_targets.find(targetId);
 | 
						||
+    if (it == m_targets.end())
 | 
						||
+        return false;
 | 
						||
+    m_targetAgent->targetCrashed(*it->value);
 | 
						||
+    m_targets.remove(it);
 | 
						||
+
 | 
						||
+    return m_targetAgent->isConnected();
 | 
						||
+}
 | 
						||
+
 | 
						||
+void WebPageInspectorController::willCreateNewPage(const WebCore::WindowFeatures& features, const URL& url)
 | 
						||
+{
 | 
						||
+    if (s_observer)
 | 
						||
+        s_observer->willCreateNewPage(m_page, features, url);
 | 
						||
+}
 | 
						||
+
 | 
						||
+void WebPageInspectorController::didShowPage()
 | 
						||
+{
 | 
						||
+    if (m_frontendRouter->hasFrontends())
 | 
						||
+        m_emulationAgent->didShowPage();
 | 
						||
+}
 | 
						||
+
 | 
						||
+void WebPageInspectorController::didProcessAllPendingKeyboardEvents()
 | 
						||
+{
 | 
						||
+    if (m_frontendRouter->hasFrontends())
 | 
						||
+        m_inputAgent->didProcessAllPendingKeyboardEvents();
 | 
						||
+}
 | 
						||
+
 | 
						||
+void WebPageInspectorController::didProcessAllPendingMouseEvents()
 | 
						||
+{
 | 
						||
+    if (m_frontendRouter->hasFrontends())
 | 
						||
+        m_inputAgent->didProcessAllPendingMouseEvents();
 | 
						||
 }
 | 
						||
 
 | 
						||
 bool WebPageInspectorController::hasLocalFrontend() const
 | 
						||
@@ -82,6 +164,17 @@ void WebPageInspectorController::connectFrontend(Inspector::FrontendChannel& fro
 | 
						||
 
 | 
						||
     bool connectingFirstFrontend = !m_frontendRouter->hasFrontends();
 | 
						||
 
 | 
						||
+    // HACK: forcefully disconnect remote connections to show local inspector starting with initial
 | 
						||
+    // agents' state.
 | 
						||
+    if (frontendChannel.connectionType() == Inspector::FrontendChannel::ConnectionType::Local &&
 | 
						||
+        !connectingFirstFrontend && !m_frontendRouter->hasLocalFrontend()) {
 | 
						||
+        disconnectAllFrontends();
 | 
						||
+        connectingFirstFrontend = true;
 | 
						||
+    }
 | 
						||
+
 | 
						||
+    if (connectingFirstFrontend)
 | 
						||
+        adjustPageSettings();
 | 
						||
+
 | 
						||
     m_frontendRouter->connectFrontend(frontendChannel);
 | 
						||
 
 | 
						||
     if (connectingFirstFrontend)
 | 
						||
@@ -100,8 +193,10 @@ void WebPageInspectorController::disconnectFrontend(FrontendChannel& frontendCha
 | 
						||
     m_frontendRouter->disconnectFrontend(frontendChannel);
 | 
						||
 
 | 
						||
     bool disconnectingLastFrontend = !m_frontendRouter->hasFrontends();
 | 
						||
-    if (disconnectingLastFrontend)
 | 
						||
+    if (disconnectingLastFrontend) {
 | 
						||
         m_agents.willDestroyFrontendAndBackend(DisconnectReason::InspectorDestroyed);
 | 
						||
+        m_pendingNavigations.clear();
 | 
						||
+    }
 | 
						||
 
 | 
						||
     m_page.didChangeInspectorFrontendCount(m_frontendRouter->frontendCount());
 | 
						||
 
 | 
						||
@@ -124,6 +219,8 @@ void WebPageInspectorController::disconnectAllFrontends()
 | 
						||
     // Disconnect any remaining remote frontends.
 | 
						||
     m_frontendRouter->disconnectAllFrontends();
 | 
						||
 
 | 
						||
+    m_pendingNavigations.clear();
 | 
						||
+
 | 
						||
     m_page.didChangeInspectorFrontendCount(m_frontendRouter->frontendCount());
 | 
						||
 
 | 
						||
 #if ENABLE(REMOTE_INSPECTOR)
 | 
						||
@@ -136,6 +233,11 @@ void WebPageInspectorController::dispatchMessageFromFrontend(const String& messa
 | 
						||
     m_backendDispatcher->dispatch(message);
 | 
						||
 }
 | 
						||
 
 | 
						||
+bool WebPageInspectorController::dispatchMessageToTargetBackend(const String& message)
 | 
						||
+{
 | 
						||
+    return m_backendDispatcher->dispatch(message, BackendDispatcher::Mode::ContinueIfDomainIsMissing) == BackendDispatcher::DispatchResult::Finished;
 | 
						||
+}
 | 
						||
+
 | 
						||
 #if ENABLE(REMOTE_INSPECTOR)
 | 
						||
 void WebPageInspectorController::setIndicating(bool indicating)
 | 
						||
 {
 | 
						||
@@ -150,6 +252,55 @@ void WebPageInspectorController::setIndicating(bool indicating)
 | 
						||
 }
 | 
						||
 #endif
 | 
						||
 
 | 
						||
+void WebPageInspectorController::navigate(WebCore::ResourceRequest&& request, WebFrameProxy* frame, NavigationHandler&& completionHandler)
 | 
						||
+{
 | 
						||
+    auto navigation = m_page.loadRequestForInspector(WTFMove(request), frame);
 | 
						||
+    if (!navigation) {
 | 
						||
+        completionHandler("Failed to navigate"_s, 0);
 | 
						||
+        return;
 | 
						||
+    }
 | 
						||
+
 | 
						||
+    m_pendingNavigations.set(navigation->navigationID(), WTFMove(completionHandler));
 | 
						||
+}
 | 
						||
+
 | 
						||
+void WebPageInspectorController::didReceivePolicyDecision(WebCore::PolicyAction action, uint64_t navigationID)
 | 
						||
+{
 | 
						||
+    if (!m_frontendRouter->hasFrontends())
 | 
						||
+        return;
 | 
						||
+
 | 
						||
+    if (!navigationID)
 | 
						||
+        return;
 | 
						||
+
 | 
						||
+    auto completionHandler = m_pendingNavigations.take(navigationID);
 | 
						||
+    if (!completionHandler)
 | 
						||
+        return;
 | 
						||
+
 | 
						||
+    if (action == WebCore::PolicyAction::Ignore)
 | 
						||
+        completionHandler("Navigation cancelled"_s, 0);
 | 
						||
+    else
 | 
						||
+        completionHandler(String(), navigationID);
 | 
						||
+}
 | 
						||
+
 | 
						||
+void WebPageInspectorController::didDestroyNavigation(uint64_t navigationID)
 | 
						||
+{
 | 
						||
+    if (!m_frontendRouter->hasFrontends())
 | 
						||
+        return;
 | 
						||
+
 | 
						||
+    auto completionHandler = m_pendingNavigations.take(navigationID);
 | 
						||
+    if (!completionHandler)
 | 
						||
+        return;
 | 
						||
+
 | 
						||
+    // Inspector initiated navigation is destroyed before policy check only when it
 | 
						||
+    // becomes a fragment navigation (which always reuses current navigation).
 | 
						||
+    completionHandler(String(), 0);
 | 
						||
+}
 | 
						||
+
 | 
						||
+void WebPageInspectorController::didFailProvisionalLoadForFrame(uint64_t navigationID, const WebCore::ResourceError& error)
 | 
						||
+{
 | 
						||
+    if (s_observer)
 | 
						||
+        s_observer->didFailProvisionalLoad(m_page, navigationID, error.localizedDescription());
 | 
						||
+}
 | 
						||
+
 | 
						||
 void WebPageInspectorController::createInspectorTarget(const String& targetId, Inspector::InspectorTargetType type)
 | 
						||
 {
 | 
						||
     addTarget(InspectorTargetProxy::create(m_page, targetId, type));
 | 
						||
@@ -169,6 +320,33 @@ void WebPageInspectorController::sendMessageToInspectorFrontend(const String& ta
 | 
						||
     m_targetAgent->sendMessageFromTargetToFrontend(targetId, message);
 | 
						||
 }
 | 
						||
 
 | 
						||
+void WebPageInspectorController::setPauseOnStart(bool shouldPause)
 | 
						||
+{
 | 
						||
+    ASSERT(m_frontendRouter->hasFrontends());
 | 
						||
+    String errorString;
 | 
						||
+    m_targetAgent->setPauseOnStart(errorString, shouldPause);
 | 
						||
+}
 | 
						||
+
 | 
						||
+bool WebPageInspectorController::shouldPauseLoading() const
 | 
						||
+{
 | 
						||
+    if (!m_frontendRouter->hasFrontends())
 | 
						||
+        return false;
 | 
						||
+
 | 
						||
+    if (!m_page.isPageOpenedByDOMShowingInitialEmptyDocument())
 | 
						||
+        return false;
 | 
						||
+
 | 
						||
+    auto* target = m_targets.get(WebPageInspectorTarget::toTargetID(m_page.webPageID()));
 | 
						||
+    ASSERT(target);
 | 
						||
+    return target->isPaused();
 | 
						||
+}
 | 
						||
+
 | 
						||
+void WebPageInspectorController::setContinueLoadingCallback(WTF::Function<void()>&& callback)
 | 
						||
+{
 | 
						||
+    auto* target = m_targets.get(WebPageInspectorTarget::toTargetID(m_page.webPageID()));
 | 
						||
+    ASSERT(target);
 | 
						||
+    target->setResumeCallback(WTFMove(callback));
 | 
						||
+}
 | 
						||
+
 | 
						||
 bool WebPageInspectorController::shouldPauseLoading(const ProvisionalPageProxy& provisionalPage) const
 | 
						||
 {
 | 
						||
     if (!m_frontendRouter->hasFrontends())
 | 
						||
@@ -188,7 +366,7 @@ void WebPageInspectorController::setContinueLoadingCallback(const ProvisionalPag
 | 
						||
 
 | 
						||
 void WebPageInspectorController::didCreateProvisionalPage(ProvisionalPageProxy& provisionalPage)
 | 
						||
 {
 | 
						||
-    addTarget(InspectorTargetProxy::create(provisionalPage, getTargetID(provisionalPage), Inspector::InspectorTargetType::Page));
 | 
						||
+    addTarget(InspectorTargetProxy::create(provisionalPage, getTargetID(provisionalPage)));
 | 
						||
 }
 | 
						||
 
 | 
						||
 void WebPageInspectorController::willDestroyProvisionalPage(const ProvisionalPageProxy& provisionalPage)
 | 
						||
@@ -241,4 +419,20 @@ void WebPageInspectorController::addTarget(std::unique_ptr<InspectorTargetProxy>
 | 
						||
     m_targets.set(target->identifier(), WTFMove(target));
 | 
						||
 }
 | 
						||
 
 | 
						||
+void WebPageInspectorController::adjustPageSettings()
 | 
						||
+{
 | 
						||
+    // Set this to true as otherwise updating any preferences will override its
 | 
						||
+    // value in the Web Process to false (and InspectorController sets it locally
 | 
						||
+    // to true when frontend is connected).
 | 
						||
+    m_page.preferences().setDeveloperExtrasEnabled(true);
 | 
						||
+
 | 
						||
+    // Navigation to cached pages doesn't fire some of the events (e.g. execution context created)
 | 
						||
+    // that inspector depends on. So we disable the cache when front-end connects.
 | 
						||
+    m_page.preferences().setUsesBackForwardCache(false);
 | 
						||
+
 | 
						||
+    // Enable popup debugging.
 | 
						||
+    // TODO: allow to set preferences over the inspector protocol or find a better place for this.
 | 
						||
+    m_page.preferences().setJavaScriptCanOpenWindowsAutomatically(true);
 | 
						||
+}
 | 
						||
+
 | 
						||
 } // namespace WebKit
 | 
						||
diff --git a/Source/WebKit/UIProcess/Inspector/WebPageInspectorController.h b/Source/WebKit/UIProcess/Inspector/WebPageInspectorController.h
 | 
						||
index 9ce5ef36b652fd56a843c1d12a4c3c3cf639282c..9b6a239b6db52a55f693654ed65d89dff8dd0ffb 100644
 | 
						||
--- a/Source/WebKit/UIProcess/Inspector/WebPageInspectorController.h
 | 
						||
+++ b/Source/WebKit/UIProcess/Inspector/WebPageInspectorController.h
 | 
						||
@@ -26,17 +26,27 @@
 | 
						||
 #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>
 | 
						||
 
 | 
						||
 namespace Inspector {
 | 
						||
 class BackendDispatcher;
 | 
						||
 class FrontendChannel;
 | 
						||
 class FrontendRouter;
 | 
						||
+class InspectorTarget;
 | 
						||
+}
 | 
						||
+
 | 
						||
+namespace WebCore {
 | 
						||
+class ResourceError;
 | 
						||
+class ResourceRequest;
 | 
						||
+enum class PolicyAction : uint8_t;
 | 
						||
+struct WindowFeatures;
 | 
						||
 }
 | 
						||
 
 | 
						||
 namespace WebKit {
 | 
						||
@@ -44,6 +54,21 @@ namespace WebKit {
 | 
						||
 class InspectorBrowserAgent;
 | 
						||
 struct WebPageAgentContext;
 | 
						||
 
 | 
						||
+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;
 | 
						||
+
 | 
						||
+protected:
 | 
						||
+    virtual ~WebPageInspectorControllerObserver() = default;
 | 
						||
+};
 | 
						||
+
 | 
						||
 class WebPageInspectorController {
 | 
						||
     WTF_MAKE_NONCOPYABLE(WebPageInspectorController);
 | 
						||
     WTF_MAKE_FAST_ALLOCATED;
 | 
						||
@@ -51,7 +76,19 @@ public:
 | 
						||
     WebPageInspectorController(WebPageProxy&);
 | 
						||
 
 | 
						||
     void init();
 | 
						||
+    void didFinishAttachingToWebProcess();
 | 
						||
+
 | 
						||
+    static void setObserver(WebPageInspectorControllerObserver*);
 | 
						||
+
 | 
						||
     void pageClosed();
 | 
						||
+    bool pageCrashed(ProcessTerminationReason);
 | 
						||
+
 | 
						||
+    void willCreateNewPage(const WebCore::WindowFeatures&, const URL&);
 | 
						||
+
 | 
						||
+    void didShowPage();
 | 
						||
+
 | 
						||
+    void didProcessAllPendingKeyboardEvents();
 | 
						||
+    void didProcessAllPendingMouseEvents();
 | 
						||
 
 | 
						||
     bool hasLocalFrontend() const;
 | 
						||
 
 | 
						||
@@ -60,15 +97,28 @@ public:
 | 
						||
     void disconnectAllFrontends();
 | 
						||
 
 | 
						||
     void dispatchMessageFromFrontend(const String& message);
 | 
						||
+    bool dispatchMessageToTargetBackend(const String&);
 | 
						||
 
 | 
						||
 #if ENABLE(REMOTE_INSPECTOR)
 | 
						||
     void setIndicating(bool);
 | 
						||
 #endif
 | 
						||
 
 | 
						||
+    using NavigationHandler = Function<void(const String&, uint64_t)>;
 | 
						||
+    void navigate(WebCore::ResourceRequest&&, WebFrameProxy*, NavigationHandler&&);
 | 
						||
+    void didReceivePolicyDecision(WebCore::PolicyAction action, uint64_t navigationID);
 | 
						||
+    void didDestroyNavigation(uint64_t navigationID);
 | 
						||
+
 | 
						||
+    void didFailProvisionalLoadForFrame(uint64_t navigationID, const WebCore::ResourceError& error);
 | 
						||
+
 | 
						||
     void createInspectorTarget(const String& targetId, Inspector::InspectorTargetType);
 | 
						||
     void destroyInspectorTarget(const String& targetId);
 | 
						||
     void sendMessageToInspectorFrontend(const String& targetId, const String& message);
 | 
						||
 
 | 
						||
+    void setPauseOnStart(bool);
 | 
						||
+
 | 
						||
+    bool shouldPauseLoading() const;
 | 
						||
+    void setContinueLoadingCallback(WTF::Function<void()>&&);
 | 
						||
+
 | 
						||
     bool shouldPauseLoading(const ProvisionalPageProxy&) const;
 | 
						||
     void setContinueLoadingCallback(const ProvisionalPageProxy&, WTF::Function<void()>&&);
 | 
						||
 
 | 
						||
@@ -84,6 +134,7 @@ private:
 | 
						||
     void createLazyAgents();
 | 
						||
 
 | 
						||
     void addTarget(std::unique_ptr<InspectorTargetProxy>&&);
 | 
						||
+    void adjustPageSettings();
 | 
						||
 
 | 
						||
     Ref<Inspector::FrontendRouter> m_frontendRouter;
 | 
						||
     Ref<Inspector::BackendDispatcher> m_backendDispatcher;
 | 
						||
@@ -92,11 +143,16 @@ private:
 | 
						||
     WebPageProxy& m_page;
 | 
						||
 
 | 
						||
     Inspector::InspectorTargetAgent* m_targetAgent;
 | 
						||
+    WebPageInspectorEmulationAgent* m_emulationAgent { nullptr };
 | 
						||
+    WebPageInspectorInputAgent* m_inputAgent { nullptr };
 | 
						||
     HashMap<String, std::unique_ptr<InspectorTargetProxy>> m_targets;
 | 
						||
 
 | 
						||
     InspectorBrowserAgent* m_enabledInspectorBrowserAgent;
 | 
						||
 
 | 
						||
     bool m_didCreateLazyAgents { false };
 | 
						||
+    HashMap<uint64_t, NavigationHandler> m_pendingNavigations;
 | 
						||
+
 | 
						||
+    static WebPageInspectorControllerObserver* s_observer;
 | 
						||
 };
 | 
						||
 
 | 
						||
 } // namespace WebKit
 | 
						||
diff --git a/Source/WebKit/UIProcess/InspectorDialogAgent.cpp b/Source/WebKit/UIProcess/InspectorDialogAgent.cpp
 | 
						||
new file mode 100644
 | 
						||
index 0000000000000000000000000000000000000000..ca5965f9d682c0821a40f0d1d43e5cbeda1353a5
 | 
						||
--- /dev/null
 | 
						||
+++ b/Source/WebKit/UIProcess/InspectorDialogAgent.cpp
 | 
						||
@@ -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.
 | 
						||
+ */
 | 
						||
+
 | 
						||
+#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()
 | 
						||
+{
 | 
						||
+    Inspector::ErrorString err;
 | 
						||
+    disable(err);
 | 
						||
+}
 | 
						||
+
 | 
						||
+void InspectorDialogAgent::didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*)
 | 
						||
+{
 | 
						||
+}
 | 
						||
+
 | 
						||
+void InspectorDialogAgent::willDestroyFrontendAndBackend(Inspector::DisconnectReason)
 | 
						||
+{
 | 
						||
+}
 | 
						||
+
 | 
						||
+void InspectorDialogAgent::enable(Inspector::ErrorString& errorString)
 | 
						||
+{
 | 
						||
+    if (m_page.inspectorDialogAgent()) {
 | 
						||
+        errorString = "Dialog domain is already enabled."_s;
 | 
						||
+        return;
 | 
						||
+    }
 | 
						||
+    m_page.setInspectorDialogAgent(this);
 | 
						||
+}
 | 
						||
+
 | 
						||
+void InspectorDialogAgent::disable(Inspector::ErrorString&)
 | 
						||
+{
 | 
						||
+    if (m_page.inspectorDialogAgent() != this)
 | 
						||
+        return;
 | 
						||
+    m_page.setInspectorDialogAgent(nullptr);
 | 
						||
+}
 | 
						||
+
 | 
						||
+void InspectorDialogAgent::handleJavaScriptDialog(Inspector::ErrorString& errorString, bool accept, const String* value)
 | 
						||
+{
 | 
						||
+    m_page.uiClient().handleJavaScriptDialog(m_page, accept, value ? *value : String());
 | 
						||
+}
 | 
						||
+
 | 
						||
+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..f356c613945fd263889bc74166bef2b279ab4ca1
 | 
						||
--- /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;
 | 
						||
+
 | 
						||
+    void enable(Inspector::ErrorString&) override;
 | 
						||
+    void disable(Inspector::ErrorString&) override;
 | 
						||
+    void handleJavaScriptDialog(Inspector::ErrorString& errorString, bool accept, const String* promptText) override;
 | 
						||
+
 | 
						||
+    void javascriptDialogOpening(const String& type, const String& message, const String* defaultValue = nullptr);
 | 
						||
+
 | 
						||
+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..66bf9c54ac5e882c5c725389ea19584438a94446
 | 
						||
--- /dev/null
 | 
						||
+++ b/Source/WebKit/UIProcess/InspectorPlaywrightAgent.cpp
 | 
						||
@@ -0,0 +1,634 @@
 | 
						||
+/*
 | 
						||
+ * Copyright (C) 2019 Microsoft Corporation.
 | 
						||
+ *
 | 
						||
+ * Redistribution and use in source and binary forms, with or without
 | 
						||
+ * modification, are permitted provided that the following conditions
 | 
						||
+ * are met:
 | 
						||
+ * 1. Redistributions of source code must retain the above copyright
 | 
						||
+ *    notice, this list of conditions and the following disclaimer.
 | 
						||
+ * 2. Redistributions in binary form must reproduce the above copyright
 | 
						||
+ *    notice, this list of conditions and the following disclaimer in the
 | 
						||
+ *    documentation and/or other materials provided with the distribution.
 | 
						||
+ *
 | 
						||
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
						||
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
						||
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
						||
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | 
						||
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | 
						||
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
						||
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | 
						||
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | 
						||
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
						||
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
						||
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
						||
+ */
 | 
						||
+
 | 
						||
+#include "config.h"
 | 
						||
+#include "InspectorPlaywrightAgent.h"
 | 
						||
+
 | 
						||
+#if ENABLE(REMOTE_INSPECTOR)
 | 
						||
+
 | 
						||
+#include "APIPageConfiguration.h"
 | 
						||
+#include "InspectorPlaywrightAgentClient.h"
 | 
						||
+#include "InspectorTargetProxy.h"
 | 
						||
+#include "NetworkProcessMessages.h"
 | 
						||
+#include "NetworkProcessProxy.h"
 | 
						||
+#include "WebGeolocationManagerProxy.h"
 | 
						||
+#include "WebGeolocationPosition.h"
 | 
						||
+#include "WebPageInspectorController.h"
 | 
						||
+#include "WebPageInspectorTarget.h"
 | 
						||
+#include "WebPageProxy.h"
 | 
						||
+#include "WebProcessPool.h"
 | 
						||
+#include "WebProcessProxy.h"
 | 
						||
+#include <WebCore/FrameIdentifier.h>
 | 
						||
+#include <WebCore/GeolocationPositionData.h>
 | 
						||
+#include <WebCore/ProcessIdentifier.h>
 | 
						||
+#include <WebCore/ResourceRequest.h>
 | 
						||
+#include <WebCore/WindowFeatures.h>
 | 
						||
+#include <JavaScriptCore/InspectorFrontendRouter.h>
 | 
						||
+#include <pal/SessionID.h>
 | 
						||
+#include <stdlib.h>
 | 
						||
+#include <wtf/HashMap.h>
 | 
						||
+#include <wtf/HexNumber.h>
 | 
						||
+
 | 
						||
+
 | 
						||
+using namespace Inspector;
 | 
						||
+
 | 
						||
+namespace WebKit {
 | 
						||
+
 | 
						||
+namespace {
 | 
						||
+
 | 
						||
+static RefPtr<JSON::ArrayOf<String>> getEnabledWindowFeatures(const WebCore::WindowFeatures& features) {
 | 
						||
+  auto result = JSON::ArrayOf<String>::create();
 | 
						||
+  if (features.x)
 | 
						||
+    result->addItem("left=" + String::number(*features.x));
 | 
						||
+  if (features.y)
 | 
						||
+    result->addItem("top=" + String::number(*features.y));
 | 
						||
+  if (features.width)
 | 
						||
+    result->addItem("width=" + String::number(*features.width));
 | 
						||
+  if (features.height)
 | 
						||
+    result->addItem("height=" + String::number(*features.height));
 | 
						||
+  if (features.menuBarVisible)
 | 
						||
+    result->addItem("menubar");
 | 
						||
+  if (features.toolBarVisible)
 | 
						||
+    result->addItem("toolbar");
 | 
						||
+  if (features.statusBarVisible)
 | 
						||
+    result->addItem("status");
 | 
						||
+  if (features.locationBarVisible)
 | 
						||
+    result->addItem("location");
 | 
						||
+  if (features.scrollbarsVisible)
 | 
						||
+    result->addItem("scrollbars");
 | 
						||
+  if (features.resizable)
 | 
						||
+    result->addItem("resizable");
 | 
						||
+  if (features.fullscreen)
 | 
						||
+    result->addItem("fullscreen");
 | 
						||
+  if (features.dialog)
 | 
						||
+    result->addItem("dialog");
 | 
						||
+  if (features.noopener)
 | 
						||
+    result->addItem("noopener");
 | 
						||
+  if (features.noreferrer)
 | 
						||
+    result->addItem("noreferrer");
 | 
						||
+  for (const auto& additionalFeature : features.additionalFeatures)
 | 
						||
+    result->addItem(additionalFeature);
 | 
						||
+  return result;
 | 
						||
+}
 | 
						||
+
 | 
						||
+Inspector::Protocol::Playwright::CookieSameSitePolicy cookieSameSitePolicy(WebCore::Cookie::SameSitePolicy policy)
 | 
						||
+{
 | 
						||
+    switch (policy) {
 | 
						||
+    case WebCore::Cookie::SameSitePolicy::None:
 | 
						||
+        return Inspector::Protocol::Playwright::CookieSameSitePolicy::None;
 | 
						||
+    case WebCore::Cookie::SameSitePolicy::Lax:
 | 
						||
+        return Inspector::Protocol::Playwright::CookieSameSitePolicy::Lax;
 | 
						||
+    case WebCore::Cookie::SameSitePolicy::Strict:
 | 
						||
+        return Inspector::Protocol::Playwright::CookieSameSitePolicy::Strict;
 | 
						||
+    }
 | 
						||
+    ASSERT_NOT_REACHED();
 | 
						||
+    return Inspector::Protocol::Playwright::CookieSameSitePolicy::None;
 | 
						||
+}
 | 
						||
+
 | 
						||
+Ref<Inspector::Protocol::Playwright::Cookie> buildObjectForCookie(const WebCore::Cookie& cookie)
 | 
						||
+{
 | 
						||
+    return Inspector::Protocol::Playwright::Cookie::create()
 | 
						||
+        .setName(cookie.name)
 | 
						||
+        .setValue(cookie.value)
 | 
						||
+        .setDomain(cookie.domain)
 | 
						||
+        .setPath(cookie.path)
 | 
						||
+        .setExpires(cookie.expires.valueOr(-1))
 | 
						||
+        .setHttpOnly(cookie.httpOnly)
 | 
						||
+        .setSecure(cookie.secure)
 | 
						||
+        .setSession(cookie.session)
 | 
						||
+        .setSameSite(cookieSameSitePolicy(cookie.sameSite))
 | 
						||
+        .release();
 | 
						||
+}
 | 
						||
+
 | 
						||
+Ref<Inspector::Protocol::Playwright::PageProxyInfo> buildPageProxyInfo(const WebPageProxy& page) {
 | 
						||
+    auto result = Inspector::Protocol::Playwright::PageProxyInfo::create()
 | 
						||
+        .setPageProxyId(InspectorPlaywrightAgent::toPageProxyIDProtocolString(page))
 | 
						||
+        .setBrowserContextId(InspectorPlaywrightAgent::toBrowserContextIDProtocolString(page.sessionID()))
 | 
						||
+        .release();
 | 
						||
+    auto* opener = page.configuration().relatedPage();
 | 
						||
+    if (opener)
 | 
						||
+        result->setOpenerId(InspectorPlaywrightAgent::toPageProxyIDProtocolString(*opener));
 | 
						||
+    return result;
 | 
						||
+}
 | 
						||
+
 | 
						||
+}  // namespace
 | 
						||
+
 | 
						||
+Vector<WebPageProxy*> BrowserContext::pages() const {
 | 
						||
+    Vector<WebPageProxy*> pages;
 | 
						||
+    for (auto& process : processPool->processes()) {
 | 
						||
+        for (auto* page : process->pages())
 | 
						||
+            pages.append(page);
 | 
						||
+    }
 | 
						||
+    return pages;
 | 
						||
+}
 | 
						||
+
 | 
						||
+class InspectorPlaywrightAgent::BrowserContextDeletion {
 | 
						||
+    WTF_MAKE_NONCOPYABLE(BrowserContextDeletion);
 | 
						||
+    WTF_MAKE_FAST_ALLOCATED;
 | 
						||
+public:
 | 
						||
+    BrowserContextDeletion(const BrowserContext& context, size_t numberOfPages, Ref<DeleteContextCallback>&& callback)
 | 
						||
+        : m_browserContext(context)
 | 
						||
+        , m_numberOfPages(numberOfPages)
 | 
						||
+        , m_callback(WTFMove(callback)) { }
 | 
						||
+
 | 
						||
+    void willDestroyPage(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) {
 | 
						||
+            Vector<WebPageProxy*> 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; }
 | 
						||
+
 | 
						||
+private:
 | 
						||
+    BrowserContext m_browserContext;
 | 
						||
+    size_t m_numberOfPages;
 | 
						||
+    Ref<DeleteContextCallback> m_callback;
 | 
						||
+};
 | 
						||
+
 | 
						||
+
 | 
						||
+InspectorPlaywrightAgent::InspectorPlaywrightAgent(Inspector::FrontendRouter& frontendRouter, Inspector::BackendDispatcher& backendDispatcher, InspectorPlaywrightAgentClient* client, PageProxyIDMap& pageProxyIDMap)
 | 
						||
+    : InspectorAgentBase("Playwright"_s)
 | 
						||
+    , m_frontendDispatcher(makeUnique<PlaywrightFrontendDispatcher>(frontendRouter))
 | 
						||
+    , m_backendDispatcher(PlaywrightBackendDispatcher::create(backendDispatcher, this))
 | 
						||
+    , m_client(client)
 | 
						||
+    , m_pageProxyIDMap(pageProxyIDMap)
 | 
						||
+{
 | 
						||
+}
 | 
						||
+
 | 
						||
+InspectorPlaywrightAgent::~InspectorPlaywrightAgent() = default;
 | 
						||
+
 | 
						||
+void InspectorPlaywrightAgent::didCreateWebPageProxy(const WebPageProxy& page)
 | 
						||
+{
 | 
						||
+    if (m_isConnected)
 | 
						||
+        m_frontendDispatcher->pageProxyCreated(buildPageProxyInfo(page));
 | 
						||
+}
 | 
						||
+
 | 
						||
+void InspectorPlaywrightAgent::willDestroyWebPageProxy(const WebPageProxy& page)
 | 
						||
+{
 | 
						||
+    if (!m_isConnected)
 | 
						||
+        return;
 | 
						||
+
 | 
						||
+    m_frontendDispatcher->pageProxyDestroyed(toPageProxyIDProtocolString(page));
 | 
						||
+
 | 
						||
+    auto it = m_browserContextDeletions.find(page.sessionID());
 | 
						||
+    if (it == m_browserContextDeletions.end())
 | 
						||
+        return;
 | 
						||
+
 | 
						||
+    it->value->willDestroyPage(page);
 | 
						||
+    if (it->value->isFinished())
 | 
						||
+        m_browserContextDeletions.remove(it);
 | 
						||
+}
 | 
						||
+
 | 
						||
+void InspectorPlaywrightAgent::didCreateFrontendAndBackend(FrontendRouter*, BackendDispatcher*)
 | 
						||
+{
 | 
						||
+    m_isConnected = true;
 | 
						||
+}
 | 
						||
+
 | 
						||
+void InspectorPlaywrightAgent::didFailProvisionalLoad(WebPageProxy& page, uint64_t navigationID, const String& error)
 | 
						||
+{
 | 
						||
+    if (!m_isConnected)
 | 
						||
+        return;
 | 
						||
+
 | 
						||
+    m_frontendDispatcher->provisionalLoadFailed(toPageProxyIDProtocolString(page), String::number(navigationID), error);
 | 
						||
+}
 | 
						||
+
 | 
						||
+void InspectorPlaywrightAgent::willCreateNewPage(WebPageProxy& page, const WebCore::WindowFeatures& features, const URL& url)
 | 
						||
+{
 | 
						||
+    if (!m_isConnected)
 | 
						||
+        return;
 | 
						||
+
 | 
						||
+    m_frontendDispatcher->windowOpen(toPageProxyIDProtocolString(page), url.string(), getEnabledWindowFeatures(features));
 | 
						||
+}
 | 
						||
+
 | 
						||
+void InspectorPlaywrightAgent::willDestroyFrontendAndBackend(DisconnectReason)
 | 
						||
+{
 | 
						||
+    m_isConnected = false;
 | 
						||
+    m_browserContextDeletions.clear();
 | 
						||
+}
 | 
						||
+
 | 
						||
+void InspectorPlaywrightAgent::close(Ref<CloseCallback>&& callback)
 | 
						||
+{
 | 
						||
+    Vector<WebPageProxy*> pages;
 | 
						||
+    for (auto& pool : WebProcessPool::allProcessPools()) {
 | 
						||
+        for (auto& process : pool->processes()) {
 | 
						||
+            for (auto* page : process->pages())
 | 
						||
+                pages.append(page);
 | 
						||
+        }
 | 
						||
+    }
 | 
						||
+    for (auto* page : pages)
 | 
						||
+        page->closePage();
 | 
						||
+
 | 
						||
+    if (!WebProcessPool::allProcessPools().size()) {
 | 
						||
+        m_client->closeBrowser();
 | 
						||
+        callback->sendSuccess();
 | 
						||
+        return;
 | 
						||
+    }
 | 
						||
+
 | 
						||
+    WebProcessPool::allProcessPools().first()->syncLocalStorage([this, callback = WTFMove(callback)] () {
 | 
						||
+        if (!callback->isActive())
 | 
						||
+            return;
 | 
						||
+
 | 
						||
+        m_browserContexts.clear();
 | 
						||
+        if (m_client == nullptr) {
 | 
						||
+            callback->sendFailure("no platform delegate to close browser");
 | 
						||
+        } else {
 | 
						||
+            m_client->closeBrowser();
 | 
						||
+            callback->sendSuccess();
 | 
						||
+        }
 | 
						||
+    });
 | 
						||
+
 | 
						||
+}
 | 
						||
+
 | 
						||
+void InspectorPlaywrightAgent::createContext(ErrorString& errorString, String* browserContextID)
 | 
						||
+{
 | 
						||
+    BrowserContext browserContext = m_client->createBrowserContext(errorString);
 | 
						||
+    if (!errorString.isEmpty())
 | 
						||
+        return;
 | 
						||
+    browserContext.processPool->setPrimaryDataStore(*browserContext.dataStore);
 | 
						||
+    browserContext.processPool->ensureNetworkProcess(browserContext.dataStore.get());
 | 
						||
+    PAL::SessionID sessionID = browserContext.dataStore->sessionID();
 | 
						||
+    *browserContextID = toBrowserContextIDProtocolString(sessionID);
 | 
						||
+    m_browserContexts.set(*browserContextID, browserContext);
 | 
						||
+}
 | 
						||
+
 | 
						||
+void InspectorPlaywrightAgent::deleteContext(const String& browserContextID, Ref<DeleteContextCallback>&& callback)
 | 
						||
+{
 | 
						||
+    String errorString;
 | 
						||
+    BrowserContext browserContext = lookupBrowserContext(errorString, &browserContextID);
 | 
						||
+    if (!errorString.isEmpty()) {
 | 
						||
+        callback->sendFailure(errorString);
 | 
						||
+        return;
 | 
						||
+    }
 | 
						||
+
 | 
						||
+    Vector<WebPageProxy*> pages = browserContext.pages();
 | 
						||
+    PAL::SessionID sessionID = browserContext.dataStore->sessionID();
 | 
						||
+    m_browserContexts.remove(browserContextID);
 | 
						||
+    if (pages.isEmpty()) {
 | 
						||
+        callback->sendSuccess();
 | 
						||
+    } else {
 | 
						||
+        m_browserContextDeletions.set(sessionID, makeUnique<BrowserContextDeletion>(browserContext, pages.size(), WTFMove(callback)));
 | 
						||
+        for (auto* page : pages)
 | 
						||
+            page->closePage();
 | 
						||
+    }
 | 
						||
+    m_client->deleteBrowserContext(errorString, sessionID);
 | 
						||
+}
 | 
						||
+
 | 
						||
+void InspectorPlaywrightAgent::createPage(ErrorString& errorString, const String* browserContextID, String* pageProxyID)
 | 
						||
+{
 | 
						||
+    BrowserContext browserContext = lookupBrowserContext(errorString, browserContextID);
 | 
						||
+    if (!errorString.isEmpty())
 | 
						||
+        return;
 | 
						||
+    RefPtr<WebPageProxy> page = m_client->createPage(errorString, browserContext);
 | 
						||
+    if (!page)
 | 
						||
+        return;
 | 
						||
+    page->setPermissionsForAutomation(m_permissions.get(browserContextID ? *browserContextID : ""));
 | 
						||
+    *pageProxyID = toPageProxyIDProtocolString(*page);
 | 
						||
+}
 | 
						||
+
 | 
						||
+WebFrameProxy* InspectorPlaywrightAgent::frameForID(const String& frameID, String& error)
 | 
						||
+{
 | 
						||
+    size_t dotPos = frameID.find(".");
 | 
						||
+    if (dotPos == notFound) {
 | 
						||
+        error = "Invalid frame id"_s;
 | 
						||
+        return nullptr;
 | 
						||
+    }
 | 
						||
+
 | 
						||
+    if (!frameID.isAllASCII()) {
 | 
						||
+        error = "Invalid frame id"_s;
 | 
						||
+        return nullptr;
 | 
						||
+    }
 | 
						||
+
 | 
						||
+    String processIDString = frameID.left(dotPos);
 | 
						||
+    uint64_t pid = strtoull(processIDString.ascii().data(), 0, 10);
 | 
						||
+    auto processID = makeObjectIdentifier<WebCore::ProcessIdentifierType>(pid);
 | 
						||
+    WebProcessProxy* process = WebProcessProxy::processForIdentifier(processID);
 | 
						||
+    if (!process) {
 | 
						||
+        error = "Cannot find web process for the frame id"_s;
 | 
						||
+        return nullptr;
 | 
						||
+    }
 | 
						||
+
 | 
						||
+    String frameIDString = frameID.substring(dotPos + 1);
 | 
						||
+    uint64_t frameIDNumber = strtoull(frameIDString.ascii().data(), 0, 10);
 | 
						||
+    auto frameIdentifier = makeObjectIdentifier<WebCore::FrameIdentifierType>(frameIDNumber);
 | 
						||
+    WebFrameProxy* frame = process->webFrame(frameIdentifier);
 | 
						||
+    if (!frame) {
 | 
						||
+        error = "Cannot find web frame for the frame id"_s;
 | 
						||
+        return nullptr;
 | 
						||
+    }
 | 
						||
+
 | 
						||
+    return frame;
 | 
						||
+}
 | 
						||
+
 | 
						||
+void InspectorPlaywrightAgent::navigate(const String& url, const String& pageProxyID, const String* frameID, const String* referrer, Ref<NavigateCallback>&& callback)
 | 
						||
+{
 | 
						||
+    WebPageProxy* page = m_pageProxyIDMap.findPageProxy(pageProxyID);
 | 
						||
+    if (!page) {
 | 
						||
+        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() != page) {
 | 
						||
+            callback->sendFailure("Frame with specified is not from the specified page"_s);
 | 
						||
+            return;
 | 
						||
+        }
 | 
						||
+    }
 | 
						||
+
 | 
						||
+    page->inspectorController().navigate(WTFMove(resourceRequest), frame, [callback = WTFMove(callback)](const String& error, uint64_t navigationID) {
 | 
						||
+        if (!error.isEmpty()) {
 | 
						||
+            callback->sendFailure(error);
 | 
						||
+            return;
 | 
						||
+        }
 | 
						||
+
 | 
						||
+        Optional<String> navigationIDString;
 | 
						||
+        if (navigationID)
 | 
						||
+            navigationIDString = String::number(navigationID);
 | 
						||
+        callback->sendSuccess(navigationIDString);
 | 
						||
+    });
 | 
						||
+}
 | 
						||
+
 | 
						||
+void InspectorPlaywrightAgent::setIgnoreCertificateErrors(Inspector::ErrorString& errorString, const String* browserContextID, bool ignore)
 | 
						||
+{
 | 
						||
+    BrowserContext browserContext = lookupBrowserContext(errorString, browserContextID);
 | 
						||
+    if (!errorString.isEmpty())
 | 
						||
+        return;
 | 
						||
+    browserContext.processPool->setIgnoreTLSErrors(ignore);
 | 
						||
+}
 | 
						||
+
 | 
						||
+void InspectorPlaywrightAgent::getAllCookies(const String* browserContextID, Ref<GetAllCookiesCallback>&& callback) {
 | 
						||
+    String errorString;
 | 
						||
+    BrowserContext browserContext = lookupBrowserContext(errorString, browserContextID);
 | 
						||
+    if (!errorString.isEmpty()) {
 | 
						||
+        callback->sendFailure(errorString);
 | 
						||
+        return;
 | 
						||
+    }
 | 
						||
+
 | 
						||
+    PAL::SessionID sessionID = browserContext.dataStore->sessionID();
 | 
						||
+    NetworkProcessProxy* networkProcess = browserContext.processPool->networkProcess();
 | 
						||
+    networkProcess->sendWithAsyncReply(Messages::NetworkProcess::GetAllCookies(sessionID),
 | 
						||
+        [callback = WTFMove(callback)](Vector<WebCore::Cookie> allCookies) {
 | 
						||
+            if (!callback->isActive())
 | 
						||
+                return;
 | 
						||
+            auto cookies = JSON::ArrayOf<Inspector::Protocol::Playwright::Cookie>::create();
 | 
						||
+            for (const auto& cookie : allCookies)
 | 
						||
+                cookies->addItem(buildObjectForCookie(cookie));
 | 
						||
+            callback->sendSuccess(WTFMove(cookies));
 | 
						||
+        }, 0);
 | 
						||
+}
 | 
						||
+
 | 
						||
+void InspectorPlaywrightAgent::setCookies(const String* browserContextID, const JSON::Array& in_cookies, Ref<SetCookiesCallback>&& callback) {
 | 
						||
+    String errorString;
 | 
						||
+    BrowserContext browserContext = lookupBrowserContext(errorString, browserContextID);
 | 
						||
+    if (!errorString.isEmpty()) {
 | 
						||
+        callback->sendFailure(errorString);
 | 
						||
+        return;
 | 
						||
+    }
 | 
						||
+
 | 
						||
+    NetworkProcessProxy* networkProcess = browserContext.processPool->networkProcess();
 | 
						||
+    PAL::SessionID sessionID = browserContext.dataStore->sessionID();
 | 
						||
+
 | 
						||
+    Vector<WebCore::Cookie> cookies;
 | 
						||
+    for (unsigned i = 0; i < in_cookies.length(); ++i) {
 | 
						||
+        RefPtr<JSON::Value> item = in_cookies.get(i);
 | 
						||
+        RefPtr<JSON::Object> obj;
 | 
						||
+        if (!item->asObject(obj)) {
 | 
						||
+            errorString = "Invalid cookie payload format"_s;
 | 
						||
+            return;
 | 
						||
+        }
 | 
						||
+
 | 
						||
+        WebCore::Cookie cookie;
 | 
						||
+        if (!obj->getString("name", cookie.name) ||
 | 
						||
+            !obj->getString("value", cookie.value) ||
 | 
						||
+            !obj->getString("domain", cookie.domain) ||
 | 
						||
+            !obj->getString("path", cookie.path)) {
 | 
						||
+            errorString = "Invalid file payload format"_s;
 | 
						||
+            return;
 | 
						||
+        }
 | 
						||
+
 | 
						||
+        double expires;
 | 
						||
+        if (obj->getDouble("expires", expires) && expires != -1)
 | 
						||
+            cookie.expires = expires;
 | 
						||
+        obj->getBoolean("httpOnly", cookie.httpOnly);
 | 
						||
+        obj->getBoolean("secure", cookie.secure);
 | 
						||
+        obj->getBoolean("session", cookie.session);
 | 
						||
+        String sameSite;
 | 
						||
+        if (obj->getString("sameSite", sameSite)) {
 | 
						||
+            if (sameSite == "None")
 | 
						||
+                cookie.sameSite = WebCore::Cookie::SameSitePolicy::None;
 | 
						||
+            if (sameSite == "Lax")
 | 
						||
+                cookie.sameSite = WebCore::Cookie::SameSitePolicy::Lax;
 | 
						||
+            if (sameSite == "Strict")
 | 
						||
+                cookie.sameSite = WebCore::Cookie::SameSitePolicy::Strict;
 | 
						||
+        }
 | 
						||
+        cookies.append(WTFMove(cookie));
 | 
						||
+    }
 | 
						||
+
 | 
						||
+    networkProcess->sendWithAsyncReply(Messages::NetworkProcess::SetCookies(sessionID, WTFMove(cookies)),
 | 
						||
+        [callback = WTFMove(callback)](bool success) {
 | 
						||
+            if (!callback->isActive())
 | 
						||
+                return;
 | 
						||
+
 | 
						||
+            if (success)
 | 
						||
+                callback->sendSuccess();
 | 
						||
+            else
 | 
						||
+                callback->sendFailure("Internal error: no network storage"_s);
 | 
						||
+            callback->sendSuccess();
 | 
						||
+        }, 0);
 | 
						||
+}
 | 
						||
+
 | 
						||
+void InspectorPlaywrightAgent::deleteAllCookies(const String* browserContextID, Ref<DeleteAllCookiesCallback>&& callback) {
 | 
						||
+    String errorString;
 | 
						||
+    BrowserContext browserContext = lookupBrowserContext(errorString, browserContextID);
 | 
						||
+    if (!errorString.isEmpty()) {
 | 
						||
+        callback->sendFailure(errorString);
 | 
						||
+        return;
 | 
						||
+    }
 | 
						||
+
 | 
						||
+    NetworkProcessProxy* networkProcess = browserContext.processPool->networkProcess();
 | 
						||
+    PAL::SessionID sessionID = browserContext.dataStore->sessionID();
 | 
						||
+    networkProcess->sendWithAsyncReply(Messages::NetworkProcess::DeleteAllCookies(sessionID),
 | 
						||
+        [callback = WTFMove(callback)](bool success) {
 | 
						||
+            if (!callback->isActive())
 | 
						||
+                return;
 | 
						||
+            if (success)
 | 
						||
+                callback->sendSuccess();
 | 
						||
+            else
 | 
						||
+                callback->sendFailure("Internal error: no network storage"_s);
 | 
						||
+        }, 0);
 | 
						||
+}
 | 
						||
+
 | 
						||
+void InspectorPlaywrightAgent::grantPermissions(Inspector::ErrorString& errorString, const String* browserContextID, const String& origin, const JSON::Array& values)
 | 
						||
+{
 | 
						||
+    BrowserContext browserContext = lookupBrowserContext(errorString, browserContextID);
 | 
						||
+    if (!errorString.isEmpty())
 | 
						||
+        return;
 | 
						||
+    HashSet<String> set;
 | 
						||
+    for (const auto& value : values) {
 | 
						||
+        String name;
 | 
						||
+        if (!value->asString(name)) {
 | 
						||
+            errorString = "Permission must be a string"_s;
 | 
						||
+            return;
 | 
						||
+        }
 | 
						||
+        set.add(name);
 | 
						||
+    }
 | 
						||
+    String key = browserContextID ? *browserContextID : "";
 | 
						||
+    auto it = m_permissions.add(key, Permissions()).iterator;
 | 
						||
+    it->value.set(origin, WTFMove(set));
 | 
						||
+    Vector<WebPageProxy*> pages;
 | 
						||
+    for (auto& process : browserContext.processPool->processes()) {
 | 
						||
+        for (auto* page : process->pages())
 | 
						||
+            page->setPermissionsForAutomation(it->value);
 | 
						||
+    }
 | 
						||
+}
 | 
						||
+
 | 
						||
+void InspectorPlaywrightAgent::resetPermissions(Inspector::ErrorString& errorString, const String* browserContextID)
 | 
						||
+{
 | 
						||
+    BrowserContext browserContext = lookupBrowserContext(errorString, browserContextID);
 | 
						||
+    if (!errorString.isEmpty())
 | 
						||
+        return;
 | 
						||
+    m_permissions.clear();
 | 
						||
+    for (auto& process : browserContext.processPool->processes()) {
 | 
						||
+        for (auto* page : process->pages())
 | 
						||
+            page->setPermissionsForAutomation(HashMap<String, HashSet<String>>());
 | 
						||
+    }
 | 
						||
+}
 | 
						||
+
 | 
						||
+void InspectorPlaywrightAgent::setLanguages(Inspector::ErrorString& errorString, const JSON::Array& languages, const String* browserContextID)
 | 
						||
+{
 | 
						||
+    BrowserContext browserContext = lookupBrowserContext(errorString, browserContextID);
 | 
						||
+    if (!errorString.isEmpty())
 | 
						||
+        return;
 | 
						||
+
 | 
						||
+    Vector<String> items;
 | 
						||
+    for (const auto& value : languages) {
 | 
						||
+        String language;
 | 
						||
+        if (!value->asString(language)) {
 | 
						||
+            errorString = "Language must be a string"_s;
 | 
						||
+            return;
 | 
						||
+        }
 | 
						||
+        items.append(language);
 | 
						||
+    }
 | 
						||
+
 | 
						||
+    browserContext.processPool->setLanguagesForAutomation(WTFMove(items));
 | 
						||
+}
 | 
						||
+
 | 
						||
+void InspectorPlaywrightAgent::setGeolocationOverride(Inspector::ErrorString& errorString, const String* browserContextID, const JSON::Object* geolocation)
 | 
						||
+{
 | 
						||
+    BrowserContext browserContext = lookupBrowserContext(errorString, browserContextID);
 | 
						||
+    if (!errorString.isEmpty())
 | 
						||
+        return;
 | 
						||
+    auto* geoManager = browserContext.processPool->supplement<WebGeolocationManagerProxy>();
 | 
						||
+    if (!geoManager) {
 | 
						||
+        errorString = "Internal error: geolocation manager is not available.";
 | 
						||
+        return;
 | 
						||
+    }
 | 
						||
+    if (geolocation) {
 | 
						||
+        double timestamp = 0;
 | 
						||
+        double latitude = 0;
 | 
						||
+        double longitude = 0;
 | 
						||
+        double accuracy = 0;
 | 
						||
+        if (!geolocation->getDouble("timestamp", timestamp) ||
 | 
						||
+            !geolocation->getDouble("latitude", latitude) ||
 | 
						||
+            !geolocation->getDouble("longitude", longitude) ||
 | 
						||
+            !geolocation->getDouble("accuracy", accuracy)) {
 | 
						||
+            errorString = "Invalid geolocation format"_s;
 | 
						||
+            return;
 | 
						||
+        }
 | 
						||
+        auto position = WebGeolocationPosition::create(WebCore::GeolocationPositionData(timestamp, latitude, longitude, accuracy));
 | 
						||
+        geoManager->providerDidChangePosition(&position.get());
 | 
						||
+    } else {
 | 
						||
+        geoManager->providerDidFailToDeterminePosition("Position unavailable"_s);
 | 
						||
+    }
 | 
						||
+}
 | 
						||
+
 | 
						||
+String InspectorPlaywrightAgent::toBrowserContextIDProtocolString(const PAL::SessionID& sessionID)
 | 
						||
+{
 | 
						||
+    StringBuilder builder;
 | 
						||
+    builder.append(hex(sessionID.toUInt64(), 16));
 | 
						||
+    return builder.toString();
 | 
						||
+}
 | 
						||
+
 | 
						||
+String InspectorPlaywrightAgent::toPageProxyIDProtocolString(const WebPageProxy& page)
 | 
						||
+{
 | 
						||
+    return makeString(page.identifier().toUInt64());
 | 
						||
+}
 | 
						||
+
 | 
						||
+BrowserContext InspectorPlaywrightAgent::lookupBrowserContext(ErrorString& errorString, const String* browserContextID)
 | 
						||
+{
 | 
						||
+    if (!browserContextID) {
 | 
						||
+        BrowserContext context;
 | 
						||
+        if (!WebProcessPool::allProcessPools().size()) {
 | 
						||
+            errorString = "Browser started with no default context"_s;
 | 
						||
+            return context;
 | 
						||
+        }
 | 
						||
+        auto* pool = WebProcessPool::allProcessPools().first();
 | 
						||
+        context.processPool = pool;
 | 
						||
+        context.dataStore = pool->websiteDataStore();
 | 
						||
+        return context;
 | 
						||
+    }
 | 
						||
+
 | 
						||
+    BrowserContext browserContext = m_browserContexts.get(*browserContextID);
 | 
						||
+    if (!browserContext.processPool)
 | 
						||
+        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..2b5518c9f7b054746a98552c24c8752eb7acb10b
 | 
						||
--- /dev/null
 | 
						||
+++ b/Source/WebKit/UIProcess/InspectorPlaywrightAgent.h
 | 
						||
@@ -0,0 +1,122 @@
 | 
						||
+/*
 | 
						||
+ * Copyright (C) 2019 Microsoft Corporation.
 | 
						||
+ *
 | 
						||
+ * Redistribution and use in source and binary forms, with or without
 | 
						||
+ * modification, are permitted provided that the following conditions
 | 
						||
+ * are met:
 | 
						||
+ * 1. Redistributions of source code must retain the above copyright
 | 
						||
+ *    notice, this list of conditions and the following disclaimer.
 | 
						||
+ * 2. Redistributions in binary form must reproduce the above copyright
 | 
						||
+ *    notice, this list of conditions and the following disclaimer in the
 | 
						||
+ *    documentation and/or other materials provided with the distribution.
 | 
						||
+ *
 | 
						||
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
						||
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
						||
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
						||
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | 
						||
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | 
						||
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
						||
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | 
						||
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | 
						||
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
						||
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
						||
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
						||
+ */
 | 
						||
+
 | 
						||
+#pragma once
 | 
						||
+
 | 
						||
+#if ENABLE(REMOTE_INSPECTOR)
 | 
						||
+
 | 
						||
+#include "InspectorPlaywrightAgentClient.h"
 | 
						||
+#include <JavaScriptCore/InspectorAgentBase.h>
 | 
						||
+#include <JavaScriptCore/InspectorBackendDispatchers.h>
 | 
						||
+#include <wtf/HashMap.h>
 | 
						||
+#include <pal/SessionID.h>
 | 
						||
+#include <wtf/Forward.h>
 | 
						||
+#include <wtf/Noncopyable.h>
 | 
						||
+#include <wtf/URL.h>
 | 
						||
+
 | 
						||
+namespace Inspector {
 | 
						||
+class BackendDispatcher;
 | 
						||
+class FrontendChannel;
 | 
						||
+class FrontendRouter;
 | 
						||
+class PlaywrightFrontendDispatcher;
 | 
						||
+}
 | 
						||
+
 | 
						||
+namespace PAL {
 | 
						||
+class SessionID;
 | 
						||
+}
 | 
						||
+
 | 
						||
+namespace WebCore {
 | 
						||
+struct WindowFeatures;
 | 
						||
+}
 | 
						||
+
 | 
						||
+namespace WebKit {
 | 
						||
+
 | 
						||
+class NetworkProcess;
 | 
						||
+class WebFrameProxy;
 | 
						||
+class WebProcessPool;
 | 
						||
+
 | 
						||
+class PageProxyIDMap {
 | 
						||
+public:
 | 
						||
+    virtual WebPageProxy* findPageProxy(const String& pageProxyID) = 0;
 | 
						||
+
 | 
						||
+protected:
 | 
						||
+    virtual ~PageProxyIDMap() = default;
 | 
						||
+};
 | 
						||
+
 | 
						||
+class InspectorPlaywrightAgent final : public Inspector::InspectorAgentBase, public Inspector::PlaywrightBackendDispatcherHandler {
 | 
						||
+    WTF_MAKE_NONCOPYABLE(InspectorPlaywrightAgent);
 | 
						||
+    WTF_MAKE_FAST_ALLOCATED;
 | 
						||
+public:
 | 
						||
+    InspectorPlaywrightAgent(Inspector::FrontendRouter&, Inspector::BackendDispatcher&, InspectorPlaywrightAgentClient*, PageProxyIDMap&);
 | 
						||
+    ~InspectorPlaywrightAgent() override;
 | 
						||
+
 | 
						||
+    void didCreateWebPageProxy(const WebPageProxy&);
 | 
						||
+    void willDestroyWebPageProxy(const WebPageProxy&);
 | 
						||
+    void didFailProvisionalLoad(WebPageProxy&, uint64_t navigationID, const String& error);
 | 
						||
+    void willCreateNewPage(WebPageProxy&, const WebCore::WindowFeatures&, const URL&);
 | 
						||
+
 | 
						||
+    // InspectorAgentBase
 | 
						||
+    void didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*) override;
 | 
						||
+    void willDestroyFrontendAndBackend(Inspector::DisconnectReason) override;
 | 
						||
+
 | 
						||
+    // PlaywrightDispatcherHandler
 | 
						||
+    void close(Ref<CloseCallback>&&) override;
 | 
						||
+    void createContext(Inspector::ErrorString&, String* browserContextID) override;
 | 
						||
+    void deleteContext(const String& browserContextID, Ref<DeleteContextCallback>&& callback) override;
 | 
						||
+    void createPage(Inspector::ErrorString&, const String* browserContextID, String* pageProxyID) override;
 | 
						||
+    void navigate(const String& url, const String& pageProxyID, const String* frameId, const String* referrer, Ref<NavigateCallback>&&) override;
 | 
						||
+    void setIgnoreCertificateErrors(Inspector::ErrorString&, const String* browserContextID, bool ignore) override;
 | 
						||
+
 | 
						||
+    void getAllCookies(const String* browserContextID, Ref<GetAllCookiesCallback>&&) override;
 | 
						||
+    void setCookies(const String* browserContextID, const JSON::Array& in_cookies, Ref<SetCookiesCallback>&&) override;
 | 
						||
+    void deleteAllCookies(const String* browserContextID, Ref<DeleteAllCookiesCallback>&&) override;
 | 
						||
+
 | 
						||
+    void grantPermissions(Inspector::ErrorString&, const String* browserContextID, const String& origin, const JSON::Array& permissions) override;
 | 
						||
+    void resetPermissions(Inspector::ErrorString&, const String* browserContextID) override;
 | 
						||
+    void setGeolocationOverride(Inspector::ErrorString&, const String* browserContextID, const JSON::Object* geolocation) override;
 | 
						||
+    void setLanguages(Inspector::ErrorString&, const JSON::Array& languages, const String* browserContextID) override;
 | 
						||
+
 | 
						||
+    static String toBrowserContextIDProtocolString(const PAL::SessionID&);
 | 
						||
+    static String toPageProxyIDProtocolString(const WebPageProxy&);
 | 
						||
+
 | 
						||
+private:
 | 
						||
+    class BrowserContextDeletion;
 | 
						||
+    BrowserContext lookupBrowserContext(Inspector::ErrorString&, const String* browserContextID);
 | 
						||
+    WebFrameProxy* frameForID(const String& frameID, String& error);
 | 
						||
+
 | 
						||
+    std::unique_ptr<Inspector::PlaywrightFrontendDispatcher> m_frontendDispatcher;
 | 
						||
+    Ref<Inspector::PlaywrightBackendDispatcher> m_backendDispatcher;
 | 
						||
+    InspectorPlaywrightAgentClient* m_client;
 | 
						||
+    PageProxyIDMap& m_pageProxyIDMap;
 | 
						||
+    using Permissions = HashMap<String, HashSet<String>>;
 | 
						||
+    HashMap<String, Permissions> m_permissions;
 | 
						||
+    HashMap<String, BrowserContext> m_browserContexts;
 | 
						||
+    HashMap<PAL::SessionID, std::unique_ptr<BrowserContextDeletion>> m_browserContextDeletions;
 | 
						||
+    bool m_isConnected { 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..d2f02082007b41b9e20dc6bb4751743835d60fce
 | 
						||
--- /dev/null
 | 
						||
+++ b/Source/WebKit/UIProcess/InspectorPlaywrightAgentClient.h
 | 
						||
@@ -0,0 +1,56 @@
 | 
						||
+/*
 | 
						||
+ * 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 <pal/SessionID.h>
 | 
						||
+#include <wtf/Forward.h>
 | 
						||
+
 | 
						||
+namespace WebKit {
 | 
						||
+
 | 
						||
+class WebsiteDataStore;
 | 
						||
+class WebPageProxy;
 | 
						||
+class WebProcessPool;
 | 
						||
+
 | 
						||
+struct BrowserContext {
 | 
						||
+    Vector<WebPageProxy*> pages() const;
 | 
						||
+    RefPtr<WebsiteDataStore> dataStore;
 | 
						||
+    RefPtr<WebProcessPool> processPool;
 | 
						||
+};
 | 
						||
+
 | 
						||
+class InspectorPlaywrightAgentClient {
 | 
						||
+public:
 | 
						||
+    virtual ~InspectorPlaywrightAgentClient() = default;
 | 
						||
+    virtual RefPtr<WebKit::WebPageProxy> createPage(WTF::String& error, const BrowserContext& context) = 0;
 | 
						||
+    virtual void closeBrowser() = 0;
 | 
						||
+    virtual BrowserContext createBrowserContext(WTF::String& error) = 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 8a871bf2916d5eab86becf5fde0faed79283d88c..a19a429c4d53edf81c3028c7053265e6c22c171a 100644
 | 
						||
--- a/Source/WebKit/UIProcess/Launcher/win/ProcessLauncherWin.cpp
 | 
						||
+++ b/Source/WebKit/UIProcess/Launcher/win/ProcessLauncherWin.cpp
 | 
						||
@@ -92,8 +92,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/RemoteInspectorPipe.cpp b/Source/WebKit/UIProcess/RemoteInspectorPipe.cpp
 | 
						||
new file mode 100644
 | 
						||
index 0000000000000000000000000000000000000000..45d8dc48601548951dc5c5ecd68958dbd47c89db
 | 
						||
--- /dev/null
 | 
						||
+++ b/Source/WebKit/UIProcess/RemoteInspectorPipe.cpp
 | 
						||
@@ -0,0 +1,220 @@
 | 
						||
+/*
 | 
						||
+ * 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 "BrowserInspectorController.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(BrowserInspectorController& browserInspectorController)
 | 
						||
+    : m_remoteFrontendChannel(makeUnique<RemoteFrontendChannel>())
 | 
						||
+    , m_browserInspectorController(browserInspectorController)
 | 
						||
+{
 | 
						||
+    start();
 | 
						||
+}
 | 
						||
+
 | 
						||
+RemoteInspectorPipe::~RemoteInspectorPipe()
 | 
						||
+{
 | 
						||
+    stop();
 | 
						||
+}
 | 
						||
+
 | 
						||
+bool RemoteInspectorPipe::start()
 | 
						||
+{
 | 
						||
+    WTF::RunLoop::initializeMainRunLoop();
 | 
						||
+    if (m_receiverThread)
 | 
						||
+        return true;
 | 
						||
+
 | 
						||
+#if PLATFORM(WIN)
 | 
						||
+    readHandle = reinterpret_cast<HANDLE>(_get_osfhandle(readFD));
 | 
						||
+    writeHandle = reinterpret_cast<HANDLE>(_get_osfhandle(writeFD));
 | 
						||
+#endif
 | 
						||
+
 | 
						||
+    m_browserInspectorController.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_browserInspectorController.disconnectFrontend();
 | 
						||
+
 | 
						||
+    m_terminated = true;
 | 
						||
+    m_receiverThread->waitForCompletion();
 | 
						||
+    m_receiverThread = nullptr;
 | 
						||
+}
 | 
						||
+
 | 
						||
+void RemoteInspectorPipe::workerRun()
 | 
						||
+{
 | 
						||
+    const size_t bufSize = 256 * 1024;
 | 
						||
+    auto buffer = makeUniqueArray<char>(bufSize);
 | 
						||
+    Vector<char> line;
 | 
						||
+    while (!m_terminated) {
 | 
						||
+        size_t size = ReadBytes(buffer.get(), bufSize, false);
 | 
						||
+        if (!size)
 | 
						||
+            break;
 | 
						||
+        size_t start = 0;
 | 
						||
+        size_t end = line.size();
 | 
						||
+        line.append(buffer.get(), size);
 | 
						||
+        while (true) {
 | 
						||
+            for (; end < line.size(); ++end) {
 | 
						||
+                if (line[end] == '\0')
 | 
						||
+                    break;
 | 
						||
+            }
 | 
						||
+            if (end == line.size())
 | 
						||
+                break;
 | 
						||
+
 | 
						||
+            if (end > start) {
 | 
						||
+                String message = String::fromUTF8(line.data() + start, end - start);
 | 
						||
+                RunLoop::main().dispatch([this, message] {
 | 
						||
+                    if (!m_terminated)
 | 
						||
+                        m_browserInspectorController.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..b1307da8b9ee02d63ef98d276473d65a1d8c3556
 | 
						||
--- /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 BrowserInspectorController;
 | 
						||
+
 | 
						||
+class RemoteInspectorPipe {
 | 
						||
+    WTF_MAKE_NONCOPYABLE(RemoteInspectorPipe);
 | 
						||
+    WTF_MAKE_FAST_ALLOCATED;
 | 
						||
+public:
 | 
						||
+    explicit RemoteInspectorPipe(BrowserInspectorController&);
 | 
						||
+    ~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;
 | 
						||
+    BrowserInspectorController& m_browserInspectorController;
 | 
						||
+};
 | 
						||
+
 | 
						||
+} // namespace WebKit
 | 
						||
+
 | 
						||
+#endif // ENABLE(REMOTE_INSPECTOR)
 | 
						||
diff --git a/Source/WebKit/UIProcess/WebAuthentication/AuthenticatorManager.cpp b/Source/WebKit/UIProcess/WebAuthentication/AuthenticatorManager.cpp
 | 
						||
index 977837517e1708bf2aa551fe64d6a25403cdaaaa..128a241c24cf12bb89af682f93566da2686db76e 100644
 | 
						||
--- a/Source/WebKit/UIProcess/WebAuthentication/AuthenticatorManager.cpp
 | 
						||
+++ b/Source/WebKit/UIProcess/WebAuthentication/AuthenticatorManager.cpp
 | 
						||
@@ -35,6 +35,7 @@
 | 
						||
 #include "NfcService.h"
 | 
						||
 #include "WebPageProxy.h"
 | 
						||
 #include "WebPreferencesKeys.h"
 | 
						||
+#include "WebProcessProxy.h"
 | 
						||
 #include <WebCore/AuthenticatorAssertionResponse.h>
 | 
						||
 #include <WebCore/AuthenticatorTransport.h>
 | 
						||
 #include <WebCore/PublicKeyCredentialCreationOptions.h>
 | 
						||
diff --git a/Source/WebKit/UIProcess/WebAuthentication/Mock/MockLocalConnection.h b/Source/WebKit/UIProcess/WebAuthentication/Mock/MockLocalConnection.h
 | 
						||
index dee773c3e132e37b72727f3538714017b1d96cf3..c8273246ed7f7de53ec6b4d4132069450952db29 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/WebGeolocationManagerProxy.cpp b/Source/WebKit/UIProcess/WebGeolocationManagerProxy.cpp
 | 
						||
index 04f3227cd55c992a42cd96a3f25d697aed7965a2..f0d36935f47bab03ea2ec50b705092068ecd3efa 100644
 | 
						||
--- a/Source/WebKit/UIProcess/WebGeolocationManagerProxy.cpp
 | 
						||
+++ b/Source/WebKit/UIProcess/WebGeolocationManagerProxy.cpp
 | 
						||
@@ -128,7 +128,8 @@ void WebGeolocationManagerProxy::startUpdating(IPC::Connection& connection, WebP
 | 
						||
     if (!wasUpdating) {
 | 
						||
         m_provider->setEnableHighAccuracy(*this, isHighAccuracyEnabled());
 | 
						||
         m_provider->startUpdating(*this);
 | 
						||
-    } else if (m_lastPosition)
 | 
						||
+    }
 | 
						||
+    if (m_lastPosition)
 | 
						||
         connection.send(Messages::WebGeolocationManager::DidChangePosition(m_lastPosition.value()), 0);
 | 
						||
 }
 | 
						||
 
 | 
						||
diff --git a/Source/WebKit/UIProcess/WebPageInspectorEmulationAgent.cpp b/Source/WebKit/UIProcess/WebPageInspectorEmulationAgent.cpp
 | 
						||
new file mode 100644
 | 
						||
index 0000000000000000000000000000000000000000..c863bd49011debe4b06cab64c113810809633777
 | 
						||
--- /dev/null
 | 
						||
+++ b/Source/WebKit/UIProcess/WebPageInspectorEmulationAgent.cpp
 | 
						||
@@ -0,0 +1,124 @@
 | 
						||
+/*
 | 
						||
+ * Copyright (C) 2019 Microsoft Corporation.
 | 
						||
+ *
 | 
						||
+ * Redistribution and use in source and binary forms, with or without
 | 
						||
+ * modification, are permitted provided that the following conditions
 | 
						||
+ * are met:
 | 
						||
+ * 1. Redistributions of source code must retain the above copyright
 | 
						||
+ *    notice, this list of conditions and the following disclaimer.
 | 
						||
+ * 2. Redistributions in binary form must reproduce the above copyright
 | 
						||
+ *    notice, this list of conditions and the following disclaimer in the
 | 
						||
+ *    documentation and/or other materials provided with the distribution.
 | 
						||
+ *
 | 
						||
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
						||
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
						||
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
						||
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | 
						||
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | 
						||
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
						||
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | 
						||
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | 
						||
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
						||
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
						||
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
						||
+ */
 | 
						||
+
 | 
						||
+#include "config.h"
 | 
						||
+#include "WebPageInspectorEmulationAgent.h"
 | 
						||
+
 | 
						||
+#include "APIPageConfiguration.h"
 | 
						||
+#include "WebPageProxy.h"
 | 
						||
+#include "WebPreferences.h"
 | 
						||
+#include "PageClient.h"
 | 
						||
+#include <JavaScriptCore/InspectorFrontendRouter.h>
 | 
						||
+#include <WebCore/Credential.h>
 | 
						||
+
 | 
						||
+
 | 
						||
+namespace WebKit {
 | 
						||
+
 | 
						||
+using namespace Inspector;
 | 
						||
+
 | 
						||
+WebPageInspectorEmulationAgent::WebPageInspectorEmulationAgent(BackendDispatcher& backendDispatcher, WebPageProxy& page)
 | 
						||
+    : InspectorAgentBase("Emulation"_s)
 | 
						||
+    , m_backendDispatcher(EmulationBackendDispatcher::create(backendDispatcher, this))
 | 
						||
+    , m_page(page)
 | 
						||
+{
 | 
						||
+}
 | 
						||
+
 | 
						||
+WebPageInspectorEmulationAgent::~WebPageInspectorEmulationAgent()
 | 
						||
+{
 | 
						||
+}
 | 
						||
+
 | 
						||
+void WebPageInspectorEmulationAgent::didCreateFrontendAndBackend(FrontendRouter*, BackendDispatcher*)
 | 
						||
+{
 | 
						||
+}
 | 
						||
+
 | 
						||
+void WebPageInspectorEmulationAgent::willDestroyFrontendAndBackend(DisconnectReason)
 | 
						||
+{
 | 
						||
+   m_commandsToRunWhenShown.clear();
 | 
						||
+}
 | 
						||
+
 | 
						||
+void WebPageInspectorEmulationAgent::setDeviceMetricsOverride(int width, int height, double deviceScaleFactor, bool fixedlayout, Ref<SetDeviceMetricsOverrideCallback>&& callback)
 | 
						||
+{
 | 
						||
+#if PLATFORM(GTK)
 | 
						||
+    // On gtk, fixed layout doesn't work with compositing enabled
 | 
						||
+    // FIXME: This turns off compositing forever, even if fixedLayout is disabled.
 | 
						||
+    if (fixedlayout) {
 | 
						||
+        auto copy = m_page.preferences().copy();
 | 
						||
+        copy->setAcceleratedCompositingEnabled(false);
 | 
						||
+        m_page.setPreferences(copy);
 | 
						||
+    }
 | 
						||
+#endif
 | 
						||
+
 | 
						||
+    m_page.setCustomDeviceScaleFactor(deviceScaleFactor);
 | 
						||
+    m_page.setUseFixedLayout(fixedlayout);
 | 
						||
+    if (!m_page.pageClient().isViewVisible() && m_page.configuration().relatedPage()) {
 | 
						||
+        m_commandsToRunWhenShown.append([this, width, height, callback = WTFMove(callback)]() mutable {
 | 
						||
+            setSize(width, height, WTFMove(callback));
 | 
						||
+        });
 | 
						||
+    } else {
 | 
						||
+        setSize(width, height, WTFMove(callback));
 | 
						||
+    }
 | 
						||
+}
 | 
						||
+
 | 
						||
+void WebPageInspectorEmulationAgent::setSize(int width, int height, Ref<SetDeviceMetricsOverrideCallback>&& callback)
 | 
						||
+{
 | 
						||
+    platformSetSize(width, height, [callback = WTFMove(callback)](const String& error) {
 | 
						||
+        if (error.isEmpty())
 | 
						||
+            callback->sendSuccess();
 | 
						||
+        else
 | 
						||
+            callback->sendFailure(error);
 | 
						||
+    });
 | 
						||
+}
 | 
						||
+
 | 
						||
+void WebPageInspectorEmulationAgent::setJavaScriptEnabled(ErrorString&, bool enabled)
 | 
						||
+{
 | 
						||
+    auto copy = m_page.preferences().copy();
 | 
						||
+    copy->setJavaScriptEnabled(enabled);
 | 
						||
+    m_page.setPreferences(copy);
 | 
						||
+}
 | 
						||
+
 | 
						||
+void WebPageInspectorEmulationAgent::setAuthCredentials(Inspector::ErrorString&, const String* username, const String* password)
 | 
						||
+{
 | 
						||
+    if (username && password)
 | 
						||
+        m_page.setAuthCredentialsForAutomation(WebCore::Credential(*username, *password, CredentialPersistencePermanent));
 | 
						||
+    else
 | 
						||
+        m_page.setAuthCredentialsForAutomation(Optional<WebCore::Credential>());
 | 
						||
+}
 | 
						||
+
 | 
						||
+void WebPageInspectorEmulationAgent::setActiveAndFocused(Inspector::ErrorString&, const bool* active)
 | 
						||
+{
 | 
						||
+    Optional<bool> value;
 | 
						||
+    if (active)
 | 
						||
+      value = *active;
 | 
						||
+    m_page.setActiveForAutomation(value);
 | 
						||
+}
 | 
						||
+
 | 
						||
+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..61969d8e4598f624df03beb56fc67375b9386edf
 | 
						||
--- /dev/null
 | 
						||
+++ b/Source/WebKit/UIProcess/WebPageInspectorEmulationAgent.h
 | 
						||
@@ -0,0 +1,72 @@
 | 
						||
+/*
 | 
						||
+ * Copyright (C) 2019 Microsoft Corporation.
 | 
						||
+ *
 | 
						||
+ * Redistribution and use in source and binary forms, with or without
 | 
						||
+ * modification, are permitted provided that the following conditions
 | 
						||
+ * are met:
 | 
						||
+ * 1. Redistributions of source code must retain the above copyright
 | 
						||
+ *    notice, this list of conditions and the following disclaimer.
 | 
						||
+ * 2. Redistributions in binary form must reproduce the above copyright
 | 
						||
+ *    notice, this list of conditions and the following disclaimer in the
 | 
						||
+ *    documentation and/or other materials provided with the distribution.
 | 
						||
+ *
 | 
						||
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
						||
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
						||
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
						||
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | 
						||
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | 
						||
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
						||
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | 
						||
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | 
						||
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
						||
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
						||
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
						||
+ */
 | 
						||
+
 | 
						||
+#pragma once
 | 
						||
+
 | 
						||
+#include <JavaScriptCore/InspectorAgentBase.h>
 | 
						||
+#include <JavaScriptCore/InspectorBackendDispatchers.h>
 | 
						||
+
 | 
						||
+#include <wtf/Forward.h>
 | 
						||
+#include <wtf/Function.h>
 | 
						||
+#include <wtf/Noncopyable.h>
 | 
						||
+#include <wtf/Vector.h>
 | 
						||
+
 | 
						||
+namespace Inspector {
 | 
						||
+class BackendDispatcher;
 | 
						||
+class FrontendChannel;
 | 
						||
+class FrontendRouter;
 | 
						||
+}
 | 
						||
+
 | 
						||
+namespace WebKit {
 | 
						||
+
 | 
						||
+class WebPageProxy;
 | 
						||
+
 | 
						||
+class WebPageInspectorEmulationAgent : public Inspector::InspectorAgentBase, public Inspector::EmulationBackendDispatcherHandler {
 | 
						||
+    WTF_MAKE_NONCOPYABLE(WebPageInspectorEmulationAgent);
 | 
						||
+    WTF_MAKE_FAST_ALLOCATED;
 | 
						||
+public:
 | 
						||
+    WebPageInspectorEmulationAgent(Inspector::BackendDispatcher& backendDispatcher, WebPageProxy& page);
 | 
						||
+    ~WebPageInspectorEmulationAgent() override;
 | 
						||
+
 | 
						||
+    void didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*) override;
 | 
						||
+    void willDestroyFrontendAndBackend(Inspector::DisconnectReason) override;
 | 
						||
+
 | 
						||
+    void setDeviceMetricsOverride(int width, int height, double deviceScaleFactor, bool fixedlayout, Ref<SetDeviceMetricsOverrideCallback>&&) override;
 | 
						||
+    void setJavaScriptEnabled(Inspector::ErrorString&, bool enabled) override;
 | 
						||
+    void setAuthCredentials(Inspector::ErrorString&, const String*, const String*) override;
 | 
						||
+    void setActiveAndFocused(Inspector::ErrorString&, const bool*) 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;
 | 
						||
+};
 | 
						||
+
 | 
						||
+} // namespace WebKit
 | 
						||
diff --git a/Source/WebKit/UIProcess/WebPageInspectorInputAgent.cpp b/Source/WebKit/UIProcess/WebPageInspectorInputAgent.cpp
 | 
						||
new file mode 100644
 | 
						||
index 0000000000000000000000000000000000000000..5043224bbd6378175c9ca7dce63fc5a233649878
 | 
						||
--- /dev/null
 | 
						||
+++ b/Source/WebKit/UIProcess/WebPageInspectorInputAgent.cpp
 | 
						||
@@ -0,0 +1,253 @@
 | 
						||
+/*
 | 
						||
+ * Copyright (C) 2019 Microsoft Corporation.
 | 
						||
+ *
 | 
						||
+ * Redistribution and use in source and binary forms, with or without
 | 
						||
+ * modification, are permitted provided that the following conditions
 | 
						||
+ * are met:
 | 
						||
+ * 1. Redistributions of source code must retain the above copyright
 | 
						||
+ *    notice, this list of conditions and the following disclaimer.
 | 
						||
+ * 2. Redistributions in binary form must reproduce the above copyright
 | 
						||
+ *    notice, this list of conditions and the following disclaimer in the
 | 
						||
+ *    documentation and/or other materials provided with the distribution.
 | 
						||
+ *
 | 
						||
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
						||
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
						||
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
						||
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | 
						||
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | 
						||
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
						||
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | 
						||
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | 
						||
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
						||
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
						||
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
						||
+ */
 | 
						||
+
 | 
						||
+#include "config.h"
 | 
						||
+#include "WebPageInspectorInputAgent.h"
 | 
						||
+
 | 
						||
+#include "NativeWebKeyboardEvent.h"
 | 
						||
+#include "NativeWebMouseEvent.h"
 | 
						||
+#include "WebPageProxy.h"
 | 
						||
+#include <wtf/MathExtras.h>
 | 
						||
+
 | 
						||
+namespace WebKit {
 | 
						||
+
 | 
						||
+using namespace Inspector;
 | 
						||
+
 | 
						||
+namespace {
 | 
						||
+
 | 
						||
+template<class T>
 | 
						||
+class CallbackList {
 | 
						||
+    WTF_MAKE_FAST_ALLOCATED;
 | 
						||
+public:
 | 
						||
+    ~CallbackList()
 | 
						||
+    {
 | 
						||
+        for (const auto& callback : m_callbacks)
 | 
						||
+            callback->sendFailure("Page closed");
 | 
						||
+    }
 | 
						||
+
 | 
						||
+    void append(Ref<T>&& callback)
 | 
						||
+    {
 | 
						||
+        m_callbacks.append(WTFMove(callback));
 | 
						||
+    }
 | 
						||
+
 | 
						||
+    void sendSuccess()
 | 
						||
+    {
 | 
						||
+        for (const auto& callback : m_callbacks)
 | 
						||
+            callback->sendSuccess();
 | 
						||
+        m_callbacks.clear();
 | 
						||
+    }
 | 
						||
+
 | 
						||
+private:
 | 
						||
+    Vector<Ref<T>> m_callbacks;
 | 
						||
+};
 | 
						||
+
 | 
						||
+} // namespace
 | 
						||
+
 | 
						||
+class WebPageInspectorInputAgent::KeyboardCallbacks : public CallbackList<Inspector::InputBackendDispatcherHandler::DispatchKeyEventCallback> {
 | 
						||
+};
 | 
						||
+
 | 
						||
+class WebPageInspectorInputAgent::MouseCallbacks : public CallbackList<Inspector::InputBackendDispatcherHandler::DispatchMouseEventCallback> {
 | 
						||
+};
 | 
						||
+
 | 
						||
+WebPageInspectorInputAgent::WebPageInspectorInputAgent(Inspector::BackendDispatcher& backendDispatcher, WebPageProxy& page)
 | 
						||
+    : InspectorAgentBase("Input"_s)
 | 
						||
+    , m_backendDispatcher(InputBackendDispatcher::create(backendDispatcher, this))
 | 
						||
+    , m_page(page)
 | 
						||
+{
 | 
						||
+}
 | 
						||
+
 | 
						||
+WebPageInspectorInputAgent::~WebPageInspectorInputAgent() = default;
 | 
						||
+
 | 
						||
+void WebPageInspectorInputAgent::didProcessAllPendingKeyboardEvents()
 | 
						||
+{
 | 
						||
+    m_keyboardCallbacks->sendSuccess();
 | 
						||
+}
 | 
						||
+
 | 
						||
+void WebPageInspectorInputAgent::didProcessAllPendingMouseEvents()
 | 
						||
+{
 | 
						||
+    m_mouseCallbacks->sendSuccess();
 | 
						||
+}
 | 
						||
+
 | 
						||
+void WebPageInspectorInputAgent::didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*)
 | 
						||
+{
 | 
						||
+    m_keyboardCallbacks = makeUnique<KeyboardCallbacks>();
 | 
						||
+    m_mouseCallbacks = makeUnique<MouseCallbacks>();
 | 
						||
+}
 | 
						||
+
 | 
						||
+void WebPageInspectorInputAgent::willDestroyFrontendAndBackend(Inspector::DisconnectReason)
 | 
						||
+{
 | 
						||
+    m_keyboardCallbacks = nullptr;
 | 
						||
+    m_mouseCallbacks = nullptr;
 | 
						||
+}
 | 
						||
+
 | 
						||
+void WebPageInspectorInputAgent::dispatchKeyEvent(const String& type, const int* modifiers, const String* text, const String* unmodifiedText, const String* code, const String* key, const int* windowsVirtualKeyCode, const int* nativeVirtualKeyCode, const bool* autoRepeat, const bool* isKeypad, const bool* isSystemKey, const JSON::Array* commands, Ref<Inspector::InputBackendDispatcherHandler::DispatchKeyEventCallback>&& callback)
 | 
						||
+{
 | 
						||
+    WebKit::WebEvent::Type eventType;
 | 
						||
+    if (type == "keyDown") {
 | 
						||
+        eventType = WebKit::WebEvent::KeyDown;
 | 
						||
+    } else if (type == "keyUp") {
 | 
						||
+        eventType = WebKit::WebEvent::KeyUp;
 | 
						||
+    } else {
 | 
						||
+        callback->sendFailure("Unsupported event type.");
 | 
						||
+        return;
 | 
						||
+    }
 | 
						||
+    OptionSet<WebEvent::Modifier> eventModifiers;
 | 
						||
+    if (modifiers)
 | 
						||
+        eventModifiers = eventModifiers.fromRaw(*modifiers);
 | 
						||
+    String eventText;
 | 
						||
+    if (text)
 | 
						||
+        eventText = *text;
 | 
						||
+    String eventUnmodifiedText;
 | 
						||
+    if (unmodifiedText)
 | 
						||
+        eventUnmodifiedText = *unmodifiedText;
 | 
						||
+    String eventCode;
 | 
						||
+    if (code)
 | 
						||
+        eventCode = *code;
 | 
						||
+    String eventKey;
 | 
						||
+    if (key)
 | 
						||
+        eventKey = *key;
 | 
						||
+    int eventWindowsVirtualKeyCode = 0;
 | 
						||
+    if (windowsVirtualKeyCode)
 | 
						||
+        eventWindowsVirtualKeyCode = *windowsVirtualKeyCode;
 | 
						||
+    int eventNativeVirtualKeyCode = 0;
 | 
						||
+    if (nativeVirtualKeyCode)
 | 
						||
+        eventNativeVirtualKeyCode = *nativeVirtualKeyCode;
 | 
						||
+    Vector<String> eventCommands;
 | 
						||
+    if (commands) {
 | 
						||
+      for (const auto& value : *commands) {
 | 
						||
+        String command;
 | 
						||
+        if (!value->asString(command)) {
 | 
						||
+          callback->sendFailure("Command must be string");
 | 
						||
+          return;
 | 
						||
+        }
 | 
						||
+        eventCommands.append(command);
 | 
						||
+      }
 | 
						||
+    }
 | 
						||
+
 | 
						||
+    bool eventIsAutoRepeat = false;
 | 
						||
+    if (autoRepeat)
 | 
						||
+        eventIsAutoRepeat = *autoRepeat;
 | 
						||
+    bool eventIsKeypad = false;
 | 
						||
+    if (isKeypad)
 | 
						||
+        eventIsKeypad = *isKeypad;
 | 
						||
+    bool eventIsSystemKey = false;
 | 
						||
+    if (isSystemKey)
 | 
						||
+        eventIsSystemKey = *isSystemKey;
 | 
						||
+    WallTime timestamp = WallTime::now();
 | 
						||
+
 | 
						||
+    m_keyboardCallbacks->append(WTFMove(callback));
 | 
						||
+    platformDispatchKeyEvent(
 | 
						||
+        eventType,
 | 
						||
+        eventText,
 | 
						||
+        eventUnmodifiedText,
 | 
						||
+        eventKey,
 | 
						||
+        eventCode,
 | 
						||
+        eventWindowsVirtualKeyCode,
 | 
						||
+        eventNativeVirtualKeyCode,
 | 
						||
+        eventIsAutoRepeat,
 | 
						||
+        eventIsKeypad,
 | 
						||
+        eventIsSystemKey,
 | 
						||
+        eventModifiers,
 | 
						||
+        eventCommands,
 | 
						||
+        timestamp);
 | 
						||
+}
 | 
						||
+
 | 
						||
+void WebPageInspectorInputAgent::dispatchMouseEvent(const String& type, int x, int y, const int* modifiers, const String* button, const int* buttons, const int* clickCount, const int* deltaX, const int* deltaY, Ref<DispatchMouseEventCallback>&& callback)
 | 
						||
+{
 | 
						||
+    WebEvent::Type eventType = WebEvent::NoType;
 | 
						||
+    if (type == "down")
 | 
						||
+        eventType = WebEvent::MouseDown;
 | 
						||
+    else if (type == "up")
 | 
						||
+        eventType = WebEvent::MouseUp;
 | 
						||
+    else if (type == "move")
 | 
						||
+        eventType = WebEvent::MouseMove;
 | 
						||
+    else {
 | 
						||
+        callback->sendFailure("Unsupported event type");
 | 
						||
+        return;
 | 
						||
+    }
 | 
						||
+
 | 
						||
+    OptionSet<WebEvent::Modifier> eventModifiers;
 | 
						||
+    if (modifiers)
 | 
						||
+        eventModifiers = eventModifiers.fromRaw(*modifiers);
 | 
						||
+
 | 
						||
+    WebMouseEvent::Button eventButton = WebMouseEvent::NoButton;
 | 
						||
+    if (button) {
 | 
						||
+        if (*button == "left")
 | 
						||
+            eventButton = WebMouseEvent::LeftButton;
 | 
						||
+        else if (*button == "middle")
 | 
						||
+            eventButton = WebMouseEvent::MiddleButton;
 | 
						||
+        else if (*button == "right")
 | 
						||
+            eventButton = WebMouseEvent::RightButton;
 | 
						||
+        else if (*button == "none")
 | 
						||
+            eventButton = WebMouseEvent::NoButton;
 | 
						||
+        else {
 | 
						||
+            callback->sendFailure("Unsupported eventButton");
 | 
						||
+            return;
 | 
						||
+        }
 | 
						||
+    }
 | 
						||
+
 | 
						||
+    unsigned short eventButtons = 0;
 | 
						||
+    if (buttons)
 | 
						||
+        eventButtons = *buttons;
 | 
						||
+
 | 
						||
+    int eventClickCount = 0;
 | 
						||
+    if (clickCount)
 | 
						||
+        eventClickCount = *clickCount;
 | 
						||
+    int eventDeltaX = 0;
 | 
						||
+    if (deltaX)
 | 
						||
+        eventDeltaX = *deltaX;
 | 
						||
+    int eventDeltaY = 0;
 | 
						||
+    if (deltaY)
 | 
						||
+        eventDeltaY = *deltaY;
 | 
						||
+    m_mouseCallbacks->append(WTFMove(callback));
 | 
						||
+
 | 
						||
+    // Convert css coordinates to view coordinates (dip).
 | 
						||
+    double totalScale = m_page.pageScaleFactor() * m_page.viewScaleFactor();
 | 
						||
+    x = clampToInteger(roundf(x * totalScale));
 | 
						||
+    y = clampToInteger(roundf(y * totalScale));
 | 
						||
+    eventDeltaX = clampToInteger(roundf(eventDeltaX * totalScale));
 | 
						||
+    eventDeltaY = clampToInteger(roundf(eventDeltaY * totalScale));
 | 
						||
+
 | 
						||
+#if PLATFORM(MAC)
 | 
						||
+    platformDispatchMouseEvent(type, x, y, modifiers, button, clickCount);
 | 
						||
+#elif PLATFORM(GTK) || PLATFORM(WPE) || PLATFORM(WIN)
 | 
						||
+    WallTime timestamp = WallTime::now();
 | 
						||
+    NativeWebMouseEvent event(
 | 
						||
+        eventType,
 | 
						||
+        eventButton,
 | 
						||
+        eventButtons,
 | 
						||
+        {x, y},
 | 
						||
+        WebCore::IntPoint(),
 | 
						||
+        eventDeltaX,
 | 
						||
+        eventDeltaY,
 | 
						||
+        0,
 | 
						||
+        eventClickCount,
 | 
						||
+        eventModifiers,
 | 
						||
+        timestamp);
 | 
						||
+    m_page.handleMouseEvent(event);
 | 
						||
+#endif
 | 
						||
+}
 | 
						||
+
 | 
						||
+} // namespace WebKit
 | 
						||
diff --git a/Source/WebKit/UIProcess/WebPageInspectorInputAgent.h b/Source/WebKit/UIProcess/WebPageInspectorInputAgent.h
 | 
						||
new file mode 100644
 | 
						||
index 0000000000000000000000000000000000000000..76290475097e756e3d932d22be4d8c797be4aa0c
 | 
						||
--- /dev/null
 | 
						||
+++ b/Source/WebKit/UIProcess/WebPageInspectorInputAgent.h
 | 
						||
@@ -0,0 +1,84 @@
 | 
						||
+/*
 | 
						||
+ * Copyright (C) 2019 Microsoft Corporation.
 | 
						||
+ *
 | 
						||
+ * Redistribution and use in source and binary forms, with or without
 | 
						||
+ * modification, are permitted provided that the following conditions
 | 
						||
+ * are met:
 | 
						||
+ * 1. Redistributions of source code must retain the above copyright
 | 
						||
+ *    notice, this list of conditions and the following disclaimer.
 | 
						||
+ * 2. Redistributions in binary form must reproduce the above copyright
 | 
						||
+ *    notice, this list of conditions and the following disclaimer in the
 | 
						||
+ *    documentation and/or other materials provided with the distribution.
 | 
						||
+ *
 | 
						||
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
						||
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
						||
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
						||
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | 
						||
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | 
						||
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
						||
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | 
						||
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | 
						||
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
						||
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
						||
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
						||
+ */
 | 
						||
+
 | 
						||
+#pragma once
 | 
						||
+
 | 
						||
+#include "WebEvent.h"
 | 
						||
+
 | 
						||
+#include <JavaScriptCore/InspectorAgentBase.h>
 | 
						||
+#include <JavaScriptCore/InspectorBackendDispatchers.h>
 | 
						||
+
 | 
						||
+#include <wtf/Forward.h>
 | 
						||
+#include <wtf/Noncopyable.h>
 | 
						||
+
 | 
						||
+namespace Inspector {
 | 
						||
+class BackendDispatcher;
 | 
						||
+class FrontendChannel;
 | 
						||
+class FrontendRouter;
 | 
						||
+}
 | 
						||
+
 | 
						||
+namespace WebKit {
 | 
						||
+
 | 
						||
+class NativeWebKeyboardEvent;
 | 
						||
+class WebPageProxy;
 | 
						||
+
 | 
						||
+class WebPageInspectorInputAgent : public Inspector::InspectorAgentBase, public Inspector::InputBackendDispatcherHandler {
 | 
						||
+    WTF_MAKE_NONCOPYABLE(WebPageInspectorInputAgent);
 | 
						||
+    WTF_MAKE_FAST_ALLOCATED;
 | 
						||
+public:
 | 
						||
+    WebPageInspectorInputAgent(Inspector::BackendDispatcher& backendDispatcher, WebPageProxy& page);
 | 
						||
+    ~WebPageInspectorInputAgent() override;
 | 
						||
+
 | 
						||
+    void didProcessAllPendingKeyboardEvents();
 | 
						||
+    void didProcessAllPendingMouseEvents();
 | 
						||
+
 | 
						||
+    void didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*) override;
 | 
						||
+    void willDestroyFrontendAndBackend(Inspector::DisconnectReason) override;
 | 
						||
+
 | 
						||
+    // Protocol handler
 | 
						||
+    void dispatchKeyEvent(const String& type, const int* modifiers, const String* text, const String* unmodifiedText, const String* code, const String* key, const int* windowsVirtualKeyCode, const int* nativeVirtualKeyCode, const bool* autoRepeat, const bool* isKeypad, const bool* isSystemKey, const JSON::Array*, Ref<DispatchKeyEventCallback>&& callback) override;
 | 
						||
+    void dispatchMouseEvent(const String& type, int x, int y, const int* modifiers, const String* button, const int* buttons, const int* clickCount, const int* deltaX, const int* deltaY, Ref<DispatchMouseEventCallback>&& callback) override;
 | 
						||
+
 | 
						||
+private:
 | 
						||
+    void platformDispatchKeyEvent(WebKeyboardEvent::Type type, const String& text, const String& unmodifiedText, const String& key, const String& code, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<WebEvent::Modifier> modifiers, Vector<String>& commands, WallTime timestamp);
 | 
						||
+#if PLATFORM(WPE)
 | 
						||
+    void platformDispatchMouseEvent(WebMouseEvent::Type type, int x, int y, WebMouseEvent::Button button, OptionSet<WebEvent::Modifier> modifiers);
 | 
						||
+#endif
 | 
						||
+#if PLATFORM(MAC)
 | 
						||
+    void platformDispatchMouseEvent(const String& type, int x, int y, const int* modifier, const String* button, const int* clickCount);
 | 
						||
+#endif
 | 
						||
+
 | 
						||
+    Ref<Inspector::InputBackendDispatcher> m_backendDispatcher;
 | 
						||
+    WebPageProxy& m_page;
 | 
						||
+    // Keep track of currently active modifiers across multiple keystrokes.
 | 
						||
+    // Most platforms do not track current modifiers from synthesized events.
 | 
						||
+    unsigned m_currentModifiers { 0 };
 | 
						||
+    class KeyboardCallbacks;
 | 
						||
+    std::unique_ptr<KeyboardCallbacks> m_keyboardCallbacks;
 | 
						||
+    class MouseCallbacks;
 | 
						||
+    std::unique_ptr<MouseCallbacks> m_mouseCallbacks;
 | 
						||
+};
 | 
						||
+
 | 
						||
+} // namespace WebKit
 | 
						||
diff --git a/Source/WebKit/UIProcess/WebPageProxy.cpp b/Source/WebKit/UIProcess/WebPageProxy.cpp
 | 
						||
index 509faa03b0bf0c76ef0b74e7a503a3e537c42937..840f60b0cb37287977bc7a2b698b2f071a41d1b3 100644
 | 
						||
--- a/Source/WebKit/UIProcess/WebPageProxy.cpp
 | 
						||
+++ b/Source/WebKit/UIProcess/WebPageProxy.cpp
 | 
						||
@@ -930,6 +930,7 @@ void WebPageProxy::finishAttachingToWebProcess(ProcessLaunchReason reason)
 | 
						||
     m_pageLoadState.didSwapWebProcesses();
 | 
						||
     if (reason != ProcessLaunchReason::InitialProcess)
 | 
						||
         m_drawingArea->waitForBackingStoreUpdateOnNextPaint();
 | 
						||
+    m_inspectorController->didFinishAttachingToWebProcess();
 | 
						||
 }
 | 
						||
 
 | 
						||
 void WebPageProxy::didAttachToRunningProcess()
 | 
						||
@@ -1269,6 +1270,21 @@ WebProcessProxy& WebPageProxy::ensureRunningProcess()
 | 
						||
     return m_process;
 | 
						||
 }
 | 
						||
 
 | 
						||
+RefPtr<API::Navigation> WebPageProxy::loadRequestForInspector(WebCore::ResourceRequest&& request, WebFrameProxy* frame)
 | 
						||
+{
 | 
						||
+    if (!frame || frame == mainFrame())
 | 
						||
+        return loadRequest(WTFMove(request), WebCore::ShouldOpenExternalURLsPolicy::ShouldNotAllow);
 | 
						||
+
 | 
						||
+    auto navigation = m_navigationState->createLoadRequestNavigation(ResourceRequest(request), m_backForwardList->currentItem());
 | 
						||
+    LoadParameters loadParameters;
 | 
						||
+    loadParameters.navigationID = navigation->navigationID();
 | 
						||
+    loadParameters.request = WTFMove(request);
 | 
						||
+    loadParameters.shouldOpenExternalURLsPolicy = WebCore::ShouldOpenExternalURLsPolicy::ShouldNotAllow;
 | 
						||
+    loadParameters.shouldTreatAsContinuingLoad = false;
 | 
						||
+    m_process->send(Messages::WebPage::LoadRequestInFrameForInspector(loadParameters, frame->frameID()),  m_webPageID);
 | 
						||
+    return navigation;
 | 
						||
+}
 | 
						||
+
 | 
						||
 RefPtr<API::Navigation> WebPageProxy::loadRequest(ResourceRequest&& request, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy, API::Object* userData)
 | 
						||
 {
 | 
						||
     if (m_isClosed)
 | 
						||
@@ -1722,6 +1738,31 @@ void WebPageProxy::setControlledByAutomation(bool controlled)
 | 
						||
     m_process->processPool().sendToNetworkingProcess(Messages::NetworkProcess::SetSessionIsControlledByAutomation(m_websiteDataStore->sessionID(), m_controlledByAutomation));
 | 
						||
 }
 | 
						||
 
 | 
						||
+void WebPageProxy::setAuthCredentialsForAutomation(Optional<WebCore::Credential>&& credentials)
 | 
						||
+{
 | 
						||
+    m_credentialsForAutomation = WTFMove(credentials);
 | 
						||
+}
 | 
						||
+
 | 
						||
+void WebPageProxy::setPermissionsForAutomation(const HashMap<String, HashSet<String>>& permissions)
 | 
						||
+{
 | 
						||
+    m_permissionsForAutomation = permissions;
 | 
						||
+}
 | 
						||
+
 | 
						||
+void WebPageProxy::setActiveForAutomation(Optional<bool> active) {
 | 
						||
+    m_activeForAutomation = active;
 | 
						||
+    OptionSet<ActivityState::Flag> state;
 | 
						||
+    state.add(ActivityState::IsFocused);
 | 
						||
+    state.add(ActivityState::WindowIsActive);
 | 
						||
+    state.add(ActivityState::IsVisible);
 | 
						||
+    state.add(ActivityState::IsVisibleOrOccluded);
 | 
						||
+    activityStateDidChange(state);
 | 
						||
+}
 | 
						||
+
 | 
						||
+void WebPageProxy::logToStderr(const String& str)
 | 
						||
+{
 | 
						||
+    fprintf(stderr, "RENDERER: %s\n", str.utf8().data());
 | 
						||
+}
 | 
						||
+
 | 
						||
 void WebPageProxy::createInspectorTarget(const String& targetId, Inspector::InspectorTargetType type)
 | 
						||
 {
 | 
						||
     MESSAGE_CHECK(m_process, !targetId.isEmpty());
 | 
						||
@@ -1864,6 +1905,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())
 | 
						||
@@ -2810,7 +2870,7 @@ static TrackingType mergeTrackingTypes(TrackingType a, TrackingType b)
 | 
						||
 
 | 
						||
 void WebPageProxy::updateTouchEventTracking(const WebTouchEvent& touchStartEvent)
 | 
						||
 {
 | 
						||
-#if ENABLE(ASYNC_SCROLLING) && PLATFORM(COCOA)
 | 
						||
+#if ENABLE(ASYNC_SCROLLING) && PLATFORM(IOS_FAMILY)
 | 
						||
     const EventNames& names = eventNames();
 | 
						||
     for (auto& touchPoint : touchStartEvent.touchPoints()) {
 | 
						||
         IntPoint location = touchPoint.location();
 | 
						||
@@ -2843,7 +2903,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
 | 
						||
@@ -3207,6 +3267,7 @@ void WebPageProxy::receivedNavigationPolicyDecision(PolicyAction policyAction, A
 | 
						||
 
 | 
						||
 void WebPageProxy::receivedPolicyDecision(PolicyAction action, API::Navigation* navigation, Optional<WebsitePoliciesData>&& websitePolicies, Ref<PolicyDecisionSender>&& sender, WillContinueLoadInNewProcess willContinueLoadInNewProcess)
 | 
						||
 {
 | 
						||
+    m_inspectorController->didReceivePolicyDecision(action, navigation ? navigation->navigationID() : 0);
 | 
						||
     if (!hasRunningProcess()) {
 | 
						||
         sender->send(PolicyDecision { sender->identifier(), isNavigatingToAppBoundDomain(), hasNavigatedAwayFromAppBoundDomain(), PolicyAction::Ignore, 0, DownloadID(), WTF::nullopt });
 | 
						||
         return;
 | 
						||
@@ -3891,6 +3952,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;
 | 
						||
@@ -4310,6 +4376,7 @@ void WebPageProxy::didDestroyNavigation(uint64_t navigationID)
 | 
						||
 
 | 
						||
     // FIXME: Message check the navigationID.
 | 
						||
     m_navigationState->didDestroyNavigation(navigationID);
 | 
						||
+    m_inspectorController->didDestroyNavigation(navigationID);
 | 
						||
 }
 | 
						||
 
 | 
						||
 void WebPageProxy::didStartProvisionalLoadForFrame(FrameIdentifier frameID, FrameInfoData&& frameInfo, ResourceRequest&& request, uint64_t navigationID, URL&& url, URL&& unreachableURL, const UserData& userData)
 | 
						||
@@ -4529,6 +4596,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;
 | 
						||
@@ -4971,7 +5040,14 @@ void WebPageProxy::decidePolicyForNavigationActionAsync(FrameIdentifier frameID,
 | 
						||
     NavigationActionData&& navigationActionData, FrameInfoData&& originatingFrameInfo, Optional<WebPageProxyIdentifier> originatingPageID, const WebCore::ResourceRequest& originalRequest, WebCore::ResourceRequest&& request,
 | 
						||
     IPC::FormDataReference&& requestBody, WebCore::ResourceResponse&& redirectResponse, const UserData& userData, uint64_t listenerID)
 | 
						||
 {
 | 
						||
-    decidePolicyForNavigationActionAsyncShared(m_process.copyRef(), m_webPageID, frameID, WTFMove(frameInfo), identifier, navigationID, WTFMove(navigationActionData), WTFMove(originatingFrameInfo), originatingPageID, originalRequest, WTFMove(request), WTFMove(requestBody), WTFMove(redirectResponse), userData, listenerID);
 | 
						||
+    if (m_inspectorController->shouldPauseLoading()) {
 | 
						||
+        m_inspectorController->setContinueLoadingCallback([this, protectedThis = makeRef(*this), frameID, frameInfo = WTFMove(frameInfo), identifier, navigationID, navigationActionData = WTFMove(navigationActionData),
 | 
						||
+                originatingFrameInfo = WTFMove(originatingFrameInfo), originatingPageID, originalRequest, request = WTFMove(request), requestBody = WTFMove(requestBody), redirectResponse = WTFMove(redirectResponse), userData, listenerID] () mutable {
 | 
						||
+            decidePolicyForNavigationActionAsyncShared(m_process.copyRef(), m_webPageID, frameID, WTFMove(frameInfo), identifier, navigationID, WTFMove(navigationActionData), WTFMove(originatingFrameInfo), originatingPageID, originalRequest, WTFMove(request), WTFMove(requestBody), WTFMove(redirectResponse), userData, listenerID);
 | 
						||
+        });
 | 
						||
+    } else {
 | 
						||
+        decidePolicyForNavigationActionAsyncShared(m_process.copyRef(), m_webPageID, frameID, WTFMove(frameInfo), identifier, navigationID, WTFMove(navigationActionData), WTFMove(originatingFrameInfo), originatingPageID, originalRequest, WTFMove(request), WTFMove(requestBody), WTFMove(redirectResponse), userData, listenerID);
 | 
						||
+    }
 | 
						||
 }
 | 
						||
 
 | 
						||
 void WebPageProxy::decidePolicyForNavigationActionAsyncShared(Ref<WebProcessProxy>&& process, PageIdentifier webPageID, FrameIdentifier frameID, FrameInfoData&& frameInfo,
 | 
						||
@@ -5461,6 +5537,7 @@ void WebPageProxy::createNewPage(FrameInfoData&& originatingFrameInfoData, Optio
 | 
						||
     auto* originatingPage = m_process->webPage(*originatingPageID);
 | 
						||
     auto originatingFrameInfo = API::FrameInfo::create(WTFMove(originatingFrameInfoData), originatingPage);
 | 
						||
     auto mainFrameURL = m_mainFrame ? m_mainFrame->url() : URL();
 | 
						||
+    m_inspectorController->willCreateNewPage(windowFeatures, request.url());
 | 
						||
     auto completionHandler = [this, protectedThis = makeRef(*this), mainFrameURL, request, reply = WTFMove(reply)] (RefPtr<WebPageProxy> newPage) mutable {
 | 
						||
         if (!newPage) {
 | 
						||
             reply(WTF::nullopt, WTF::nullopt);
 | 
						||
@@ -5490,6 +5567,7 @@ void WebPageProxy::createNewPage(FrameInfoData&& originatingFrameInfoData, Optio
 | 
						||
 void WebPageProxy::showPage()
 | 
						||
 {
 | 
						||
     m_uiClient->showPage(this);
 | 
						||
+    m_inspectorController->didShowPage();
 | 
						||
 }
 | 
						||
 
 | 
						||
 void WebPageProxy::exitFullscreenImmediately()
 | 
						||
@@ -5546,6 +5624,8 @@ void WebPageProxy::runJavaScriptAlert(FrameIdentifier frameID, FrameInfoData&& f
 | 
						||
         if (auto* automationSession = process().processPool().automationSession())
 | 
						||
             automationSession->willShowJavaScriptDialog(*this);
 | 
						||
     }
 | 
						||
+    if (m_inspectorDialogAgent)
 | 
						||
+        m_inspectorDialogAgent->javascriptDialogOpening("alert"_s, message);
 | 
						||
     m_uiClient->runJavaScriptAlert(*this, message, frame, WTFMove(frameInfo), WTFMove(reply));
 | 
						||
 }
 | 
						||
 
 | 
						||
@@ -5565,6 +5645,8 @@ void WebPageProxy::runJavaScriptConfirm(FrameIdentifier frameID, FrameInfoData&&
 | 
						||
         if (auto* automationSession = process().processPool().automationSession())
 | 
						||
             automationSession->willShowJavaScriptDialog(*this);
 | 
						||
     }
 | 
						||
+    if (m_inspectorDialogAgent)
 | 
						||
+        m_inspectorDialogAgent->javascriptDialogOpening("confirm"_s, message);
 | 
						||
 
 | 
						||
     m_uiClient->runJavaScriptConfirm(*this, message, frame, WTFMove(frameInfo), WTFMove(reply));
 | 
						||
 }
 | 
						||
@@ -5584,6 +5666,8 @@ void WebPageProxy::runJavaScriptPrompt(FrameIdentifier frameID, FrameInfoData&&
 | 
						||
         if (auto* automationSession = process().processPool().automationSession())
 | 
						||
             automationSession->willShowJavaScriptDialog(*this);
 | 
						||
     }
 | 
						||
+    if (m_inspectorDialogAgent)
 | 
						||
+        m_inspectorDialogAgent->javascriptDialogOpening("prompt"_s, message, &defaultValue);
 | 
						||
 
 | 
						||
     m_uiClient->runJavaScriptPrompt(*this, message, defaultValue, frame, WTFMove(frameInfo), WTFMove(reply));
 | 
						||
 }
 | 
						||
@@ -5743,6 +5827,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();
 | 
						||
@@ -6805,6 +6891,7 @@ void WebPageProxy::didReceiveEvent(uint32_t opaqueType, bool handled)
 | 
						||
             if (auto* automationSession = process().processPool().automationSession())
 | 
						||
                 automationSession->mouseEventsFlushedForPage(*this);
 | 
						||
             didFinishProcessingAllPendingMouseEvents();
 | 
						||
+            m_inspectorController->didProcessAllPendingMouseEvents();
 | 
						||
         }
 | 
						||
 
 | 
						||
         break;
 | 
						||
@@ -6831,7 +6918,6 @@ void WebPageProxy::didReceiveEvent(uint32_t opaqueType, bool handled)
 | 
						||
     case WebEvent::RawKeyDown:
 | 
						||
     case WebEvent::Char: {
 | 
						||
         LOG(KeyHandling, "WebPageProxy::didReceiveEvent: %s (queue empty %d)", webKeyboardEventTypeString(type), m_keyEventQueue.isEmpty());
 | 
						||
-
 | 
						||
         MESSAGE_CHECK(m_process, !m_keyEventQueue.isEmpty());
 | 
						||
         NativeWebKeyboardEvent event = m_keyEventQueue.takeFirst();
 | 
						||
 
 | 
						||
@@ -6851,7 +6937,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);
 | 
						||
@@ -6860,6 +6945,7 @@ void WebPageProxy::didReceiveEvent(uint32_t opaqueType, bool handled)
 | 
						||
         if (!canProcessMoreKeyEvents) {
 | 
						||
             if (auto* automationSession = process().processPool().automationSession())
 | 
						||
                 automationSession->keyboardEventsFlushedForPage(*this);
 | 
						||
+            m_inspectorController->didProcessAllPendingKeyboardEvents();
 | 
						||
         }
 | 
						||
         break;
 | 
						||
     }
 | 
						||
@@ -7317,8 +7403,10 @@ static bool shouldReloadAfterProcessTermination(ProcessTerminationReason reason)
 | 
						||
 void WebPageProxy::dispatchProcessDidTerminate(ProcessTerminationReason reason)
 | 
						||
 {
 | 
						||
     RELEASE_LOG_IF_ALLOWED(Loading, "dispatchProcessDidTerminate: reason = %d", reason);
 | 
						||
+    bool handledByClient = m_inspectorController->pageCrashed(reason);
 | 
						||
+    if (handledByClient)
 | 
						||
+        return;
 | 
						||
 
 | 
						||
-    bool handledByClient = false;
 | 
						||
     if (m_loaderClient)
 | 
						||
         handledByClient = reason != ProcessTerminationReason::RequestedByClient && m_loaderClient->processDidCrash(*this);
 | 
						||
     else
 | 
						||
@@ -7600,6 +7688,7 @@ void WebPageProxy::resetStateAfterProcessExited(ProcessTerminationReason termina
 | 
						||
 
 | 
						||
 WebPageCreationParameters WebPageProxy::creationParameters(WebProcessProxy& process, DrawingAreaProxy& drawingArea)
 | 
						||
 {
 | 
						||
+
 | 
						||
     WebPageCreationParameters parameters;
 | 
						||
 
 | 
						||
     parameters.processDisplayName = configuration().processDisplayName();
 | 
						||
@@ -7734,6 +7823,8 @@ WebPageCreationParameters WebPageProxy::creationParameters(WebProcessProxy& proc
 | 
						||
     parameters.shouldRenderCanvasInGPUProcess = preferences().renderCanvasInGPUProcessEnabled();
 | 
						||
     parameters.shouldCaptureDisplayInUIProcess = m_process->processPool().configuration().shouldCaptureDisplayInUIProcess();
 | 
						||
 
 | 
						||
+    parameters.shouldPauseInInspectorWhenShown = m_inspectorController->shouldPauseLoading();
 | 
						||
+
 | 
						||
 #if PLATFORM(GTK)
 | 
						||
     parameters.themeName = pageClient().themeName();
 | 
						||
 #endif
 | 
						||
@@ -7797,6 +7888,14 @@ void WebPageProxy::gamepadActivity(const Vector<GamepadData>& gamepadDatas, bool
 | 
						||
 
 | 
						||
 void WebPageProxy::didReceiveAuthenticationChallengeProxy(Ref<AuthenticationChallengeProxy>&& authenticationChallenge, NegotiatedLegacyTLS negotiatedLegacyTLS)
 | 
						||
 {
 | 
						||
+    if (m_credentialsForAutomation.hasValue()) {
 | 
						||
+        if (m_credentialsForAutomation->isEmpty() || authenticationChallenge->core().previousFailureCount()) {
 | 
						||
+            authenticationChallenge->listener().completeChallenge(AuthenticationChallengeDisposition::PerformDefaultHandling);
 | 
						||
+            return;
 | 
						||
+        }
 | 
						||
+        authenticationChallenge->listener().completeChallenge(AuthenticationChallengeDisposition::UseCredential, *m_credentialsForAutomation);
 | 
						||
+        return;
 | 
						||
+    }
 | 
						||
     if (negotiatedLegacyTLS == NegotiatedLegacyTLS::Yes) {
 | 
						||
         m_navigationClient->shouldAllowLegacyTLS(*this, authenticationChallenge.get(), [this, protectedThis = makeRef(*this), authenticationChallenge = authenticationChallenge.copyRef()] (bool shouldAllowLegacyTLS) {
 | 
						||
             if (shouldAllowLegacyTLS)
 | 
						||
@@ -7877,7 +7976,8 @@ void WebPageProxy::requestGeolocationPermissionForFrame(uint64_t geolocationID,
 | 
						||
     MESSAGE_CHECK(m_process, frame);
 | 
						||
 
 | 
						||
     // FIXME: Geolocation should probably be using toString() as its string representation instead of databaseIdentifier().
 | 
						||
-    auto origin = API::SecurityOrigin::create(frameInfo.securityOrigin.securityOrigin());
 | 
						||
+    auto securityOrigin = frameInfo.securityOrigin.securityOrigin();
 | 
						||
+    auto origin = API::SecurityOrigin::create(securityOrigin);
 | 
						||
     auto request = m_geolocationPermissionRequestManager.createRequest(geolocationID);
 | 
						||
     Function<void(bool)> completionHandler = [request = WTFMove(request)](bool allowed) {
 | 
						||
         if (allowed)
 | 
						||
@@ -7886,6 +7986,14 @@ void WebPageProxy::requestGeolocationPermissionForFrame(uint64_t geolocationID,
 | 
						||
             request->deny();
 | 
						||
     };
 | 
						||
 
 | 
						||
+    auto permissions = m_permissionsForAutomation.find(securityOrigin->toString());
 | 
						||
+    if (permissions == m_permissionsForAutomation.end())
 | 
						||
+      permissions = m_permissionsForAutomation.find("*");
 | 
						||
+    if (permissions != m_permissionsForAutomation.end()) {
 | 
						||
+        completionHandler(permissions->value.contains("geolocation"));
 | 
						||
+        return;
 | 
						||
+    }
 | 
						||
+
 | 
						||
     // FIXME: Once iOS migrates to the new WKUIDelegate SPI, clean this up
 | 
						||
     // and make it one UIClient call that calls the completionHandler with false
 | 
						||
     // if there is no delegate instead of returning the completionHandler
 | 
						||
diff --git a/Source/WebKit/UIProcess/WebPageProxy.h b/Source/WebKit/UIProcess/WebPageProxy.h
 | 
						||
index c7b6ec487a66bc92b2eb7f58d86c95646cadbfc4..9a444263299a0a5d26cbabed1a7e961866d2bb60 100644
 | 
						||
--- a/Source/WebKit/UIProcess/WebPageProxy.h
 | 
						||
+++ b/Source/WebKit/UIProcess/WebPageProxy.h
 | 
						||
@@ -36,6 +36,7 @@
 | 
						||
 #include "FocusedElementInformation.h"
 | 
						||
 #include "GeolocationPermissionRequestManagerProxy.h"
 | 
						||
 #include "HiddenPageThrottlingAutoIncreasesCounter.h"
 | 
						||
+#include "InspectorDialogAgent.h"
 | 
						||
 #include "LayerTreeContext.h"
 | 
						||
 #include "MessageSender.h"
 | 
						||
 #include "NotificationPermissionRequestManagerProxy.h"
 | 
						||
@@ -495,6 +496,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();
 | 
						||
@@ -566,6 +569,11 @@ public:
 | 
						||
 
 | 
						||
     void setPageLoadStateObserver(std::unique_ptr<PageLoadState::Observer>&&);
 | 
						||
 
 | 
						||
+    void setAuthCredentialsForAutomation(Optional<WebCore::Credential>&&);
 | 
						||
+    void setPermissionsForAutomation(const HashMap<String, HashSet<String>>&);
 | 
						||
+    void setActiveForAutomation(Optional<bool> active);
 | 
						||
+    void logToStderr(const String& str);
 | 
						||
+
 | 
						||
     void initializeWebPage();
 | 
						||
     void setDrawingArea(std::unique_ptr<DrawingAreaProxy>&&);
 | 
						||
 
 | 
						||
@@ -591,6 +599,7 @@ public:
 | 
						||
     void closePage();
 | 
						||
 
 | 
						||
     void addPlatformLoadParameters(LoadParameters&);
 | 
						||
+    RefPtr<API::Navigation> loadRequestForInspector(WebCore::ResourceRequest&&, WebFrameProxy*);
 | 
						||
     RefPtr<API::Navigation> loadRequest(WebCore::ResourceRequest&&, WebCore::ShouldOpenExternalURLsPolicy = WebCore::ShouldOpenExternalURLsPolicy::ShouldAllowExternalSchemes, API::Object* userData = nullptr);
 | 
						||
     RefPtr<API::Navigation> loadFile(const String& fileURL, const String& resourceDirectoryURL, API::Object* userData = nullptr);
 | 
						||
     RefPtr<API::Navigation> loadData(const IPC::DataReference&, const String& MIMEType, const String& encoding, const String& baseURL, API::Object* userData = nullptr, WebCore::ShouldOpenExternalURLsPolicy = WebCore::ShouldOpenExternalURLsPolicy::ShouldNotAllow);
 | 
						||
@@ -1071,6 +1080,7 @@ public:
 | 
						||
 #endif
 | 
						||
 
 | 
						||
     void pageScaleFactorDidChange(double);
 | 
						||
+    void viewScaleFactorDidChange(double);
 | 
						||
     void pluginScaleFactorDidChange(double);
 | 
						||
     void pluginZoomFactorDidChange(double);
 | 
						||
 
 | 
						||
@@ -2328,6 +2338,7 @@ private:
 | 
						||
     String m_overrideContentSecurityPolicy;
 | 
						||
 
 | 
						||
     RefPtr<WebInspectorProxy> m_inspector;
 | 
						||
+    InspectorDialogAgent* m_inspectorDialogAgent { nullptr };
 | 
						||
 
 | 
						||
 #if ENABLE(FULLSCREEN_API)
 | 
						||
     std::unique_ptr<WebFullScreenManagerProxy> m_fullScreenManager;
 | 
						||
@@ -2748,6 +2759,9 @@ private:
 | 
						||
         RefPtr<API::Object> messageBody;
 | 
						||
     };
 | 
						||
     Vector<InjectedBundleMessage> m_pendingInjectedBundleMessages;
 | 
						||
+    Optional<WebCore::Credential> m_credentialsForAutomation;
 | 
						||
+    HashMap<String, HashSet<String>> m_permissionsForAutomation;
 | 
						||
+    Optional<bool> m_activeForAutomation;
 | 
						||
         
 | 
						||
 #if PLATFORM(IOS_FAMILY) && ENABLE(DEVICE_ORIENTATION)
 | 
						||
     std::unique_ptr<WebDeviceOrientationUpdateProviderProxy> m_webDeviceOrientationUpdateProviderProxy;
 | 
						||
diff --git a/Source/WebKit/UIProcess/WebPageProxy.messages.in b/Source/WebKit/UIProcess/WebPageProxy.messages.in
 | 
						||
index 94424d022edea92789d847ed2b18b58c2e9ac67f..9041c45c0bcca77cf2fa26f79318564e24204a12 100644
 | 
						||
--- a/Source/WebKit/UIProcess/WebPageProxy.messages.in
 | 
						||
+++ b/Source/WebKit/UIProcess/WebPageProxy.messages.in
 | 
						||
@@ -29,6 +29,7 @@ messages -> WebPageProxy {
 | 
						||
     RunJavaScriptConfirm(WebCore::FrameIdentifier frameID, struct WebKit::FrameInfoData frameInfo, String message) -> (bool result) Synchronous
 | 
						||
     RunJavaScriptPrompt(WebCore::FrameIdentifier frameID, struct WebKit::FrameInfoData frameInfo, String message, String defaultValue) -> (String result) Synchronous
 | 
						||
     MouseDidMoveOverElement(struct WebKit::WebHitTestResultData hitTestResultData, uint32_t modifiers, WebKit::UserData userData)
 | 
						||
+    LogToStderr(String text)
 | 
						||
 
 | 
						||
 #if ENABLE(NETSCAPE_PLUGIN_API)
 | 
						||
     UnavailablePluginButtonClicked(uint32_t pluginUnavailabilityReason, String mimeType, String pluginURLString, String pluginspageAttributeURLString, String frameURLString, String pageURLString)
 | 
						||
@@ -209,6 +210,7 @@ messages -> WebPageProxy {
 | 
						||
     FindStringCallback(bool found, WebKit::CallbackID callbackID)
 | 
						||
 
 | 
						||
     PageScaleFactorDidChange(double scaleFactor)
 | 
						||
+    ViewScaleFactorDidChange(double scaleFactor)
 | 
						||
     PluginScaleFactorDidChange(double zoomFactor)
 | 
						||
     PluginZoomFactorDidChange(double zoomFactor)
 | 
						||
 
 | 
						||
diff --git a/Source/WebKit/UIProcess/WebProcessPool.cpp b/Source/WebKit/UIProcess/WebProcessPool.cpp
 | 
						||
index ceef0483bc0201a00950450424144b9a906afec8..2796423306d03190888369901cee7391a860ba95 100644
 | 
						||
--- a/Source/WebKit/UIProcess/WebProcessPool.cpp
 | 
						||
+++ b/Source/WebKit/UIProcess/WebProcessPool.cpp
 | 
						||
@@ -432,12 +432,19 @@ void WebProcessPool::languageChanged(void* context)
 | 
						||
     static_cast<WebProcessPool*>(context)->languageChanged();
 | 
						||
 }
 | 
						||
 
 | 
						||
+void WebProcessPool::setLanguagesForAutomation(Vector<String>&& languages)
 | 
						||
+{
 | 
						||
+    m_languagesForAutomation = WTFMove(languages);
 | 
						||
+    languageChanged();
 | 
						||
+}
 | 
						||
+
 | 
						||
 void WebProcessPool::languageChanged()
 | 
						||
 {
 | 
						||
-    sendToAllProcesses(Messages::WebProcess::UserPreferredLanguagesChanged(userPreferredLanguages()));
 | 
						||
+    const Vector<String>& languages = m_languagesForAutomation.size() ? m_languagesForAutomation : userPreferredLanguages();
 | 
						||
+    sendToAllProcesses(Messages::WebProcess::UserPreferredLanguagesChanged(languages));
 | 
						||
 #if USE(SOUP)
 | 
						||
     if (m_networkProcess)
 | 
						||
-        m_networkProcess->send(Messages::NetworkProcess::UserPreferredLanguagesChanged(userPreferredLanguages()), 0);
 | 
						||
+        m_networkProcess->send(Messages::NetworkProcess::UserPreferredLanguagesChanged(languages), 0);
 | 
						||
 #endif
 | 
						||
 }
 | 
						||
 
 | 
						||
@@ -991,7 +998,10 @@ void WebProcessPool::initializeNewWebProcess(WebProcessProxy& process, WebsiteDa
 | 
						||
 #endif
 | 
						||
 
 | 
						||
     parameters.cacheModel = LegacyGlobalSettings::singleton().cacheModel();
 | 
						||
-    parameters.languages = configuration().overrideLanguages().isEmpty() ? userPreferredLanguages() : configuration().overrideLanguages();
 | 
						||
+    if (m_languagesForAutomation.size())
 | 
						||
+        parameters.languages = m_languagesForAutomation;
 | 
						||
+    else
 | 
						||
+        parameters.languages = configuration().overrideLanguages().isEmpty() ? userPreferredLanguages() : configuration().overrideLanguages();
 | 
						||
 
 | 
						||
     parameters.urlSchemesRegisteredAsEmptyDocument = copyToVector(m_schemesToRegisterAsEmptyDocument);
 | 
						||
     parameters.urlSchemesRegisteredAsSecure = copyToVector(LegacyGlobalSettings::singleton().schemesToRegisterAsSecure());
 | 
						||
diff --git a/Source/WebKit/UIProcess/WebProcessPool.h b/Source/WebKit/UIProcess/WebProcessPool.h
 | 
						||
index d5b9c2637cda626b075e87484ba764a0b965372d..24d7c16c5afba982ddf5cf1cdf96d75ead64df9f 100644
 | 
						||
--- a/Source/WebKit/UIProcess/WebProcessPool.h
 | 
						||
+++ b/Source/WebKit/UIProcess/WebProcessPool.h
 | 
						||
@@ -417,7 +417,7 @@ public:
 | 
						||
 
 | 
						||
     void windowServerConnectionStateChanged();
 | 
						||
 
 | 
						||
-#if USE(SOUP)
 | 
						||
+#if USE(SOUP) || PLATFORM(COCOA) || PLATFORM(WIN)
 | 
						||
     void setIgnoreTLSErrors(bool);
 | 
						||
     bool ignoreTLSErrors() const { return m_ignoreTLSErrors; }
 | 
						||
 #endif
 | 
						||
@@ -538,6 +538,8 @@ public:
 | 
						||
     
 | 
						||
     PlugInAutoStartProvider& plugInAutoStartProvider() { return m_plugInAutoStartProvider; }
 | 
						||
 
 | 
						||
+    void setLanguagesForAutomation(Vector<String>&&);
 | 
						||
+
 | 
						||
     void setUseSeparateServiceWorkerProcess(bool);
 | 
						||
     bool useSeparateServiceWorkerProcess() const { return m_useSeparateServiceWorkerProcess; }
 | 
						||
 
 | 
						||
@@ -650,6 +652,7 @@ private:
 | 
						||
     std::unique_ptr<API::CustomProtocolManagerClient> m_customProtocolManagerClient;
 | 
						||
 
 | 
						||
     RefPtr<WebAutomationSession> m_automationSession;
 | 
						||
+    Vector<String> m_languagesForAutomation;
 | 
						||
 
 | 
						||
 #if ENABLE(NETSCAPE_PLUGIN_API)
 | 
						||
     PluginInfoStore m_pluginInfoStore;
 | 
						||
@@ -719,8 +722,8 @@ private:
 | 
						||
     HashMap<uint64_t, RefPtr<DictionaryCallback>> m_dictionaryCallbacks;
 | 
						||
     HashMap<uint64_t, RefPtr<StatisticsRequest>> m_statisticsRequests;
 | 
						||
 
 | 
						||
-#if USE(SOUP)
 | 
						||
-    bool m_ignoreTLSErrors { true };
 | 
						||
+#if USE(SOUP) || PLATFORM(COCOA) || PLATFORM(WIN)
 | 
						||
+    bool m_ignoreTLSErrors { false };
 | 
						||
 #endif
 | 
						||
 
 | 
						||
     bool m_memoryCacheDisabled { false };
 | 
						||
diff --git a/Source/WebKit/UIProcess/geoclue/GeoclueGeolocationProvider.cpp b/Source/WebKit/UIProcess/geoclue/GeoclueGeolocationProvider.cpp
 | 
						||
index 7ba39332bce6e28f0f4b2f7acf636f835c54f486..7c3d8125df147b6049075491b12cce1dc84bf514 100644
 | 
						||
--- a/Source/WebKit/UIProcess/geoclue/GeoclueGeolocationProvider.cpp
 | 
						||
+++ b/Source/WebKit/UIProcess/geoclue/GeoclueGeolocationProvider.cpp
 | 
						||
@@ -60,6 +60,8 @@ void GeoclueGeolocationProvider::start(UpdateNotifyFunction&& updateNotifyFuncti
 | 
						||
     m_isRunning = true;
 | 
						||
     m_cancellable = adoptGRef(g_cancellable_new());
 | 
						||
     if (!m_manager) {
 | 
						||
+        g_cancellable_cancel(m_cancellable_start.get());
 | 
						||
+        m_cancellable_start = adoptGRef(g_cancellable_new());
 | 
						||
         g_dbus_proxy_new_for_bus(G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, nullptr,
 | 
						||
             "org.freedesktop.GeoClue2", "/org/freedesktop/GeoClue2/Manager", "org.freedesktop.GeoClue2.Manager", m_cancellable.get(),
 | 
						||
             [](GObject*, GAsyncResult* result, gpointer userData) {
 | 
						||
@@ -91,6 +93,12 @@ void GeoclueGeolocationProvider::stop()
 | 
						||
     g_cancellable_cancel(m_cancellable.get());
 | 
						||
     m_cancellable = nullptr;
 | 
						||
     stopClient();
 | 
						||
+    g_cancellable_cancel(m_cancellable_start.get());
 | 
						||
+    m_cancellable_start = nullptr;
 | 
						||
+    g_cancellable_cancel(m_cancellable_setup.get());
 | 
						||
+    m_cancellable_setup = nullptr;
 | 
						||
+    g_cancellable_cancel(m_cancellable_create.get());
 | 
						||
+    m_cancellable_create = nullptr;
 | 
						||
     destroyManagerLater();
 | 
						||
 }
 | 
						||
 
 | 
						||
@@ -153,6 +161,8 @@ void GeoclueGeolocationProvider::createClient(const char* clientPath)
 | 
						||
         return;
 | 
						||
     }
 | 
						||
 
 | 
						||
+    g_cancellable_cancel(m_cancellable_create.get());
 | 
						||
+    m_cancellable_create = adoptGRef(g_cancellable_new());
 | 
						||
     g_dbus_proxy_new_for_bus(G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, nullptr,
 | 
						||
         "org.freedesktop.GeoClue2", clientPath, "org.freedesktop.GeoClue2.Client", m_cancellable.get(),
 | 
						||
         [](GObject*, GAsyncResult* result, gpointer userData) {
 | 
						||
diff --git a/Source/WebKit/UIProcess/geoclue/GeoclueGeolocationProvider.h b/Source/WebKit/UIProcess/geoclue/GeoclueGeolocationProvider.h
 | 
						||
index 31d29091985f34a65134a2b0e7cb3ace1dae441d..571ceac8a4b291fa6e91eb8b17065c0aba908ac3 100644
 | 
						||
--- a/Source/WebKit/UIProcess/geoclue/GeoclueGeolocationProvider.h
 | 
						||
+++ b/Source/WebKit/UIProcess/geoclue/GeoclueGeolocationProvider.h
 | 
						||
@@ -71,6 +71,9 @@ private:
 | 
						||
     GRefPtr<GDBusProxy> m_manager;
 | 
						||
     GRefPtr<GDBusProxy> m_client;
 | 
						||
     GRefPtr<GCancellable> m_cancellable;
 | 
						||
+    GRefPtr<GCancellable> m_cancellable_start;
 | 
						||
+    GRefPtr<GCancellable> m_cancellable_setup;
 | 
						||
+    GRefPtr<GCancellable> m_cancellable_create;
 | 
						||
     UpdateNotifyFunction m_updateNotifyFunction;
 | 
						||
     RunLoop::Timer<GeoclueGeolocationProvider> m_destroyManagerLaterTimer;
 | 
						||
 };
 | 
						||
diff --git a/Source/WebKit/UIProcess/glib/InspectorPlaywrightAgentClientGLib.cpp b/Source/WebKit/UIProcess/glib/InspectorPlaywrightAgentClientGLib.cpp
 | 
						||
new file mode 100644
 | 
						||
index 0000000000000000000000000000000000000000..c16ef9d7c0ba6b4aca36b0aad68296505dbacb50
 | 
						||
--- /dev/null
 | 
						||
+++ b/Source/WebKit/UIProcess/glib/InspectorPlaywrightAgentClientGLib.cpp
 | 
						||
@@ -0,0 +1,115 @@
 | 
						||
+/*
 | 
						||
+ * 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 {
 | 
						||
+
 | 
						||
+InspectorPlaywrightAgentClientGlib::InspectorPlaywrightAgentClientGlib(GMainLoop* mainLoop)
 | 
						||
+    : m_mainLoop(mainLoop)
 | 
						||
+{
 | 
						||
+}
 | 
						||
+
 | 
						||
+RefPtr<WebPageProxy> InspectorPlaywrightAgentClientGlib::createPage(WTF::String& error, const BrowserContext& browserContext)
 | 
						||
+{
 | 
						||
+    auto sessionID = browserContext.dataStore->sessionID();
 | 
						||
+    WebKitWebContext* context = m_idToContext.get(sessionID);
 | 
						||
+    if (!context && !browserContext.dataStore->isPersistent()) {
 | 
						||
+        ASSERT_NOT_REACHED();
 | 
						||
+        error = "Context with provided id not found";
 | 
						||
+        return nullptr;
 | 
						||
+    }
 | 
						||
+
 | 
						||
+    RefPtr<WebPageProxy> page = webkitBrowserInspectorCreateNewPageInContext(context);
 | 
						||
+    if (page == nullptr) {
 | 
						||
+        error = "Failed to create new page in the context";
 | 
						||
+        return nullptr;
 | 
						||
+    }
 | 
						||
+
 | 
						||
+    if (context == nullptr && sessionID != page->sessionID()) {
 | 
						||
+        ASSERT_NOT_REACHED();
 | 
						||
+        error = " Failed to create new page in default context";
 | 
						||
+        return nullptr;
 | 
						||
+    }
 | 
						||
+
 | 
						||
+    return page;
 | 
						||
+}
 | 
						||
+
 | 
						||
+void InspectorPlaywrightAgentClientGlib::closeBrowser()
 | 
						||
+{
 | 
						||
+    m_idToContext.clear();
 | 
						||
+#if PLATFORM(GTK)
 | 
						||
+    gtk_main_quit();
 | 
						||
+#else
 | 
						||
+    if (m_mainLoop)
 | 
						||
+        g_main_loop_quit(m_mainLoop);
 | 
						||
+#endif
 | 
						||
+}
 | 
						||
+
 | 
						||
+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();
 | 
						||
+}
 | 
						||
+
 | 
						||
+BrowserContext InspectorPlaywrightAgentClientGlib::createBrowserContext(WTF::String& error)
 | 
						||
+{
 | 
						||
+    BrowserContext browserContext;
 | 
						||
+    GRefPtr<WebKitWebsiteDataManager> data_manager = adoptGRef(webkit_website_data_manager_new_ephemeral());
 | 
						||
+    GRefPtr<WebKitWebContext> context = adoptGRef(WEBKIT_WEB_CONTEXT(g_object_new(WEBKIT_TYPE_WEB_CONTEXT, "website-data-manager", data_manager.get(), "process-swap-on-cross-site-navigation-enabled", true, nullptr)));
 | 
						||
+    if (!context) {
 | 
						||
+        error = "Failed to create GLib ephemeral context";
 | 
						||
+        return browserContext;
 | 
						||
+    }
 | 
						||
+    browserContext.processPool = &webkitWebContextGetProcessPool(context.get());
 | 
						||
+    browserContext.dataStore = &webkitWebsiteDataManagerGetDataStore(data_manager.get());
 | 
						||
+    PAL::SessionID sessionID = sessionIDFromContext(context.get());
 | 
						||
+    m_idToContext.set(sessionID, WTFMove(context));
 | 
						||
+    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..4cba2671042d3517e4b8f66e7b2bb780d57aa402
 | 
						||
--- /dev/null
 | 
						||
+++ b/Source/WebKit/UIProcess/glib/InspectorPlaywrightAgentClientGLib.h
 | 
						||
@@ -0,0 +1,59 @@
 | 
						||
+/*
 | 
						||
+ * 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 "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(GMainLoop* mainLoop);
 | 
						||
+    ~InspectorPlaywrightAgentClientGlib() override = default;
 | 
						||
+
 | 
						||
+    RefPtr<WebPageProxy> createPage(WTF::String& error, const BrowserContext&) override;
 | 
						||
+    void closeBrowser() override;
 | 
						||
+    BrowserContext createBrowserContext(WTF::String& error) override;
 | 
						||
+    void deleteBrowserContext(WTF::String& error, PAL::SessionID) override;
 | 
						||
+
 | 
						||
+private:
 | 
						||
+    WebKitWebContext* findContext(WTF::String& error, PAL::SessionID);
 | 
						||
+
 | 
						||
+    HashMap<PAL::SessionID, GRefPtr<WebKitWebContext>> m_idToContext;
 | 
						||
+    GMainLoop* m_mainLoop;
 | 
						||
+};
 | 
						||
+
 | 
						||
+} // namespace API
 | 
						||
+
 | 
						||
+#endif // ENABLE(REMOTE_INSPECTOR)
 | 
						||
diff --git a/Source/WebKit/UIProcess/gtk/InspectorTargetProxyGtk.cpp b/Source/WebKit/UIProcess/gtk/InspectorTargetProxyGtk.cpp
 | 
						||
new file mode 100644
 | 
						||
index 0000000000000000000000000000000000000000..8a86cc348bc210b71bb463dcb3057f575ad7c1d3
 | 
						||
--- /dev/null
 | 
						||
+++ b/Source/WebKit/UIProcess/gtk/InspectorTargetProxyGtk.cpp
 | 
						||
@@ -0,0 +1,44 @@
 | 
						||
+/*
 | 
						||
+ * Copyright (C) 2019 Microsoft Corporation.
 | 
						||
+ *
 | 
						||
+ * Redistribution and use in source and binary forms, with or without
 | 
						||
+ * modification, are permitted provided that the following conditions
 | 
						||
+ * are met:
 | 
						||
+ * 1. Redistributions of source code must retain the above copyright
 | 
						||
+ *    notice, this list of conditions and the following disclaimer.
 | 
						||
+ * 2. Redistributions in binary form must reproduce the above copyright
 | 
						||
+ *    notice, this list of conditions and the following disclaimer in the
 | 
						||
+ *    documentation and/or other materials provided with the distribution.
 | 
						||
+ *
 | 
						||
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
						||
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
						||
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
						||
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | 
						||
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | 
						||
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
						||
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | 
						||
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | 
						||
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
						||
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
						||
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
						||
+ */
 | 
						||
+
 | 
						||
+#include "config.h"
 | 
						||
+#include "InspectorTargetProxy.h"
 | 
						||
+
 | 
						||
+#include "WebPageProxy.h"
 | 
						||
+#include <WebCore/GtkUtilities.h>
 | 
						||
+#include <gtk/gtk.h>
 | 
						||
+
 | 
						||
+namespace WebKit {
 | 
						||
+
 | 
						||
+void InspectorTargetProxy::platformActivate(String& error) const
 | 
						||
+{
 | 
						||
+    GtkWidget* parent = gtk_widget_get_toplevel(m_page.viewWidget());
 | 
						||
+    if (WebCore::widgetIsOnscreenToplevelWindow(parent))
 | 
						||
+        gtk_window_present(GTK_WINDOW(parent));
 | 
						||
+    else
 | 
						||
+        error = "The view is not on screen";
 | 
						||
+}
 | 
						||
+
 | 
						||
+} // namespace WebKit
 | 
						||
diff --git a/Source/WebKit/UIProcess/gtk/WebPageInspectorEmulationAgentGtk.cpp b/Source/WebKit/UIProcess/gtk/WebPageInspectorEmulationAgentGtk.cpp
 | 
						||
new file mode 100644
 | 
						||
index 0000000000000000000000000000000000000000..e5e25acebabb76a05a77db02a99f1267bd99a3af
 | 
						||
--- /dev/null
 | 
						||
+++ b/Source/WebKit/UIProcess/gtk/WebPageInspectorEmulationAgentGtk.cpp
 | 
						||
@@ -0,0 +1,69 @@
 | 
						||
+/*
 | 
						||
+ * Copyright (C) 2019 Microsoft Corporation.
 | 
						||
+ *
 | 
						||
+ * Redistribution and use in source and binary forms, with or without
 | 
						||
+ * modification, are permitted provided that the following conditions
 | 
						||
+ * are met:
 | 
						||
+ * 1. Redistributions of source code must retain the above copyright
 | 
						||
+ *    notice, this list of conditions and the following disclaimer.
 | 
						||
+ * 2. Redistributions in binary form must reproduce the above copyright
 | 
						||
+ *    notice, this list of conditions and the following disclaimer in the
 | 
						||
+ *    documentation and/or other materials provided with the distribution.
 | 
						||
+ *
 | 
						||
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
						||
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
						||
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
						||
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | 
						||
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | 
						||
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
						||
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | 
						||
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | 
						||
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
						||
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
						||
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
						||
+ */
 | 
						||
+
 | 
						||
+#include "config.h"
 | 
						||
+#include "DrawingAreaProxyCoordinatedGraphics.h"
 | 
						||
+#include "WebPageInspectorEmulationAgent.h"
 | 
						||
+#include "WebPageProxy.h"
 | 
						||
+#include <WebCore/IntSize.h>
 | 
						||
+#include <gtk/gtk.h>
 | 
						||
+
 | 
						||
+namespace WebKit {
 | 
						||
+void WebPageInspectorEmulationAgent::platformSetSize(int width, int height, Function<void (const String& error)>&& callback)
 | 
						||
+{
 | 
						||
+    GtkWidget* viewWidget = m_page.viewWidget();
 | 
						||
+    GtkWidget* window = gtk_widget_get_toplevel(viewWidget);
 | 
						||
+    if (!window) {
 | 
						||
+        callback("Cannot find parent window"_s);
 | 
						||
+        return;
 | 
						||
+    }
 | 
						||
+    if (!GTK_IS_WINDOW(window)) {
 | 
						||
+        callback("Toplevel is not a window"_s);
 | 
						||
+        return;
 | 
						||
+    }
 | 
						||
+    GtkAllocation viewAllocation;
 | 
						||
+    gtk_widget_get_allocation(viewWidget, &viewAllocation);
 | 
						||
+    if (viewAllocation.width == width && viewAllocation.height == height) {
 | 
						||
+        callback(String());
 | 
						||
+        return;
 | 
						||
+    }
 | 
						||
+
 | 
						||
+    GtkAllocation windowAllocation;
 | 
						||
+    gtk_widget_get_allocation(window, &windowAllocation);
 | 
						||
+
 | 
						||
+    width += windowAllocation.width - viewAllocation.width;
 | 
						||
+    height += windowAllocation.height - viewAllocation.height;
 | 
						||
+
 | 
						||
+    if (auto* drawingArea = static_cast<DrawingAreaProxyCoordinatedGraphics*>(m_page.drawingArea())) {
 | 
						||
+        drawingArea->waitForSizeUpdate([callback = WTFMove(callback)]() {
 | 
						||
+            callback(String());
 | 
						||
+        });
 | 
						||
+    } else {
 | 
						||
+        callback("No backing store for window"_s);
 | 
						||
+    }
 | 
						||
+    gtk_window_resize(GTK_WINDOW(window), width, height);
 | 
						||
+}
 | 
						||
+
 | 
						||
+} // namespace WebKit
 | 
						||
diff --git a/Source/WebKit/UIProcess/gtk/WebPageInspectorInputAgentGtk.cpp b/Source/WebKit/UIProcess/gtk/WebPageInspectorInputAgentGtk.cpp
 | 
						||
new file mode 100644
 | 
						||
index 0000000000000000000000000000000000000000..7ad3fe416c5c747eaad8c6948c3549a3984223ea
 | 
						||
--- /dev/null
 | 
						||
+++ b/Source/WebKit/UIProcess/gtk/WebPageInspectorInputAgentGtk.cpp
 | 
						||
@@ -0,0 +1,107 @@
 | 
						||
+/*
 | 
						||
+ * 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, 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);
 | 
						||
+    String keyIdentifier;
 | 
						||
+    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);
 | 
						||
+        keyIdentifier = WebCore::PlatformKeyboardEvent::keyIdentifierForGdkKeyCode(keyVal);
 | 
						||
+    }
 | 
						||
+    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 8754183edc70b3a341a6584eaf277af1bb1fb4db..34296c8f37dc1914debe00c251db405957fdaccf 100644
 | 
						||
--- a/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm
 | 
						||
+++ b/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm
 | 
						||
@@ -459,6 +459,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..b75c2ce5ce9e9da3a33bca41ab548ec7a2f819ed
 | 
						||
--- /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;
 | 
						||
+    BrowserContext createBrowserContext(WTF::String& error) 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..5db92c0580fd4f216ac86ede56eaac2eabec27da
 | 
						||
--- /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];
 | 
						||
+}
 | 
						||
+
 | 
						||
+BrowserContext InspectorPlaywrightAgentClientMac::createBrowserContext(WTF::String& error)
 | 
						||
+{
 | 
						||
+    _WKBrowserContext* wkBrowserContext = [[delegate_ createBrowserContext] autorelease];
 | 
						||
+    BrowserContext 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 f0cc38a489474fb9e964fefc91e837f6266d2c04..71caf1fd10757a34aa9ef21d88d7326a66bb3a47 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();
 | 
						||
 
 | 
						||
@@ -204,6 +206,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 03192d76aefb19cac18fdd5c4c6de50a2f2585c5..02ea60cb127f68fc073e417856c8c3248df3397c 100644
 | 
						||
--- a/Source/WebKit/UIProcess/mac/PageClientImplMac.mm
 | 
						||
+++ b/Source/WebKit/UIProcess/mac/PageClientImplMac.mm
 | 
						||
@@ -78,6 +78,7 @@
 | 
						||
 #import <WebCore/TextUndoInsertionMarkupMac.h>
 | 
						||
 #import <WebCore/ValidationBubble.h>
 | 
						||
 #import <WebCore/WebCoreCALayerExtras.h>
 | 
						||
+#import <WebCore/NotImplemented.h>
 | 
						||
 #import <wtf/ProcessPrivilege.h>
 | 
						||
 #import <wtf/RetainPtr.h>
 | 
						||
 #import <wtf/text/CString.h>
 | 
						||
@@ -103,6 +104,13 @@ namespace WebKit {
 | 
						||
 
 | 
						||
 using namespace WebCore;
 | 
						||
 
 | 
						||
+static bool _headless = false;
 | 
						||
+
 | 
						||
+// static
 | 
						||
+void PageClientImpl::setHeadless(bool headless) {
 | 
						||
+    _headless = true;
 | 
						||
+}
 | 
						||
+
 | 
						||
 PageClientImpl::PageClientImpl(NSView *view, WKWebView *webView)
 | 
						||
     : PageClientImplCocoa(webView)
 | 
						||
     , m_view(view)
 | 
						||
@@ -156,6 +164,9 @@ NSWindow *PageClientImpl::activeWindow() const
 | 
						||
 
 | 
						||
 bool PageClientImpl::isViewWindowActive()
 | 
						||
 {
 | 
						||
+    if (_headless)
 | 
						||
+        return true;
 | 
						||
+
 | 
						||
     ASSERT(hasProcessPrivilege(ProcessPrivilege::CanCommunicateWithWindowServer));
 | 
						||
     NSWindow *activeViewWindow = activeWindow();
 | 
						||
     return activeViewWindow.isKeyWindow || [NSApp keyWindow] == activeViewWindow;
 | 
						||
@@ -163,6 +174,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)
 | 
						||
@@ -186,6 +200,9 @@ void PageClientImpl::makeFirstResponder()
 | 
						||
     
 | 
						||
 bool PageClientImpl::isViewVisible()
 | 
						||
 {
 | 
						||
+    if (_headless)
 | 
						||
+        return true;
 | 
						||
+
 | 
						||
     NSView *activeView = this->activeView();
 | 
						||
     NSWindow *activeViewWindow = activeWindow();
 | 
						||
 
 | 
						||
@@ -269,7 +286,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)
 | 
						||
@@ -447,6 +465,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);
 | 
						||
 }
 | 
						||
 
 | 
						||
@@ -738,6 +758,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);
 | 
						||
@@ -904,6 +931,9 @@ void PageClientImpl::didRestoreScrollPosition()
 | 
						||
 
 | 
						||
 bool PageClientImpl::windowIsFrontWindowUnderMouse(const NativeWebMouseEvent& event)
 | 
						||
 {
 | 
						||
+    // Simulated event.
 | 
						||
+    if (!event.nativeEvent())
 | 
						||
+        return false;
 | 
						||
     return m_impl->windowIsFrontWindowUnderMouse(event.nativeEvent());
 | 
						||
 }
 | 
						||
 
 | 
						||
diff --git a/Source/WebKit/UIProcess/mac/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..30e6ae3bdc8c1695189885afae949071add54c4e
 | 
						||
--- /dev/null
 | 
						||
+++ b/Source/WebKit/UIProcess/mac/WebPageInspectorInputAgentMac.mm
 | 
						||
@@ -0,0 +1,124 @@
 | 
						||
+/*
 | 
						||
+ * Copyright (C) 2019 Microsoft Corporation.
 | 
						||
+ *
 | 
						||
+ * Redistribution and use in source and binary forms, with or without
 | 
						||
+ * modification, are permitted provided that the following conditions
 | 
						||
+ * are met:
 | 
						||
+ * 1. Redistributions of source code must retain the above copyright
 | 
						||
+ *    notice, this list of conditions and the following disclaimer.
 | 
						||
+ * 2. Redistributions in binary form must reproduce the above copyright
 | 
						||
+ *    notice, this list of conditions and the following disclaimer in the
 | 
						||
+ *    documentation and/or other materials provided with the distribution.
 | 
						||
+ *
 | 
						||
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
						||
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
						||
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
						||
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | 
						||
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | 
						||
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
						||
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | 
						||
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | 
						||
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
						||
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
						||
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
						||
+ */
 | 
						||
+
 | 
						||
+#import "config.h"
 | 
						||
+#import "NativeWebMouseEvent.h"
 | 
						||
+#import "WebPageInspectorInputAgent.h"
 | 
						||
+#import "WebPageProxy.h"
 | 
						||
+#import <WebCore/IntPoint.h>
 | 
						||
+#import <WebCore/IntSize.h>
 | 
						||
+#import "NativeWebKeyboardEvent.h"
 | 
						||
+#import <wtf/HexNumber.h>
 | 
						||
+
 | 
						||
+namespace WebKit {
 | 
						||
+
 | 
						||
+using namespace WebCore;
 | 
						||
+
 | 
						||
+void WebPageInspectorInputAgent::platformDispatchMouseEvent(const String& type, int x, int y, const int* optionalModifiers, const String* button, const int* optionalClickCount) {
 | 
						||
+    IntPoint locationInWindow(x, y);
 | 
						||
+
 | 
						||
+    NSEventModifierFlags modifiers = 0;
 | 
						||
+    if (optionalModifiers) {
 | 
						||
+        int inputModifiers = *optionalModifiers;
 | 
						||
+        if (inputModifiers & 1)
 | 
						||
+            modifiers |= NSEventModifierFlagShift;
 | 
						||
+        if (inputModifiers & 2)
 | 
						||
+            modifiers |= NSEventModifierFlagControl;
 | 
						||
+        if (inputModifiers & 4)
 | 
						||
+            modifiers |= NSEventModifierFlagOption;
 | 
						||
+        if (inputModifiers & 8)
 | 
						||
+            modifiers |= NSEventModifierFlagCommand;
 | 
						||
+    }
 | 
						||
+    int clickCount = optionalClickCount ? *optionalClickCount : 0;
 | 
						||
+
 | 
						||
+    NSTimeInterval timestamp = [NSDate timeIntervalSinceReferenceDate];
 | 
						||
+    NSWindow *window = m_page.platformWindow();
 | 
						||
+    NSInteger windowNumber = window.windowNumber;
 | 
						||
+
 | 
						||
+    NSEventType downEventType = (NSEventType)0;
 | 
						||
+    NSEventType dragEventType = (NSEventType)0;
 | 
						||
+    NSEventType upEventType = (NSEventType)0;
 | 
						||
+
 | 
						||
+    if (!button || *button == "none") {
 | 
						||
+        downEventType = NSEventTypeMouseMoved;
 | 
						||
+        dragEventType = NSEventTypeMouseMoved;
 | 
						||
+        upEventType = NSEventTypeMouseMoved;
 | 
						||
+    } else if (*button == "left") {
 | 
						||
+        downEventType = NSEventTypeLeftMouseDown;
 | 
						||
+        dragEventType = NSEventTypeLeftMouseDragged;
 | 
						||
+        upEventType = NSEventTypeLeftMouseUp;
 | 
						||
+    } else if (*button == "middle") {
 | 
						||
+        downEventType = NSEventTypeOtherMouseDown;
 | 
						||
+        dragEventType = NSEventTypeLeftMouseDragged;
 | 
						||
+        upEventType = NSEventTypeOtherMouseUp;
 | 
						||
+    } else if (*button == "right") {
 | 
						||
+        downEventType = NSEventTypeRightMouseDown;
 | 
						||
+        upEventType = NSEventTypeRightMouseUp;
 | 
						||
+    }
 | 
						||
+
 | 
						||
+    NSInteger eventNumber = 0;
 | 
						||
+
 | 
						||
+    NSEvent* event = nil;
 | 
						||
+    if (type == "move") {
 | 
						||
+        event = [NSEvent mouseEventWithType:dragEventType location:locationInWindow modifierFlags:modifiers timestamp:timestamp windowNumber:windowNumber context:nil eventNumber:eventNumber clickCount:clickCount pressure:0.0f];
 | 
						||
+    } else if (type == "down") {
 | 
						||
+        event = [NSEvent mouseEventWithType:downEventType location:locationInWindow modifierFlags:modifiers timestamp:timestamp windowNumber:windowNumber context:nil eventNumber:eventNumber clickCount:clickCount pressure:WebCore::ForceAtClick];
 | 
						||
+    } else if (type == "up") {
 | 
						||
+        event = [NSEvent mouseEventWithType:upEventType location:locationInWindow modifierFlags:modifiers timestamp:timestamp windowNumber:windowNumber context:nil eventNumber:eventNumber clickCount:clickCount pressure:0.0f];
 | 
						||
+    }
 | 
						||
+
 | 
						||
+    if (event) {
 | 
						||
+        NativeWebMouseEvent nativeEvent(event, nil, [window contentView]);
 | 
						||
+        m_page.handleMouseEvent(nativeEvent);
 | 
						||
+    }
 | 
						||
+}
 | 
						||
+
 | 
						||
+void WebPageInspectorInputAgent::platformDispatchKeyEvent(WebKeyboardEvent::Type type, const String& text, const String& unmodifiedText, const String& key, const String& code, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<WebEvent::Modifier> modifiers, Vector<String>& commands, WallTime timestamp)
 | 
						||
+{
 | 
						||
+    String keyIdentifier = key.length() == 1 ? makeString("U+", hex(toASCIIUpper(key.characterAt(0)), 4)) : key;
 | 
						||
+    Vector<WebCore::KeypressCommand> macCommands;
 | 
						||
+    for (const String& command : commands)
 | 
						||
+      macCommands.append(WebCore::KeypressCommand(command.utf8().data()));
 | 
						||
+    if (text.length() > 0 && macCommands.size() == 0)
 | 
						||
+      macCommands.append(WebCore::KeypressCommand("insertText:", text));
 | 
						||
+    NativeWebKeyboardEvent event(
 | 
						||
+        type,
 | 
						||
+        text,
 | 
						||
+        unmodifiedText,
 | 
						||
+        key,
 | 
						||
+        code,
 | 
						||
+        keyIdentifier,
 | 
						||
+        windowsVirtualKeyCode,
 | 
						||
+        nativeVirtualKeyCode,
 | 
						||
+        isAutoRepeat,
 | 
						||
+        isKeypad,
 | 
						||
+        isSystemKey,
 | 
						||
+        modifiers,
 | 
						||
+        timestamp,
 | 
						||
+        WTFMove(macCommands));
 | 
						||
+    m_page.handleKeyboardEvent(event);
 | 
						||
+}
 | 
						||
+
 | 
						||
+} // namespace WebKit
 | 
						||
diff --git a/Source/WebKit/UIProcess/win/InspectorPlaywrightAgentClientWin.cpp b/Source/WebKit/UIProcess/win/InspectorPlaywrightAgentClientWin.cpp
 | 
						||
new file mode 100644
 | 
						||
index 0000000000000000000000000000000000000000..544442b75afcba6e121ab202ad32dcdfaf923e2e
 | 
						||
--- /dev/null
 | 
						||
+++ b/Source/WebKit/UIProcess/win/InspectorPlaywrightAgentClientWin.cpp
 | 
						||
@@ -0,0 +1,83 @@
 | 
						||
+/*
 | 
						||
+ * 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 <wtf/HashMap.h>
 | 
						||
+#include <wtf/RefPtr.h>
 | 
						||
+#include <wtf/text/StringView.h>
 | 
						||
+#include <wtf/text/WTFString.h>
 | 
						||
+
 | 
						||
+namespace WebKit {
 | 
						||
+
 | 
						||
+InspectorPlaywrightAgentClientWin::InspectorPlaywrightAgentClientWin(CreatePageCallback createPage, QuitCallback quit)
 | 
						||
+    : m_createPage(createPage)
 | 
						||
+    , m_quit(quit)
 | 
						||
+{
 | 
						||
+}
 | 
						||
+
 | 
						||
+RefPtr<WebPageProxy> InspectorPlaywrightAgentClientWin::createPage(WTF::String& error, const BrowserContext& context)
 | 
						||
+{
 | 
						||
+    auto conf = API::PageConfiguration::create();
 | 
						||
+    auto prefs = WebPreferences::create(String(), "WebKit2Automation.", "WebKit2Automation.");
 | 
						||
+    conf->setProcessPool(context.processPool.get());
 | 
						||
+    conf->setWebsiteDataStore(context.dataStore.get());
 | 
						||
+    return toImpl(m_createPage(toAPI(&conf.get())));
 | 
						||
+}
 | 
						||
+
 | 
						||
+void InspectorPlaywrightAgentClientWin::closeBrowser()
 | 
						||
+{
 | 
						||
+    m_quit();
 | 
						||
+}
 | 
						||
+
 | 
						||
+BrowserContext InspectorPlaywrightAgentClientWin::createBrowserContext(WTF::String& error)
 | 
						||
+{
 | 
						||
+    auto config = API::ProcessPoolConfiguration::create();
 | 
						||
+    BrowserContext browserContext;
 | 
						||
+    browserContext.processPool = WebKit::WebProcessPool::create(config);
 | 
						||
+    browserContext.dataStore = WebKit::WebsiteDataStore::createNonPersistent();
 | 
						||
+    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..2536fe399ef9a5916803954e1f4971a24b7ca4ec
 | 
						||
--- /dev/null
 | 
						||
+++ b/Source/WebKit/UIProcess/win/InspectorPlaywrightAgentClientWin.h
 | 
						||
@@ -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.
 | 
						||
+ */
 | 
						||
+
 | 
						||
+#pragma once
 | 
						||
+
 | 
						||
+#if ENABLE(REMOTE_INSPECTOR)
 | 
						||
+
 | 
						||
+#include "InspectorPlaywrightAgentClient.h"
 | 
						||
+#include <WebKit/WKInspector.h>
 | 
						||
+#include <wtf/Forward.h>
 | 
						||
+#include <wtf/text/StringHash.h>
 | 
						||
+
 | 
						||
+typedef WKPageRef (*CreatePageCallback)(WKPageConfigurationRef configuration);
 | 
						||
+typedef void (*QuitCallback)();
 | 
						||
+
 | 
						||
+namespace WebKit {
 | 
						||
+
 | 
						||
+class InspectorPlaywrightAgentClientWin : public InspectorPlaywrightAgentClient {
 | 
						||
+    WTF_MAKE_FAST_ALLOCATED;
 | 
						||
+public:
 | 
						||
+    InspectorPlaywrightAgentClientWin(CreatePageCallback, QuitCallback);
 | 
						||
+    ~InspectorPlaywrightAgentClientWin() override = default;
 | 
						||
+
 | 
						||
+    RefPtr<WebPageProxy> createPage(WTF::String& error, const BrowserContext&) override;
 | 
						||
+    void closeBrowser() override;
 | 
						||
+    BrowserContext createBrowserContext(WTF::String& error) override;
 | 
						||
+    void deleteBrowserContext(WTF::String& error, PAL::SessionID) override;
 | 
						||
+
 | 
						||
+private:
 | 
						||
+    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/WebPageInspectorEmulationAgentWin.cpp b/Source/WebKit/UIProcess/win/WebPageInspectorEmulationAgentWin.cpp
 | 
						||
new file mode 100644
 | 
						||
index 0000000000000000000000000000000000000000..520d9714bac279a8b778c2c377af4411fba8d5d7
 | 
						||
--- /dev/null
 | 
						||
+++ b/Source/WebKit/UIProcess/win/WebPageInspectorEmulationAgentWin.cpp
 | 
						||
@@ -0,0 +1,58 @@
 | 
						||
+/*
 | 
						||
+ * Copyright (C) 2020 Microsoft Corporation.
 | 
						||
+ *
 | 
						||
+ * Redistribution and use in source and binary forms, with or without
 | 
						||
+ * modification, are permitted provided that the following conditions
 | 
						||
+ * are met:
 | 
						||
+ * 1. Redistributions of source code must retain the above copyright
 | 
						||
+ *    notice, this list of conditions and the following disclaimer.
 | 
						||
+ * 2. Redistributions in binary form must reproduce the above copyright
 | 
						||
+ *    notice, this list of conditions and the following disclaimer in the
 | 
						||
+ *    documentation and/or other materials provided with the distribution.
 | 
						||
+ *
 | 
						||
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
						||
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
						||
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
						||
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | 
						||
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | 
						||
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
						||
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | 
						||
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | 
						||
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
						||
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
						||
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
						||
+ */
 | 
						||
+
 | 
						||
+#include "config.h"
 | 
						||
+#include "WebPageInspectorEmulationAgent.h"
 | 
						||
+#include "WebPageProxy.h"
 | 
						||
+
 | 
						||
+namespace WebKit {
 | 
						||
+
 | 
						||
+void WebPageInspectorEmulationAgent::platformSetSize(int width, int height, Function<void (const String& error)>&& callback)
 | 
						||
+{
 | 
						||
+    HWND viewHwnd = m_page.viewWidget();
 | 
						||
+    HWND windowHwnd = GetAncestor(viewHwnd, GA_ROOT);
 | 
						||
+    RECT viewRect;
 | 
						||
+    RECT windowRect;
 | 
						||
+
 | 
						||
+    if (!windowHwnd || !GetWindowRect(windowHwnd, &windowRect)) {
 | 
						||
+        callback("Could not retrieve window size");
 | 
						||
+        return;
 | 
						||
+    }
 | 
						||
+    if (!GetWindowRect(viewHwnd, &viewRect)) {
 | 
						||
+        callback("Could retrieve view size");
 | 
						||
+        return;
 | 
						||
+    }
 | 
						||
+
 | 
						||
+    width += windowRect.right - windowRect.left - viewRect.right + viewRect.left;
 | 
						||
+    height += windowRect.bottom - windowRect.top - viewRect.bottom + viewRect.top;
 | 
						||
+
 | 
						||
+    if (!SetWindowPos(windowHwnd, 0, 0, 0, width, height, SWP_NOMOVE)) {
 | 
						||
+        callback("Could not resize window");
 | 
						||
+        return;
 | 
						||
+    }
 | 
						||
+    callback(String());
 | 
						||
+}
 | 
						||
+
 | 
						||
+} // namespace WebKit
 | 
						||
diff --git a/Source/WebKit/UIProcess/win/WebPageInspectorInputAgentWin.cpp b/Source/WebKit/UIProcess/win/WebPageInspectorInputAgentWin.cpp
 | 
						||
new file mode 100644
 | 
						||
index 0000000000000000000000000000000000000000..a299240b1fea96694cb47fa11fc6a6411ffdaf70
 | 
						||
--- /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, 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,
 | 
						||
+        "",
 | 
						||
+        windowsVirtualKeyCode,
 | 
						||
+        nativeVirtualKeyCode,
 | 
						||
+        isAutoRepeat,
 | 
						||
+        isKeypad,
 | 
						||
+        isSystemKey,
 | 
						||
+        modifiers,
 | 
						||
+        timestamp);
 | 
						||
+    m_page.handleKeyboardEvent(event);
 | 
						||
+}
 | 
						||
+
 | 
						||
+} // namespace WebKit
 | 
						||
diff --git a/Source/WebKit/UIProcess/win/WebProcessPoolWin.cpp b/Source/WebKit/UIProcess/win/WebProcessPoolWin.cpp
 | 
						||
index 18f9e93932793b7c3e44e6346be0f13ed6dbf233..acb0617bcded07029665d4949659c73adf2fd633 100644
 | 
						||
--- a/Source/WebKit/UIProcess/win/WebProcessPoolWin.cpp
 | 
						||
+++ b/Source/WebKit/UIProcess/win/WebProcessPoolWin.cpp
 | 
						||
@@ -26,7 +26,7 @@
 | 
						||
 
 | 
						||
 #include "config.h"
 | 
						||
 #include "WebProcessPool.h"
 | 
						||
-
 | 
						||
+#include "NetworkProcessMessages.h"
 | 
						||
 #include "WebProcessCreationParameters.h"
 | 
						||
 #include <WebCore/NotImplemented.h>
 | 
						||
 
 | 
						||
@@ -97,4 +97,11 @@ void WebProcessPool::platformResolvePathsForSandboxExtensions()
 | 
						||
 {
 | 
						||
 }
 | 
						||
 
 | 
						||
+void WebProcessPool::setIgnoreTLSErrors(bool ignoreTLSErrors)
 | 
						||
+{
 | 
						||
+    m_ignoreTLSErrors = ignoreTLSErrors;
 | 
						||
+    if (networkProcess())
 | 
						||
+        networkProcess()->send(Messages::NetworkProcess::SetIgnoreTLSErrors(m_ignoreTLSErrors), 0);
 | 
						||
+}
 | 
						||
+
 | 
						||
 } // namespace WebKit
 | 
						||
diff --git a/Source/WebKit/UIProcess/wpe/InspectorTargetProxyWPE.cpp b/Source/WebKit/UIProcess/wpe/InspectorTargetProxyWPE.cpp
 | 
						||
new file mode 100644
 | 
						||
index 0000000000000000000000000000000000000000..7453194ca6f032ba86a4c67f5bf12688ab6ec1be
 | 
						||
--- /dev/null
 | 
						||
+++ b/Source/WebKit/UIProcess/wpe/InspectorTargetProxyWPE.cpp
 | 
						||
@@ -0,0 +1,40 @@
 | 
						||
+/*
 | 
						||
+ * Copyright (C) 2019 Microsoft Corporation.
 | 
						||
+ *
 | 
						||
+ * Redistribution and use in source and binary forms, with or without
 | 
						||
+ * modification, are permitted provided that the following conditions
 | 
						||
+ * are met:
 | 
						||
+ * 1. Redistributions of source code must retain the above copyright
 | 
						||
+ *    notice, this list of conditions and the following disclaimer.
 | 
						||
+ * 2. Redistributions in binary form must reproduce the above copyright
 | 
						||
+ *    notice, this list of conditions and the following disclaimer in the
 | 
						||
+ *    documentation and/or other materials provided with the distribution.
 | 
						||
+ *
 | 
						||
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
						||
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
						||
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
						||
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | 
						||
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | 
						||
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
						||
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | 
						||
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | 
						||
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
						||
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
						||
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
						||
+ */
 | 
						||
+
 | 
						||
+#include "config.h"
 | 
						||
+#include "InspectorTargetProxy.h"
 | 
						||
+
 | 
						||
+#include "WebPageProxy.h"
 | 
						||
+#include <wpe/wpe.h>
 | 
						||
+
 | 
						||
+namespace WebKit {
 | 
						||
+
 | 
						||
+void InspectorTargetProxy::platformActivate(String& error) const
 | 
						||
+{
 | 
						||
+    struct wpe_view_backend* backend = m_page.viewBackend();
 | 
						||
+    wpe_view_backend_add_activity_state(backend, wpe_view_activity_state_visible | wpe_view_activity_state_focused | wpe_view_activity_state_in_window);
 | 
						||
+}
 | 
						||
+
 | 
						||
+} // namespace WebKit
 | 
						||
diff --git a/Source/WebKit/UIProcess/wpe/WebPageInspectorEmulationAgentWPE.cpp b/Source/WebKit/UIProcess/wpe/WebPageInspectorEmulationAgentWPE.cpp
 | 
						||
new file mode 100644
 | 
						||
index 0000000000000000000000000000000000000000..5dc76aa302cb574307059e66a1b73730efe920da
 | 
						||
--- /dev/null
 | 
						||
+++ b/Source/WebKit/UIProcess/wpe/WebPageInspectorEmulationAgentWPE.cpp
 | 
						||
@@ -0,0 +1,41 @@
 | 
						||
+/*
 | 
						||
+ * Copyright (C) 2019 Microsoft Corporation.
 | 
						||
+ *
 | 
						||
+ * Redistribution and use in source and binary forms, with or without
 | 
						||
+ * modification, are permitted provided that the following conditions
 | 
						||
+ * are met:
 | 
						||
+ * 1. Redistributions of source code must retain the above copyright
 | 
						||
+ *    notice, this list of conditions and the following disclaimer.
 | 
						||
+ * 2. Redistributions in binary form must reproduce the above copyright
 | 
						||
+ *    notice, this list of conditions and the following disclaimer in the
 | 
						||
+ *    documentation and/or other materials provided with the distribution.
 | 
						||
+ *
 | 
						||
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
						||
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
						||
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
						||
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | 
						||
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | 
						||
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
						||
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | 
						||
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | 
						||
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
						||
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
						||
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
						||
+ */
 | 
						||
+
 | 
						||
+#include "config.h"
 | 
						||
+#include "WebPageInspectorEmulationAgent.h"
 | 
						||
+
 | 
						||
+#include "WebPageProxy.h"
 | 
						||
+#include <wpe/wpe.h>
 | 
						||
+
 | 
						||
+namespace WebKit {
 | 
						||
+
 | 
						||
+void WebPageInspectorEmulationAgent::platformSetSize(int width, int height, Function<void (const String& error)>&& callback)
 | 
						||
+{
 | 
						||
+    struct wpe_view_backend* backend = m_page.viewBackend();
 | 
						||
+    wpe_view_backend_dispatch_set_size(backend, width, height);
 | 
						||
+    callback(String());
 | 
						||
+}
 | 
						||
+
 | 
						||
+} // namespace WebKit
 | 
						||
diff --git a/Source/WebKit/UIProcess/wpe/WebPageInspectorInputAgentWPE.cpp b/Source/WebKit/UIProcess/wpe/WebPageInspectorInputAgentWPE.cpp
 | 
						||
new file mode 100644
 | 
						||
index 0000000000000000000000000000000000000000..585fb151f302e4b376c705ed0d0974d518733605
 | 
						||
--- /dev/null
 | 
						||
+++ b/Source/WebKit/UIProcess/wpe/WebPageInspectorInputAgentWPE.cpp
 | 
						||
@@ -0,0 +1,59 @@
 | 
						||
+/*
 | 
						||
+ * 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, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<WebEvent::Modifier> modifiers, Vector<String>& macCommands, WallTime timestamp)
 | 
						||
+{
 | 
						||
+    unsigned keyCode = WebCore::PlatformKeyboardEvent::WPEKeyCodeForWindowsKeyCode(windowsVirtualKeyCode);
 | 
						||
+    String keyIdentifier;
 | 
						||
+    if (keyCode)
 | 
						||
+        keyIdentifier = WebCore::PlatformKeyboardEvent::keyIdentifierForWPEKeyCode(keyCode);
 | 
						||
+    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 864f9fa399b899a19223a0b31b9b5eaadbfe947f..82a73575abeaadb112ff0e3866e59adc62dac44b 100644
 | 
						||
--- a/Source/WebKit/WebKit.xcodeproj/project.pbxproj
 | 
						||
+++ b/Source/WebKit/WebKit.xcodeproj/project.pbxproj
 | 
						||
@@ -1767,6 +1767,19 @@
 | 
						||
 		CEE4AE2B1A5DCF430002F49B /* UIKitSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = CEE4AE2A1A5DCF430002F49B /* UIKitSPI.h */; };
 | 
						||
 		D3B9484711FF4B6500032B39 /* WebPopupMenu.h in Headers */ = {isa = PBXBuildFile; fileRef = D3B9484311FF4B6500032B39 /* WebPopupMenu.h */; };
 | 
						||
 		D3B9484911FF4B6500032B39 /* WebSearchPopupMenu.h in Headers */ = {isa = PBXBuildFile; fileRef = D3B9484511FF4B6500032B39 /* WebSearchPopupMenu.h */; };
 | 
						||
+		D71A94322370E025002C4D9E /* InspectorPlaywrightAgentClientMac.h in Headers */ = {isa = PBXBuildFile; fileRef = D71A94302370E025002C4D9E /* InspectorPlaywrightAgentClientMac.h */; };
 | 
						||
+		D71A94342370E07A002C4D9E /* InspectorPlaywrightAgentClient.h in Headers */ = {isa = PBXBuildFile; fileRef = D71A94332370E07A002C4D9E /* InspectorPlaywrightAgentClient.h */; };
 | 
						||
+		D71A94382370F032002C4D9E /* BrowserInspectorController.h in Headers */ = {isa = PBXBuildFile; fileRef = D71A94372370F032002C4D9E /* BrowserInspectorController.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, ); }; };
 | 
						||
 		E105FE5418D7B9DE008F57A8 /* EditingRange.h in Headers */ = {isa = PBXBuildFile; fileRef = E105FE5318D7B9DE008F57A8 /* EditingRange.h */; };
 | 
						||
@@ -5202,6 +5215,20 @@
 | 
						||
 		D3B9484311FF4B6500032B39 /* WebPopupMenu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebPopupMenu.h; sourceTree = "<group>"; };
 | 
						||
 		D3B9484411FF4B6500032B39 /* WebSearchPopupMenu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebSearchPopupMenu.cpp; sourceTree = "<group>"; };
 | 
						||
 		D3B9484511FF4B6500032B39 /* WebSearchPopupMenu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebSearchPopupMenu.h; sourceTree = "<group>"; };
 | 
						||
+		D71A942C2370DF81002C4D9E /* WKBrowserInspector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKBrowserInspector.h; sourceTree = "<group>"; };
 | 
						||
+		D71A94302370E025002C4D9E /* InspectorPlaywrightAgentClientMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorPlaywrightAgentClientMac.h; sourceTree = "<group>"; };
 | 
						||
+		D71A94332370E07A002C4D9E /* InspectorPlaywrightAgentClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorPlaywrightAgentClient.h; sourceTree = "<group>"; };
 | 
						||
+		D71A94372370F032002C4D9E /* BrowserInspectorController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BrowserInspectorController.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>"; };
 | 
						||
@@ -7131,6 +7158,7 @@
 | 
						||
 		37C4C08318149C2A003688B9 /* Cocoa */ = {
 | 
						||
 			isa = PBXGroup;
 | 
						||
 			children = (
 | 
						||
+				D71A94492372290B002C4D9E /* _WKBrowserInspector.h */,
 | 
						||
 				1A43E826188F38E2009E4D30 /* Deprecated */,
 | 
						||
 				37A5E01218BBF937000A081E /* _WKActivatedElementInfo.h */,
 | 
						||
 				37A5E01118BBF937000A081E /* _WKActivatedElementInfo.mm */,
 | 
						||
@@ -8833,6 +8861,13 @@
 | 
						||
 		BC032DC310F438260058C15A /* UIProcess */ = {
 | 
						||
 			isa = PBXGroup;
 | 
						||
 			children = (
 | 
						||
+				D76D6887238DBD80008D314B /* InspectorDialogAgent.h */,
 | 
						||
+				D71A944B237239FB002C4D9E /* BrowserInspectorPipe.h */,
 | 
						||
+				D71A943F2371F67E002C4D9E /* WebPageInspectorEmulationAgent.h */,
 | 
						||
+				D71A94402371F67E002C4D9E /* WebPageInspectorInputAgent.h */,
 | 
						||
+				D71A94392370F060002C4D9E /* RemoteInspectorPipe.h */,
 | 
						||
+				D71A94372370F032002C4D9E /* BrowserInspectorController.h */,
 | 
						||
+				D71A94332370E07A002C4D9E /* InspectorPlaywrightAgentClient.h */,
 | 
						||
 				BC032DC410F4387C0058C15A /* API */,
 | 
						||
 				512F588D12A8836F00629530 /* Authentication */,
 | 
						||
 				9955A6E81C79809000EB6A93 /* Automation */,
 | 
						||
@@ -9112,6 +9147,7 @@
 | 
						||
 		BC0C376610F807660076D7CB /* C */ = {
 | 
						||
 			isa = PBXGroup;
 | 
						||
 			children = (
 | 
						||
+				D71A942C2370DF81002C4D9E /* WKBrowserInspector.h */,
 | 
						||
 				5123CF18133D25E60056F800 /* cg */,
 | 
						||
 				6EE849C41368D9040038D481 /* mac */,
 | 
						||
 				BCB63477116BF10600603215 /* WebKit2_C.h */,
 | 
						||
@@ -9714,6 +9750,11 @@
 | 
						||
 		BCCF085C113F3B7500C650C5 /* mac */ = {
 | 
						||
 			isa = PBXGroup;
 | 
						||
 			children = (
 | 
						||
+				D7EB04E62372A73B00F744CE /* InspectorPlaywrightAgentClientMac.mm */,
 | 
						||
+				D71A94302370E025002C4D9E /* InspectorPlaywrightAgentClientMac.h */,
 | 
						||
+				D79902AE236E9404005D6F7E /* WebPageInspectorEmulationAgentMac.mm */,
 | 
						||
+				D79902B0236E9404005D6F7E /* WebPageInspectorInputAgentMac.mm */,
 | 
						||
+				D79902AF236E9404005D6F7E /* InspectorTargetProxyMac.mm */,
 | 
						||
 				B878B613133428DC006888E9 /* CorrectionPanel.h */,
 | 
						||
 				B878B614133428DC006888E9 /* CorrectionPanel.mm */,
 | 
						||
 				C1817362205844A900DFDA65 /* DisplayLink.cpp */,
 | 
						||
@@ -10467,6 +10508,7 @@
 | 
						||
 				991F492F23A812C60054642B /* _WKInspectorDebuggableInfo.h in Headers */,
 | 
						||
 				99036AE223A949CF0000B06A /* _WKInspectorDebuggableInfoInternal.h in Headers */,
 | 
						||
 				9197940C23DBC50300257892 /* _WKInspectorDelegate.h in Headers */,
 | 
						||
+				D71A944A2372290B002C4D9E /* _WKBrowserInspector.h in Headers */,
 | 
						||
 				5CAFDE472130846A00B1F7E1 /* _WKInspectorInternal.h in Headers */,
 | 
						||
 				9979CA58237F49F10039EC05 /* _WKInspectorPrivate.h in Headers */,
 | 
						||
 				A5C0F0AB2000658200536536 /* _WKInspectorWindow.h in Headers */,
 | 
						||
@@ -10591,6 +10633,7 @@
 | 
						||
 				7C89D2981A6753B2003A5FDE /* APIPageConfiguration.h in Headers */,
 | 
						||
 				1AC1336C18565C7A00F3EC05 /* APIPageHandle.h in Headers */,
 | 
						||
 				1AFDD3151891B54000153970 /* APIPolicyClient.h in Headers */,
 | 
						||
+				D71A94382370F032002C4D9E /* BrowserInspectorController.h in Headers */,
 | 
						||
 				7CE4D2201A4914CA00C7F152 /* APIProcessPoolConfiguration.h in Headers */,
 | 
						||
 				49BCA19223A177660028A836 /* APIResourceLoadStatisticsFirstParty.h in Headers */,
 | 
						||
 				49BCA19723A1930D0028A836 /* APIResourceLoadStatisticsThirdParty.h in Headers */,
 | 
						||
@@ -10716,6 +10759,7 @@
 | 
						||
 				BC06F43A12DBCCFB002D78DE /* GeolocationPermissionRequestProxy.h in Headers */,
 | 
						||
 				2DA944A41884E4F000ED86DB /* GestureTypes.h in Headers */,
 | 
						||
 				2DA049B8180CCD0A00AAFA9E /* GraphicsLayerCARemote.h in Headers */,
 | 
						||
+				D71A94342370E07A002C4D9E /* InspectorPlaywrightAgentClient.h in Headers */,
 | 
						||
 				C0CE72AD1247E78D00BC0EC4 /* HandleMessage.h in Headers */,
 | 
						||
 				1AC75A1B1B3368270056745B /* HangDetectionDisabler.h in Headers */,
 | 
						||
 				57AC8F50217FEED90055438C /* HidConnection.h in Headers */,
 | 
						||
@@ -10842,8 +10886,10 @@
 | 
						||
 				41DC45961E3D6E2200B11F51 /* NetworkRTCProvider.h in Headers */,
 | 
						||
 				413075AB1DE85F330039EC69 /* NetworkRTCSocket.h in Headers */,
 | 
						||
 				5C20CBA01BB1ECD800895BB1 /* NetworkSession.h in Headers */,
 | 
						||
+				D71A94422371F67E002C4D9E /* WebPageInspectorEmulationAgent.h in Headers */,
 | 
						||
 				532159551DBAE7290054AA3C /* NetworkSessionCocoa.h in Headers */,
 | 
						||
 				417915B92257046F00D6F97E /* NetworkSocketChannel.h in Headers */,
 | 
						||
+				D71A943A2370F061002C4D9E /* RemoteInspectorPipe.h in Headers */,
 | 
						||
 				570DAAC22303730300E8FC04 /* NfcConnection.h in Headers */,
 | 
						||
 				570DAAAE23026F5C00E8FC04 /* NfcService.h in Headers */,
 | 
						||
 				31A2EC5614899C0900810D71 /* NotificationPermissionRequest.h in Headers */,
 | 
						||
@@ -10927,6 +10973,7 @@
 | 
						||
 				CD2865EE2255562000606AC7 /* ProcessTaskStateObserver.h in Headers */,
 | 
						||
 				463FD4821EB94EC000A2982C /* ProcessTerminationReason.h in Headers */,
 | 
						||
 				86E67A251910B9D100004AB7 /* ProcessThrottler.h in Headers */,
 | 
						||
+				D71A944C237239FB002C4D9E /* BrowserInspectorPipe.h in Headers */,
 | 
						||
 				83048AE61ACA45DC0082C832 /* ProcessThrottlerClient.h in Headers */,
 | 
						||
 				A1E688701F6E2BAB007006A6 /* QuarantineSPI.h in Headers */,
 | 
						||
 				57FD318222B3515E008D0E8B /* RedirectSOAuthorizationSession.h in Headers */,
 | 
						||
@@ -11355,6 +11402,7 @@
 | 
						||
 				BCD25F1711D6BDE100169B0E /* WKBundleFrame.h in Headers */,
 | 
						||
 				BCF049E611FE20F600F86A58 /* WKBundleFramePrivate.h in Headers */,
 | 
						||
 				BC49862F124D18C100D834E1 /* WKBundleHitTestResult.h in Headers */,
 | 
						||
+				D71A94432371F67E002C4D9E /* WebPageInspectorInputAgent.h in Headers */,
 | 
						||
 				BC204EF211C83EC8008F3375 /* WKBundleInitialize.h in Headers */,
 | 
						||
 				65B86F1E12F11DE300B7DD8A /* WKBundleInspector.h in Headers */,
 | 
						||
 				1A8B66B41BC45B010082DF77 /* WKBundleMac.h in Headers */,
 | 
						||
@@ -11407,6 +11455,7 @@
 | 
						||
 				5C795D71229F3757003FF1C4 /* WKContextMenuElementInfoPrivate.h in Headers */,
 | 
						||
 				51A555F6128C6C47009ABCEC /* WKContextMenuItem.h in Headers */,
 | 
						||
 				51A55601128C6D92009ABCEC /* WKContextMenuItemTypes.h in Headers */,
 | 
						||
+				D76D6888238DBD81008D314B /* InspectorDialogAgent.h in Headers */,
 | 
						||
 				A1EA02381DABFF7E0096021F /* WKContextMenuListener.h in Headers */,
 | 
						||
 				BCC938E11180DE440085E5FE /* WKContextPrivate.h in Headers */,
 | 
						||
 				9FB5F395169E6A80002C25BF /* WKContextPrivateMac.h in Headers */,
 | 
						||
@@ -11557,6 +11606,7 @@
 | 
						||
 				1AB8A1F818400BB800E9AE69 /* WKPageContextMenuClient.h in Headers */,
 | 
						||
 				8372DB251A674C8F00C697C5 /* WKPageDiagnosticLoggingClient.h in Headers */,
 | 
						||
 				1AB8A1F418400B8F00E9AE69 /* WKPageFindClient.h in Headers */,
 | 
						||
+				D71A94322370E025002C4D9E /* InspectorPlaywrightAgentClientMac.h in Headers */,
 | 
						||
 				1AB8A1F618400B9D00E9AE69 /* WKPageFindMatchesClient.h in Headers */,
 | 
						||
 				1AB8A1F018400B0000E9AE69 /* WKPageFormClient.h in Headers */,
 | 
						||
 				BC7B633712A45ABA00D174A4 /* WKPageGroup.h in Headers */,
 | 
						||
@@ -12605,6 +12655,7 @@
 | 
						||
 				CDA93DB122F8BCF400490A69 /* FullscreenTouchSecheuristicParameters.cpp in Sources */,
 | 
						||
 				2749F6442146561B008380BF /* InjectedBundleNodeHandle.cpp in Sources */,
 | 
						||
 				2749F6452146561E008380BF /* InjectedBundleRangeHandle.cpp in Sources */,
 | 
						||
+				D79902B2236E9404005D6F7E /* InspectorTargetProxyMac.mm in Sources */,
 | 
						||
 				2D913441212CF9F000128AFD /* JSNPMethod.cpp in Sources */,
 | 
						||
 				2D913442212CF9F000128AFD /* JSNPObject.cpp in Sources */,
 | 
						||
 				2984F588164BA095004BC0C6 /* LegacyCustomProtocolManagerMessageReceiver.cpp in Sources */,
 | 
						||
@@ -12615,6 +12666,7 @@
 | 
						||
 				2D92A781212B6A7100F493FD /* MessageReceiverMap.cpp in Sources */,
 | 
						||
 				2D92A782212B6A7100F493FD /* MessageSender.cpp in Sources */,
 | 
						||
 				2D92A77A212B6A6100F493FD /* Module.cpp in Sources */,
 | 
						||
+				D79902B1236E9404005D6F7E /* WebPageInspectorEmulationAgentMac.mm in Sources */,
 | 
						||
 				57B826452304F14000B72EB0 /* NearFieldSoftLink.mm in Sources */,
 | 
						||
 				2D913443212CF9F000128AFD /* NetscapeBrowserFuncs.cpp in Sources */,
 | 
						||
 				2D913444212CF9F000128AFD /* NetscapePlugin.cpp in Sources */,
 | 
						||
@@ -12639,6 +12691,7 @@
 | 
						||
 				1A2D8439127F65D5001EB962 /* NPObjectMessageReceiverMessageReceiver.cpp in Sources */,
 | 
						||
 				2D92A792212B6AD400F493FD /* NPObjectProxy.cpp in Sources */,
 | 
						||
 				2D92A793212B6AD400F493FD /* NPRemoteObjectMap.cpp in Sources */,
 | 
						||
+				D7EB04E72372A73B00F744CE /* InspectorPlaywrightAgentClientMac.mm in Sources */,
 | 
						||
 				2D913447212CF9F000128AFD /* NPRuntimeObjectMap.cpp in Sources */,
 | 
						||
 				2D913448212CF9F000128AFD /* NPRuntimeUtilities.cpp in Sources */,
 | 
						||
 				2D92A794212B6AD400F493FD /* NPVariantData.cpp in Sources */,
 | 
						||
@@ -12919,6 +12972,7 @@
 | 
						||
 				2D92A78C212B6AB100F493FD /* WebMouseEvent.cpp in Sources */,
 | 
						||
 				31BA924D148831260062EDB5 /* WebNotificationManagerMessageReceiver.cpp in Sources */,
 | 
						||
 				2DF6FE52212E110900469030 /* WebPage.cpp in Sources */,
 | 
						||
+				D79902B3236E9404005D6F7E /* WebPageInspectorInputAgentMac.mm in Sources */,
 | 
						||
 				C0CE72A01247E71D00BC0EC4 /* WebPageMessageReceiver.cpp in Sources */,
 | 
						||
 				BCBD3914125BB1A800D2C29F /* WebPageProxyMessageReceiver.cpp in Sources */,
 | 
						||
 				7CE9CE101FA0767A000177DE /* WebPageUpdatePreferences.cpp in Sources */,
 | 
						||
diff --git a/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp b/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp
 | 
						||
index 446eb53a20bec268c51fd1dcb9c31db0efb96a97..483fd1d7b431312b6b5897fa2489773d0e7ae87e 100644
 | 
						||
--- a/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp
 | 
						||
+++ b/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp
 | 
						||
@@ -58,6 +58,7 @@
 | 
						||
 #include <WebCore/Frame.h>
 | 
						||
 #include <WebCore/FrameLoader.h>
 | 
						||
 #include <WebCore/HTMLFrameOwnerElement.h>
 | 
						||
+#include <WebCore/InspectorInstrumentationWebKit.h>
 | 
						||
 #include <WebCore/NetscapePlugInStreamLoader.h>
 | 
						||
 #include <WebCore/NetworkLoadInformation.h>
 | 
						||
 #include <WebCore/PlatformStrategies.h>
 | 
						||
@@ -228,8 +229,24 @@ void WebLoaderStrategy::scheduleLoad(ResourceLoader& resourceLoader, CachedResou
 | 
						||
     }
 | 
						||
 #endif
 | 
						||
 
 | 
						||
+    if (m_emulateOfflineState) {
 | 
						||
+        scheduleInternallyFailedLoad(resourceLoader);
 | 
						||
+        return;
 | 
						||
+    }
 | 
						||
+
 | 
						||
     if (!tryLoadingUsingURLSchemeHandler(resourceLoader, trackingParameters)) {
 | 
						||
         WEBLOADERSTRATEGY_RELEASE_LOG_IF_ALLOWED("scheduleLoad: URL will be scheduled with the NetworkProcess");
 | 
						||
+
 | 
						||
+        RefPtr<ResourceLoader> coreLoader = &resourceLoader;
 | 
						||
+        if (!resourceLoader.options().serviceWorkerRegistrationIdentifier) {
 | 
						||
+            if (InspectorInstrumentationWebKit::interceptRequest(resourceLoader, [this, coreLoader, trackingParameters, shouldClearReferrerOnHTTPSToHTTPRedirect, resource](bool handled) mutable {
 | 
						||
+                    if (!handled)
 | 
						||
+                        scheduleLoadFromNetworkProcess(*coreLoader, coreLoader->request(), trackingParameters, shouldClearReferrerOnHTTPSToHTTPRedirect, maximumBufferingTime(resource));
 | 
						||
+                    })) {
 | 
						||
+                return;
 | 
						||
+            }
 | 
						||
+        }
 | 
						||
+
 | 
						||
         scheduleLoadFromNetworkProcess(resourceLoader, resourceLoader.request(), trackingParameters, shouldClearReferrerOnHTTPSToHTTPRedirect, maximumBufferingTime(resource));
 | 
						||
         return;
 | 
						||
     }
 | 
						||
@@ -774,7 +791,7 @@ void WebLoaderStrategy::didFinishPreconnection(uint64_t preconnectionIdentifier,
 | 
						||
 
 | 
						||
 bool WebLoaderStrategy::isOnLine() const
 | 
						||
 {
 | 
						||
-    return m_isOnLine;
 | 
						||
+    return m_emulateOfflineState ? false : m_isOnLine;
 | 
						||
 }
 | 
						||
 
 | 
						||
 void WebLoaderStrategy::addOnlineStateChangeListener(Function<void(bool)>&& listener)
 | 
						||
@@ -785,6 +802,11 @@ void WebLoaderStrategy::addOnlineStateChangeListener(Function<void(bool)>&& list
 | 
						||
 
 | 
						||
 void WebLoaderStrategy::setOnLineState(bool isOnLine)
 | 
						||
 {
 | 
						||
+    if (m_emulateOfflineState) {
 | 
						||
+        m_isOnLine = isOnLine;
 | 
						||
+        return;
 | 
						||
+    }
 | 
						||
+
 | 
						||
     if (m_isOnLine == isOnLine)
 | 
						||
         return;
 | 
						||
 
 | 
						||
@@ -793,6 +815,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 22f644fd7f450d32ea45f97e27488ef5f34c153a..9ac93959568cb4561c039cc0ce7b28c404699390 100644
 | 
						||
--- a/Source/WebKit/WebProcess/Network/WebLoaderStrategy.h
 | 
						||
+++ b/Source/WebKit/WebProcess/Network/WebLoaderStrategy.h
 | 
						||
@@ -88,6 +88,7 @@ public:
 | 
						||
     bool isOnLine() const final;
 | 
						||
     void addOnlineStateChangeListener(Function<void(bool)>&&) final;
 | 
						||
     void setOnLineState(bool);
 | 
						||
+    void setEmulateOfflineState(bool) final;
 | 
						||
 
 | 
						||
 private:
 | 
						||
     void scheduleLoad(WebCore::ResourceLoader&, WebCore::CachedResource*, bool shouldClearReferrerOnHTTPSToHTTPRedirect);
 | 
						||
@@ -126,6 +127,7 @@ private:
 | 
						||
     HashMap<unsigned long, PreconnectCompletionHandler> m_preconnectCompletionHandlers;
 | 
						||
     Vector<Function<void(bool)>> m_onlineStateChangeListeners;
 | 
						||
     bool m_isOnLine { true };
 | 
						||
+    bool m_emulateOfflineState { false };
 | 
						||
     HashSet<WebResourceLoader*> m_loadersWithUploads;
 | 
						||
 };
 | 
						||
 
 | 
						||
diff --git a/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp b/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp
 | 
						||
index 25fb020932123687c79c0bee74e3e54d22c47b74..0a3935937f42913db2ca26ad980d030b448f712d 100644
 | 
						||
--- a/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp
 | 
						||
+++ b/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp
 | 
						||
@@ -410,6 +410,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);
 | 
						||
 }
 | 
						||
diff --git a/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/DrawingAreaCoordinatedGraphics.cpp b/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/DrawingAreaCoordinatedGraphics.cpp
 | 
						||
index 2c1a3362304c0aab9eccca58c3fe67b7250d2232..bde6a8e7b76eaa367aeba99489c06e46419890be 100644
 | 
						||
--- a/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/DrawingAreaCoordinatedGraphics.cpp
 | 
						||
+++ b/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/DrawingAreaCoordinatedGraphics.cpp
 | 
						||
@@ -244,12 +244,20 @@ void DrawingAreaCoordinatedGraphics::updatePreferences(const WebPreferencesStore
 | 
						||
         settings.setAcceleratedCompositingEnabled(false);
 | 
						||
     }
 | 
						||
 #endif
 | 
						||
+
 | 
						||
+#if USE(LIBWPE)
 | 
						||
+    settings.setAcceleratedCompositingEnabled(false);
 | 
						||
+    settings.setForceCompositingMode(false);
 | 
						||
+    settings.setAcceleratedCompositingForFixedPositionEnabled(false);
 | 
						||
+    m_alwaysUseCompositing = false;
 | 
						||
+#else
 | 
						||
     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.
 | 
						||
     settings.setAcceleratedCompositingForFixedPositionEnabled(settings.acceleratedCompositingEnabled());
 | 
						||
 
 | 
						||
     m_alwaysUseCompositing = settings.acceleratedCompositingEnabled() && settings.forceCompositingMode();
 | 
						||
+#endif
 | 
						||
 
 | 
						||
     // If async scrolling is disabled, we have to force-disable async frame and overflow scrolling
 | 
						||
     // to keep the non-async scrolling on those elements working.
 | 
						||
diff --git a/Source/WebKit/WebProcess/WebPage/WebDocumentLoader.cpp b/Source/WebKit/WebProcess/WebPage/WebDocumentLoader.cpp
 | 
						||
index b2d54a627b94583bda3518c4e7c3364481b605a4..d407e32b6a7b8b27925c49391e86d42c9b3dfa8b 100644
 | 
						||
--- a/Source/WebKit/WebProcess/WebPage/WebDocumentLoader.cpp
 | 
						||
+++ b/Source/WebKit/WebProcess/WebPage/WebDocumentLoader.cpp
 | 
						||
@@ -47,6 +47,14 @@ void WebDocumentLoader::detachFromFrame()
 | 
						||
     DocumentLoader::detachFromFrame();
 | 
						||
 }
 | 
						||
 
 | 
						||
+void WebDocumentLoader::replacedByFragmentNavigation(Frame& frame)
 | 
						||
+{
 | 
						||
+    ASSERT(!this->frame());
 | 
						||
+    // Notify WebPageProxy that the navigation has been converted into same page navigation.
 | 
						||
+    if (m_navigationID)
 | 
						||
+        WebFrame::fromCoreFrame(frame)->documentLoaderDetached(m_navigationID);
 | 
						||
+}
 | 
						||
+
 | 
						||
 void WebDocumentLoader::setNavigationID(uint64_t navigationID)
 | 
						||
 {
 | 
						||
     ASSERT(navigationID);
 | 
						||
diff --git a/Source/WebKit/WebProcess/WebPage/WebDocumentLoader.h b/Source/WebKit/WebProcess/WebPage/WebDocumentLoader.h
 | 
						||
index f127d64d005ab7b93875591b94a5899205e91579..df0de26e4dc449a0fbf93e7037444df4e5365822 100644
 | 
						||
--- a/Source/WebKit/WebProcess/WebPage/WebDocumentLoader.h
 | 
						||
+++ b/Source/WebKit/WebProcess/WebPage/WebDocumentLoader.h
 | 
						||
@@ -43,7 +43,10 @@ public:
 | 
						||
 private:
 | 
						||
     WebDocumentLoader(const WebCore::ResourceRequest&, const WebCore::SubstituteData&);
 | 
						||
 
 | 
						||
+    uint64_t loaderIDForInspector() override { return navigationID(); }
 | 
						||
+
 | 
						||
     void detachFromFrame() override;
 | 
						||
+    void replacedByFragmentNavigation(WebCore::Frame&) override;
 | 
						||
 
 | 
						||
     uint64_t m_navigationID;
 | 
						||
 };
 | 
						||
diff --git a/Source/WebKit/WebProcess/WebPage/WebPage.cpp b/Source/WebKit/WebProcess/WebPage/WebPage.cpp
 | 
						||
index 1ba789ad1a31c400cab17e03ef2cb43a6108c309..e8133744a9eca8660d90e3aeb8d038a5c0be271f 100644
 | 
						||
--- a/Source/WebKit/WebProcess/WebPage/WebPage.cpp
 | 
						||
+++ b/Source/WebKit/WebProcess/WebPage/WebPage.cpp
 | 
						||
@@ -746,6 +746,9 @@ WebPage::WebPage(PageIdentifier pageID, WebPageCreationParameters&& parameters)
 | 
						||
     send(Messages::WebPageProxy::DidCreateContextForVisibilityPropagation(m_contextForVisibilityPropagation->contextID()));
 | 
						||
 #endif
 | 
						||
 
 | 
						||
+    if (parameters.shouldPauseInInspectorWhenShown)
 | 
						||
+        m_page->inspectorController().pauseWhenShown();
 | 
						||
+
 | 
						||
     updateThrottleState();
 | 
						||
 }
 | 
						||
 
 | 
						||
@@ -1575,6 +1578,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, ShouldOpenExternalURLsPolicy::ShouldNotAllow };
 | 
						||
+    frame->coreFrame()->loader().load(WTFMove(frameLoadRequest));
 | 
						||
+    ASSERT(!m_pendingFrameNavigationID);
 | 
						||
+}
 | 
						||
+
 | 
						||
 void WebPage::loadRequest(LoadParameters&& loadParameters)
 | 
						||
 {
 | 
						||
     setIsNavigatingToAppBoundDomain(loadParameters.isNavigatingToAppBoundDomain);
 | 
						||
@@ -1782,17 +1801,13 @@ void WebPage::setSize(const WebCore::IntSize& viewSize)
 | 
						||
     view->resize(viewSize);
 | 
						||
     m_drawingArea->setNeedsDisplay();
 | 
						||
 
 | 
						||
-#if USE(COORDINATED_GRAPHICS)
 | 
						||
     if (view->useFixedLayout())
 | 
						||
         sendViewportAttributesChanged(m_page->viewportArguments());
 | 
						||
-#endif
 | 
						||
 }
 | 
						||
 
 | 
						||
-#if USE(COORDINATED_GRAPHICS)
 | 
						||
 void WebPage::sendViewportAttributesChanged(const ViewportArguments& viewportArguments)
 | 
						||
 {
 | 
						||
-    FrameView* view = m_page->mainFrame().view();
 | 
						||
-    ASSERT(view && view->useFixedLayout());
 | 
						||
+    ASSERT(m_page->mainFrame().view() && m_page->mainFrame().view()->useFixedLayout());
 | 
						||
 
 | 
						||
     // Viewport properties have no impact on zero sized fixed viewports.
 | 
						||
     if (m_viewSize.isEmpty())
 | 
						||
@@ -1809,20 +1824,18 @@ void WebPage::sendViewportAttributesChanged(const ViewportArguments& viewportArg
 | 
						||
 
 | 
						||
     ViewportAttributes attr = computeViewportAttributes(viewportArguments, minimumLayoutFallbackWidth, deviceWidth, deviceHeight, 1, m_viewSize);
 | 
						||
 
 | 
						||
-    // If no layout was done yet set contentFixedOrigin to (0,0).
 | 
						||
-    IntPoint contentFixedOrigin = view->didFirstLayout() ? view->fixedVisibleContentRect().location() : IntPoint();
 | 
						||
-
 | 
						||
-    // Put the width and height to the viewport width and height. In css units however.
 | 
						||
-    // Use FloatSize to avoid truncated values during scale.
 | 
						||
-    FloatSize contentFixedSize = m_viewSize;
 | 
						||
-
 | 
						||
-    contentFixedSize.scale(1 / attr.initialScale);
 | 
						||
-    view->setFixedVisibleContentRect(IntRect(contentFixedOrigin, roundedIntSize(contentFixedSize)));
 | 
						||
+#if ENABLE(CSS_DEVICE_ADAPTATION)
 | 
						||
+    FrameView* view = m_page->mainFrame().view();
 | 
						||
+    // CSS viewport descriptors might be applied to already affected viewport size
 | 
						||
+    // if the page enables/disables stylesheets, so need to keep initial viewport size.
 | 
						||
+    view->setInitialViewportSize(roundedIntSize(m_viewSize));
 | 
						||
+#endif
 | 
						||
 
 | 
						||
     attr.initialScale = m_page->viewportArguments().zoom; // Resets auto (-1) if no value was set by user.
 | 
						||
 
 | 
						||
     // This also takes care of the relayout.
 | 
						||
     setFixedLayoutSize(roundedIntSize(attr.layoutSize));
 | 
						||
+    scaleView(deviceWidth / attr.layoutSize.width());
 | 
						||
 
 | 
						||
 #if USE(COORDINATED_GRAPHICS)
 | 
						||
     m_drawingArea->didChangeViewportAttributes(WTFMove(attr));
 | 
						||
@@ -1830,7 +1843,6 @@ void WebPage::sendViewportAttributesChanged(const ViewportArguments& viewportArg
 | 
						||
     send(Messages::WebPageProxy::DidChangeViewportProperties(attr));
 | 
						||
 #endif
 | 
						||
 }
 | 
						||
-#endif
 | 
						||
 
 | 
						||
 void WebPage::scrollMainFrameIfNotAtMaxScrollPosition(const IntSize& scrollOffset)
 | 
						||
 {
 | 
						||
@@ -2112,6 +2124,7 @@ void WebPage::scaleView(double scale)
 | 
						||
     }
 | 
						||
 
 | 
						||
     m_page->setViewScaleFactor(scale);
 | 
						||
+    send(Messages::WebPageProxy::ViewScaleFactorDidChange(scale));
 | 
						||
     scalePage(pageScale, scrollPositionAtNewScale);
 | 
						||
 }
 | 
						||
 
 | 
						||
@@ -2216,17 +2229,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)
 | 
						||
@@ -3111,6 +3120,11 @@ void WebPage::sendMessageToTargetBackend(const String& targetId, const String& m
 | 
						||
     m_inspectorTargetController->sendMessageToTargetBackend(targetId, message);
 | 
						||
 }
 | 
						||
 
 | 
						||
+void WebPage::resumeInspectorIfPausedInNewWindow()
 | 
						||
+{
 | 
						||
+    m_page->inspectorController().resumeIfPausedInNewWindow();
 | 
						||
+}
 | 
						||
+
 | 
						||
 void WebPage::insertNewlineInQuotedContent()
 | 
						||
 {
 | 
						||
     Frame& frame = m_page->focusController().focusedOrMainFrame();
 | 
						||
@@ -3357,6 +3371,7 @@ void WebPage::didCompletePageTransition()
 | 
						||
 void WebPage::show()
 | 
						||
 {
 | 
						||
     send(Messages::WebPageProxy::ShowPage());
 | 
						||
+    m_page->inspectorController().didShowNewWindow();
 | 
						||
 }
 | 
						||
 
 | 
						||
 String WebPage::userAgent(const URL& webCoreURL) const
 | 
						||
@@ -6364,6 +6379,9 @@ Ref<DocumentLoader> WebPage::createDocumentLoader(Frame& frame, const ResourceRe
 | 
						||
             WebsitePoliciesData::applyToDocumentLoader(WTFMove(*m_pendingWebsitePolicies), documentLoader);
 | 
						||
             m_pendingWebsitePolicies = WTF::nullopt;
 | 
						||
         }
 | 
						||
+    } else if (m_pendingFrameNavigationID) {
 | 
						||
+        documentLoader->setNavigationID(m_pendingFrameNavigationID);
 | 
						||
+        m_pendingFrameNavigationID = 0;
 | 
						||
     }
 | 
						||
 
 | 
						||
     return documentLoader;
 | 
						||
diff --git a/Source/WebKit/WebProcess/WebPage/WebPage.h b/Source/WebKit/WebProcess/WebPage/WebPage.h
 | 
						||
index 8fa0b2a5f4e4df26ea73ce4605336ba502b58869..1d8a0b3a17c9b491cd36f1327dc6ad6a3276296b 100644
 | 
						||
--- a/Source/WebKit/WebProcess/WebPage/WebPage.h
 | 
						||
+++ b/Source/WebKit/WebProcess/WebPage/WebPage.h
 | 
						||
@@ -1145,6 +1145,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();
 | 
						||
 
 | 
						||
@@ -1401,6 +1402,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&&);
 | 
						||
@@ -1545,9 +1547,7 @@ private:
 | 
						||
     void countStringMatches(const String&, uint32_t findOptions, uint32_t maxMatchCount);
 | 
						||
     void replaceMatches(const Vector<uint32_t>& matchIndices, const String& replacementText, bool selectionOnly, CallbackID);
 | 
						||
 
 | 
						||
-#if USE(COORDINATED_GRAPHICS)
 | 
						||
     void sendViewportAttributesChanged(const WebCore::ViewportArguments&);
 | 
						||
-#endif
 | 
						||
 
 | 
						||
     void didChangeSelectedIndexForActivePopupMenu(int32_t newIndex);
 | 
						||
     void setTextForActivePopupMenu(int32_t index);
 | 
						||
@@ -2006,6 +2006,7 @@ private:
 | 
						||
     UserActivity m_userActivity;
 | 
						||
 
 | 
						||
     uint64_t m_pendingNavigationID { 0 };
 | 
						||
+    uint64_t m_pendingFrameNavigationID { 0 };
 | 
						||
     Optional<WebsitePoliciesData> m_pendingWebsitePolicies;
 | 
						||
 
 | 
						||
     bool m_mainFrameProgressCompleted { false };
 | 
						||
diff --git a/Source/WebKit/WebProcess/WebPage/WebPage.messages.in b/Source/WebKit/WebProcess/WebPage/WebPage.messages.in
 | 
						||
index 04fc425228e62a535b314ba027b6b3f4570f4bf8..a085d46b64a03a6dc24aeb138e4fe1d4fc37ddba 100644
 | 
						||
--- a/Source/WebKit/WebProcess/WebPage/WebPage.messages.in
 | 
						||
+++ b/Source/WebKit/WebProcess/WebPage/WebPage.messages.in
 | 
						||
@@ -128,6 +128,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);
 | 
						||
@@ -168,6 +169,7 @@ GenerateSyntheticEditingCommand(enum:uint8_t WebKit::SyntheticEditingCommandType
 | 
						||
     LoadURLInFrame(URL url, String referrer, WebCore::FrameIdentifier frameID)
 | 
						||
     LoadDataInFrame(IPC::DataReference data, String MIMEType, String encodingName, URL baseURL, WebCore::FrameIdentifier frameID)
 | 
						||
     LoadRequest(struct WebKit::LoadParameters loadParameters)
 | 
						||
+    LoadRequestInFrameForInspector(struct WebKit::LoadParameters loadParameters, WebCore::FrameIdentifier frameID)
 | 
						||
     LoadRequestWaitingForProcessLaunch(struct WebKit::LoadParameters loadParameters, URL resourceDirectoryURL, WebKit::WebPageProxyIdentifier pageID, bool checkAssumedReadAccessToResourceURL)
 | 
						||
     LoadData(struct WebKit::LoadParameters loadParameters)
 | 
						||
     LoadAlternateHTML(struct WebKit::LoadParameters loadParameters)
 | 
						||
diff --git a/Source/WebKit/WebProcess/WebProcess.cpp b/Source/WebKit/WebProcess/WebProcess.cpp
 | 
						||
index fa6d520a55a11e811092587f2adb2af1b938dbef..85b926277a0660d8b01ae1cdf77f3d13f8466735 100644
 | 
						||
--- a/Source/WebKit/WebProcess/WebProcess.cpp
 | 
						||
+++ b/Source/WebKit/WebProcess/WebProcess.cpp
 | 
						||
@@ -82,6 +82,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>
 | 
						||
@@ -276,6 +277,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/WebKitLegacy/mac/WebView/WebHTMLView.mm b/Source/WebKitLegacy/mac/WebView/WebHTMLView.mm
 | 
						||
index eeaf0a09e8b906d165daa148146c4c832ce6ba2e..37c37de1447185f11449841f012c77ac056e60c9 100644
 | 
						||
--- a/Source/WebKitLegacy/mac/WebView/WebHTMLView.mm
 | 
						||
+++ b/Source/WebKitLegacy/mac/WebView/WebHTMLView.mm
 | 
						||
@@ -4245,7 +4245,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 cb3379a7bcddb0f83e0c5db7621aebbc4bccac88..8c1e472f0800b7a1c80c49cce6c7c46f6d4784d6 100644
 | 
						||
--- a/Source/WebKitLegacy/mac/WebView/WebView.mm
 | 
						||
+++ b/Source/WebKitLegacy/mac/WebView/WebView.mm
 | 
						||
@@ -4343,7 +4343,7 @@ IGNORE_WARNINGS_END
 | 
						||
 }
 | 
						||
 #endif // PLATFORM(IOS_FAMILY)
 | 
						||
 
 | 
						||
-#if ENABLE(TOUCH_EVENTS)
 | 
						||
+#if ENABLE(IOS_TOUCH_EVENTS)
 | 
						||
 - (NSArray *)_touchEventRegions
 | 
						||
 {
 | 
						||
     auto* frame = [self _mainCoreFrame];
 | 
						||
@@ -4389,7 +4389,7 @@ IGNORE_WARNINGS_END
 | 
						||
 
 | 
						||
     return eventRegionArray;
 | 
						||
 }
 | 
						||
-#endif // ENABLE(TOUCH_EVENTS)
 | 
						||
+#endif // ENABLE(IOS_TOUCH_EVENTS)
 | 
						||
 
 | 
						||
 // For backwards compatibility with the WebBackForwardList API, we honor both
 | 
						||
 // a per-WebView and a per-preferences setting for whether to use the back/forward cache.
 | 
						||
diff --git a/Source/cmake/OptionsGTK.cmake b/Source/cmake/OptionsGTK.cmake
 | 
						||
index d88133c6c1dcb5554ffa61ee8c08c824181ee2de..ffa751ee547c3e60b5d2ff147ca680c6619cb14f 100644
 | 
						||
--- a/Source/cmake/OptionsGTK.cmake
 | 
						||
+++ b/Source/cmake/OptionsGTK.cmake
 | 
						||
@@ -3,6 +3,7 @@ include(VersioningUtils)
 | 
						||
 
 | 
						||
 SET_PROJECT_VERSION(2 29 0)
 | 
						||
 set(WEBKITGTK_API_VERSION 4.0)
 | 
						||
+set(ENABLE_WEBKIT_LEGACY OFF)
 | 
						||
 
 | 
						||
 CALCULATE_LIBRARY_VERSIONS_FROM_LIBTOOL_TRIPLE(WEBKIT 82 0 45)
 | 
						||
 CALCULATE_LIBRARY_VERSIONS_FROM_LIBTOOL_TRIPLE(JAVASCRIPTCORE 35 0 17)
 | 
						||
@@ -172,6 +173,13 @@ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_CSS_PAINTING_API PRIVATE ${ENABLE_EXPERI
 | 
						||
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_CSS_TYPED_OM PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
 | 
						||
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_CSS_CONIC_GRADIENTS PRIVATE ON)
 | 
						||
 
 | 
						||
+# Playwright
 | 
						||
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_APPLICATION_MANIFEST PRIVATE ON)
 | 
						||
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_CSS_TRAILING_WORD PRIVATE ON)
 | 
						||
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_CURSOR_VISIBILITY PRIVATE ON)
 | 
						||
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_DOWNLOAD_ATTRIBUTE PRIVATE ON)
 | 
						||
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_LEGACY_CSS_VENDOR_PREFIXES PRIVATE ON)
 | 
						||
+
 | 
						||
 include(GStreamerDependencies)
 | 
						||
 
 | 
						||
 # Finalize the value for all options. Do not attempt to use an option before
 | 
						||
diff --git a/Source/cmake/OptionsWPE.cmake b/Source/cmake/OptionsWPE.cmake
 | 
						||
index d3e08c87f458a079e5061069484899169f1774fd..c7edfdd83591aa8f13282c0582c74ca5f80a69bc 100644
 | 
						||
--- a/Source/cmake/OptionsWPE.cmake
 | 
						||
+++ b/Source/cmake/OptionsWPE.cmake
 | 
						||
@@ -3,6 +3,7 @@ include(VersioningUtils)
 | 
						||
 
 | 
						||
 SET_PROJECT_VERSION(2 27 4)
 | 
						||
 set(WPE_API_VERSION 1.0)
 | 
						||
+set(ENABLE_WEBKIT_LEGACY OFF)
 | 
						||
 
 | 
						||
 CALCULATE_LIBRARY_VERSIONS_FROM_LIBTOOL_TRIPLE(WEBKIT 12 0 9)
 | 
						||
 
 | 
						||
@@ -66,6 +67,14 @@ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_CSS_PAINTING_API PRIVATE ${ENABLE_EXPERI
 | 
						||
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_CSS_TYPED_OM PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
 | 
						||
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_CSS_CONIC_GRADIENTS PRIVATE ON)
 | 
						||
 
 | 
						||
+# Playwright
 | 
						||
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_APPLICATION_MANIFEST PRIVATE ON)
 | 
						||
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_CSS_TRAILING_WORD PRIVATE ON)
 | 
						||
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_CURSOR_VISIBILITY PRIVATE ON)
 | 
						||
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_DARK_MODE_CSS PRIVATE ON)
 | 
						||
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_DOWNLOAD_ATTRIBUTE PRIVATE ON)
 | 
						||
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_LEGACY_CSS_VENDOR_PREFIXES PRIVATE ON)
 | 
						||
+
 | 
						||
 # Public options specific to the WPE port. Do not add any options here unless
 | 
						||
 # there is a strong reason we should support changing the value of the option,
 | 
						||
 # and the option is not relevant to any other WebKit ports.
 | 
						||
diff --git a/Source/cmake/OptionsWin.cmake b/Source/cmake/OptionsWin.cmake
 | 
						||
index 705b2ae2bc5d9ee8f52db307efcd0a1efeddd05d..36da968822e8c00179aa61920607e7d299b7a662 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 ()
 | 
						||
 
 | 
						||
@@ -93,6 +94,13 @@ if (${WTF_PLATFORM_WIN_CAIRO})
 | 
						||
     WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEBDRIVER PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
 | 
						||
     WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEB_CRYPTO PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
 | 
						||
 
 | 
						||
+    # Playwright
 | 
						||
+    WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_CSS_CONIC_GRADIENTS PRIVATE ON)
 | 
						||
+    WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_CSS_TRAILING_WORD PRIVATE ON)
 | 
						||
+    WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_DARK_MODE_CSS PRIVATE ON)
 | 
						||
+    WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_DOWNLOAD_ATTRIBUTE PRIVATE ON)
 | 
						||
+    WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_TOUCH_EVENTS PRIVATE ON)
 | 
						||
+
 | 
						||
     # FIXME: Implement plugin process on Modern WebKit. https://bugs.webkit.org/show_bug.cgi?id=185313
 | 
						||
     WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_NETSCAPE_PLUGIN_API PRIVATE OFF)
 | 
						||
 else ()
 | 
						||
diff --git a/Tools/MiniBrowser/gtk/BrowserTab.c b/Tools/MiniBrowser/gtk/BrowserTab.c
 | 
						||
index 9e9978efd3d821c7afcd7b65e14c64e36b355802..a5eef119bddd011470319ac80a0ac443ff0e5441 100644
 | 
						||
--- a/Tools/MiniBrowser/gtk/BrowserTab.c
 | 
						||
+++ b/Tools/MiniBrowser/gtk/BrowserTab.c
 | 
						||
@@ -147,6 +147,11 @@ static void loadChanged(WebKitWebView *webView, WebKitLoadEvent loadEvent, Brows
 | 
						||
     gtk_container_foreach(GTK_CONTAINER(tab), (GtkCallback)removeChildIfInfoBar, tab);
 | 
						||
 }
 | 
						||
 
 | 
						||
+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);
 | 
						||
@@ -457,6 +462,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);
 | 
						||
diff --git a/Tools/MiniBrowser/gtk/BrowserWindow.c b/Tools/MiniBrowser/gtk/BrowserWindow.c
 | 
						||
index 37f9eefbafd14b69c2bedf928ef379670cfef531..5e7e5db253cf788a079e4a0922833b0778b4640d 100644
 | 
						||
--- a/Tools/MiniBrowser/gtk/BrowserWindow.c
 | 
						||
+++ b/Tools/MiniBrowser/gtk/BrowserWindow.c
 | 
						||
@@ -79,6 +79,8 @@ static const gdouble defaultZoomLevel = 1;
 | 
						||
 static const gdouble zoomStep = 1.2;
 | 
						||
 static GList *windowList;
 | 
						||
 
 | 
						||
+static gboolean no_quit = false;
 | 
						||
+
 | 
						||
 G_DEFINE_TYPE(BrowserWindow, browser_window, GTK_TYPE_WINDOW)
 | 
						||
 
 | 
						||
 static char *getExternalURI(const char *uri)
 | 
						||
@@ -707,7 +709,7 @@ static void browserWindowFinalize(GObject *gObject)
 | 
						||
 
 | 
						||
     G_OBJECT_CLASS(browser_window_parent_class)->finalize(gObject);
 | 
						||
 
 | 
						||
-    if (!windowList)
 | 
						||
+    if (!windowList && !no_quit)
 | 
						||
         gtk_main_quit();
 | 
						||
 }
 | 
						||
 
 | 
						||
@@ -1233,6 +1235,11 @@ void browser_window_set_background_color(BrowserWindow *window, GdkRGBA *rgba)
 | 
						||
     gtk_widget_set_app_paintable(GTK_WIDGET(window), TRUE);
 | 
						||
 }
 | 
						||
 
 | 
						||
+void browser_window_no_quit(void)
 | 
						||
+{
 | 
						||
+    no_quit = true;
 | 
						||
+}
 | 
						||
+
 | 
						||
 static BrowserWindow *findActiveWindow(void)
 | 
						||
 {
 | 
						||
     GList *l;
 | 
						||
diff --git a/Tools/MiniBrowser/gtk/BrowserWindow.h b/Tools/MiniBrowser/gtk/BrowserWindow.h
 | 
						||
index 1570d65effb5d601ee3c44a2a7461436f4691c2c..65e62adad0c3684e5cec2f6bc8e7f5281e1f77eb 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;
 | 
						||
@@ -53,7 +53,7 @@ void browser_window_load_session(BrowserWindow *, const char *sessionFile);
 | 
						||
 void browser_window_set_background_color(BrowserWindow*, GdkRGBA*);
 | 
						||
 WebKitWebView* browser_window_get_or_create_web_view_for_automation(void);
 | 
						||
 WebKitWebView *browser_window_create_web_view_in_new_tab_for_automation(void);
 | 
						||
-
 | 
						||
+void browser_window_no_quit(void);
 | 
						||
 G_END_DECLS
 | 
						||
 
 | 
						||
 #endif
 | 
						||
diff --git a/Tools/MiniBrowser/gtk/main.c b/Tools/MiniBrowser/gtk/main.c
 | 
						||
index 4c5147dcd38a53e2feaeaae0fce38f92dc60eba6..77d031add801b2f45c9d90e74afab8802aa08e20 100644
 | 
						||
--- a/Tools/MiniBrowser/gtk/main.c
 | 
						||
+++ b/Tools/MiniBrowser/gtk/main.c
 | 
						||
@@ -53,6 +53,10 @@ static const char *cookiesFile;
 | 
						||
 static const char *cookiesPolicy;
 | 
						||
 static const char *proxy;
 | 
						||
 static gboolean darkMode;
 | 
						||
+static gboolean inspectorPipe;
 | 
						||
+static gboolean headless;
 | 
						||
+static gboolean noStartupWindow;
 | 
						||
+static const char *userDataDir;
 | 
						||
 static gboolean printVersion;
 | 
						||
 
 | 
						||
 typedef enum {
 | 
						||
@@ -121,6 +125,10 @@ static const GOptionEntry commandLineOptions[] =
 | 
						||
     { "ignore-tls-errors", 0, 0, G_OPTION_ARG_NONE, &ignoreTLSErrors, "Ignore TLS errors", NULL },
 | 
						||
     { "content-filter", 0, 0, G_OPTION_ARG_FILENAME, &contentFilter, "JSON with content filtering rules", "FILE" },
 | 
						||
     { "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 }
 | 
						||
 };
 | 
						||
@@ -498,6 +506,34 @@ static void filterSavedCallback(WebKitUserContentFilterStore *store, GAsyncResul
 | 
						||
     g_main_loop_quit(data->mainLoop);
 | 
						||
 }
 | 
						||
 
 | 
						||
+static WebKitWebContext *persistentWebContext = NULL;
 | 
						||
+
 | 
						||
+static WebKitWebView *createNewPage(WebKitBrowserInspector *browser_inspector, WebKitWebContext *context)
 | 
						||
+{
 | 
						||
+    if (context == NULL)
 | 
						||
+        context = persistentWebContext;
 | 
						||
+
 | 
						||
+    WebKitWebView *newWebView = WEBKIT_WEB_VIEW(g_object_new(WEBKIT_TYPE_WEB_VIEW,
 | 
						||
+        "web-context", context,
 | 
						||
+        "is-ephemeral", webkit_web_context_is_ephemeral(context),
 | 
						||
+        "is-controlled-by-automation", TRUE,
 | 
						||
+        NULL));
 | 
						||
+    GtkWidget *newWindow = browser_window_new(NULL, context);
 | 
						||
+    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 configureBrowserInspectorPipe()
 | 
						||
+{
 | 
						||
+    WebKitBrowserInspector* browserInspector = webkit_browser_inspector_get_default();
 | 
						||
+    g_signal_connect(browserInspector, "create-new-page", G_CALLBACK(createNewPage), NULL);
 | 
						||
+
 | 
						||
+    webkit_browser_inspector_initialize_pipe(NULL);
 | 
						||
+}
 | 
						||
+
 | 
						||
 int main(int argc, char *argv[])
 | 
						||
 {
 | 
						||
 #if ENABLE_DEVELOPER_MODE
 | 
						||
@@ -541,8 +577,28 @@ int main(int argc, char *argv[])
 | 
						||
         return 0;
 | 
						||
     }
 | 
						||
 
 | 
						||
-    WebKitWebsiteDataManager *manager = (privateMode || automationMode) ? webkit_website_data_manager_new_ephemeral() : webkit_website_data_manager_new(NULL);
 | 
						||
+    if (inspectorPipe)
 | 
						||
+        configureBrowserInspectorPipe();
 | 
						||
+
 | 
						||
+    if (noStartupWindow) {
 | 
						||
+        browser_window_no_quit();
 | 
						||
+        gtk_main();
 | 
						||
+        g_clear_object(&webkitSettings);
 | 
						||
+        return 0;
 | 
						||
+    }
 | 
						||
+
 | 
						||
+    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);
 | 
						||
+    }
 | 
						||
+
 | 
						||
     WebKitWebContext *webContext = g_object_new(WEBKIT_TYPE_WEB_CONTEXT, "website-data-manager", manager, "process-swap-on-cross-site-navigation-enabled", TRUE, NULL);
 | 
						||
+    persistentWebContext = webContext;
 | 
						||
     g_object_unref(manager);
 | 
						||
 
 | 
						||
     if (cookiesPolicy) {
 | 
						||
@@ -648,8 +704,7 @@ int main(int argc, char *argv[])
 | 
						||
 
 | 
						||
     gtk_main();
 | 
						||
 
 | 
						||
-    if (privateMode)
 | 
						||
-        g_object_unref(webContext);
 | 
						||
+    g_object_unref(webContext);
 | 
						||
 
 | 
						||
     return 0;
 | 
						||
 }
 | 
						||
diff --git a/Tools/MiniBrowser/win/Common.cpp b/Tools/MiniBrowser/win/Common.cpp
 | 
						||
index 87fde928c12a91f13a4f8bc2f2dc24097e42f2d0..40f62e51f18279a1c48d01386120b49a0f9f6029 100644
 | 
						||
--- a/Tools/MiniBrowser/win/Common.cpp
 | 
						||
+++ b/Tools/MiniBrowser/win/Common.cpp
 | 
						||
@@ -278,6 +278,14 @@ CommandLineOptions parseCommandLine()
 | 
						||
 #if ENABLE(WEBKIT)
 | 
						||
         else if (!wcsicmp(argv[i], L"--wk2") || !wcsicmp(argv[i], L"--webkit"))
 | 
						||
             options.windowType = BrowserWindowType::WebKit;
 | 
						||
+        else if (!wcsicmp(argv[i], L"--inspector-pipe"))
 | 
						||
+            options.inspectorPipe = true;
 | 
						||
+        else if (!wcsncmp(argv[i], L"--user-data-dir=", 16))
 | 
						||
+            options.userDataDir = argv[i] + 16;
 | 
						||
+        else if (!wcsicmp(argv[i], L"--headless"))
 | 
						||
+            options.headless = true;
 | 
						||
+        else if (!wcsicmp(argv[i], L"--no-startup-window"))
 | 
						||
+            options.noStartupWindow = true;
 | 
						||
 #endif
 | 
						||
         else if (!options.requestedURL)
 | 
						||
             options.requestedURL = argv[i];
 | 
						||
diff --git a/Tools/MiniBrowser/win/Common.h b/Tools/MiniBrowser/win/Common.h
 | 
						||
index d996feb64e02d7399f2ed0b34d3d0dd03133f824..044069ecd792654e533bac276b98ad45410fb9c7 100644
 | 
						||
--- a/Tools/MiniBrowser/win/Common.h
 | 
						||
+++ b/Tools/MiniBrowser/win/Common.h
 | 
						||
@@ -36,8 +36,12 @@ enum class BrowserWindowType {
 | 
						||
 struct CommandLineOptions {
 | 
						||
     bool usesLayeredWebView { };
 | 
						||
     bool useFullDesktop { };
 | 
						||
+    bool inspectorPipe { };
 | 
						||
+    bool headless { };
 | 
						||
+    bool noStartupWindow { };
 | 
						||
     BrowserWindowType windowType;
 | 
						||
     _bstr_t requestedURL;
 | 
						||
+    _bstr_t userDataDir;
 | 
						||
 
 | 
						||
     CommandLineOptions()
 | 
						||
 #if ENABLE(WEBKIT)
 | 
						||
diff --git a/Tools/MiniBrowser/win/MainWindow.cpp b/Tools/MiniBrowser/win/MainWindow.cpp
 | 
						||
index 08131e61107bc4163c4fb1e9a65ee5a1ecda6b04..d157cb5c13bf61ad2593989353237629ae60d710 100644
 | 
						||
--- a/Tools/MiniBrowser/win/MainWindow.cpp
 | 
						||
+++ b/Tools/MiniBrowser/win/MainWindow.cpp
 | 
						||
@@ -60,6 +60,14 @@ static INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
 | 
						||
 std::wstring MainWindow::s_windowClass;
 | 
						||
 size_t MainWindow::s_numInstances;
 | 
						||
 
 | 
						||
+bool MainWindow::s_headless = false;
 | 
						||
+bool MainWindow::s_noStartupWindow = false;
 | 
						||
+
 | 
						||
+void MainWindow::configure(bool headless, bool noStartupWindow) {
 | 
						||
+    s_headless = headless;
 | 
						||
+    s_noStartupWindow = noStartupWindow;
 | 
						||
+}
 | 
						||
+
 | 
						||
 static std::wstring loadString(int id)
 | 
						||
 {
 | 
						||
     constexpr size_t length = 100;
 | 
						||
@@ -102,7 +110,9 @@ bool MainWindow::isInstance(HWND hwnd)
 | 
						||
     return s_windowClass == buff;
 | 
						||
 }
 | 
						||
 
 | 
						||
-MainWindow::MainWindow()
 | 
						||
+MainWindow::MainWindow(WKContextRef context, WKWebsiteDataStoreRef dataStore)
 | 
						||
+    : m_context(context)
 | 
						||
+    , m_dataStore(dataStore)
 | 
						||
 {
 | 
						||
     s_numInstances++;
 | 
						||
 }
 | 
						||
@@ -112,9 +122,9 @@ MainWindow::~MainWindow()
 | 
						||
     s_numInstances--;
 | 
						||
 }
 | 
						||
 
 | 
						||
-Ref<MainWindow> MainWindow::create()
 | 
						||
+Ref<MainWindow> MainWindow::create(WKContextRef context, WKWebsiteDataStoreRef dataStore)
 | 
						||
 {
 | 
						||
-    return adoptRef(*new MainWindow());
 | 
						||
+    return adoptRef(*new MainWindow(context, dataStore));
 | 
						||
 }
 | 
						||
 
 | 
						||
 void MainWindow::createToolbar(HINSTANCE hInstance)
 | 
						||
@@ -202,24 +212,26 @@ bool MainWindow::init(BrowserWindowFactory factory, HINSTANCE hInstance, bool us
 | 
						||
 
 | 
						||
     auto title = loadString(IDS_APP_TITLE);
 | 
						||
 
 | 
						||
-    m_hMainWnd = CreateWindow(s_windowClass.c_str(), title.c_str(), WS_OVERLAPPEDWINDOW,
 | 
						||
-        CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, 0, 0, hInstance, this);
 | 
						||
+    m_hMainWnd = CreateWindowExW(s_headless ? WS_EX_NOACTIVATE : 0, s_windowClass.c_str(), title.c_str(),
 | 
						||
+        WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, 0, 0, hInstance, this);
 | 
						||
 
 | 
						||
     if (!m_hMainWnd)
 | 
						||
         return false;
 | 
						||
 
 | 
						||
+    if (!s_headless) {
 | 
						||
 #if !ENABLE(WEBKIT)
 | 
						||
-    EnableMenuItem(GetMenu(m_hMainWnd), IDM_NEW_WEBKIT_WINDOW, MF_GRAYED);
 | 
						||
+        EnableMenuItem(GetMenu(m_hMainWnd), IDM_NEW_WEBKIT_WINDOW, MF_GRAYED);
 | 
						||
 #endif
 | 
						||
 #if !ENABLE(WEBKIT_LEGACY)
 | 
						||
-    EnableMenuItem(GetMenu(m_hMainWnd), IDM_NEW_WEBKITLEGACY_WINDOW, MF_GRAYED);
 | 
						||
+        EnableMenuItem(GetMenu(m_hMainWnd), IDM_NEW_WEBKITLEGACY_WINDOW, MF_GRAYED);
 | 
						||
 #endif
 | 
						||
 
 | 
						||
-    createToolbar(hInstance);
 | 
						||
-    if (!m_hToolbarWnd)
 | 
						||
-        return false;
 | 
						||
+      createToolbar(hInstance);
 | 
						||
+      if (!m_hToolbarWnd)
 | 
						||
+          return false;
 | 
						||
+    }
 | 
						||
 
 | 
						||
-    m_browserWindow = factory(*this, m_hMainWnd, usesLayeredWebView);
 | 
						||
+    m_browserWindow = factory(*this, m_hMainWnd, m_context.get(), m_dataStore.get(), usesLayeredWebView);
 | 
						||
     if (!m_browserWindow)
 | 
						||
         return false;
 | 
						||
     HRESULT hr = m_browserWindow->init();
 | 
						||
@@ -228,7 +240,13 @@ bool MainWindow::init(BrowserWindowFactory factory, HINSTANCE hInstance, bool us
 | 
						||
 
 | 
						||
     updateDeviceScaleFactor();
 | 
						||
     resizeSubViews();
 | 
						||
-    SetFocus(m_hURLBarWnd);
 | 
						||
+
 | 
						||
+    if (s_headless) {
 | 
						||
+        SetMenu(m_hMainWnd, NULL);
 | 
						||
+    } else {
 | 
						||
+        SetFocus(m_hURLBarWnd);
 | 
						||
+        ShowWindow(m_hMainWnd, SW_SHOW);
 | 
						||
+    }
 | 
						||
     return true;
 | 
						||
 }
 | 
						||
 
 | 
						||
@@ -236,6 +254,10 @@ void MainWindow::resizeSubViews()
 | 
						||
 {
 | 
						||
     RECT rcClient;
 | 
						||
     GetClientRect(m_hMainWnd, &rcClient);
 | 
						||
+    if (s_headless) {
 | 
						||
+        MoveWindow(m_browserWindow->hwnd(), 0, 0, rcClient.right, rcClient.bottom, true);
 | 
						||
+        return;
 | 
						||
+    }
 | 
						||
 
 | 
						||
     resizeToolbar(rcClient.right);
 | 
						||
 
 | 
						||
@@ -254,6 +276,9 @@ LRESULT CALLBACK MainWindow::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPA
 | 
						||
 {
 | 
						||
     LRESULT result = 0;
 | 
						||
     RefPtr<MainWindow> thisWindow = reinterpret_cast<MainWindow*>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
 | 
						||
+    if (!thisWindow && message != WM_CREATE)
 | 
						||
+        return DefWindowProc(hWnd, message, wParam, lParam);
 | 
						||
+
 | 
						||
     switch (message) {
 | 
						||
     case WM_ACTIVATE:
 | 
						||
         switch (LOWORD(wParam)) {
 | 
						||
@@ -309,17 +334,15 @@ LRESULT CALLBACK MainWindow::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPA
 | 
						||
             break;
 | 
						||
 #if ENABLE(WEBKIT)
 | 
						||
         case IDM_NEW_WEBKIT_WINDOW: {
 | 
						||
-            auto& newWindow = MainWindow::create().leakRef();
 | 
						||
+            auto& newWindow = MainWindow::create(thisWindow->m_context.get(), thisWindow->m_dataStore.get()).leakRef();
 | 
						||
             newWindow.init(WebKitBrowserWindow::create, hInst);
 | 
						||
-            ShowWindow(newWindow.hwnd(), SW_SHOW);
 | 
						||
             break;
 | 
						||
         }
 | 
						||
 #endif
 | 
						||
 #if ENABLE(WEBKIT_LEGACY)
 | 
						||
         case IDM_NEW_WEBKITLEGACY_WINDOW: {
 | 
						||
-            auto& newWindow = MainWindow::create().leakRef();
 | 
						||
+            auto& newWindow = MainWindow::create(thisWindow->m_context.get(), thisWindow->m_dataStore.get()).leakRef();
 | 
						||
             newWindow.init(WebKitLegacyBrowserWindow::create, hInst);
 | 
						||
-            ShowWindow(newWindow.hwnd(), SW_SHOW);
 | 
						||
             break;
 | 
						||
         }
 | 
						||
 #endif
 | 
						||
@@ -384,7 +407,7 @@ LRESULT CALLBACK MainWindow::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPA
 | 
						||
     case WM_DESTROY:
 | 
						||
         SetWindowLongPtr(hWnd, GWLP_USERDATA, 0);
 | 
						||
         thisWindow->deref();
 | 
						||
-        if (s_numInstances > 1)
 | 
						||
+        if (s_noStartupWindow || s_numInstances > 1)
 | 
						||
             return 0;
 | 
						||
 #if USE(CF)
 | 
						||
         CFRunLoopStop(CFRunLoopGetMain());
 | 
						||
@@ -443,6 +466,9 @@ void MainWindow::setDefaultURLToCurrentURL()
 | 
						||
 
 | 
						||
 bool MainWindow::toggleMenuItem(UINT menuID)
 | 
						||
 {
 | 
						||
+    if (s_headless)
 | 
						||
+        return (INT_PTR)FALSE;
 | 
						||
+
 | 
						||
     HMENU menu = ::GetMenu(hwnd());
 | 
						||
 
 | 
						||
     switch (menuID) {
 | 
						||
@@ -518,6 +544,8 @@ INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
 | 
						||
 
 | 
						||
 INT_PTR CALLBACK MainWindow::cachesDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
 | 
						||
 {
 | 
						||
+    if (s_headless)
 | 
						||
+        return (INT_PTR)FALSE;
 | 
						||
     MainWindow& thisWindow = *reinterpret_cast<MainWindow*>(GetWindowLongPtr(hDlg, DWLP_USER));
 | 
						||
     switch (message) {
 | 
						||
     case WM_INITDIALOG:
 | 
						||
@@ -548,6 +576,8 @@ INT_PTR CALLBACK MainWindow::cachesDialogProc(HWND hDlg, UINT message, WPARAM wP
 | 
						||
 
 | 
						||
 INT_PTR CALLBACK MainWindow::customUserAgentDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
 | 
						||
 {
 | 
						||
+    if (s_headless)
 | 
						||
+        return (INT_PTR)FALSE;
 | 
						||
     MainWindow& thisWindow = *reinterpret_cast<MainWindow*>(GetWindowLongPtr(hDlg, DWLP_USER));
 | 
						||
     switch (message) {
 | 
						||
     case WM_INITDIALOG: {
 | 
						||
@@ -594,27 +624,26 @@ void MainWindow::loadURL(std::wstring url)
 | 
						||
         if (SUCCEEDED(::UrlCreateFromPath(url.c_str(), fileURL, &fileURLLength, 0)))
 | 
						||
             url = fileURL;
 | 
						||
     }
 | 
						||
-    if (url.find(L"://") == url.npos)
 | 
						||
+    if (url.find(L"://") == url.npos && url.find(L"about:blank") == url.npos)
 | 
						||
         url = L"http://" + url;
 | 
						||
 
 | 
						||
     if (FAILED(m_browserWindow->loadURL(_bstr_t(url.c_str()))))
 | 
						||
         return;
 | 
						||
 
 | 
						||
-    SetFocus(m_browserWindow->hwnd());
 | 
						||
+    if (!s_headless)
 | 
						||
+        SetFocus(m_browserWindow->hwnd());
 | 
						||
 }
 | 
						||
 
 | 
						||
 void MainWindow::goHome()
 | 
						||
 {
 | 
						||
-    std::wstring defaultURL = L"https://www.webkit.org/";
 | 
						||
-    wchar_t url[INTERNET_MAX_URL_LENGTH];
 | 
						||
-    DWORD urlLength = sizeof(url);
 | 
						||
-    if (!RegGetValue(HKEY_CURRENT_USER, kMiniBrowserRegistryKey, L"DefaultURL", RRF_RT_REG_SZ, nullptr, &url, &urlLength))
 | 
						||
-        defaultURL = url;
 | 
						||
+    std::wstring defaultURL = L"about:blank";
 | 
						||
     loadURL(defaultURL);
 | 
						||
 }
 | 
						||
 
 | 
						||
 void MainWindow::onURLBarEnter()
 | 
						||
 {
 | 
						||
+    if (s_headless)
 | 
						||
+        return;
 | 
						||
     wchar_t url[INTERNET_MAX_URL_LENGTH];
 | 
						||
     GetWindowText(m_hURLBarWnd, url, INTERNET_MAX_URL_LENGTH);
 | 
						||
     loadURL(url);
 | 
						||
@@ -622,6 +651,8 @@ void MainWindow::onURLBarEnter()
 | 
						||
 
 | 
						||
 void MainWindow::updateDeviceScaleFactor()
 | 
						||
 {
 | 
						||
+    if (s_headless)
 | 
						||
+        return;
 | 
						||
     if (m_hURLBarFont)
 | 
						||
         ::DeleteObject(m_hURLBarFont);
 | 
						||
 
 | 
						||
@@ -638,6 +669,8 @@ void MainWindow::updateDeviceScaleFactor()
 | 
						||
 
 | 
						||
 void MainWindow::progressChanged(double progress)
 | 
						||
 {
 | 
						||
+    if (s_headless)
 | 
						||
+        return;
 | 
						||
     std::wostringstream text;
 | 
						||
     text << static_cast<int>(progress * 100) << L'%';
 | 
						||
     SetWindowText(m_hProgressIndicator, text.str().c_str());
 | 
						||
@@ -645,10 +678,14 @@ void MainWindow::progressChanged(double progress)
 | 
						||
 
 | 
						||
 void MainWindow::progressFinished()
 | 
						||
 {
 | 
						||
+    if (s_headless)
 | 
						||
+        return;
 | 
						||
     SetWindowText(m_hProgressIndicator, L"");
 | 
						||
 }
 | 
						||
 
 | 
						||
 void MainWindow::activeURLChanged(std::wstring url)
 | 
						||
 {
 | 
						||
+    if (s_headless)
 | 
						||
+        return;
 | 
						||
     SetWindowText(m_hURLBarWnd, url.c_str());
 | 
						||
 }
 | 
						||
diff --git a/Tools/MiniBrowser/win/MainWindow.h b/Tools/MiniBrowser/win/MainWindow.h
 | 
						||
index d79c6fdc4fa05e1e4b9acdcc6932e571163320eb..99718b19797788634f4233a8892729b57ae642d0 100644
 | 
						||
--- a/Tools/MiniBrowser/win/MainWindow.h
 | 
						||
+++ b/Tools/MiniBrowser/win/MainWindow.h
 | 
						||
@@ -26,6 +26,8 @@
 | 
						||
 #pragma once
 | 
						||
 
 | 
						||
 #include "BrowserWindow.h"
 | 
						||
+#include <WebKit/WKBase.h>
 | 
						||
+#include <WebKit/WKRetainPtr.h>
 | 
						||
 #include <functional>
 | 
						||
 #include <memory>
 | 
						||
 #include <string>
 | 
						||
@@ -33,9 +35,10 @@
 | 
						||
 
 | 
						||
 class MainWindow final : public RefCounted<MainWindow>, public BrowserWindowClient {
 | 
						||
 public:
 | 
						||
-    using BrowserWindowFactory = std::function<Ref<BrowserWindow>(BrowserWindowClient&, HWND mainWnd, bool usesLayeredWebView)>;
 | 
						||
+    using BrowserWindowFactory = std::function<Ref<BrowserWindow>(BrowserWindowClient&, HWND mainWnd, WKContextRef, WKWebsiteDataStoreRef, bool usesLayeredWebView)>;
 | 
						||
+    static void configure(bool headless, bool noStartupWindow);
 | 
						||
 
 | 
						||
-    static Ref<MainWindow> create();
 | 
						||
+    static Ref<MainWindow> create(WKContextRef context, WKWebsiteDataStoreRef dataStore);
 | 
						||
 
 | 
						||
     ~MainWindow();
 | 
						||
     bool init(BrowserWindowFactory, HINSTANCE hInstance, bool usesLayeredWebView = false);
 | 
						||
@@ -56,8 +59,10 @@ private:
 | 
						||
     static void registerClass(HINSTANCE hInstance);
 | 
						||
     static std::wstring s_windowClass;
 | 
						||
     static size_t s_numInstances;
 | 
						||
+    static bool s_headless;
 | 
						||
+    static bool s_noStartupWindow;
 | 
						||
 
 | 
						||
-    MainWindow();
 | 
						||
+    MainWindow(WKContextRef context, WKWebsiteDataStoreRef dataStore);
 | 
						||
     void setDefaultURLToCurrentURL();
 | 
						||
     bool toggleMenuItem(UINT menuID);
 | 
						||
     void onURLBarEnter();
 | 
						||
@@ -78,6 +83,8 @@ private:
 | 
						||
     HWND m_hProgressIndicator { nullptr };
 | 
						||
     HWND m_hCacheWnd { nullptr };
 | 
						||
     HGDIOBJ m_hURLBarFont { nullptr };
 | 
						||
+    WKRetainPtr<WKContextRef> m_context; 
 | 
						||
+    WKRetainPtr<WKWebsiteDataStoreRef> m_dataStore;
 | 
						||
     RefPtr<BrowserWindow> m_browserWindow;
 | 
						||
     int m_toolbarItemsWidth { };
 | 
						||
 };
 | 
						||
diff --git a/Tools/MiniBrowser/win/WebKitBrowserWindow.cpp b/Tools/MiniBrowser/win/WebKitBrowserWindow.cpp
 | 
						||
index dc2b3f257600e3f4d172875ebb821769a160979d..9e0072a181ebea8834b96ba5c0020a722f7f3cd4 100644
 | 
						||
--- a/Tools/MiniBrowser/win/WebKitBrowserWindow.cpp
 | 
						||
+++ b/Tools/MiniBrowser/win/WebKitBrowserWindow.cpp
 | 
						||
@@ -107,7 +107,7 @@ WKRetainPtr<WKURLRef> createWKURL(const std::wstring& str)
 | 
						||
     return adoptWK(WKURLCreateWithUTF8CString(utf8.data()));
 | 
						||
 }
 | 
						||
 
 | 
						||
-Ref<BrowserWindow> WebKitBrowserWindow::create(BrowserWindowClient& client, HWND mainWnd, bool)
 | 
						||
+Ref<BrowserWindow> WebKitBrowserWindow::create(BrowserWindowClient& client, HWND mainWnd, WKContextRef context, WKWebsiteDataStoreRef dataStore, bool)
 | 
						||
 {
 | 
						||
     auto conf = adoptWK(WKPageConfigurationCreate());
 | 
						||
 
 | 
						||
@@ -121,8 +121,8 @@ Ref<BrowserWindow> WebKitBrowserWindow::create(BrowserWindowClient& client, HWND
 | 
						||
     WKPreferencesSetDeveloperExtrasEnabled(prefs.get(), true);
 | 
						||
     WKPageConfigurationSetPreferences(conf.get(), prefs.get());
 | 
						||
 
 | 
						||
-    auto context =adoptWK(WKContextCreateWithConfiguration(nullptr));
 | 
						||
-    WKPageConfigurationSetContext(conf.get(), context.get());
 | 
						||
+    WKPageConfigurationSetContext(conf.get(), context);
 | 
						||
+    WKPageConfigurationSetWebsiteDataStore(conf.get(), dataStore);
 | 
						||
 
 | 
						||
     return adoptRef(*new WebKitBrowserWindow(client, conf.get(), mainWnd));
 | 
						||
 }
 | 
						||
@@ -143,11 +143,17 @@ WebKitBrowserWindow::WebKitBrowserWindow(BrowserWindowClient& client, WKPageConf
 | 
						||
     navigationClient.didReceiveAuthenticationChallenge = didReceiveAuthenticationChallenge;
 | 
						||
     WKPageSetPageNavigationClient(page, &navigationClient.base);
 | 
						||
 
 | 
						||
-    WKPageUIClientV13 uiClient = { };
 | 
						||
-    uiClient.base.version = 13;
 | 
						||
+    WKPageUIClientV14 uiClient = { };
 | 
						||
+    uiClient.base.version = 14;
 | 
						||
     uiClient.base.clientInfo = this;
 | 
						||
     uiClient.createNewPage = createNewPage;
 | 
						||
     uiClient.didNotHandleKeyEvent = didNotHandleKeyEvent;
 | 
						||
+    uiClient.close = closeWindow;
 | 
						||
+    uiClient.runJavaScriptAlert = runJavaScriptAlert;
 | 
						||
+    uiClient.runJavaScriptConfirm = runJavaScriptConfirm;
 | 
						||
+    uiClient.runJavaScriptPrompt = runJavaScriptPrompt;
 | 
						||
+    uiClient.runBeforeUnloadConfirmPanel = runBeforeUnloadConfirmPanel;
 | 
						||
+    uiClient.handleJavaScriptDialog = handleJavaScriptDialog;
 | 
						||
     WKPageSetPageUIClient(page, &uiClient.base);
 | 
						||
 
 | 
						||
     WKPageStateClientV0 stateClient = { };
 | 
						||
@@ -159,7 +165,6 @@ WebKitBrowserWindow::WebKitBrowserWindow(BrowserWindowClient& client, WKPageConf
 | 
						||
     stateClient.didChangeActiveURL = didChangeActiveURL;
 | 
						||
     WKPageSetPageStateClient(page, &stateClient.base);
 | 
						||
 
 | 
						||
-    updateProxySettings();
 | 
						||
     resetZoom();
 | 
						||
 }
 | 
						||
 
 | 
						||
@@ -183,6 +188,29 @@ void WebKitBrowserWindow::updateProxySettings()
 | 
						||
     WKWebsiteDataStoreEnableCustomNetworkProxySettings(store, url.get(), excludeHosts.get());
 | 
						||
 }
 | 
						||
 
 | 
						||
+WebKitBrowserWindow::~WebKitBrowserWindow()
 | 
						||
+{
 | 
						||
+    if (m_alertDialog) {
 | 
						||
+        WKRelease(m_alertDialog);
 | 
						||
+        m_alertDialog = NULL;
 | 
						||
+    }
 | 
						||
+
 | 
						||
+    if (m_confirmDialog) {
 | 
						||
+        WKRelease(m_confirmDialog);
 | 
						||
+        m_confirmDialog = NULL;
 | 
						||
+    }
 | 
						||
+
 | 
						||
+    if (m_promptDialog) {
 | 
						||
+        WKRelease(m_promptDialog);
 | 
						||
+        m_promptDialog = NULL;
 | 
						||
+    }
 | 
						||
+
 | 
						||
+    if (m_beforeUnloadDialog) {
 | 
						||
+        WKRelease(m_beforeUnloadDialog);
 | 
						||
+        m_beforeUnloadDialog = NULL;
 | 
						||
+    }
 | 
						||
+}
 | 
						||
+
 | 
						||
 HRESULT WebKitBrowserWindow::init()
 | 
						||
 {
 | 
						||
     return S_OK;
 | 
						||
@@ -251,7 +279,6 @@ void WebKitBrowserWindow::openProxySettings()
 | 
						||
 {
 | 
						||
     if (askProxySettings(m_hMainWnd, m_proxy))
 | 
						||
         updateProxySettings();
 | 
						||
-
 | 
						||
 }
 | 
						||
 
 | 
						||
 void WebKitBrowserWindow::setUserAgent(_bstr_t& customUAString)
 | 
						||
@@ -381,18 +408,94 @@ bool WebKitBrowserWindow::canTrustServerCertificate(WKProtectionSpaceRef protect
 | 
						||
     return false;
 | 
						||
 }
 | 
						||
 
 | 
						||
-WKPageRef WebKitBrowserWindow::createNewPage(WKPageRef page, WKPageConfigurationRef configuration, WKNavigationActionRef navigationAction, WKWindowFeaturesRef windowFeatures, const void *clientInfo)
 | 
						||
+void WebKitBrowserWindow::closeWindow(WKPageRef page, const void* clientInfo)
 | 
						||
 {
 | 
						||
-    auto& newWindow = MainWindow::create().leakRef();
 | 
						||
-    auto factory = [configuration](BrowserWindowClient& client, HWND mainWnd, bool) -> auto {
 | 
						||
+    auto& thisWindow = toWebKitBrowserWindow(clientInfo);
 | 
						||
+    PostMessage(thisWindow.m_hMainWnd, WM_CLOSE, 0, 0);
 | 
						||
+}
 | 
						||
+
 | 
						||
+void WebKitBrowserWindow::runJavaScriptAlert(WKPageRef page, WKStringRef alertText, WKFrameRef frame, WKSecurityOriginRef securityOrigin, WKPageRunJavaScriptAlertResultListenerRef listener, const void *clientInfo)
 | 
						||
+{
 | 
						||
+    auto& thisWindow = toWebKitBrowserWindow(clientInfo);
 | 
						||
+    WKRetain(listener);
 | 
						||
+    thisWindow.m_alertDialog = listener;
 | 
						||
+}
 | 
						||
+
 | 
						||
+void WebKitBrowserWindow::runJavaScriptConfirm(WKPageRef page, WKStringRef message, WKFrameRef frame, WKSecurityOriginRef securityOrigin, WKPageRunJavaScriptConfirmResultListenerRef listener, const void *clientInfo)
 | 
						||
+{
 | 
						||
+    auto& thisWindow = toWebKitBrowserWindow(clientInfo);
 | 
						||
+    WKRetain(listener);
 | 
						||
+    thisWindow.m_confirmDialog = listener;
 | 
						||
+}
 | 
						||
+
 | 
						||
+void WebKitBrowserWindow::runJavaScriptPrompt(WKPageRef page, WKStringRef message, WKStringRef defaultValue, WKFrameRef frame, WKSecurityOriginRef securityOrigin, WKPageRunJavaScriptPromptResultListenerRef listener, const void *clientInfo)
 | 
						||
+{
 | 
						||
+    auto& thisWindow = toWebKitBrowserWindow(clientInfo);
 | 
						||
+    WKRetain(listener);
 | 
						||
+    thisWindow.m_promptDialog = listener;
 | 
						||
+}
 | 
						||
+
 | 
						||
+void WebKitBrowserWindow::runBeforeUnloadConfirmPanel(WKPageRef page, WKStringRef message, WKFrameRef frame, WKPageRunBeforeUnloadConfirmPanelResultListenerRef listener, const void *clientInfo)
 | 
						||
+{
 | 
						||
+    auto& thisWindow = toWebKitBrowserWindow(clientInfo);
 | 
						||
+    WKRetain(listener);
 | 
						||
+    thisWindow.m_beforeUnloadDialog = listener;
 | 
						||
+}
 | 
						||
+    
 | 
						||
+void WebKitBrowserWindow::handleJavaScriptDialog(WKPageRef page, bool accept, WKStringRef value, const void *clientInfo)
 | 
						||
+{
 | 
						||
+    auto& thisWindow = toWebKitBrowserWindow(clientInfo);
 | 
						||
+    if (thisWindow.m_alertDialog) {
 | 
						||
+        WKPageRunJavaScriptAlertResultListenerCall(thisWindow.m_alertDialog);
 | 
						||
+        WKRelease(thisWindow.m_alertDialog);
 | 
						||
+        thisWindow.m_alertDialog = NULL;
 | 
						||
+    }
 | 
						||
+
 | 
						||
+    if (thisWindow.m_confirmDialog) {
 | 
						||
+        WKPageRunJavaScriptConfirmResultListenerCall(thisWindow.m_confirmDialog, accept);
 | 
						||
+        WKRelease(thisWindow.m_confirmDialog);
 | 
						||
+        thisWindow.m_confirmDialog = NULL;
 | 
						||
+    }
 | 
						||
+
 | 
						||
+    if (thisWindow.m_promptDialog) {
 | 
						||
+        WKPageRunJavaScriptPromptResultListenerCall(thisWindow.m_promptDialog, accept ? value : NULL);
 | 
						||
+        WKRelease(thisWindow.m_promptDialog);
 | 
						||
+        thisWindow.m_promptDialog = NULL;
 | 
						||
+    }
 | 
						||
+
 | 
						||
+    if (thisWindow.m_beforeUnloadDialog) {
 | 
						||
+        WKPageRunBeforeUnloadConfirmPanelResultListenerCall(thisWindow.m_beforeUnloadDialog, accept);
 | 
						||
+        WKRelease(thisWindow.m_beforeUnloadDialog);
 | 
						||
+        thisWindow.m_beforeUnloadDialog = NULL;
 | 
						||
+    }
 | 
						||
+}
 | 
						||
+
 | 
						||
+WKPageRef WebKitBrowserWindow::createPageCallback(WKPageConfigurationRef configuration)
 | 
						||
+{
 | 
						||
+    return WebKitBrowserWindow::createViewCallback(configuration, true);
 | 
						||
+}
 | 
						||
+
 | 
						||
+WKPageRef WebKitBrowserWindow::createViewCallback(WKPageConfigurationRef configuration, bool navigate)
 | 
						||
+{
 | 
						||
+    auto context = WKPageConfigurationGetContext(configuration);
 | 
						||
+    auto dataStore = WKPageConfigurationGetWebsiteDataStore(configuration);
 | 
						||
+    auto& newWindow = MainWindow::create(context, dataStore).leakRef();
 | 
						||
+    auto factory = [configuration](BrowserWindowClient& client, HWND mainWnd, WKContextRef, WKWebsiteDataStoreRef, bool) -> auto {
 | 
						||
         return adoptRef(*new WebKitBrowserWindow(client, configuration, mainWnd));
 | 
						||
     };
 | 
						||
     bool ok = newWindow.init(factory, hInst);
 | 
						||
-    if (!ok)
 | 
						||
-        return nullptr;
 | 
						||
-    ShowWindow(newWindow.hwnd(), SW_SHOW);
 | 
						||
+    if (navigate)
 | 
						||
+        newWindow.browserWindow()->loadURL(_bstr_t("about:blank").GetBSTR());
 | 
						||
+
 | 
						||
     auto& newBrowserWindow = *static_cast<WebKitBrowserWindow*>(newWindow.browserWindow());
 | 
						||
-    WKRetainPtr<WKPageRef> newPage = WKViewGetPage(newBrowserWindow.m_view.get());
 | 
						||
+    return WKViewGetPage(newBrowserWindow.m_view.get());
 | 
						||
+}
 | 
						||
+
 | 
						||
+
 | 
						||
+WKPageRef WebKitBrowserWindow::createNewPage(WKPageRef, WKPageConfigurationRef configuration, WKNavigationActionRef, WKWindowFeaturesRef, const void*)
 | 
						||
+{
 | 
						||
+    // Retain popups as per API contract.
 | 
						||
+    WKRetainPtr<WKPageRef> newPage = createViewCallback(configuration, false);
 | 
						||
     return newPage.leakRef();
 | 
						||
 }
 | 
						||
 
 | 
						||
diff --git a/Tools/MiniBrowser/win/WebKitBrowserWindow.h b/Tools/MiniBrowser/win/WebKitBrowserWindow.h
 | 
						||
index 373d0de77e852c673a6615e0acedd5195e3c021b..cfeb4f806f79d1a213fdb13346e2b383b9a64273 100644
 | 
						||
--- a/Tools/MiniBrowser/win/WebKitBrowserWindow.h
 | 
						||
+++ b/Tools/MiniBrowser/win/WebKitBrowserWindow.h
 | 
						||
@@ -26,6 +26,7 @@
 | 
						||
 
 | 
						||
 #include "BrowserWindow.h"
 | 
						||
 #include "Common.h"
 | 
						||
+#include <WebKit/WKBase.h>
 | 
						||
 #include <WebKit/WKRetainPtr.h>
 | 
						||
 #include <WebKit/WebKit2_C.h>
 | 
						||
 #include <unordered_map>
 | 
						||
@@ -33,10 +34,13 @@
 | 
						||
 
 | 
						||
 class WebKitBrowserWindow : public BrowserWindow {
 | 
						||
 public:
 | 
						||
-    static Ref<BrowserWindow> create(BrowserWindowClient&, HWND mainWnd, bool useLayeredWebView = false);
 | 
						||
+    static Ref<BrowserWindow> create(BrowserWindowClient&, HWND mainWnd, WKContextRef, WKWebsiteDataStoreRef, bool useLayeredWebView = false);
 | 
						||
+    static WKPageRef createPageCallback(WKPageConfigurationRef);
 | 
						||
 
 | 
						||
 private:
 | 
						||
+    static WKPageRef createViewCallback(WKPageConfigurationRef, bool navigate);
 | 
						||
     WebKitBrowserWindow(BrowserWindowClient&, WKPageConfigurationRef, HWND mainWnd);
 | 
						||
+    ~WebKitBrowserWindow() override;
 | 
						||
 
 | 
						||
     HRESULT init() override;
 | 
						||
     HWND hwnd() override;
 | 
						||
@@ -71,6 +75,12 @@ private:
 | 
						||
     static void didChangeActiveURL(const void*);
 | 
						||
     static void didReceiveAuthenticationChallenge(WKPageRef, WKAuthenticationChallengeRef, const void*);
 | 
						||
     static WKPageRef createNewPage(WKPageRef, WKPageConfigurationRef, WKNavigationActionRef, WKWindowFeaturesRef, const void *);
 | 
						||
+    static void closeWindow(WKPageRef, const void*);
 | 
						||
+    static void runJavaScriptAlert(WKPageRef page, WKStringRef alertText, WKFrameRef frame, WKSecurityOriginRef securityOrigin, WKPageRunJavaScriptAlertResultListenerRef listener, const void *clientInfo);
 | 
						||
+    static void runJavaScriptConfirm(WKPageRef page, WKStringRef message, WKFrameRef frame, WKSecurityOriginRef securityOrigin, WKPageRunJavaScriptConfirmResultListenerRef listener, const void *clientInfo);
 | 
						||
+    static void runJavaScriptPrompt(WKPageRef page, WKStringRef message, WKStringRef defaultValue, WKFrameRef frame, WKSecurityOriginRef securityOrigin, WKPageRunJavaScriptPromptResultListenerRef listener, const void *clientInfo);
 | 
						||
+    static void runBeforeUnloadConfirmPanel(WKPageRef page, WKStringRef message, WKFrameRef frame, WKPageRunBeforeUnloadConfirmPanelResultListenerRef listener, const void *clientInfo);
 | 
						||
+    static void handleJavaScriptDialog(WKPageRef page, bool accept, WKStringRef value, const void *clientInfo);
 | 
						||
     static void didNotHandleKeyEvent(WKPageRef, WKNativeEventPtr, const void*);
 | 
						||
 
 | 
						||
     BrowserWindowClient& m_client;
 | 
						||
@@ -78,4 +88,8 @@ private:
 | 
						||
     HWND m_hMainWnd { nullptr };
 | 
						||
     ProxySettings m_proxy { };
 | 
						||
     std::unordered_map<std::wstring, std::wstring> m_acceptedServerTrustCerts;
 | 
						||
+    WKPageRunJavaScriptAlertResultListenerRef m_alertDialog = { };
 | 
						||
+    WKPageRunJavaScriptConfirmResultListenerRef m_confirmDialog = { };
 | 
						||
+    WKPageRunJavaScriptPromptResultListenerRef m_promptDialog = { };
 | 
						||
+    WKPageRunBeforeUnloadConfirmPanelResultListenerRef m_beforeUnloadDialog = { };
 | 
						||
 };
 | 
						||
diff --git a/Tools/MiniBrowser/win/WinMain.cpp b/Tools/MiniBrowser/win/WinMain.cpp
 | 
						||
index 6008ca19e26a938cf962c0c336299fff7d13f9a3..8005d72f8c0d9ef82efda8aec1ff0e7d96501ae8 100644
 | 
						||
--- a/Tools/MiniBrowser/win/WinMain.cpp
 | 
						||
+++ b/Tools/MiniBrowser/win/WinMain.cpp
 | 
						||
@@ -31,6 +31,10 @@
 | 
						||
 #include "stdafx.h"
 | 
						||
 #include "Common.h"
 | 
						||
 #include "MiniBrowserLibResource.h"
 | 
						||
+#include "MiniBrowserReplace.h"
 | 
						||
+#include <WebKit/WKContext.h>
 | 
						||
+#include <WebKit/WKWebsiteDataStoreConfigurationRef.h>
 | 
						||
+#include <WebKit/WKWebsiteDataStoreRef.h>
 | 
						||
 #include <wtf/win/SoftLinking.h>
 | 
						||
 
 | 
						||
 #if USE(CF)
 | 
						||
@@ -46,9 +50,25 @@
 | 
						||
 #include <WebKitLegacy/WebKitCOMAPI.h>
 | 
						||
 #endif
 | 
						||
 
 | 
						||
+#include <wtf/MainThread.h>
 | 
						||
+#include <WebKit/WKInspector.h>
 | 
						||
+
 | 
						||
 SOFT_LINK_LIBRARY(user32);
 | 
						||
 SOFT_LINK_OPTIONAL(user32, SetProcessDpiAwarenessContext, BOOL, STDAPICALLTYPE, (DPI_AWARENESS_CONTEXT));
 | 
						||
 
 | 
						||
+WKRetainPtr<WKStringRef> toWK(const std::string& string)
 | 
						||
+{
 | 
						||
+    return adoptWK(WKStringCreateWithUTF8CString(string.c_str()));
 | 
						||
+}
 | 
						||
+
 | 
						||
+std::string toUTF8String(const wchar_t* src, size_t srcLength)
 | 
						||
+{
 | 
						||
+    int length = WideCharToMultiByte(CP_UTF8, 0, src, srcLength, 0, 0, nullptr, nullptr);
 | 
						||
+    std::vector<char> buffer(length);
 | 
						||
+    size_t actualLength = WideCharToMultiByte(CP_UTF8, 0, src, srcLength, buffer.data(), length, nullptr, nullptr);
 | 
						||
+    return { buffer.data(), actualLength };
 | 
						||
+}
 | 
						||
+
 | 
						||
 int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpstrCmdLine, _In_ int nCmdShow)
 | 
						||
 {
 | 
						||
 #ifdef _CRTDBG_MAP_ALLOC
 | 
						||
@@ -66,6 +86,11 @@ int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,
 | 
						||
     InitCommonControlsEx(&InitCtrlEx);
 | 
						||
 
 | 
						||
     auto options = parseCommandLine();
 | 
						||
+    if (options.inspectorPipe) {
 | 
						||
+        WKInspectorInitializeRemoteInspectorPipe(
 | 
						||
+            WebKitBrowserWindow::createPageCallback,
 | 
						||
+            []() { PostQuitMessage(0); });
 | 
						||
+    }
 | 
						||
 
 | 
						||
     if (options.useFullDesktop)
 | 
						||
         computeFullDesktopFrame();
 | 
						||
@@ -74,32 +99,50 @@ int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,
 | 
						||
     OleInitialize(nullptr);
 | 
						||
 
 | 
						||
     if (SetProcessDpiAwarenessContextPtr())
 | 
						||
-        SetProcessDpiAwarenessContextPtr()(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
 | 
						||
-    else
 | 
						||
-        ::SetProcessDPIAware();
 | 
						||
+        SetProcessDpiAwarenessContextPtr()(DPI_AWARENESS_CONTEXT_UNAWARE);
 | 
						||
+
 | 
						||
+    MainWindow::configure(options.headless, options.noStartupWindow);
 | 
						||
 
 | 
						||
+    if (!options.noStartupWindow) {
 | 
						||
 #if !ENABLE(WEBKIT_LEGACY)
 | 
						||
-    auto factory = WebKitBrowserWindow::create;
 | 
						||
+        auto factory = WebKitBrowserWindow::create;
 | 
						||
 #elif !ENABLE(WEBKIT)
 | 
						||
-    auto factory = WebKitLegacyBrowserWindow::create;
 | 
						||
+        auto factory = WebKitLegacyBrowserWindow::create;
 | 
						||
 #else
 | 
						||
-    auto factory = options.windowType == BrowserWindowType::WebKit ? WebKitBrowserWindow::create : WebKitLegacyBrowserWindow::create;
 | 
						||
+        auto factory = options.windowType == BrowserWindowType::WebKit ? WebKitBrowserWindow::create : WebKitLegacyBrowserWindow::create;
 | 
						||
 #endif
 | 
						||
-    auto& mainWindow = MainWindow::create().leakRef();
 | 
						||
-    HRESULT hr = mainWindow.init(factory, hInst, options.usesLayeredWebView);
 | 
						||
-    if (FAILED(hr))
 | 
						||
-        goto exit;
 | 
						||
 
 | 
						||
-    ShowWindow(mainWindow.hwnd(), nCmdShow);
 | 
						||
+        auto configuration = adoptWK(WKWebsiteDataStoreConfigurationCreate());
 | 
						||
+        if (options.userDataDir.length()) {
 | 
						||
+            std::string profileFolder = toUTF8String(options.userDataDir, options.userDataDir.length());
 | 
						||
+            WKWebsiteDataStoreConfigurationSetApplicationCacheDirectory(configuration.get(), toWK(profileFolder + "\\ApplicationCache").get());
 | 
						||
+            WKWebsiteDataStoreConfigurationSetNetworkCacheDirectory(configuration.get(), toWK(profileFolder + "\\Cache").get());
 | 
						||
+            WKWebsiteDataStoreConfigurationSetCacheStorageDirectory(configuration.get(), toWK(profileFolder + "\\CacheStorage").get());
 | 
						||
+            WKWebsiteDataStoreConfigurationSetIndexedDBDatabaseDirectory(configuration.get(), toWK(profileFolder + "\\Databases" + "\\IndexedDB").get());
 | 
						||
+            WKWebsiteDataStoreConfigurationSetLocalStorageDirectory(configuration.get(), toWK(profileFolder + "\\LocalStorage").get());
 | 
						||
+            WKWebsiteDataStoreConfigurationSetWebSQLDatabaseDirectory(configuration.get(), toWK(profileFolder + "\\Databases" + "\\WebSQL").get());
 | 
						||
+            WKWebsiteDataStoreConfigurationSetMediaKeysStorageDirectory(configuration.get(), toWK(profileFolder + "\\MediaKeys").get());
 | 
						||
+            WKWebsiteDataStoreConfigurationSetResourceLoadStatisticsDirectory(configuration.get(), toWK(profileFolder + "\\ResourceLoadStatistics").get());
 | 
						||
+            WKWebsiteDataStoreConfigurationSetServiceWorkerRegistrationDirectory(configuration.get(), toWK(profileFolder + "\\ServiceWorkers").get());
 | 
						||
+        }
 | 
						||
+        auto context = adoptWK(WKContextCreateWithConfiguration(nullptr));
 | 
						||
+        auto dataStore = adoptWK(WKWebsiteDataStoreCreateWithConfiguration(configuration.get()));
 | 
						||
+        WKContextSetPrimaryDataStore(context.get(), dataStore.get());
 | 
						||
+
 | 
						||
+        auto& mainWindow = MainWindow::create(context.get(), dataStore.get()).leakRef();
 | 
						||
+        HRESULT hr = mainWindow.init(factory, hInst, options.usesLayeredWebView);
 | 
						||
+        if (FAILED(hr))
 | 
						||
+            goto exit;
 | 
						||
+
 | 
						||
+        if (options.requestedURL.length())
 | 
						||
+            mainWindow.loadURL(options.requestedURL.GetBSTR());
 | 
						||
+        else
 | 
						||
+            mainWindow.goHome();
 | 
						||
+    }
 | 
						||
 
 | 
						||
     hAccelTable = LoadAccelerators(hInst, MAKEINTRESOURCE(IDC_MINIBROWSER));
 | 
						||
     hPreAccelTable = LoadAccelerators(hInst, MAKEINTRESOURCE(IDR_ACCELERATORS_PRE));
 | 
						||
 
 | 
						||
-    if (options.requestedURL.length())
 | 
						||
-        mainWindow.loadURL(options.requestedURL.GetBSTR());
 | 
						||
-    else
 | 
						||
-        mainWindow.goHome();
 | 
						||
-
 | 
						||
 #pragma warning(disable:4509)
 | 
						||
 
 | 
						||
     // Main message loop:
 | 
						||
diff --git a/Tools/MiniBrowser/wpe/CMakeLists.txt b/Tools/MiniBrowser/wpe/CMakeLists.txt
 | 
						||
index 04d3630dc2b0f5e937af173046268001da003753..ba0a60b832cd353776bb50b8198df2d8c4ee9f68 100644
 | 
						||
--- a/Tools/MiniBrowser/wpe/CMakeLists.txt
 | 
						||
+++ b/Tools/MiniBrowser/wpe/CMakeLists.txt
 | 
						||
@@ -13,6 +13,7 @@ set(MiniBrowser_INCLUDE_DIRECTORIES
 | 
						||
 
 | 
						||
 set(MiniBrowser_SYSTEM_INCLUDE_DIRECTORIES
 | 
						||
     ${ATK_INCLUDE_DIRS}
 | 
						||
+    ${GLIB_INCLUDE_DIRS}
 | 
						||
     ${WPEBACKEND_FDO_INCLUDE_DIRS}
 | 
						||
 )
 | 
						||
 
 | 
						||
diff --git a/Tools/MiniBrowser/wpe/main.cpp b/Tools/MiniBrowser/wpe/main.cpp
 | 
						||
index a8cccb6c1d567823fe8e6503f1a137856b0a9975..00b39f96b6b48dc0bd3df54659850dfc233ea0be 100644
 | 
						||
--- a/Tools/MiniBrowser/wpe/main.cpp
 | 
						||
+++ b/Tools/MiniBrowser/wpe/main.cpp
 | 
						||
@@ -25,7 +25,7 @@
 | 
						||
 
 | 
						||
 #include "cmakeconfig.h"
 | 
						||
 
 | 
						||
-#include "HeadlessViewBackend.h"
 | 
						||
+#include "NullViewBackend.h"
 | 
						||
 #include "WindowViewBackend.h"
 | 
						||
 #if ENABLE_WEB_AUDIO || ENABLE_VIDEO
 | 
						||
 #include <gst/gst.h>
 | 
						||
@@ -43,6 +43,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;
 | 
						||
@@ -64,6 +67,9 @@ static const GOptionEntry commandLineOptions[] =
 | 
						||
     { "content-filter", 0, 0, G_OPTION_ARG_FILENAME, &contentFilter, "JSON with content filtering rules", "FILE" },
 | 
						||
     { "bg-color", 0, 0, G_OPTION_ARG_STRING, &bgColor, "Window background color. Default: white", "COLOR" },
 | 
						||
     { "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 }
 | 
						||
 };
 | 
						||
@@ -132,7 +138,7 @@ static gboolean decidePermissionRequest(WebKitWebView *, WebKitPermissionRequest
 | 
						||
 static std::unique_ptr<WPEToolingBackends::ViewBackend> createViewBackend(uint32_t width, uint32_t height)
 | 
						||
 {
 | 
						||
     if (headlessMode)
 | 
						||
-        return std::make_unique<WPEToolingBackends::HeadlessViewBackend>(width, height);
 | 
						||
+        return std::make_unique<WPEToolingBackends::NullViewBackend>();
 | 
						||
     return std::make_unique<WPEToolingBackends::WindowViewBackend>(width, height);
 | 
						||
 }
 | 
						||
 
 | 
						||
@@ -148,13 +154,34 @@ static void filterSavedCallback(WebKitUserContentFilterStore *store, GAsyncResul
 | 
						||
     g_main_loop_quit(data->mainLoop);
 | 
						||
 }
 | 
						||
 
 | 
						||
+static gboolean webViewLoadFailed()
 | 
						||
+{
 | 
						||
+    return TRUE;
 | 
						||
+}
 | 
						||
+
 | 
						||
 static void webViewClose(WebKitWebView* webView, gpointer)
 | 
						||
 {
 | 
						||
     // Hash table key delete func takes care of unref'ing the view
 | 
						||
     g_hash_table_remove(openViews, webView);
 | 
						||
 }
 | 
						||
 
 | 
						||
-static WebKitWebView* createWebView(WebKitWebView* webView, WebKitNavigationAction*, gpointer)
 | 
						||
+static gboolean scriptDialog(WebKitWebView*, WebKitScriptDialog* dialog, gpointer)
 | 
						||
+{
 | 
						||
+    if (inspectorPipe)
 | 
						||
+        webkit_script_dialog_ref(dialog);
 | 
						||
+    return TRUE;
 | 
						||
+}
 | 
						||
+
 | 
						||
+static gboolean scriptDialogHandled(WebKitWebView*, WebKitScriptDialog* dialog, gpointer)
 | 
						||
+{
 | 
						||
+    if (inspectorPipe)
 | 
						||
+        webkit_script_dialog_unref(dialog);
 | 
						||
+    return TRUE;
 | 
						||
+}
 | 
						||
+
 | 
						||
+static WebKitWebView* createWebView(WebKitWebView* webView, WebKitNavigationAction*, gpointer);
 | 
						||
+
 | 
						||
+static WebKitWebView* createWebViewImpl(WebKitWebView* webView, WebKitWebContext *webContext)
 | 
						||
 {
 | 
						||
     auto backend = createViewBackend(1280, 720);
 | 
						||
     struct wpe_view_backend* wpeBackend = backend->backend();
 | 
						||
@@ -166,16 +193,50 @@ 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));
 | 
						||
+    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, "close", G_CALLBACK(webViewClose), nullptr);
 | 
						||
 
 | 
						||
     g_hash_table_add(openViews, newWebView);
 | 
						||
 
 | 
						||
+    g_signal_connect(newWebView, "load-failed", G_CALLBACK(webViewLoadFailed), nullptr);
 | 
						||
+    g_signal_connect(newWebView, "script-dialog", G_CALLBACK(scriptDialog), nullptr);
 | 
						||
+    g_signal_connect(newWebView, "script-dialog-handled", G_CALLBACK(scriptDialogHandled), nullptr);
 | 
						||
+    g_signal_connect(newWebView, "create", G_CALLBACK(createWebView), nullptr);
 | 
						||
     return newWebView;
 | 
						||
 }
 | 
						||
 
 | 
						||
+static WebKitWebView* createWebView(WebKitWebView* webView, WebKitNavigationAction*, gpointer)
 | 
						||
+{
 | 
						||
+    return createWebViewImpl(webView, nullptr);
 | 
						||
+}
 | 
						||
+
 | 
						||
+static WebKitWebContext *persistentWebContext = NULL;
 | 
						||
+
 | 
						||
+static WebKitWebView* createNewPage(WebKitBrowserInspector*, WebKitWebContext *webContext)
 | 
						||
+{
 | 
						||
+    if (!webContext)
 | 
						||
+        webContext = persistentWebContext;
 | 
						||
+    WebKitWebView* webView = createWebViewImpl(nullptr, webContext);
 | 
						||
+    webkit_web_view_load_uri(webView, "about:blank");
 | 
						||
+    return webView;
 | 
						||
+}
 | 
						||
+
 | 
						||
+static void configureBrowserInspector(GMainLoop* mainLoop)
 | 
						||
+{
 | 
						||
+    WebKitBrowserInspector* browserInspector = webkit_browser_inspector_get_default();
 | 
						||
+    g_signal_connect(browserInspector, "create-new-page", G_CALLBACK(createNewPage), NULL);
 | 
						||
+    webkit_browser_inspector_initialize_pipe(mainLoop);
 | 
						||
+}
 | 
						||
+
 | 
						||
 int main(int argc, char *argv[])
 | 
						||
 {
 | 
						||
 #if ENABLE_DEVELOPER_MODE
 | 
						||
@@ -210,6 +271,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();
 | 
						||
@@ -219,7 +290,19 @@ int main(int argc, char *argv[])
 | 
						||
         return 1;
 | 
						||
     }
 | 
						||
 
 | 
						||
-    auto* webContext = (privateMode || automationMode) ? webkit_web_context_new_ephemeral() : webkit_web_context_get_default();
 | 
						||
+    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);
 | 
						||
+    }
 | 
						||
+
 | 
						||
+    WebKitWebContext *webContext = WEBKIT_WEB_CONTEXT(g_object_new(WEBKIT_TYPE_WEB_CONTEXT, "website-data-manager", manager, "process-swap-on-cross-site-navigation-enabled", TRUE, NULL));
 | 
						||
+    persistentWebContext = webContext;
 | 
						||
+    g_object_unref(manager);
 | 
						||
 
 | 
						||
     if (cookiesPolicy) {
 | 
						||
         auto* cookieManager = webkit_web_context_get_cookie_manager(webContext);
 | 
						||
@@ -300,8 +383,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);
 | 
						||
@@ -326,7 +407,7 @@ int main(int argc, char *argv[])
 | 
						||
         g_object_unref(file);
 | 
						||
         webkit_web_view_load_uri(webView, url);
 | 
						||
         g_free(url);
 | 
						||
-    } else if (automationMode)
 | 
						||
+    } else if (automationMode || inspectorPipe)
 | 
						||
         webkit_web_view_load_uri(webView, "about:blank");
 | 
						||
     else
 | 
						||
         webkit_web_view_load_uri(webView, "https://wpewebkit.org");
 | 
						||
@@ -336,8 +417,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/Playwright/Configurations/Base.xcconfig b/Tools/Playwright/Configurations/Base.xcconfig
 | 
						||
new file mode 100644
 | 
						||
index 0000000000000000000000000000000000000000..fc61d5227c8608488514cbd92a28dc7c1c2efaf4
 | 
						||
--- /dev/null
 | 
						||
+++ b/Tools/Playwright/Configurations/Base.xcconfig
 | 
						||
@@ -0,0 +1,87 @@
 | 
						||
+// Copyright (C) 2010-2017 Apple Inc. All rights reserved.
 | 
						||
+//
 | 
						||
+// Redistribution and use in source and binary forms, with or without
 | 
						||
+// modification, are permitted provided that the following conditions
 | 
						||
+// 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? "../../../../Internal/Configurations/HaveInternalSDK.xcconfig"
 | 
						||
+#include "SDKVariant.xcconfig"
 | 
						||
+
 | 
						||
+USE_INTERNAL_SDK = $(USE_INTERNAL_SDK_$(CONFIGURATION));
 | 
						||
+USE_INTERNAL_SDK_Production = YES;
 | 
						||
+USE_INTERNAL_SDK_Debug = $(HAVE_INTERNAL_SDK);
 | 
						||
+USE_INTERNAL_SDK_Release = $(HAVE_INTERNAL_SDK);
 | 
						||
+
 | 
						||
+GCC_PREPROCESSOR_DEFINITIONS = DISABLE_LEGACY_WEBKIT_DEPRECATIONS $(inherited);
 | 
						||
+
 | 
						||
+CLANG_CXX_LANGUAGE_STANDARD = gnu++1z;
 | 
						||
+CLANG_CXX_LIBRARY = libc++;
 | 
						||
+CLANG_ENABLE_OBJC_WEAK = YES;
 | 
						||
+DEBUG_INFORMATION_FORMAT = dwarf-with-dsym;
 | 
						||
+PREBINDING = NO
 | 
						||
+GCC_C_LANGUAGE_STANDARD = gnu99
 | 
						||
+GCC_ENABLE_CPP_EXCEPTIONS = NO;
 | 
						||
+GCC_PRECOMPILE_PREFIX_HEADER = YES
 | 
						||
+ENABLE_STRICT_OBJC_MSGSEND = YES;
 | 
						||
+GCC_TREAT_WARNINGS_AS_ERRORS = YES
 | 
						||
+CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
 | 
						||
+CLANG_WARN_BOOL_CONVERSION = YES;
 | 
						||
+CLANG_WARN_COMMA = YES;
 | 
						||
+CLANG_WARN_CONSTANT_CONVERSION = YES;
 | 
						||
+CLANG_WARN_EMPTY_BODY = YES;
 | 
						||
+CLANG_WARN_ENUM_CONVERSION = YES;
 | 
						||
+CLANG_WARN_INFINITE_RECURSION = YES;
 | 
						||
+CLANG_WARN_INT_CONVERSION = YES;
 | 
						||
+CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
 | 
						||
+CLANG_WARN_STRICT_PROTOTYPES = YES;
 | 
						||
+CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
 | 
						||
+CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
 | 
						||
+CLANG_WARN_SUSPICIOUS_MOVE = YES;
 | 
						||
+CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
 | 
						||
+CLANG_WARN_UNREACHABLE_CODE = YES;
 | 
						||
+GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
 | 
						||
+GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO;
 | 
						||
+GCC_WARN_ABOUT_RETURN_TYPE = YES;
 | 
						||
+GCC_WARN_UNINITIALIZED_AUTOS = YES;
 | 
						||
+GCC_WARN_UNUSED_FUNCTION = YES
 | 
						||
+GCC_WARN_UNUSED_VARIABLE = YES
 | 
						||
+CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
 | 
						||
+GCC_WARN_UNDECLARED_SELECTOR = YES;
 | 
						||
+CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
 | 
						||
+CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
 | 
						||
+GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
 | 
						||
+WARNING_CFLAGS = -Wall -W -Wno-unused-parameter
 | 
						||
+GCC_NO_COMMON_BLOCKS = YES;
 | 
						||
+
 | 
						||
+SUPPORTED_PLATFORMS = iphoneos iphonesimulator macosx tvos tvsimulator watchos watchsimulator;
 | 
						||
+
 | 
						||
+TARGET_MAC_OS_X_VERSION_MAJOR = $(TARGET_MAC_OS_X_VERSION_MAJOR$(MACOSX_DEPLOYMENT_TARGET:suffix:identifier));
 | 
						||
+TARGET_MAC_OS_X_VERSION_MAJOR_13 = 101300;
 | 
						||
+TARGET_MAC_OS_X_VERSION_MAJOR_14 = 101400;
 | 
						||
+TARGET_MAC_OS_X_VERSION_MAJOR_15 = 101500;
 | 
						||
+TARGET_MAC_OS_X_VERSION_MAJOR_16 = 101600;
 | 
						||
+
 | 
						||
+SDKROOT = macosx.internal;
 | 
						||
+
 | 
						||
+OTHER_CFLAGS = $(ASAN_OTHER_CFLAGS);
 | 
						||
+OTHER_CPLUSPLUSFLAGS = $(ASAN_OTHER_CPLUSPLUSFLAGS);
 | 
						||
+OTHER_LDFLAGS = $(ASAN_OTHER_LDFLAGS);
 | 
						||
+
 | 
						||
+CODE_SIGN_IDENTITY = -;
 | 
						||
diff --git a/Tools/Playwright/Configurations/DebugRelease.xcconfig b/Tools/Playwright/Configurations/DebugRelease.xcconfig
 | 
						||
new file mode 100644
 | 
						||
index 0000000000000000000000000000000000000000..44dc1139c298bd119368ef4f45bbf0888dc71cdb
 | 
						||
--- /dev/null
 | 
						||
+++ b/Tools/Playwright/Configurations/DebugRelease.xcconfig
 | 
						||
@@ -0,0 +1,45 @@
 | 
						||
+// Copyright (C) 2010, 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. 
 | 
						||
+
 | 
						||
+#include "Base.xcconfig"
 | 
						||
+
 | 
						||
+ARCHS = $(ARCHS_STANDARD_32_64_BIT);
 | 
						||
+
 | 
						||
+ONLY_ACTIVE_ARCH = YES;
 | 
						||
+
 | 
						||
+TARGET_MAC_OS_X_VERSION_MAJOR = $(MAC_OS_X_VERSION_MAJOR);
 | 
						||
+
 | 
						||
+MACOSX_DEPLOYMENT_TARGET = $(MACOSX_DEPLOYMENT_TARGET_$(TARGET_MAC_OS_X_VERSION_MAJOR))
 | 
						||
+MACOSX_DEPLOYMENT_TARGET_101300 = 10.13;
 | 
						||
+MACOSX_DEPLOYMENT_TARGET_101400 = 10.14;
 | 
						||
+MACOSX_DEPLOYMENT_TARGET_101500 = 10.15;
 | 
						||
+MACOSX_DEPLOYMENT_TARGET_101600 = 10.16;
 | 
						||
+
 | 
						||
+GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = YES;
 | 
						||
+
 | 
						||
+SDKROOT = $(SDKROOT_$(USE_INTERNAL_SDK));
 | 
						||
+SDKROOT_ = macosx;
 | 
						||
+SDKROOT_YES = macosx.internal;
 | 
						||
+
 | 
						||
+WK_CCACHE_DIR = $(SRCROOT)/../ccache;
 | 
						||
+#include "../../ccache/ccache.xcconfig"
 | 
						||
diff --git a/Tools/Playwright/Configurations/Playwright.xcconfig b/Tools/Playwright/Configurations/Playwright.xcconfig
 | 
						||
new file mode 100644
 | 
						||
index 0000000000000000000000000000000000000000..d05c841a5b0f5fce481f16b8c98caf3a5846db77
 | 
						||
--- /dev/null
 | 
						||
+++ b/Tools/Playwright/Configurations/Playwright.xcconfig
 | 
						||
@@ -0,0 +1,30 @@
 | 
						||
+// Copyright (C) 2010 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. 
 | 
						||
+
 | 
						||
+PRODUCT_NAME = Playwright
 | 
						||
+PRODUCT_BUNDLE_IDENTIFIER = org.webkit.$(PRODUCT_NAME:rfc1034identifier)
 | 
						||
+GCC_PREFIX_HEADER = mac/Playwright_Prefix.pch
 | 
						||
+INFOPLIST_FILE = mac/Info.plist
 | 
						||
+EXCLUDED_SOURCE_FILE_NAMES[sdk=iphone*] = *
 | 
						||
+OTHER_LDFLAGS[sdk=macosx*] = $(inherited) -framework Cocoa -framework WebKit
 | 
						||
+STRIP_STYLE = debugging;
 | 
						||
diff --git a/Tools/Playwright/Configurations/SDKVariant.xcconfig b/Tools/Playwright/Configurations/SDKVariant.xcconfig
 | 
						||
new file mode 100644
 | 
						||
index 0000000000000000000000000000000000000000..fcdf7e65a67c61fb19ef19c428652f336c180e8e
 | 
						||
--- /dev/null
 | 
						||
+++ b/Tools/Playwright/Configurations/SDKVariant.xcconfig
 | 
						||
@@ -0,0 +1,45 @@
 | 
						||
+// Copyright (C) 2019 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.
 | 
						||
+
 | 
						||
+WK_EMPTY_ = YES;
 | 
						||
+WK_NOT_ = YES;
 | 
						||
+WK_NOT_YES = NO;
 | 
						||
+
 | 
						||
+WK_ALTERNATE_FRAMEWORKS_DIR = $(WK_ALTERNATE_FRAMEWORKS_DIR_$(SDK_VARIANT));
 | 
						||
+WK_ALTERNATE_FRAMEWORKS_DIR_iosmac = /System/iOSSupport;
 | 
						||
+WK_USE_ALTERNATE_FRAMEWORKS_DIR = $(WK_NOT_$(WK_EMPTY_$(WK_ALTERNATE_FRAMEWORKS_DIR)));
 | 
						||
+
 | 
						||
+WK_ALTERNATE_PLATFORM_NAME = $(WK_ALTERNATE_PLATFORM_NAME_$(SDK_VARIANT));
 | 
						||
+WK_ALTERNATE_PLATFORM_NAME_iosmac = maccatalyst;
 | 
						||
+WK_USE_ALTERNATE_PLATFORM_NAME = $(WK_NOT_$(WK_EMPTY_$(WK_ALTERNATE_PLATFORM_NAME)));
 | 
						||
+
 | 
						||
+WK_ALTERNATE_WEBKIT_SDK_PATH = $(WK_ALTERNATE_WEBKIT_SDK_PATH_$(WK_USE_ALTERNATE_FRAMEWORKS_DIR));
 | 
						||
+WK_ALTERNATE_WEBKIT_SDK_PATH_YES = $(WK_ALTERNATE_FRAMEWORKS_DIR)/;
 | 
						||
+
 | 
						||
+WK_PLATFORM_NAME = $(WK_PLATFORM_NAME_ALTERNATE_$(WK_USE_ALTERNATE_PLATFORM_NAME));
 | 
						||
+WK_PLATFORM_NAME_ALTERNATE_YES = $(WK_ALTERNATE_PLATFORM_NAME);
 | 
						||
+WK_PLATFORM_NAME_ALTERNATE_NO = $(PLATFORM_NAME);
 | 
						||
+
 | 
						||
+EFFECTIVE_PLATFORM_NAME = $(EFFECTIVE_PLATFORM_NAME_ALTERNATE_$(WK_USE_ALTERNATE_PLATFORM_NAME));
 | 
						||
+EFFECTIVE_PLATFORM_NAME_ALTERNATE_YES = -$(WK_ALTERNATE_PLATFORM_NAME);
 | 
						||
+EFFECTIVE_PLATFORM_NAME_ALTERNATE_NO = $(EFFECTIVE_PLATFORM_NAME);
 | 
						||
diff --git a/Tools/Playwright/MBToolbarItem.h b/Tools/Playwright/MBToolbarItem.h
 | 
						||
new file mode 100644
 | 
						||
index 0000000000000000000000000000000000000000..9971d4c1023a9f6e57c6058ae20729e51bb6d503
 | 
						||
--- /dev/null
 | 
						||
+++ b/Tools/Playwright/MBToolbarItem.h
 | 
						||
@@ -0,0 +1,27 @@
 | 
						||
+/*
 | 
						||
+ * Copyright (C) 2010 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. 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.
 | 
						||
+ */
 | 
						||
+
 | 
						||
+@interface MBToolbarItem : NSToolbarItem
 | 
						||
+@end
 | 
						||
diff --git a/Tools/Playwright/MBToolbarItem.m b/Tools/Playwright/MBToolbarItem.m
 | 
						||
new file mode 100644
 | 
						||
index 0000000000000000000000000000000000000000..56f777891519e820105ae50a86141a534ec4794b
 | 
						||
--- /dev/null
 | 
						||
+++ b/Tools/Playwright/MBToolbarItem.m
 | 
						||
@@ -0,0 +1,35 @@
 | 
						||
+/*
 | 
						||
+ * Copyright (C) 2010 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. 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.
 | 
						||
+ */
 | 
						||
+
 | 
						||
+#import "MBToolbarItem.h"
 | 
						||
+
 | 
						||
+@implementation MBToolbarItem
 | 
						||
+
 | 
						||
+- (void)validate
 | 
						||
+{
 | 
						||
+    [self setEnabled:[[self target] validateUserInterfaceItem:self]];
 | 
						||
+}
 | 
						||
+
 | 
						||
+@end
 | 
						||
diff --git a/Tools/Playwright/Makefile b/Tools/Playwright/Makefile
 | 
						||
new file mode 100644
 | 
						||
index 0000000000000000000000000000000000000000..58e52428388d927ae7681d999e6dd28e0fb3ec6b
 | 
						||
--- /dev/null
 | 
						||
+++ b/Tools/Playwright/Makefile
 | 
						||
@@ -0,0 +1,21 @@
 | 
						||
+# Build Playwright only on SnowLeopard and later.
 | 
						||
+
 | 
						||
+OSX_VERSION ?= $(shell sw_vers -productVersion | cut -d. -f 2)
 | 
						||
+BUILD_PLAYWRIGHT = $(shell (( $(OSX_VERSION) >= 6 )) && echo "YES" )
 | 
						||
+
 | 
						||
+ifeq "$(BUILD_PLAYWRIGHT)" "YES"
 | 
						||
+
 | 
						||
+SCRIPTS_PATH = ../Scripts
 | 
						||
+include ../../Makefile.shared
 | 
						||
+
 | 
						||
+else
 | 
						||
+
 | 
						||
+all: ;
 | 
						||
+
 | 
						||
+debug d development dev develop: ;
 | 
						||
+
 | 
						||
+release r deployment dep deploy: ;
 | 
						||
+
 | 
						||
+clean: ;
 | 
						||
+
 | 
						||
+endif
 | 
						||
diff --git a/Tools/Playwright/Playwright.xcodeproj/project.pbxproj b/Tools/Playwright/Playwright.xcodeproj/project.pbxproj
 | 
						||
new file mode 100644
 | 
						||
index 0000000000000000000000000000000000000000..75a945e72d9fcad94bb89fc6325df18d3259383d
 | 
						||
--- /dev/null
 | 
						||
+++ b/Tools/Playwright/Playwright.xcodeproj/project.pbxproj
 | 
						||
@@ -0,0 +1,264 @@
 | 
						||
+// !$*UTF8*$!
 | 
						||
+{
 | 
						||
+	archiveVersion = 1;
 | 
						||
+	classes = {
 | 
						||
+	};
 | 
						||
+	objectVersion = 46;
 | 
						||
+	objects = {
 | 
						||
+
 | 
						||
+/* Begin PBXBuildFile section */
 | 
						||
+		256AC3DA0F4B6AC300CF336A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 256AC3D90F4B6AC300CF336A /* AppDelegate.m */; };
 | 
						||
+		51E244FA11EFCE07008228D2 /* MBToolbarItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 51E244F911EFCE07008228D2 /* MBToolbarItem.m */; };
 | 
						||
+		BC329487116A92E2008635D1 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = BC329486116A92E2008635D1 /* main.m */; };
 | 
						||
+		BC329498116A941B008635D1 /* BrowserWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = BC329497116A941B008635D1 /* BrowserWindowController.m */; };
 | 
						||
+		BC72B89511E57E07001EB4EB /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1DDD58150DA1D0A300B3202A /* MainMenu.xib */; };
 | 
						||
+		BC72B89611E57E0F001EB4EB /* BrowserWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC3294A2116A9852008635D1 /* BrowserWindow.xib */; };
 | 
						||
+/* End PBXBuildFile section */
 | 
						||
+
 | 
						||
+/* Begin PBXFileReference section */
 | 
						||
+		1AFFEF761860EE6800DA465F /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
 | 
						||
+		1AFFEF781860EE6800DA465F /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; };
 | 
						||
+		1DDD58150DA1D0A300B3202A /* MainMenu.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = MainMenu.xib; path = mac/MainMenu.xib; sourceTree = "<group>"; };
 | 
						||
+		256AC3D80F4B6AC300CF336A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = mac/AppDelegate.h; sourceTree = "<group>"; };
 | 
						||
+		256AC3D90F4B6AC300CF336A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = mac/AppDelegate.m; sourceTree = "<group>"; };
 | 
						||
+		256AC3F00F4B6AF500CF336A /* Playwright_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Playwright_Prefix.pch; path = mac/Playwright_Prefix.pch; sourceTree = "<group>"; };
 | 
						||
+		29B97324FDCFA39411CA2CEB /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; };
 | 
						||
+		29B97325FDCFA39411CA2CEB /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
 | 
						||
+		37BAF90620218053000EA87A /* Playwright.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Playwright.entitlements; sourceTree = "<group>"; };
 | 
						||
+		51E244F811EFCE07008228D2 /* MBToolbarItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MBToolbarItem.h; sourceTree = "<group>"; };
 | 
						||
+		51E244F911EFCE07008228D2 /* MBToolbarItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MBToolbarItem.m; sourceTree = "<group>"; };
 | 
						||
+		8D1107320486CEB800E47091 /* Playwright.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Playwright.app; sourceTree = BUILT_PRODUCTS_DIR; };
 | 
						||
+		A1B89B95221E027A00EB4CEB /* SDKVariant.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = SDKVariant.xcconfig; sourceTree = "<group>"; };
 | 
						||
+		BC329486116A92E2008635D1 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = mac/main.m; sourceTree = "<group>"; };
 | 
						||
+		BC329496116A941B008635D1 /* BrowserWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BrowserWindowController.h; path = mac/BrowserWindowController.h; sourceTree = "<group>"; };
 | 
						||
+		BC329497116A941B008635D1 /* BrowserWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BrowserWindowController.m; path = mac/BrowserWindowController.m; sourceTree = "<group>"; };
 | 
						||
+		BC3294A2116A9852008635D1 /* BrowserWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = BrowserWindow.xib; path = mac/BrowserWindow.xib; sourceTree = "<group>"; };
 | 
						||
+		BC72B89A11E57E8A001EB4EB /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = mac/Info.plist; sourceTree = "<group>"; };
 | 
						||
+		BCA8CBDD11E578A000812FB8 /* Base.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Base.xcconfig; sourceTree = "<group>"; };
 | 
						||
+		BCA8CBDE11E578A000812FB8 /* DebugRelease.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = DebugRelease.xcconfig; sourceTree = "<group>"; };
 | 
						||
+		BCA8CBDF11E578A000812FB8 /* Playwright.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Playwright.xcconfig; sourceTree = "<group>"; };
 | 
						||
+/* End PBXFileReference section */
 | 
						||
+
 | 
						||
+/* Begin PBXFrameworksBuildPhase section */
 | 
						||
+		8D11072E0486CEB800E47091 /* Frameworks */ = {
 | 
						||
+			isa = PBXFrameworksBuildPhase;
 | 
						||
+			buildActionMask = 2147483647;
 | 
						||
+			files = (
 | 
						||
+			);
 | 
						||
+			runOnlyForDeploymentPostprocessing = 0;
 | 
						||
+		};
 | 
						||
+/* End PBXFrameworksBuildPhase section */
 | 
						||
+
 | 
						||
+/* Begin PBXGroup section */
 | 
						||
+		080E96DDFE201D6D7F000002 /* Playwright */ = {
 | 
						||
+			isa = PBXGroup;
 | 
						||
+			children = (
 | 
						||
+				256AC3D80F4B6AC300CF336A /* AppDelegate.h */,
 | 
						||
+				256AC3D90F4B6AC300CF336A /* AppDelegate.m */,
 | 
						||
+				BC72B89A11E57E8A001EB4EB /* Info.plist */,
 | 
						||
+				BC329486116A92E2008635D1 /* main.m */,
 | 
						||
+				51E244F811EFCE07008228D2 /* MBToolbarItem.h */,
 | 
						||
+				51E244F911EFCE07008228D2 /* MBToolbarItem.m */,
 | 
						||
+				37BAF90620218053000EA87A /* Playwright.entitlements */,
 | 
						||
+				BC329496116A941B008635D1 /* BrowserWindowController.h */,
 | 
						||
+				BC329497116A941B008635D1 /* BrowserWindowController.m */,
 | 
						||
+			);
 | 
						||
+			name = Playwright;
 | 
						||
+			sourceTree = "<group>";
 | 
						||
+		};
 | 
						||
+		1058C7A2FEA54F0111CA2CBC /* Other Frameworks */ = {
 | 
						||
+			isa = PBXGroup;
 | 
						||
+			children = (
 | 
						||
+				29B97324FDCFA39411CA2CEB /* AppKit.framework */,
 | 
						||
+				1AFFEF781860EE6800DA465F /* CoreData.framework */,
 | 
						||
+				29B97325FDCFA39411CA2CEB /* Foundation.framework */,
 | 
						||
+			);
 | 
						||
+			name = "Other Frameworks";
 | 
						||
+			sourceTree = "<group>";
 | 
						||
+		};
 | 
						||
+		19C28FACFE9D520D11CA2CBC /* Products */ = {
 | 
						||
+			isa = PBXGroup;
 | 
						||
+			children = (
 | 
						||
+				8D1107320486CEB800E47091 /* Playwright.app */,
 | 
						||
+			);
 | 
						||
+			name = Products;
 | 
						||
+			sourceTree = "<group>";
 | 
						||
+		};
 | 
						||
+		29B97314FDCFA39411CA2CEB /* Playwright */ = {
 | 
						||
+			isa = PBXGroup;
 | 
						||
+			children = (
 | 
						||
+				256AC3F00F4B6AF500CF336A /* Playwright_Prefix.pch */,
 | 
						||
+				080E96DDFE201D6D7F000002 /* Playwright */,
 | 
						||
+				29B97317FDCFA39411CA2CEB /* Resources */,
 | 
						||
+				BCA8CBDA11E5787800812FB8 /* Configurations */,
 | 
						||
+				29B97323FDCFA39411CA2CEB /* Frameworks */,
 | 
						||
+				19C28FACFE9D520D11CA2CBC /* Products */,
 | 
						||
+			);
 | 
						||
+			name = Playwright;
 | 
						||
+			sourceTree = "<group>";
 | 
						||
+		};
 | 
						||
+		29B97317FDCFA39411CA2CEB /* Resources */ = {
 | 
						||
+			isa = PBXGroup;
 | 
						||
+			children = (
 | 
						||
+				BC3294A2116A9852008635D1 /* BrowserWindow.xib */,
 | 
						||
+				1DDD58150DA1D0A300B3202A /* MainMenu.xib */,
 | 
						||
+			);
 | 
						||
+			name = Resources;
 | 
						||
+			sourceTree = "<group>";
 | 
						||
+		};
 | 
						||
+		29B97323FDCFA39411CA2CEB /* Frameworks */ = {
 | 
						||
+			isa = PBXGroup;
 | 
						||
+			children = (
 | 
						||
+				1058C7A2FEA54F0111CA2CBC /* Other Frameworks */,
 | 
						||
+				1AFFEF761860EE6800DA465F /* Cocoa.framework */,
 | 
						||
+			);
 | 
						||
+			name = Frameworks;
 | 
						||
+			sourceTree = "<group>";
 | 
						||
+		};
 | 
						||
+		BCA8CBDA11E5787800812FB8 /* Configurations */ = {
 | 
						||
+			isa = PBXGroup;
 | 
						||
+			children = (
 | 
						||
+				BCA8CBDD11E578A000812FB8 /* Base.xcconfig */,
 | 
						||
+				BCA8CBDE11E578A000812FB8 /* DebugRelease.xcconfig */,
 | 
						||
+				BCA8CBDF11E578A000812FB8 /* Playwright.xcconfig */,
 | 
						||
+				A1B89B95221E027A00EB4CEB /* SDKVariant.xcconfig */,
 | 
						||
+			);
 | 
						||
+			path = Configurations;
 | 
						||
+			sourceTree = "<group>";
 | 
						||
+		};
 | 
						||
+/* End PBXGroup section */
 | 
						||
+
 | 
						||
+/* Begin PBXNativeTarget section */
 | 
						||
+		8D1107260486CEB800E47091 /* Playwright */ = {
 | 
						||
+			isa = PBXNativeTarget;
 | 
						||
+			buildConfigurationList = C01FCF4A08A954540054247C /* Build configuration list for PBXNativeTarget "Playwright" */;
 | 
						||
+			buildPhases = (
 | 
						||
+				8D1107290486CEB800E47091 /* Resources */,
 | 
						||
+				8D11072C0486CEB800E47091 /* Sources */,
 | 
						||
+				8D11072E0486CEB800E47091 /* Frameworks */,
 | 
						||
+			);
 | 
						||
+			buildRules = (
 | 
						||
+			);
 | 
						||
+			dependencies = (
 | 
						||
+			);
 | 
						||
+			name = Playwright;
 | 
						||
+			productInstallPath = "$(HOME)/Applications";
 | 
						||
+			productName = Playwright;
 | 
						||
+			productReference = 8D1107320486CEB800E47091 /* Playwright.app */;
 | 
						||
+			productType = "com.apple.product-type.application";
 | 
						||
+		};
 | 
						||
+/* End PBXNativeTarget section */
 | 
						||
+
 | 
						||
+/* Begin PBXProject section */
 | 
						||
+		29B97313FDCFA39411CA2CEC /* Project object */ = {
 | 
						||
+			isa = PBXProject;
 | 
						||
+			attributes = {
 | 
						||
+				LastSwiftUpdateCheck = 0700;
 | 
						||
+				LastUpgradeCheck = 1000;
 | 
						||
+				TargetAttributes = {
 | 
						||
+					8D1107260486CEB800E47091 = {
 | 
						||
+						SystemCapabilities = {
 | 
						||
+							com.apple.Sandbox = {
 | 
						||
+								enabled = 1;
 | 
						||
+							};
 | 
						||
+						};
 | 
						||
+					};
 | 
						||
+				};
 | 
						||
+			};
 | 
						||
+			buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Playwright" */;
 | 
						||
+			compatibilityVersion = "Xcode 3.2";
 | 
						||
+			developmentRegion = en;
 | 
						||
+			hasScannedForEncodings = 1;
 | 
						||
+			knownRegions = (
 | 
						||
+				en,
 | 
						||
+			);
 | 
						||
+			mainGroup = 29B97314FDCFA39411CA2CEB /* Playwright */;
 | 
						||
+			projectDirPath = "";
 | 
						||
+			projectRoot = "";
 | 
						||
+			targets = (
 | 
						||
+				8D1107260486CEB800E47091 /* Playwright */,
 | 
						||
+			);
 | 
						||
+		};
 | 
						||
+/* End PBXProject section */
 | 
						||
+
 | 
						||
+/* Begin PBXResourcesBuildPhase section */
 | 
						||
+		8D1107290486CEB800E47091 /* Resources */ = {
 | 
						||
+			isa = PBXResourcesBuildPhase;
 | 
						||
+			buildActionMask = 2147483647;
 | 
						||
+			files = (
 | 
						||
+				BC72B89611E57E0F001EB4EB /* BrowserWindow.xib in Resources */,
 | 
						||
+				BC72B89511E57E07001EB4EB /* MainMenu.xib in Resources */,
 | 
						||
+			);
 | 
						||
+			runOnlyForDeploymentPostprocessing = 0;
 | 
						||
+		};
 | 
						||
+/* End PBXResourcesBuildPhase section */
 | 
						||
+
 | 
						||
+/* Begin PBXSourcesBuildPhase section */
 | 
						||
+		8D11072C0486CEB800E47091 /* Sources */ = {
 | 
						||
+			isa = PBXSourcesBuildPhase;
 | 
						||
+			buildActionMask = 2147483647;
 | 
						||
+			files = (
 | 
						||
+				256AC3DA0F4B6AC300CF336A /* AppDelegate.m in Sources */,
 | 
						||
+				BC329487116A92E2008635D1 /* main.m in Sources */,
 | 
						||
+				51E244FA11EFCE07008228D2 /* MBToolbarItem.m in Sources */,
 | 
						||
+				BC329498116A941B008635D1 /* BrowserWindowController.m in Sources */,
 | 
						||
+			);
 | 
						||
+			runOnlyForDeploymentPostprocessing = 0;
 | 
						||
+		};
 | 
						||
+/* End PBXSourcesBuildPhase section */
 | 
						||
+
 | 
						||
+/* Begin XCBuildConfiguration section */
 | 
						||
+		C01FCF4B08A954540054247C /* Debug */ = {
 | 
						||
+			isa = XCBuildConfiguration;
 | 
						||
+			baseConfigurationReference = BCA8CBDF11E578A000812FB8 /* Playwright.xcconfig */;
 | 
						||
+			buildSettings = {
 | 
						||
+			};
 | 
						||
+			name = Debug;
 | 
						||
+		};
 | 
						||
+		C01FCF4C08A954540054247B /* Release */ = {
 | 
						||
+			isa = XCBuildConfiguration;
 | 
						||
+			baseConfigurationReference = BCA8CBDF11E578A000812FB8 /* Playwright.xcconfig */;
 | 
						||
+			buildSettings = {
 | 
						||
+			};
 | 
						||
+			name = Release;
 | 
						||
+		};
 | 
						||
+		C01FCF4F08A954540054247C /* Debug */ = {
 | 
						||
+			isa = XCBuildConfiguration;
 | 
						||
+			baseConfigurationReference = BCA8CBDE11E578A000812FB8 /* DebugRelease.xcconfig */;
 | 
						||
+			buildSettings = {
 | 
						||
+				GCC_OPTIMIZATION_LEVEL = 0;
 | 
						||
+			};
 | 
						||
+			name = Debug;
 | 
						||
+		};
 | 
						||
+		C01FCF5008A954540054247C /* Release */ = {
 | 
						||
+			isa = XCBuildConfiguration;
 | 
						||
+			baseConfigurationReference = BCA8CBDE11E578A000812FB8 /* DebugRelease.xcconfig */;
 | 
						||
+			buildSettings = {
 | 
						||
+			};
 | 
						||
+			name = Release;
 | 
						||
+		};
 | 
						||
+/* End XCBuildConfiguration section */
 | 
						||
+
 | 
						||
+/* Begin XCConfigurationList section */
 | 
						||
+		C01FCF4A08A954540054247C /* Build configuration list for PBXNativeTarget "Playwright" */ = {
 | 
						||
+			isa = XCConfigurationList;
 | 
						||
+			buildConfigurations = (
 | 
						||
+				C01FCF4B08A954540054247C /* Debug */,
 | 
						||
+				C01FCF4C08A954540054247B /* Release */,
 | 
						||
+			);
 | 
						||
+			defaultConfigurationIsVisible = 0;
 | 
						||
+			defaultConfigurationName = Release;
 | 
						||
+		};
 | 
						||
+		C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Playwright" */ = {
 | 
						||
+			isa = XCConfigurationList;
 | 
						||
+			buildConfigurations = (
 | 
						||
+				C01FCF4F08A954540054247C /* Debug */,
 | 
						||
+				C01FCF5008A954540054247C /* Release */,
 | 
						||
+			);
 | 
						||
+			defaultConfigurationIsVisible = 0;
 | 
						||
+			defaultConfigurationName = Release;
 | 
						||
+		};
 | 
						||
+/* End XCConfigurationList section */
 | 
						||
+	};
 | 
						||
+	rootObject = 29B97313FDCFA39411CA2CEC /* Project object */;
 | 
						||
+}
 | 
						||
diff --git a/Tools/Playwright/Playwright.xcodeproj/xcshareddata/xcschemes/Playwright.xcscheme b/Tools/Playwright/Playwright.xcodeproj/xcshareddata/xcschemes/Playwright.xcscheme
 | 
						||
new file mode 100644
 | 
						||
index 0000000000000000000000000000000000000000..00fb6b0006c743091a8bbf8edb18b21192ea7d6c
 | 
						||
--- /dev/null
 | 
						||
+++ b/Tools/Playwright/Playwright.xcodeproj/xcshareddata/xcschemes/Playwright.xcscheme
 | 
						||
@@ -0,0 +1,78 @@
 | 
						||
+<?xml version="1.0" encoding="UTF-8"?>
 | 
						||
+<Scheme
 | 
						||
+   LastUpgradeVersion = "1140"
 | 
						||
+   version = "1.3">
 | 
						||
+   <BuildAction
 | 
						||
+      parallelizeBuildables = "YES"
 | 
						||
+      buildImplicitDependencies = "YES">
 | 
						||
+      <BuildActionEntries>
 | 
						||
+         <BuildActionEntry
 | 
						||
+            buildForTesting = "YES"
 | 
						||
+            buildForRunning = "YES"
 | 
						||
+            buildForProfiling = "YES"
 | 
						||
+            buildForArchiving = "YES"
 | 
						||
+            buildForAnalyzing = "YES">
 | 
						||
+            <BuildableReference
 | 
						||
+               BuildableIdentifier = "primary"
 | 
						||
+               BlueprintIdentifier = "8D1107260486CEB800E47090"
 | 
						||
+               BuildableName = "Playwright.app"
 | 
						||
+               BlueprintName = "Playwright"
 | 
						||
+               ReferencedContainer = "container:Playwright.xcodeproj">
 | 
						||
+            </BuildableReference>
 | 
						||
+         </BuildActionEntry>
 | 
						||
+      </BuildActionEntries>
 | 
						||
+   </BuildAction>
 | 
						||
+   <TestAction
 | 
						||
+      buildConfiguration = "Debug"
 | 
						||
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
 | 
						||
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
 | 
						||
+      shouldUseLaunchSchemeArgsEnv = "YES">
 | 
						||
+      <Testables>
 | 
						||
+      </Testables>
 | 
						||
+   </TestAction>
 | 
						||
+   <LaunchAction
 | 
						||
+      buildConfiguration = "Debug"
 | 
						||
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
 | 
						||
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
 | 
						||
+      launchStyle = "0"
 | 
						||
+      useCustomWorkingDirectory = "NO"
 | 
						||
+      ignoresPersistentStateOnLaunch = "NO"
 | 
						||
+      debugDocumentVersioning = "YES"
 | 
						||
+      debugServiceExtension = "internal"
 | 
						||
+      allowLocationSimulation = "YES">
 | 
						||
+      <BuildableProductRunnable
 | 
						||
+         runnableDebuggingMode = "0">
 | 
						||
+         <BuildableReference
 | 
						||
+            BuildableIdentifier = "primary"
 | 
						||
+            BlueprintIdentifier = "8D1107260486CEB800E47090"
 | 
						||
+            BuildableName = "Playwright.app"
 | 
						||
+            BlueprintName = "Playwright"
 | 
						||
+            ReferencedContainer = "container:Playwright.xcodeproj">
 | 
						||
+         </BuildableReference>
 | 
						||
+      </BuildableProductRunnable>
 | 
						||
+   </LaunchAction>
 | 
						||
+   <ProfileAction
 | 
						||
+      buildConfiguration = "Release"
 | 
						||
+      shouldUseLaunchSchemeArgsEnv = "YES"
 | 
						||
+      savedToolIdentifier = ""
 | 
						||
+      useCustomWorkingDirectory = "NO"
 | 
						||
+      debugDocumentVersioning = "YES">
 | 
						||
+      <BuildableProductRunnable
 | 
						||
+         runnableDebuggingMode = "0">
 | 
						||
+         <BuildableReference
 | 
						||
+            BuildableIdentifier = "primary"
 | 
						||
+            BlueprintIdentifier = "8D1107260486CEB800E47090"
 | 
						||
+            BuildableName = "Playwright.app"
 | 
						||
+            BlueprintName = "Playwright"
 | 
						||
+            ReferencedContainer = "container:Playwright.xcodeproj">
 | 
						||
+         </BuildableReference>
 | 
						||
+      </BuildableProductRunnable>
 | 
						||
+   </ProfileAction>
 | 
						||
+   <AnalyzeAction
 | 
						||
+      buildConfiguration = "Debug">
 | 
						||
+   </AnalyzeAction>
 | 
						||
+   <ArchiveAction
 | 
						||
+      buildConfiguration = "Release"
 | 
						||
+      revealArchiveInOrganizer = "YES">
 | 
						||
+   </ArchiveAction>
 | 
						||
+</Scheme>
 | 
						||
diff --git a/Tools/Playwright/mac/AppDelegate.h b/Tools/Playwright/mac/AppDelegate.h
 | 
						||
new file mode 100644
 | 
						||
index 0000000000000000000000000000000000000000..86e7b0c64df5fccdd66b87eecd995e0a10d57b83
 | 
						||
--- /dev/null
 | 
						||
+++ b/Tools/Playwright/mac/AppDelegate.h
 | 
						||
@@ -0,0 +1,53 @@
 | 
						||
+/*
 | 
						||
+ * Copyright (C) 2010 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. 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.
 | 
						||
+ */
 | 
						||
+
 | 
						||
+#import <WebKit/_WKBrowserInspector.h>
 | 
						||
+
 | 
						||
+@interface WebViewDialog : NSObject
 | 
						||
+@property (nonatomic, strong) WKWebView *webView;
 | 
						||
+@property (nonatomic, copy) void (^completionHandler)(BOOL accept, NSString* value);
 | 
						||
+@end
 | 
						||
+
 | 
						||
+@interface BrowserAppDelegate : NSObject <NSApplicationDelegate, WKUIDelegate, _WKBrowserInspectorDelegate> {
 | 
						||
+    NSMutableSet *_browserWindowControllers;
 | 
						||
+    NSMutableSet *_headlessWindows;
 | 
						||
+    NSMutableSet *_browserContexts;
 | 
						||
+    bool _headless;
 | 
						||
+    bool _noStartupWindow;
 | 
						||
+    NSMutableSet *_dialogs;
 | 
						||
+    NSString* _initialURL;
 | 
						||
+    NSString* _userDataDir;
 | 
						||
+    IBOutlet NSMenuItem *_newWebKit2WindowItem;
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (void)browserWindowWillClose:(NSWindow *)window;
 | 
						||
+
 | 
						||
+@end
 | 
						||
+
 | 
						||
+@interface NSApplication (PlaywrightApplicationExtensions)
 | 
						||
+
 | 
						||
+- (BrowserAppDelegate *)browserAppDelegate;
 | 
						||
+
 | 
						||
+@end
 | 
						||
diff --git a/Tools/Playwright/mac/AppDelegate.m b/Tools/Playwright/mac/AppDelegate.m
 | 
						||
new file mode 100644
 | 
						||
index 0000000000000000000000000000000000000000..144bb42f13cc92a5ddd91417cbef2512613bd27c
 | 
						||
--- /dev/null
 | 
						||
+++ b/Tools/Playwright/mac/AppDelegate.m
 | 
						||
@@ -0,0 +1,401 @@
 | 
						||
+/*
 | 
						||
+ * Copyright (C) 2010-2016 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. 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.
 | 
						||
+ */
 | 
						||
+
 | 
						||
+#import "AppDelegate.h"
 | 
						||
+
 | 
						||
+#import "BrowserWindowController.h"
 | 
						||
+#import <WebKit/WKPreferencesPrivate.h>
 | 
						||
+#import <WebKit/WKProcessPoolPrivate.h>
 | 
						||
+#import <WebKit/WKUserContentControllerPrivate.h>
 | 
						||
+#import <WebKit/WKWebViewConfigurationPrivate.h>
 | 
						||
+#import <WebKit/WKWebViewPrivate.h>
 | 
						||
+#import <WebKit/WKWebsiteDataStorePrivate.h>
 | 
						||
+#import <WebKit/WebNSURLExtras.h>
 | 
						||
+#import <WebKit/WebKit.h>
 | 
						||
+#import <WebKit/_WKExperimentalFeature.h>
 | 
						||
+#import <WebKit/_WKInternalDebugFeature.h>
 | 
						||
+#import <WebKit/_WKProcessPoolConfiguration.h>
 | 
						||
+#import <WebKit/_WKWebsiteDataStoreConfiguration.h>
 | 
						||
+
 | 
						||
+@implementation NSApplication (PlaywrightApplicationExtensions)
 | 
						||
+
 | 
						||
+- (BrowserAppDelegate *)browserAppDelegate
 | 
						||
+{
 | 
						||
+    return (BrowserAppDelegate *)[self delegate];
 | 
						||
+}
 | 
						||
+
 | 
						||
+@end
 | 
						||
+
 | 
						||
+@interface NSApplication (TouchBar)
 | 
						||
+@property (getter=isAutomaticCustomizeTouchBarMenuItemEnabled) BOOL automaticCustomizeTouchBarMenuItemEnabled;
 | 
						||
+
 | 
						||
+@property (readonly, nonatomic) WKWebViewConfiguration *defaultConfiguration;
 | 
						||
+
 | 
						||
+@end
 | 
						||
+
 | 
						||
+@implementation WebViewDialog
 | 
						||
+- (void)dealloc
 | 
						||
+{
 | 
						||
+    [_webView release];
 | 
						||
+    _webView = nil;
 | 
						||
+    [super dealloc];
 | 
						||
+}
 | 
						||
+@end
 | 
						||
+
 | 
						||
+enum {
 | 
						||
+    _NSBackingStoreUnbuffered = 3
 | 
						||
+};
 | 
						||
+
 | 
						||
+NSString* const ActivityReason = @"Batch headless process";
 | 
						||
+const NSActivityOptions ActivityOptions =
 | 
						||
+    (NSActivityUserInitiatedAllowingIdleSystemSleep |
 | 
						||
+     NSActivityLatencyCritical) &
 | 
						||
+    ~(NSActivitySuddenTerminationDisabled |
 | 
						||
+    NSActivityAutomaticTerminationDisabled);
 | 
						||
+
 | 
						||
+@implementation BrowserAppDelegate
 | 
						||
+
 | 
						||
+- (id)init
 | 
						||
+{
 | 
						||
+    self = [super init];
 | 
						||
+    if (!self)
 | 
						||
+        return nil;
 | 
						||
+
 | 
						||
+    _initialURL = nil;
 | 
						||
+    _userDataDir = nil;
 | 
						||
+    NSArray *arguments = [[NSProcessInfo processInfo] arguments];
 | 
						||
+    NSRange subargs = NSMakeRange(1, [arguments count] - 1);
 | 
						||
+    NSArray *subArray = [arguments subarrayWithRange:subargs];
 | 
						||
+
 | 
						||
+    for (NSString *argument in subArray) {
 | 
						||
+        if (![argument hasPrefix:@"--"])
 | 
						||
+            _initialURL = argument;
 | 
						||
+        if ([argument hasPrefix:@"--user-data-dir="]) {
 | 
						||
+            NSRange range = NSMakeRange(16, [argument length] - 16);
 | 
						||
+            _userDataDir = [[argument substringWithRange:range] copy];
 | 
						||
+        }
 | 
						||
+    }
 | 
						||
+
 | 
						||
+    _headless = [arguments containsObject: @"--headless"];
 | 
						||
+    _noStartupWindow = [arguments containsObject: @"--no-startup-window"];
 | 
						||
+    _browserContexts = [[NSMutableSet alloc] init];
 | 
						||
+
 | 
						||
+    if (_headless) {
 | 
						||
+        _headlessWindows = [[NSMutableSet alloc] init];
 | 
						||
+        [NSApp setActivationPolicy:NSApplicationActivationPolicyAccessory];
 | 
						||
+        [[NSProcessInfo processInfo] beginActivityWithOptions:ActivityOptions
 | 
						||
+                                                       reason:ActivityReason];
 | 
						||
+        _dialogs = [[NSMutableSet alloc] init];
 | 
						||
+    } else {
 | 
						||
+        [NSApp activateIgnoringOtherApps:YES];
 | 
						||
+        _browserWindowControllers = [[NSMutableSet alloc] init];
 | 
						||
+    }
 | 
						||
+    if ([arguments containsObject: @"--inspector-pipe"])
 | 
						||
+        [_WKBrowserInspector initializeRemoteInspectorPipe:self headless:_headless];
 | 
						||
+    return self;
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (void)awakeFromNib
 | 
						||
+{
 | 
						||
+    if ([NSApp respondsToSelector:@selector(setAutomaticCustomizeTouchBarMenuItemEnabled:)])
 | 
						||
+        [NSApp setAutomaticCustomizeTouchBarMenuItemEnabled:YES];
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (WKWebsiteDataStore *)persistentDataStore
 | 
						||
+{
 | 
						||
+    static WKWebsiteDataStore *dataStore;
 | 
						||
+
 | 
						||
+    if (!dataStore) {
 | 
						||
+        _WKWebsiteDataStoreConfiguration *configuration = [[[_WKWebsiteDataStoreConfiguration alloc] init] autorelease];
 | 
						||
+        if (_userDataDir) {
 | 
						||
+            NSURL *cookieFile = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/cookie.db", _userDataDir]];
 | 
						||
+            [configuration _setCookieStorageFile:cookieFile];
 | 
						||
+
 | 
						||
+            NSURL *applicationCacheDirectory = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/ApplicationCache", _userDataDir]];
 | 
						||
+            [configuration setApplicationCacheDirectory:applicationCacheDirectory];
 | 
						||
+
 | 
						||
+            NSURL *cacheStorageDirectory = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/CacheStorage", _userDataDir]];
 | 
						||
+            [configuration _setCacheStorageDirectory:cacheStorageDirectory];
 | 
						||
+
 | 
						||
+            NSURL *indexedDBDirectory = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/IndexedDB", _userDataDir]];
 | 
						||
+            [configuration _setIndexedDBDatabaseDirectory:indexedDBDirectory];
 | 
						||
+
 | 
						||
+            NSURL *localStorageDirectory = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/LocalStorage", _userDataDir]];
 | 
						||
+            [configuration _setWebStorageDirectory:localStorageDirectory];
 | 
						||
+
 | 
						||
+            NSURL *mediaCacheDirectory = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/MediaCache", _userDataDir]];
 | 
						||
+            [configuration setMediaCacheDirectory:mediaCacheDirectory];
 | 
						||
+
 | 
						||
+            NSURL *mediaKeysDirectory = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/MediaKeys", _userDataDir]];
 | 
						||
+            [configuration setMediaKeysStorageDirectory:mediaKeysDirectory];
 | 
						||
+
 | 
						||
+            NSURL *networkCacheDirectory = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/NetworkCache", _userDataDir]];
 | 
						||
+            [configuration setNetworkCacheDirectory:networkCacheDirectory];
 | 
						||
+
 | 
						||
+            NSURL *loadStatsDirectory = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/ResourceLoadStatistics", _userDataDir]];
 | 
						||
+            [configuration _setResourceLoadStatisticsDirectory:loadStatsDirectory];
 | 
						||
+
 | 
						||
+            NSURL *serviceWorkersDirectory = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/ServiceWorkers", _userDataDir]];
 | 
						||
+            [configuration _setServiceWorkerRegistrationDirectory:serviceWorkersDirectory];
 | 
						||
+
 | 
						||
+            NSURL *webSqlDirectory = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/WebSQL", _userDataDir]];
 | 
						||
+            [configuration _setWebSQLDatabaseDirectory:webSqlDirectory];
 | 
						||
+        }
 | 
						||
+        dataStore = [[WKWebsiteDataStore alloc] _initWithConfiguration:configuration];
 | 
						||
+    }
 | 
						||
+
 | 
						||
+    return dataStore;
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (WKWebViewConfiguration *)defaultConfiguration
 | 
						||
+{
 | 
						||
+    static WKWebViewConfiguration *configuration;
 | 
						||
+
 | 
						||
+    if (!configuration) {
 | 
						||
+        configuration = [[WKWebViewConfiguration alloc] init];
 | 
						||
+        configuration.websiteDataStore = [self persistentDataStore];
 | 
						||
+        configuration.preferences._fullScreenEnabled = YES;
 | 
						||
+        configuration.preferences._developerExtrasEnabled = YES;
 | 
						||
+        configuration.preferences._mediaDevicesEnabled = YES;
 | 
						||
+        configuration.preferences._mockCaptureDevicesEnabled = YES;
 | 
						||
+        configuration.preferences._hiddenPageDOMTimerThrottlingEnabled = NO;
 | 
						||
+        configuration.preferences._hiddenPageDOMTimerThrottlingAutoIncreases = NO;
 | 
						||
+        configuration.preferences._pageVisibilityBasedProcessSuppressionEnabled = NO;
 | 
						||
+        configuration.preferences._domTimersThrottlingEnabled = NO;
 | 
						||
+        configuration.preferences._requestAnimationFrameEnabled = YES;
 | 
						||
+        _WKProcessPoolConfiguration *processConfiguration = [[[_WKProcessPoolConfiguration alloc] init] autorelease];
 | 
						||
+        processConfiguration.forceOverlayScrollbars = YES;
 | 
						||
+        configuration.processPool = [[[WKProcessPool alloc] _initWithConfiguration:processConfiguration AndDataStore:configuration.websiteDataStore] autorelease];
 | 
						||
+    }
 | 
						||
+    return configuration;
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (BrowserWindowController *)createBrowserWindowController:(id)sender
 | 
						||
+{
 | 
						||
+    if (_headless)
 | 
						||
+        return nil;
 | 
						||
+
 | 
						||
+    BrowserWindowController *controller = [[[BrowserWindowController alloc] initWithConfiguration:[self defaultConfiguration]] autorelease];
 | 
						||
+    if (!controller)
 | 
						||
+        return nil;
 | 
						||
+    [_browserWindowControllers addObject:controller];
 | 
						||
+    return controller;
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (void)browserWindowWillClose:(NSWindow *)window
 | 
						||
+{
 | 
						||
+    [_browserWindowControllers removeObject:window.windowController];
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
 | 
						||
+{
 | 
						||
+    if (!_headless)
 | 
						||
+        [self _updateNewWindowKeyEquivalents];
 | 
						||
+
 | 
						||
+    if (_noStartupWindow)
 | 
						||
+        return;
 | 
						||
+
 | 
						||
+    [self createNewPage:0];
 | 
						||
+    _initialURL = nil;
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (BrowserWindowController *)frontmostBrowserWindowController
 | 
						||
+{
 | 
						||
+    for (NSWindow* window in [NSApp windows]) {
 | 
						||
+        id delegate = [window delegate];
 | 
						||
+
 | 
						||
+        if (![delegate isKindOfClass:[BrowserWindowController class]])
 | 
						||
+            continue;
 | 
						||
+
 | 
						||
+        BrowserWindowController *controller = (BrowserWindowController *)delegate;
 | 
						||
+        assert([_browserWindowControllers containsObject:controller]);
 | 
						||
+        return controller;
 | 
						||
+    }
 | 
						||
+
 | 
						||
+    return nil;
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (void)_updateNewWindowKeyEquivalents
 | 
						||
+{
 | 
						||
+    NSString *normalWindowEquivalent = @"n";
 | 
						||
+    _newWebKit2WindowItem.keyEquivalentModifierMask = NSEventModifierFlagCommand;
 | 
						||
+    _newWebKit2WindowItem.keyEquivalent = normalWindowEquivalent;
 | 
						||
+}
 | 
						||
+
 | 
						||
+#pragma mark WKBrowserInspectorDelegate
 | 
						||
+
 | 
						||
+- (WKWebViewConfiguration *) sessionConfiguration:(uint64_t)sessionID
 | 
						||
+{
 | 
						||
+    for (_WKBrowserContext *browserContext in _browserContexts) {
 | 
						||
+        if ([[browserContext dataStore] sessionID] != sessionID)
 | 
						||
+            continue;
 | 
						||
+        WKWebViewConfiguration *configuration = [[[self defaultConfiguration] copy] autorelease];
 | 
						||
+        configuration.websiteDataStore = [browserContext dataStore];
 | 
						||
+        configuration.processPool = [browserContext processPool];
 | 
						||
+        return configuration;
 | 
						||
+    }
 | 
						||
+    return [self defaultConfiguration];
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (WKWebView *)createNewPage:(uint64_t)sessionID
 | 
						||
+{
 | 
						||
+    NSString* urlString = _initialURL ? _initialURL : @"about:blank";
 | 
						||
+    WKWebViewConfiguration *configuration = [self sessionConfiguration:sessionID];
 | 
						||
+    if (_headless)
 | 
						||
+        return [self createHeadlessPage:configuration withURL:urlString];
 | 
						||
+    return [self createHeadfulPage:configuration withURL:urlString];
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (WKWebView *)createHeadfulPage:(WKWebViewConfiguration *)configuration withURL:(NSString*)urlString
 | 
						||
+{
 | 
						||
+
 | 
						||
+    BrowserWindowController *controller = [[[BrowserWindowController alloc] initWithConfiguration:configuration] autorelease];
 | 
						||
+    if (!controller)
 | 
						||
+        return nil;
 | 
						||
+    [[controller window] makeKeyAndOrderFront:nil];
 | 
						||
+    [_browserWindowControllers addObject:controller];
 | 
						||
+    [controller loadURLString:urlString];
 | 
						||
+    return [controller webView];
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (WKWebView *)createHeadlessPage:(WKWebViewConfiguration *)configuration withURL:(NSString*)urlString
 | 
						||
+{
 | 
						||
+    NSRect rect = NSMakeRect(0, 0, 1024, 768);
 | 
						||
+    NSScreen *firstScreen = [[NSScreen screens] objectAtIndex:0];
 | 
						||
+    NSRect windowRect = NSOffsetRect(rect, -10000, [firstScreen frame].size.height - rect.size.height + 10000);
 | 
						||
+    NSWindow* window = [[NSWindow alloc] initWithContentRect:windowRect styleMask:NSWindowStyleMaskBorderless backing:(NSBackingStoreType)_NSBackingStoreUnbuffered defer:YES];
 | 
						||
+
 | 
						||
+    WKWebView* webView = [[WKWebView alloc] initWithFrame:[window.contentView bounds] configuration:configuration];
 | 
						||
+    webView._windowOcclusionDetectionEnabled = NO;
 | 
						||
+    if (!webView)
 | 
						||
+        return nil;
 | 
						||
+
 | 
						||
+    webView.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
 | 
						||
+    [window.contentView addSubview:webView];
 | 
						||
+    if (urlString) {
 | 
						||
+        NSURL *url = [NSURL _webkit_URLWithUserTypedString:urlString];
 | 
						||
+        [webView loadRequest:[NSURLRequest requestWithURL:url]];
 | 
						||
+    }
 | 
						||
+    [_headlessWindows addObject:window];
 | 
						||
+    webView.UIDelegate = self;
 | 
						||
+    return [webView autorelease];
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (_WKBrowserContext *)createBrowserContext
 | 
						||
+{
 | 
						||
+    _WKBrowserContext *browserContext = [[_WKBrowserContext alloc] init];
 | 
						||
+    _WKProcessPoolConfiguration *processConfiguration = [[[_WKProcessPoolConfiguration alloc] init] autorelease];
 | 
						||
+    processConfiguration.forceOverlayScrollbars = YES;
 | 
						||
+    browserContext.dataStore = [WKWebsiteDataStore nonPersistentDataStore];
 | 
						||
+    browserContext.processPool = [[[WKProcessPool alloc] _initWithConfiguration:processConfiguration] autorelease];
 | 
						||
+    [_browserContexts addObject:browserContext];
 | 
						||
+    return browserContext;
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (void)deleteBrowserContext:(uint64_t)sessionID
 | 
						||
+{
 | 
						||
+    for (_WKBrowserContext *browserContext in _browserContexts) {
 | 
						||
+        if ([[browserContext dataStore] sessionID] != sessionID)
 | 
						||
+            continue;
 | 
						||
+        [_browserContexts removeObject:browserContext];
 | 
						||
+        return;
 | 
						||
+    }
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (void)quit
 | 
						||
+{
 | 
						||
+    [NSApp performSelector:@selector(terminate:) withObject:nil afterDelay:0.0];
 | 
						||
+}
 | 
						||
+
 | 
						||
+#pragma mark WKUIDelegate
 | 
						||
+
 | 
						||
+- (void)webViewDidClose:(WKWebView *)webView {
 | 
						||
+    for (NSWindow *window in _headlessWindows) {
 | 
						||
+        if (webView.window != window)
 | 
						||
+            continue;
 | 
						||
+        [webView removeFromSuperview];
 | 
						||
+        [window close];
 | 
						||
+        [_headlessWindows removeObject:window];
 | 
						||
+        break;
 | 
						||
+    }
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler
 | 
						||
+{
 | 
						||
+    WebViewDialog* dialog = [[WebViewDialog alloc] autorelease];
 | 
						||
+    dialog.webView = webView;
 | 
						||
+    dialog.completionHandler = ^void (BOOL accept, NSString* value) {
 | 
						||
+        completionHandler();
 | 
						||
+    };
 | 
						||
+    [_dialogs addObject:dialog];
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler
 | 
						||
+{
 | 
						||
+    WebViewDialog* dialog = [[WebViewDialog alloc] autorelease];
 | 
						||
+    dialog.webView = webView;
 | 
						||
+    dialog.completionHandler = ^void (BOOL accept, NSString* value) {
 | 
						||
+        completionHandler(accept);
 | 
						||
+    };
 | 
						||
+    [_dialogs addObject:dialog];
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString *result))completionHandler
 | 
						||
+{
 | 
						||
+    WebViewDialog* dialog = [[WebViewDialog alloc] autorelease];
 | 
						||
+    dialog.webView = webView;
 | 
						||
+    dialog.completionHandler = ^void (BOOL accept, NSString* value) {
 | 
						||
+        completionHandler(accept && value ? value : nil);
 | 
						||
+    };
 | 
						||
+    [_dialogs addObject:dialog];
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (void)_webView:(WKWebView *)webView runBeforeUnloadConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler
 | 
						||
+{
 | 
						||
+    WebViewDialog* dialog = [[WebViewDialog alloc] autorelease];
 | 
						||
+    dialog.webView = webView;
 | 
						||
+    dialog.completionHandler = ^void (BOOL accept, NSString* value) {
 | 
						||
+        completionHandler(accept);
 | 
						||
+    };
 | 
						||
+    [_dialogs addObject:dialog];
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (void)webView:(WKWebView *)webView handleJavaScriptDialog:(BOOL)accept value:(NSString *)value
 | 
						||
+{
 | 
						||
+    for (WebViewDialog *dialog in _dialogs) {
 | 
						||
+        if (dialog.webView != webView)
 | 
						||
+            continue;
 | 
						||
+        dialog.completionHandler(accept, value);
 | 
						||
+        [_dialogs removeObject:dialog];
 | 
						||
+        break;
 | 
						||
+    }
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (nullable WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures
 | 
						||
+{
 | 
						||
+    return [self createHeadlessPage:configuration withURL:nil];
 | 
						||
+}
 | 
						||
+
 | 
						||
+@end
 | 
						||
diff --git a/Tools/Playwright/mac/BrowserWindow.xib b/Tools/Playwright/mac/BrowserWindow.xib
 | 
						||
new file mode 100644
 | 
						||
index 0000000000000000000000000000000000000000..f6f3d8e3a0f163e61b2f3d54819e9d25a0a3eb75
 | 
						||
--- /dev/null
 | 
						||
+++ b/Tools/Playwright/mac/BrowserWindow.xib
 | 
						||
@@ -0,0 +1,153 @@
 | 
						||
+<?xml version="1.0" encoding="UTF-8"?>
 | 
						||
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="11191" systemVersion="16D17a" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
 | 
						||
+    <dependencies>
 | 
						||
+        <deployment identifier="macosx"/>
 | 
						||
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="11191"/>
 | 
						||
+    </dependencies>
 | 
						||
+    <objects>
 | 
						||
+        <customObject id="-2" userLabel="File's Owner" customClass="BrowserWindowController">
 | 
						||
+            <connections>
 | 
						||
+                <outlet property="backButton" destination="40" id="46"/>
 | 
						||
+                <outlet property="containerView" destination="9" id="37"/>
 | 
						||
+                <outlet property="forwardButton" destination="42" id="47"/>
 | 
						||
+                <outlet property="progressIndicator" destination="21" id="33"/>
 | 
						||
+                <outlet property="reloadButton" destination="23" id="34"/>
 | 
						||
+                <outlet property="share" destination="1hB-AH-eUl" id="si4-8e-DsM"/>
 | 
						||
+                <outlet property="toggleUseShrinkToFitButton" destination="82" id="9w7-AB-Ye3"/>
 | 
						||
+                <outlet property="toolbar" destination="48" id="67"/>
 | 
						||
+                <outlet property="urlText" destination="10" id="32"/>
 | 
						||
+                <outlet property="window" destination="1" id="3"/>
 | 
						||
+            </connections>
 | 
						||
+        </customObject>
 | 
						||
+        <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
 | 
						||
+        <customObject id="-3" userLabel="Application" customClass="NSObject"/>
 | 
						||
+        <window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" frameAutosaveName="Main Window" animationBehavior="default" id="1">
 | 
						||
+            <windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES" unifiedTitleAndToolbar="YES" fullSizeContentView="YES"/>
 | 
						||
+            <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
 | 
						||
+            <rect key="contentRect" x="517" y="330" width="776" height="608"/>
 | 
						||
+            <rect key="screenRect" x="0.0" y="0.0" width="1920" height="1177"/>
 | 
						||
+            <view key="contentView" id="2">
 | 
						||
+                <rect key="frame" x="0.0" y="0.0" width="776" height="608"/>
 | 
						||
+                <autoresizingMask key="autoresizingMask"/>
 | 
						||
+                <subviews>
 | 
						||
+                    <customView id="9">
 | 
						||
+                        <rect key="frame" x="0.0" y="0.0" width="776" height="608"/>
 | 
						||
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
 | 
						||
+                    </customView>
 | 
						||
+                </subviews>
 | 
						||
+            </view>
 | 
						||
+            <toolbar key="toolbar" implicitIdentifier="994A0CB1-7575-4F39-A65B-7165AB1E8015" displayMode="iconOnly" sizeMode="regular" id="48">
 | 
						||
+                <allowedToolbarItems>
 | 
						||
+                    <toolbarItem implicitItemIdentifier="73DE9F4B-73E2-4036-A134-2D9E029DA980" label="Go Back" paletteLabel="Go Back" image="NSGoLeftTemplate" id="56" customClass="MBToolbarItem">
 | 
						||
+                        <nil key="toolTip"/>
 | 
						||
+                        <size key="minSize" width="32" height="27"/>
 | 
						||
+                        <size key="maxSize" width="32" height="25"/>
 | 
						||
+                        <button key="view" verticalHuggingPriority="750" id="40">
 | 
						||
+                            <rect key="frame" x="10" y="14" width="32" height="25"/>
 | 
						||
+                            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
 | 
						||
+                            <buttonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" image="NSGoLeftTemplate" imagePosition="overlaps" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="41">
 | 
						||
+                                <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
 | 
						||
+                                <font key="font" metaFont="system"/>
 | 
						||
+                            </buttonCell>
 | 
						||
+                        </button>
 | 
						||
+                        <connections>
 | 
						||
+                            <action selector="goBack:" target="-2" id="61"/>
 | 
						||
+                        </connections>
 | 
						||
+                    </toolbarItem>
 | 
						||
+                    <toolbarItem implicitItemIdentifier="E1A9D32A-59E3-467B-9ABA-A95780416E69" label="Go Forward" paletteLabel="Go Forward" image="NSGoRightTemplate" id="57" customClass="MBToolbarItem">
 | 
						||
+                        <nil key="toolTip"/>
 | 
						||
+                        <size key="minSize" width="32" height="27"/>
 | 
						||
+                        <size key="maxSize" width="32" height="27"/>
 | 
						||
+                        <button key="view" verticalHuggingPriority="750" id="42">
 | 
						||
+                            <rect key="frame" x="18" y="14" width="32" height="25"/>
 | 
						||
+                            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
 | 
						||
+                            <buttonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" image="NSGoRightTemplate" imagePosition="overlaps" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="43">
 | 
						||
+                                <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
 | 
						||
+                                <font key="font" metaFont="system"/>
 | 
						||
+                            </buttonCell>
 | 
						||
+                        </button>
 | 
						||
+                        <connections>
 | 
						||
+                            <action selector="goForward:" target="-2" id="62"/>
 | 
						||
+                        </connections>
 | 
						||
+                    </toolbarItem>
 | 
						||
+                    <toolbarItem implicitItemIdentifier="88C16109-D40F-4682-BCE4-CBEE2EDE32D2" label="Refresh" paletteLabel="Refresh" image="NSRefreshTemplate" id="58" customClass="MBToolbarItem">
 | 
						||
+                        <nil key="toolTip"/>
 | 
						||
+                        <size key="minSize" width="29" height="27"/>
 | 
						||
+                        <size key="maxSize" width="29" height="27"/>
 | 
						||
+                        <button key="view" verticalHuggingPriority="750" id="23">
 | 
						||
+                            <rect key="frame" x="10" y="14" width="29" height="25"/>
 | 
						||
+                            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
 | 
						||
+                            <buttonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" image="NSRefreshTemplate" imagePosition="overlaps" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="24">
 | 
						||
+                                <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
 | 
						||
+                                <font key="font" metaFont="system"/>
 | 
						||
+                            </buttonCell>
 | 
						||
+                            <connections>
 | 
						||
+                                <action selector="reload:" target="-2" id="35"/>
 | 
						||
+                            </connections>
 | 
						||
+                        </button>
 | 
						||
+                    </toolbarItem>
 | 
						||
+                    <toolbarItem implicitItemIdentifier="F1738B7F-895C-48F7-955D-0915E150BE1B" label="Share" paletteLabel="Share" image="NSShareTemplate" id="dJx-dw-gcC" customClass="MBToolbarItem">
 | 
						||
+                        <nil key="toolTip"/>
 | 
						||
+                        <size key="minSize" width="29" height="27"/>
 | 
						||
+                        <size key="maxSize" width="29" height="27"/>
 | 
						||
+                        <button key="view" verticalHuggingPriority="750" id="1hB-AH-eUl">
 | 
						||
+                            <rect key="frame" x="5" y="14" width="29" height="25"/>
 | 
						||
+                            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
 | 
						||
+                            <buttonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" image="NSShareTemplate" imagePosition="overlaps" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="S1v-UD-QhI">
 | 
						||
+                                <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
 | 
						||
+                                <font key="font" metaFont="system"/>
 | 
						||
+                                <connections>
 | 
						||
+                                    <action selector="share:" target="-2" id="5e3-hg-bKN"/>
 | 
						||
+                                </connections>
 | 
						||
+                            </buttonCell>
 | 
						||
+                        </button>
 | 
						||
+                    </toolbarItem>
 | 
						||
+                    <toolbarItem implicitItemIdentifier="255D29F2-C9AA-4B4B-BB43-B38FCD6A0BBB" label="Location" paletteLabel="Location" id="59">
 | 
						||
+                        <nil key="toolTip"/>
 | 
						||
+                        <size key="minSize" width="200" height="22"/>
 | 
						||
+                        <size key="maxSize" width="100000" height="22"/>
 | 
						||
+                        <textField key="view" verticalHuggingPriority="750" id="10">
 | 
						||
+                            <rect key="frame" x="0.0" y="14" width="565" height="22"/>
 | 
						||
+                            <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
 | 
						||
+                            <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="11">
 | 
						||
+                                <font key="font" metaFont="system"/>
 | 
						||
+                                <color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
 | 
						||
+                                <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
 | 
						||
+                            </textFieldCell>
 | 
						||
+                            <connections>
 | 
						||
+                                <action selector="fetch:" target="-2" id="36"/>
 | 
						||
+                            </connections>
 | 
						||
+                        </textField>
 | 
						||
+                    </toolbarItem>
 | 
						||
+                    <toolbarItem implicitItemIdentifier="86912BAA-B8D0-400F-BFEE-71FC166986E6" label="Progress" paletteLabel="Progress" tag="-1" id="60">
 | 
						||
+                        <nil key="toolTip"/>
 | 
						||
+                        <size key="minSize" width="16" height="16"/>
 | 
						||
+                        <size key="maxSize" width="16" height="16"/>
 | 
						||
+                        <progressIndicator key="view" horizontalHuggingPriority="750" verticalHuggingPriority="750" maxValue="1" displayedWhenStopped="NO" bezeled="NO" controlSize="small" style="spinning" id="21">
 | 
						||
+                            <rect key="frame" x="19" y="14" width="16" height="16"/>
 | 
						||
+                            <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
 | 
						||
+                        </progressIndicator>
 | 
						||
+                    </toolbarItem>
 | 
						||
+                </allowedToolbarItems>
 | 
						||
+                <defaultToolbarItems>
 | 
						||
+                    <toolbarItem reference="56"/>
 | 
						||
+                    <toolbarItem reference="57"/>
 | 
						||
+                    <toolbarItem reference="58"/>
 | 
						||
+                    <toolbarItem reference="59"/>
 | 
						||
+                    <toolbarItem reference="60"/>
 | 
						||
+                    <toolbarItem reference="dJx-dw-gcC"/>
 | 
						||
+                </defaultToolbarItems>
 | 
						||
+            </toolbar>
 | 
						||
+            <connections>
 | 
						||
+                <outlet property="delegate" destination="-2" id="4"/>
 | 
						||
+            </connections>
 | 
						||
+        </window>
 | 
						||
+    </objects>
 | 
						||
+    <resources>
 | 
						||
+        <image name="NSEnterFullScreenTemplate" width="15" height="15"/>
 | 
						||
+        <image name="NSGoLeftTemplate" width="9" height="12"/>
 | 
						||
+        <image name="NSGoRightTemplate" width="9" height="12"/>
 | 
						||
+        <image name="NSRefreshTemplate" width="11" height="15"/>
 | 
						||
+        <image name="NSShareTemplate" width="11" height="16"/>
 | 
						||
+    </resources>
 | 
						||
+</document>
 | 
						||
diff --git a/Tools/Playwright/mac/BrowserWindowController.h b/Tools/Playwright/mac/BrowserWindowController.h
 | 
						||
new file mode 100644
 | 
						||
index 0000000000000000000000000000000000000000..4dbf13c8fb31a745ae8e1965a457d4fbcd8e5866
 | 
						||
--- /dev/null
 | 
						||
+++ b/Tools/Playwright/mac/BrowserWindowController.h
 | 
						||
@@ -0,0 +1,46 @@
 | 
						||
+/*
 | 
						||
+ * Copyright (C) 2010 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. 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.
 | 
						||
+ */
 | 
						||
+
 | 
						||
+@class WKWebView;
 | 
						||
+
 | 
						||
+@interface BrowserWindowController : NSWindowController
 | 
						||
+
 | 
						||
+- (IBAction)goBack:(id)sender;
 | 
						||
+- (IBAction)goForward:(id)sender;
 | 
						||
+- (IBAction)reload:(id)sender;
 | 
						||
+- (IBAction)saveAsPDF:(id)sender;
 | 
						||
+- (IBAction)saveAsWebArchive:(id)sender;
 | 
						||
+- (IBAction)zoomIn:(id)sender;
 | 
						||
+- (IBAction)zoomOut:(id)sender;
 | 
						||
+- (IBAction)resetZoom:(id)sender;
 | 
						||
+- (IBAction)showHideWebInspector:(id)sender;
 | 
						||
+
 | 
						||
+- (IBAction)setPageScale:(id)sender;
 | 
						||
+- (IBAction)setViewScale:(id)sender;
 | 
						||
+- (instancetype)initWithConfiguration:(WKWebViewConfiguration *)configuration;
 | 
						||
+- (void)loadURLString:(NSString *)urlString;
 | 
						||
+- (WKWebView *)webView;
 | 
						||
+
 | 
						||
+@end
 | 
						||
diff --git a/Tools/Playwright/mac/BrowserWindowController.m b/Tools/Playwright/mac/BrowserWindowController.m
 | 
						||
new file mode 100644
 | 
						||
index 0000000000000000000000000000000000000000..72edf5c432f58659765d16dabdb536b44942b1f2
 | 
						||
--- /dev/null
 | 
						||
+++ b/Tools/Playwright/mac/BrowserWindowController.m
 | 
						||
@@ -0,0 +1,828 @@
 | 
						||
+/*
 | 
						||
+ * Copyright (C) 2010-2016 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. 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.
 | 
						||
+ */
 | 
						||
+
 | 
						||
+#import "BrowserWindowController.h"
 | 
						||
+
 | 
						||
+#import "AppDelegate.h"
 | 
						||
+#import <WebKit/WKFrameInfo.h>
 | 
						||
+#import <WebKit/WKNavigationActionPrivate.h>
 | 
						||
+#import <WebKit/WKNavigationDelegate.h>
 | 
						||
+#import <WebKit/WKPreferencesPrivate.h>
 | 
						||
+#import <WebKit/WKUIDelegate.h>
 | 
						||
+#import <WebKit/WKUIDelegatePrivate.h>
 | 
						||
+#import <WebKit/WKWebViewConfigurationPrivate.h>
 | 
						||
+#import <WebKit/WKWebViewPrivate.h>
 | 
						||
+#import <WebKit/WKWebViewPrivateForTesting.h>
 | 
						||
+#import <WebKit/WKWebsiteDataStorePrivate.h>
 | 
						||
+#import <WebKit/WebNSURLExtras.h>
 | 
						||
+#import <WebKit/_WKIconLoadingDelegate.h>
 | 
						||
+#import <WebKit/_WKInspector.h>
 | 
						||
+#import <WebKit/_WKLinkIconParameters.h>
 | 
						||
+#import <WebKit/_WKUserInitiatedAction.h>
 | 
						||
+
 | 
						||
+static void* keyValueObservingContext = &keyValueObservingContext;
 | 
						||
+
 | 
						||
+@interface PlaywrightNSTextFinder : NSTextFinder
 | 
						||
+
 | 
						||
+@property (nonatomic, copy) dispatch_block_t hideInterfaceCallback;
 | 
						||
+
 | 
						||
+@end
 | 
						||
+
 | 
						||
+@implementation PlaywrightNSTextFinder
 | 
						||
+
 | 
						||
+- (void)performAction:(NSTextFinderAction)op
 | 
						||
+{
 | 
						||
+    [super performAction:op];
 | 
						||
+
 | 
						||
+    if (op == NSTextFinderActionHideFindInterface && _hideInterfaceCallback)
 | 
						||
+        _hideInterfaceCallback();
 | 
						||
+}
 | 
						||
+
 | 
						||
+@end
 | 
						||
+
 | 
						||
+@interface BrowserWindowController () <NSTextFinderBarContainer, WKNavigationDelegate, WKUIDelegate, _WKIconLoadingDelegate, NSSharingServicePickerDelegate, NSSharingServiceDelegate>
 | 
						||
+@end
 | 
						||
+
 | 
						||
+@implementation BrowserWindowController {
 | 
						||
+    IBOutlet NSProgressIndicator *progressIndicator;
 | 
						||
+    IBOutlet NSButton *reloadButton;
 | 
						||
+    IBOutlet NSButton *backButton;
 | 
						||
+    IBOutlet NSButton *forwardButton;
 | 
						||
+    IBOutlet NSButton *share;
 | 
						||
+    IBOutlet NSToolbar *toolbar;
 | 
						||
+    IBOutlet NSTextField *urlText;
 | 
						||
+    IBOutlet NSView *containerView;
 | 
						||
+    IBOutlet NSButton *toggleUseShrinkToFitButton;
 | 
						||
+
 | 
						||
+    WKWebViewConfiguration *_configuration;
 | 
						||
+    WKWebView *_webView;
 | 
						||
+    BOOL _zoomTextOnly;
 | 
						||
+    BOOL _isPrivateBrowsingWindow;
 | 
						||
+    NSAlert* _alert;
 | 
						||
+
 | 
						||
+    BOOL _useShrinkToFit;
 | 
						||
+
 | 
						||
+    PlaywrightNSTextFinder *_textFinder;
 | 
						||
+    NSView *_textFindBarView;
 | 
						||
+    BOOL _findBarVisible;
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (id)initWithWindow:(NSWindow *)window
 | 
						||
+{
 | 
						||
+    self = [super initWithWindow:window];
 | 
						||
+    return self;
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (void)windowDidLoad
 | 
						||
+{
 | 
						||
+    [share sendActionOn:NSEventMaskLeftMouseDown];
 | 
						||
+    [super windowDidLoad];
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (IBAction)openLocation:(id)sender
 | 
						||
+{
 | 
						||
+    [[self window] makeFirstResponder:urlText];
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (NSString *)addProtocolIfNecessary:(NSString *)address
 | 
						||
+{
 | 
						||
+    if ([address rangeOfString:@"://"].length > 0)
 | 
						||
+        return address;
 | 
						||
+
 | 
						||
+    if ([address hasPrefix:@"data:"])
 | 
						||
+        return address;
 | 
						||
+
 | 
						||
+    if ([address hasPrefix:@"about:"])
 | 
						||
+        return address;
 | 
						||
+
 | 
						||
+    return [@"http://" stringByAppendingString:address];
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (IBAction)share:(id)sender
 | 
						||
+{
 | 
						||
+    NSSharingServicePicker *picker = [[NSSharingServicePicker alloc] initWithItems:@[ self.currentURL ]];
 | 
						||
+    picker.delegate = self;
 | 
						||
+    [picker showRelativeToRect:NSZeroRect ofView:sender preferredEdge:NSRectEdgeMinY];
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (IBAction)showHideWebView:(id)sender
 | 
						||
+{
 | 
						||
+    self.mainContentView.hidden = !self.mainContentView.isHidden;
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (CGFloat)pageScaleForMenuItemTag:(NSInteger)tag
 | 
						||
+{
 | 
						||
+    if (tag == 1)
 | 
						||
+        return 1;
 | 
						||
+    if (tag == 2)
 | 
						||
+        return 1.25;
 | 
						||
+    if (tag == 3)
 | 
						||
+        return 1.5;
 | 
						||
+    if (tag == 4)
 | 
						||
+        return 2.0;
 | 
						||
+
 | 
						||
+    return 1;
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (void)awakeFromNib
 | 
						||
+{
 | 
						||
+    _webView = [[WKWebView alloc] initWithFrame:[containerView bounds] configuration:_configuration];
 | 
						||
+    _webView._windowOcclusionDetectionEnabled = NO;
 | 
						||
+
 | 
						||
+    _webView.allowsMagnification = YES;
 | 
						||
+    _webView.allowsBackForwardNavigationGestures = YES;
 | 
						||
+
 | 
						||
+    [_webView setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];
 | 
						||
+    [containerView addSubview:_webView];
 | 
						||
+
 | 
						||
+    [progressIndicator bind:NSHiddenBinding toObject:_webView withKeyPath:@"loading" options:@{ NSValueTransformerNameBindingOption : NSNegateBooleanTransformerName }];
 | 
						||
+    [progressIndicator bind:NSValueBinding toObject:_webView withKeyPath:@"estimatedProgress" options:nil];
 | 
						||
+
 | 
						||
+    [_webView addObserver:self forKeyPath:@"title" options:0 context:keyValueObservingContext];
 | 
						||
+    [_webView addObserver:self forKeyPath:@"URL" options:0 context:keyValueObservingContext];
 | 
						||
+
 | 
						||
+    _webView.navigationDelegate = self;
 | 
						||
+    _webView.UIDelegate = self;
 | 
						||
+
 | 
						||
+    _webView._observedRenderingProgressEvents = _WKRenderingProgressEventFirstLayout
 | 
						||
+        | _WKRenderingProgressEventFirstVisuallyNonEmptyLayout
 | 
						||
+        | _WKRenderingProgressEventFirstPaintWithSignificantArea
 | 
						||
+        | _WKRenderingProgressEventFirstLayoutAfterSuppressedIncrementalRendering
 | 
						||
+        | _WKRenderingProgressEventFirstPaintAfterSuppressedIncrementalRendering;
 | 
						||
+
 | 
						||
+    _webView.customUserAgent = @"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.4 Safari/605.1.15";
 | 
						||
+
 | 
						||
+    _webView._usePlatformFindUI = NO;
 | 
						||
+
 | 
						||
+    _textFinder = [[PlaywrightNSTextFinder alloc] init];
 | 
						||
+    _textFinder.incrementalSearchingEnabled = YES;
 | 
						||
+    _textFinder.incrementalSearchingShouldDimContentView = NO;
 | 
						||
+    _textFinder.client = _webView;
 | 
						||
+    _textFinder.findBarContainer = self;
 | 
						||
+    _textFinder.hideInterfaceCallback = ^{
 | 
						||
+        [_webView _hideFindUI];
 | 
						||
+    };
 | 
						||
+
 | 
						||
+    _zoomTextOnly = NO;
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (instancetype)initWithConfiguration:(WKWebViewConfiguration *)configuration
 | 
						||
+{
 | 
						||
+    if (!(self = [super initWithWindowNibName:@"BrowserWindow"]))
 | 
						||
+        return nil;
 | 
						||
+    _configuration = [configuration copy];
 | 
						||
+    _isPrivateBrowsingWindow = !_configuration.websiteDataStore.isPersistent;
 | 
						||
+    self.window.styleMask &= ~NSWindowStyleMaskFullSizeContentView;
 | 
						||
+    return self;
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (void)dealloc
 | 
						||
+{
 | 
						||
+    [[NSNotificationCenter defaultCenter] removeObserver:self];
 | 
						||
+
 | 
						||
+    [progressIndicator unbind:NSHiddenBinding];
 | 
						||
+    [progressIndicator unbind:NSValueBinding];
 | 
						||
+
 | 
						||
+    [_textFinder release];
 | 
						||
+    [_webView release];
 | 
						||
+    [_configuration release];
 | 
						||
+
 | 
						||
+    [super dealloc];
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (IBAction)fetch:(id)sender
 | 
						||
+{
 | 
						||
+    [urlText setStringValue:[self addProtocolIfNecessary:urlText.stringValue]];
 | 
						||
+    NSURL *url = [NSURL _webkit_URLWithUserTypedString:urlText.stringValue];
 | 
						||
+    [_webView loadRequest:[NSURLRequest requestWithURL:url]];
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (IBAction)setPageScale:(id)sender
 | 
						||
+{
 | 
						||
+    CGFloat scale = [self pageScaleForMenuItemTag:[sender tag]];
 | 
						||
+    [_webView _setPageScale:scale withOrigin:CGPointZero];
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (CGFloat)viewScaleForMenuItemTag:(NSInteger)tag
 | 
						||
+{
 | 
						||
+    if (tag == 1)
 | 
						||
+        return 1;
 | 
						||
+    if (tag == 2)
 | 
						||
+        return 0.75;
 | 
						||
+    if (tag == 3)
 | 
						||
+        return 0.5;
 | 
						||
+    if (tag == 4)
 | 
						||
+        return 0.25;
 | 
						||
+
 | 
						||
+    return 1;
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (IBAction)setViewScale:(id)sender
 | 
						||
+{
 | 
						||
+    CGFloat scale = [self viewScaleForMenuItemTag:[sender tag]];
 | 
						||
+    CGFloat oldScale = [_webView _viewScale];
 | 
						||
+
 | 
						||
+    if (scale == oldScale)
 | 
						||
+        return;
 | 
						||
+
 | 
						||
+    [_webView _setLayoutMode:_WKLayoutModeDynamicSizeComputedFromViewScale];
 | 
						||
+
 | 
						||
+    NSRect oldFrame = self.window.frame;
 | 
						||
+    NSSize newFrameSize = NSMakeSize(oldFrame.size.width * (scale / oldScale), oldFrame.size.height * (scale / oldScale));
 | 
						||
+    [self.window setFrame:NSMakeRect(oldFrame.origin.x, oldFrame.origin.y - (newFrameSize.height - oldFrame.size.height), newFrameSize.width, newFrameSize.height) display:NO animate:NO];
 | 
						||
+
 | 
						||
+    [_webView _setViewScale:scale];
 | 
						||
+}
 | 
						||
+
 | 
						||
+static BOOL areEssentiallyEqual(double a, double b)
 | 
						||
+{
 | 
						||
+    double tolerance = 0.001;
 | 
						||
+    return (fabs(a - b) <= tolerance);
 | 
						||
+}
 | 
						||
+
 | 
						||
+#pragma GCC diagnostic push
 | 
						||
+#pragma GCC diagnostic ignored "-Wdeprecated-implementations"
 | 
						||
+- (BOOL)validateMenuItem:(NSMenuItem *)menuItem
 | 
						||
+#pragma GCC diagnostic pop
 | 
						||
+{
 | 
						||
+    SEL action = menuItem.action;
 | 
						||
+
 | 
						||
+    if (action == @selector(saveAsPDF:))
 | 
						||
+        return YES;
 | 
						||
+    if (action == @selector(saveAsWebArchive:))
 | 
						||
+        return YES;
 | 
						||
+
 | 
						||
+    if (action == @selector(zoomIn:))
 | 
						||
+        return [self canZoomIn];
 | 
						||
+    if (action == @selector(zoomOut:))
 | 
						||
+        return [self canZoomOut];
 | 
						||
+    if (action == @selector(resetZoom:))
 | 
						||
+        return [self canResetZoom];
 | 
						||
+
 | 
						||
+    if (action == @selector(toggleZoomMode:))
 | 
						||
+        [menuItem setState:_zoomTextOnly ? NSControlStateValueOn : NSControlStateValueOff];
 | 
						||
+    else if (action == @selector(showHideWebInspector:))
 | 
						||
+        [menuItem setTitle:_webView._inspector.isVisible ? @"Close Web Inspector" : @"Show Web Inspector"];
 | 
						||
+
 | 
						||
+    if (action == @selector(setPageScale:))
 | 
						||
+        [menuItem setState:areEssentiallyEqual([_webView _pageScale], [self pageScaleForMenuItemTag:[menuItem tag]])];
 | 
						||
+
 | 
						||
+    if (action == @selector(setViewScale:))
 | 
						||
+        [menuItem setState:areEssentiallyEqual([_webView _viewScale], [self viewScaleForMenuItemTag:[menuItem tag]])];
 | 
						||
+
 | 
						||
+    return YES;
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (IBAction)reload:(id)sender
 | 
						||
+{
 | 
						||
+    [_webView reload];
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (IBAction)goBack:(id)sender
 | 
						||
+{
 | 
						||
+    [_webView goBack];
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (IBAction)goForward:(id)sender
 | 
						||
+{
 | 
						||
+    [_webView goForward];
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (IBAction)toggleZoomMode:(id)sender
 | 
						||
+{
 | 
						||
+    if (_zoomTextOnly) {
 | 
						||
+        _zoomTextOnly = NO;
 | 
						||
+        double currentTextZoom = _webView._textZoomFactor;
 | 
						||
+        _webView._textZoomFactor = 1;
 | 
						||
+        _webView.pageZoom = currentTextZoom;
 | 
						||
+    } else {
 | 
						||
+        _zoomTextOnly = YES;
 | 
						||
+        double currentPageZoom = _webView._pageZoomFactor;
 | 
						||
+        _webView._textZoomFactor = currentPageZoom;
 | 
						||
+        _webView.pageZoom = 1;
 | 
						||
+    }
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (IBAction)resetZoom:(id)sender
 | 
						||
+{
 | 
						||
+    if (![self canResetZoom])
 | 
						||
+        return;
 | 
						||
+
 | 
						||
+    if (_zoomTextOnly)
 | 
						||
+        _webView._textZoomFactor = 1;
 | 
						||
+    else
 | 
						||
+        _webView.pageZoom = 1;
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (BOOL)canResetZoom
 | 
						||
+{
 | 
						||
+    return _zoomTextOnly ? (_webView._textZoomFactor != 1) : (_webView.pageZoom != 1);
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (IBAction)showHideWebInspector:(id)sender
 | 
						||
+{
 | 
						||
+    _WKInspector *inspector = _webView._inspector;
 | 
						||
+    if (inspector.isVisible)
 | 
						||
+        [inspector hide];
 | 
						||
+    else
 | 
						||
+        [inspector show];
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (NSURL *)currentURL
 | 
						||
+{
 | 
						||
+    return _webView.URL;
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (NSView *)mainContentView
 | 
						||
+{
 | 
						||
+    return _webView;
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)item
 | 
						||
+{
 | 
						||
+    SEL action = item.action;
 | 
						||
+
 | 
						||
+    if (action == @selector(goBack:) || action == @selector(goForward:))
 | 
						||
+        return [_webView validateUserInterfaceItem:item];
 | 
						||
+
 | 
						||
+    return YES;
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (void)validateToolbar
 | 
						||
+{
 | 
						||
+    [toolbar validateVisibleItems];
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (BOOL)windowShouldClose:(id)sender
 | 
						||
+{
 | 
						||
+    return YES;
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (void)windowWillClose:(NSNotification *)notification
 | 
						||
+{
 | 
						||
+    [[[NSApplication sharedApplication] browserAppDelegate] browserWindowWillClose:self.window];
 | 
						||
+    [_webView removeObserver:self forKeyPath:@"title"];
 | 
						||
+    [_webView removeObserver:self forKeyPath:@"URL"];
 | 
						||
+    [self autorelease];
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (void)webViewDidClose:(WKWebView *)webView {
 | 
						||
+    [self.window close];
 | 
						||
+}
 | 
						||
+
 | 
						||
+#define DefaultMinimumZoomFactor (.5)
 | 
						||
+#define DefaultMaximumZoomFactor (3.0)
 | 
						||
+#define DefaultZoomFactorRatio (1.2)
 | 
						||
+
 | 
						||
+- (CGFloat)currentZoomFactor
 | 
						||
+{
 | 
						||
+    return _zoomTextOnly ? _webView._textZoomFactor : _webView.pageZoom;
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (void)setCurrentZoomFactor:(CGFloat)factor
 | 
						||
+{
 | 
						||
+    if (_zoomTextOnly)
 | 
						||
+        _webView._textZoomFactor = factor;
 | 
						||
+    else
 | 
						||
+        _webView.pageZoom = factor;
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (BOOL)canZoomIn
 | 
						||
+{
 | 
						||
+    return self.currentZoomFactor * DefaultZoomFactorRatio < DefaultMaximumZoomFactor;
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (void)zoomIn:(id)sender
 | 
						||
+{
 | 
						||
+    if (!self.canZoomIn)
 | 
						||
+        return;
 | 
						||
+
 | 
						||
+    self.currentZoomFactor *= DefaultZoomFactorRatio;
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (BOOL)canZoomOut
 | 
						||
+{
 | 
						||
+    return self.currentZoomFactor / DefaultZoomFactorRatio > DefaultMinimumZoomFactor;
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (void)zoomOut:(id)sender
 | 
						||
+{
 | 
						||
+    if (!self.canZoomIn)
 | 
						||
+        return;
 | 
						||
+
 | 
						||
+    self.currentZoomFactor /= DefaultZoomFactorRatio;
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (void)updateTitle:(NSString *)title
 | 
						||
+{
 | 
						||
+    if (!title) {
 | 
						||
+        NSURL *url = _webView.URL;
 | 
						||
+        title = url.lastPathComponent ?: url._web_userVisibleString;
 | 
						||
+    }
 | 
						||
+
 | 
						||
+    self.window.title = [NSString stringWithFormat:@"%@%@ [%d]%@", _isPrivateBrowsingWindow ? @"🙈 " : @"", title, _webView._webProcessIdentifier, @""];
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
 | 
						||
+{
 | 
						||
+    if (context != keyValueObservingContext || object != _webView)
 | 
						||
+        return;
 | 
						||
+
 | 
						||
+    if ([keyPath isEqualToString:@"title"])
 | 
						||
+        [self updateTitle:_webView.title];
 | 
						||
+    else if ([keyPath isEqualToString:@"URL"])
 | 
						||
+        [self updateTextFieldFromURL:_webView.URL];
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (nullable WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures
 | 
						||
+{
 | 
						||
+    BrowserWindowController *controller = [[BrowserWindowController alloc] initWithConfiguration:configuration];
 | 
						||
+    [controller.window makeKeyAndOrderFront:self];
 | 
						||
+
 | 
						||
+    return controller->_webView;
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler
 | 
						||
+{
 | 
						||
+    NSAlert* alert = [[NSAlert alloc] init];
 | 
						||
+
 | 
						||
+    [alert setMessageText:[NSString stringWithFormat:@"JavaScript alert dialog from %@.", [frame.request.URL absoluteString]]];
 | 
						||
+    [alert setInformativeText:message];
 | 
						||
+    [alert addButtonWithTitle:@"OK"];
 | 
						||
+
 | 
						||
+    _alert = alert;
 | 
						||
+    [alert beginSheetModalForWindow:self.window completionHandler:^void (NSModalResponse response) {
 | 
						||
+        completionHandler();
 | 
						||
+        [alert release];
 | 
						||
+        _alert = nil;
 | 
						||
+    }];
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler
 | 
						||
+{
 | 
						||
+    NSAlert* alert = [[NSAlert alloc] init];
 | 
						||
+
 | 
						||
+    [alert setMessageText:[NSString stringWithFormat:@"JavaScript confirm dialog from %@.", [frame.request.URL  absoluteString]]];
 | 
						||
+    [alert setInformativeText:message];
 | 
						||
+
 | 
						||
+    [alert addButtonWithTitle:@"OK"];
 | 
						||
+    [alert addButtonWithTitle:@"Cancel"];
 | 
						||
+
 | 
						||
+    _alert = alert;
 | 
						||
+    [alert beginSheetModalForWindow:self.window completionHandler:^void (NSModalResponse response) {
 | 
						||
+        completionHandler(response == NSAlertFirstButtonReturn);
 | 
						||
+        [alert release];
 | 
						||
+        _alert = nil;
 | 
						||
+    }];
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString *result))completionHandler
 | 
						||
+{
 | 
						||
+    NSAlert* alert = [[NSAlert alloc] init];
 | 
						||
+
 | 
						||
+    [alert setMessageText:[NSString stringWithFormat:@"JavaScript prompt dialog from %@.", [frame.request.URL absoluteString]]];
 | 
						||
+    [alert setInformativeText:prompt];
 | 
						||
+
 | 
						||
+    [alert addButtonWithTitle:@"OK"];
 | 
						||
+    [alert addButtonWithTitle:@"Cancel"];
 | 
						||
+
 | 
						||
+    NSTextField* input = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 200, 24)];
 | 
						||
+    [input setStringValue:defaultText];
 | 
						||
+    [alert setAccessoryView:input];
 | 
						||
+
 | 
						||
+    _alert = alert;
 | 
						||
+    [alert beginSheetModalForWindow:self.window completionHandler:^void (NSModalResponse response) {
 | 
						||
+        [input validateEditing];
 | 
						||
+        completionHandler(response == NSAlertFirstButtonReturn ? [input stringValue] : nil);
 | 
						||
+        [alert release];
 | 
						||
+        _alert = nil;
 | 
						||
+    }];
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (void)webView:(WKWebView *)webView handleJavaScriptDialog:(BOOL)accept value:(NSString *)value
 | 
						||
+{
 | 
						||
+    if (!_alert)
 | 
						||
+        return;
 | 
						||
+    NSTextField* input = (NSTextField*)_alert.accessoryView;
 | 
						||
+    if (accept && input && value)
 | 
						||
+        [input setStringValue:value];
 | 
						||
+    [self.window endSheet:_alert.window returnCode: accept ? NSAlertFirstButtonReturn : NSModalResponseCancel];
 | 
						||
+}
 | 
						||
+
 | 
						||
+#if __has_feature(objc_generics)
 | 
						||
+- (void)webView:(WKWebView *)webView runOpenPanelWithParameters:(WKOpenPanelParameters *)parameters initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSArray<NSURL *> * URLs))completionHandler
 | 
						||
+#else
 | 
						||
+- (void)webView:(WKWebView *)webView runOpenPanelWithParameters:(WKOpenPanelParameters *)parameters initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSArray *URLs))completionHandler
 | 
						||
+#endif
 | 
						||
+{
 | 
						||
+    NSOpenPanel *openPanel = [NSOpenPanel openPanel];
 | 
						||
+
 | 
						||
+    openPanel.allowsMultipleSelection = parameters.allowsMultipleSelection;
 | 
						||
+
 | 
						||
+    [openPanel beginSheetModalForWindow:webView.window completionHandler:^(NSInteger result) {
 | 
						||
+        if (result == NSModalResponseOK)
 | 
						||
+            completionHandler(openPanel.URLs);
 | 
						||
+        else
 | 
						||
+            completionHandler(nil);
 | 
						||
+    }];
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (void)_webView:(WebView *)sender runBeforeUnloadConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler
 | 
						||
+{
 | 
						||
+    NSAlert *alert = [[NSAlert alloc] init];
 | 
						||
+
 | 
						||
+    alert.messageText = [NSString stringWithFormat:@"JavaScript before unload dialog from %@.", [frame.request.URL absoluteString]];
 | 
						||
+    alert.informativeText = message;
 | 
						||
+
 | 
						||
+    [alert addButtonWithTitle:@"Leave Page"];
 | 
						||
+    [alert addButtonWithTitle:@"Stay On Page"];
 | 
						||
+
 | 
						||
+    _alert = alert;
 | 
						||
+    [alert beginSheetModalForWindow:self.window completionHandler:^void (NSModalResponse response) {
 | 
						||
+        completionHandler(response == NSAlertFirstButtonReturn);
 | 
						||
+        [alert release];
 | 
						||
+        _alert = nil;
 | 
						||
+    }];
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (WKDragDestinationAction)_webView:(WKWebView *)webView dragDestinationActionMaskForDraggingInfo:(id)draggingInfo
 | 
						||
+{
 | 
						||
+    return WKDragDestinationActionAny;
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (void)updateTextFieldFromURL:(NSURL *)URL
 | 
						||
+{
 | 
						||
+    if (!URL)
 | 
						||
+        return;
 | 
						||
+
 | 
						||
+    if (!URL.absoluteString.length)
 | 
						||
+        return;
 | 
						||
+
 | 
						||
+    urlText.stringValue = [URL _web_userVisibleString];
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (void)loadURLString:(NSString *)urlString
 | 
						||
+{
 | 
						||
+    // FIXME: We shouldn't have to set the url text here.
 | 
						||
+    [urlText setStringValue:urlString];
 | 
						||
+    [self fetch:nil];
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (void)loadHTMLString:(NSString *)HTMLString
 | 
						||
+{
 | 
						||
+    [_webView loadHTMLString:HTMLString baseURL:nil];
 | 
						||
+}
 | 
						||
+
 | 
						||
+static NSSet *dataTypes()
 | 
						||
+{
 | 
						||
+    return [WKWebsiteDataStore allWebsiteDataTypes];
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (IBAction)fetchWebsiteData:(id)sender
 | 
						||
+{
 | 
						||
+    [_configuration.websiteDataStore _fetchDataRecordsOfTypes:dataTypes() withOptions:_WKWebsiteDataStoreFetchOptionComputeSizes completionHandler:^(NSArray *websiteDataRecords) {
 | 
						||
+        NSLog(@"did fetch website data %@.", websiteDataRecords);
 | 
						||
+    }];
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (IBAction)fetchAndClearWebsiteData:(id)sender
 | 
						||
+{
 | 
						||
+    [_configuration.websiteDataStore fetchDataRecordsOfTypes:dataTypes() completionHandler:^(NSArray *websiteDataRecords) {
 | 
						||
+        [_configuration.websiteDataStore removeDataOfTypes:dataTypes() forDataRecords:websiteDataRecords completionHandler:^{
 | 
						||
+            [_configuration.websiteDataStore fetchDataRecordsOfTypes:dataTypes() completionHandler:^(NSArray *websiteDataRecords) {
 | 
						||
+                NSLog(@"did clear website data, after clearing data is %@.", websiteDataRecords);
 | 
						||
+            }];
 | 
						||
+        }];
 | 
						||
+    }];
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (IBAction)clearWebsiteData:(id)sender
 | 
						||
+{
 | 
						||
+    [_configuration.websiteDataStore removeDataOfTypes:dataTypes() modifiedSince:[NSDate distantPast] completionHandler:^{
 | 
						||
+        NSLog(@"Did clear website data.");
 | 
						||
+    }];
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (IBAction)printWebView:(id)sender
 | 
						||
+{
 | 
						||
+    [[_webView printOperationWithPrintInfo:[NSPrintInfo sharedPrintInfo]] runOperationModalForWindow:self.window delegate:nil didRunSelector:nil contextInfo:nil];
 | 
						||
+}
 | 
						||
+
 | 
						||
+#pragma mark WKNavigationDelegate
 | 
						||
+
 | 
						||
+- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
 | 
						||
+{
 | 
						||
+    LOG(@"decidePolicyForNavigationAction");
 | 
						||
+
 | 
						||
+    if (navigationAction._canHandleRequest) {
 | 
						||
+        decisionHandler(WKNavigationActionPolicyAllow);
 | 
						||
+        return;
 | 
						||
+    }
 | 
						||
+    decisionHandler(WKNavigationActionPolicyCancel);
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler
 | 
						||
+{
 | 
						||
+    LOG(@"decidePolicyForNavigationResponse");
 | 
						||
+    decisionHandler(WKNavigationResponsePolicyAllow);
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation
 | 
						||
+{
 | 
						||
+    LOG(@"didStartProvisionalNavigation: %@", navigation);
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation
 | 
						||
+{
 | 
						||
+    LOG(@"didReceiveServerRedirectForProvisionalNavigation: %@", navigation);
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error
 | 
						||
+{
 | 
						||
+    LOG(@"didFailProvisionalNavigation: %@navigation, error: %@", navigation, error);
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation
 | 
						||
+{
 | 
						||
+    LOG(@"didCommitNavigation: %@", navigation);
 | 
						||
+    [self updateTitle:nil];
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
 | 
						||
+{
 | 
						||
+    LOG(@"didFinishNavigation: %@", navigation);
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *__nullable credential))completionHandler
 | 
						||
+{
 | 
						||
+    LOG(@"didReceiveAuthenticationChallenge: %@", challenge);
 | 
						||
+    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodHTTPBasic]) {
 | 
						||
+        NSAlert *alert = [[NSAlert alloc] init];
 | 
						||
+        NSView *container = [[[NSView alloc] initWithFrame:NSMakeRect(0, 0, 200, 48)] autorelease];
 | 
						||
+        NSTextField *userInput = [[[NSTextField alloc] initWithFrame:NSMakeRect(0, 24, 200, 24)] autorelease];
 | 
						||
+        NSTextField *passwordInput = [[[NSSecureTextField alloc] initWithFrame:NSMakeRect(0, 0, 200, 24)] autorelease];
 | 
						||
+
 | 
						||
+        [alert setMessageText:[NSString stringWithFormat:@"Log in to %@:%lu.", challenge.protectionSpace.host, challenge.protectionSpace.port]];
 | 
						||
+        [alert addButtonWithTitle:@"Log in"];
 | 
						||
+        [alert addButtonWithTitle:@"Cancel"];
 | 
						||
+        [container addSubview:userInput];
 | 
						||
+        [container addSubview:passwordInput];
 | 
						||
+        [alert setAccessoryView:container];
 | 
						||
+        [userInput setNextKeyView:passwordInput];
 | 
						||
+        [alert.window setInitialFirstResponder:userInput];
 | 
						||
+
 | 
						||
+        [alert beginSheetModalForWindow:self.window completionHandler:^(NSModalResponse response) {
 | 
						||
+            [userInput validateEditing];
 | 
						||
+            if (response == NSAlertFirstButtonReturn)
 | 
						||
+                completionHandler(NSURLSessionAuthChallengeUseCredential, [[[NSURLCredential alloc] initWithUser:[userInput stringValue] password:[passwordInput stringValue] persistence:NSURLCredentialPersistenceForSession] autorelease]);
 | 
						||
+            else
 | 
						||
+                completionHandler(NSURLSessionAuthChallengeRejectProtectionSpace, nil);
 | 
						||
+            [alert release];
 | 
						||
+        }];
 | 
						||
+        return;
 | 
						||
+    }
 | 
						||
+    completionHandler(NSURLSessionAuthChallengeRejectProtectionSpace, nil);
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error
 | 
						||
+{
 | 
						||
+    LOG(@"didFailNavigation: %@, error %@", navigation, error);
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView
 | 
						||
+{
 | 
						||
+    NSLog(@"WebContent process crashed; reloading");
 | 
						||
+    [self reload:nil];
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (void)_webView:(WKWebView *)webView renderingProgressDidChange:(_WKRenderingProgressEvents)progressEvents
 | 
						||
+{
 | 
						||
+    if (progressEvents & _WKRenderingProgressEventFirstLayout)
 | 
						||
+        LOG(@"renderingProgressDidChange: %@", @"first layout");
 | 
						||
+
 | 
						||
+    if (progressEvents & _WKRenderingProgressEventFirstVisuallyNonEmptyLayout)
 | 
						||
+        LOG(@"renderingProgressDidChange: %@", @"first visually non-empty layout");
 | 
						||
+
 | 
						||
+    if (progressEvents & _WKRenderingProgressEventFirstPaintWithSignificantArea)
 | 
						||
+        LOG(@"renderingProgressDidChange: %@", @"first paint with significant area");
 | 
						||
+
 | 
						||
+    if (progressEvents & _WKRenderingProgressEventFirstLayoutAfterSuppressedIncrementalRendering)
 | 
						||
+        LOG(@"renderingProgressDidChange: %@", @"first layout after suppressed incremental rendering");
 | 
						||
+
 | 
						||
+    if (progressEvents & _WKRenderingProgressEventFirstPaintAfterSuppressedIncrementalRendering)
 | 
						||
+        LOG(@"renderingProgressDidChange: %@", @"first paint after suppressed incremental rendering");
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (void)webView:(WKWebView *)webView shouldLoadIconWithParameters:(_WKLinkIconParameters *)parameters completionHandler:(void (^)(void (^)(NSData*)))completionHandler
 | 
						||
+{
 | 
						||
+    completionHandler(^void (NSData *data) {
 | 
						||
+        LOG(@"Icon URL %@ received icon data of length %u", parameters.url, (unsigned)data.length);
 | 
						||
+    });
 | 
						||
+}
 | 
						||
+
 | 
						||
+#pragma mark Find in Page
 | 
						||
+
 | 
						||
+- (IBAction)performTextFinderAction:(id)sender
 | 
						||
+{
 | 
						||
+    [_textFinder performAction:[sender tag]];
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (NSView *)findBarView
 | 
						||
+{
 | 
						||
+    return _textFindBarView;
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (void)setFindBarView:(NSView *)findBarView
 | 
						||
+{
 | 
						||
+    _textFindBarView = findBarView;
 | 
						||
+    _findBarVisible = YES;
 | 
						||
+    [_textFindBarView setFrame:NSMakeRect(0, 0, containerView.bounds.size.width, _textFindBarView.frame.size.height)];
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (BOOL)isFindBarVisible
 | 
						||
+{
 | 
						||
+    return _findBarVisible;
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (void)setFindBarVisible:(BOOL)findBarVisible
 | 
						||
+{
 | 
						||
+    _findBarVisible = findBarVisible;
 | 
						||
+    if (findBarVisible)
 | 
						||
+        [containerView addSubview:_textFindBarView];
 | 
						||
+    else
 | 
						||
+        [_textFindBarView removeFromSuperview];
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (NSView *)contentView
 | 
						||
+{
 | 
						||
+    return _webView;
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (void)findBarViewDidChangeHeight
 | 
						||
+{
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (void)_webView:(WKWebView *)webView requestMediaCaptureAuthorization: (_WKCaptureDevices)devices decisionHandler:(void (^)(BOOL authorized))decisionHandler
 | 
						||
+{
 | 
						||
+    decisionHandler(true);
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (void)_webView:(WKWebView *)webView includeSensitiveMediaDeviceDetails:(void (^)(BOOL includeSensitiveDetails))decisionHandler
 | 
						||
+{
 | 
						||
+    decisionHandler(false);
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (IBAction)saveAsPDF:(id)sender
 | 
						||
+{
 | 
						||
+    NSSavePanel *panel = [NSSavePanel savePanel];
 | 
						||
+    panel.allowedFileTypes = @[ @"pdf" ];
 | 
						||
+    [panel beginSheetModalForWindow:self.window completionHandler:^(NSInteger result) {
 | 
						||
+        if (result == NSModalResponseOK) {
 | 
						||
+            [_webView createPDFWithConfiguration:nil completionHandler:^(NSData *pdfSnapshotData, NSError *error) {
 | 
						||
+                [pdfSnapshotData writeToURL:[panel URL] options:0 error:nil];
 | 
						||
+            }];
 | 
						||
+        }
 | 
						||
+    }];
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (IBAction)saveAsWebArchive:(id)sender
 | 
						||
+{
 | 
						||
+    NSSavePanel *panel = [NSSavePanel savePanel];
 | 
						||
+    panel.allowedFileTypes = @[ @"webarchive" ];
 | 
						||
+    [panel beginSheetModalForWindow:self.window completionHandler:^(NSInteger result) {
 | 
						||
+        if (result == NSModalResponseOK) {
 | 
						||
+            [_webView createWebArchiveDataWithCompletionHandler:^(NSData *archiveData, NSError *error) {
 | 
						||
+                [archiveData writeToURL:[panel URL] options:0 error:nil];
 | 
						||
+            }];
 | 
						||
+        }
 | 
						||
+    }];
 | 
						||
+}
 | 
						||
+
 | 
						||
+- (WKWebView *)webView
 | 
						||
+{
 | 
						||
+    return _webView;
 | 
						||
+}
 | 
						||
+
 | 
						||
+@end
 | 
						||
diff --git a/Tools/Playwright/mac/CMakeLists.txt b/Tools/Playwright/mac/CMakeLists.txt
 | 
						||
new file mode 100644
 | 
						||
index 0000000000000000000000000000000000000000..410d47425b79367114b17274355350894a70a5e6
 | 
						||
--- /dev/null
 | 
						||
+++ b/Tools/Playwright/mac/CMakeLists.txt
 | 
						||
@@ -0,0 +1,43 @@
 | 
						||
+set(PLAYWRIGHT_DIR "${TOOLS_DIR}/Playwright/mac")
 | 
						||
+
 | 
						||
+#FIXME: This should not need WEBCORE_EXPORT defined.  This means we are including WebCore headers, and we should not.
 | 
						||
+add_definitions("-include Playwright_Prefix.pch -DWEBCORE_EXPORT=")
 | 
						||
+
 | 
						||
+set(Playwright_SOURCES
 | 
						||
+    ${PLAYWRIGHT_DIR}/AppDelegate.m
 | 
						||
+    ${PLAYWRIGHT_DIR}/BrowserWindowController.m
 | 
						||
+    ${PLAYWRIGHT_DIR}/main.m
 | 
						||
+    ${TOOLS_DIR}/Playwright/MBToolbarItem.m
 | 
						||
+)
 | 
						||
+
 | 
						||
+set(Playwright_INCLUDE_DIRECTORIES
 | 
						||
+    ${CMAKE_SOURCE_DIR}/Source
 | 
						||
+    ${FORWARDING_HEADERS_DIR}
 | 
						||
+    ${PLAYWRIGHT_DIR}
 | 
						||
+)
 | 
						||
+
 | 
						||
+set(Playwright_LIBRARIES
 | 
						||
+    WebKit
 | 
						||
+)
 | 
						||
+
 | 
						||
+set(CMAKE_EXE_LINKER_FLAGS "-framework Cocoa")
 | 
						||
+
 | 
						||
+set(EXECUTABLE_NAME Playwright)
 | 
						||
+set(PRODUCT_NAME Playwright)
 | 
						||
+
 | 
						||
+set(Playwright_Contents_Directory ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Playwright.app/Contents)
 | 
						||
+make_directory(${Playwright_Contents_Directory}/Resources)
 | 
						||
+add_custom_command(OUTPUT ${Playwright_Contents_Directory}/Resources/BrowserWindow.nib
 | 
						||
+    COMMAND ibtool --compile ${Playwright_Contents_Directory}/Resources/BrowserWindow.nib ${PLAYWRIGHT_DIR}/BrowserWindow.xib VERBATIM)
 | 
						||
+add_custom_command(OUTPUT ${Playwright_Contents_Directory}/Resources/MainMenu.nib
 | 
						||
+    COMMAND ibtool --compile ${Playwright_Contents_Directory}/Resources/MainMenu.nib ${PLAYWRIGHT_DIR}/MainMenu.xib VERBATIM)
 | 
						||
+add_custom_target(PlaywrightNibs ALL DEPENDS
 | 
						||
+    ${Playwright_Contents_Directory}/Resources/BrowserWindow.nib
 | 
						||
+    ${Playwright_Contents_Directory}/Resources/MainMenu.nib
 | 
						||
+)
 | 
						||
+
 | 
						||
+include_directories(${Playwright_INCLUDE_DIRECTORIES})
 | 
						||
+add_executable(Playwright MACOSX_BUNDLE ${Playwright_SOURCES})
 | 
						||
+set_target_properties(Playwright PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${PLAYWRIGHT_DIR}/Info.plist)
 | 
						||
+target_link_libraries(Playwright ${Playwright_LIBRARIES})
 | 
						||
+add_dependencies(Playwright PlaywrightNibs)
 | 
						||
diff --git a/Tools/Playwright/mac/Info.plist b/Tools/Playwright/mac/Info.plist
 | 
						||
new file mode 100644
 | 
						||
index 0000000000000000000000000000000000000000..4ed50c40f2f0dfd0ddf7c546b3451ab426c0501e
 | 
						||
--- /dev/null
 | 
						||
+++ b/Tools/Playwright/mac/Info.plist
 | 
						||
@@ -0,0 +1,56 @@
 | 
						||
+<?xml version="1.0" encoding="UTF-8"?>
 | 
						||
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 | 
						||
+<plist version="1.0">
 | 
						||
+<dict>
 | 
						||
+	<key>CFBundleDevelopmentRegion</key>
 | 
						||
+	<string>English</string>
 | 
						||
+	<key>CFBundleExecutable</key>
 | 
						||
+	<string>${EXECUTABLE_NAME}</string>
 | 
						||
+	<key>CFBundleIconFile</key>
 | 
						||
+	<string>WebKit Browser</string>
 | 
						||
+	<key>CFBundleIdentifier</key>
 | 
						||
+	<string>${PRODUCT_BUNDLE_IDENTIFIER}</string>
 | 
						||
+	<key>CFBundleInfoDictionaryVersion</key>
 | 
						||
+	<string>6.0</string>
 | 
						||
+	<key>CFBundleName</key>
 | 
						||
+	<string>${PRODUCT_NAME}</string>
 | 
						||
+	<key>CFBundlePackageType</key>
 | 
						||
+	<string>APPL</string>
 | 
						||
+	<key>CFBundleSignature</key>
 | 
						||
+	<string>????</string>
 | 
						||
+	<key>CFBundleShortVersionString</key>
 | 
						||
+	<string>1.0</string>
 | 
						||
+	<key>LSMinimumSystemVersion</key>
 | 
						||
+	<string>${MACOSX_DEPLOYMENT_TARGET}</string>
 | 
						||
+	<key>CFBundleVersion</key>
 | 
						||
+	<string>1</string>
 | 
						||
+	<key>NSMainNibFile</key>
 | 
						||
+	<string>MainMenu</string>
 | 
						||
+	<key>NSPrincipalClass</key>
 | 
						||
+	<string>NSApplication</string>
 | 
						||
+	<key>NSAppTransportSecurity</key>
 | 
						||
+	<dict>
 | 
						||
+		<key>NSAllowsArbitraryLoads</key>
 | 
						||
+		<true/>
 | 
						||
+	</dict>
 | 
						||
+	<key>NSSupportsAutomaticGraphicsSwitching</key>
 | 
						||
+	<true/>
 | 
						||
+	<key>CFBundleDocumentTypes</key>
 | 
						||
+	<array>
 | 
						||
+		<dict>
 | 
						||
+			<key>CFBundleTypeExtensions</key>
 | 
						||
+			<array>
 | 
						||
+				<string>html</string>
 | 
						||
+			</array>
 | 
						||
+			<key>CFBundleTypeMIMETypes</key>
 | 
						||
+			<array>
 | 
						||
+				<string>text/html</string>
 | 
						||
+			</array>
 | 
						||
+			<key>CFBundleTypeName</key>
 | 
						||
+			<string>HTML</string>
 | 
						||
+			<key>CFBundleTypeRole</key>
 | 
						||
+			<string>Editor</string>
 | 
						||
+		</dict>
 | 
						||
+	</array>
 | 
						||
+</dict>
 | 
						||
+</plist>
 | 
						||
diff --git a/Tools/Playwright/mac/MainMenu.xib b/Tools/Playwright/mac/MainMenu.xib
 | 
						||
new file mode 100644
 | 
						||
index 0000000000000000000000000000000000000000..b16d639a1ad18354e058c613987d846acd70b361
 | 
						||
--- /dev/null
 | 
						||
+++ b/Tools/Playwright/mac/MainMenu.xib
 | 
						||
@@ -0,0 +1,333 @@
 | 
						||
+<?xml version="1.0" encoding="UTF-8"?>
 | 
						||
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="15505" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
 | 
						||
+    <dependencies>
 | 
						||
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="15505"/>
 | 
						||
+    </dependencies>
 | 
						||
+    <objects>
 | 
						||
+        <customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
 | 
						||
+            <connections>
 | 
						||
+                <outlet property="delegate" destination="494" id="495"/>
 | 
						||
+            </connections>
 | 
						||
+        </customObject>
 | 
						||
+        <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
 | 
						||
+        <customObject id="-3" userLabel="Application" customClass="NSObject"/>
 | 
						||
+        <menu title="AMainMenu" systemMenu="main" id="29">
 | 
						||
+            <items>
 | 
						||
+                <menuItem title="Playwright" id="56">
 | 
						||
+                    <menu key="submenu" title="Playwright" systemMenu="apple" id="57">
 | 
						||
+                        <items>
 | 
						||
+                            <menuItem title="About Playwright" id="58">
 | 
						||
+                                <modifierMask key="keyEquivalentModifierMask"/>
 | 
						||
+                                <connections>
 | 
						||
+                                    <action selector="orderFrontStandardAboutPanel:" target="-2" id="142"/>
 | 
						||
+                                </connections>
 | 
						||
+                            </menuItem>
 | 
						||
+                            <menuItem isSeparatorItem="YES" id="236">
 | 
						||
+                                <modifierMask key="keyEquivalentModifierMask" command="YES"/>
 | 
						||
+                            </menuItem>
 | 
						||
+                            <menuItem title="Preferences…" keyEquivalent="," id="129"/>
 | 
						||
+                            <menuItem isSeparatorItem="YES" id="143">
 | 
						||
+                                <modifierMask key="keyEquivalentModifierMask" command="YES"/>
 | 
						||
+                            </menuItem>
 | 
						||
+                            <menuItem title="Services" id="131">
 | 
						||
+                                <menu key="submenu" title="Services" systemMenu="services" id="130"/>
 | 
						||
+                            </menuItem>
 | 
						||
+                            <menuItem isSeparatorItem="YES" id="144">
 | 
						||
+                                <modifierMask key="keyEquivalentModifierMask" command="YES"/>
 | 
						||
+                            </menuItem>
 | 
						||
+                            <menuItem title="Hide Playwright" keyEquivalent="h" id="134">
 | 
						||
+                                <connections>
 | 
						||
+                                    <action selector="hide:" target="-1" id="367"/>
 | 
						||
+                                </connections>
 | 
						||
+                            </menuItem>
 | 
						||
+                            <menuItem title="Hide Others" keyEquivalent="h" id="145">
 | 
						||
+                                <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
 | 
						||
+                                <connections>
 | 
						||
+                                    <action selector="hideOtherApplications:" target="-1" id="368"/>
 | 
						||
+                                </connections>
 | 
						||
+                            </menuItem>
 | 
						||
+                            <menuItem title="Show All" id="150">
 | 
						||
+                                <connections>
 | 
						||
+                                    <action selector="unhideAllApplications:" target="-1" id="370"/>
 | 
						||
+                                </connections>
 | 
						||
+                            </menuItem>
 | 
						||
+                            <menuItem isSeparatorItem="YES" id="149">
 | 
						||
+                                <modifierMask key="keyEquivalentModifierMask" command="YES"/>
 | 
						||
+                            </menuItem>
 | 
						||
+                            <menuItem title="Quit Playwright" keyEquivalent="q" id="136">
 | 
						||
+                                <connections>
 | 
						||
+                                    <action selector="terminate:" target="-3" id="449"/>
 | 
						||
+                                </connections>
 | 
						||
+                            </menuItem>
 | 
						||
+                        </items>
 | 
						||
+                    </menu>
 | 
						||
+                </menuItem>
 | 
						||
+                <menuItem title="File" id="83">
 | 
						||
+                    <menu key="submenu" title="File" id="81">
 | 
						||
+                        <items>
 | 
						||
+                            <menuItem title="Open Location " tag="1" keyEquivalent="l" id="82">
 | 
						||
+                                <connections>
 | 
						||
+                                    <action selector="openLocation:" target="-1" id="575"/>
 | 
						||
+                                </connections>
 | 
						||
+                            </menuItem>
 | 
						||
+                            <menuItem isSeparatorItem="YES" id="79">
 | 
						||
+                                <modifierMask key="keyEquivalentModifierMask" command="YES"/>
 | 
						||
+                            </menuItem>
 | 
						||
+                            <menuItem title="Close" keyEquivalent="w" id="73">
 | 
						||
+                                <connections>
 | 
						||
+                                    <action selector="performClose:" target="-1" id="193"/>
 | 
						||
+                                </connections>
 | 
						||
+                            </menuItem>
 | 
						||
+                            <menuItem title="Save" keyEquivalent="s" id="75">
 | 
						||
+                                <connections>
 | 
						||
+                                    <action selector="saveDocument:" target="-1" id="362"/>
 | 
						||
+                                </connections>
 | 
						||
+                            </menuItem>
 | 
						||
+                            <menuItem title="Save As…" keyEquivalent="S" id="80">
 | 
						||
+                                <modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
 | 
						||
+                                <connections>
 | 
						||
+                                    <action selector="saveDocumentAs:" target="-1" id="363"/>
 | 
						||
+                                </connections>
 | 
						||
+                            </menuItem>
 | 
						||
+                            <menuItem title="Save As PDF…" keyEquivalent="S" id="gmS-3Q-oLs">
 | 
						||
+                                <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
 | 
						||
+                                <connections>
 | 
						||
+                                    <action selector="saveAsPDF:" target="-1" id="25T-Id-334"/>
 | 
						||
+                                </connections>
 | 
						||
+                            </menuItem>
 | 
						||
+                            <menuItem title="Save As WebArchive..." id="112">
 | 
						||
+                                <modifierMask key="keyEquivalentModifierMask"/>
 | 
						||
+                                <connections>
 | 
						||
+                                    <action selector="saveAsWebArchive:" target="-1" id="AGx-3e-6Nt"/>
 | 
						||
+                                </connections>
 | 
						||
+                            </menuItem>
 | 
						||
+                            <menuItem isSeparatorItem="YES" id="74">
 | 
						||
+                                <modifierMask key="keyEquivalentModifierMask" command="YES"/>
 | 
						||
+                            </menuItem>
 | 
						||
+                            <menuItem title="Page Setup..." keyEquivalent="P" id="77">
 | 
						||
+                                <modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
 | 
						||
+                                <connections>
 | 
						||
+                                    <action selector="runPageLayout:" target="-1" id="87"/>
 | 
						||
+                                </connections>
 | 
						||
+                            </menuItem>
 | 
						||
+                            <menuItem title="Print…" keyEquivalent="p" id="78">
 | 
						||
+                                <connections>
 | 
						||
+                                    <action selector="printWebView:" target="-1" id="86"/>
 | 
						||
+                                </connections>
 | 
						||
+                            </menuItem>
 | 
						||
+                        </items>
 | 
						||
+                    </menu>
 | 
						||
+                </menuItem>
 | 
						||
+                <menuItem title="Edit" id="217">
 | 
						||
+                    <menu key="submenu" title="Edit" id="205">
 | 
						||
+                        <items>
 | 
						||
+                            <menuItem title="Undo" keyEquivalent="z" id="207">
 | 
						||
+                                <connections>
 | 
						||
+                                    <action selector="undo:" target="-1" id="223"/>
 | 
						||
+                                </connections>
 | 
						||
+                            </menuItem>
 | 
						||
+                            <menuItem title="Redo" keyEquivalent="Z" id="215">
 | 
						||
+                                <modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
 | 
						||
+                                <connections>
 | 
						||
+                                    <action selector="redo:" target="-1" id="231"/>
 | 
						||
+                                </connections>
 | 
						||
+                            </menuItem>
 | 
						||
+                            <menuItem isSeparatorItem="YES" id="206">
 | 
						||
+                                <modifierMask key="keyEquivalentModifierMask" command="YES"/>
 | 
						||
+                            </menuItem>
 | 
						||
+                            <menuItem title="Cut" keyEquivalent="x" id="199">
 | 
						||
+                                <connections>
 | 
						||
+                                    <action selector="cut:" target="-1" id="228"/>
 | 
						||
+                                </connections>
 | 
						||
+                            </menuItem>
 | 
						||
+                            <menuItem title="Copy" keyEquivalent="c" id="197">
 | 
						||
+                                <connections>
 | 
						||
+                                    <action selector="copy:" target="-1" id="224"/>
 | 
						||
+                                </connections>
 | 
						||
+                            </menuItem>
 | 
						||
+                            <menuItem title="Paste" keyEquivalent="v" id="203">
 | 
						||
+                                <connections>
 | 
						||
+                                    <action selector="paste:" target="-1" id="226"/>
 | 
						||
+                                </connections>
 | 
						||
+                            </menuItem>
 | 
						||
+                            <menuItem title="Delete" id="202">
 | 
						||
+                                <connections>
 | 
						||
+                                    <action selector="delete:" target="-1" id="235"/>
 | 
						||
+                                </connections>
 | 
						||
+                            </menuItem>
 | 
						||
+                            <menuItem title="Select All" keyEquivalent="a" id="198">
 | 
						||
+                                <connections>
 | 
						||
+                                    <action selector="selectAll:" target="-1" id="232"/>
 | 
						||
+                                </connections>
 | 
						||
+                            </menuItem>
 | 
						||
+                            <menuItem isSeparatorItem="YES" id="214">
 | 
						||
+                                <modifierMask key="keyEquivalentModifierMask" command="YES"/>
 | 
						||
+                            </menuItem>
 | 
						||
+                            <menuItem title="Find" id="218">
 | 
						||
+                                <menu key="submenu" title="Find" id="220">
 | 
						||
+                                    <items>
 | 
						||
+                                        <menuItem title="Find…" tag="1" keyEquivalent="f" id="209">
 | 
						||
+                                            <connections>
 | 
						||
+                                                <action selector="performTextFinderAction:" target="-1" id="241"/>
 | 
						||
+                                            </connections>
 | 
						||
+                                        </menuItem>
 | 
						||
+                                        <menuItem title="Find Next" tag="2" keyEquivalent="g" id="208">
 | 
						||
+                                            <connections>
 | 
						||
+                                                <action selector="performTextFinderAction:" target="-1" id="487"/>
 | 
						||
+                                            </connections>
 | 
						||
+                                        </menuItem>
 | 
						||
+                                        <menuItem title="Find Previous" tag="3" keyEquivalent="G" id="213">
 | 
						||
+                                            <modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
 | 
						||
+                                            <connections>
 | 
						||
+                                                <action selector="performTextFinderAction:" target="-1" id="488"/>
 | 
						||
+                                            </connections>
 | 
						||
+                                        </menuItem>
 | 
						||
+                                        <menuItem title="Use Selection for Find" tag="7" keyEquivalent="e" id="221">
 | 
						||
+                                            <connections>
 | 
						||
+                                                <action selector="performTextFinderAction:" target="-1" id="489"/>
 | 
						||
+                                            </connections>
 | 
						||
+                                        </menuItem>
 | 
						||
+                                        <menuItem title="Jump to Selection" keyEquivalent="j" id="210">
 | 
						||
+                                            <connections>
 | 
						||
+                                                <action selector="centerSelectionInVisibleArea:" target="-1" id="245"/>
 | 
						||
+                                            </connections>
 | 
						||
+                                        </menuItem>
 | 
						||
+                                    </items>
 | 
						||
+                                </menu>
 | 
						||
+                            </menuItem>
 | 
						||
+                        </items>
 | 
						||
+                    </menu>
 | 
						||
+                </menuItem>
 | 
						||
+                <menuItem title="View" id="295">
 | 
						||
+                    <menu key="submenu" title="View" id="296">
 | 
						||
+                        <items>
 | 
						||
+                            <menuItem title="Zoom In" keyEquivalent="+" id="555">
 | 
						||
+                                <connections>
 | 
						||
+                                    <action selector="zoomIn:" target="-1" id="559"/>
 | 
						||
+                                </connections>
 | 
						||
+                            </menuItem>
 | 
						||
+                            <menuItem title="Zoom Out" keyEquivalent="-" id="557">
 | 
						||
+                                <connections>
 | 
						||
+                                    <action selector="zoomOut:" target="-1" id="560"/>
 | 
						||
+                                </connections>
 | 
						||
+                            </menuItem>
 | 
						||
+                            <menuItem title="Reset Zoom" keyEquivalent="0" id="558">
 | 
						||
+                                <connections>
 | 
						||
+                                    <action selector="resetZoom:" target="-1" id="561"/>
 | 
						||
+                                </connections>
 | 
						||
+                            </menuItem>
 | 
						||
+                            <menuItem title="Zoom Text Only" id="562">
 | 
						||
+                                <modifierMask key="keyEquivalentModifierMask"/>
 | 
						||
+                                <connections>
 | 
						||
+                                    <action selector="toggleZoomMode:" target="-1" id="564"/>
 | 
						||
+                                </connections>
 | 
						||
+                            </menuItem>
 | 
						||
+                            <menuItem title="Page Scale" id="Hzb-c3-Qfv">
 | 
						||
+                                <modifierMask key="keyEquivalentModifierMask"/>
 | 
						||
+                                <menu key="submenu" title="Page Scale" id="jdo-5V-3CM">
 | 
						||
+                                    <items>
 | 
						||
+                                        <menuItem title="100%" state="on" tag="1" keyEquivalent="1" id="wHb-mR-Fv0">
 | 
						||
+                                            <connections>
 | 
						||
+                                                <action selector="setPageScale:" target="-1" id="uMw-eY-289"/>
 | 
						||
+                                            </connections>
 | 
						||
+                                        </menuItem>
 | 
						||
+                                        <menuItem title="125%" tag="2" keyEquivalent="2" id="u4i-F7-rPb">
 | 
						||
+                                            <connections>
 | 
						||
+                                                <action selector="setPageScale:" target="-1" id="IbE-Ep-hfc"/>
 | 
						||
+                                            </connections>
 | 
						||
+                                        </menuItem>
 | 
						||
+                                        <menuItem title="150%" tag="3" keyEquivalent="3" id="fwT-Iy-oK9">
 | 
						||
+                                            <connections>
 | 
						||
+                                                <action selector="setPageScale:" target="-1" id="9c0-eN-0f5"/>
 | 
						||
+                                            </connections>
 | 
						||
+                                        </menuItem>
 | 
						||
+                                        <menuItem title="200%" tag="4" keyEquivalent="4" id="R5e-ct-O2u">
 | 
						||
+                                            <connections>
 | 
						||
+                                                <action selector="setPageScale:" target="-1" id="mkk-gh-dlN"/>
 | 
						||
+                                            </connections>
 | 
						||
+                                        </menuItem>
 | 
						||
+                                    </items>
 | 
						||
+                                </menu>
 | 
						||
+                            </menuItem>
 | 
						||
+                            <menuItem title="View Scale" id="8UY-Pj-H13">
 | 
						||
+                                <modifierMask key="keyEquivalentModifierMask"/>
 | 
						||
+                                <menu key="submenu" title="View Scale" id="Ml8-mk-ffu">
 | 
						||
+                                    <items>
 | 
						||
+                                        <menuItem title="100%" state="on" tag="1" id="EAm-Xn-VrC">
 | 
						||
+                                            <modifierMask key="keyEquivalentModifierMask"/>
 | 
						||
+                                            <connections>
 | 
						||
+                                                <action selector="setViewScale:" target="-1" id="dkW-CI-RG4"/>
 | 
						||
+                                            </connections>
 | 
						||
+                                        </menuItem>
 | 
						||
+                                        <menuItem title="75%" tag="2" id="jcA-I1-Cbq">
 | 
						||
+                                            <modifierMask key="keyEquivalentModifierMask"/>
 | 
						||
+                                            <connections>
 | 
						||
+                                                <action selector="setViewScale:" target="-1" id="BAF-Ym-IqV"/>
 | 
						||
+                                            </connections>
 | 
						||
+                                        </menuItem>
 | 
						||
+                                        <menuItem title="50%" tag="3" id="BRM-D5-YNO">
 | 
						||
+                                            <modifierMask key="keyEquivalentModifierMask"/>
 | 
						||
+                                            <connections>
 | 
						||
+                                                <action selector="setViewScale:" target="-1" id="nXy-2b-9Zz"/>
 | 
						||
+                                            </connections>
 | 
						||
+                                        </menuItem>
 | 
						||
+                                        <menuItem title="25%" tag="4" id="gzk-YK-x0W">
 | 
						||
+                                            <modifierMask key="keyEquivalentModifierMask"/>
 | 
						||
+                                            <connections>
 | 
						||
+                                                <action selector="setViewScale:" target="-1" id="KXK-f6-24N"/>
 | 
						||
+                                            </connections>
 | 
						||
+                                        </menuItem>
 | 
						||
+                                    </items>
 | 
						||
+                                </menu>
 | 
						||
+                            </menuItem>
 | 
						||
+                            <menuItem title="Reload Page" keyEquivalent="r" id="579">
 | 
						||
+                                <connections>
 | 
						||
+                                    <action selector="reload:" target="-1" id="582"/>
 | 
						||
+                                </connections>
 | 
						||
+                            </menuItem>
 | 
						||
+                        </items>
 | 
						||
+                    </menu>
 | 
						||
+                </menuItem>
 | 
						||
+                <menuItem title="Debug" id="534">
 | 
						||
+                    <modifierMask key="keyEquivalentModifierMask"/>
 | 
						||
+                    <menu key="submenu" title="Debug" id="535">
 | 
						||
+                        <items>
 | 
						||
+                            <menuItem title="Show Web Inspector" keyEquivalent="i" id="xso-9z-R4u">
 | 
						||
+                                <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
 | 
						||
+                                <connections>
 | 
						||
+                                    <action selector="showHideWebInspector:" target="-1" id="Cmx-g7-EPb"/>
 | 
						||
+                                </connections>
 | 
						||
+                            </menuItem>
 | 
						||
+                        </items>
 | 
						||
+                    </menu>
 | 
						||
+                </menuItem>
 | 
						||
+                <menuItem title="Window" id="19">
 | 
						||
+                    <menu key="submenu" title="Window" systemMenu="window" id="24">
 | 
						||
+                        <items>
 | 
						||
+                            <menuItem title="Minimize" keyEquivalent="m" id="23">
 | 
						||
+                                <connections>
 | 
						||
+                                    <action selector="performMiniaturize:" target="-1" id="37"/>
 | 
						||
+                                </connections>
 | 
						||
+                            </menuItem>
 | 
						||
+                            <menuItem title="Zoom" id="239">
 | 
						||
+                                <connections>
 | 
						||
+                                    <action selector="performZoom:" target="-1" id="240"/>
 | 
						||
+                                </connections>
 | 
						||
+                            </menuItem>
 | 
						||
+                            <menuItem isSeparatorItem="YES" id="92">
 | 
						||
+                                <modifierMask key="keyEquivalentModifierMask" command="YES"/>
 | 
						||
+                            </menuItem>
 | 
						||
+                            <menuItem title="Bring All to Front" id="5">
 | 
						||
+                                <connections>
 | 
						||
+                                    <action selector="arrangeInFront:" target="-1" id="39"/>
 | 
						||
+                                </connections>
 | 
						||
+                            </menuItem>
 | 
						||
+                        </items>
 | 
						||
+                    </menu>
 | 
						||
+                </menuItem>
 | 
						||
+            </items>
 | 
						||
+            <point key="canvasLocation" x="139" y="-50"/>
 | 
						||
+        </menu>
 | 
						||
+        <customObject id="494" customClass="BrowserAppDelegate"/>
 | 
						||
+    </objects>
 | 
						||
+</document>
 | 
						||
diff --git a/Tools/Playwright/mac/Playwright_Prefix.pch b/Tools/Playwright/mac/Playwright_Prefix.pch
 | 
						||
new file mode 100644
 | 
						||
index 0000000000000000000000000000000000000000..ab6e9bce9a41291bb35664c2c63751c3413601f2
 | 
						||
--- /dev/null
 | 
						||
+++ b/Tools/Playwright/mac/Playwright_Prefix.pch
 | 
						||
@@ -0,0 +1,37 @@
 | 
						||
+/*
 | 
						||
+ * Copyright (C) 2010 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. 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.
 | 
						||
+ */
 | 
						||
+
 | 
						||
+#ifdef __OBJC__
 | 
						||
+#import <Cocoa/Cocoa.h>
 | 
						||
+#import <WebKit/WebKit.h>
 | 
						||
+#endif
 | 
						||
+
 | 
						||
+#define ENABLE_LOGGING 0
 | 
						||
+
 | 
						||
+#if ENABLE_LOGGING
 | 
						||
+#define LOG NSLog
 | 
						||
+#else
 | 
						||
+#define LOG(...) ((void)0)
 | 
						||
+#endif
 | 
						||
diff --git a/Tools/Playwright/mac/main.m b/Tools/Playwright/mac/main.m
 | 
						||
new file mode 100644
 | 
						||
index 0000000000000000000000000000000000000000..ba2ca12482c0ab809998131f693c876019c595f1
 | 
						||
--- /dev/null
 | 
						||
+++ b/Tools/Playwright/mac/main.m
 | 
						||
@@ -0,0 +1,33 @@
 | 
						||
+/*
 | 
						||
+ * Copyright (C) 2010 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. 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.
 | 
						||
+ */
 | 
						||
+
 | 
						||
+#import <Cocoa/Cocoa.h>
 | 
						||
+
 | 
						||
+int main(int argc, char *argv[])
 | 
						||
+{
 | 
						||
+    [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"WebKitLinkedOnOrAfterEverything"];
 | 
						||
+
 | 
						||
+    return NSApplicationMain(argc,  (const char **) argv);
 | 
						||
+}
 | 
						||
diff --git a/Tools/Scripts/build-webkit b/Tools/Scripts/build-webkit
 | 
						||
index fc0664a6505546f428c7514b9675119b75a62140..14556b3742856ba88d9363957ea97f337fe63191 100755
 | 
						||
--- a/Tools/Scripts/build-webkit
 | 
						||
+++ b/Tools/Scripts/build-webkit
 | 
						||
@@ -246,7 +246,7 @@ if (isAppleCocoaWebKit()) {
 | 
						||
     push @projects, ("Source/WebKit");
 | 
						||
 
 | 
						||
     if (!isIOSWebKit()) {
 | 
						||
-        push @projects, ("Tools/MiniBrowser");
 | 
						||
+        push @projects, ("Tools/Playwright");
 | 
						||
 
 | 
						||
         # WebInspectorUI must come after JavaScriptCore and WebCore but before WebKit and WebKit2
 | 
						||
         my $webKitIndex = first { $projects[$_] eq "Source/WebKitLegacy" } 0..$#projects;
 | 
						||
diff --git a/Tools/WebKitTestRunner/TestController.cpp b/Tools/WebKitTestRunner/TestController.cpp
 | 
						||
index 71c358a27de26c8fc9e68e72fc6753a52a6a927e..1f561a039ff72ca5b1bce17d138c6e5ec62e4a3f 100644
 | 
						||
--- a/Tools/WebKitTestRunner/TestController.cpp
 | 
						||
+++ b/Tools/WebKitTestRunner/TestController.cpp
 | 
						||
@@ -727,7 +727,8 @@ void TestController::createWebViewWithOptions(const TestOptions& options)
 | 
						||
         0, // didResignInputElementStrongPasswordAppearance
 | 
						||
         0, // requestStorageAccessConfirm
 | 
						||
         shouldAllowDeviceOrientationAndMotionAccess,
 | 
						||
-        runWebAuthenticationPanel
 | 
						||
+        runWebAuthenticationPanel,
 | 
						||
+        0 // handleJavaScriptDialog
 | 
						||
     };
 | 
						||
     WKPageSetPageUIClient(m_mainWebView->page(), &pageUIClient.base);
 | 
						||
 
 | 
						||
diff --git a/Tools/WebKitTestRunner/win/EventSenderProxyWin.cpp b/Tools/WebKitTestRunner/win/EventSenderProxyWin.cpp
 | 
						||
index 06f19261b387ce02a44c319bd7016e824847ad24..c4e2f8f8816b06a105c18872e735ae4dbca6fe68 100644
 | 
						||
--- a/Tools/WebKitTestRunner/win/EventSenderProxyWin.cpp
 | 
						||
+++ b/Tools/WebKitTestRunner/win/EventSenderProxyWin.cpp
 | 
						||
@@ -312,4 +312,59 @@ void EventSenderProxy::keyDown(WKStringRef keyRef, WKEventModifiers wkModifiers,
 | 
						||
         SetKeyboardState(keyState);
 | 
						||
 }
 | 
						||
 
 | 
						||
+void EventSenderProxy::addTouchPoint(int, int)
 | 
						||
+{
 | 
						||
+    notImplemented();
 | 
						||
+}
 | 
						||
+
 | 
						||
+void EventSenderProxy::updateTouchPoint(int, int, int)
 | 
						||
+{
 | 
						||
+    notImplemented();
 | 
						||
+}
 | 
						||
+
 | 
						||
+void EventSenderProxy::setTouchModifier(WKEventModifiers, bool)
 | 
						||
+{
 | 
						||
+    notImplemented();
 | 
						||
+}
 | 
						||
+
 | 
						||
+void EventSenderProxy::setTouchPointRadius(int, int)
 | 
						||
+{
 | 
						||
+    notImplemented();
 | 
						||
+}
 | 
						||
+
 | 
						||
+void EventSenderProxy::touchStart()
 | 
						||
+{
 | 
						||
+    notImplemented();
 | 
						||
+}
 | 
						||
+
 | 
						||
+void EventSenderProxy::touchMove()
 | 
						||
+{
 | 
						||
+    notImplemented();
 | 
						||
+}
 | 
						||
+
 | 
						||
+void EventSenderProxy::touchEnd()
 | 
						||
+{
 | 
						||
+    notImplemented();
 | 
						||
+}
 | 
						||
+
 | 
						||
+void EventSenderProxy::touchCancel()
 | 
						||
+{
 | 
						||
+    notImplemented();
 | 
						||
+}
 | 
						||
+
 | 
						||
+void EventSenderProxy::clearTouchPoints()
 | 
						||
+{
 | 
						||
+    notImplemented();
 | 
						||
+}
 | 
						||
+
 | 
						||
+void EventSenderProxy::releaseTouchPoint(int)
 | 
						||
+{
 | 
						||
+    notImplemented();
 | 
						||
+}
 | 
						||
+
 | 
						||
+void EventSenderProxy::cancelTouchPoint(int)
 | 
						||
+{
 | 
						||
+    notImplemented();
 | 
						||
+}
 | 
						||
+
 | 
						||
 } // namespace WTR
 | 
						||
diff --git a/Tools/wpe/backends/CMakeLists.txt b/Tools/wpe/backends/CMakeLists.txt
 | 
						||
index 6456f4408c95b22246817912d430c42fc982932b..a08cc6da1936127a516fe0e95007de9cd18bdb02 100644
 | 
						||
--- a/Tools/wpe/backends/CMakeLists.txt
 | 
						||
+++ b/Tools/wpe/backends/CMakeLists.txt
 | 
						||
@@ -10,6 +10,7 @@ file(MAKE_DIRECTORY ${DERIVED_SOURCES_WPETOOLINGBACKENDS_DIR})
 | 
						||
 set(WPEToolingBackends_SOURCES
 | 
						||
     ${DERIVED_SOURCES_WPETOOLINGBACKENDS_DIR}/xdg-shell-unstable-v6-protocol.c
 | 
						||
     ${TOOLS_DIR}/wpe/backends/HeadlessViewBackend.cpp
 | 
						||
+    ${TOOLS_DIR}/wpe/backends/NullViewBackend.cpp
 | 
						||
     ${TOOLS_DIR}/wpe/backends/ViewBackend.cpp
 | 
						||
     ${TOOLS_DIR}/wpe/backends/WebKitAccessibleApplication.cpp
 | 
						||
     ${TOOLS_DIR}/wpe/backends/WindowViewBackend.cpp
 | 
						||
diff --git a/Tools/wpe/backends/NullViewBackend.cpp b/Tools/wpe/backends/NullViewBackend.cpp
 | 
						||
new file mode 100644
 | 
						||
index 0000000000000000000000000000000000000000..033ff802d3971a455667cd64c0e68dd10f448aa7
 | 
						||
--- /dev/null
 | 
						||
+++ b/Tools/wpe/backends/NullViewBackend.cpp
 | 
						||
@@ -0,0 +1,41 @@
 | 
						||
+/*
 | 
						||
+ * Copyright (C) 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 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 "NullViewBackend.h"
 | 
						||
+
 | 
						||
+#include <wpe/fdo-egl.h>
 | 
						||
+
 | 
						||
+namespace WPEToolingBackends {
 | 
						||
+
 | 
						||
+NullViewBackend::NullViewBackend()
 | 
						||
+    : ViewBackend(1, 1)
 | 
						||
+{
 | 
						||
+    static struct wpe_view_backend_exportable_fdo_egl_client exportableClient = { nullptr, nullptr, nullptr, nullptr, nullptr };
 | 
						||
+    m_exportable = wpe_view_backend_exportable_fdo_egl_create(&exportableClient, this, 1, 1);
 | 
						||
+    initializeAccessibility();
 | 
						||
+    addActivityState(wpe_view_activity_state_visible | wpe_view_activity_state_focused | wpe_view_activity_state_in_window);
 | 
						||
+}
 | 
						||
+
 | 
						||
+} // namespace WPEToolingBackends
 | 
						||
diff --git a/Tools/wpe/backends/NullViewBackend.h b/Tools/wpe/backends/NullViewBackend.h
 | 
						||
new file mode 100644
 | 
						||
index 0000000000000000000000000000000000000000..c4489294acfe73adcb3593f2d54a3be625307f28
 | 
						||
--- /dev/null
 | 
						||
+++ b/Tools/wpe/backends/NullViewBackend.h
 | 
						||
@@ -0,0 +1,46 @@
 | 
						||
+/*
 | 
						||
+ * Copyright (C) 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 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 "ViewBackend.h"
 | 
						||
+#include <cairo.h>
 | 
						||
+#include <glib.h>
 | 
						||
+#include <unordered_map>
 | 
						||
+
 | 
						||
+namespace WPEToolingBackends {
 | 
						||
+
 | 
						||
+class NullViewBackend final : public ViewBackend {
 | 
						||
+public:
 | 
						||
+    NullViewBackend();
 | 
						||
+    virtual ~NullViewBackend() = default;
 | 
						||
+private:
 | 
						||
+    void displayBuffer(struct wpe_fdo_egl_exported_image*) override { };
 | 
						||
+#if WPE_FDO_CHECK_VERSION(1, 5, 0)
 | 
						||
+    void displayBuffer(struct wpe_fdo_shm_exported_buffer*) override { };
 | 
						||
+#endif
 | 
						||
+};
 | 
						||
+
 | 
						||
+} // namespace WPEToolingBackends
 |