23090 lines
		
	
	
		
			1000 KiB
		
	
	
	
		
			Diff
		
	
	
	
			
		
		
	
	
			23090 lines
		
	
	
		
			1000 KiB
		
	
	
	
		
			Diff
		
	
	
	
| diff --git a/Source/JavaScriptCore/CMakeLists.txt b/Source/JavaScriptCore/CMakeLists.txt
 | |
| index cc949e8304d49f72552cc4f11f5806f9ac8c313f..3b5137abf27276f2506a944f71e9f3bd6d0a7e6d 100644
 | |
| --- a/Source/JavaScriptCore/CMakeLists.txt
 | |
| +++ b/Source/JavaScriptCore/CMakeLists.txt
 | |
| @@ -1352,22 +1352,27 @@ set(JavaScriptCore_INSPECTOR_DOMAINS
 | |
|      ${JAVASCRIPTCORE_DIR}/inspector/protocol/CSS.json
 | |
|      ${JAVASCRIPTCORE_DIR}/inspector/protocol/Canvas.json
 | |
|      ${JAVASCRIPTCORE_DIR}/inspector/protocol/Console.json
 | |
| +    ${JAVASCRIPTCORE_DIR}/inspector/protocol/Dialog.json
 | |
|      ${JAVASCRIPTCORE_DIR}/inspector/protocol/DOM.json
 | |
|      ${JAVASCRIPTCORE_DIR}/inspector/protocol/DOMDebugger.json
 | |
|      ${JAVASCRIPTCORE_DIR}/inspector/protocol/DOMStorage.json
 | |
|      ${JAVASCRIPTCORE_DIR}/inspector/protocol/Database.json
 | |
|      ${JAVASCRIPTCORE_DIR}/inspector/protocol/Debugger.json
 | |
| +    ${JAVASCRIPTCORE_DIR}/inspector/protocol/Emulation.json
 | |
|      ${JAVASCRIPTCORE_DIR}/inspector/protocol/GenericTypes.json
 | |
|      ${JAVASCRIPTCORE_DIR}/inspector/protocol/Heap.json
 | |
|      ${JAVASCRIPTCORE_DIR}/inspector/protocol/IndexedDB.json
 | |
| +    ${JAVASCRIPTCORE_DIR}/inspector/protocol/Input.json
 | |
|      ${JAVASCRIPTCORE_DIR}/inspector/protocol/Inspector.json
 | |
|      ${JAVASCRIPTCORE_DIR}/inspector/protocol/LayerTree.json
 | |
|      ${JAVASCRIPTCORE_DIR}/inspector/protocol/Memory.json
 | |
|      ${JAVASCRIPTCORE_DIR}/inspector/protocol/Network.json
 | |
|      ${JAVASCRIPTCORE_DIR}/inspector/protocol/Page.json
 | |
| +    ${JAVASCRIPTCORE_DIR}/inspector/protocol/Playwright.json
 | |
|      ${JAVASCRIPTCORE_DIR}/inspector/protocol/Recording.json
 | |
|      ${JAVASCRIPTCORE_DIR}/inspector/protocol/Runtime.json
 | |
|      ${JAVASCRIPTCORE_DIR}/inspector/protocol/ScriptProfiler.json
 | |
| +    ${JAVASCRIPTCORE_DIR}/inspector/protocol/Screencast.json
 | |
|      ${JAVASCRIPTCORE_DIR}/inspector/protocol/Security.json
 | |
|      ${JAVASCRIPTCORE_DIR}/inspector/protocol/ServiceWorker.json
 | |
|      ${JAVASCRIPTCORE_DIR}/inspector/protocol/Target.json
 | |
| diff --git a/Source/JavaScriptCore/DerivedSources.make b/Source/JavaScriptCore/DerivedSources.make
 | |
| index 1fb623cd6f6e8d8987f94804544f0d44e5b35f08..98a74d2b1ca19b044f2f75960e1b5134773f3c14 100644
 | |
| --- a/Source/JavaScriptCore/DerivedSources.make
 | |
| +++ b/Source/JavaScriptCore/DerivedSources.make
 | |
| @@ -291,22 +291,27 @@ INSPECTOR_DOMAINS := \
 | |
|      $(JavaScriptCore)/inspector/protocol/CSS.json \
 | |
|      $(JavaScriptCore)/inspector/protocol/Canvas.json \
 | |
|      $(JavaScriptCore)/inspector/protocol/Console.json \
 | |
| +    $(JavaScriptCore)/inspector/protocol/Dialog.json \
 | |
|      $(JavaScriptCore)/inspector/protocol/DOM.json \
 | |
|      $(JavaScriptCore)/inspector/protocol/DOMDebugger.json \
 | |
|      $(JavaScriptCore)/inspector/protocol/DOMStorage.json \
 | |
|      $(JavaScriptCore)/inspector/protocol/Database.json \
 | |
|      $(JavaScriptCore)/inspector/protocol/Debugger.json \
 | |
| +    $(JavaScriptCore)/inspector/protocol/Emulation.json \
 | |
|      $(JavaScriptCore)/inspector/protocol/GenericTypes.json \
 | |
|      $(JavaScriptCore)/inspector/protocol/Heap.json \
 | |
|      $(JavaScriptCore)/inspector/protocol/IndexedDB.json \
 | |
| +    $(JavaScriptCore)/inspector/protocol/Input.json \
 | |
|      $(JavaScriptCore)/inspector/protocol/Inspector.json \
 | |
|      $(JavaScriptCore)/inspector/protocol/LayerTree.json \
 | |
|      $(JavaScriptCore)/inspector/protocol/Memory.json \
 | |
|      $(JavaScriptCore)/inspector/protocol/Network.json \
 | |
|      $(JavaScriptCore)/inspector/protocol/Page.json \
 | |
| +    $(JavaScriptCore)/inspector/protocol/Playwright.json \
 | |
|      $(JavaScriptCore)/inspector/protocol/Recording.json \
 | |
|      $(JavaScriptCore)/inspector/protocol/Runtime.json \
 | |
|      $(JavaScriptCore)/inspector/protocol/ScriptProfiler.json \
 | |
| +    $(JavaScriptCore)/inspector/protocol/Screencast.json \
 | |
|      $(JavaScriptCore)/inspector/protocol/Security.json \
 | |
|      $(JavaScriptCore)/inspector/protocol/ServiceWorker.json \
 | |
|      $(JavaScriptCore)/inspector/protocol/Target.json \
 | |
| diff --git a/Source/JavaScriptCore/bindings/ScriptValue.cpp b/Source/JavaScriptCore/bindings/ScriptValue.cpp
 | |
| index d28bffd30f21910bb63f515efc6fa9c7749825a4..498ea4b88e0befb9b526c188e079bb5b9882b374 100644
 | |
| --- a/Source/JavaScriptCore/bindings/ScriptValue.cpp
 | |
| +++ b/Source/JavaScriptCore/bindings/ScriptValue.cpp
 | |
| @@ -79,7 +79,10 @@ static RefPtr<JSON::Value> jsToInspectorValue(JSGlobalObject* globalObject, JSVa
 | |
|          PropertyNameArray propertyNames(vm, PropertyNameMode::Strings, PrivateSymbolMode::Exclude);
 | |
|          object.methodTable()->getOwnPropertyNames(&object, globalObject, propertyNames, DontEnumPropertiesMode::Exclude);
 | |
|          for (auto& name : propertyNames) {
 | |
| -            auto inspectorValue = jsToInspectorValue(globalObject, object.get(globalObject, name), maxDepth);
 | |
| +            JSValue childValue = object.get(globalObject, name);
 | |
| +            if (childValue.isUndefined())
 | |
| +                continue;
 | |
| +            auto inspectorValue = jsToInspectorValue(globalObject, childValue, maxDepth);
 | |
|              if (!inspectorValue)
 | |
|                  return nullptr;
 | |
|              inspectorObject->setValue(name.string(), inspectorValue.releaseNonNull());
 | |
| diff --git a/Source/JavaScriptCore/inspector/IdentifiersFactory.cpp b/Source/JavaScriptCore/inspector/IdentifiersFactory.cpp
 | |
| index 18b6dab3b9df38d781c5c767f76a29d8d18dbe02..0f3a341056f429ff282abcab22be4843c60f546c 100644
 | |
| --- a/Source/JavaScriptCore/inspector/IdentifiersFactory.cpp
 | |
| +++ b/Source/JavaScriptCore/inspector/IdentifiersFactory.cpp
 | |
| @@ -32,14 +32,21 @@
 | |
|  namespace Inspector {
 | |
|  
 | |
|  namespace {
 | |
| +static uint64_t s_processID = 0;
 | |
|  static unsigned long s_lastUsedIdentifier = 0;
 | |
|  }
 | |
|  
 | |
|  static String addPrefixToIdentifier(unsigned long identifier)
 | |
|  {
 | |
| -    return makeString("0.", identifier);
 | |
| +    return makeString(s_processID, ".", identifier);
 | |
|  }
 | |
|  
 | |
| +void IdentifiersFactory::initializeWithProcessID(uint64_t processID) {
 | |
| +    ASSERT(!s_processID);
 | |
| +    s_processID = processID;
 | |
| +}
 | |
| +
 | |
| +
 | |
|  String IdentifiersFactory::createIdentifier()
 | |
|  {
 | |
|      return addPrefixToIdentifier(++s_lastUsedIdentifier);
 | |
| diff --git a/Source/JavaScriptCore/inspector/IdentifiersFactory.h b/Source/JavaScriptCore/inspector/IdentifiersFactory.h
 | |
| index eb25aedee4cd9ebe007e06c2515b37ee095b06f4..badf6559595c8377db1089ca3c25008e1be2c8f1 100644
 | |
| --- a/Source/JavaScriptCore/inspector/IdentifiersFactory.h
 | |
| +++ b/Source/JavaScriptCore/inspector/IdentifiersFactory.h
 | |
| @@ -31,6 +31,7 @@ namespace Inspector {
 | |
|  
 | |
|  class JS_EXPORT_PRIVATE IdentifiersFactory {
 | |
|  public:
 | |
| +    static void initializeWithProcessID(uint64_t);
 | |
|      static String createIdentifier();
 | |
|      static String requestId(unsigned long identifier);
 | |
|  };
 | |
| diff --git a/Source/JavaScriptCore/inspector/InjectedScript.cpp b/Source/JavaScriptCore/inspector/InjectedScript.cpp
 | |
| index 8b290faebc1865519b0e7c514f497585dfc0bbda..53c68bca057c85c94201ef8e9870f0cb9e4cef6f 100644
 | |
| --- a/Source/JavaScriptCore/inspector/InjectedScript.cpp
 | |
| +++ b/Source/JavaScriptCore/inspector/InjectedScript.cpp
 | |
| @@ -91,7 +91,7 @@ void InjectedScript::awaitPromise(const String& promiseObjectId, bool returnByVa
 | |
|      makeAsyncCall(function, WTFMove(callback));
 | |
|  }
 | |
|  
 | |
| -void InjectedScript::callFunctionOn(Protocol::ErrorString& errorString, const String& objectId, const String& expression, const String& arguments, bool returnByValue, bool generatePreview, RefPtr<Protocol::Runtime::RemoteObject>& result, std::optional<bool>& wasThrown)
 | |
| +void InjectedScript::callFunctionOn(const String& objectId, const String& expression, const String& arguments, bool returnByValue, bool generatePreview, bool awaitPromise, AsyncCallCallback&& callback)
 | |
|  {
 | |
|      Deprecated::ScriptFunctionCall function(injectedScriptObject(), "callFunctionOn"_s, inspectorEnvironment()->functionCallHandler());
 | |
|      function.appendArgument(objectId);
 | |
| @@ -99,10 +99,8 @@ void InjectedScript::callFunctionOn(Protocol::ErrorString& errorString, const St
 | |
|      function.appendArgument(arguments);
 | |
|      function.appendArgument(returnByValue);
 | |
|      function.appendArgument(generatePreview);
 | |
| -
 | |
| -    std::optional<int> savedResultIndex;
 | |
| -    makeEvalCall(errorString, function, result, wasThrown, savedResultIndex);
 | |
| -    ASSERT(!savedResultIndex);
 | |
| +    function.appendArgument(awaitPromise);
 | |
| +    makeAsyncCall(function, WTFMove(callback));
 | |
|  }
 | |
|  
 | |
|  void InjectedScript::evaluateOnCallFrame(Protocol::ErrorString& errorString, JSC::JSValue callFrames, const String& callFrameId, const String& expression, const String& objectGroup, bool includeCommandLineAPI, bool returnByValue, bool generatePreview, bool saveResult, RefPtr<Protocol::Runtime::RemoteObject>& result, std::optional<bool>& wasThrown, std::optional<int>& savedResultIndex)
 | |
| @@ -289,6 +287,10 @@ RefPtr<Protocol::Runtime::RemoteObject> InjectedScript::wrapObject(JSC::JSValue
 | |
|      auto callResult = callFunctionWithEvalEnabled(wrapFunction);
 | |
|      if (!callResult)
 | |
|          return nullptr;
 | |
| +    auto callResultValue = callResult.value();
 | |
| +    // callResultValue could be missing if the execution was terminated
 | |
| +    if (!callResultValue)
 | |
| +        return nullptr;
 | |
|  
 | |
|      auto resultValue = toInspectorValue(globalObject(), callResult.value());
 | |
|      if (!resultValue)
 | |
| diff --git a/Source/JavaScriptCore/inspector/InjectedScript.h b/Source/JavaScriptCore/inspector/InjectedScript.h
 | |
| index e6b24967273095ae424ac9b3fe5e081ee8999ab7..9f7b72259ab79504b8bfcc24d35abe70d7372065 100644
 | |
| --- a/Source/JavaScriptCore/inspector/InjectedScript.h
 | |
| +++ b/Source/JavaScriptCore/inspector/InjectedScript.h
 | |
| @@ -64,7 +64,7 @@ public:
 | |
|      void evaluate(Protocol::ErrorString&, const String& expression, const String& objectGroup, bool includeCommandLineAPI, bool returnByValue, bool generatePreview, bool saveResult, RefPtr<Protocol::Runtime::RemoteObject>& result, std::optional<bool>& wasThrown, std::optional<int>& savedResultIndex);
 | |
|      void awaitPromise(const String& promiseObjectId, bool returnByValue, bool generatePreview, bool saveResult, AsyncCallCallback&&);
 | |
|      void evaluateOnCallFrame(Protocol::ErrorString&, JSC::JSValue callFrames, const String& callFrameId, const String& expression, const String& objectGroup, bool includeCommandLineAPI, bool returnByValue, bool generatePreview, bool saveResult, RefPtr<Protocol::Runtime::RemoteObject>& result, std::optional<bool>& wasThrown, std::optional<int>& savedResultIndex);
 | |
| -    void callFunctionOn(Protocol::ErrorString&, const String& objectId, const String& expression, const String& arguments, bool returnByValue, bool generatePreview, RefPtr<Protocol::Runtime::RemoteObject>& result, std::optional<bool>& wasThrown);
 | |
| +    void callFunctionOn(const String& objectId, const String& expression, const String& arguments, bool returnByValue, bool generatePreview, bool awaitPromise, AsyncCallCallback&&);
 | |
|      void getFunctionDetails(Protocol::ErrorString&, const String& functionId, RefPtr<Protocol::Debugger::FunctionDetails>& result);
 | |
|      void functionDetails(Protocol::ErrorString&, JSC::JSValue, RefPtr<Protocol::Debugger::FunctionDetails>& result);
 | |
|      void getPreview(Protocol::ErrorString&, const String& objectId, RefPtr<Protocol::Runtime::ObjectPreview>& result);
 | |
| diff --git a/Source/JavaScriptCore/inspector/InjectedScriptSource.js b/Source/JavaScriptCore/inspector/InjectedScriptSource.js
 | |
| index 0080366628c66a5be04024aa560e0d812c27884a..9c325c085feddd42920dce3c71fd60703b670e3f 100644
 | |
| --- a/Source/JavaScriptCore/inspector/InjectedScriptSource.js
 | |
| +++ b/Source/JavaScriptCore/inspector/InjectedScriptSource.js
 | |
| @@ -166,7 +166,7 @@ let InjectedScript = class InjectedScript
 | |
|              return;
 | |
|          }
 | |
|  
 | |
| -        if (!(promiseObject instanceof @Promise)) {
 | |
| +        if (InjectedScriptHost.internalConstructorName(promiseObject) !== 'Promise') {
 | |
|              callback("Object with given id is not a Promise");
 | |
|              return;
 | |
|          }
 | |
| @@ -201,14 +201,16 @@ let InjectedScript = class InjectedScript
 | |
|          return this._evaluateAndWrap(callFrame.evaluateWithScopeExtension, callFrame, expression, objectGroup, isEvalOnCallFrame, includeCommandLineAPI, returnByValue, generatePreview, saveResult);
 | |
|      }
 | |
|  
 | |
| -    callFunctionOn(objectId, expression, args, returnByValue, generatePreview)
 | |
| +    callFunctionOn(objectId, expression, args, returnByValue, generatePreview, awaitPromise, callback)
 | |
|      {
 | |
|          let parsedObjectId = this._parseObjectId(objectId);
 | |
|          let object = this._objectForId(parsedObjectId);
 | |
|          let objectGroupName = this._idToObjectGroupName[parsedObjectId.id];
 | |
|  
 | |
| -        if (!isDefined(object))
 | |
| -            return "Could not find object with given id";
 | |
| +        if (!isDefined(object)) {
 | |
| +            callback(this._createThrownValue("Could not find object with given id", objectGroupName));
 | |
| +            return ;
 | |
| +        }
 | |
|  
 | |
|          let resolvedArgs = @createArrayWithoutPrototype();
 | |
|          if (args) {
 | |
| @@ -217,22 +219,37 @@ let InjectedScript = class InjectedScript
 | |
|                  try {
 | |
|                      resolvedArgs[i] = this._resolveCallArgument(callArgs[i]);
 | |
|                  } catch (e) {
 | |
| -                    return @String(e);
 | |
| +                    callback(this._createThrownValue(e, objectGroupName));
 | |
| +                    return;
 | |
|                  }
 | |
|              }
 | |
|          }
 | |
|  
 | |
|          try {
 | |
|              let func = InjectedScriptHost.evaluate("(" + expression + ")");
 | |
| -            if (typeof func !== "function")
 | |
| -                return "Given expression does not evaluate to a function";
 | |
| -
 | |
| -            return @createObjectWithoutPrototype(
 | |
| -                "wasThrown", false,
 | |
| -                "result", RemoteObject.create(func.@apply(object, resolvedArgs), objectGroupName, returnByValue, generatePreview),
 | |
| -            );
 | |
| +            if (typeof func !== "function") {
 | |
| +                callback(this._createThrownValue("Given expression does not evaluate to a function", objectGroupName));
 | |
| +                return;
 | |
| +            }
 | |
| +            let result = func.apply(object, resolvedArgs);
 | |
| +            if (awaitPromise && isDefined(result) && (InjectedScriptHost.internalConstructorName(result) === 'Promise')) {
 | |
| +                result.then(value => {
 | |
| +                    callback({
 | |
| +                        wasThrown: false,
 | |
| +                        result: RemoteObject.create(value, objectGroupName, returnByValue, generatePreview),
 | |
| +                    });
 | |
| +                }, reason => {
 | |
| +                    callback(this._createThrownValue(reason, objectGroupName));
 | |
| +                });
 | |
| +            } else {
 | |
| +                callback({
 | |
| +                    wasThrown: false,
 | |
| +                    result: RemoteObject.create(result, objectGroupName, returnByValue, generatePreview)
 | |
| +                });
 | |
| +            }
 | |
|          } catch (e) {
 | |
| -            return this._createThrownValue(e, objectGroupName);
 | |
| +            callback(this._createThrownValue(e, objectGroupName));
 | |
| +            return;
 | |
|          }
 | |
|      }
 | |
|  
 | |
| diff --git a/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.cpp b/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.cpp
 | |
| index 1088a6a8f2965e17e52d7ba1d1142b9ed697ad3f..a928811c56eaac0ea5a9a350093cb69e7b3ad59d 100644
 | |
| --- a/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.cpp
 | |
| +++ b/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.cpp
 | |
| @@ -101,7 +101,7 @@ void BackendDispatcher::registerDispatcherForDomain(const String& domain, Supple
 | |
|      m_dispatchers.set(domain, dispatcher);
 | |
|  }
 | |
|  
 | |
| -void BackendDispatcher::dispatch(const String& message)
 | |
| +void BackendDispatcher::dispatch(const String& message, Interceptor&& interceptor)
 | |
|  {
 | |
|      Ref<BackendDispatcher> protect(*this);
 | |
|  
 | |
| @@ -146,6 +146,9 @@ void BackendDispatcher::dispatch(const String& message)
 | |
|          requestId = *requestIdInt;
 | |
|      }
 | |
|  
 | |
| +    if (interceptor && interceptor(messageObject) == InterceptionResult::Intercepted)
 | |
| +        return;
 | |
| +
 | |
|      {
 | |
|          // We could be called re-entrantly from a nested run loop, so restore the previous id.
 | |
|          SetForScope scopedRequestId(m_currentRequestId, requestId);
 | |
| diff --git a/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.h b/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.h
 | |
| index 37c4f9833d4981b47bcd8debd4a79109254641a2..1c82cc9783618234bef7024d91821ce509912526 100644
 | |
| --- a/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.h
 | |
| +++ b/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.h
 | |
| @@ -83,7 +83,10 @@ public:
 | |
|      };
 | |
|  
 | |
|      void registerDispatcherForDomain(const String& domain, SupplementalBackendDispatcher*);
 | |
| -    void dispatch(const String& message);
 | |
| +
 | |
| +    enum class InterceptionResult { Intercepted, Continue };
 | |
| +    using Interceptor = WTF::Function<InterceptionResult(const RefPtr<JSON::Object>&)>;
 | |
| +    void dispatch(const String& message, Interceptor&& interceptor = Interceptor());
 | |
|  
 | |
|      // Note that 'unused' is a workaround so the compiler can pick the right sendResponse based on arity.
 | |
|      // When <http://webkit.org/b/179847> is fixed or this class is renamed for the JSON::Object case,
 | |
| diff --git a/Source/JavaScriptCore/inspector/InspectorFrontendRouter.cpp b/Source/JavaScriptCore/inspector/InspectorFrontendRouter.cpp
 | |
| index d408d364f1986983161f9d44efbc8bc6f6898676..1375ce9990f0c63d7e6f33ee62930051d6cd44cb 100644
 | |
| --- a/Source/JavaScriptCore/inspector/InspectorFrontendRouter.cpp
 | |
| +++ b/Source/JavaScriptCore/inspector/InspectorFrontendRouter.cpp
 | |
| @@ -49,7 +49,7 @@ void FrontendRouter::connectFrontend(FrontendChannel& connection)
 | |
|  void FrontendRouter::disconnectFrontend(FrontendChannel& connection)
 | |
|  {
 | |
|      if (!m_connections.contains(&connection)) {
 | |
| -        ASSERT_NOT_REACHED();
 | |
| +        ASSERT(m_connections.isEmpty());
 | |
|          return;
 | |
|      }
 | |
|  
 | |
| diff --git a/Source/JavaScriptCore/inspector/InspectorTarget.cpp b/Source/JavaScriptCore/inspector/InspectorTarget.cpp
 | |
| index 0cc2127c9c12c2d82dea9550bad73f4ffb99ba24..8ca65cc042d435cbc0e05dcc5c5dfc958eb24f5a 100644
 | |
| --- a/Source/JavaScriptCore/inspector/InspectorTarget.cpp
 | |
| +++ b/Source/JavaScriptCore/inspector/InspectorTarget.cpp
 | |
| @@ -44,6 +44,8 @@ void InspectorTarget::resume()
 | |
|      ASSERT(m_isPaused);
 | |
|      m_isPaused = false;
 | |
|  
 | |
| +    willResume();
 | |
| +
 | |
|      if (m_resumeCallback) {
 | |
|          m_resumeCallback();
 | |
|          m_resumeCallback = nullptr;
 | |
| @@ -52,7 +54,6 @@ void InspectorTarget::resume()
 | |
|  
 | |
|  void InspectorTarget::setResumeCallback(WTF::Function<void()>&& callback)
 | |
|  {
 | |
| -    ASSERT(!m_resumeCallback);
 | |
|      m_resumeCallback = WTFMove(callback);
 | |
|  }
 | |
|  
 | |
| diff --git a/Source/JavaScriptCore/inspector/InspectorTarget.h b/Source/JavaScriptCore/inspector/InspectorTarget.h
 | |
| index 4b95964db4d902b4b7f4b0b4c40afea51654ff2f..653842a82ed7a7be8603c9ef88ff48d1cda421be 100644
 | |
| --- a/Source/JavaScriptCore/inspector/InspectorTarget.h
 | |
| +++ b/Source/JavaScriptCore/inspector/InspectorTarget.h
 | |
| @@ -56,8 +56,12 @@ public:
 | |
|      virtual void connect(FrontendChannel::ConnectionType) = 0;
 | |
|      virtual void disconnect() = 0;
 | |
|      virtual void sendMessageToTargetBackend(const String&) = 0;
 | |
| +    virtual void activate(String& error) { error = "Target cannot be activated"_s; }
 | |
| +    virtual void close(String& error, bool /* runBeforeUnload */) { error = "Target cannot be closed"_s; }
 | |
|  
 | |
|  private:
 | |
| +    virtual void willResume() { }
 | |
| +
 | |
|      WTF::Function<void()> m_resumeCallback;
 | |
|      bool m_isPaused { false };
 | |
|  };
 | |
| diff --git a/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.cpp b/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.cpp
 | |
| index 6e976621186326be53aedeeda618a441d7bea6a6..ab46b5e2d1688ab538ebac0f5b908dc5a49a365a 100644
 | |
| --- a/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.cpp
 | |
| +++ b/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.cpp
 | |
| @@ -177,41 +177,38 @@ void InspectorRuntimeAgent::awaitPromise(const Protocol::Runtime::RemoteObjectId
 | |
|      });
 | |
|  }
 | |
|  
 | |
| -Protocol::ErrorStringOr<std::tuple<Ref<Protocol::Runtime::RemoteObject>, std::optional<bool> /* wasThrown */>> InspectorRuntimeAgent::callFunctionOn(const Protocol::Runtime::RemoteObjectId& objectId, const String& functionDeclaration, RefPtr<JSON::Array>&& arguments, std::optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& emulateUserGesture)
 | |
| +void InspectorRuntimeAgent::callFunctionOn(const Protocol::Runtime::RemoteObjectId& objectId, const String& functionDeclaration, RefPtr<JSON::Array>&& arguments, std::optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& emulateUserGesture, std::optional<bool>&& awaitPromise, Ref<CallFunctionOnCallback>&& callback)
 | |
|  {
 | |
|      InjectedScript injectedScript = m_injectedScriptManager.injectedScriptForObjectId(objectId);
 | |
| -    if (injectedScript.hasNoValue())
 | |
| -        return makeUnexpected("Missing injected script for given objectId"_s);
 | |
| +    if (injectedScript.hasNoValue()) {
 | |
| +        callback->sendFailure("Missing injected script for given objectId"_s);
 | |
| +        return;
 | |
| +    }
 | |
|  
 | |
| -    return callFunctionOn(injectedScript, objectId, functionDeclaration, WTFMove(arguments), WTFMove(doNotPauseOnExceptionsAndMuteConsole), WTFMove(returnByValue), WTFMove(generatePreview), WTFMove(emulateUserGesture));
 | |
| +    callFunctionOn(injectedScript, objectId, functionDeclaration, WTFMove(arguments), WTFMove(doNotPauseOnExceptionsAndMuteConsole), WTFMove(returnByValue), WTFMove(generatePreview), WTFMove(emulateUserGesture), WTFMove(awaitPromise), WTFMove(callback));
 | |
|  }
 | |
|  
 | |
| -Protocol::ErrorStringOr<std::tuple<Ref<Protocol::Runtime::RemoteObject>, std::optional<bool> /* wasThrown */>> InspectorRuntimeAgent::callFunctionOn(InjectedScript& injectedScript, const Protocol::Runtime::RemoteObjectId& objectId, const String& functionDeclaration, RefPtr<JSON::Array>&& arguments, std::optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& /* emulateUserGesture */)
 | |
| +void InspectorRuntimeAgent::callFunctionOn(InjectedScript& injectedScript, const Protocol::Runtime::RemoteObjectId& objectId, const String& functionDeclaration, RefPtr<JSON::Array>&& arguments, std::optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& /* emulateUserGesture */, std::optional<bool>&& awaitPromise, Ref<CallFunctionOnCallback>&& callback)
 | |
|  {
 | |
|      ASSERT(!injectedScript.hasNoValue());
 | |
| -
 | |
| -    Protocol::ErrorString errorString;
 | |
| -
 | |
| -    RefPtr<Protocol::Runtime::RemoteObject> result;
 | |
| -    std::optional<bool> wasThrown;
 | |
| -
 | |
| +    
 | |
|      JSC::Debugger::TemporarilyDisableExceptionBreakpoints temporarilyDisableExceptionBreakpoints(m_debugger);
 | |
| -
 | |
| +    
 | |
|      bool pauseAndMute = doNotPauseOnExceptionsAndMuteConsole.value_or(false);
 | |
|      if (pauseAndMute) {
 | |
|          temporarilyDisableExceptionBreakpoints.replace();
 | |
|          muteConsole();
 | |
|      }
 | |
| -
 | |
| -    injectedScript.callFunctionOn(errorString, objectId, functionDeclaration, arguments ? arguments->toJSONString() : nullString(), returnByValue.value_or(false), generatePreview.value_or(false), result, wasThrown);
 | |
| +    
 | |
| +    injectedScript.callFunctionOn(objectId, functionDeclaration, arguments ? arguments->toJSONString() : nullString(), returnByValue.value_or(false), generatePreview.value_or(false), awaitPromise.value_or(false), [callback=WTFMove(callback)] (Protocol::ErrorString& errorString, RefPtr<Protocol::Runtime::RemoteObject>&& result, std::optional<bool>&& wasThrown, std::optional<int>&&) {
 | |
| +        if (!result)
 | |
| +            callback->sendFailure(errorString);
 | |
| +        else
 | |
| +            callback->sendSuccess(result.releaseNonNull(), WTFMove(wasThrown));
 | |
| +    });
 | |
|  
 | |
|      if (pauseAndMute)
 | |
|          unmuteConsole();
 | |
| -
 | |
| -    if (!result)
 | |
| -        return makeUnexpected(errorString);
 | |
| -
 | |
| -    return { { result.releaseNonNull(), WTFMove(wasThrown) } };
 | |
|  }
 | |
|  
 | |
|  Protocol::ErrorStringOr<Ref<Protocol::Runtime::ObjectPreview>> InspectorRuntimeAgent::getPreview(const Protocol::Runtime::RemoteObjectId& objectId)
 | |
| diff --git a/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.h b/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.h
 | |
| index 1db64831b835df816130be4e7d42b7b213625656..5c3488200ab2df6dfc914ff780f05eba7ffd92a2 100644
 | |
| --- a/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.h
 | |
| +++ b/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.h
 | |
| @@ -62,7 +62,7 @@ public:
 | |
|      Protocol::ErrorStringOr<std::tuple<Protocol::Runtime::SyntaxErrorType, String /* message */, RefPtr<Protocol::Runtime::ErrorRange>>> parse(const String& expression) final;
 | |
|      Protocol::ErrorStringOr<std::tuple<Ref<Protocol::Runtime::RemoteObject>, std::optional<bool> /* wasThrown */, std::optional<int> /* savedResultIndex */>> evaluate(const String& expression, const String& objectGroup, std::optional<bool>&& includeCommandLineAPI, std::optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, std::optional<Protocol::Runtime::ExecutionContextId>&&, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& saveResult, std::optional<bool>&& emulateUserGesture) override;
 | |
|      void awaitPromise(const Protocol::Runtime::RemoteObjectId&, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& saveResult, Ref<AwaitPromiseCallback>&&) final;
 | |
| -    Protocol::ErrorStringOr<std::tuple<Ref<Protocol::Runtime::RemoteObject>, std::optional<bool> /* wasThrown */>> callFunctionOn(const Protocol::Runtime::RemoteObjectId&, const String& functionDeclaration, RefPtr<JSON::Array>&& arguments, std::optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& emulateUserGesture) override;
 | |
| +    void callFunctionOn(const Protocol::Runtime::RemoteObjectId&, const String& functionDeclaration, RefPtr<JSON::Array>&& arguments, std::optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& emulateUserGesture, std::optional<bool>&& awaitPromise, Ref<CallFunctionOnCallback>&&) override;
 | |
|      Protocol::ErrorStringOr<void> releaseObject(const Protocol::Runtime::RemoteObjectId&) final;
 | |
|      Protocol::ErrorStringOr<Ref<Protocol::Runtime::ObjectPreview>> getPreview(const Protocol::Runtime::RemoteObjectId&) final;
 | |
|      Protocol::ErrorStringOr<std::tuple<Ref<JSON::ArrayOf<Protocol::Runtime::PropertyDescriptor>>, RefPtr<JSON::ArrayOf<Protocol::Runtime::InternalPropertyDescriptor>>>> getProperties(const Protocol::Runtime::RemoteObjectId&, std::optional<bool>&& ownProperties, std::optional<int>&& fetchStart, std::optional<int>&& fetchCount, std::optional<bool>&& generatePreview) final;
 | |
| @@ -82,7 +82,7 @@ protected:
 | |
|      InspectorRuntimeAgent(AgentContext&);
 | |
|  
 | |
|      Protocol::ErrorStringOr<std::tuple<Ref<Protocol::Runtime::RemoteObject>, std::optional<bool> /* wasThrown */, std::optional<int> /* savedResultIndex */>> evaluate(InjectedScript&, const String& expression, const String& objectGroup, std::optional<bool>&& includeCommandLineAPI, std::optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& saveResult, std::optional<bool>&& emulateUserGesture);
 | |
| -    Protocol::ErrorStringOr<std::tuple<Ref<Protocol::Runtime::RemoteObject>, std::optional<bool> /* wasThrown */>> callFunctionOn(InjectedScript&, const Protocol::Runtime::RemoteObjectId&, const String& functionDeclaration, RefPtr<JSON::Array>&& arguments, std::optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& emulateUserGesture);
 | |
| +    void callFunctionOn(InjectedScript&, const Protocol::Runtime::RemoteObjectId&, const String& functionDeclaration, RefPtr<JSON::Array>&& arguments, std::optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& emulateUserGesture, std::optional<bool>&& awaitPromise, Ref<CallFunctionOnCallback>&&);
 | |
|  
 | |
|      InjectedScriptManager& injectedScriptManager() { return m_injectedScriptManager; }
 | |
|  
 | |
| diff --git a/Source/JavaScriptCore/inspector/agents/InspectorTargetAgent.cpp b/Source/JavaScriptCore/inspector/agents/InspectorTargetAgent.cpp
 | |
| index 508eb02ec95c52408384a1e2b77648afd426dd9d..93d6757e170272cda8c346bf51578d2b5f8aafaa 100644
 | |
| --- a/Source/JavaScriptCore/inspector/agents/InspectorTargetAgent.cpp
 | |
| +++ b/Source/JavaScriptCore/inspector/agents/InspectorTargetAgent.cpp
 | |
| @@ -87,6 +87,34 @@ Protocol::ErrorStringOr<void> InspectorTargetAgent::sendMessageToTarget(const St
 | |
|      return { };
 | |
|  }
 | |
|  
 | |
| +Protocol::ErrorStringOr<void> InspectorTargetAgent::activate(const String& targetId)
 | |
| +{
 | |
| +    InspectorTarget* target = m_targets.get(targetId);
 | |
| +    if (!target)
 | |
| +        return makeUnexpected("Missing target for given targetId"_s);
 | |
| +
 | |
| +    String errorString;
 | |
| +    target->activate(errorString);
 | |
| +    if (!errorString.isEmpty())
 | |
| +        return makeUnexpected(errorString);
 | |
| +
 | |
| +    return { };
 | |
| +}
 | |
| +
 | |
| +Protocol::ErrorStringOr<void> InspectorTargetAgent::close(const String& targetId,  std::optional<bool>&& runBeforeUnload)
 | |
| +{
 | |
| +    InspectorTarget* target = m_targets.get(targetId);
 | |
| +    if (!target)
 | |
| +        return makeUnexpected("Missing target for given targetId"_s);
 | |
| +
 | |
| +    String errorString;
 | |
| +    target->close(errorString, runBeforeUnload && *runBeforeUnload);
 | |
| +    if (!errorString.isEmpty())
 | |
| +        return makeUnexpected(errorString);
 | |
| +
 | |
| +    return { };
 | |
| +}
 | |
| +
 | |
|  void InspectorTargetAgent::sendMessageFromTargetToFrontend(const String& targetId, const String& message)
 | |
|  {
 | |
|      ASSERT_WITH_MESSAGE(m_targets.get(targetId), "Sending a message from an untracked target to the frontend.");
 | |
| @@ -144,7 +172,17 @@ void InspectorTargetAgent::targetDestroyed(InspectorTarget& target)
 | |
|      if (!m_isConnected)
 | |
|          return;
 | |
|  
 | |
| -    m_frontendDispatcher->targetDestroyed(target.identifier());
 | |
| +    m_frontendDispatcher->targetDestroyed(target.identifier(), false);
 | |
| +}
 | |
| +
 | |
| +void InspectorTargetAgent::targetCrashed(InspectorTarget& target)
 | |
| +{
 | |
| +    m_targets.remove(target.identifier());
 | |
| +
 | |
| +    if (!m_isConnected)
 | |
| +        return;
 | |
| +
 | |
| +    m_frontendDispatcher->targetDestroyed(target.identifier(), true);
 | |
|  }
 | |
|  
 | |
|  void InspectorTargetAgent::didCommitProvisionalTarget(const String& oldTargetID, const String& committedTargetID)
 | |
| diff --git a/Source/JavaScriptCore/inspector/agents/InspectorTargetAgent.h b/Source/JavaScriptCore/inspector/agents/InspectorTargetAgent.h
 | |
| index e81573fd0fffaaf6fd2af36635c78fcdf8608c69..c8cde6cfcde9612624f12e21bd9fa56b426bec7f 100644
 | |
| --- a/Source/JavaScriptCore/inspector/agents/InspectorTargetAgent.h
 | |
| +++ b/Source/JavaScriptCore/inspector/agents/InspectorTargetAgent.h
 | |
| @@ -50,15 +50,20 @@ public:
 | |
|      Protocol::ErrorStringOr<void> setPauseOnStart(bool) final;
 | |
|      Protocol::ErrorStringOr<void> resume(const String& targetId) final;
 | |
|      Protocol::ErrorStringOr<void> sendMessageToTarget(const String& targetId, const String& message) final;
 | |
| +    Protocol::ErrorStringOr<void> activate(const String& targetId) override;
 | |
| +    Protocol::ErrorStringOr<void> close(const String& targetId, std::optional<bool>&& runBeforeUnload) override;
 | |
|  
 | |
|      // Target lifecycle.
 | |
|      void targetCreated(InspectorTarget&);
 | |
|      void targetDestroyed(InspectorTarget&);
 | |
| +    void targetCrashed(InspectorTarget&);
 | |
|      void didCommitProvisionalTarget(const String& oldTargetID, const String& committedTargetID);
 | |
|  
 | |
|      // Target messages.
 | |
|      void sendMessageFromTargetToFrontend(const String& targetId, const String& message);
 | |
|  
 | |
| +    bool isConnected() { return m_isConnected; }
 | |
| +
 | |
|  private:
 | |
|      // FrontendChannel
 | |
|      FrontendChannel::ConnectionType connectionType() const;
 | |
| diff --git a/Source/JavaScriptCore/inspector/protocol/DOM.json b/Source/JavaScriptCore/inspector/protocol/DOM.json
 | |
| index 8de3ac227ca561a647ce78bb610d712378e20352..e999d1ac814a2ad9fbceca25e9fa56cea137e928 100644
 | |
| --- a/Source/JavaScriptCore/inspector/protocol/DOM.json
 | |
| +++ b/Source/JavaScriptCore/inspector/protocol/DOM.json
 | |
| @@ -80,6 +80,16 @@
 | |
|                  { "name": "value", "type": "string", "description": "The value that is resolved to with this data binding relationship." }
 | |
|              ]
 | |
|          },
 | |
| +        {
 | |
| +          "id": "Rect",
 | |
| +          "type": "object",
 | |
| +          "properties": [
 | |
| +            { "name": "x", "type": "integer", "description": "X coordinate" },
 | |
| +            { "name": "y", "type": "integer", "description": "Y coordinate" },
 | |
| +            { "name": "width", "type": "integer", "description": "Rectangle width" },
 | |
| +            { "name": "height", "type": "integer", "description": "Rectangle height" }
 | |
| +      ]
 | |
| +        },
 | |
|          {
 | |
|              "id": "EventListener",
 | |
|              "type": "object",
 | |
| @@ -177,6 +187,16 @@
 | |
|                  { "name": "pseudoId", "$ref": "CSS.PseudoId", "optional": true }
 | |
|              ],
 | |
|              "description": "An object referencing a node and a pseudo-element, primarily used to identify an animation effect target."
 | |
| +        },
 | |
| +        {
 | |
| +            "id": "FilePayload",
 | |
| +            "type": "object",
 | |
| +            "description": "Data to construct File object.",
 | |
| +            "properties": [
 | |
| +                { "name": "name", "type": "string", "description": "File name." },
 | |
| +                { "name": "type", "type": "string", "description": "File type." },
 | |
| +                { "name": "data", "type": "string", "description": "Base64-encoded file data." }
 | |
| +            ]
 | |
|          }
 | |
|      ],
 | |
|      "commands": [
 | |
| @@ -559,7 +579,9 @@
 | |
|              "description": "Resolves JavaScript node object for given node id.",
 | |
|              "targetTypes": ["page"],
 | |
|              "parameters": [
 | |
| -                { "name": "nodeId", "$ref": "NodeId", "description": "Id of the node to resolve." },
 | |
| +                { "name": "nodeId", "$ref": "NodeId", "optional": true, "description": "Id of the node to resolve." },
 | |
| +                { "name": "objectId", "$ref": "Runtime.RemoteObjectId", "optional": true, "description": "Source element handle." },
 | |
| +                { "name": "executionContextId", "$ref": "Runtime.ExecutionContextId", "optional": true, "description": "Specifies in which execution context to adopt to." },
 | |
|                  { "name": "objectGroup", "type": "string", "optional": true, "description": "Symbolic group name that can be used to release multiple objects." }
 | |
|              ],
 | |
|              "returns": [
 | |
| @@ -626,6 +648,46 @@
 | |
|              "parameters": [
 | |
|                  { "name": "allow", "type": "boolean" }
 | |
|              ]
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "describeNode",
 | |
| +            "description": "Returns node description.",
 | |
| +            "parameters": [
 | |
| +                { "name": "objectId", "$ref": "Runtime.RemoteObjectId", "description": "JavaScript object id of the node wrapper." }
 | |
| +            ],
 | |
| +            "returns": [
 | |
| +                { "name": "contentFrameId", "$ref": "Network.FrameId", "optional": true, "description": "Frame ID for frame owner elements." },
 | |
| +                { "name": "ownerFrameId", "$ref": "Network.FrameId", "optional": true, "description": "ID of the owning frame element." }
 | |
| +            ]
 | |
| +        },
 | |
| +        {
 | |
| +          "name": "scrollIntoViewIfNeeded",
 | |
| +          "description": "Scrolls the given rect into view if not already in the viewport.",
 | |
| +          "parameters": [
 | |
| +              { "name": "objectId", "$ref": "Runtime.RemoteObjectId", "description": "JavaScript object id of the node wrapper." },
 | |
| +              { "name": "rect", "$ref": "Rect", "optional": true, "description": "Rect relative to the node's border box, in CSS pixels." }
 | |
| +          ]
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "getContentQuads",
 | |
| +            "description": "Returns quads that describe node position on the page. This method\nmight return multiple quads for inline nodes.",
 | |
| +            "parameters": [
 | |
| +                { "name": "objectId", "$ref": "Runtime.RemoteObjectId", "description": "JavaScript object id of the node wrapper." }
 | |
| +            ],
 | |
| +            "returns": [
 | |
| +                {
 | |
| +                    "name": "quads", "type": "array", "items": { "$ref": "Quad" }, "description": "Quads that describe node layout relative to viewport."
 | |
| +                }
 | |
| +            ]
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "setInputFiles",
 | |
| +            "description": "Sets input files for given <input type=file>",
 | |
| +            "parameters": [
 | |
| +                { "name": "objectId", "$ref": "Runtime.RemoteObjectId", "description": "Input element handle." },
 | |
| +                { "name": "files", "type": "array", "items": { "$ref": "FilePayload" }, "optional": true, "description": "Files to set" },
 | |
| +                { "name": "paths", "type": "array", "items": { "type": "string" }, "optional": true, "description": "File paths to set" }
 | |
| +            ]
 | |
|          }
 | |
|      ],
 | |
|      "events": [
 | |
| diff --git a/Source/JavaScriptCore/inspector/protocol/Dialog.json b/Source/JavaScriptCore/inspector/protocol/Dialog.json
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..79edea03fed4e9be5da96e1275e182a479cb7a0a
 | |
| --- /dev/null
 | |
| +++ b/Source/JavaScriptCore/inspector/protocol/Dialog.json
 | |
| @@ -0,0 +1,36 @@
 | |
| +{
 | |
| +    "domain": "Dialog",
 | |
| +    "description": "Actions and events related to alert boxes.",
 | |
| +    "availability": ["web"],
 | |
| +    "types": [
 | |
| +    ],
 | |
| +    "commands": [
 | |
| +        {
 | |
| +            "name": "enable",
 | |
| +            "description": "Enables dialog domain notifications."
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "disable",
 | |
| +            "description": "Disables dialog domain notifications."
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "handleJavaScriptDialog",
 | |
| +            "description": "Accepts or dismisses a JavaScript initiated dialog (alert, confirm, prompt, or onbeforeunload).",
 | |
| +            "parameters": [
 | |
| +                { "name": "accept", "type": "boolean", "description": "Whether to accept or dismiss the dialog."},
 | |
| +                { "name": "promptText", "optional": true, "type": "string", "description": "The text to enter into the dialog prompt before accepting. Used only if this is a prompt dialog."}
 | |
| +            ]
 | |
| +        }
 | |
| +    ],
 | |
| +    "events": [
 | |
| +        {
 | |
| +            "name": "javascriptDialogOpening",
 | |
| +            "description": "Fired when a JavaScript initiated dialog (alert, confirm, prompt, or onbeforeunload) is about to open.",
 | |
| +            "parameters": [
 | |
| +                { "name": "type", "type": "string", "description": "Dialog type."},
 | |
| +                { "name": "message", "type": "string", "description": "Message that will be displayed by the dialog."},
 | |
| +                { "name": "defaultPrompt", "optional": true, "type": "string", "description": "Default dialog prompt."}
 | |
| +            ]
 | |
| +        }
 | |
| +    ]
 | |
| +}
 | |
| diff --git a/Source/JavaScriptCore/inspector/protocol/Emulation.json b/Source/JavaScriptCore/inspector/protocol/Emulation.json
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..347a01b3fdd1a8277cb4104558e8bbfa63539374
 | |
| --- /dev/null
 | |
| +++ b/Source/JavaScriptCore/inspector/protocol/Emulation.json
 | |
| @@ -0,0 +1,51 @@
 | |
| +{
 | |
| +    "domain": "Emulation",
 | |
| +    "availability": ["web"],
 | |
| +    "commands": [
 | |
| +        {
 | |
| +            "name": "setDeviceMetricsOverride",
 | |
| +            "description": "Overrides device metrics with provided values.",
 | |
| +            "async": true,
 | |
| +            "parameters": [
 | |
| +                { "name": "width", "type": "integer" },
 | |
| +                { "name": "height", "type": "integer" },
 | |
| +                { "name": "fixedLayout", "type": "boolean" },
 | |
| +                { "name": "deviceScaleFactor", "type": "number", "optional": true }
 | |
| +            ]
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "setJavaScriptEnabled",
 | |
| +            "description": "Allows to disable script execution for the page.",
 | |
| +            "parameters": [
 | |
| +                { "name": "enabled", "type": "boolean" }
 | |
| +            ]
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "setAuthCredentials",
 | |
| +            "description": "Credentials to use during HTTP authentication.",
 | |
| +            "parameters": [
 | |
| +                { "name": "username", "type": "string", "optional": true },
 | |
| +                { "name": "password", "type": "string", "optional": true }
 | |
| +            ]
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "setActiveAndFocused",
 | |
| +            "description": "Makes page focused for test.",
 | |
| +            "parameters": [
 | |
| +                { "name": "active", "type": "boolean", "optional": true }
 | |
| +            ]
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "grantPermissions",
 | |
| +            "parameters": [
 | |
| +                { "name": "origin", "type": "string" },
 | |
| +                { "name": "permissions", "type": "array", "items": { "type": "string" } }
 | |
| +            ],
 | |
| +            "description": "Overrides the permissions."
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "resetPermissions",
 | |
| +            "description": "Clears permission overrides."
 | |
| +        }
 | |
| +    ]
 | |
| +}
 | |
| diff --git a/Source/JavaScriptCore/inspector/protocol/Input.json b/Source/JavaScriptCore/inspector/protocol/Input.json
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..b9ab57a2b5739ed997231399b4bd4042a0cb0935
 | |
| --- /dev/null
 | |
| +++ b/Source/JavaScriptCore/inspector/protocol/Input.json
 | |
| @@ -0,0 +1,223 @@
 | |
| +{
 | |
| +    "domain": "Input",
 | |
| +    "availability": ["web"],
 | |
| +    "types": [
 | |
| +        {
 | |
| +            "id": "TimeSinceEpoch",
 | |
| +            "description": "UTC time in seconds, counted from January 1, 1970.",
 | |
| +            "type": "number"
 | |
| +        }
 | |
| +    ],
 | |
| +    "commands": [
 | |
| +        {
 | |
| +            "name": "dispatchKeyEvent",
 | |
| +            "description": "Dispatches a key event to the page.",
 | |
| +            "async": true,
 | |
| +            "parameters": [
 | |
| +                {
 | |
| +                    "name": "type",
 | |
| +                    "description": "Type of the key event.",
 | |
| +                    "type": "string",
 | |
| +                    "enum": [
 | |
| +                        "keyDown",
 | |
| +                        "keyUp"
 | |
| +                    ]
 | |
| +                },
 | |
| +                {
 | |
| +                    "name": "modifiers",
 | |
| +                    "description": "Bit field representing pressed modifier keys. (default: 0).",
 | |
| +                    "optional": true,
 | |
| +                    "type": "integer"
 | |
| +                },
 | |
| +                {
 | |
| +                    "name": "text",
 | |
| +                    "description": "Text as generated by processing a virtual key code with a keyboard layout. Not needed for\nfor `keyUp` and `rawKeyDown` events (default: \"\")",
 | |
| +                    "optional": true,
 | |
| +                    "type": "string"
 | |
| +                },
 | |
| +                {
 | |
| +                    "name": "unmodifiedText",
 | |
| +                    "description": "Text that would have been generated by the keyboard if no modifiers were pressed (except for\nshift). Useful for shortcut (accelerator) key handling (default: \"\").",
 | |
| +                    "optional": true,
 | |
| +                    "type": "string"
 | |
| +                },
 | |
| +                {
 | |
| +                    "name": "code",
 | |
| +                    "description": "Unique DOM defined string value for each physical key (e.g., 'KeyA') (default: \"\").",
 | |
| +                    "optional": true,
 | |
| +                    "type": "string"
 | |
| +                },
 | |
| +                {
 | |
| +                    "name": "key",
 | |
| +                    "description": "Unique DOM defined string value describing the meaning of the key in the context of active\nmodifiers, keyboard layout, etc (e.g., 'AltGr') (default: \"\").",
 | |
| +                    "optional": true,
 | |
| +                    "type": "string"
 | |
| +                },
 | |
| +                {
 | |
| +                    "name": "windowsVirtualKeyCode",
 | |
| +                    "description": "Windows virtual key code (default: 0).",
 | |
| +                    "optional": true,
 | |
| +                    "type": "integer"
 | |
| +                },
 | |
| +                {
 | |
| +                    "name": "nativeVirtualKeyCode",
 | |
| +                    "description": "Native virtual key code (default: 0).",
 | |
| +                    "optional": true,
 | |
| +                    "type": "integer"
 | |
| +                },
 | |
| +                {
 | |
| +                    "name": "autoRepeat",
 | |
| +                    "description": "Whether the event was generated from auto repeat (default: false).",
 | |
| +                    "optional": true,
 | |
| +                    "type": "boolean"
 | |
| +                },
 | |
| +                {
 | |
| +                    "name": "isKeypad",
 | |
| +                    "description": "Whether the event was generated from the keypad (default: false).",
 | |
| +                    "optional": true,
 | |
| +                    "type": "boolean"
 | |
| +                },
 | |
| +                {
 | |
| +                    "name": "isSystemKey",
 | |
| +                    "description": "Whether the event was a system key event (default: false).",
 | |
| +                    "optional": true,
 | |
| +                    "type": "boolean"
 | |
| +                },
 | |
| +                {
 | |
| +                    "name": "macCommands",
 | |
| +                    "description": "Mac editing commands associated with this key",
 | |
| +                    "type": "array",
 | |
| +                    "optional": true,
 | |
| +                    "items": {
 | |
| +                      "type": "string"
 | |
| +                    }
 | |
| +                }
 | |
| +            ]
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "dispatchMouseEvent",
 | |
| +            "description": "Dispatches a mouse event to the page.",
 | |
| +            "async": true,
 | |
| +            "parameters": [
 | |
| +                {
 | |
| +                    "name": "type",
 | |
| +                    "description": "Type of the mouse event.",
 | |
| +                    "type": "string",
 | |
| +                    "enum": [ "move", "down", "up", "wheel"]
 | |
| +                },
 | |
| +                {
 | |
| +                    "name": "x",
 | |
| +                    "description": "X coordinate of the event relative to the main frame's viewport in CSS pixels.",
 | |
| +                    "type": "integer"
 | |
| +                },
 | |
| +                {
 | |
| +                    "name": "y",
 | |
| +                    "description": "Y coordinate of the event relative to the main frame's viewport in CSS pixels. 0 refers to\nthe top of the viewport and Y increases as it proceeds towards the bottom of the viewport.",
 | |
| +                    "type": "integer"
 | |
| +                },
 | |
| +                {
 | |
| +                    "name": "modifiers",
 | |
| +                    "description": "Bit field representing pressed modifier keys. Alt=1, Ctrl=2, Meta/Command=4, Shift=8\n(default: 0).",
 | |
| +                    "optional": true,
 | |
| +                    "type": "integer"
 | |
| +                },
 | |
| +                {
 | |
| +                    "name": "button",
 | |
| +                    "description": "Mouse button (default: \"none\").",
 | |
| +                    "optional": true,
 | |
| +                    "type": "string",
 | |
| +                    "enum": [
 | |
| +                        "none",
 | |
| +                        "left",
 | |
| +                        "middle",
 | |
| +                        "right",
 | |
| +                        "back",
 | |
| +                        "forward"
 | |
| +                    ]
 | |
| +                },
 | |
| +                {
 | |
| +                    "name": "buttons",
 | |
| +                    "description": "A number indicating which buttons are pressed on the mouse when a mouse event is triggered.\nLeft=1, Right=2, Middle=4, Back=8, Forward=16, None=0.",
 | |
| +                    "optional": true,
 | |
| +                    "type": "integer"
 | |
| +                },
 | |
| +                {
 | |
| +                    "name": "clickCount",
 | |
| +                    "description": "Number of times the mouse button was clicked (default: 0).",
 | |
| +                    "optional": true,
 | |
| +                    "type": "integer"
 | |
| +                },
 | |
| +                {
 | |
| +                    "name": "deltaX",
 | |
| +                    "description": "X delta in CSS pixels for mouse wheel event (default: 0).",
 | |
| +                    "optional": true,
 | |
| +                    "type": "integer"
 | |
| +                },
 | |
| +                {
 | |
| +                    "name": "deltaY",
 | |
| +                    "description": "Y delta in CSS pixels for mouse wheel event (default: 0).",
 | |
| +                    "optional": true,
 | |
| +                    "type": "integer"
 | |
| +                }
 | |
| +            ]
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "dispatchWheelEvent",
 | |
| +            "description": "Dispatches a wheel event to the page.",
 | |
| +            "async": true,
 | |
| +            "parameters": [
 | |
| +                {
 | |
| +                    "name": "x",
 | |
| +                    "description": "X coordinate of the event relative to the main frame's viewport in CSS pixels.",
 | |
| +                    "type": "integer"
 | |
| +                },
 | |
| +                {
 | |
| +                    "name": "y",
 | |
| +                    "description": "Y coordinate of the event relative to the main frame's viewport in CSS pixels. 0 refers to\nthe top of the viewport and Y increases as it proceeds towards the bottom of the viewport.",
 | |
| +                    "type": "integer"
 | |
| +                },
 | |
| +                {
 | |
| +                    "name": "modifiers",
 | |
| +                    "description": "Bit field representing pressed modifier keys. Alt=1, Ctrl=2, Meta/Command=4, Shift=8\n(default: 0).",
 | |
| +                    "optional": true,
 | |
| +                    "type": "integer"
 | |
| +                },
 | |
| +                {
 | |
| +                    "name": "deltaX",
 | |
| +                    "description": "X delta in CSS pixels for mouse wheel event (default: 0).",
 | |
| +                    "optional": true,
 | |
| +                    "type": "integer"
 | |
| +                },
 | |
| +                {
 | |
| +                    "name": "deltaY",
 | |
| +                    "description": "Y delta in CSS pixels for mouse wheel event (default: 0).",
 | |
| +                    "optional": true,
 | |
| +                    "type": "integer"
 | |
| +                }
 | |
| +            ]
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "dispatchTapEvent",
 | |
| +            "description": "Dispatches a tap event to the page.",
 | |
| +            "async": true,
 | |
| +            "parameters": [
 | |
| +                {
 | |
| +                    "name": "x",
 | |
| +                    "description": "X coordinate of the event relative to the main frame's viewport in CSS pixels.",
 | |
| +                    "type": "integer"
 | |
| +                },
 | |
| +                {
 | |
| +                    "name": "y",
 | |
| +                    "description": "Y coordinate of the event relative to the main frame's viewport in CSS pixels. 0 refers to\nthe top of the viewport and Y increases as it proceeds towards the bottom of the viewport.",
 | |
| +                    "type": "integer"
 | |
| +                },
 | |
| +                {
 | |
| +                    "name": "modifiers",
 | |
| +                    "description": "Bit field representing pressed modifier keys. Alt=1, Ctrl=2, Meta/Command=4, Shift=8\n(default: 0).",
 | |
| +                    "optional": true,
 | |
| +                    "type": "integer"
 | |
| +                }
 | |
| +            ]
 | |
| +        }
 | |
| +    ]
 | |
| +}
 | |
| diff --git a/Source/JavaScriptCore/inspector/protocol/Network.json b/Source/JavaScriptCore/inspector/protocol/Network.json
 | |
| index 2fc4aaf98e06c468a2500cbf7d8676e523cf6327..6d005cd9de8450196a91a8a61cdce61977554cfc 100644
 | |
| --- a/Source/JavaScriptCore/inspector/protocol/Network.json
 | |
| +++ b/Source/JavaScriptCore/inspector/protocol/Network.json
 | |
| @@ -325,6 +325,13 @@
 | |
|                  { "name": "requestId", "$ref": "RequestId", "description": "Identifier for the intercepted Network request to fail." },
 | |
|                  { "name": "errorType", "$ref": "ResourceErrorType", "description": "Deliver error reason for the request failure." }
 | |
|              ]
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "setEmulateOfflineState",
 | |
| +            "description": "Emulate offline state overriding the actual state.",
 | |
| +            "parameters": [
 | |
| +                { "name": "offline", "type": "boolean", "description": "True to emulate offline." }
 | |
| +            ]
 | |
|          }
 | |
|      ],
 | |
|      "events": [
 | |
| diff --git a/Source/JavaScriptCore/inspector/protocol/Page.json b/Source/JavaScriptCore/inspector/protocol/Page.json
 | |
| index 1c97ad011c5ec183a5866bb98319badd5ec9442f..658937fdc58425b9a164d9bc368a9e61ed836918 100644
 | |
| --- a/Source/JavaScriptCore/inspector/protocol/Page.json
 | |
| +++ b/Source/JavaScriptCore/inspector/protocol/Page.json
 | |
| @@ -21,7 +21,14 @@
 | |
|                  "ShowDebugBorders",
 | |
|                  "ShowRepaintCounter",
 | |
|                  "WebRTCEncryptionEnabled",
 | |
| -                "WebSecurityEnabled"
 | |
| +                "WebSecurityEnabled",
 | |
| +                "DeviceOrientationEventEnabled",
 | |
| +                "SpeechRecognitionEnabled",
 | |
| +                "PointerLockEnabled",
 | |
| +                "NotificationsEnabled",
 | |
| +                "FullScreenEnabled",
 | |
| +                "InputTypeMonthEnabled",
 | |
| +                "InputTypeWeekEnabled"
 | |
|              ]
 | |
|          },
 | |
|          {
 | |
| @@ -49,6 +56,12 @@
 | |
|              "enum": ["Light", "Dark"],
 | |
|              "description": "Page appearance name."
 | |
|          },
 | |
| +        {
 | |
| +            "id": "ReducedMotion",
 | |
| +            "type": "string",
 | |
| +            "enum": ["Reduce", "NoPreference"],
 | |
| +            "description": "Page reduced-motion media query override."
 | |
| +        },
 | |
|          {
 | |
|              "id": "Frame",
 | |
|              "type": "object",
 | |
| @@ -112,6 +125,51 @@
 | |
|                  { "name": "secure", "type": "boolean", "description": "True if cookie is secure." },
 | |
|                  { "name": "sameSite", "$ref": "CookieSameSitePolicy", "description": "Cookie Same-Site policy." }
 | |
|              ]
 | |
| +        },
 | |
| +        {
 | |
| +            "id": "AXNode",
 | |
| +            "type": "object",
 | |
| +            "description": "Accessibility Node",
 | |
| +            "properties": [
 | |
| +                { "name": "role", "type": "string", "description": "The role."},
 | |
| +                { "name": "name", "type": "string","optional": true, "description": "A human readable name for the node."},
 | |
| +                { "name": "value", "type": "any", "optional": true, "description": "The current value of the node."},
 | |
| +                { "name": "description", "type": "string", "optional": true, "description": "An additional human readable description of the node."},
 | |
| +                { "name": "keyshortcuts", "type": "string", "optional": true, "description": "Keyboard shortcuts associated with this node."},
 | |
| +                { "name": "roledescription", "type": "string", "optional": true, "description": "A human readable alternative to the role."},
 | |
| +                { "name": "valuetext", "type": "string", "optional": true, "description": "A description of the current value."},
 | |
| +                { "name": "disabled", "type": "boolean", "optional": true, "description": "Whether the node is disabled."},
 | |
| +                { "name": "expanded", "type": "boolean", "optional": true, "description": "Whether the node is expanded or collapsed."},
 | |
| +                { "name": "focused", "type": "boolean", "optional": true, "description": "Whether the node is focused."},
 | |
| +                { "name": "modal", "type": "boolean", "optional": true, "description": "Whether the node is modal."},
 | |
| +                { "name": "multiline", "type": "boolean", "optional": true, "description": "Whether the node text input supports multiline."},
 | |
| +                { "name": "multiselectable", "type": "boolean", "optional": true, "description": "Whether more than one child can be selected."},
 | |
| +                { "name": "readonly", "type": "boolean", "optional": true, "description": "Whether the node is read only."},
 | |
| +                { "name": "required", "type": "boolean", "optional": true, "description": "Whether the node is required."},
 | |
| +                { "name": "selected", "type": "boolean", "optional": true, "description": "Whether the node is selected in its parent node."},
 | |
| +                { "name": "checked", "type": "string", "optional": true, "enum": ["true", "false", "mixed"], "description": "Whether the checkbox is checked, or \"mixed\"."},
 | |
| +                { "name": "pressed", "type": "string", "optional": true, "enum": ["true", "false", "mixed"], "description": "Whether the toggle button is checked, or \"mixed\"."},
 | |
| +                { "name": "level", "type": "integer", "optional": true, "description": "The level of a heading."},
 | |
| +                { "name": "valuemin", "type": "number", "optional": true, "description": "The minimum value in a node."},
 | |
| +                { "name": "valuemax", "type": "number", "optional": true, "description": "The maximum value in a node."},
 | |
| +                { "name": "autocomplete", "type": "string", "optional": true, "description": "What kind of autocomplete is supported by a control."},
 | |
| +                { "name": "haspopup", "type": "string", "optional": true, "description": "What kind of popup is currently being shown for a node."},
 | |
| +                { "name": "invalid", "type": "string", "optional": true, "enum": ["true", "false", "grammar", "spelling"], "description": "Whether and in what way this node's value is invalid."},
 | |
| +                { "name": "orientation", "type": "string", "optional": true, "description": "Whether the node is oriented horizontally or vertically."},
 | |
| +                { "name": "focusable", "type": "boolean", "optional": true, "description": "Whether the node is focusable."},
 | |
| +                { "name": "children", "type": "array", "optional": true, "items": { "$ref": "AXNode"}, "description": "Child AXNodes of this node, if any."},
 | |
| +                { "name": "found", "type": "boolean", "optional": true, "description": "True if this AXNode corresponds with the ObjectId passed into acessibilitySnapshot."}
 | |
| +            ]
 | |
| +        },
 | |
| +        {
 | |
| +            "id": "Insets",
 | |
| +            "type": "object",
 | |
| +            "properties": [
 | |
| +                { "name": "top", "type": "number" },
 | |
| +                { "name": "right", "type": "number" },
 | |
| +                { "name": "bottom", "type": "number" },
 | |
| +                { "name": "left", "type": "number" }
 | |
| +            ]
 | |
|          }
 | |
|      ],
 | |
|      "commands": [
 | |
| @@ -131,6 +189,14 @@
 | |
|                  { "name": "revalidateAllResources", "type": "boolean", "optional": true, "description": "If true, all cached subresources will be revalidated when the main resource loads. Otherwise, only expired cached subresources will be revalidated (the default behavior for most WebKit clients)." }
 | |
|              ]
 | |
|          },
 | |
| +        {
 | |
| +            "name": "goBack",
 | |
| +            "description": "Goes back in the history."
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "goForward",
 | |
| +            "description": "Goes forward in the history."
 | |
| +        },
 | |
|          {
 | |
|              "name": "navigate",
 | |
|              "description": "Navigates current page to the given URL.",
 | |
| @@ -147,6 +213,14 @@
 | |
|                  { "name": "value", "type": "string", "optional": true, "description": "Value to override the user agent with. If this value is not provided, the override is removed. Overrides are removed when Web Inspector closes/disconnects." }
 | |
|              ]
 | |
|          },
 | |
| +        {
 | |
| +            "name": "overridePlatform",
 | |
| +            "description": "Override's the navigator.platform of the inspected page",
 | |
| +            "targetTypes": ["page"],
 | |
| +            "parameters": [
 | |
| +                { "name": "value", "type": "string", "optional": true, "description": "Value to override the platform with. If this value is not provided, the override is removed. Overrides are removed when Web Inspector closes/disconnects." }
 | |
| +            ]
 | |
| +        },
 | |
|          {
 | |
|              "name": "overrideSetting",
 | |
|              "description": "Allows the frontend to override the inspected page's settings.",
 | |
| @@ -204,7 +278,8 @@
 | |
|              "name": "setBootstrapScript",
 | |
|              "targetTypes": ["page"],
 | |
|              "parameters": [
 | |
| -                { "name": "source", "type": "string", "optional": true, "description": "If `source` is provided (and not empty), it will be injected into all future global objects as soon as they're created. Omitting `source` will stop this from happening." }
 | |
| +                { "name": "source", "type": "string", "optional": true, "description": "If `source` is provided (and not empty), it will be injected into all future global objects as soon as they're created. Omitting `source` will stop this from happening." },
 | |
| +                { "name": "worldName", "type": "string", "optional": true, "description": "Isolated world name to evaluate the script in. If not specified main world will be used." }
 | |
|              ]
 | |
|          },
 | |
|          {
 | |
| @@ -270,6 +345,28 @@
 | |
|                  { "name": "appearance", "$ref": "Appearance", "optional": true }
 | |
|              ]
 | |
|          },
 | |
| +        {
 | |
| +            "name": "setForcedReducedMotion",
 | |
| +            "description": "Forces the reduced-motion media query for the page.",
 | |
| +            "targetTypes": ["page"],
 | |
| +            "parameters": [
 | |
| +                { "name": "reducedMotion", "$ref": "ReducedMotion", "optional": true }
 | |
| +            ]
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "setTimeZone",
 | |
| +            "description": "Enables time zone emulation.",
 | |
| +            "parameters": [
 | |
| +                { "name": "timeZone", "type": "string", "optional": true }
 | |
| +            ]
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "setTouchEmulationEnabled",
 | |
| +            "description": "Enables touch events on platforms that lack them.",
 | |
| +            "parameters": [
 | |
| +                {"name": "enabled", "type": "boolean", "description": "Whether touch should be enabled."}
 | |
| +            ]
 | |
| +        },
 | |
|          {
 | |
|              "name": "snapshotNode",
 | |
|              "description": "Capture a snapshot of the specified node that does not include unrelated layers.",
 | |
| @@ -290,7 +387,8 @@
 | |
|                  { "name": "y", "type": "integer", "description": "Y coordinate" },
 | |
|                  { "name": "width", "type": "integer", "description": "Rectangle width" },
 | |
|                  { "name": "height", "type": "integer", "description": "Rectangle height" },
 | |
| -                { "name": "coordinateSystem", "$ref": "CoordinateSystem", "description": "Indicates the coordinate system of the supplied rectangle." }
 | |
| +                { "name": "coordinateSystem", "$ref": "CoordinateSystem", "description": "Indicates the coordinate system of the supplied rectangle." },
 | |
| +                { "name": "omitDeviceScaleFactor", "type": "boolean", "optional": true, "description": "By default, screenshot is inflated by device scale factor to avoid blurry image. This flag disables it." }
 | |
|              ],
 | |
|              "returns": [
 | |
|                  { "name": "dataURL", "type": "string", "description": "Base64-encoded image data (PNG)." }
 | |
| @@ -308,12 +406,92 @@
 | |
|          {
 | |
|              "name": "setScreenSizeOverride",
 | |
|              "description": "Overrides screen size exposed to DOM and used in media queries for testing with provided values.",
 | |
| -            "condition": "!(defined(WTF_PLATFORM_COCOA) && WTF_PLATFORM_COCOA)",
 | |
|              "targetTypes": ["page"],
 | |
|              "parameters": [
 | |
|                  { "name": "width", "type": "integer", "description": "Screen width", "optional": true },
 | |
|                  { "name": "height", "type": "integer", "description": "Screen height", "optional": true }
 | |
|              ]
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "insertText",
 | |
| +            "description": "Insert text into the current selection of the page.",
 | |
| +            "parameters": [
 | |
| +                { "name": "text", "type": "string", "description": "Text to insert." }
 | |
| +            ]
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "setComposition",
 | |
| +            "description": "Set the current IME composition.",
 | |
| +            "parameters": [
 | |
| +                { "name": "text", "type": "string" },
 | |
| +                { "name": "selectionStart", "type": "integer" },
 | |
| +                { "name": "selectionLength", "type": "integer" },
 | |
| +                { "name": "replacementStart", "type": "integer", "optional": true },
 | |
| +                { "name": "replacementLength", "type": "integer", "optional": true }
 | |
| +            ]
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "accessibilitySnapshot",
 | |
| +            "description": "Serializes and returns all of the accessibility nodes of the page.",
 | |
| +            "parameters": [
 | |
| +                { "name": "objectId", "type": "string", "optional": true, "description": "Object Id of a node to find in the accessibility tree."}
 | |
| +            ],
 | |
| +            "returns": [
 | |
| +                { "name": "axNode", "$ref": "AXNode", "description": "The root AXNode."}
 | |
| +            ]
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "setInterceptFileChooserDialog",
 | |
| +            "description": "Intercepts file chooser dialog",
 | |
| +            "parameters": [
 | |
| +                { "name": "enabled", "type": "boolean", "description": "True to enable." }
 | |
| +            ]
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "setDefaultBackgroundColorOverride",
 | |
| +            "description": "Sets or clears an override of the default background color of the frame. This override is used if the content does not specify one.",
 | |
| +            "parameters": [
 | |
| +                { "name": "color", "$ref": "DOM.RGBAColor", "optional": true, "description": "RGBA of the default background color. If not specified, any existing override will be cleared." }
 | |
| +            ]
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "createUserWorld",
 | |
| +            "description": "Creates an user world for every loaded frame.",
 | |
| +            "parameters": [
 | |
| +                { "name": "name", "type": "string", "description": "Isolated world name, will be used as an execution context name." }
 | |
| +            ]
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "setBypassCSP",
 | |
| +            "description": "Enable page Content Security Policy by-passing.",
 | |
| +            "parameters": [
 | |
| +                { "name": "enabled", "type": "boolean", "description": "Whether to bypass page CSP." }
 | |
| +            ]
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "crash",
 | |
| +            "description": "Crashes the page process"
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "setOrientationOverride",
 | |
| +            "description": "Overrides window.orientation with provided value.",
 | |
| +            "parameters": [
 | |
| +                { "name": "angle", "type": "integer", "optional": true }
 | |
| +            ]
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "setVisibleContentRects",
 | |
| +            "targetTypes": ["page"],
 | |
| +            "parameters": [
 | |
| +                { "name": "unobscuredContentRect", "$ref": "DOM.Rect", "optional": true },
 | |
| +                { "name": "contentInsets", "$ref": "Insets", "optional": true },
 | |
| +                { "name": "obscuredInsets", "$ref": "Insets", "optional": true },
 | |
| +                { "name": "unobscuredInsets", "$ref": "Insets", "optional": true }
 | |
| +            ]
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "updateScrollingState",
 | |
| +            "description": "Ensures that the scroll regions are up to date."
 | |
|          }
 | |
|      ],
 | |
|      "events": [
 | |
| @@ -321,14 +499,16 @@
 | |
|              "name": "domContentEventFired",
 | |
|              "targetTypes": ["page"],
 | |
|              "parameters": [
 | |
| -                { "name": "timestamp", "type": "number" }
 | |
| +                { "name": "timestamp", "type": "number" },
 | |
| +                { "name": "frameId", "$ref": "Network.FrameId", "description": "Id of the frame that has fired DOMContentLoaded event." }
 | |
|              ]
 | |
|          },
 | |
|          {
 | |
|              "name": "loadEventFired",
 | |
|              "targetTypes": ["page"],
 | |
|              "parameters": [
 | |
| -                { "name": "timestamp", "type": "number" }
 | |
| +              { "name": "timestamp", "type": "number" },
 | |
| +              { "name": "frameId", "$ref": "Network.FrameId", "description": "Id of the frame that has fired load event." }
 | |
|              ]
 | |
|          },
 | |
|          {
 | |
| @@ -338,6 +518,14 @@
 | |
|                  { "name": "frame", "$ref": "Frame", "description": "Frame object." }
 | |
|              ]
 | |
|          },
 | |
| +        {
 | |
| +          "name": "frameAttached",
 | |
| +          "description": "Fired when frame has been attached to its parent.",
 | |
| +          "parameters": [
 | |
| +              { "name": "frameId", "$ref": "Network.FrameId", "description": "Id of the frame that has been detached." },
 | |
| +              { "name": "parentFrameId", "$ref": "Network.FrameId", "optional": true, "description": "Parent frame id if non-root." }
 | |
| +          ]
 | |
| +        },
 | |
|          {
 | |
|              "name": "frameDetached",
 | |
|              "description": "Fired when frame has been detached from its parent.",
 | |
| @@ -377,6 +565,22 @@
 | |
|                  { "name": "frameId", "$ref": "Network.FrameId", "description": "Id of the frame that has cleared its scheduled navigation." }
 | |
|              ]
 | |
|          },
 | |
| +        {
 | |
| +            "name": "navigatedWithinDocument",
 | |
| +            "description": "Fired when same-document navigation happens, e.g. due to history API usage or anchor navigation.",
 | |
| +            "parameters": [
 | |
| +                {
 | |
| +                    "name": "frameId",
 | |
| +                    "description": "Id of the frame.",
 | |
| +                    "$ref": "Network.FrameId"
 | |
| +                },
 | |
| +                {
 | |
| +                    "name": "url",
 | |
| +                    "description": "Frame's new url.",
 | |
| +                    "type": "string"
 | |
| +                }
 | |
| +            ]
 | |
| +        },
 | |
|          {
 | |
|              "name": "defaultAppearanceDidChange",
 | |
|              "description": "Fired when page's default appearance changes, even if there is a forced appearance.",
 | |
| @@ -385,6 +589,42 @@
 | |
|              "parameters": [
 | |
|                  { "name": "appearance", "$ref": "Appearance", "description": "Name of the appearance that is active (not considering any forced appearance.)" }
 | |
|              ]
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "willCheckNavigationPolicy",
 | |
| +            "description": "Fired when page is about to check policy for newly triggered navigation.",
 | |
| +            "parameters": [
 | |
| +                {
 | |
| +                    "name": "frameId",
 | |
| +                    "description": "Id of the frame.",
 | |
| +                    "$ref": "Network.FrameId"
 | |
| +                }
 | |
| +            ]
 | |
| +          },
 | |
| +          {
 | |
| +            "name": "didCheckNavigationPolicy",
 | |
| +            "description": "Fired when page has received navigation policy decision.",
 | |
| +            "parameters": [
 | |
| +                {
 | |
| +                    "name": "frameId",
 | |
| +                    "description": "Id of the frame.",
 | |
| +                    "$ref": "Network.FrameId"
 | |
| +                },
 | |
| +                {
 | |
| +                    "name": "cancel",
 | |
| +                    "description": "True if the navigation will not continue in this frame.",
 | |
| +                    "type": "boolean",
 | |
| +                    "optional": true
 | |
| +                }
 | |
| +            ]
 | |
| +          },
 | |
| +          {
 | |
| +            "name": "fileChooserOpened",
 | |
| +            "description": "Fired when the page shows file chooser for it's <input type=file>.",
 | |
| +            "parameters": [
 | |
| +                { "name": "frameId", "$ref": "Network.FrameId", "description": "Frame where file chooser is opened." },
 | |
| +                { "name": "element", "$ref": "Runtime.RemoteObject", "description": "Input element." }
 | |
| +            ]
 | |
|          }
 | |
|      ]
 | |
|  }
 | |
| diff --git a/Source/JavaScriptCore/inspector/protocol/Playwright.json b/Source/JavaScriptCore/inspector/protocol/Playwright.json
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..91bdeadaeb77d223cd4dc47b8bb90850d54a9056
 | |
| --- /dev/null
 | |
| +++ b/Source/JavaScriptCore/inspector/protocol/Playwright.json
 | |
| @@ -0,0 +1,277 @@
 | |
| +{
 | |
| +    "domain": "Playwright",
 | |
| +    "availability": ["web"],
 | |
| +    "types": [
 | |
| +        {
 | |
| +            "id": "ContextID",
 | |
| +            "type": "string",
 | |
| +            "description": "Id of Browser context."
 | |
| +        },
 | |
| +        {
 | |
| +            "id": "PageProxyID",
 | |
| +            "type": "string",
 | |
| +            "description": "Id of WebPageProxy."
 | |
| +        },
 | |
| +        {
 | |
| +            "id": "CookieSameSitePolicy",
 | |
| +            "type": "string",
 | |
| +            "enum": ["None", "Lax", "Strict"],
 | |
| +            "description": "Same-Site policy of a cookie."
 | |
| +        },
 | |
| +        {
 | |
| +            "id": "Cookie",
 | |
| +            "type": "object",
 | |
| +            "description": "Cookie object",
 | |
| +            "properties": [
 | |
| +                { "name": "name", "type": "string", "description": "Cookie name." },
 | |
| +                { "name": "value", "type": "string", "description": "Cookie value." },
 | |
| +                { "name": "domain", "type": "string", "description": "Cookie domain." },
 | |
| +                { "name": "path", "type": "string", "description": "Cookie path." },
 | |
| +                { "name": "expires", "type": "number", "description": "Cookie expires." },
 | |
| +                { "name": "httpOnly", "type": "boolean", "description": "True if cookie is http-only." },
 | |
| +                { "name": "secure", "type": "boolean", "description": "True if cookie is secure." },
 | |
| +                { "name": "session", "type": "boolean", "description": "True if cookie is session cookie." },
 | |
| +                { "name": "sameSite", "$ref": "CookieSameSitePolicy", "description": "Cookie Same-Site policy." }
 | |
| +            ]
 | |
| +        },
 | |
| +        {
 | |
| +            "id": "SetCookieParam",
 | |
| +            "type": "object",
 | |
| +            "description": "Cookie object",
 | |
| +            "properties": [
 | |
| +                { "name": "name", "type": "string", "description": "Cookie name." },
 | |
| +                { "name": "value", "type": "string", "description": "Cookie value." },
 | |
| +                { "name": "domain", "type": "string", "description": "Cookie domain." },
 | |
| +                { "name": "path", "type": "string", "description": "Cookie path." },
 | |
| +                { "name": "expires", "type": "number", "optional": true, "description": "Cookie expires." },
 | |
| +                { "name": "httpOnly", "type": "boolean", "optional": true, "description": "True if cookie is http-only." },
 | |
| +                { "name": "secure", "type": "boolean", "optional": true, "description": "True if cookie is secure." },
 | |
| +                { "name": "session", "type": "boolean", "optional": true, "description": "True if cookie is session cookie." },
 | |
| +                { "name": "sameSite", "$ref": "CookieSameSitePolicy", "optional": true, "description": "Cookie Same-Site policy." }
 | |
| +            ]
 | |
| +        },
 | |
| +        {
 | |
| +            "id": "NameValue",
 | |
| +            "type": "object",
 | |
| +            "description": "Name-value pair",
 | |
| +            "properties": [
 | |
| +                { "name": "name", "type": "string" },
 | |
| +                { "name": "value", "type": "string" }
 | |
| +            ]
 | |
| +        },
 | |
| +        {
 | |
| +            "id": "OriginStorage",
 | |
| +            "type": "object",
 | |
| +            "description": "Origin object",
 | |
| +            "properties": [
 | |
| +                { "name": "origin", "type": "string", "description": "Origin." },
 | |
| +                { "name": "items", "type": "array", "items": { "$ref": "NameValue" }, "description": "Storage entries." }
 | |
| +            ]
 | |
| +        },
 | |
| +        {
 | |
| +            "id": "Geolocation",
 | |
| +            "type": "object",
 | |
| +            "description": "Geolocation",
 | |
| +            "properties": [
 | |
| +                { "name": "timestamp", "type": "number", "description": "Mock latitude" },
 | |
| +                { "name": "latitude", "type": "number", "description": "Mock latitude" },
 | |
| +                { "name": "longitude", "type": "number", "description": "Mock longitude" },
 | |
| +                { "name": "accuracy", "type": "number", "description": "Mock accuracy" }
 | |
| +            ]
 | |
| +        }
 | |
| +    ],
 | |
| +    "commands": [
 | |
| +        {
 | |
| +            "name": "enable"
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "disable"
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "close",
 | |
| +            "async": true,
 | |
| +            "description": "Close browser."
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "createContext",
 | |
| +            "description": "Creates new ephemeral browser context.",
 | |
| +            "parameters": [
 | |
| +                { "name": "proxyServer", "type": "string", "optional": true, "description": "Proxy server, similar to the one passed to --proxy-server" },
 | |
| +                { "name": "proxyBypassList", "type": "string", "optional": true, "description": "Proxy bypass list, similar to the one passed to --proxy-bypass-list" }
 | |
| +            ],
 | |
| +            "returns": [
 | |
| +                { "name": "browserContextId", "$ref": "ContextID", "description": "Unique identifier of the context." }
 | |
| +            ]
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "deleteContext",
 | |
| +            "async": true,
 | |
| +            "description": "Deletes browser context previously created with createContect. The command will automatically close all pages that use the context.",
 | |
| +            "parameters": [
 | |
| +                { "name": "browserContextId", "$ref": "ContextID", "description": "Identifier of the context to delete." }
 | |
| +            ]
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "createPage",
 | |
| +            "parameters": [
 | |
| +                { "name": "browserContextId", "$ref": "ContextID", "optional": true, "description": "JSON Inspector Protocol message (command) to be dispatched on the backend." }
 | |
| +            ],
 | |
| +            "returns": [
 | |
| +                { "name": "pageProxyId", "$ref": "PageProxyID", "description": "Unique identifier of the page proxy." }
 | |
| +            ]
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "navigate",
 | |
| +            "async": true,
 | |
| +            "description": "Navigates current page to the given URL.",
 | |
| +            "parameters": [
 | |
| +                { "name": "url", "type": "string", "description": "URL to navigate the page to." },
 | |
| +                { "name": "pageProxyId", "$ref": "PageProxyID", "description": "Unique identifier of the page proxy." },
 | |
| +                { "name": "frameId", "$ref": "Network.FrameId", "optional": true, "description": "Id of the frame to navigate."},
 | |
| +                { "name": "referrer", "type": "string", "optional": true, "description": "Referrer URL." }
 | |
| +            ],
 | |
| +            "returns": [
 | |
| +                { "name": "loaderId", "$ref": "Network.LoaderId", "optional": true, "description": "Identifier of the loader associated with the navigation." }
 | |
| +            ]
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "grantFileReadAccess",
 | |
| +            "description": "Grants read access for the specified files to the web process of the page.",
 | |
| +            "parameters": [
 | |
| +                { "name": "pageProxyId", "$ref": "PageProxyID", "description": "Unique identifier of the page proxy." },
 | |
| +                { "name": "paths", "type": "array", "items": { "type": "string" }, "description": "Id of the frame to navigate."}
 | |
| +            ]
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "setIgnoreCertificateErrors",
 | |
| +            "description": "Change whether all certificate errors should be ignored.",
 | |
| +            "parameters": [
 | |
| +                { "name": "browserContextId", "$ref": "ContextID", "optional": true, "description": "Browser context id." },
 | |
| +                { "name": "ignore", "type": "boolean" }
 | |
| +            ]
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "getAllCookies",
 | |
| +            "description": "Returns all cookies in the given browser context.",
 | |
| +            "async": true,
 | |
| +            "parameters": [
 | |
| +                { "name": "browserContextId", "$ref": "ContextID", "optional": true, "description": "Browser context id." }
 | |
| +            ],
 | |
| +            "returns": [
 | |
| +                { "name": "cookies", "type": "array", "items": { "$ref": "Cookie" }, "description": "Cookies." }
 | |
| +            ]
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "setCookies",
 | |
| +            "description": "Sets cookies in the given browser context.",
 | |
| +            "async": true,
 | |
| +            "parameters": [
 | |
| +                { "name": "browserContextId", "$ref": "ContextID", "optional": true, "description": "Browser context id." },
 | |
| +                { "name": "cookies", "type": "array", "items": { "$ref": "SetCookieParam" }, "description": "Cookies." }
 | |
| +            ]
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "deleteAllCookies",
 | |
| +            "description": "Deletes cookies in the given browser context.",
 | |
| +            "async": true,
 | |
| +            "parameters": [
 | |
| +                { "name": "browserContextId", "$ref": "ContextID", "optional": true, "description": "Browser context id." }
 | |
| +            ]
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "setGeolocationOverride",
 | |
| +            "parameters": [
 | |
| +                { "name": "browserContextId", "$ref": "ContextID", "optional": true, "description": "Browser context id." },
 | |
| +                { "name": "geolocation", "$ref": "Geolocation", "optional": true, "description": "Geolocation to set, if missing emulates position unavailable." }
 | |
| +            ],
 | |
| +            "description": "Overrides the geolocation position or error."
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "setLanguages",
 | |
| +            "description": "Allows to set locale language for context.",
 | |
| +            "parameters": [
 | |
| +                { "name": "languages", "type": "array", "items": { "type": "string" } },
 | |
| +                { "name": "browserContextId", "$ref": "ContextID", "optional": true, "description": "Browser context id." }
 | |
| +            ]
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "setDownloadBehavior",
 | |
| +            "description": "Allows to override download behavior.",
 | |
| +            "parameters": [
 | |
| +                { "name": "behavior", "optional": true, "type": "string", "enum": ["allow", "deny"] },
 | |
| +                { "name": "downloadPath", "optional": true, "type": "string" },
 | |
| +                { "name": "browserContextId", "$ref": "ContextID", "optional": true, "description": "Browser context id." }
 | |
| +            ]
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "cancelDownload",
 | |
| +            "parameters": [
 | |
| +                { "name": "uuid", "type": "string" }
 | |
| +            ],
 | |
| +            "description": "Cancels a current running download."
 | |
| +        }
 | |
| +    ],
 | |
| +    "events": [
 | |
| +        {
 | |
| +            "name": "pageProxyCreated",
 | |
| +            "parameters": [
 | |
| +                { "name": "browserContextId", "$ref": "ContextID", "description": "Unique identifier of the context." },
 | |
| +                { "name": "pageProxyId", "$ref": "PageProxyID" },
 | |
| +                { "name": "openerId", "$ref": "PageProxyID", "optional": true, "description": "Unique identifier of the opening page. Only set for pages created by window.open()." }
 | |
| +            ]
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "pageProxyDestroyed",
 | |
| +            "parameters": [
 | |
| +                { "name": "pageProxyId", "$ref": "PageProxyID" }
 | |
| +            ]
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "provisionalLoadFailed",
 | |
| +            "description": "Fired when provisional load fails.",
 | |
| +            "parameters": [
 | |
| +                { "name": "pageProxyId", "$ref": "PageProxyID", "description": "Unique identifier of the page proxy." },
 | |
| +                { "name": "loaderId", "$ref": "Network.LoaderId", "description": "Identifier of the loader associated with the navigation." },
 | |
| +                { "name": "error", "type": "string", "description": "Localized error string." }
 | |
| +            ]
 | |
| +        },
 | |
| +        {
 | |
| +          "name": "windowOpen",
 | |
| +          "description": "Fired when page opens a new window.",
 | |
| +          "parameters": [
 | |
| +              { "name": "pageProxyId", "$ref": "PageProxyID", "description": "Unique identifier of the page proxy." },
 | |
| +              { "name": "url", "type": "string" },
 | |
| +              { "name": "windowFeatures", "type": "array", "items": { "type": "string" } }
 | |
| +          ]
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "downloadCreated",
 | |
| +            "parameters": [
 | |
| +                { "name": "pageProxyId", "$ref": "PageProxyID", "description": "Unique identifier of the page proxy." },
 | |
| +                { "name": "frameId", "$ref": "Network.FrameId", "description": "Unique identifier of the originating frame." },
 | |
| +                { "name": "uuid", "type": "string" },
 | |
| +                { "name": "url", "type": "string" }
 | |
| +            ]
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "downloadFilenameSuggested",
 | |
| +            "parameters": [
 | |
| +                { "name": "uuid", "type": "string" },
 | |
| +                { "name": "suggestedFilename", "type": "string" }
 | |
| +            ]
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "downloadFinished",
 | |
| +            "parameters": [
 | |
| +                { "name": "uuid", "type": "string" },
 | |
| +                { "name": "error", "type": "string" }
 | |
| +            ]
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "screencastFinished",
 | |
| +            "parameters": [
 | |
| +                { "name": "screencastId", "$ref": "Screencast.ScreencastId", "description": "Unique identifier of the screencast." }
 | |
| +            ]
 | |
| +        }
 | |
| +    ]
 | |
| +}
 | |
| diff --git a/Source/JavaScriptCore/inspector/protocol/Runtime.json b/Source/JavaScriptCore/inspector/protocol/Runtime.json
 | |
| index 274b01596d490fb81b48cf89bf668e0634e8b423..d08a9ddd745c748767ba8055907daa7beeffc219 100644
 | |
| --- a/Source/JavaScriptCore/inspector/protocol/Runtime.json
 | |
| +++ b/Source/JavaScriptCore/inspector/protocol/Runtime.json
 | |
| @@ -261,12 +261,14 @@
 | |
|                  { "name": "doNotPauseOnExceptionsAndMuteConsole", "type": "boolean", "optional": true, "description": "Specifies whether function call should stop on exceptions and mute console. Overrides setPauseOnException state." },
 | |
|                  { "name": "returnByValue", "type": "boolean", "optional": true, "description": "Whether the result is expected to be a JSON object which should be sent by value." },
 | |
|                  { "name": "generatePreview", "type": "boolean", "optional": true, "description": "Whether preview should be generated for the result." },
 | |
| -                { "name": "emulateUserGesture", "type": "boolean", "optional": true, "description": "Whether the expression should be considered to be in a user gesture or not." }
 | |
| +                { "name": "emulateUserGesture", "type": "boolean", "optional": true, "description": "Whether the expression should be considered to be in a user gesture or not." },
 | |
| +                { "name": "awaitPromise", "type": "boolean", "optional": true, "description": "Whether to automatically await returned promise." }
 | |
|              ],
 | |
|              "returns": [
 | |
|                  { "name": "result", "$ref": "RemoteObject", "description": "Call result." },
 | |
|                  { "name": "wasThrown", "type": "boolean", "optional": true, "description": "True if the result was thrown during the evaluation." }
 | |
| -            ]
 | |
| +            ],
 | |
| +            "async": true
 | |
|          },
 | |
|          {
 | |
|              "name": "getPreview",
 | |
| diff --git a/Source/JavaScriptCore/inspector/protocol/Screencast.json b/Source/JavaScriptCore/inspector/protocol/Screencast.json
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..73a4e53ced3acc41316bb8d4c787306d3f28a27e
 | |
| --- /dev/null
 | |
| +++ b/Source/JavaScriptCore/inspector/protocol/Screencast.json
 | |
| @@ -0,0 +1,64 @@
 | |
| +{
 | |
| +    "domain": "Screencast",
 | |
| +    "availability": ["web"],
 | |
| +    "types": [
 | |
| +        {
 | |
| +            "id": "ScreencastId",
 | |
| +            "type": "string",
 | |
| +            "description": "Unique identifier of the screencast."
 | |
| +        }
 | |
| +    ],
 | |
| +    "commands": [
 | |
| +        {
 | |
| +            "name": "startVideo",
 | |
| +            "description": "Starts recoring video to speified file.",
 | |
| +            "parameters": [
 | |
| +                { "name": "file", "type": "string", "description": "Output file location." },
 | |
| +                { "name": "width", "type": "integer" },
 | |
| +                { "name": "height", "type": "integer" },
 | |
| +                { "name": "toolbarHeight", "type": "integer" }
 | |
| +            ],
 | |
| +            "returns": [
 | |
| +                { "name": "screencastId", "$ref": "ScreencastId", "description": "Unique identifier of the screencast." }
 | |
| +            ]
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "stopVideo",
 | |
| +            "async": true,
 | |
| +            "description": "Stops recoding video. Returns after the file has been closed."
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "startScreencast",
 | |
| +            "description": "Starts screencast.",
 | |
| +            "parameters": [
 | |
| +                { "name": "width", "type": "integer" },
 | |
| +                { "name": "height", "type": "integer" },
 | |
| +                { "name": "toolbarHeight", "type": "integer" },
 | |
| +                { "name": "quality", "type": "integer" }
 | |
| +            ],
 | |
| +            "returns": [
 | |
| +                { "name": "generation", "type": "integer", "description": "Screencast session generation." }
 | |
| +            ]
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "stopScreencast",
 | |
| +            "description": "Stops screencast."
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "screencastFrameAck",
 | |
| +            "parameters": [
 | |
| +                { "name": "generation", "type": "integer", "description": "Screencast session generation" }
 | |
| +            ]
 | |
| +        }
 | |
| +    ],
 | |
| +    "events": [
 | |
| +        {
 | |
| +            "name": "screencastFrame",
 | |
| +            "parameters": [
 | |
| +                { "name": "data", "type": "string", "description": "Base64 data" },
 | |
| +                { "name": "deviceWidth", "type": "integer" },
 | |
| +                { "name": "deviceHeight", "type": "integer" }
 | |
| +            ]
 | |
| +        }
 | |
| +    ]
 | |
| +}
 | |
| diff --git a/Source/JavaScriptCore/inspector/protocol/Target.json b/Source/JavaScriptCore/inspector/protocol/Target.json
 | |
| index 52920cded24a9c6b0ef6fb4e518664955db4f9fa..bbbabc4e7259088b9404e8cc07eecd6f45077da0 100644
 | |
| --- a/Source/JavaScriptCore/inspector/protocol/Target.json
 | |
| +++ b/Source/JavaScriptCore/inspector/protocol/Target.json
 | |
| @@ -10,7 +10,7 @@
 | |
|              "properties": [
 | |
|                  { "name": "targetId", "type": "string", "description": "Unique identifier for the target." },
 | |
|                  { "name": "type", "type": "string", "enum": ["page", "service-worker", "worker"] },
 | |
| -                { "name": "isProvisional", "type": "boolean", "optional": true, "description": "Whether this is a provisional page target." },
 | |
| +                { "name": "isProvisional", "type": "boolean", "optional": true, "description": "True value indicates that this is a provisional page target i.e. Such target may be created when current page starts cross-origin navigation. Eventually each provisional target is either committed and swaps with the current target or gets destroyed, e.g. in case of load request failure." },
 | |
|                  { "name": "isPaused", "type": "boolean", "optional": true, "description": "Whether the target is paused on start and has to be explicitely resumed by inspector." }
 | |
|              ]
 | |
|          }
 | |
| @@ -37,6 +37,21 @@
 | |
|                  { "name": "targetId", "type": "string" },
 | |
|                  { "name": "message", "type": "string", "description": "JSON Inspector Protocol message (command) to be dispatched on the backend." }
 | |
|              ]
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "activate",
 | |
| +            "description": "Reveals the target on screen.",
 | |
| +            "parameters": [
 | |
| +                { "name": "targetId", "type": "string" }
 | |
| +            ]
 | |
| +        },
 | |
| +        {
 | |
| +            "name": "close",
 | |
| +            "description": "Closes the target.",
 | |
| +            "parameters": [
 | |
| +                { "name": "targetId", "type": "string" },
 | |
| +                { "name": "runBeforeUnload", "type": "boolean", "optional": true }
 | |
| +            ]
 | |
|          }
 | |
|      ],
 | |
|      "events": [
 | |
| @@ -49,7 +64,8 @@
 | |
|          {
 | |
|              "name": "targetDestroyed",
 | |
|              "parameters": [
 | |
| -                { "name": "targetId", "type": "string" }
 | |
| +                { "name": "targetId", "type": "string" },
 | |
| +                { "name": "crashed", "type": "boolean" }
 | |
|              ]
 | |
|          },
 | |
|          {
 | |
| diff --git a/Source/JavaScriptCore/inspector/protocol/Worker.json b/Source/JavaScriptCore/inspector/protocol/Worker.json
 | |
| index 638612413466efc87b737e8a81042ed07ca12703..6f9e518ff0bfa2a6228675d25b6b785f1ed3022a 100644
 | |
| --- a/Source/JavaScriptCore/inspector/protocol/Worker.json
 | |
| +++ b/Source/JavaScriptCore/inspector/protocol/Worker.json
 | |
| @@ -16,7 +16,7 @@
 | |
|              "description": "Sent after the frontend has sent all initialization messages and can resume this worker. This command is required to allow execution in the worker.",
 | |
|              "parameters": [
 | |
|                  { "name": "workerId", "type": "string" }
 | |
| -            ]            
 | |
| +            ]
 | |
|          },
 | |
|          {
 | |
|              "name": "sendMessageToWorker",
 | |
| @@ -33,7 +33,8 @@
 | |
|              "parameters": [
 | |
|                  { "name": "workerId", "type": "string" },
 | |
|                  { "name": "url", "type": "string" },
 | |
| -                { "name": "name", "type": "string" }
 | |
| +                { "name": "name", "type": "string" },
 | |
| +                { "name": "frameId", "$ref": "Network.FrameId", "description": "Id of the frame this worker belongs to." }
 | |
|              ]
 | |
|          },
 | |
|          {
 | |
| diff --git a/Source/ThirdParty/libwebrtc/CMakeLists.txt b/Source/ThirdParty/libwebrtc/CMakeLists.txt
 | |
| index 0d42c17c6a85b2a9f6af319431332f7f8a709188..8899c8e85b11db81d1da14c7f27814883f75da50 100644
 | |
| --- a/Source/ThirdParty/libwebrtc/CMakeLists.txt
 | |
| +++ b/Source/ThirdParty/libwebrtc/CMakeLists.txt
 | |
| @@ -398,6 +398,11 @@ set(webrtc_SOURCES
 | |
|      Source/third_party/boringssl/src/ssl/tls13_server.cc
 | |
|      Source/third_party/boringssl/src/ssl/tls_method.cc
 | |
|      Source/third_party/boringssl/src/ssl/tls_record.cc
 | |
| +# Playwright begin
 | |
| +    Source/third_party/libwebm/mkvmuxer/mkvmuxer.cc
 | |
| +    Source/third_party/libwebm/mkvmuxer/mkvmuxerutil.cc
 | |
| +    Source/third_party/libwebm/mkvmuxer/mkvwriter.cc
 | |
| +# Playwright end
 | |
|      Source/third_party/libyuv/source/compare_common.cc
 | |
|      Source/third_party/libyuv/source/compare_gcc.cc
 | |
|      Source/third_party/libyuv/source/convert.cc
 | |
| @@ -1857,6 +1862,10 @@ set(webrtc_INCLUDE_DIRECTORIES PRIVATE
 | |
|      Source/third_party/libsrtp/config
 | |
|      Source/third_party/libsrtp/crypto/include
 | |
|      Source/third_party/libsrtp/include
 | |
| +# Playwright begin
 | |
| +    Source/third_party/libwebm
 | |
| +    Source/third_party/libvpx/source/libvpx
 | |
| +# Playwright end
 | |
|      Source/third_party/libyuv/include
 | |
|      Source/third_party/opus/src/celt
 | |
|      Source/third_party/opus/src/include
 | |
| diff --git a/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.mac.exp b/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.mac.exp
 | |
| index 4157c0a95fa332ac85a295814fda2fb61f3da434..6edd90d2c5fc3b16d19f4d73edacf8b3c776bb9e 100644
 | |
| --- a/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.mac.exp
 | |
| +++ b/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.mac.exp
 | |
| @@ -338,3 +338,23 @@ __ZN6webrtc32createPixelBufferFromFrameBufferERNS_16VideoFrameBufferERKNSt3__18f
 | |
|  __ZN6webrtc25CreateTaskQueueGcdFactoryEv
 | |
|  __ZN6webrtc27CreatePeerConnectionFactoryEPN3rtc6ThreadES2_S2_NS0_13scoped_refptrINS_17AudioDeviceModuleEEENS3_INS_19AudioEncoderFactoryEEENS3_INS_19AudioDecoderFactoryEEENSt3__110unique_ptrINS_19VideoEncoderFactoryENSA_14default_deleteISC_EEEENSB_INS_19VideoDecoderFactoryENSD_ISG_EEEENS3_INS_10AudioMixerEEENS3_INS_15AudioProcessingEEEPNS_19AudioFrameProcessorENSB_INS_16TaskQueueFactoryENSD_ISP_EEEE
 | |
|  __ZN6webrtc16convertBGRAToYUVEP10__CVBufferS1_
 | |
| +__ZN8mkvmuxer11SegmentInfo15set_writing_appEPKc
 | |
| +__ZN8mkvmuxer11SegmentInfo4InitEv
 | |
| +__ZN8mkvmuxer7Segment10OutputCuesEb
 | |
| +__ZN8mkvmuxer7Segment13AddVideoTrackEiii
 | |
| +__ZN8mkvmuxer7Segment4InitEPNS_10IMkvWriterE
 | |
| +__ZN8mkvmuxer7Segment8AddFrameEPKhyyyb
 | |
| +__ZN8mkvmuxer7Segment8FinalizeEv
 | |
| +__ZN8mkvmuxer7SegmentC1Ev
 | |
| +__ZN8mkvmuxer7SegmentD1Ev
 | |
| +__ZN8mkvmuxer9MkvWriterC1EP7__sFILE
 | |
| +_ARGBToI420
 | |
| +_vpx_codec_enc_config_default
 | |
| +_vpx_codec_enc_init_ver
 | |
| +_vpx_codec_encode
 | |
| +_vpx_codec_err_to_string
 | |
| +_vpx_codec_error
 | |
| +_vpx_codec_get_cx_data
 | |
| +_vpx_codec_iface_name
 | |
| +_vpx_codec_version_str
 | |
| +_vpx_codec_vp8_cx
 | |
| diff --git a/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.xcconfig b/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.xcconfig
 | |
| index 38a4ad6f76932fe5ad6a00689fe60c5b8cc5d042..3cab39566912440255fdbfb765e3a5e7acc0491a 100644
 | |
| --- a/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.xcconfig
 | |
| +++ b/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.xcconfig
 | |
| @@ -52,7 +52,7 @@ DYLIB_INSTALL_NAME_BASE_WK_RELOCATABLE_FRAMEWORKS_ = $(NORMAL_WEBCORE_FRAMEWORKS
 | |
|  DYLIB_INSTALL_NAME_BASE_WK_RELOCATABLE_FRAMEWORKS_YES = @loader_path/../../../;
 | |
|  
 | |
|  GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
 | |
| -HEADER_SEARCH_PATHS = Source Source/third_party/libsrtp/crypto/include Source/third_party/libsrtp/include Source/third_party/boringssl/src/include Source/third_party/libyuv/include Source/third_party/usrsctp Source/third_party/usrsctp/usrsctplib Source/third_party/usrsctp/usrsctplib/usrsctplib Source/webrtc/sdk/objc/Framework/Headers Source/webrtc/common_audio/signal_processing/include Source/webrtc/modules/audio_coding/codecs/isac/main/include Source/third_party/opus/src/celt Source/third_party/opus/src/include Source/third_party/opus/src/src Source/webrtc/modules/audio_device/mac Source/third_party/usrsctp/usrsctplib/usrsctplib/netinet Source/webrtc/modules/audio_device/ios Source/webrtc Source/webrtc/sdk/objc Source/webrtc/sdk/objc/base Source/webrtc/sdk/objc/Framework/Classes Source/third_party/libsrtp/config Source/webrtc/sdk/objc/Framework/Classes/Common Source/webrtc/sdk/objc/Framework/Classes/Video Source/webrtc/sdk/objc/Framework/Classes/PeerConnection Source/third_party/abseil-cpp Source/third_party/libvpx/source/libvpx Source/third_party/libwebm/webm_parser/include;
 | |
| +HEADER_SEARCH_PATHS = Source Source/third_party/libsrtp/crypto/include Source/third_party/libsrtp/include Source/third_party/boringssl/src/include Source/third_party/libyuv/include Source/third_party/usrsctp Source/third_party/usrsctp/usrsctplib Source/third_party/usrsctp/usrsctplib/usrsctplib Source/webrtc/sdk/objc/Framework/Headers Source/webrtc/common_audio/signal_processing/include Source/webrtc/modules/audio_coding/codecs/isac/main/include Source/third_party/opus/src/celt Source/third_party/opus/src/include Source/third_party/opus/src/src Source/webrtc/modules/audio_device/mac Source/third_party/usrsctp/usrsctplib/usrsctplib/netinet Source/webrtc/modules/audio_device/ios Source/webrtc Source/webrtc/sdk/objc Source/webrtc/sdk/objc/base Source/webrtc/sdk/objc/Framework/Classes Source/third_party/libsrtp/config Source/webrtc/sdk/objc/Framework/Classes/Common Source/webrtc/sdk/objc/Framework/Classes/Video Source/webrtc/sdk/objc/Framework/Classes/PeerConnection Source/third_party/abseil-cpp Source/third_party/libvpx/source/libvpx Source/third_party/libwebm/webm_parser/include Source/third_party/libvpx/source/libvpx/third_party/libwebm;
 | |
|  
 | |
|  PUBLIC_HEADERS_FOLDER_PREFIX = /usr/local/include;
 | |
|  INSTALL_PUBLIC_HEADER_PREFIX = $(INSTALL_PATH_PREFIX)$(PUBLIC_HEADERS_FOLDER_PREFIX);
 | |
| diff --git a/Source/ThirdParty/libwebrtc/libwebrtc.xcodeproj/project.pbxproj b/Source/ThirdParty/libwebrtc/libwebrtc.xcodeproj/project.pbxproj
 | |
| index e4b94b59216277aae01696e6d4846abf8f287dce..86dd35168450f2d9ab91c2b2d0f6ca954ecf8ba7 100644
 | |
| --- a/Source/ThirdParty/libwebrtc/libwebrtc.xcodeproj/project.pbxproj
 | |
| +++ b/Source/ThirdParty/libwebrtc/libwebrtc.xcodeproj/project.pbxproj
 | |
| @@ -6,6 +6,20 @@
 | |
|  	objectVersion = 52;
 | |
|  	objects = {
 | |
|  
 | |
| +/* Begin PBXAggregateTarget section */
 | |
| +		F31720AC27FE215900EEE407 /* Copy libvpx headers */ = {
 | |
| +			isa = PBXAggregateTarget;
 | |
| +			buildConfigurationList = F31720B027FE215900EEE407 /* Build configuration list for PBXAggregateTarget "Copy libvpx headers" */;
 | |
| +			buildPhases = (
 | |
| +				F31720B127FE216400EEE407 /* ShellScript */,
 | |
| +			);
 | |
| +			dependencies = (
 | |
| +			);
 | |
| +			name = "Copy libvpx headers";
 | |
| +			productName = "Copy libvpx headers";
 | |
| +		};
 | |
| +/* End PBXAggregateTarget section */
 | |
| +
 | |
|  /* Begin PBXBuildFile section */
 | |
|  		410091CF242CFD6500C5EDA2 /* internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 41A391FA1EFC493000C4516A /* internal.h */; };
 | |
|  		410091D2242CFF6F00C5EDA2 /* gcm_nohw.c in Sources */ = {isa = PBXBuildFile; fileRef = 410091D0242CFD8200C5EDA2 /* gcm_nohw.c */; };
 | |
| @@ -4529,6 +4543,9 @@
 | |
|  		DDF30D9127C5C725006A526F /* receive_side_congestion_controller.h in Headers */ = {isa = PBXBuildFile; fileRef = DDF30D9027C5C725006A526F /* receive_side_congestion_controller.h */; };
 | |
|  		DDF30D9527C5C756006A526F /* bwe_defines.h in Headers */ = {isa = PBXBuildFile; fileRef = DDF30D9327C5C756006A526F /* bwe_defines.h */; };
 | |
|  		DDF30D9627C5C756006A526F /* remote_bitrate_estimator.h in Headers */ = {isa = PBXBuildFile; fileRef = DDF30D9427C5C756006A526F /* remote_bitrate_estimator.h */; };
 | |
| +		F3B7819924C7CC5200FCB122 /* mkvmuxerutil.cc in Sources */ = {isa = PBXBuildFile; fileRef = F3B7819624C7CC5100FCB122 /* mkvmuxerutil.cc */; };
 | |
| +		F3B7819A24C7CC5200FCB122 /* mkvmuxer.cc in Sources */ = {isa = PBXBuildFile; fileRef = F3B7819724C7CC5200FCB122 /* mkvmuxer.cc */; };
 | |
| +		F3B7819B24C7CC5200FCB122 /* mkvwriter.cc in Sources */ = {isa = PBXBuildFile; fileRef = F3B7819824C7CC5200FCB122 /* mkvwriter.cc */; };
 | |
|  /* End PBXBuildFile section */
 | |
|  
 | |
|  /* Begin PBXBuildRule section */
 | |
| @@ -4779,6 +4796,13 @@
 | |
|  			remoteGlobalIDString = DDF30D0527C5C003006A526F;
 | |
|  			remoteInfo = absl;
 | |
|  		};
 | |
| +		F31720B327FE273100EEE407 /* PBXContainerItemProxy */ = {
 | |
| +			isa = PBXContainerItemProxy;
 | |
| +			containerPortal = FB39D0701200ED9200088E69 /* Project object */;
 | |
| +			proxyType = 1;
 | |
| +			remoteGlobalIDString = F31720AC27FE215900EEE407;
 | |
| +			remoteInfo = "Copy libvpx headers";
 | |
| +		};
 | |
|  /* End PBXContainerItemProxy section */
 | |
|  
 | |
|  /* Begin PBXCopyFilesBuildPhase section */
 | |
| @@ -9558,6 +9582,9 @@
 | |
|  		DDF30D9027C5C725006A526F /* receive_side_congestion_controller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = receive_side_congestion_controller.h; sourceTree = "<group>"; };
 | |
|  		DDF30D9327C5C756006A526F /* bwe_defines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bwe_defines.h; sourceTree = "<group>"; };
 | |
|  		DDF30D9427C5C756006A526F /* remote_bitrate_estimator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = remote_bitrate_estimator.h; sourceTree = "<group>"; };
 | |
| +		F3B7819624C7CC5100FCB122 /* mkvmuxerutil.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = mkvmuxerutil.cc; path = mkvmuxer/mkvmuxerutil.cc; sourceTree = "<group>"; };
 | |
| +		F3B7819724C7CC5200FCB122 /* mkvmuxer.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = mkvmuxer.cc; path = mkvmuxer/mkvmuxer.cc; sourceTree = "<group>"; };
 | |
| +		F3B7819824C7CC5200FCB122 /* mkvwriter.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = mkvwriter.cc; path = mkvmuxer/mkvwriter.cc; sourceTree = "<group>"; };
 | |
|  		FB39D0D11200F0E300088E69 /* libwebrtc.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libwebrtc.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
 | |
|  /* End PBXFileReference section */
 | |
|  
 | |
| @@ -16876,6 +16903,7 @@
 | |
|  			isa = PBXGroup;
 | |
|  			children = (
 | |
|  				CDFD2F9224C4B2F90048DAC3 /* common */,
 | |
| +				F3B7819524C7CC1300FCB122 /* mkvmuxer */,
 | |
|  				CDEBB19224C0191800ADBD44 /* webm_parser */,
 | |
|  			);
 | |
|  			path = libwebm;
 | |
| @@ -17343,6 +17371,16 @@
 | |
|  			path = include;
 | |
|  			sourceTree = "<group>";
 | |
|  		};
 | |
| +		F3B7819524C7CC1300FCB122 /* mkvmuxer */ = {
 | |
| +			isa = PBXGroup;
 | |
| +			children = (
 | |
| +				F3B7819724C7CC5200FCB122 /* mkvmuxer.cc */,
 | |
| +				F3B7819624C7CC5100FCB122 /* mkvmuxerutil.cc */,
 | |
| +				F3B7819824C7CC5200FCB122 /* mkvwriter.cc */,
 | |
| +			);
 | |
| +			name = mkvmuxer;
 | |
| +			sourceTree = "<group>";
 | |
| +		};
 | |
|  		FB39D06E1200ED9200088E69 = {
 | |
|  			isa = PBXGroup;
 | |
|  			children = (
 | |
| @@ -20024,6 +20062,7 @@
 | |
|  				DDF30CFA27C5A98F006A526F /* PBXBuildRule */,
 | |
|  			);
 | |
|  			dependencies = (
 | |
| +				F31720B427FE273100EEE407 /* PBXTargetDependency */,
 | |
|  				DD2E76E827C6B69A00F2A74C /* PBXTargetDependency */,
 | |
|  				CDEBB4CC24C01AB400ADBD44 /* PBXTargetDependency */,
 | |
|  				411ED040212E0811004320BA /* PBXTargetDependency */,
 | |
| @@ -20084,6 +20123,7 @@
 | |
|  				41F77D15215BE45E00E72967 /* yasm */,
 | |
|  				CDEBB11824C0187400ADBD44 /* webm */,
 | |
|  				DDF30D0527C5C003006A526F /* absl */,
 | |
| +				F31720AC27FE215900EEE407 /* Copy libvpx headers */,
 | |
|  			);
 | |
|  		};
 | |
|  /* End PBXProject section */
 | |
| @@ -20217,6 +20257,23 @@
 | |
|  			shellPath = /bin/sh;
 | |
|  			shellScript = "[ \"${WK_USE_NEW_BUILD_SYSTEM}\" = YES ] && exit 0\nxcodebuild -project \"${PROJECT_FILE_PATH}\" -target \"${TARGET_NAME}\" installhdrs SYMROOT=\"${TARGET_TEMP_DIR}/LegacyNestHeaders-build\" DSTROOT=\"${BUILT_PRODUCTS_DIR}\" SDKROOT=\"${SDKROOT}\" -UseNewBuildSystem=YES\n";
 | |
|  		};
 | |
| +		F31720B127FE216400EEE407 /* ShellScript */ = {
 | |
| +			isa = PBXShellScriptBuildPhase;
 | |
| +			buildActionMask = 2147483647;
 | |
| +			files = (
 | |
| +			);
 | |
| +			inputFileListPaths = (
 | |
| +			);
 | |
| +			inputPaths = (
 | |
| +			);
 | |
| +			outputFileListPaths = (
 | |
| +			);
 | |
| +			outputPaths = (
 | |
| +			);
 | |
| +			runOnlyForDeploymentPostprocessing = 0;
 | |
| +			shellPath = /bin/sh;
 | |
| +			shellScript = "PRIVATE_HEADERS_FOLDER_PATH=usr/local/include\n\nif [[ \"${DEPLOYMENT_LOCATION}\" == \"NO\" ]]; then\n    PRIVATE_HEADERS_PATH=\"${TARGET_BUILD_DIR%/}/${PRIVATE_HEADERS_FOLDER_PATH}\"\nelse\n    PRIVATE_HEADERS_PATH=\"${DSTROOT}${INSTALL_PATH_PREFIX%/}/${PRIVATE_HEADERS_FOLDER_PATH}\"\nfi;\n\necho \"#### PRIVATE_HEADERS_PATH = ${PRIVATE_HEADERS_PATH}\"\necho\n\nmkdir -p \"${PRIVATE_HEADERS_PATH}\"\n\nrsync -av --no-owner --no-group --prune-empty-dirs --exclude \".svn\" --exclude \"usr\" --include \"*/\" --include \"*.h\" --exclude \"*\" \"${SRCROOT}/Source/third_party/libyuv/include/\" \"${PRIVATE_HEADERS_PATH}\"\n\nrsync -av --no-owner --no-group --prune-empty-dirs --exclude \".svn\" --exclude \"usr\" --exclude \"src\" --exclude \"internal\" --include \"*/\" --include \"*.h\" --exclude \"*\" \"${SRCROOT}/Source/third_party/libvpx/source/libvpx/vpx\" \"${PRIVATE_HEADERS_PATH}\"\n\nrsync -av --no-owner --no-group --prune-empty-dirs --exclude \".svn\" --exclude \"usr\" --include \"*/\" --include \"*.h\" --exclude \"*\" \"${SRCROOT}/Source/third_party/libwebm/\" \"${PRIVATE_HEADERS_PATH}\"\n\n";
 | |
| +		};
 | |
|  /* End PBXShellScriptBuildPhase section */
 | |
|  
 | |
|  /* Begin PBXSourcesBuildPhase section */
 | |
| @@ -21348,6 +21405,7 @@
 | |
|  				419C82F51FE20EB50040C30F /* audio_encoder_opus.cc in Sources */,
 | |
|  				419C82F31FE20EB50040C30F /* audio_encoder_opus_config.cc in Sources */,
 | |
|  				4140B8201E4E3383007409E6 /* audio_encoder_pcm.cc in Sources */,
 | |
| +				F3B7819A24C7CC5200FCB122 /* mkvmuxer.cc in Sources */,
 | |
|  				5CDD8FFE1E43CE3A00621E92 /* audio_encoder_pcm16b.cc in Sources */,
 | |
|  				5CD285461E6A61D20094FDC8 /* audio_format.cc in Sources */,
 | |
|  				41DDB26F212679D200296D47 /* audio_format_to_string.cc in Sources */,
 | |
| @@ -21787,6 +21845,7 @@
 | |
|  				417953DB216983910028266B /* metrics.cc in Sources */,
 | |
|  				5CDD865E1E43B8B500621E92 /* min_max_operations.c in Sources */,
 | |
|  				4189395B242A71F5007FDC41 /* min_video_bitrate_experiment.cc in Sources */,
 | |
| +				F3B7819B24C7CC5200FCB122 /* mkvwriter.cc in Sources */,
 | |
|  				4131C387234B957D0028A615 /* moving_average.cc in Sources */,
 | |
|  				41FCBB1521B1F7AA00A5DF27 /* moving_average.cc in Sources */,
 | |
|  				5CD286101E6A64C90094FDC8 /* moving_max.cc in Sources */,
 | |
| @@ -22020,6 +22079,7 @@
 | |
|  				4131C53B234C8B190028A615 /* rtc_event_rtp_packet_outgoing.cc in Sources */,
 | |
|  				4131C552234C8B190028A615 /* rtc_event_video_receive_stream_config.cc in Sources */,
 | |
|  				4131C554234C8B190028A615 /* rtc_event_video_send_stream_config.cc in Sources */,
 | |
| +				F3B7819924C7CC5200FCB122 /* mkvmuxerutil.cc in Sources */,
 | |
|  				4131C3CF234B98420028A615 /* rtc_stats.cc in Sources */,
 | |
|  				4131BF2D234B88200028A615 /* rtc_stats_collector.cc in Sources */,
 | |
|  				4131C3CE234B98420028A615 /* rtc_stats_report.cc in Sources */,
 | |
| @@ -22471,6 +22531,11 @@
 | |
|  			target = DDF30D0527C5C003006A526F /* absl */;
 | |
|  			targetProxy = DD2E76E727C6B69A00F2A74C /* PBXContainerItemProxy */;
 | |
|  		};
 | |
| +		F31720B427FE273100EEE407 /* PBXTargetDependency */ = {
 | |
| +			isa = PBXTargetDependency;
 | |
| +			target = F31720AC27FE215900EEE407 /* Copy libvpx headers */;
 | |
| +			targetProxy = F31720B327FE273100EEE407 /* PBXContainerItemProxy */;
 | |
| +		};
 | |
|  /* End PBXTargetDependency section */
 | |
|  
 | |
|  /* Begin XCBuildConfiguration section */
 | |
| @@ -22719,6 +22784,27 @@
 | |
|  			};
 | |
|  			name = Production;
 | |
|  		};
 | |
| +		F31720AD27FE215900EEE407 /* Debug */ = {
 | |
| +			isa = XCBuildConfiguration;
 | |
| +			buildSettings = {
 | |
| +				PRODUCT_NAME = "$(TARGET_NAME)";
 | |
| +			};
 | |
| +			name = Debug;
 | |
| +		};
 | |
| +		F31720AE27FE215900EEE407 /* Release */ = {
 | |
| +			isa = XCBuildConfiguration;
 | |
| +			buildSettings = {
 | |
| +				PRODUCT_NAME = "$(TARGET_NAME)";
 | |
| +			};
 | |
| +			name = Release;
 | |
| +		};
 | |
| +		F31720AF27FE215900EEE407 /* Production */ = {
 | |
| +			isa = XCBuildConfiguration;
 | |
| +			buildSettings = {
 | |
| +				PRODUCT_NAME = "$(TARGET_NAME)";
 | |
| +			};
 | |
| +			name = Production;
 | |
| +		};
 | |
|  		FB39D0711200ED9200088E69 /* Debug */ = {
 | |
|  			isa = XCBuildConfiguration;
 | |
|  			baseConfigurationReference = 5D7C59C71208C68B001C873E /* DebugRelease.xcconfig */;
 | |
| @@ -22851,6 +22937,16 @@
 | |
|  			defaultConfigurationIsVisible = 0;
 | |
|  			defaultConfigurationName = Production;
 | |
|  		};
 | |
| +		F31720B027FE215900EEE407 /* Build configuration list for PBXAggregateTarget "Copy libvpx headers" */ = {
 | |
| +			isa = XCConfigurationList;
 | |
| +			buildConfigurations = (
 | |
| +				F31720AD27FE215900EEE407 /* Debug */,
 | |
| +				F31720AE27FE215900EEE407 /* Release */,
 | |
| +				F31720AF27FE215900EEE407 /* Production */,
 | |
| +			);
 | |
| +			defaultConfigurationIsVisible = 0;
 | |
| +			defaultConfigurationName = Production;
 | |
| +		};
 | |
|  		FB39D0731200ED9200088E69 /* Build configuration list for PBXProject "libwebrtc" */ = {
 | |
|  			isa = XCConfigurationList;
 | |
|  			buildConfigurations = (
 | |
| diff --git a/Source/WTF/Scripts/Preferences/WebPreferences.yaml b/Source/WTF/Scripts/Preferences/WebPreferences.yaml
 | |
| index 2383d5b94b869e13a305571add135a730e15d5b1..9399a38171ba2ed87e10f0944138d1483957bb0a 100644
 | |
| --- a/Source/WTF/Scripts/Preferences/WebPreferences.yaml
 | |
| +++ b/Source/WTF/Scripts/Preferences/WebPreferences.yaml
 | |
| @@ -976,7 +976,7 @@ InspectorStartsAttached:
 | |
|    exposed: [ WebKit ]
 | |
|    defaultValue:
 | |
|      WebKit:
 | |
| -      default: true
 | |
| +      default: false
 | |
|  
 | |
|  InspectorWindowFrame:
 | |
|    type: String
 | |
| @@ -1735,6 +1735,17 @@ PluginsEnabled:
 | |
|      WebCore:
 | |
|        default: false
 | |
|  
 | |
| +PointerLockEnabled:
 | |
| +  type: bool
 | |
| +  condition: ENABLE(POINTER_LOCK)
 | |
| +  defaultValue:
 | |
| +    WebKitLegacy:
 | |
| +      default: true
 | |
| +    WebKit:
 | |
| +      default: true
 | |
| +    WebCore:
 | |
| +      default: true
 | |
| +
 | |
|  PrivateClickMeasurementEnabled:
 | |
|    type: bool
 | |
|    humanReadableName: "Private Click Measurement"
 | |
| diff --git a/Source/WTF/Scripts/Preferences/WebPreferencesExperimental.yaml b/Source/WTF/Scripts/Preferences/WebPreferencesExperimental.yaml
 | |
| index 32082f485960ee61e3aa46b7d618228870e6f896..466f96c29ecb7e151d711f5fd7499e8ec83a6857 100644
 | |
| --- a/Source/WTF/Scripts/Preferences/WebPreferencesExperimental.yaml
 | |
| +++ b/Source/WTF/Scripts/Preferences/WebPreferencesExperimental.yaml
 | |
| @@ -479,7 +479,7 @@ CrossOriginOpenerPolicyEnabled:
 | |
|      WebKitLegacy:
 | |
|        default: false
 | |
|      WebKit:
 | |
| -      default: true
 | |
| +      default: false
 | |
|      WebCore:
 | |
|        default: false
 | |
|  
 | |
| @@ -856,9 +856,9 @@ MaskWebGLStringsEnabled:
 | |
|      WebKitLegacy:
 | |
|        default: true
 | |
|      WebKit:
 | |
| -      default: true
 | |
| +      default: false
 | |
|      WebCore:
 | |
| -      default: true
 | |
| +      default: false
 | |
|  
 | |
|  # FIXME: This is on by default in WebKit2. Perhaps we should consider turning it on for WebKitLegacy as well.
 | |
|  MediaCapabilitiesExtensionsEnabled:
 | |
| @@ -1366,7 +1366,7 @@ SpeechRecognitionEnabled:
 | |
|      WebKitLegacy:
 | |
|        default: false
 | |
|      WebKit:
 | |
| -      "HAVE(SPEECHRECOGNIZER) && ENABLE(MEDIA_STREAM)": true
 | |
| +      "ENABLE(MEDIA_STREAM)": true
 | |
|        default: false
 | |
|      WebCore:
 | |
|        default: false
 | |
| @@ -1481,6 +1481,7 @@ UseGPUProcessForDisplayCapture:
 | |
|      WebKit:
 | |
|        default: false
 | |
|  
 | |
| +# Playwright: force-disable on Windows
 | |
|  UseGPUProcessForWebGLEnabled:
 | |
|    type: bool
 | |
|    humanReadableName: "GPU Process: WebGL"
 | |
| @@ -1491,7 +1492,7 @@ UseGPUProcessForWebGLEnabled:
 | |
|    defaultValue:
 | |
|      WebKit:
 | |
|        "ENABLE(GPU_PROCESS_BY_DEFAULT) && PLATFORM(IOS_FAMILY) && !HAVE(UIKIT_WEBKIT_INTERNALS)": true
 | |
| -      "PLATFORM(WIN)": true
 | |
| +      "PLATFORM(WIN)": false
 | |
|        default: false
 | |
|  
 | |
|  UserGesturePromisePropagationEnabled:
 | |
| diff --git a/Source/WTF/Scripts/Preferences/WebPreferencesInternal.yaml b/Source/WTF/Scripts/Preferences/WebPreferencesInternal.yaml
 | |
| index 8bb2c7270c30b3bfc4bbd65b93985d5e97019ac9..c597c721e5f721ce9f0f131dcb8251e751997518 100644
 | |
| --- a/Source/WTF/Scripts/Preferences/WebPreferencesInternal.yaml
 | |
| +++ b/Source/WTF/Scripts/Preferences/WebPreferencesInternal.yaml
 | |
| @@ -919,6 +919,7 @@ UseCGDisplayListsForDOMRendering:
 | |
|      WebKit:
 | |
|        default: true
 | |
|  
 | |
| +# Playwright: force-disable on Windows
 | |
|  UseGPUProcessForCanvasRenderingEnabled:
 | |
|    type: bool
 | |
|    humanReadableName: "GPU Process: Canvas Rendering"
 | |
| @@ -929,7 +930,7 @@ UseGPUProcessForCanvasRenderingEnabled:
 | |
|    defaultValue:
 | |
|      WebKit:
 | |
|        "ENABLE(GPU_PROCESS_BY_DEFAULT)": true
 | |
| -      "PLATFORM(WIN)": true
 | |
| +      "PLATFORM(WIN)": false
 | |
|        default: false
 | |
|  
 | |
|  UseGPUProcessForMediaEnabled:
 | |
| diff --git a/Source/WTF/wtf/PlatformEnable.h b/Source/WTF/wtf/PlatformEnable.h
 | |
| index 919f9a02d1a6b11d2d3773be94c2e6c5b63f1ce5..6757f230255a2e947f44ee8a73ce6dd9a2ebb4d5 100644
 | |
| --- a/Source/WTF/wtf/PlatformEnable.h
 | |
| +++ b/Source/WTF/wtf/PlatformEnable.h
 | |
| @@ -420,7 +420,7 @@
 | |
|  #endif
 | |
|  
 | |
|  #if !defined(ENABLE_ORIENTATION_EVENTS)
 | |
| -#define ENABLE_ORIENTATION_EVENTS 0
 | |
| +#define ENABLE_ORIENTATION_EVENTS 1
 | |
|  #endif
 | |
|  
 | |
|  #if OS(WINDOWS)
 | |
| @@ -481,7 +481,7 @@
 | |
|  #endif
 | |
|  
 | |
|  #if !defined(ENABLE_TOUCH_EVENTS)
 | |
| -#define ENABLE_TOUCH_EVENTS 0
 | |
| +#define ENABLE_TOUCH_EVENTS 1
 | |
|  #endif
 | |
|  
 | |
|  #if !defined(ENABLE_TOUCH_ACTION_REGIONS)
 | |
| diff --git a/Source/WTF/wtf/PlatformEnableCocoa.h b/Source/WTF/wtf/PlatformEnableCocoa.h
 | |
| index ca3a163a9576abbfa7a8c110cfd0e10570a656b1..a4be1e18d528a2f2b19997b042afe3ee59fd436f 100644
 | |
| --- a/Source/WTF/wtf/PlatformEnableCocoa.h
 | |
| +++ b/Source/WTF/wtf/PlatformEnableCocoa.h
 | |
| @@ -223,7 +223,7 @@
 | |
|  #define ENABLE_DATA_DETECTION 1
 | |
|  #endif
 | |
|  
 | |
| -#if !defined(ENABLE_DEVICE_ORIENTATION) && !PLATFORM(MAC) && !PLATFORM(MACCATALYST)
 | |
| +#if !defined(ENABLE_DEVICE_ORIENTATION) && !PLATFORM(MACCATALYST)
 | |
|  #define ENABLE_DEVICE_ORIENTATION 1
 | |
|  #endif
 | |
|  
 | |
| diff --git a/Source/WTF/wtf/PlatformGTK.cmake b/Source/WTF/wtf/PlatformGTK.cmake
 | |
| index bb01bfeeac63f854fa656ec6b8d262fafc4c9df5..f8376ea8aada69d2e53734ba8fd234c2455c2b09 100644
 | |
| --- a/Source/WTF/wtf/PlatformGTK.cmake
 | |
| +++ b/Source/WTF/wtf/PlatformGTK.cmake
 | |
| @@ -79,6 +79,7 @@ list(APPEND WTF_LIBRARIES
 | |
|      ${GLIB_LIBRARIES}
 | |
|      Threads::Threads
 | |
|      ZLIB::ZLIB
 | |
| +    stdc++fs
 | |
|  )
 | |
|  
 | |
|  if (Journald_FOUND)
 | |
| diff --git a/Source/WTF/wtf/PlatformHave.h b/Source/WTF/wtf/PlatformHave.h
 | |
| index c250c8e4f41c039182f317cf776efbdb80286af1..91fd78cddfe53b995c14f7fdd917f54b4409bbca 100644
 | |
| --- a/Source/WTF/wtf/PlatformHave.h
 | |
| +++ b/Source/WTF/wtf/PlatformHave.h
 | |
| @@ -414,7 +414,7 @@
 | |
|  #define HAVE_FOUNDATION_WITH_SAME_SITE_COOKIE_SUPPORT 1
 | |
|  #endif
 | |
|  
 | |
| -#if PLATFORM(MAC) || PLATFORM(IOS) || PLATFORM(MACCATALYST) || PLATFORM(GTK) || PLATFORM(WPE)
 | |
| +#if PLATFORM(MAC) || PLATFORM(IOS) || PLATFORM(MACCATALYST) || PLATFORM(GTK) || PLATFORM(WPE) || PLATFORM(WIN)
 | |
|  #define HAVE_OS_DARK_MODE_SUPPORT 1
 | |
|  #endif
 | |
|  
 | |
| diff --git a/Source/WTF/wtf/PlatformWPE.cmake b/Source/WTF/wtf/PlatformWPE.cmake
 | |
| index 09d4af604a835c7c6be1e43c249565bd1053aff4..0d6112342480454ce41a6b56dd925e1d41880e0b 100644
 | |
| --- a/Source/WTF/wtf/PlatformWPE.cmake
 | |
| +++ b/Source/WTF/wtf/PlatformWPE.cmake
 | |
| @@ -52,6 +52,7 @@ list(APPEND WTF_LIBRARIES
 | |
|      ${GLIB_LIBRARIES}
 | |
|      Threads::Threads
 | |
|      ZLIB::ZLIB
 | |
| +    stdc++fs
 | |
|  )
 | |
|  
 | |
|  if (Journald_FOUND)
 | |
| diff --git a/Source/WebCore/DerivedSources.make b/Source/WebCore/DerivedSources.make
 | |
| index b123abf93e2758d21148c101c9d1734d0496f9a4..b0f076df5692925a4f93c67f2dca9bc86e3cdf53 100644
 | |
| --- a/Source/WebCore/DerivedSources.make
 | |
| +++ b/Source/WebCore/DerivedSources.make
 | |
| @@ -976,6 +976,10 @@ JS_BINDING_IDLS := \
 | |
|      $(WebCore)/dom/Slotable.idl \
 | |
|      $(WebCore)/dom/StaticRange.idl \
 | |
|      $(WebCore)/dom/StringCallback.idl \
 | |
| +    $(WebCore)/dom/Document+Touch.idl \
 | |
| +    $(WebCore)/dom/Touch.idl \
 | |
| +    $(WebCore)/dom/TouchEvent.idl \
 | |
| +    $(WebCore)/dom/TouchList.idl \
 | |
|      $(WebCore)/dom/Text.idl \
 | |
|      $(WebCore)/dom/TextDecoder.idl \
 | |
|      $(WebCore)/dom/TextDecoderStream.idl \
 | |
| @@ -1519,9 +1523,6 @@ JS_BINDING_IDLS := \
 | |
|  ADDITIONAL_BINDING_IDLS = \
 | |
|      DocumentTouch.idl \
 | |
|      GestureEvent.idl \
 | |
| -    Touch.idl \
 | |
| -    TouchEvent.idl \
 | |
| -    TouchList.idl \
 | |
|  #
 | |
|  
 | |
|  vpath %.in $(WEBKITADDITIONS_HEADER_SEARCH_PATHS)
 | |
| diff --git a/Source/WebCore/Modules/geolocation/Geolocation.cpp b/Source/WebCore/Modules/geolocation/Geolocation.cpp
 | |
| index a0f3a2f50826db31cf7d6c133e4dfc47bac27528..a09ba013dc815b3f14f67ce799c2edb4bf77134b 100644
 | |
| --- a/Source/WebCore/Modules/geolocation/Geolocation.cpp
 | |
| +++ b/Source/WebCore/Modules/geolocation/Geolocation.cpp
 | |
| @@ -371,8 +371,9 @@ bool Geolocation::shouldBlockGeolocationRequests()
 | |
|      bool isSecure = SecurityOrigin::isSecure(document()->url()) || document()->isSecureContext();
 | |
|      bool hasMixedContent = !document()->foundMixedContent().isEmpty();
 | |
|      bool isLocalOrigin = securityOrigin()->isLocal();
 | |
| +    bool isPotentiallyTrustworthy = securityOrigin()->isPotentiallyTrustworthy();
 | |
|      if (document()->canAccessResource(ScriptExecutionContext::ResourceType::Geolocation) != ScriptExecutionContext::HasResourceAccess::No) {
 | |
| -        if (isLocalOrigin || (isSecure && !hasMixedContent) || isRequestFromIBooks())
 | |
| +        if (isLocalOrigin || isPotentiallyTrustworthy || (isSecure && !hasMixedContent) || isRequestFromIBooks())
 | |
|              return false;
 | |
|      }
 | |
|  
 | |
| diff --git a/Source/WebCore/Modules/speech/cocoa/WebSpeechRecognizerTask.mm b/Source/WebCore/Modules/speech/cocoa/WebSpeechRecognizerTask.mm
 | |
| index a941d76a4f748718df1e3cff2a6c5e0827f48891..f62db5a27ac0e4c12430e7d19e60c83d768ace22 100644
 | |
| --- a/Source/WebCore/Modules/speech/cocoa/WebSpeechRecognizerTask.mm
 | |
| +++ b/Source/WebCore/Modules/speech/cocoa/WebSpeechRecognizerTask.mm
 | |
| @@ -198,6 +198,7 @@ NS_ASSUME_NONNULL_BEGIN
 | |
|  
 | |
|  - (void)speechRecognizer:(SFSpeechRecognizer *)speechRecognizer availabilityDidChange:(BOOL)available
 | |
|  {
 | |
| +    UNUSED_PARAM(speechRecognizer);
 | |
|      ASSERT(isMainThread());
 | |
|  
 | |
|      if (available || !_task)
 | |
| @@ -211,6 +212,7 @@ NS_ASSUME_NONNULL_BEGIN
 | |
|  
 | |
|  - (void)speechRecognitionTask:(SFSpeechRecognitionTask *)task didHypothesizeTranscription:(SFTranscription *)transcription
 | |
|  {
 | |
| +    UNUSED_PARAM(task);
 | |
|      ASSERT(isMainThread());
 | |
|  
 | |
|      [self sendSpeechStartIfNeeded];
 | |
| @@ -219,6 +221,7 @@ NS_ASSUME_NONNULL_BEGIN
 | |
|  
 | |
|  - (void)speechRecognitionTask:(SFSpeechRecognitionTask *)task didFinishRecognition:(SFSpeechRecognitionResult *)recognitionResult
 | |
|  {
 | |
| +    UNUSED_PARAM(task);
 | |
|      ASSERT(isMainThread());
 | |
|      [self callbackWithTranscriptions:recognitionResult.transcriptions isFinal:YES];
 | |
|  
 | |
| @@ -230,6 +233,7 @@ NS_ASSUME_NONNULL_BEGIN
 | |
|  
 | |
|  - (void)speechRecognitionTaskWasCancelled:(SFSpeechRecognitionTask *)task
 | |
|  {
 | |
| +    UNUSED_PARAM(task);
 | |
|      ASSERT(isMainThread());
 | |
|  
 | |
|      [self sendSpeechEndIfNeeded];
 | |
| diff --git a/Source/WebCore/PlatformWPE.cmake b/Source/WebCore/PlatformWPE.cmake
 | |
| index 9d021a1a887fb06779b063b525ac985f8f4ba37a..8378753eacb14e9fd34e906111352b5833032d38 100644
 | |
| --- a/Source/WebCore/PlatformWPE.cmake
 | |
| +++ b/Source/WebCore/PlatformWPE.cmake
 | |
| @@ -48,6 +48,7 @@ list(APPEND WebCore_PRIVATE_FRAMEWORK_HEADERS
 | |
|  
 | |
|      platform/graphics/wayland/PlatformDisplayWayland.h
 | |
|      platform/graphics/wayland/WlUniquePtr.h
 | |
| +    platform/wpe/SelectionData.h
 | |
|  )
 | |
|  
 | |
|  set(CSS_VALUE_PLATFORM_DEFINES "HAVE_OS_DARK_MODE_SUPPORT=1")
 | |
| diff --git a/Source/WebCore/SourcesCocoa.txt b/Source/WebCore/SourcesCocoa.txt
 | |
| index daea10b61d1585d8553eddd26014b9e5d1cc1255..fd004eec3d057f1b5ab18b9acdc065a882a19e8a 100644
 | |
| --- a/Source/WebCore/SourcesCocoa.txt
 | |
| +++ b/Source/WebCore/SourcesCocoa.txt
 | |
| @@ -632,3 +632,9 @@ platform/graphics/angle/GraphicsContextGLANGLE.cpp @no-unify
 | |
|  platform/graphics/cocoa/ANGLEUtilitiesCocoa.cpp @no-unify
 | |
|  platform/graphics/cocoa/GraphicsContextGLCocoa.mm @no-unify
 | |
|  platform/graphics/cv/GraphicsContextGLCVCocoa.cpp @no-unify
 | |
| +
 | |
| +// Playwright begin
 | |
| +JSTouch.cpp
 | |
| +JSTouchEvent.cpp
 | |
| +JSTouchList.cpp
 | |
| +// Playwright end
 | |
| diff --git a/Source/WebCore/SourcesGTK.txt b/Source/WebCore/SourcesGTK.txt
 | |
| index 2322e2fd1686832942465614051db738cabfe9e4..d9e3cbe7d54e54b84c4293937b948b4161937574 100644
 | |
| --- a/Source/WebCore/SourcesGTK.txt
 | |
| +++ b/Source/WebCore/SourcesGTK.txt
 | |
| @@ -37,6 +37,9 @@ accessibility/atspi/AccessibilityObjectValueAtspi.cpp
 | |
|  accessibility/atspi/AccessibilityRootAtspi.cpp
 | |
|  accessibility/atspi/AXObjectCacheAtspi.cpp
 | |
|  
 | |
| +accessibility/empty/AXObjectCacheEmpty.cpp
 | |
| +accessibility/empty/AccessibilityObjectEmpty.cpp
 | |
| +
 | |
|  editing/atspi/FrameSelectionAtspi.cpp
 | |
|  
 | |
|  editing/gtk/EditorGtk.cpp
 | |
| @@ -134,3 +137,10 @@ platform/xdg/MIMETypeRegistryXdg.cpp
 | |
|  
 | |
|  rendering/RenderThemeAdwaita.cpp
 | |
|  rendering/RenderThemeGtk.cpp
 | |
| +
 | |
| +// Playwright: begin.
 | |
| +JSSpeechSynthesisErrorCode.cpp
 | |
| +JSSpeechSynthesisErrorEvent.cpp
 | |
| +JSSpeechSynthesisErrorEventInit.cpp
 | |
| +JSSpeechSynthesisEventInit.cpp
 | |
| +// Playwright: end.
 | |
| diff --git a/Source/WebCore/SourcesWPE.txt b/Source/WebCore/SourcesWPE.txt
 | |
| index 3c64bfd9e2a5ed56ffd61f6c0e1a42f78c9e726b..1e01d0a3f3d71021661f9b43238e9c1f5289e7ae 100644
 | |
| --- a/Source/WebCore/SourcesWPE.txt
 | |
| +++ b/Source/WebCore/SourcesWPE.txt
 | |
| @@ -37,11 +37,16 @@ accessibility/atspi/AccessibilityObjectValueAtspi.cpp
 | |
|  accessibility/atspi/AccessibilityRootAtspi.cpp
 | |
|  accessibility/atspi/AXObjectCacheAtspi.cpp
 | |
|  
 | |
| +accessibility/empty/AXObjectCacheEmpty.cpp
 | |
| +accessibility/empty/AccessibilityObjectEmpty.cpp
 | |
| +
 | |
|  editing/atspi/FrameSelectionAtspi.cpp
 | |
|  editing/libwpe/EditorLibWPE.cpp
 | |
|  
 | |
|  loader/soup/ResourceLoaderSoup.cpp
 | |
|  
 | |
| +page/wpe/DragControllerWPE.cpp
 | |
| +
 | |
|  page/linux/ResourceUsageOverlayLinux.cpp
 | |
|  page/linux/ResourceUsageThreadLinux.cpp
 | |
|  
 | |
| @@ -88,8 +93,19 @@ platform/text/LocaleICU.cpp
 | |
|  
 | |
|  platform/unix/LoggingUnix.cpp
 | |
|  
 | |
| +platform/wpe/DragDataWPE.cpp
 | |
| +platform/wpe/DragImageWPE.cpp
 | |
|  platform/wpe/PlatformScreenWPE.cpp
 | |
|  
 | |
|  platform/xdg/MIMETypeRegistryXdg.cpp
 | |
|  
 | |
|  rendering/RenderThemeAdwaita.cpp
 | |
| +
 | |
| +platform/wpe/SelectionData.cpp
 | |
| +
 | |
| +// Playwright: begin.
 | |
| +JSSpeechSynthesisErrorCode.cpp
 | |
| +JSSpeechSynthesisErrorEvent.cpp
 | |
| +JSSpeechSynthesisErrorEventInit.cpp
 | |
| +JSSpeechSynthesisEventInit.cpp
 | |
| +// Playwright: end.
 | |
| diff --git a/Source/WebCore/WebCore.order b/Source/WebCore/WebCore.order
 | |
| index c4898d6db6bf06552f602c4b7f0a7267e64e44f4..7cf2e30729671a89c373870c5691d337ec3f8a59 100644
 | |
| --- a/Source/WebCore/WebCore.order
 | |
| +++ b/Source/WebCore/WebCore.order
 | |
| @@ -3090,7 +3090,6 @@ __ZN7WebCore14DocumentLoader23stopLoadingSubresourcesEv
 | |
|  __ZN7WebCore14DocumentLoader18stopLoadingPlugInsEv
 | |
|  __ZN7WebCore14DocumentLoader15detachFromFrameEv
 | |
|  __ZN7WebCore20ApplicationCacheHost22setDOMApplicationCacheEPNS_19DOMApplicationCacheE
 | |
| -__ZN7WebCore24InspectorInstrumentation27loaderDetachedFromFrameImplEPNS_19InstrumentingAgentsEPNS_14DocumentLoaderE
 | |
|  __ZN7WebCore14DocumentLoaderD0Ev
 | |
|  __ZN7WebCore14DocumentLoaderD2Ev
 | |
|  __ZN7WebCore14DocumentLoader17clearMainResourceEv
 | |
| diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj
 | |
| index dd997cfba140eaf593a120f031aa2b34ce85abc7..cfaa7c02167ab54b6fb5b49f48fe1cbf405aad00 100644
 | |
| --- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj
 | |
| +++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj
 | |
| @@ -5529,6 +5529,13 @@
 | |
|  		EDE3A5000C7A430600956A37 /* ColorMac.h in Headers */ = {isa = PBXBuildFile; fileRef = EDE3A4FF0C7A430600956A37 /* ColorMac.h */; settings = {ATTRIBUTES = (Private, ); }; };
 | |
|  		EDEC98030AED7E170059137F /* WebCorePrefix.h in Headers */ = {isa = PBXBuildFile; fileRef = EDEC98020AED7E170059137F /* WebCorePrefix.h */; };
 | |
|  		EFCC6C8F20FE914400A2321B /* CanvasActivityRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = EFCC6C8D20FE914000A2321B /* CanvasActivityRecord.h */; settings = {ATTRIBUTES = (Private, ); }; };
 | |
| +		F050E16823AC9C080011CE47 /* PlatformTouchEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = F050E16623AC9C070011CE47 /* PlatformTouchEvent.h */; settings = {ATTRIBUTES = (Private, ); }; };
 | |
| +		F050E16A23AD660C0011CE47 /* Touch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F050E16923AD660C0011CE47 /* Touch.cpp */; };
 | |
| +		F050E16D23AD66630011CE47 /* TouchList.h in Headers */ = {isa = PBXBuildFile; fileRef = F050E16B23AD66620011CE47 /* TouchList.h */; settings = {ATTRIBUTES = (Private, ); }; };
 | |
| +		F050E16E23AD66630011CE47 /* TouchList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F050E16C23AD66630011CE47 /* TouchList.cpp */; };
 | |
| +		F050E17123AD669F0011CE47 /* TouchEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F050E16F23AD669E0011CE47 /* TouchEvent.cpp */; };
 | |
| +		F050E17423AD6A800011CE47 /* DocumentTouch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F050E17323AD6A800011CE47 /* DocumentTouch.cpp */; };
 | |
| +		F050E17823AD70C50011CE47 /* PlatformTouchPoint.h in Headers */ = {isa = PBXBuildFile; fileRef = F050E17623AD70C40011CE47 /* PlatformTouchPoint.h */; settings = {ATTRIBUTES = (Private, ); }; };
 | |
|  		F12171F616A8CF0B000053CA /* WebVTTElement.h in Headers */ = {isa = PBXBuildFile; fileRef = F12171F416A8BC63000053CA /* WebVTTElement.h */; };
 | |
|  		F32BDCD92363AACA0073B6AE /* UserGestureEmulationScope.h in Headers */ = {isa = PBXBuildFile; fileRef = F32BDCD72363AACA0073B6AE /* UserGestureEmulationScope.h */; };
 | |
|  		F344C7141125B82C00F26EEE /* InspectorFrontendClient.h in Headers */ = {isa = PBXBuildFile; fileRef = F344C7121125B82C00F26EEE /* InspectorFrontendClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
 | |
| @@ -17865,6 +17872,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>"; };
 | |
| @@ -24286,7 +24301,12 @@
 | |
|  				1AF326770D78B9440068F0C4 /* EditorClient.h */,
 | |
|  				E36D701E27B71F04006531B7 /* EmptyAttachmentElementClient.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 */,
 | |
| @@ -30320,6 +30340,8 @@
 | |
|  				29E4D8DF16B0940F00C84704 /* PlatformSpeechSynthesizer.h */,
 | |
|  				1AD8F81A11CAB9E900E93E54 /* PlatformStrategies.cpp */,
 | |
|  				1AD8F81911CAB9E900E93E54 /* PlatformStrategies.h */,
 | |
| +				F050E16623AC9C070011CE47 /* PlatformTouchEvent.h */,
 | |
| +				F050E17623AD70C40011CE47 /* PlatformTouchPoint.h */,
 | |
|  				0FD7C21D23CE41E30096D102 /* PlatformWheelEvent.cpp */,
 | |
|  				935C476A09AC4D4F00A6AAB4 /* PlatformWheelEvent.h */,
 | |
|  				BCBB8AB513F1AFB000734DF0 /* PODInterval.h */,
 | |
| @@ -32628,6 +32650,7 @@
 | |
|  				BCCFBAE70B5152ED0001F1D7 /* DocumentParser.h */,
 | |
|  				AD6E71AA1668899D00320C13 /* DocumentSharedObjectPool.cpp */,
 | |
|  				AD6E71AB1668899D00320C13 /* DocumentSharedObjectPool.h */,
 | |
| +				F050E17323AD6A800011CE47 /* DocumentTouch.cpp */,
 | |
|  				6BDB5DC1227BD3B800919770 /* DocumentStorageAccess.cpp */,
 | |
|  				6BDB5DC0227BD3B800919770 /* DocumentStorageAccess.h */,
 | |
|  				7CE7FA5B1EF882300060C9D6 /* DocumentTouch.cpp */,
 | |
| @@ -33637,6 +33660,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 */,
 | |
| @@ -35782,6 +35806,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 */,
 | |
| @@ -36904,6 +36929,7 @@
 | |
|  				0F7D07331884C56C00B4AF86 /* PlatformTextTrack.h in Headers */,
 | |
|  				074E82BB18A69F0E007EF54C /* PlatformTimeRanges.h in Headers */,
 | |
|  				CDD08ABD277E542600EA3755 /* PlatformTrackConfiguration.h in Headers */,
 | |
| +				F050E16823AC9C080011CE47 /* PlatformTouchEvent.h in Headers */,
 | |
|  				CD1F9B022700323D00617EB6 /* PlatformVideoColorPrimaries.h in Headers */,
 | |
|  				CD1F9B01270020B700617EB6 /* PlatformVideoColorSpace.h in Headers */,
 | |
|  				CD1F9B032700323D00617EB6 /* PlatformVideoMatrixCoefficients.h in Headers */,
 | |
| @@ -38999,6 +39025,7 @@
 | |
|  				1ABA76CA11D20E50004C201C /* CSSPropertyNames.cpp in Sources */,
 | |
|  				2D22830323A8470700364B7E /* CursorMac.mm in Sources */,
 | |
|  				5CBD59592280E926002B22AA /* CustomHeaderFields.cpp in Sources */,
 | |
| +				F050E17423AD6A800011CE47 /* DocumentTouch.cpp in Sources */,
 | |
|  				7CE6CBFD187F394900D46BF5 /* FormatConverter.cpp in Sources */,
 | |
|  				5130F2F624AEA60A00E1D0A0 /* GameControllerSoftLink.mm in Sources */,
 | |
|  				51A4BB0A1954D61600FA5C2E /* Gamepad.cpp in Sources */,
 | |
| @@ -39075,6 +39102,7 @@
 | |
|  				C1692DD223D23ABD006E88F7 /* SystemBattery.mm in Sources */,
 | |
|  				CE88EE262414467B007F29C2 /* TextAlternativeWithRange.mm in Sources */,
 | |
|  				51DF6D800B92A18E00C2DC85 /* ThreadCheck.mm in Sources */,
 | |
| +				F050E17123AD669F0011CE47 /* TouchEvent.cpp in Sources */,
 | |
|  				538EC8031F96AF81004D22A8 /* UnifiedSource1-mm.mm in Sources */,
 | |
|  				538EC8021F96AF81004D22A8 /* UnifiedSource1.cpp in Sources */,
 | |
|  				538EC8051F96AF81004D22A8 /* UnifiedSource2-mm.mm in Sources */,
 | |
| @@ -39123,6 +39151,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 */,
 | |
| @@ -39655,6 +39684,7 @@
 | |
|  				2D8B92F1203D13E1009C868F /* UnifiedSource516.cpp in Sources */,
 | |
|  				2D8B92F2203D13E1009C868F /* UnifiedSource517.cpp in Sources */,
 | |
|  				2D8B92F3203D13E1009C868F /* UnifiedSource518.cpp in Sources */,
 | |
| +				F050E16A23AD660C0011CE47 /* Touch.cpp in Sources */,
 | |
|  				2D8B92F4203D13E1009C868F /* UnifiedSource519.cpp in Sources */,
 | |
|  				2D8B92F5203D13E1009C868F /* UnifiedSource520.cpp in Sources */,
 | |
|  				2D8B92F6203D13E1009C868F /* UnifiedSource521.cpp in Sources */,
 | |
| diff --git a/Source/WebCore/accessibility/AccessibilityObject.cpp b/Source/WebCore/accessibility/AccessibilityObject.cpp
 | |
| index a8108919d8da21dfc741f44a999985695662b771..95e5863a73299d1212e67600ca611d87159b9095 100644
 | |
| --- a/Source/WebCore/accessibility/AccessibilityObject.cpp
 | |
| +++ b/Source/WebCore/accessibility/AccessibilityObject.cpp
 | |
| @@ -61,6 +61,7 @@
 | |
|  #include "HTMLParserIdioms.h"
 | |
|  #include "HTMLTextAreaElement.h"
 | |
|  #include "HitTestResult.h"
 | |
| +#include "InspectorInstrumentation.h"
 | |
|  #include "LocalizedStrings.h"
 | |
|  #include "MathMLNames.h"
 | |
|  #include "NodeList.h"
 | |
| @@ -3724,9 +3725,14 @@ AccessibilityObjectInclusion AccessibilityObject::defaultObjectInclusion() const
 | |
|      if (roleValue() == AccessibilityRole::ApplicationDialog)
 | |
|          return AccessibilityObjectInclusion::IncludeObject;
 | |
|  
 | |
| -    return accessibilityPlatformIncludesObject();
 | |
| +    AccessibilityObjectInclusion platformBehavior = accessibilityPlatformIncludesObject();
 | |
| +    if (platformBehavior != AccessibilityObjectInclusion::DefaultBehavior) {
 | |
| +        if (auto* page = this->page())
 | |
| +            InspectorInstrumentation::maybeOverrideDefaultObjectInclusion(*page, platformBehavior);
 | |
| +    }
 | |
| +    return platformBehavior;
 | |
|  }
 | |
| -    
 | |
| +
 | |
|  bool AccessibilityObject::accessibilityIsIgnored() const
 | |
|  {
 | |
|      AXComputedObjectAttributeCache* attributeCache = nullptr;
 | |
| diff --git a/Source/WebCore/accessibility/AccessibilityObjectInterface.h b/Source/WebCore/accessibility/AccessibilityObjectInterface.h
 | |
| index fc43cb10a804186f754dc27cd3d1d5884a8dc6f7..047af6938869ccf5fedb19973d67402bcd940901 100644
 | |
| --- a/Source/WebCore/accessibility/AccessibilityObjectInterface.h
 | |
| +++ b/Source/WebCore/accessibility/AccessibilityObjectInterface.h
 | |
| @@ -57,7 +57,7 @@ typedef const struct __AXTextMarkerRange* AXTextMarkerRangeRef;
 | |
|  #elif USE(ATSPI)
 | |
|  typedef WebCore::AccessibilityObjectAtspi AccessibilityObjectWrapper;
 | |
|  #else
 | |
| -class AccessibilityObjectWrapper;
 | |
| +class AccessibilityObjectWrapper : public RefCounted<AccessibilityObjectWrapper> {};
 | |
|  #endif
 | |
|  
 | |
|  namespace PAL {
 | |
| @@ -1529,6 +1529,8 @@ private:
 | |
|      COMPtr<AccessibilityObjectWrapper> m_wrapper;
 | |
|  #elif USE(ATSPI)
 | |
|      RefPtr<AccessibilityObjectAtspi> m_wrapper;
 | |
| +#else
 | |
| +    RefPtr<AccessibilityObjectWrapper> m_wrapper;
 | |
|  #endif
 | |
|      virtual void detachPlatformWrapper(AccessibilityDetachmentType) = 0;
 | |
|  };
 | |
| diff --git a/Source/WebCore/accessibility/empty/AXObjectCacheEmpty.cpp b/Source/WebCore/accessibility/empty/AXObjectCacheEmpty.cpp
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..0233d1046f7074c11e9a3bab50f8fe8c5af7d95a
 | |
| --- /dev/null
 | |
| +++ b/Source/WebCore/accessibility/empty/AXObjectCacheEmpty.cpp
 | |
| @@ -0,0 +1,45 @@
 | |
| +/*
 | |
| + * Copyright (C) 2022 Microsoft Corporation.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
| + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#include "config.h"
 | |
| +
 | |
| +#if ENABLE(ACCESSIBILITY) && !USE(ATK) && !USE(ATSPI)
 | |
| +
 | |
| +#include "AXObjectCache.h"
 | |
| +
 | |
| +namespace WebCore {
 | |
| +
 | |
| +void AXObjectCache::detachWrapper(AXCoreObject* obj, AccessibilityDetachmentType) { }
 | |
| +void AXObjectCache::attachWrapper(AXCoreObject*) { }
 | |
| +void AXObjectCache::handleScrolledToAnchor(const Node* anchorNode) { }
 | |
| +void AXObjectCache::postPlatformNotification(AXCoreObject* obj, AXNotification notification) { }
 | |
| +void AXObjectCache::nodeTextChangePlatformNotification(AccessibilityObject*, AXTextChange, unsigned, const String&){ }
 | |
| +void AXObjectCache::frameLoadingEventPlatformNotification(AccessibilityObject* obj, AXLoadingEvent notification) { }
 | |
| +void AXObjectCache::platformHandleFocusedUIElementChanged(Node*, Node* newFocusedNode) { }
 | |
| +void AXObjectCache::platformPerformDeferredCacheUpdate() { }
 | |
| +
 | |
| +} // namespace WebCore
 | |
| +
 | |
| +#endif // ENABLE(ACCESSIBILITY)
 | |
| diff --git a/Source/WebCore/accessibility/empty/AccessibilityObjectEmpty.cpp b/Source/WebCore/accessibility/empty/AccessibilityObjectEmpty.cpp
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..dd2d8452302999e4a89b0bc18e842645c939247d
 | |
| --- /dev/null
 | |
| +++ b/Source/WebCore/accessibility/empty/AccessibilityObjectEmpty.cpp
 | |
| @@ -0,0 +1,40 @@
 | |
| +/*
 | |
| + * Copyright (C) 2022 Microsoft Corporation.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
| + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#include "config.h"
 | |
| +
 | |
| +#if ENABLE(ACCESSIBILITY) && !USE(ATK) && !USE(ATSPI)
 | |
| +
 | |
| +#include "AccessibilityObject.h"
 | |
| +
 | |
| +namespace WebCore {
 | |
| +
 | |
| +bool AccessibilityObject::accessibilityIgnoreAttachment() const { return true; }
 | |
| +AccessibilityObjectInclusion AccessibilityObject::accessibilityPlatformIncludesObject() const { return AccessibilityObjectInclusion::DefaultBehavior; }
 | |
| +void AccessibilityObject::detachPlatformWrapper(AccessibilityDetachmentType) { }
 | |
| +
 | |
| +} // namespace WebCore
 | |
| +
 | |
| +#endif // ENABLE(ACCESSIBILITY) && !USE(ATK) && !USE(ATSPI)
 | |
| diff --git a/Source/WebCore/bindings/js/WebCoreBuiltinNames.h b/Source/WebCore/bindings/js/WebCoreBuiltinNames.h
 | |
| index 63ea7faaf59dd77940293446338fa8b228355fa5..ea522b60acc03e3ff82cb0a4afa2d2317bd2e31d 100644
 | |
| --- a/Source/WebCore/bindings/js/WebCoreBuiltinNames.h
 | |
| +++ b/Source/WebCore/bindings/js/WebCoreBuiltinNames.h
 | |
| @@ -131,6 +131,8 @@ namespace WebCore {
 | |
|      macro(DataTransferItem) \
 | |
|      macro(DataTransferItemList) \
 | |
|      macro(DelayNode) \
 | |
| +    macro(DeviceMotionEvent) \
 | |
| +    macro(DeviceOrientationEvent) \
 | |
|      macro(DocumentTimeline) \
 | |
|      macro(DynamicsCompressorNode) \
 | |
|      macro(ExtendableEvent) \
 | |
| diff --git a/Source/WebCore/css/MediaQueryEvaluator.cpp b/Source/WebCore/css/MediaQueryEvaluator.cpp
 | |
| index 01d312c38e8e273099cf8d9b187ac704300f4c34..62570e7024cebae99b9d2eef711e70d867c7602f 100644
 | |
| --- a/Source/WebCore/css/MediaQueryEvaluator.cpp
 | |
| +++ b/Source/WebCore/css/MediaQueryEvaluator.cpp
 | |
| @@ -856,7 +856,11 @@ static bool prefersContrastEvaluate(CSSValue* value, const CSSToLengthConversion
 | |
|  static bool prefersReducedMotionEvaluate(CSSValue* value, const CSSToLengthConversionData&, Frame& frame, MediaFeaturePrefix)
 | |
|  {
 | |
|      bool userPrefersReducedMotion = false;
 | |
| -
 | |
| +    
 | |
| +    std::optional<bool> reducedMotionOverride = frame.page()->useReducedMotionOverride();
 | |
| +    if (reducedMotionOverride)
 | |
| +        userPrefersReducedMotion = reducedMotionOverride.value();
 | |
| +    else {
 | |
|      switch (frame.settings().forcedPrefersReducedMotionAccessibilityValue()) {
 | |
|      case ForcedAccessibilityValue::On:
 | |
|          userPrefersReducedMotion = true;
 | |
| @@ -869,6 +873,7 @@ static bool prefersReducedMotionEvaluate(CSSValue* value, const CSSToLengthConve
 | |
|  #endif
 | |
|          break;
 | |
|      }
 | |
| +    }
 | |
|  
 | |
|      if (!value)
 | |
|          return userPrefersReducedMotion;
 | |
| diff --git a/Source/WebCore/dom/DataTransfer.cpp b/Source/WebCore/dom/DataTransfer.cpp
 | |
| index 0340d056020c605e40e5c2a8265c855758bca8a1..c06566711f66c192607c2b520d6650066c3270b5 100644
 | |
| --- a/Source/WebCore/dom/DataTransfer.cpp
 | |
| +++ b/Source/WebCore/dom/DataTransfer.cpp
 | |
| @@ -496,6 +496,14 @@ Ref<DataTransfer> DataTransfer::createForDrag(const Document& document)
 | |
|      return adoptRef(*new DataTransfer(StoreMode::ReadWrite, Pasteboard::createForDragAndDrop(PagePasteboardContext::create(document.pageID())), Type::DragAndDropData));
 | |
|  }
 | |
|  
 | |
| +#if PLATFORM(MAC)
 | |
| +Ref<DataTransfer> DataTransfer::createForDrag(const Document& document, const String& pasteboardName)
 | |
| +{
 | |
| +    return adoptRef(*new DataTransfer(StoreMode::ReadWrite, makeUnique<Pasteboard>(PagePasteboardContext::create(document.pageID()), pasteboardName), Type::DragAndDropData));
 | |
| +}
 | |
| +#endif
 | |
| +
 | |
| +
 | |
|  Ref<DataTransfer> DataTransfer::createForDragStartEvent(const Document& document)
 | |
|  {
 | |
|      auto dataTransfer = adoptRef(*new DataTransfer(StoreMode::ReadWrite, makeUnique<StaticPasteboard>(), Type::DragAndDropData));
 | |
| diff --git a/Source/WebCore/dom/DataTransfer.h b/Source/WebCore/dom/DataTransfer.h
 | |
| index 4b1b54ddc37426c51614e594c3a99b3862929b65..be102d9d6369e36540e342d35febf16e7aa9927b 100644
 | |
| --- a/Source/WebCore/dom/DataTransfer.h
 | |
| +++ b/Source/WebCore/dom/DataTransfer.h
 | |
| @@ -90,6 +90,9 @@ public:
 | |
|  
 | |
|  #if ENABLE(DRAG_SUPPORT)
 | |
|      static Ref<DataTransfer> createForDrag(const Document&);
 | |
| +#if PLATFORM(MAC)
 | |
| +    static Ref<DataTransfer> createForDrag(const Document&, const String& pasteboardName);
 | |
| +#endif
 | |
|      static Ref<DataTransfer> createForDragStartEvent(const Document&);
 | |
|      static Ref<DataTransfer> createForDrop(const Document&, std::unique_ptr<Pasteboard>&&, OptionSet<DragOperation>, bool draggingFiles);
 | |
|      static Ref<DataTransfer> createForUpdatingDropTarget(const Document&, std::unique_ptr<Pasteboard>&&, OptionSet<DragOperation>, bool draggingFiles);
 | |
| diff --git a/Source/WebCore/dom/DeviceMotionEvent.idl b/Source/WebCore/dom/DeviceMotionEvent.idl
 | |
| index ea39a33a6250b4d10b20802f98aa9a5d57e63a7b..300a763508d311fd7b34cb3df3cc93080bb52930 100644
 | |
| --- a/Source/WebCore/dom/DeviceMotionEvent.idl
 | |
| +++ b/Source/WebCore/dom/DeviceMotionEvent.idl
 | |
| @@ -25,6 +25,7 @@
 | |
|  
 | |
|  [
 | |
|      Conditional=DEVICE_ORIENTATION,
 | |
| +    EnabledBySetting=DeviceOrientationEventEnabled,
 | |
|      Exposed=Window
 | |
|  ] interface DeviceMotionEvent : Event {
 | |
|      readonly attribute Acceleration? acceleration;
 | |
| diff --git a/Source/WebCore/dom/DeviceOrientationEvent.idl b/Source/WebCore/dom/DeviceOrientationEvent.idl
 | |
| index 9043052540b13d8120fb641de6337af46c3b36ef..a0f89e64b64640d2d4dbc14734868c4d4b03fc6f 100644
 | |
| --- a/Source/WebCore/dom/DeviceOrientationEvent.idl
 | |
| +++ b/Source/WebCore/dom/DeviceOrientationEvent.idl
 | |
| @@ -25,6 +25,7 @@
 | |
|  
 | |
|  [
 | |
|      Conditional=DEVICE_ORIENTATION,
 | |
| +    EnabledBySetting=DeviceOrientationEventEnabled,
 | |
|      Exposed=Window
 | |
|  ] interface DeviceOrientationEvent : Event {
 | |
|      readonly attribute unrestricted double? alpha;
 | |
| diff --git a/Source/WebCore/dom/Document+PointerLock.idl b/Source/WebCore/dom/Document+PointerLock.idl
 | |
| index 898027004b8553cac8130541026af70ffb5ee073..883d6a7df7a164625037cd8cee95c8fe4312b9e8 100644
 | |
| --- a/Source/WebCore/dom/Document+PointerLock.idl
 | |
| +++ b/Source/WebCore/dom/Document+PointerLock.idl
 | |
| @@ -25,6 +25,7 @@
 | |
|  
 | |
|  // https://w3c.github.io/pointerlock/#extensions-to-the-document-interface
 | |
|  [
 | |
| +    EnabledBySetting=PointerLockEnabled,
 | |
|      Conditional=POINTER_LOCK
 | |
|  ] partial interface Document {
 | |
|      [NotEnumerable] attribute EventHandler onpointerlockchange; // FIXME: Should be enumerable.
 | |
| diff --git a/Source/WebCore/dom/DocumentOrShadowRoot+PointerLock.idl b/Source/WebCore/dom/DocumentOrShadowRoot+PointerLock.idl
 | |
| index 9b8dbfc15ce078702321abcd6c0e636df7a60510..2956f7098e87af10ab8f5584b456ce9a6d432a20 100644
 | |
| --- a/Source/WebCore/dom/DocumentOrShadowRoot+PointerLock.idl
 | |
| +++ b/Source/WebCore/dom/DocumentOrShadowRoot+PointerLock.idl
 | |
| @@ -25,6 +25,7 @@
 | |
|  
 | |
|  // https://w3c.github.io/pointerlock/#extensions-to-the-documentorshadowroot-mixin
 | |
|  [
 | |
| +    EnabledBySetting=PointerLockEnabled,
 | |
|      Conditional=POINTER_LOCK
 | |
|  ] partial interface mixin DocumentOrShadowRoot {
 | |
|      readonly attribute Element? pointerLockElement;
 | |
| diff --git a/Source/WebCore/dom/Element+PointerLock.idl b/Source/WebCore/dom/Element+PointerLock.idl
 | |
| index f27718c1e2b8cd0a8075e556d4cdba7d9ae8fc54..2b61721594e5435845f3151e0de345e90eafc9ea 100644
 | |
| --- a/Source/WebCore/dom/Element+PointerLock.idl
 | |
| +++ b/Source/WebCore/dom/Element+PointerLock.idl
 | |
| @@ -24,6 +24,7 @@
 | |
|   */
 | |
|  
 | |
|  [
 | |
| +    EnabledBySetting=PointerLockEnabled,
 | |
|      Conditional=POINTER_LOCK
 | |
|  ] partial interface Element {
 | |
|      undefined requestPointerLock();
 | |
| diff --git a/Source/WebCore/dom/PointerEvent.cpp b/Source/WebCore/dom/PointerEvent.cpp
 | |
| index 4433bc1c4a055d0a8386fd01e7e9d44b99425516..a8a43743370f3a00bed40a206ae98a5cc50bc7c7 100644
 | |
| --- a/Source/WebCore/dom/PointerEvent.cpp
 | |
| +++ b/Source/WebCore/dom/PointerEvent.cpp
 | |
| @@ -114,4 +114,61 @@ EventInterface PointerEvent::eventInterface() const
 | |
|      return PointerEventInterfaceType;
 | |
|  }
 | |
|  
 | |
| +#if ENABLE(TOUCH_EVENTS) && !PLATFORM(IOS_FAMILY)
 | |
| +
 | |
| +static const AtomString& pointerEventType(PlatformTouchPoint::State state)
 | |
| +{
 | |
| +    switch (state) {
 | |
| +    case PlatformTouchPoint::State::TouchPressed:
 | |
| +        return eventNames().pointerdownEvent;
 | |
| +    case PlatformTouchPoint::State::TouchMoved:
 | |
| +        return eventNames().pointermoveEvent;
 | |
| +    case PlatformTouchPoint::State::TouchStationary:
 | |
| +        return eventNames().pointermoveEvent;
 | |
| +    case PlatformTouchPoint::State::TouchReleased:
 | |
| +        return eventNames().pointerupEvent;
 | |
| +    case PlatformTouchPoint::State::TouchCancelled:
 | |
| +        return eventNames().pointercancelEvent;
 | |
| +    case PlatformTouchPoint::State::TouchStateEnd:
 | |
| +        break;
 | |
| +    }
 | |
| +    ASSERT_NOT_REACHED();
 | |
| +    return nullAtom();
 | |
| +}
 | |
| +
 | |
| +static short buttonForType(const AtomString& type)
 | |
| +{
 | |
| +    return type == eventNames().pointermoveEvent ? -1 : 0;
 | |
| +}
 | |
| +
 | |
| +static unsigned short buttonsForType(const AtomString& type)
 | |
| +{
 | |
| +    // We have contact with the touch surface for most events except when we've released the touch or canceled it.
 | |
| +    return (type == eventNames().pointerupEvent || type == eventNames().pointeroutEvent || type == eventNames().pointerleaveEvent || type == eventNames().pointercancelEvent) ? 0 : 1;
 | |
| +}
 | |
| +
 | |
| +Ref<PointerEvent> PointerEvent::create(const PlatformTouchEvent& event, unsigned index, bool isPrimary, Ref<WindowProxy>&& view)
 | |
| +{
 | |
| +    const auto& type = pointerEventType(event.touchPoints().at(index).state());
 | |
| +    return adoptRef(*new PointerEvent(type, event, typeIsCancelable(type), index, isPrimary, WTFMove(view)));
 | |
| +}
 | |
| +
 | |
| +Ref<PointerEvent> PointerEvent::create(const AtomString& type, const PlatformTouchEvent& event, unsigned index, bool isPrimary, Ref<WindowProxy>&& view)
 | |
| +{
 | |
| +    return adoptRef(*new PointerEvent(type, event, typeIsCancelable(type), index, isPrimary, WTFMove(view)));
 | |
| +}
 | |
| +
 | |
| +PointerEvent::PointerEvent(const AtomString& type, const PlatformTouchEvent& event, IsCancelable isCancelable, unsigned index, bool isPrimary, Ref<WindowProxy>&& view)
 | |
| +    : MouseEvent(type, typeCanBubble(type), isCancelable, typeIsComposed(type), event.timestamp().approximateMonotonicTime(), WTFMove(view), 0, event.touchPoints().at(index).pos(), event.touchPoints().at(index).pos(), { }, event.modifiers(), buttonForType(type), buttonsForType(type), nullptr, 0, 0, IsSimulated::No, IsTrusted::Yes)
 | |
| +    , m_pointerId(2)
 | |
| +    , m_width(2 * event.touchPoints().at(index).radiusX())
 | |
| +    , m_height(2 * event.touchPoints().at(index).radiusY())
 | |
| +    , m_pressure(event.touchPoints().at(index).force())
 | |
| +    , m_pointerType(touchPointerEventType())
 | |
| +    , m_isPrimary(isPrimary)
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +#endif // ENABLE(TOUCH_EVENTS) && !PLATFORM(IOS_FAMILY)
 | |
| +
 | |
|  } // namespace WebCore
 | |
| diff --git a/Source/WebCore/dom/PointerEvent.h b/Source/WebCore/dom/PointerEvent.h
 | |
| index 7542bab569d49879f0eb460520738b3da37116f6..17c92229cc596bc80a718911b74737d3575137e1 100644
 | |
| --- a/Source/WebCore/dom/PointerEvent.h
 | |
| +++ b/Source/WebCore/dom/PointerEvent.h
 | |
| @@ -33,6 +33,8 @@
 | |
|  
 | |
|  #if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS_FAMILY)
 | |
|  #include "PlatformTouchEventIOS.h"
 | |
| +#else
 | |
| +#include "PlatformTouchEvent.h"
 | |
|  #endif
 | |
|  
 | |
|  namespace WebCore {
 | |
| @@ -81,7 +83,7 @@ public:
 | |
|      static Ref<PointerEvent> create(const AtomString& type, short button, const MouseEvent&, PointerID, const String& pointerType);
 | |
|      static Ref<PointerEvent> create(const AtomString& type, PointerID, const String& pointerType, IsPrimary = IsPrimary::No);
 | |
|  
 | |
| -#if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS_FAMILY)
 | |
| +#if ENABLE(TOUCH_EVENTS)
 | |
|      static Ref<PointerEvent> create(const PlatformTouchEvent&, unsigned touchIndex, bool isPrimary, Ref<WindowProxy>&&);
 | |
|      static Ref<PointerEvent> create(const AtomString& type, const PlatformTouchEvent&, unsigned touchIndex, bool isPrimary, Ref<WindowProxy>&&);
 | |
|  #endif
 | |
| @@ -121,7 +123,7 @@ private:
 | |
|      PointerEvent(const AtomString&, Init&&);
 | |
|      PointerEvent(const AtomString& type, short button, const MouseEvent&, PointerID, const String& pointerType);
 | |
|      PointerEvent(const AtomString& type, PointerID, const String& pointerType, IsPrimary);
 | |
| -#if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS_FAMILY)
 | |
| +#if ENABLE(TOUCH_EVENTS)
 | |
|      PointerEvent(const AtomString& type, const PlatformTouchEvent&, IsCancelable isCancelable, unsigned touchIndex, bool isPrimary, Ref<WindowProxy>&&);
 | |
|  #endif
 | |
|  
 | |
| diff --git a/Source/WebCore/editing/libwpe/EditorLibWPE.cpp b/Source/WebCore/editing/libwpe/EditorLibWPE.cpp
 | |
| index b8a3148b067373dadfb43975473a18caeb266d51..504172cd327b38ffbd103259e86d374752ee3474 100644
 | |
| --- a/Source/WebCore/editing/libwpe/EditorLibWPE.cpp
 | |
| +++ b/Source/WebCore/editing/libwpe/EditorLibWPE.cpp
 | |
| @@ -34,6 +34,7 @@
 | |
|  #include "NotImplemented.h"
 | |
|  #include "Pasteboard.h"
 | |
|  #include "Settings.h"
 | |
| +#include "WebContentReader.h"
 | |
|  #include "markup.h"
 | |
|  
 | |
|  namespace WebCore {
 | |
| @@ -99,6 +100,14 @@ void Editor::platformPasteFont()
 | |
|  {
 | |
|  }
 | |
|  
 | |
| +RefPtr<DocumentFragment> Editor::webContentFromPasteboard(Pasteboard& pasteboard, const SimpleRange& context, bool allowPlainText, bool& chosePlainText)
 | |
| +{
 | |
| +    WebContentReader reader(*m_document.frame(), context, allowPlainText);
 | |
| +    pasteboard.read(reader);
 | |
| +    chosePlainText = reader.madeFragmentFromPlainText;
 | |
| +    return WTFMove(reader.fragment);
 | |
| +}
 | |
| +
 | |
|  } // namespace WebCore
 | |
|  
 | |
|  #endif // USE(LIBWPE)
 | |
| diff --git a/Source/WebCore/html/FileInputType.cpp b/Source/WebCore/html/FileInputType.cpp
 | |
| index e739d217b780fc475c78762f0b04b96f57fa7df1..2d8479d1695fc6239c9f55ab29371d5d10a62a5f 100644
 | |
| --- a/Source/WebCore/html/FileInputType.cpp
 | |
| +++ b/Source/WebCore/html/FileInputType.cpp
 | |
| @@ -37,6 +37,7 @@
 | |
|  #include "HTMLNames.h"
 | |
|  #include "Icon.h"
 | |
|  #include "InputTypeNames.h"
 | |
| +#include "InspectorInstrumentation.h"
 | |
|  #include "LocalizedStrings.h"
 | |
|  #include "MIMETypeRegistry.h"
 | |
|  #include "RenderFileUploadControl.h"
 | |
| @@ -200,6 +201,11 @@ void FileInputType::handleDOMActivateEvent(Event& event)
 | |
|      if (input.isDisabledFormControl())
 | |
|          return;
 | |
|  
 | |
| +    bool intercept = false;
 | |
| +    InspectorInstrumentation::runOpenPanel(input.document().frame(), element(), &intercept);
 | |
| +    if (intercept)
 | |
| +        return;
 | |
| +
 | |
|      if (!UserGestureIndicator::processingUserGesture())
 | |
|          return;
 | |
|  
 | |
| diff --git a/Source/WebCore/inspector/InspectorController.cpp b/Source/WebCore/inspector/InspectorController.cpp
 | |
| index 23b330d6d57226dd0e3e2d19117520097f6baf7f..45531ee0561e8783f245f05f27cd51c175c52b70 100644
 | |
| --- a/Source/WebCore/inspector/InspectorController.cpp
 | |
| +++ b/Source/WebCore/inspector/InspectorController.cpp
 | |
| @@ -285,6 +285,8 @@ void InspectorController::disconnectFrontend(FrontendChannel& frontendChannel)
 | |
|  
 | |
|          // Unplug all instrumentations since they aren't needed now.
 | |
|          InspectorInstrumentation::unregisterInstrumentingAgents(m_instrumentingAgents.get());
 | |
| +
 | |
| +        m_pauseWhenShown = false;
 | |
|      }
 | |
|  
 | |
|      m_inspectorClient->frontendCountChanged(m_frontendRouter->frontendCount());
 | |
| @@ -304,6 +306,8 @@ void InspectorController::disconnectAllFrontends()
 | |
|      // The frontend should call setInspectorFrontendClient(nullptr) under closeWindow().
 | |
|      ASSERT(!m_inspectorFrontendClient);
 | |
|  
 | |
| +    m_pauseWhenShown = false;
 | |
| +
 | |
|      if (!m_frontendRouter->hasFrontends())
 | |
|          return;
 | |
|  
 | |
| @@ -392,8 +396,8 @@ void InspectorController::inspect(Node* node)
 | |
|      if (!enabled())
 | |
|          return;
 | |
|  
 | |
| -    if (!hasRemoteFrontend())
 | |
| -        show();
 | |
| +    // HACK: Always attempt to show inspector even if there is a remote connection.
 | |
| +    show();
 | |
|  
 | |
|      ensureDOMAgent().inspect(node);
 | |
|  }
 | |
| @@ -534,4 +538,24 @@ void InspectorController::didComposite(Frame& frame)
 | |
|      InspectorInstrumentation::didComposite(frame);
 | |
|  }
 | |
|  
 | |
| +void InspectorController::pauseWhenShown()
 | |
| +{
 | |
| +    m_pauseWhenShown = true;
 | |
| +}
 | |
| +
 | |
| +void InspectorController::resumeIfPausedInNewWindow()
 | |
| +{
 | |
| +    m_pauseWhenShown = false;
 | |
| +}
 | |
| +
 | |
| +void InspectorController::didShowNewWindow()
 | |
| +{
 | |
| +    if (!m_pauseWhenShown)
 | |
| +        return;
 | |
| +    while (m_pauseWhenShown) {
 | |
| +        if (RunLoop::cycle() == RunLoop::CycleResult::Stop)
 | |
| +            break;
 | |
| +    }
 | |
| +}
 | |
| +
 | |
|  } // namespace WebCore
 | |
| diff --git a/Source/WebCore/inspector/InspectorController.h b/Source/WebCore/inspector/InspectorController.h
 | |
| index 4d5a3859ec6a46d07d45c80a3b5870ee2ef13d36..75eb55a024a6ae3892a4fedc535bf6a647cc3bc7 100644
 | |
| --- a/Source/WebCore/inspector/InspectorController.h
 | |
| +++ b/Source/WebCore/inspector/InspectorController.h
 | |
| @@ -101,6 +101,10 @@ public:
 | |
|      WEBCORE_EXPORT void willComposite(Frame&);
 | |
|      WEBCORE_EXPORT void didComposite(Frame&);
 | |
|  
 | |
| +    WEBCORE_EXPORT void pauseWhenShown();
 | |
| +    WEBCORE_EXPORT void resumeIfPausedInNewWindow();
 | |
| +    WEBCORE_EXPORT void didShowNewWindow();
 | |
| +
 | |
|      // Testing support.
 | |
|      WEBCORE_EXPORT bool isUnderTest() const;
 | |
|      void setIsUnderTest(bool isUnderTest) { m_isUnderTest = isUnderTest; }
 | |
| @@ -154,6 +158,7 @@ private:
 | |
|      bool m_isAutomaticInspection { false };
 | |
|      bool m_pauseAfterInitialization = { false };
 | |
|      bool m_didCreateLazyAgents { false };
 | |
| +    bool m_pauseWhenShown { false };
 | |
|  };
 | |
|  
 | |
|  } // namespace WebCore
 | |
| diff --git a/Source/WebCore/inspector/InspectorInstrumentation.cpp b/Source/WebCore/inspector/InspectorInstrumentation.cpp
 | |
| index 40758afa09fa29f9ce677c4a3b606e0a9b213c13..a681e28d2aef5d0b9f968fc974668febf3d62c78 100644
 | |
| --- a/Source/WebCore/inspector/InspectorInstrumentation.cpp
 | |
| +++ b/Source/WebCore/inspector/InspectorInstrumentation.cpp
 | |
| @@ -572,6 +572,13 @@ void InspectorInstrumentation::applyUserAgentOverrideImpl(InstrumentingAgents& i
 | |
|          pageAgent->applyUserAgentOverride(userAgent);
 | |
|  }
 | |
|  
 | |
| +void InspectorInstrumentation::applyPlatformOverrideImpl(InstrumentingAgents& instrumentingAgents, String& platform)
 | |
| +{
 | |
| +    if (auto* pageAgent = instrumentingAgents.enabledPageAgent())
 | |
| +        pageAgent->applyPlatformOverride(platform);
 | |
| +}
 | |
| +
 | |
| +
 | |
|  void InspectorInstrumentation::applyEmulatedMediaImpl(InstrumentingAgents& instrumentingAgents, String& media)
 | |
|  {
 | |
|      if (auto* pageAgent = instrumentingAgents.enabledPageAgent())
 | |
| @@ -651,6 +658,12 @@ void InspectorInstrumentation::didFailLoadingImpl(InstrumentingAgents& instrumen
 | |
|          consoleAgent->didFailLoading(identifier, error); // This should come AFTER resource notification, front-end relies on this.
 | |
|  }
 | |
|  
 | |
| +void InspectorInstrumentation::didReceiveMainResourceErrorImpl(InstrumentingAgents& instrumentingAgents, Frame& frame, const ResourceError&)
 | |
| +{
 | |
| +    if (auto* pageRuntimeAgent = instrumentingAgents.enabledPageRuntimeAgent())
 | |
| +        pageRuntimeAgent->didReceiveMainResourceError(frame);
 | |
| +}
 | |
| +
 | |
|  void InspectorInstrumentation::willLoadXHRSynchronouslyImpl(InstrumentingAgents& instrumentingAgents)
 | |
|  {
 | |
|      if (auto* networkAgent = instrumentingAgents.enabledNetworkAgent())
 | |
| @@ -683,20 +696,17 @@ void InspectorInstrumentation::didReceiveScriptResponseImpl(InstrumentingAgents&
 | |
|  
 | |
|  void InspectorInstrumentation::domContentLoadedEventFiredImpl(InstrumentingAgents& instrumentingAgents, Frame& frame)
 | |
|  {
 | |
| -    if (!frame.isMainFrame())
 | |
| -        return;
 | |
| -
 | |
|      if (auto* pageAgent = instrumentingAgents.enabledPageAgent())
 | |
| -        pageAgent->domContentEventFired();
 | |
| +        pageAgent->domContentEventFired(frame);
 | |
|  }
 | |
|  
 | |
|  void InspectorInstrumentation::loadEventFiredImpl(InstrumentingAgents& instrumentingAgents, Frame* frame)
 | |
|  {
 | |
| -    if (!frame || !frame->isMainFrame())
 | |
| +    if (!frame)
 | |
|          return;
 | |
|  
 | |
|      if (auto* pageAgent = instrumentingAgents.enabledPageAgent())
 | |
| -        pageAgent->loadEventFired();
 | |
| +        pageAgent->loadEventFired(*frame);
 | |
|  }
 | |
|  
 | |
|  void InspectorInstrumentation::frameDetachedFromParentImpl(InstrumentingAgents& instrumentingAgents, Frame& frame)
 | |
| @@ -777,12 +787,6 @@ void InspectorInstrumentation::frameDocumentUpdatedImpl(InstrumentingAgents& ins
 | |
|          pageDOMDebuggerAgent->frameDocumentUpdated(frame);
 | |
|  }
 | |
|  
 | |
| -void InspectorInstrumentation::loaderDetachedFromFrameImpl(InstrumentingAgents& instrumentingAgents, DocumentLoader& loader)
 | |
| -{
 | |
| -    if (auto* inspectorPageAgent = instrumentingAgents.enabledPageAgent())
 | |
| -        inspectorPageAgent->loaderDetachedFromFrame(loader);
 | |
| -}
 | |
| -
 | |
|  void InspectorInstrumentation::frameStartedLoadingImpl(InstrumentingAgents& instrumentingAgents, Frame& frame)
 | |
|  {
 | |
|      if (frame.isMainFrame()) {
 | |
| @@ -819,6 +823,12 @@ void InspectorInstrumentation::frameClearedScheduledNavigationImpl(Instrumenting
 | |
|          inspectorPageAgent->frameClearedScheduledNavigation(frame);
 | |
|  }
 | |
|  
 | |
| +void InspectorInstrumentation::didNavigateWithinPageImpl(InstrumentingAgents& instrumentingAgents, Frame& frame)
 | |
| +{
 | |
| +    if (InspectorPageAgent* inspectorPageAgent = instrumentingAgents.enabledPageAgent())
 | |
| +        inspectorPageAgent->didNavigateWithinPage(frame);
 | |
| +}
 | |
| +
 | |
|  #if ENABLE(DARK_MODE_CSS) || HAVE(OS_DARK_MODE_SUPPORT)
 | |
|  void InspectorInstrumentation::defaultAppearanceDidChangeImpl(InstrumentingAgents& instrumentingAgents, bool useDarkAppearance)
 | |
|  {
 | |
| @@ -1301,6 +1311,36 @@ void InspectorInstrumentation::renderLayerDestroyedImpl(InstrumentingAgents& ins
 | |
|          layerTreeAgent->renderLayerDestroyed(renderLayer);
 | |
|  }
 | |
|  
 | |
| +void InspectorInstrumentation::runOpenPanelImpl(InstrumentingAgents& instrumentingAgents, HTMLInputElement* element, bool* intercept)
 | |
| +{
 | |
| +    if (InspectorPageAgent* pageAgent = instrumentingAgents.enabledPageAgent())
 | |
| +        pageAgent->runOpenPanel(element, intercept);
 | |
| +}
 | |
| +
 | |
| +void InspectorInstrumentation::frameAttachedImpl(InstrumentingAgents& instrumentingAgents, Frame& frame) {
 | |
| +    if (InspectorPageAgent* pageAgent = instrumentingAgents.enabledPageAgent())
 | |
| +        pageAgent->frameAttached(frame);
 | |
| +}
 | |
| +
 | |
| +bool InspectorInstrumentation::shouldBypassCSPImpl(InstrumentingAgents& instrumentingAgents)
 | |
| +{
 | |
| +    if (InspectorPageAgent* pageAgent = instrumentingAgents.enabledPageAgent())
 | |
| +        return pageAgent->shouldBypassCSP();
 | |
| +    return false;
 | |
| +}
 | |
| +
 | |
| +void InspectorInstrumentation::willCheckNavigationPolicyImpl(InstrumentingAgents& instrumentingAgents, Frame& frame)
 | |
| +{
 | |
| +    if (InspectorPageAgent* pageAgent = instrumentingAgents.enabledPageAgent())
 | |
| +        pageAgent->willCheckNavigationPolicy(frame);
 | |
| +}
 | |
| +
 | |
| +void InspectorInstrumentation::didCheckNavigationPolicyImpl(InstrumentingAgents& instrumentingAgents, Frame& frame, bool cancel)
 | |
| +{
 | |
| +    if (InspectorPageAgent* pageAgent = instrumentingAgents.enabledPageAgent())
 | |
| +        pageAgent->didCheckNavigationPolicy(frame, cancel);
 | |
| +}
 | |
| +
 | |
|  InstrumentingAgents& InspectorInstrumentation::instrumentingAgents(WorkerOrWorkletGlobalScope& globalScope)
 | |
|  {
 | |
|      return globalScope.inspectorController().m_instrumentingAgents;
 | |
| @@ -1312,6 +1352,13 @@ InstrumentingAgents& InspectorInstrumentation::instrumentingAgents(Page& page)
 | |
|      return page.inspectorController().m_instrumentingAgents.get();
 | |
|  }
 | |
|  
 | |
| +void InspectorInstrumentation::maybeOverrideDefaultObjectInclusion(Page& page, AccessibilityObjectInclusion& inclusion) {
 | |
| +    if (InspectorPageAgent* pageAgent = instrumentingAgents(page).enabledPageAgent()) {
 | |
| +        if (pageAgent->doingAccessibilitySnapshot())
 | |
| +            inclusion = AccessibilityObjectInclusion::DefaultBehavior;
 | |
| +    }
 | |
| +}
 | |
| +
 | |
|  InstrumentingAgents* InspectorInstrumentation::instrumentingAgents(ScriptExecutionContext& context)
 | |
|  {
 | |
|      if (is<Document>(context))
 | |
| diff --git a/Source/WebCore/inspector/InspectorInstrumentation.h b/Source/WebCore/inspector/InspectorInstrumentation.h
 | |
| index bde7c16e2e3fbe0b5d3891996e550f99785bb5c1..899b13d1eac5bd7dd35fe82cce1bf796cf18125d 100644
 | |
| --- a/Source/WebCore/inspector/InspectorInstrumentation.h
 | |
| +++ b/Source/WebCore/inspector/InspectorInstrumentation.h
 | |
| @@ -31,6 +31,7 @@
 | |
|  
 | |
|  #pragma once
 | |
|  
 | |
| +#include "AccessibilityObjectInterface.h"
 | |
|  #include "CSSSelector.h"
 | |
|  #include "CanvasBase.h"
 | |
|  #include "CanvasRenderingContext.h"
 | |
| @@ -45,6 +46,7 @@
 | |
|  #include "HitTestResult.h"
 | |
|  #include "InspectorInstrumentationPublic.h"
 | |
|  #include "Page.h"
 | |
| +#include "ResourceError.h"
 | |
|  #include "ResourceLoader.h"
 | |
|  #include "ResourceLoaderIdentifier.h"
 | |
|  #include "StorageArea.h"
 | |
| @@ -77,6 +79,7 @@ class DOMWrapperWorld;
 | |
|  class Document;
 | |
|  class DocumentLoader;
 | |
|  class EventListener;
 | |
| +class HTMLInputElement;
 | |
|  class HTTPHeaderMap;
 | |
|  class InspectorTimelineAgent;
 | |
|  class InstrumentingAgents;
 | |
| @@ -189,6 +192,7 @@ public:
 | |
|      static void didRecalculateStyle(Document&);
 | |
|      static void didScheduleStyleRecalculation(Document&);
 | |
|      static void applyUserAgentOverride(Frame&, String&);
 | |
| +    static void applyPlatformOverride(Frame&, String&);
 | |
|      static void applyEmulatedMedia(Frame&, String&);
 | |
|  
 | |
|      static void flexibleBoxRendererBeganLayout(const RenderObject&);
 | |
| @@ -201,6 +205,7 @@ public:
 | |
|      static void didReceiveData(Frame*, ResourceLoaderIdentifier, const SharedBuffer*, int encodedDataLength);
 | |
|      static void didFinishLoading(Frame*, DocumentLoader*, ResourceLoaderIdentifier, const NetworkLoadMetrics&, ResourceLoader*);
 | |
|      static void didFailLoading(Frame*, DocumentLoader*, ResourceLoaderIdentifier, const ResourceError&);
 | |
| +    static void didReceiveMainResourceError(Frame&, const ResourceError&);
 | |
|  
 | |
|      static void willSendRequest(WorkerOrWorkletGlobalScope&, ResourceLoaderIdentifier, ResourceRequest&);
 | |
|      static void didReceiveResourceResponse(WorkerOrWorkletGlobalScope&, ResourceLoaderIdentifier, const ResourceResponse&);
 | |
| @@ -227,11 +232,11 @@ public:
 | |
|      static void frameDetachedFromParent(Frame&);
 | |
|      static void didCommitLoad(Frame&, DocumentLoader*);
 | |
|      static void frameDocumentUpdated(Frame&);
 | |
| -    static void loaderDetachedFromFrame(Frame&, DocumentLoader&);
 | |
|      static void frameStartedLoading(Frame&);
 | |
|      static void frameStoppedLoading(Frame&);
 | |
|      static void frameScheduledNavigation(Frame&, Seconds delay);
 | |
|      static void frameClearedScheduledNavigation(Frame&);
 | |
| +    static void didNavigateWithinPage(Frame&);
 | |
|  #if ENABLE(DARK_MODE_CSS) || HAVE(OS_DARK_MODE_SUPPORT)
 | |
|      static void defaultAppearanceDidChange(Page&, bool useDarkAppearance);
 | |
|  #endif
 | |
| @@ -318,6 +323,12 @@ public:
 | |
|      static void layerTreeDidChange(Page*);
 | |
|      static void renderLayerDestroyed(Page*, const RenderLayer&);
 | |
|  
 | |
| +    static void runOpenPanel(Frame*, HTMLInputElement*, bool*);
 | |
| +    static void frameAttached(Frame*);
 | |
| +    static bool shouldBypassCSP(ScriptExecutionContext*);
 | |
| +    static void willCheckNavigationPolicy(Frame&);
 | |
| +    static void didCheckNavigationPolicy(Frame&, bool cancel);
 | |
| +
 | |
|      static void frontendCreated();
 | |
|      static void frontendDeleted();
 | |
|      static bool hasFrontends() { return InspectorInstrumentationPublic::hasFrontends(); }
 | |
| @@ -334,6 +345,8 @@ public:
 | |
|      static void registerInstrumentingAgents(InstrumentingAgents&);
 | |
|      static void unregisterInstrumentingAgents(InstrumentingAgents&);
 | |
|  
 | |
| +    static void maybeOverrideDefaultObjectInclusion(Page&, AccessibilityObjectInclusion&);
 | |
| +
 | |
|  private:
 | |
|      static void didClearWindowObjectInWorldImpl(InstrumentingAgents&, Frame&, DOMWrapperWorld&);
 | |
|      static bool isDebuggerPausedImpl(InstrumentingAgents&);
 | |
| @@ -411,6 +424,7 @@ private:
 | |
|      static void didRecalculateStyleImpl(InstrumentingAgents&);
 | |
|      static void didScheduleStyleRecalculationImpl(InstrumentingAgents&, Document&);
 | |
|      static void applyUserAgentOverrideImpl(InstrumentingAgents&, String&);
 | |
| +    static void applyPlatformOverrideImpl(InstrumentingAgents&, String&);
 | |
|      static void applyEmulatedMediaImpl(InstrumentingAgents&, String&);
 | |
|  
 | |
|      static void flexibleBoxRendererBeganLayoutImpl(InstrumentingAgents&, const RenderObject&);
 | |
| @@ -425,6 +439,7 @@ private:
 | |
|      static void didReceiveDataImpl(InstrumentingAgents&, ResourceLoaderIdentifier, const SharedBuffer*, int encodedDataLength);
 | |
|      static void didFinishLoadingImpl(InstrumentingAgents&, ResourceLoaderIdentifier, DocumentLoader*, const NetworkLoadMetrics&, ResourceLoader*);
 | |
|      static void didFailLoadingImpl(InstrumentingAgents&, ResourceLoaderIdentifier, DocumentLoader*, const ResourceError&);
 | |
| +    static void didReceiveMainResourceErrorImpl(InstrumentingAgents&, Frame&, const ResourceError&);
 | |
|      static void willLoadXHRSynchronouslyImpl(InstrumentingAgents&);
 | |
|      static void didLoadXHRSynchronouslyImpl(InstrumentingAgents&);
 | |
|      static void scriptImportedImpl(InstrumentingAgents&, ResourceLoaderIdentifier, const String& sourceString);
 | |
| @@ -435,11 +450,11 @@ private:
 | |
|      static void frameDetachedFromParentImpl(InstrumentingAgents&, Frame&);
 | |
|      static void didCommitLoadImpl(InstrumentingAgents&, Frame&, DocumentLoader*);
 | |
|      static void frameDocumentUpdatedImpl(InstrumentingAgents&, Frame&);
 | |
| -    static void loaderDetachedFromFrameImpl(InstrumentingAgents&, DocumentLoader&);
 | |
|      static void frameStartedLoadingImpl(InstrumentingAgents&, Frame&);
 | |
|      static void frameStoppedLoadingImpl(InstrumentingAgents&, Frame&);
 | |
|      static void frameScheduledNavigationImpl(InstrumentingAgents&, Frame&, Seconds delay);
 | |
|      static void frameClearedScheduledNavigationImpl(InstrumentingAgents&, Frame&);
 | |
| +    static void didNavigateWithinPageImpl(InstrumentingAgents&, Frame&);
 | |
|  #if ENABLE(DARK_MODE_CSS) || HAVE(OS_DARK_MODE_SUPPORT)
 | |
|      static void defaultAppearanceDidChangeImpl(InstrumentingAgents&, bool useDarkAppearance);
 | |
|  #endif
 | |
| @@ -521,6 +536,12 @@ private:
 | |
|      static void layerTreeDidChangeImpl(InstrumentingAgents&);
 | |
|      static void renderLayerDestroyedImpl(InstrumentingAgents&, const RenderLayer&);
 | |
|  
 | |
| +    static void runOpenPanelImpl(InstrumentingAgents&, HTMLInputElement*, bool*);
 | |
| +    static void frameAttachedImpl(InstrumentingAgents&, Frame&);
 | |
| +    static bool shouldBypassCSPImpl(InstrumentingAgents&);
 | |
| +    static void willCheckNavigationPolicyImpl(InstrumentingAgents&, Frame&);
 | |
| +    static void didCheckNavigationPolicyImpl(InstrumentingAgents&, Frame&, bool cancel);
 | |
| +
 | |
|      static InstrumentingAgents& instrumentingAgents(Page&);
 | |
|      static InstrumentingAgents& instrumentingAgents(WorkerOrWorkletGlobalScope&);
 | |
|  
 | |
| @@ -1039,6 +1060,13 @@ inline void InspectorInstrumentation::applyUserAgentOverride(Frame& frame, Strin
 | |
|          applyUserAgentOverrideImpl(*agents, userAgent);
 | |
|  }
 | |
|  
 | |
| +inline void InspectorInstrumentation::applyPlatformOverride(Frame& frame, String& platform)
 | |
| +{
 | |
| +    FAST_RETURN_IF_NO_FRONTENDS(void());
 | |
| +    if (auto* agents = instrumentingAgents(frame))
 | |
| +        applyPlatformOverrideImpl(*agents, platform);
 | |
| +}
 | |
| +
 | |
|  inline void InspectorInstrumentation::applyEmulatedMedia(Frame& frame, String& media)
 | |
|  {
 | |
|      FAST_RETURN_IF_NO_FRONTENDS(void());
 | |
| @@ -1141,6 +1169,13 @@ inline void InspectorInstrumentation::didFailLoading(WorkerOrWorkletGlobalScope&
 | |
|      didFailLoadingImpl(instrumentingAgents(globalScope), identifier, nullptr, error);
 | |
|  }
 | |
|  
 | |
| +inline void InspectorInstrumentation::didReceiveMainResourceError(Frame& frame, const ResourceError& error)
 | |
| +{
 | |
| +    FAST_RETURN_IF_NO_FRONTENDS(void());
 | |
| +    if (auto* agents = instrumentingAgents(frame))
 | |
| +        didReceiveMainResourceErrorImpl(*agents, frame, error);
 | |
| +}
 | |
| +
 | |
|  inline void InspectorInstrumentation::continueAfterXFrameOptionsDenied(Frame& frame, ResourceLoaderIdentifier identifier, DocumentLoader& loader, const ResourceResponse& response)
 | |
|  {
 | |
|      // Treat the same as didReceiveResponse.
 | |
| @@ -1231,13 +1266,6 @@ inline void InspectorInstrumentation::frameDocumentUpdated(Frame& frame)
 | |
|          frameDocumentUpdatedImpl(*agents, frame);
 | |
|  }
 | |
|  
 | |
| -inline void InspectorInstrumentation::loaderDetachedFromFrame(Frame& frame, DocumentLoader& loader)
 | |
| -{
 | |
| -    FAST_RETURN_IF_NO_FRONTENDS(void());
 | |
| -    if (auto* agents = instrumentingAgents(frame))
 | |
| -        loaderDetachedFromFrameImpl(*agents, loader);
 | |
| -}
 | |
| -
 | |
|  inline void InspectorInstrumentation::frameStartedLoading(Frame& frame)
 | |
|  {
 | |
|      FAST_RETURN_IF_NO_FRONTENDS(void());
 | |
| @@ -1266,6 +1294,13 @@ inline void InspectorInstrumentation::frameClearedScheduledNavigation(Frame& fra
 | |
|          frameClearedScheduledNavigationImpl(*agents, frame);
 | |
|  }
 | |
|  
 | |
| +inline void InspectorInstrumentation::didNavigateWithinPage(Frame& frame)
 | |
| +{
 | |
| +    FAST_RETURN_IF_NO_FRONTENDS(void());
 | |
| +    if (auto* agents = instrumentingAgents(frame))
 | |
| +        didNavigateWithinPageImpl(*agents, frame);
 | |
| +}
 | |
| +
 | |
|  #if ENABLE(DARK_MODE_CSS) || HAVE(OS_DARK_MODE_SUPPORT)
 | |
|  inline void InspectorInstrumentation::defaultAppearanceDidChange(Page& page, bool useDarkAppearance)
 | |
|  {
 | |
| @@ -1696,6 +1731,42 @@ inline void InspectorInstrumentation::renderLayerDestroyed(Page* page, const Ren
 | |
|          renderLayerDestroyedImpl(*agents, renderLayer);
 | |
|  }
 | |
|  
 | |
| +inline void InspectorInstrumentation::runOpenPanel(Frame* frame, HTMLInputElement* element, bool* intercept)
 | |
| +{
 | |
| +    FAST_RETURN_IF_NO_FRONTENDS(void());
 | |
| +    if (auto* agents = instrumentingAgents(*frame))
 | |
| +        runOpenPanelImpl(*agents, element, intercept);
 | |
| +}
 | |
| +
 | |
| +inline void InspectorInstrumentation::frameAttached(Frame* frame)
 | |
| +{
 | |
| +    FAST_RETURN_IF_NO_FRONTENDS(void());
 | |
| +    if (auto* agents = instrumentingAgents(frame))
 | |
| +        frameAttachedImpl(*agents, *frame);
 | |
| +}
 | |
| +
 | |
| +inline bool InspectorInstrumentation::shouldBypassCSP(ScriptExecutionContext* context)
 | |
| +{
 | |
| +    FAST_RETURN_IF_NO_FRONTENDS(false);
 | |
| +    if (auto* agents = instrumentingAgents(context))
 | |
| +        return shouldBypassCSPImpl(*agents);
 | |
| +    return false;
 | |
| +}
 | |
| +
 | |
| +inline void InspectorInstrumentation::willCheckNavigationPolicy(Frame& frame)
 | |
| +{
 | |
| +    FAST_RETURN_IF_NO_FRONTENDS(void());
 | |
| +    if (auto* agents = instrumentingAgents(frame))
 | |
| +        willCheckNavigationPolicyImpl(*agents, frame);
 | |
| +}
 | |
| +
 | |
| +inline void InspectorInstrumentation::didCheckNavigationPolicy(Frame& frame, bool cancel)
 | |
| +{
 | |
| +    FAST_RETURN_IF_NO_FRONTENDS(void());
 | |
| +    if (auto* agents = instrumentingAgents(frame))
 | |
| +        didCheckNavigationPolicyImpl(*agents, frame, cancel);
 | |
| +}
 | |
| +
 | |
|  inline InstrumentingAgents* InspectorInstrumentation::instrumentingAgents(ScriptExecutionContext* context)
 | |
|  {
 | |
|      return context ? instrumentingAgents(*context) : nullptr;
 | |
| diff --git a/Source/WebCore/inspector/agents/InspectorDOMAgent.cpp b/Source/WebCore/inspector/agents/InspectorDOMAgent.cpp
 | |
| index 66967959aff451eda20716b8ae9616fb7a915a29..4f8b75e852da5a24570d3a0bc4a6871f19d502fc 100644
 | |
| --- a/Source/WebCore/inspector/agents/InspectorDOMAgent.cpp
 | |
| +++ b/Source/WebCore/inspector/agents/InspectorDOMAgent.cpp
 | |
| @@ -62,12 +62,16 @@
 | |
|  #include "Event.h"
 | |
|  #include "EventListener.h"
 | |
|  #include "EventNames.h"
 | |
| +#include "File.h"
 | |
| +#include "FileList.h"
 | |
|  #include "Frame.h"
 | |
|  #include "FrameTree.h"
 | |
|  #include "FrameView.h"
 | |
|  #include "FullscreenManager.h"
 | |
| +#include "FloatQuad.h"
 | |
|  #include "HTMLElement.h"
 | |
|  #include "HTMLFrameOwnerElement.h"
 | |
| +#include "HTMLInputElement.h"
 | |
|  #include "HTMLMediaElement.h"
 | |
|  #include "HTMLNames.h"
 | |
|  #include "HTMLParserIdioms.h"
 | |
| @@ -95,12 +99,14 @@
 | |
|  #include "Pasteboard.h"
 | |
|  #include "PseudoElement.h"
 | |
|  #include "RenderGrid.h"
 | |
| +#include "RenderLayer.h"
 | |
|  #include "RenderObject.h"
 | |
|  #include "RenderStyle.h"
 | |
|  #include "RenderStyleConstants.h"
 | |
|  #include "ScriptController.h"
 | |
|  #include "SelectorChecker.h"
 | |
|  #include "ShadowRoot.h"
 | |
| +#include "SharedBuffer.h"
 | |
|  #include "StaticNodeList.h"
 | |
|  #include "StyleProperties.h"
 | |
|  #include "StyleResolver.h"
 | |
| @@ -134,7 +140,8 @@ using namespace HTMLNames;
 | |
|  static const size_t maxTextSize = 10000;
 | |
|  static const UChar ellipsisUChar[] = { 0x2026, 0 };
 | |
|  
 | |
| -static std::optional<Color> parseColor(RefPtr<JSON::Object>&& colorObject)
 | |
| +// static
 | |
| +std::optional<Color> InspectorDOMAgent::parseColor(RefPtr<JSON::Object>&& colorObject)
 | |
|  {
 | |
|      if (!colorObject)
 | |
|          return std::nullopt;
 | |
| @@ -153,7 +160,7 @@ static std::optional<Color> parseColor(RefPtr<JSON::Object>&& colorObject)
 | |
|  
 | |
|  static Color parseConfigColor(const String& fieldName, JSON::Object& configObject)
 | |
|  {
 | |
| -    return parseColor(configObject.getObject(fieldName)).value_or(Color::transparentBlack);
 | |
| +    return InspectorDOMAgent::parseColor(configObject.getObject(fieldName)).value_or(Color::transparentBlack);
 | |
|  }
 | |
|  
 | |
|  static bool parseQuad(Ref<JSON::Array>&& quadArray, FloatQuad* quad)
 | |
| @@ -417,6 +424,20 @@ Node* InspectorDOMAgent::assertNode(Protocol::ErrorString& errorString, Protocol
 | |
|      return node;
 | |
|  }
 | |
|  
 | |
| +Node* InspectorDOMAgent::assertNode(Protocol::ErrorString& errorString, std::optional<Protocol::DOM::NodeId>&& nodeId, const String& objectId)
 | |
| +{
 | |
| +    Node* node = nullptr;
 | |
| +    if (nodeId) {
 | |
| +        node = assertNode(errorString, *nodeId);
 | |
| +    } else if (!!objectId) {
 | |
| +        node = nodeForObjectId(objectId);
 | |
| +        if (!node)
 | |
| +            errorString = "Missing node for given objectId"_s;
 | |
| +    } else
 | |
| +        errorString = "Either nodeId or objectId must be specified"_s;
 | |
| +    return node;
 | |
| +}
 | |
| +
 | |
|  Document* InspectorDOMAgent::assertDocument(Protocol::ErrorString& errorString, Protocol::DOM::NodeId nodeId)
 | |
|  {
 | |
|      Node* node = assertNode(errorString, nodeId);
 | |
| @@ -1408,16 +1429,7 @@ Protocol::ErrorStringOr<void> InspectorDOMAgent::highlightSelector(Ref<JSON::Obj
 | |
|  Protocol::ErrorStringOr<void> InspectorDOMAgent::highlightNode(Ref<JSON::Object>&& highlightInspectorObject, std::optional<Protocol::DOM::NodeId>&& nodeId, const Protocol::Runtime::RemoteObjectId& objectId)
 | |
|  {
 | |
|      Protocol::ErrorString errorString;
 | |
| -
 | |
| -    Node* node = nullptr;
 | |
| -    if (nodeId)
 | |
| -        node = assertNode(errorString, *nodeId);
 | |
| -    else if (!!objectId) {
 | |
| -        node = nodeForObjectId(objectId);
 | |
| -        errorString = "Missing node for given objectId"_s;
 | |
| -    } else
 | |
| -        errorString = "Either nodeId or objectId must be specified"_s;
 | |
| -
 | |
| +    Node* node = assertNode(errorString, WTFMove(nodeId), objectId);
 | |
|      if (!node)
 | |
|          return makeUnexpected(errorString);
 | |
|  
 | |
| @@ -1655,15 +1667,136 @@ Protocol::ErrorStringOr<void> InspectorDOMAgent::setInspectedNode(Protocol::DOM:
 | |
|      return { };
 | |
|  }
 | |
|  
 | |
| -Protocol::ErrorStringOr<Ref<Protocol::Runtime::RemoteObject>> InspectorDOMAgent::resolveNode(Protocol::DOM::NodeId nodeId, const String& objectGroup)
 | |
| +static FloatPoint contentsToRootView(FrameView& containingView, const FloatPoint& point)
 | |
|  {
 | |
| -    Protocol::ErrorString errorString;
 | |
| +    return containingView.convertToRootView(point - toFloatSize(containingView.documentScrollPositionRelativeToViewOrigin()));
 | |
| +}
 | |
|  
 | |
| -    Node* node = assertNode(errorString, nodeId);
 | |
| +static void frameQuadToViewport(FrameView& containingView, FloatQuad& quad, float pageScaleFactor)
 | |
| +{
 | |
| +    // Return css (not dip) coordinates by scaling back.
 | |
| +    quad.setP1(contentsToRootView(containingView, quad.p1()).scaled(1 / pageScaleFactor));
 | |
| +    quad.setP2(contentsToRootView(containingView, quad.p2()).scaled(1 / pageScaleFactor));
 | |
| +    quad.setP3(contentsToRootView(containingView, quad.p3()).scaled(1 / pageScaleFactor));
 | |
| +    quad.setP4(contentsToRootView(containingView, quad.p4()).scaled(1 / pageScaleFactor));
 | |
| +}
 | |
| +
 | |
| +static Ref<Inspector::Protocol::DOM::Quad> buildObjectForQuad(const FloatQuad& quad)
 | |
| +{
 | |
| +    auto result = Inspector::Protocol::DOM::Quad::create();
 | |
| +    result->addItem(quad.p1().x());
 | |
| +    result->addItem(quad.p1().y());
 | |
| +    result->addItem(quad.p2().x());
 | |
| +    result->addItem(quad.p2().y());
 | |
| +    result->addItem(quad.p3().x());
 | |
| +    result->addItem(quad.p3().y());
 | |
| +    result->addItem(quad.p4().x());
 | |
| +    result->addItem(quad.p4().y());
 | |
| +    return result;
 | |
| +}
 | |
| +
 | |
| +static Ref<JSON::ArrayOf<Inspector::Protocol::DOM::Quad>> buildArrayOfQuads(const Vector<FloatQuad>& quads)
 | |
| +{
 | |
| +    auto result = JSON::ArrayOf<Inspector::Protocol::DOM::Quad>::create();
 | |
| +    for (const auto& quad : quads)
 | |
| +        result->addItem(buildObjectForQuad(quad));
 | |
| +    return result;
 | |
| +}
 | |
| +
 | |
| +Inspector::Protocol::ErrorStringOr<std::tuple<String /* contentFrameId */, String /* ownerFrameId */>> InspectorDOMAgent::describeNode(const String& objectId)
 | |
| +{
 | |
| +    Node* node = nodeForObjectId(objectId);
 | |
| +    if (!node)
 | |
| +        return makeUnexpected("Node not found"_s);
 | |
| +
 | |
| +    auto* pageAgent = m_instrumentingAgents.enabledPageAgent();
 | |
| +    if (!pageAgent)
 | |
| +        return makeUnexpected("Page agent must be enabled"_s);
 | |
| +
 | |
| +    String ownerFrameId;
 | |
| +    String frameId = pageAgent->frameId(node->document().frame());
 | |
| +    if (!frameId.isEmpty())
 | |
| +        ownerFrameId = frameId;
 | |
| +
 | |
| +    String contentFrameId;
 | |
| +    if (is<HTMLFrameOwnerElement>(*node)) {
 | |
| +        const auto& frameOwner = downcast<HTMLFrameOwnerElement>(*node);
 | |
| +        String frameId = pageAgent->frameId(frameOwner.contentFrame());
 | |
| +        if (!frameId.isEmpty())
 | |
| +            contentFrameId = frameId;
 | |
| +    }
 | |
| +
 | |
| +    return { { contentFrameId, ownerFrameId } };
 | |
| +}
 | |
| +
 | |
| +Protocol::ErrorStringOr<void> InspectorDOMAgent::scrollIntoViewIfNeeded(const String& objectId, RefPtr<JSON::Object>&& rect)
 | |
| +{
 | |
| +    Node* node = nodeForObjectId(objectId);
 | |
| +    if (!node)
 | |
| +        return makeUnexpected("Node not found"_s);
 | |
| +
 | |
| +    m_inspectedPage.isolatedUpdateRendering();
 | |
| +    if (!node->isConnected())
 | |
| +        return makeUnexpected("Node is detached from document"_s);
 | |
| +
 | |
| +    RenderObject* renderer = node->renderer();
 | |
| +    if (!renderer)
 | |
| +        return makeUnexpected("Node does not have a layout object"_s);
 | |
| +
 | |
| +    bool insideFixed;
 | |
| +    LayoutRect absoluteBounds = renderer->absoluteBoundingBoxRect(true, &insideFixed);
 | |
| +    if (rect) {
 | |
| +        std::optional<double> x = rect->getDouble("x"_s);
 | |
| +        std::optional<double> y = rect->getDouble("y"_s);
 | |
| +        std::optional<double> width = rect->getDouble("width"_s);
 | |
| +        std::optional<double> height = rect->getDouble("height"_s);
 | |
| +        if (!x || !y || !width || !height)
 | |
| +            return makeUnexpected("Malformed rect"_s);
 | |
| +
 | |
| +        absoluteBounds.setX(absoluteBounds.x() + LayoutUnit(*x));
 | |
| +        absoluteBounds.setY(absoluteBounds.y() + LayoutUnit(*y));
 | |
| +        absoluteBounds.setWidth(LayoutUnit(std::max(*width, 1.0)));
 | |
| +        absoluteBounds.setHeight(LayoutUnit(std::max(*height, 1.0)));
 | |
| +    }
 | |
| +    ScrollAlignment alignment = ScrollAlignment::alignCenterIfNeeded;
 | |
| +    alignment.m_enableLegacyHorizontalVisibilityThreshold = false; // Disable RenderLayer minium horizontal scroll threshold.
 | |
| +    renderer->scrollRectToVisible(absoluteBounds, insideFixed, { SelectionRevealMode::Reveal, alignment, alignment, ShouldAllowCrossOriginScrolling::Yes, ScrollBehavior::Instant });
 | |
| +    return { };
 | |
| +}
 | |
| +
 | |
| +Protocol::ErrorStringOr<Ref<JSON::ArrayOf<Protocol::DOM::Quad>>> InspectorDOMAgent::getContentQuads(const String& objectId)
 | |
| +{
 | |
| +    Node* node = nodeForObjectId(objectId);
 | |
| +    if (!node)
 | |
| +        return makeUnexpected("Node not found"_s);
 | |
| +
 | |
| +    RenderObject* renderer = node->renderer();
 | |
| +    if (!renderer)
 | |
| +        return makeUnexpected("Node doesn't have renderer"_s);
 | |
| +
 | |
| +    // Ensure quads are up to date.
 | |
| +    m_inspectedPage.isolatedUpdateRendering();
 | |
| +
 | |
| +    Frame* containingFrame = renderer->document().frame();
 | |
| +    FrameView* containingView = containingFrame ? containingFrame->view() : nullptr;
 | |
| +    if (!containingView)
 | |
| +        return makeUnexpected("Internal error: no containing view"_s);
 | |
| +
 | |
| +    Vector<FloatQuad> quads;
 | |
| +    renderer->absoluteQuads(quads);
 | |
| +    for (auto& quad : quads)
 | |
| +        frameQuadToViewport(*containingView, quad, m_inspectedPage.pageScaleFactor());
 | |
| +    return buildArrayOfQuads(quads);
 | |
| +}
 | |
| +
 | |
| +Protocol::ErrorStringOr<Ref<Protocol::Runtime::RemoteObject>> InspectorDOMAgent::resolveNode(std::optional<Inspector::Protocol::DOM::NodeId>&& nodeId, const String& objectId, std::optional<int>&& contextId, const String& objectGroup)
 | |
| +{
 | |
| +    Protocol::ErrorString errorString;
 | |
| +    Node* node = assertNode(errorString, WTFMove(nodeId), objectId);
 | |
|      if (!node)
 | |
|          return makeUnexpected(errorString);
 | |
|  
 | |
| -    auto object = resolveNode(node, objectGroup);
 | |
| +    auto object = resolveNode(node, objectGroup, WTFMove(contextId));
 | |
|      if (!object)
 | |
|          return makeUnexpected("Missing injected script for given nodeId"_s);
 | |
|  
 | |
| @@ -2897,7 +3030,7 @@ Protocol::ErrorStringOr<Protocol::DOM::NodeId> InspectorDOMAgent::pushNodeByPath
 | |
|      return makeUnexpected("Missing node for given path"_s);
 | |
|  }
 | |
|  
 | |
| -RefPtr<Protocol::Runtime::RemoteObject> InspectorDOMAgent::resolveNode(Node* node, const String& objectGroup)
 | |
| +RefPtr<Inspector::Protocol::Runtime::RemoteObject> InspectorDOMAgent::resolveNode(Node* node, const String& objectGroup, std::optional<int>&& contextId)
 | |
|  {
 | |
|      Document* document = &node->document();
 | |
|      if (auto* templateHost = document->templateDocumentHost())
 | |
| @@ -2906,12 +3039,18 @@ RefPtr<Protocol::Runtime::RemoteObject> InspectorDOMAgent::resolveNode(Node* nod
 | |
|      if (!frame)
 | |
|          return nullptr;
 | |
|  
 | |
| -    auto& globalObject = mainWorldGlobalObject(*frame);
 | |
| -    auto injectedScript = m_injectedScriptManager.injectedScriptFor(&globalObject);
 | |
| +    InjectedScript injectedScript;
 | |
| +    if (contextId) {
 | |
| +        injectedScript = m_injectedScriptManager.injectedScriptForId(*contextId);
 | |
| +    } else {
 | |
| +        auto& globalObject = mainWorldGlobalObject(*frame);
 | |
| +        injectedScript = m_injectedScriptManager.injectedScriptFor(&globalObject);
 | |
| +    }
 | |
| +
 | |
|      if (injectedScript.hasNoValue())
 | |
|          return nullptr;
 | |
|  
 | |
| -    return injectedScript.wrapObject(nodeAsScriptValue(globalObject, node), objectGroup);
 | |
| +    return injectedScript.wrapObject(nodeAsScriptValue(*injectedScript.globalObject(), node), objectGroup);
 | |
|  }
 | |
|  
 | |
|  Node* InspectorDOMAgent::scriptValueAsNode(JSC::JSValue value)
 | |
| @@ -2934,4 +3073,57 @@ Protocol::ErrorStringOr<void> InspectorDOMAgent::setAllowEditingUserAgentShadowT
 | |
|      return { };
 | |
|  }
 | |
|  
 | |
| +Protocol::ErrorStringOr<void> InspectorDOMAgent::setInputFiles(const String& objectId, RefPtr<JSON::Array>&& files, RefPtr<JSON::Array>&& paths) {
 | |
| +    InjectedScript injectedScript = m_injectedScriptManager.injectedScriptForObjectId(objectId);
 | |
| +    if (injectedScript.hasNoValue())
 | |
| +        return makeUnexpected("Can not find element's context for given id"_s);
 | |
| +
 | |
| +    Node* node = scriptValueAsNode(injectedScript.findObjectById(objectId));
 | |
| +    if (!node)
 | |
| +        return makeUnexpected("Can not find element for given id"_s);
 | |
| +
 | |
| +    if (node->nodeType() != Node::ELEMENT_NODE || node->nodeName() != "INPUT")
 | |
| +        return makeUnexpected("Not an input node"_s);
 | |
| +
 | |
| +    if (!(bool(files) ^ bool(paths)))
 | |
| +        return makeUnexpected("Exactly one of files and paths should be specified"_s);
 | |
| +
 | |
| +    HTMLInputElement* element = static_cast<HTMLInputElement*>(node);
 | |
| +    Vector<Ref<File>> fileObjects;
 | |
| +    if (files) {
 | |
| +        for (unsigned i = 0; i < files->length(); ++i) {
 | |
| +            RefPtr<JSON::Value> item = files->get(i);
 | |
| +            RefPtr<JSON::Object> obj = item->asObject();
 | |
| +            if (!obj)
 | |
| +                return makeUnexpected("Invalid file payload format"_s);
 | |
| +
 | |
| +            String name;
 | |
| +            String type;
 | |
| +            String data;
 | |
| +            if (!obj->getString("name"_s, name) || !obj->getString("type"_s, type) || !obj->getString("data"_s, data))
 | |
| +                return makeUnexpected("Invalid file payload format"_s);
 | |
| +
 | |
| +            std::optional<Vector<uint8_t>> buffer = base64Decode(data);
 | |
| +            if (!buffer)
 | |
| +                return makeUnexpected("Unable to decode given content"_s);
 | |
| +
 | |
| +            ScriptExecutionContext* context = element->scriptExecutionContext();
 | |
| +            fileObjects.append(File::create(context, Blob::create(context, WTFMove(*buffer), type), name));
 | |
| +        }
 | |
| +    } else {
 | |
| +        for (unsigned i = 0; i < paths->length(); ++i) {
 | |
| +            RefPtr<JSON::Value> item = paths->get(i);
 | |
| +            String path = item->asString();
 | |
| +            if (path.isEmpty())
 | |
| +                return makeUnexpected("Invalid file path"_s);
 | |
| +
 | |
| +            ScriptExecutionContext* context = element->scriptExecutionContext();
 | |
| +            fileObjects.append(File::create(context, path));
 | |
| +        }
 | |
| +    }
 | |
| +    RefPtr<FileList> fileList = FileList::create(WTFMove(fileObjects));
 | |
| +    element->setFiles(WTFMove(fileList));
 | |
| +    return { };
 | |
| +}
 | |
| +
 | |
|  } // namespace WebCore
 | |
| diff --git a/Source/WebCore/inspector/agents/InspectorDOMAgent.h b/Source/WebCore/inspector/agents/InspectorDOMAgent.h
 | |
| index c503d5db51b75de57e3b09357f48f60470986da4..79947b44063d85951d2f6314c5cb78a54ab2d46e 100644
 | |
| --- a/Source/WebCore/inspector/agents/InspectorDOMAgent.h
 | |
| +++ b/Source/WebCore/inspector/agents/InspectorDOMAgent.h
 | |
| @@ -57,6 +57,7 @@ namespace WebCore {
 | |
|  
 | |
|  class AXCoreObject;
 | |
|  class CharacterData;
 | |
| +class Color;
 | |
|  class DOMEditor;
 | |
|  class Document;
 | |
|  class Element;
 | |
| @@ -89,6 +90,7 @@ public:
 | |
|      static String toErrorString(Exception&&);
 | |
|  
 | |
|      static String documentURLString(Document*);
 | |
| +    static std::optional<Color> parseColor(RefPtr<JSON::Object>&&);
 | |
|  
 | |
|      // We represent embedded doms as a part of the same hierarchy. Hence we treat children of frame owners differently.
 | |
|      // We also skip whitespace text nodes conditionally. Following methods encapsulate these specifics.
 | |
| @@ -132,7 +134,7 @@ public:
 | |
|      Inspector::Protocol::ErrorStringOr<std::tuple<String /* searchId */, int /* resultCount */>> performSearch(const String& query, RefPtr<JSON::Array>&& nodeIds, std::optional<bool>&& caseSensitive);
 | |
|      Inspector::Protocol::ErrorStringOr<Ref<JSON::ArrayOf<Inspector::Protocol::DOM::NodeId>>> getSearchResults(const String& searchId, int fromIndex, int toIndex);
 | |
|      Inspector::Protocol::ErrorStringOr<void> discardSearchResults(const String& searchId);
 | |
| -    Inspector::Protocol::ErrorStringOr<Ref<Inspector::Protocol::Runtime::RemoteObject>> resolveNode(Inspector::Protocol::DOM::NodeId, const String& objectGroup);
 | |
| +    Inspector::Protocol::ErrorStringOr<Ref<Inspector::Protocol::Runtime::RemoteObject>> resolveNode(std::optional<Inspector::Protocol::DOM::NodeId>&& nodeId, const String& objectId, std::optional<int>&& contextId, const String& objectGroup);
 | |
|      Inspector::Protocol::ErrorStringOr<Ref<JSON::ArrayOf<String>>> getAttributes(Inspector::Protocol::DOM::NodeId);
 | |
|  #if PLATFORM(IOS_FAMILY)
 | |
|      Inspector::Protocol::ErrorStringOr<void> setInspectModeEnabled(bool, RefPtr<JSON::Object>&& highlightConfig);
 | |
| @@ -159,6 +161,10 @@ public:
 | |
|      Inspector::Protocol::ErrorStringOr<void> focus(Inspector::Protocol::DOM::NodeId);
 | |
|      Inspector::Protocol::ErrorStringOr<void> setInspectedNode(Inspector::Protocol::DOM::NodeId);
 | |
|      Inspector::Protocol::ErrorStringOr<void> setAllowEditingUserAgentShadowTrees(bool);
 | |
| +    Inspector::Protocol::ErrorStringOr<std::tuple<String /* contentFrameId */, String /* ownerFrameId */>> describeNode(const String& objectId);
 | |
| +    Inspector::Protocol::ErrorStringOr<void> scrollIntoViewIfNeeded(const String& objectId, RefPtr<JSON::Object>&& rect);
 | |
| +    Inspector::Protocol::ErrorStringOr<Ref<JSON::ArrayOf<Inspector::Protocol::DOM::Quad>>> getContentQuads(const String& objectId);
 | |
| +    Inspector::Protocol::ErrorStringOr<void> setInputFiles(const String& objectId, RefPtr<JSON::Array>&& files, RefPtr<JSON::Array>&& paths);
 | |
|  
 | |
|      // InspectorInstrumentation
 | |
|      Inspector::Protocol::DOM::NodeId identifierForNode(Node&);
 | |
| @@ -200,7 +206,7 @@ public:
 | |
|      Node* nodeForId(Inspector::Protocol::DOM::NodeId);
 | |
|      Inspector::Protocol::DOM::NodeId boundNodeId(const Node*);
 | |
|  
 | |
| -    RefPtr<Inspector::Protocol::Runtime::RemoteObject> resolveNode(Node*, const String& objectGroup);
 | |
| +    RefPtr<Inspector::Protocol::Runtime::RemoteObject> resolveNode(Node*, const String& objectGroup, std::optional<int>&& contextId);
 | |
|      bool handleMousePress();
 | |
|      void mouseDidMoveOverElement(const HitTestResult&, unsigned modifierFlags);
 | |
|      void inspect(Node*);
 | |
| @@ -212,12 +218,15 @@ public:
 | |
|      void reset();
 | |
|  
 | |
|      Node* assertNode(Inspector::Protocol::ErrorString&, Inspector::Protocol::DOM::NodeId);
 | |
| +    Node* assertNode(Inspector::Protocol::ErrorString&, std::optional<Inspector::Protocol::DOM::NodeId>&& nodeId, const String& objectId);
 | |
|      Element* assertElement(Inspector::Protocol::ErrorString&, Inspector::Protocol::DOM::NodeId);
 | |
|      Document* assertDocument(Inspector::Protocol::ErrorString&, Inspector::Protocol::DOM::NodeId);
 | |
|  
 | |
|      RefPtr<JSC::Breakpoint> breakpointForEventListener(EventTarget&, const AtomString& eventType, EventListener&, bool capture);
 | |
|      Inspector::Protocol::DOM::EventListenerId idForEventListener(EventTarget&, const AtomString& eventType, EventListener&, bool capture);
 | |
|  
 | |
| +    Node* nodeForObjectId(const Inspector::Protocol::Runtime::RemoteObjectId&);
 | |
| +
 | |
|  private:
 | |
|  #if ENABLE(VIDEO)
 | |
|      void mediaMetricsTimerFired();
 | |
| @@ -245,7 +254,6 @@ private:
 | |
|      void processAccessibilityChildren(AXCoreObject&, JSON::ArrayOf<Inspector::Protocol::DOM::NodeId>&);
 | |
|      
 | |
|      Node* nodeForPath(const String& path);
 | |
| -    Node* nodeForObjectId(const Inspector::Protocol::Runtime::RemoteObjectId&);
 | |
|  
 | |
|      void discardBindings();
 | |
|  
 | |
| diff --git a/Source/WebCore/inspector/agents/InspectorNetworkAgent.cpp b/Source/WebCore/inspector/agents/InspectorNetworkAgent.cpp
 | |
| index a6601cae918cc76aab630e88c05acc445977169c..e1504bd2726889be47c4f5dfd0688743434b5562 100644
 | |
| --- a/Source/WebCore/inspector/agents/InspectorNetworkAgent.cpp
 | |
| +++ b/Source/WebCore/inspector/agents/InspectorNetworkAgent.cpp
 | |
| @@ -45,6 +45,7 @@
 | |
|  #include "DocumentThreadableLoader.h"
 | |
|  #include "FormData.h"
 | |
|  #include "Frame.h"
 | |
| +#include "FormData.h"
 | |
|  #include "FrameLoader.h"
 | |
|  #include "HTTPHeaderMap.h"
 | |
|  #include "HTTPHeaderNames.h"
 | |
| @@ -58,6 +59,7 @@
 | |
|  #include "MIMETypeRegistry.h"
 | |
|  #include "MemoryCache.h"
 | |
|  #include "NetworkResourcesData.h"
 | |
| +#include "NetworkStateNotifier.h"
 | |
|  #include "Page.h"
 | |
|  #include "PlatformStrategies.h"
 | |
|  #include "ProgressTracker.h"
 | |
| @@ -307,8 +309,8 @@ static Ref<Protocol::Network::Request> buildObjectForResourceRequest(const Resou
 | |
|          .setHeaders(buildObjectForHeaders(request.httpHeaderFields()))
 | |
|          .release();
 | |
|      if (request.httpBody() && !request.httpBody()->isEmpty()) {
 | |
| -        auto bytes = request.httpBody()->flatten();
 | |
| -        requestObject->setPostData(String::fromUTF8WithLatin1Fallback(bytes.data(), bytes.size()));
 | |
| +        Vector<uint8_t> bytes = request.httpBody()->flatten();
 | |
| +        requestObject->setPostData(base64EncodeToString(bytes));
 | |
|      }
 | |
|      return requestObject;
 | |
|  }
 | |
| @@ -353,6 +355,8 @@ RefPtr<Protocol::Network::Response> InspectorNetworkAgent::buildObjectForResourc
 | |
|          .setSource(responseSource(response.source()))
 | |
|          .release();
 | |
|  
 | |
| +    responseObject->setRequestHeaders(buildObjectForHeaders(response.m_httpRequestHeaderFields));
 | |
| +
 | |
|      if (resourceLoader) {
 | |
|          auto* metrics = response.deprecatedNetworkLoadMetricsOrNull();
 | |
|          responseObject->setTiming(buildObjectForTiming(metrics ? *metrics : NetworkLoadMetrics::emptyMetrics(), *resourceLoader));
 | |
| @@ -490,9 +494,15 @@ static InspectorPageAgent::ResourceType resourceTypeForLoadType(InspectorInstrum
 | |
|  
 | |
|  void InspectorNetworkAgent::willSendRequest(ResourceLoaderIdentifier identifier, DocumentLoader* loader, ResourceRequest& request, const ResourceResponse& redirectResponse, const CachedResource* cachedResource)
 | |
|  {
 | |
| -    if (!cachedResource && loader)
 | |
| -        cachedResource = InspectorPageAgent::cachedResource(loader->frame(), request.url());
 | |
| -    willSendRequest(identifier, loader, request, redirectResponse, resourceTypeForCachedResource(cachedResource));
 | |
| +    InspectorPageAgent::ResourceType resourceType;
 | |
| +    if (request.initiatorIdentifier() == initiatorIdentifierForEventSource()) {
 | |
| +        resourceType = InspectorPageAgent::EventSourceResource;
 | |
| +    } else {
 | |
| +        if (!cachedResource && loader)
 | |
| +            cachedResource = InspectorPageAgent::cachedResource(loader->frame(), request.url());
 | |
| +        resourceType = resourceTypeForCachedResource(cachedResource);
 | |
| +    }
 | |
| +    willSendRequest(identifier, loader, request, redirectResponse, resourceType);
 | |
|  }
 | |
|  
 | |
|  void InspectorNetworkAgent::willSendRequestOfType(ResourceLoaderIdentifier identifier, DocumentLoader* loader, ResourceRequest& request, InspectorInstrumentation::LoadType loadType)
 | |
| @@ -914,6 +924,7 @@ void InspectorNetworkAgent::continuePendingResponses()
 | |
|  
 | |
|  Protocol::ErrorStringOr<void> InspectorNetworkAgent::setExtraHTTPHeaders(Ref<JSON::Object>&& headers)
 | |
|  {
 | |
| +    m_extraRequestHeaders.clear();
 | |
|      for (auto& entry : headers.get()) {
 | |
|          auto stringValue = entry.value->asString();
 | |
|          if (!!stringValue)
 | |
| @@ -1194,6 +1205,9 @@ Protocol::ErrorStringOr<void> InspectorNetworkAgent::interceptWithRequest(const
 | |
|          return makeUnexpected("Missing pending intercept request for given requestId"_s);
 | |
|  
 | |
|      auto& loader = *pendingRequest->m_loader;
 | |
| +    if (loader.reachedTerminalState())
 | |
| +        return makeUnexpected("Unable to intercept request, it has already been processed"_s);
 | |
| +
 | |
|      ResourceRequest request = loader.request();
 | |
|      if (!!url)
 | |
|          request.setURL(URL({ }, url));
 | |
| @@ -1293,14 +1307,23 @@ Protocol::ErrorStringOr<void> InspectorNetworkAgent::interceptRequestWithRespons
 | |
|      response.setHTTPStatusCode(status);
 | |
|      response.setHTTPStatusText(AtomString { statusText });
 | |
|      HTTPHeaderMap explicitHeaders;
 | |
| +    String setCookieValue;
 | |
|      for (auto& header : headers.get()) {
 | |
|          auto headerValue = header.value->asString();
 | |
| -        if (!!headerValue)
 | |
| +        if (equalIgnoringASCIICase(header.key, "Set-Cookie"_s))
 | |
| +            setCookieValue = headerValue;
 | |
| +        else if (!!headerValue)
 | |
|              explicitHeaders.add(header.key, headerValue);
 | |
| +
 | |
|      }
 | |
|      response.setHTTPHeaderFields(WTFMove(explicitHeaders));
 | |
|      response.setHTTPHeaderField(HTTPHeaderName::ContentType, response.mimeType());
 | |
| -    loader->didReceiveResponse(response, [loader, buffer = data.releaseNonNull()]() {
 | |
| +
 | |
| +    auto* frame = loader->frame();
 | |
| +    if (!setCookieValue.isEmpty() && frame && frame->page())
 | |
| +        frame->page()->cookieJar().setCookieFromResponse(*loader.get(), setCookieValue);
 | |
| +
 | |
| +    loader->didReceiveResponse(response, [loader, buffer = data.releaseNonNull()]() mutable {
 | |
|          if (loader->reachedTerminalState())
 | |
|              return;
 | |
|  
 | |
| @@ -1348,6 +1371,12 @@ Protocol::ErrorStringOr<void> InspectorNetworkAgent::interceptRequestWithError(c
 | |
|      return { };
 | |
|  }
 | |
|  
 | |
| +Inspector::Protocol::ErrorStringOr<void> InspectorNetworkAgent::setEmulateOfflineState(bool offline)
 | |
| +{
 | |
| +    platformStrategies()->loaderStrategy()->setEmulateOfflineState(offline);
 | |
| +    return { };
 | |
| +}
 | |
| +
 | |
|  bool InspectorNetworkAgent::shouldTreatAsText(const String& mimeType)
 | |
|  {
 | |
|      return startsWithLettersIgnoringASCIICase(mimeType, "text/"_s)
 | |
| @@ -1389,6 +1418,12 @@ std::optional<String> InspectorNetworkAgent::textContentForCachedResource(Cached
 | |
|      return std::nullopt;
 | |
|  }
 | |
|  
 | |
| +// static
 | |
| +String InspectorNetworkAgent::initiatorIdentifierForEventSource()
 | |
| +{
 | |
| +    return "InspectorNetworkAgent: eventSource"_s;
 | |
| +}
 | |
| +
 | |
|  bool InspectorNetworkAgent::cachedResourceContent(CachedResource& resource, String* result, bool* base64Encoded)
 | |
|  {
 | |
|      ASSERT(result);
 | |
| diff --git a/Source/WebCore/inspector/agents/InspectorNetworkAgent.h b/Source/WebCore/inspector/agents/InspectorNetworkAgent.h
 | |
| index 1a4779cbc9f388434295a94fd9da566d6ff4e3f7..9703d8b8c30845f750813f9666b0998f27cf1338 100644
 | |
| --- a/Source/WebCore/inspector/agents/InspectorNetworkAgent.h
 | |
| +++ b/Source/WebCore/inspector/agents/InspectorNetworkAgent.h
 | |
| @@ -34,6 +34,8 @@
 | |
|  #include "InspectorInstrumentation.h"
 | |
|  #include "InspectorPageAgent.h"
 | |
|  #include "InspectorWebAgentBase.h"
 | |
| +#include "ResourceError.h"
 | |
| +#include "SharedBuffer.h"
 | |
|  #include "WebSocket.h"
 | |
|  #include <JavaScriptCore/InspectorBackendDispatchers.h>
 | |
|  #include <JavaScriptCore/InspectorFrontendDispatchers.h>
 | |
| @@ -76,6 +78,7 @@ public:
 | |
|      static Ref<TextResourceDecoder> createTextDecoder(const String& mimeType, const String& textEncodingName);
 | |
|      static std::optional<String> textContentForCachedResource(CachedResource&);
 | |
|      static bool cachedResourceContent(CachedResource&, String* result, bool* base64Encoded);
 | |
| +    static String initiatorIdentifierForEventSource();
 | |
|  
 | |
|      // InspectorAgentBase
 | |
|      void didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*) final;
 | |
| @@ -98,6 +101,7 @@ public:
 | |
|      Inspector::Protocol::ErrorStringOr<void> interceptWithResponse(const Inspector::Protocol::Network::RequestId&, const String& content, bool base64Encoded, const String& mimeType, std::optional<int>&& status, const String& statusText, RefPtr<JSON::Object>&& headers) final;
 | |
|      Inspector::Protocol::ErrorStringOr<void> interceptRequestWithResponse(const Inspector::Protocol::Network::RequestId&, const String& content, bool base64Encoded, const String& mimeType, int status, const String& statusText, Ref<JSON::Object>&& headers) final;
 | |
|      Inspector::Protocol::ErrorStringOr<void> interceptRequestWithError(const Inspector::Protocol::Network::RequestId&, Inspector::Protocol::Network::ResourceErrorType) final;
 | |
| +    Inspector::Protocol::ErrorStringOr<void> setEmulateOfflineState(bool offline) final;
 | |
|  
 | |
|      // InspectorInstrumentation
 | |
|      void willRecalculateStyle();
 | |
| diff --git a/Source/WebCore/inspector/agents/InspectorPageAgent.cpp b/Source/WebCore/inspector/agents/InspectorPageAgent.cpp
 | |
| index 258429e97b12ddf52aa2d23b1dd541a5ddcf532f..e5be0d69facff68cef5311f4fd2ca4b68aa1c660 100644
 | |
| --- a/Source/WebCore/inspector/agents/InspectorPageAgent.cpp
 | |
| +++ b/Source/WebCore/inspector/agents/InspectorPageAgent.cpp
 | |
| @@ -32,20 +32,28 @@
 | |
|  #include "config.h"
 | |
|  #include "InspectorPageAgent.h"
 | |
|  
 | |
| +#include "AXObjectCache.h"
 | |
| +#include "BackForwardController.h"
 | |
|  #include "CachedResource.h"
 | |
|  #include "CachedResourceLoader.h"
 | |
| +#include "CompositionHighlight.h"
 | |
|  #include "Cookie.h"
 | |
|  #include "CookieJar.h"
 | |
| +#include "CustomHeaderFields.h"
 | |
|  #include "DOMWrapperWorld.h"
 | |
|  #include "DocumentInlines.h"
 | |
|  #include "DocumentLoader.h"
 | |
| +#include "Editor.h"
 | |
|  #include "ElementInlines.h"
 | |
| +#include "FocusController.h"
 | |
|  #include "Frame.h"
 | |
|  #include "FrameLoadRequest.h"
 | |
|  #include "FrameLoader.h"
 | |
| +#include "FrameLoaderClient.h"
 | |
|  #include "FrameSnapshotting.h"
 | |
|  #include "FrameView.h"
 | |
|  #include "HTMLFrameOwnerElement.h"
 | |
| +#include "HTMLInputElement.h"
 | |
|  #include "HTMLNames.h"
 | |
|  #include "ImageBuffer.h"
 | |
|  #include "InspectorClient.h"
 | |
| @@ -56,19 +64,29 @@
 | |
|  #include "MIMETypeRegistry.h"
 | |
|  #include "MemoryCache.h"
 | |
|  #include "Page.h"
 | |
| +#include "PageRuntimeAgent.h"
 | |
|  #include "RenderObject.h"
 | |
|  #include "RenderTheme.h"
 | |
| +#include "RuntimeEnabledFeatures.h"
 | |
| +#include "SimpleRange.h"
 | |
|  #include "ScriptController.h"
 | |
|  #include "ScriptSourceCode.h"
 | |
|  #include "SecurityOrigin.h"
 | |
|  #include "Settings.h"
 | |
|  #include "StyleScope.h"
 | |
|  #include <pal/text/TextEncoding.h>
 | |
| +#include "TextIterator.h"
 | |
| +#include "TypingCommand.h"
 | |
|  #include "UserGestureIndicator.h"
 | |
|  #include <JavaScriptCore/ContentSearchUtilities.h>
 | |
|  #include <JavaScriptCore/IdentifiersFactory.h>
 | |
| +#include <JavaScriptCore/InjectedScriptManager.h>
 | |
|  #include <JavaScriptCore/RegularExpression.h>
 | |
| +#include <wtf/DateMath.h>
 | |
|  #include <wtf/ListHashSet.h>
 | |
| +#include <wtf/NeverDestroyed.h>
 | |
| +#include <wtf/Ref.h>
 | |
| +#include <wtf/RefPtr.h>
 | |
|  #include <wtf/Stopwatch.h>
 | |
|  #include <wtf/text/Base64.h>
 | |
|  #include <wtf/text/StringBuilder.h>
 | |
| @@ -81,11 +99,15 @@
 | |
|  #include "LegacyWebArchive.h"
 | |
|  #endif
 | |
|  
 | |
| -
 | |
|  namespace WebCore {
 | |
|  
 | |
|  using namespace Inspector;
 | |
|  
 | |
| +static HashMap<String, Ref<DOMWrapperWorld>>& createdUserWorlds() {
 | |
| +    static NeverDestroyed<HashMap<String, Ref<DOMWrapperWorld>>> nameToWorld;
 | |
| +    return nameToWorld;
 | |
| +}
 | |
| +
 | |
|  static bool decodeBuffer(const uint8_t* buffer, unsigned size, const String& textEncodingName, String* result)
 | |
|  {
 | |
|      if (buffer) {
 | |
| @@ -326,6 +348,7 @@ InspectorPageAgent::InspectorPageAgent(PageAgentContext& context, InspectorClien
 | |
|      , m_frontendDispatcher(makeUnique<Inspector::PageFrontendDispatcher>(context.frontendRouter))
 | |
|      , m_backendDispatcher(Inspector::PageBackendDispatcher::create(context.backendDispatcher, this))
 | |
|      , m_inspectedPage(context.inspectedPage)
 | |
| +    , m_injectedScriptManager(context.injectedScriptManager)
 | |
|      , m_client(client)
 | |
|      , m_overlay(overlay)
 | |
|  {
 | |
| @@ -357,12 +380,20 @@ Protocol::ErrorStringOr<void> InspectorPageAgent::enable()
 | |
|      defaultAppearanceDidChange(m_inspectedPage.defaultUseDarkAppearance());
 | |
|  #endif
 | |
|  
 | |
| +    if (!createdUserWorlds().isEmpty()) {
 | |
| +        Vector<DOMWrapperWorld*> worlds;
 | |
| +        for (const auto& world : createdUserWorlds().values())
 | |
| +            worlds.append(world.ptr());
 | |
| +        ensureUserWorldsExistInAllFrames(worlds);
 | |
| +    }
 | |
|      return { };
 | |
|  }
 | |
|  
 | |
|  Protocol::ErrorStringOr<void> InspectorPageAgent::disable()
 | |
|  {
 | |
|      m_instrumentingAgents.setEnabledPageAgent(nullptr);
 | |
| +    m_interceptFileChooserDialog = false;
 | |
| +    m_bypassCSP = false;
 | |
|  
 | |
|      setShowPaintRects(false);
 | |
|  #if !PLATFORM(IOS_FAMILY)
 | |
| @@ -411,6 +442,22 @@ Protocol::ErrorStringOr<void> InspectorPageAgent::reload(std::optional<bool>&& i
 | |
|      return { };
 | |
|  }
 | |
|  
 | |
| +Protocol::ErrorStringOr<void> InspectorPageAgent::goBack()
 | |
| +{
 | |
| +    if (!m_inspectedPage.backForward().goBack())
 | |
| +        return makeUnexpected("Failed to go back"_s);
 | |
| +
 | |
| +    return { };
 | |
| +}
 | |
| +
 | |
| +Protocol::ErrorStringOr<void> InspectorPageAgent::goForward()
 | |
| +{
 | |
| +    if (!m_inspectedPage.backForward().goForward())
 | |
| +        return makeUnexpected("Failed to go forward"_s);
 | |
| +
 | |
| +    return { };
 | |
| +}
 | |
| +
 | |
|  Protocol::ErrorStringOr<void> InspectorPageAgent::navigate(const String& url)
 | |
|  {
 | |
|      Frame& frame = m_inspectedPage.mainFrame();
 | |
| @@ -432,6 +479,13 @@ Protocol::ErrorStringOr<void> InspectorPageAgent::overrideUserAgent(const String
 | |
|      return { };
 | |
|  }
 | |
|  
 | |
| +Protocol::ErrorStringOr<void> InspectorPageAgent::overridePlatform(const String& value)
 | |
| +{
 | |
| +    m_platformOverride = value;
 | |
| +
 | |
| +    return { };
 | |
| +}
 | |
| +
 | |
|  Protocol::ErrorStringOr<void> InspectorPageAgent::overrideSetting(Protocol::Page::Setting setting, std::optional<bool>&& value)
 | |
|  {
 | |
|      auto& inspectedPageSettings = m_inspectedPage.settings();
 | |
| @@ -445,6 +499,12 @@ Protocol::ErrorStringOr<void> InspectorPageAgent::overrideSetting(Protocol::Page
 | |
|          inspectedPageSettings.setAuthorAndUserStylesEnabledInspectorOverride(value);
 | |
|          return { };
 | |
|  
 | |
| +#if ENABLE(DEVICE_ORIENTATION)
 | |
| +    case Protocol::Page::Setting::DeviceOrientationEventEnabled:
 | |
| +        inspectedPageSettings.setDeviceOrientationEventEnabled(value.value_or(false));
 | |
| +        return { };
 | |
| +#endif
 | |
| +
 | |
|      case Protocol::Page::Setting::ICECandidateFilteringEnabled:
 | |
|          inspectedPageSettings.setICECandidateFilteringEnabledInspectorOverride(value);
 | |
|          return { };
 | |
| @@ -470,6 +530,36 @@ Protocol::ErrorStringOr<void> InspectorPageAgent::overrideSetting(Protocol::Page
 | |
|          inspectedPageSettings.setNeedsSiteSpecificQuirksInspectorOverride(value);
 | |
|          return { };
 | |
|  
 | |
| +#if ENABLE(NOTIFICATIONS)
 | |
| +    case Protocol::Page::Setting::NotificationsEnabled:
 | |
| +        inspectedPageSettings.setNotificationsEnabled(value.value_or(false));
 | |
| +        return { };
 | |
| +#endif
 | |
| +
 | |
| +#if ENABLE(FULLSCREEN_API)
 | |
| +    case Protocol::Page::Setting::FullScreenEnabled:
 | |
| +        inspectedPageSettings.setFullScreenEnabled(value.value_or(false));
 | |
| +        return { };
 | |
| +#endif
 | |
| +
 | |
| +#if ENABLE(INPUT_TYPE_MONTH)
 | |
| +    case Protocol::Page::Setting::InputTypeMonthEnabled:
 | |
| +        inspectedPageSettings.setInputTypeMonthEnabled(value.value_or(false));
 | |
| +        return { };
 | |
| +#endif
 | |
| +
 | |
| +#if ENABLE(INPUT_TYPE_WEEK)
 | |
| +    case Protocol::Page::Setting::InputTypeWeekEnabled:
 | |
| +        inspectedPageSettings.setInputTypeWeekEnabled(value.value_or(false));
 | |
| +        return { };
 | |
| +#endif
 | |
| +
 | |
| +#if ENABLE(POINTER_LOCK)
 | |
| +    case Protocol::Page::Setting::PointerLockEnabled:
 | |
| +        inspectedPageSettings.setPointerLockEnabled(value.value_or(false));
 | |
| +        return { };
 | |
| +#endif
 | |
| +
 | |
|      case Protocol::Page::Setting::ScriptEnabled:
 | |
|          inspectedPageSettings.setScriptEnabledInspectorOverride(value);
 | |
|          return { };
 | |
| @@ -482,6 +572,12 @@ Protocol::ErrorStringOr<void> InspectorPageAgent::overrideSetting(Protocol::Page
 | |
|          inspectedPageSettings.setShowRepaintCounterInspectorOverride(value);
 | |
|          return { };
 | |
|  
 | |
| +#if ENABLE(MEDIA_STREAM)
 | |
| +    case Protocol::Page::Setting::SpeechRecognitionEnabled:
 | |
| +        inspectedPageSettings.setSpeechRecognitionEnabled(value.value_or(false));
 | |
| +        return { };
 | |
| +#endif
 | |
| +
 | |
|      case Protocol::Page::Setting::WebRTCEncryptionEnabled:
 | |
|          inspectedPageSettings.setWebRTCEncryptionEnabledInspectorOverride(value);
 | |
|          return { };
 | |
| @@ -702,9 +798,13 @@ Protocol::ErrorStringOr<std::tuple<String, bool /* base64Encoded */>> InspectorP
 | |
|      return { { content, base64Encoded } };
 | |
|  }
 | |
|  
 | |
| -Protocol::ErrorStringOr<void> InspectorPageAgent::setBootstrapScript(const String& source)
 | |
| +Protocol::ErrorStringOr<void> InspectorPageAgent::setBootstrapScript(const String& source, const String& worldName)
 | |
|  {
 | |
| -    m_bootstrapScript = source;
 | |
| +    String key = worldName.isNull() ? emptyString() : worldName;
 | |
| +    if (source.isEmpty())
 | |
| +        m_worldNameToBootstrapScript.remove(key);
 | |
| +    else
 | |
| +        m_worldNameToBootstrapScript.set(key, source);
 | |
|  
 | |
|      return { };
 | |
|  }
 | |
| @@ -807,15 +907,16 @@ Protocol::ErrorStringOr<void> InspectorPageAgent::setShowPaintRects(bool show)
 | |
|      return { };
 | |
|  }
 | |
|  
 | |
| -void InspectorPageAgent::domContentEventFired()
 | |
| +void InspectorPageAgent::domContentEventFired(Frame& frame)
 | |
|  {
 | |
| -    m_isFirstLayoutAfterOnLoad = true;
 | |
| -    m_frontendDispatcher->domContentEventFired(timestamp());
 | |
| +    if (frame.isMainFrame())
 | |
| +        m_isFirstLayoutAfterOnLoad = true;
 | |
| +    m_frontendDispatcher->domContentEventFired(timestamp(), frameId(&frame));
 | |
|  }
 | |
|  
 | |
| -void InspectorPageAgent::loadEventFired()
 | |
| +void InspectorPageAgent::loadEventFired(Frame& frame)
 | |
|  {
 | |
| -    m_frontendDispatcher->loadEventFired(timestamp());
 | |
| +    m_frontendDispatcher->loadEventFired(timestamp(), frameId(&frame));
 | |
|  }
 | |
|  
 | |
|  void InspectorPageAgent::frameNavigated(Frame& frame)
 | |
| @@ -823,13 +924,23 @@ void InspectorPageAgent::frameNavigated(Frame& frame)
 | |
|      m_frontendDispatcher->frameNavigated(buildObjectForFrame(&frame));
 | |
|  }
 | |
|  
 | |
| +String InspectorPageAgent::makeFrameID(ProcessIdentifier processID,  FrameIdentifier frameID)
 | |
| +{
 | |
| +    return makeString(processID.toUInt64(), ".", frameID.toUInt64());
 | |
| +}
 | |
| +
 | |
| +static String globalIDForFrame(Frame& frame)
 | |
| +{
 | |
| +    return InspectorPageAgent::makeFrameID(Process::identifier(), *frame.loader().client().frameID());
 | |
| +}
 | |
| +
 | |
|  void InspectorPageAgent::frameDetached(Frame& frame)
 | |
|  {
 | |
| -    auto identifier = m_frameToIdentifier.take(&frame);
 | |
| -    if (identifier.isNull())
 | |
| +    String identifier = globalIDForFrame(frame);
 | |
| +    if (!m_identifierToFrame.take(identifier))
 | |
|          return;
 | |
| +
 | |
|      m_frontendDispatcher->frameDetached(identifier);
 | |
| -    m_identifierToFrame.remove(identifier);
 | |
|  }
 | |
|  
 | |
|  Frame* InspectorPageAgent::frameForId(const Protocol::Network::FrameId& frameId)
 | |
| @@ -841,20 +952,18 @@ String InspectorPageAgent::frameId(Frame* frame)
 | |
|  {
 | |
|      if (!frame)
 | |
|          return emptyString();
 | |
| -    return m_frameToIdentifier.ensure(frame, [this, frame] {
 | |
| -        auto identifier = IdentifiersFactory::createIdentifier();
 | |
| -        m_identifierToFrame.set(identifier, frame);
 | |
| -        return identifier;
 | |
| -    }).iterator->value;
 | |
| +
 | |
| +    String identifier = globalIDForFrame(*frame);
 | |
| +    m_identifierToFrame.set(identifier, frame);
 | |
| +    return identifier;
 | |
|  }
 | |
|  
 | |
|  String InspectorPageAgent::loaderId(DocumentLoader* loader)
 | |
|  {
 | |
|      if (!loader)
 | |
|          return emptyString();
 | |
| -    return m_loaderToIdentifier.ensure(loader, [] {
 | |
| -        return IdentifiersFactory::createIdentifier();
 | |
| -    }).iterator->value;
 | |
| +
 | |
| +    return String::number(loader->loaderIDForInspector());
 | |
|  }
 | |
|  
 | |
|  Frame* InspectorPageAgent::assertFrame(Protocol::ErrorString& errorString, const Protocol::Network::FrameId& frameId)
 | |
| @@ -865,11 +974,6 @@ Frame* InspectorPageAgent::assertFrame(Protocol::ErrorString& errorString, const
 | |
|      return frame;
 | |
|  }
 | |
|  
 | |
| -void InspectorPageAgent::loaderDetachedFromFrame(DocumentLoader& loader)
 | |
| -{
 | |
| -    m_loaderToIdentifier.remove(&loader);
 | |
| -}
 | |
| -
 | |
|  void InspectorPageAgent::frameStartedLoading(Frame& frame)
 | |
|  {
 | |
|      m_frontendDispatcher->frameStartedLoading(frameId(&frame));
 | |
| @@ -890,6 +994,12 @@ void InspectorPageAgent::frameClearedScheduledNavigation(Frame& frame)
 | |
|      m_frontendDispatcher->frameClearedScheduledNavigation(frameId(&frame));
 | |
|  }
 | |
|  
 | |
| +void InspectorPageAgent::didNavigateWithinPage(Frame& frame)
 | |
| +{
 | |
| +    String url = frame.document()->url().string();
 | |
| +    m_frontendDispatcher->navigatedWithinDocument(frameId(&frame), url);
 | |
| +}
 | |
| +
 | |
|  #if ENABLE(DARK_MODE_CSS) || HAVE(OS_DARK_MODE_SUPPORT)
 | |
|  void InspectorPageAgent::defaultAppearanceDidChange(bool useDarkAppearance)
 | |
|  {
 | |
| @@ -899,13 +1009,22 @@ void InspectorPageAgent::defaultAppearanceDidChange(bool useDarkAppearance)
 | |
|  
 | |
|  void InspectorPageAgent::didClearWindowObjectInWorld(Frame& frame, DOMWrapperWorld& world)
 | |
|  {
 | |
| -    if (&world != &mainThreadNormalWorld())
 | |
| +    if (m_worldNameToBootstrapScript.isEmpty())
 | |
|          return;
 | |
|  
 | |
| -    if (m_bootstrapScript.isEmpty())
 | |
| +    if (world.name().isEmpty() && &world != &mainThreadNormalWorld())
 | |
| +       return;
 | |
| +
 | |
| +    String worldName = world.name();
 | |
| +    // Null string cannot be used as a key.
 | |
| +    if (worldName.isNull())
 | |
| +        worldName = emptyString();
 | |
| +
 | |
| +    if (!m_worldNameToBootstrapScript.contains(worldName))
 | |
|          return;
 | |
|  
 | |
| -    frame.script().evaluateIgnoringException(ScriptSourceCode(m_bootstrapScript, URL { "web-inspector://bootstrap.js"_str }));
 | |
| +    String bootstrapScript = m_worldNameToBootstrapScript.get(worldName);
 | |
| +    frame.script().evaluateInWorldIgnoringException(ScriptSourceCode(bootstrapScript, URL { "web-inspector://bootstrap.js"_str }), world);
 | |
|  }
 | |
|  
 | |
|  void InspectorPageAgent::didPaint(RenderObject& renderer, const LayoutRect& rect)
 | |
| @@ -949,6 +1068,52 @@ void InspectorPageAgent::didRecalculateStyle()
 | |
|      m_overlay->update();
 | |
|  }
 | |
|  
 | |
| +void InspectorPageAgent::runOpenPanel(HTMLInputElement* element, bool* intercept)
 | |
| +{
 | |
| +    if (m_interceptFileChooserDialog) {
 | |
| +        *intercept = true;
 | |
| +    } else {
 | |
| +        return;
 | |
| +    }
 | |
| +    Document& document = element->document();
 | |
| +    auto* frame =  document.frame();
 | |
| +    if (!frame)
 | |
| +        return;
 | |
| +
 | |
| +    auto& globalObject = mainWorldGlobalObject(*frame);
 | |
| +    auto injectedScript = m_injectedScriptManager.injectedScriptFor(&globalObject);
 | |
| +    if (injectedScript.hasNoValue())
 | |
| +        return;
 | |
| +
 | |
| +    auto object = injectedScript.wrapObject(InspectorDOMAgent::nodeAsScriptValue(globalObject, element), WTF::String());
 | |
| +    if (!object)
 | |
| +        return;
 | |
| +
 | |
| +    m_frontendDispatcher->fileChooserOpened(frameId(frame), object.releaseNonNull());
 | |
| +}
 | |
| +
 | |
| +void InspectorPageAgent::frameAttached(Frame& frame)
 | |
| +{
 | |
| +    Frame* parent = frame.tree().parent();
 | |
| +    String parentFrameId = frameId(parent);
 | |
| +    m_frontendDispatcher->frameAttached(frameId(&frame), parentFrameId);
 | |
| +}
 | |
| +
 | |
| +bool InspectorPageAgent::shouldBypassCSP()
 | |
| +{
 | |
| +    return m_bypassCSP;
 | |
| +}
 | |
| +
 | |
| +void InspectorPageAgent::willCheckNavigationPolicy(Frame& frame)
 | |
| +{
 | |
| +    m_frontendDispatcher->willCheckNavigationPolicy(frameId(&frame));
 | |
| +}
 | |
| +
 | |
| +void InspectorPageAgent::didCheckNavigationPolicy(Frame& frame, bool cancel)
 | |
| +{
 | |
| +    m_frontendDispatcher->didCheckNavigationPolicy(frameId(&frame), cancel);
 | |
| +}
 | |
| +
 | |
|  Ref<Protocol::Page::Frame> InspectorPageAgent::buildObjectForFrame(Frame* frame)
 | |
|  {
 | |
|      ASSERT_ARG(frame, frame);
 | |
| @@ -1062,6 +1227,12 @@ void InspectorPageAgent::applyUserAgentOverride(String& userAgent)
 | |
|          userAgent = m_userAgentOverride;
 | |
|  }
 | |
|  
 | |
| +void InspectorPageAgent::applyPlatformOverride(String& platform)
 | |
| +{
 | |
| +    if (!m_platformOverride.isEmpty())
 | |
| +        platform = m_platformOverride;
 | |
| +}
 | |
| +
 | |
|  void InspectorPageAgent::applyEmulatedMedia(String& media)
 | |
|  {
 | |
|      if (!m_emulatedMedia.isEmpty())
 | |
| @@ -1085,11 +1256,13 @@ Protocol::ErrorStringOr<String> InspectorPageAgent::snapshotNode(Protocol::DOM::
 | |
|      return snapshot->toDataURL("image/png"_s, std::nullopt, PreserveResolution::Yes);
 | |
|  }
 | |
|  
 | |
| -Protocol::ErrorStringOr<String> InspectorPageAgent::snapshotRect(int x, int y, int width, int height, Protocol::Page::CoordinateSystem coordinateSystem)
 | |
| +Protocol::ErrorStringOr<String> InspectorPageAgent::snapshotRect(int x, int y, int width, int height, Protocol::Page::CoordinateSystem coordinateSystem, std::optional<bool>&& omitDeviceScaleFactor)
 | |
|  {
 | |
|      SnapshotOptions options { { }, PixelFormat::BGRA8, DestinationColorSpace::SRGB() };
 | |
|      if (coordinateSystem == Protocol::Page::CoordinateSystem::Viewport)
 | |
|          options.flags.add(SnapshotFlags::InViewCoordinates);
 | |
| +    if (omitDeviceScaleFactor.has_value() && *omitDeviceScaleFactor)
 | |
| +        options.flags.add(SnapshotFlags::OmitDeviceScaleFactor);
 | |
|  
 | |
|      IntRect rectangle(x, y, width, height);
 | |
|      auto snapshot = snapshotFrameRect(m_inspectedPage.mainFrame(), rectangle, WTFMove(options));
 | |
| @@ -1100,6 +1273,47 @@ Protocol::ErrorStringOr<String> InspectorPageAgent::snapshotRect(int x, int y, i
 | |
|      return snapshot->toDataURL("image/png"_s, std::nullopt, PreserveResolution::Yes);
 | |
|  }
 | |
|  
 | |
| +Protocol::ErrorStringOr<void> InspectorPageAgent::setForcedReducedMotion(std::optional<Protocol::Page::ReducedMotion>&& reducedMotion)
 | |
| +{
 | |
| +    if (!reducedMotion) {
 | |
| +        m_inspectedPage.setUseReducedMotionOverride(std::nullopt);
 | |
| +        return { };
 | |
| +    }
 | |
| +
 | |
| +    switch (*reducedMotion) {
 | |
| +        case Protocol::Page::ReducedMotion::Reduce:
 | |
| +            m_inspectedPage.setUseReducedMotionOverride(true);
 | |
| +            return { };
 | |
| +        case Protocol::Page::ReducedMotion::NoPreference:
 | |
| +            m_inspectedPage.setUseReducedMotionOverride(false);
 | |
| +            return { };
 | |
| +    }
 | |
| +
 | |
| +    ASSERT_NOT_REACHED();
 | |
| +    return { };
 | |
| +}
 | |
| +
 | |
| +Protocol::ErrorStringOr<void> InspectorPageAgent::setTimeZone(const String& timeZone)
 | |
| +{
 | |
| +    bool success = WTF::setTimeZoneOverride(timeZone);
 | |
| +    if (!success)
 | |
| +        return makeUnexpected("Invalid time zone " + timeZone);
 | |
| +
 | |
| +    return { };
 | |
| +}
 | |
| +
 | |
| +Protocol::ErrorStringOr<void> InspectorPageAgent::setTouchEmulationEnabled(bool enabled)
 | |
| +{
 | |
| +#if ENABLE(TOUCH_EVENTS)
 | |
| +    RuntimeEnabledFeatures::sharedFeatures().setTouchEventsEnabled(enabled);
 | |
| +    return { };
 | |
| +#else
 | |
| +    UNUSED_PARAM(enabled);
 | |
| +    return makeUnexpected("Not supported"_s);
 | |
| +#endif
 | |
| +}
 | |
| +
 | |
| +
 | |
|  #if ENABLE(WEB_ARCHIVE) && USE(CF)
 | |
|  Protocol::ErrorStringOr<String> InspectorPageAgent::archive()
 | |
|  {
 | |
| @@ -1112,7 +1326,6 @@ Protocol::ErrorStringOr<String> InspectorPageAgent::archive()
 | |
|  }
 | |
|  #endif
 | |
|  
 | |
| -#if !PLATFORM(COCOA)
 | |
|  Protocol::ErrorStringOr<void> InspectorPageAgent::setScreenSizeOverride(std::optional<int>&& width, std::optional<int>&& height)
 | |
|  {
 | |
|      if (width.has_value() != height.has_value())
 | |
| @@ -1127,6 +1340,630 @@ Protocol::ErrorStringOr<void> InspectorPageAgent::setScreenSizeOverride(std::opt
 | |
|      m_inspectedPage.mainFrame().setOverrideScreenSize(FloatSize(width.value_or(0), height.value_or(0)));
 | |
|      return { };
 | |
|  }
 | |
| +
 | |
| +Protocol::ErrorStringOr<void> InspectorPageAgent::insertText(const String& text)
 | |
| +{
 | |
| +    UserGestureIndicator indicator { ProcessingUserGesture };
 | |
| +    Frame& frame = m_inspectedPage.focusController().focusedOrMainFrame();
 | |
| +
 | |
| +    if (frame.editor().hasComposition()) {
 | |
| +        frame.editor().confirmComposition(text);
 | |
| +    } else {
 | |
| +        Document* focusedDocument = frame.document();
 | |
| +        TypingCommand::insertText(*focusedDocument, text, 0);
 | |
| +    }
 | |
| +    return { };
 | |
| +}
 | |
| +
 | |
| +Protocol::ErrorStringOr<void> InspectorPageAgent::setComposition(const String& text, int selectionStart, int selectionLength, std::optional<int>&& replacementStart, std::optional<int>&& replacementLength)
 | |
| +{
 | |
| +    Frame& frame = m_inspectedPage.focusController().focusedOrMainFrame();
 | |
| +
 | |
| +    UserGestureIndicator indicator { ProcessingUserGesture };
 | |
| +
 | |
| +    if (!frame.selection().selection().isContentEditable())
 | |
| +        return { };
 | |
| +    if (replacementStart) {
 | |
| +        WebCore::CharacterRange range { static_cast<uint64_t>(*replacementStart), replacementLength ? static_cast<uint64_t>(*replacementLength) : 0 };
 | |
| +        auto* element = frame.selection().rootEditableElementOrDocumentElement();
 | |
| +        if (element)
 | |
| +            frame.selection().setSelection(VisibleSelection(resolveCharacterRange(makeRangeSelectingNodeContents(*element), range)));
 | |
| +    }
 | |
| +    frame.editor().setComposition(text, { }, { }, static_cast<uint64_t>(selectionStart), selectionStart + selectionLength);
 | |
| +    return { };
 | |
| +}
 | |
| +
 | |
| +static String roleFromObject(RefPtr<AXCoreObject> axObject)
 | |
| +{
 | |
| +    String computedRoleString = axObject->computedRoleString();
 | |
| +    if (!computedRoleString.isEmpty())
 | |
| +        return computedRoleString;
 | |
| +    AccessibilityRole role = axObject->roleValue();
 | |
| +    switch(role) {
 | |
| +        case AccessibilityRole::Annotation:
 | |
| +            return "Annotation"_s;
 | |
| +        case AccessibilityRole::Application:
 | |
| +            return "Application"_s;
 | |
| +        case AccessibilityRole::ApplicationAlert:
 | |
| +            return "ApplicationAlert"_s;
 | |
| +        case AccessibilityRole::ApplicationAlertDialog:
 | |
| +            return "ApplicationAlertDialog"_s;
 | |
| +        case AccessibilityRole::ApplicationDialog:
 | |
| +            return "ApplicationDialog"_s;
 | |
| +        case AccessibilityRole::ApplicationGroup:
 | |
| +            return "ApplicationGroup"_s;
 | |
| +        case AccessibilityRole::ApplicationLog:
 | |
| +            return "ApplicationLog"_s;
 | |
| +        case AccessibilityRole::ApplicationMarquee:
 | |
| +            return "ApplicationMarquee"_s;
 | |
| +        case AccessibilityRole::ApplicationStatus:
 | |
| +            return "ApplicationStatus"_s;
 | |
| +        case AccessibilityRole::ApplicationTextGroup:
 | |
| +            return "ApplicationTextGroup"_s;
 | |
| +        case AccessibilityRole::ApplicationTimer:
 | |
| +            return "ApplicationTimer"_s;
 | |
| +        case AccessibilityRole::Audio:
 | |
| +            return "Audio"_s;
 | |
| +        case AccessibilityRole::Blockquote:
 | |
| +            return "Blockquote"_s;
 | |
| +        case AccessibilityRole::Browser:
 | |
| +            return "Browser"_s;
 | |
| +        case AccessibilityRole::BusyIndicator:
 | |
| +            return "BusyIndicator"_s;
 | |
| +        case AccessibilityRole::Button:
 | |
| +            return "Button"_s;
 | |
| +        case AccessibilityRole::Canvas:
 | |
| +            return "Canvas"_s;
 | |
| +        case AccessibilityRole::Caption:
 | |
| +            return "Caption"_s;
 | |
| +        case AccessibilityRole::Cell:
 | |
| +            return "Cell"_s;
 | |
| +        case AccessibilityRole::CheckBox:
 | |
| +            return "CheckBox"_s;
 | |
| +        case AccessibilityRole::ColorWell:
 | |
| +            return "ColorWell"_s;
 | |
| +        case AccessibilityRole::Column:
 | |
| +            return "Column"_s;
 | |
| +        case AccessibilityRole::ColumnHeader:
 | |
| +            return "ColumnHeader"_s;
 | |
| +        case AccessibilityRole::ComboBox:
 | |
| +            return "ComboBox"_s;
 | |
| +        case AccessibilityRole::Definition:
 | |
| +            return "Definition"_s;
 | |
| +        case AccessibilityRole::Deletion:
 | |
| +            return "Deletion"_s;
 | |
| +        case AccessibilityRole::DescriptionList:
 | |
| +            return "DescriptionList"_s;
 | |
| +        case AccessibilityRole::DescriptionListTerm:
 | |
| +            return "DescriptionListTerm"_s;
 | |
| +        case AccessibilityRole::DescriptionListDetail:
 | |
| +            return "DescriptionListDetail"_s;
 | |
| +        case AccessibilityRole::Details:
 | |
| +            return "Details"_s;
 | |
| +        case AccessibilityRole::Directory:
 | |
| +            return "Directory"_s;
 | |
| +        case AccessibilityRole::DisclosureTriangle:
 | |
| +            return "DisclosureTriangle"_s;
 | |
| +        case AccessibilityRole::Div:
 | |
| +            return "Div"_s;
 | |
| +        case AccessibilityRole::Document:
 | |
| +            return "Document"_s;
 | |
| +        case AccessibilityRole::DocumentArticle:
 | |
| +            return "DocumentArticle"_s;
 | |
| +        case AccessibilityRole::DocumentMath:
 | |
| +            return "DocumentMath"_s;
 | |
| +        case AccessibilityRole::DocumentNote:
 | |
| +            return "DocumentNote"_s;
 | |
| +        case AccessibilityRole::Drawer:
 | |
| +            return "Drawer"_s;
 | |
| +        case AccessibilityRole::EditableText:
 | |
| +            return "EditableText"_s;
 | |
| +        case AccessibilityRole::Feed:
 | |
| +            return "Feed"_s;
 | |
| +        case AccessibilityRole::Figure:
 | |
| +            return "Figure"_s;
 | |
| +        case AccessibilityRole::Footer:
 | |
| +            return "Footer"_s;
 | |
| +        case AccessibilityRole::Footnote:
 | |
| +            return "Footnote"_s;
 | |
| +        case AccessibilityRole::Form:
 | |
| +            return "Form"_s;
 | |
| +        case AccessibilityRole::GraphicsDocument:
 | |
| +            return "GraphicsDocument"_s;
 | |
| +        case AccessibilityRole::GraphicsObject:
 | |
| +            return "GraphicsObject"_s;
 | |
| +        case AccessibilityRole::GraphicsSymbol:
 | |
| +            return "GraphicsSymbol"_s;
 | |
| +        case AccessibilityRole::Grid:
 | |
| +            return "Grid"_s;
 | |
| +        case AccessibilityRole::GridCell:
 | |
| +            return "GridCell"_s;
 | |
| +        case AccessibilityRole::Group:
 | |
| +            return "Group"_s;
 | |
| +        case AccessibilityRole::GrowArea:
 | |
| +            return "GrowArea"_s;
 | |
| +        case AccessibilityRole::Heading:
 | |
| +            return "Heading"_s;
 | |
| +        case AccessibilityRole::HelpTag:
 | |
| +            return "HelpTag"_s;
 | |
| +        case AccessibilityRole::HorizontalRule:
 | |
| +            return "HorizontalRule"_s;
 | |
| +        case AccessibilityRole::Ignored:
 | |
| +            return "Ignored"_s;
 | |
| +        case AccessibilityRole::Inline:
 | |
| +            return "Inline"_s;
 | |
| +        case AccessibilityRole::Image:
 | |
| +            return "Image"_s;
 | |
| +        case AccessibilityRole::ImageMap:
 | |
| +            return "ImageMap"_s;
 | |
| +        case AccessibilityRole::ImageMapLink:
 | |
| +            return "ImageMapLink"_s;
 | |
| +        case AccessibilityRole::Incrementor:
 | |
| +            return "Incrementor"_s;
 | |
| +        case AccessibilityRole::Insertion:
 | |
| +            return "Insertion"_s;
 | |
| +        case AccessibilityRole::Label:
 | |
| +            return "Label"_s;
 | |
| +        case AccessibilityRole::LandmarkBanner:
 | |
| +            return "LandmarkBanner"_s;
 | |
| +        case AccessibilityRole::LandmarkComplementary:
 | |
| +            return "LandmarkComplementary"_s;
 | |
| +        case AccessibilityRole::LandmarkContentInfo:
 | |
| +            return "LandmarkContentInfo"_s;
 | |
| +        case AccessibilityRole::LandmarkDocRegion:
 | |
| +            return "LandmarkDocRegion"_s;
 | |
| +        case AccessibilityRole::LandmarkMain:
 | |
| +            return "LandmarkMain"_s;
 | |
| +        case AccessibilityRole::LandmarkNavigation:
 | |
| +            return "LandmarkNavigation"_s;
 | |
| +        case AccessibilityRole::LandmarkRegion:
 | |
| +            return "LandmarkRegion"_s;
 | |
| +        case AccessibilityRole::LandmarkSearch:
 | |
| +            return "LandmarkSearch"_s;
 | |
| +        case AccessibilityRole::Legend:
 | |
| +            return "Legend"_s;
 | |
| +        case AccessibilityRole::Link:
 | |
| +            return "Link"_s;
 | |
| +        case AccessibilityRole::List:
 | |
| +            return "List"_s;
 | |
| +        case AccessibilityRole::ListBox:
 | |
| +            return "ListBox"_s;
 | |
| +        case AccessibilityRole::ListBoxOption:
 | |
| +            return "ListBoxOption"_s;
 | |
| +        case AccessibilityRole::ListItem:
 | |
| +            return "ListItem"_s;
 | |
| +        case AccessibilityRole::ListMarker:
 | |
| +            return "ListMarker"_s;
 | |
| +        case AccessibilityRole::Mark:
 | |
| +            return "Mark"_s;
 | |
| +        case AccessibilityRole::MathElement:
 | |
| +            return "MathElement"_s;
 | |
| +        case AccessibilityRole::Matte:
 | |
| +            return "Matte"_s;
 | |
| +        case AccessibilityRole::Menu:
 | |
| +            return "Menu"_s;
 | |
| +        case AccessibilityRole::MenuBar:
 | |
| +            return "MenuBar"_s;
 | |
| +        case AccessibilityRole::MenuButton:
 | |
| +            return "MenuButton"_s;
 | |
| +        case AccessibilityRole::MenuItem:
 | |
| +            return "MenuItem"_s;
 | |
| +        case AccessibilityRole::MenuItemCheckbox:
 | |
| +            return "MenuItemCheckbox"_s;
 | |
| +        case AccessibilityRole::MenuItemRadio:
 | |
| +            return "MenuItemRadio"_s;
 | |
| +        case AccessibilityRole::MenuListPopup:
 | |
| +            return "MenuListPopup"_s;
 | |
| +        case AccessibilityRole::MenuListOption:
 | |
| +            return "MenuListOption"_s;
 | |
| +        case AccessibilityRole::Meter:
 | |
| +            return "Meter"_s;
 | |
| +        case AccessibilityRole::Model:
 | |
| +            return "Model"_s;
 | |
| +        case AccessibilityRole::Outline:
 | |
| +            return "Outline"_s;
 | |
| +        case AccessibilityRole::Paragraph:
 | |
| +            return "Paragraph"_s;
 | |
| +        case AccessibilityRole::PopUpButton:
 | |
| +            return "PopUpButton"_s;
 | |
| +        case AccessibilityRole::Pre:
 | |
| +            return "Pre"_s;
 | |
| +        case AccessibilityRole::Presentational:
 | |
| +            return "Presentational"_s;
 | |
| +        case AccessibilityRole::ProgressIndicator:
 | |
| +            return "ProgressIndicator"_s;
 | |
| +        case AccessibilityRole::RadioButton:
 | |
| +            return "RadioButton"_s;
 | |
| +        case AccessibilityRole::RadioGroup:
 | |
| +            return "RadioGroup"_s;
 | |
| +        case AccessibilityRole::RowHeader:
 | |
| +            return "RowHeader"_s;
 | |
| +        case AccessibilityRole::Row:
 | |
| +            return "Row"_s;
 | |
| +        case AccessibilityRole::RowGroup:
 | |
| +            return "RowGroup"_s;
 | |
| +        case AccessibilityRole::RubyBase:
 | |
| +            return "RubyBase"_s;
 | |
| +        case AccessibilityRole::RubyBlock:
 | |
| +            return "RubyBlock"_s;
 | |
| +        case AccessibilityRole::RubyInline:
 | |
| +            return "RubyInline"_s;
 | |
| +        case AccessibilityRole::RubyRun:
 | |
| +            return "RubyRun"_s;
 | |
| +        case AccessibilityRole::RubyText:
 | |
| +            return "RubyText"_s;
 | |
| +        case AccessibilityRole::Ruler:
 | |
| +            return "Ruler"_s;
 | |
| +        case AccessibilityRole::RulerMarker:
 | |
| +            return "RulerMarker"_s;
 | |
| +        case AccessibilityRole::ScrollArea:
 | |
| +            return "ScrollArea"_s;
 | |
| +        case AccessibilityRole::ScrollBar:
 | |
| +            return "ScrollBar"_s;
 | |
| +        case AccessibilityRole::SearchField:
 | |
| +            return "SearchField"_s;
 | |
| +        case AccessibilityRole::Sheet:
 | |
| +            return "Sheet"_s;
 | |
| +        case AccessibilityRole::Slider:
 | |
| +            return "Slider"_s;
 | |
| +        case AccessibilityRole::SliderThumb:
 | |
| +            return "SliderThumb"_s;
 | |
| +        case AccessibilityRole::SpinButton:
 | |
| +            return "SpinButton"_s;
 | |
| +        case AccessibilityRole::SpinButtonPart:
 | |
| +            return "SpinButtonPart"_s;
 | |
| +        case AccessibilityRole::SplitGroup:
 | |
| +            return "SplitGroup"_s;
 | |
| +        case AccessibilityRole::Splitter:
 | |
| +            return "Splitter"_s;
 | |
| +        case AccessibilityRole::StaticText:
 | |
| +            return "StaticText"_s;
 | |
| +        case AccessibilityRole::Subscript:
 | |
| +            return "Subscript"_s;
 | |
| +        case AccessibilityRole::Summary:
 | |
| +            return "Summary"_s;
 | |
| +        case AccessibilityRole::Superscript:
 | |
| +            return "Superscript"_s;
 | |
| +        case AccessibilityRole::Switch:
 | |
| +            return "Switch"_s;
 | |
| +        case AccessibilityRole::SystemWide:
 | |
| +            return "SystemWide"_s;
 | |
| +        case AccessibilityRole::SVGRoot:
 | |
| +            return "SVGRoot"_s;
 | |
| +        case AccessibilityRole::SVGText:
 | |
| +            return "SVGText"_s;
 | |
| +        case AccessibilityRole::SVGTSpan:
 | |
| +            return "SVGTSpan"_s;
 | |
| +        case AccessibilityRole::SVGTextPath:
 | |
| +            return "SVGTextPath"_s;
 | |
| +        case AccessibilityRole::TabGroup:
 | |
| +            return "TabGroup"_s;
 | |
| +        case AccessibilityRole::TabList:
 | |
| +            return "TabList"_s;
 | |
| +        case AccessibilityRole::TabPanel:
 | |
| +            return "TabPanel"_s;
 | |
| +        case AccessibilityRole::Tab:
 | |
| +            return "Tab"_s;
 | |
| +        case AccessibilityRole::Table:
 | |
| +            return "Table"_s;
 | |
| +        case AccessibilityRole::TableHeaderContainer:
 | |
| +            return "TableHeaderContainer"_s;
 | |
| +        case AccessibilityRole::TextArea:
 | |
| +            return "TextArea"_s;
 | |
| +        case AccessibilityRole::TextGroup:
 | |
| +            return "TextGroup"_s;
 | |
| +        case AccessibilityRole::Term:
 | |
| +            return "Term"_s;
 | |
| +        case AccessibilityRole::Time:
 | |
| +            return "Time"_s;
 | |
| +        case AccessibilityRole::Tree:
 | |
| +            return "Tree"_s;
 | |
| +        case AccessibilityRole::TreeGrid:
 | |
| +            return "TreeGrid"_s;
 | |
| +        case AccessibilityRole::TreeItem:
 | |
| +            return "TreeItem"_s;
 | |
| +        case AccessibilityRole::TextField:
 | |
| +            return "TextField"_s;
 | |
| +        case AccessibilityRole::ToggleButton:
 | |
| +            return "ToggleButton"_s;
 | |
| +        case AccessibilityRole::Toolbar:
 | |
| +            return "Toolbar"_s;
 | |
| +        case AccessibilityRole::Unknown:
 | |
| +            return "Unknown"_s;
 | |
| +        case AccessibilityRole::UserInterfaceTooltip:
 | |
| +            return "UserInterfaceTooltip"_s;
 | |
| +        case AccessibilityRole::ValueIndicator:
 | |
| +            return "ValueIndicator"_s;
 | |
| +        case AccessibilityRole::Video:
 | |
| +            return "Video"_s;
 | |
| +        case AccessibilityRole::WebApplication:
 | |
| +            return "WebApplication"_s;
 | |
| +        case AccessibilityRole::WebArea:
 | |
| +            return "WebArea"_s;
 | |
| +        case AccessibilityRole::WebCoreLink:
 | |
| +            return "WebCoreLink"_s;
 | |
| +        case AccessibilityRole::Window:
 | |
| +            return "Window"_s;
 | |
| +    };
 | |
| +    return "Unknown"_s;
 | |
| +}
 | |
| +
 | |
| +static Ref<Inspector::Protocol::Page::AXNode> snapshotForAXObject(RefPtr<AXCoreObject> axObject, Node* nodeToFind)
 | |
| +{
 | |
| +    auto axNode = Inspector::Protocol::Page::AXNode::create()
 | |
| +        .setRole(roleFromObject(axObject))
 | |
| +        .release();
 | |
| +
 | |
| +    if (!axObject->computedLabel().isEmpty())
 | |
| +        axNode->setName(axObject->computedLabel());
 | |
| +    if (!axObject->stringValue().isEmpty())
 | |
| +        axNode->setValue(JSON::Value::create(axObject->stringValue()));
 | |
| +    if (!axObject->accessibilityDescription().isEmpty())
 | |
| +        axNode->setDescription(axObject->accessibilityDescription());
 | |
| +    if (!axObject->keyShortcutsValue().isEmpty())
 | |
| +        axNode->setKeyshortcuts(axObject->keyShortcutsValue());
 | |
| +    if (!axObject->valueDescription().isEmpty())
 | |
| +        axNode->setValuetext(axObject->valueDescription());
 | |
| +    if (!axObject->roleDescription().isEmpty())
 | |
| +        axNode->setRoledescription(axObject->roleDescription());
 | |
| +    if (!axObject->isEnabled())
 | |
| +        axNode->setDisabled(!axObject->isEnabled());
 | |
| +    if (axObject->supportsExpanded())
 | |
| +        axNode->setExpanded(axObject->isExpanded());
 | |
| +    if (axObject->isFocused())
 | |
| +        axNode->setFocused(axObject->isFocused());
 | |
| +    if (axObject->isModalNode())
 | |
| +        axNode->setModal(axObject->isModalNode());
 | |
| +    bool multiline = axObject->ariaIsMultiline() || axObject->roleValue() == AccessibilityRole::TextArea;
 | |
| +    if (multiline)
 | |
| +        axNode->setMultiline(multiline);
 | |
| +    if (axObject->isMultiSelectable())
 | |
| +        axNode->setMultiselectable(axObject->isMultiSelectable());
 | |
| +    if (axObject->supportsReadOnly() && !axObject->canSetValueAttribute() && axObject->isEnabled())
 | |
| +        axNode->setReadonly(true);
 | |
| +    if (axObject->supportsRequiredAttribute())
 | |
| +        axNode->setRequired(axObject->isRequired());
 | |
| +    if (axObject->isSelected())
 | |
| +        axNode->setSelected(axObject->isSelected());
 | |
| +    if (axObject->supportsChecked()) {
 | |
| +        AccessibilityButtonState checkedState = axObject->checkboxOrRadioValue();
 | |
| +        switch (checkedState) {
 | |
| +            case AccessibilityButtonState::On:
 | |
| +                axNode->setChecked(Inspector::Protocol::Page::AXNode::Checked::True);
 | |
| +                break;
 | |
| +            case AccessibilityButtonState::Off:
 | |
| +                axNode->setChecked(Inspector::Protocol::Page::AXNode::Checked::False);
 | |
| +                break;
 | |
| +            case AccessibilityButtonState::Mixed:
 | |
| +                axNode->setChecked(Inspector::Protocol::Page::AXNode::Checked::Mixed);
 | |
| +                break;
 | |
| +        }
 | |
| +    }
 | |
| +    if (axObject->supportsPressed()) {
 | |
| +        AccessibilityButtonState checkedState = axObject->checkboxOrRadioValue();
 | |
| +        switch (checkedState) {
 | |
| +            case AccessibilityButtonState::On:
 | |
| +                axNode->setPressed(Inspector::Protocol::Page::AXNode::Pressed::True);
 | |
| +                break;
 | |
| +            case AccessibilityButtonState::Off:
 | |
| +                axNode->setPressed(Inspector::Protocol::Page::AXNode::Pressed::False);
 | |
| +                break;
 | |
| +            case AccessibilityButtonState::Mixed:
 | |
| +                axNode->setPressed(Inspector::Protocol::Page::AXNode::Pressed::Mixed);
 | |
| +                break;
 | |
| +        }
 | |
| +    }
 | |
| +    unsigned level = axObject->hierarchicalLevel() ? axObject->hierarchicalLevel() : axObject->headingLevel();
 | |
| +    if (level)
 | |
| +        axNode->setLevel(level);
 | |
| +    if (axObject->minValueForRange() != 0)
 | |
| +        axNode->setValuemin(axObject->minValueForRange());
 | |
| +    if (axObject->maxValueForRange() != 0)
 | |
| +        axNode->setValuemax(axObject->maxValueForRange());
 | |
| +    if (axObject->supportsAutoComplete())
 | |
| +        axNode->setAutocomplete(axObject->autoCompleteValue());
 | |
| +    if (axObject->hasPopup())
 | |
| +        axNode->setHaspopup(axObject->popupValue());
 | |
| +
 | |
| +    String invalidValue = axObject->invalidStatus();
 | |
| +    if (invalidValue != "false") {
 | |
| +        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->children().isEmpty()) {
 | |
| +        Ref<JSON::ArrayOf<Inspector::Protocol::Page::AXNode>> children = JSON::ArrayOf<Inspector::Protocol::Page::AXNode>::create();
 | |
| +        for (auto& childObject : axObject->children())
 | |
| +            children->addItem(snapshotForAXObject(childObject, nodeToFind));
 | |
| +        axNode->setChildren(WTFMove(children));
 | |
| +    }
 | |
| +    return axNode;
 | |
| +}
 | |
| +
 | |
| +
 | |
| +Protocol::ErrorStringOr<Ref<Protocol::Page::AXNode>> InspectorPageAgent::accessibilitySnapshot(const String& objectId)
 | |
| +{
 | |
| +    if (!WebCore::AXObjectCache::accessibilityEnabled())
 | |
| +        WebCore::AXObjectCache::enableAccessibility();
 | |
| +    RefPtr document = m_inspectedPage.mainFrame().document();
 | |
| +    if (!document)
 | |
| +        return makeUnexpected("No document for main frame"_s);
 | |
| +
 | |
| +    AXObjectCache* axObjectCache = document->axObjectCache();
 | |
| +    if (!axObjectCache)
 | |
| +        return makeUnexpected("No AXObjectCache for main document"_s);
 | |
| +
 | |
| +    AXCoreObject* axObject = axObjectCache->rootObject();
 | |
| +    if (!axObject)
 | |
| +        return makeUnexpected("No AXObject for main document"_s);
 | |
| +
 | |
| +    Node* node = nullptr;
 | |
| +    if (!objectId.isEmpty()) {
 | |
| +        InspectorDOMAgent* domAgent = m_instrumentingAgents.persistentDOMAgent();
 | |
| +        ASSERT(domAgent);
 | |
| +        node = domAgent->nodeForObjectId(objectId);
 | |
| +        if (!node)
 | |
| +            return makeUnexpected("No Node for objectId"_s);
 | |
| +    }
 | |
| +
 | |
| +    m_doingAccessibilitySnapshot = true;
 | |
| +    Ref<Inspector::Protocol::Page::AXNode> axNode = snapshotForAXObject(RefPtr { axObject }, node);
 | |
| +    m_doingAccessibilitySnapshot = false;
 | |
| +    return axNode;
 | |
| +}
 | |
| +
 | |
| +Protocol::ErrorStringOr<void> InspectorPageAgent::setInterceptFileChooserDialog(bool enabled)
 | |
| +{
 | |
| +    m_interceptFileChooserDialog = enabled;
 | |
| +    return { };
 | |
| +}
 | |
| +
 | |
| +Protocol::ErrorStringOr<void> InspectorPageAgent::setDefaultBackgroundColorOverride(RefPtr<JSON::Object>&& color)
 | |
| +{
 | |
| +    FrameView* view = m_inspectedPage.mainFrame().view();
 | |
| +    if (!view)
 | |
| +        return makeUnexpected("Internal error: No frame view to set color two"_s);
 | |
| +
 | |
| +    if (!color) {
 | |
| +        view->updateBackgroundRecursively(std::optional<Color>());
 | |
| +        return { };
 | |
| +    }
 | |
| +
 | |
| +    view->updateBackgroundRecursively(InspectorDOMAgent::parseColor(WTFMove(color)));
 | |
| +    return { };
 | |
| +}
 | |
| +
 | |
| +Protocol::ErrorStringOr<void> InspectorPageAgent::createUserWorld(const String& name)
 | |
| +{
 | |
| +    if (createdUserWorlds().contains(name))
 | |
| +        return makeUnexpected("World with the given name already exists"_s);
 | |
| +
 | |
| +    Ref<DOMWrapperWorld> world = ScriptController::createWorld(name, ScriptController::WorldType::User);
 | |
| +    ensureUserWorldsExistInAllFrames({world.ptr()});
 | |
| +    createdUserWorlds().set(name, WTFMove(world));
 | |
| +    return { };
 | |
| +}
 | |
| +
 | |
| +void InspectorPageAgent::ensureUserWorldsExistInAllFrames(const Vector<DOMWrapperWorld*>& worlds)
 | |
| +{
 | |
| +    for (Frame* frame = &m_inspectedPage.mainFrame(); frame; frame = frame->tree().traverseNext()) {
 | |
| +        for (auto* world : worlds)
 | |
| +            frame->windowProxy().jsWindowProxy(*world)->window();
 | |
| +    }
 | |
| +}
 | |
| +
 | |
| +Protocol::ErrorStringOr<void> InspectorPageAgent::setBypassCSP(bool enabled)
 | |
| +{
 | |
| +    m_bypassCSP = enabled;
 | |
| +    return { };
 | |
| +}
 | |
| +
 | |
| +Protocol::ErrorStringOr<void> InspectorPageAgent::crash()
 | |
| +{
 | |
| +    CRASH();
 | |
| +    return { };
 | |
| +}
 | |
| +
 | |
| +Protocol::ErrorStringOr<void> InspectorPageAgent::setOrientationOverride(std::optional<int>&& angle)
 | |
| +{
 | |
| +#if ENABLE(ORIENTATION_EVENTS)
 | |
| +    m_inspectedPage.setOverrideOrientation(WTFMove(angle));
 | |
| +    return { };
 | |
| +#else
 | |
| +    UNUSED_PARAM(angle);
 | |
| +    return makeUnexpected("Orientation events are disabled in this build");
 | |
|  #endif
 | |
| +}
 | |
| +
 | |
| +static std::optional<FloatBoxExtent> parseInsets(RefPtr<JSON::Object>&& insets)
 | |
| +{
 | |
| +    std::optional<double> top = insets->getDouble("top"_s);
 | |
| +    std::optional<double> right = insets->getDouble("right"_s);
 | |
| +    std::optional<double> bottom = insets->getDouble("bottom"_s);
 | |
| +    std::optional<double> left = insets->getDouble("left"_s);
 | |
| +    if (top && right && bottom && left)
 | |
| +        return FloatBoxExtent(static_cast<float>(*top), static_cast<float>(*right), static_cast<float>(*bottom), static_cast<float>(*left));
 | |
| +    return std::optional<FloatBoxExtent>();
 | |
| +}
 | |
| +
 | |
| +static std::optional<FloatRect> parseRect(RefPtr<JSON::Object>&& insets)
 | |
| +{
 | |
| +    std::optional<double> x = insets->getDouble("x"_s);
 | |
| +    std::optional<double> y = insets->getDouble("y"_s);
 | |
| +    std::optional<double> width = insets->getDouble("width"_s);
 | |
| +    std::optional<double> height = insets->getDouble("height"_s);
 | |
| +    if (x && y && width && height)
 | |
| +        return FloatRect(static_cast<float>(*x), static_cast<float>(*y), static_cast<float>(*width), static_cast<float>(*height));
 | |
| +    return std::optional<FloatRect>();
 | |
| +}
 | |
| +
 | |
| +Protocol::ErrorStringOr<void> InspectorPageAgent::setVisibleContentRects(RefPtr<JSON::Object>&& unobscuredContentRect, RefPtr<JSON::Object>&& contentInsets, RefPtr<JSON::Object>&& obscuredInsets, RefPtr<JSON::Object>&& unobscuredInsets)
 | |
| +{
 | |
| +    FrameView* view = m_inspectedPage.mainFrame().view();
 | |
| +    if (!view)
 | |
| +        return makeUnexpected("Internal error: No frame view to set content rects for"_s);
 | |
| +
 | |
| +    if (unobscuredContentRect) {
 | |
| +        std::optional<FloatRect> ucr = parseRect(WTFMove(unobscuredContentRect));
 | |
| +        if (!ucr)
 | |
| +            return makeUnexpected("Invalid unobscured content rect"_s);
 | |
| +
 | |
| +        view->setUnobscuredContentSize(FloatSize(ucr->width(), ucr->height()));
 | |
| +    }
 | |
| +
 | |
| +    if (contentInsets) {
 | |
| +        std::optional<FloatBoxExtent> ci = parseInsets(WTFMove(contentInsets));
 | |
| +        if (!ci)
 | |
| +            return makeUnexpected("Invalid content insets"_s);
 | |
| +
 | |
| +        m_inspectedPage.setContentInsets(*ci);
 | |
| +    }
 | |
| +
 | |
| +    if (obscuredInsets) {
 | |
| +        std::optional<FloatBoxExtent> oi = parseInsets(WTFMove(obscuredInsets));
 | |
| +        if (!oi)
 | |
| +            return makeUnexpected("Invalid obscured insets"_s);
 | |
| +
 | |
| +        m_inspectedPage.setObscuredInsets(*oi);
 | |
| +    }
 | |
| +
 | |
| +    if (unobscuredInsets) {
 | |
| +        std::optional<FloatBoxExtent> ui = parseInsets(WTFMove(unobscuredInsets));
 | |
| +        if (!ui)
 | |
| +            return makeUnexpected("Invalid unobscured insets"_s);
 | |
| +
 | |
| +        m_inspectedPage.setUnobscuredSafeAreaInsets(*ui);
 | |
| +    }
 | |
| +    return {};
 | |
| +}
 | |
| +
 | |
| +Protocol::ErrorStringOr<void> InspectorPageAgent::updateScrollingState()
 | |
| +{
 | |
| +    auto* scrollingCoordinator = m_inspectedPage.scrollingCoordinator();
 | |
| +    if (!scrollingCoordinator)
 | |
| +        return {};
 | |
| +    scrollingCoordinator->commitTreeStateIfNeeded();
 | |
| +    return {};
 | |
| +}
 | |
|  
 | |
|  } // namespace WebCore
 | |
| diff --git a/Source/WebCore/inspector/agents/InspectorPageAgent.h b/Source/WebCore/inspector/agents/InspectorPageAgent.h
 | |
| index dfd4cdd61f52c9386a215428b07cad1705344f65..2d93349e91582a5e0c0d0e63358d7e1aebc1854c 100644
 | |
| --- a/Source/WebCore/inspector/agents/InspectorPageAgent.h
 | |
| +++ b/Source/WebCore/inspector/agents/InspectorPageAgent.h
 | |
| @@ -32,19 +32,26 @@
 | |
|  #pragma once
 | |
|  
 | |
|  #include "CachedResource.h"
 | |
| +#include "FrameIdentifier.h"
 | |
|  #include "InspectorWebAgentBase.h"
 | |
|  #include "LayoutRect.h"
 | |
| +#include "ProcessIdentifier.h"
 | |
|  #include <JavaScriptCore/InspectorBackendDispatchers.h>
 | |
|  #include <JavaScriptCore/InspectorFrontendDispatchers.h>
 | |
|  #include <wtf/RobinHoodHashMap.h>
 | |
|  #include <wtf/Seconds.h>
 | |
|  #include <wtf/text/WTFString.h>
 | |
|  
 | |
| +namespace Inspector {
 | |
| +class InjectedScriptManager;
 | |
| +}
 | |
| +
 | |
|  namespace WebCore {
 | |
|  
 | |
|  class DOMWrapperWorld;
 | |
|  class DocumentLoader;
 | |
|  class Frame;
 | |
| +class HTMLInputElement;
 | |
|  class InspectorClient;
 | |
|  class InspectorOverlay;
 | |
|  class Page;
 | |
| @@ -76,6 +83,7 @@ public:
 | |
|          OtherResource,
 | |
|      };
 | |
|  
 | |
| +    WEBCORE_EXPORT static String makeFrameID(ProcessIdentifier processID,  FrameIdentifier frameID);
 | |
|      static bool sharedBufferContent(RefPtr<FragmentedSharedBuffer>&&, const String& textEncodingName, bool withBase64Encode, String* result);
 | |
|      static Vector<CachedResource*> cachedResourcesForFrame(Frame*);
 | |
|      static void resourceContent(Inspector::Protocol::ErrorString&, Frame*, const URL&, String* result, bool* base64Encoded);
 | |
| @@ -96,15 +104,18 @@ public:
 | |
|      Inspector::Protocol::ErrorStringOr<void> enable();
 | |
|      Inspector::Protocol::ErrorStringOr<void> disable();
 | |
|      Inspector::Protocol::ErrorStringOr<void> reload(std::optional<bool>&& ignoreCache, std::optional<bool>&& revalidateAllResources);
 | |
| +    Inspector::Protocol::ErrorStringOr<void> goBack();
 | |
| +    Inspector::Protocol::ErrorStringOr<void> goForward();
 | |
|      Inspector::Protocol::ErrorStringOr<void> navigate(const String& url);
 | |
|      Inspector::Protocol::ErrorStringOr<void> overrideUserAgent(const String&);
 | |
| +    Inspector::Protocol::ErrorStringOr<void> overridePlatform(const String&);
 | |
|      Inspector::Protocol::ErrorStringOr<void> overrideSetting(Inspector::Protocol::Page::Setting, std::optional<bool>&& value);
 | |
|      Inspector::Protocol::ErrorStringOr<Ref<JSON::ArrayOf<Inspector::Protocol::Page::Cookie>>> getCookies();
 | |
|      Inspector::Protocol::ErrorStringOr<void> setCookie(Ref<JSON::Object>&&);
 | |
|      Inspector::Protocol::ErrorStringOr<void> deleteCookie(const String& cookieName, const String& url);
 | |
|      Inspector::Protocol::ErrorStringOr<Ref<Inspector::Protocol::Page::FrameResourceTree>> getResourceTree();
 | |
|      Inspector::Protocol::ErrorStringOr<std::tuple<String, bool /* base64Encoded */>> getResourceContent(const Inspector::Protocol::Network::FrameId&, const String& url);
 | |
| -    Inspector::Protocol::ErrorStringOr<void> setBootstrapScript(const String& source);
 | |
| +    Inspector::Protocol::ErrorStringOr<void> setBootstrapScript(const String& source, const String& worldName);
 | |
|      Inspector::Protocol::ErrorStringOr<Ref<JSON::ArrayOf<Inspector::Protocol::GenericTypes::SearchMatch>>> searchInResource(const Inspector::Protocol::Network::FrameId&, const String& url, const String& query, std::optional<bool>&& caseSensitive, std::optional<bool>&& isRegex, const Inspector::Protocol::Network::RequestId&);
 | |
|      Inspector::Protocol::ErrorStringOr<Ref<JSON::ArrayOf<Inspector::Protocol::Page::SearchResult>>> searchInResources(const String&, std::optional<bool>&& caseSensitive, std::optional<bool>&& isRegex);
 | |
|  #if !PLATFORM(IOS_FAMILY)
 | |
| @@ -115,35 +126,55 @@ public:
 | |
|  #if ENABLE(DARK_MODE_CSS) || HAVE(OS_DARK_MODE_SUPPORT)
 | |
|      Inspector::Protocol::ErrorStringOr<void> setForcedAppearance(std::optional<Inspector::Protocol::Page::Appearance>&&);
 | |
|  #endif
 | |
| +    Inspector::Protocol::ErrorStringOr<void> setForcedReducedMotion(std::optional<Inspector::Protocol::Page::ReducedMotion>&&);
 | |
| +    Inspector::Protocol::ErrorStringOr<void> setTimeZone(const String&);
 | |
| +    Inspector::Protocol::ErrorStringOr<void> setTouchEmulationEnabled(bool);
 | |
|      Inspector::Protocol::ErrorStringOr<String> snapshotNode(Inspector::Protocol::DOM::NodeId);
 | |
| -    Inspector::Protocol::ErrorStringOr<String> snapshotRect(int x, int y, int width, int height, Inspector::Protocol::Page::CoordinateSystem);
 | |
| +    Inspector::Protocol::ErrorStringOr<String> snapshotRect(int x, int y, int width, int height, Inspector::Protocol::Page::CoordinateSystem, std::optional<bool>&& omitDeviceScaleFactor);
 | |
|  #if ENABLE(WEB_ARCHIVE) && USE(CF)
 | |
|      Inspector::Protocol::ErrorStringOr<String> archive();
 | |
|  #endif
 | |
| -#if !PLATFORM(COCOA)
 | |
|      Inspector::Protocol::ErrorStringOr<void> setScreenSizeOverride(std::optional<int>&& width, std::optional<int>&& height);
 | |
| -#endif
 | |
| +
 | |
| +    Inspector::Protocol::ErrorStringOr<void> insertText(const String& text);
 | |
| +    Inspector::Protocol::ErrorStringOr<void> setComposition(const String& text, int selectionStart, int selectionLength, std::optional<int>&& replacementStart, std::optional<int>&& replacementLength);
 | |
| +    Inspector::Protocol::ErrorStringOr<Ref<Inspector::Protocol::Page::AXNode>> accessibilitySnapshot(const String& objectId);
 | |
| +    Inspector::Protocol::ErrorStringOr<void> setInterceptFileChooserDialog(bool enabled);
 | |
| +    Inspector::Protocol::ErrorStringOr<void> setDefaultBackgroundColorOverride(RefPtr<JSON::Object>&&);
 | |
| +    Inspector::Protocol::ErrorStringOr<void> createUserWorld(const String&);
 | |
| +    Inspector::Protocol::ErrorStringOr<void> setBypassCSP(bool);
 | |
| +    Inspector::Protocol::ErrorStringOr<void> crash();
 | |
| +    Inspector::Protocol::ErrorStringOr<void> setOrientationOverride(std::optional<int>&& angle);
 | |
| +    Inspector::Protocol::ErrorStringOr<void> setVisibleContentRects(RefPtr<JSON::Object>&& unobscuredContentRect, RefPtr<JSON::Object>&& contentInsets, RefPtr<JSON::Object>&& obscuredInsets, RefPtr<JSON::Object>&& unobscuredInsets);
 | |
| +    Inspector::Protocol::ErrorStringOr<void> updateScrollingState();
 | |
|  
 | |
|      // InspectorInstrumentation
 | |
| -    void domContentEventFired();
 | |
| -    void loadEventFired();
 | |
| +    void domContentEventFired(Frame&);
 | |
| +    void loadEventFired(Frame&);
 | |
|      void frameNavigated(Frame&);
 | |
|      void frameDetached(Frame&);
 | |
| -    void loaderDetachedFromFrame(DocumentLoader&);
 | |
|      void frameStartedLoading(Frame&);
 | |
|      void frameStoppedLoading(Frame&);
 | |
|      void frameScheduledNavigation(Frame&, Seconds delay);
 | |
|      void frameClearedScheduledNavigation(Frame&);
 | |
| +    void didNavigateWithinPage(Frame&);
 | |
|  #if ENABLE(DARK_MODE_CSS) || HAVE(OS_DARK_MODE_SUPPORT)
 | |
|      void defaultAppearanceDidChange(bool useDarkAppearance);
 | |
|  #endif
 | |
|      void applyUserAgentOverride(String&);
 | |
| +    void applyPlatformOverride(String&);
 | |
|      void applyEmulatedMedia(String&);
 | |
|      void didClearWindowObjectInWorld(Frame&, DOMWrapperWorld&);
 | |
|      void didPaint(RenderObject&, const LayoutRect&);
 | |
|      void didLayout();
 | |
|      void didScroll();
 | |
|      void didRecalculateStyle();
 | |
| +    void runOpenPanel(HTMLInputElement* element, bool* intercept);
 | |
| +    void frameAttached(Frame&);
 | |
| +    bool shouldBypassCSP();
 | |
| +    void willCheckNavigationPolicy(Frame&);
 | |
| +    void didCheckNavigationPolicy(Frame&, bool cancel);
 | |
| +    bool doingAccessibilitySnapshot() const { return m_doingAccessibilitySnapshot; };
 | |
|  
 | |
|      Frame* frameForId(const Inspector::Protocol::Network::FrameId&);
 | |
|      WEBCORE_EXPORT String frameId(Frame*);
 | |
| @@ -152,6 +183,7 @@ public:
 | |
|  
 | |
|  private:
 | |
|      double timestamp();
 | |
| +    void ensureUserWorldsExistInAllFrames(const Vector<DOMWrapperWorld*>&);
 | |
|  
 | |
|      static bool mainResourceContent(Frame*, bool withBase64Encode, String* result);
 | |
|      static bool dataContent(const uint8_t* data, unsigned size, const String& textEncodingName, bool withBase64Encode, String* result);
 | |
| @@ -163,18 +195,20 @@ private:
 | |
|      RefPtr<Inspector::PageBackendDispatcher> m_backendDispatcher;
 | |
|  
 | |
|      Page& m_inspectedPage;
 | |
| +    Inspector::InjectedScriptManager& m_injectedScriptManager;
 | |
|      InspectorClient* m_client { nullptr };
 | |
|      InspectorOverlay* m_overlay { nullptr };
 | |
|  
 | |
| -    // FIXME: Make a WeakHashMap and use it for m_frameToIdentifier and m_loaderToIdentifier.
 | |
| -    HashMap<Frame*, String> m_frameToIdentifier;
 | |
|      MemoryCompactRobinHoodHashMap<String, WeakPtr<Frame>> m_identifierToFrame;
 | |
| -    HashMap<DocumentLoader*, String> m_loaderToIdentifier;
 | |
| +    HashMap<String, String> m_worldNameToBootstrapScript;
 | |
|      String m_userAgentOverride;
 | |
| +    String m_platformOverride;
 | |
|      String m_emulatedMedia;
 | |
| -    String m_bootstrapScript;
 | |
|      bool m_isFirstLayoutAfterOnLoad { false };
 | |
|      bool m_showPaintRects { false };
 | |
| +    bool m_interceptFileChooserDialog { false };
 | |
| +    bool m_bypassCSP { false };
 | |
| +    bool m_doingAccessibilitySnapshot { false };
 | |
|  };
 | |
|  
 | |
|  } // namespace WebCore
 | |
| diff --git a/Source/WebCore/inspector/agents/InspectorWorkerAgent.cpp b/Source/WebCore/inspector/agents/InspectorWorkerAgent.cpp
 | |
| index fe1cc2dbb9863cd4480476d2e21a5a229dc8a0e8..35dd7ca4cabe0d0ec76d44e260870a99becaa128 100644
 | |
| --- a/Source/WebCore/inspector/agents/InspectorWorkerAgent.cpp
 | |
| +++ b/Source/WebCore/inspector/agents/InspectorWorkerAgent.cpp
 | |
| @@ -168,7 +168,11 @@ void InspectorWorkerAgent::connectToWorkerInspectorProxy(WorkerInspectorProxy& p
 | |
|  
 | |
|      m_connectedProxies.set(proxy.identifier(), proxy);
 | |
|  
 | |
| -    m_frontendDispatcher->workerCreated(proxy.identifier(), proxy.url().string(), proxy.name());
 | |
| +    ASSERT(is<Document>(proxy.scriptExecutionContext()));
 | |
| +    Document& document = downcast<Document>(*proxy.scriptExecutionContext());
 | |
| +    auto* pageAgent = m_instrumentingAgents.enabledPageAgent();
 | |
| +    m_frontendDispatcher->workerCreated(proxy.identifier(), proxy.url().string(), proxy.name(),
 | |
| +        pageAgent ? pageAgent->frameId(document.frame()) : emptyString());
 | |
|  }
 | |
|  
 | |
|  void InspectorWorkerAgent::disconnectFromWorkerInspectorProxy(WorkerInspectorProxy& proxy)
 | |
| diff --git a/Source/WebCore/inspector/agents/page/PageDebuggerAgent.cpp b/Source/WebCore/inspector/agents/page/PageDebuggerAgent.cpp
 | |
| index 31ca79d6410560456c89a5be62560fc33e082cee..4a1e4dbc2ff3c13761014ae614ebf4b7199dbdcd 100644
 | |
| --- a/Source/WebCore/inspector/agents/page/PageDebuggerAgent.cpp
 | |
| +++ b/Source/WebCore/inspector/agents/page/PageDebuggerAgent.cpp
 | |
| @@ -38,6 +38,7 @@
 | |
|  #include "Frame.h"
 | |
|  #include "InspectorPageAgent.h"
 | |
|  #include "InstrumentingAgents.h"
 | |
| +#include "JSDOMWindowBase.h"
 | |
|  #include "JSDOMWindowCustom.h"
 | |
|  #include "JSExecState.h"
 | |
|  #include "Page.h"
 | |
| @@ -74,7 +75,9 @@ Protocol::ErrorStringOr<std::tuple<Ref<Protocol::Runtime::RemoteObject>, std::op
 | |
|      if (injectedScript.hasNoValue())
 | |
|          return makeUnexpected("Missing injected script for given callFrameId"_s);
 | |
|  
 | |
| -    UserGestureEmulationScope userGestureScope(m_inspectedPage, emulateUserGesture.value_or(false), dynamicDowncast<Document>(executionContext(injectedScript.globalObject())));
 | |
| +    JSC::JSGlobalObject* globalObject = injectedScript.globalObject();
 | |
| +    Document* document = globalObject ? activeDOMWindow(*globalObject).document() : nullptr;
 | |
| +    UserGestureEmulationScope userGestureScope(m_inspectedPage, emulateUserGesture.value_or(false), document);
 | |
|      return WebDebuggerAgent::evaluateOnCallFrame(injectedScript, callFrameId, expression, objectGroup, WTFMove(includeCommandLineAPI), WTFMove(doNotPauseOnExceptionsAndMuteConsole), WTFMove(returnByValue), WTFMove(generatePreview), WTFMove(saveResult), WTFMove(emulateUserGesture));
 | |
|  }
 | |
|  
 | |
| diff --git a/Source/WebCore/inspector/agents/page/PageRuntimeAgent.cpp b/Source/WebCore/inspector/agents/page/PageRuntimeAgent.cpp
 | |
| index 5e7a1214da060ba3a168cf21b22e6c398c0e07f7..ef38546315e7e88f09738b18d44a0268a009307c 100644
 | |
| --- a/Source/WebCore/inspector/agents/page/PageRuntimeAgent.cpp
 | |
| +++ b/Source/WebCore/inspector/agents/page/PageRuntimeAgent.cpp
 | |
| @@ -35,6 +35,7 @@
 | |
|  #include "DOMWrapperWorld.h"
 | |
|  #include "Document.h"
 | |
|  #include "Frame.h"
 | |
| +#include "FrameLoader.h"
 | |
|  #include "InspectorPageAgent.h"
 | |
|  #include "InstrumentingAgents.h"
 | |
|  #include "JSDOMWindowCustom.h"
 | |
| @@ -42,6 +43,7 @@
 | |
|  #include "Page.h"
 | |
|  #include "PageConsoleClient.h"
 | |
|  #include "ScriptController.h"
 | |
| +#include "ScriptSourceCode.h"
 | |
|  #include "SecurityOrigin.h"
 | |
|  #include "UserGestureEmulationScope.h"
 | |
|  #include <JavaScriptCore/InjectedScript.h>
 | |
| @@ -103,6 +105,15 @@ void PageRuntimeAgent::didClearWindowObjectInWorld(Frame& frame, DOMWrapperWorld
 | |
|      notifyContextCreated(pageAgent->frameId(&frame), frame.script().globalObject(world), world);
 | |
|  }
 | |
|  
 | |
| +void PageRuntimeAgent::didReceiveMainResourceError(Frame& frame)
 | |
| +{
 | |
| +    if (frame.loader().stateMachine().isDisplayingInitialEmptyDocument()) {
 | |
| +        // Ensure execution context is created for the empty docment to make
 | |
| +        // it usable in case loading failed.
 | |
| +        mainWorldGlobalObject(frame);
 | |
| +    }
 | |
| +}
 | |
| +
 | |
|  InjectedScript PageRuntimeAgent::injectedScriptForEval(Protocol::ErrorString& errorString, std::optional<Protocol::Runtime::ExecutionContextId>&& executionContextId)
 | |
|  {
 | |
|      if (!executionContextId) {
 | |
| @@ -196,18 +207,24 @@ Protocol::ErrorStringOr<std::tuple<Ref<Protocol::Runtime::RemoteObject>, std::op
 | |
|      if (injectedScript.hasNoValue())
 | |
|          return makeUnexpected(errorString);
 | |
|  
 | |
| -    UserGestureEmulationScope userGestureScope(m_inspectedPage, emulateUserGesture.value_or(false), dynamicDowncast<Document>(executionContext(injectedScript.globalObject())));
 | |
| +    JSC::JSGlobalObject* globalObject = injectedScript.globalObject();
 | |
| +    Document* document = globalObject ? activeDOMWindow(*globalObject).document() : nullptr;
 | |
| +    UserGestureEmulationScope userGestureScope(m_inspectedPage, emulateUserGesture.value_or(false), document);
 | |
|      return InspectorRuntimeAgent::evaluate(injectedScript, expression, objectGroup, WTFMove(includeCommandLineAPI), WTFMove(doNotPauseOnExceptionsAndMuteConsole), WTFMove(returnByValue), WTFMove(generatePreview), WTFMove(saveResult), WTFMove(emulateUserGesture));
 | |
|  }
 | |
|  
 | |
| -Protocol::ErrorStringOr<std::tuple<Ref<Protocol::Runtime::RemoteObject>, std::optional<bool> /* wasThrown */>> PageRuntimeAgent::callFunctionOn(const Protocol::Runtime::RemoteObjectId& objectId, const String& expression, RefPtr<JSON::Array>&& optionalArguments, std::optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& emulateUserGesture)
 | |
| +void PageRuntimeAgent::callFunctionOn(const Protocol::Runtime::RemoteObjectId& objectId, const String& expression, RefPtr<JSON::Array>&& optionalArguments, std::optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& emulateUserGesture, std::optional<bool>&& awaitPromise, Ref<CallFunctionOnCallback>&& callback)
 | |
|  {
 | |
|      auto injectedScript = injectedScriptManager().injectedScriptForObjectId(objectId);
 | |
| -    if (injectedScript.hasNoValue())
 | |
| -        return makeUnexpected("Missing injected script for given objectId"_s);
 | |
| +    if (injectedScript.hasNoValue()) {
 | |
| +        callback->sendFailure("Missing injected script for given objectId"_s);
 | |
| +        return;
 | |
| +    }
 | |
|  
 | |
| -    UserGestureEmulationScope userGestureScope(m_inspectedPage, emulateUserGesture.value_or(false), dynamicDowncast<Document>(executionContext(injectedScript.globalObject())));
 | |
| -    return InspectorRuntimeAgent::callFunctionOn(injectedScript, objectId, expression, WTFMove(optionalArguments), WTFMove(doNotPauseOnExceptionsAndMuteConsole), WTFMove(returnByValue), WTFMove(generatePreview), WTFMove(emulateUserGesture));
 | |
| +    JSC::JSGlobalObject* globalObject = injectedScript.globalObject();
 | |
| +    Document* document = globalObject ? activeDOMWindow(*globalObject).document() : nullptr;
 | |
| +    UserGestureEmulationScope userGestureScope(m_inspectedPage, emulateUserGesture.value_or(false), document);
 | |
| +    return InspectorRuntimeAgent::callFunctionOn(objectId, expression, WTFMove(optionalArguments), WTFMove(doNotPauseOnExceptionsAndMuteConsole), WTFMove(returnByValue), WTFMove(generatePreview), WTFMove(emulateUserGesture), WTFMove(awaitPromise), WTFMove(callback));
 | |
|  }
 | |
|  
 | |
|  } // namespace WebCore
 | |
| diff --git a/Source/WebCore/inspector/agents/page/PageRuntimeAgent.h b/Source/WebCore/inspector/agents/page/PageRuntimeAgent.h
 | |
| index 6aba3a2c6e8bbb7a0bca4f07824cf4de8ce36f8e..537e3b34d6405e412bf0e2350909c9afda06bed8 100644
 | |
| --- a/Source/WebCore/inspector/agents/page/PageRuntimeAgent.h
 | |
| +++ b/Source/WebCore/inspector/agents/page/PageRuntimeAgent.h
 | |
| @@ -54,25 +54,25 @@ public:
 | |
|      ~PageRuntimeAgent();
 | |
|  
 | |
|      // RuntimeBackendDispatcherHandler
 | |
| -    Inspector::Protocol::ErrorStringOr<void> enable();
 | |
| -    Inspector::Protocol::ErrorStringOr<void> disable();
 | |
| -    Inspector::Protocol::ErrorStringOr<std::tuple<Ref<Inspector::Protocol::Runtime::RemoteObject>, std::optional<bool> /* wasThrown */, std::optional<int> /* savedResultIndex */>> evaluate(const String& expression, const String& objectGroup, std::optional<bool>&& includeCommandLineAPI, std::optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, std::optional<Inspector::Protocol::Runtime::ExecutionContextId>&&, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& saveResult, std::optional<bool>&& emulateUserGesture);
 | |
| -    Inspector::Protocol::ErrorStringOr<std::tuple<Ref<Inspector::Protocol::Runtime::RemoteObject>, std::optional<bool> /* wasThrown */>> callFunctionOn(const Inspector::Protocol::Runtime::RemoteObjectId&, const String& expression, RefPtr<JSON::Array>&& arguments, std::optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& emulateUserGesture);
 | |
| +    Inspector::Protocol::ErrorStringOr<void> enable() override;
 | |
| +    Inspector::Protocol::ErrorStringOr<void> disable() override;
 | |
| +    Inspector::Protocol::ErrorStringOr<std::tuple<Ref<Inspector::Protocol::Runtime::RemoteObject>, std::optional<bool> /* wasThrown */, std::optional<int> /* savedResultIndex */>> evaluate(const String& expression, const String& objectGroup, std::optional<bool>&& includeCommandLineAPI, std::optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, std::optional<Inspector::Protocol::Runtime::ExecutionContextId>&&, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& saveResult, std::optional<bool>&& emulateUserGesture) override;
 | |
| +    void callFunctionOn(const Inspector::Protocol::Runtime::RemoteObjectId&, const String& functionDeclaration, RefPtr<JSON::Array>&& arguments, std::optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& emulateUserGesture, std::optional<bool>&& awaitPromise, Ref<CallFunctionOnCallback>&&) override;
 | |
|  
 | |
|      // InspectorInstrumentation
 | |
|      void frameNavigated(Frame&);
 | |
|      void didClearWindowObjectInWorld(Frame&, DOMWrapperWorld&);
 | |
| +    void didReceiveMainResourceError(Frame&);
 | |
|  
 | |
|  private:
 | |
| -    Inspector::InjectedScript injectedScriptForEval(Inspector::Protocol::ErrorString&, std::optional<Inspector::Protocol::Runtime::ExecutionContextId>&&);
 | |
| -    void muteConsole();
 | |
| -    void unmuteConsole();
 | |
| +    Inspector::InjectedScript injectedScriptForEval(Inspector::Protocol::ErrorString&, std::optional<Inspector::Protocol::Runtime::ExecutionContextId>&&) override;
 | |
| +    void muteConsole() override;
 | |
| +    void unmuteConsole() override;
 | |
|      void reportExecutionContextCreation();
 | |
|      void notifyContextCreated(const Inspector::Protocol::Network::FrameId&, JSC::JSGlobalObject*, const DOMWrapperWorld&, SecurityOrigin* = nullptr);
 | |
|  
 | |
|      std::unique_ptr<Inspector::RuntimeFrontendDispatcher> m_frontendDispatcher;
 | |
|      RefPtr<Inspector::RuntimeBackendDispatcher> m_backendDispatcher;
 | |
| -
 | |
|      InstrumentingAgents& m_instrumentingAgents;
 | |
|  
 | |
|      Page& m_inspectedPage;
 | |
| diff --git a/Source/WebCore/inspector/agents/page/UserGestureEmulationScope.h b/Source/WebCore/inspector/agents/page/UserGestureEmulationScope.h
 | |
| index 11bda04703c38c0ac3c81ca8d575c453ed3430a2..d1d0d7c2002e3e4021584e6493d91ac214cd5534 100644
 | |
| --- a/Source/WebCore/inspector/agents/page/UserGestureEmulationScope.h
 | |
| +++ b/Source/WebCore/inspector/agents/page/UserGestureEmulationScope.h
 | |
| @@ -39,6 +39,7 @@ namespace WebCore {
 | |
|  class ChromeClient;
 | |
|  class Document;
 | |
|  class Page;
 | |
| +class Document;
 | |
|  
 | |
|  class UserGestureEmulationScope {
 | |
|      WTF_MAKE_NONCOPYABLE(UserGestureEmulationScope);
 | |
| diff --git a/Source/WebCore/loader/CookieJar.h b/Source/WebCore/loader/CookieJar.h
 | |
| index 982691dd2dfe2f65201370a12302b5086703c126..4af72beb3b1405ffac78e89e7fbb2b14d6647903 100644
 | |
| --- a/Source/WebCore/loader/CookieJar.h
 | |
| +++ b/Source/WebCore/loader/CookieJar.h
 | |
| @@ -43,6 +43,7 @@ struct CookieRequestHeaderFieldProxy;
 | |
|  class NetworkStorageSession;
 | |
|  class StorageSessionProvider;
 | |
|  struct SameSiteInfo;
 | |
| +class ResourceLoader;
 | |
|  
 | |
|  class WEBCORE_EXPORT CookieJar : public RefCounted<CookieJar> {
 | |
|  public:
 | |
| @@ -66,6 +67,9 @@ public:
 | |
|      virtual void clearCache() { }
 | |
|      virtual void clearCacheForHost(const String&) { }
 | |
|  
 | |
| +    // Playwright.
 | |
| +    virtual void setCookieFromResponse(ResourceLoader&, const String&) { }
 | |
| +
 | |
|      virtual ~CookieJar();
 | |
|  protected:
 | |
|      static SameSiteInfo sameSiteInfo(const Document&, IsForDOMCookieAccess = IsForDOMCookieAccess::No);
 | |
| diff --git a/Source/WebCore/loader/DocumentLoader.cpp b/Source/WebCore/loader/DocumentLoader.cpp
 | |
| index ce453415884b3400185c8f9ebb400b01e7325447..367b38e1cc79da385772cee0dfc2776389ac9674 100644
 | |
| --- a/Source/WebCore/loader/DocumentLoader.cpp
 | |
| +++ b/Source/WebCore/loader/DocumentLoader.cpp
 | |
| @@ -1507,8 +1507,6 @@ void DocumentLoader::detachFromFrame()
 | |
|      if (!m_frame)
 | |
|          return;
 | |
|  
 | |
| -    InspectorInstrumentation::loaderDetachedFromFrame(*m_frame, *this);
 | |
| -
 | |
|      observeFrame(nullptr);
 | |
|  }
 | |
|  
 | |
| diff --git a/Source/WebCore/loader/DocumentLoader.h b/Source/WebCore/loader/DocumentLoader.h
 | |
| index d985eb2ec8f94e3197ef6055c5ae7d1f39f3fbf1..fc02b3e3239c890a25ba099985157ea0f48669d9 100644
 | |
| --- a/Source/WebCore/loader/DocumentLoader.h
 | |
| +++ b/Source/WebCore/loader/DocumentLoader.h
 | |
| @@ -181,9 +181,13 @@ public:
 | |
|  
 | |
|      WEBCORE_EXPORT virtual void detachFromFrame();
 | |
|  
 | |
| +    virtual void replacedByFragmentNavigation(Frame&) { }
 | |
| +
 | |
|      WEBCORE_EXPORT FrameLoader* frameLoader() const;
 | |
|      WEBCORE_EXPORT SubresourceLoader* mainResourceLoader() const;
 | |
|      WEBCORE_EXPORT RefPtr<FragmentedSharedBuffer> mainResourceData() const;
 | |
| +
 | |
| +    virtual uint64_t loaderIDForInspector() { return 0; }
 | |
|      
 | |
|      DocumentWriter& writer() const { return m_writer; }
 | |
|  
 | |
| diff --git a/Source/WebCore/loader/FrameLoader.cpp b/Source/WebCore/loader/FrameLoader.cpp
 | |
| index 9737b7924e0be7de6b92ce374f82c98d40adc8dd..f58147df22978db38efef7a3e9555a3d2c6fed39 100644
 | |
| --- a/Source/WebCore/loader/FrameLoader.cpp
 | |
| +++ b/Source/WebCore/loader/FrameLoader.cpp
 | |
| @@ -1167,6 +1167,7 @@ void FrameLoader::loadInSameDocument(URL url, RefPtr<SerializedScriptValue> stat
 | |
|      }
 | |
|  
 | |
|      m_client->dispatchDidNavigateWithinPage();
 | |
| +    InspectorInstrumentation::didNavigateWithinPage(m_frame);
 | |
|  
 | |
|      m_frame.document()->statePopped(stateObject ? stateObject.releaseNonNull() : SerializedScriptValue::nullValue());
 | |
|      m_client->dispatchDidPopStateWithinPage();
 | |
| @@ -1603,6 +1604,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 };
 | |
|  
 | |
| @@ -1632,7 +1635,9 @@ void FrameLoader::loadWithDocumentLoader(DocumentLoader* loader, FrameLoadType t
 | |
|      }
 | |
|  
 | |
|      RELEASE_ASSERT(!isBackForwardLoadType(policyChecker().loadType()) || history().provisionalItem());
 | |
| +    InspectorInstrumentation::willCheckNavigationPolicy(m_frame);
 | |
|      policyChecker().checkNavigationPolicy(ResourceRequest(loader->request()), ResourceResponse { } /* redirectResponse */, loader, WTFMove(formState), [this, protectedFrame = Ref { m_frame }, allowNavigationToInvalidURL, completionHandler = completionHandlerCaller.release()] (const ResourceRequest& request, WeakPtr<FormState>&& formState, NavigationPolicyDecision navigationPolicyDecision) mutable {
 | |
| +        InspectorInstrumentation::didCheckNavigationPolicy(m_frame, navigationPolicyDecision != NavigationPolicyDecision::ContinueLoad);
 | |
|          continueLoadAfterNavigationPolicy(request, formState.get(), navigationPolicyDecision, allowNavigationToInvalidURL);
 | |
|          completionHandler();
 | |
|      }, PolicyDecisionMode::Asynchronous);
 | |
| @@ -2800,12 +2805,17 @@ String FrameLoader::userAgent(const URL& url) const
 | |
|  
 | |
|  String FrameLoader::navigatorPlatform() const
 | |
|  {
 | |
| +    String platform;
 | |
| +
 | |
|      if (auto* documentLoader = m_frame.mainFrame().loader().activeDocumentLoader()) {
 | |
|          auto& customNavigatorPlatform = documentLoader->customNavigatorPlatform();
 | |
|          if (!customNavigatorPlatform.isEmpty())
 | |
| -            return customNavigatorPlatform;
 | |
| +            platform = customNavigatorPlatform;
 | |
|      }
 | |
| -    return String();
 | |
| +
 | |
| +    InspectorInstrumentation::applyPlatformOverride(m_frame, platform);
 | |
| +
 | |
| +    return platform;
 | |
|  }
 | |
|  
 | |
|  void FrameLoader::dispatchOnloadEvents()
 | |
| @@ -3212,6 +3222,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)
 | |
| @@ -3982,9 +3994,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)
 | |
| @@ -3993,13 +4002,13 @@ void FrameLoader::dispatchDidClearWindowObjectsInAllWorlds()
 | |
|  
 | |
|  void FrameLoader::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld& world)
 | |
|  {
 | |
| -    if (!m_frame.script().canExecuteScripts(NotAboutToExecuteScript) || !m_frame.windowProxy().existingJSWindowProxy(world))
 | |
| -        return;
 | |
| +    if (m_frame.windowProxy().existingJSWindowProxy(world)) {
 | |
| +        if (m_frame.script().canExecuteScripts(NotAboutToExecuteScript))
 | |
| +            m_client->dispatchDidClearWindowObjectInWorld(world);
 | |
|  
 | |
| -    m_client->dispatchDidClearWindowObjectInWorld(world);
 | |
| -
 | |
| -    if (Page* page = m_frame.page())
 | |
| -        page->inspectorController().didClearWindowObjectInWorld(m_frame, world);
 | |
| +        if (Page* page = m_frame.page())
 | |
| +            page->inspectorController().didClearWindowObjectInWorld(m_frame, world);
 | |
| +    }
 | |
|  
 | |
|      InspectorInstrumentation::didClearWindowObjectInWorld(m_frame, world);
 | |
|  }
 | |
| diff --git a/Source/WebCore/loader/LoaderStrategy.h b/Source/WebCore/loader/LoaderStrategy.h
 | |
| index 29d2e3f46140aaa51160e6a28562f370e371eb21..676ddc9369050c19454fbf5faffac2b27e0fad41 100644
 | |
| --- a/Source/WebCore/loader/LoaderStrategy.h
 | |
| +++ b/Source/WebCore/loader/LoaderStrategy.h
 | |
| @@ -86,6 +86,7 @@ public:
 | |
|  
 | |
|      virtual bool isOnLine() const = 0;
 | |
|      virtual void addOnlineStateChangeListener(Function<void(bool)>&&) = 0;
 | |
| +    virtual void setEmulateOfflineState(bool) {};
 | |
|  
 | |
|      virtual bool shouldPerformSecurityChecks() const { return false; }
 | |
|      virtual bool havePerformedSecurityChecks(const ResourceResponse&) const { return false; }
 | |
| diff --git a/Source/WebCore/loader/PolicyChecker.cpp b/Source/WebCore/loader/PolicyChecker.cpp
 | |
| index 24c07a5b19379f2bd9c8532c6e1d99deae5a0045..7e72901d911a1e918b12292a3c2cd72a84941506 100644
 | |
| --- a/Source/WebCore/loader/PolicyChecker.cpp
 | |
| +++ b/Source/WebCore/loader/PolicyChecker.cpp
 | |
| @@ -46,6 +46,7 @@
 | |
|  #include "HTMLFormElement.h"
 | |
|  #include "HTMLFrameOwnerElement.h"
 | |
|  #include "HTMLPlugInElement.h"
 | |
| +#include "InspectorInstrumentation.h"
 | |
|  #include "Logging.h"
 | |
|  #include "ThreadableBlobRegistry.h"
 | |
|  #include <wtf/CompletionHandler.h>
 | |
| diff --git a/Source/WebCore/loader/ProgressTracker.cpp b/Source/WebCore/loader/ProgressTracker.cpp
 | |
| index a2c6d72b5ba0f04a49ca6dc710ef6fa5e0125c33..759b0d34b7db839027063a1b6ce8fb0f7ee2acd4 100644
 | |
| --- a/Source/WebCore/loader/ProgressTracker.cpp
 | |
| +++ b/Source/WebCore/loader/ProgressTracker.cpp
 | |
| @@ -160,6 +160,8 @@ void ProgressTracker::progressCompleted(Frame& frame)
 | |
|      if (!m_numProgressTrackedFrames || m_originatingProgressFrame == &frame)
 | |
|          finalProgressComplete();
 | |
|  
 | |
| +    InspectorInstrumentation::frameStoppedLoading(frame);
 | |
| +
 | |
|      m_client->didChangeEstimatedProgress();
 | |
|  }
 | |
|  
 | |
| @@ -186,8 +188,6 @@ void ProgressTracker::finalProgressComplete()
 | |
|      m_client->progressFinished(*frame);
 | |
|      m_page.progressFinished(*frame);
 | |
|      frame->loader().loadProgressingStatusChanged();
 | |
| -
 | |
| -    InspectorInstrumentation::frameStoppedLoading(*frame);
 | |
|  }
 | |
|  
 | |
|  void ProgressTracker::incrementProgress(ResourceLoaderIdentifier identifier, const ResourceResponse& response)
 | |
| diff --git a/Source/WebCore/page/ChromeClient.h b/Source/WebCore/page/ChromeClient.h
 | |
| index 4a65cd84e5b3c627f16712427d8059a73c759403..90a6262005694741aaaa59c869d35d5cd539a1eb 100644
 | |
| --- a/Source/WebCore/page/ChromeClient.h
 | |
| +++ b/Source/WebCore/page/ChromeClient.h
 | |
| @@ -320,7 +320,7 @@ public:
 | |
|  #endif
 | |
|  
 | |
|  #if ENABLE(ORIENTATION_EVENTS)
 | |
| -    virtual int deviceOrientation() const = 0;
 | |
| +    virtual int deviceOrientation() const { return 0; }
 | |
|  #endif
 | |
|  
 | |
|  #if ENABLE(INPUT_TYPE_COLOR)
 | |
| diff --git a/Source/WebCore/page/EventHandler.cpp b/Source/WebCore/page/EventHandler.cpp
 | |
| index ac725d46758f9c325a9f84075aba43c0166bb37d..ac7e73d26ac40e498bc75d64e00712d1d42d7fc0 100644
 | |
| --- a/Source/WebCore/page/EventHandler.cpp
 | |
| +++ b/Source/WebCore/page/EventHandler.cpp
 | |
| @@ -142,6 +142,7 @@
 | |
|  
 | |
|  #if ENABLE(TOUCH_EVENTS) && !ENABLE(IOS_TOUCH_EVENTS)
 | |
|  #include "PlatformTouchEvent.h"
 | |
| +#include "PointerCaptureController.h"
 | |
|  #endif
 | |
|  
 | |
|  #if ENABLE(MAC_GESTURE_EVENTS)
 | |
| @@ -808,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 +849,6 @@ VisiblePosition EventHandler::selectionExtentRespectingEditingBoundary(const Vis
 | |
|      return adjustedTarget->renderer()->positionForPoint(LayoutPoint(selectionEndPoint), nullptr);
 | |
|  }
 | |
|  
 | |
| -#if ENABLE(DRAG_SUPPORT)
 | |
| -
 | |
|  #if !PLATFORM(IOS_FAMILY)
 | |
|  
 | |
|  bool EventHandler::supportsSelectionUpdatesOnMouseDrag() const
 | |
| @@ -873,8 +870,10 @@ bool EventHandler::handleMouseDraggedEvent(const MouseEventWithHitTestResults& e
 | |
|  
 | |
|      Ref<Frame> protectedFrame(m_frame);
 | |
|  
 | |
| +#if ENABLE(DRAG_SUPPORT)
 | |
|      if (handleDrag(event, checkDragHysteresis))
 | |
|          return true;
 | |
| +#endif
 | |
|  
 | |
|      RefPtr targetNode = event.targetNode();
 | |
|      if (event.event().button() != LeftButton || !targetNode)
 | |
| @@ -895,7 +894,9 @@ bool EventHandler::handleMouseDraggedEvent(const MouseEventWithHitTestResults& e
 | |
|      ASSERT(mouseDownMayStartSelect() || m_mouseDownMayStartAutoscroll);
 | |
|  #endif
 | |
|  
 | |
| +#if ENABLE(DRAG_SUPPORT)
 | |
|      m_mouseDownMayStartDrag = false;
 | |
| +#endif
 | |
|  
 | |
|      if (m_mouseDownMayStartAutoscroll && !panScrollInProgress()) {
 | |
|          m_autoscrollController->startAutoscrollForSelection(renderer);
 | |
| @@ -912,6 +913,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 +946,8 @@ bool EventHandler::eventMayStartDrag(const PlatformMouseEvent& event) const
 | |
|      return targetElement && page->dragController().draggableElement(&m_frame, targetElement.get(), result.roundedPointInInnerNodeFrame(), state);
 | |
|  }
 | |
|  
 | |
| +#endif // ENABLE(DRAG_SUPPORT)
 | |
| +
 | |
|  void EventHandler::updateSelectionForMouseDrag()
 | |
|  {
 | |
|      if (!supportsSelectionUpdatesOnMouseDrag())
 | |
| @@ -1037,7 +1042,6 @@ void EventHandler::updateSelectionForMouseDrag(const HitTestResult& hitTestResul
 | |
|      if (oldSelection != newSelection && ImageOverlay::isOverlayText(newSelection.start().containerNode()) && ImageOverlay::isOverlayText(newSelection.end().containerNode()))
 | |
|          invalidateClick();
 | |
|  }
 | |
| -#endif // ENABLE(DRAG_SUPPORT)
 | |
|  
 | |
|  void EventHandler::lostMouseCapture()
 | |
|  {
 | |
| @@ -1085,9 +1089,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;
 | |
| @@ -2055,10 +2057,8 @@ bool EventHandler::handleMouseMoveEvent(const PlatformMouseEvent& platformMouseE
 | |
|      
 | |
|      swallowEvent = !dispatchMouseEvent(eventNames().mousemoveEvent, mouseEvent.targetNode(), 0, platformMouseEvent, FireMouseOverOut::Yes);
 | |
|  
 | |
| -#if ENABLE(DRAG_SUPPORT)
 | |
|      if (!swallowEvent)
 | |
|          swallowEvent = handleMouseDraggedEvent(mouseEvent);
 | |
| -#endif
 | |
|  
 | |
|      return swallowEvent;
 | |
|  }
 | |
| @@ -4146,7 +4146,14 @@ bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event, CheckDr
 | |
|      if (!m_frame.document())
 | |
|          return false;
 | |
|  
 | |
| -    dragState().dataTransfer = DataTransfer::createForDrag(*m_frame.document());
 | |
| +#if PLATFORM(MAC)
 | |
| +    auto* page = m_frame.page();
 | |
| +    if (page && !page->overrideDragPasteboardName().isEmpty())
 | |
| +        dragState().dataTransfer = DataTransfer::createForDrag(*m_frame.document(), page->overrideDragPasteboardName());
 | |
| +    else
 | |
| +#endif
 | |
| +        dragState().dataTransfer = DataTransfer::createForDrag(*m_frame.document());
 | |
| +
 | |
|      auto hasNonDefaultPasteboardData = HasNonDefaultPasteboardData::No;
 | |
|      
 | |
|      if (dragState().shouldDispatchEvents) {
 | |
| @@ -4536,7 +4543,8 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
 | |
|              allTouchReleased = false;
 | |
|      }
 | |
|  
 | |
| -    for (auto& point : points) {
 | |
| +    for (unsigned index = 0; index < points.size(); index++) {
 | |
| +        auto& point = points[index];
 | |
|          PlatformTouchPoint::State pointState = point.state();
 | |
|          LayoutPoint pagePoint = documentPointForWindowPoint(m_frame, point.pos());
 | |
|  
 | |
| @@ -4663,6 +4671,9 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
 | |
|              changedTouches[pointState].m_touches->append(WTFMove(touch));
 | |
|              changedTouches[pointState].m_targets.add(touchTarget);
 | |
|          }
 | |
| +        document.page()->pointerCaptureController().dispatchEventForTouchAtIndex(
 | |
| +            *touchTarget, event, index, index == 0, *document.windowProxy());
 | |
| +
 | |
|      }
 | |
|      m_touchPressed = touches->length() > 0;
 | |
|      if (allTouchReleased)
 | |
| diff --git a/Source/WebCore/page/EventHandler.h b/Source/WebCore/page/EventHandler.h
 | |
| index 51d36bd866b1d5f1daea4b02ce86b213eaa44adb..fd3cd3dad309416f41a0a0bcac22c9e50b0abd8d 100644
 | |
| --- a/Source/WebCore/page/EventHandler.h
 | |
| +++ b/Source/WebCore/page/EventHandler.h
 | |
| @@ -135,9 +135,7 @@ public:
 | |
|  
 | |
|      WEBCORE_EXPORT VisiblePosition selectionExtentRespectingEditingBoundary(const VisibleSelection&, const LayoutPoint&, Node*);
 | |
|  
 | |
| -#if ENABLE(DRAG_SUPPORT)
 | |
|      void updateSelectionForMouseDrag();
 | |
| -#endif
 | |
|  
 | |
|  #if ENABLE(PAN_SCROLLING)
 | |
|      void didPanScrollStart();
 | |
| @@ -385,10 +383,8 @@ private:
 | |
|      bool startKeyboardScrolling(KeyboardEvent&);
 | |
|      void stopKeyboardScrolling();
 | |
|  
 | |
| -#if ENABLE(DRAG_SUPPORT)
 | |
|      bool handleMouseDraggedEvent(const MouseEventWithHitTestResults&, CheckDragHysteresis = ShouldCheckDragHysteresis);
 | |
|      bool shouldAllowMouseDownToStartDrag() const;
 | |
| -#endif
 | |
|  
 | |
|      WEBCORE_EXPORT bool handleMouseReleaseEvent(const MouseEventWithHitTestResults&);
 | |
|  
 | |
| @@ -488,10 +484,8 @@ private:
 | |
|      void defaultTabEventHandler(KeyboardEvent&);
 | |
|      void defaultArrowEventHandler(FocusDirection, KeyboardEvent&);
 | |
|  
 | |
| -#if ENABLE(DRAG_SUPPORT)
 | |
|      OptionSet<DragSourceAction> updateDragSourceActionsAllowed() const;
 | |
|      bool supportsSelectionUpdatesOnMouseDrag() const;
 | |
| -#endif
 | |
|  
 | |
|      // The following are called at the beginning of handleMouseUp and handleDrag.  
 | |
|      // If they return true it indicates that they have consumed the event.
 | |
| @@ -499,9 +493,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);
 | |
|      
 | |
| @@ -593,8 +588,8 @@ private:
 | |
|      Timer m_autoHideCursorTimer;
 | |
|  #endif
 | |
|  
 | |
| -#if ENABLE(DRAG_SUPPORT)
 | |
|      LayoutPoint m_dragStartPosition;
 | |
| +#if ENABLE(DRAG_SUPPORT)
 | |
|      RefPtr<Element> m_dragTarget;
 | |
|      bool m_mouseDownMayStartDrag { false };
 | |
|      bool m_dragMayStartSelectionInstead { false };
 | |
| diff --git a/Source/WebCore/page/EventSource.cpp b/Source/WebCore/page/EventSource.cpp
 | |
| index 300218f40e04b7b361a1f86c11060aee68898b9d..2117c080ba43d26e32d21cc73039c9597ff17fec 100644
 | |
| --- a/Source/WebCore/page/EventSource.cpp
 | |
| +++ b/Source/WebCore/page/EventSource.cpp
 | |
| @@ -36,6 +36,7 @@
 | |
|  #include "CachedResourceRequestInitiators.h"
 | |
|  #include "ContentSecurityPolicy.h"
 | |
|  #include "EventNames.h"
 | |
| +#include "InspectorNetworkAgent.h"
 | |
|  #include "MessageEvent.h"
 | |
|  #include "ResourceError.h"
 | |
|  #include "ResourceRequest.h"
 | |
| diff --git a/Source/WebCore/page/Frame.cpp b/Source/WebCore/page/Frame.cpp
 | |
| index edf6ed1889560fd4332592d35d52fab2b6858e1c..2c3083caecd1f4281e970c3c531844ae33e433f0 100644
 | |
| --- a/Source/WebCore/page/Frame.cpp
 | |
| +++ b/Source/WebCore/page/Frame.cpp
 | |
| @@ -39,6 +39,7 @@
 | |
|  #include "CachedResourceLoader.h"
 | |
|  #include "Chrome.h"
 | |
|  #include "ChromeClient.h"
 | |
| +#include "ComposedTreeIterator.h"
 | |
|  #include "DOMWindow.h"
 | |
|  #include "DocumentTimelinesController.h"
 | |
|  #include "DocumentType.h"
 | |
| @@ -73,6 +74,7 @@
 | |
|  #include "NavigationScheduler.h"
 | |
|  #include "Navigator.h"
 | |
|  #include "NodeList.h"
 | |
| +#include "NodeRenderStyle.h"
 | |
|  #include "NodeTraversal.h"
 | |
|  #include "Page.h"
 | |
|  #include "ProcessWarming.h"
 | |
| @@ -191,6 +193,7 @@ Frame::Frame(Page& page, HTMLFrameOwnerElement* ownerElement, UniqueRef<FrameLoa
 | |
|  void Frame::init()
 | |
|  {
 | |
|      m_loader->init();
 | |
| +    InspectorInstrumentation::frameAttached(this);
 | |
|  }
 | |
|  
 | |
|  Ref<Frame> Frame::create(Page* page, HTMLFrameOwnerElement* ownerElement, UniqueRef<FrameLoaderClient>&& client)
 | |
| @@ -374,7 +377,7 @@ void Frame::orientationChanged()
 | |
|  int Frame::orientation() const
 | |
|  {
 | |
|      if (m_page)
 | |
| -        return m_page->chrome().client().deviceOrientation();
 | |
| +        return m_page->orientation();
 | |
|      return 0;
 | |
|  }
 | |
|  #endif // ENABLE(ORIENTATION_EVENTS)
 | |
| @@ -1171,6 +1174,362 @@ DataDetectionResultsStorage& Frame::dataDetectionResults()
 | |
|  
 | |
|  #endif
 | |
|  
 | |
| +#if !PLATFORM(IOS_FAMILY)
 | |
| +
 | |
| +void Frame::betterApproximateNode(const IntPoint& testPoint, const NodeQualifier& nodeQualifierFunction, Node*& best, Node* failedNode, IntPoint& bestPoint, IntRect& bestRect, const IntRect& testRect)
 | |
| +{
 | |
| +    IntRect candidateRect;
 | |
| +    constexpr OptionSet<HitTestRequest::Type> hitType { HitTestRequest::Type::ReadOnly, HitTestRequest::Type::Active, HitTestRequest::Type::DisallowUserAgentShadowContent, HitTestRequest::Type::AllowVisibleChildFrameContentOnly };
 | |
| +    auto* candidate = nodeQualifierFunction(eventHandler().hitTestResultAtPoint(testPoint, hitType), failedNode, &candidateRect);
 | |
| +
 | |
| +    // Bail if we have no candidate, or the candidate is already equal to our current best node,
 | |
| +    // or our candidate is the avoidedNode and there is a current best node.
 | |
| +    if (!candidate || candidate == best)
 | |
| +        return;
 | |
| +
 | |
| +    // The document should never be considered the best alternative.
 | |
| +    if (candidate->isDocumentNode())
 | |
| +        return;
 | |
| +
 | |
| +    if (best) {
 | |
| +        IntRect bestIntersect = intersection(testRect, bestRect);
 | |
| +        IntRect candidateIntersect = intersection(testRect, candidateRect);
 | |
| +        // if the candidate intersection is smaller than the current best intersection, bail.
 | |
| +        if (candidateIntersect.width() * candidateIntersect.height() <= bestIntersect.width() * bestIntersect.height())
 | |
| +            return;
 | |
| +    }
 | |
| +
 | |
| +    // At this point we either don't have a previous best, or our current candidate has a better intersection.
 | |
| +    best = candidate;
 | |
| +    bestPoint = testPoint;
 | |
| +    bestRect = candidateRect;
 | |
| +}
 | |
| +
 | |
| +bool Frame::hitTestResultAtViewportLocation(const FloatPoint& viewportLocation, HitTestResult& hitTestResult, IntPoint& center)
 | |
| +{
 | |
| +    if (!m_doc || !m_doc->renderView())
 | |
| +        return false;
 | |
| +
 | |
| +    FrameView* view = m_view.get();
 | |
| +    if (!view)
 | |
| +        return false;
 | |
| +
 | |
| +    center = view->windowToContents(roundedIntPoint(viewportLocation));
 | |
| +    constexpr OptionSet<HitTestRequest::Type> hitType { HitTestRequest::Type::ReadOnly, HitTestRequest::Type::Active, HitTestRequest::Type::DisallowUserAgentShadowContent, HitTestRequest::Type::AllowVisibleChildFrameContentOnly };
 | |
| +    hitTestResult = eventHandler().hitTestResultAtPoint(center, hitType);
 | |
| +    return true;
 | |
| +}
 | |
| +
 | |
| +Node* Frame::qualifyingNodeAtViewportLocation(const FloatPoint& viewportLocation, FloatPoint& adjustedViewportLocation, const NodeQualifier& nodeQualifierFunction, ShouldApproximate shouldApproximate, ShouldFindRootEditableElement shouldFindRootEditableElement)
 | |
| +{
 | |
| +    adjustedViewportLocation = viewportLocation;
 | |
| +
 | |
| +    IntPoint testCenter;
 | |
| +    HitTestResult candidateInfo;
 | |
| +    if (!hitTestResultAtViewportLocation(viewportLocation, candidateInfo, testCenter))
 | |
| +        return nullptr;
 | |
| +
 | |
| +    IntPoint bestPoint = testCenter;
 | |
| +
 | |
| +    // We have the candidate node at the location, check whether it or one of its ancestors passes
 | |
| +    // the qualifier function, which typically checks if the node responds to a particular event type.
 | |
| +    Node* approximateNode = nodeQualifierFunction(candidateInfo, 0, 0);
 | |
| +
 | |
| +    if (shouldFindRootEditableElement == ShouldFindRootEditableElement::Yes && approximateNode && approximateNode->isContentEditable()) {
 | |
| +        // If we are in editable content, we look for the root editable element.
 | |
| +        approximateNode = approximateNode->rootEditableElement();
 | |
| +        // If we have a focusable node, there is no need to approximate.
 | |
| +        if (approximateNode)
 | |
| +            shouldApproximate = ShouldApproximate::No;
 | |
| +    }
 | |
| +
 | |
| +    float scale = page() ? page()->pageScaleFactor() : 1;
 | |
| +#if PLATFORM(IOS_FAMILY)
 | |
| +    float ppiFactor = screenPPIFactor();
 | |
| +#else
 | |
| +    float ppiFactor = 326; // most popular iPhone PPI
 | |
| +#endif
 | |
| +
 | |
| +    static const float unscaledSearchRadius = 15;
 | |
| +    int searchRadius = static_cast<int>(unscaledSearchRadius * ppiFactor / scale);
 | |
| +
 | |
| +    if (approximateNode && shouldApproximate == ShouldApproximate::Yes) {
 | |
| +        const float testOffsets[] = {
 | |
| +            -.3f, -.3f,
 | |
| +            -.6f, -.6f,
 | |
| +            +.3f, +.3f,
 | |
| +            -.9f, -.9f,
 | |
| +        };
 | |
| +
 | |
| +        Node* originalApproximateNode = approximateNode;
 | |
| +        for (unsigned n = 0; n < WTF_ARRAY_LENGTH(testOffsets); n += 2) {
 | |
| +            IntSize testOffset(testOffsets[n] * searchRadius, testOffsets[n + 1] * searchRadius);
 | |
| +            IntPoint testPoint = testCenter + testOffset;
 | |
| +
 | |
| +            constexpr OptionSet<HitTestRequest::Type> hitType { HitTestRequest::Type::ReadOnly, HitTestRequest::Type::Active, HitTestRequest::Type::DisallowUserAgentShadowContent, HitTestRequest::Type::AllowChildFrameContent };
 | |
| +            auto candidateInfo = eventHandler().hitTestResultAtPoint(testPoint, hitType);
 | |
| +            Node* candidateNode = nodeQualifierFunction(candidateInfo, 0, 0);
 | |
| +            if (candidateNode && candidateNode->isDescendantOf(originalApproximateNode)) {
 | |
| +                approximateNode = candidateNode;
 | |
| +                bestPoint = testPoint;
 | |
| +                break;
 | |
| +            }
 | |
| +        }
 | |
| +    } else if (!approximateNode && shouldApproximate == ShouldApproximate::Yes) {
 | |
| +        // Grab the closest parent element of our failed candidate node.
 | |
| +        Node* candidate = candidateInfo.innerNode();
 | |
| +        Node* failedNode = candidate;
 | |
| +
 | |
| +        while (candidate && !candidate->isElementNode())
 | |
| +            candidate = candidate->parentInComposedTree();
 | |
| +
 | |
| +        if (candidate)
 | |
| +            failedNode = candidate;
 | |
| +
 | |
| +        // The center point was tested earlier.
 | |
| +        const float testOffsets[] = {
 | |
| +            -.3f, -.3f,
 | |
| +            +.3f, -.3f,
 | |
| +            -.3f, +.3f,
 | |
| +            +.3f, +.3f,
 | |
| +            -.6f, -.6f,
 | |
| +            +.6f, -.6f,
 | |
| +            -.6f, +.6f,
 | |
| +            +.6f, +.6f,
 | |
| +            -1.f, 0,
 | |
| +            +1.f, 0,
 | |
| +            0, +1.f,
 | |
| +            0, -1.f,
 | |
| +        };
 | |
| +        IntRect bestFrame;
 | |
| +        IntRect testRect(testCenter, IntSize());
 | |
| +        testRect.inflate(searchRadius);
 | |
| +        int currentTestRadius = 0;
 | |
| +        for (unsigned n = 0; n < WTF_ARRAY_LENGTH(testOffsets); n += 2) {
 | |
| +            IntSize testOffset(testOffsets[n] * searchRadius, testOffsets[n + 1] * searchRadius);
 | |
| +            IntPoint testPoint = testCenter + testOffset;
 | |
| +            int testRadius = std::max(abs(testOffset.width()), abs(testOffset.height()));
 | |
| +            if (testRadius > currentTestRadius) {
 | |
| +                // Bail out with the best match within a radius
 | |
| +                currentTestRadius = testRadius;
 | |
| +                if (approximateNode)
 | |
| +                    break;
 | |
| +            }
 | |
| +            betterApproximateNode(testPoint, nodeQualifierFunction, approximateNode, failedNode, bestPoint, bestFrame, testRect);
 | |
| +        }
 | |
| +    }
 | |
| +
 | |
| +    if (approximateNode) {
 | |
| +        IntPoint p = m_view->contentsToWindow(bestPoint);
 | |
| +        adjustedViewportLocation = p;
 | |
| +        if (shouldFindRootEditableElement == ShouldFindRootEditableElement::Yes && approximateNode->isContentEditable()) {
 | |
| +            // When in editable content, look for the root editable node again,
 | |
| +            // since this could be the node found with the approximation.
 | |
| +            approximateNode = approximateNode->rootEditableElement();
 | |
| +        }
 | |
| +    }
 | |
| +
 | |
| +    return approximateNode;
 | |
| +}
 | |
| +
 | |
| +Node* Frame::deepestNodeAtLocation(const FloatPoint& viewportLocation)
 | |
| +{
 | |
| +    IntPoint center;
 | |
| +    HitTestResult hitTestResult;
 | |
| +    if (!hitTestResultAtViewportLocation(viewportLocation, hitTestResult, center))
 | |
| +        return nullptr;
 | |
| +
 | |
| +    return hitTestResult.innerNode();
 | |
| +}
 | |
| +
 | |
| +static bool nodeIsMouseFocusable(Node& node)
 | |
| +{
 | |
| +    if (!is<Element>(node))
 | |
| +        return false;
 | |
| +
 | |
| +    auto& element = downcast<Element>(node);
 | |
| +    if (element.isMouseFocusable())
 | |
| +        return true;
 | |
| +
 | |
| +    if (RefPtr shadowRoot = element.shadowRoot()) {
 | |
| +        if (shadowRoot->delegatesFocus()) {
 | |
| +            for (auto& node : composedTreeDescendants(element)) {
 | |
| +                if (is<Element>(node) && downcast<Element>(node).isMouseFocusable())
 | |
| +                    return true;
 | |
| +            }
 | |
| +        }
 | |
| +    }
 | |
| +
 | |
| +    return false;
 | |
| +}
 | |
| +
 | |
| +static bool nodeWillRespondToMouseEvents(Node& node)
 | |
| +{
 | |
| +    return node.willRespondToMouseClickEvents() || node.willRespondToMouseMoveEvents() || nodeIsMouseFocusable(node);
 | |
| +}
 | |
| +
 | |
| +Node* Frame::approximateNodeAtViewportLocationLegacy(const FloatPoint& viewportLocation, FloatPoint& adjustedViewportLocation)
 | |
| +{
 | |
| +    // This function is only used for UIWebView.
 | |
| +    auto&& ancestorRespondingToClickEvents = [](const HitTestResult& hitTestResult, Node* terminationNode, IntRect* nodeBounds) -> Node* {
 | |
| +        bool bodyHasBeenReached = false;
 | |
| +        bool pointerCursorStillValid = true;
 | |
| +
 | |
| +        if (nodeBounds)
 | |
| +            *nodeBounds = IntRect();
 | |
| +
 | |
| +        auto node = hitTestResult.innerNode();
 | |
| +        if (!node)
 | |
| +            return nullptr;
 | |
| +
 | |
| +        Node* pointerCursorNode = nullptr;
 | |
| +        for (; node && node != terminationNode; node = node->parentInComposedTree()) {
 | |
| +            // We only accept pointer nodes before reaching the body tag.
 | |
| +            if (node->hasTagName(HTMLNames::bodyTag)) {
 | |
| +                // Make sure we cover the case of an empty editable body.
 | |
| +                if (!pointerCursorNode && node->isContentEditable())
 | |
| +                    pointerCursorNode = node;
 | |
| +                bodyHasBeenReached = true;
 | |
| +                pointerCursorStillValid = false;
 | |
| +            }
 | |
| +
 | |
| +            // If we already have a pointer, and we reach a table, don't accept it.
 | |
| +            if (pointerCursorNode && (node->hasTagName(HTMLNames::tableTag) || node->hasTagName(HTMLNames::tbodyTag)))
 | |
| +                pointerCursorStillValid = false;
 | |
| +
 | |
| +            // If we haven't reached the body, and we are still paying attention to pointer cursors, and the node has a pointer cursor.
 | |
| +            if (pointerCursorStillValid && node->renderStyle() && node->renderStyle()->cursor() == CursorType::Pointer)
 | |
| +                pointerCursorNode = node;
 | |
| +            else if (pointerCursorNode) {
 | |
| +                // We want the lowest unbroken chain of pointer cursors.
 | |
| +                pointerCursorStillValid = false;
 | |
| +            }
 | |
| +
 | |
| +            if (nodeWillRespondToMouseEvents(*node)) {
 | |
| +                // If we're at the body or higher, use the pointer cursor node (which may be null).
 | |
| +                if (bodyHasBeenReached)
 | |
| +                    node = pointerCursorNode;
 | |
| +
 | |
| +                // If we are interested about the frame, use it.
 | |
| +                if (nodeBounds) {
 | |
| +                    // This is a check to see whether this node is an area element. The only way this can happen is if this is the first check.
 | |
| +                    if (node == hitTestResult.innerNode() && node != hitTestResult.innerNonSharedNode() && is<HTMLAreaElement>(*node))
 | |
| +                        *nodeBounds = snappedIntRect(downcast<HTMLAreaElement>(*node).computeRect(hitTestResult.innerNonSharedNode()->renderer()));
 | |
| +                    else if (node && node->renderer())
 | |
| +                        *nodeBounds = node->renderer()->absoluteBoundingBoxRect(true);
 | |
| +                }
 | |
| +
 | |
| +                return node;
 | |
| +            }
 | |
| +        }
 | |
| +
 | |
| +        return nullptr;
 | |
| +    };
 | |
| +
 | |
| +    return qualifyingNodeAtViewportLocation(viewportLocation, adjustedViewportLocation, WTFMove(ancestorRespondingToClickEvents), ShouldApproximate::Yes);
 | |
| +}
 | |
| +
 | |
| +static inline NodeQualifier ancestorRespondingToClickEventsNodeQualifier(SecurityOrigin* securityOrigin = nullptr)
 | |
| +{
 | |
| +    return [securityOrigin](const HitTestResult& hitTestResult, Node* terminationNode, IntRect* nodeBounds) -> Node* {
 | |
| +        if (nodeBounds)
 | |
| +            *nodeBounds = IntRect();
 | |
| +
 | |
| +        auto node = hitTestResult.innerNode();
 | |
| +        if (!node || (securityOrigin && !securityOrigin->isSameOriginAs(node->document().securityOrigin())))
 | |
| +            return nullptr;
 | |
| +
 | |
| +        for (; node && node != terminationNode; node = node->parentInComposedTree()) {
 | |
| +            if (nodeWillRespondToMouseEvents(*node)) {
 | |
| +                // If we are interested about the frame, use it.
 | |
| +                if (nodeBounds) {
 | |
| +                    // This is a check to see whether this node is an area element. The only way this can happen is if this is the first check.
 | |
| +                    if (node == hitTestResult.innerNode() && node != hitTestResult.innerNonSharedNode() && is<HTMLAreaElement>(*node))
 | |
| +                        *nodeBounds = snappedIntRect(downcast<HTMLAreaElement>(*node).computeRect(hitTestResult.innerNonSharedNode()->renderer()));
 | |
| +                    else if (node && node->renderer())
 | |
| +                        *nodeBounds = node->renderer()->absoluteBoundingBoxRect(true);
 | |
| +                }
 | |
| +
 | |
| +                return node;
 | |
| +            }
 | |
| +        }
 | |
| +
 | |
| +        return nullptr;
 | |
| +    };
 | |
| +}
 | |
| +
 | |
| +Node* Frame::nodeRespondingToClickEvents(const FloatPoint& viewportLocation, FloatPoint& adjustedViewportLocation, SecurityOrigin* securityOrigin)
 | |
| +{
 | |
| +    return qualifyingNodeAtViewportLocation(viewportLocation, adjustedViewportLocation, ancestorRespondingToClickEventsNodeQualifier(securityOrigin), ShouldApproximate::Yes);
 | |
| +}
 | |
| +
 | |
| +Node* Frame::nodeRespondingToDoubleClickEvent(const FloatPoint& viewportLocation, FloatPoint& adjustedViewportLocation)
 | |
| +{
 | |
| +    auto&& ancestorRespondingToDoubleClickEvent = [](const HitTestResult& hitTestResult, Node* terminationNode, IntRect* nodeBounds) -> Node* {
 | |
| +        if (nodeBounds)
 | |
| +            *nodeBounds = IntRect();
 | |
| +
 | |
| +        auto* node = hitTestResult.innerNode();
 | |
| +        if (!node)
 | |
| +            return nullptr;
 | |
| +
 | |
| +        for (; node && node != terminationNode; node = node->parentInComposedTree()) {
 | |
| +            if (!node->hasEventListeners(eventNames().dblclickEvent))
 | |
| +                continue;
 | |
| +#if ENABLE(TOUCH_EVENTS)
 | |
| +            if (!node->allowsDoubleTapGesture())
 | |
| +                continue;
 | |
| +#endif
 | |
| +            if (nodeBounds && node->renderer())
 | |
| +                *nodeBounds = node->renderer()->absoluteBoundingBoxRect(true);
 | |
| +            return node;
 | |
| +        }
 | |
| +        return nullptr;
 | |
| +    };
 | |
| +
 | |
| +    return qualifyingNodeAtViewportLocation(viewportLocation, adjustedViewportLocation, WTFMove(ancestorRespondingToDoubleClickEvent), ShouldApproximate::Yes);
 | |
| +}
 | |
| +
 | |
| +Node* Frame::nodeRespondingToInteraction(const FloatPoint& viewportLocation, FloatPoint& adjustedViewportLocation)
 | |
| +{
 | |
| +    return qualifyingNodeAtViewportLocation(viewportLocation, adjustedViewportLocation, ancestorRespondingToClickEventsNodeQualifier(), ShouldApproximate::Yes, ShouldFindRootEditableElement::No);
 | |
| +}
 | |
| +
 | |
| +Node* Frame::nodeRespondingToScrollWheelEvents(const FloatPoint& viewportLocation)
 | |
| +{
 | |
| +    auto&& ancestorRespondingToScrollWheelEvents = [](const HitTestResult& hitTestResult, Node* terminationNode, IntRect* nodeBounds) -> Node* {
 | |
| +        if (nodeBounds)
 | |
| +            *nodeBounds = IntRect();
 | |
| +
 | |
| +        Node* scrollingAncestor = nullptr;
 | |
| +        for (Node* node = hitTestResult.innerNode(); node && node != terminationNode && !node->hasTagName(HTMLNames::bodyTag); node = node->parentNode()) {
 | |
| +            RenderObject* renderer = node->renderer();
 | |
| +            if (!renderer)
 | |
| +                continue;
 | |
| +
 | |
| +            if ((renderer->isTextField() || renderer->isTextArea()) && downcast<RenderTextControl>(*renderer).canScroll()) {
 | |
| +                scrollingAncestor = node;
 | |
| +                continue;
 | |
| +            }
 | |
| +
 | |
| +            auto& style = renderer->style();
 | |
| +
 | |
| +            if (renderer->hasNonVisibleOverflow()
 | |
| +                && (style.overflowY() == Overflow::Auto || style.overflowY() == Overflow::Scroll
 | |
| +                || style.overflowX() == Overflow::Auto || style.overflowX() == Overflow::Scroll)) {
 | |
| +                scrollingAncestor = node;
 | |
| +            }
 | |
| +        }
 | |
| +
 | |
| +        return scrollingAncestor;
 | |
| +    };
 | |
| +
 | |
| +    FloatPoint adjustedViewportLocation;
 | |
| +    return qualifyingNodeAtViewportLocation(viewportLocation, adjustedViewportLocation, WTFMove(ancestorRespondingToScrollWheelEvents), ShouldApproximate::No);
 | |
| +}
 | |
| +
 | |
| +#endif // !PLATFORM(IOS_FAMILY)
 | |
| +
 | |
|  } // namespace WebCore
 | |
|  
 | |
|  #undef FRAME_RELEASE_LOG_ERROR
 | |
| diff --git a/Source/WebCore/page/Frame.h b/Source/WebCore/page/Frame.h
 | |
| index 856ff374f367332ca5ab10a46bff825b8bcb159b..24bbbcd6b51a9ae27c72a0810c97678afb6b018c 100644
 | |
| --- a/Source/WebCore/page/Frame.h
 | |
| +++ b/Source/WebCore/page/Frame.h
 | |
| @@ -113,8 +113,8 @@ enum {
 | |
|  };
 | |
|  
 | |
|  enum OverflowScrollAction { DoNotPerformOverflowScroll, PerformOverflowScroll };
 | |
| -using NodeQualifier = Function<Node* (const HitTestResult&, Node* terminationNode, IntRect* nodeBounds)>;
 | |
|  #endif
 | |
| +using NodeQualifier = Function<Node* (const HitTestResult&, Node* terminationNode, IntRect* nodeBounds)>;
 | |
|  
 | |
|  // FIXME: Rename Frame to LocalFrame and AbstractFrame to Frame.
 | |
|  class Frame final : public AbstractFrame {
 | |
| @@ -220,10 +220,6 @@ public:
 | |
|      WEBCORE_EXPORT DataDetectionResultsStorage& dataDetectionResults();
 | |
|  #endif
 | |
|  
 | |
| -#if PLATFORM(IOS_FAMILY)
 | |
| -    const ViewportArguments& viewportArguments() const;
 | |
| -    WEBCORE_EXPORT void setViewportArguments(const ViewportArguments&);
 | |
| -
 | |
|      WEBCORE_EXPORT Node* deepestNodeAtLocation(const FloatPoint& viewportLocation);
 | |
|      WEBCORE_EXPORT Node* nodeRespondingToClickEvents(const FloatPoint& viewportLocation, FloatPoint& adjustedViewportLocation, SecurityOrigin* = nullptr);
 | |
|      WEBCORE_EXPORT Node* nodeRespondingToDoubleClickEvent(const FloatPoint& viewportLocation, FloatPoint& adjustedViewportLocation);
 | |
| @@ -231,6 +227,10 @@ public:
 | |
|      WEBCORE_EXPORT Node* nodeRespondingToScrollWheelEvents(const FloatPoint& viewportLocation);
 | |
|      WEBCORE_EXPORT Node* approximateNodeAtViewportLocationLegacy(const FloatPoint& viewportLocation, FloatPoint& adjustedViewportLocation);
 | |
|  
 | |
| +#if PLATFORM(IOS_FAMILY)
 | |
| +    const ViewportArguments& viewportArguments() const;
 | |
| +    WEBCORE_EXPORT void setViewportArguments(const ViewportArguments&);
 | |
| +
 | |
|      WEBCORE_EXPORT NSArray *wordsInCurrentParagraph() const;
 | |
|      WEBCORE_EXPORT CGRect renderRectForPoint(CGPoint, bool* isReplaced, float* fontSize) const;
 | |
|  
 | |
| @@ -298,6 +298,7 @@ public:
 | |
|  
 | |
|      WEBCORE_EXPORT FloatSize screenSize() const;
 | |
|      void setOverrideScreenSize(FloatSize&&);
 | |
| +    bool hasScreenSizeOverride() const { return !m_overrideScreenSize.isEmpty(); }
 | |
|  
 | |
|      void selfOnlyRef();
 | |
|      void selfOnlyDeref();
 | |
| @@ -336,7 +337,6 @@ private:
 | |
|  #if ENABLE(DATA_DETECTION)
 | |
|      std::unique_ptr<DataDetectionResultsStorage> m_dataDetectionResults;
 | |
|  #endif
 | |
| -#if PLATFORM(IOS_FAMILY)
 | |
|      void betterApproximateNode(const IntPoint& testPoint, const NodeQualifier&, Node*& best, Node* failedNode, IntPoint& bestPoint, IntRect& bestRect, const IntRect& testRect);
 | |
|      bool hitTestResultAtViewportLocation(const FloatPoint& viewportLocation, HitTestResult&, IntPoint& center);
 | |
|      
 | |
| @@ -344,6 +344,7 @@ private:
 | |
|      enum class ShouldFindRootEditableElement : bool { No, Yes };
 | |
|      Node* qualifyingNodeAtViewportLocation(const FloatPoint& viewportLocation, FloatPoint& adjustedViewportLocation, const NodeQualifier&, ShouldApproximate, ShouldFindRootEditableElement = ShouldFindRootEditableElement::Yes);
 | |
|  
 | |
| +#if PLATFORM(IOS_FAMILY)
 | |
|      void setTimersPausedInternal(bool);
 | |
|  
 | |
|      ViewportArguments m_viewportArguments;
 | |
| diff --git a/Source/WebCore/page/FrameSnapshotting.cpp b/Source/WebCore/page/FrameSnapshotting.cpp
 | |
| index 4e524dcb9f03fcc0e50919b16448be6b0421b5da..b566f02589bac9c3259a63db94a3108bbcbff554 100644
 | |
| --- a/Source/WebCore/page/FrameSnapshotting.cpp
 | |
| +++ b/Source/WebCore/page/FrameSnapshotting.cpp
 | |
| @@ -107,7 +107,7 @@ RefPtr<ImageBuffer> snapshotFrameRectWithClip(Frame& frame, const IntRect& image
 | |
|      // Other paint behaviors are set by paintContentsForSnapshot.
 | |
|      frame.view()->setPaintBehavior(paintBehavior);
 | |
|  
 | |
| -    float scaleFactor = frame.page()->deviceScaleFactor();
 | |
| +    float scaleFactor = options.flags.contains(SnapshotFlags::OmitDeviceScaleFactor) ? 1 : frame.page()->deviceScaleFactor();
 | |
|  
 | |
|      if (frame.page()->delegatesScaling())
 | |
|          scaleFactor *= frame.page()->pageScaleFactor();
 | |
| @@ -122,7 +122,13 @@ RefPtr<ImageBuffer> snapshotFrameRectWithClip(Frame& frame, const IntRect& image
 | |
|      if (!buffer)
 | |
|          return nullptr;
 | |
|  
 | |
| +#if !PLATFORM(MAC)
 | |
| +    buffer->context().scale(scaleFactor);
 | |
| +#endif
 | |
| +
 | |
|      buffer->context().translate(-imageRect.location());
 | |
| +    if (coordinateSpace != FrameView::ViewCoordinates)
 | |
| +        buffer->context().scale(1 / frame.page()->pageScaleFactor());
 | |
|  
 | |
|      if (!clipRects.isEmpty()) {
 | |
|          Path clipPath;
 | |
| @@ -131,7 +137,10 @@ RefPtr<ImageBuffer> snapshotFrameRectWithClip(Frame& frame, const IntRect& image
 | |
|          buffer->context().clipPath(clipPath);
 | |
|      }
 | |
|  
 | |
| -    frame.view()->paintContentsForSnapshot(buffer->context(), imageRect, shouldIncludeSelection, coordinateSpace);
 | |
| +    FloatRect fr = imageRect;
 | |
| +    if (coordinateSpace != FrameView::ViewCoordinates)
 | |
| +        fr.scale(frame.page()->pageScaleFactor());
 | |
| +    frame.view()->paintContentsForSnapshot(buffer->context(), enclosingIntRect(fr), shouldIncludeSelection, coordinateSpace);
 | |
|      return buffer;
 | |
|  }
 | |
|  
 | |
| diff --git a/Source/WebCore/page/FrameSnapshotting.h b/Source/WebCore/page/FrameSnapshotting.h
 | |
| index bb1bc2ffd02177718a77c5534e66bed55232e660..1eaff1702c30b337d4a8f5a804a9a4b134e1b111 100644
 | |
| --- a/Source/WebCore/page/FrameSnapshotting.h
 | |
| +++ b/Source/WebCore/page/FrameSnapshotting.h
 | |
| @@ -44,7 +44,7 @@ class IntRect;
 | |
|  class ImageBuffer;
 | |
|  class Node;
 | |
|  
 | |
| -enum class SnapshotFlags : uint8_t {
 | |
| +enum class SnapshotFlags : uint16_t {
 | |
|      ExcludeSelectionHighlighting = 1 << 0,
 | |
|      PaintSelectionOnly = 1 << 1,
 | |
|      InViewCoordinates = 1 << 2,
 | |
| @@ -53,6 +53,7 @@ enum class SnapshotFlags : uint8_t {
 | |
|      PaintEverythingExcludingSelection = 1 << 5,
 | |
|      PaintWithIntegralScaleFactor = 1 << 6,
 | |
|      Shareable = 1 << 7,
 | |
| +    OmitDeviceScaleFactor = 1 << 8,
 | |
|  };
 | |
|  
 | |
|  struct SnapshotOptions {
 | |
| diff --git a/Source/WebCore/page/History.cpp b/Source/WebCore/page/History.cpp
 | |
| index a782c3be51ca113a52482c5a10583c8fa64724ef..1d82dff81be5c5492efb3bfe77d2f259c2f2b5db 100644
 | |
| --- a/Source/WebCore/page/History.cpp
 | |
| +++ b/Source/WebCore/page/History.cpp
 | |
| @@ -33,6 +33,7 @@
 | |
|  #include "FrameLoaderClient.h"
 | |
|  #include "HistoryController.h"
 | |
|  #include "HistoryItem.h"
 | |
| +#include "InspectorInstrumentation.h"
 | |
|  #include "Logging.h"
 | |
|  #include "NavigationScheduler.h"
 | |
|  #include "Page.h"
 | |
| @@ -260,6 +261,7 @@ ExceptionOr<void> History::stateObjectAdded(RefPtr<SerializedScriptValue>&& data
 | |
|  
 | |
|      if (!urlString.isEmpty())
 | |
|          frame->document()->updateURLForPushOrReplaceState(fullURL);
 | |
| +    InspectorInstrumentation::didNavigateWithinPage(*frame);
 | |
|  
 | |
|      if (stateObjectType == StateObjectType::Push) {
 | |
|          frame->loader().history().pushState(WTFMove(data), title, fullURL.string());
 | |
| diff --git a/Source/WebCore/page/Page.cpp b/Source/WebCore/page/Page.cpp
 | |
| index 22737c5d7554d0ba158ef3e1a63fbde11502e72b..6474b73078528345f8e2addcdbca0eb670974d22 100644
 | |
| --- a/Source/WebCore/page/Page.cpp
 | |
| +++ b/Source/WebCore/page/Page.cpp
 | |
| @@ -487,6 +487,37 @@ void Page::setOverrideViewportArguments(const std::optional<ViewportArguments>&
 | |
|          document->updateViewportArguments();
 | |
|  }
 | |
|  
 | |
| +FloatSize Page::screenSize()
 | |
| +{
 | |
| +    return m_overrideScreenSize.value_or(screenRect(mainFrame().view()).size());
 | |
| +}
 | |
| +
 | |
| +void Page::setOverrideScreenSize(std::optional<FloatSize> size)
 | |
| +{
 | |
| +    if (size == m_overrideScreenSize)
 | |
| +        return;
 | |
| +
 | |
| +    m_overrideScreenSize = size;
 | |
| +    if (auto* document = mainFrame().document())
 | |
| +        document->updateViewportArguments();
 | |
| +}
 | |
| +
 | |
| +#if ENABLE(ORIENTATION_EVENTS)
 | |
| +int Page::orientation() const
 | |
| +{
 | |
| +    return m_overrideOrientation.value_or(chrome().client().deviceOrientation());
 | |
| +}
 | |
| +
 | |
| +void Page::setOverrideOrientation(std::optional<int> orientation)
 | |
| +{
 | |
| +    if (orientation == m_overrideOrientation)
 | |
| +        return;
 | |
| +
 | |
| +    m_overrideOrientation = orientation;
 | |
| +    mainFrame().orientationChanged();
 | |
| +}
 | |
| +#endif
 | |
| +
 | |
|  ScrollingCoordinator* Page::scrollingCoordinator()
 | |
|  {
 | |
|      if (!m_scrollingCoordinator && m_settings->scrollingCoordinatorEnabled()) {
 | |
| @@ -1356,10 +1387,6 @@ void Page::didCommitLoad()
 | |
|      m_isEditableRegionEnabled = false;
 | |
|  #endif
 | |
|  
 | |
| -#if HAVE(OS_DARK_MODE_SUPPORT)
 | |
| -    setUseDarkAppearanceOverride(std::nullopt);
 | |
| -#endif
 | |
| -
 | |
|      resetSeenPlugins();
 | |
|      resetSeenMediaEngines();
 | |
|  
 | |
| @@ -3406,6 +3433,16 @@ void Page::setUseDarkAppearanceOverride(std::optional<bool> valueOverride)
 | |
|  #endif
 | |
|  }
 | |
|  
 | |
| +void Page::setUseReducedMotionOverride(std::optional<bool> valueOverride)
 | |
| +{
 | |
| +    if (valueOverride == m_useReducedMotionOverride)
 | |
| +        return;
 | |
| +
 | |
| +    m_useReducedMotionOverride = valueOverride;
 | |
| +
 | |
| +    appearanceDidChange();
 | |
| +}
 | |
| +
 | |
|  void Page::setFullscreenInsets(const FloatBoxExtent& insets)
 | |
|  {
 | |
|      if (insets == m_fullscreenInsets)
 | |
| diff --git a/Source/WebCore/page/Page.h b/Source/WebCore/page/Page.h
 | |
| index ccf2e14844c9ad578e4e262a5881167c846fc9d3..a10ad39fc75b52e8484e7562b21ee230e865c0e2 100644
 | |
| --- a/Source/WebCore/page/Page.h
 | |
| +++ b/Source/WebCore/page/Page.h
 | |
| @@ -279,6 +279,9 @@ public:
 | |
|      const std::optional<ViewportArguments>& overrideViewportArguments() const { return m_overrideViewportArguments; }
 | |
|      WEBCORE_EXPORT void setOverrideViewportArguments(const std::optional<ViewportArguments>&);
 | |
|  
 | |
| +    WEBCORE_EXPORT FloatSize screenSize();
 | |
| +    void setOverrideScreenSize(std::optional<FloatSize> size);
 | |
| +
 | |
|      static void refreshPlugins(bool reload);
 | |
|      WEBCORE_EXPORT PluginData& pluginData();
 | |
|      void clearPluginData();
 | |
| @@ -329,6 +332,10 @@ public:
 | |
|      DragCaretController& dragCaretController() const { return *m_dragCaretController; }
 | |
|  #if ENABLE(DRAG_SUPPORT)
 | |
|      DragController& dragController() const { return *m_dragController; }
 | |
| +#if PLATFORM(MAC)
 | |
| +    void setDragPasteboardName(const String& pasteboardName) { m_overrideDragPasteboardName = pasteboardName; }
 | |
| +    const String& overrideDragPasteboardName() { return m_overrideDragPasteboardName; }
 | |
| +#endif
 | |
|  #endif
 | |
|      FocusController& focusController() const { return *m_focusController; }
 | |
|  #if ENABLE(CONTEXT_MENUS)
 | |
| @@ -496,6 +503,8 @@ public:
 | |
|      WEBCORE_EXPORT void effectiveAppearanceDidChange(bool useDarkAppearance, bool useElevatedUserInterfaceLevel);
 | |
|      bool defaultUseDarkAppearance() const { return m_useDarkAppearance; }
 | |
|      void setUseDarkAppearanceOverride(std::optional<bool>);
 | |
| +    std::optional<bool> useReducedMotionOverride() const { return m_useReducedMotionOverride; }
 | |
| +    void setUseReducedMotionOverride(std::optional<bool>);
 | |
|  
 | |
|  #if ENABLE(TEXT_AUTOSIZING)
 | |
|      float textAutosizingWidth() const { return m_textAutosizingWidth; }
 | |
| @@ -903,6 +912,11 @@ public:
 | |
|      bool shouldBuildInteractionRegions() const;
 | |
|  #endif
 | |
|  
 | |
| +#if ENABLE(ORIENTATION_EVENTS)
 | |
| +    int orientation() const;
 | |
| +    void setOverrideOrientation(std::optional<int>);
 | |
| +#endif
 | |
| +
 | |
|  #if ENABLE(DEVICE_ORIENTATION) && PLATFORM(IOS_FAMILY)
 | |
|      DeviceOrientationUpdateProvider* deviceOrientationUpdateProvider() const { return m_deviceOrientationUpdateProvider.get(); }
 | |
|  #endif
 | |
| @@ -1019,6 +1033,9 @@ private:
 | |
|  
 | |
|  #if ENABLE(DRAG_SUPPORT)
 | |
|      const std::unique_ptr<DragController> m_dragController;
 | |
| +#if PLATFORM(MAC)
 | |
| +    String m_overrideDragPasteboardName;
 | |
| +#endif
 | |
|  #endif
 | |
|      const std::unique_ptr<FocusController> m_focusController;
 | |
|  #if ENABLE(CONTEXT_MENUS)
 | |
| @@ -1098,6 +1115,7 @@ private:
 | |
|      bool m_useElevatedUserInterfaceLevel { false };
 | |
|      bool m_useDarkAppearance { false };
 | |
|      std::optional<bool> m_useDarkAppearanceOverride;
 | |
| +    std::optional<bool> m_useReducedMotionOverride;
 | |
|  
 | |
|  #if ENABLE(TEXT_AUTOSIZING)
 | |
|      float m_textAutosizingWidth { 0 };
 | |
| @@ -1275,6 +1293,11 @@ private:
 | |
|  #endif
 | |
|  
 | |
|      std::optional<ViewportArguments> m_overrideViewportArguments;
 | |
| +    std::optional<FloatSize> m_overrideScreenSize;
 | |
| +
 | |
| +#if ENABLE(ORIENTATION_EVENTS)
 | |
| +    std::optional<int> m_overrideOrientation;
 | |
| +#endif
 | |
|  
 | |
|  #if ENABLE(DEVICE_ORIENTATION) && PLATFORM(IOS_FAMILY)
 | |
|      RefPtr<DeviceOrientationUpdateProvider> m_deviceOrientationUpdateProvider;
 | |
| diff --git a/Source/WebCore/page/PointerCaptureController.cpp b/Source/WebCore/page/PointerCaptureController.cpp
 | |
| index 88c3ca9610ca27e2bfa8d548597170b990990897..21de65f197804a31bbc0bf1a1098579c5dc2bfd7 100644
 | |
| --- a/Source/WebCore/page/PointerCaptureController.cpp
 | |
| +++ b/Source/WebCore/page/PointerCaptureController.cpp
 | |
| @@ -195,7 +195,7 @@ bool PointerCaptureController::preventsCompatibilityMouseEventsForIdentifier(Poi
 | |
|      return capturingData && capturingData->preventsCompatibilityMouseEvents;
 | |
|  }
 | |
|  
 | |
| -#if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS_FAMILY)
 | |
| +#if ENABLE(TOUCH_EVENTS)
 | |
|  static bool hierarchyHasCapturingEventListeners(Element* target, const AtomString& eventName)
 | |
|  {
 | |
|      for (RefPtr<ContainerNode> currentNode = target; currentNode; currentNode = currentNode->parentInComposedTree()) {
 | |
| @@ -476,7 +476,7 @@ void PointerCaptureController::cancelPointer(PointerID pointerId, const IntPoint
 | |
|      capturingData->pendingTargetOverride = nullptr;
 | |
|      capturingData->state = CapturingData::State::Cancelled;
 | |
|  
 | |
| -#if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS_FAMILY)
 | |
| +#if ENABLE(TOUCH_EVENTS)
 | |
|      capturingData->previousTarget = nullptr;
 | |
|  #endif
 | |
|  
 | |
| diff --git a/Source/WebCore/page/PointerCaptureController.h b/Source/WebCore/page/PointerCaptureController.h
 | |
| index 8c911ca663507b61640a4e29245dabe79573c420..08cdd2bfea9f5ac19c8cc39dc80032e140828ca4 100644
 | |
| --- a/Source/WebCore/page/PointerCaptureController.h
 | |
| +++ b/Source/WebCore/page/PointerCaptureController.h
 | |
| @@ -57,7 +57,7 @@ public:
 | |
|  
 | |
|      RefPtr<PointerEvent> pointerEventForMouseEvent(const MouseEvent&, PointerID, const String& pointerType);
 | |
|  
 | |
| -#if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS_FAMILY)
 | |
| +#if ENABLE(TOUCH_EVENTS)
 | |
|      void dispatchEventForTouchAtIndex(EventTarget&, const PlatformTouchEvent&, unsigned, bool isPrimary, WindowProxy&);
 | |
|  #endif
 | |
|  
 | |
| @@ -77,7 +77,7 @@ private:
 | |
|  
 | |
|          RefPtr<Element> pendingTargetOverride;
 | |
|          RefPtr<Element> targetOverride;
 | |
| -#if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS_FAMILY)
 | |
| +#if ENABLE(TOUCH_EVENTS)
 | |
|          RefPtr<Element> previousTarget;
 | |
|  #endif
 | |
|          bool hasAnyElement() const {
 | |
| diff --git a/Source/WebCore/page/RuntimeEnabledFeatures.cpp b/Source/WebCore/page/RuntimeEnabledFeatures.cpp
 | |
| index 897d2a009752a4030659a88e8b16382e00ac2316..08bb3344c59a0462668762815473659ff005d363 100644
 | |
| --- a/Source/WebCore/page/RuntimeEnabledFeatures.cpp
 | |
| +++ b/Source/WebCore/page/RuntimeEnabledFeatures.cpp
 | |
| @@ -61,7 +61,11 @@ RuntimeEnabledFeatures& RuntimeEnabledFeatures::sharedFeatures()
 | |
|  #if ENABLE(TOUCH_EVENTS)
 | |
|  bool RuntimeEnabledFeatures::touchEventsEnabled() const
 | |
|  {
 | |
| -    return m_touchEventsEnabled.value_or(screenHasTouchDevice());
 | |
| +    return m_touchEventsEnabled.value_or(platformScreenHasTouchDevice());
 | |
| +}
 | |
| +bool RuntimeEnabledFeatures::isTouchPrimaryInputDevice() const
 | |
| +{
 | |
| +    return m_touchEventsEnabled.value_or(platformScreenIsTouchPrimaryInputDevice());
 | |
|  }
 | |
|  #endif
 | |
|  
 | |
| diff --git a/Source/WebCore/page/RuntimeEnabledFeatures.h b/Source/WebCore/page/RuntimeEnabledFeatures.h
 | |
| index da65510492bb4a810124b05cba7e74d485c9cba9..e36002bfa44188306b65b494ad14e2c8db8eb8ac 100644
 | |
| --- a/Source/WebCore/page/RuntimeEnabledFeatures.h
 | |
| +++ b/Source/WebCore/page/RuntimeEnabledFeatures.h
 | |
| @@ -175,6 +175,7 @@ public:
 | |
|      void setMouseEventsSimulationEnabled(bool isEnabled) { m_mouseEventsSimulationEnabled = isEnabled; }
 | |
|      bool touchEventsEnabled() const;
 | |
|      void setTouchEventsEnabled(bool isEnabled) { m_touchEventsEnabled = isEnabled; }
 | |
| +    bool isTouchPrimaryInputDevice() const;
 | |
|  #endif
 | |
|  
 | |
|      bool pageAtRuleSupportEnabled() const { return m_pageAtRuleSupportEnabled; }
 | |
| diff --git a/Source/WebCore/page/Screen.cpp b/Source/WebCore/page/Screen.cpp
 | |
| index 7ac11c8289347e3a2f3e7316cf9e32932b9544ed..764b2d4fe36ac2e5588bd22595424ac11d42acd0 100644
 | |
| --- a/Source/WebCore/page/Screen.cpp
 | |
| +++ b/Source/WebCore/page/Screen.cpp
 | |
| @@ -102,6 +102,8 @@ int Screen::availLeft() const
 | |
|          return 0;
 | |
|      if (RuntimeEnabledFeatures::sharedFeatures().webAPIStatisticsEnabled())
 | |
|          ResourceLoadObserver::shared().logScreenAPIAccessed(*frame->document(), ResourceLoadStatistics::ScreenAPI::AvailLeft);
 | |
| +    if (frame->hasScreenSizeOverride())
 | |
| +        return 0;
 | |
|      return static_cast<int>(screenAvailableRect(frame->view()).x());
 | |
|  }
 | |
|  
 | |
| @@ -112,6 +114,8 @@ int Screen::availTop() const
 | |
|          return 0;
 | |
|      if (RuntimeEnabledFeatures::sharedFeatures().webAPIStatisticsEnabled())
 | |
|          ResourceLoadObserver::shared().logScreenAPIAccessed(*frame->document(), ResourceLoadStatistics::ScreenAPI::AvailTop);
 | |
| +    if (frame->hasScreenSizeOverride())
 | |
| +        return 0;
 | |
|      return static_cast<int>(screenAvailableRect(frame->view()).y());
 | |
|  }
 | |
|  
 | |
| @@ -122,6 +126,8 @@ unsigned Screen::availHeight() const
 | |
|          return 0;
 | |
|      if (RuntimeEnabledFeatures::sharedFeatures().webAPIStatisticsEnabled())
 | |
|          ResourceLoadObserver::shared().logScreenAPIAccessed(*frame->document(), ResourceLoadStatistics::ScreenAPI::AvailHeight);
 | |
| +    if (frame->hasScreenSizeOverride())
 | |
| +        return static_cast<unsigned>(frame->screenSize().height());
 | |
|      return static_cast<unsigned>(screenAvailableRect(frame->view()).height());
 | |
|  }
 | |
|  
 | |
| @@ -132,6 +138,8 @@ unsigned Screen::availWidth() const
 | |
|          return 0;
 | |
|      if (RuntimeEnabledFeatures::sharedFeatures().webAPIStatisticsEnabled())
 | |
|          ResourceLoadObserver::shared().logScreenAPIAccessed(*frame->document(), ResourceLoadStatistics::ScreenAPI::AvailWidth);
 | |
| +    if (frame->hasScreenSizeOverride())
 | |
| +        return static_cast<unsigned>(frame->screenSize().width());
 | |
|      return static_cast<unsigned>(screenAvailableRect(frame->view()).width());
 | |
|  }
 | |
|  
 | |
| diff --git a/Source/WebCore/page/csp/ContentSecurityPolicy.cpp b/Source/WebCore/page/csp/ContentSecurityPolicy.cpp
 | |
| index 2fd52a5b9267aaa29e2760c5cda125ec5af95009..43f07ea81e401764ea34145b1a08b80b7cb7c746 100644
 | |
| --- a/Source/WebCore/page/csp/ContentSecurityPolicy.cpp
 | |
| +++ b/Source/WebCore/page/csp/ContentSecurityPolicy.cpp
 | |
| @@ -298,6 +298,8 @@ bool ContentSecurityPolicy::allowContentSecurityPolicySourceStarToMatchAnyProtoc
 | |
|  template<typename Predicate, typename... Args>
 | |
|  typename std::enable_if<!std::is_convertible<Predicate, ContentSecurityPolicy::ViolatedDirectiveCallback>::value, bool>::type ContentSecurityPolicy::allPoliciesWithDispositionAllow(Disposition disposition, Predicate&& predicate, Args&&... args) const
 | |
|  {
 | |
| +    if (InspectorInstrumentation::shouldBypassCSP(m_scriptExecutionContext))
 | |
| +        return true;
 | |
|      bool isReportOnly = disposition == ContentSecurityPolicy::Disposition::ReportOnly;
 | |
|      for (auto& policy : m_policies) {
 | |
|          if (policy->isReportOnly() != isReportOnly)
 | |
| @@ -311,6 +313,8 @@ typename std::enable_if<!std::is_convertible<Predicate, ContentSecurityPolicy::V
 | |
|  template<typename Predicate, typename... Args>
 | |
|  bool ContentSecurityPolicy::allPoliciesWithDispositionAllow(Disposition disposition, ViolatedDirectiveCallback&& callback, Predicate&& predicate, Args&&... args) const
 | |
|  {
 | |
| +    if (InspectorInstrumentation::shouldBypassCSP(m_scriptExecutionContext))
 | |
| +        return true;
 | |
|      bool isReportOnly = disposition == ContentSecurityPolicy::Disposition::ReportOnly;
 | |
|      bool isAllowed = true;
 | |
|      for (auto& policy : m_policies) {
 | |
| @@ -327,6 +331,8 @@ bool ContentSecurityPolicy::allPoliciesWithDispositionAllow(Disposition disposit
 | |
|  template<typename Predicate, typename... Args>
 | |
|  bool ContentSecurityPolicy::allPoliciesAllow(ViolatedDirectiveCallback&& callback, Predicate&& predicate, Args&&... args) const
 | |
|  {
 | |
| +    if (InspectorInstrumentation::shouldBypassCSP(m_scriptExecutionContext))
 | |
| +        return true;
 | |
|      bool isAllowed = true;
 | |
|      for (auto& policy : m_policies) {
 | |
|          if (const ContentSecurityPolicyDirective* violatedDirective = (policy.get()->*predicate)(std::forward<Args>(args)...)) {
 | |
| diff --git a/Source/WebCore/page/wpe/DragControllerWPE.cpp b/Source/WebCore/page/wpe/DragControllerWPE.cpp
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..2549355fc55ca55d2b6917dbfd05999f0e5607b3
 | |
| --- /dev/null
 | |
| +++ b/Source/WebCore/page/wpe/DragControllerWPE.cpp
 | |
| @@ -0,0 +1,80 @@
 | |
| +/*
 | |
| + * Copyright (C) 2007-20 Apple Inc.  All rights reserved.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 | |
| + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | |
| + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 | |
| + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 | |
| + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 | |
| + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 | |
| + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 | |
| + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 | |
| + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#include "config.h"
 | |
| +#include "DragController.h"
 | |
| +
 | |
| +#include "DataTransfer.h"
 | |
| +#include "Document.h"
 | |
| +#include "DragData.h"
 | |
| +#include "Editor.h"
 | |
| +#include "Element.h"
 | |
| +#include "Frame.h"
 | |
| +#include "FrameDestructionObserverInlines.h"
 | |
| +#include "Pasteboard.h"
 | |
| +#include "markup.h"
 | |
| +
 | |
| +namespace WebCore {
 | |
| +
 | |
| +// FIXME: These values are straight out of DragControllerMac, so probably have
 | |
| +// little correlation with Gdk standards...
 | |
| +const int DragController::MaxOriginalImageArea = 1500 * 1500;
 | |
| +const int DragController::DragIconRightInset = 7;
 | |
| +const int DragController::DragIconBottomInset = 3;
 | |
| +
 | |
| +const float DragController::DragImageAlpha = 0.75f;
 | |
| +
 | |
| +bool DragController::isCopyKeyDown(const DragData& dragData)
 | |
| +{
 | |
| +    return dragData.flags().contains(DragApplicationFlags::IsCopyKeyDown);
 | |
| +}
 | |
| +
 | |
| +std::optional<DragOperation> DragController::dragOperation(const DragData& dragData)
 | |
| +{
 | |
| +    // FIXME: This logic is incomplete
 | |
| +    if (dragData.containsURL())
 | |
| +        return DragOperation::Copy;
 | |
| +
 | |
| +    return std::nullopt;
 | |
| +}
 | |
| +
 | |
| +const IntSize& DragController::maxDragImageSize()
 | |
| +{
 | |
| +    static const IntSize maxDragImageSize(200, 200);
 | |
| +    return maxDragImageSize;
 | |
| +}
 | |
| +
 | |
| +void DragController::cleanupAfterSystemDrag()
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +void DragController::declareAndWriteDragImage(DataTransfer& dataTransfer, Element& element, const URL& url, const String& label)
 | |
| +{
 | |
| +    Frame* frame = element.document().frame();
 | |
| +    ASSERT(frame);
 | |
| +    frame->editor().writeImageToPasteboard(dataTransfer.pasteboard(), element, url, label);
 | |
| +}
 | |
| +
 | |
| +}
 | |
| diff --git a/Source/WebCore/platform/Cairo.cmake b/Source/WebCore/platform/Cairo.cmake
 | |
| index 1fb0e9d5cee3b3df4ee1e96eb8d75016ad687fc5..497bd34cc97e2d20c9d6982a8d92d852451743cd 100644
 | |
| --- a/Source/WebCore/platform/Cairo.cmake
 | |
| +++ b/Source/WebCore/platform/Cairo.cmake
 | |
| @@ -16,6 +16,7 @@ list(APPEND WebCore_PRIVATE_FRAMEWORK_HEADERS
 | |
|      platform/graphics/cairo/ImageBufferCairoBackend.h
 | |
|      platform/graphics/cairo/ImageBufferCairoImageSurfaceBackend.h
 | |
|      platform/graphics/cairo/ImageBufferCairoSurfaceBackend.h
 | |
| +    platform/graphics/cairo/ImageBufferUtilitiesCairo.h
 | |
|      platform/graphics/cairo/RefPtrCairo.h
 | |
|  )
 | |
|  
 | |
| diff --git a/Source/WebCore/platform/DragData.h b/Source/WebCore/platform/DragData.h
 | |
| index 6600dfa7b189e15fab7fb796f66ef1a79dcd22f3..4c0bc485ca92614efca23a5a2da871b77d5285d3 100644
 | |
| --- a/Source/WebCore/platform/DragData.h
 | |
| +++ b/Source/WebCore/platform/DragData.h
 | |
| @@ -48,7 +48,7 @@ typedef void* DragDataRef;
 | |
|  
 | |
|  #elif PLATFORM(WIN)
 | |
|  typedef struct IDataObject* DragDataRef;
 | |
| -#elif PLATFORM(GTK)
 | |
| +#elif PLATFORM(GTK) || PLATFORM(WPE)
 | |
|  namespace WebCore {
 | |
|  class SelectionData;
 | |
|  }
 | |
| diff --git a/Source/WebCore/platform/DragImage.cpp b/Source/WebCore/platform/DragImage.cpp
 | |
| index 9e97dd5f689e6a1a90c9069445dc3f4b8c45e840..cc3ddc3e6d656a91c5ed58e050483d37e36d015a 100644
 | |
| --- a/Source/WebCore/platform/DragImage.cpp
 | |
| +++ b/Source/WebCore/platform/DragImage.cpp
 | |
| @@ -279,7 +279,7 @@ DragImage::~DragImage()
 | |
|          deleteDragImage(m_dragImageRef);
 | |
|  }
 | |
|  
 | |
| -#if !PLATFORM(COCOA) && !PLATFORM(GTK) && !PLATFORM(WIN)
 | |
| +#if !PLATFORM(COCOA) && !PLATFORM(GTK) && !PLATFORM(WIN) && !PLATFORM(WPE)
 | |
|  
 | |
|  IntSize dragImageSize(DragImageRef)
 | |
|  {
 | |
| diff --git a/Source/WebCore/platform/Pasteboard.h b/Source/WebCore/platform/Pasteboard.h
 | |
| index 6c8bff431b593b2443e411381f634e417f71cf06..c48473c936e9f7d997db8006770ae1488e1b2a1f 100644
 | |
| --- a/Source/WebCore/platform/Pasteboard.h
 | |
| +++ b/Source/WebCore/platform/Pasteboard.h
 | |
| @@ -44,7 +44,7 @@ OBJC_CLASS NSString;
 | |
|  OBJC_CLASS NSArray;
 | |
|  #endif
 | |
|  
 | |
| -#if PLATFORM(GTK)
 | |
| +#if PLATFORM(GTK) || PLATFORM(WPE)
 | |
|  #include "SelectionData.h"
 | |
|  #endif
 | |
|  
 | |
| @@ -92,16 +92,12 @@ struct PasteboardWebContent {
 | |
|      Vector<String> clientTypes;
 | |
|      Vector<RefPtr<SharedBuffer>> clientData;
 | |
|  #endif
 | |
| -#if PLATFORM(GTK)
 | |
| +#if PLATFORM(GTK) || PLATFORM(WPE)
 | |
|      String contentOrigin;
 | |
|      bool canSmartCopyOrDelete;
 | |
|      String text;
 | |
|      String markup;
 | |
|  #endif
 | |
| -#if USE(LIBWPE)
 | |
| -    String text;
 | |
| -    String markup;
 | |
| -#endif
 | |
|  };
 | |
|  
 | |
|  struct PasteboardURL {
 | |
| @@ -110,7 +106,7 @@ struct PasteboardURL {
 | |
|  #if PLATFORM(MAC)
 | |
|      String userVisibleForm;
 | |
|  #endif
 | |
| -#if PLATFORM(GTK)
 | |
| +#if PLATFORM(GTK) || PLATFORM(WPE)
 | |
|      String markup;
 | |
|  #endif
 | |
|  };
 | |
| @@ -200,6 +196,11 @@ public:
 | |
|  #endif
 | |
|  #endif
 | |
|  
 | |
| +#if PLATFORM(WPE) && ENABLE(DRAG_SUPPORT)
 | |
| +    explicit Pasteboard(std::unique_ptr<PasteboardContext>&&, SelectionData&);
 | |
| +    explicit Pasteboard(std::unique_ptr<PasteboardContext>&&, SelectionData&&);
 | |
| +#endif
 | |
| +
 | |
|  #if PLATFORM(WIN)
 | |
|      explicit Pasteboard(std::unique_ptr<PasteboardContext>&&, IDataObject*);
 | |
|      explicit Pasteboard(std::unique_ptr<PasteboardContext>&&, WCDataObject*);
 | |
| @@ -266,6 +267,12 @@ public:
 | |
|      static std::unique_ptr<Pasteboard> createForGlobalSelection(std::unique_ptr<PasteboardContext>&&);
 | |
|  #endif
 | |
|  
 | |
| +#if PLATFORM(WPE)
 | |
| +    const SelectionData& selectionData() const {
 | |
| +        return *m_selectionData;
 | |
| +    }
 | |
| +#endif
 | |
| +
 | |
|  #if PLATFORM(IOS_FAMILY)
 | |
|      explicit Pasteboard(std::unique_ptr<PasteboardContext>&&, int64_t changeCount);
 | |
|      explicit Pasteboard(std::unique_ptr<PasteboardContext>&&, const String& pasteboardName);
 | |
| @@ -300,6 +307,7 @@ public:
 | |
|      COMPtr<IDataObject> dataObject() const { return m_dataObject; }
 | |
|      void setExternalDataObject(IDataObject*);
 | |
|      const DragDataMap& dragDataMap() const { return m_dragDataMap; }
 | |
| +    WEBCORE_EXPORT DragDataMap createDragDataMap();
 | |
|      void writeURLToWritableDataObject(const URL&, const String&);
 | |
|      COMPtr<WCDataObject> writableDataObject() const { return m_writableDataObject; }
 | |
|      void writeImageToDataObject(Element&, const URL&); // FIXME: Layering violation.
 | |
| @@ -351,6 +359,10 @@ private:
 | |
|      String m_name;
 | |
|  #endif
 | |
|  
 | |
| +#if PLATFORM(WPE)
 | |
| +    std::optional<SelectionData> m_selectionData;
 | |
| +#endif
 | |
| +
 | |
|  #if PLATFORM(COCOA)
 | |
|      String m_pasteboardName;
 | |
|      int64_t m_changeCount;
 | |
| @@ -366,6 +378,7 @@ private:
 | |
|      COMPtr<IDataObject> m_dataObject;
 | |
|      COMPtr<WCDataObject> m_writableDataObject;
 | |
|      DragDataMap m_dragDataMap;
 | |
| +    bool m_forDrag = false;
 | |
|  #endif
 | |
|  };
 | |
|  
 | |
| diff --git a/Source/WebCore/platform/PlatformKeyboardEvent.h b/Source/WebCore/platform/PlatformKeyboardEvent.h
 | |
| index 1d3edd9585338828c7074fd8389e437c16c42d92..0f4b5b074f6c95919a09567bd1338577c0930627 100644
 | |
| --- a/Source/WebCore/platform/PlatformKeyboardEvent.h
 | |
| +++ b/Source/WebCore/platform/PlatformKeyboardEvent.h
 | |
| @@ -134,6 +134,7 @@ namespace WebCore {
 | |
|          static String keyCodeForHardwareKeyCode(unsigned);
 | |
|          static String keyIdentifierForGdkKeyCode(unsigned);
 | |
|          static int windowsKeyCodeForGdkKeyCode(unsigned);
 | |
| +        static unsigned gdkKeyCodeForWindowsKeyCode(int);
 | |
|          static String singleCharacterString(unsigned);
 | |
|          static bool modifiersContainCapsLock(unsigned);
 | |
|  #endif
 | |
| @@ -143,6 +144,7 @@ namespace WebCore {
 | |
|          static String keyCodeForHardwareKeyCode(unsigned);
 | |
|          static String keyIdentifierForWPEKeyCode(unsigned);
 | |
|          static int windowsKeyCodeForWPEKeyCode(unsigned);
 | |
| +        static unsigned WPEKeyCodeForWindowsKeyCode(int);
 | |
|          static String singleCharacterString(unsigned);
 | |
|  #endif
 | |
|  
 | |
| diff --git a/Source/WebCore/platform/PlatformScreen.cpp b/Source/WebCore/platform/PlatformScreen.cpp
 | |
| index ba50b688ab6d0bae5d199fa0bac4b7e2004baf81..0b83a798b00835635a95a0db22173de094ba4035 100644
 | |
| --- a/Source/WebCore/platform/PlatformScreen.cpp
 | |
| +++ b/Source/WebCore/platform/PlatformScreen.cpp
 | |
| @@ -25,6 +25,7 @@
 | |
|  
 | |
|  #include "config.h"
 | |
|  #include "PlatformScreen.h"
 | |
| +#include "RuntimeEnabledFeatures.h"
 | |
|  
 | |
|  #if PLATFORM(COCOA)
 | |
|  
 | |
| @@ -72,3 +73,16 @@ const ScreenData* screenData(PlatformDisplayID screenDisplayID)
 | |
|  } // namespace WebCore
 | |
|  
 | |
|  #endif // PLATFORM(COCOA)
 | |
| +
 | |
| +#if ENABLE(TOUCH_EVENTS)
 | |
| +namespace WebCore {
 | |
| +
 | |
| +bool screenHasTouchDevice() {
 | |
| +    return RuntimeEnabledFeatures::sharedFeatures().touchEventsEnabled();
 | |
| +}
 | |
| +bool screenIsTouchPrimaryInputDevice() {
 | |
| +    return RuntimeEnabledFeatures::sharedFeatures().isTouchPrimaryInputDevice();
 | |
| +}
 | |
| +
 | |
| +} // namespace WebCore
 | |
| +#endif
 | |
| diff --git a/Source/WebCore/platform/PlatformScreen.h b/Source/WebCore/platform/PlatformScreen.h
 | |
| index 44799e0b2a93cbcf25f4315d62a3d95896c02f3d..29277223448a0936a16f975970ab60d739b000cd 100644
 | |
| --- a/Source/WebCore/platform/PlatformScreen.h
 | |
| +++ b/Source/WebCore/platform/PlatformScreen.h
 | |
| @@ -151,12 +151,14 @@ WEBCORE_EXPORT float screenScaleFactor(UIScreen * = nullptr);
 | |
|  #endif
 | |
|  
 | |
|  #if ENABLE(TOUCH_EVENTS)
 | |
| -#if PLATFORM(GTK) || PLATFORM(WPE)
 | |
|  WEBCORE_EXPORT bool screenHasTouchDevice();
 | |
|  WEBCORE_EXPORT bool screenIsTouchPrimaryInputDevice();
 | |
| +#if PLATFORM(GTK) || PLATFORM(WPE)
 | |
| +bool platformScreenHasTouchDevice();
 | |
| +bool platformScreenIsTouchPrimaryInputDevice();
 | |
|  #else
 | |
| -constexpr bool screenHasTouchDevice() { return true; }
 | |
| -constexpr bool screenIsTouchPrimaryInputDevice() { return true; }
 | |
| +constexpr bool platformScreenHasTouchDevice() { return true; }
 | |
| +constexpr bool platformScreenIsTouchPrimaryInputDevice() { return true; }
 | |
|  #endif
 | |
|  #endif
 | |
|  
 | |
| diff --git a/Source/WebCore/platform/ScrollableArea.h b/Source/WebCore/platform/ScrollableArea.h
 | |
| index 0fbd9949f8a8927f1f342cbe33dea685dd482f41..27be181d431d58ef25c3f638178bd78593d7bb61 100644
 | |
| --- a/Source/WebCore/platform/ScrollableArea.h
 | |
| +++ b/Source/WebCore/platform/ScrollableArea.h
 | |
| @@ -102,7 +102,7 @@ public:
 | |
|      void stopKeyboardScrollAnimation();
 | |
|  
 | |
|  #if ENABLE(TOUCH_EVENTS)
 | |
| -    virtual bool handleTouchEvent(const PlatformTouchEvent&);
 | |
| +    WEBCORE_EXPORT virtual bool handleTouchEvent(const PlatformTouchEvent&);
 | |
|  #endif
 | |
|  
 | |
|  #if PLATFORM(IOS_FAMILY)
 | |
| diff --git a/Source/WebCore/platform/SourcesGLib.txt b/Source/WebCore/platform/SourcesGLib.txt
 | |
| index 53f48ba8ad99364680457daf4dcbae632360be12..8825859d561113f14ba6ef8d860c5202d2fbd253 100644
 | |
| --- a/Source/WebCore/platform/SourcesGLib.txt
 | |
| +++ b/Source/WebCore/platform/SourcesGLib.txt
 | |
| @@ -33,6 +33,7 @@ platform/glib/LowPowerModeNotifierGLib.cpp
 | |
|  platform/glib/RemoteCommandListenerGLib.cpp
 | |
|  platform/glib/SharedBufferGlib.cpp
 | |
|  platform/glib/UserAgentGLib.cpp
 | |
| +platform/glib/PlatformSpeechSynthesizerGLib.cpp
 | |
|  
 | |
|  platform/network/glib/DNSResolveQueueGLib.cpp
 | |
|  platform/network/glib/NetworkStateNotifierGLib.cpp
 | |
| diff --git a/Source/WebCore/platform/glib/PlatformSpeechSynthesizerGLib.cpp b/Source/WebCore/platform/glib/PlatformSpeechSynthesizerGLib.cpp
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..f0c3a183e5bc44bdfa4201e0db2067b41bf51580
 | |
| --- /dev/null
 | |
| +++ b/Source/WebCore/platform/glib/PlatformSpeechSynthesizerGLib.cpp
 | |
| @@ -0,0 +1,68 @@
 | |
| +/*
 | |
| + * Copyright (C) 2013 Apple Inc.  All rights reserved.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 | |
| + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | |
| + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 | |
| + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 | |
| + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 | |
| + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 | |
| + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 | |
| + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 | |
| + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#import "config.h"
 | |
| +#import "PlatformSpeechSynthesizer.h"
 | |
| +
 | |
| +#if ENABLE(SPEECH_SYNTHESIS)
 | |
| +
 | |
| +namespace WebCore {
 | |
| +
 | |
| +PlatformSpeechSynthesizer::PlatformSpeechSynthesizer(PlatformSpeechSynthesizerClient* client)
 | |
| +    : m_speechSynthesizerClient(client)
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +PlatformSpeechSynthesizer::~PlatformSpeechSynthesizer()
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +void PlatformSpeechSynthesizer::initializeVoiceList()
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +void PlatformSpeechSynthesizer::pause()
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +void PlatformSpeechSynthesizer::resume()
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +void PlatformSpeechSynthesizer::speak(RefPtr<PlatformSpeechSynthesisUtterance>&& utterance)
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +void PlatformSpeechSynthesizer::cancel()
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +void PlatformSpeechSynthesizer::resetState()
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +} // namespace WebCore
 | |
| +
 | |
| +#endif // ENABLE(SPEECH_SYNTHESIS)
 | |
| diff --git a/Source/WebCore/platform/graphics/FontCascade.h b/Source/WebCore/platform/graphics/FontCascade.h
 | |
| index ee63764693bb08b70a4ee6c54bf566f5143182cf..947c9c4f4bde763469e66b915e054f8d6426fe31 100644
 | |
| --- a/Source/WebCore/platform/graphics/FontCascade.h
 | |
| +++ b/Source/WebCore/platform/graphics/FontCascade.h
 | |
| @@ -306,7 +306,8 @@ private:
 | |
|              return true;
 | |
|          if (textRenderingMode == TextRenderingMode::OptimizeSpeed)
 | |
|              return false;
 | |
| -#if PLATFORM(COCOA) || USE(FREETYPE)
 | |
| +        // WIN: quick fix for https://bugs.webkit.org/show_bug.cgi?id=201213
 | |
| +#if PLATFORM(COCOA) || USE(FREETYPE) || PLATFORM(WIN)
 | |
|          return true;
 | |
|  #else
 | |
|          return false;
 | |
| diff --git a/Source/WebCore/platform/graphics/cairo/ImageBufferUtilitiesCairo.cpp b/Source/WebCore/platform/graphics/cairo/ImageBufferUtilitiesCairo.cpp
 | |
| index 4db603a94f3af1b1bce94ab0f1ae36054c004fcc..c1820f48eb86348f8ca678fde636244e8c91267e 100644
 | |
| --- a/Source/WebCore/platform/graphics/cairo/ImageBufferUtilitiesCairo.cpp
 | |
| +++ b/Source/WebCore/platform/graphics/cairo/ImageBufferUtilitiesCairo.cpp
 | |
| @@ -48,6 +48,13 @@
 | |
|  #include <wtf/glib/GUniquePtr.h>
 | |
|  #endif
 | |
|  
 | |
| +#if PLATFORM(WPE) || PLATFORM(WIN)
 | |
| +#include <stdio.h> // Needed by jpeglib.h for FILE.
 | |
| +extern "C" {
 | |
| +#include "jpeglib.h"
 | |
| +}
 | |
| +#endif
 | |
| +
 | |
|  namespace WebCore {
 | |
|  
 | |
|  #if !PLATFORM(GTK)
 | |
| @@ -65,8 +72,75 @@ static bool encodeImage(cairo_surface_t* image, const String& mimeType, Vector<u
 | |
|      return cairo_surface_write_to_png_stream(image, writeFunction, output) == CAIRO_STATUS_SUCCESS;
 | |
|  }
 | |
|  
 | |
| -Vector<uint8_t> data(cairo_surface_t* image, const String& mimeType, std::optional<double>)
 | |
| +static Vector<uint8_t> encodeJpeg(cairo_surface_t* image, int quality)
 | |
| +{
 | |
| +    if (cairo_surface_get_type(image) != CAIRO_SURFACE_TYPE_IMAGE) {
 | |
| +        fprintf(stderr, "Unexpected cairo surface type: %d\n", cairo_surface_get_type(image));
 | |
| +        return { };
 | |
| +    }
 | |
| +
 | |
| +    if (cairo_image_surface_get_format(image) != CAIRO_FORMAT_ARGB32) {
 | |
| +        fprintf(stderr, "Unexpected surface image format: %d\n", cairo_image_surface_get_format(image));
 | |
| +        return { };
 | |
| +    }
 | |
| +
 | |
| +    struct jpeg_compress_struct info;
 | |
| +    struct jpeg_error_mgr error;
 | |
| +    info.err = jpeg_std_error(&error);
 | |
| +    jpeg_create_compress(&info);
 | |
| +
 | |
| +    unsigned char* bufferPtr = nullptr;
 | |
| +    unsigned long bufferSize;
 | |
| +    jpeg_mem_dest(&info, &bufferPtr, &bufferSize);
 | |
| +    info.image_width = cairo_image_surface_get_width(image);
 | |
| +    info.image_height = cairo_image_surface_get_height(image);
 | |
| +
 | |
| +#ifndef LIBJPEG_TURBO_VERSION
 | |
| +    COMPILE_ASSERT(false, only_libjpeg_turbo_is_supported);
 | |
| +#endif
 | |
| +
 | |
| +#if CPU(LITTLE_ENDIAN)
 | |
| +    info.in_color_space = JCS_EXT_BGRA;
 | |
| +#else
 | |
| +    info.in_color_space = JCS_EXT_ARGB;
 | |
| +#endif
 | |
| +    // # of color components in input image
 | |
| +    info.input_components = 4;
 | |
| +
 | |
| +    jpeg_set_defaults(&info);
 | |
| +    jpeg_set_quality(&info, quality, true);
 | |
| +
 | |
| +    jpeg_start_compress(&info, true);
 | |
| +
 | |
| +    while (info.next_scanline < info.image_height)
 | |
| +    {
 | |
| +        JSAMPROW row = cairo_image_surface_get_data(image) + (info.next_scanline * cairo_image_surface_get_stride(image));
 | |
| +        if (jpeg_write_scanlines(&info, &row, 1) != 1) {
 | |
| +            fprintf(stderr, "JPEG library failed to encode line\n");
 | |
| +            break;
 | |
| +        }
 | |
| +    }
 | |
| +
 | |
| +    jpeg_finish_compress(&info);
 | |
| +    jpeg_destroy_compress(&info);
 | |
| +
 | |
| +    Vector<uint8_t> output;
 | |
| +    output.append(bufferPtr, bufferSize);
 | |
| +    // Cannot use unique_ptr as bufferPtr changes during compression. GUniquePtr would work
 | |
| +    // but it's under GLib and won't work on Windows.
 | |
| +    free(bufferPtr);
 | |
| +    return output;
 | |
| +}
 | |
| +
 | |
| +Vector<uint8_t> data(cairo_surface_t* image, const String& mimeType, std::optional<double> quality)
 | |
|  {
 | |
| +    if (mimeType == "image/jpeg") {
 | |
| +        int qualityPercent = 100;
 | |
| +        if (quality)
 | |
| +            qualityPercent = static_cast<int>(*quality * 100.0 + 0.5);
 | |
| +        return encodeJpeg(image, qualityPercent);
 | |
| +    }
 | |
| +
 | |
|      Vector<uint8_t> encodedImage;
 | |
|      if (!image || !encodeImage(image, mimeType, &encodedImage))
 | |
|          return { };
 | |
| diff --git a/Source/WebCore/platform/graphics/cg/ImageBufferUtilitiesCG.h b/Source/WebCore/platform/graphics/cg/ImageBufferUtilitiesCG.h
 | |
| index 8677d106bf2d0f53044b47fba0e6736efcd3aeb6..9b28f9d917536d2c2699f613adf296bbdd965969 100644
 | |
| --- a/Source/WebCore/platform/graphics/cg/ImageBufferUtilitiesCG.h
 | |
| +++ b/Source/WebCore/platform/graphics/cg/ImageBufferUtilitiesCG.h
 | |
| @@ -36,10 +36,10 @@ class PixelBuffer;
 | |
|  
 | |
|  WEBCORE_EXPORT uint8_t verifyImageBufferIsBigEnough(const void* buffer, size_t bufferSize);
 | |
|  
 | |
| -CFStringRef jpegUTI();
 | |
| +WEBCORE_EXPORT CFStringRef jpegUTI();
 | |
|  WEBCORE_EXPORT RetainPtr<CFStringRef> utiFromImageBufferMIMEType(const String&);
 | |
|  
 | |
| -Vector<uint8_t> data(CGImageRef, CFStringRef destinationUTI, std::optional<double> quality);
 | |
| +WEBCORE_EXPORT Vector<uint8_t> data(CGImageRef, CFStringRef destinationUTI, std::optional<double> quality);
 | |
|  Vector<uint8_t> data(const PixelBuffer&, const String& mimeType, std::optional<double> quality);
 | |
|  
 | |
|  WEBCORE_EXPORT String dataURL(CGImageRef, CFStringRef destinationUTI, const String& mimeType, std::optional<double> quality);
 | |
| diff --git a/Source/WebCore/platform/graphics/filters/software/FEComponentTransferSoftwareApplier.h b/Source/WebCore/platform/graphics/filters/software/FEComponentTransferSoftwareApplier.h
 | |
| index b60f9a64bacc8282860da6de299b75aeb295b9b5..55bd017c03c6478ca334bd5ef164160fef5d5302 100644
 | |
| --- a/Source/WebCore/platform/graphics/filters/software/FEComponentTransferSoftwareApplier.h
 | |
| +++ b/Source/WebCore/platform/graphics/filters/software/FEComponentTransferSoftwareApplier.h
 | |
| @@ -23,6 +23,7 @@
 | |
|  #pragma once
 | |
|  
 | |
|  #include "FilterEffectApplier.h"
 | |
| +#include "PixelBuffer.h"
 | |
|  
 | |
|  namespace WebCore {
 | |
|  
 | |
| diff --git a/Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGLBase.cpp b/Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGLBase.cpp
 | |
| index 7b54a01f3e963c18791734ec4a3c4ea8c8f38a9e..dd7ce59e0cef49f1214a71f35bda597708081496 100644
 | |
| --- a/Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGLBase.cpp
 | |
| +++ b/Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGLBase.cpp
 | |
| @@ -27,7 +27,7 @@
 | |
|  #include "config.h"
 | |
|  #include "GraphicsContextGLOpenGL.h"
 | |
|  
 | |
| -#if ENABLE(WEBGL) && USE(OPENGL)
 | |
| +#if !PLATFORM(WIN) && ENABLE(WEBGL) && USE(OPENGL)
 | |
|  
 | |
|  #include "ExtensionsGLOpenGL.h"
 | |
|  #include "IntRect.h"
 | |
| diff --git a/Source/WebCore/platform/graphics/win/ComplexTextControllerUniscribe.cpp b/Source/WebCore/platform/graphics/win/ComplexTextControllerUniscribe.cpp
 | |
| index 6d6820fc22f9a7102bbdad6c4b5e3e7e9645f66c..f44797b8c197bf1b3daaa9b59dad2a8e250c4791 100644
 | |
| --- a/Source/WebCore/platform/graphics/win/ComplexTextControllerUniscribe.cpp
 | |
| +++ b/Source/WebCore/platform/graphics/win/ComplexTextControllerUniscribe.cpp
 | |
| @@ -170,6 +170,33 @@ static Vector<unsigned> stringIndicesFromClusters(const Vector<WORD>& clusters,
 | |
|      return stringIndices;
 | |
|  }
 | |
|  
 | |
| +static int compactScriptItemsIfNeeded(const UChar* cp, unsigned stringLength, Vector<SCRIPT_ITEM>& items, int numItems, const Font* font)
 | |
| +{
 | |
| +    // https://bugs.webkit.org/show_bug.cgi?id=201214
 | |
| +    // Uniscribe is overly aggressive in separating the runs. It'll split "3d_rotation" into "3", "d", "_" and "rotation" and we
 | |
| +    // will ScriptShape them separately. As a result, a ligature for "3d_rotation" in the Material icon set
 | |
| +    // (https://www.materialui.co/icon/3d-rotation) will not be used. A quick and dirty hack is to glue them back here, only making
 | |
| +    // this apply to the readable characters, digits and _.
 | |
| +
 | |
| +    if (!numItems)
 | |
| +        return numItems;
 | |
| +
 | |
| +    if (font->platformData().isSystemFont() || font->platformData().hasVariations())
 | |
| +        return numItems;
 | |
| +
 | |
| +    bool allGoodCharacters = true;
 | |
| +    for (unsigned i = 0; allGoodCharacters && i < stringLength; ++i) {
 | |
| +        const UChar c = cp[i];
 | |
| +        allGoodCharacters = (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c == '_';
 | |
| +    }
 | |
| +    if (!allGoodCharacters)
 | |
| +        return numItems;
 | |
| +
 | |
| +    // Consume entire string into a single run. |items| is at least numItems + 1 long.
 | |
| +    items[1] = items[numItems];
 | |
| +    return 1;
 | |
| +}
 | |
| +
 | |
|  void ComplexTextController::collectComplexTextRunsForCharacters(const UChar* cp, unsigned stringLength, unsigned stringLocation, const Font* font)
 | |
|  {
 | |
|      if (!font) {
 | |
| @@ -199,6 +226,8 @@ void ComplexTextController::collectComplexTextRunsForCharacters(const UChar* cp,
 | |
|      }
 | |
|      items.resize(numItems + 1);
 | |
|  
 | |
| +    numItems = compactScriptItemsIfNeeded(cp, stringLength, items, numItems, font);
 | |
| +
 | |
|      for (int i = 0; i < numItems; i++) {
 | |
|          // Determine the string for this item.
 | |
|          const UChar* str = cp + items[i].iCharPos;
 | |
| diff --git a/Source/WebCore/platform/gtk/PlatformKeyboardEventGtk.cpp b/Source/WebCore/platform/gtk/PlatformKeyboardEventGtk.cpp
 | |
| index dd5fb8634277baea92be6ecaf6d2fbc7ce7ee9f0..9aa9e4d923d487cd4003e7396ebe61c7df51057d 100644
 | |
| --- a/Source/WebCore/platform/gtk/PlatformKeyboardEventGtk.cpp
 | |
| +++ b/Source/WebCore/platform/gtk/PlatformKeyboardEventGtk.cpp
 | |
| @@ -37,8 +37,10 @@
 | |
|  #include <gdk/gdk.h>
 | |
|  #include <gdk/gdkkeysyms.h>
 | |
|  #include <pal/text/TextEncoding.h>
 | |
| +#include <wtf/HashMap.h>
 | |
|  #include <wtf/HexNumber.h>
 | |
|  #include <wtf/glib/GUniquePtr.h>
 | |
| +#include <mutex>
 | |
|  
 | |
|  namespace WebCore {
 | |
|  
 | |
| @@ -1294,6 +1296,246 @@ int PlatformKeyboardEvent::windowsKeyCodeForGdkKeyCode(unsigned keycode)
 | |
|  
 | |
|  }
 | |
|  
 | |
| +static const HashMap<int, unsigned>& gdkToWindowsKeyCodeMap()
 | |
| +{
 | |
| +    static HashMap<int, unsigned>* result;
 | |
| +    static std::once_flag once;
 | |
| +    std::call_once(
 | |
| +        once,
 | |
| +        [] {
 | |
| +            const unsigned gdkKeyCodes[] = {
 | |
| +                GDK_KEY_Cancel,
 | |
| +                // FIXME: non-keypad keys should take precedence, so we skip GDK_KEY_KP_*
 | |
| +                // GDK_KEY_KP_0,
 | |
| +                // GDK_KEY_KP_1,
 | |
| +                // GDK_KEY_KP_2,
 | |
| +                // GDK_KEY_KP_3,
 | |
| +                // GDK_KEY_KP_4,
 | |
| +                // GDK_KEY_KP_5,
 | |
| +                // GDK_KEY_KP_6,
 | |
| +                // GDK_KEY_KP_7,
 | |
| +                // GDK_KEY_KP_8,
 | |
| +                // GDK_KEY_KP_9,
 | |
| +                // GDK_KEY_KP_Multiply,
 | |
| +                // GDK_KEY_KP_Add,
 | |
| +                // GDK_KEY_KP_Subtract,
 | |
| +                // GDK_KEY_KP_Decimal,
 | |
| +                // GDK_KEY_KP_Divide,
 | |
| +                // GDK_KEY_KP_Page_Up,
 | |
| +                // GDK_KEY_KP_Page_Down,
 | |
| +                // GDK_KEY_KP_End,
 | |
| +                // GDK_KEY_KP_Home,
 | |
| +                // GDK_KEY_KP_Left,
 | |
| +                // GDK_KEY_KP_Up,
 | |
| +                // GDK_KEY_KP_Right,
 | |
| +                // GDK_KEY_KP_Down,
 | |
| +                GDK_KEY_BackSpace,
 | |
| +                // GDK_KEY_ISO_Left_Tab,
 | |
| +                // GDK_KEY_3270_BackTab,
 | |
| +                GDK_KEY_Tab,
 | |
| +                GDK_KEY_Clear,
 | |
| +                // GDK_KEY_ISO_Enter,
 | |
| +                // GDK_KEY_KP_Enter,
 | |
| +                GDK_KEY_Return,
 | |
| +                GDK_KEY_Menu,
 | |
| +                GDK_KEY_Pause,
 | |
| +                GDK_KEY_AudioPause,
 | |
| +                GDK_KEY_Caps_Lock,
 | |
| +                GDK_KEY_Kana_Lock,
 | |
| +                GDK_KEY_Kana_Shift,
 | |
| +                GDK_KEY_Hangul,
 | |
| +                GDK_KEY_Hangul_Hanja,
 | |
| +                GDK_KEY_Kanji,
 | |
| +                GDK_KEY_Escape,
 | |
| +                GDK_KEY_space,
 | |
| +                GDK_KEY_Page_Up,
 | |
| +                GDK_KEY_Page_Down,
 | |
| +                GDK_KEY_End,
 | |
| +                GDK_KEY_Home,
 | |
| +                GDK_KEY_Left,
 | |
| +                GDK_KEY_Up,
 | |
| +                GDK_KEY_Right,
 | |
| +                GDK_KEY_Down,
 | |
| +                GDK_KEY_Select,
 | |
| +                GDK_KEY_Print,
 | |
| +                GDK_KEY_Execute,
 | |
| +                GDK_KEY_Insert,
 | |
| +                GDK_KEY_KP_Insert,
 | |
| +                GDK_KEY_Delete,
 | |
| +                GDK_KEY_KP_Delete,
 | |
| +                GDK_KEY_Help,
 | |
| +                GDK_KEY_0,
 | |
| +                GDK_KEY_parenright,
 | |
| +                GDK_KEY_1,
 | |
| +                GDK_KEY_exclam,
 | |
| +                GDK_KEY_2,
 | |
| +                GDK_KEY_at,
 | |
| +                GDK_KEY_3,
 | |
| +                GDK_KEY_numbersign,
 | |
| +                GDK_KEY_4,
 | |
| +                GDK_KEY_dollar,
 | |
| +                GDK_KEY_5,
 | |
| +                GDK_KEY_percent,
 | |
| +                GDK_KEY_6,
 | |
| +                GDK_KEY_asciicircum,
 | |
| +                GDK_KEY_7,
 | |
| +                GDK_KEY_ampersand,
 | |
| +                GDK_KEY_8,
 | |
| +                GDK_KEY_asterisk,
 | |
| +                GDK_KEY_9,
 | |
| +                GDK_KEY_parenleft,
 | |
| +                GDK_KEY_a,
 | |
| +                GDK_KEY_A,
 | |
| +                GDK_KEY_b,
 | |
| +                GDK_KEY_B,
 | |
| +                GDK_KEY_c,
 | |
| +                GDK_KEY_C,
 | |
| +                GDK_KEY_d,
 | |
| +                GDK_KEY_D,
 | |
| +                GDK_KEY_e,
 | |
| +                GDK_KEY_E,
 | |
| +                GDK_KEY_f,
 | |
| +                GDK_KEY_F,
 | |
| +                GDK_KEY_g,
 | |
| +                GDK_KEY_G,
 | |
| +                GDK_KEY_h,
 | |
| +                GDK_KEY_H,
 | |
| +                GDK_KEY_i,
 | |
| +                GDK_KEY_I,
 | |
| +                GDK_KEY_j,
 | |
| +                GDK_KEY_J,
 | |
| +                GDK_KEY_k,
 | |
| +                GDK_KEY_K,
 | |
| +                GDK_KEY_l,
 | |
| +                GDK_KEY_L,
 | |
| +                GDK_KEY_m,
 | |
| +                GDK_KEY_M,
 | |
| +                GDK_KEY_n,
 | |
| +                GDK_KEY_N,
 | |
| +                GDK_KEY_o,
 | |
| +                GDK_KEY_O,
 | |
| +                GDK_KEY_p,
 | |
| +                GDK_KEY_P,
 | |
| +                GDK_KEY_q,
 | |
| +                GDK_KEY_Q,
 | |
| +                GDK_KEY_r,
 | |
| +                GDK_KEY_R,
 | |
| +                GDK_KEY_s,
 | |
| +                GDK_KEY_S,
 | |
| +                GDK_KEY_t,
 | |
| +                GDK_KEY_T,
 | |
| +                GDK_KEY_u,
 | |
| +                GDK_KEY_U,
 | |
| +                GDK_KEY_v,
 | |
| +                GDK_KEY_V,
 | |
| +                GDK_KEY_w,
 | |
| +                GDK_KEY_W,
 | |
| +                GDK_KEY_x,
 | |
| +                GDK_KEY_X,
 | |
| +                GDK_KEY_y,
 | |
| +                GDK_KEY_Y,
 | |
| +                GDK_KEY_z,
 | |
| +                GDK_KEY_Z,
 | |
| +                GDK_KEY_Meta_L,
 | |
| +                GDK_KEY_Meta_R,
 | |
| +                GDK_KEY_Sleep,
 | |
| +                GDK_KEY_Num_Lock,
 | |
| +                GDK_KEY_Scroll_Lock,
 | |
| +                GDK_KEY_Shift_L,
 | |
| +                GDK_KEY_Shift_R,
 | |
| +                GDK_KEY_Control_L,
 | |
| +                GDK_KEY_Control_R,
 | |
| +                GDK_KEY_Alt_L,
 | |
| +                GDK_KEY_Alt_R,
 | |
| +                GDK_KEY_Back,
 | |
| +                GDK_KEY_Forward,
 | |
| +                GDK_KEY_Refresh,
 | |
| +                GDK_KEY_Stop,
 | |
| +                GDK_KEY_Search,
 | |
| +                GDK_KEY_Favorites,
 | |
| +                GDK_KEY_HomePage,
 | |
| +                GDK_KEY_AudioMute,
 | |
| +                GDK_KEY_AudioLowerVolume,
 | |
| +                GDK_KEY_AudioRaiseVolume,
 | |
| +                GDK_KEY_AudioNext,
 | |
| +                GDK_KEY_AudioPrev,
 | |
| +                GDK_KEY_AudioStop,
 | |
| +                GDK_KEY_AudioMedia,
 | |
| +                GDK_KEY_semicolon,
 | |
| +                GDK_KEY_colon,
 | |
| +                GDK_KEY_plus,
 | |
| +                GDK_KEY_equal,
 | |
| +                GDK_KEY_comma,
 | |
| +                GDK_KEY_less,
 | |
| +                GDK_KEY_minus,
 | |
| +                GDK_KEY_underscore,
 | |
| +                GDK_KEY_period,
 | |
| +                GDK_KEY_greater,
 | |
| +                GDK_KEY_slash,
 | |
| +                GDK_KEY_question,
 | |
| +                GDK_KEY_asciitilde,
 | |
| +                GDK_KEY_quoteleft,
 | |
| +                GDK_KEY_bracketleft,
 | |
| +                GDK_KEY_braceleft,
 | |
| +                GDK_KEY_backslash,
 | |
| +                GDK_KEY_bar,
 | |
| +                GDK_KEY_bracketright,
 | |
| +                GDK_KEY_braceright,
 | |
| +                GDK_KEY_quoteright,
 | |
| +                GDK_KEY_quotedbl,
 | |
| +                GDK_KEY_AudioRewind,
 | |
| +                GDK_KEY_AudioForward,
 | |
| +                GDK_KEY_AudioPlay,
 | |
| +                GDK_KEY_F1,
 | |
| +                GDK_KEY_F2,
 | |
| +                GDK_KEY_F3,
 | |
| +                GDK_KEY_F4,
 | |
| +                GDK_KEY_F5,
 | |
| +                GDK_KEY_F6,
 | |
| +                GDK_KEY_F7,
 | |
| +                GDK_KEY_F8,
 | |
| +                GDK_KEY_F9,
 | |
| +                GDK_KEY_F10,
 | |
| +                GDK_KEY_F11,
 | |
| +                GDK_KEY_F12,
 | |
| +                GDK_KEY_F13,
 | |
| +                GDK_KEY_F14,
 | |
| +                GDK_KEY_F15,
 | |
| +                GDK_KEY_F16,
 | |
| +                GDK_KEY_F17,
 | |
| +                GDK_KEY_F18,
 | |
| +                GDK_KEY_F19,
 | |
| +                GDK_KEY_F20,
 | |
| +                GDK_KEY_F21,
 | |
| +                GDK_KEY_F22,
 | |
| +                GDK_KEY_F23,
 | |
| +                GDK_KEY_F24,
 | |
| +                GDK_KEY_VoidSymbol,
 | |
| +                GDK_KEY_Red,
 | |
| +                GDK_KEY_Green,
 | |
| +                GDK_KEY_Yellow,
 | |
| +                GDK_KEY_Blue,
 | |
| +                GDK_KEY_PowerOff,
 | |
| +                GDK_KEY_AudioRecord,
 | |
| +                GDK_KEY_Display,
 | |
| +                GDK_KEY_Subtitle,
 | |
| +                GDK_KEY_Video
 | |
| +            };
 | |
| +            result = new HashMap<int, unsigned>();
 | |
| +            for (unsigned gdkKeyCode : gdkKeyCodes) {
 | |
| +                int winKeyCode = PlatformKeyboardEvent::windowsKeyCodeForGdkKeyCode(gdkKeyCode);
 | |
| +                // If several gdk key codes map to the same win key code first one is used.
 | |
| +                result->add(winKeyCode, gdkKeyCode);
 | |
| +            }
 | |
| +        });
 | |
| +    return *result;
 | |
| +}
 | |
| +
 | |
| +unsigned PlatformKeyboardEvent::gdkKeyCodeForWindowsKeyCode(int keycode)
 | |
| +{
 | |
| +    return gdkToWindowsKeyCodeMap().get(keycode);
 | |
| +}
 | |
| +
 | |
|  String PlatformKeyboardEvent::singleCharacterString(unsigned val)
 | |
|  {
 | |
|      switch (val) {
 | |
| diff --git a/Source/WebCore/platform/gtk/PlatformScreenGtk.cpp b/Source/WebCore/platform/gtk/PlatformScreenGtk.cpp
 | |
| index 80958ba565a877224d0ed37e4e4057b4be0dde24..eca42bf5181bc4a95efca9c9c3f5ce0f987fea43 100644
 | |
| --- a/Source/WebCore/platform/gtk/PlatformScreenGtk.cpp
 | |
| +++ b/Source/WebCore/platform/gtk/PlatformScreenGtk.cpp
 | |
| @@ -224,7 +224,7 @@ bool screenSupportsExtendedColor(Widget*)
 | |
|  }
 | |
|  
 | |
|  #if ENABLE(TOUCH_EVENTS)
 | |
| -bool screenHasTouchDevice()
 | |
| +bool platformScreenHasTouchDevice()
 | |
|  {
 | |
|      auto* display = gdk_display_get_default();
 | |
|      if (!display)
 | |
| @@ -234,7 +234,7 @@ bool screenHasTouchDevice()
 | |
|      return seat ? gdk_seat_get_capabilities(seat) & GDK_SEAT_CAPABILITY_TOUCH : true;
 | |
|  }
 | |
|  
 | |
| -bool screenIsTouchPrimaryInputDevice()
 | |
| +bool platformScreenIsTouchPrimaryInputDevice()
 | |
|  {
 | |
|      auto* display = gdk_display_get_default();
 | |
|      if (!display)
 | |
| diff --git a/Source/WebCore/platform/libwpe/PasteboardLibWPE.cpp b/Source/WebCore/platform/libwpe/PasteboardLibWPE.cpp
 | |
| index ae439e30f1fb239d18e1164e8896dfb272c75673..93bbf2bdfc99df151c9b82df07eb5a07fae0b2c4 100644
 | |
| --- a/Source/WebCore/platform/libwpe/PasteboardLibWPE.cpp
 | |
| +++ b/Source/WebCore/platform/libwpe/PasteboardLibWPE.cpp
 | |
| @@ -32,6 +32,10 @@
 | |
|  #include "PasteboardStrategy.h"
 | |
|  #include "PlatformStrategies.h"
 | |
|  
 | |
| +#if ENABLE(DRAG_SUPPORT)
 | |
| +#include "DragData.h"
 | |
| +#endif
 | |
| +
 | |
|  namespace WebCore {
 | |
|  
 | |
|  std::unique_ptr<Pasteboard> Pasteboard::createForCopyAndPaste(std::unique_ptr<PasteboardContext>&& context)
 | |
| @@ -73,6 +77,16 @@ String Pasteboard::readOrigin()
 | |
|  
 | |
|  String Pasteboard::readString(const String& type)
 | |
|  {
 | |
| +    if (m_selectionData) {
 | |
| +        if (type == "text/plain")
 | |
| +            return m_selectionData->text();;
 | |
| +        if (type == "text/html")
 | |
| +            return m_selectionData->markup();
 | |
| +        if (type == "Files" || type == "text/uri-list")
 | |
| +            return m_selectionData->uriList();
 | |
| +        return { };
 | |
| +    }
 | |
| +
 | |
|      return platformStrategies()->pasteboardStrategy()->readStringFromPasteboard(0, type, name(), context());
 | |
|  }
 | |
|  
 | |
| @@ -84,6 +98,15 @@ String Pasteboard::readStringInCustomData(const String&)
 | |
|  
 | |
|  void Pasteboard::writeString(const String& type, const String& text)
 | |
|  {
 | |
| +   if (m_selectionData) {
 | |
| +        if (type == "Files" || type == "text/uri-list")
 | |
| +            m_selectionData->setURIList(text);
 | |
| +        else if (type == "text/html")
 | |
| +            m_selectionData->setMarkup(text);
 | |
| +        else if (type == "text/plain")
 | |
| +            m_selectionData->setText(text);
 | |
| +        return;
 | |
| +    }
 | |
|      platformStrategies()->pasteboardStrategy()->writeToPasteboard(type, text);
 | |
|  }
 | |
|  
 | |
| @@ -111,7 +134,12 @@ void Pasteboard::read(PasteboardFileReader&, std::optional<size_t>)
 | |
|  
 | |
|  void Pasteboard::write(const PasteboardURL& url)
 | |
|  {
 | |
| -    platformStrategies()->pasteboardStrategy()->writeToPasteboard("text/plain;charset=utf-8"_s, url.url.string());
 | |
| +    if (m_selectionData) {
 | |
| +        m_selectionData->clearAll();
 | |
| +        m_selectionData->setURL(url.url, url.title);
 | |
| +    } else {
 | |
| +        platformStrategies()->pasteboardStrategy()->writeToPasteboard("text/plain;charset=utf-8"_s, url.url.string());
 | |
| +    }
 | |
|  }
 | |
|  
 | |
|  void Pasteboard::writeTrustworthyWebURLsPboardType(const PasteboardURL&)
 | |
| @@ -119,8 +147,16 @@ void Pasteboard::writeTrustworthyWebURLsPboardType(const PasteboardURL&)
 | |
|      notImplemented();
 | |
|  }
 | |
|  
 | |
| -void Pasteboard::write(const PasteboardImage&)
 | |
| +void Pasteboard::write(const PasteboardImage& pasteboardImage)
 | |
|  {
 | |
| +    if (m_selectionData) {
 | |
| +        m_selectionData->clearAll();
 | |
| +        if (!pasteboardImage.url.url.isEmpty()) {
 | |
| +            m_selectionData->setURL(pasteboardImage.url.url, pasteboardImage.url.title);
 | |
| +            m_selectionData->setMarkup(pasteboardImage.url.markup);
 | |
| +        }
 | |
| +        m_selectionData->setImage(pasteboardImage.image.get());
 | |
| +    }
 | |
|  }
 | |
|  
 | |
|  void Pasteboard::write(const PasteboardBuffer&)
 | |
| @@ -129,7 +165,14 @@ void Pasteboard::write(const PasteboardBuffer&)
 | |
|  
 | |
|  void Pasteboard::write(const PasteboardWebContent& content)
 | |
|  {
 | |
| -    platformStrategies()->pasteboardStrategy()->writeToPasteboard(content);
 | |
| +    if (m_selectionData) {
 | |
| +        m_selectionData->clearAll();
 | |
| +        m_selectionData->setText(content.text);
 | |
| +        m_selectionData->setMarkup(content.markup);
 | |
| +        m_selectionData->setCanSmartReplace(content.canSmartCopyOrDelete);
 | |
| +    } else {
 | |
| +        platformStrategies()->pasteboardStrategy()->writeToPasteboard(content);
 | |
| +    }
 | |
|  }
 | |
|  
 | |
|  Pasteboard::FileContentState Pasteboard::fileContentState()
 | |
| @@ -160,6 +203,35 @@ void Pasteboard::write(const Color&)
 | |
|  {
 | |
|  }
 | |
|  
 | |
| +#if ENABLE(DRAG_SUPPORT)
 | |
| +
 | |
| +Pasteboard::Pasteboard(std::unique_ptr<PasteboardContext>&& context, SelectionData&& selectionData)
 | |
| +    : m_context(WTFMove(context))
 | |
| +    , m_selectionData(WTFMove(selectionData))
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +Pasteboard::Pasteboard(std::unique_ptr<PasteboardContext>&& context, SelectionData& selectionData)
 | |
| +    : m_context(WTFMove(context))
 | |
| +    , m_selectionData(selectionData)
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +std::unique_ptr<Pasteboard> Pasteboard::createForDragAndDrop(std::unique_ptr<PasteboardContext>&& context)
 | |
| +{
 | |
| +    return makeUnique<Pasteboard>(WTFMove(context), SelectionData());
 | |
| +}
 | |
| +
 | |
| +std::unique_ptr<Pasteboard> Pasteboard::create(const DragData& dragData)
 | |
| +{
 | |
| +    RELEASE_ASSERT(dragData.platformData());
 | |
| +    return makeUnique<Pasteboard>(dragData.createPasteboardContext(), *dragData.platformData());
 | |
| +}
 | |
| +void Pasteboard::setDragImage(DragImage, const IntPoint&)
 | |
| +{
 | |
| +}
 | |
| +#endif
 | |
| +
 | |
|  } // namespace WebCore
 | |
|  
 | |
|  #endif // USE(LIBWPE)
 | |
| diff --git a/Source/WebCore/platform/libwpe/PlatformKeyboardEventLibWPE.cpp b/Source/WebCore/platform/libwpe/PlatformKeyboardEventLibWPE.cpp
 | |
| index a724f126f8f389d46ba5c1a941eef76fdc59c94c..aa40f6c3ee81213074639cce1d18eb21c6e204f4 100644
 | |
| --- a/Source/WebCore/platform/libwpe/PlatformKeyboardEventLibWPE.cpp
 | |
| +++ b/Source/WebCore/platform/libwpe/PlatformKeyboardEventLibWPE.cpp
 | |
| @@ -30,8 +30,10 @@
 | |
|  
 | |
|  #include "WindowsKeyboardCodes.h"
 | |
|  #include <wpe/wpe.h>
 | |
| +#include <wtf/HashMap.h>
 | |
|  #include <wtf/HexNumber.h>
 | |
|  #include <wtf/text/StringBuilder.h>
 | |
| +#include <mutex>
 | |
|  
 | |
|  namespace WebCore {
 | |
|  
 | |
| @@ -1291,6 +1293,246 @@ int PlatformKeyboardEvent::windowsKeyCodeForWPEKeyCode(unsigned keycode)
 | |
|      return 0;
 | |
|  }
 | |
|  
 | |
| +static const HashMap<int, unsigned>& WPEToWindowsKeyCodeMap()
 | |
| +{
 | |
| +    static HashMap<int, unsigned>* result;
 | |
| +    static std::once_flag once;
 | |
| +    std::call_once(
 | |
| +        once,
 | |
| +        [] {
 | |
| +            const unsigned WPEKeyCodes[] = {
 | |
| +                WPE_KEY_Cancel,
 | |
| +                // FIXME: non-keypad keys should take precedence, so we skip WPE_KEY_KP_*
 | |
| +                // WPE_KEY_KP_0,
 | |
| +                // WPE_KEY_KP_1,
 | |
| +                // WPE_KEY_KP_2,
 | |
| +                // WPE_KEY_KP_3,
 | |
| +                // WPE_KEY_KP_4,
 | |
| +                // WPE_KEY_KP_5,
 | |
| +                // WPE_KEY_KP_6,
 | |
| +                // WPE_KEY_KP_7,
 | |
| +                // WPE_KEY_KP_8,
 | |
| +                // WPE_KEY_KP_9,
 | |
| +                // WPE_KEY_KP_Multiply,
 | |
| +                // WPE_KEY_KP_Add,
 | |
| +                // WPE_KEY_KP_Subtract,
 | |
| +                // WPE_KEY_KP_Decimal,
 | |
| +                // WPE_KEY_KP_Divide,
 | |
| +                // WPE_KEY_KP_Page_Up,
 | |
| +                // WPE_KEY_KP_Page_Down,
 | |
| +                // WPE_KEY_KP_End,
 | |
| +                // WPE_KEY_KP_Home,
 | |
| +                // WPE_KEY_KP_Left,
 | |
| +                // WPE_KEY_KP_Up,
 | |
| +                // WPE_KEY_KP_Right,
 | |
| +                // WPE_KEY_KP_Down,
 | |
| +                WPE_KEY_BackSpace,
 | |
| +                // WPE_KEY_ISO_Left_Tab,
 | |
| +                // WPE_KEY_3270_BackTab,
 | |
| +                WPE_KEY_Tab,
 | |
| +                WPE_KEY_Clear,
 | |
| +                // WPE_KEY_ISO_Enter,
 | |
| +                // WPE_KEY_KP_Enter,
 | |
| +                WPE_KEY_Return,
 | |
| +                WPE_KEY_Menu,
 | |
| +                WPE_KEY_Pause,
 | |
| +                WPE_KEY_AudioPause,
 | |
| +                WPE_KEY_Caps_Lock,
 | |
| +                WPE_KEY_Kana_Lock,
 | |
| +                WPE_KEY_Kana_Shift,
 | |
| +                WPE_KEY_Hangul,
 | |
| +                WPE_KEY_Hangul_Hanja,
 | |
| +                WPE_KEY_Kanji,
 | |
| +                WPE_KEY_Escape,
 | |
| +                WPE_KEY_space,
 | |
| +                WPE_KEY_Page_Up,
 | |
| +                WPE_KEY_Page_Down,
 | |
| +                WPE_KEY_End,
 | |
| +                WPE_KEY_Home,
 | |
| +                WPE_KEY_Left,
 | |
| +                WPE_KEY_Up,
 | |
| +                WPE_KEY_Right,
 | |
| +                WPE_KEY_Down,
 | |
| +                WPE_KEY_Select,
 | |
| +                WPE_KEY_Print,
 | |
| +                WPE_KEY_Execute,
 | |
| +                WPE_KEY_Insert,
 | |
| +                WPE_KEY_KP_Insert,
 | |
| +                WPE_KEY_Delete,
 | |
| +                WPE_KEY_KP_Delete,
 | |
| +                WPE_KEY_Help,
 | |
| +                WPE_KEY_0,
 | |
| +                WPE_KEY_parenright,
 | |
| +                WPE_KEY_1,
 | |
| +                WPE_KEY_exclam,
 | |
| +                WPE_KEY_2,
 | |
| +                WPE_KEY_at,
 | |
| +                WPE_KEY_3,
 | |
| +                WPE_KEY_numbersign,
 | |
| +                WPE_KEY_4,
 | |
| +                WPE_KEY_dollar,
 | |
| +                WPE_KEY_5,
 | |
| +                WPE_KEY_percent,
 | |
| +                WPE_KEY_6,
 | |
| +                WPE_KEY_asciicircum,
 | |
| +                WPE_KEY_7,
 | |
| +                WPE_KEY_ampersand,
 | |
| +                WPE_KEY_8,
 | |
| +                WPE_KEY_asterisk,
 | |
| +                WPE_KEY_9,
 | |
| +                WPE_KEY_parenleft,
 | |
| +                WPE_KEY_a,
 | |
| +                WPE_KEY_A,
 | |
| +                WPE_KEY_b,
 | |
| +                WPE_KEY_B,
 | |
| +                WPE_KEY_c,
 | |
| +                WPE_KEY_C,
 | |
| +                WPE_KEY_d,
 | |
| +                WPE_KEY_D,
 | |
| +                WPE_KEY_e,
 | |
| +                WPE_KEY_E,
 | |
| +                WPE_KEY_f,
 | |
| +                WPE_KEY_F,
 | |
| +                WPE_KEY_g,
 | |
| +                WPE_KEY_G,
 | |
| +                WPE_KEY_h,
 | |
| +                WPE_KEY_H,
 | |
| +                WPE_KEY_i,
 | |
| +                WPE_KEY_I,
 | |
| +                WPE_KEY_j,
 | |
| +                WPE_KEY_J,
 | |
| +                WPE_KEY_k,
 | |
| +                WPE_KEY_K,
 | |
| +                WPE_KEY_l,
 | |
| +                WPE_KEY_L,
 | |
| +                WPE_KEY_m,
 | |
| +                WPE_KEY_M,
 | |
| +                WPE_KEY_n,
 | |
| +                WPE_KEY_N,
 | |
| +                WPE_KEY_o,
 | |
| +                WPE_KEY_O,
 | |
| +                WPE_KEY_p,
 | |
| +                WPE_KEY_P,
 | |
| +                WPE_KEY_q,
 | |
| +                WPE_KEY_Q,
 | |
| +                WPE_KEY_r,
 | |
| +                WPE_KEY_R,
 | |
| +                WPE_KEY_s,
 | |
| +                WPE_KEY_S,
 | |
| +                WPE_KEY_t,
 | |
| +                WPE_KEY_T,
 | |
| +                WPE_KEY_u,
 | |
| +                WPE_KEY_U,
 | |
| +                WPE_KEY_v,
 | |
| +                WPE_KEY_V,
 | |
| +                WPE_KEY_w,
 | |
| +                WPE_KEY_W,
 | |
| +                WPE_KEY_x,
 | |
| +                WPE_KEY_X,
 | |
| +                WPE_KEY_y,
 | |
| +                WPE_KEY_Y,
 | |
| +                WPE_KEY_z,
 | |
| +                WPE_KEY_Z,
 | |
| +                WPE_KEY_Meta_L,
 | |
| +                WPE_KEY_Meta_R,
 | |
| +                WPE_KEY_Sleep,
 | |
| +                WPE_KEY_Num_Lock,
 | |
| +                WPE_KEY_Scroll_Lock,
 | |
| +                WPE_KEY_Shift_L,
 | |
| +                WPE_KEY_Shift_R,
 | |
| +                WPE_KEY_Control_L,
 | |
| +                WPE_KEY_Control_R,
 | |
| +                WPE_KEY_Alt_L,
 | |
| +                WPE_KEY_Alt_R,
 | |
| +                WPE_KEY_Back,
 | |
| +                WPE_KEY_Forward,
 | |
| +                WPE_KEY_Refresh,
 | |
| +                WPE_KEY_Stop,
 | |
| +                WPE_KEY_Search,
 | |
| +                WPE_KEY_Favorites,
 | |
| +                WPE_KEY_HomePage,
 | |
| +                WPE_KEY_AudioMute,
 | |
| +                WPE_KEY_AudioLowerVolume,
 | |
| +                WPE_KEY_AudioRaiseVolume,
 | |
| +                WPE_KEY_AudioNext,
 | |
| +                WPE_KEY_AudioPrev,
 | |
| +                WPE_KEY_AudioStop,
 | |
| +                WPE_KEY_AudioMedia,
 | |
| +                WPE_KEY_semicolon,
 | |
| +                WPE_KEY_colon,
 | |
| +                WPE_KEY_plus,
 | |
| +                WPE_KEY_equal,
 | |
| +                WPE_KEY_comma,
 | |
| +                WPE_KEY_less,
 | |
| +                WPE_KEY_minus,
 | |
| +                WPE_KEY_underscore,
 | |
| +                WPE_KEY_period,
 | |
| +                WPE_KEY_greater,
 | |
| +                WPE_KEY_slash,
 | |
| +                WPE_KEY_question,
 | |
| +                WPE_KEY_asciitilde,
 | |
| +                WPE_KEY_quoteleft,
 | |
| +                WPE_KEY_bracketleft,
 | |
| +                WPE_KEY_braceleft,
 | |
| +                WPE_KEY_backslash,
 | |
| +                WPE_KEY_bar,
 | |
| +                WPE_KEY_bracketright,
 | |
| +                WPE_KEY_braceright,
 | |
| +                WPE_KEY_quoteright,
 | |
| +                WPE_KEY_quotedbl,
 | |
| +                WPE_KEY_AudioRewind,
 | |
| +                WPE_KEY_AudioForward,
 | |
| +                WPE_KEY_AudioPlay,
 | |
| +                WPE_KEY_F1,
 | |
| +                WPE_KEY_F2,
 | |
| +                WPE_KEY_F3,
 | |
| +                WPE_KEY_F4,
 | |
| +                WPE_KEY_F5,
 | |
| +                WPE_KEY_F6,
 | |
| +                WPE_KEY_F7,
 | |
| +                WPE_KEY_F8,
 | |
| +                WPE_KEY_F9,
 | |
| +                WPE_KEY_F10,
 | |
| +                WPE_KEY_F11,
 | |
| +                WPE_KEY_F12,
 | |
| +                WPE_KEY_F13,
 | |
| +                WPE_KEY_F14,
 | |
| +                WPE_KEY_F15,
 | |
| +                WPE_KEY_F16,
 | |
| +                WPE_KEY_F17,
 | |
| +                WPE_KEY_F18,
 | |
| +                WPE_KEY_F19,
 | |
| +                WPE_KEY_F20,
 | |
| +                WPE_KEY_F21,
 | |
| +                WPE_KEY_F22,
 | |
| +                WPE_KEY_F23,
 | |
| +                WPE_KEY_F24,
 | |
| +                WPE_KEY_VoidSymbol,
 | |
| +                WPE_KEY_Red,
 | |
| +                WPE_KEY_Green,
 | |
| +                WPE_KEY_Yellow,
 | |
| +                WPE_KEY_Blue,
 | |
| +                WPE_KEY_PowerOff,
 | |
| +                WPE_KEY_AudioRecord,
 | |
| +                WPE_KEY_Display,
 | |
| +                WPE_KEY_Subtitle,
 | |
| +                WPE_KEY_Video
 | |
| +            };
 | |
| +            result = new HashMap<int, unsigned>();
 | |
| +            for (unsigned WPEKeyCode : WPEKeyCodes) {
 | |
| +                int winKeyCode = PlatformKeyboardEvent::windowsKeyCodeForWPEKeyCode(WPEKeyCode);
 | |
| +                // If several gdk key codes map to the same win key code first one is used.
 | |
| +                result->add(winKeyCode, WPEKeyCode);
 | |
| +            }
 | |
| +        });
 | |
| +    return *result;
 | |
| +}
 | |
| +
 | |
| +unsigned PlatformKeyboardEvent::WPEKeyCodeForWindowsKeyCode(int keycode)
 | |
| +{
 | |
| +    return WPEToWindowsKeyCodeMap().get(keycode);
 | |
| +}
 | |
| +
 | |
|  String PlatformKeyboardEvent::singleCharacterString(unsigned val)
 | |
|  {
 | |
|      switch (val) {
 | |
| diff --git a/Source/WebCore/platform/network/HTTPHeaderMap.cpp b/Source/WebCore/platform/network/HTTPHeaderMap.cpp
 | |
| index f169677e661510b225b899c79b68d040179a097a..420e101c7bb7a49b5c644076a8a2ffab2282d758 100644
 | |
| --- a/Source/WebCore/platform/network/HTTPHeaderMap.cpp
 | |
| +++ b/Source/WebCore/platform/network/HTTPHeaderMap.cpp
 | |
| @@ -229,8 +229,11 @@ void HTTPHeaderMap::add(HTTPHeaderName name, const String& value)
 | |
|      auto index = m_commonHeaders.findIf([&](auto& header) {
 | |
|          return header.key == name;
 | |
|      });
 | |
| +    // Align with Chromium and Firefox, but just for SetCookies where it is critical:
 | |
| +    // https://bit.ly/2HCa0iq
 | |
| +    String separator = name == HTTPHeaderName::SetCookie ? "\n "_s : ", "_s;
 | |
|      if (index != notFound)
 | |
| -        m_commonHeaders[index].value = makeString(m_commonHeaders[index].value, ", ", value);
 | |
| +        m_commonHeaders[index].value = makeString(m_commonHeaders[index].value, separator, value);
 | |
|      else
 | |
|          m_commonHeaders.append(CommonHeader { name, value });
 | |
|  }
 | |
| diff --git a/Source/WebCore/platform/network/NetworkStorageSession.h b/Source/WebCore/platform/network/NetworkStorageSession.h
 | |
| index deca176523b8838fd9d0cf365aa49c24be02dde6..f81f51906bd226554e75ef495f90c24942e4ae36 100644
 | |
| --- a/Source/WebCore/platform/network/NetworkStorageSession.h
 | |
| +++ b/Source/WebCore/platform/network/NetworkStorageSession.h
 | |
| @@ -155,6 +155,8 @@ public:
 | |
|      NetworkingContext* context() const;
 | |
|  #endif
 | |
|  
 | |
| +    WEBCORE_EXPORT void setCookiesFromResponse(const URL& firstParty, const SameSiteInfo&, const URL&, const String& setCookieValue);
 | |
| +
 | |
|      WEBCORE_EXPORT HTTPCookieAcceptPolicy cookieAcceptPolicy() const;
 | |
|      WEBCORE_EXPORT void setCookie(const Cookie&);
 | |
|      WEBCORE_EXPORT void setCookies(const Vector<Cookie>&, const URL&, const URL& mainDocumentURL);
 | |
| diff --git a/Source/WebCore/platform/network/ResourceResponseBase.h b/Source/WebCore/platform/network/ResourceResponseBase.h
 | |
| index b1e38001d2338d8ddb393ac6c8758a34d7c4008b..84228abb4b8188440c2443be0c198814968d19e8 100644
 | |
| --- a/Source/WebCore/platform/network/ResourceResponseBase.h
 | |
| +++ b/Source/WebCore/platform/network/ResourceResponseBase.h
 | |
| @@ -223,6 +223,8 @@ public:
 | |
|  
 | |
|      WEBCORE_EXPORT static ResourceResponse dataURLResponse(const URL&, const DataURLDecoder::Result&);
 | |
|  
 | |
| +    HTTPHeaderMap m_httpRequestHeaderFields;
 | |
| +
 | |
|  protected:
 | |
|      enum InitLevel {
 | |
|          Uninitialized,
 | |
| @@ -302,6 +304,7 @@ void ResourceResponseBase::encode(Encoder& encoder) const
 | |
|      encoder << m_httpStatusText;
 | |
|      encoder << m_httpVersion;
 | |
|      encoder << m_httpHeaderFields;
 | |
| +    encoder << m_httpRequestHeaderFields;
 | |
|  
 | |
|      // We don't want to put the networkLoadMetrics info
 | |
|      // into the disk cache, because we will never use the old info.
 | |
| @@ -374,6 +377,12 @@ bool ResourceResponseBase::decode(Decoder& decoder, ResourceResponseBase& respon
 | |
|          return false;
 | |
|      response.m_httpHeaderFields = WTFMove(*httpHeaderFields);
 | |
|  
 | |
| +    std::optional<HTTPHeaderMap> httpRequestHeaderFields;
 | |
| +    decoder >> httpRequestHeaderFields;
 | |
| +    if (!httpRequestHeaderFields)
 | |
| +        return false;
 | |
| +    response.m_httpRequestHeaderFields = WTFMove(*httpRequestHeaderFields);
 | |
| +
 | |
|      // The networkLoadMetrics info is only send over IPC and not stored in disk cache.
 | |
|      if constexpr (Decoder::isIPCDecoder) {
 | |
|          std::optional<Box<NetworkLoadMetrics>> networkLoadMetrics;
 | |
| diff --git a/Source/WebCore/platform/network/cocoa/NetworkStorageSessionCocoa.mm b/Source/WebCore/platform/network/cocoa/NetworkStorageSessionCocoa.mm
 | |
| index 49993be7ccaab3a7dd7e4b62a945df732b7608c4..d421683e2332b47849fef5a18d25f4e480f25962 100644
 | |
| --- a/Source/WebCore/platform/network/cocoa/NetworkStorageSessionCocoa.mm
 | |
| +++ b/Source/WebCore/platform/network/cocoa/NetworkStorageSessionCocoa.mm
 | |
| @@ -477,6 +477,22 @@ void NetworkStorageSession::setCookiesFromDOM(const URL& firstParty, const SameS
 | |
|      END_BLOCK_OBJC_EXCEPTIONS
 | |
|  }
 | |
|  
 | |
| +void NetworkStorageSession::setCookiesFromResponse(const URL& firstParty, const SameSiteInfo& sameSiteInfo, const URL& url, const String& setCookieValue)
 | |
| +{
 | |
| +    Vector<String> cookieValues = setCookieValue.split('\n');
 | |
| +    size_t count = cookieValues.size();
 | |
| +    auto* cookies = [NSMutableArray arrayWithCapacity:count];
 | |
| +    for (const auto& cookieValue : cookieValues) {
 | |
| +        NSString* cookieString = (NSString *)cookieValue;
 | |
| +        NSString* cookieKey = @"Set-Cookie";
 | |
| +        NSDictionary* headers = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObject:cookieString] forKeys:[NSArray arrayWithObject:cookieKey]];
 | |
| +        NSArray<NSHTTPCookie*>* parsedCookies = [NSHTTPCookie cookiesWithResponseHeaderFields:headers forURL:(NSURL *)url];
 | |
| +        [cookies addObject:parsedCookies[0]];
 | |
| +    }
 | |
| +    NSURL *cookieURL = url;
 | |
| +    setHTTPCookiesForURL(cookieStorage().get(), cookies, cookieURL, firstParty, sameSiteInfo);
 | |
| +}
 | |
| +
 | |
|  static NSHTTPCookieAcceptPolicy httpCookieAcceptPolicy(CFHTTPCookieStorageRef cookieStorage)
 | |
|  {
 | |
|      ASSERT(hasProcessPrivilege(ProcessPrivilege::CanAccessRawCookies));
 | |
| diff --git a/Source/WebCore/platform/network/curl/CookieJarDB.h b/Source/WebCore/platform/network/curl/CookieJarDB.h
 | |
| index c4eb67d6f7c334076b32b798dcea40b570681e6f..ce86ab28225aa466350671441294f2ace8851bbd 100644
 | |
| --- a/Source/WebCore/platform/network/curl/CookieJarDB.h
 | |
| +++ b/Source/WebCore/platform/network/curl/CookieJarDB.h
 | |
| @@ -72,7 +72,7 @@ public:
 | |
|      WEBCORE_EXPORT ~CookieJarDB();
 | |
|  
 | |
|  private:
 | |
| -    CookieAcceptPolicy m_acceptPolicy { CookieAcceptPolicy::Always };
 | |
| +    CookieAcceptPolicy m_acceptPolicy { CookieAcceptPolicy::OnlyFromMainDocumentDomain };
 | |
|      String m_databasePath;
 | |
|  
 | |
|      bool m_detectedDatabaseCorruption { false };
 | |
| diff --git a/Source/WebCore/platform/network/curl/CurlStream.cpp b/Source/WebCore/platform/network/curl/CurlStream.cpp
 | |
| index 36658f91dc9d67230b239e497c0000ac62aae981..de09412ef68a0d21e16b3c958254768e8b7eda87 100644
 | |
| --- a/Source/WebCore/platform/network/curl/CurlStream.cpp
 | |
| +++ b/Source/WebCore/platform/network/curl/CurlStream.cpp
 | |
| @@ -34,7 +34,7 @@
 | |
|  
 | |
|  namespace WebCore {
 | |
|  
 | |
| -CurlStream::CurlStream(CurlStreamScheduler& scheduler, CurlStreamID streamID, URL&& url)
 | |
| +CurlStream::CurlStream(CurlStreamScheduler& scheduler, CurlStreamID streamID, bool ignoreCertificateErrors, URL&& url)
 | |
|      : m_scheduler(scheduler)
 | |
|      , m_streamID(streamID)
 | |
|  {
 | |
| @@ -46,6 +46,9 @@ CurlStream::CurlStream(CurlStreamScheduler& scheduler, CurlStreamID streamID, UR
 | |
|      m_curlHandle->setUrl(WTFMove(url));
 | |
|  
 | |
|      m_curlHandle->enableConnectionOnly();
 | |
| +    if (ignoreCertificateErrors)
 | |
| +        m_curlHandle->disableServerTrustEvaluation();
 | |
| +
 | |
|  
 | |
|      auto errorCode = m_curlHandle->perform();
 | |
|      if (errorCode != CURLE_OK) {
 | |
| diff --git a/Source/WebCore/platform/network/curl/CurlStream.h b/Source/WebCore/platform/network/curl/CurlStream.h
 | |
| index e8a32c26461b4308ea227c6df8c972439905d0bc..5da1a95615b04fca8402f53ecd7f05a006640372 100644
 | |
| --- a/Source/WebCore/platform/network/curl/CurlStream.h
 | |
| +++ b/Source/WebCore/platform/network/curl/CurlStream.h
 | |
| @@ -51,12 +51,12 @@ public:
 | |
|          virtual void didFail(CurlStreamID, CURLcode) = 0;
 | |
|      };
 | |
|  
 | |
| -    static std::unique_ptr<CurlStream> create(CurlStreamScheduler& scheduler, CurlStreamID streamID, URL&& url)
 | |
| +    static std::unique_ptr<CurlStream> create(CurlStreamScheduler& scheduler, CurlStreamID streamID, bool ignoreCertificateErrors, URL&& url)
 | |
|      {
 | |
| -        return makeUnique<CurlStream>(scheduler, streamID, WTFMove(url));
 | |
| +        return makeUnique<CurlStream>(scheduler, streamID, ignoreCertificateErrors, WTFMove(url));
 | |
|      }
 | |
|  
 | |
| -    CurlStream(CurlStreamScheduler&, CurlStreamID, URL&&);
 | |
| +    CurlStream(CurlStreamScheduler&, CurlStreamID, bool ignoreCertificateErrors, URL&&);
 | |
|      virtual ~CurlStream();
 | |
|  
 | |
|      void send(UniqueArray<uint8_t>&&, size_t);
 | |
| diff --git a/Source/WebCore/platform/network/curl/CurlStreamScheduler.cpp b/Source/WebCore/platform/network/curl/CurlStreamScheduler.cpp
 | |
| index d94ff4f9169a6c0b5adb9719f5506d0fb80e6f89..3f955607764d028807d150619bf7f49e08bc3e7e 100644
 | |
| --- a/Source/WebCore/platform/network/curl/CurlStreamScheduler.cpp
 | |
| +++ b/Source/WebCore/platform/network/curl/CurlStreamScheduler.cpp
 | |
| @@ -40,7 +40,7 @@ CurlStreamScheduler::~CurlStreamScheduler()
 | |
|      ASSERT(isMainThread());
 | |
|  }
 | |
|  
 | |
| -CurlStreamID CurlStreamScheduler::createStream(const URL& url, CurlStream::Client& client)
 | |
| +CurlStreamID CurlStreamScheduler::createStream(const URL& url, bool ignoreCertificateErrors, CurlStream::Client& client)
 | |
|  {
 | |
|      ASSERT(isMainThread());
 | |
|  
 | |
| @@ -51,8 +51,8 @@ CurlStreamID CurlStreamScheduler::createStream(const URL& url, CurlStream::Clien
 | |
|      auto streamID = m_currentStreamID;
 | |
|      m_clientList.add(streamID, &client);
 | |
|  
 | |
| -    callOnWorkerThread([this, streamID, url = url.isolatedCopy()]() mutable {
 | |
| -        m_streamList.add(streamID, CurlStream::create(*this, streamID, WTFMove(url)));
 | |
| +    callOnWorkerThread([this, streamID, ignoreCertificateErrors, url = url.isolatedCopy()]() mutable {
 | |
| +        m_streamList.add(streamID, CurlStream::create(*this, streamID, ignoreCertificateErrors, WTFMove(url)));
 | |
|      });
 | |
|  
 | |
|      return streamID;
 | |
| diff --git a/Source/WebCore/platform/network/curl/CurlStreamScheduler.h b/Source/WebCore/platform/network/curl/CurlStreamScheduler.h
 | |
| index 0c39c90aac884fca48849388acc1b42bad16d620..dd8e50686c348b46d5ae92fd67a31eb0cbdb014f 100644
 | |
| --- a/Source/WebCore/platform/network/curl/CurlStreamScheduler.h
 | |
| +++ b/Source/WebCore/platform/network/curl/CurlStreamScheduler.h
 | |
| @@ -38,7 +38,7 @@ public:
 | |
|      CurlStreamScheduler();
 | |
|      virtual ~CurlStreamScheduler();
 | |
|  
 | |
| -    CurlStreamID createStream(const URL&, CurlStream::Client&);
 | |
| +    CurlStreamID createStream(const URL&, bool ignoreCertificateErrors, CurlStream::Client&);
 | |
|      void destroyStream(CurlStreamID);
 | |
|      void send(CurlStreamID, UniqueArray<uint8_t>&&, size_t);
 | |
|  
 | |
| diff --git a/Source/WebCore/platform/network/curl/NetworkStorageSessionCurl.cpp b/Source/WebCore/platform/network/curl/NetworkStorageSessionCurl.cpp
 | |
| index a3be8be8329320a56fae4205fa9ba9ec38ec8580..ca1d7d1b7bbd8686b0c5458b25e0f82c3ae06c22 100644
 | |
| --- a/Source/WebCore/platform/network/curl/NetworkStorageSessionCurl.cpp
 | |
| +++ b/Source/WebCore/platform/network/curl/NetworkStorageSessionCurl.cpp
 | |
| @@ -118,6 +118,12 @@ void NetworkStorageSession::setCookieAcceptPolicy(CookieAcceptPolicy policy) con
 | |
|      cookieDatabase().setAcceptPolicy(policy);
 | |
|  }
 | |
|  
 | |
| +void  NetworkStorageSession::setCookiesFromResponse(const URL& firstParty, const SameSiteInfo&, const URL& url, const String& setCookieValue)
 | |
| +{
 | |
| +    for (auto& cookieString : setCookieValue.split('\n'))
 | |
| +        cookieDatabase().setCookie(firstParty, url, cookieString, CookieJarDB::Source::Network);
 | |
| +}
 | |
| +
 | |
|  HTTPCookieAcceptPolicy NetworkStorageSession::cookieAcceptPolicy() const
 | |
|  {
 | |
|      switch (cookieDatabase().acceptPolicy()) {
 | |
| diff --git a/Source/WebCore/platform/network/curl/SocketStreamHandleImpl.h b/Source/WebCore/platform/network/curl/SocketStreamHandleImpl.h
 | |
| index 950cd1b1ac6800212e8192b5cb53e69b34409111..58b1f55543f1bdcfc8e6b19b06633c0c4c45095a 100644
 | |
| --- a/Source/WebCore/platform/network/curl/SocketStreamHandleImpl.h
 | |
| +++ b/Source/WebCore/platform/network/curl/SocketStreamHandleImpl.h
 | |
| @@ -44,7 +44,7 @@ class StorageSessionProvider;
 | |
|  
 | |
|  class SocketStreamHandleImpl : public SocketStreamHandle, public CurlStream::Client {
 | |
|  public:
 | |
| -    static Ref<SocketStreamHandleImpl> create(const URL& url, SocketStreamHandleClient& client, PAL::SessionID, const String&, SourceApplicationAuditToken&&, const StorageSessionProvider* provider, bool) { return adoptRef(*new SocketStreamHandleImpl(url, client, provider)); }
 | |
| +    static Ref<SocketStreamHandleImpl> create(const URL& url, SocketStreamHandleClient& client, PAL::SessionID, const String&, SourceApplicationAuditToken&&, const StorageSessionProvider* provider, bool ignoreCertificateErrors) { return adoptRef(*new SocketStreamHandleImpl(url, ignoreCertificateErrors, client, provider)); }
 | |
|  
 | |
|      virtual ~SocketStreamHandleImpl();
 | |
|  
 | |
| @@ -53,7 +53,7 @@ public:
 | |
|      WEBCORE_EXPORT void platformClose() final;
 | |
|  
 | |
|  private:
 | |
| -    WEBCORE_EXPORT SocketStreamHandleImpl(const URL&, SocketStreamHandleClient&, const StorageSessionProvider*);
 | |
| +    WEBCORE_EXPORT SocketStreamHandleImpl(const URL&, bool ignoreCertificateErrors, SocketStreamHandleClient&, const StorageSessionProvider*);
 | |
|  
 | |
|      size_t bufferedAmount() final;
 | |
|      std::optional<size_t> platformSendInternal(const uint8_t*, size_t);
 | |
| diff --git a/Source/WebCore/platform/network/curl/SocketStreamHandleImplCurl.cpp b/Source/WebCore/platform/network/curl/SocketStreamHandleImplCurl.cpp
 | |
| index a8f57a72d0eacca7755be84fcaa1c9bf10958c0b..a5d67b8016a86b9184ded0904e317048e0eb9ea1 100644
 | |
| --- a/Source/WebCore/platform/network/curl/SocketStreamHandleImplCurl.cpp
 | |
| +++ b/Source/WebCore/platform/network/curl/SocketStreamHandleImplCurl.cpp
 | |
| @@ -44,7 +44,7 @@
 | |
|  
 | |
|  namespace WebCore {
 | |
|  
 | |
| -SocketStreamHandleImpl::SocketStreamHandleImpl(const URL& url, SocketStreamHandleClient& client, const StorageSessionProvider* provider)
 | |
| +SocketStreamHandleImpl::SocketStreamHandleImpl(const URL& url, bool ignoreCertificateErrors, SocketStreamHandleClient& client, const StorageSessionProvider* provider)
 | |
|      : SocketStreamHandle(url, client)
 | |
|      , m_storageSessionProvider(provider)
 | |
|      , m_scheduler(CurlContext::singleton().streamScheduler())
 | |
| @@ -53,7 +53,7 @@ SocketStreamHandleImpl::SocketStreamHandleImpl(const URL& url, SocketStreamHandl
 | |
|      if (m_url.protocolIs("wss") && DeprecatedGlobalSettings::allowsAnySSLCertificate())
 | |
|          CurlContext::singleton().sslHandle().setIgnoreSSLErrors(true);
 | |
|  
 | |
| -    m_streamID = m_scheduler.createStream(m_url, *this);
 | |
| +    m_streamID = m_scheduler.createStream(m_url, ignoreCertificateErrors, *this);
 | |
|  }
 | |
|  
 | |
|  SocketStreamHandleImpl::~SocketStreamHandleImpl()
 | |
| diff --git a/Source/WebCore/platform/network/soup/NetworkStorageSessionSoup.cpp b/Source/WebCore/platform/network/soup/NetworkStorageSessionSoup.cpp
 | |
| index 6e0a3dc7ac5adf22f553f81113633a135ae9271c..16e629a1489bede4f3266253c11077b82524e576 100644
 | |
| --- a/Source/WebCore/platform/network/soup/NetworkStorageSessionSoup.cpp
 | |
| +++ b/Source/WebCore/platform/network/soup/NetworkStorageSessionSoup.cpp
 | |
| @@ -410,6 +410,30 @@ void NetworkStorageSession::setCookie(const Cookie& cookie)
 | |
|      soup_cookie_jar_add_cookie(cookieStorage(), cookie.toSoupCookie());
 | |
|  }
 | |
|  
 | |
| +void  NetworkStorageSession::setCookiesFromResponse(const URL& firstParty, const SameSiteInfo&, const URL& url, const String& setCookieValue)
 | |
| +{
 | |
| +    auto origin = urlToSoupURI(url);
 | |
| +    if (!origin)
 | |
| +        return;
 | |
| +
 | |
| +    auto firstPartyURI = urlToSoupURI(firstParty);
 | |
| +    if (!firstPartyURI)
 | |
| +        return;
 | |
| +
 | |
| +    for (auto& cookieString : setCookieValue.split('\n')) {
 | |
| +        GUniquePtr<SoupCookie> cookie(soup_cookie_parse(cookieString.utf8().data(), origin.get()));
 | |
| +
 | |
| +        if (!cookie)
 | |
| +            continue;
 | |
| +
 | |
| +#if SOUP_CHECK_VERSION(2, 67, 1)
 | |
| +        soup_cookie_jar_add_cookie_full(cookieStorage(), cookie.release(), origin.get(), firstPartyURI.get());
 | |
| +#else
 | |
| +        soup_cookie_jar_add_cookie_with_first_party(cookieStorage(), firstPartyURI.get(), cookie.release());
 | |
| +#endif
 | |
| +    }
 | |
| +}
 | |
| +
 | |
|  void NetworkStorageSession::deleteCookie(const Cookie& cookie)
 | |
|  {
 | |
|      GUniquePtr<SoupCookie> targetCookie(cookie.toSoupCookie());
 | |
| diff --git a/Source/WebCore/platform/win/ClipboardUtilitiesWin.cpp b/Source/WebCore/platform/win/ClipboardUtilitiesWin.cpp
 | |
| index 0031750d39ed8908f44e4c62521291c164e94acd..f2ff5238b83c18bab1cc6736005e1e2b5668ae79 100644
 | |
| --- a/Source/WebCore/platform/win/ClipboardUtilitiesWin.cpp
 | |
| +++ b/Source/WebCore/platform/win/ClipboardUtilitiesWin.cpp
 | |
| @@ -39,6 +39,7 @@
 | |
|  #include <wtf/text/StringBuilder.h>
 | |
|  #include <wtf/text/win/WCharStringExtras.h>
 | |
|  #include <wtf/unicode/CharacterNames.h>
 | |
| +#include "Pasteboard.h"
 | |
|  
 | |
|  namespace WebCore {
 | |
|  
 | |
| @@ -690,7 +691,10 @@ template<typename T> void getStringData(IDataObject* data, FORMATETC* format, Ve
 | |
|      STGMEDIUM store;
 | |
|      if (FAILED(data->GetData(format, &store)))
 | |
|          return;
 | |
| -    dataStrings.append(String(static_cast<T*>(GlobalLock(store.hGlobal)), ::GlobalSize(store.hGlobal) / sizeof(T)));
 | |
| +    // The string here should be null terminated, but it could come from another app so lets lock it
 | |
| +    // to the size to prevent an overflow.
 | |
| +    String rawString = String(static_cast<T*>(GlobalLock(store.hGlobal)), ::GlobalSize(store.hGlobal) / sizeof(T));
 | |
| +    dataStrings.append(String::fromUTF8(rawString.utf8().data()));
 | |
|      GlobalUnlock(store.hGlobal);
 | |
|      ReleaseStgMedium(&store);
 | |
|  }
 | |
| diff --git a/Source/WebCore/platform/win/ClipboardUtilitiesWin.h b/Source/WebCore/platform/win/ClipboardUtilitiesWin.h
 | |
| index c50799b63e05adbe32bae3535d786c7d268f980f..9cf1cc7ec4eaae22947f80ba272dfae272167bd6 100644
 | |
| --- a/Source/WebCore/platform/win/ClipboardUtilitiesWin.h
 | |
| +++ b/Source/WebCore/platform/win/ClipboardUtilitiesWin.h
 | |
| @@ -34,6 +34,7 @@ namespace WebCore {
 | |
|  
 | |
|  class Document;
 | |
|  class DocumentFragment;
 | |
| +class Pasteboard;
 | |
|  
 | |
|  HGLOBAL createGlobalData(const String&);
 | |
|  HGLOBAL createGlobalData(const Vector<char>&);
 | |
| diff --git a/Source/WebCore/platform/win/DragDataWin.cpp b/Source/WebCore/platform/win/DragDataWin.cpp
 | |
| index 207572d157ba2173c045e01da8f9b83b034c047e..6590bd36b23bdcbc947b191d2c011414655dfd68 100644
 | |
| --- a/Source/WebCore/platform/win/DragDataWin.cpp
 | |
| +++ b/Source/WebCore/platform/win/DragDataWin.cpp
 | |
| @@ -48,6 +48,7 @@ DragData::DragData(const DragDataMap& data, const IntPoint& clientPosition, cons
 | |
|      , m_applicationFlags(flags)
 | |
|      , m_pageID(pageID)
 | |
|      , m_dragDataMap(data)
 | |
| +    , m_dragDestinationActionMask(anyDragDestinationAction())
 | |
|  {
 | |
|  }
 | |
|  
 | |
| diff --git a/Source/WebCore/platform/win/KeyEventWin.cpp b/Source/WebCore/platform/win/KeyEventWin.cpp
 | |
| index 05a0d1256a136982507b732c7852bbece201b513..f2c00eca40fbf3a88780610228f60ba6f8c1f441 100644
 | |
| --- a/Source/WebCore/platform/win/KeyEventWin.cpp
 | |
| +++ b/Source/WebCore/platform/win/KeyEventWin.cpp
 | |
| @@ -239,10 +239,16 @@ PlatformKeyboardEvent::PlatformKeyboardEvent(HWND, WPARAM code, LPARAM keyData,
 | |
|  {
 | |
|  }
 | |
|  
 | |
| -void PlatformKeyboardEvent::disambiguateKeyDownEvent(Type, bool)
 | |
| +void PlatformKeyboardEvent::disambiguateKeyDownEvent(Type type, bool backwardsCompatibility)
 | |
|  {
 | |
| -    // No KeyDown events on Windows to disambiguate.
 | |
| -    ASSERT_NOT_REACHED();
 | |
| +    m_type = type;
 | |
| +    if (type == PlatformEvent::RawKeyDown) {
 | |
| +        m_text = String();
 | |
| +        m_unmodifiedText = String();
 | |
| +    } else {
 | |
| +        m_keyIdentifier = String();
 | |
| +        m_windowsVirtualKeyCode = 0;
 | |
| +    }
 | |
|  }
 | |
|  
 | |
|  bool PlatformKeyboardEvent::currentCapsLockState()
 | |
| diff --git a/Source/WebCore/platform/win/PasteboardWin.cpp b/Source/WebCore/platform/win/PasteboardWin.cpp
 | |
| index 5e64d73381ec823978295aed1c40401ce54f0aa9..a34378d865208ddce94b829a6add7d1064f27a5d 100644
 | |
| --- a/Source/WebCore/platform/win/PasteboardWin.cpp
 | |
| +++ b/Source/WebCore/platform/win/PasteboardWin.cpp
 | |
| @@ -1129,7 +1129,21 @@ void Pasteboard::writeCustomData(const Vector<PasteboardCustomData>& data)
 | |
|      }
 | |
|  
 | |
|      clear();
 | |
| +    if (m_dataObject) {
 | |
| +        const auto& customData = data.first();
 | |
| +        customData.forEachPlatformString([&](auto& type, auto& string) {
 | |
| +            writeString(type, string);
 | |
| +        });
 | |
|  
 | |
| +        if (customData.hasSameOriginCustomData() || !customData.origin().isEmpty()) {
 | |
| +            customData.forEachCustomString([&](auto& type, auto& string) {
 | |
| +                writeString(type, string);
 | |
| +            });
 | |
| +        }
 | |
| +        return;
 | |
| +    }
 | |
| +
 | |
| +    // this is the real real clipboard. Prbaobly need to be doing drag data stuff.
 | |
|      if (::OpenClipboard(m_owner)) {
 | |
|          const auto& customData = data.first();
 | |
|          customData.forEachPlatformStringOrBuffer([](auto& type, auto& stringOrBuffer) {
 | |
| @@ -1168,4 +1182,25 @@ void Pasteboard::write(const Color&)
 | |
|  {
 | |
|  }
 | |
|  
 | |
| +DragDataMap Pasteboard::createDragDataMap() {
 | |
| +    DragDataMap dragDataMap;
 | |
| +    auto dragObject = dataObject();
 | |
| +    if (!dragObject)
 | |
| +        return dragDataMap;
 | |
| +    // Enumerate clipboard content and load it in the map.
 | |
| +    COMPtr<IEnumFORMATETC> itr;
 | |
| +
 | |
| +    if (FAILED(dragObject->EnumFormatEtc(DATADIR_GET, &itr)) || !itr)
 | |
| +        return dragDataMap;
 | |
| +
 | |
| +    FORMATETC dataFormat;
 | |
| +    while (itr->Next(1, &dataFormat, 0) == S_OK) {
 | |
| +        Vector<String> dataStrings;
 | |
| +        getClipboardData(dragObject.get(), &dataFormat, dataStrings);
 | |
| +        if (!dataStrings.isEmpty())
 | |
| +            dragDataMap.set(dataFormat.cfFormat, dataStrings);
 | |
| +    }
 | |
| +    return dragDataMap;
 | |
| +}
 | |
| +
 | |
|  } // namespace WebCore
 | |
| diff --git a/Source/WebCore/platform/win/ScrollbarThemeWin.cpp b/Source/WebCore/platform/win/ScrollbarThemeWin.cpp
 | |
| index e89ec9d83d8abc141938716f24eaba061a085af3..6005d02b9bf20ef2cbf9382fdf50c863952c8db5 100644
 | |
| --- a/Source/WebCore/platform/win/ScrollbarThemeWin.cpp
 | |
| +++ b/Source/WebCore/platform/win/ScrollbarThemeWin.cpp
 | |
| @@ -114,8 +114,7 @@ static int scrollbarThicknessInPixels()
 | |
|  
 | |
|  int ScrollbarThemeWin::scrollbarThickness(ScrollbarControlSize, ScrollbarExpansionState)
 | |
|  {
 | |
| -    float inverseScaleFactor = 1.0f / deviceScaleFactorForWindow(0);
 | |
| -    return clampTo<int>(inverseScaleFactor * scrollbarThicknessInPixels());
 | |
| +    return 0;
 | |
|  }
 | |
|  
 | |
|  void ScrollbarThemeWin::themeChanged()
 | |
| diff --git a/Source/WebCore/platform/wpe/DragDataWPE.cpp b/Source/WebCore/platform/wpe/DragDataWPE.cpp
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..07fb260a5203167fdf94a552949394bb73ca8c61
 | |
| --- /dev/null
 | |
| +++ b/Source/WebCore/platform/wpe/DragDataWPE.cpp
 | |
| @@ -0,0 +1,87 @@
 | |
| +/*
 | |
| + *  This library is free software; you can redistribute it and/or
 | |
| + *  modify it under the terms of the GNU Lesser General Public
 | |
| + *  License as published by the Free Software Foundation; either
 | |
| + *  version 2 of the License, or (at your option) any later version.
 | |
| + *
 | |
| + *  This library is distributed in the hope that it will be useful,
 | |
| + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
| + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | |
| + *  Lesser General Public License for more details.
 | |
| + *
 | |
| + *  You should have received a copy of the GNU Lesser General Public
 | |
| + *  License along with this library; if not, write to the Free Software
 | |
| + *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 | |
| + */
 | |
| +
 | |
| +#include "config.h"
 | |
| +#include "DragData.h"
 | |
| +#include "SelectionData.h"
 | |
| +
 | |
| +namespace WebCore {
 | |
| +
 | |
| +bool DragData::canSmartReplace() const
 | |
| +{
 | |
| +    return false;
 | |
| +}
 | |
| +
 | |
| +bool DragData::containsColor() const
 | |
| +{
 | |
| +    return false;
 | |
| +}
 | |
| +
 | |
| +bool DragData::containsFiles() const
 | |
| +{
 | |
| +    return m_platformDragData->hasFilenames();
 | |
| +}
 | |
| +
 | |
| +unsigned DragData::numberOfFiles() const
 | |
| +{
 | |
| +    return m_platformDragData->filenames().size();
 | |
| +}
 | |
| +
 | |
| +Vector<String> DragData::asFilenames() const
 | |
| +{
 | |
| +    return m_platformDragData->filenames();
 | |
| +}
 | |
| +
 | |
| +bool DragData::containsPlainText() const
 | |
| +{
 | |
| +    return m_platformDragData->hasText();
 | |
| +}
 | |
| +
 | |
| +String DragData::asPlainText() const
 | |
| +{
 | |
| +    return m_platformDragData->text();
 | |
| +}
 | |
| +
 | |
| +Color DragData::asColor() const
 | |
| +{
 | |
| +    return Color();
 | |
| +}
 | |
| +
 | |
| +bool DragData::containsCompatibleContent(DraggingPurpose) const
 | |
| +{
 | |
| +    return containsPlainText() || containsURL() || containsColor() || containsFiles();
 | |
| +}
 | |
| +
 | |
| +bool DragData::containsURL(FilenameConversionPolicy filenamePolicy) const
 | |
| +{
 | |
| +    return !asURL(filenamePolicy).isEmpty();
 | |
| +}
 | |
| +
 | |
| +String DragData::asURL(FilenameConversionPolicy filenamePolicy, String* title) const
 | |
| +{
 | |
| +    if (!m_platformDragData->hasURL())
 | |
| +        return String();
 | |
| +    if (filenamePolicy != ConvertFilenames) {
 | |
| +        if (m_platformDragData->url().isLocalFile())
 | |
| +            return { };
 | |
| +    }
 | |
| +
 | |
| +    if (title)
 | |
| +        *title = m_platformDragData->urlLabel();
 | |
| +    return m_platformDragData->url().string();
 | |
| +}
 | |
| +
 | |
| +}
 | |
| diff --git a/Source/WebCore/platform/wpe/DragImageWPE.cpp b/Source/WebCore/platform/wpe/DragImageWPE.cpp
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..e77e6db7a93a9dfcaad3866eb445edf4ebfe33b5
 | |
| --- /dev/null
 | |
| +++ b/Source/WebCore/platform/wpe/DragImageWPE.cpp
 | |
| @@ -0,0 +1,73 @@
 | |
| +/*
 | |
| + *  Copyright (C) 2010,2017 Igalia S.L.
 | |
| + *
 | |
| + *  This library is free software; you can redistribute it and/or
 | |
| + *  modify it under the terms of the GNU Lesser General Public
 | |
| + *  License as published by the Free Software Foundation; either
 | |
| + *  version 2 of the License, or (at your option) any later version.
 | |
| + *
 | |
| + *  This library is distributed in the hope that it will be useful,
 | |
| + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
| + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | |
| + *  Lesser General Public License for more details.
 | |
| + *
 | |
| + *  You should have received a copy of the GNU Lesser General Public
 | |
| + *  License along with this library; if not, write to the Free Software
 | |
| + *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 | |
| + */
 | |
| +
 | |
| +#include "config.h"
 | |
| +#include "DragImage.h"
 | |
| +#include "NotImplemented.h"
 | |
| +
 | |
| +#include "Image.h"
 | |
| +
 | |
| +namespace WebCore {
 | |
| +
 | |
| +IntSize dragImageSize(DragImageRef)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return { 0, 0 };
 | |
| +}
 | |
| +
 | |
| +void deleteDragImage(DragImageRef)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +}
 | |
| +
 | |
| +DragImageRef scaleDragImage(DragImageRef, FloatSize)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +DragImageRef dissolveDragImageToFraction(DragImageRef image, float)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return image;
 | |
| +}
 | |
| +
 | |
| +DragImageRef createDragImageFromImage(Image* image, ImageOrientation)
 | |
| +{
 | |
| +    return image->nativeImageForCurrentFrame()->platformImage();
 | |
| +}
 | |
| +
 | |
| +
 | |
| +DragImageRef createDragImageIconForCachedImageFilename(const String&)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +DragImageRef createDragImageForLink(Element&, URL&, const String&, TextIndicatorData&, FontRenderingMode, float)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +DragImageRef createDragImageForColor(const Color&, const FloatRect&, float, Path&)
 | |
| +{
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +}
 | |
| diff --git a/Source/WebCore/platform/wpe/PlatformScreenWPE.cpp b/Source/WebCore/platform/wpe/PlatformScreenWPE.cpp
 | |
| index bbdd1ce76241d933ada9c43fabae4912cbfa64e1..e6ae01a77350c519b203f6ed2910f63871b9b829 100644
 | |
| --- a/Source/WebCore/platform/wpe/PlatformScreenWPE.cpp
 | |
| +++ b/Source/WebCore/platform/wpe/PlatformScreenWPE.cpp
 | |
| @@ -93,12 +93,12 @@ bool screenSupportsExtendedColor(Widget*)
 | |
|  }
 | |
|  
 | |
|  #if ENABLE(TOUCH_EVENTS)
 | |
| -bool screenHasTouchDevice()
 | |
| +bool platformScreenHasTouchDevice()
 | |
|  {
 | |
|      return true;
 | |
|  }
 | |
|  
 | |
| -bool screenIsTouchPrimaryInputDevice()
 | |
| +bool platformScreenIsTouchPrimaryInputDevice()
 | |
|  {
 | |
|      return true;
 | |
|  }
 | |
| diff --git a/Source/WebCore/platform/wpe/SelectionData.cpp b/Source/WebCore/platform/wpe/SelectionData.cpp
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..2a461c25464ec787513369527743671d34f56709
 | |
| --- /dev/null
 | |
| +++ b/Source/WebCore/platform/wpe/SelectionData.cpp
 | |
| @@ -0,0 +1,134 @@
 | |
| +/*
 | |
| + * Copyright (C) 2009, Martin Robinson
 | |
| + *
 | |
| + *  This library is free software; you can redistribute it and/or
 | |
| + *  modify it under the terms of the GNU Lesser General Public
 | |
| + *  License as published by the Free Software Foundation; either
 | |
| + *  version 2 of the License, or (at your option) any later version.
 | |
| + *
 | |
| + *  This library is distributed in the hope that it will be useful,
 | |
| + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
| + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | |
| + *  Lesser General Public License for more details.
 | |
| + *
 | |
| + *  You should have received a copy of the GNU Lesser General Public
 | |
| + *  License along with this library; if not, write to the Free Software
 | |
| + *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 | |
| + */
 | |
| +
 | |
| +#include "config.h"
 | |
| +#include "SelectionData.h"
 | |
| +
 | |
| +#include <wtf/glib/GUniquePtr.h>
 | |
| +#include <wtf/text/CString.h>
 | |
| +#include <wtf/text/StringBuilder.h>
 | |
| +
 | |
| +namespace WebCore {
 | |
| +
 | |
| +static void replaceNonBreakingSpaceWithSpace(String& str)
 | |
| +{
 | |
| +    static const UChar NonBreakingSpaceCharacter = 0xA0;
 | |
| +    static const UChar SpaceCharacter = ' ';
 | |
| +    str = makeStringByReplacingAll(str, NonBreakingSpaceCharacter, SpaceCharacter);
 | |
| +}
 | |
| +
 | |
| +void SelectionData::setText(const String& newText)
 | |
| +{
 | |
| +    m_text = newText;
 | |
| +    replaceNonBreakingSpaceWithSpace(m_text);
 | |
| +}
 | |
| +
 | |
| +void SelectionData::setURIList(const String& uriListString)
 | |
| +{
 | |
| +    m_uriList = uriListString;
 | |
| +
 | |
| +    // This code is originally from: platform/chromium/ChromiumDataObject.cpp.
 | |
| +    // FIXME: We should make this code cross-platform eventually.
 | |
| +
 | |
| +    // Line separator is \r\n per RFC 2483 - however, for compatibility
 | |
| +    // reasons we also allow just \n here.
 | |
| +
 | |
| +    // Process the input and copy the first valid URL into the url member.
 | |
| +    // In case no URLs can be found, subsequent calls to getData("URL")
 | |
| +    // will get an empty string. This is in line with the HTML5 spec (see
 | |
| +    // "The DragEvent and DataTransfer interfaces"). Also extract all filenames
 | |
| +    // from the URI list.
 | |
| +    bool setURL = hasURL();
 | |
| +    for (auto& line : uriListString.split('\n')) {
 | |
| +        line = line.stripWhiteSpace();
 | |
| +        if (line.isEmpty())
 | |
| +            continue;
 | |
| +        if (line[0] == '#')
 | |
| +            continue;
 | |
| +
 | |
| +        URL url = URL(URL(), line);
 | |
| +        if (url.isValid()) {
 | |
| +            if (!setURL) {
 | |
| +                m_url = url;
 | |
| +                setURL = true;
 | |
| +            }
 | |
| +
 | |
| +            GUniqueOutPtr<GError> error;
 | |
| +            GUniquePtr<gchar> filename(g_filename_from_uri(line.utf8().data(), 0, &error.outPtr()));
 | |
| +            if (!error && filename)
 | |
| +                m_filenames.append(String::fromUTF8(filename.get()));
 | |
| +        }
 | |
| +    }
 | |
| +}
 | |
| +
 | |
| +void SelectionData::setURL(const URL& url, const String& label)
 | |
| +{
 | |
| +    m_url = url;
 | |
| +    if (m_uriList.isEmpty())
 | |
| +        m_uriList = url.string();
 | |
| +
 | |
| +    if (!hasText())
 | |
| +        setText(url.string());
 | |
| +
 | |
| +    if (hasMarkup())
 | |
| +        return;
 | |
| +
 | |
| +    String actualLabel(label);
 | |
| +    if (actualLabel.isEmpty())
 | |
| +        actualLabel = url.string();
 | |
| +
 | |
| +    StringBuilder markup;
 | |
| +    markup.append("<a href=\"");
 | |
| +    markup.append(url.string());
 | |
| +    markup.append("\">");
 | |
| +    GUniquePtr<gchar> escaped(g_markup_escape_text(actualLabel.utf8().data(), -1));
 | |
| +    markup.append(String::fromUTF8(escaped.get()));
 | |
| +    markup.append("</a>");
 | |
| +    setMarkup(markup.toString());
 | |
| +}
 | |
| +
 | |
| +const String& SelectionData::urlLabel() const
 | |
| +{
 | |
| +    if (hasText())
 | |
| +        return text();
 | |
| +
 | |
| +    if (hasURL())
 | |
| +        return url().string();
 | |
| +
 | |
| +    return emptyString();
 | |
| +}
 | |
| +
 | |
| +void SelectionData::clearAllExceptFilenames()
 | |
| +{
 | |
| +    clearText();
 | |
| +    clearMarkup();
 | |
| +    clearURIList();
 | |
| +    clearURL();
 | |
| +    clearImage();
 | |
| +    clearCustomData();
 | |
| +
 | |
| +    m_canSmartReplace = false;
 | |
| +}
 | |
| +
 | |
| +void SelectionData::clearAll()
 | |
| +{
 | |
| +    clearAllExceptFilenames();
 | |
| +    m_filenames.clear();
 | |
| +}
 | |
| +
 | |
| +} // namespace WebCore
 | |
| diff --git a/Source/WebCore/platform/wpe/SelectionData.h b/Source/WebCore/platform/wpe/SelectionData.h
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..cf2b51f6f02837a1106f4d999f2f130e2580986a
 | |
| --- /dev/null
 | |
| +++ b/Source/WebCore/platform/wpe/SelectionData.h
 | |
| @@ -0,0 +1,82 @@
 | |
| +/*
 | |
| + * Copyright (C) 2009, Martin Robinson
 | |
| + *
 | |
| + *  This library is free software; you can redistribute it and/or
 | |
| + *  modify it under the terms of the GNU Lesser General Public
 | |
| + *  License as published by the Free Software Foundation; either
 | |
| + *  version 2 of the License, or (at your option) any later version.
 | |
| + *
 | |
| + *  This library is distributed in the hope that it will be useful,
 | |
| + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
| + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | |
| + *  Lesser General Public License for more details.
 | |
| + *
 | |
| + *  You should have received a copy of the GNU Lesser General Public
 | |
| + *  License along with this library; if not, write to the Free Software
 | |
| + *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 | |
| + */
 | |
| +
 | |
| +#pragma once
 | |
| +
 | |
| +#include "Image.h"
 | |
| +#include "SharedBuffer.h"
 | |
| +#include <wtf/HashMap.h>
 | |
| +#include <wtf/URL.h>
 | |
| +#include <wtf/text/StringHash.h>
 | |
| +
 | |
| +namespace WebCore {
 | |
| +
 | |
| +class SelectionData {
 | |
| +    WTF_MAKE_FAST_ALLOCATED;
 | |
| +public:
 | |
| +    void setText(const String&);
 | |
| +    const String& text() const { return m_text; }
 | |
| +    bool hasText() const { return !m_text.isEmpty(); }
 | |
| +    void clearText() { m_text = emptyString(); }
 | |
| +
 | |
| +    void setMarkup(const String& newMarkup) { m_markup = newMarkup; }
 | |
| +    const String& markup() const { return m_markup; }
 | |
| +    bool hasMarkup() const { return !m_markup.isEmpty(); }
 | |
| +    void clearMarkup() { m_markup = emptyString(); }
 | |
| +
 | |
| +    void setURL(const URL&, const String&);
 | |
| +    const URL& url() const { return m_url; }
 | |
| +    const String& urlLabel() const;
 | |
| +    bool hasURL() const { return !m_url.isEmpty() && m_url.isValid(); }
 | |
| +    void clearURL() { m_url = URL(); }
 | |
| +
 | |
| +    void setURIList(const String&);
 | |
| +    const String& uriList() const { return m_uriList; }
 | |
| +    const Vector<String>& filenames() const { return m_filenames; }
 | |
| +    bool hasURIList() const { return !m_uriList.isEmpty(); }
 | |
| +    bool hasFilenames() const { return !m_filenames.isEmpty(); }
 | |
| +    void clearURIList() { m_uriList = emptyString(); }
 | |
| +
 | |
| +    void setImage(Image* newImage) { m_image = newImage; }
 | |
| +    Image* image() const { return m_image.get(); }
 | |
| +    bool hasImage() const { return m_image; }
 | |
| +    void clearImage() { m_image = nullptr; }
 | |
| +
 | |
| +    void setCanSmartReplace(bool canSmartReplace) { m_canSmartReplace = canSmartReplace; }
 | |
| +    bool canSmartReplace() const { return m_canSmartReplace; }
 | |
| +
 | |
| +    void setCustomData(Ref<SharedBuffer>&& buffer) { m_customData = WTFMove(buffer); }
 | |
| +    SharedBuffer* customData() const { return m_customData.get(); }
 | |
| +    bool hasCustomData() const { return !!m_customData; }
 | |
| +    void clearCustomData() { m_customData = nullptr; }
 | |
| +
 | |
| +    void clearAll();
 | |
| +    void clearAllExceptFilenames();
 | |
| +
 | |
| +private:
 | |
| +    String m_text;
 | |
| +    String m_markup;
 | |
| +    URL m_url;
 | |
| +    String m_uriList;
 | |
| +    Vector<String> m_filenames;
 | |
| +    RefPtr<Image> m_image;
 | |
| +    bool m_canSmartReplace { false };
 | |
| +    RefPtr<SharedBuffer> m_customData;
 | |
| +};
 | |
| +
 | |
| +} // namespace WebCore
 | |
| diff --git a/Source/WebCore/rendering/RenderTextControl.cpp b/Source/WebCore/rendering/RenderTextControl.cpp
 | |
| index 1c99a7d1faec752dbfe0aaacfa95f8fca35de446..9be94e70398713a65b1aff134f894463dad625d7 100644
 | |
| --- a/Source/WebCore/rendering/RenderTextControl.cpp
 | |
| +++ b/Source/WebCore/rendering/RenderTextControl.cpp
 | |
| @@ -212,13 +212,13 @@ void RenderTextControl::layoutExcludedChildren(bool relayoutChildren)
 | |
|      }
 | |
|  }
 | |
|  
 | |
| -#if PLATFORM(IOS_FAMILY)
 | |
|  bool RenderTextControl::canScroll() const
 | |
|  {
 | |
|      auto innerText = innerTextElement();
 | |
|      return innerText && innerText->renderer() && innerText->renderer()->hasNonVisibleOverflow();
 | |
|  }
 | |
|  
 | |
| +#if PLATFORM(IOS_FAMILY)
 | |
|  int RenderTextControl::innerLineHeight() const
 | |
|  {
 | |
|      auto innerText = innerTextElement();
 | |
| diff --git a/Source/WebCore/rendering/RenderTextControl.h b/Source/WebCore/rendering/RenderTextControl.h
 | |
| index fac9402820702989bf72ed2425678bfb82bd6523..40b5a6441d22714fd370ce1a7c2f534e6e7510f5 100644
 | |
| --- a/Source/WebCore/rendering/RenderTextControl.h
 | |
| +++ b/Source/WebCore/rendering/RenderTextControl.h
 | |
| @@ -36,9 +36,9 @@ public:
 | |
|  
 | |
|      WEBCORE_EXPORT HTMLTextFormControlElement& textFormControlElement() const;
 | |
|  
 | |
| -#if PLATFORM(IOS_FAMILY)
 | |
|      bool canScroll() const;
 | |
|  
 | |
| +#if PLATFORM(IOS_FAMILY)
 | |
|      // Returns the line height of the inner renderer.
 | |
|      int innerLineHeight() const override;
 | |
|  #endif
 | |
| diff --git a/Source/WebKit/NetworkProcess/Cookies/WebCookieManager.cpp b/Source/WebKit/NetworkProcess/Cookies/WebCookieManager.cpp
 | |
| index 3b7fd04ff503a71b9e53b3d0a25764f839005602..d0af8634fbff3f32cb713900386e125faae1dace 100644
 | |
| --- a/Source/WebKit/NetworkProcess/Cookies/WebCookieManager.cpp
 | |
| +++ b/Source/WebKit/NetworkProcess/Cookies/WebCookieManager.cpp
 | |
| @@ -69,10 +69,11 @@ void WebCookieManager::deleteCookiesForHostnames(PAL::SessionID sessionID, const
 | |
|          storageSession->deleteCookiesForHostnames(hostnames);
 | |
|  }
 | |
|  
 | |
| -void WebCookieManager::deleteAllCookies(PAL::SessionID sessionID)
 | |
| +void WebCookieManager::deleteAllCookies(PAL::SessionID sessionID, CompletionHandler<void()>&& completionHandler)
 | |
|  {
 | |
|      if (auto* storageSession = m_process.storageSession(sessionID))
 | |
|          storageSession->deleteAllCookies();
 | |
| +    completionHandler();
 | |
|  }
 | |
|  
 | |
|  void WebCookieManager::deleteCookie(PAL::SessionID sessionID, const Cookie& cookie, CompletionHandler<void()>&& completionHandler)
 | |
| diff --git a/Source/WebKit/NetworkProcess/Cookies/WebCookieManager.h b/Source/WebKit/NetworkProcess/Cookies/WebCookieManager.h
 | |
| index 35ce8a9ecfc294cd6de1e7ff9310e0a57ea49d7e..6b03f334763e5c46e7d35064e3a169a8308a1b46 100644
 | |
| --- a/Source/WebKit/NetworkProcess/Cookies/WebCookieManager.h
 | |
| +++ b/Source/WebKit/NetworkProcess/Cookies/WebCookieManager.h
 | |
| @@ -73,7 +73,7 @@ private:
 | |
|  
 | |
|      void deleteCookie(PAL::SessionID, const WebCore::Cookie&, CompletionHandler<void()>&&);
 | |
|      void deleteCookiesForHostnames(PAL::SessionID, const Vector<String>&);
 | |
| -    void deleteAllCookies(PAL::SessionID);
 | |
| +    void deleteAllCookies(PAL::SessionID, CompletionHandler<void()>&&);
 | |
|      void deleteAllCookiesModifiedSince(PAL::SessionID, WallTime, CompletionHandler<void()>&&);
 | |
|  
 | |
|      void setCookie(PAL::SessionID, const Vector<WebCore::Cookie>&, CompletionHandler<void()>&&);
 | |
| diff --git a/Source/WebKit/NetworkProcess/Cookies/WebCookieManager.messages.in b/Source/WebKit/NetworkProcess/Cookies/WebCookieManager.messages.in
 | |
| index 46d9708bdb8ea74213a4636ca319a09de87f249e..d785669417f8e32f39d422ac1698b303aee5190a 100644
 | |
| --- a/Source/WebKit/NetworkProcess/Cookies/WebCookieManager.messages.in
 | |
| +++ b/Source/WebKit/NetworkProcess/Cookies/WebCookieManager.messages.in
 | |
| @@ -26,13 +26,13 @@
 | |
|  messages -> WebCookieManager NotRefCounted {
 | |
|      void GetHostnamesWithCookies(PAL::SessionID sessionID) -> (Vector<String> hostnames)
 | |
|      void DeleteCookiesForHostnames(PAL::SessionID sessionID, Vector<String> hostnames)
 | |
| -    void DeleteAllCookies(PAL::SessionID sessionID)
 | |
|  
 | |
|      void SetCookie(PAL::SessionID sessionID, Vector<WebCore::Cookie> cookie) -> ()
 | |
|      void SetCookies(PAL::SessionID sessionID, Vector<WebCore::Cookie> cookies, URL url, URL mainDocumentURL) -> ()
 | |
|      void GetAllCookies(PAL::SessionID sessionID) -> (Vector<WebCore::Cookie> cookies)
 | |
|      void GetCookies(PAL::SessionID sessionID, URL url) -> (Vector<WebCore::Cookie> cookies)
 | |
|      void DeleteCookie(PAL::SessionID sessionID, struct WebCore::Cookie cookie) -> ()
 | |
| +    void DeleteAllCookies(PAL::SessionID sessionID) -> ()
 | |
|      void DeleteAllCookiesModifiedSince(PAL::SessionID sessionID, WallTime time) -> ()
 | |
|  
 | |
|      void SetHTTPCookieAcceptPolicy(enum:uint8_t WebCore::HTTPCookieAcceptPolicy policy) -> ()
 | |
| diff --git a/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp b/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp
 | |
| index 61a609b6f9394d53f610c7e9673ada3f1e5da0de..7f317fb6da663e64ea935fb4567613315e567aa4 100644
 | |
| --- a/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp
 | |
| +++ b/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp
 | |
| @@ -83,6 +83,11 @@
 | |
|  #include <WebCore/SameSiteInfo.h>
 | |
|  #include <WebCore/SecurityPolicy.h>
 | |
|  
 | |
| +#if PLATFORM(COCOA)
 | |
| +#include "NetworkDataTaskCocoa.h"
 | |
| +#include "NetworkSessionCocoa.h"
 | |
| +#endif
 | |
| +
 | |
|  #if ENABLE(APPLE_PAY_REMOTE_UI)
 | |
|  #include "WebPaymentCoordinatorProxyMessages.h"
 | |
|  #endif
 | |
| @@ -486,6 +491,10 @@ void NetworkConnectionToWebProcess::createSocketStream(URL&& url, String cachePa
 | |
|      if (auto* session = networkSession())
 | |
|          acceptInsecureCertificates = session->shouldAcceptInsecureCertificatesForWebSockets();
 | |
|  #endif
 | |
| +    if (auto* session = networkSession()) {
 | |
| +        if (session->ignoreCertificateErrors())
 | |
| +            acceptInsecureCertificates = true;
 | |
| +    }
 | |
|      m_networkSocketStreams.add(identifier, NetworkSocketStream::create(m_networkProcess.get(), WTFMove(url), m_sessionID, cachePartition, identifier, m_connection, WTFMove(token), acceptInsecureCertificates));
 | |
|  }
 | |
|  
 | |
| @@ -1030,6 +1039,14 @@ void NetworkConnectionToWebProcess::clearPageSpecificData(PageIdentifier pageID)
 | |
|  #endif
 | |
|  }
 | |
|  
 | |
| +void NetworkConnectionToWebProcess::setCookieFromResponse(const URL& firstParty, const SameSiteInfo& sameSiteInfo, const URL& url, const String& setCookieValue)
 | |
| +{
 | |
| +    auto* networkStorageSession = storageSession();
 | |
| +    if (!networkStorageSession)
 | |
| +        return;
 | |
| +    networkStorageSession->setCookiesFromResponse(firstParty, sameSiteInfo, url, setCookieValue);
 | |
| +}
 | |
| +
 | |
|  #if ENABLE(INTELLIGENT_TRACKING_PREVENTION)
 | |
|  void NetworkConnectionToWebProcess::removeStorageAccessForFrame(FrameIdentifier frameID, PageIdentifier pageID)
 | |
|  {
 | |
| diff --git a/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h b/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h
 | |
| index 02fbed766529dca1c047832dfc85f9506ca8f6cd..7094f82ee6f6220e0ff2793edd8e0589468b1869 100644
 | |
| --- a/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h
 | |
| +++ b/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h
 | |
| @@ -312,6 +312,8 @@ private:
 | |
|  
 | |
|      void clearPageSpecificData(WebCore::PageIdentifier);
 | |
|  
 | |
| +    void setCookieFromResponse(const URL& firstParty, const WebCore::SameSiteInfo&, const URL& url, const String& setCookieValue);
 | |
| +
 | |
|  #if ENABLE(INTELLIGENT_TRACKING_PREVENTION)
 | |
|      void removeStorageAccessForFrame(WebCore::FrameIdentifier, WebCore::PageIdentifier);
 | |
|  
 | |
| diff --git a/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.messages.in b/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.messages.in
 | |
| index a2629e4edb214b3d26aca78da845c65d0e5aa341..d034f3a57badda1f34729afd712db7cddbfce8bf 100644
 | |
| --- a/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.messages.in
 | |
| +++ b/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.messages.in
 | |
| @@ -66,6 +66,8 @@ messages -> NetworkConnectionToWebProcess LegacyReceiver {
 | |
|  
 | |
|      ClearPageSpecificData(WebCore::PageIdentifier pageID);
 | |
|  
 | |
| +    SetCookieFromResponse(URL firstParty, struct WebCore::SameSiteInfo sameSiteInfo, URL url, String setCookieValue);
 | |
| +
 | |
|  #if ENABLE(INTELLIGENT_TRACKING_PREVENTION)
 | |
|      RemoveStorageAccessForFrame(WebCore::FrameIdentifier frameID, WebCore::PageIdentifier pageID);
 | |
|      LogUserInteraction(WebCore::RegistrableDomain domain)
 | |
| diff --git a/Source/WebKit/NetworkProcess/NetworkProcess.cpp b/Source/WebKit/NetworkProcess/NetworkProcess.cpp
 | |
| index 0c6f2435a3c75cd5112403085ff2b9ee58e0c0fd..12720a7b3a1279a04cde8e322d5e5b67d85ee021 100644
 | |
| --- a/Source/WebKit/NetworkProcess/NetworkProcess.cpp
 | |
| +++ b/Source/WebKit/NetworkProcess/NetworkProcess.cpp
 | |
| @@ -530,6 +530,12 @@ void NetworkProcess::destroySession(PAL::SessionID sessionID)
 | |
|      m_sessionsControlledByAutomation.remove(sessionID);
 | |
|  }
 | |
|  
 | |
| +void NetworkProcess::setIgnoreCertificateErrors(PAL::SessionID sessionID, bool ignore)
 | |
| +{
 | |
| +    if (auto* networkSession = this->networkSession(sessionID))
 | |
| +        networkSession->setIgnoreCertificateErrors(ignore);
 | |
| +}
 | |
| +
 | |
|  #if ENABLE(INTELLIGENT_TRACKING_PREVENTION)
 | |
|  void NetworkProcess::dumpResourceLoadStatistics(PAL::SessionID sessionID, CompletionHandler<void(String)>&& completionHandler)
 | |
|  {
 | |
| diff --git a/Source/WebKit/NetworkProcess/NetworkProcess.h b/Source/WebKit/NetworkProcess/NetworkProcess.h
 | |
| index 4cb9db009a89e6e78ecf955b4792b736c22ba1ba..3458a5b5d4ee873969aaefa0cddd670006542bf6 100644
 | |
| --- a/Source/WebKit/NetworkProcess/NetworkProcess.h
 | |
| +++ b/Source/WebKit/NetworkProcess/NetworkProcess.h
 | |
| @@ -37,6 +37,7 @@
 | |
|  #include "QuotaIncreaseRequestIdentifier.h"
 | |
|  #include "RTCDataChannelRemoteManagerProxy.h"
 | |
|  #include "SandboxExtension.h"
 | |
| +#include "StorageNamespaceIdentifier.h"
 | |
|  #include "WebPageProxyIdentifier.h"
 | |
|  #include "WebResourceLoadStatisticsStore.h"
 | |
|  #include "WebsiteData.h"
 | |
| @@ -83,6 +84,7 @@ class SessionID;
 | |
|  
 | |
|  namespace WebCore {
 | |
|  class CertificateInfo;
 | |
| +struct Cookie;
 | |
|  class CurlProxySettings;
 | |
|  class ProtectionSpace;
 | |
|  class NetworkStorageSession;
 | |
| @@ -202,6 +204,8 @@ public:
 | |
|  
 | |
|      void addWebsiteDataStore(WebsiteDataStoreParameters&&);
 | |
|  
 | |
| +    void setIgnoreCertificateErrors(PAL::SessionID, bool);
 | |
| +
 | |
|  #if ENABLE(INTELLIGENT_TRACKING_PREVENTION)
 | |
|      void clearPrevalentResource(PAL::SessionID, RegistrableDomain&&, CompletionHandler<void()>&&);
 | |
|      void clearUserInteraction(PAL::SessionID, RegistrableDomain&&, CompletionHandler<void()>&&);
 | |
| diff --git a/Source/WebKit/NetworkProcess/NetworkProcess.messages.in b/Source/WebKit/NetworkProcess/NetworkProcess.messages.in
 | |
| index 3206dcb97599ce445a73c9667af7d21c61f7c870..78abd1fa5d52103383ef8765db299d1c544490d7 100644
 | |
| --- a/Source/WebKit/NetworkProcess/NetworkProcess.messages.in
 | |
| +++ b/Source/WebKit/NetworkProcess/NetworkProcess.messages.in
 | |
| @@ -77,6 +77,8 @@ messages -> NetworkProcess LegacyReceiver {
 | |
|  
 | |
|      PreconnectTo(PAL::SessionID sessionID, WebKit::WebPageProxyIdentifier webPageProxyID, WebCore::PageIdentifier webPageID, URL url, String userAgent, enum:uint8_t WebCore::StoredCredentialsPolicy storedCredentialsPolicy, enum:bool std::optional<WebKit::NavigatingToAppBoundDomain> isNavigatingToAppBoundDomain, enum:bool WebKit::LastNavigationWasAppInitiated lastNavigationWasAppInitiated);
 | |
|  
 | |
| +    SetIgnoreCertificateErrors(PAL::SessionID sessionID, bool ignoreTLSErrors)
 | |
| +
 | |
|  #if ENABLE(INTELLIGENT_TRACKING_PREVENTION)
 | |
|      ClearPrevalentResource(PAL::SessionID sessionID, WebCore::RegistrableDomain resourceDomain) -> ()
 | |
|      ClearUserInteraction(PAL::SessionID sessionID, WebCore::RegistrableDomain resourceDomain) -> ()
 | |
| diff --git a/Source/WebKit/NetworkProcess/NetworkSession.h b/Source/WebKit/NetworkProcess/NetworkSession.h
 | |
| index 11b3fc7c4267ef9e412d7d48bb6cfbe70b2bdfeb..af1fb6660696cf9c91d319670d5542727ae3ac18 100644
 | |
| --- a/Source/WebKit/NetworkProcess/NetworkSession.h
 | |
| +++ b/Source/WebKit/NetworkProcess/NetworkSession.h
 | |
| @@ -192,6 +192,9 @@ public:
 | |
|  
 | |
|      void lowMemoryHandler(WTF::Critical);
 | |
|  
 | |
| +    void setIgnoreCertificateErrors(bool ignore) { m_ignoreCertificateErrors = ignore; }
 | |
| +    bool ignoreCertificateErrors() { return m_ignoreCertificateErrors; }
 | |
| +
 | |
|  #if ENABLE(SERVICE_WORKER)
 | |
|      void addSoftUpdateLoader(std::unique_ptr<ServiceWorkerSoftUpdateLoader>&& loader) { m_softUpdateLoaders.add(WTFMove(loader)); }
 | |
|      void removeSoftUpdateLoader(ServiceWorkerSoftUpdateLoader* loader) { m_softUpdateLoaders.remove(loader); }
 | |
| @@ -273,6 +276,7 @@ protected:
 | |
|      bool m_privateClickMeasurementDebugModeEnabled { false };
 | |
|      std::optional<WebCore::PrivateClickMeasurement> m_ephemeralMeasurement;
 | |
|      bool m_isRunningEphemeralMeasurementTest { false };
 | |
| +    bool m_ignoreCertificateErrors { false };
 | |
|  
 | |
|      HashSet<Ref<NetworkResourceLoader>> m_keptAliveLoads;
 | |
|  
 | |
| diff --git a/Source/WebKit/NetworkProcess/WebStorage/LocalStorageNamespace.cpp b/Source/WebKit/NetworkProcess/WebStorage/LocalStorageNamespace.cpp
 | |
| index 04c49bb4c914ebd93c7bcc09154e8c1d76e844b3..ace4b6eaa8ff94bdbd9d6aa041233b46f02f4fa1 100644
 | |
| --- a/Source/WebKit/NetworkProcess/WebStorage/LocalStorageNamespace.cpp
 | |
| +++ b/Source/WebKit/NetworkProcess/WebStorage/LocalStorageNamespace.cpp
 | |
| @@ -29,6 +29,7 @@
 | |
|  #include "StorageArea.h"
 | |
|  #include "StorageManager.h"
 | |
|  #include <WebCore/SecurityOriginData.h>
 | |
| +#include <wtf/Forward.h>
 | |
|  
 | |
|  namespace WebKit {
 | |
|  
 | |
| @@ -103,4 +104,11 @@ Vector<StorageAreaIdentifier> LocalStorageNamespace::storageAreaIdentifiers() co
 | |
|      return identifiers;
 | |
|  }
 | |
|  
 | |
| +void LocalStorageNamespace::forEachStorageArea(Function<void(const StorageArea&)> callback) const
 | |
| +{
 | |
| +    ASSERT(!RunLoop::isMain());
 | |
| +    for (auto& storageArea : m_storageAreaMap.values())
 | |
| +        callback(*storageArea);
 | |
| +}
 | |
| +
 | |
|  } // namespace WebKit
 | |
| diff --git a/Source/WebKit/NetworkProcess/WebStorage/LocalStorageNamespace.h b/Source/WebKit/NetworkProcess/WebStorage/LocalStorageNamespace.h
 | |
| index 73c35fc615f88a8d313848a4384875ac7d42505e..eaecae4ba4eda91ed39ecf35d075bc6369eac72b 100644
 | |
| --- a/Source/WebKit/NetworkProcess/WebStorage/LocalStorageNamespace.h
 | |
| +++ b/Source/WebKit/NetworkProcess/WebStorage/LocalStorageNamespace.h
 | |
| @@ -28,7 +28,7 @@
 | |
|  #include "StorageAreaIdentifier.h"
 | |
|  #include "StorageNamespaceIdentifier.h"
 | |
|  #include <WebCore/SecurityOriginData.h>
 | |
| -#include <wtf/Forward.h>
 | |
| +#include <wtf/Function.h>
 | |
|  #include <wtf/HashMap.h>
 | |
|  #include <wtf/WeakPtr.h>
 | |
|  
 | |
| @@ -58,6 +58,8 @@ public:
 | |
|  
 | |
|      Vector<StorageAreaIdentifier> storageAreaIdentifiers() const;
 | |
|  
 | |
| +    void forEachStorageArea(Function<void(const StorageArea&)>) const;
 | |
| +
 | |
|  private:
 | |
|      StorageManager& m_storageManager;
 | |
|      unsigned m_quotaInBytes { 0 };
 | |
| diff --git a/Source/WebKit/NetworkProcess/WebStorage/StorageArea.cpp b/Source/WebKit/NetworkProcess/WebStorage/StorageArea.cpp
 | |
| index 0c41ab92e31f49d6a5a949a403728c2aa9d040b1..4c5b378abb10ab1ba93543477e841f4ba1243dee 100644
 | |
| --- a/Source/WebKit/NetworkProcess/WebStorage/StorageArea.cpp
 | |
| +++ b/Source/WebKit/NetworkProcess/WebStorage/StorageArea.cpp
 | |
| @@ -112,6 +112,18 @@ void StorageArea::setItem(IPC::Connection::UniqueID sourceConnection, StorageAre
 | |
|      dispatchEvents(sourceConnection, storageAreaImplID, key, oldValue, value, urlString);
 | |
|  }
 | |
|  
 | |
| +void StorageArea::setItems(const HashMap<String, String>& items, bool& quotaException) {
 | |
| +    ASSERT(!RunLoop::isMain());
 | |
| +
 | |
| +    for (const auto& item : items) {
 | |
| +        String oldValue;
 | |
| +        if (isEphemeral())
 | |
| +            m_sessionStorageMap->setItem(item.key, item.value, oldValue, quotaException);
 | |
| +        else
 | |
| +            ensureDatabase().setItem(item.key, item.value, oldValue, quotaException);
 | |
| +    }
 | |
| +}
 | |
| +
 | |
|  void StorageArea::removeItem(IPC::Connection::UniqueID sourceConnection, StorageAreaImplIdentifier storageAreaImplID, const String& key, const String& urlString)
 | |
|  {
 | |
|      ASSERT(!RunLoop::isMain());
 | |
| diff --git a/Source/WebKit/NetworkProcess/WebStorage/StorageArea.h b/Source/WebKit/NetworkProcess/WebStorage/StorageArea.h
 | |
| index f57a72b6bdc3382469d69adb1b1201c7a9f07a84..c501211b094312ca44f0bf92de5d6ebc6bb843f9 100644
 | |
| --- a/Source/WebKit/NetworkProcess/WebStorage/StorageArea.h
 | |
| +++ b/Source/WebKit/NetworkProcess/WebStorage/StorageArea.h
 | |
| @@ -64,6 +64,7 @@ public:
 | |
|      void removeItem(IPC::Connection::UniqueID sourceConnection, StorageAreaImplIdentifier, const String& key, const String& urlString);
 | |
|      void clear(IPC::Connection::UniqueID sourceConnection, StorageAreaImplIdentifier, const String& urlString);
 | |
|  
 | |
| +    void setItems(const HashMap<String, String>& items, bool& quotaException);
 | |
|      HashMap<String, String> items() const;
 | |
|      void clear();
 | |
|  
 | |
| diff --git a/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm b/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm
 | |
| index ba33be375f926e0f5d71a9bb6ca8663f13ba59be..80c781b0e7a39b130311d090d7ccf1c233af1261 100644
 | |
| --- a/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm
 | |
| +++ b/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm
 | |
| @@ -720,7 +720,7 @@ void NetworkSessionCocoa::setClientAuditToken(const WebCore::AuthenticationChall
 | |
|  
 | |
|      if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
 | |
|          sessionCocoa->setClientAuditToken(challenge);
 | |
| -        if (NetworkSessionCocoa::allowsSpecificHTTPSCertificateForHost(challenge))
 | |
| +        if (sessionCocoa->ignoreCertificateErrors() || sessionCocoa->allowsSpecificHTTPSCertificateForHost(challenge))
 | |
|              return completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]);
 | |
|  
 | |
|          NSURLSessionTaskTransactionMetrics *metrics = task._incompleteTaskMetrics.transactionMetrics.lastObject;
 | |
| @@ -964,6 +964,13 @@ ALLOW_DEPRECATED_DECLARATIONS_END
 | |
|  
 | |
|          resourceResponse.setDeprecatedNetworkLoadMetrics(WebCore::copyTimingData(taskMetrics, networkDataTask->networkLoadMetrics()));
 | |
|  
 | |
| +        __block WebCore::HTTPHeaderMap requestHeaders;
 | |
| +        NSURLSessionTaskTransactionMetrics *m = dataTask._incompleteTaskMetrics.transactionMetrics.lastObject;
 | |
| +        [m.request.allHTTPHeaderFields enumerateKeysAndObjectsUsingBlock:^(NSString *name, NSString *value, BOOL *) {
 | |
| +            requestHeaders.set(String(name), String(value));
 | |
| +        }];
 | |
| +        resourceResponse.m_httpRequestHeaderFields = WTFMove(requestHeaders);
 | |
| +
 | |
|          networkDataTask->didReceiveResponse(WTFMove(resourceResponse), negotiatedLegacyTLS, privateRelayed, [completionHandler = makeBlockPtr(completionHandler), taskIdentifier](WebCore::PolicyAction policyAction) {
 | |
|  #if !LOG_DISABLED
 | |
|              LOG(NetworkSession, "%llu didReceiveResponse completionHandler (%d)", taskIdentifier, policyAction);
 | |
| diff --git a/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.cpp b/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.cpp
 | |
| index 2e6fa61594ff12bd7e864ac6edc71849f89e4028..3d550041a35d617843f0e18b54b7c22337d64709 100644
 | |
| --- a/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.cpp
 | |
| +++ b/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.cpp
 | |
| @@ -33,6 +33,7 @@
 | |
|  #include "Download.h"
 | |
|  #include "NetworkProcess.h"
 | |
|  #include "NetworkSessionCurl.h"
 | |
| +#include "NetworkProcess.h"
 | |
|  #include "PrivateRelayed.h"
 | |
|  #include <WebCore/AuthenticationChallenge.h>
 | |
|  #include <WebCore/CookieJar.h>
 | |
| @@ -84,6 +85,8 @@ NetworkDataTaskCurl::NetworkDataTaskCurl(NetworkSession& session, NetworkDataTas
 | |
|          m_curlRequest->setUserPass(m_initialCredential.user(), m_initialCredential.password());
 | |
|          m_curlRequest->setAuthenticationScheme(ProtectionSpace::AuthenticationScheme::HTTPBasic);
 | |
|      }
 | |
| +    if (m_session->ignoreCertificateErrors())
 | |
| +        m_curlRequest->disableServerTrustEvaluation();
 | |
|      m_curlRequest->start();
 | |
|  }
 | |
|  
 | |
| @@ -160,6 +163,7 @@ void NetworkDataTaskCurl::curlDidReceiveResponse(CurlRequest& request, CurlRespo
 | |
|      m_response = ResourceResponse(receivedResponse);
 | |
|      m_response.setCertificateInfo(WTFMove(receivedResponse.certificateInfo));
 | |
|      m_response.setDeprecatedNetworkLoadMetrics(Box<NetworkLoadMetrics>::create(WTFMove(receivedResponse.networkLoadMetrics)));
 | |
| +    m_response.m_httpRequestHeaderFields = request.resourceRequest().httpHeaderFields();
 | |
|  
 | |
|      handleCookieHeaders(request.resourceRequest(), receivedResponse);
 | |
|  
 | |
| @@ -386,6 +390,8 @@ void NetworkDataTaskCurl::willPerformHTTPRedirection()
 | |
|              m_curlRequest->setUserPass(m_initialCredential.user(), m_initialCredential.password());
 | |
|              m_curlRequest->setAuthenticationScheme(ProtectionSpace::AuthenticationScheme::HTTPBasic);
 | |
|          }
 | |
| +        if (m_session->ignoreCertificateErrors())
 | |
| +            m_curlRequest->disableServerTrustEvaluation();
 | |
|          m_curlRequest->start();
 | |
|  
 | |
|          if (m_state != State::Suspended) {
 | |
| diff --git a/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.h b/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.h
 | |
| index 73d76c7702988ea513039ba22b53dfc5c2e20d53..e0c1355c2fba10d8413d7c4bc75af0cfd4c79fe8 100644
 | |
| --- a/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.h
 | |
| +++ b/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.h
 | |
| @@ -87,6 +87,7 @@ private:
 | |
|  
 | |
|      void appendCookieHeader(WebCore::ResourceRequest&);
 | |
|      void handleCookieHeaders(const WebCore::ResourceRequest&, const WebCore::CurlResponse&);
 | |
| +    String suggestedFilename() const override;
 | |
|  
 | |
|      bool isThirdPartyRequest(const WebCore::ResourceRequest&);
 | |
|      bool shouldBlockCookies(const WebCore::ResourceRequest&);
 | |
| diff --git a/Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.cpp b/Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.cpp
 | |
| index e61d6ab76241aa8834d91d3a02fc9472f068c4ee..38531a742ec079f52d238577ec8426e606a60f4c 100644
 | |
| --- a/Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.cpp
 | |
| +++ b/Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.cpp
 | |
| @@ -494,6 +494,8 @@ void NetworkDataTaskSoup::didSendRequest(GRefPtr<GInputStream>&& inputStream)
 | |
|              m_networkLoadMetrics.failsTAOCheck = !passesTimingAllowOriginCheck(m_response, *origin);
 | |
|      }
 | |
|  
 | |
| +    auto& additionalMetrics = additionalNetworkLoadMetricsForWebInspector();
 | |
| +    m_response.m_httpRequestHeaderFields = additionalMetrics.requestHeaders;
 | |
|      dispatchDidReceiveResponse();
 | |
|  }
 | |
|  
 | |
| @@ -591,6 +593,8 @@ bool NetworkDataTaskSoup::acceptCertificate(GTlsCertificate* certificate, GTlsCe
 | |
|  {
 | |
|      ASSERT(m_soupMessage);
 | |
|      URL url = soupURIToURL(soup_message_get_uri(m_soupMessage.get()));
 | |
| +    if (m_session->ignoreCertificateErrors())
 | |
| +        return true;
 | |
|      auto error = static_cast<NetworkSessionSoup&>(*m_session).soupNetworkSession().checkTLSErrors(url, certificate, tlsErrors);
 | |
|      if (!error)
 | |
|          return true;
 | |
| diff --git a/Source/WebKit/NetworkProcess/soup/NetworkSessionSoup.cpp b/Source/WebKit/NetworkProcess/soup/NetworkSessionSoup.cpp
 | |
| index bc06eb37854c1ec72b30568e95dba6ef60c132a4..7b8fd54b740c828be204d4fedba0286fd5be6ace 100644
 | |
| --- a/Source/WebKit/NetworkProcess/soup/NetworkSessionSoup.cpp
 | |
| +++ b/Source/WebKit/NetworkProcess/soup/NetworkSessionSoup.cpp
 | |
| @@ -109,6 +109,11 @@ static gboolean webSocketAcceptCertificateCallback(GTlsConnection* connection, G
 | |
|      return !session->soupNetworkSession().checkTLSErrors(soupURIToURL(soup_message_get_uri(soupMessage)), certificate, errors);
 | |
|  }
 | |
|  
 | |
| +static gboolean webSocketAcceptCertificateCallbackIgnoreTLSErrors(GTlsConnection* connection, GTlsCertificate* certificate, GTlsCertificateFlags errors, NetworkSessionSoup* session)
 | |
| +{
 | |
| +    return TRUE;
 | |
| +}
 | |
| +
 | |
|  static void webSocketMessageNetworkEventCallback(SoupMessage* soupMessage, GSocketClientEvent event, GIOStream* connection, NetworkSessionSoup* session)
 | |
|  {
 | |
|      if (event != G_SOCKET_CLIENT_TLS_HANDSHAKING)
 | |
| @@ -119,6 +124,15 @@ static void webSocketMessageNetworkEventCallback(SoupMessage* soupMessage, GSock
 | |
|  }
 | |
|  #endif
 | |
|  
 | |
| +static void webSocketMessageNetworkEventCallbackIgnoreTLSErrors(SoupMessage* soupMessage, GSocketClientEvent event, GIOStream* connection)
 | |
| +{
 | |
| +    if (event != G_SOCKET_CLIENT_TLS_HANDSHAKING)
 | |
| +        return;
 | |
| +
 | |
| +    g_object_set_data(G_OBJECT(connection), "wk-soup-message", soupMessage);
 | |
| +    g_signal_connect(connection, "accept-certificate", G_CALLBACK(webSocketAcceptCertificateCallbackIgnoreTLSErrors), soupMessage);
 | |
| +}
 | |
| +
 | |
|  std::unique_ptr<WebSocketTask> NetworkSessionSoup::createWebSocketTask(WebPageProxyIdentifier, NetworkSocketChannel& channel, const ResourceRequest& request, const String& protocol, const ClientOrigin&, bool)
 | |
|  {
 | |
|      GRefPtr<SoupMessage> soupMessage = request.createSoupMessage(blobRegistry());
 | |
| @@ -127,14 +141,21 @@ std::unique_ptr<WebSocketTask> NetworkSessionSoup::createWebSocketTask(WebPagePr
 | |
|  
 | |
|      if (request.url().protocolIs("wss")) {
 | |
|  #if USE(SOUP2)
 | |
| -        g_signal_connect(soupMessage.get(), "network-event", G_CALLBACK(webSocketMessageNetworkEventCallback), this);
 | |
| +        if (ignoreCertificateErrors())
 | |
| +          g_signal_connect(soupMessage.get(), "network-event", G_CALLBACK(webSocketMessageNetworkEventCallbackIgnoreTLSErrors), this);
 | |
| +        else
 | |
| +          g_signal_connect(soupMessage.get(), "network-event", G_CALLBACK(webSocketMessageNetworkEventCallback), this);
 | |
|  #else
 | |
| -        g_signal_connect(soupMessage.get(), "accept-certificate", G_CALLBACK(+[](SoupMessage* message, GTlsCertificate* certificate, GTlsCertificateFlags errors,  NetworkSessionSoup* session) -> gboolean {
 | |
| -            if (DeprecatedGlobalSettings::allowsAnySSLCertificate())
 | |
| -                return TRUE;
 | |
| -
 | |
| -            return !session->soupNetworkSession().checkTLSErrors(soup_message_get_uri(message), certificate, errors);
 | |
| -        }), this);
 | |
| +        if (ignoreCertificateErrors()) {
 | |
| +            g_signal_connect(soupMessage.get(), "accept-certificate", G_CALLBACK(webSocketAcceptCertificateCallbackIgnoreTLSErrors), this);
 | |
| +        } else {            
 | |
| +            g_signal_connect(soupMessage.get(), "accept-certificate", G_CALLBACK(+[](SoupMessage* message, GTlsCertificate* certificate, GTlsCertificateFlags errors,  NetworkSessionSoup* session) -> gboolean {
 | |
| +                if (DeprecatedGlobalSettings::allowsAnySSLCertificate())
 | |
| +                    return TRUE;
 | |
| +
 | |
| +                return !session->soupNetworkSession().checkTLSErrors(soup_message_get_uri(message), certificate, errors);
 | |
| +            }), this);
 | |
| +        }
 | |
|  #endif
 | |
|      }
 | |
|      return makeUnique<WebSocketTask>(channel, request, soupSession(), soupMessage.get(), protocol);
 | |
| diff --git a/Source/WebKit/PlatformGTK.cmake b/Source/WebKit/PlatformGTK.cmake
 | |
| index 701de727c8ca19283d4da10529f2d50b370d9757..51f0b17a24b3869966ddebdda32cdc539f6863bd 100644
 | |
| --- a/Source/WebKit/PlatformGTK.cmake
 | |
| +++ b/Source/WebKit/PlatformGTK.cmake
 | |
| @@ -476,6 +476,9 @@ list(APPEND WebKit_SYSTEM_INCLUDE_DIRECTORIES
 | |
|      ${GSTREAMER_PBUTILS_INCLUDE_DIRS}
 | |
|      ${GTK_INCLUDE_DIRS}
 | |
|      ${LIBSOUP_INCLUDE_DIRS}
 | |
| +# Playwright begin
 | |
| +    ${LIBVPX_INCLUDE_DIRS}
 | |
| +# Playwright end
 | |
|  )
 | |
|  
 | |
|  if (USE_WPE_RENDERER)
 | |
| @@ -529,6 +532,9 @@ if (USE_LIBWEBRTC)
 | |
|      list(APPEND WebKit_SYSTEM_INCLUDE_DIRECTORIES
 | |
|          "${THIRDPARTY_DIR}/libwebrtc/Source/"
 | |
|          "${THIRDPARTY_DIR}/libwebrtc/Source/webrtc"
 | |
| +# Playwright begin
 | |
| +        "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/include"
 | |
| +# Playwright end
 | |
|      )
 | |
|  endif ()
 | |
|  
 | |
| @@ -543,6 +549,12 @@ if (ENABLE_MEDIA_STREAM)
 | |
|      )
 | |
|  endif ()
 | |
|  
 | |
| +# Playwright begin
 | |
| +list(APPEND WebKit_PRIVATE_INCLUDE_DIRECTORIES
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libwebm"
 | |
| +)
 | |
| +# Playwright end
 | |
| +
 | |
|  # To generate WebKitEnumTypes.h we want to use all installed headers, except WebKitEnumTypes.h itself.
 | |
|  set(WebKit2GTK_ENUM_GENERATION_HEADERS ${WebKit2GTK_INSTALLED_HEADERS})
 | |
|  list(REMOVE_ITEM WebKit2GTK_ENUM_GENERATION_HEADERS ${WebKit2Gtk_DERIVED_SOURCES_DIR}/webkit/WebKitEnumTypes.h)
 | |
| diff --git a/Source/WebKit/PlatformWPE.cmake b/Source/WebKit/PlatformWPE.cmake
 | |
| index 93c194b1e3c2462fee6b8c66ecbb9323c4841350..51e0f52c363ecd4b1d64c78834473ceb0e6cab30 100644
 | |
| --- a/Source/WebKit/PlatformWPE.cmake
 | |
| +++ b/Source/WebKit/PlatformWPE.cmake
 | |
| @@ -185,6 +185,7 @@ set(WPE_API_INSTALLED_HEADERS
 | |
|      ${WEBKIT_DIR}/UIProcess/API/wpe/WebKitOptionMenuItem.h
 | |
|      ${WEBKIT_DIR}/UIProcess/API/wpe/WebKitPermissionRequest.h
 | |
|      ${WEBKIT_DIR}/UIProcess/API/wpe/WebKitPlugin.h
 | |
| +    ${WEBKIT_DIR}/UIProcess/API/wpe/WebKitPointerLockPermissionRequest.h
 | |
|      ${WEBKIT_DIR}/UIProcess/API/wpe/WebKitPolicyDecision.h
 | |
|      ${WEBKIT_DIR}/UIProcess/API/wpe/WebKitRectangle.h
 | |
|      ${WEBKIT_DIR}/UIProcess/API/wpe/WebKitResponsePolicyDecision.h
 | |
| @@ -313,6 +314,7 @@ list(APPEND WebKit_INCLUDE_DIRECTORIES
 | |
|      "${WEBKIT_DIR}/UIProcess/CoordinatedGraphics"
 | |
|      "${WEBKIT_DIR}/UIProcess/Inspector/glib"
 | |
|      "${WEBKIT_DIR}/UIProcess/geoclue"
 | |
| +    "${WEBKIT_DIR}/UIProcess/glib"
 | |
|      "${WEBKIT_DIR}/UIProcess/gstreamer"
 | |
|      "${WEBKIT_DIR}/UIProcess/linux"
 | |
|      "${WEBKIT_DIR}/UIProcess/soup"
 | |
| @@ -334,8 +336,17 @@ list(APPEND WebKit_SYSTEM_INCLUDE_DIRECTORIES
 | |
|      ${GIO_UNIX_INCLUDE_DIRS}
 | |
|      ${GLIB_INCLUDE_DIRS}
 | |
|      ${LIBSOUP_INCLUDE_DIRS}
 | |
| +# Playwright begin
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/include"
 | |
| +# Playwright end
 | |
|  )
 | |
|  
 | |
| +# Playwright begin
 | |
| +list(APPEND WebKit_PRIVATE_INCLUDE_DIRECTORIES
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libwebm"
 | |
| +)
 | |
| +# Playwright end
 | |
| +
 | |
|  list(APPEND WebKit_LIBRARIES
 | |
|      Cairo::Cairo
 | |
|      Freetype::Freetype
 | |
| diff --git a/Source/WebKit/PlatformWin.cmake b/Source/WebKit/PlatformWin.cmake
 | |
| index 93b9f5f8dbdec3555944d13685486937a3f71eb6..f829a7c9b71c66f1dcf76b954dd8346c32e3e466 100644
 | |
| --- a/Source/WebKit/PlatformWin.cmake
 | |
| +++ b/Source/WebKit/PlatformWin.cmake
 | |
| @@ -66,8 +66,12 @@ list(APPEND WebKit_SOURCES
 | |
|  
 | |
|      UIProcess/wc/DrawingAreaProxyWC.cpp
 | |
|  
 | |
| +    UIProcess/win/InspectorTargetProxyWin.cpp
 | |
| +    UIProcess/win/InspectorPlaywrightAgentClientWin.cpp
 | |
|      UIProcess/win/PageClientImpl.cpp
 | |
|      UIProcess/win/WebContextMenuProxyWin.cpp
 | |
| +    UIProcess/win/WebPageInspectorEmulationAgentWin.cpp
 | |
| +    UIProcess/win/WebPageInspectorInputAgentWin.cpp
 | |
|      UIProcess/win/WebPageProxyWin.cpp
 | |
|      UIProcess/win/WebPopupMenuProxyWin.cpp
 | |
|      UIProcess/win/WebProcessPoolWin.cpp
 | |
| @@ -85,6 +89,7 @@ list(APPEND WebKit_SOURCES
 | |
|      WebProcess/MediaCache/WebMediaKeyStorageManager.cpp
 | |
|  
 | |
|      WebProcess/WebCoreSupport/win/WebPopupMenuWin.cpp
 | |
| +    WebProcess/WebCoreSupport/win/WebDragClientWin.cpp
 | |
|  
 | |
|      WebProcess/WebPage/AcceleratedSurface.cpp
 | |
|  
 | |
| @@ -138,6 +143,72 @@ list(APPEND WebKit_MESSAGES_IN_FILES
 | |
|      GPUProcess/graphics/wc/RemoteWCLayerTreeHost
 | |
|  )
 | |
|  
 | |
| +# Playwright begin
 | |
| +list(APPEND WebKit_SYSTEM_INCLUDE_DIRECTORIES
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/include"
 | |
| +    "${LIBVPX_CUSTOM_INCLUDE_DIR}"
 | |
| +)
 | |
| +
 | |
| +list(APPEND WebKit_PRIVATE_INCLUDE_DIRECTORIES
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libwebm"
 | |
| +)
 | |
| +
 | |
| +list(APPEND WebKit_SOURCES
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libwebm/mkvmuxer/mkvmuxer.cc"
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libwebm/mkvmuxer/mkvmuxerutil.cc"
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libwebm/mkvmuxer/mkvwriter.cc"
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/compare.cc"
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/compare_common.cc"
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/compare_gcc.cc"
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/compare_mmi.cc"
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/compare_msa.cc"
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/compare_neon64.cc"
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/compare_neon.cc"
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/compare_win.cc"
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/convert_argb.cc"
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/convert.cc"
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/convert_from_argb.cc"
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/convert_from.cc"
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/convert_jpeg.cc"
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/convert_to_argb.cc"
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/convert_to_i420.cc"
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/cpu_id.cc"
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/mjpeg_decoder.cc"
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/mjpeg_validate.cc"
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/planar_functions.cc"
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/rotate_any.cc"
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/rotate_argb.cc"
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/rotate.cc"
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/rotate_common.cc"
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/rotate_gcc.cc"
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/rotate_mmi.cc"
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/rotate_msa.cc"
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/rotate_neon64.cc"
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/rotate_neon.cc"
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/rotate_win.cc"
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/row_any.cc"
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/row_common.cc"
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/row_gcc.cc"
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/row_mmi.cc"
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/row_msa.cc"
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/row_neon64.cc"
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/row_neon.cc"
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/row_win.cc"
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/scale_any.cc"
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/scale_argb.cc"
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/scale.cc"
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/scale_common.cc"
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/scale_gcc.cc"
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/scale_mmi.cc"
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/scale_msa.cc"
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/scale_neon64.cc"
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/scale_neon.cc"
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/scale_uv.cc"
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/scale_win.cc"
 | |
| +    "${THIRDPARTY_DIR}/libwebrtc/Source/third_party/libyuv/source/video_common.cc"
 | |
| +)
 | |
| +# Playwright end
 | |
| +
 | |
|  set(WebKitCommonIncludeDirectories ${WebKit_INCLUDE_DIRECTORIES})
 | |
|  set(WebKitCommonSystemIncludeDirectories ${WebKit_SYSTEM_INCLUDE_DIRECTORIES})
 | |
|  
 | |
| @@ -197,6 +268,7 @@ if (${WTF_PLATFORM_WIN_CAIRO})
 | |
|          OpenSSL::SSL
 | |
|          mfuuid.lib
 | |
|          strmiids.lib
 | |
| +        ${LIBVPX_CUSTOM_LIBRARY}
 | |
|      )
 | |
|  endif ()
 | |
|  
 | |
| diff --git a/Source/WebKit/Shared/API/c/wpe/WebKit.h b/Source/WebKit/Shared/API/c/wpe/WebKit.h
 | |
| index caf67e1dece5b727e43eba780e70814f8fdb0f63..740150d2589d6e16a516daa3bf6ef899ac538c99 100644
 | |
| --- a/Source/WebKit/Shared/API/c/wpe/WebKit.h
 | |
| +++ b/Source/WebKit/Shared/API/c/wpe/WebKit.h
 | |
| @@ -77,6 +77,7 @@
 | |
|  // From Source/WebKit/UIProcess/API/C
 | |
|  #include <WebKit/WKBackForwardListItemRef.h>
 | |
|  #include <WebKit/WKBackForwardListRef.h>
 | |
| +#include <WebKit/WKBrowserInspector.h>
 | |
|  #include <WebKit/WKContext.h>
 | |
|  #include <WebKit/WKContextConfigurationRef.h>
 | |
|  #include <WebKit/WKCredential.h>
 | |
| diff --git a/Source/WebKit/Shared/NativeWebKeyboardEvent.h b/Source/WebKit/Shared/NativeWebKeyboardEvent.h
 | |
| index ee8cac1c980039c4a36de5501ab7f135e710d06b..deae2be9e720ff76186ecea89920dfc39c4f186a 100644
 | |
| --- a/Source/WebKit/Shared/NativeWebKeyboardEvent.h
 | |
| +++ b/Source/WebKit/Shared/NativeWebKeyboardEvent.h
 | |
| @@ -33,6 +33,7 @@
 | |
|  #if USE(APPKIT)
 | |
|  #include <wtf/RetainPtr.h>
 | |
|  OBJC_CLASS NSView;
 | |
| +OBJC_CLASS NSEvent;
 | |
|  #endif
 | |
|  
 | |
|  #if PLATFORM(GTK)
 | |
| @@ -65,19 +66,35 @@ public:
 | |
|  #if USE(APPKIT)
 | |
|      // FIXME: Share iOS's HandledByInputMethod enum here instead of passing a boolean.
 | |
|      NativeWebKeyboardEvent(NSEvent *, bool handledByInputMethod, bool replacesSoftSpace, const Vector<WebCore::KeypressCommand>&);
 | |
| +    NativeWebKeyboardEvent(Type type, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<Modifier> modifiers, WallTime timestamp, Vector<WebCore::KeypressCommand>&& commands)
 | |
| +        : WebKeyboardEvent(type, text, unmodifiedText, key, code, keyIdentifier, windowsVirtualKeyCode, nativeVirtualKeyCode, isAutoRepeat, isKeypad, isSystemKey, modifiers, timestamp, WTFMove(commands))
 | |
| +    {
 | |
| +    }
 | |
|  #elif PLATFORM(GTK)
 | |
|      NativeWebKeyboardEvent(const NativeWebKeyboardEvent&);
 | |
|      NativeWebKeyboardEvent(GdkEvent*, const String&, Vector<String>&& commands);
 | |
|      NativeWebKeyboardEvent(const String&, std::optional<Vector<WebCore::CompositionUnderline>>&&, std::optional<EditingRange>&&);
 | |
|      NativeWebKeyboardEvent(Type, const String& text, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, Vector<String>&& commands, bool isKeypad, OptionSet<Modifier>);
 | |
| +    NativeWebKeyboardEvent(Type type, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<Modifier> modifiers, WallTime timestamp, Vector<String>&& commands)
 | |
| +        : WebKeyboardEvent(type, text, unmodifiedText, key, code, keyIdentifier, windowsVirtualKeyCode, nativeVirtualKeyCode, isAutoRepeat, isKeypad, isSystemKey, modifiers, timestamp, WTFMove(commands))
 | |
| +    {
 | |
| +    }
 | |
|  #elif PLATFORM(IOS_FAMILY)
 | |
|      enum class HandledByInputMethod : bool { No, Yes };
 | |
|      NativeWebKeyboardEvent(::WebEvent *, HandledByInputMethod);
 | |
|  #elif USE(LIBWPE)
 | |
|      enum class HandledByInputMethod : bool { No, Yes };
 | |
|      NativeWebKeyboardEvent(struct wpe_input_keyboard_event*, const String&, HandledByInputMethod, std::optional<Vector<WebCore::CompositionUnderline>>&&, std::optional<EditingRange>&&);
 | |
| +    NativeWebKeyboardEvent(Type type, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<Modifier> modifiers, WallTime timestamp)
 | |
| +        : WebKeyboardEvent(type, text, unmodifiedText, key, code, keyIdentifier, windowsVirtualKeyCode, nativeVirtualKeyCode, isAutoRepeat, isKeypad, isSystemKey, modifiers, timestamp)
 | |
| +    {
 | |
| +    }
 | |
|  #elif PLATFORM(WIN)
 | |
|      NativeWebKeyboardEvent(HWND, UINT message, WPARAM, LPARAM, Vector<MSG>&& pendingCharEvents);
 | |
| +    NativeWebKeyboardEvent(Type type, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<Modifier> modifiers, WallTime timestamp)
 | |
| +        : WebKeyboardEvent(type, text, unmodifiedText, key, code, keyIdentifier, windowsVirtualKeyCode, nativeVirtualKeyCode, isAutoRepeat, isKeypad, isSystemKey, modifiers, timestamp)
 | |
| +    {
 | |
| +    }
 | |
|  #endif
 | |
|  
 | |
|  #if USE(APPKIT)
 | |
| diff --git a/Source/WebKit/Shared/NativeWebMouseEvent.h b/Source/WebKit/Shared/NativeWebMouseEvent.h
 | |
| index fef57e34be6ed7592187c3e1fd73c989bf79da1a..e35612e9b88877627802df18e9084e7f4022e629 100644
 | |
| --- a/Source/WebKit/Shared/NativeWebMouseEvent.h
 | |
| +++ b/Source/WebKit/Shared/NativeWebMouseEvent.h
 | |
| @@ -78,6 +78,11 @@ public:
 | |
|      NativeWebMouseEvent(HWND, UINT message, WPARAM, LPARAM, bool);
 | |
|  #endif
 | |
|  
 | |
| +#if PLATFORM(GTK) || USE(LIBWPE) || PLATFORM(WIN)
 | |
| +    NativeWebMouseEvent(Type type, Button button, unsigned short buttons, const WebCore::IntPoint& position, const WebCore::IntPoint& globalPosition, float deltaX, float deltaY, float deltaZ, int clickCount, OptionSet<Modifier> modifiers, WallTime timestamp)
 | |
| +       : WebMouseEvent(type, button, buttons, position, globalPosition, deltaX, deltaY, deltaZ, clickCount, modifiers, timestamp) { }
 | |
| +#endif
 | |
| +
 | |
|  #if USE(APPKIT)
 | |
|      NSEvent* nativeEvent() const { return m_nativeEvent.get(); }
 | |
|  #elif PLATFORM(GTK)
 | |
| diff --git a/Source/WebKit/Shared/NativeWebWheelEvent.h b/Source/WebKit/Shared/NativeWebWheelEvent.h
 | |
| index f2f3979fcac9dfd97d0e0ead600fe35eb8defd40..ac91412e1a96bdf521b1890a66e465dc54293d31 100644
 | |
| --- a/Source/WebKit/Shared/NativeWebWheelEvent.h
 | |
| +++ b/Source/WebKit/Shared/NativeWebWheelEvent.h
 | |
| @@ -67,7 +67,8 @@ public:
 | |
|  #elif PLATFORM(WIN)
 | |
|      NativeWebWheelEvent(HWND, UINT message, WPARAM, LPARAM);
 | |
|  #endif
 | |
| -
 | |
| +    NativeWebWheelEvent(const WebWheelEvent & webWheelEvent)
 | |
| +        : WebWheelEvent(webWheelEvent) { }
 | |
|  #if USE(APPKIT)
 | |
|      NSEvent* nativeEvent() const { return m_nativeEvent.get(); }
 | |
|  #elif PLATFORM(GTK)
 | |
| diff --git a/Source/WebKit/Shared/WebCoreArgumentCoders.cpp b/Source/WebKit/Shared/WebCoreArgumentCoders.cpp
 | |
| index f8ef060699794f04601c5844db52feab1dd1abf0..94068960bf74feff30b11f21e810956b740b4dba 100644
 | |
| --- a/Source/WebKit/Shared/WebCoreArgumentCoders.cpp
 | |
| +++ b/Source/WebKit/Shared/WebCoreArgumentCoders.cpp
 | |
| @@ -122,6 +122,10 @@
 | |
|  #include <WebCore/TextRecognitionResult.h>
 | |
|  #endif
 | |
|  
 | |
| +#if PLATFORM(WPE)
 | |
| +#include "ArgumentCodersWPE.h"
 | |
| +#endif
 | |
| +
 | |
|  // FIXME: Seems like we could use std::tuple to cut down the code below a lot!
 | |
|  
 | |
|  namespace IPC {
 | |
| @@ -1382,6 +1386,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)
 | |
| @@ -1410,6 +1417,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;
 | |
|  }
 | |
|  
 | |
| @@ -1423,6 +1436,11 @@ void ArgumentCoder<DragData>::encode(Encoder& encoder, const DragData& dragData)
 | |
|  #if PLATFORM(COCOA)
 | |
|      encoder << dragData.pasteboardName();
 | |
|      encoder << dragData.fileNames();
 | |
| +#endif
 | |
| +#if PLATFORM(WIN)
 | |
| +    DragData dragDataCopy = dragData;
 | |
| +    HashMap<unsigned int, Vector<String>> hash = dragDataCopy.dragDataMap();
 | |
| +    encoder << hash;
 | |
|  #endif
 | |
|      encoder << dragData.dragDestinationActionMask();
 | |
|      encoder << dragData.pageID();
 | |
| @@ -1446,9 +1464,16 @@ bool ArgumentCoder<DragData>::decode(Decoder& decoder, DragData& dragData)
 | |
|      if (!decoder.decode(applicationFlags))
 | |
|          return false;
 | |
|  
 | |
| +#if PLATFORM(WIN)
 | |
| +    DragDataMap dragDataMap;
 | |
| +    if (!decoder.decode(dragDataMap))
 | |
| +        return false;
 | |
| +#else
 | |
|      String pasteboardName;
 | |
| -    Vector<String> fileNames;
 | |
| +#endif
 | |
| +
 | |
|  #if PLATFORM(COCOA)
 | |
| +    Vector<String> fileNames;
 | |
|      if (!decoder.decode(pasteboardName))
 | |
|          return false;
 | |
|  
 | |
| @@ -1464,8 +1489,14 @@ bool ArgumentCoder<DragData>::decode(Decoder& decoder, DragData& dragData)
 | |
|      if (!decoder.decode(pageID))
 | |
|          return false;
 | |
|  
 | |
| +#if PLATFORM(WIN)
 | |
| +    dragData = DragData(dragDataMap, clientPosition, globalPosition, draggingSourceOperationMask, applicationFlags, pageID);
 | |
| +#else
 | |
|      dragData = DragData(pasteboardName, clientPosition, globalPosition, draggingSourceOperationMask, applicationFlags, dragDestinationActionMask, pageID);
 | |
| +#endif
 | |
| +#if PLATFORM(COCOA)
 | |
|      dragData.setFileNames(fileNames);
 | |
| +#endif
 | |
|  
 | |
|      return true;
 | |
|  }
 | |
| diff --git a/Source/WebKit/Shared/WebEvent.h b/Source/WebKit/Shared/WebEvent.h
 | |
| index 3ae6504779d3917a79f69f32b58260afeda270b4..72d44c33953cc13bf2ed7c762b4f9a7b88571b56 100644
 | |
| --- a/Source/WebKit/Shared/WebEvent.h
 | |
| +++ b/Source/WebKit/Shared/WebEvent.h
 | |
| @@ -31,6 +31,7 @@
 | |
|  
 | |
|  #include <wtf/EnumTraits.h>
 | |
|  #include <wtf/OptionSet.h>
 | |
| +#include <wtf/RefCounted.h>
 | |
|  #include <wtf/WallTime.h>
 | |
|  #include <wtf/text/WTFString.h>
 | |
|  
 | |
| diff --git a/Source/WebKit/Shared/WebKeyboardEvent.cpp b/Source/WebKit/Shared/WebKeyboardEvent.cpp
 | |
| index 3679736973ebc06771c7d94591909688f28a70b4..8df0a8e223551e2ee73e816adcb3b31153c54eb5 100644
 | |
| --- a/Source/WebKit/Shared/WebKeyboardEvent.cpp
 | |
| +++ b/Source/WebKit/Shared/WebKeyboardEvent.cpp
 | |
| @@ -35,6 +35,7 @@ WebKeyboardEvent::WebKeyboardEvent()
 | |
|  {
 | |
|  }
 | |
|  
 | |
| +
 | |
|  #if USE(APPKIT)
 | |
|  
 | |
|  WebKeyboardEvent::WebKeyboardEvent(Type type, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, int macCharCode, bool handledByInputMethod, const Vector<WebCore::KeypressCommand>& commands, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<Modifier> modifiers, WallTime timestamp)
 | |
| @@ -56,6 +57,24 @@ WebKeyboardEvent::WebKeyboardEvent(Type type, const String& text, const String&
 | |
|      ASSERT(isKeyboardEventType(type));
 | |
|  }
 | |
|  
 | |
| +WebKeyboardEvent::WebKeyboardEvent(Type type, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<Modifier> modifiers, WallTime timestamp, Vector<WebCore::KeypressCommand>&& commands)
 | |
| +    : WebEvent(type, modifiers, timestamp)
 | |
| +    , m_text(text)
 | |
| +    , m_unmodifiedText(text)
 | |
| +    , m_key(key)
 | |
| +    , m_code(code)
 | |
| +    , m_keyIdentifier(keyIdentifier)
 | |
| +    , m_windowsVirtualKeyCode(windowsVirtualKeyCode)
 | |
| +    , m_nativeVirtualKeyCode(nativeVirtualKeyCode)
 | |
| +    , m_macCharCode(0)
 | |
| +    , m_commands(WTFMove(commands))
 | |
| +    , m_isAutoRepeat(isAutoRepeat)
 | |
| +    , m_isKeypad(isKeypad)
 | |
| +    , m_isSystemKey(isSystemKey)
 | |
| +{
 | |
| +    ASSERT(isKeyboardEventType(type));
 | |
| +}
 | |
| +
 | |
|  #elif PLATFORM(GTK)
 | |
|  
 | |
|  WebKeyboardEvent::WebKeyboardEvent(Type type, const String& text, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool handledByInputMethod, std::optional<Vector<WebCore::CompositionUnderline>>&& preeditUnderlines, std::optional<EditingRange>&& preeditSelectionRange, Vector<String>&& commands, bool isKeypad, OptionSet<Modifier> modifiers, WallTime timestamp)
 | |
| @@ -79,6 +98,24 @@ WebKeyboardEvent::WebKeyboardEvent(Type type, const String& text, const String&
 | |
|      ASSERT(isKeyboardEventType(type));
 | |
|  }
 | |
|  
 | |
| +WebKeyboardEvent::WebKeyboardEvent(Type type, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<Modifier> modifiers, WallTime timestamp, Vector<String>&& commands)
 | |
| +    : WebEvent(type, modifiers, timestamp)
 | |
| +    , m_text(text)
 | |
| +    , m_unmodifiedText(text)
 | |
| +    , m_key(key)
 | |
| +    , m_code(code)
 | |
| +    , m_keyIdentifier(keyIdentifier)
 | |
| +    , m_windowsVirtualKeyCode(windowsVirtualKeyCode)
 | |
| +    , m_nativeVirtualKeyCode(nativeVirtualKeyCode)
 | |
| +    , m_macCharCode(0)
 | |
| +    , m_commands(WTFMove(commands))
 | |
| +    , m_isAutoRepeat(isAutoRepeat)
 | |
| +    , m_isKeypad(isKeypad)
 | |
| +    , m_isSystemKey(isSystemKey)
 | |
| +{
 | |
| +    ASSERT(isKeyboardEventType(type));
 | |
| +}
 | |
| +
 | |
|  #elif PLATFORM(IOS_FAMILY)
 | |
|  
 | |
|  WebKeyboardEvent::WebKeyboardEvent(Type type, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, int macCharCode, bool handledByInputMethod, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<Modifier> modifiers, WallTime timestamp)
 | |
| @@ -142,6 +179,27 @@ WebKeyboardEvent::WebKeyboardEvent(Type type, const String& text, const String&
 | |
|  
 | |
|  #endif
 | |
|  
 | |
| +#if PLATFORM(WIN) || USE(LIBWPE)
 | |
| +
 | |
| +WebKeyboardEvent::WebKeyboardEvent(Type type, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<Modifier> modifiers, WallTime timestamp)
 | |
| +    : WebEvent(type, modifiers, timestamp)
 | |
| +    , m_text(text)
 | |
| +    , m_unmodifiedText(text)
 | |
| +    , m_key(key)
 | |
| +    , m_code(code)
 | |
| +    , m_keyIdentifier(keyIdentifier)
 | |
| +    , m_windowsVirtualKeyCode(windowsVirtualKeyCode)
 | |
| +    , m_nativeVirtualKeyCode(nativeVirtualKeyCode)
 | |
| +    , m_macCharCode(0)
 | |
| +    , m_isAutoRepeat(isAutoRepeat)
 | |
| +    , m_isKeypad(isKeypad)
 | |
| +    , m_isSystemKey(isSystemKey)
 | |
| +{
 | |
| +    ASSERT(isKeyboardEventType(type));
 | |
| +}
 | |
| +
 | |
| +#endif
 | |
| +
 | |
|  WebKeyboardEvent::~WebKeyboardEvent()
 | |
|  {
 | |
|  }
 | |
| diff --git a/Source/WebKit/Shared/WebKeyboardEvent.h b/Source/WebKit/Shared/WebKeyboardEvent.h
 | |
| index 1817691d3e12ddec8169248c791826cc13b057e3..cdc90eda23ed5ba20ee78a02c0dd632be4bc615a 100644
 | |
| --- a/Source/WebKit/Shared/WebKeyboardEvent.h
 | |
| +++ b/Source/WebKit/Shared/WebKeyboardEvent.h
 | |
| @@ -43,14 +43,18 @@ public:
 | |
|  
 | |
|  #if USE(APPKIT)
 | |
|      WebKeyboardEvent(Type, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, int macCharCode, bool handledByInputMethod, const Vector<WebCore::KeypressCommand>&, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<Modifier>, WallTime timestamp);
 | |
| +    WebKeyboardEvent(Type, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<Modifier>, WallTime timestamp, Vector<WebCore::KeypressCommand>&& commands);
 | |
|  #elif PLATFORM(GTK)
 | |
|      WebKeyboardEvent(Type, const String& text, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool handledByInputMethod, std::optional<Vector<WebCore::CompositionUnderline>>&&, std::optional<EditingRange>&&, Vector<String>&& commands, bool isKeypad, OptionSet<Modifier>, WallTime timestamp);
 | |
| +    WebKeyboardEvent(Type, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<Modifier>, WallTime timestamp, Vector<String>&& commands);
 | |
|  #elif PLATFORM(IOS_FAMILY)
 | |
|      WebKeyboardEvent(Type, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, int macCharCode, bool handledByInputMethod, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<Modifier>, WallTime timestamp);
 | |
|  #elif USE(LIBWPE)
 | |
|      WebKeyboardEvent(Type, const String& text, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool handledByInputMethod, std::optional<Vector<WebCore::CompositionUnderline>>&&, std::optional<EditingRange>&&, bool isKeypad, OptionSet<Modifier>, WallTime timestamp);
 | |
| +    WebKeyboardEvent(Type, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<Modifier>, WallTime timestamp);
 | |
|  #else
 | |
|      WebKeyboardEvent(Type, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, int macCharCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<Modifier>, WallTime timestamp);
 | |
| +    WebKeyboardEvent(Type, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<Modifier>, WallTime timestamp);
 | |
|  #endif
 | |
|  
 | |
|      const String& text() const { return m_text; }
 | |
| diff --git a/Source/WebKit/Shared/WebMouseEvent.h b/Source/WebKit/Shared/WebMouseEvent.h
 | |
| index cf2adc382b3f59890c43a54b6c28bab2c4a965c6..998e96ec8c997bd1b51434c77e73e9420f5ebaa7 100644
 | |
| --- a/Source/WebKit/Shared/WebMouseEvent.h
 | |
| +++ b/Source/WebKit/Shared/WebMouseEvent.h
 | |
| @@ -62,6 +62,7 @@ public:
 | |
|  
 | |
|      Button button() const { return static_cast<Button>(m_button); }
 | |
|      unsigned short buttons() const { return m_buttons; }
 | |
| +    void playwrightSetButtons(unsigned short buttons) { m_buttons = buttons; }
 | |
|      const WebCore::IntPoint& position() const { return m_position; } // Relative to the view.
 | |
|      const WebCore::IntPoint& globalPosition() const { return m_globalPosition; }
 | |
|      float deltaX() const { return m_deltaX; }
 | |
| diff --git a/Source/WebKit/Shared/WebPageCreationParameters.cpp b/Source/WebKit/Shared/WebPageCreationParameters.cpp
 | |
| index 345044e6e121d3d9dfcc3721f41b22ff2b5f03c0..63c65cbf9e2e363efb4ef27602e15069f9db5cea 100644
 | |
| --- a/Source/WebKit/Shared/WebPageCreationParameters.cpp
 | |
| +++ b/Source/WebKit/Shared/WebPageCreationParameters.cpp
 | |
| @@ -155,6 +155,8 @@ void WebPageCreationParameters::encode(IPC::Encoder& encoder) const
 | |
|      encoder << crossOriginAccessControlCheckEnabled;
 | |
|      encoder << processDisplayName;
 | |
|  
 | |
| +    encoder << shouldPauseInInspectorWhenShown;
 | |
| +
 | |
|      encoder << shouldCaptureAudioInUIProcess;
 | |
|      encoder << shouldCaptureAudioInGPUProcess;
 | |
|      encoder << shouldCaptureVideoInUIProcess;
 | |
| @@ -533,7 +535,10 @@ std::optional<WebPageCreationParameters> WebPageCreationParameters::decode(IPC::
 | |
|      if (!processDisplayName)
 | |
|          return std::nullopt;
 | |
|      parameters.processDisplayName = WTFMove(*processDisplayName);
 | |
| -    
 | |
| +
 | |
| +    if (!decoder.decode(parameters.shouldPauseInInspectorWhenShown))
 | |
| +        return std::nullopt;
 | |
| +
 | |
|      if (!decoder.decode(parameters.shouldCaptureAudioInUIProcess))
 | |
|          return std::nullopt;
 | |
|  
 | |
| diff --git a/Source/WebKit/Shared/WebPageCreationParameters.h b/Source/WebKit/Shared/WebPageCreationParameters.h
 | |
| index 14b30937a5c75ae4fd9a9e9fc59e9cd958a138ff..dc1a5a83493748c3ceb948be14a45ee98069dabe 100644
 | |
| --- a/Source/WebKit/Shared/WebPageCreationParameters.h
 | |
| +++ b/Source/WebKit/Shared/WebPageCreationParameters.h
 | |
| @@ -254,6 +254,8 @@ struct WebPageCreationParameters {
 | |
|      
 | |
|      bool httpsUpgradeEnabled { true };
 | |
|  
 | |
| +    bool shouldPauseInInspectorWhenShown { false };
 | |
| +
 | |
|  #if PLATFORM(IOS)
 | |
|      bool allowsDeprecatedSynchronousXMLHttpRequestDuringUnload { false };
 | |
|  #endif
 | |
| diff --git a/Source/WebKit/Shared/gtk/NativeWebKeyboardEventGtk.cpp b/Source/WebKit/Shared/gtk/NativeWebKeyboardEventGtk.cpp
 | |
| index c204637774ee803eac42a34cde79aa556f143b82..345f5b08179e3dd239725bed06e48b46bc718336 100644
 | |
| --- a/Source/WebKit/Shared/gtk/NativeWebKeyboardEventGtk.cpp
 | |
| +++ b/Source/WebKit/Shared/gtk/NativeWebKeyboardEventGtk.cpp
 | |
| @@ -50,7 +50,7 @@ NativeWebKeyboardEvent::NativeWebKeyboardEvent(Type type, const String& text, co
 | |
|  }
 | |
|  
 | |
|  NativeWebKeyboardEvent::NativeWebKeyboardEvent(const NativeWebKeyboardEvent& event)
 | |
| -    : WebKeyboardEvent(event.type(), event.text(), event.key(), event.code(), event.keyIdentifier(), event.windowsVirtualKeyCode(), event.nativeVirtualKeyCode(), event.handledByInputMethod(), std::optional<Vector<WebCore::CompositionUnderline>>(event.preeditUnderlines()), std::optional<EditingRange>(event.preeditSelectionRange()), Vector<String>(event.commands()), event.isKeypad(), event.modifiers(), event.timestamp())
 | |
| +    : WebKeyboardEvent(event)
 | |
|      , m_nativeEvent(event.nativeEvent() ? gdk_event_copy(event.nativeEvent()) : nullptr)
 | |
|  {
 | |
|  }
 | |
| diff --git a/Source/WebKit/Shared/gtk/NativeWebMouseEventGtk.cpp b/Source/WebKit/Shared/gtk/NativeWebMouseEventGtk.cpp
 | |
| index ebf179e3f11c3e05e2354d36b1a68c4c3b965403..c00ea8a5ebe6f1d7fa987cac003dc3a281cfb386 100644
 | |
| --- a/Source/WebKit/Shared/gtk/NativeWebMouseEventGtk.cpp
 | |
| +++ b/Source/WebKit/Shared/gtk/NativeWebMouseEventGtk.cpp
 | |
| @@ -54,7 +54,7 @@ NativeWebMouseEvent::NativeWebMouseEvent(Type type, Button button, unsigned shor
 | |
|  }
 | |
|  
 | |
|  NativeWebMouseEvent::NativeWebMouseEvent(const NativeWebMouseEvent& event)
 | |
| -    : WebMouseEvent(event.type(), event.button(), event.buttons(), event.position(), event.globalPosition(), event.deltaX(), event.deltaY(), event.deltaZ(), event.clickCount(), event.modifiers(), event.timestamp(), 0, NoTap, event.isTouchEvent(), event.pointerId(), event.pointerType())
 | |
| +    : WebMouseEvent(event)
 | |
|      , m_nativeEvent(event.nativeEvent() ? gdk_event_copy(const_cast<GdkEvent*>(event.nativeEvent())) : nullptr)
 | |
|  {
 | |
|  }
 | |
| diff --git a/Source/WebKit/Shared/ios/WebPlatformTouchPointIOS.cpp b/Source/WebKit/Shared/ios/WebPlatformTouchPointIOS.cpp
 | |
| index 03e118154f6bb5b704b4ecb83d3d9543f8c5a5fa..9725caaac6ee65a96ea324ddbb4e1a3785bbc028 100644
 | |
| --- a/Source/WebKit/Shared/ios/WebPlatformTouchPointIOS.cpp
 | |
| +++ b/Source/WebKit/Shared/ios/WebPlatformTouchPointIOS.cpp
 | |
| @@ -26,7 +26,7 @@
 | |
|  #include "config.h"
 | |
|  #include "WebTouchEvent.h"
 | |
|  
 | |
| -#if ENABLE(TOUCH_EVENTS)
 | |
| +#if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS_FAMILY)
 | |
|  
 | |
|  #include "WebCoreArgumentCoders.h"
 | |
|  
 | |
| @@ -79,4 +79,4 @@ std::optional<WebPlatformTouchPoint> WebPlatformTouchPoint::decode(IPC::Decoder&
 | |
|  
 | |
|  } // namespace WebKit
 | |
|  
 | |
| -#endif // ENABLE(TOUCH_EVENTS)
 | |
| +#endif // ENABLE(TOUCH_EVENTS) && PLATFORM(IOS_FAMILY)
 | |
| diff --git a/Source/WebKit/Shared/ios/WebTouchEventIOS.cpp b/Source/WebKit/Shared/ios/WebTouchEventIOS.cpp
 | |
| index e40a6e172bfd2b75076fd4053da643ebab9eb81f..2516655bbc9e5bc863537a554c5faac0f6fc1a09 100644
 | |
| --- a/Source/WebKit/Shared/ios/WebTouchEventIOS.cpp
 | |
| +++ b/Source/WebKit/Shared/ios/WebTouchEventIOS.cpp
 | |
| @@ -26,7 +26,7 @@
 | |
|  #include "config.h"
 | |
|  #include "WebTouchEvent.h"
 | |
|  
 | |
| -#if ENABLE(TOUCH_EVENTS)
 | |
| +#if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS_FAMILY)
 | |
|  
 | |
|  #include "ArgumentCoders.h"
 | |
|  #include "WebCoreArgumentCoders.h"
 | |
| @@ -71,4 +71,4 @@ bool WebTouchEvent::decode(IPC::Decoder& decoder, WebTouchEvent& result)
 | |
|  
 | |
|  } // namespace WebKit
 | |
|  
 | |
| -#endif // ENABLE(TOUCH_EVENTS)
 | |
| +#endif // ENABLE(TOUCH_EVENTS) && PLATFORM(IOS_FAMILY)
 | |
| diff --git a/Source/WebKit/Shared/libwpe/ArgumentCodersWPE.cpp b/Source/WebKit/Shared/libwpe/ArgumentCodersWPE.cpp
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..85842bcbac87cb4964c8b144f549a512034fb392
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/Shared/libwpe/ArgumentCodersWPE.cpp
 | |
| @@ -0,0 +1,173 @@
 | |
| +/*
 | |
| + * Copyright (C) 2011 Igalia S.L.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 | |
| + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 | |
| + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 | |
| + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 | |
| + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 | |
| + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 | |
| + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 | |
| + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 | |
| + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 | |
| + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 | |
| + * THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#include "config.h"
 | |
| +#include "ArgumentCodersWPE.h"
 | |
| +
 | |
| +#include "DataReference.h"
 | |
| +#include "ShareableBitmap.h"
 | |
| +#include "WebCoreArgumentCoders.h"
 | |
| +#include <WebCore/GraphicsContext.h>
 | |
| +#include <WebCore/Image.h>
 | |
| +#include <WebCore/SelectionData.h>
 | |
| +
 | |
| +namespace IPC {
 | |
| +using namespace WebCore;
 | |
| +using namespace WebKit;
 | |
| +
 | |
| +static void encodeImage(Encoder& encoder, Image& image)
 | |
| +{
 | |
| +    RefPtr<ShareableBitmap> bitmap = ShareableBitmap::create(IntSize(image.size()), { });
 | |
| +    bitmap->createGraphicsContext()->drawImage(image, IntPoint());
 | |
| +
 | |
| +    ShareableBitmap::Handle handle;
 | |
| +    bitmap->createHandle(handle);
 | |
| +
 | |
| +    encoder << handle;
 | |
| +}
 | |
| +
 | |
| +static WARN_UNUSED_RETURN bool decodeImage(Decoder& decoder, RefPtr<Image>& image)
 | |
| +{
 | |
| +    ShareableBitmap::Handle handle;
 | |
| +    if (!decoder.decode(handle))
 | |
| +        return false;
 | |
| +
 | |
| +    RefPtr<ShareableBitmap> bitmap = ShareableBitmap::create(handle);
 | |
| +    if (!bitmap)
 | |
| +        return false;
 | |
| +    image = bitmap->createImage();
 | |
| +    if (!image)
 | |
| +        return false;
 | |
| +    return true;
 | |
| +}
 | |
| +
 | |
| +void ArgumentCoder<SelectionData>::encode(Encoder& encoder, const SelectionData& selection)
 | |
| +{
 | |
| +    bool hasText = selection.hasText();
 | |
| +    encoder << hasText;
 | |
| +    if (hasText)
 | |
| +        encoder << selection.text();
 | |
| +    bool hasMarkup = selection.hasMarkup();
 | |
| +    encoder << hasMarkup;
 | |
| +    if (hasMarkup)
 | |
| +        encoder << selection.markup();
 | |
| +
 | |
| +    bool hasURL = selection.hasURL();
 | |
| +    encoder << hasURL;
 | |
| +    if (hasURL)
 | |
| +        encoder << selection.url().string();
 | |
| +
 | |
| +    bool hasURIList = selection.hasURIList();
 | |
| +    encoder << hasURIList;
 | |
| +    if (hasURIList)
 | |
| +        encoder << selection.uriList();
 | |
| +
 | |
| +    bool hasImage = selection.hasImage();
 | |
| +    encoder << hasImage;
 | |
| +    if (hasImage)
 | |
| +        encodeImage(encoder, *selection.image());
 | |
| +
 | |
| +    bool hasCustomData = selection.hasCustomData();
 | |
| +    encoder << hasCustomData;
 | |
| +    if (hasCustomData)
 | |
| +        encoder << RefPtr<SharedBuffer>(selection.customData());
 | |
| +
 | |
| +    bool canSmartReplace = selection.canSmartReplace();
 | |
| +    encoder << canSmartReplace;
 | |
| +}
 | |
| +
 | |
| +std::optional<SelectionData> ArgumentCoder<SelectionData>::decode(Decoder& decoder)
 | |
| +{
 | |
| +    SelectionData selection;
 | |
| +
 | |
| +    bool hasText;
 | |
| +    if (!decoder.decode(hasText))
 | |
| +        return std::nullopt;
 | |
| +    if (hasText) {
 | |
| +        String text;
 | |
| +        if (!decoder.decode(text))
 | |
| +            return std::nullopt;
 | |
| +        selection.setText(text);
 | |
| +    }
 | |
| +
 | |
| +    bool hasMarkup;
 | |
| +    if (!decoder.decode(hasMarkup))
 | |
| +        return std::nullopt;
 | |
| +    if (hasMarkup) {
 | |
| +        String markup;
 | |
| +        if (!decoder.decode(markup))
 | |
| +            return std::nullopt;
 | |
| +        selection.setMarkup(markup);
 | |
| +    }
 | |
| +
 | |
| +    bool hasURL;
 | |
| +    if (!decoder.decode(hasURL))
 | |
| +        return std::nullopt;
 | |
| +    if (hasURL) {
 | |
| +        String url;
 | |
| +        if (!decoder.decode(url))
 | |
| +            return std::nullopt;
 | |
| +        selection.setURL(URL(URL(), url), String());
 | |
| +    }
 | |
| +
 | |
| +    bool hasURIList;
 | |
| +    if (!decoder.decode(hasURIList))
 | |
| +        return std::nullopt;
 | |
| +    if (hasURIList) {
 | |
| +        String uriList;
 | |
| +        if (!decoder.decode(uriList))
 | |
| +            return std::nullopt;
 | |
| +        selection.setURIList(uriList);
 | |
| +    }
 | |
| +
 | |
| +    bool hasImage;
 | |
| +    if (!decoder.decode(hasImage))
 | |
| +        return std::nullopt;
 | |
| +    if (hasImage) {
 | |
| +        RefPtr<Image> image;
 | |
| +        if (!decodeImage(decoder, image))
 | |
| +            return std::nullopt;
 | |
| +        selection.setImage(image.get());
 | |
| +    }
 | |
| +
 | |
| +    bool hasCustomData;
 | |
| +    if (!decoder.decode(hasCustomData))
 | |
| +        return std::nullopt;
 | |
| +    if (hasCustomData) {
 | |
| +        RefPtr<SharedBuffer> buffer;
 | |
| +        if (!decoder.decode(buffer))
 | |
| +            return std::nullopt;
 | |
| +        selection.setCustomData(Ref<SharedBuffer>(*buffer));
 | |
| +    }
 | |
| +
 | |
| +    bool canSmartReplace;
 | |
| +    if (!decoder.decode(canSmartReplace))
 | |
| +        return std::nullopt;
 | |
| +    selection.setCanSmartReplace(canSmartReplace);
 | |
| +
 | |
| +    return selection;
 | |
| +}
 | |
| +
 | |
| +}
 | |
| diff --git a/Source/WebKit/Shared/libwpe/ArgumentCodersWPE.h b/Source/WebKit/Shared/libwpe/ArgumentCodersWPE.h
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..789a0d7cf69704c8f665a9ed79348fbcbc1301c4
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/Shared/libwpe/ArgumentCodersWPE.h
 | |
| @@ -0,0 +1,41 @@
 | |
| +/*
 | |
| + * Copyright (C) 2011 Igalia S.L.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 | |
| + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 | |
| + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 | |
| + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 | |
| + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 | |
| + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 | |
| + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 | |
| + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 | |
| + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 | |
| + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 | |
| + * THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#pragma once
 | |
| +
 | |
| +#include "ArgumentCoders.h"
 | |
| +
 | |
| +namespace WebCore {
 | |
| +class SelectionData;
 | |
| +}
 | |
| +
 | |
| +namespace IPC {
 | |
| +
 | |
| +template<> struct ArgumentCoder<WebCore::SelectionData> {
 | |
| +    static void encode(Encoder&, const WebCore::SelectionData&);
 | |
| +    static std::optional<WebCore::SelectionData> decode(Decoder&);
 | |
| +};
 | |
| +
 | |
| +} // namespace IPC
 | |
| diff --git a/Source/WebKit/Shared/win/WebEventFactory.cpp b/Source/WebKit/Shared/win/WebEventFactory.cpp
 | |
| index 90df093a49c09dc670dfea55077c77d889dd1c1b..6ffd51532e29b941b8dc10f545b7f5b81e9407b4 100644
 | |
| --- a/Source/WebKit/Shared/win/WebEventFactory.cpp
 | |
| +++ b/Source/WebKit/Shared/win/WebEventFactory.cpp
 | |
| @@ -473,7 +473,7 @@ WebKeyboardEvent WebEventFactory::createWebKeyboardEvent(HWND hwnd, UINT message
 | |
|  }
 | |
|  
 | |
|  #if ENABLE(TOUCH_EVENTS)
 | |
| -WebTouchEvent WebEventFactory::createWebTouchEvent(const GdkEvent* event, Vector<WebPlatformTouchPoint>&& touchPoints)
 | |
| +WebTouchEvent WebEventFactory::createWebTouchEvent()
 | |
|  {
 | |
|      return WebTouchEvent();
 | |
|  }
 | |
| diff --git a/Source/WebKit/Sources.txt b/Source/WebKit/Sources.txt
 | |
| index 9479c5d1a7bad442018a6215518b2fca7994ee57..dc72d45c44a1d6b7fdc840a4264e574c37461897 100644
 | |
| --- a/Source/WebKit/Sources.txt
 | |
| +++ b/Source/WebKit/Sources.txt
 | |
| @@ -403,11 +403,14 @@ Shared/XR/XRDeviceProxy.cpp
 | |
|  
 | |
|  UIProcess/AuxiliaryProcessProxy.cpp
 | |
|  UIProcess/BackgroundProcessResponsivenessTimer.cpp
 | |
| +UIProcess/BrowserInspectorPipe.cpp
 | |
|  UIProcess/DeviceIdHashSaltStorage.cpp
 | |
|  UIProcess/DrawingAreaProxy.cpp
 | |
|  UIProcess/FrameLoadState.cpp
 | |
|  UIProcess/GeolocationPermissionRequestManagerProxy.cpp
 | |
|  UIProcess/GeolocationPermissionRequestProxy.cpp
 | |
| +UIProcess/InspectorDialogAgent.cpp
 | |
| +UIProcess/InspectorPlaywrightAgent.cpp
 | |
|  UIProcess/LegacyGlobalSettings.cpp
 | |
|  UIProcess/MediaKeySystemPermissionRequestManagerProxy.cpp
 | |
|  UIProcess/MediaKeySystemPermissionRequestProxy.cpp
 | |
| @@ -416,6 +419,7 @@ UIProcess/PageLoadState.cpp
 | |
|  UIProcess/ProcessAssertion.cpp
 | |
|  UIProcess/ProcessThrottler.cpp
 | |
|  UIProcess/ProvisionalPageProxy.cpp
 | |
| +UIProcess/RemoteInspectorPipe.cpp
 | |
|  UIProcess/ResponsivenessTimer.cpp
 | |
|  UIProcess/SpeechRecognitionRemoteRealtimeMediaSource.cpp
 | |
|  UIProcess/SpeechRecognitionRemoteRealtimeMediaSourceManager.cpp
 | |
| @@ -458,6 +462,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
 | |
| @@ -581,7 +587,11 @@ UIProcess/Inspector/WebInspectorUtilities.cpp
 | |
|  UIProcess/Inspector/WebPageDebuggable.cpp
 | |
|  UIProcess/Inspector/WebPageInspectorController.cpp
 | |
|  
 | |
| +UIProcess/Inspector/Agents/CairoJpegEncoder.cpp
 | |
|  UIProcess/Inspector/Agents/InspectorBrowserAgent.cpp
 | |
| +UIProcess/Inspector/Agents/InspectorScreencastAgent.cpp
 | |
| +UIProcess/Inspector/Agents/ScreencastEncoder.cpp
 | |
| +UIProcess/Inspector/Agents/WebMFileWriter.cpp
 | |
|  
 | |
|  UIProcess/Media/AudioSessionRoutingArbitratorProxy.cpp
 | |
|  UIProcess/Media/MediaUsageManager.cpp
 | |
| diff --git a/Source/WebKit/SourcesCocoa.txt b/Source/WebKit/SourcesCocoa.txt
 | |
| index 46259b4f3771630e5b93646704db44b91ae2564a..ebc3fef44e7d74d28409df8ceb48ec2960c32afa 100644
 | |
| --- a/Source/WebKit/SourcesCocoa.txt
 | |
| +++ b/Source/WebKit/SourcesCocoa.txt
 | |
| @@ -278,6 +278,7 @@ UIProcess/API/Cocoa/_WKApplicationManifest.mm
 | |
|  UIProcess/API/Cocoa/_WKAttachment.mm
 | |
|  UIProcess/API/Cocoa/_WKAutomationSession.mm
 | |
|  UIProcess/API/Cocoa/_WKAutomationSessionConfiguration.mm
 | |
| +UIProcess/API/Cocoa/_WKBrowserInspector.mm
 | |
|  UIProcess/API/Cocoa/_WKContentRuleListAction.mm
 | |
|  UIProcess/API/Cocoa/_WKContextMenuElementInfo.mm
 | |
|  UIProcess/API/Cocoa/_WKCustomHeaderFields.mm @no-unify
 | |
| @@ -456,6 +457,7 @@ UIProcess/Inspector/ios/WKInspectorHighlightView.mm
 | |
|  UIProcess/Inspector/ios/WKInspectorNodeSearchGestureRecognizer.mm
 | |
|  
 | |
|  UIProcess/Inspector/mac/RemoteWebInspectorUIProxyMac.mm
 | |
| +UIProcess/Inspector/mac/ScreencastEncoderMac.mm
 | |
|  UIProcess/Inspector/mac/WebInspectorUIProxyMac.mm
 | |
|  UIProcess/Inspector/mac/WKInspectorResourceURLSchemeHandler.mm
 | |
|  UIProcess/Inspector/mac/WKInspectorViewController.mm
 | |
| diff --git a/Source/WebKit/SourcesGTK.txt b/Source/WebKit/SourcesGTK.txt
 | |
| index 3b52d10af68fa9048d93193720fe3068defa8606..089ad9d5e0faf0a34c87dbbaf11abf96e33d8d71 100644
 | |
| --- a/Source/WebKit/SourcesGTK.txt
 | |
| +++ b/Source/WebKit/SourcesGTK.txt
 | |
| @@ -128,6 +128,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
 | |
| @@ -245,6 +246,7 @@ UIProcess/WebsiteData/unix/WebsiteDataStoreUnix.cpp
 | |
|  
 | |
|  UIProcess/cairo/BackingStoreCairo.cpp @no-unify
 | |
|  
 | |
| +UIProcess/glib/InspectorPlaywrightAgentClientGLib.cpp
 | |
|  UIProcess/glib/WebPageProxyGLib.cpp
 | |
|  UIProcess/glib/WebProcessPoolGLib.cpp
 | |
|  UIProcess/glib/WebProcessProxyGLib.cpp
 | |
| @@ -262,6 +264,7 @@ UIProcess/gtk/ClipboardGtk4.cpp @no-unify
 | |
|  UIProcess/gtk/WebDateTimePickerGtk.cpp
 | |
|  UIProcess/gtk/GtkSettingsManager.cpp
 | |
|  UIProcess/gtk/HardwareAccelerationManager.cpp
 | |
| +UIProcess/gtk/InspectorTargetProxyGtk.cpp
 | |
|  UIProcess/gtk/KeyBindingTranslator.cpp
 | |
|  UIProcess/gtk/PointerLockManager.cpp @no-unify
 | |
|  UIProcess/gtk/PointerLockManagerWayland.cpp @no-unify
 | |
| @@ -274,6 +277,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 ae2181088f8221594c9a2b4fbe5d99f2b6936d67..0c51c08ebf3352f7ec80aa8490e7e10c119da28a 100644
 | |
| --- a/Source/WebKit/SourcesWPE.txt
 | |
| +++ b/Source/WebKit/SourcesWPE.txt
 | |
| @@ -87,6 +87,7 @@ Shared/glib/ProcessExecutablePathGLib.cpp
 | |
|  Shared/glib/UserMessage.cpp
 | |
|  Shared/glib/WebContextMenuItemGlib.cpp
 | |
|  
 | |
| +Shared/libwpe/ArgumentCodersWPE.cpp
 | |
|  Shared/libwpe/NativeWebKeyboardEventLibWPE.cpp
 | |
|  Shared/libwpe/NativeWebMouseEventLibWPE.cpp
 | |
|  Shared/libwpe/NativeWebTouchEventLibWPE.cpp
 | |
| @@ -121,6 +122,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
 | |
| @@ -155,6 +157,7 @@ UIProcess/API/glib/WebKitOptionMenu.cpp @no-unify
 | |
|  UIProcess/API/glib/WebKitOptionMenuItem.cpp @no-unify
 | |
|  UIProcess/API/glib/WebKitPermissionRequest.cpp @no-unify
 | |
|  UIProcess/API/glib/WebKitPlugin.cpp @no-unify
 | |
| +UIProcess/API/glib/WebKitPointerLockPermissionRequest.cpp @no-unify
 | |
|  UIProcess/API/glib/WebKitPolicyDecision.cpp @no-unify
 | |
|  UIProcess/API/glib/WebKitPrivate.cpp @no-unify
 | |
|  UIProcess/API/glib/WebKitProtocolHandler.cpp @no-unify
 | |
| @@ -187,6 +190,7 @@ UIProcess/API/wpe/InputMethodFilterWPE.cpp @no-unify
 | |
|  UIProcess/API/wpe/PageClientImpl.cpp @no-unify
 | |
|  UIProcess/API/wpe/TouchGestureController.cpp @no-unify
 | |
|  UIProcess/API/wpe/WebKitColor.cpp @no-unify
 | |
| +UIProcess/API/wpe/WebKitDataListSuggestionsDropdown.cpp @no-unify
 | |
|  UIProcess/API/wpe/WebKitInputMethodContextWPE.cpp @no-unify
 | |
|  UIProcess/API/wpe/WebKitPopupMenu.cpp @no-unify
 | |
|  UIProcess/API/wpe/WebKitRectangle.cpp @no-unify
 | |
| @@ -203,6 +207,7 @@ UIProcess/CoordinatedGraphics/DrawingAreaProxyCoordinatedGraphics.cpp
 | |
|  
 | |
|  UIProcess/geoclue/GeoclueGeolocationProvider.cpp
 | |
|  
 | |
| +UIProcess/glib/InspectorPlaywrightAgentClientGLib.cpp
 | |
|  UIProcess/glib/WebPageProxyGLib.cpp
 | |
|  UIProcess/glib/WebProcessPoolGLib.cpp
 | |
|  UIProcess/glib/WebProcessProxyGLib.cpp
 | |
| @@ -229,6 +234,11 @@ UIProcess/linux/MemoryPressureMonitor.cpp
 | |
|  UIProcess/soup/WebCookieManagerProxySoup.cpp
 | |
|  UIProcess/soup/WebProcessPoolSoup.cpp
 | |
|  
 | |
| +UIProcess/wpe/InspectorTargetProxyWPE.cpp
 | |
| +UIProcess/wpe/WebColorPickerWPE.cpp
 | |
| +UIProcess/wpe/WebDateTimePickerWPE.cpp
 | |
| +UIProcess/wpe/WebPageInspectorEmulationAgentWPE.cpp
 | |
| +UIProcess/wpe/WebPageInspectorInputAgentWPE.cpp
 | |
|  UIProcess/wpe/WebPageProxyWPE.cpp
 | |
|  
 | |
|  WebProcess/GPU/graphics/gbm/RemoteGraphicsContextGLProxyGBM.cpp
 | |
| @@ -259,6 +269,8 @@ WebProcess/WebCoreSupport/glib/WebEditorClientGLib.cpp
 | |
|  
 | |
|  WebProcess/WebCoreSupport/soup/WebFrameNetworkingContext.cpp
 | |
|  
 | |
| +WebProcess/WebCoreSupport/wpe/WebDragClientWPE.cpp
 | |
| +
 | |
|  WebProcess/WebCoreSupport/wpe/WebEditorClientWPE.cpp
 | |
|  
 | |
|  WebProcess/WebPage/AcceleratedSurface.cpp
 | |
| diff --git a/Source/WebKit/UIProcess/API/APIHTTPCookieStore.cpp b/Source/WebKit/UIProcess/API/APIHTTPCookieStore.cpp
 | |
| index 3311eedbb49db7d2cc15b275a8bd9db34d3be119..ed3e1a6b0b1c676d93a1bd8f75591bbaf2fa7d7a 100644
 | |
| --- a/Source/WebKit/UIProcess/API/APIHTTPCookieStore.cpp
 | |
| +++ b/Source/WebKit/UIProcess/API/APIHTTPCookieStore.cpp
 | |
| @@ -119,9 +119,7 @@ void HTTPCookieStore::deleteAllCookies(CompletionHandler<void()>&& completionHan
 | |
|      if (!m_owningDataStore)
 | |
|          return completionHandler();
 | |
|      auto& cookieManager = m_owningDataStore->networkProcess().cookieManager();
 | |
| -    cookieManager.deleteAllCookies(m_owningDataStore->sessionID());
 | |
| -    // FIXME: The CompletionHandler should be passed to WebCookieManagerProxy::deleteAllCookies.
 | |
| -    RunLoop::main().dispatch(WTFMove(completionHandler));
 | |
| +    cookieManager.deleteAllCookies(m_owningDataStore->sessionID(), WTFMove(completionHandler));
 | |
|  }
 | |
|  
 | |
|  void HTTPCookieStore::setHTTPCookieAcceptPolicy(WebCore::HTTPCookieAcceptPolicy policy, CompletionHandler<void()>&& completionHandler)
 | |
| diff --git a/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.cpp b/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.cpp
 | |
| index a16fe13c08576194ec8c43e9dae62a20566904be..f1bc17b878c3103475fa371e05f53cce3a27cff1 100644
 | |
| --- a/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.cpp
 | |
| +++ b/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.cpp
 | |
| @@ -54,6 +54,9 @@ Ref<ProcessPoolConfiguration> ProcessPoolConfiguration::copy()
 | |
|      copy->m_attrStyleEnabled = this->m_attrStyleEnabled;
 | |
|      copy->m_shouldThrowExceptionForGlobalConstantRedeclaration = this->m_shouldThrowExceptionForGlobalConstantRedeclaration;
 | |
|      copy->m_overrideLanguages = this->m_overrideLanguages;
 | |
| +#if PLATFORM(MAC)
 | |
| +    copy->m_forceOverlayScrollbars = this->m_forceOverlayScrollbars;
 | |
| +#endif
 | |
|      copy->m_alwaysRunsAtBackgroundPriority = this->m_alwaysRunsAtBackgroundPriority;
 | |
|      copy->m_shouldTakeUIBackgroundAssertion = this->m_shouldTakeUIBackgroundAssertion;
 | |
|      copy->m_shouldCaptureDisplayInUIProcess = this->m_shouldCaptureDisplayInUIProcess;
 | |
| diff --git a/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.h b/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.h
 | |
| index c779d045500bb2ac9efe535c2c3c64b64a6e1212..868e2a1164277321fdc18ea25e8f6c73d8d2a6b6 100644
 | |
| --- a/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.h
 | |
| +++ b/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.h
 | |
| @@ -102,6 +102,11 @@ public:
 | |
|      const Vector<WTF::String>& overrideLanguages() const { return m_overrideLanguages; }
 | |
|      void setOverrideLanguages(Vector<WTF::String>&& languages) { m_overrideLanguages = WTFMove(languages); }
 | |
|      
 | |
| +#if PLATFORM(MAC)
 | |
| +    bool forceOverlayScrollbars() const { return m_forceOverlayScrollbars; }
 | |
| +    void setForceOverlayScrollbars(bool forceOverlayScrollbars) { m_forceOverlayScrollbars = forceOverlayScrollbars; }
 | |
| +#endif
 | |
| +
 | |
|      bool alwaysRunsAtBackgroundPriority() const { return m_alwaysRunsAtBackgroundPriority; }
 | |
|      void setAlwaysRunsAtBackgroundPriority(bool alwaysRunsAtBackgroundPriority) { m_alwaysRunsAtBackgroundPriority = alwaysRunsAtBackgroundPriority; }
 | |
|  
 | |
| @@ -178,6 +183,9 @@ private:
 | |
|      bool m_attrStyleEnabled { false };
 | |
|      bool m_shouldThrowExceptionForGlobalConstantRedeclaration { true };
 | |
|      Vector<WTF::String> m_overrideLanguages;
 | |
| +#if PLATFORM(MAC)
 | |
| +    bool m_forceOverlayScrollbars { false };
 | |
| +#endif
 | |
|      bool m_alwaysRunsAtBackgroundPriority { false };
 | |
|      bool m_shouldTakeUIBackgroundAssertion { true };
 | |
|      bool m_shouldCaptureDisplayInUIProcess { DEFAULT_CAPTURE_DISPLAY_IN_UI_PROCESS };
 | |
| diff --git a/Source/WebKit/UIProcess/API/APIUIClient.h b/Source/WebKit/UIProcess/API/APIUIClient.h
 | |
| index 4e48757e4d41547798c74f0b16734d6aa71992e5..2188b93b42c2364347c04ab2be3d3e7b279e1710 100644
 | |
| --- a/Source/WebKit/UIProcess/API/APIUIClient.h
 | |
| +++ b/Source/WebKit/UIProcess/API/APIUIClient.h
 | |
| @@ -106,6 +106,7 @@ public:
 | |
|      virtual void runJavaScriptAlert(WebKit::WebPageProxy&, const WTF::String&, WebKit::WebFrameProxy*, WebKit::FrameInfoData&&, Function<void()>&& completionHandler) { completionHandler(); }
 | |
|      virtual void runJavaScriptConfirm(WebKit::WebPageProxy&, const WTF::String&, WebKit::WebFrameProxy*, WebKit::FrameInfoData&&, Function<void(bool)>&& completionHandler) { completionHandler(false); }
 | |
|      virtual void runJavaScriptPrompt(WebKit::WebPageProxy&, const WTF::String&, const WTF::String&, WebKit::WebFrameProxy*, WebKit::FrameInfoData&&, Function<void(const WTF::String&)>&& completionHandler) { completionHandler(WTF::String()); }
 | |
| +    virtual void handleJavaScriptDialog(WebKit::WebPageProxy&, bool, const WTF::String&) { }
 | |
|  
 | |
|      virtual void setStatusText(WebKit::WebPageProxy*, const WTF::String&) { }
 | |
|      virtual void mouseDidMoveOverElement(WebKit::WebPageProxy&, const WebKit::WebHitTestResultData&, OptionSet<WebKit::WebEvent::Modifier>, Object*) { }
 | |
| diff --git a/Source/WebKit/UIProcess/API/C/WKInspector.cpp b/Source/WebKit/UIProcess/API/C/WKInspector.cpp
 | |
| index e1465edd29caf3109c17d44bb3c88aaba98cfbb5..32d569d3240c583334b8b6512407430fd448ae75 100644
 | |
| --- a/Source/WebKit/UIProcess/API/C/WKInspector.cpp
 | |
| +++ b/Source/WebKit/UIProcess/API/C/WKInspector.cpp
 | |
| @@ -28,6 +28,11 @@
 | |
|  
 | |
|  #if !PLATFORM(IOS_FAMILY)
 | |
|  
 | |
| +#if PLATFORM(WIN)
 | |
| +#include "BrowserInspectorPipe.h"
 | |
| +#include "InspectorPlaywrightAgentClientWin.h"
 | |
| +#endif
 | |
| +
 | |
|  #include "WKAPICast.h"
 | |
|  #include "WebInspectorUIProxy.h"
 | |
|  #include "WebPageProxy.h"
 | |
| @@ -130,4 +135,11 @@ void WKInspectorToggleElementSelection(WKInspectorRef inspectorRef)
 | |
|      toImpl(inspectorRef)->toggleElementSelection();
 | |
|  }
 | |
|  
 | |
| +void WKInspectorInitializeRemoteInspectorPipe(ConfigureDataStoreCallback configureDataStore, CreatePageCallback createPage, QuitCallback quit)
 | |
| +{
 | |
| +#if PLATFORM(WIN)
 | |
| +    initializeBrowserInspectorPipe(makeUnique<InspectorPlaywrightAgentClientWin>(configureDataStore, createPage, quit));
 | |
| +#endif
 | |
| +}
 | |
| +
 | |
|  #endif // !PLATFORM(IOS_FAMILY)
 | |
| diff --git a/Source/WebKit/UIProcess/API/C/WKInspector.h b/Source/WebKit/UIProcess/API/C/WKInspector.h
 | |
| index 026121d114c5fcad84c1396be8d692625beaa3bd..edd6e5cae033124c589959a42522fde07a42fdf6 100644
 | |
| --- a/Source/WebKit/UIProcess/API/C/WKInspector.h
 | |
| +++ b/Source/WebKit/UIProcess/API/C/WKInspector.h
 | |
| @@ -66,6 +66,10 @@ WK_EXPORT void WKInspectorTogglePageProfiling(WKInspectorRef inspector);
 | |
|  WK_EXPORT bool WKInspectorIsElementSelectionActive(WKInspectorRef inspector);
 | |
|  WK_EXPORT void WKInspectorToggleElementSelection(WKInspectorRef inspector);
 | |
|  
 | |
| +typedef void (*ConfigureDataStoreCallback)(WKWebsiteDataStoreRef dataStore);
 | |
| +typedef WKPageRef (*CreatePageCallback)(WKPageConfigurationRef configuration);
 | |
| +typedef void (*QuitCallback)();
 | |
| +WK_EXPORT void WKInspectorInitializeRemoteInspectorPipe(ConfigureDataStoreCallback, CreatePageCallback, QuitCallback);
 | |
|  #ifdef __cplusplus
 | |
|  }
 | |
|  #endif
 | |
| diff --git a/Source/WebKit/UIProcess/API/C/WKPage.cpp b/Source/WebKit/UIProcess/API/C/WKPage.cpp
 | |
| index e4e510ce2a2e56460a23c45d6dda374a75537c4b..010cc5812d7ccb42120876f184b4a2204ca43f85 100644
 | |
| --- a/Source/WebKit/UIProcess/API/C/WKPage.cpp
 | |
| +++ b/Source/WebKit/UIProcess/API/C/WKPage.cpp
 | |
| @@ -1762,6 +1762,13 @@ void WKPageSetPageUIClient(WKPageRef pageRef, const WKPageUIClientBase* wkClient
 | |
|              completionHandler(String());
 | |
|          }
 | |
|  
 | |
| +        void handleJavaScriptDialog(WebPageProxy& page, bool accept, const String& value) final {
 | |
| +            if (m_client.handleJavaScriptDialog) {
 | |
| +                m_client.handleJavaScriptDialog(toAPI(&page), accept, toAPI(value.impl()), m_client.base.clientInfo);
 | |
| +                return;
 | |
| +            }
 | |
| +        }
 | |
| +
 | |
|          void setStatusText(WebPageProxy* page, const String& text) final
 | |
|          {
 | |
|              if (!m_client.setStatusText)
 | |
| @@ -1791,6 +1798,8 @@ void WKPageSetPageUIClient(WKPageRef pageRef, const WKPageUIClientBase* wkClient
 | |
|          {
 | |
|              if (!m_client.didNotHandleKeyEvent)
 | |
|                  return;
 | |
| +            if (!event.nativeEvent())
 | |
| +                return;
 | |
|              m_client.didNotHandleKeyEvent(toAPI(page), event.nativeEvent(), m_client.base.clientInfo);
 | |
|          }
 | |
|  
 | |
| diff --git a/Source/WebKit/UIProcess/API/C/WKPageUIClient.h b/Source/WebKit/UIProcess/API/C/WKPageUIClient.h
 | |
| index 63323ea918dcddf512dadfff52dd5e60326e6ab8..63acaadcdb0d4a80b543db2728f3657cd4ed6f5f 100644
 | |
| --- a/Source/WebKit/UIProcess/API/C/WKPageUIClient.h
 | |
| +++ b/Source/WebKit/UIProcess/API/C/WKPageUIClient.h
 | |
| @@ -90,6 +90,7 @@ typedef void (*WKPageRunBeforeUnloadConfirmPanelCallback)(WKPageRef page, WKStri
 | |
|  typedef void (*WKPageRunJavaScriptAlertCallback)(WKPageRef page, WKStringRef alertText, WKFrameRef frame, WKSecurityOriginRef securityOrigin, WKPageRunJavaScriptAlertResultListenerRef listener, const void *clientInfo);
 | |
|  typedef void (*WKPageRunJavaScriptConfirmCallback)(WKPageRef page, WKStringRef message, WKFrameRef frame, WKSecurityOriginRef securityOrigin, WKPageRunJavaScriptConfirmResultListenerRef listener, const void *clientInfo);
 | |
|  typedef void (*WKPageRunJavaScriptPromptCallback)(WKPageRef page, WKStringRef message, WKStringRef defaultValue, WKFrameRef frame, WKSecurityOriginRef securityOrigin, WKPageRunJavaScriptPromptResultListenerRef listener, const void *clientInfo);
 | |
| +typedef void (*WKPageHandleJavaScriptDialogCallback)(WKPageRef page, bool accept, WKStringRef value, const void *clientInfo);
 | |
|  typedef void (*WKPageRequestStorageAccessConfirmCallback)(WKPageRef page, WKFrameRef frame, WKStringRef requestingDomain, WKStringRef currentDomain, WKPageRequestStorageAccessConfirmResultListenerRef listener, const void *clientInfo);
 | |
|  typedef void (*WKPageTakeFocusCallback)(WKPageRef page, WKFocusDirection direction, const void *clientInfo);
 | |
|  typedef void (*WKPageFocusCallback)(WKPageRef page, const void *clientInfo);
 | |
| @@ -1355,6 +1356,7 @@ typedef struct WKPageUIClientV14 {
 | |
|  
 | |
|      // Version 14.
 | |
|      WKPageRunWebAuthenticationPanelCallback                             runWebAuthenticationPanel;
 | |
| +    WKPageHandleJavaScriptDialogCallback                                handleJavaScriptDialog;
 | |
|  } WKPageUIClientV14;
 | |
|  
 | |
|  typedef struct WKPageUIClientV15 {
 | |
| @@ -1462,6 +1464,7 @@ typedef struct WKPageUIClientV15 {
 | |
|  
 | |
|      // Version 14.
 | |
|      WKPageRunWebAuthenticationPanelCallback                             runWebAuthenticationPanel;
 | |
| +    WKPageHandleJavaScriptDialogCallback                                handleJavaScriptDialog;
 | |
|  
 | |
|      // Version 15.
 | |
|      WKPageDecidePolicyForSpeechRecognitionPermissionRequestCallback     decidePolicyForSpeechRecognitionPermissionRequest;
 | |
| @@ -1573,6 +1576,7 @@ typedef struct WKPageUIClientV16 {
 | |
|  
 | |
|      // Version 14.
 | |
|      WKPageRunWebAuthenticationPanelCallback                             runWebAuthenticationPanel;
 | |
| +    WKPageHandleJavaScriptDialogCallback                                handleJavaScriptDialog;
 | |
|  
 | |
|      // Version 15.
 | |
|      WKPageDecidePolicyForSpeechRecognitionPermissionRequestCallback     decidePolicyForSpeechRecognitionPermissionRequest;
 | |
| @@ -1687,6 +1691,7 @@ typedef struct WKPageUIClientV17 {
 | |
|  
 | |
|      // Version 14.
 | |
|      WKPageRunWebAuthenticationPanelCallback                             runWebAuthenticationPanel;
 | |
| +    WKPageHandleJavaScriptDialogCallback                                handleJavaScriptDialog;
 | |
|  
 | |
|      // Version 15.
 | |
|      WKPageDecidePolicyForSpeechRecognitionPermissionRequestCallback     decidePolicyForSpeechRecognitionPermissionRequest;
 | |
| @@ -1803,6 +1808,7 @@ typedef struct WKPageUIClientV18 {
 | |
|  
 | |
|      // Version 14.
 | |
|      WKPageRunWebAuthenticationPanelCallback                             runWebAuthenticationPanel;
 | |
| +    WKPageHandleJavaScriptDialogCallback                                handleJavaScriptDialog;
 | |
|  
 | |
|      // Version 15.
 | |
|      WKPageDecidePolicyForSpeechRecognitionPermissionRequestCallback     decidePolicyForSpeechRecognitionPermissionRequest;
 | |
| diff --git a/Source/WebKit/UIProcess/API/Cocoa/WKUIDelegate.h b/Source/WebKit/UIProcess/API/Cocoa/WKUIDelegate.h
 | |
| index 82003ea11098fa60e7ac7e2cdd29ea86154c7ccb..b0ebb2874de88f8e11c515d973b4e2cea160304a 100644
 | |
| --- a/Source/WebKit/UIProcess/API/Cocoa/WKUIDelegate.h
 | |
| +++ b/Source/WebKit/UIProcess/API/Cocoa/WKUIDelegate.h
 | |
| @@ -135,6 +135,12 @@ typedef NS_ENUM(NSInteger, WKMediaCaptureType) {
 | |
|   */
 | |
|  - (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable result))completionHandler;
 | |
|  
 | |
| +/*! @abstract Handle a JavaScript dialog.
 | |
| + @param webView The web view invoking the delegate method.
 | |
| + @param accept Whether to accept the dialog.
 | |
| + @param value Value to use for prompt dialog.
 | |
| + */
 | |
| +- (void)webView:(WKWebView *)webView handleJavaScriptDialog:(BOOL)accept value:(nullable NSString *)value;
 | |
|  
 | |
|  /*! @abstract A delegate to request permission for microphone audio and camera video access.
 | |
|   @param webView The web view invoking the delegate method.
 | |
| diff --git a/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.h b/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.h
 | |
| index afa925f36c29db9c23921298dead9cce737500d6..42d396342acdb6d39830f611df0ee40ea6ec879e 100644
 | |
| --- a/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.h
 | |
| +++ b/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.h
 | |
| @@ -24,7 +24,6 @@
 | |
|   */
 | |
|  
 | |
|  #import <WebKit/WKFoundation.h>
 | |
| -
 | |
|  #import <WebKit/WKWebsiteDataRecord.h>
 | |
|  
 | |
|  NS_ASSUME_NONNULL_BEGIN
 | |
| @@ -79,6 +78,8 @@ WK_CLASS_AVAILABLE(macos(10.11), ios(9.0))
 | |
|  /*! @abstract Returns the cookie store representing HTTP cookies in this website data store. */
 | |
|  @property (nonatomic, readonly) WKHTTPCookieStore *httpCookieStore WK_API_AVAILABLE(macos(10.13), ios(11.0));
 | |
|  
 | |
| +- (uint64_t)sessionID;
 | |
| +
 | |
|  @end
 | |
|  
 | |
|  NS_ASSUME_NONNULL_END
 | |
| diff --git a/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.mm b/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.mm
 | |
| index e6f2fcf02b24fa16021c3be83f6116f989610027..bc2ddd59dd037fe3f52f996124b8cd2d426d526d 100644
 | |
| --- a/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.mm
 | |
| +++ b/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.mm
 | |
| @@ -47,6 +47,7 @@
 | |
|  #import "_WKResourceLoadStatisticsThirdPartyInternal.h"
 | |
|  #import "_WKWebsiteDataStoreConfigurationInternal.h"
 | |
|  #import "_WKWebsiteDataStoreDelegate.h"
 | |
| +#import <pal/SessionID.h>
 | |
|  #import <WebCore/Credential.h>
 | |
|  #import <WebCore/RegistrationDatabase.h>
 | |
|  #import <WebCore/ServiceWorkerClientData.h>
 | |
| @@ -234,6 +235,11 @@ static WallTime toSystemClockTime(NSDate *date)
 | |
|      });
 | |
|  }
 | |
|  
 | |
| +- (uint64_t) sessionID
 | |
| +{
 | |
| +    return _websiteDataStore->sessionID().toUInt64();
 | |
| +}
 | |
| +
 | |
|  static Vector<WebKit::WebsiteDataRecord> toWebsiteDataRecords(NSArray *dataRecords)
 | |
|  {
 | |
|      Vector<WebKit::WebsiteDataRecord> result;
 | |
| diff --git a/Source/WebKit/UIProcess/API/Cocoa/_WKBrowserInspector.h b/Source/WebKit/UIProcess/API/Cocoa/_WKBrowserInspector.h
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..5fabe06a3289689246c36dfd96eb9900a48b2b0f
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/UIProcess/API/Cocoa/_WKBrowserInspector.h
 | |
| @@ -0,0 +1,55 @@
 | |
| +/*
 | |
| + * Copyright (C) 2019 Microsoft Corporation.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
| + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#import <WebKit/WKFoundation.h>
 | |
| +#import <WebKit/WKProcessPool.h>
 | |
| +#import <WebKit/WKWebsiteDataStore.h>
 | |
| +#import <Foundation/Foundation.h>
 | |
| +
 | |
| +NS_ASSUME_NONNULL_BEGIN
 | |
| +
 | |
| +@class WKWebView;
 | |
| +
 | |
| +WK_CLASS_AVAILABLE(macos(10.14.0))
 | |
| +@interface _WKBrowserContext : NSObject
 | |
| +@property (nonatomic, strong) WKWebsiteDataStore *dataStore;
 | |
| +@property (nonatomic, strong) WKProcessPool *processPool;
 | |
| +@end
 | |
| +
 | |
| +@protocol _WKBrowserInspectorDelegate <NSObject>
 | |
| +- (WKWebView *)createNewPage:(uint64_t)sessionID;
 | |
| +- (_WKBrowserContext *)createBrowserContext:(NSString *)proxyServer WithBypassList:(NSString *)proxyBypassList;
 | |
| +- (void)deleteBrowserContext:(uint64_t)sessionID;
 | |
| +- (void)quit;
 | |
| +@end
 | |
| +
 | |
| +WK_CLASS_AVAILABLE(macos(10.14.0))
 | |
| +@interface _WKBrowserInspector : NSObject
 | |
| ++ (void)initializeRemoteInspectorPipe:(id<_WKBrowserInspectorDelegate>)delegate headless:(BOOL)headless;
 | |
| +@end
 | |
| +
 | |
| +
 | |
| +NS_ASSUME_NONNULL_END
 | |
| +
 | |
| diff --git a/Source/WebKit/UIProcess/API/Cocoa/_WKBrowserInspector.mm b/Source/WebKit/UIProcess/API/Cocoa/_WKBrowserInspector.mm
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..e7143513ea2be8e1cdab5c86a28643fffea626dd
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/UIProcess/API/Cocoa/_WKBrowserInspector.mm
 | |
| @@ -0,0 +1,60 @@
 | |
| +/*
 | |
| + * Copyright (C) 2019 Microsoft Corporation.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
| + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#include "config.h"
 | |
| +#include "_WKBrowserInspector.h"
 | |
| +
 | |
| +#include "BrowserInspectorPipe.h"
 | |
| +#include "InspectorPlaywrightAgentClientMac.h"
 | |
| +#include "PageClientImplMac.h"
 | |
| +#include "WebKit2Initialize.h"
 | |
| +
 | |
| +#import "WKWebView.h"
 | |
| +
 | |
| +using namespace WebKit;
 | |
| +
 | |
| +@implementation _WKBrowserInspector
 | |
| +
 | |
| ++ (void)initializeRemoteInspectorPipe:(id<_WKBrowserInspectorDelegate>)delegate headless:(BOOL)headless
 | |
| +{
 | |
| +#if ENABLE(REMOTE_INSPECTOR)
 | |
| +    InitializeWebKit2();
 | |
| +    PageClientImpl::setHeadless(headless);
 | |
| +    initializeBrowserInspectorPipe(makeUnique<InspectorPlaywrightAgentClientMac>(delegate));
 | |
| +#endif
 | |
| +}
 | |
| +
 | |
| +@end
 | |
| +
 | |
| +@implementation _WKBrowserContext
 | |
| +- (void)dealloc
 | |
| +{
 | |
| +    [_dataStore release];
 | |
| +    [_processPool release];
 | |
| +    _dataStore = nil;
 | |
| +    _processPool = nil;
 | |
| +    [super dealloc];
 | |
| +}
 | |
| +@end
 | |
| diff --git a/Source/WebKit/UIProcess/API/Cocoa/_WKDownload.mm b/Source/WebKit/UIProcess/API/Cocoa/_WKDownload.mm
 | |
| index f585618b83609aa3664cc248ee1aa56ed35221a5..96bfd6a709a4ca6bc5a76abc5d98323ef8a5bf07 100644
 | |
| --- a/Source/WebKit/UIProcess/API/Cocoa/_WKDownload.mm
 | |
| +++ b/Source/WebKit/UIProcess/API/Cocoa/_WKDownload.mm
 | |
| @@ -32,6 +32,7 @@
 | |
|  #import "WKFrameInfoInternal.h"
 | |
|  #import "WKNSData.h"
 | |
|  #import "WKWebViewInternal.h"
 | |
| +#import <wtf/cocoa/VectorCocoa.h>
 | |
|  #import <wtf/WeakObjCPtr.h>
 | |
|  #import <wtf/cocoa/VectorCocoa.h>
 | |
|  
 | |
| diff --git a/Source/WebKit/UIProcess/API/Cocoa/_WKDownloadInternal.h b/Source/WebKit/UIProcess/API/Cocoa/_WKDownloadInternal.h
 | |
| index b1c6e033c8a86353f96161482d92c227d7946201..64e592705c97d2d78668aa532f271ddf83ed4c9a 100644
 | |
| --- a/Source/WebKit/UIProcess/API/Cocoa/_WKDownloadInternal.h
 | |
| +++ b/Source/WebKit/UIProcess/API/Cocoa/_WKDownloadInternal.h
 | |
| @@ -24,6 +24,7 @@
 | |
|   */
 | |
|  
 | |
|  #import "_WKDownload.h"
 | |
| +#import "WKObject.h"
 | |
|  
 | |
|  #import "WKObject.h"
 | |
|  #import <wtf/RetainPtr.h>
 | |
| diff --git a/Source/WebKit/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.h b/Source/WebKit/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.h
 | |
| index a4b6d757e066334af98dec218ac52261b9d5ccd8..2c2e3c70b4bb9a4ddcd2ba2afd5af842d9b59eb6 100644
 | |
| --- a/Source/WebKit/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.h
 | |
| +++ b/Source/WebKit/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.h
 | |
| @@ -67,6 +67,7 @@ WK_CLASS_AVAILABLE(macos(10.10), ios(8.0))
 | |
|  @property (nonatomic) pid_t presentingApplicationPID WK_API_AVAILABLE(macos(10.13), ios(11.0));
 | |
|  @property (nonatomic) audit_token_t presentingApplicationProcessToken WK_API_AVAILABLE(macos(10.13), ios(11.3));
 | |
|  @property (nonatomic) BOOL processSwapsOnNavigation WK_API_AVAILABLE(macos(10.14), ios(12.0));
 | |
| +@property (nonatomic) BOOL forceOverlayScrollbars WK_API_AVAILABLE(macos(10.14));
 | |
|  @property (nonatomic) BOOL alwaysKeepAndReuseSwappedProcesses WK_API_AVAILABLE(macos(10.14), ios(12.0));
 | |
|  @property (nonatomic) BOOL processSwapsOnWindowOpenWithOpener WK_API_AVAILABLE(macos(10.14), ios(12.0));
 | |
|  @property (nonatomic) BOOL processSwapsOnNavigationWithinSameNonHTTPFamilyProtocol WK_API_AVAILABLE(macos(12.0), ios(15.0));
 | |
| diff --git a/Source/WebKit/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.mm b/Source/WebKit/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.mm
 | |
| index cb7445b7fe814feff50a14b8dd25f5a32f70a17d..d6d2b2d5ed41ffda551e47dd14801c0e036a0890 100644
 | |
| --- a/Source/WebKit/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.mm
 | |
| +++ b/Source/WebKit/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.mm
 | |
| @@ -257,6 +257,16 @@
 | |
|      return _processPoolConfiguration->processSwapsOnNavigation();
 | |
|  }
 | |
|  
 | |
| +- (void)setForceOverlayScrollbars:(BOOL)force
 | |
| +{
 | |
| +    _processPoolConfiguration->setForceOverlayScrollbars(force);
 | |
| +}
 | |
| +
 | |
| +- (BOOL)forceOverlayScrollbars
 | |
| +{
 | |
| +    return _processPoolConfiguration->forceOverlayScrollbars();
 | |
| +}
 | |
| +
 | |
|  - (void)setPrewarmsProcessesAutomatically:(BOOL)prewarms
 | |
|  {
 | |
|      _processPoolConfiguration->setIsAutomaticProcessWarmingEnabled(prewarms);
 | |
| diff --git a/Source/WebKit/UIProcess/API/Cocoa/_WKRemoteWebInspectorViewController.mm b/Source/WebKit/UIProcess/API/Cocoa/_WKRemoteWebInspectorViewController.mm
 | |
| index 37fc2ad398dfb9a821b381308e901d194dfea05a..17bd960aa28eec80ed78878a76f32a45d238ab04 100644
 | |
| --- a/Source/WebKit/UIProcess/API/Cocoa/_WKRemoteWebInspectorViewController.mm
 | |
| +++ b/Source/WebKit/UIProcess/API/Cocoa/_WKRemoteWebInspectorViewController.mm
 | |
| @@ -24,6 +24,7 @@
 | |
|   */
 | |
|  
 | |
|  #import "config.h"
 | |
| +#import "WKWebViewPrivate.h"
 | |
|  #import "_WKRemoteWebInspectorViewControllerInternal.h"
 | |
|  
 | |
|  #if PLATFORM(MAC)
 | |
| diff --git a/Source/WebKit/UIProcess/API/Cocoa/_WKUserStyleSheet.h b/Source/WebKit/UIProcess/API/Cocoa/_WKUserStyleSheet.h
 | |
| index 4974e14214e2bb3e982325b885bab33e54f83998..cacdf8c71fab248d38d2faf03f7affdcfed1ef62 100644
 | |
| --- a/Source/WebKit/UIProcess/API/Cocoa/_WKUserStyleSheet.h
 | |
| +++ b/Source/WebKit/UIProcess/API/Cocoa/_WKUserStyleSheet.h
 | |
| @@ -31,6 +31,7 @@ NS_ASSUME_NONNULL_BEGIN
 | |
|  @class _WKUserContentWorld;
 | |
|  @class WKContentWorld;
 | |
|  @class WKWebView;
 | |
| +@class WKContentWorld;
 | |
|  
 | |
|  typedef NS_ENUM(NSInteger, _WKUserStyleLevel) {
 | |
|      _WKUserStyleUserLevel,
 | |
| diff --git a/Source/WebKit/UIProcess/API/Cocoa/_WKUserStyleSheet.mm b/Source/WebKit/UIProcess/API/Cocoa/_WKUserStyleSheet.mm
 | |
| index 1e827013c603ae8bd43d798170deb98fc3153852..2075bc78069bde530ec237c0b761773c10013948 100644
 | |
| --- a/Source/WebKit/UIProcess/API/Cocoa/_WKUserStyleSheet.mm
 | |
| +++ b/Source/WebKit/UIProcess/API/Cocoa/_WKUserStyleSheet.mm
 | |
| @@ -35,6 +35,7 @@
 | |
|  #import "WebPageProxy.h"
 | |
|  #import "_WKUserContentWorldInternal.h"
 | |
|  #import <WebCore/WebCoreObjCExtras.h>
 | |
| +#import <WebKit/WKContentWorldInternal.h>
 | |
|  #import <wtf/cocoa/VectorCocoa.h>
 | |
|  
 | |
|  @implementation _WKUserStyleSheet
 | |
| diff --git a/Source/WebKit/UIProcess/API/glib/WebKitBrowserInspector.cpp b/Source/WebKit/UIProcess/API/glib/WebKitBrowserInspector.cpp
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..575245fc1f279a75f7e74c26652cf772a2fc95b7
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/UIProcess/API/glib/WebKitBrowserInspector.cpp
 | |
| @@ -0,0 +1,158 @@
 | |
| +/*
 | |
| + * Copyright (C) 2019 Microsoft Corporation.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
| + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#include "config.h"
 | |
| +#include "WebKitBrowserInspector.h"
 | |
| +
 | |
| +#include "BrowserInspectorPipe.h"
 | |
| +#include "InspectorPlaywrightAgentClientGLib.h"
 | |
| +#include "WebKitBrowserInspectorPrivate.h"
 | |
| +#include "WebKitWebViewPrivate.h"
 | |
| +#include <wtf/glib/GRefPtr.h>
 | |
| +#include <wtf/glib/WTFGType.h>
 | |
| +
 | |
| +/**
 | |
| + * SECTION: WebKitBrowserInspector
 | |
| + * @Short_description: Access to the WebKit browser inspector
 | |
| + * @Title: WebKitBrowserInspector
 | |
| + *
 | |
| + * The WebKit Browser Inspector is an experimental API that provides
 | |
| + * access to the inspector via the remote debugging protocol. The protocol
 | |
| + * allows to create ephemeral contexts and create pages in them and then
 | |
| + * manipulate them using the inspector commands. This may be useful for
 | |
| + * the browser automation or remote debugging.
 | |
| + *
 | |
| + * Currently the protocol can be exposed to the parent process via a unix
 | |
| + * pipe.
 | |
| + */
 | |
| +
 | |
| +enum {
 | |
| +    CREATE_NEW_PAGE,
 | |
| +    QUIT_APPLICATION,
 | |
| +
 | |
| +    LAST_SIGNAL
 | |
| +};
 | |
| +
 | |
| +struct _WebKitBrowserInspectorPrivate {
 | |
| +    int unused { 0 };
 | |
| +};
 | |
| +
 | |
| +WEBKIT_DEFINE_TYPE(WebKitBrowserInspector, webkit_browser_inspector, G_TYPE_OBJECT)
 | |
| +
 | |
| +static guint signals[LAST_SIGNAL] = { 0, };
 | |
| +
 | |
| +static void webkit_browser_inspector_class_init(WebKitBrowserInspectorClass* findClass)
 | |
| +{
 | |
| +    GObjectClass* gObjectClass = G_OBJECT_CLASS(findClass);
 | |
| +
 | |
| +    /**
 | |
| +     * WebKitBrowserInspector::create-new-page:
 | |
| +     * @inspector: the #WebKitBrowserInspector on which the signal is emitted
 | |
| +     *
 | |
| +     * Emitted when the inspector is requested to create a new page in the provided
 | |
| +     * #WebKitWebContext.
 | |
| +     *
 | |
| +     * This signal is emitted when inspector receives 'Browser.createPage' command
 | |
| +     * from its remote client. If the signal is not handled the command will fail.
 | |
| +     *
 | |
| +     * Returns: %WebKitWebView that contains created page.
 | |
| +     */
 | |
| +    signals[CREATE_NEW_PAGE] = g_signal_new(
 | |
| +        "create-new-page",
 | |
| +        G_TYPE_FROM_CLASS(gObjectClass),
 | |
| +        G_SIGNAL_RUN_LAST,
 | |
| +        G_STRUCT_OFFSET(WebKitBrowserInspectorClass, create_new_page),
 | |
| +        nullptr, nullptr,
 | |
| +        g_cclosure_marshal_generic,
 | |
| +#if PLATFORM(GTK)
 | |
| +        GTK_TYPE_WIDGET,
 | |
| +#else
 | |
| +        WEBKIT_TYPE_WEB_VIEW,
 | |
| +#endif
 | |
| +        1,
 | |
| +        WEBKIT_TYPE_WEB_CONTEXT);
 | |
| +
 | |
| +    /**
 | |
| +     * WebKitBrowserInspector::quit-application:
 | |
| +     * @inspector: the #WebKitBrowserInspector on which the signal is emitted
 | |
| +     *
 | |
| +     * Emitted when the inspector is requested to close the browser application.
 | |
| +     *
 | |
| +     * This signal is emitted when inspector receives 'Browser.close' command
 | |
| +     * from its remote client. If the signal is not handled the command will fail.
 | |
| +     */
 | |
| +    signals[QUIT_APPLICATION] = g_signal_new(
 | |
| +        "quit-application",
 | |
| +        G_TYPE_FROM_CLASS(gObjectClass),
 | |
| +        G_SIGNAL_RUN_LAST,
 | |
| +        G_STRUCT_OFFSET(WebKitBrowserInspectorClass, quit_application),
 | |
| +        nullptr, nullptr,
 | |
| +        g_cclosure_marshal_VOID__VOID,
 | |
| +        G_TYPE_NONE, 0);
 | |
| +}
 | |
| +
 | |
| +WebKit::WebPageProxy* webkitBrowserInspectorCreateNewPageInContext(WebKitWebContext* context)
 | |
| +{
 | |
| +    WebKitWebView* newWebView;
 | |
| +    g_signal_emit(webkit_browser_inspector_get_default(), signals[CREATE_NEW_PAGE], 0, context, &newWebView);
 | |
| +    if (!newWebView)
 | |
| +        return nullptr;
 | |
| +    return  &webkitWebViewGetPage(newWebView);
 | |
| +}
 | |
| +
 | |
| +void webkitBrowserInspectorQuitApplication()
 | |
| +{
 | |
| +    g_signal_emit(webkit_browser_inspector_get_default(), signals[QUIT_APPLICATION], 0, NULL);
 | |
| +}
 | |
| +
 | |
| +static gpointer createWebKitBrowserInspector(gpointer)
 | |
| +{
 | |
| +    static GRefPtr<WebKitBrowserInspector> browserInspector = adoptGRef(WEBKIT_BROWSER_INSPECTOR(g_object_new(WEBKIT_TYPE_BROWSER_INSPECTOR, nullptr)));
 | |
| +    return browserInspector.get();
 | |
| +}
 | |
| +
 | |
| +/**
 | |
| + * webkit_browser_inspector_get_default:
 | |
| + *
 | |
| + * Gets the default instance of the browser inspector.
 | |
| + *
 | |
| + * Returns: (transfer none): a #WebKitBrowserInspector
 | |
| + */
 | |
| +WebKitBrowserInspector* webkit_browser_inspector_get_default(void)
 | |
| +{
 | |
| +    static GOnce onceInit = G_ONCE_INIT;
 | |
| +    return WEBKIT_BROWSER_INSPECTOR(g_once(&onceInit, createWebKitBrowserInspector, 0));
 | |
| +}
 | |
| +
 | |
| +/**
 | |
| + * webkit_browser_inspector_initialize_pipe:
 | |
| + *
 | |
| + * Creates browser inspector and configures pipe handler to communicate with
 | |
| + * the parent process.
 | |
| + */
 | |
| +void webkit_browser_inspector_initialize_pipe(const char* defaultProxyURI, const char* const* ignoreHosts)
 | |
| +{
 | |
| +    WebKit::initializeBrowserInspectorPipe(makeUnique<WebKit::InspectorPlaywrightAgentClientGlib>(String::fromUTF8(defaultProxyURI), ignoreHosts));
 | |
| +}
 | |
| diff --git a/Source/WebKit/UIProcess/API/glib/WebKitBrowserInspectorPrivate.h b/Source/WebKit/UIProcess/API/glib/WebKitBrowserInspectorPrivate.h
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..e0b1da48465c850f541532ed961d1b778bea6028
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/UIProcess/API/glib/WebKitBrowserInspectorPrivate.h
 | |
| @@ -0,0 +1,32 @@
 | |
| +/*
 | |
| + * Copyright (C) 2019 Microsoft Corporation.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
| + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#pragma once
 | |
| +
 | |
| +#include "WebKitBrowserInspector.h"
 | |
| +#include "WebPageProxy.h"
 | |
| +
 | |
| +WebKit::WebPageProxy* webkitBrowserInspectorCreateNewPageInContext(WebKitWebContext*);
 | |
| +void webkitBrowserInspectorQuitApplication();
 | |
| diff --git a/Source/WebKit/UIProcess/API/glib/WebKitUIClient.cpp b/Source/WebKit/UIProcess/API/glib/WebKitUIClient.cpp
 | |
| index 64c90f9f25fc44911e819ab94fa973bf0b82a0e4..8d8c739fb903b71f7881801cb41901f241709b2a 100644
 | |
| --- a/Source/WebKit/UIProcess/API/glib/WebKitUIClient.cpp
 | |
| +++ b/Source/WebKit/UIProcess/API/glib/WebKitUIClient.cpp
 | |
| @@ -98,6 +98,10 @@ private:
 | |
|          page.makeViewBlankIfUnpaintedSinceLastLoadCommit();
 | |
|          webkitWebViewRunJavaScriptPrompt(m_webView, message.utf8(), defaultValue.utf8(), WTFMove(completionHandler));
 | |
|      }
 | |
| +    void handleJavaScriptDialog(WebPageProxy&, bool accept, const String& value) final
 | |
| +    {
 | |
| +        webkitWebViewHandleJavaScriptDialog(m_webView, accept, value);
 | |
| +    }
 | |
|  
 | |
|      bool canRunBeforeUnloadConfirmPanel() const final { return true; }
 | |
|  
 | |
| diff --git a/Source/WebKit/UIProcess/API/glib/WebKitWebContext.cpp b/Source/WebKit/UIProcess/API/glib/WebKitWebContext.cpp
 | |
| index 7f7851e154385e2f5cc6b104fabfd596f0ae4621..a70a012dbd1cbea18fbe61debfbe82bb79586b3f 100644
 | |
| --- a/Source/WebKit/UIProcess/API/glib/WebKitWebContext.cpp
 | |
| +++ b/Source/WebKit/UIProcess/API/glib/WebKitWebContext.cpp
 | |
| @@ -403,10 +403,19 @@ static void webkitWebContextSetProperty(GObject* object, guint propID, const GVa
 | |
|      }
 | |
|  }
 | |
|  
 | |
| +static int webkitWebContext = 0;
 | |
| +
 | |
| +int webkitWebContextExistingCount()
 | |
| +{
 | |
| +    return webkitWebContext;
 | |
| +}
 | |
| +
 | |
|  static void webkitWebContextConstructed(GObject* object)
 | |
|  {
 | |
|      G_OBJECT_CLASS(webkit_web_context_parent_class)->constructed(object);
 | |
|  
 | |
| +    ++webkitWebContext;
 | |
| +
 | |
|      GUniquePtr<char> bundleFilename(g_build_filename(injectedBundleDirectory(), INJECTED_BUNDLE_FILENAME, nullptr));
 | |
|  
 | |
|      WebKitWebContext* webContext = WEBKIT_WEB_CONTEXT(object);
 | |
| @@ -459,6 +468,8 @@ static void webkitWebContextConstructed(GObject* object)
 | |
|  
 | |
|  static void webkitWebContextDispose(GObject* object)
 | |
|  {
 | |
| +    --webkitWebContext;
 | |
| +
 | |
|      WebKitWebContextPrivate* priv = WEBKIT_WEB_CONTEXT(object)->priv;
 | |
|      if (!priv->clientsDetached) {
 | |
|          priv->clientsDetached = true;
 | |
| diff --git a/Source/WebKit/UIProcess/API/glib/WebKitWebContextPrivate.h b/Source/WebKit/UIProcess/API/glib/WebKitWebContextPrivate.h
 | |
| index 78d1578f94793e9e59a3d4d2b33e79ea8530fa04..493cdadac3873508b3efa3048638e73a13f4c976 100644
 | |
| --- a/Source/WebKit/UIProcess/API/glib/WebKitWebContextPrivate.h
 | |
| +++ b/Source/WebKit/UIProcess/API/glib/WebKitWebContextPrivate.h
 | |
| @@ -45,3 +45,4 @@ void webkitWebContextInitializeNotificationPermissions(WebKitWebContext*);
 | |
|  #if ENABLE(REMOTE_INSPECTOR)
 | |
|  void webkitWebContextWillCloseAutomationSession(WebKitWebContext*);
 | |
|  #endif
 | |
| +int webkitWebContextExistingCount();
 | |
| diff --git a/Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp b/Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp
 | |
| index 484239165b6dd5352906e7741d17fd508b465bc9..fbff73e2aa3847c5ab1a7d0a2fe728b4b93b84e0 100644
 | |
| --- a/Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp
 | |
| +++ b/Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp
 | |
| @@ -32,6 +32,7 @@
 | |
|  #include "WebCertificateInfo.h"
 | |
|  #include "WebContextMenuItem.h"
 | |
|  #include "WebContextMenuItemData.h"
 | |
| +#include "WebPageInspectorController.h"
 | |
|  #include "WebKitAuthenticationRequestPrivate.h"
 | |
|  #include "WebKitBackForwardListPrivate.h"
 | |
|  #include "WebKitContextMenuClient.h"
 | |
| @@ -51,6 +52,7 @@
 | |
|  #include "WebKitJavascriptResultPrivate.h"
 | |
|  #include "WebKitNavigationClient.h"
 | |
|  #include "WebKitNotificationPrivate.h"
 | |
| +#include "WebKitPointerLockPermissionRequest.h"
 | |
|  #include "WebKitPrivate.h"
 | |
|  #include "WebKitResponsePolicyDecision.h"
 | |
|  #include "WebKitScriptDialogPrivate.h"
 | |
| @@ -85,7 +87,6 @@
 | |
|  
 | |
|  #if PLATFORM(GTK)
 | |
|  #include "WebKitInputMethodContextImplGtk.h"
 | |
| -#include "WebKitPointerLockPermissionRequest.h"
 | |
|  #include "WebKitPrintOperationPrivate.h"
 | |
|  #include "WebKitWebInspectorPrivate.h"
 | |
|  #include "WebKitWebViewBasePrivate.h"
 | |
| @@ -133,6 +134,7 @@ enum {
 | |
|      CLOSE,
 | |
|  
 | |
|      SCRIPT_DIALOG,
 | |
| +    SCRIPT_DIALOG_HANDLED,
 | |
|  
 | |
|      DECIDE_POLICY,
 | |
|      PERMISSION_REQUEST,
 | |
| @@ -465,6 +467,9 @@ void WebKitWebViewClient::handleDownloadRequest(WKWPE::View&, DownloadProxy& dow
 | |
|  
 | |
|  void WebKitWebViewClient::frameDisplayed(WKWPE::View&)
 | |
|  {
 | |
| +    if (RefPtr<cairo_surface_t> surface = adoptRef(webkitWebViewBackendTakeScreenshot(m_webView->priv->backend.get())))
 | |
| +        getPage(m_webView).inspectorController().didPaint(surface.get());
 | |
| +
 | |
|      {
 | |
|          SetForScope inFrameDisplayedGuard(m_webView->priv->inFrameDisplayed, true);
 | |
|          for (const auto& callback : m_webView->priv->frameDisplayedCallbacks) {
 | |
| @@ -495,6 +500,7 @@ void WebKitWebViewClient::didReceiveUserMessage(WKWPE::View&, UserMessage&& mess
 | |
|  {
 | |
|      webkitWebViewDidReceiveUserMessage(m_webView, WTFMove(message), WTFMove(completionHandler));
 | |
|  }
 | |
| +
 | |
|  #endif
 | |
|  
 | |
|  static gboolean webkitWebViewLoadFail(WebKitWebView* webView, WebKitLoadEvent, const char* failingURI, GError* error)
 | |
| @@ -546,7 +552,7 @@ static gboolean webkitWebViewDecidePolicy(WebKitWebView*, WebKitPolicyDecision*
 | |
|  
 | |
|  static gboolean webkitWebViewPermissionRequest(WebKitWebView*, WebKitPermissionRequest* request)
 | |
|  {
 | |
| -#if ENABLE(POINTER_LOCK)
 | |
| +#if ENABLE(POINTER_LOCK) && PLATFORM(GTK)
 | |
|      if (WEBKIT_IS_POINTER_LOCK_PERMISSION_REQUEST(request)) {
 | |
|          webkit_permission_request_allow(request);
 | |
|          return TRUE;
 | |
| @@ -1722,6 +1728,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
 | |
| @@ -2554,6 +2569,23 @@ void webkitWebViewRunJavaScriptBeforeUnloadConfirm(WebKitWebView* webView, const
 | |
|      webkit_script_dialog_unref(webView->priv->currentScriptDialog);
 | |
|  }
 | |
|  
 | |
| +void webkitWebViewHandleJavaScriptDialog(WebKitWebView* webView, bool accept, const String& value) {
 | |
| +    auto* dialog = webView->priv->currentScriptDialog;
 | |
| +#if PLATFORM(WPE)
 | |
| +    dialog->isUserHandled = false;
 | |
| +#endif
 | |
| +    webkit_script_dialog_ref(dialog);
 | |
| +    if (!value.isNull())
 | |
| +        webkitWebViewSetCurrentScriptDialogUserInput(webView, value);
 | |
| +    if (accept)
 | |
| +        webkitWebViewAcceptCurrentScriptDialog(webView);
 | |
| +    else
 | |
| +        webkitWebViewDismissCurrentScriptDialog(webView);
 | |
| +    gboolean returnValue;
 | |
| +    g_signal_emit(webView, signals[SCRIPT_DIALOG_HANDLED], 0, dialog, &returnValue);
 | |
| +    webkit_script_dialog_unref(dialog);
 | |
| +}
 | |
| +
 | |
|  bool webkitWebViewIsShowingScriptDialog(WebKitWebView* webView)
 | |
|  {
 | |
|      if (!webView->priv->currentScriptDialog)
 | |
| diff --git a/Source/WebKit/UIProcess/API/glib/WebKitWebViewPrivate.h b/Source/WebKit/UIProcess/API/glib/WebKitWebViewPrivate.h
 | |
| index fbab1afe9ca09f5e6a6793f5065f08fc76bfedaf..23f66f4da6229d88271e4b732414088b7cc0397e 100644
 | |
| --- a/Source/WebKit/UIProcess/API/glib/WebKitWebViewPrivate.h
 | |
| +++ b/Source/WebKit/UIProcess/API/glib/WebKitWebViewPrivate.h
 | |
| @@ -60,6 +60,7 @@ void webkitWebViewRunJavaScriptAlert(WebKitWebView*, const CString& message, Fun
 | |
|  void webkitWebViewRunJavaScriptConfirm(WebKitWebView*, const CString& message, Function<void(bool)>&& completionHandler);
 | |
|  void webkitWebViewRunJavaScriptPrompt(WebKitWebView*, const CString& message, const CString& defaultText, Function<void(const String&)>&& completionHandler);
 | |
|  void webkitWebViewRunJavaScriptBeforeUnloadConfirm(WebKitWebView*, const CString& message, Function<void(bool)>&& completionHandler);
 | |
| +void webkitWebViewHandleJavaScriptDialog(WebKitWebView*, bool accept, const String& value);
 | |
|  bool webkitWebViewIsShowingScriptDialog(WebKitWebView*);
 | |
|  bool webkitWebViewIsScriptDialogRunning(WebKitWebView*, WebKitScriptDialog*);
 | |
|  String webkitWebViewGetCurrentScriptDialogMessage(WebKitWebView*);
 | |
| diff --git a/Source/WebKit/UIProcess/API/gtk/PageClientImpl.cpp b/Source/WebKit/UIProcess/API/gtk/PageClientImpl.cpp
 | |
| index 5a44624f8d2fc8fb7f8871c97c8ffd3cd73c3b5e..39751c87230dee3e800b8c1c8a54fbe86efc5b3f 100644
 | |
| --- a/Source/WebKit/UIProcess/API/gtk/PageClientImpl.cpp
 | |
| +++ b/Source/WebKit/UIProcess/API/gtk/PageClientImpl.cpp
 | |
| @@ -252,6 +252,8 @@ void PageClientImpl::doneWithKeyEvent(const NativeWebKeyboardEvent& event, bool
 | |
|  {
 | |
|      if (wasEventHandled || event.type() != WebEvent::Type::KeyDown || !event.nativeEvent())
 | |
|          return;
 | |
| +    if (!event.nativeEvent())
 | |
| +        return;
 | |
|  
 | |
|      WebKitWebViewBase* webkitWebViewBase = WEBKIT_WEB_VIEW_BASE(m_viewWidget);
 | |
|      webkitWebViewBaseForwardNextKeyEvent(webkitWebViewBase);
 | |
| diff --git a/Source/WebKit/UIProcess/API/gtk/WebKitBrowserInspector.h b/Source/WebKit/UIProcess/API/gtk/WebKitBrowserInspector.h
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..9f1a0173a5641d6f158d815b8f7b9ea66f65c26d
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/UIProcess/API/gtk/WebKitBrowserInspector.h
 | |
| @@ -0,0 +1,81 @@
 | |
| +/*
 | |
| + * Copyright (C) 2019 Microsoft Corporation.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
| + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION)
 | |
| +#error "Only <webkit2/webkit2.h> can be included directly."
 | |
| +#endif
 | |
| +
 | |
| +#ifndef WebKitBrowserInspector_h
 | |
| +#define WebKitBrowserInspector_h
 | |
| +
 | |
| +#include <glib-object.h>
 | |
| +#include <webkit2/WebKitDefines.h>
 | |
| +#include <webkit2/WebKitWebView.h>
 | |
| +
 | |
| +G_BEGIN_DECLS
 | |
| +
 | |
| +#define WEBKIT_TYPE_BROWSER_INSPECTOR            (webkit_browser_inspector_get_type())
 | |
| +#define WEBKIT_BROWSER_INSPECTOR(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_BROWSER_INSPECTOR, WebKitBrowserInspector))
 | |
| +#define WEBKIT_IS_BROWSER_INSPECTOR(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_BROWSER_INSPECTOR))
 | |
| +#define WEBKIT_BROWSER_INSPECTOR_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass),  WEBKIT_TYPE_BROWSER_INSPECTOR, WebKitBrowserInspectorClass))
 | |
| +#define WEBKIT_IS_BROWSER_INSPECTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),  WEBKIT_TYPE_BROWSER_INSPECTOR))
 | |
| +#define WEBKIT_BROWSER_INSPECTOR_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj),  WEBKIT_TYPE_BROWSER_INSPECTOR, WebKitBrowserInspectorClass))
 | |
| +
 | |
| +typedef struct _WebKitBrowserInspector        WebKitBrowserInspector;
 | |
| +typedef struct _WebKitBrowserInspectorClass   WebKitBrowserInspectorClass;
 | |
| +typedef struct _WebKitBrowserInspectorPrivate WebKitBrowserInspectorPrivate;
 | |
| +
 | |
| +struct _WebKitBrowserInspector {
 | |
| +    GObject parent;
 | |
| +
 | |
| +    WebKitBrowserInspectorPrivate *priv;
 | |
| +};
 | |
| +
 | |
| +struct _WebKitBrowserInspectorClass {
 | |
| +    GObjectClass parent_class;
 | |
| +
 | |
| +    WebKitWebView *(* create_new_page)           (WebKitBrowserInspector    *browser_inspector,
 | |
| +                                                  WebKitWebContext          *context);
 | |
| +    WebKitWebView *(* quit_application)          (WebKitBrowserInspector    *browser_inspector);
 | |
| +
 | |
| +    void (*_webkit_reserved0) (void);
 | |
| +    void (*_webkit_reserved1) (void);
 | |
| +    void (*_webkit_reserved2) (void);
 | |
| +    void (*_webkit_reserved3) (void);
 | |
| +};
 | |
| +
 | |
| +WEBKIT_API GType
 | |
| +webkit_browser_inspector_get_type                     (void);
 | |
| +
 | |
| +WEBKIT_API WebKitBrowserInspector *
 | |
| +webkit_browser_inspector_get_default                  (void);
 | |
| +
 | |
| +WEBKIT_API void
 | |
| +webkit_browser_inspector_initialize_pipe              (const char* defaultProxyURI,
 | |
| +                                                       const char* const* ignoreHosts);
 | |
| +
 | |
| +G_END_DECLS
 | |
| +
 | |
| +#endif
 | |
| diff --git a/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBase.cpp b/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBase.cpp
 | |
| index 54293e7e4c923eafb2459c243cc9a3913e970e3f..f7a16a553798b0608371cb9a4aade2c0ccb00114 100644
 | |
| --- a/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBase.cpp
 | |
| +++ b/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBase.cpp
 | |
| @@ -2558,6 +2558,11 @@ void webkitWebViewBaseResetClickCounter(WebKitWebViewBase* webkitWebViewBase)
 | |
|  #endif
 | |
|  }
 | |
|  
 | |
| +WebKit::AcceleratedBackingStore* webkitWebViewBaseGetAcceleratedBackingStore(WebKitWebViewBase* webkitWebViewBase)
 | |
| +{
 | |
| +    return webkitWebViewBase->priv->acceleratedBackingStore.get();
 | |
| +}
 | |
| +
 | |
|  void webkitWebViewBaseEnterAcceleratedCompositingMode(WebKitWebViewBase* webkitWebViewBase, const LayerTreeContext& layerTreeContext)
 | |
|  {
 | |
|      ASSERT(webkitWebViewBase->priv->acceleratedBackingStore);
 | |
| diff --git a/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBasePrivate.h b/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBasePrivate.h
 | |
| index b60e10c4fb1c6c867579b58661a6e3f017ba81b0..3f8ec4479449e9cc1e3b2503ba2e3e352e329d84 100644
 | |
| --- a/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBasePrivate.h
 | |
| +++ b/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBasePrivate.h
 | |
| @@ -27,6 +27,7 @@
 | |
|  
 | |
|  #pragma once
 | |
|  
 | |
| +#include "AcceleratedBackingStore.h"
 | |
|  #include "APIPageConfiguration.h"
 | |
|  #include "InputMethodState.h"
 | |
|  #include "SameDocumentNavigationType.h"
 | |
| @@ -122,3 +123,5 @@ void webkitWebViewBaseSynthesizeWheelEvent(WebKitWebViewBase*, const GdkEvent*,
 | |
|  void webkitWebViewBaseMakeBlank(WebKitWebViewBase*, bool);
 | |
|  void webkitWebViewBasePageGrabbedTouch(WebKitWebViewBase*);
 | |
|  void webkitWebViewBaseSetShouldNotifyFocusEvents(WebKitWebViewBase*, bool);
 | |
| +
 | |
| +WebKit::AcceleratedBackingStore* webkitWebViewBaseGetAcceleratedBackingStore(WebKitWebViewBase*);
 | |
| diff --git a/Source/WebKit/UIProcess/API/gtk/webkit2.h b/Source/WebKit/UIProcess/API/gtk/webkit2.h
 | |
| index 5cd9524252a97d4ea64dfeb22e5a47b55f36c887..45da62b4ffe54d5cfd680dd40cabd6f45bc993a6 100644
 | |
| --- a/Source/WebKit/UIProcess/API/gtk/webkit2.h
 | |
| +++ b/Source/WebKit/UIProcess/API/gtk/webkit2.h
 | |
| @@ -32,6 +32,7 @@
 | |
|  #include <webkit2/WebKitAutomationSession.h>
 | |
|  #include <webkit2/WebKitBackForwardList.h>
 | |
|  #include <webkit2/WebKitBackForwardListItem.h>
 | |
| +#include <webkit2/WebKitBrowserInspector.h>
 | |
|  #include <webkit2/WebKitColorChooserRequest.h>
 | |
|  #include <webkit2/WebKitContextMenu.h>
 | |
|  #include <webkit2/WebKitContextMenuActions.h>
 | |
| diff --git a/Source/WebKit/UIProcess/API/wpe/PageClientImpl.cpp b/Source/WebKit/UIProcess/API/wpe/PageClientImpl.cpp
 | |
| index cfe3689f22c6659ceab3950e40b686e9b97b4254..d2de92105afecd8e1a5ffb6de16965aad74c71a0 100644
 | |
| --- a/Source/WebKit/UIProcess/API/wpe/PageClientImpl.cpp
 | |
| +++ b/Source/WebKit/UIProcess/API/wpe/PageClientImpl.cpp
 | |
| @@ -32,8 +32,11 @@
 | |
|  #include "NativeWebWheelEvent.h"
 | |
|  #include "TouchGestureController.h"
 | |
|  #include "WPEView.h"
 | |
| +#include "WebColorPickerWPE.h"
 | |
| +#include "WebDateTimePickerWPE.h"
 | |
|  #include "WebContextMenuProxy.h"
 | |
|  #include "WebContextMenuProxyWPE.h"
 | |
| +#include "WebKitDataListSuggestionsDropdown.h"
 | |
|  #include "WebKitPopupMenu.h"
 | |
|  #include <WebCore/ActivityState.h>
 | |
|  #include <WebCore/DOMPasteAccess.h>
 | |
| @@ -194,7 +197,7 @@ WebCore::IntPoint PageClientImpl::accessibilityScreenToRootView(const WebCore::I
 | |
|  
 | |
|  WebCore::IntRect PageClientImpl::rootViewToAccessibilityScreen(const WebCore::IntRect& rect)
 | |
|  {
 | |
| -    return rootViewToScreen(rect);    
 | |
| +    return rootViewToScreen(rect);
 | |
|  }
 | |
|  
 | |
|  void PageClientImpl::doneWithKeyEvent(const NativeWebKeyboardEvent&, bool)
 | |
| @@ -447,4 +450,23 @@ void PageClientImpl::selectionDidChange()
 | |
|      m_view.selectionDidChange();
 | |
|  }
 | |
|  
 | |
| +#if ENABLE(DATALIST_ELEMENT)
 | |
| +RefPtr<WebKit::WebDataListSuggestionsDropdown> PageClientImpl::createDataListSuggestionsDropdown(WebKit::WebPageProxy& page)
 | |
| +{
 | |
| +    return WebKitDataListSuggestionsDropdown::create(page);
 | |
| +}
 | |
| +#endif
 | |
| +
 | |
| +RefPtr<WebColorPicker> PageClientImpl::createColorPicker(WebPageProxy* page, const WebCore::Color& color, const WebCore::IntRect& rect, Vector<WebCore::Color>&&)
 | |
| +{
 | |
| +    return WebColorPickerWPE::create(*page, color, rect);
 | |
| +}
 | |
| +
 | |
| +#if ENABLE(DATE_AND_TIME_INPUT_TYPES)
 | |
| +RefPtr<WebDateTimePicker> PageClientImpl::createDateTimePicker(WebPageProxy& page)
 | |
| +{
 | |
| +    return WebDateTimePickerWPE::create(page);
 | |
| +}
 | |
| +#endif
 | |
| +
 | |
|  } // namespace WebKit
 | |
| diff --git a/Source/WebKit/UIProcess/API/wpe/PageClientImpl.h b/Source/WebKit/UIProcess/API/wpe/PageClientImpl.h
 | |
| index 7c08a13e10c75677452b74f52be2b447a5edaa13..56cf11581d453e8234f0957828083ee7c9bce8a6 100644
 | |
| --- a/Source/WebKit/UIProcess/API/wpe/PageClientImpl.h
 | |
| +++ b/Source/WebKit/UIProcess/API/wpe/PageClientImpl.h
 | |
| @@ -167,6 +167,17 @@ private:
 | |
|  
 | |
|      void selectionDidChange() override;
 | |
|  
 | |
| +#if ENABLE(DATALIST_ELEMENT)
 | |
| +    RefPtr<WebKit::WebDataListSuggestionsDropdown> createDataListSuggestionsDropdown(WebKit::WebPageProxy& page) override;
 | |
| +#endif
 | |
| +
 | |
| +#if ENABLE(INPUT_TYPE_COLOR)
 | |
| +    RefPtr<WebColorPicker> createColorPicker(WebPageProxy*, const WebCore::Color& initialColor, const WebCore::IntRect&, Vector<WebCore::Color>&&) override;
 | |
| +#endif
 | |
| +#if ENABLE(DATE_AND_TIME_INPUT_TYPES)
 | |
| +    RefPtr<WebDateTimePicker> createDateTimePicker(WebPageProxy&) override;
 | |
| +#endif
 | |
| +
 | |
|      WKWPE::View& m_view;
 | |
|  };
 | |
|  
 | |
| diff --git a/Source/WebKit/UIProcess/API/wpe/WebKitBrowserInspector.h b/Source/WebKit/UIProcess/API/wpe/WebKitBrowserInspector.h
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..cb1a540d341b07581ec87b922b7d007ce45ba989
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/UIProcess/API/wpe/WebKitBrowserInspector.h
 | |
| @@ -0,0 +1,81 @@
 | |
| +/*
 | |
| + * Copyright (C) 2019 Microsoft Corporation.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
| + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#if !defined(__WEBKIT_H_INSIDE__) && !defined(WEBKIT2_COMPILATION)
 | |
| +#error "Only <wpe/webkit.h> can be included directly."
 | |
| +#endif
 | |
| +
 | |
| +#ifndef WebKitBrowserInspector_h
 | |
| +#define WebKitBrowserInspector_h
 | |
| +
 | |
| +#include <glib-object.h>
 | |
| +#include <wpe/WebKitDefines.h>
 | |
| +#include <wpe/WebKitWebView.h>
 | |
| +
 | |
| +G_BEGIN_DECLS
 | |
| +
 | |
| +#define WEBKIT_TYPE_BROWSER_INSPECTOR            (webkit_browser_inspector_get_type())
 | |
| +#define WEBKIT_BROWSER_INSPECTOR(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_BROWSER_INSPECTOR, WebKitBrowserInspector))
 | |
| +#define WEBKIT_IS_BROWSER_INSPECTOR(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_BROWSER_INSPECTOR))
 | |
| +#define WEBKIT_BROWSER_INSPECTOR_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass),  WEBKIT_TYPE_BROWSER_INSPECTOR, WebKitBrowserInspectorClass))
 | |
| +#define WEBKIT_IS_BROWSER_INSPECTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),  WEBKIT_TYPE_BROWSER_INSPECTOR))
 | |
| +#define WEBKIT_BROWSER_INSPECTOR_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj),  WEBKIT_TYPE_BROWSER_INSPECTOR, WebKitBrowserInspectorClass))
 | |
| +
 | |
| +typedef struct _WebKitBrowserInspector        WebKitBrowserInspector;
 | |
| +typedef struct _WebKitBrowserInspectorClass   WebKitBrowserInspectorClass;
 | |
| +typedef struct _WebKitBrowserInspectorPrivate WebKitBrowserInspectorPrivate;
 | |
| +
 | |
| +struct _WebKitBrowserInspector {
 | |
| +    GObject parent;
 | |
| +
 | |
| +    WebKitBrowserInspectorPrivate *priv;
 | |
| +};
 | |
| +
 | |
| +struct _WebKitBrowserInspectorClass {
 | |
| +    GObjectClass parent_class;
 | |
| +
 | |
| +    WebKitWebView *(* create_new_page)           (WebKitBrowserInspector    *browser_inspector,
 | |
| +                                                  WebKitWebContext          *context);
 | |
| +    WebKitWebView *(* quit_application)          (WebKitBrowserInspector    *browser_inspector);
 | |
| +
 | |
| +    void (*_webkit_reserved0) (void);
 | |
| +    void (*_webkit_reserved1) (void);
 | |
| +    void (*_webkit_reserved2) (void);
 | |
| +    void (*_webkit_reserved3) (void);
 | |
| +};
 | |
| +
 | |
| +WEBKIT_API GType
 | |
| +webkit_browser_inspector_get_type                     (void);
 | |
| +
 | |
| +WEBKIT_API WebKitBrowserInspector *
 | |
| +webkit_browser_inspector_get_default                  (void);
 | |
| +
 | |
| +WEBKIT_API void
 | |
| +webkit_browser_inspector_initialize_pipe              (const char* defaultProxyURI,
 | |
| +                                                       const char* const* ignoreHosts);
 | |
| +
 | |
| +G_END_DECLS
 | |
| +
 | |
| +#endif
 | |
| diff --git a/Source/WebKit/UIProcess/API/wpe/WebKitDataListSuggestionsDropdown.cpp b/Source/WebKit/UIProcess/API/wpe/WebKitDataListSuggestionsDropdown.cpp
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..afafef2b7fb433e006b1763e653e200bc80edcbd
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/UIProcess/API/wpe/WebKitDataListSuggestionsDropdown.cpp
 | |
| @@ -0,0 +1,58 @@
 | |
| +/*
 | |
| + * Copyright (C) 2019 Igalia S.L.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS AS IS''
 | |
| + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 | |
| + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 | |
| + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 | |
| + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 | |
| + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 | |
| + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 | |
| + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 | |
| + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 | |
| + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 | |
| + * THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#include "config.h"
 | |
| +#include "WebKitDataListSuggestionsDropdown.h"
 | |
| +
 | |
| +#if ENABLE(DATALIST_ELEMENT)
 | |
| +
 | |
| +#include "WebPageProxy.h"
 | |
| +
 | |
| +namespace WebKit {
 | |
| +
 | |
| +WebKitDataListSuggestionsDropdown::WebKitDataListSuggestionsDropdown(WebPageProxy& page)
 | |
| +    : WebDataListSuggestionsDropdown(page)
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +WebKitDataListSuggestionsDropdown::~WebKitDataListSuggestionsDropdown()
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +void WebKitDataListSuggestionsDropdown::show(WebCore::DataListSuggestionInformation&& information)
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +void WebKitDataListSuggestionsDropdown::handleKeydownWithIdentifier(const String& key)
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +void WebKitDataListSuggestionsDropdown::close()
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +} // namespace WebKit
 | |
| +
 | |
| +#endif // ENABLE(DATALIST_ELEMENT)
 | |
| diff --git a/Source/WebKit/UIProcess/API/wpe/WebKitDataListSuggestionsDropdown.h b/Source/WebKit/UIProcess/API/wpe/WebKitDataListSuggestionsDropdown.h
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..0a099832c3dd959f456fcae49a1d62a9477d2758
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/UIProcess/API/wpe/WebKitDataListSuggestionsDropdown.h
 | |
| @@ -0,0 +1,55 @@
 | |
| +/*
 | |
| + * Copyright (C) 2019 Igalia S.L.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS AS IS''
 | |
| + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 | |
| + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 | |
| + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 | |
| + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 | |
| + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 | |
| + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 | |
| + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 | |
| + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 | |
| + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 | |
| + * THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#pragma once
 | |
| +
 | |
| +#if ENABLE(DATALIST_ELEMENT)
 | |
| +
 | |
| +#include "WebDataListSuggestionsDropdown.h"
 | |
| +
 | |
| +namespace WebKit {
 | |
| +
 | |
| +class WebPageProxy;
 | |
| +
 | |
| +class WebKitDataListSuggestionsDropdown final : public WebDataListSuggestionsDropdown {
 | |
| +public:
 | |
| +    static Ref<WebKitDataListSuggestionsDropdown> create(WebPageProxy& page)
 | |
| +    {
 | |
| +        return adoptRef(*new WebKitDataListSuggestionsDropdown(page));
 | |
| +    }
 | |
| +
 | |
| +    ~WebKitDataListSuggestionsDropdown();
 | |
| +
 | |
| +private:
 | |
| +    WebKitDataListSuggestionsDropdown(WebPageProxy&);
 | |
| +
 | |
| +    void show(WebCore::DataListSuggestionInformation&&) final;
 | |
| +    void handleKeydownWithIdentifier(const String&) final;
 | |
| +    void close() final;
 | |
| +};
 | |
| +
 | |
| +} // namespace WebKit
 | |
| +
 | |
| +#endif // ENABLE(DATALIST_ELEMENT)
 | |
| diff --git a/Source/WebKit/UIProcess/API/wpe/WebKitPointerLockPermissionRequest.h b/Source/WebKit/UIProcess/API/wpe/WebKitPointerLockPermissionRequest.h
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..a47e7eeb15094655c87d41ad0de7973306121184
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/UIProcess/API/wpe/WebKitPointerLockPermissionRequest.h
 | |
| @@ -0,0 +1,64 @@
 | |
| +/*
 | |
| + * Copyright (C) 2019 Igalia S.L.
 | |
| + *
 | |
| + * This library is free software; you can redistribute it and/or
 | |
| + * modify it under the terms of the GNU Library General Public
 | |
| + * License as published by the Free Software Foundation; either
 | |
| + * version 2 of the License, or (at your option) any later version.
 | |
| + *
 | |
| + * This library is distributed in the hope that it will be useful,
 | |
| + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
| + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | |
| + * Library General Public License for more details.
 | |
| + *
 | |
| + * You should have received a copy of the GNU Library General Public License
 | |
| + * along with this library; see the file COPYING.LIB.  If not, write to
 | |
| + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 | |
| + * Boston, MA 02110-1301, USA.
 | |
| + */
 | |
| +
 | |
| +#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION)
 | |
| +#error "Only <webkit2/webkit2.h> can be included directly."
 | |
| +#endif
 | |
| +
 | |
| +#ifndef WebKitPointerLockPermissionRequest_h
 | |
| +#define WebKitPointerLockPermissionRequest_h
 | |
| +
 | |
| +#include <glib-object.h>
 | |
| +#include <wpe/WebKitDefines.h>
 | |
| +
 | |
| +G_BEGIN_DECLS
 | |
| +
 | |
| +#define WEBKIT_TYPE_POINTER_LOCK_PERMISSION_REQUEST            (webkit_pointer_lock_permission_request_get_type())
 | |
| +#define WEBKIT_POINTER_LOCK_PERMISSION_REQUEST(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_POINTER_LOCK_PERMISSION_REQUEST, WebKitPointerLockPermissionRequest))
 | |
| +#define WEBKIT_POINTER_LOCK_PERMISSION_REQUEST_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass),  WEBKIT_TYPE_POINTER_LOCK_PERMISSION_REQUEST, WebKitPointerLockPermissionRequestClass))
 | |
| +#define WEBKIT_IS_POINTER_LOCK_PERMISSION_REQUEST(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_POINTER_LOCK_PERMISSION_REQUEST))
 | |
| +#define WEBKIT_IS_POINTER_LOCK_PERMISSION_REQUEST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),  WEBKIT_TYPE_POINTER_LOCK_PERMISSION_REQUEST))
 | |
| +#define WEBKIT_POINTER_LOCK_PERMISSION_REQUEST_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj),  WEBKIT_TYPE_POINTER_LOCK_PERMISSION_REQUEST, WebKitPointerLockPermissionRequestClass))
 | |
| +
 | |
| +typedef struct _WebKitPointerLockPermissionRequest        WebKitPointerLockPermissionRequest;
 | |
| +typedef struct _WebKitPointerLockPermissionRequestClass   WebKitPointerLockPermissionRequestClass;
 | |
| +typedef struct _WebKitPointerLockPermissionRequestPrivate WebKitPointerLockPermissionRequestPrivate;
 | |
| +
 | |
| +struct _WebKitPointerLockPermissionRequest {
 | |
| +    GObject parent;
 | |
| +
 | |
| +    /*< private >*/
 | |
| +    WebKitPointerLockPermissionRequestPrivate *priv;
 | |
| +};
 | |
| +
 | |
| +struct _WebKitPointerLockPermissionRequestClass {
 | |
| +    GObjectClass parent_class;
 | |
| +
 | |
| +    void (*_webkit_reserved0) (void);
 | |
| +    void (*_webkit_reserved1) (void);
 | |
| +    void (*_webkit_reserved2) (void);
 | |
| +    void (*_webkit_reserved3) (void);
 | |
| +};
 | |
| +
 | |
| +WEBKIT_API GType
 | |
| +webkit_pointer_lock_permission_request_get_type (void);
 | |
| +
 | |
| +G_END_DECLS
 | |
| +
 | |
| +#endif
 | |
| diff --git a/Source/WebKit/UIProcess/API/wpe/WebKitWebViewBackend.cpp b/Source/WebKit/UIProcess/API/wpe/WebKitWebViewBackend.cpp
 | |
| index 763bda5b29304f7ed7133c0a8158e6c8b94c5ea1..ff5d01438e44ce6785a2aa70fc5423ba74e7101c 100644
 | |
| --- a/Source/WebKit/UIProcess/API/wpe/WebKitWebViewBackend.cpp
 | |
| +++ b/Source/WebKit/UIProcess/API/wpe/WebKitWebViewBackend.cpp
 | |
| @@ -54,6 +54,7 @@ struct _WebKitWebViewBackend {
 | |
|      struct wpe_view_backend* backend;
 | |
|      GDestroyNotify notifyCallback;
 | |
|      gpointer notifyCallbackData;
 | |
| +    take_screenshot_callback screenshotCallback;
 | |
|      int referenceCount { 1 };
 | |
|  };
 | |
|  
 | |
| @@ -116,6 +117,19 @@ struct wpe_view_backend* webkit_web_view_backend_get_wpe_backend(WebKitWebViewBa
 | |
|      return viewBackend->backend;
 | |
|  }
 | |
|  
 | |
| +void webkit_web_view_backend_set_screenshot_callback(WebKitWebViewBackend *view_backend, take_screenshot_callback callback)
 | |
| +{
 | |
| +    view_backend->screenshotCallback = callback;
 | |
| +}
 | |
| +
 | |
| +cairo_surface_t* webkitWebViewBackendTakeScreenshot(WebKitWebViewBackend* view_backend)
 | |
| +{
 | |
| +    if (!view_backend->screenshotCallback)
 | |
| +        return nullptr;
 | |
| +
 | |
| +    return view_backend->screenshotCallback(view_backend->notifyCallbackData);
 | |
| +}
 | |
| +
 | |
|  namespace WTF {
 | |
|  
 | |
|  template <> WebKitWebViewBackend* refGPtr(WebKitWebViewBackend* ptr)
 | |
| diff --git a/Source/WebKit/UIProcess/API/wpe/WebKitWebViewBackend.h b/Source/WebKit/UIProcess/API/wpe/WebKitWebViewBackend.h
 | |
| index 6663964d5abac79e123d90e0351590884c66aa72..13ba5e7c3895c6e4efda95f1f90b9baea1c1bf30 100644
 | |
| --- a/Source/WebKit/UIProcess/API/wpe/WebKitWebViewBackend.h
 | |
| +++ b/Source/WebKit/UIProcess/API/wpe/WebKitWebViewBackend.h
 | |
| @@ -27,6 +27,7 @@
 | |
|  #include <glib-object.h>
 | |
|  #include <wpe/WebKitDefines.h>
 | |
|  #include <wpe/wpe.h>
 | |
| +#include <cairo.h>
 | |
|  
 | |
|  G_BEGIN_DECLS
 | |
|  
 | |
| @@ -44,6 +45,12 @@ webkit_web_view_backend_new             (struct wpe_view_backend *backend,
 | |
|  WEBKIT_API struct wpe_view_backend *
 | |
|  webkit_web_view_backend_get_wpe_backend (WebKitWebViewBackend    *view_backend);
 | |
|  
 | |
| +typedef cairo_surface_t* (*take_screenshot_callback)(gpointer              user_data);
 | |
| +
 | |
| +WEBKIT_API void
 | |
| +webkit_web_view_backend_set_screenshot_callback   (WebKitWebViewBackend      *view_backend,
 | |
| +                                                   take_screenshot_callback  callback);
 | |
| +
 | |
|  G_END_DECLS
 | |
|  
 | |
|  #endif /* WebKitWebViewBackend_h */
 | |
| diff --git a/Source/WebKit/UIProcess/API/wpe/WebKitWebViewBackendPrivate.h b/Source/WebKit/UIProcess/API/wpe/WebKitWebViewBackendPrivate.h
 | |
| index e4b92ace1531090ae38a7aec3d3d4febf19aee84..43690f9ef4969a39084501613bfc00a77fd5df49 100644
 | |
| --- a/Source/WebKit/UIProcess/API/wpe/WebKitWebViewBackendPrivate.h
 | |
| +++ b/Source/WebKit/UIProcess/API/wpe/WebKitWebViewBackendPrivate.h
 | |
| @@ -31,3 +31,5 @@ template <> void derefGPtr(WebKitWebViewBackend* ptr);
 | |
|  }
 | |
|  
 | |
|  void webkitWebViewBackendUnref(WebKitWebViewBackend*);
 | |
| +
 | |
| +cairo_surface_t* webkitWebViewBackendTakeScreenshot(WebKitWebViewBackend*);
 | |
| diff --git a/Source/WebKit/UIProcess/API/wpe/webkit.h b/Source/WebKit/UIProcess/API/wpe/webkit.h
 | |
| index c2221efc00618c2ec4d20a88c59840767bd52ff5..71f1cd7e07c705a7c830ff5c4f7d7f981bb363f2 100644
 | |
| --- a/Source/WebKit/UIProcess/API/wpe/webkit.h
 | |
| +++ b/Source/WebKit/UIProcess/API/wpe/webkit.h
 | |
| @@ -32,6 +32,7 @@
 | |
|  #include <wpe/WebKitAutomationSession.h>
 | |
|  #include <wpe/WebKitBackForwardList.h>
 | |
|  #include <wpe/WebKitBackForwardListItem.h>
 | |
| +#include <wpe/WebKitBrowserInspector.h>
 | |
|  #include <wpe/WebKitContextMenu.h>
 | |
|  #include <wpe/WebKitContextMenuActions.h>
 | |
|  #include <wpe/WebKitContextMenuItem.h>
 | |
| diff --git a/Source/WebKit/UIProcess/BackingStore.h b/Source/WebKit/UIProcess/BackingStore.h
 | |
| index d3a707a6b440421565144a56e586fa2723fe41c3..6e2492539efdf476452873f069bdaa34163f4a30 100644
 | |
| --- a/Source/WebKit/UIProcess/BackingStore.h
 | |
| +++ b/Source/WebKit/UIProcess/BackingStore.h
 | |
| @@ -51,6 +51,7 @@ public:
 | |
|  
 | |
|  #if USE(CAIRO)
 | |
|      typedef cairo_t* PlatformGraphicsContext;
 | |
| +    cairo_surface_t* surface() const;
 | |
|  #endif
 | |
|  
 | |
|      void paint(PlatformGraphicsContext, const WebCore::IntRect&);
 | |
| diff --git a/Source/WebKit/UIProcess/BrowserInspectorPipe.cpp b/Source/WebKit/UIProcess/BrowserInspectorPipe.cpp
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..cfb57a48ce387b79613b757e2eb4de2c378aac30
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/UIProcess/BrowserInspectorPipe.cpp
 | |
| @@ -0,0 +1,61 @@
 | |
| +/*
 | |
| + * Copyright (C) 2019 Microsoft Corporation.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
| + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#include "config.h"
 | |
| +#include "BrowserInspectorPipe.h"
 | |
| +
 | |
| +#if ENABLE(REMOTE_INSPECTOR)
 | |
| +
 | |
| +#include "InspectorPlaywrightAgent.h"
 | |
| +#include "InspectorPlaywrightAgentClient.h"
 | |
| +#include "RemoteInspectorPipe.h"
 | |
| +#include "WebKit2Initialize.h"
 | |
| +#include <wtf/NeverDestroyed.h>
 | |
| +
 | |
| +namespace WebKit {
 | |
| +
 | |
| +void initializeBrowserInspectorPipe(std::unique_ptr<InspectorPlaywrightAgentClient> client)
 | |
| +{
 | |
| +    // Initialize main loop before creating inspecor agent and pipe queues.
 | |
| +    WebKit::InitializeWebKit2();
 | |
| +
 | |
| +    class BrowserInspectorPipe {
 | |
| +    public:
 | |
| +        BrowserInspectorPipe(std::unique_ptr<InspectorPlaywrightAgentClient> client)
 | |
| +            : m_playwrightAgent(std::move(client))
 | |
| +            , m_remoteInspectorPipe(m_playwrightAgent)
 | |
| +        {
 | |
| +        }
 | |
| +
 | |
| +        InspectorPlaywrightAgent m_playwrightAgent;
 | |
| +        RemoteInspectorPipe m_remoteInspectorPipe;
 | |
| +    };
 | |
| +
 | |
| +    static NeverDestroyed<BrowserInspectorPipe> pipe(std::move(client));
 | |
| +}
 | |
| +
 | |
| +} // namespace WebKit
 | |
| +
 | |
| +#endif // ENABLE(REMOTE_INSPECTOR)
 | |
| diff --git a/Source/WebKit/UIProcess/BrowserInspectorPipe.h b/Source/WebKit/UIProcess/BrowserInspectorPipe.h
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..cd66887de171cda7d15a8e4dc6dbff63665dc619
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/UIProcess/BrowserInspectorPipe.h
 | |
| @@ -0,0 +1,38 @@
 | |
| +/*
 | |
| + * Copyright (C) 2019 Microsoft Corporation.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
| + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#pragma once
 | |
| +
 | |
| +#if ENABLE(REMOTE_INSPECTOR)
 | |
| +
 | |
| +namespace WebKit {
 | |
| +
 | |
| +class InspectorPlaywrightAgentClient;
 | |
| +
 | |
| +void initializeBrowserInspectorPipe(std::unique_ptr<InspectorPlaywrightAgentClient> client);
 | |
| +
 | |
| +} // namespace WebKit
 | |
| +
 | |
| +#endif // ENABLE(REMOTE_INSPECTOR)
 | |
| diff --git a/Source/WebKit/UIProcess/Cocoa/AutomationClient.mm b/Source/WebKit/UIProcess/Cocoa/AutomationClient.mm
 | |
| index 30860712f58b2a8d48cef5da4e6f03345f2921ba..e715496c24529689784ba4d481d23441ab68cf1e 100644
 | |
| --- a/Source/WebKit/UIProcess/Cocoa/AutomationClient.mm
 | |
| +++ b/Source/WebKit/UIProcess/Cocoa/AutomationClient.mm
 | |
| @@ -35,6 +35,7 @@
 | |
|  #import <wtf/RunLoop.h>
 | |
|  #import <wtf/spi/cf/CFBundleSPI.h>
 | |
|  #import <wtf/text/WTFString.h>
 | |
| +#import <wtf/RunLoop.h>
 | |
|  
 | |
|  using namespace Inspector;
 | |
|  
 | |
| diff --git a/Source/WebKit/UIProcess/Cocoa/ModalContainerControlClassifier.mm b/Source/WebKit/UIProcess/Cocoa/ModalContainerControlClassifier.mm
 | |
| index 9edf4e2ca81f85f4cf8827932964e5fc352af99e..2eb7b0a327f517b7975cc0cab100a3818d44635e 100644
 | |
| --- a/Source/WebKit/UIProcess/Cocoa/ModalContainerControlClassifier.mm
 | |
| +++ b/Source/WebKit/UIProcess/Cocoa/ModalContainerControlClassifier.mm
 | |
| @@ -36,6 +36,11 @@
 | |
|  #import <pal/cocoa/CoreMLSoftLink.h>
 | |
|  #import <pal/cocoa/NaturalLanguageSoftLink.h>
 | |
|  
 | |
| +#include <wtf/CrossThreadCopier.h>
 | |
| +#include <wtf/CompletionHandler.h>
 | |
| +
 | |
| +#include <wtf/RunLoop.h>
 | |
| +
 | |
|  static NSString *const classifierInputFeatureKey = @"text";
 | |
|  static NSString *const classifierOutputFeatureKey = @"label";
 | |
|  
 | |
| diff --git a/Source/WebKit/UIProcess/Cocoa/SOAuthorization/PopUpSOAuthorizationSession.h b/Source/WebKit/UIProcess/Cocoa/SOAuthorization/PopUpSOAuthorizationSession.h
 | |
| index 454c61ffdefecc476d1560c7c43f5b5d345f281d..59f93c79167d3d392b46ff5243494b02af073550 100644
 | |
| --- a/Source/WebKit/UIProcess/Cocoa/SOAuthorization/PopUpSOAuthorizationSession.h
 | |
| +++ b/Source/WebKit/UIProcess/Cocoa/SOAuthorization/PopUpSOAuthorizationSession.h
 | |
| @@ -29,6 +29,7 @@
 | |
|  
 | |
|  #include "SOAuthorizationSession.h"
 | |
|  #include <wtf/CompletionHandler.h>
 | |
| +#include <wtf/Forward.h>
 | |
|  
 | |
|  OBJC_CLASS WKSOSecretDelegate;
 | |
|  OBJC_CLASS WKWebView;
 | |
| @@ -39,6 +40,8 @@ class NavigationAction;
 | |
|  
 | |
|  namespace WebKit {
 | |
|  
 | |
| +class WebPageProxy;
 | |
| +
 | |
|  // FSM: Idle => Active => Completed
 | |
|  class PopUpSOAuthorizationSession final : public SOAuthorizationSession {
 | |
|  public:
 | |
| diff --git a/Source/WebKit/UIProcess/Cocoa/UIDelegate.h b/Source/WebKit/UIProcess/Cocoa/UIDelegate.h
 | |
| index 20b08ac2df75f589bbbe29e2f924c92f33cf2242..2aaa37a18eb31ade4ff8d7fb8b85fee612bb47f1 100644
 | |
| --- a/Source/WebKit/UIProcess/Cocoa/UIDelegate.h
 | |
| +++ b/Source/WebKit/UIProcess/Cocoa/UIDelegate.h
 | |
| @@ -95,6 +95,7 @@ private:
 | |
|          void runJavaScriptAlert(WebPageProxy&, const WTF::String&, WebFrameProxy*, FrameInfoData&&, Function<void()>&& completionHandler) final;
 | |
|          void runJavaScriptConfirm(WebPageProxy&, const WTF::String&, WebFrameProxy*, FrameInfoData&&, Function<void(bool)>&& completionHandler) final;
 | |
|          void runJavaScriptPrompt(WebPageProxy&, const WTF::String&, const WTF::String&, WebFrameProxy*, FrameInfoData&&, Function<void(const WTF::String&)>&&) final;
 | |
| +        void handleJavaScriptDialog(WebKit::WebPageProxy&, bool accept, const WTF::String&) final;
 | |
|          void presentStorageAccessConfirmDialog(const WTF::String& requestingDomain, const WTF::String& currentDomain, CompletionHandler<void(bool)>&&);
 | |
|          void requestStorageAccessConfirm(WebPageProxy&, WebFrameProxy*, const WebCore::RegistrableDomain& requestingDomain, const WebCore::RegistrableDomain& currentDomain, CompletionHandler<void(bool)>&&) final;
 | |
|          void decidePolicyForGeolocationPermissionRequest(WebPageProxy&, WebFrameProxy&, const FrameInfoData&, Function<void(bool)>&) final;
 | |
| @@ -198,6 +199,7 @@ private:
 | |
|          bool webViewRunJavaScriptAlertPanelWithMessageInitiatedByFrameCompletionHandler : 1;
 | |
|          bool webViewRunJavaScriptConfirmPanelWithMessageInitiatedByFrameCompletionHandler : 1;
 | |
|          bool webViewRunJavaScriptTextInputPanelWithPromptDefaultTextInitiatedByFrameCompletionHandler : 1;
 | |
| +        bool webViewHandleJavaScriptDialogValue : 1;
 | |
|          bool webViewRequestStorageAccessPanelUnderFirstPartyCompletionHandler : 1;
 | |
|          bool webViewRunBeforeUnloadConfirmPanelWithMessageInitiatedByFrameCompletionHandler : 1;
 | |
|          bool webViewRequestGeolocationPermissionForFrameDecisionHandler : 1;
 | |
| diff --git a/Source/WebKit/UIProcess/Cocoa/UIDelegate.mm b/Source/WebKit/UIProcess/Cocoa/UIDelegate.mm
 | |
| index 1942490889b8be84160087c0f388302fbc6e96fd..eaa42475b1d56aa8980abd972df116b5aa72ba44 100644
 | |
| --- a/Source/WebKit/UIProcess/Cocoa/UIDelegate.mm
 | |
| +++ b/Source/WebKit/UIProcess/Cocoa/UIDelegate.mm
 | |
| @@ -111,6 +111,7 @@ void UIDelegate::setDelegate(id <WKUIDelegate> delegate)
 | |
|      m_delegateMethods.webViewRunJavaScriptAlertPanelWithMessageInitiatedByFrameCompletionHandler = [delegate respondsToSelector:@selector(webView:runJavaScriptAlertPanelWithMessage:initiatedByFrame:completionHandler:)];
 | |
|      m_delegateMethods.webViewRunJavaScriptConfirmPanelWithMessageInitiatedByFrameCompletionHandler = [delegate respondsToSelector:@selector(webView:runJavaScriptConfirmPanelWithMessage:initiatedByFrame:completionHandler:)];
 | |
|      m_delegateMethods.webViewRunJavaScriptTextInputPanelWithPromptDefaultTextInitiatedByFrameCompletionHandler = [delegate respondsToSelector:@selector(webView:runJavaScriptTextInputPanelWithPrompt:defaultText:initiatedByFrame:completionHandler:)];
 | |
| +    m_delegateMethods.webViewHandleJavaScriptDialogValue = [delegate respondsToSelector:@selector(webView:handleJavaScriptDialog:value:)];
 | |
|      m_delegateMethods.webViewRequestStorageAccessPanelUnderFirstPartyCompletionHandler = [delegate respondsToSelector:@selector(_webView:requestStorageAccessPanelForDomain:underCurrentDomain:completionHandler:)];
 | |
|      m_delegateMethods.webViewRunBeforeUnloadConfirmPanelWithMessageInitiatedByFrameCompletionHandler = [delegate respondsToSelector:@selector(_webView:runBeforeUnloadConfirmPanelWithMessage:initiatedByFrame:completionHandler:)];
 | |
|      m_delegateMethods.webViewRequestGeolocationPermissionForOriginDecisionHandler = [delegate respondsToSelector:@selector(_webView:requestGeolocationPermissionForOrigin:initiatedByFrame:decisionHandler:)];
 | |
| @@ -411,6 +412,15 @@ void UIDelegate::UIClient::runJavaScriptPrompt(WebPageProxy& page, const WTF::St
 | |
|      }).get()];
 | |
|  }
 | |
|  
 | |
| +void UIDelegate::UIClient::handleJavaScriptDialog(WebKit::WebPageProxy&, bool accept, const WTF::String& value) {
 | |
| +    if (!m_uiDelegate->m_delegateMethods.webViewHandleJavaScriptDialogValue)
 | |
| +        return;
 | |
| +    auto delegate = m_uiDelegate->m_delegate.get();
 | |
| +    if (!delegate)
 | |
| +        return;
 | |
| +    [delegate webView:m_uiDelegate->m_webView.get().get() handleJavaScriptDialog:accept value:value];
 | |
| +}
 | |
| +
 | |
|  void UIDelegate::UIClient::requestStorageAccessConfirm(WebPageProxy& webPageProxy, WebFrameProxy*, const WebCore::RegistrableDomain& requestingDomain, const WebCore::RegistrableDomain& currentDomain, CompletionHandler<void(bool)>&& completionHandler)
 | |
|  {
 | |
|      if (!m_uiDelegate)
 | |
| diff --git a/Source/WebKit/UIProcess/Cocoa/WebPageProxyCocoa.mm b/Source/WebKit/UIProcess/Cocoa/WebPageProxyCocoa.mm
 | |
| index d1553d8c91b7ad8647aa156d7f029398f1a2ebe9..993ad73607b20eb1be890a6199cdbe7312a2f256 100644
 | |
| --- a/Source/WebKit/UIProcess/Cocoa/WebPageProxyCocoa.mm
 | |
| +++ b/Source/WebKit/UIProcess/Cocoa/WebPageProxyCocoa.mm
 | |
| @@ -37,6 +37,7 @@
 | |
|  #import "LoadParameters.h"
 | |
|  #import "ModalContainerControlClassifier.h"
 | |
|  #import "PageClient.h"
 | |
| +#import "PasteboardTypes.h"
 | |
|  #import "PlaybackSessionManagerProxy.h"
 | |
|  #import "QuarantineSPI.h"
 | |
|  #import "QuickLookThumbnailLoader.h"
 | |
| @@ -250,9 +251,66 @@ bool WebPageProxy::scrollingUpdatesDisabledForTesting()
 | |
|  
 | |
|  void WebPageProxy::startDrag(const DragItem& dragItem, const ShareableBitmap::Handle& dragImageHandle)
 | |
|  {
 | |
| +    if (m_interceptDrags) {
 | |
| +        NSPasteboard *pasteboard = [NSPasteboard pasteboardWithName: m_overrideDragPasteboardName];
 | |
| +
 | |
| +        m_dragSelectionData = String([pasteboard name]);
 | |
| +        grantAccessToCurrentPasteboardData(String([pasteboard name]));
 | |
| +        m_dragSourceOperationMask = WebCore::anyDragOperation();
 | |
| +
 | |
| +        if (auto& info = dragItem.promisedAttachmentInfo) {
 | |
| +            auto attachment = attachmentForIdentifier(info.attachmentIdentifier);
 | |
| +            if (!attachment) {
 | |
| +                dragCancelled();
 | |
| +                return;
 | |
| +            }
 | |
| +            NSString *utiType = attachment->utiType();
 | |
| +            if (!utiType.length) {
 | |
| +                dragCancelled();
 | |
| +                return;
 | |
| +            }
 | |
| +
 | |
| +            ASSERT(info.additionalTypes.size() == info.additionalData.size());
 | |
| +            if (info.additionalTypes.size() == info.additionalData.size()) {
 | |
| +                for (size_t index = 0; index < info.additionalTypes.size(); ++index) {
 | |
| +                    auto nsData = info.additionalData[index]->createNSData();
 | |
| +                    [pasteboard setData:nsData.get() forType:info.additionalTypes[index]];
 | |
| +                }
 | |
| +            }
 | |
| +        } else {
 | |
| +            [pasteboard setString:@"" forType:PasteboardTypes::WebDummyPboardType];
 | |
| +        }
 | |
| +        didStartDrag();
 | |
| +        return;
 | |
| +    }
 | |
| +
 | |
|      pageClient().startDrag(dragItem, dragImageHandle);
 | |
|  }
 | |
|  
 | |
| +void WebPageProxy::releaseInspectorDragPasteboard() {
 | |
| +    if (!!m_dragSelectionData)
 | |
| +        m_dragSelectionData = std::nullopt;
 | |
| +    if (!m_overrideDragPasteboardName.isEmpty()) {
 | |
| +        NSPasteboard *pasteboard = [NSPasteboard pasteboardWithUniqueName];
 | |
| +        [pasteboard releaseGlobally];
 | |
| +        m_overrideDragPasteboardName = ""_s;
 | |
| +    }
 | |
| +}
 | |
| +
 | |
| +
 | |
| +void WebPageProxy::setInterceptDrags(bool shouldIntercept) {
 | |
| +    m_interceptDrags = shouldIntercept;
 | |
| +    if (m_interceptDrags) {
 | |
| +        if (m_overrideDragPasteboardName.isEmpty()) {
 | |
| +            NSPasteboard *pasteboard = [NSPasteboard pasteboardWithUniqueName];
 | |
| +            m_overrideDragPasteboardName = String([pasteboard name]);
 | |
| +        }
 | |
| +        send(Messages::WebPage::SetDragPasteboardName(m_overrideDragPasteboardName));
 | |
| +    } else {
 | |
| +        send(Messages::WebPage::SetDragPasteboardName(""_s));
 | |
| +    }
 | |
| +}
 | |
| +
 | |
|  // FIXME: Move these functions to WebPageProxyIOS.mm.
 | |
|  #if PLATFORM(IOS_FAMILY)
 | |
|  
 | |
| diff --git a/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm b/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm
 | |
| index f18a05f0ec81b350502d17471c8754e44f504491..75dce762f6fdffafdd19692fa5d54b90dac3f929 100644
 | |
| --- a/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm
 | |
| +++ b/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm
 | |
| @@ -359,7 +359,7 @@ void WebProcessPool::platformInitializeWebProcess(const WebProcessProxy& process
 | |
|      auto screenProperties = WebCore::collectScreenProperties();
 | |
|      parameters.screenProperties = WTFMove(screenProperties);
 | |
|  #if PLATFORM(MAC)
 | |
| -    parameters.useOverlayScrollbars = ([NSScroller preferredScrollerStyle] == NSScrollerStyleOverlay);
 | |
| +    parameters.useOverlayScrollbars = m_configuration->forceOverlayScrollbars() || ([NSScroller preferredScrollerStyle] == NSScrollerStyleOverlay);
 | |
|  #endif
 | |
|      
 | |
|  #if PLATFORM(IOS)
 | |
| @@ -619,8 +619,8 @@ void WebProcessPool::registerNotificationObservers()
 | |
|      }];
 | |
|  
 | |
|      m_scrollerStyleNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:NSPreferredScrollerStyleDidChangeNotification object:nil queue:[NSOperationQueue currentQueue] usingBlock:^(NSNotification *notification) {
 | |
| -        auto scrollbarStyle = [NSScroller preferredScrollerStyle];
 | |
| -        sendToAllProcesses(Messages::WebProcess::ScrollerStylePreferenceChanged(scrollbarStyle));
 | |
| +        bool useOverlayScrollbars = m_configuration->forceOverlayScrollbars() || ([NSScroller preferredScrollerStyle] == NSScrollerStyleOverlay);
 | |
| +        sendToAllProcesses(Messages::WebProcess::ScrollerStylePreferenceChanged(useOverlayScrollbars));
 | |
|      }];
 | |
|  
 | |
|      m_activationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:NSApplicationDidBecomeActiveNotification object:NSApp queue:[NSOperationQueue currentQueue] usingBlock:^(NSNotification *notification) {
 | |
| diff --git a/Source/WebKit/UIProcess/Cocoa/WebViewImpl.h b/Source/WebKit/UIProcess/Cocoa/WebViewImpl.h
 | |
| index a4d0e7c10ffe1cfd50203c996cec083f167ac03f..95cfb310026746a10d36c50bbbcbc40e1a4db37b 100644
 | |
| --- a/Source/WebKit/UIProcess/Cocoa/WebViewImpl.h
 | |
| +++ b/Source/WebKit/UIProcess/Cocoa/WebViewImpl.h
 | |
| @@ -507,6 +507,9 @@ public:
 | |
|      void provideDataForPasteboard(NSPasteboard *, NSString *type);
 | |
|      NSArray *namesOfPromisedFilesDroppedAtDestination(NSURL *dropDestination);
 | |
|  
 | |
| +// Paywright begin
 | |
| +    RetainPtr<CGImageRef> takeSnapshotForAutomation();
 | |
| +// Paywright end
 | |
|      RefPtr<ViewSnapshot> takeViewSnapshot();
 | |
|      void saveBackForwardSnapshotForCurrentItem();
 | |
|      void saveBackForwardSnapshotForItem(WebBackForwardListItem&);
 | |
| diff --git a/Source/WebKit/UIProcess/Cocoa/WebViewImpl.mm b/Source/WebKit/UIProcess/Cocoa/WebViewImpl.mm
 | |
| index f8f4a3ffe656dfbc72ee12425deb72adbd024566..03d6d358d6101eb926174c78cbbe18eededd16c1 100644
 | |
| --- a/Source/WebKit/UIProcess/Cocoa/WebViewImpl.mm
 | |
| +++ b/Source/WebKit/UIProcess/Cocoa/WebViewImpl.mm
 | |
| @@ -2776,6 +2776,11 @@ WebCore::DestinationColorSpace WebViewImpl::colorSpace()
 | |
|          if (!m_colorSpace)
 | |
|              m_colorSpace = [NSColorSpace sRGBColorSpace];
 | |
|      }
 | |
| +    // Playwright begin
 | |
| +    // window.colorSpace is sometimes null on popup windows in headless mode
 | |
| +    if (!m_colorSpace)
 | |
| +        return WebCore::DestinationColorSpace::SRGB();
 | |
| +    // Playwright end
 | |
|  
 | |
|      ASSERT(m_colorSpace);
 | |
|      return WebCore::DestinationColorSpace { [m_colorSpace CGColorSpace] };
 | |
| @@ -4777,6 +4782,18 @@ static RetainPtr<CGImageRef> takeWindowSnapshot(CGSWindowID windowID, bool captu
 | |
|      return adoptCF(CGWindowListCreateImage(CGRectNull, kCGWindowListOptionIncludingWindow, windowID, imageOptions));
 | |
|  }
 | |
|  
 | |
| +// Paywright begin
 | |
| +RetainPtr<CGImageRef> WebViewImpl::takeSnapshotForAutomation() {
 | |
| +    NSWindow *window = [m_view window];
 | |
| +
 | |
| +    CGSWindowID windowID = (CGSWindowID)window.windowNumber;
 | |
| +    if (!windowID || !window.isVisible)
 | |
| +        return nullptr;
 | |
| +
 | |
| +    return takeWindowSnapshot(windowID, true);
 | |
| +}
 | |
| +// Paywright end
 | |
| +
 | |
|  RefPtr<ViewSnapshot> WebViewImpl::takeViewSnapshot()
 | |
|  {
 | |
|      NSWindow *window = [m_view window];
 | |
| diff --git a/Source/WebKit/UIProcess/CoordinatedGraphics/DrawingAreaProxyCoordinatedGraphics.cpp b/Source/WebKit/UIProcess/CoordinatedGraphics/DrawingAreaProxyCoordinatedGraphics.cpp
 | |
| index 32c82b899b301c957c5632c09e0ae321cf64e961..71cabafb96edd24d63f21f7fcc0a841cf8e72deb 100644
 | |
| --- a/Source/WebKit/UIProcess/CoordinatedGraphics/DrawingAreaProxyCoordinatedGraphics.cpp
 | |
| +++ b/Source/WebKit/UIProcess/CoordinatedGraphics/DrawingAreaProxyCoordinatedGraphics.cpp
 | |
| @@ -32,13 +32,16 @@
 | |
|  #include "DrawingAreaProxyMessages.h"
 | |
|  #include "LayerTreeContext.h"
 | |
|  #include "UpdateInfo.h"
 | |
| +#include "WebPageInspectorController.h"
 | |
|  #include "WebPageProxy.h"
 | |
|  #include "WebPreferences.h"
 | |
|  #include "WebProcessProxy.h"
 | |
|  #include <WebCore/PlatformDisplay.h>
 | |
|  #include <WebCore/Region.h>
 | |
| +#include <wtf/Vector.h>
 | |
|  
 | |
|  #if PLATFORM(GTK)
 | |
| +#include "WebKitWebViewBasePrivate.h"
 | |
|  #include <gtk/gtk.h>
 | |
|  #endif
 | |
|  
 | |
| @@ -46,6 +49,13 @@
 | |
|  #include <wtf/glib/RunLoopSourcePriority.h>
 | |
|  #endif
 | |
|  
 | |
| +#if PLATFORM(WIN)
 | |
| +#include <cairo-win32.h>
 | |
| +#include <windows.h>
 | |
| +#include <WebCore/HWndDC.h>
 | |
| +#include <WebCore/RefPtrCairo.h>
 | |
| +#endif
 | |
| +
 | |
|  namespace WebKit {
 | |
|  using namespace WebCore;
 | |
|  
 | |
| @@ -114,6 +124,10 @@ void DrawingAreaProxyCoordinatedGraphics::paint(BackingStore::PlatformGraphicsCo
 | |
|  
 | |
|  void DrawingAreaProxyCoordinatedGraphics::sizeDidChange()
 | |
|  {
 | |
| +    for (auto& value : m_callbacks)
 | |
| +        value();
 | |
| +    m_callbacks.clear();
 | |
| +
 | |
|      backingStoreStateDidChange(RespondImmediately);
 | |
|  }
 | |
|  
 | |
| @@ -122,6 +136,11 @@ void DrawingAreaProxyCoordinatedGraphics::deviceScaleFactorDidChange()
 | |
|      backingStoreStateDidChange(RespondImmediately);
 | |
|  }
 | |
|  
 | |
| +void DrawingAreaProxyCoordinatedGraphics::waitForSizeUpdate(Function<void ()>&& callback)
 | |
| +{
 | |
| +    m_callbacks.append(WTFMove(callback));
 | |
| +}
 | |
| +
 | |
|  void DrawingAreaProxyCoordinatedGraphics::waitForBackingStoreUpdateOnNextPaint()
 | |
|  {
 | |
|      m_hasReceivedFirstUpdate = true;
 | |
| @@ -244,6 +263,45 @@ void DrawingAreaProxyCoordinatedGraphics::targetRefreshRateDidChange(unsigned ra
 | |
|      send(Messages::DrawingArea::TargetRefreshRateDidChange(rate));
 | |
|  }
 | |
|  
 | |
| +#if PLATFORM(WIN)
 | |
| +void DrawingAreaProxyCoordinatedGraphics::didChangeAcceleratedCompositingMode(bool enabled)
 | |
| +{
 | |
| +    m_isInAcceleratedCompositingMode = enabled;
 | |
| +}
 | |
| +#endif
 | |
| +
 | |
| +#if !PLATFORM(WPE)
 | |
| +void DrawingAreaProxyCoordinatedGraphics::captureFrame()
 | |
| +{
 | |
| +    RefPtr<cairo_surface_t> surface;
 | |
| +#if PLATFORM(WIN)
 | |
| +    HWndDC dc;
 | |
| +    if (m_isInAcceleratedCompositingMode) {
 | |
| +        dc.setHWnd(m_webPageProxy.viewWidget());
 | |
| +        surface = adoptRef(cairo_win32_surface_create(dc));
 | |
| +#else
 | |
| +    if (isInAcceleratedCompositingMode()) {
 | |
| +#  if PLATFORM(GTK)
 | |
| +        AcceleratedBackingStore* backingStore = webkitWebViewBaseGetAcceleratedBackingStore(WEBKIT_WEB_VIEW_BASE(m_webPageProxy.viewWidget()));
 | |
| +        if (!backingStore)
 | |
| +            return;
 | |
| +
 | |
| +        surface = backingStore->surface();
 | |
| +#  else
 | |
| +        fprintf(stderr, "captureFrame() is not supported in accelerated compositing mode on this platform.\n");
 | |
| +#  endif
 | |
| +#endif
 | |
| +    } else if (m_backingStore) {
 | |
| +        surface = m_backingStore->surface();
 | |
| +    }
 | |
| +
 | |
| +    if (!surface)
 | |
| +        return;
 | |
| +
 | |
| +    m_webPageProxy.inspectorController().didPaint(surface.get());
 | |
| +}
 | |
| +#endif
 | |
| +
 | |
|  #if !PLATFORM(WPE)
 | |
|  void DrawingAreaProxyCoordinatedGraphics::incorporateUpdate(const UpdateInfo& updateInfo)
 | |
|  {
 | |
| diff --git a/Source/WebKit/UIProcess/CoordinatedGraphics/DrawingAreaProxyCoordinatedGraphics.h b/Source/WebKit/UIProcess/CoordinatedGraphics/DrawingAreaProxyCoordinatedGraphics.h
 | |
| index f3dfe6614bad532c49995cf7afc5f6818a469ca6..78971e7296e5395079590fdf491b1ba1781b216f 100644
 | |
| --- a/Source/WebKit/UIProcess/CoordinatedGraphics/DrawingAreaProxyCoordinatedGraphics.h
 | |
| +++ b/Source/WebKit/UIProcess/CoordinatedGraphics/DrawingAreaProxyCoordinatedGraphics.h
 | |
| @@ -30,6 +30,7 @@
 | |
|  #include "BackingStore.h"
 | |
|  #include "DrawingAreaProxy.h"
 | |
|  #include "LayerTreeContext.h"
 | |
| +#include <wtf/Function.h>
 | |
|  #include <wtf/RunLoop.h>
 | |
|  
 | |
|  namespace WebCore {
 | |
| @@ -49,6 +50,10 @@ public:
 | |
|  
 | |
|      bool isInAcceleratedCompositingMode() const { return !m_layerTreeContext.isEmpty(); }
 | |
|      const LayerTreeContext& layerTreeContext() const { return m_layerTreeContext; }
 | |
| +    void waitForSizeUpdate(Function<void ()>&&);
 | |
| +#if !PLATFORM(WPE)
 | |
| +    void captureFrame();
 | |
| +#endif
 | |
|  
 | |
|  private:
 | |
|      // DrawingAreaProxy
 | |
| @@ -69,6 +74,9 @@ private:
 | |
|      void exitAcceleratedCompositingMode(uint64_t backingStoreStateID, const UpdateInfo&) override;
 | |
|      void updateAcceleratedCompositingMode(uint64_t backingStoreStateID, const LayerTreeContext&) override;
 | |
|      void targetRefreshRateDidChange(unsigned) override;
 | |
| +#if PLATFORM(WIN)
 | |
| +    void didChangeAcceleratedCompositingMode(bool enabled) override;
 | |
| +#endif
 | |
|  
 | |
|  #if !PLATFORM(WPE)
 | |
|      void incorporateUpdate(const UpdateInfo&);
 | |
| @@ -132,12 +140,18 @@ private:
 | |
|      // For a new Drawing Area don't draw anything until the WebProcess has sent over the first content.
 | |
|      bool m_hasReceivedFirstUpdate { false };
 | |
|  
 | |
| +    Vector<Function<void ()>> m_callbacks;
 | |
| +
 | |
|  #if !PLATFORM(WPE)
 | |
|      bool m_isBackingStoreDiscardable { true };
 | |
|      std::unique_ptr<BackingStore> m_backingStore;
 | |
|      RunLoop::Timer<DrawingAreaProxyCoordinatedGraphics> m_discardBackingStoreTimer;
 | |
|  #endif
 | |
|      std::unique_ptr<DrawingMonitor> m_drawingMonitor;
 | |
| +
 | |
| +#if PLATFORM(WIN)
 | |
| +    bool m_isInAcceleratedCompositingMode { false };
 | |
| +#endif
 | |
|  };
 | |
|  
 | |
|  } // namespace WebKit
 | |
| diff --git a/Source/WebKit/UIProcess/Downloads/DownloadProxy.cpp b/Source/WebKit/UIProcess/Downloads/DownloadProxy.cpp
 | |
| index 7f5868577fd5bb251bd9eb25f2edeaa225ee0845..9894d5fcd9ee69ecdbdc5fc58a2d99779ec8794f 100644
 | |
| --- a/Source/WebKit/UIProcess/Downloads/DownloadProxy.cpp
 | |
| +++ b/Source/WebKit/UIProcess/Downloads/DownloadProxy.cpp
 | |
| @@ -42,8 +42,10 @@
 | |
|  #include <WebCore/MIMETypeRegistry.h>
 | |
|  #include <WebCore/ResourceResponseBase.h>
 | |
|  #include <wtf/FileSystem.h>
 | |
| +#include <wtf/NeverDestroyed.h>
 | |
|  #include <wtf/text/CString.h>
 | |
|  #include <wtf/text/WTFString.h>
 | |
| +#include <wtf/UUID.h>
 | |
|  
 | |
|  namespace WebKit {
 | |
|  using namespace WebCore;
 | |
| @@ -56,7 +58,10 @@ DownloadProxy::DownloadProxy(DownloadProxyMap& downloadProxyMap, WebsiteDataStor
 | |
|      , m_request(resourceRequest)
 | |
|      , m_originatingPage(originatingPage)
 | |
|      , m_frameInfo(API::FrameInfo::create(FrameInfoData { frameInfoData }, originatingPage))
 | |
| +    , m_uuid(createVersion4UUIDString())
 | |
|  {
 | |
| +    if (auto* instrumentation = m_dataStore->downloadInstrumentation())
 | |
| +      instrumentation->downloadCreated(m_uuid, m_request, frameInfoData, originatingPage, this);
 | |
|  }
 | |
|  
 | |
|  DownloadProxy::~DownloadProxy()
 | |
| @@ -75,9 +80,12 @@ static RefPtr<API::Data> createData(const IPC::DataReference& data)
 | |
|  void DownloadProxy::cancel(CompletionHandler<void(API::Data*)>&& completionHandler)
 | |
|  {
 | |
|      if (m_dataStore) {
 | |
| -        m_dataStore->networkProcess().sendWithAsyncReply(Messages::NetworkProcess::CancelDownload(m_downloadID), [this, protectedThis = Ref { *this }, completionHandler = WTFMove(completionHandler)] (const IPC::DataReference& resumeData) mutable {
 | |
| +        auto* instrumentation = m_dataStore->downloadInstrumentation();
 | |
| +        m_dataStore->networkProcess().sendWithAsyncReply(Messages::NetworkProcess::CancelDownload(m_downloadID), [this, protectedThis = Ref { *this }, completionHandler = WTFMove(completionHandler), instrumentation] (const IPC::DataReference& resumeData) mutable {
 | |
|              m_legacyResumeData = createData(resumeData);
 | |
|              completionHandler(m_legacyResumeData.get());
 | |
| +            if (instrumentation)
 | |
| +                instrumentation->downloadFinished(m_uuid, "canceled"_s);
 | |
|              m_downloadProxyMap.downloadFinished(*this);
 | |
|          });
 | |
|      } else
 | |
| @@ -163,6 +171,21 @@ void DownloadProxy::decideDestinationWithSuggestedFilename(const WebCore::Resour
 | |
|          suggestedFilename = m_suggestedFilename;
 | |
|      suggestedFilename = MIMETypeRegistry::appendFileExtensionIfNecessary(suggestedFilename, response.mimeType());
 | |
|  
 | |
| +    if (auto* instrumentation = m_dataStore->downloadInstrumentation())
 | |
| +      instrumentation->downloadFilenameSuggested(m_uuid, suggestedFilename);
 | |
| +
 | |
| +    if (m_dataStore->allowDownloadForAutomation()) {
 | |
| +        SandboxExtension::Handle sandboxExtensionHandle;
 | |
| +        String destination;
 | |
| +        if (*m_dataStore->allowDownloadForAutomation()) {
 | |
| +            destination = FileSystem::pathByAppendingComponent(m_dataStore->downloadPathForAutomation(), m_uuid);
 | |
| +            if (auto handle = SandboxExtension::createHandle(destination, SandboxExtension::Type::ReadWrite))
 | |
| +                sandboxExtensionHandle = WTFMove(*handle);
 | |
| +        }
 | |
| +        completionHandler(destination, WTFMove(sandboxExtensionHandle), AllowOverwrite::Yes);
 | |
| +        return;
 | |
| +    }
 | |
| +
 | |
|      m_client->decideDestinationWithSuggestedFilename(*this, response, ResourceResponseBase::sanitizeSuggestedFilename(suggestedFilename), [this, protectedThis = Ref { *this }, completionHandler = WTFMove(completionHandler)] (AllowOverwrite allowOverwrite, String destination) mutable {
 | |
|          SandboxExtension::Handle sandboxExtensionHandle;
 | |
|          if (!destination.isNull()) {
 | |
| @@ -183,6 +206,8 @@ void DownloadProxy::didCreateDestination(const String& path)
 | |
|  void DownloadProxy::didFinish()
 | |
|  {
 | |
|      m_client->didFinish(*this);
 | |
| +    if (auto* instrumentation = m_dataStore->downloadInstrumentation())
 | |
| +      instrumentation->downloadFinished(m_uuid, String());
 | |
|  
 | |
|      // This can cause the DownloadProxy object to be deleted.
 | |
|      m_downloadProxyMap.downloadFinished(*this);
 | |
| @@ -193,6 +218,8 @@ void DownloadProxy::didFail(const ResourceError& error, const IPC::DataReference
 | |
|      m_legacyResumeData = createData(resumeData);
 | |
|  
 | |
|      m_client->didFail(*this, error, m_legacyResumeData.get());
 | |
| +    if (auto* instrumentation = m_dataStore->downloadInstrumentation())
 | |
| +      instrumentation->downloadFinished(m_uuid, error.localizedDescription());
 | |
|  
 | |
|      // This can cause the DownloadProxy object to be deleted.
 | |
|      m_downloadProxyMap.downloadFinished(*this);
 | |
| diff --git a/Source/WebKit/UIProcess/Downloads/DownloadProxy.h b/Source/WebKit/UIProcess/Downloads/DownloadProxy.h
 | |
| index e87f14a1772973db924624671dd40fe919904a5e..711335158c64e743a17e31c082a402eb0be9ac23 100644
 | |
| --- a/Source/WebKit/UIProcess/Downloads/DownloadProxy.h
 | |
| +++ b/Source/WebKit/UIProcess/Downloads/DownloadProxy.h
 | |
| @@ -147,6 +147,7 @@ private:
 | |
|  #if PLATFORM(COCOA)
 | |
|      RetainPtr<NSProgress> m_progress;
 | |
|  #endif
 | |
| +    String m_uuid;
 | |
|  };
 | |
|  
 | |
|  } // namespace WebKit
 | |
| diff --git a/Source/WebKit/UIProcess/DrawingAreaProxy.h b/Source/WebKit/UIProcess/DrawingAreaProxy.h
 | |
| index 21dd04d3fb314a0a96ccad8191edde3ada5de326..5a2ac57e9bcedd650996161112441d9598c036ee 100644
 | |
| --- a/Source/WebKit/UIProcess/DrawingAreaProxy.h
 | |
| +++ b/Source/WebKit/UIProcess/DrawingAreaProxy.h
 | |
| @@ -75,6 +75,7 @@ public:
 | |
|  
 | |
|      const WebCore::IntSize& size() const { return m_size; }
 | |
|      bool setSize(const WebCore::IntSize&, const WebCore::IntSize& scrollOffset = { });
 | |
| +    void waitForSizeUpdate(Function<void ()>&&);
 | |
|  
 | |
|  #if USE(COORDINATED_GRAPHICS) || USE(TEXTURE_MAPPER)
 | |
|      // The timeout we use when waiting for a DidUpdateGeometry message.
 | |
| @@ -162,6 +163,9 @@ private:
 | |
|      virtual void update(uint64_t /* backingStoreStateID */, const UpdateInfo&) { }
 | |
|      virtual void didUpdateBackingStoreState(uint64_t /* backingStoreStateID */, const UpdateInfo&, const LayerTreeContext&) { }
 | |
|      virtual void exitAcceleratedCompositingMode(uint64_t /* backingStoreStateID */, const UpdateInfo&) { }
 | |
| +#endif
 | |
| +#if PLATFORM(WIN)
 | |
| +    virtual void didChangeAcceleratedCompositingMode(bool) { }
 | |
|  #endif
 | |
|      bool m_startedReceivingMessages { false };
 | |
|  };
 | |
| diff --git a/Source/WebKit/UIProcess/DrawingAreaProxy.messages.in b/Source/WebKit/UIProcess/DrawingAreaProxy.messages.in
 | |
| index b0722e7da81e56530deb570b82ed7cfece970362..05ec3e3ea97ba49135a27d7f9b91f14c507d9318 100644
 | |
| --- a/Source/WebKit/UIProcess/DrawingAreaProxy.messages.in
 | |
| +++ b/Source/WebKit/UIProcess/DrawingAreaProxy.messages.in
 | |
| @@ -36,4 +36,7 @@ messages -> DrawingAreaProxy NotRefCounted {
 | |
|      DidUpdateBackingStoreState(uint64_t backingStoreStateID, WebKit::UpdateInfo updateInfo, WebKit::LayerTreeContext context)
 | |
|      ExitAcceleratedCompositingMode(uint64_t backingStoreStateID, WebKit::UpdateInfo updateInfo)
 | |
|  #endif
 | |
| +#if PLATFORM(WIN)
 | |
| +    DidChangeAcceleratedCompositingMode(bool enabled)
 | |
| +#endif
 | |
|  }
 | |
| diff --git a/Source/WebKit/UIProcess/Inspector/Agents/CairoJpegEncoder.cpp b/Source/WebKit/UIProcess/Inspector/Agents/CairoJpegEncoder.cpp
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..9426d9eed59f433eac62b8eb6a16139b84079949
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/UIProcess/Inspector/Agents/CairoJpegEncoder.cpp
 | |
| @@ -0,0 +1,244 @@
 | |
| +/* Copyright 2018 Bernhard R. Fischer, 4096R/8E24F29D <bf@abenteuerland.at>
 | |
| + *
 | |
| + * This file is part of Cairo_JPG.
 | |
| + *
 | |
| + * Cairo_JPG is free software: you can redistribute it and/or modify
 | |
| + * it under the terms of the GNU Lesser General Public License as published by
 | |
| + * the Free Software Foundation, either version 3 of the License, or
 | |
| + * (at your option) any later version.
 | |
| + *
 | |
| + * Cairo_JPG is distributed in the hope that it will be useful,
 | |
| + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
| + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
| + * GNU Lesser General Public License for more details.
 | |
| + *
 | |
| + * You should have received a copy of the GNU General Public License
 | |
| + * along with Cairo_JPG.  If not, see <https://www.gnu.org/licenses/>.
 | |
| + */
 | |
| +
 | |
| +/*! \file cairo_jpg.c
 | |
| + * This file contains two functions for reading and writing JPEG files from
 | |
| + * and to Cairo image surfaces. It uses the functions from the libjpeg.
 | |
| + * Most of the code is directly derived from the online example at
 | |
| + * http://libjpeg-turbo.virtualgl.org/Documentation/Documentation
 | |
| + *
 | |
| + * All prototypes are defined in cairo_jpg.h All functions and their parameters
 | |
| + * and return values are described below directly at the functions. You may
 | |
| + * also have a look at the preprocessor macros defined below.
 | |
| + *
 | |
| + * To compile this code you need to have installed the packages libcairo2-dev
 | |
| + * and libjpeg-dev. Compile with the following to create an object file to link
 | |
| + * with your code:
 | |
| + * gcc -std=c99 -Wall -c `pkg-config cairo libjpeg --cflags --libs` cairo_jpg.c
 | |
| + * Use the following command to include the main() function and create an
 | |
| + * executable for testing of this code:
 | |
| + * gcc -std=c99 -Wall -o cairo_jpg -DCAIRO_JPEG_MAIN `pkg-config cairo libjpeg --cflags --libs` cairo_jpg.c
 | |
| + *
 | |
| + * @author Bernhard R. Fischer, 4096R/8E24F29D bf@abenteuerland.at
 | |
| + * @version 2020/01/18
 | |
| + * @license LGPL3.
 | |
| + */
 | |
| +
 | |
| +#if USE(CAIRO)
 | |
| +
 | |
| +#include "CairoJpegEncoder.h"
 | |
| +
 | |
| +#include <stdio.h>
 | |
| +#include <stdlib.h>
 | |
| +#include <stdint.h>
 | |
| +#include <sys/types.h>
 | |
| +#include <sys/stat.h>
 | |
| +#include <cairo.h>
 | |
| +extern "C" {
 | |
| +#include "jpeglib.h"
 | |
| +}
 | |
| +
 | |
| +/*! Macro to activate main() function. This is only used for testing. Comment
 | |
| + * it out (#undef) if you link this file to your own program.
 | |
| + */
 | |
| +//#define CAIRO_JPEG_MAIN
 | |
| +//
 | |
| +/*! Define this to use an alternate implementation of
 | |
| + * cairo_image_surface_create_from_jpeg() which fstat(3)s the file before
 | |
| + * reading (see below). For huge files this /may/ be slightly faster.
 | |
| + */
 | |
| +#undef CAIRO_JPEG_USE_FSTAT
 | |
| +
 | |
| +/*! This is the read block size for the stream reader
 | |
| + * cairo_image_surface_create_from_jpeg_stream().
 | |
| + */
 | |
| +#ifdef USE_CAIRO_READ_FUNC_LEN_T
 | |
| +#define CAIRO_JPEG_IO_BLOCK_SIZE 4096
 | |
| +#else
 | |
| +/*! Block size has to be one if cairo_read_func_t is in use because of the lack
 | |
| + * to detect EOF (truncated reads).
 | |
| + */
 | |
| +#define CAIRO_JPEG_IO_BLOCK_SIZE 1
 | |
| +/*! In case of original cairo_read_func_t is used fstat() should be used for
 | |
| + * performance reasons (see CAIRO_JPEG_USE_FSTAT above).
 | |
| + */
 | |
| +#define CAIRO_JPEG_USE_FSTAT
 | |
| +#endif
 | |
| +
 | |
| +/*! Define this to test jpeg creation with non-image surfaces. This is only for
 | |
| + * testing and is to be used together with CAIRO_JPEG_MAIN.  
 | |
| + */
 | |
| +#undef CAIRO_JPEG_TEST_SIMILAR
 | |
| +#if defined(CAIRO_JPEG_TEST_SIMILAR) && defined(CAIRO_JPEG_MAIN)
 | |
| +#include <cairo-pdf.h>
 | |
| +#endif
 | |
| +
 | |
| +
 | |
| +#ifndef LIBJPEG_TURBO_VERSION
 | |
| +/*! This function makes a covnersion for "odd" pixel sizes which typically is a
 | |
| + * conversion from a 3-byte to a 4-byte (or more) pixel size or vice versa.
 | |
| + * The conversion is done from the source buffer src to the destination buffer
 | |
| + * dst. The caller MUST ensure that src and dst have the correct memory size.
 | |
| + * This is dw * num for dst and sw * num for src. src and dst may point to the
 | |
| + * same memory address.
 | |
| + * @param dst Pointer to destination buffer.
 | |
| + * @param dw Pixel width (in bytes) of pixels in destination buffer, dw >= 3.
 | |
| + * @param src Pointer to source buffer.
 | |
| + * @param sw Pixel width (in bytes) of pixels in source buffer, sw >= 3.
 | |
| + * @param num Number of pixels to convert, num >= 1;
 | |
| + */
 | |
| +static void pix_conv(unsigned char *dst, int dw, const unsigned char *src, int sw, int num)
 | |
| +{
 | |
| +   int si, di;
 | |
| +
 | |
| +   // safety check
 | |
| +   if (dw < 3 || sw < 3 || dst == NULL || src == NULL)
 | |
| +      return;
 | |
| +
 | |
| +   num--;
 | |
| +   for (si = num * sw, di = num * dw; si >= 0; si -= sw, di -= dw)
 | |
| +   {
 | |
| +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
 | |
| +      dst[di + 2] = src[si    ];
 | |
| +      dst[di + 1] = src[si + 1];
 | |
| +      dst[di + 0] = src[si + 2];
 | |
| +#else
 | |
| +      // FIXME: This is untested, it may be wrong.
 | |
| +      dst[di - 3] = src[si - 3];
 | |
| +      dst[di - 2] = src[si - 2];
 | |
| +      dst[di - 1] = src[si - 1];
 | |
| +#endif
 | |
| +   }
 | |
| +}
 | |
| +#endif
 | |
| +
 | |
| +
 | |
| +/*! This function creates a JPEG file in memory from a Cairo image surface.
 | |
| + * @param sfc Pointer to a Cairo surface. It should be an image surface of
 | |
| + * either CAIRO_FORMAT_ARGB32 or CAIRO_FORMAT_RGB24. Other formats are
 | |
| + * converted to CAIRO_FORMAT_RGB24 before compression.
 | |
| + * Please note that this may give unexpected results because JPEG does not
 | |
| + * support transparency. Thus, default background color is used to replace
 | |
| + * transparent regions. The default background color is black if not specified
 | |
| + * explicitly. Thus converting e.g. PDF surfaces without having any specific
 | |
| + * background color set will apear with black background and not white as you
 | |
| + * might expect. In such cases it is suggested to manually convert the surface
 | |
| + * to RGB24 before calling this function.
 | |
| + * @param data Pointer to a memory pointer. This parameter receives a pointer
 | |
| + * to the memory area where the final JPEG data is found in memory. This
 | |
| + * function reserves the memory properly and it has to be freed by the caller
 | |
| + * with free(3).
 | |
| + * @param len Pointer to a variable of type size_t which will receive the final
 | |
| + * lenght of the memory buffer.
 | |
| + * @param quality Compression quality, 0-100.
 | |
| + * @return On success the function returns CAIRO_STATUS_SUCCESS. In case of
 | |
| + * error CAIRO_STATUS_INVALID_FORMAT is returned.
 | |
| + */
 | |
| +cairo_status_t cairo_image_surface_write_to_jpeg_mem(cairo_surface_t *sfc, unsigned char **data, size_t *len, int quality)
 | |
| +{
 | |
| +   struct jpeg_compress_struct cinfo;
 | |
| +   struct jpeg_error_mgr jerr;
 | |
| +   JSAMPROW row_pointer[1];
 | |
| +   cairo_surface_t *other = NULL;
 | |
| +
 | |
| +   // check valid input format (must be IMAGE_SURFACE && (ARGB32 || RGB24))
 | |
| +   if (cairo_surface_get_type(sfc) != CAIRO_SURFACE_TYPE_IMAGE ||
 | |
| +         (cairo_image_surface_get_format(sfc) != CAIRO_FORMAT_ARGB32 &&
 | |
| +         cairo_image_surface_get_format(sfc) != CAIRO_FORMAT_RGB24))
 | |
| +   {
 | |
| +      // create a similar surface with a proper format if supplied input format
 | |
| +      // does not fulfill the requirements
 | |
| +      double x1, y1, x2, y2;
 | |
| +      other = sfc;
 | |
| +      cairo_t *ctx = cairo_create(other);
 | |
| +      // get extents of original surface
 | |
| +      cairo_clip_extents(ctx, &x1, &y1, &x2, &y2);
 | |
| +      cairo_destroy(ctx);
 | |
| +
 | |
| +      // create new image surface
 | |
| +      sfc = cairo_surface_create_similar_image(other, CAIRO_FORMAT_RGB24, x2 - x1, y2 - y1);
 | |
| +      if (cairo_surface_status(sfc) != CAIRO_STATUS_SUCCESS)
 | |
| +         return CAIRO_STATUS_INVALID_FORMAT;
 | |
| +
 | |
| +      // paint original surface to new surface
 | |
| +      ctx = cairo_create(sfc);
 | |
| +      cairo_set_source_surface(ctx, other, 0, 0);
 | |
| +      cairo_paint(ctx);
 | |
| +      cairo_destroy(ctx);
 | |
| +   }
 | |
| +
 | |
| +   // finish queued drawing operations
 | |
| +   cairo_surface_flush(sfc);
 | |
| +
 | |
| +   // init jpeg compression structures
 | |
| +   cinfo.err = jpeg_std_error(&jerr);
 | |
| +   jpeg_create_compress(&cinfo);
 | |
| +
 | |
| +   // set compression parameters
 | |
| +   unsigned long targetSize;
 | |
| +   jpeg_mem_dest(&cinfo, data, &targetSize);
 | |
| +
 | |
| +   cinfo.image_width = cairo_image_surface_get_width(sfc);
 | |
| +   cinfo.image_height = cairo_image_surface_get_height(sfc);
 | |
| +#ifdef LIBJPEG_TURBO_VERSION
 | |
| +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
 | |
| +   //cinfo.in_color_space = JCS_EXT_BGRX;
 | |
| +   cinfo.in_color_space = cairo_image_surface_get_format(sfc) == CAIRO_FORMAT_ARGB32 ? JCS_EXT_BGRA : JCS_EXT_BGRX;
 | |
| +#else
 | |
| +   //cinfo.in_color_space = JCS_EXT_XRGB;
 | |
| +   cinfo.in_color_space = cairo_image_surface_get_format(sfc) == CAIRO_FORMAT_ARGB32 ? JCS_EXT_ARGB : JCS_EXT_XRGB;
 | |
| +#endif
 | |
| +   cinfo.input_components = 4;
 | |
| +#else
 | |
| +   cinfo.in_color_space = JCS_RGB;
 | |
| +   cinfo.input_components = 3;
 | |
| +#endif
 | |
| +   jpeg_set_defaults(&cinfo);
 | |
| +   jpeg_set_quality(&cinfo, quality, TRUE);
 | |
| +
 | |
| +   // start compressor
 | |
| +   jpeg_start_compress(&cinfo, TRUE);
 | |
| +
 | |
| +   // loop over all lines and compress
 | |
| +   while (cinfo.next_scanline < cinfo.image_height)
 | |
| +   {
 | |
| +#ifdef LIBJPEG_TURBO_VERSION
 | |
| +      row_pointer[0] = cairo_image_surface_get_data(sfc) + (cinfo.next_scanline
 | |
| +            * cairo_image_surface_get_stride(sfc));
 | |
| +#else
 | |
| +      unsigned char row_buf[3 * cinfo.image_width];
 | |
| +      pix_conv(row_buf, 3, cairo_image_surface_get_data(sfc) +
 | |
| +            (cinfo.next_scanline * cairo_image_surface_get_stride(sfc)), 4, cinfo.image_width);
 | |
| +      row_pointer[0] = row_buf;
 | |
| +#endif
 | |
| +      (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
 | |
| +   }
 | |
| +
 | |
| +   // finalize and close everything
 | |
| +   jpeg_finish_compress(&cinfo);
 | |
| +   jpeg_destroy_compress(&cinfo);
 | |
| +
 | |
| +   // destroy temporary image surface (if available)
 | |
| +   if (other != NULL)
 | |
| +      cairo_surface_destroy(sfc);
 | |
| +
 | |
| +   *len = targetSize;
 | |
| +   return CAIRO_STATUS_SUCCESS;
 | |
| +}
 | |
| +
 | |
| +#endif
 | |
| diff --git a/Source/WebKit/UIProcess/Inspector/Agents/CairoJpegEncoder.h b/Source/WebKit/UIProcess/Inspector/Agents/CairoJpegEncoder.h
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..4ec8b96bbbddf8a7b042f53a8068754a384fc7ad
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/UIProcess/Inspector/Agents/CairoJpegEncoder.h
 | |
| @@ -0,0 +1,30 @@
 | |
| +/*
 | |
| + * Copyright (C) Microsoft. All rights reserved.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 | |
| + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 | |
| + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 | |
| + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 | |
| + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 | |
| + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 | |
| + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 | |
| + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 | |
| + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 | |
| + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 | |
| + * THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#pragma once
 | |
| +
 | |
| +#include <cairo.h>
 | |
| +
 | |
| +cairo_status_t cairo_image_surface_write_to_jpeg_mem(cairo_surface_t *sfc, unsigned char **data, size_t *len, int quality);
 | |
| diff --git a/Source/WebKit/UIProcess/Inspector/Agents/InspectorScreencastAgent.cpp b/Source/WebKit/UIProcess/Inspector/Agents/InspectorScreencastAgent.cpp
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..68f4dfb777dc4b51d4e3e2f3f849131d40dd9879
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/UIProcess/Inspector/Agents/InspectorScreencastAgent.cpp
 | |
| @@ -0,0 +1,302 @@
 | |
| +/*
 | |
| + * Copyright (C) 2020 Microsoft Corporation.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
| + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#include "config.h"
 | |
| +#include "InspectorScreencastAgent.h"
 | |
| +
 | |
| +#include "GenericCallback.h"
 | |
| +#include "PageClient.h"
 | |
| +#include "ScreencastEncoder.h"
 | |
| +#include "WebPageInspectorController.h"
 | |
| +#include "WebPageProxy.h"
 | |
| +#include "WebsiteDataStore.h"
 | |
| +#include <pal/crypto/CryptoDigest.h>
 | |
| +#include <JavaScriptCore/InspectorFrontendRouter.h>
 | |
| +#include <WebCore/NotImplemented.h>
 | |
| +#include <wtf/RunLoop.h>
 | |
| +#include <wtf/UUID.h>
 | |
| +#include <wtf/text/Base64.h>
 | |
| +
 | |
| +#if USE(CAIRO)
 | |
| +#include "CairoJpegEncoder.h"
 | |
| +#include "DrawingAreaProxyCoordinatedGraphics.h"
 | |
| +#include "DrawingAreaProxy.h"
 | |
| +#endif
 | |
| +
 | |
| +#if PLATFORM(MAC)
 | |
| +#include <WebCore/ImageBufferUtilitiesCG.h>
 | |
| +#endif
 | |
| +
 | |
| +namespace WebKit {
 | |
| +
 | |
| +const int kMaxFramesInFlight = 1;
 | |
| +
 | |
| +using namespace Inspector;
 | |
| +
 | |
| +InspectorScreencastAgent::InspectorScreencastAgent(BackendDispatcher& backendDispatcher, Inspector::FrontendRouter& frontendRouter, WebPageProxy& page)
 | |
| +    : InspectorAgentBase("Screencast"_s)
 | |
| +    , m_frontendDispatcher(makeUnique<ScreencastFrontendDispatcher>(frontendRouter))
 | |
| +    , m_backendDispatcher(ScreencastBackendDispatcher::create(backendDispatcher, this))
 | |
| +    , m_page(page)
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +InspectorScreencastAgent::~InspectorScreencastAgent()
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +void InspectorScreencastAgent::didCreateFrontendAndBackend(FrontendRouter*, BackendDispatcher*)
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +void InspectorScreencastAgent::willDestroyFrontendAndBackend(DisconnectReason)
 | |
| +{
 | |
| +    if (!m_encoder)
 | |
| +        return;
 | |
| +
 | |
| +    // The agent may be destroyed when the callback is invoked.
 | |
| +    m_encoder->finish([sessionID = m_page.websiteDataStore().sessionID(), screencastID = WTFMove(m_currentScreencastID)] {
 | |
| +        if (WebPageInspectorController::observer())
 | |
| +            WebPageInspectorController::observer()->didFinishScreencast(sessionID, screencastID);
 | |
| +    });
 | |
| +
 | |
| +    m_encoder = nullptr;
 | |
| +}
 | |
| +
 | |
| +#if USE(CAIRO)
 | |
| +void InspectorScreencastAgent::didPaint(cairo_surface_t* surface)
 | |
| +{
 | |
| +#if PLATFORM(WPE)
 | |
| +    // Get actual image size (in device pixels).
 | |
| +    WebCore::IntSize displaySize(cairo_image_surface_get_width(surface), cairo_image_surface_get_height(surface));
 | |
| +
 | |
| +    WebCore::IntSize drawingAreaSize = m_page.drawingArea()->size();
 | |
| +    drawingAreaSize.scale(m_page.deviceScaleFactor());
 | |
| +    if (drawingAreaSize != displaySize) {
 | |
| +        return;
 | |
| +    }
 | |
| +
 | |
| +#else
 | |
| +    WebCore::IntSize displaySize = m_page.drawingArea()->size();
 | |
| +#endif
 | |
| +    if (m_encoder)
 | |
| +        m_encoder->encodeFrame(surface, displaySize);
 | |
| +    if (m_screencast) {
 | |
| +
 | |
| +        {
 | |
| +            // Do not send the same frame over and over.
 | |
| +            unsigned char *data = cairo_image_surface_get_data(surface);
 | |
| +            int stride = cairo_image_surface_get_stride(surface);
 | |
| +            int height = cairo_image_surface_get_height(surface);
 | |
| +            auto cryptoDigest = PAL::CryptoDigest::create(PAL::CryptoDigest::Algorithm::SHA_1);
 | |
| +            cryptoDigest->addBytes(data, stride * height);
 | |
| +            auto digest = cryptoDigest->computeHash();
 | |
| +            if (m_lastFrameDigest == digest)
 | |
| +                return;
 | |
| +            m_lastFrameDigest = digest;
 | |
| +        }
 | |
| +
 | |
| +        if (m_screencastFramesInFlight > kMaxFramesInFlight)
 | |
| +            return;
 | |
| +        // Scale image to fit width / height
 | |
| +        double scale = std::min(m_screencastWidth / displaySize.width(), m_screencastHeight / displaySize.height());
 | |
| +        RefPtr<cairo_surface_t> scaledSurface;
 | |
| +        if (scale < 1) {
 | |
| +            WebCore::IntSize scaledSize = displaySize;
 | |
| +            scaledSize.scale(scale);
 | |
| +            cairo_matrix_t transform;
 | |
| +            cairo_matrix_init_scale(&transform, scale, scale);
 | |
| +            scaledSurface = adoptRef(cairo_image_surface_create(CAIRO_FORMAT_ARGB32, scaledSize.width(), scaledSize.height()));
 | |
| +            RefPtr<cairo_t> cr = adoptRef(cairo_create(scaledSurface.get()));
 | |
| +            cairo_transform(cr.get(), &transform);
 | |
| +            cairo_set_source_surface(cr.get(), surface, 0, 0);
 | |
| +            cairo_paint(cr.get());
 | |
| +            surface = scaledSurface.get();
 | |
| +        }
 | |
| +        unsigned char *data = nullptr;
 | |
| +        size_t len = 0;
 | |
| +        cairo_image_surface_write_to_jpeg_mem(surface, &data, &len, m_screencastQuality);
 | |
| +        String result = base64EncodeToString(data, len);
 | |
| +        ++m_screencastFramesInFlight;
 | |
| +        m_frontendDispatcher->screencastFrame(result, displaySize.width(), displaySize.height());
 | |
| +    }
 | |
| +}
 | |
| +#endif
 | |
| +
 | |
| +Inspector::Protocol::ErrorStringOr<String /* screencastID */> InspectorScreencastAgent::startVideo(const String& file, int width, int height, int toolbarHeight)
 | |
| +{
 | |
| +    if (m_encoder)
 | |
| +        return makeUnexpected("Already recording"_s);
 | |
| +
 | |
| +    if (width < 10 || width > 10000 || height < 10 || height > 10000)
 | |
| +        return makeUnexpected("Invalid size"_s);
 | |
| +
 | |
| +    String errorString;
 | |
| +    m_encoder = ScreencastEncoder::create(errorString, file, WebCore::IntSize(width, height));
 | |
| +    if (!m_encoder)
 | |
| +        return makeUnexpected(errorString);
 | |
| +
 | |
| +    m_currentScreencastID = createVersion4UUIDString();
 | |
| +
 | |
| +#if PLATFORM(MAC)
 | |
| +    m_encoder->setOffsetTop(toolbarHeight);
 | |
| +#endif
 | |
| +
 | |
| +    kickFramesStarted();
 | |
| +    return { { m_currentScreencastID } };
 | |
| +}
 | |
| +
 | |
| +void InspectorScreencastAgent::stopVideo(Ref<StopVideoCallback>&& callback)
 | |
| +{
 | |
| +    if (!m_encoder) {
 | |
| +        callback->sendFailure("Not recording"_s);
 | |
| +        return;
 | |
| +    }
 | |
| +
 | |
| +    // The agent may be destroyed when the callback is invoked.
 | |
| +    m_encoder->finish([sessionID = m_page.websiteDataStore().sessionID(), screencastID = WTFMove(m_currentScreencastID), callback = WTFMove(callback)] {
 | |
| +        if (WebPageInspectorController::observer())
 | |
| +            WebPageInspectorController::observer()->didFinishScreencast(sessionID, screencastID);
 | |
| +        callback->sendSuccess();
 | |
| +    });
 | |
| +    m_encoder = nullptr;
 | |
| +    if (!m_screencast)
 | |
| +      m_framesAreGoing = false;
 | |
| +}
 | |
| +
 | |
| +Inspector::Protocol::ErrorStringOr<int /* generation */> InspectorScreencastAgent::startScreencast(int width, int height, int toolbarHeight, int quality)
 | |
| +{
 | |
| +    if (m_screencast)
 | |
| +        return makeUnexpected("Already screencasting"_s);
 | |
| +    m_screencast = true;
 | |
| +    m_screencastWidth = width;
 | |
| +    m_screencastHeight = height;
 | |
| +    m_screencastQuality = quality;
 | |
| +    m_screencastToolbarHeight = toolbarHeight;
 | |
| +    m_screencastFramesInFlight = 0;
 | |
| +    ++m_screencastGeneration;
 | |
| +    kickFramesStarted();
 | |
| +    return m_screencastGeneration;
 | |
| +}
 | |
| +
 | |
| +Inspector::Protocol::ErrorStringOr<void> InspectorScreencastAgent::screencastFrameAck(int generation)
 | |
| +{
 | |
| +    if (m_screencastGeneration != generation)
 | |
| +        return { };
 | |
| +    --m_screencastFramesInFlight;
 | |
| +    return { };
 | |
| +}
 | |
| +
 | |
| +Inspector::Protocol::ErrorStringOr<void> InspectorScreencastAgent::stopScreencast()
 | |
| +{
 | |
| +    if (!m_screencast)
 | |
| +        return makeUnexpected("Not screencasting"_s);
 | |
| +    m_screencast = false;
 | |
| +    if (!m_encoder)
 | |
| +      m_framesAreGoing = false;
 | |
| +    return { };
 | |
| +}
 | |
| +
 | |
| +void InspectorScreencastAgent::kickFramesStarted()
 | |
| +{
 | |
| +    if (!m_framesAreGoing) {
 | |
| +        m_framesAreGoing = true;
 | |
| +#if !PLATFORM(WPE)
 | |
| +        scheduleFrameEncoding();
 | |
| +#endif
 | |
| +    }
 | |
| +    m_page.forceRepaint([] { });
 | |
| +}
 | |
| +
 | |
| +#if !PLATFORM(WPE)
 | |
| +void InspectorScreencastAgent::scheduleFrameEncoding()
 | |
| +{
 | |
| +    if (!m_encoder && !m_screencast)
 | |
| +        return;
 | |
| +
 | |
| +    RunLoop::main().dispatchAfter(Seconds(1.0 / ScreencastEncoder::fps), [agent = WeakPtr { this }]() mutable {
 | |
| +        if (!agent)
 | |
| +            return;
 | |
| +
 | |
| +        agent->encodeFrame();
 | |
| +        agent->scheduleFrameEncoding();
 | |
| +    });
 | |
| +}
 | |
| +#endif
 | |
| +
 | |
| +#if PLATFORM(MAC)
 | |
| +void InspectorScreencastAgent::encodeFrame()
 | |
| +{
 | |
| +    if (!m_encoder && !m_screencast)
 | |
| +        return;
 | |
| +    RetainPtr<CGImageRef> imageRef = m_page.pageClient().takeSnapshotForAutomation();
 | |
| +    if (m_screencast && m_screencastFramesInFlight <= kMaxFramesInFlight) {
 | |
| +        CGImage* imagePtr = imageRef.get();
 | |
| +        WebCore::IntSize imageSize(CGImageGetWidth(imagePtr), CGImageGetHeight(imagePtr));
 | |
| +        WebCore::IntSize displaySize = imageSize;
 | |
| +        displaySize.contract(0, m_screencastToolbarHeight);
 | |
| +        double scale = std::min(m_screencastWidth / displaySize.width(), m_screencastHeight / displaySize.height());
 | |
| +        RetainPtr<CGImageRef> scaledImageRef;
 | |
| +        if (scale < 1 || m_screencastToolbarHeight) {
 | |
| +            WebCore::IntSize screencastSize = displaySize;
 | |
| +            screencastSize.scale(scale);
 | |
| +            WebCore::IntSize scaledImageSize = imageSize;
 | |
| +            scaledImageSize.scale(scale);
 | |
| +            auto colorSpace = adoptCF(CGColorSpaceCreateDeviceRGB());
 | |
| +            auto context = adoptCF(CGBitmapContextCreate(nullptr, screencastSize.width(), screencastSize.height(), 8, 4 * screencastSize.width(), colorSpace.get(), (CGBitmapInfo)kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host));
 | |
| +            CGContextDrawImage(context.get(), CGRectMake(0, 0, scaledImageSize.width(), scaledImageSize.height()), imagePtr);
 | |
| +            scaledImageRef = adoptCF(CGBitmapContextCreateImage(context.get()));
 | |
| +            imagePtr = scaledImageRef.get();
 | |
| +        }
 | |
| +        auto data = WebCore::data(imagePtr, WebCore::jpegUTI(), m_screencastQuality * 0.1);
 | |
| +
 | |
| +        // Do not send the same frame over and over.
 | |
| +        auto cryptoDigest = PAL::CryptoDigest::create(PAL::CryptoDigest::Algorithm::SHA_1);
 | |
| +        cryptoDigest->addBytes(data.data(), data.size());
 | |
| +        auto digest = cryptoDigest->computeHash();
 | |
| +        if (m_lastFrameDigest != digest) {
 | |
| +            String base64Data = base64EncodeToString(data);
 | |
| +            ++m_screencastFramesInFlight;
 | |
| +            m_frontendDispatcher->screencastFrame(base64Data, displaySize.width(), displaySize.height());
 | |
| +            m_lastFrameDigest = digest;
 | |
| +        }
 | |
| +    }
 | |
| +    if (m_encoder)
 | |
| +        m_encoder->encodeFrame(WTFMove(imageRef));
 | |
| +}
 | |
| +#endif
 | |
| +
 | |
| +#if USE(CAIRO) && !PLATFORM(WPE)
 | |
| +void InspectorScreencastAgent::encodeFrame()
 | |
| +{
 | |
| +    if (!m_encoder && !m_screencast)
 | |
| +        return;
 | |
| +
 | |
| +    if (auto* drawingArea = m_page.drawingArea())
 | |
| +        static_cast<DrawingAreaProxyCoordinatedGraphics*>(drawingArea)->captureFrame();
 | |
| +}
 | |
| +#endif
 | |
| +
 | |
| +} // namespace WebKit
 | |
| diff --git a/Source/WebKit/UIProcess/Inspector/Agents/InspectorScreencastAgent.h b/Source/WebKit/UIProcess/Inspector/Agents/InspectorScreencastAgent.h
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..d28dde452275f18739e3b1c8d709185c9bf0f40e
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/UIProcess/Inspector/Agents/InspectorScreencastAgent.h
 | |
| @@ -0,0 +1,97 @@
 | |
| +/*
 | |
| + * Copyright (C) 2020 Microsoft Corporation.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
| + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#pragma once
 | |
| +
 | |
| +#include <JavaScriptCore/InspectorAgentBase.h>
 | |
| +#include <JavaScriptCore/InspectorBackendDispatchers.h>
 | |
| +#include <JavaScriptCore/InspectorFrontendDispatchers.h>
 | |
| +
 | |
| +#if USE(CAIRO)
 | |
| +#include <cairo.h>
 | |
| +#endif
 | |
| +
 | |
| +#include <wtf/Forward.h>
 | |
| +#include <wtf/Noncopyable.h>
 | |
| +#include <wtf/WeakPtr.h>
 | |
| +
 | |
| +namespace Inspector {
 | |
| +class BackendDispatcher;
 | |
| +class FrontendChannel;
 | |
| +class FrontendRouter;
 | |
| +class ScreencastFrontendDispatcher;
 | |
| +}
 | |
| +
 | |
| +namespace WebKit {
 | |
| +
 | |
| +class ScreencastEncoder;
 | |
| +class WebPageProxy;
 | |
| +
 | |
| +class InspectorScreencastAgent : public Inspector::InspectorAgentBase, public Inspector::ScreencastBackendDispatcherHandler, public CanMakeWeakPtr<InspectorScreencastAgent> {
 | |
| +    WTF_MAKE_NONCOPYABLE(InspectorScreencastAgent);
 | |
| +    WTF_MAKE_FAST_ALLOCATED;
 | |
| +public:
 | |
| +    InspectorScreencastAgent(Inspector::BackendDispatcher& backendDispatcher, Inspector::FrontendRouter& frontendRouter, WebPageProxy& page);
 | |
| +    ~InspectorScreencastAgent() override;
 | |
| +
 | |
| +    void didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*) override;
 | |
| +    void willDestroyFrontendAndBackend(Inspector::DisconnectReason) override;
 | |
| +
 | |
| +#if USE(CAIRO)
 | |
| +    void didPaint(cairo_surface_t*);
 | |
| +#endif
 | |
| +
 | |
| +    Inspector::Protocol::ErrorStringOr<String /* screencastID */> startVideo(const String& file, int width, int height, int toolbarHeight) override;
 | |
| +    void stopVideo(Ref<StopVideoCallback>&&) override;
 | |
| +
 | |
| +    Inspector::Protocol::ErrorStringOr<int /* generation */> startScreencast(int width, int height, int toolbarHeight, int quality) override;
 | |
| +    Inspector::Protocol::ErrorStringOr<void> screencastFrameAck(int generation) override;
 | |
| +    Inspector::Protocol::ErrorStringOr<void> stopScreencast() override;
 | |
| +
 | |
| +private:
 | |
| +#if !PLATFORM(WPE)
 | |
| +    void scheduleFrameEncoding();
 | |
| +    void encodeFrame();
 | |
| +#endif
 | |
| +
 | |
| +    void kickFramesStarted();
 | |
| +
 | |
| +    std::unique_ptr<Inspector::ScreencastFrontendDispatcher> m_frontendDispatcher;
 | |
| +    Ref<Inspector::ScreencastBackendDispatcher> m_backendDispatcher;
 | |
| +    WebPageProxy& m_page;
 | |
| +    Vector<uint8_t> m_lastFrameDigest;
 | |
| +    RefPtr<ScreencastEncoder> m_encoder;
 | |
| +    bool m_screencast = false;
 | |
| +    bool m_framesAreGoing = false;
 | |
| +    double m_screencastWidth = 0;
 | |
| +    double m_screencastHeight = 0;
 | |
| +    int m_screencastQuality = 0;
 | |
| +    int m_screencastToolbarHeight = 0;
 | |
| +    int m_screencastGeneration = 0;
 | |
| +    int m_screencastFramesInFlight = 0;
 | |
| +    String m_currentScreencastID;
 | |
| +};
 | |
| +
 | |
| +} // namespace WebKit
 | |
| diff --git a/Source/WebKit/UIProcess/Inspector/Agents/ScreencastEncoder.cpp b/Source/WebKit/UIProcess/Inspector/Agents/ScreencastEncoder.cpp
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..489fb9a4a98de71526a6c3d6746e8b7192bac9b8
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/UIProcess/Inspector/Agents/ScreencastEncoder.cpp
 | |
| @@ -0,0 +1,379 @@
 | |
| +/*
 | |
| + * Copyright (c) 2010, The WebM Project authors. All rights reserved.
 | |
| + * Copyright (c) 2013 The Chromium Authors. All rights reserved.
 | |
| + * Copyright (C) 2020 Microsoft Corporation.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
| + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#include "config.h"
 | |
| +#include "ScreencastEncoder.h"
 | |
| +
 | |
| +#include "WebMFileWriter.h"
 | |
| +#include <algorithm>
 | |
| +#include <libyuv.h>
 | |
| +#include <vpx/vp8.h>
 | |
| +#include <vpx/vp8cx.h>
 | |
| +#include <vpx/vpx_encoder.h>
 | |
| +#include <wtf/RunLoop.h>
 | |
| +#include <wtf/UniqueArray.h>
 | |
| +#include <wtf/WorkQueue.h>
 | |
| +#include <wtf/text/StringConcatenateNumbers.h>
 | |
| +
 | |
| +#if USE(CAIRO)
 | |
| +#include <WebCore/RefPtrCairo.h>
 | |
| +#endif
 | |
| +
 | |
| +using namespace WebCore;
 | |
| +
 | |
| +namespace WebKit {
 | |
| +
 | |
| +namespace {
 | |
| +
 | |
| +// Number of timebase unints per one frame.
 | |
| +constexpr int timeScale = 1000;
 | |
| +
 | |
| +// Defines the dimension of a macro block. This is used to compute the active
 | |
| +// map for the encoder.
 | |
| +const int kMacroBlockSize = 16;
 | |
| +
 | |
| +void createImage(unsigned int width, unsigned int height,
 | |
| +                 std::unique_ptr<vpx_image_t>& out_image,
 | |
| +                 std::unique_ptr<uint8_t[]>& out_image_buffer) {
 | |
| +  std::unique_ptr<vpx_image_t> image(new vpx_image_t());
 | |
| +  memset(image.get(), 0, sizeof(vpx_image_t));
 | |
| +
 | |
| +  // libvpx seems to require both to be assigned.
 | |
| +  image->d_w = width;
 | |
| +  image->w = width;
 | |
| +  image->d_h = height;
 | |
| +  image->h = height;
 | |
| +
 | |
| +  // I420
 | |
| +  image->fmt = VPX_IMG_FMT_YV12;
 | |
| +  image->x_chroma_shift = 1;
 | |
| +  image->y_chroma_shift = 1;
 | |
| +
 | |
| +  // libyuv's fast-path requires 16-byte aligned pointers and strides, so pad
 | |
| +  // the Y, U and V planes' strides to multiples of 16 bytes.
 | |
| +  const int y_stride = ((image->w - 1) & ~15) + 16;
 | |
| +  const int uv_unaligned_stride = y_stride >> image->x_chroma_shift;
 | |
| +  const int uv_stride = ((uv_unaligned_stride - 1) & ~15) + 16;
 | |
| +
 | |
| +  // libvpx accesses the source image in macro blocks, and will over-read
 | |
| +  // if the image is not padded out to the next macroblock: crbug.com/119633.
 | |
| +  // Pad the Y, U and V planes' height out to compensate.
 | |
| +  // Assuming macroblocks are 16x16, aligning the planes' strides above also
 | |
| +  // macroblock aligned them.
 | |
| +  static_assert(kMacroBlockSize == 16, "macroblock_size_not_16");
 | |
| +  const int y_rows = ((image->h - 1) & ~(kMacroBlockSize-1)) + kMacroBlockSize;
 | |
| +  const int uv_rows = y_rows >> image->y_chroma_shift;
 | |
| +
 | |
| +  // Allocate a YUV buffer large enough for the aligned data & padding.
 | |
| +  const int buffer_size = y_stride * y_rows + 2*uv_stride * uv_rows;
 | |
| +  std::unique_ptr<uint8_t[]> image_buffer(new uint8_t[buffer_size]);
 | |
| +
 | |
| +  // Reset image value to 128 so we just need to fill in the y plane.
 | |
| +  memset(image_buffer.get(), 128, buffer_size);
 | |
| +
 | |
| +  // Fill in the information for |image_|.
 | |
| +  unsigned char* uchar_buffer =
 | |
| +      reinterpret_cast<unsigned char*>(image_buffer.get());
 | |
| +  image->planes[0] = uchar_buffer;
 | |
| +  image->planes[1] = image->planes[0] + y_stride * y_rows;
 | |
| +  image->planes[2] = image->planes[1] + uv_stride * uv_rows;
 | |
| +  image->stride[0] = y_stride;
 | |
| +  image->stride[1] = uv_stride;
 | |
| +  image->stride[2] = uv_stride;
 | |
| +
 | |
| +  out_image = std::move(image);
 | |
| +  out_image_buffer = std::move(image_buffer);
 | |
| +}
 | |
| +
 | |
| +} // namespace
 | |
| +
 | |
| +class ScreencastEncoder::VPXFrame {
 | |
| +    WTF_MAKE_NONCOPYABLE(VPXFrame);
 | |
| +    WTF_MAKE_FAST_ALLOCATED;
 | |
| +public:
 | |
| +#if USE(CAIRO)
 | |
| +    explicit VPXFrame(RefPtr<cairo_surface_t>&& surface)
 | |
| +        : m_surface(WTFMove(surface))
 | |
| +    { }
 | |
| +#elif PLATFORM(MAC)
 | |
| +    VPXFrame(RetainPtr<CGImageRef> windowImage, int offsetTop)
 | |
| +        : m_windowImage(WTFMove(windowImage))
 | |
| +        , m_offsetTop(offsetTop)
 | |
| +    { }
 | |
| +#endif
 | |
| +
 | |
| +    void setDuration(Seconds duration) { m_duration = duration; }
 | |
| +    Seconds duration() const { return m_duration; }
 | |
| +
 | |
| +    void convertToVpxImage(vpx_image_t* image)
 | |
| +    {
 | |
| +#if USE(CAIRO)
 | |
| +        // Convert the updated region to YUV ready for encoding.
 | |
| +        const uint8_t* argb_data = cairo_image_surface_get_data(m_surface.get());
 | |
| +        int argb_stride = cairo_image_surface_get_stride(m_surface.get());
 | |
| +#elif PLATFORM(MAC)
 | |
| +        int argb_stride = image->w * 4;
 | |
| +        UniqueArray<uint8_t> buffer = makeUniqueArray<uint8_t>(argb_stride * image->h);
 | |
| +        uint8_t* argb_data = buffer.get();
 | |
| +        ScreencastEncoder::imageToARGB(m_windowImage.get(), argb_data, image->w, image->h, m_offsetTop);
 | |
| +#endif
 | |
| +        const int y_stride = image->stride[0];
 | |
| +        ASSERT(image->stride[1] == image->stride[2]);
 | |
| +        const int uv_stride = image->stride[1];
 | |
| +        uint8_t* y_data = image->planes[0];
 | |
| +        uint8_t* u_data = image->planes[1];
 | |
| +        uint8_t* v_data = image->planes[2];
 | |
| +
 | |
| +        // TODO: redraw only damaged regions?
 | |
| +        libyuv::ARGBToI420(argb_data, argb_stride,
 | |
| +                            y_data, y_stride,
 | |
| +                            u_data, uv_stride,
 | |
| +                            v_data, uv_stride,
 | |
| +                            image->w, image->h);
 | |
| +    }
 | |
| +
 | |
| +private:
 | |
| +#if USE(CAIRO)
 | |
| +    RefPtr<cairo_surface_t> m_surface;
 | |
| +#elif PLATFORM(MAC)
 | |
| +    RetainPtr<CGImageRef> m_windowImage;
 | |
| +    int m_offsetTop { 0 };
 | |
| +#endif
 | |
| +    Seconds m_duration;
 | |
| +};
 | |
| +
 | |
| +
 | |
| +class ScreencastEncoder::VPXCodec {
 | |
| +public:
 | |
| +    VPXCodec(vpx_codec_ctx_t codec, vpx_codec_enc_cfg_t cfg, FILE* file)
 | |
| +        : m_encoderQueue(WorkQueue::create("Screencast encoder"))
 | |
| +        , m_codec(codec)
 | |
| +        , m_cfg(cfg)
 | |
| +        , m_file(file)
 | |
| +        , m_writer(new WebMFileWriter(file, &m_cfg))
 | |
| +    {
 | |
| +        createImage(cfg.g_w, cfg.g_h, m_image, m_imageBuffer);
 | |
| +    }
 | |
| +
 | |
| +    void encodeFrameAsync(std::unique_ptr<VPXFrame>&& frame)
 | |
| +    {
 | |
| +        m_encoderQueue->dispatch([this, frame = WTFMove(frame)] {
 | |
| +            frame->convertToVpxImage(m_image.get());
 | |
| +            double frameCount = frame->duration().seconds() * fps;
 | |
| +            // For long duration repeat frame at 1 fps to ensure last frame duration is short enough.
 | |
| +            // TODO: figure out why simply passing duration doesn't work well.
 | |
| +            for (;frameCount > 1.5; frameCount -= 1) {
 | |
| +                encodeFrame(m_image.get(), timeScale);
 | |
| +            }
 | |
| +            encodeFrame(m_image.get(), std::max<int>(1, frameCount * timeScale));
 | |
| +        });
 | |
| +    }
 | |
| +
 | |
| +    void finishAsync(Function<void()>&& callback)
 | |
| +    {
 | |
| +        m_encoderQueue->dispatch([this, callback = WTFMove(callback)] {
 | |
| +            finish();
 | |
| +            callback();
 | |
| +        });
 | |
| +    }
 | |
| +
 | |
| +private:
 | |
| +    bool encodeFrame(vpx_image_t *img, int duration)
 | |
| +    {
 | |
| +        vpx_codec_iter_t iter = nullptr;
 | |
| +        const vpx_codec_cx_pkt_t *pkt = nullptr;
 | |
| +        int flags = 0;
 | |
| +        const vpx_codec_err_t res = vpx_codec_encode(&m_codec, img, m_pts, duration, flags, VPX_DL_REALTIME);
 | |
| +        if (res != VPX_CODEC_OK) {
 | |
| +            fprintf(stderr, "Failed to encode frame: %s\n", vpx_codec_error(&m_codec));
 | |
| +            return false;
 | |
| +        }
 | |
| +
 | |
| +        bool gotPkts = false;
 | |
| +        while ((pkt = vpx_codec_get_cx_data(&m_codec, &iter)) != nullptr) {
 | |
| +            gotPkts = true;
 | |
| +
 | |
| +            if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) {
 | |
| +                if (!m_writer->writeFrame(pkt)) {
 | |
| +                    fprintf(stderr, "Failed to write compressed frame\n");
 | |
| +                    return false;
 | |
| +                }
 | |
| +                ++m_frameCount;
 | |
| +                m_pts += pkt->data.frame.duration;
 | |
| +            }
 | |
| +        }
 | |
| +
 | |
| +        return gotPkts;
 | |
| +    }
 | |
| +
 | |
| +    void finish()
 | |
| +    {
 | |
| +        // Flush encoder.
 | |
| +        while (encodeFrame(nullptr, 1))
 | |
| +            ++m_frameCount;
 | |
| +
 | |
| +        m_writer->finish();
 | |
| +        fclose(m_file);
 | |
| +    }
 | |
| +
 | |
| +    Ref<WorkQueue> m_encoderQueue;
 | |
| +    vpx_codec_ctx_t m_codec;
 | |
| +    vpx_codec_enc_cfg_t m_cfg;
 | |
| +    FILE* m_file { nullptr };
 | |
| +    std::unique_ptr<WebMFileWriter> m_writer;
 | |
| +    int m_frameCount { 0 };
 | |
| +    int64_t m_pts { 0 };
 | |
| +    std::unique_ptr<uint8_t[]> m_imageBuffer;
 | |
| +    std::unique_ptr<vpx_image_t> m_image;
 | |
| +};
 | |
| +
 | |
| +ScreencastEncoder::ScreencastEncoder(std::unique_ptr<VPXCodec>&& vpxCodec, IntSize size)
 | |
| +    : m_vpxCodec(WTFMove(vpxCodec))
 | |
| +    , m_size(size)
 | |
| +{
 | |
| +    ASSERT(!size.isZero());
 | |
| +}
 | |
| +
 | |
| +ScreencastEncoder::~ScreencastEncoder()
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +RefPtr<ScreencastEncoder> ScreencastEncoder::create(String& errorString, const String& filePath, IntSize size)
 | |
| +{
 | |
| +    vpx_codec_iface_t* codec_interface = vpx_codec_vp8_cx();
 | |
| +    if (!codec_interface) {
 | |
| +        errorString = "Codec not found."_s;
 | |
| +        return nullptr;
 | |
| +    }
 | |
| +
 | |
| +    if (size.width() <= 0 || size.height() <= 0 || (size.width() % 2) != 0 || (size.height() % 2) != 0) {
 | |
| +        errorString = makeString("Invalid frame size: "_s, size.width(), "x"_s, size.height());
 | |
| +        return nullptr;
 | |
| +    }
 | |
| +
 | |
| +    vpx_codec_enc_cfg_t cfg;
 | |
| +    memset(&cfg, 0, sizeof(cfg));
 | |
| +    vpx_codec_err_t error = vpx_codec_enc_config_default(codec_interface, &cfg, 0);
 | |
| +    if (error) {
 | |
| +        errorString = makeString("Failed to get default codec config: "_s, vpx_codec_err_to_string(error));
 | |
| +        return nullptr;
 | |
| +    }
 | |
| +
 | |
| +    cfg.g_w = size.width();
 | |
| +    cfg.g_h = size.height();
 | |
| +    cfg.g_timebase.num = 1;
 | |
| +    cfg.g_timebase.den = fps * timeScale;
 | |
| +    cfg.g_error_resilient = VPX_ERROR_RESILIENT_DEFAULT;
 | |
| +
 | |
| +    vpx_codec_ctx_t codec;
 | |
| +    if (vpx_codec_enc_init(&codec, codec_interface, &cfg, 0)) {
 | |
| +        errorString = makeString("Failed to initialize encoder: "_s, vpx_codec_error(&codec));
 | |
| +        return nullptr;
 | |
| +    }
 | |
| +
 | |
| +    FILE* file = fopen(filePath.utf8().data(), "wb");
 | |
| +    if (!file) {
 | |
| +        errorString = makeString("Failed to open file '", filePath, "' for writing: ", strerror(errno));
 | |
| +        return nullptr;
 | |
| +    }
 | |
| +
 | |
| +    std::unique_ptr<VPXCodec> vpxCodec(new VPXCodec(codec, cfg, file));
 | |
| +    return adoptRef(new ScreencastEncoder(WTFMove(vpxCodec), size));
 | |
| +}
 | |
| +
 | |
| +void ScreencastEncoder::flushLastFrame()
 | |
| +{
 | |
| +    MonotonicTime now = MonotonicTime::now();
 | |
| +    if (m_lastFrameTimestamp) {
 | |
| +        // If previous frame encoding failed for some rason leave the timestampt intact.
 | |
| +        if (!m_lastFrame)
 | |
| +            return;
 | |
| +
 | |
| +        Seconds seconds = now - m_lastFrameTimestamp;
 | |
| +        m_lastFrame->setDuration(seconds);
 | |
| +        m_vpxCodec->encodeFrameAsync(WTFMove(m_lastFrame));
 | |
| +    }
 | |
| +    m_lastFrameTimestamp = now;
 | |
| +}
 | |
| +
 | |
| +#if USE(CAIRO)
 | |
| +void ScreencastEncoder::encodeFrame(cairo_surface_t* drawingAreaSurface, IntSize size)
 | |
| +{
 | |
| +    flushLastFrame();
 | |
| +    // Note that in WPE drawing area size is updated asynchronously and may differ from acutal
 | |
| +    // size of the surface.
 | |
| +    if (size.isZero()) {
 | |
| +        return;
 | |
| +    }
 | |
| +
 | |
| +    RefPtr<cairo_surface_t> surface = adoptRef(cairo_image_surface_create(CAIRO_FORMAT_ARGB32, m_size.width(), m_size.height()));
 | |
| +    {
 | |
| +        RefPtr<cairo_t> cr = adoptRef(cairo_create(surface.get()));
 | |
| +
 | |
| +        cairo_matrix_t transform;
 | |
| +        if (size.width() > m_size.width() || size.height() > m_size.height()) {
 | |
| +            // If no scale is specified shrink to fit the frame.
 | |
| +            double scale = std::min(static_cast<double>(m_size.width()) / size.width(),
 | |
| +                                    static_cast<double>(m_size.height()) / size.height());
 | |
| +            cairo_matrix_init_scale(&transform, scale, scale);
 | |
| +            cairo_transform(cr.get(), &transform);
 | |
| +        }
 | |
| +
 | |
| +        // Record top left part of the drawing area that fits into the frame.
 | |
| +        cairo_set_source_surface(cr.get(), drawingAreaSurface, 0, 0);
 | |
| +        cairo_paint(cr.get());
 | |
| +    }
 | |
| +    cairo_surface_flush(surface.get());
 | |
| +
 | |
| +    m_lastFrame = makeUnique<VPXFrame>(WTFMove(surface));
 | |
| +}
 | |
| +#elif PLATFORM(MAC)
 | |
| +void ScreencastEncoder::encodeFrame(RetainPtr<CGImageRef>&& windowImage)
 | |
| +{
 | |
| +    flushLastFrame();
 | |
| +
 | |
| +    m_lastFrame = makeUnique<VPXFrame>(WTFMove(windowImage), m_offsetTop);
 | |
| +}
 | |
| +#endif
 | |
| +
 | |
| +void ScreencastEncoder::finish(Function<void()>&& callback)
 | |
| +{
 | |
| +    if (!m_vpxCodec) {
 | |
| +        callback();
 | |
| +        return;
 | |
| +    }
 | |
| +
 | |
| +    flushLastFrame();
 | |
| +    m_vpxCodec->finishAsync([protectRef = Ref { *this }, callback = WTFMove(callback)] () mutable {
 | |
| +        RunLoop::main().dispatch([callback = WTFMove(callback)] {
 | |
| +            callback();
 | |
| +        });
 | |
| +    });
 | |
| +}
 | |
| +
 | |
| +
 | |
| +} // namespace WebKit
 | |
| diff --git a/Source/WebKit/UIProcess/Inspector/Agents/ScreencastEncoder.h b/Source/WebKit/UIProcess/Inspector/Agents/ScreencastEncoder.h
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..36df6131950ca95f74dc191628376fc589dbcb33
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/UIProcess/Inspector/Agents/ScreencastEncoder.h
 | |
| @@ -0,0 +1,80 @@
 | |
| +/*
 | |
| + * Copyright (C) 2020 Microsoft Corporation.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
| + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#pragma once
 | |
| +
 | |
| +#include <WebCore/IntSize.h>
 | |
| +#include <wtf/Forward.h>
 | |
| +#include <wtf/MonotonicTime.h>
 | |
| +#include <wtf/Noncopyable.h>
 | |
| +#include <wtf/ThreadSafeRefCounted.h>
 | |
| +#include <wtf/WeakPtr.h>
 | |
| +
 | |
| +#if USE(CAIRO)
 | |
| +#include <cairo.h>
 | |
| +#endif
 | |
| +
 | |
| +namespace WebKit {
 | |
| +
 | |
| +class WebPageProxy;
 | |
| +
 | |
| +class ScreencastEncoder : public ThreadSafeRefCounted<ScreencastEncoder> {
 | |
| +    WTF_MAKE_NONCOPYABLE(ScreencastEncoder);
 | |
| +    WTF_MAKE_FAST_ALLOCATED;
 | |
| +public:
 | |
| +    static constexpr int fps = 25;
 | |
| +
 | |
| +    static RefPtr<ScreencastEncoder> create(String& errorString, const String& filePath, WebCore::IntSize);
 | |
| +
 | |
| +    class VPXCodec;
 | |
| +    ScreencastEncoder(std::unique_ptr<VPXCodec>&&, WebCore::IntSize);
 | |
| +    ~ScreencastEncoder();
 | |
| +
 | |
| +#if USE(CAIRO)
 | |
| +    void encodeFrame(cairo_surface_t*, WebCore::IntSize);
 | |
| +#elif PLATFORM(MAC)
 | |
| +    void encodeFrame(RetainPtr<CGImageRef>&&);
 | |
| +    void setOffsetTop(int offset) { m_offsetTop = offset;}
 | |
| +#endif
 | |
| +
 | |
| +    void finish(Function<void()>&& callback);
 | |
| +
 | |
| +private:
 | |
| +    void flushLastFrame();
 | |
| +#if PLATFORM(MAC)
 | |
| +    static void imageToARGB(CGImageRef, uint8_t* rgba_data, int width, int height, int offsetTop);
 | |
| +#endif
 | |
| +
 | |
| +    std::unique_ptr<VPXCodec> m_vpxCodec;
 | |
| +    const WebCore::IntSize m_size;
 | |
| +    MonotonicTime m_lastFrameTimestamp;
 | |
| +    class VPXFrame;
 | |
| +    std::unique_ptr<VPXFrame> m_lastFrame;
 | |
| +#if PLATFORM(MAC)
 | |
| +    int m_offsetTop { 0 };
 | |
| +#endif
 | |
| +};
 | |
| +
 | |
| +} // namespace WebKit
 | |
| diff --git a/Source/WebKit/UIProcess/Inspector/Agents/WebMFileWriter.cpp b/Source/WebKit/UIProcess/Inspector/Agents/WebMFileWriter.cpp
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..9b269b356e206f0252245a1497adb0d05128c9b4
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/UIProcess/Inspector/Agents/WebMFileWriter.cpp
 | |
| @@ -0,0 +1,69 @@
 | |
| +/*
 | |
| + * Copyright (c) 2014 The WebM project authors. All Rights Reserved.
 | |
| + * Copyright (C) 2020 Microsoft Corporation.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
| + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#include "config.h"
 | |
| +#include "WebMFileWriter.h"
 | |
| +
 | |
| +#include <string>
 | |
| +#include "mkvmuxer/mkvmuxerutil.h"
 | |
| +
 | |
| +namespace WebKit {
 | |
| +
 | |
| +WebMFileWriter::WebMFileWriter(FILE* file, vpx_codec_enc_cfg_t* cfg)
 | |
| +    : m_cfg(cfg)
 | |
| +    , m_writer(new mkvmuxer::MkvWriter(file))
 | |
| +    , m_segment(new mkvmuxer::Segment()) {
 | |
| +  m_segment->Init(m_writer.get());
 | |
| +  m_segment->set_mode(mkvmuxer::Segment::kFile);
 | |
| +  m_segment->OutputCues(true);
 | |
| +
 | |
| +  mkvmuxer::SegmentInfo* info = m_segment->GetSegmentInfo();
 | |
| +  std::string version = "Playwright " + std::string(vpx_codec_version_str());
 | |
| +  info->set_writing_app(version.c_str());
 | |
| +
 | |
| +  // Add vp8 track.
 | |
| +  m_videoTrackId = m_segment->AddVideoTrack(
 | |
| +      static_cast<int>(m_cfg->g_w), static_cast<int>(m_cfg->g_h), 0);
 | |
| +  if (!m_videoTrackId) {
 | |
| +    fprintf(stderr, "Failed to add video track\n");
 | |
| +  }
 | |
| +}
 | |
| +
 | |
| +WebMFileWriter::~WebMFileWriter() {}
 | |
| +
 | |
| +bool WebMFileWriter::writeFrame(const vpx_codec_cx_pkt_t* pkt) {
 | |
| +  int64_t pts_ns = pkt->data.frame.pts * 1000000000ll * m_cfg->g_timebase.num /
 | |
| +                   m_cfg->g_timebase.den;
 | |
| +  return m_segment->AddFrame(static_cast<uint8_t*>(pkt->data.frame.buf),
 | |
| +                             pkt->data.frame.sz, m_videoTrackId, pts_ns,
 | |
| +                             pkt->data.frame.flags & VPX_FRAME_IS_KEY);
 | |
| +}
 | |
| +
 | |
| +void WebMFileWriter::finish() {
 | |
| +  m_segment->Finalize();
 | |
| +}
 | |
| +
 | |
| +} // namespace WebKit
 | |
| diff --git a/Source/WebKit/UIProcess/Inspector/Agents/WebMFileWriter.h b/Source/WebKit/UIProcess/Inspector/Agents/WebMFileWriter.h
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..e2ce910f3fd7f587add552275b7e7176cf8b2723
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/UIProcess/Inspector/Agents/WebMFileWriter.h
 | |
| @@ -0,0 +1,53 @@
 | |
| +/*
 | |
| + * Copyright (C) 2020 Microsoft Corporation.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
| + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#pragma once
 | |
| +
 | |
| +#include <memory>
 | |
| +#include <stdio.h>
 | |
| +#include <stdlib.h>
 | |
| +#include "vpx/vpx_encoder.h"
 | |
| +
 | |
| +#include "mkvmuxer/mkvmuxer.h"
 | |
| +#include "mkvmuxer/mkvwriter.h"
 | |
| +
 | |
| +namespace WebKit {
 | |
| +
 | |
| +class WebMFileWriter {
 | |
| +public:
 | |
| +    WebMFileWriter(FILE*, vpx_codec_enc_cfg_t* cfg);
 | |
| +    ~WebMFileWriter();
 | |
| +
 | |
| +    bool writeFrame(const vpx_codec_cx_pkt_t* pkt);
 | |
| +    void finish();
 | |
| +
 | |
| +private:
 | |
| +    vpx_codec_enc_cfg_t* m_cfg = nullptr;
 | |
| +    std::unique_ptr<mkvmuxer::MkvWriter> m_writer;
 | |
| +    std::unique_ptr<mkvmuxer::Segment> m_segment;
 | |
| +    uint64_t m_videoTrackId = 0;
 | |
| +};
 | |
| +
 | |
| +} // namespace WebKit
 | |
| diff --git a/Source/WebKit/UIProcess/Inspector/Cocoa/InspectorExtensionDelegate.h b/Source/WebKit/UIProcess/Inspector/Cocoa/InspectorExtensionDelegate.h
 | |
| index 0f83f41855bf996b5846e677934a202851941d54..cf4afbd2cccf4607dd8d6e6d7983b03c1c044d42 100644
 | |
| --- a/Source/WebKit/UIProcess/Inspector/Cocoa/InspectorExtensionDelegate.h
 | |
| +++ b/Source/WebKit/UIProcess/Inspector/Cocoa/InspectorExtensionDelegate.h
 | |
| @@ -29,6 +29,7 @@
 | |
|  
 | |
|  #import "APIInspectorExtensionClient.h"
 | |
|  #import "WKFoundation.h"
 | |
| +#import <WebCore/FrameIdentifier.h>
 | |
|  #import <wtf/WeakObjCPtr.h>
 | |
|  
 | |
|  @class _WKInspectorExtension;
 | |
| diff --git a/Source/WebKit/UIProcess/Inspector/InspectorTargetProxy.cpp b/Source/WebKit/UIProcess/Inspector/InspectorTargetProxy.cpp
 | |
| index cfcacce0122bb03fa47fd8580cfbedfb2ad37d48..5619cbd7e4e842be0d8e2db2c64a7e0028838808 100644
 | |
| --- a/Source/WebKit/UIProcess/Inspector/InspectorTargetProxy.cpp
 | |
| +++ b/Source/WebKit/UIProcess/Inspector/InspectorTargetProxy.cpp
 | |
| @@ -27,11 +27,10 @@
 | |
|  #include "InspectorTargetProxy.h"
 | |
|  
 | |
|  #include "ProvisionalPageProxy.h"
 | |
| -#include "WebFrameProxy.h"
 | |
| +#include "WebPageInspectorController.h"
 | |
|  #include "WebPageInspectorTarget.h"
 | |
|  #include "WebPageMessages.h"
 | |
|  #include "WebPageProxy.h"
 | |
| -#include "WebProcessProxy.h"
 | |
|  
 | |
|  namespace WebKit {
 | |
|  
 | |
| @@ -39,18 +38,17 @@ using namespace Inspector;
 | |
|  
 | |
|  std::unique_ptr<InspectorTargetProxy> InspectorTargetProxy::create(WebPageProxy& page, const String& targetId, Inspector::InspectorTargetType type)
 | |
|  {
 | |
| -    return makeUnique<InspectorTargetProxy>(page, targetId, type);
 | |
| +    return makeUnique<InspectorTargetProxy>(page, nullptr, targetId, type);
 | |
|  }
 | |
|  
 | |
| -std::unique_ptr<InspectorTargetProxy> InspectorTargetProxy::create(ProvisionalPageProxy& provisionalPage, const String& targetId, Inspector::InspectorTargetType type)
 | |
| +std::unique_ptr<InspectorTargetProxy> InspectorTargetProxy::create(ProvisionalPageProxy& provisionalPage, const String& targetId)
 | |
|  {
 | |
| -    auto target = InspectorTargetProxy::create(provisionalPage.page(), targetId, type);
 | |
| -    target->m_provisionalPage = provisionalPage;
 | |
| -    return target;
 | |
| +    return makeUnique<InspectorTargetProxy>(provisionalPage.page(), &provisionalPage, targetId, Inspector::InspectorTargetType::Page);
 | |
|  }
 | |
|  
 | |
| -InspectorTargetProxy::InspectorTargetProxy(WebPageProxy& page, const String& targetId, Inspector::InspectorTargetType type)
 | |
| +InspectorTargetProxy::InspectorTargetProxy(WebPageProxy& page, ProvisionalPageProxy* provisionalPage, const String& targetId, Inspector::InspectorTargetType type)
 | |
|      : m_page(page)
 | |
| +    , m_provisionalPage(provisionalPage)
 | |
|      , m_identifier(targetId)
 | |
|      , m_type(type)
 | |
|  {
 | |
| @@ -97,6 +95,31 @@ void InspectorTargetProxy::didCommitProvisionalTarget()
 | |
|      m_provisionalPage = nullptr;
 | |
|  }
 | |
|  
 | |
| +void InspectorTargetProxy::willResume()
 | |
| +{
 | |
| +    if (m_page.hasRunningProcess())
 | |
| +        m_page.send(Messages::WebPage::ResumeInspectorIfPausedInNewWindow());
 | |
| +}
 | |
| +
 | |
| +void InspectorTargetProxy::activate(String& error)
 | |
| +{
 | |
| +    if (m_type != Inspector::InspectorTargetType::Page)
 | |
| +        return InspectorTarget::activate(error);
 | |
| +
 | |
| +    platformActivate(error);
 | |
| +}
 | |
| +
 | |
| +void InspectorTargetProxy::close(String& error, bool runBeforeUnload)
 | |
| +{
 | |
| +    if (m_type != Inspector::InspectorTargetType::Page)
 | |
| +        return InspectorTarget::close(error, runBeforeUnload);
 | |
| +
 | |
| +    if (runBeforeUnload)
 | |
| +        m_page.tryClose();
 | |
| +    else
 | |
| +        m_page.closePage();
 | |
| +}
 | |
| +
 | |
|  bool InspectorTargetProxy::isProvisional() const
 | |
|  {
 | |
|      return !!m_provisionalPage;
 | |
| diff --git a/Source/WebKit/UIProcess/Inspector/InspectorTargetProxy.h b/Source/WebKit/UIProcess/Inspector/InspectorTargetProxy.h
 | |
| index a2239cec8e18850f35f7f88a9c4ebadc62bf4023..79f3ff84327dc075ec96983e04db4b10343b7fae 100644
 | |
| --- a/Source/WebKit/UIProcess/Inspector/InspectorTargetProxy.h
 | |
| +++ b/Source/WebKit/UIProcess/Inspector/InspectorTargetProxy.h
 | |
| @@ -37,13 +37,13 @@ class WebPageProxy;
 | |
|  // NOTE: This UIProcess side InspectorTarget doesn't care about the frontend channel, since
 | |
|  // any target -> frontend messages will be routed to the WebPageProxy with a targetId.
 | |
|  
 | |
| -class InspectorTargetProxy final : public Inspector::InspectorTarget {
 | |
| +class InspectorTargetProxy : public Inspector::InspectorTarget {
 | |
|      WTF_MAKE_FAST_ALLOCATED;
 | |
|      WTF_MAKE_NONCOPYABLE(InspectorTargetProxy);
 | |
|  public:
 | |
|      static std::unique_ptr<InspectorTargetProxy> create(WebPageProxy&, const String& targetId, Inspector::InspectorTargetType);
 | |
| -    static std::unique_ptr<InspectorTargetProxy> create(ProvisionalPageProxy&, const String& targetId, Inspector::InspectorTargetType);
 | |
| -    InspectorTargetProxy(WebPageProxy&, const String& targetId, Inspector::InspectorTargetType);
 | |
| +    static std::unique_ptr<InspectorTargetProxy> create(ProvisionalPageProxy&, const String& targetId);
 | |
| +    InspectorTargetProxy(WebPageProxy&, ProvisionalPageProxy*, const String& targetId, Inspector::InspectorTargetType);
 | |
|      ~InspectorTargetProxy() = default;
 | |
|  
 | |
|      Inspector::InspectorTargetType type() const final { return m_type; }
 | |
| @@ -55,12 +55,17 @@ public:
 | |
|      void connect(Inspector::FrontendChannel::ConnectionType) override;
 | |
|      void disconnect() override;
 | |
|      void sendMessageToTargetBackend(const String&) override;
 | |
| +    void activate(String& error) override;
 | |
| +    void close(String& error, bool runBeforeUnload) override;
 | |
|  
 | |
|  private:
 | |
| +    void willResume() override;
 | |
| +    void platformActivate(String& error) const;
 | |
| +
 | |
|      WebPageProxy& m_page;
 | |
| +    WeakPtr<ProvisionalPageProxy> m_provisionalPage;
 | |
|      String m_identifier;
 | |
|      Inspector::InspectorTargetType m_type;
 | |
| -    WeakPtr<ProvisionalPageProxy> m_provisionalPage;
 | |
|  };
 | |
|  
 | |
|  } // namespace WebKit
 | |
| diff --git a/Source/WebKit/UIProcess/Inspector/WebPageInspectorController.cpp b/Source/WebKit/UIProcess/Inspector/WebPageInspectorController.cpp
 | |
| index ed4e6f30b8c35966075573dccee801daceec865e..81e10124a8a745727fc25316345cda01201a5dba 100644
 | |
| --- a/Source/WebKit/UIProcess/Inspector/WebPageInspectorController.cpp
 | |
| +++ b/Source/WebKit/UIProcess/Inspector/WebPageInspectorController.cpp
 | |
| @@ -26,13 +26,21 @@
 | |
|  #include "config.h"
 | |
|  #include "WebPageInspectorController.h"
 | |
|  
 | |
| +#include "APINavigation.h"
 | |
|  #include "APIUIClient.h"
 | |
|  #include "InspectorBrowserAgent.h"
 | |
| +#include "InspectorDialogAgent.h"
 | |
| +#include "InspectorScreencastAgent.h"
 | |
|  #include "ProvisionalPageProxy.h"
 | |
|  #include "WebFrameProxy.h"
 | |
|  #include "WebPageInspectorAgentBase.h"
 | |
| +#include "WebPageInspectorEmulationAgent.h"
 | |
| +#include "WebPageInspectorInputAgent.h"
 | |
|  #include "WebPageInspectorTarget.h"
 | |
|  #include "WebPageProxy.h"
 | |
| +#include "WebPreferences.h"
 | |
| +#include <WebCore/ResourceError.h>
 | |
| +#include <WebCore/WindowFeatures.h>
 | |
|  #include <JavaScriptCore/InspectorAgentBase.h>
 | |
|  #include <JavaScriptCore/InspectorBackendDispatcher.h>
 | |
|  #include <JavaScriptCore/InspectorBackendDispatchers.h>
 | |
| @@ -49,27 +57,114 @@ static String getTargetID(const ProvisionalPageProxy& provisionalPage)
 | |
|      return WebPageInspectorTarget::toTargetID(provisionalPage.webPageID());
 | |
|  }
 | |
|  
 | |
| +WebPageInspectorControllerObserver* WebPageInspectorController::s_observer = nullptr;
 | |
| +
 | |
| +void WebPageInspectorController::setObserver(WebPageInspectorControllerObserver* observer)
 | |
| +{
 | |
| +    s_observer = observer;
 | |
| +}
 | |
| +
 | |
| +WebPageInspectorControllerObserver* WebPageInspectorController::observer() {
 | |
| +    return s_observer;
 | |
| +}
 | |
| +
 | |
|  WebPageInspectorController::WebPageInspectorController(WebPageProxy& inspectedPage)
 | |
|      : m_frontendRouter(FrontendRouter::create())
 | |
|      , m_backendDispatcher(BackendDispatcher::create(m_frontendRouter.copyRef()))
 | |
|      , m_inspectedPage(inspectedPage)
 | |
|  {
 | |
| -    auto targetAgent = makeUnique<InspectorTargetAgent>(m_frontendRouter.get(), m_backendDispatcher.get());
 | |
| -    m_targetAgent = targetAgent.get();
 | |
| -    m_agents.append(WTFMove(targetAgent));
 | |
|  }
 | |
|  
 | |
|  void WebPageInspectorController::init()
 | |
|  {
 | |
| +    auto targetAgent = makeUnique<InspectorTargetAgent>(m_frontendRouter.get(), m_backendDispatcher.get());
 | |
| +    m_targetAgent = targetAgent.get();
 | |
| +    m_agents.append(WTFMove(targetAgent));
 | |
| +    auto emulationAgent = makeUnique<WebPageInspectorEmulationAgent>(m_backendDispatcher.get(), m_inspectedPage);
 | |
| +    m_emulationAgent = emulationAgent.get();
 | |
| +    m_agents.append(WTFMove(emulationAgent));
 | |
| +    auto inputAgent = makeUnique<WebPageInspectorInputAgent>(m_backendDispatcher.get(), m_inspectedPage);
 | |
| +    m_inputAgent = inputAgent.get();
 | |
| +    m_agents.append(WTFMove(inputAgent));
 | |
| +    m_agents.append(makeUnique<InspectorDialogAgent>(m_backendDispatcher.get(), m_frontendRouter.get(), m_inspectedPage));
 | |
| +    auto screencastAgent = makeUnique<InspectorScreencastAgent>(m_backendDispatcher.get(), m_frontendRouter.get(), m_inspectedPage);
 | |
| +    m_screecastAgent = screencastAgent.get();
 | |
| +    m_agents.append(WTFMove(screencastAgent));
 | |
| +    if (s_observer)
 | |
| +        s_observer->didCreateInspectorController(m_inspectedPage);
 | |
| +
 | |
| +    // window.open will create page with already running process.
 | |
| +    if (!m_inspectedPage.hasRunningProcess())
 | |
| +        return;
 | |
|      String pageTargetId = WebPageInspectorTarget::toTargetID(m_inspectedPage.webPageID());
 | |
|      createInspectorTarget(pageTargetId, Inspector::InspectorTargetType::Page);
 | |
|  }
 | |
|  
 | |
| +void WebPageInspectorController::didFinishAttachingToWebProcess()
 | |
| +{
 | |
| +    String pageTargetID = WebPageInspectorTarget::toTargetID(m_inspectedPage.webPageID());
 | |
| +    // Create target only after attaching to a Web Process first time. Before that
 | |
| +    // we cannot event establish frontend connection.
 | |
| +    if (m_targets.contains(pageTargetID))
 | |
| +        return;
 | |
| +    createInspectorTarget(pageTargetID, Inspector::InspectorTargetType::Page);
 | |
| +}
 | |
| +
 | |
|  void WebPageInspectorController::pageClosed()
 | |
|  {
 | |
| +    String pageTargetId = WebPageInspectorTarget::toTargetID(m_inspectedPage.webPageID());
 | |
| +    destroyInspectorTarget(pageTargetId);
 | |
| +
 | |
|      disconnectAllFrontends();
 | |
|  
 | |
|      m_agents.discardValues();
 | |
| +
 | |
| +    if (s_observer)
 | |
| +        s_observer->willDestroyInspectorController(m_inspectedPage);
 | |
| +}
 | |
| +
 | |
| +bool WebPageInspectorController::pageCrashed(ProcessTerminationReason reason)
 | |
| +{
 | |
| +    if (reason != ProcessTerminationReason::Crash)
 | |
| +        return false;
 | |
| +    String targetId = WebPageInspectorTarget::toTargetID(m_inspectedPage.webPageID());
 | |
| +    auto it = m_targets.find(targetId);
 | |
| +    if (it == m_targets.end())
 | |
| +        return false;
 | |
| +    m_targetAgent->targetCrashed(*it->value);
 | |
| +    m_targets.remove(it);
 | |
| +
 | |
| +    return m_targetAgent->isConnected();
 | |
| +}
 | |
| +
 | |
| +void WebPageInspectorController::willCreateNewPage(const WebCore::WindowFeatures& features, const URL& url)
 | |
| +{
 | |
| +    if (s_observer)
 | |
| +        s_observer->willCreateNewPage(m_inspectedPage, features, url);
 | |
| +}
 | |
| +
 | |
| +void WebPageInspectorController::didShowPage()
 | |
| +{
 | |
| +    if (m_frontendRouter->hasFrontends())
 | |
| +        m_emulationAgent->didShowPage();
 | |
| +}
 | |
| +
 | |
| +void WebPageInspectorController::didProcessAllPendingKeyboardEvents()
 | |
| +{
 | |
| +    if (m_frontendRouter->hasFrontends())
 | |
| +        m_inputAgent->didProcessAllPendingKeyboardEvents();
 | |
| +}
 | |
| +
 | |
| +void WebPageInspectorController::didProcessAllPendingMouseEvents()
 | |
| +{
 | |
| +    if (m_frontendRouter->hasFrontends())
 | |
| +        m_inputAgent->didProcessAllPendingMouseEvents();
 | |
| +}
 | |
| +
 | |
| +void WebPageInspectorController::didProcessAllPendingWheelEvents()
 | |
| +{
 | |
| +    if (m_frontendRouter->hasFrontends())
 | |
| +        m_inputAgent->didProcessAllPendingWheelEvents();
 | |
|  }
 | |
|  
 | |
|  bool WebPageInspectorController::hasLocalFrontend() const
 | |
| @@ -83,6 +178,17 @@ void WebPageInspectorController::connectFrontend(Inspector::FrontendChannel& fro
 | |
|  
 | |
|      bool connectingFirstFrontend = !m_frontendRouter->hasFrontends();
 | |
|  
 | |
| +    // HACK: forcefully disconnect remote connections to show local inspector starting with initial
 | |
| +    // agents' state.
 | |
| +    if (frontendChannel.connectionType() == Inspector::FrontendChannel::ConnectionType::Local &&
 | |
| +        !connectingFirstFrontend && !m_frontendRouter->hasLocalFrontend()) {
 | |
| +        disconnectAllFrontends();
 | |
| +        connectingFirstFrontend = true;
 | |
| +    }
 | |
| +
 | |
| +    if (connectingFirstFrontend)
 | |
| +        adjustPageSettings();
 | |
| +
 | |
|      m_frontendRouter->connectFrontend(frontendChannel);
 | |
|  
 | |
|      if (connectingFirstFrontend)
 | |
| @@ -101,8 +207,10 @@ void WebPageInspectorController::disconnectFrontend(FrontendChannel& frontendCha
 | |
|      m_frontendRouter->disconnectFrontend(frontendChannel);
 | |
|  
 | |
|      bool disconnectingLastFrontend = !m_frontendRouter->hasFrontends();
 | |
| -    if (disconnectingLastFrontend)
 | |
| +    if (disconnectingLastFrontend) {
 | |
|          m_agents.willDestroyFrontendAndBackend(DisconnectReason::InspectorDestroyed);
 | |
| +        m_pendingNavigations.clear();
 | |
| +    }
 | |
|  
 | |
|      m_inspectedPage.didChangeInspectorFrontendCount(m_frontendRouter->frontendCount());
 | |
|  
 | |
| @@ -125,6 +233,8 @@ void WebPageInspectorController::disconnectAllFrontends()
 | |
|      // Disconnect any remaining remote frontends.
 | |
|      m_frontendRouter->disconnectAllFrontends();
 | |
|  
 | |
| +    m_pendingNavigations.clear();
 | |
| +
 | |
|      m_inspectedPage.didChangeInspectorFrontendCount(m_frontendRouter->frontendCount());
 | |
|  
 | |
|  #if ENABLE(REMOTE_INSPECTOR)
 | |
| @@ -151,6 +261,66 @@ void WebPageInspectorController::setIndicating(bool indicating)
 | |
|  }
 | |
|  #endif
 | |
|  
 | |
| +#if USE(CAIRO)
 | |
| +void WebPageInspectorController::didPaint(cairo_surface_t* surface)
 | |
| +{
 | |
| +    if (!m_frontendRouter->hasFrontends())
 | |
| +        return;
 | |
| +
 | |
| +    m_screecastAgent->didPaint(surface);
 | |
| +}
 | |
| +#endif
 | |
| +
 | |
| +
 | |
| +void WebPageInspectorController::navigate(WebCore::ResourceRequest&& request, WebFrameProxy* frame, NavigationHandler&& completionHandler)
 | |
| +{
 | |
| +    auto navigation = m_inspectedPage.loadRequestForInspector(WTFMove(request), frame);
 | |
| +    if (!navigation) {
 | |
| +        completionHandler("Failed to navigate"_s, 0);
 | |
| +        return;
 | |
| +    }
 | |
| +
 | |
| +    m_pendingNavigations.set(navigation->navigationID(), WTFMove(completionHandler));
 | |
| +}
 | |
| +
 | |
| +void WebPageInspectorController::didReceivePolicyDecision(WebCore::PolicyAction action, uint64_t navigationID)
 | |
| +{
 | |
| +    if (!m_frontendRouter->hasFrontends())
 | |
| +        return;
 | |
| +
 | |
| +    if (!navigationID)
 | |
| +        return;
 | |
| +
 | |
| +    auto completionHandler = m_pendingNavigations.take(navigationID);
 | |
| +    if (!completionHandler)
 | |
| +        return;
 | |
| +
 | |
| +    if (action == WebCore::PolicyAction::Ignore)
 | |
| +        completionHandler("Navigation cancelled"_s, 0);
 | |
| +    else
 | |
| +        completionHandler(String(), navigationID);
 | |
| +}
 | |
| +
 | |
| +void WebPageInspectorController::didDestroyNavigation(uint64_t navigationID)
 | |
| +{
 | |
| +    if (!m_frontendRouter->hasFrontends())
 | |
| +        return;
 | |
| +
 | |
| +    auto completionHandler = m_pendingNavigations.take(navigationID);
 | |
| +    if (!completionHandler)
 | |
| +        return;
 | |
| +
 | |
| +    // Inspector initiated navigation is destroyed before policy check only when it
 | |
| +    // becomes a fragment navigation (which always reuses current navigation).
 | |
| +    completionHandler(String(), 0);
 | |
| +}
 | |
| +
 | |
| +void WebPageInspectorController::didFailProvisionalLoadForFrame(uint64_t navigationID, const WebCore::ResourceError& error)
 | |
| +{
 | |
| +    if (s_observer)
 | |
| +        s_observer->didFailProvisionalLoad(m_inspectedPage, navigationID, error.localizedDescription());
 | |
| +}
 | |
| +
 | |
|  void WebPageInspectorController::createInspectorTarget(const String& targetId, Inspector::InspectorTargetType type)
 | |
|  {
 | |
|      addTarget(InspectorTargetProxy::create(m_inspectedPage, targetId, type));
 | |
| @@ -170,6 +340,32 @@ void WebPageInspectorController::sendMessageToInspectorFrontend(const String& ta
 | |
|      m_targetAgent->sendMessageFromTargetToFrontend(targetId, message);
 | |
|  }
 | |
|  
 | |
| +void WebPageInspectorController::setPauseOnStart(bool shouldPause)
 | |
| +{
 | |
| +    ASSERT(m_frontendRouter->hasFrontends());
 | |
| +    m_targetAgent->setPauseOnStart(shouldPause);
 | |
| +}
 | |
| +
 | |
| +bool WebPageInspectorController::shouldPauseLoading() const
 | |
| +{
 | |
| +    if (!m_frontendRouter->hasFrontends())
 | |
| +        return false;
 | |
| +
 | |
| +    if (!m_inspectedPage.isPageOpenedByDOMShowingInitialEmptyDocument())
 | |
| +        return false;
 | |
| +
 | |
| +    auto* target = m_targets.get(WebPageInspectorTarget::toTargetID(m_inspectedPage.webPageID()));
 | |
| +    ASSERT(target);
 | |
| +    return target->isPaused();
 | |
| +}
 | |
| +
 | |
| +void WebPageInspectorController::setContinueLoadingCallback(WTF::Function<void()>&& callback)
 | |
| +{
 | |
| +    auto* target = m_targets.get(WebPageInspectorTarget::toTargetID(m_inspectedPage.webPageID()));
 | |
| +    ASSERT(target);
 | |
| +    target->setResumeCallback(WTFMove(callback));
 | |
| +}
 | |
| +
 | |
|  bool WebPageInspectorController::shouldPauseLoading(const ProvisionalPageProxy& provisionalPage) const
 | |
|  {
 | |
|      if (!m_frontendRouter->hasFrontends())
 | |
| @@ -189,7 +385,7 @@ void WebPageInspectorController::setContinueLoadingCallback(const ProvisionalPag
 | |
|  
 | |
|  void WebPageInspectorController::didCreateProvisionalPage(ProvisionalPageProxy& provisionalPage)
 | |
|  {
 | |
| -    addTarget(InspectorTargetProxy::create(provisionalPage, getTargetID(provisionalPage), Inspector::InspectorTargetType::Page));
 | |
| +    addTarget(InspectorTargetProxy::create(provisionalPage, getTargetID(provisionalPage)));
 | |
|  }
 | |
|  
 | |
|  void WebPageInspectorController::willDestroyProvisionalPage(const ProvisionalPageProxy& provisionalPage)
 | |
| @@ -267,4 +463,27 @@ void WebPageInspectorController::browserExtensionsDisabled(HashSet<String>&& ext
 | |
|          m_enabledBrowserAgent->extensionsDisabled(WTFMove(extensionIDs));
 | |
|  }
 | |
|  
 | |
| +void WebPageInspectorController::adjustPageSettings()
 | |
| +{
 | |
| +    // Set this to true as otherwise updating any preferences will override its
 | |
| +    // value in the Web Process to false (and InspectorController sets it locally
 | |
| +    // to true when frontend is connected).
 | |
| +    m_inspectedPage.preferences().setDeveloperExtrasEnabled(true);
 | |
| +
 | |
| +    // Navigation to cached pages doesn't fire some of the events (e.g. execution context created)
 | |
| +    // that inspector depends on. So we disable the cache when front-end connects.
 | |
| +    m_inspectedPage.preferences().setUsesBackForwardCache(false);
 | |
| +
 | |
| +    // Enable popup debugging.
 | |
| +    // TODO: allow to set preferences over the inspector protocol or find a better place for this.
 | |
| +    m_inspectedPage.preferences().setJavaScriptCanOpenWindowsAutomatically(true);
 | |
| +
 | |
| +    // Enable media stream.
 | |
| +    if (!m_inspectedPage.preferences().mediaStreamEnabled()) {
 | |
| +        m_inspectedPage.preferences().setMediaDevicesEnabled(true);
 | |
| +        m_inspectedPage.preferences().setMediaStreamEnabled(true);
 | |
| +        m_inspectedPage.preferences().setPeerConnectionEnabled(true);
 | |
| +    }
 | |
| +}
 | |
| +
 | |
|  } // namespace WebKit
 | |
| diff --git a/Source/WebKit/UIProcess/Inspector/WebPageInspectorController.h b/Source/WebKit/UIProcess/Inspector/WebPageInspectorController.h
 | |
| index 8c1339345d451874502b271f6aa2eca3fa0d3faf..1f8f5e74c86b61c1c5a16ac33d48afdd0e59a2e9 100644
 | |
| --- a/Source/WebKit/UIProcess/Inspector/WebPageInspectorController.h
 | |
| +++ b/Source/WebKit/UIProcess/Inspector/WebPageInspectorController.h
 | |
| @@ -26,17 +26,35 @@
 | |
|  #pragma once
 | |
|  
 | |
|  #include "InspectorTargetProxy.h"
 | |
| +#include "ProcessTerminationReason.h"
 | |
|  #include <JavaScriptCore/InspectorAgentRegistry.h>
 | |
|  #include <JavaScriptCore/InspectorTargetAgent.h>
 | |
|  #include <WebCore/PageIdentifier.h>
 | |
|  #include <wtf/Forward.h>
 | |
|  #include <wtf/Noncopyable.h>
 | |
|  #include <wtf/text/WTFString.h>
 | |
| +#include <wtf/URL.h>
 | |
| +
 | |
| +#if USE(CAIRO)
 | |
| +#include <cairo.h>
 | |
| +#endif
 | |
|  
 | |
|  namespace Inspector {
 | |
|  class BackendDispatcher;
 | |
|  class FrontendChannel;
 | |
|  class FrontendRouter;
 | |
| +class InspectorTarget;
 | |
| +}
 | |
| +
 | |
| +namespace WebCore {
 | |
| +class ResourceError;
 | |
| +class ResourceRequest;
 | |
| +enum class PolicyAction : uint8_t;
 | |
| +struct WindowFeatures;
 | |
| +}
 | |
| +
 | |
| +namespace PAL {
 | |
| +class SessionID;
 | |
|  }
 | |
|  
 | |
|  namespace WebKit {
 | |
| @@ -44,6 +62,23 @@ namespace WebKit {
 | |
|  class InspectorBrowserAgent;
 | |
|  struct WebPageAgentContext;
 | |
|  
 | |
| +class InspectorScreencastAgent;
 | |
| +class WebFrameProxy;
 | |
| +class WebPageInspectorEmulationAgent;
 | |
| +class WebPageInspectorInputAgent;
 | |
| +
 | |
| +class WebPageInspectorControllerObserver {
 | |
| +public:
 | |
| +    virtual void didCreateInspectorController(WebPageProxy&) = 0;
 | |
| +    virtual void willDestroyInspectorController(WebPageProxy&) = 0;
 | |
| +    virtual void didFailProvisionalLoad(WebPageProxy&, uint64_t navigationID, const String& error) = 0;
 | |
| +    virtual void willCreateNewPage(WebPageProxy&, const WebCore::WindowFeatures&, const URL&) = 0;
 | |
| +    virtual void didFinishScreencast(const PAL::SessionID& sessionID, const String& screencastID) = 0;
 | |
| +
 | |
| +protected:
 | |
| +    virtual ~WebPageInspectorControllerObserver() = default;
 | |
| +};
 | |
| +
 | |
|  class WebPageInspectorController {
 | |
|      WTF_MAKE_NONCOPYABLE(WebPageInspectorController);
 | |
|      WTF_MAKE_FAST_ALLOCATED;
 | |
| @@ -51,7 +86,21 @@ public:
 | |
|      WebPageInspectorController(WebPageProxy&);
 | |
|  
 | |
|      void init();
 | |
| +    void didFinishAttachingToWebProcess();
 | |
| +
 | |
| +    static void setObserver(WebPageInspectorControllerObserver*);
 | |
| +    static WebPageInspectorControllerObserver* observer();
 | |
| +
 | |
|      void pageClosed();
 | |
| +    bool pageCrashed(ProcessTerminationReason);
 | |
| +
 | |
| +    void willCreateNewPage(const WebCore::WindowFeatures&, const URL&);
 | |
| +
 | |
| +    void didShowPage();
 | |
| +
 | |
| +    void didProcessAllPendingKeyboardEvents();
 | |
| +    void didProcessAllPendingMouseEvents();
 | |
| +    void didProcessAllPendingWheelEvents();
 | |
|  
 | |
|      bool hasLocalFrontend() const;
 | |
|  
 | |
| @@ -64,11 +113,25 @@ public:
 | |
|  #if ENABLE(REMOTE_INSPECTOR)
 | |
|      void setIndicating(bool);
 | |
|  #endif
 | |
| +#if USE(CAIRO)
 | |
| +    void didPaint(cairo_surface_t*);
 | |
| +#endif
 | |
| +    using NavigationHandler = Function<void(const String&, uint64_t)>;
 | |
| +    void navigate(WebCore::ResourceRequest&&, WebFrameProxy*, NavigationHandler&&);
 | |
| +    void didReceivePolicyDecision(WebCore::PolicyAction action, uint64_t navigationID);
 | |
| +    void didDestroyNavigation(uint64_t navigationID);
 | |
| +
 | |
| +    void didFailProvisionalLoadForFrame(uint64_t navigationID, const WebCore::ResourceError& error);
 | |
|  
 | |
|      void createInspectorTarget(const String& targetId, Inspector::InspectorTargetType);
 | |
|      void destroyInspectorTarget(const String& targetId);
 | |
|      void sendMessageToInspectorFrontend(const String& targetId, const String& message);
 | |
|  
 | |
| +    void setPauseOnStart(bool);
 | |
| +
 | |
| +    bool shouldPauseLoading() const;
 | |
| +    void setContinueLoadingCallback(WTF::Function<void()>&&);
 | |
| +
 | |
|      bool shouldPauseLoading(const ProvisionalPageProxy&) const;
 | |
|      void setContinueLoadingCallback(const ProvisionalPageProxy&, WTF::Function<void()>&&);
 | |
|  
 | |
| @@ -87,6 +150,7 @@ private:
 | |
|      void createLazyAgents();
 | |
|  
 | |
|      void addTarget(std::unique_ptr<InspectorTargetProxy>&&);
 | |
| +    void adjustPageSettings();
 | |
|  
 | |
|      Ref<Inspector::FrontendRouter> m_frontendRouter;
 | |
|      Ref<Inspector::BackendDispatcher> m_backendDispatcher;
 | |
| @@ -95,11 +159,17 @@ private:
 | |
|      WebPageProxy& m_inspectedPage;
 | |
|  
 | |
|      Inspector::InspectorTargetAgent* m_targetAgent { nullptr };
 | |
| +    WebPageInspectorEmulationAgent* m_emulationAgent { nullptr };
 | |
| +    WebPageInspectorInputAgent* m_inputAgent { nullptr };
 | |
| +    InspectorScreencastAgent* m_screecastAgent { nullptr };
 | |
|      HashMap<String, std::unique_ptr<InspectorTargetProxy>> m_targets;
 | |
|  
 | |
|      InspectorBrowserAgent* m_enabledBrowserAgent;
 | |
|  
 | |
|      bool m_didCreateLazyAgents { false };
 | |
| +    HashMap<uint64_t, NavigationHandler> m_pendingNavigations;
 | |
| +
 | |
| +    static WebPageInspectorControllerObserver* s_observer;
 | |
|  };
 | |
|  
 | |
|  } // namespace WebKit
 | |
| diff --git a/Source/WebKit/UIProcess/Inspector/mac/ScreencastEncoderMac.mm b/Source/WebKit/UIProcess/Inspector/mac/ScreencastEncoderMac.mm
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..6a04ee480bc3a8270a7de20b1cd0da718242b4c1
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/UIProcess/Inspector/mac/ScreencastEncoderMac.mm
 | |
| @@ -0,0 +1,55 @@
 | |
| +/*
 | |
| + * Copyright (C) 2020 Microsoft Corporation.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
| + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#include "config.h"
 | |
| +#include "ScreencastEncoder.h"
 | |
| +
 | |
| +#include <algorithm>
 | |
| +#include <CoreGraphics/CoreGraphics.h>
 | |
| +#include <wtf/RetainPtr.h>
 | |
| +
 | |
| +namespace WebKit {
 | |
| +
 | |
| +void ScreencastEncoder::imageToARGB(CGImageRef image, uint8_t* argb_data, int width, int height, int offsetTop)
 | |
| +{
 | |
| +    size_t bitsPerComponent = 8;
 | |
| +    size_t bytesPerPixel = 4;
 | |
| +    size_t bytesPerRow = bytesPerPixel * width;
 | |
| +    RetainPtr<CGColorSpaceRef> colorSpace = adoptCF(CGColorSpaceCreateDeviceRGB());
 | |
| +    RetainPtr<CGContextRef> context = adoptCF(CGBitmapContextCreate(argb_data, width, height, bitsPerComponent, bytesPerRow, colorSpace.get(), (CGBitmapInfo)kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Little));
 | |
| +    double imageWidth = CGImageGetWidth(image);
 | |
| +    double imageHeight = CGImageGetHeight(image);
 | |
| +    double pageHeight = imageHeight - offsetTop;
 | |
| +    double ratio = 1;
 | |
| +    if (imageWidth > width || pageHeight > height) {
 | |
| +        ratio = std::min(width / imageWidth, height / pageHeight);
 | |
| +    }
 | |
| +    imageWidth *= ratio;
 | |
| +    imageHeight *= ratio;
 | |
| +    pageHeight *= ratio;
 | |
| +    CGContextDrawImage(context.get(), CGRectMake(0, height - pageHeight, imageWidth, imageHeight), image);
 | |
| +}
 | |
| +
 | |
| +} // namespace WebKit
 | |
| diff --git a/Source/WebKit/UIProcess/InspectorDialogAgent.cpp b/Source/WebKit/UIProcess/InspectorDialogAgent.cpp
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..663f92f0df76042cf6385b056f8a917d688259f9
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/UIProcess/InspectorDialogAgent.cpp
 | |
| @@ -0,0 +1,88 @@
 | |
| +/*
 | |
| + * Copyright (C) 2019 Microsoft Corporation.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
| + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#include "config.h"
 | |
| +#include "InspectorDialogAgent.h"
 | |
| +
 | |
| +#include "APINavigation.h"
 | |
| +#include "APIUIClient.h"
 | |
| +#include "WebPageProxy.h"
 | |
| +#include <JavaScriptCore/InspectorFrontendRouter.h>
 | |
| +
 | |
| +
 | |
| +namespace WebKit {
 | |
| +
 | |
| +using namespace Inspector;
 | |
| +
 | |
| +InspectorDialogAgent::InspectorDialogAgent(Inspector::BackendDispatcher& backendDispatcher, Inspector::FrontendRouter& frontendRouter, WebPageProxy& page)
 | |
| +    : InspectorAgentBase("Dialog"_s)
 | |
| +    , m_frontendDispatcher(makeUnique<DialogFrontendDispatcher>(frontendRouter))
 | |
| +    , m_backendDispatcher(DialogBackendDispatcher::create(backendDispatcher, this))
 | |
| +    , m_page(page)
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +InspectorDialogAgent::~InspectorDialogAgent()
 | |
| +{
 | |
| +    disable();
 | |
| +}
 | |
| +
 | |
| +void InspectorDialogAgent::didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*)
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +void InspectorDialogAgent::willDestroyFrontendAndBackend(Inspector::DisconnectReason)
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +Inspector::Protocol::ErrorStringOr<void> InspectorDialogAgent::enable()
 | |
| +{
 | |
| +    if (m_page.inspectorDialogAgent())
 | |
| +        return makeUnexpected("Dialog domain is already enabled."_s);
 | |
| +
 | |
| +    m_page.setInspectorDialogAgent(this);
 | |
| +    return { };
 | |
| +}
 | |
| +
 | |
| +Inspector::Protocol::ErrorStringOr<void> InspectorDialogAgent::disable()
 | |
| +{
 | |
| +    if (m_page.inspectorDialogAgent() != this)
 | |
| +        return { };
 | |
| +
 | |
| +    m_page.setInspectorDialogAgent(nullptr);
 | |
| +    return { };
 | |
| +}
 | |
| +
 | |
| +Inspector::Protocol::ErrorStringOr<void> InspectorDialogAgent::handleJavaScriptDialog(bool accept, const String& value)
 | |
| +{
 | |
| +    m_page.uiClient().handleJavaScriptDialog(m_page, accept, value);
 | |
| +    return { };
 | |
| +}
 | |
| +
 | |
| +void InspectorDialogAgent::javascriptDialogOpening(const String& type, const String& message, const String& defaultValue) {
 | |
| +    m_frontendDispatcher->javascriptDialogOpening(type, message, defaultValue);
 | |
| +}
 | |
| +
 | |
| +} // namespace WebKit
 | |
| diff --git a/Source/WebKit/UIProcess/InspectorDialogAgent.h b/Source/WebKit/UIProcess/InspectorDialogAgent.h
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..d0e11ed81a6257c011df23d5870da7403f8e9fe4
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/UIProcess/InspectorDialogAgent.h
 | |
| @@ -0,0 +1,70 @@
 | |
| +/*
 | |
| + * Copyright (C) 2019 Microsoft Corporation.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
| + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#pragma once
 | |
| +
 | |
| +#include "WebEvent.h"
 | |
| +
 | |
| +#include <JavaScriptCore/InspectorAgentBase.h>
 | |
| +#include <JavaScriptCore/InspectorBackendDispatchers.h>
 | |
| +#include <JavaScriptCore/InspectorFrontendDispatchers.h>
 | |
| +
 | |
| +#include <wtf/Forward.h>
 | |
| +#include <wtf/Noncopyable.h>
 | |
| +
 | |
| +namespace Inspector {
 | |
| +class FrontendChannel;
 | |
| +class FrontendRouter;
 | |
| +}
 | |
| +
 | |
| +namespace WebKit {
 | |
| +
 | |
| +class NativeWebKeyboardEvent;
 | |
| +class WebPageProxy;
 | |
| +
 | |
| +class InspectorDialogAgent : public Inspector::InspectorAgentBase, public Inspector::DialogBackendDispatcherHandler {
 | |
| +    WTF_MAKE_NONCOPYABLE(InspectorDialogAgent);
 | |
| +    WTF_MAKE_FAST_ALLOCATED;
 | |
| +public:
 | |
| +    InspectorDialogAgent(Inspector::BackendDispatcher& backendDispatcher, Inspector::FrontendRouter& frontendRouter, WebPageProxy& page);
 | |
| +    ~InspectorDialogAgent() override;
 | |
| +
 | |
| +    void didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*) override;
 | |
| +    void willDestroyFrontendAndBackend(Inspector::DisconnectReason) override;
 | |
| +
 | |
| +    Inspector::Protocol::ErrorStringOr<void> enable() override;
 | |
| +    Inspector::Protocol::ErrorStringOr<void> disable() override;
 | |
| +    Inspector::Protocol::ErrorStringOr<void> handleJavaScriptDialog(bool accept, const String& promptText) override;
 | |
| +
 | |
| +    void javascriptDialogOpening(const String& type, const String& message, const String& defaultValue = String());
 | |
| +
 | |
| +private:
 | |
| +    void platformHandleJavaScriptDialog(bool accept, const String* promptText);
 | |
| +    std::unique_ptr<Inspector::DialogFrontendDispatcher> m_frontendDispatcher;
 | |
| +    Ref<Inspector::DialogBackendDispatcher> m_backendDispatcher;
 | |
| +    WebPageProxy& m_page;
 | |
| +};
 | |
| +
 | |
| +} // namespace WebKit
 | |
| diff --git a/Source/WebKit/UIProcess/InspectorPlaywrightAgent.cpp b/Source/WebKit/UIProcess/InspectorPlaywrightAgent.cpp
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..6039fdbcef4cc08e51a195b0c82a4cfb3a5ef8a1
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/UIProcess/InspectorPlaywrightAgent.cpp
 | |
| @@ -0,0 +1,963 @@
 | |
| +/*
 | |
| + * Copyright (C) 2019 Microsoft Corporation.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
| + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#include "config.h"
 | |
| +#include "InspectorPlaywrightAgent.h"
 | |
| +
 | |
| +#if ENABLE(REMOTE_INSPECTOR)
 | |
| +
 | |
| +#include "APIGeolocationProvider.h"
 | |
| +#include "APIPageConfiguration.h"
 | |
| +#include "FrameInfoData.h"
 | |
| +#include "InspectorPlaywrightAgentClient.h"
 | |
| +#include "InspectorTargetProxy.h"
 | |
| +#include "NetworkProcessMessages.h"
 | |
| +#include "NetworkProcessProxy.h"
 | |
| +#include "PageClient.h"
 | |
| +#include "SandboxExtension.h"
 | |
| +#include "StorageNamespaceIdentifier.h"
 | |
| +#include "WebAutomationSession.h"
 | |
| +#include "WebCookieManagerProxy.h"
 | |
| +#include "WebGeolocationManagerProxy.h"
 | |
| +#include "WebGeolocationPosition.h"
 | |
| +#include "WebInspectorUtilities.h"
 | |
| +#include "WebPageGroup.h"
 | |
| +#include "WebPageInspectorController.h"
 | |
| +#include "WebPageInspectorTarget.h"
 | |
| +#include "WebPageMessages.h"
 | |
| +#include "WebPageProxy.h"
 | |
| +#include "WebProcessPool.h"
 | |
| +#include "WebProcessProxy.h"
 | |
| +#include "WebsiteDataRecord.h"
 | |
| +#include <WebCore/FrameIdentifier.h>
 | |
| +#include <WebCore/GeolocationPositionData.h>
 | |
| +#include <WebCore/InspectorPageAgent.h>
 | |
| +#include <WebCore/ProcessIdentifier.h>
 | |
| +#include <WebCore/ResourceRequest.h>
 | |
| +#include <WebCore/SecurityOriginData.h>
 | |
| +#include <WebCore/WindowFeatures.h>
 | |
| +#include <JavaScriptCore/InspectorBackendDispatcher.h>
 | |
| +#include <JavaScriptCore/InspectorFrontendChannel.h>
 | |
| +#include <JavaScriptCore/InspectorFrontendRouter.h>
 | |
| +#include <pal/SessionID.h>
 | |
| +#include <stdlib.h>
 | |
| +#include <wtf/HashMap.h>
 | |
| +#include <wtf/HashSet.h>
 | |
| +#include <wtf/HexNumber.h>
 | |
| +#include <wtf/URL.h>
 | |
| +
 | |
| +
 | |
| +using namespace Inspector;
 | |
| +
 | |
| +namespace WebKit {
 | |
| +
 | |
| +class InspectorPlaywrightAgent::PageProxyChannel : public FrontendChannel {
 | |
| +    WTF_MAKE_FAST_ALLOCATED;
 | |
| +public:
 | |
| +    PageProxyChannel(FrontendChannel& frontendChannel, String browserContextID, String pageProxyID, WebPageProxy& page)
 | |
| +        : m_browserContextID(browserContextID)
 | |
| +        , m_pageProxyID(pageProxyID)
 | |
| +        , m_frontendChannel(frontendChannel)
 | |
| +        , m_page(page)
 | |
| +    {
 | |
| +    }
 | |
| +
 | |
| +    ~PageProxyChannel() override = default;
 | |
| +
 | |
| +    void dispatchMessageFromFrontend(const String& message)
 | |
| +    {
 | |
| +        m_page.inspectorController().dispatchMessageFromFrontend(message);
 | |
| +    }
 | |
| +
 | |
| +    WebPageProxy& page() { return m_page; }
 | |
| +
 | |
| +    void disconnect()
 | |
| +    {
 | |
| +        m_page.inspectorController().disconnectFrontend(*this);
 | |
| +    }
 | |
| +
 | |
| +private:
 | |
| +    ConnectionType connectionType() const override { return m_frontendChannel.connectionType(); }
 | |
| +    void sendMessageToFrontend(const String& message) override
 | |
| +    {
 | |
| +        m_frontendChannel.sendMessageToFrontend(addTabIdToMessage(message));
 | |
| +    }
 | |
| +
 | |
| +    String addTabIdToMessage(const String& message) {
 | |
| +        RefPtr<JSON::Value> parsedMessage = JSON::Value::parseJSON(message);
 | |
| +        if (!parsedMessage)
 | |
| +            return message;
 | |
| +
 | |
| +        RefPtr<JSON::Object> messageObject = parsedMessage->asObject();
 | |
| +        if (!messageObject)
 | |
| +            return message;
 | |
| +
 | |
| +        messageObject->setString("browserContextId"_s, m_browserContextID);
 | |
| +        messageObject->setString("pageProxyId"_s, m_pageProxyID);
 | |
| +        return messageObject->toJSONString();
 | |
| +    }
 | |
| +
 | |
| +    String m_browserContextID;
 | |
| +    String m_pageProxyID;
 | |
| +    FrontendChannel& m_frontendChannel;
 | |
| +    WebPageProxy& m_page;
 | |
| +};
 | |
| +
 | |
| +class OverridenGeolocationProvider final : public API::GeolocationProvider, public CanMakeWeakPtr<OverridenGeolocationProvider> {
 | |
| +     WTF_MAKE_NONCOPYABLE(OverridenGeolocationProvider);
 | |
| +public:
 | |
| +    OverridenGeolocationProvider()
 | |
| +        : m_position(WebGeolocationPosition::create(WebCore::GeolocationPositionData()))
 | |
| +    {
 | |
| +    }
 | |
| +
 | |
| +    void setPosition(const Ref<WebGeolocationPosition>& position) {
 | |
| +        m_position = position;
 | |
| +    }
 | |
| +
 | |
| +private:
 | |
| +    void startUpdating(WebGeolocationManagerProxy& proxy) override
 | |
| +    {
 | |
| +        proxy.providerDidChangePosition(&m_position.get());
 | |
| +    }
 | |
| +
 | |
| +    void stopUpdating(WebGeolocationManagerProxy&) override
 | |
| +    {
 | |
| +    }
 | |
| +
 | |
| +    void setEnableHighAccuracy(WebGeolocationManagerProxy&, bool enabled) override
 | |
| +    {
 | |
| +    }
 | |
| +
 | |
| +    Ref<WebGeolocationPosition> m_position;
 | |
| +};
 | |
| +
 | |
| +namespace {
 | |
| +
 | |
| +void setGeolocationProvider(BrowserContext* browserContext) {
 | |
| +    auto provider = makeUnique<OverridenGeolocationProvider>();
 | |
| +    browserContext->geolocationProvider = *provider;
 | |
| +    auto* geoManager = browserContext->processPool->supplement<WebGeolocationManagerProxy>();
 | |
| +    geoManager->setProvider(WTFMove(provider));
 | |
| +}
 | |
| +
 | |
| +String toBrowserContextIDProtocolString(const PAL::SessionID& sessionID)
 | |
| +{
 | |
| +    StringBuilder builder;
 | |
| +    builder.append(hex(sessionID.toUInt64(), 16));
 | |
| +    return builder.toString();
 | |
| +}
 | |
| +
 | |
| +String toPageProxyIDProtocolString(const WebPageProxy& page)
 | |
| +{
 | |
| +    return makeString(page.identifier().toUInt64());
 | |
| +}
 | |
| +
 | |
| +
 | |
| +static Ref<JSON::ArrayOf<String>> getEnabledWindowFeatures(const WebCore::WindowFeatures& features) {
 | |
| +  auto result = JSON::ArrayOf<String>::create();
 | |
| +  if (features.x)
 | |
| +    result->addItem("left=" + String::number(*features.x));
 | |
| +  if (features.y)
 | |
| +    result->addItem("top=" + String::number(*features.y));
 | |
| +  if (features.width)
 | |
| +    result->addItem("width=" + String::number(*features.width));
 | |
| +  if (features.height)
 | |
| +    result->addItem("height=" + String::number(*features.height));
 | |
| +  if (features.menuBarVisible)
 | |
| +    result->addItem("menubar"_s);
 | |
| +  if (features.toolBarVisible)
 | |
| +    result->addItem("toolbar"_s);
 | |
| +  if (features.statusBarVisible)
 | |
| +    result->addItem("status"_s);
 | |
| +  if (features.locationBarVisible)
 | |
| +    result->addItem("location"_s);
 | |
| +  if (features.scrollbarsVisible)
 | |
| +    result->addItem("scrollbars"_s);
 | |
| +  if (features.resizable)
 | |
| +    result->addItem("resizable"_s);
 | |
| +  if (features.fullscreen)
 | |
| +    result->addItem("fullscreen"_s);
 | |
| +  if (features.dialog)
 | |
| +    result->addItem("dialog"_s);
 | |
| +  if (features.noopener)
 | |
| +    result->addItem("noopener"_s);
 | |
| +  if (features.noreferrer)
 | |
| +    result->addItem("noreferrer"_s);
 | |
| +  for (const auto& additionalFeature : features.additionalFeatures)
 | |
| +    result->addItem(additionalFeature);
 | |
| +  return result;
 | |
| +}
 | |
| +
 | |
| +Inspector::Protocol::Playwright::CookieSameSitePolicy cookieSameSitePolicy(WebCore::Cookie::SameSitePolicy policy)
 | |
| +{
 | |
| +    switch (policy) {
 | |
| +    case WebCore::Cookie::SameSitePolicy::None:
 | |
| +        return Inspector::Protocol::Playwright::CookieSameSitePolicy::None;
 | |
| +    case WebCore::Cookie::SameSitePolicy::Lax:
 | |
| +        return Inspector::Protocol::Playwright::CookieSameSitePolicy::Lax;
 | |
| +    case WebCore::Cookie::SameSitePolicy::Strict:
 | |
| +        return Inspector::Protocol::Playwright::CookieSameSitePolicy::Strict;
 | |
| +    }
 | |
| +    ASSERT_NOT_REACHED();
 | |
| +    return Inspector::Protocol::Playwright::CookieSameSitePolicy::None;
 | |
| +}
 | |
| +
 | |
| +Ref<Inspector::Protocol::Playwright::Cookie> buildObjectForCookie(const WebCore::Cookie& cookie)
 | |
| +{
 | |
| +    return Inspector::Protocol::Playwright::Cookie::create()
 | |
| +        .setName(cookie.name)
 | |
| +        .setValue(cookie.value)
 | |
| +        .setDomain(cookie.domain)
 | |
| +        .setPath(cookie.path)
 | |
| +        .setExpires(cookie.expires.value_or(-1))
 | |
| +        .setHttpOnly(cookie.httpOnly)
 | |
| +        .setSecure(cookie.secure)
 | |
| +        .setSession(cookie.session)
 | |
| +        .setSameSite(cookieSameSitePolicy(cookie.sameSite))
 | |
| +        .release();
 | |
| +}
 | |
| +
 | |
| +}  // namespace
 | |
| +
 | |
| +BrowserContext::BrowserContext() = default;
 | |
| +
 | |
| +BrowserContext::~BrowserContext() = default;
 | |
| +
 | |
| +class InspectorPlaywrightAgent::BrowserContextDeletion {
 | |
| +    WTF_MAKE_NONCOPYABLE(BrowserContextDeletion);
 | |
| +    WTF_MAKE_FAST_ALLOCATED;
 | |
| +public:
 | |
| +    BrowserContextDeletion(std::unique_ptr<BrowserContext>&& context, size_t numberOfPages, Ref<DeleteContextCallback>&& callback)
 | |
| +        : m_browserContext(WTFMove(context))
 | |
| +        , m_numberOfPages(numberOfPages)
 | |
| +        , m_callback(WTFMove(callback)) { }
 | |
| +
 | |
| +    void didDestroyPage(const WebPageProxy& page)
 | |
| +    {
 | |
| +        ASSERT(m_browserContext->dataStore->sessionID() == page.sessionID());
 | |
| +        // Check if new pages have been created during the context destruction and
 | |
| +        // close all of them if necessary.
 | |
| +        if (m_numberOfPages == 1) {
 | |
| +            auto pages = m_browserContext->pages;
 | |
| +            size_t numberOfPages = pages.size();
 | |
| +            if (numberOfPages > 1) {
 | |
| +                m_numberOfPages = numberOfPages;
 | |
| +                for (auto* existingPage : pages) {
 | |
| +                    if (existingPage != &page)
 | |
| +                        existingPage->closePage();
 | |
| +                }
 | |
| +            }
 | |
| +        }
 | |
| +        --m_numberOfPages;
 | |
| +        if (m_numberOfPages)
 | |
| +            return;
 | |
| +        m_callback->sendSuccess();
 | |
| +    }
 | |
| +
 | |
| +    bool isFinished() const { return !m_numberOfPages; }
 | |
| +
 | |
| +    BrowserContext* context() const { return m_browserContext.get(); }
 | |
| +
 | |
| +private:
 | |
| +    std::unique_ptr<BrowserContext> m_browserContext;
 | |
| +    size_t m_numberOfPages;
 | |
| +    Ref<DeleteContextCallback> m_callback;
 | |
| +};
 | |
| +
 | |
| +
 | |
| +InspectorPlaywrightAgent::InspectorPlaywrightAgent(std::unique_ptr<InspectorPlaywrightAgentClient> client)
 | |
| +    : m_frontendChannel(nullptr)
 | |
| +    , m_frontendRouter(FrontendRouter::create())
 | |
| +    , m_backendDispatcher(BackendDispatcher::create(m_frontendRouter.copyRef()))
 | |
| +    , m_client(std::move(client))
 | |
| +    , m_frontendDispatcher(makeUnique<PlaywrightFrontendDispatcher>(m_frontendRouter))
 | |
| +    , m_playwrightDispatcher(PlaywrightBackendDispatcher::create(m_backendDispatcher.get(), this))
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +InspectorPlaywrightAgent::~InspectorPlaywrightAgent()
 | |
| +{
 | |
| +    if (m_frontendChannel)
 | |
| +        disconnectFrontend();
 | |
| +}
 | |
| +
 | |
| +void InspectorPlaywrightAgent::connectFrontend(FrontendChannel& frontendChannel)
 | |
| +{
 | |
| +    ASSERT(!m_frontendChannel);
 | |
| +    m_frontendChannel = &frontendChannel;
 | |
| +    WebPageInspectorController::setObserver(this);
 | |
| +
 | |
| +    m_frontendRouter->connectFrontend(frontendChannel);
 | |
| +}
 | |
| +
 | |
| +void InspectorPlaywrightAgent::disconnectFrontend()
 | |
| +{
 | |
| +    if (!m_frontendChannel)
 | |
| +        return;
 | |
| +
 | |
| +    disable();
 | |
| +
 | |
| +    m_frontendRouter->disconnectFrontend(*m_frontendChannel);
 | |
| +    ASSERT(!m_frontendRouter->hasFrontends());
 | |
| +
 | |
| +    WebPageInspectorController::setObserver(nullptr);
 | |
| +    m_frontendChannel = nullptr;
 | |
| +
 | |
| +    closeImpl([](String error){});
 | |
| +}
 | |
| +
 | |
| +void InspectorPlaywrightAgent::dispatchMessageFromFrontend(const String& message)
 | |
| +{
 | |
| +    m_backendDispatcher->dispatch(message, [&](const RefPtr<JSON::Object>& messageObject) {
 | |
| +        RefPtr<JSON::Value> idValue;
 | |
| +        if (!messageObject->getValue("id"_s, idValue))
 | |
| +            return BackendDispatcher::InterceptionResult::Continue;
 | |
| +        RefPtr<JSON::Value> pageProxyIDValue;
 | |
| +        if (!messageObject->getValue("pageProxyId"_s, pageProxyIDValue))
 | |
| +            return BackendDispatcher::InterceptionResult::Continue;
 | |
| +
 | |
| +        String pageProxyID;
 | |
| +        if (!pageProxyIDValue->asString(pageProxyID)) {
 | |
| +            m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidRequest, "The type of 'pageProxyId' must be string"_s);
 | |
| +            m_backendDispatcher->sendPendingErrors();
 | |
| +            return BackendDispatcher::InterceptionResult::Intercepted;
 | |
| +        }
 | |
| +
 | |
| +        if (auto pageProxyChannel = m_pageProxyChannels.get(pageProxyID)) {
 | |
| +            pageProxyChannel->dispatchMessageFromFrontend(message);
 | |
| +            return BackendDispatcher::InterceptionResult::Intercepted;
 | |
| +        }
 | |
| +
 | |
| +        std::optional<int> requestId = idValue->asInteger();
 | |
| +        if (!requestId) {
 | |
| +            m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidRequest, "The type of 'id' must be number"_s);
 | |
| +            m_backendDispatcher->sendPendingErrors();
 | |
| +            return BackendDispatcher::InterceptionResult::Intercepted;
 | |
| +        }
 | |
| +
 | |
| +        m_backendDispatcher->reportProtocolError(*requestId, BackendDispatcher::InvalidParams, "Cannot find page proxy with provided 'pageProxyId'"_s);
 | |
| +        m_backendDispatcher->sendPendingErrors();
 | |
| +        return BackendDispatcher::InterceptionResult::Intercepted;
 | |
| +    });
 | |
| +}
 | |
| +
 | |
| +void InspectorPlaywrightAgent::didCreateInspectorController(WebPageProxy& page)
 | |
| +{
 | |
| +    if (!m_isEnabled)
 | |
| +        return;
 | |
| +
 | |
| +    if (isInspectorProcessPool(page.process().processPool()))
 | |
| +        return;
 | |
| +
 | |
| +    ASSERT(m_frontendChannel);
 | |
| +
 | |
| +    String browserContextID = toBrowserContextIDProtocolString(page.sessionID());
 | |
| +    String pageProxyID = toPageProxyIDProtocolString(page);
 | |
| +    auto* opener = page.configuration().relatedPage();
 | |
| +    String openerId;
 | |
| +    if (opener)
 | |
| +        openerId = toPageProxyIDProtocolString(*opener);
 | |
| +
 | |
| +    BrowserContext* browserContext = getExistingBrowserContext(browserContextID);
 | |
| +    browserContext->pages.add(&page);
 | |
| +    m_frontendDispatcher->pageProxyCreated(browserContextID, pageProxyID, openerId);
 | |
| +
 | |
| +    // Auto-connect to all new pages.
 | |
| +    auto pageProxyChannel = makeUnique<PageProxyChannel>(*m_frontendChannel, browserContextID, pageProxyID, page);
 | |
| +    page.inspectorController().connectFrontend(*pageProxyChannel);
 | |
| +    // Always pause new targets if controlled remotely.
 | |
| +    page.inspectorController().setPauseOnStart(true);
 | |
| +    m_pageProxyChannels.set(pageProxyID, WTFMove(pageProxyChannel));
 | |
| +}
 | |
| +
 | |
| +void InspectorPlaywrightAgent::willDestroyInspectorController(WebPageProxy& page)
 | |
| +{
 | |
| +    if (!m_isEnabled)
 | |
| +        return;
 | |
| +
 | |
| +    if (isInspectorProcessPool(page.process().processPool()))
 | |
| +        return;
 | |
| +
 | |
| +    String browserContextID = toBrowserContextIDProtocolString(page.sessionID());
 | |
| +    BrowserContext* browserContext = getExistingBrowserContext(browserContextID);
 | |
| +    browserContext->pages.remove(&page);
 | |
| +    m_frontendDispatcher->pageProxyDestroyed(toPageProxyIDProtocolString(page));
 | |
| +
 | |
| +    auto it = m_browserContextDeletions.find(browserContextID);
 | |
| +    if (it != m_browserContextDeletions.end()) {
 | |
| +        it->value->didDestroyPage(page);
 | |
| +        if (it->value->isFinished())
 | |
| +            m_browserContextDeletions.remove(it);
 | |
| +    }
 | |
| +
 | |
| +    String pageProxyID = toPageProxyIDProtocolString(page);
 | |
| +    auto channelIt = m_pageProxyChannels.find(pageProxyID);
 | |
| +    ASSERT(channelIt != m_pageProxyChannels.end());
 | |
| +    channelIt->value->disconnect();
 | |
| +    m_pageProxyChannels.remove(channelIt);
 | |
| +}
 | |
| +
 | |
| +void InspectorPlaywrightAgent::didFailProvisionalLoad(WebPageProxy& page, uint64_t navigationID, const String& error)
 | |
| +{
 | |
| +    if (!m_isEnabled)
 | |
| +        return;
 | |
| +
 | |
| +    m_frontendDispatcher->provisionalLoadFailed(
 | |
| +        toPageProxyIDProtocolString(page),
 | |
| +        String::number(navigationID), error);
 | |
| +}
 | |
| +
 | |
| +void InspectorPlaywrightAgent::willCreateNewPage(WebPageProxy& page, const WebCore::WindowFeatures& features, const URL& url)
 | |
| +{
 | |
| +    if (!m_isEnabled)
 | |
| +        return;
 | |
| +
 | |
| +    m_frontendDispatcher->windowOpen(
 | |
| +        toPageProxyIDProtocolString(page),
 | |
| +        url.string(),
 | |
| +        getEnabledWindowFeatures(features));
 | |
| +}
 | |
| +
 | |
| +void InspectorPlaywrightAgent::didFinishScreencast(const PAL::SessionID& sessionID, const String& screencastID)
 | |
| +{
 | |
| +    if (!m_isEnabled)
 | |
| +        return;
 | |
| +
 | |
| +    m_frontendDispatcher->screencastFinished(screencastID);
 | |
| +}
 | |
| +
 | |
| +static WebsiteDataStore* findDefaultWebsiteDataStore() {
 | |
| +    WebsiteDataStore* result = nullptr;
 | |
| +    WebsiteDataStore::forEachWebsiteDataStore([&result] (WebsiteDataStore& dataStore) {
 | |
| +        if (dataStore.isPersistent()) {
 | |
| +            RELEASE_ASSERT(result == nullptr);
 | |
| +            result = &dataStore;
 | |
| +        }
 | |
| +    });
 | |
| +    return result;
 | |
| +}
 | |
| +
 | |
| +Inspector::Protocol::ErrorStringOr<void> InspectorPlaywrightAgent::enable()
 | |
| +{
 | |
| +    if (m_isEnabled)
 | |
| +        return { };
 | |
| +
 | |
| +    m_isEnabled = true;
 | |
| +
 | |
| +    auto* defaultDataStore = findDefaultWebsiteDataStore();
 | |
| +    if (!m_defaultContext && defaultDataStore) {
 | |
| +        auto context = std::make_unique<BrowserContext>();
 | |
| +        m_defaultContext = context.get();
 | |
| +        context->processPool = WebProcessPool::allProcessPools().first().ptr();
 | |
| +        context->dataStore = defaultDataStore;
 | |
| +        setGeolocationProvider(context.get());
 | |
| +        // Add default context to the map so that we can easily find it for
 | |
| +        // created/deleted pages.
 | |
| +        PAL::SessionID sessionID = context->dataStore->sessionID();
 | |
| +        m_browserContexts.set(toBrowserContextIDProtocolString(sessionID), WTFMove(context));
 | |
| +    }
 | |
| +
 | |
| +    WebsiteDataStore::forEachWebsiteDataStore([this] (WebsiteDataStore& dataStore) {
 | |
| +        dataStore.setDownloadInstrumentation(this);
 | |
| +    });
 | |
| +    for (auto& pool : WebProcessPool::allProcessPools()) {
 | |
| +        for (auto& process : pool->processes()) {
 | |
| +            for (auto* page : process->pages())
 | |
| +                didCreateInspectorController(*page);
 | |
| +        }
 | |
| +    }
 | |
| +    return { };
 | |
| +}
 | |
| +
 | |
| +Inspector::Protocol::ErrorStringOr<void> InspectorPlaywrightAgent::disable()
 | |
| +{
 | |
| +    if (!m_isEnabled)
 | |
| +        return { };
 | |
| +
 | |
| +    m_isEnabled = false;
 | |
| +
 | |
| +    for (auto it = m_pageProxyChannels.begin(); it != m_pageProxyChannels.end(); ++it)
 | |
| +        it->value->disconnect();
 | |
| +    m_pageProxyChannels.clear();
 | |
| +
 | |
| +    WebsiteDataStore::forEachWebsiteDataStore([] (WebsiteDataStore& dataStore) {
 | |
| +        dataStore.setDownloadInstrumentation(nullptr);
 | |
| +        dataStore.setDownloadForAutomation(std::optional<bool>(), String());
 | |
| +    });
 | |
| +    for (auto& it : m_browserContexts) {
 | |
| +        it.value->dataStore->setDownloadInstrumentation(nullptr);
 | |
| +        it.value->pages.clear();
 | |
| +    }
 | |
| +    m_browserContextDeletions.clear();
 | |
| +    return { };
 | |
| +}
 | |
| +
 | |
| +void InspectorPlaywrightAgent::close(Ref<CloseCallback>&& callback)
 | |
| +{
 | |
| +    closeImpl([callback = WTFMove(callback)] (String error) {
 | |
| +        if (!callback->isActive())
 | |
| +            return;
 | |
| +        if (error.isNull())
 | |
| +            callback->sendSuccess();
 | |
| +        else
 | |
| +            callback->sendFailure(error);
 | |
| +    });
 | |
| +}
 | |
| +
 | |
| +void InspectorPlaywrightAgent::closeImpl(Function<void(String)>&& callback)
 | |
| +{
 | |
| +    Vector<WebPageProxy*> pages;
 | |
| +    // If Web Process crashed it will be disconnected from its pool until
 | |
| +    // the page reloads. So we cannot discover such processes and the pages
 | |
| +    // by traversing all process pools and their processes. Instead we look at
 | |
| +    // all existing Web Processes wether in a pool or not.
 | |
| +    for (auto* process : WebProcessProxy::allProcessesForInspector()) {
 | |
| +        for (auto* page : process->pages())
 | |
| +            pages.append(page);
 | |
| +    }
 | |
| +    for (auto* page : pages)
 | |
| +        page->closePage();
 | |
| +
 | |
| +    if (!m_defaultContext) {
 | |
| +        m_client->closeBrowser();
 | |
| +        callback(String());
 | |
| +        return;
 | |
| +    }
 | |
| +
 | |
| +    m_defaultContext->dataStore->syncLocalStorage([this, callback = WTFMove(callback)] () {
 | |
| +        if (m_client == nullptr) {
 | |
| +            callback("no platform delegate to close browser"_s);
 | |
| +        } else {
 | |
| +            m_client->closeBrowser();
 | |
| +            callback(String());
 | |
| +        }
 | |
| +    });
 | |
| +
 | |
| +}
 | |
| +
 | |
| +Inspector::Protocol::ErrorStringOr<String /* browserContextID */> InspectorPlaywrightAgent::createContext(const String& proxyServer, const String& proxyBypassList)
 | |
| +{
 | |
| +    String errorString;
 | |
| +    std::unique_ptr<BrowserContext> browserContext = m_client->createBrowserContext(errorString, proxyServer, proxyBypassList);
 | |
| +    if (!browserContext)
 | |
| +        return makeUnexpected(errorString);
 | |
| +
 | |
| +    // Ensure network process.
 | |
| +    browserContext->dataStore->networkProcess();
 | |
| +    browserContext->dataStore->setDownloadInstrumentation(this);
 | |
| +    setGeolocationProvider(browserContext.get());
 | |
| +    PAL::SessionID sessionID = browserContext->dataStore->sessionID();
 | |
| +    String browserContextID = toBrowserContextIDProtocolString(sessionID);
 | |
| +    m_browserContexts.set(browserContextID, WTFMove(browserContext));
 | |
| +    return browserContextID;
 | |
| +}
 | |
| +
 | |
| +void InspectorPlaywrightAgent::deleteContext(const String& browserContextID, Ref<DeleteContextCallback>&& callback)
 | |
| +{
 | |
| +    String errorString;
 | |
| +    BrowserContext* browserContext = lookupBrowserContext(errorString, browserContextID);
 | |
| +    if (!lookupBrowserContext(errorString, browserContextID)) {
 | |
| +        callback->sendFailure(errorString);
 | |
| +        return;
 | |
| +    }
 | |
| +
 | |
| +    if (browserContext == m_defaultContext) {
 | |
| +        callback->sendFailure("Cannot delete default context"_s);
 | |
| +        return;
 | |
| +    }
 | |
| +
 | |
| +    auto pages = browserContext->pages;
 | |
| +    PAL::SessionID sessionID = browserContext->dataStore->sessionID();
 | |
| +    auto contextHolder = m_browserContexts.take(browserContextID);
 | |
| +    if (pages.isEmpty()) {
 | |
| +        callback->sendSuccess();
 | |
| +    } else {
 | |
| +        m_browserContextDeletions.set(browserContextID, makeUnique<BrowserContextDeletion>(WTFMove(contextHolder), pages.size(), WTFMove(callback)));
 | |
| +        for (auto* page : pages)
 | |
| +            page->closePage();
 | |
| +    }
 | |
| +    m_client->deleteBrowserContext(errorString, sessionID);
 | |
| +}
 | |
| +
 | |
| +Inspector::Protocol::ErrorStringOr<String /* pageProxyID */> InspectorPlaywrightAgent::createPage(const String& browserContextID)
 | |
| +{
 | |
| +    String errorString;
 | |
| +    BrowserContext* browserContext = lookupBrowserContext(errorString, browserContextID);
 | |
| +    if (!browserContext)
 | |
| +        return makeUnexpected(errorString);
 | |
| +
 | |
| +    RefPtr<WebPageProxy> page = m_client->createPage(errorString, *browserContext);
 | |
| +    if (!page)
 | |
| +        return makeUnexpected(errorString);
 | |
| +
 | |
| +    return toPageProxyIDProtocolString(*page);
 | |
| +}
 | |
| +
 | |
| +WebFrameProxy* InspectorPlaywrightAgent::frameForID(const String& frameID, String& error)
 | |
| +{
 | |
| +    size_t dotPos = frameID.find("."_s);
 | |
| +    if (dotPos == notFound) {
 | |
| +        error = "Invalid frame id"_s;
 | |
| +        return nullptr;
 | |
| +    }
 | |
| +
 | |
| +    if (!frameID.isAllASCII()) {
 | |
| +        error = "Invalid frame id"_s;
 | |
| +        return nullptr;
 | |
| +    }
 | |
| +
 | |
| +    String processIDString = frameID.left(dotPos);
 | |
| +    uint64_t pid = strtoull(processIDString.ascii().data(), 0, 10);
 | |
| +    auto processID = makeObjectIdentifier<WebCore::ProcessIdentifierType>(pid);
 | |
| +    WebProcessProxy* process = WebProcessProxy::processForIdentifier(processID);
 | |
| +    if (!process) {
 | |
| +        error = "Cannot find web process for the frame id"_s;
 | |
| +        return nullptr;
 | |
| +    }
 | |
| +
 | |
| +    String frameIDString = frameID.substring(dotPos + 1);
 | |
| +    uint64_t frameIDNumber = strtoull(frameIDString.ascii().data(), 0, 10);
 | |
| +    auto frameIdentifier = makeObjectIdentifier<WebCore::FrameIdentifierType>(frameIDNumber);
 | |
| +    WebFrameProxy* frame = process->webFrame(frameIdentifier);
 | |
| +    if (!frame) {
 | |
| +        error = "Cannot find web frame for the frame id"_s;
 | |
| +        return nullptr;
 | |
| +    }
 | |
| +
 | |
| +    return frame;
 | |
| +}
 | |
| +
 | |
| +void InspectorPlaywrightAgent::navigate(const String& url, const String& pageProxyID, const String& frameID, const String& referrer, Ref<NavigateCallback>&& callback)
 | |
| +{
 | |
| +    auto* pageProxyChannel = m_pageProxyChannels.get(pageProxyID);
 | |
| +    if (!pageProxyChannel) {
 | |
| +        callback->sendFailure("Cannot find page proxy with provided 'pageProxyId'"_s);
 | |
| +        return;
 | |
| +    }
 | |
| +
 | |
| +    WebCore::ResourceRequest resourceRequest { url };
 | |
| +
 | |
| +    if (!!referrer)
 | |
| +        resourceRequest.setHTTPReferrer(referrer);
 | |
| +
 | |
| +    if (!resourceRequest.url().isValid()) {
 | |
| +        callback->sendFailure("Cannot navigate to invalid URL"_s);
 | |
| +        return;
 | |
| +    }
 | |
| +
 | |
| +    WebFrameProxy* frame = nullptr;
 | |
| +    if (!!frameID) {
 | |
| +        String error;
 | |
| +        frame = frameForID(frameID, error);
 | |
| +        if (!frame) {
 | |
| +            callback->sendFailure(error);
 | |
| +            return;
 | |
| +        }
 | |
| +
 | |
| +        if (frame->page() != &pageProxyChannel->page()) {
 | |
| +            callback->sendFailure("Frame with specified is not from the specified page"_s);
 | |
| +            return;
 | |
| +        }
 | |
| +    }
 | |
| +
 | |
| +    pageProxyChannel->page().inspectorController().navigate(WTFMove(resourceRequest), frame, [callback = WTFMove(callback)](const String& error, uint64_t navigationID) {
 | |
| +        if (!error.isEmpty()) {
 | |
| +            callback->sendFailure(error);
 | |
| +            return;
 | |
| +        }
 | |
| +
 | |
| +        String navigationIDString;
 | |
| +        if (navigationID)
 | |
| +            navigationIDString = String::number(navigationID);
 | |
| +        callback->sendSuccess(navigationIDString);
 | |
| +    });
 | |
| +}
 | |
| +
 | |
| +Inspector::Protocol::ErrorStringOr<void> InspectorPlaywrightAgent::grantFileReadAccess(const String& pageProxyID, Ref<JSON::Array>&& paths)
 | |
| +{
 | |
| +#if ENABLE(SANDBOX_EXTENSIONS)
 | |
| +    auto* pageProxyChannel = m_pageProxyChannels.get(pageProxyID);
 | |
| +    if (!pageProxyChannel)
 | |
| +        return makeUnexpected("Unknown pageProxyID"_s);
 | |
| +
 | |
| +    Vector<String> files;
 | |
| +    for (const auto& value : paths.get()) {
 | |
| +        String path;
 | |
| +        if (!value->asString(path))
 | |
| +            return makeUnexpected("Filr path must be a string"_s);
 | |
| +
 | |
| +        files.append(path);
 | |
| +    }
 | |
| +
 | |
| +    auto sandboxExtensionHandles = SandboxExtension::createReadOnlyHandlesForFiles("InspectorPlaywrightAgent::grantFileReadAccess"_s, files);
 | |
| +    pageProxyChannel->page().send(Messages::WebPage::ExtendSandboxForFilesFromOpenPanel(WTFMove(sandboxExtensionHandles)));
 | |
| +#endif
 | |
| +    return { };
 | |
| +}
 | |
| +
 | |
| +Inspector::Protocol::ErrorStringOr<void> InspectorPlaywrightAgent::setIgnoreCertificateErrors(const String& browserContextID, bool ignore)
 | |
| +{
 | |
| +    String errorString;
 | |
| +    BrowserContext* browserContext = lookupBrowserContext(errorString, browserContextID);
 | |
| +    if (!errorString.isEmpty())
 | |
| +        return makeUnexpected(errorString);
 | |
| +
 | |
| +    PAL::SessionID sessionID = browserContext->dataStore->sessionID();
 | |
| +    NetworkProcessProxy& networkProcess = browserContext->dataStore->networkProcess();
 | |
| +    networkProcess.send(Messages::NetworkProcess::SetIgnoreCertificateErrors(sessionID, ignore), 0);
 | |
| +    return { };
 | |
| +}
 | |
| +
 | |
| +void InspectorPlaywrightAgent::getAllCookies(const String& browserContextID, Ref<GetAllCookiesCallback>&& callback) {
 | |
| +    String errorString;
 | |
| +    BrowserContext* browserContext = lookupBrowserContext(errorString, browserContextID);
 | |
| +    if (!errorString.isEmpty()) {
 | |
| +        callback->sendFailure(errorString);
 | |
| +        return;
 | |
| +    }
 | |
| +
 | |
| +    PAL::SessionID sessionID = browserContext->dataStore->sessionID();
 | |
| +    NetworkProcessProxy& networkProcess = browserContext->dataStore->networkProcess();
 | |
| +    networkProcess.cookieManager().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));
 | |
| +        });
 | |
| +}
 | |
| +
 | |
| +void InspectorPlaywrightAgent::setCookies(const String& browserContextID, Ref<JSON::Array>&& in_cookies, Ref<SetCookiesCallback>&& callback) {
 | |
| +    String errorString;
 | |
| +    BrowserContext* browserContext = lookupBrowserContext(errorString, browserContextID);
 | |
| +    if (!errorString.isEmpty()) {
 | |
| +        callback->sendFailure(errorString);
 | |
| +        return;
 | |
| +    }
 | |
| +
 | |
| +    NetworkProcessProxy& networkProcess = browserContext->dataStore->networkProcess();
 | |
| +    PAL::SessionID sessionID = browserContext->dataStore->sessionID();
 | |
| +
 | |
| +    Vector<WebCore::Cookie> cookies;
 | |
| +    for (unsigned i = 0; i < in_cookies->length(); ++i) {
 | |
| +        RefPtr<JSON::Value> item = in_cookies->get(i);
 | |
| +        RefPtr<JSON::Object> obj = item->asObject();
 | |
| +        if (!obj) {
 | |
| +            callback->sendFailure("Invalid cookie payload format"_s);
 | |
| +            return;
 | |
| +        }
 | |
| +
 | |
| +        WebCore::Cookie cookie;
 | |
| +        cookie.name = obj->getString("name"_s);
 | |
| +        cookie.value = obj->getString("value"_s);
 | |
| +        cookie.domain = obj->getString("domain"_s);
 | |
| +        cookie.path = obj->getString("path"_s);
 | |
| +        if (!cookie.name || !cookie.value || !cookie.domain || !cookie.path) {
 | |
| +            callback->sendFailure("Invalid file payload format"_s);
 | |
| +            return;
 | |
| +        }
 | |
| +
 | |
| +        std::optional<double> expires = obj->getDouble("expires"_s);
 | |
| +        if (expires && *expires != -1)
 | |
| +            cookie.expires = *expires;
 | |
| +        if (std::optional<bool> value = obj->getBoolean("httpOnly"_s))
 | |
| +            cookie.httpOnly = *value;
 | |
| +        if (std::optional<bool> value = obj->getBoolean("secure"_s))
 | |
| +            cookie.secure = *value;
 | |
| +        if (std::optional<bool> value = obj->getBoolean("session"_s))
 | |
| +            cookie.session = *value;
 | |
| +        String sameSite;
 | |
| +        if (obj->getString("sameSite"_s, sameSite)) {
 | |
| +            if (sameSite == "None")
 | |
| +                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.cookieManager().setCookies(sessionID, WTFMove(cookies),
 | |
| +        [callback = WTFMove(callback)]() {
 | |
| +            if (!callback->isActive())
 | |
| +                return;
 | |
| +            callback->sendSuccess();
 | |
| +        });
 | |
| +}
 | |
| +
 | |
| +void InspectorPlaywrightAgent::deleteAllCookies(const String& browserContextID, Ref<DeleteAllCookiesCallback>&& callback) {
 | |
| +    String errorString;
 | |
| +    BrowserContext* browserContext = lookupBrowserContext(errorString, browserContextID);
 | |
| +    if (!errorString.isEmpty()) {
 | |
| +        callback->sendFailure(errorString);
 | |
| +        return;
 | |
| +    }
 | |
| +
 | |
| +    NetworkProcessProxy& networkProcess = browserContext->dataStore->networkProcess();
 | |
| +    PAL::SessionID sessionID = browserContext->dataStore->sessionID();
 | |
| +    networkProcess.cookieManager().deleteAllCookies(sessionID,
 | |
| +        [callback = WTFMove(callback)]() {
 | |
| +            if (!callback->isActive())
 | |
| +                return;
 | |
| +            callback->sendSuccess();
 | |
| +        });
 | |
| +}
 | |
| +
 | |
| +Inspector::Protocol::ErrorStringOr<void> InspectorPlaywrightAgent::setLanguages(Ref<JSON::Array>&& languages, const String& browserContextID)
 | |
| +{
 | |
| +    String errorString;
 | |
| +    BrowserContext* browserContext = lookupBrowserContext(errorString, browserContextID);
 | |
| +    if (!errorString.isEmpty())
 | |
| +        return makeUnexpected(errorString);
 | |
| +
 | |
| +    Vector<String> items;
 | |
| +    for (const auto& value : languages.get()) {
 | |
| +        String language;
 | |
| +        if (!value->asString(language))
 | |
| +            return makeUnexpected("Language must be a string"_s);
 | |
| +
 | |
| +        items.append(language);
 | |
| +    }
 | |
| +
 | |
| +    browserContext->processPool->configuration().setOverrideLanguages(WTFMove(items));
 | |
| +    return { };
 | |
| +}
 | |
| +
 | |
| +Inspector::Protocol::ErrorStringOr<void> InspectorPlaywrightAgent::setDownloadBehavior(const String& behavior, const String& downloadPath, const String& browserContextID)
 | |
| +{
 | |
| +    String errorString;
 | |
| +    BrowserContext* browserContext = lookupBrowserContext(errorString, browserContextID);
 | |
| +    if (!errorString.isEmpty())
 | |
| +        return makeUnexpected(errorString);
 | |
| +
 | |
| +    std::optional<bool> allow;
 | |
| +    if (behavior == "allow"_s)
 | |
| +      allow = true;
 | |
| +    if (behavior == "deny"_s)
 | |
| +      allow = false;
 | |
| +    browserContext->dataStore->setDownloadForAutomation(allow, downloadPath);
 | |
| +    return { };
 | |
| +}
 | |
| +
 | |
| +Inspector::Protocol::ErrorStringOr<void> InspectorPlaywrightAgent::setGeolocationOverride(const String& browserContextID, RefPtr<JSON::Object>&& geolocation)
 | |
| +{
 | |
| +    String errorString;
 | |
| +    BrowserContext* browserContext = lookupBrowserContext(errorString, browserContextID);
 | |
| +    if (!errorString.isEmpty())
 | |
| +        return makeUnexpected(errorString);
 | |
| +
 | |
| +    auto* geoManager = browserContext->processPool->supplement<WebGeolocationManagerProxy>();
 | |
| +    if (!geoManager)
 | |
| +        return makeUnexpected("Internal error: geolocation manager is not available."_s);
 | |
| +
 | |
| +    if (geolocation) {
 | |
| +        std::optional<double> timestamp = geolocation->getDouble("timestamp"_s);
 | |
| +        std::optional<double> latitude = geolocation->getDouble("latitude"_s);
 | |
| +        std::optional<double> longitude = geolocation->getDouble("longitude"_s);
 | |
| +        std::optional<double> accuracy = geolocation->getDouble("accuracy"_s);
 | |
| +        if (!timestamp || !latitude || !longitude || !accuracy)
 | |
| +            return makeUnexpected("Invalid geolocation format"_s);
 | |
| +
 | |
| +        auto position = WebGeolocationPosition::create(WebCore::GeolocationPositionData(*timestamp, *latitude, *longitude, *accuracy));
 | |
| +        if (!browserContext->geolocationProvider)
 | |
| +            return makeUnexpected("Internal error: geolocation provider has been destroyed."_s);
 | |
| +        browserContext->geolocationProvider->setPosition(position);
 | |
| +        geoManager->providerDidChangePosition(&position.get());
 | |
| +    } else {
 | |
| +        geoManager->providerDidFailToDeterminePosition("Position unavailable"_s);
 | |
| +    }
 | |
| +    return { };
 | |
| +}
 | |
| +
 | |
| +void InspectorPlaywrightAgent::downloadCreated(const String& uuid, const WebCore::ResourceRequest& request, const FrameInfoData& frameInfoData, WebPageProxy* page, RefPtr<DownloadProxy> download)
 | |
| +{
 | |
| +    if (!m_isEnabled)
 | |
| +        return;
 | |
| +    String frameID = WebCore::InspectorPageAgent::makeFrameID(page->process().coreProcessIdentifier(), frameInfoData.frameID ? *frameInfoData.frameID : page->mainFrame()->frameID());
 | |
| +    m_downloads.set(uuid, download);
 | |
| +    m_frontendDispatcher->downloadCreated(
 | |
| +        toPageProxyIDProtocolString(*page),
 | |
| +        frameID,
 | |
| +        uuid, request.url().string());
 | |
| +}
 | |
| +
 | |
| +void InspectorPlaywrightAgent::downloadFilenameSuggested(const String& uuid, const String& suggestedFilename)
 | |
| +{
 | |
| +    if (!m_isEnabled)
 | |
| +        return;
 | |
| +    m_frontendDispatcher->downloadFilenameSuggested(uuid, suggestedFilename);
 | |
| +}
 | |
| +
 | |
| +void InspectorPlaywrightAgent::downloadFinished(const String& uuid, const String& error)
 | |
| +{
 | |
| +    if (!m_isEnabled)
 | |
| +        return;
 | |
| +    m_frontendDispatcher->downloadFinished(uuid, error);
 | |
| +    m_downloads.remove(uuid);
 | |
| +}
 | |
| +
 | |
| +Inspector::Protocol::ErrorStringOr<void> InspectorPlaywrightAgent::cancelDownload(const String& uuid)
 | |
| +{
 | |
| +    if (!m_isEnabled)
 | |
| +        return { };
 | |
| +    auto download = m_downloads.get(uuid);
 | |
| +    if (!download)
 | |
| +        return { };
 | |
| +    download->cancel([] (auto*) {});
 | |
| +    return { };
 | |
| +}
 | |
| +
 | |
| +BrowserContext* InspectorPlaywrightAgent::getExistingBrowserContext(const String& browserContextID)
 | |
| +{
 | |
| +    BrowserContext* browserContext = m_browserContexts.get(browserContextID);
 | |
| +    if (browserContext)
 | |
| +        return browserContext;
 | |
| +
 | |
| +    auto it = m_browserContextDeletions.find(browserContextID);
 | |
| +    RELEASE_ASSERT(it != m_browserContextDeletions.end());
 | |
| +    return it->value->context();
 | |
| +}
 | |
| +
 | |
| +BrowserContext* InspectorPlaywrightAgent::lookupBrowserContext(ErrorString& errorString, const String& browserContextID)
 | |
| +{
 | |
| +    if (!browserContextID) {
 | |
| +        if (!m_defaultContext)
 | |
| +            errorString = "Browser started with no default context"_s;
 | |
| +        return m_defaultContext;
 | |
| +    }
 | |
| +
 | |
| +    BrowserContext* browserContext = m_browserContexts.get(browserContextID);
 | |
| +    if (!browserContext)
 | |
| +        errorString = "Could not find browser context for given id"_s;
 | |
| +    return browserContext;
 | |
| +}
 | |
| +
 | |
| +} // namespace WebKit
 | |
| +
 | |
| +#endif // ENABLE(REMOTE_INSPECTOR)
 | |
| diff --git a/Source/WebKit/UIProcess/InspectorPlaywrightAgent.h b/Source/WebKit/UIProcess/InspectorPlaywrightAgent.h
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..8522b4942343d9a6f2473ea9a133d1ff5267e8ed
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/UIProcess/InspectorPlaywrightAgent.h
 | |
| @@ -0,0 +1,127 @@
 | |
| +/*
 | |
| + * Copyright (C) 2019 Microsoft Corporation.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
| + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#pragma once
 | |
| +
 | |
| +#if ENABLE(REMOTE_INSPECTOR)
 | |
| +
 | |
| +#include "InspectorPlaywrightAgentClient.h"
 | |
| +#include <JavaScriptCore/InspectorBackendDispatchers.h>
 | |
| +#include "WebPageInspectorController.h"
 | |
| +#include "WebProcessPool.h"
 | |
| +#include "DownloadProxy.h"
 | |
| +#include <wtf/HashMap.h>
 | |
| +#include <wtf/Forward.h>
 | |
| +#include <wtf/Noncopyable.h>
 | |
| +
 | |
| +namespace Inspector {
 | |
| +class BackendDispatcher;
 | |
| +class FrontendChannel;
 | |
| +class FrontendRouter;
 | |
| +class PlaywrightFrontendDispatcher;
 | |
| +}
 | |
| +
 | |
| +namespace PAL {
 | |
| +class SessionID;
 | |
| +}
 | |
| +
 | |
| +namespace WebKit {
 | |
| +
 | |
| +class WebFrameProxy;
 | |
| +
 | |
| +class InspectorPlaywrightAgent final
 | |
| +    : public WebPageInspectorControllerObserver
 | |
| +    , public Inspector::PlaywrightBackendDispatcherHandler
 | |
| +    , public DownloadInstrumentation {
 | |
| +    WTF_MAKE_NONCOPYABLE(InspectorPlaywrightAgent);
 | |
| +    WTF_MAKE_FAST_ALLOCATED;
 | |
| +public:
 | |
| +    explicit InspectorPlaywrightAgent(std::unique_ptr<InspectorPlaywrightAgentClient> client);
 | |
| +    ~InspectorPlaywrightAgent() override;
 | |
| +
 | |
| +    // Transport
 | |
| +    void connectFrontend(Inspector::FrontendChannel&);
 | |
| +    void disconnectFrontend();
 | |
| +    void dispatchMessageFromFrontend(const String& message);
 | |
| +
 | |
| +private:
 | |
| +    class BrowserContextDeletion;
 | |
| +    class PageProxyChannel;
 | |
| +    class TargetHandler;
 | |
| +
 | |
| +    // WebPageInspectorControllerObserver
 | |
| +    void didCreateInspectorController(WebPageProxy&) override;
 | |
| +    void willDestroyInspectorController(WebPageProxy&) override;
 | |
| +    void didFailProvisionalLoad(WebPageProxy&, uint64_t navigationID, const String& error) override;
 | |
| +    void willCreateNewPage(WebPageProxy&, const WebCore::WindowFeatures&, const URL&) override;
 | |
| +    void didFinishScreencast(const PAL::SessionID& sessionID, const String& screencastID) override;
 | |
| +
 | |
| +    // PlaywrightDispatcherHandler
 | |
| +    Inspector::Protocol::ErrorStringOr<void> enable() override;
 | |
| +    Inspector::Protocol::ErrorStringOr<void> disable() override;
 | |
| +    void close(Ref<CloseCallback>&&) override;
 | |
| +    Inspector::Protocol::ErrorStringOr<String /* browserContextID */> createContext(const String& proxyServer, const String& proxyBypassList) override;
 | |
| +    void deleteContext(const String& browserContextID, Ref<DeleteContextCallback>&& callback) override;
 | |
| +    Inspector::Protocol::ErrorStringOr<String /* pageProxyID */> createPage(const String& browserContextID) override;
 | |
| +    void navigate(const String& url, const String& pageProxyID, const String& frameId, const String& referrer, Ref<NavigateCallback>&&) override;
 | |
| +    Inspector::Protocol::ErrorStringOr<void> grantFileReadAccess(const String& pageProxyID, Ref<JSON::Array>&& paths) override;
 | |
| +    Inspector::Protocol::ErrorStringOr<void> setIgnoreCertificateErrors(const String& browserContextID, bool ignore) override;
 | |
| +
 | |
| +    void getAllCookies(const String& browserContextID, Ref<GetAllCookiesCallback>&&) override;
 | |
| +    void setCookies(const String& browserContextID, Ref<JSON::Array>&& in_cookies, Ref<SetCookiesCallback>&&) override;
 | |
| +    void deleteAllCookies(const String& browserContextID, Ref<DeleteAllCookiesCallback>&&) override;
 | |
| +
 | |
| +    Inspector::Protocol::ErrorStringOr<void> setGeolocationOverride(const String& browserContextID, RefPtr<JSON::Object>&& geolocation) override;
 | |
| +    Inspector::Protocol::ErrorStringOr<void> setLanguages(Ref<JSON::Array>&& languages, const String& browserContextID) override;
 | |
| +    Inspector::Protocol::ErrorStringOr<void> setDownloadBehavior(const String& behavior, const String& downloadPath, const String& browserContextID) override;
 | |
| +    Inspector::Protocol::ErrorStringOr<void> cancelDownload(const String& uuid) override;
 | |
| +
 | |
| +    // DownloadInstrumentation
 | |
| +    void downloadCreated(const String& uuid, const WebCore::ResourceRequest&, const FrameInfoData& frameInfoData, WebPageProxy* page, RefPtr<DownloadProxy> download) override;
 | |
| +    void downloadFilenameSuggested(const String& uuid, const String& suggestedFilename) override;
 | |
| +    void downloadFinished(const String& uuid, const String& error) override;
 | |
| +
 | |
| +    BrowserContext* getExistingBrowserContext(const String& browserContextID);
 | |
| +    BrowserContext* lookupBrowserContext(Inspector::ErrorString&, const String& browserContextID);
 | |
| +    WebFrameProxy* frameForID(const String& frameID, String& error);
 | |
| +    void closeImpl(Function<void(String)>&&);
 | |
| +
 | |
| +    Inspector::FrontendChannel* m_frontendChannel { nullptr };
 | |
| +    Ref<Inspector::FrontendRouter> m_frontendRouter;
 | |
| +    Ref<Inspector::BackendDispatcher> m_backendDispatcher;
 | |
| +    std::unique_ptr<InspectorPlaywrightAgentClient> m_client;
 | |
| +    std::unique_ptr<Inspector::PlaywrightFrontendDispatcher> m_frontendDispatcher;
 | |
| +    Ref<Inspector::PlaywrightBackendDispatcher> m_playwrightDispatcher;
 | |
| +    HashMap<String, std::unique_ptr<PageProxyChannel>> m_pageProxyChannels;
 | |
| +    BrowserContext* m_defaultContext;
 | |
| +    HashMap<String, RefPtr<DownloadProxy>> m_downloads;
 | |
| +    HashMap<String, std::unique_ptr<BrowserContext>> m_browserContexts;
 | |
| +    HashMap<String, std::unique_ptr<BrowserContextDeletion>> m_browserContextDeletions;
 | |
| +    bool m_isEnabled { false };
 | |
| +};
 | |
| +
 | |
| +} // namespace WebKit
 | |
| +
 | |
| +#endif // ENABLE(REMOTE_INSPECTOR)
 | |
| diff --git a/Source/WebKit/UIProcess/InspectorPlaywrightAgentClient.h b/Source/WebKit/UIProcess/InspectorPlaywrightAgentClient.h
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..c9f2d7ec888e819a49cb898803432013f6270c2a
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/UIProcess/InspectorPlaywrightAgentClient.h
 | |
| @@ -0,0 +1,69 @@
 | |
| +/*
 | |
| + * Copyright (C) 2019 Microsoft Corporation.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
| + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#pragma once
 | |
| +
 | |
| +#if ENABLE(REMOTE_INSPECTOR)
 | |
| +
 | |
| +#include <memory>
 | |
| +#include <pal/SessionID.h>
 | |
| +#include <wtf/Forward.h>
 | |
| +#include <wtf/HashSet.h>
 | |
| +#include <wtf/Noncopyable.h>
 | |
| +#include <wtf/RefCounted.h>
 | |
| +#include <wtf/WeakPtr.h>
 | |
| +
 | |
| +namespace WebKit {
 | |
| +
 | |
| +class OverridenGeolocationProvider;
 | |
| +class WebsiteDataStore;
 | |
| +class WebPageProxy;
 | |
| +class WebProcessPool;
 | |
| +
 | |
| +class BrowserContext {
 | |
| +    WTF_MAKE_NONCOPYABLE(BrowserContext);
 | |
| +    WTF_MAKE_FAST_ALLOCATED;
 | |
| +public:
 | |
| +    BrowserContext();
 | |
| +    ~BrowserContext();
 | |
| +
 | |
| +    RefPtr<WebsiteDataStore> dataStore;
 | |
| +    RefPtr<WebProcessPool> processPool;
 | |
| +    HashSet<WebPageProxy*> pages;
 | |
| +    WeakPtr<OverridenGeolocationProvider> geolocationProvider;
 | |
| +};
 | |
| +
 | |
| +class InspectorPlaywrightAgentClient {
 | |
| +public:
 | |
| +    virtual ~InspectorPlaywrightAgentClient() = default;
 | |
| +    virtual RefPtr<WebKit::WebPageProxy> createPage(WTF::String& error, const BrowserContext& context) = 0;
 | |
| +    virtual void closeBrowser() = 0;
 | |
| +    virtual std::unique_ptr<BrowserContext> createBrowserContext(WTF::String& error, const WTF::String& proxyServer, const WTF::String& proxyBypassList) = 0;
 | |
| +    virtual void deleteBrowserContext(WTF::String& error, PAL::SessionID) = 0;
 | |
| +};
 | |
| +
 | |
| +} // namespace WebKit
 | |
| +
 | |
| +#endif // ENABLE(REMOTE_INSPECTOR)
 | |
| diff --git a/Source/WebKit/UIProcess/Launcher/win/ProcessLauncherWin.cpp b/Source/WebKit/UIProcess/Launcher/win/ProcessLauncherWin.cpp
 | |
| index 7a14cfba15c103a2d4fe263fa49d25af3c396ec2..3ee0e154349661632799057c71f1d1f1551c2d69 100644
 | |
| --- a/Source/WebKit/UIProcess/Launcher/win/ProcessLauncherWin.cpp
 | |
| +++ b/Source/WebKit/UIProcess/Launcher/win/ProcessLauncherWin.cpp
 | |
| @@ -96,8 +96,11 @@ void ProcessLauncher::launchProcess()
 | |
|  
 | |
|      STARTUPINFO startupInfo { };
 | |
|      startupInfo.cb = sizeof(startupInfo);
 | |
| -    startupInfo.dwFlags = STARTF_USESHOWWINDOW;
 | |
| +    startupInfo.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
 | |
|      startupInfo.wShowWindow = SW_HIDE;
 | |
| +    startupInfo.hStdInput = ::GetStdHandle(STD_INPUT_HANDLE);
 | |
| +    startupInfo.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE);
 | |
| +    startupInfo.hStdError = ::GetStdHandle(STD_ERROR_HANDLE);
 | |
|      PROCESS_INFORMATION processInformation { };
 | |
|      BOOL result = ::CreateProcess(0, commandLine.data(), 0, 0, true, 0, 0, 0, &startupInfo, &processInformation);
 | |
|  
 | |
| diff --git a/Source/WebKit/UIProcess/PageClient.h b/Source/WebKit/UIProcess/PageClient.h
 | |
| index 195b11a248fb2f2fcd0ee270a1d478caa37c708d..78fbe6d3c4d2b0944c3ef979a52e14bc3da4f625 100644
 | |
| --- a/Source/WebKit/UIProcess/PageClient.h
 | |
| +++ b/Source/WebKit/UIProcess/PageClient.h
 | |
| @@ -321,6 +321,11 @@ public:
 | |
|      virtual void selectionDidChange() = 0;
 | |
|  #endif
 | |
|  
 | |
| +// Paywright begin
 | |
| +#if PLATFORM(COCOA)
 | |
| +    virtual RetainPtr<CGImageRef> takeSnapshotForAutomation() = 0;
 | |
| +#endif
 | |
| +// Paywright end
 | |
|  #if PLATFORM(COCOA) || PLATFORM(GTK)
 | |
|      virtual RefPtr<ViewSnapshot> takeViewSnapshot(std::optional<WebCore::IntRect>&&) = 0;
 | |
|  #endif
 | |
| diff --git a/Source/WebKit/UIProcess/ProvisionalPageProxy.cpp b/Source/WebKit/UIProcess/ProvisionalPageProxy.cpp
 | |
| index f85e2a653d0dff83a2970b0a05e75459830a5c21..f64097fc38ef2a3630d7625a4a7ea678ed12fdaf 100644
 | |
| --- a/Source/WebKit/UIProcess/ProvisionalPageProxy.cpp
 | |
| +++ b/Source/WebKit/UIProcess/ProvisionalPageProxy.cpp
 | |
| @@ -635,3 +635,5 @@ bool ProvisionalPageProxy::sendMessage(UniqueRef<IPC::Encoder>&& encoder, Option
 | |
|  }
 | |
|  
 | |
|  } // namespace WebKit
 | |
| +
 | |
| +#undef MESSAGE_CHECK
 | |
| diff --git a/Source/WebKit/UIProcess/RemoteInspectorPipe.cpp b/Source/WebKit/UIProcess/RemoteInspectorPipe.cpp
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..dd8b28e692dca4078eb710b2a97e61716126a4cb
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/UIProcess/RemoteInspectorPipe.cpp
 | |
| @@ -0,0 +1,224 @@
 | |
| +/*
 | |
| + * Copyright (C) 2019 Microsoft Corporation.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
| + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#include "config.h"
 | |
| +#include "RemoteInspectorPipe.h"
 | |
| +
 | |
| +#if ENABLE(REMOTE_INSPECTOR)
 | |
| +
 | |
| +#include "InspectorPlaywrightAgent.h"
 | |
| +#include <JavaScriptCore/InspectorFrontendChannel.h>
 | |
| +#include <wtf/MainThread.h>
 | |
| +#include <wtf/RunLoop.h>
 | |
| +#include <wtf/UniqueArray.h>
 | |
| +#include <wtf/Vector.h>
 | |
| +#include <wtf/WorkQueue.h>
 | |
| +
 | |
| +#if OS(UNIX)
 | |
| +#include <stdio.h>
 | |
| +#include <unistd.h>
 | |
| +#endif
 | |
| +
 | |
| +#if PLATFORM(WIN)
 | |
| +#include <io.h>
 | |
| +#endif
 | |
| +
 | |
| +namespace WebKit {
 | |
| +
 | |
| +namespace {
 | |
| +
 | |
| +const int readFD = 3;
 | |
| +const int writeFD = 4;
 | |
| +
 | |
| +const size_t kWritePacketSize = 1 << 16;
 | |
| +
 | |
| +#if PLATFORM(WIN)
 | |
| +HANDLE readHandle;
 | |
| +HANDLE writeHandle;
 | |
| +#endif
 | |
| +
 | |
| +size_t ReadBytes(void* buffer, size_t size, bool exact_size)
 | |
| +{
 | |
| +    size_t bytesRead = 0;
 | |
| +    while (bytesRead < size) {
 | |
| +#if PLATFORM(WIN)
 | |
| +        DWORD sizeRead = 0;
 | |
| +        bool hadError = !ReadFile(readHandle, static_cast<char*>(buffer) + bytesRead,
 | |
| +            size - bytesRead, &sizeRead, nullptr);
 | |
| +#else
 | |
| +        int sizeRead = read(readFD, static_cast<char*>(buffer) + bytesRead,
 | |
| +            size - bytesRead);
 | |
| +        if (sizeRead < 0 && errno == EINTR)
 | |
| +            continue;
 | |
| +        bool hadError = sizeRead <= 0;
 | |
| +#endif
 | |
| +        if (hadError) {
 | |
| +            return 0;
 | |
| +        }
 | |
| +        bytesRead += sizeRead;
 | |
| +        if (!exact_size)
 | |
| +            break;
 | |
| +    }
 | |
| +    return bytesRead;
 | |
| +}
 | |
| +
 | |
| +void WriteBytes(const char* bytes, size_t size)
 | |
| +{
 | |
| +    size_t totalWritten = 0;
 | |
| +    while (totalWritten < size) {
 | |
| +        size_t length = size - totalWritten;
 | |
| +        if (length > kWritePacketSize)
 | |
| +            length = kWritePacketSize;
 | |
| +#if PLATFORM(WIN)
 | |
| +        DWORD bytesWritten = 0;
 | |
| +        bool hadError = !WriteFile(writeHandle, bytes + totalWritten, static_cast<DWORD>(length), &bytesWritten, nullptr);
 | |
| +#else
 | |
| +        int bytesWritten = write(writeFD, bytes + totalWritten, length);
 | |
| +        if (bytesWritten < 0 && errno == EINTR)
 | |
| +            continue;
 | |
| +        bool hadError = bytesWritten <= 0;
 | |
| +#endif
 | |
| +        if (hadError)
 | |
| +            return;
 | |
| +        totalWritten += bytesWritten;
 | |
| +    }
 | |
| +}
 | |
| +
 | |
| +}  // namespace
 | |
| +
 | |
| +class RemoteInspectorPipe::RemoteFrontendChannel : public Inspector::FrontendChannel {
 | |
| +    WTF_MAKE_FAST_ALLOCATED;
 | |
| +
 | |
| +public:
 | |
| +    RemoteFrontendChannel()
 | |
| +        : m_senderQueue(WorkQueue::create("Inspector pipe writer"))
 | |
| +    {
 | |
| +    }
 | |
| +
 | |
| +    ~RemoteFrontendChannel() override = default;
 | |
| +
 | |
| +    ConnectionType connectionType() const override
 | |
| +    {
 | |
| +        return ConnectionType::Remote;
 | |
| +    }
 | |
| +
 | |
| +    void sendMessageToFrontend(const String& message) override
 | |
| +    {
 | |
| +        m_senderQueue->dispatch([message = message.isolatedCopy()]() {
 | |
| +            WriteBytes(message.ascii().data(), message.length());
 | |
| +            WriteBytes("\0", 1);
 | |
| +        });
 | |
| +    }
 | |
| +
 | |
| +private:
 | |
| +    Ref<WorkQueue> m_senderQueue;
 | |
| +};
 | |
| +
 | |
| +RemoteInspectorPipe::RemoteInspectorPipe(InspectorPlaywrightAgent& playwrightAgent)
 | |
| +    : m_playwrightAgent(playwrightAgent)
 | |
| +{
 | |
| +    m_remoteFrontendChannel = makeUnique<RemoteFrontendChannel>();
 | |
| +    start();
 | |
| +}
 | |
| +
 | |
| +RemoteInspectorPipe::~RemoteInspectorPipe()
 | |
| +{
 | |
| +    stop();
 | |
| +}
 | |
| +
 | |
| +bool RemoteInspectorPipe::start()
 | |
| +{
 | |
| +    if (m_receiverThread)
 | |
| +        return true;
 | |
| +
 | |
| +#if PLATFORM(WIN)
 | |
| +    readHandle = reinterpret_cast<HANDLE>(_get_osfhandle(readFD));
 | |
| +    writeHandle = reinterpret_cast<HANDLE>(_get_osfhandle(writeFD));
 | |
| +#endif
 | |
| +
 | |
| +    m_playwrightAgent.connectFrontend(*m_remoteFrontendChannel);
 | |
| +    m_terminated = false;
 | |
| +    m_receiverThread = Thread::create("Inspector pipe reader", [this] {
 | |
| +        workerRun();
 | |
| +    });
 | |
| +    return true;
 | |
| +}
 | |
| +
 | |
| +void RemoteInspectorPipe::stop()
 | |
| +{
 | |
| +    if (!m_receiverThread)
 | |
| +        return;
 | |
| +
 | |
| +    m_playwrightAgent.disconnectFrontend();
 | |
| +
 | |
| +    m_terminated = true;
 | |
| +    m_receiverThread->waitForCompletion();
 | |
| +    m_receiverThread = nullptr;
 | |
| +}
 | |
| +
 | |
| +void RemoteInspectorPipe::workerRun()
 | |
| +{
 | |
| +    const size_t bufSize = 256 * 1024;
 | |
| +    auto buffer = makeUniqueArray<char>(bufSize);
 | |
| +    Vector<char> line;
 | |
| +    while (!m_terminated) {
 | |
| +        size_t size = ReadBytes(buffer.get(), bufSize, false);
 | |
| +        if (!size) {
 | |
| +            RunLoop::main().dispatch([this] {
 | |
| +                if (!m_terminated)
 | |
| +                    m_playwrightAgent.disconnectFrontend();
 | |
| +            });
 | |
| +            break;
 | |
| +        }
 | |
| +        size_t start = 0;
 | |
| +        size_t end = line.size();
 | |
| +        line.append(buffer.get(), size);
 | |
| +        while (true) {
 | |
| +            for (; end < line.size(); ++end) {
 | |
| +                if (line[end] == '\0')
 | |
| +                    break;
 | |
| +            }
 | |
| +            if (end == line.size())
 | |
| +                break;
 | |
| +
 | |
| +            if (end > start) {
 | |
| +                String message = String::fromUTF8(line.data() + start, end - start);
 | |
| +                RunLoop::main().dispatch([this, message = WTFMove(message)] {
 | |
| +                    if (!m_terminated)
 | |
| +                        m_playwrightAgent.dispatchMessageFromFrontend(message);
 | |
| +                });
 | |
| +            }
 | |
| +            ++end;
 | |
| +            start = end;
 | |
| +        }
 | |
| +        if (start != 0 && start < line.size())
 | |
| +            memmove(line.data(), line.data() + start, line.size() - start);
 | |
| +        line.shrink(line.size() - start);
 | |
| +    }
 | |
| +}
 | |
| +
 | |
| +} // namespace WebKit
 | |
| +
 | |
| +#endif // ENABLE(REMOTE_INSPECTOR)
 | |
| diff --git a/Source/WebKit/UIProcess/RemoteInspectorPipe.h b/Source/WebKit/UIProcess/RemoteInspectorPipe.h
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..6d04f9290135069359ce6bf8726546482fd1dc95
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/UIProcess/RemoteInspectorPipe.h
 | |
| @@ -0,0 +1,65 @@
 | |
| +/*
 | |
| + * Copyright (C) 2019 Microsoft Corporation.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
| + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#pragma once
 | |
| +
 | |
| +#if ENABLE(REMOTE_INSPECTOR)
 | |
| +
 | |
| +#include <wtf/Ref.h>
 | |
| +#include <wtf/RefPtr.h>
 | |
| +#include <wtf/Threading.h>
 | |
| +
 | |
| +namespace Inspector {
 | |
| +class FrontendChannel;
 | |
| +}
 | |
| +
 | |
| +namespace WebKit {
 | |
| +
 | |
| +class InspectorPlaywrightAgent;
 | |
| +
 | |
| +class RemoteInspectorPipe {
 | |
| +    WTF_MAKE_NONCOPYABLE(RemoteInspectorPipe);
 | |
| +    WTF_MAKE_FAST_ALLOCATED;
 | |
| +public:
 | |
| +    explicit RemoteInspectorPipe(InspectorPlaywrightAgent&);
 | |
| +    ~RemoteInspectorPipe();
 | |
| +
 | |
| +private:
 | |
| +    class RemoteFrontendChannel;
 | |
| +
 | |
| +    bool start();
 | |
| +    void stop();
 | |
| +
 | |
| +    void workerRun();
 | |
| +
 | |
| +    RefPtr<Thread> m_receiverThread;
 | |
| +    std::atomic<bool> m_terminated { false };
 | |
| +    std::unique_ptr<Inspector::FrontendChannel> m_remoteFrontendChannel;
 | |
| +    InspectorPlaywrightAgent& m_playwrightAgent;
 | |
| +};
 | |
| +
 | |
| +} // namespace WebKit
 | |
| +
 | |
| +#endif // ENABLE(REMOTE_INSPECTOR)
 | |
| diff --git a/Source/WebKit/UIProcess/WebAuthentication/Mock/MockLocalConnection.h b/Source/WebKit/UIProcess/WebAuthentication/Mock/MockLocalConnection.h
 | |
| index 684b9616573761123fbcc0d94be29de519ecced6..51ff18323ece0ee15c87d63a1d6fd604377ee968 100644
 | |
| --- a/Source/WebKit/UIProcess/WebAuthentication/Mock/MockLocalConnection.h
 | |
| +++ b/Source/WebKit/UIProcess/WebAuthentication/Mock/MockLocalConnection.h
 | |
| @@ -28,6 +28,7 @@
 | |
|  #if ENABLE(WEB_AUTHN)
 | |
|  
 | |
|  #include "LocalConnection.h"
 | |
| +#include <WebCore/AuthenticatorAssertionResponse.h>
 | |
|  #include <WebCore/MockWebAuthenticationConfiguration.h>
 | |
|  
 | |
|  namespace WebKit {
 | |
| diff --git a/Source/WebKit/UIProcess/WebContextMenuProxy.h b/Source/WebKit/UIProcess/WebContextMenuProxy.h
 | |
| index 8a506c2f4b96185560c8ee198f9af9575152b15a..2e76e28266dfd71061373e8ee4211653f4655bd1 100644
 | |
| --- a/Source/WebKit/UIProcess/WebContextMenuProxy.h
 | |
| +++ b/Source/WebKit/UIProcess/WebContextMenuProxy.h
 | |
| @@ -33,6 +33,7 @@
 | |
|  #include <wtf/RefCounted.h>
 | |
|  #include <wtf/WeakPtr.h>
 | |
|  
 | |
| +OBJC_CLASS NSArray;
 | |
|  OBJC_CLASS NSMenu;
 | |
|  
 | |
|  namespace WebKit {
 | |
| @@ -45,6 +46,7 @@ public:
 | |
|      virtual ~WebContextMenuProxy();
 | |
|  
 | |
|      virtual void show();
 | |
| +    virtual void hide() {}
 | |
|  
 | |
|      WebPageProxy* page() const { return m_page.get(); }
 | |
|  
 | |
| diff --git a/Source/WebKit/UIProcess/WebCookieManagerProxy.cpp b/Source/WebKit/UIProcess/WebCookieManagerProxy.cpp
 | |
| index a719411abe5895a6a4ce9c28e0576f94251701d6..c4a28fff84fa91754d962e7caf7e71ca07322032 100644
 | |
| --- a/Source/WebKit/UIProcess/WebCookieManagerProxy.cpp
 | |
| +++ b/Source/WebKit/UIProcess/WebCookieManagerProxy.cpp
 | |
| @@ -66,10 +66,12 @@ void WebCookieManagerProxy::deleteCookiesForHostnames(PAL::SessionID sessionID,
 | |
|          m_networkProcess->send(Messages::WebCookieManager::DeleteCookiesForHostnames(sessionID, hostnames), 0);
 | |
|  }
 | |
|  
 | |
| -void WebCookieManagerProxy::deleteAllCookies(PAL::SessionID sessionID)
 | |
| +void WebCookieManagerProxy::deleteAllCookies(PAL::SessionID sessionID, CompletionHandler<void()>&& callbackFunction)
 | |
|  {
 | |
|      if (m_networkProcess)
 | |
| -        m_networkProcess->send(Messages::WebCookieManager::DeleteAllCookies(sessionID), 0);
 | |
| +        m_networkProcess->sendWithAsyncReply(Messages::WebCookieManager::DeleteAllCookies(sessionID), WTFMove(callbackFunction));
 | |
| +    else
 | |
| +        callbackFunction();
 | |
|  }
 | |
|  
 | |
|  void WebCookieManagerProxy::deleteCookie(PAL::SessionID sessionID, const Cookie& cookie, CompletionHandler<void()>&& callbackFunction)
 | |
| diff --git a/Source/WebKit/UIProcess/WebCookieManagerProxy.h b/Source/WebKit/UIProcess/WebCookieManagerProxy.h
 | |
| index 3dcf54ad7c8bab1b5ab6a6ec28f5a1f871a4191c..b80849fa2604e63f837f35141ee61b62cb926869 100644
 | |
| --- a/Source/WebKit/UIProcess/WebCookieManagerProxy.h
 | |
| +++ b/Source/WebKit/UIProcess/WebCookieManagerProxy.h
 | |
| @@ -61,7 +61,7 @@ public:
 | |
|      void getHostnamesWithCookies(PAL::SessionID, CompletionHandler<void(Vector<String>&&)>&&);
 | |
|      void deleteCookie(PAL::SessionID, const WebCore::Cookie&, CompletionHandler<void()>&&);
 | |
|      void deleteCookiesForHostnames(PAL::SessionID, const Vector<String>&);
 | |
| -    void deleteAllCookies(PAL::SessionID);
 | |
| +    void deleteAllCookies(PAL::SessionID, CompletionHandler<void()>&&);
 | |
|      void deleteAllCookiesModifiedSince(PAL::SessionID, WallTime, CompletionHandler<void()>&&);
 | |
|  
 | |
|      void setCookies(PAL::SessionID, const Vector<WebCore::Cookie>&, CompletionHandler<void()>&&);
 | |
| diff --git a/Source/WebKit/UIProcess/WebPageInspectorEmulationAgent.cpp b/Source/WebKit/UIProcess/WebPageInspectorEmulationAgent.cpp
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..ae45b4212bdb3f6a004cc80a1d91146b540f86f5
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/UIProcess/WebPageInspectorEmulationAgent.cpp
 | |
| @@ -0,0 +1,147 @@
 | |
| +/*
 | |
| + * Copyright (C) 2019 Microsoft Corporation.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
| + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#include "config.h"
 | |
| +#include "WebPageInspectorEmulationAgent.h"
 | |
| +
 | |
| +#include "APIPageConfiguration.h"
 | |
| +#include "WebPageProxy.h"
 | |
| +#include "WebPreferences.h"
 | |
| +#include "PageClient.h"
 | |
| +#include <JavaScriptCore/InspectorFrontendRouter.h>
 | |
| +#include <WebCore/Credential.h>
 | |
| +
 | |
| +
 | |
| +namespace WebKit {
 | |
| +
 | |
| +using namespace Inspector;
 | |
| +
 | |
| +WebPageInspectorEmulationAgent::WebPageInspectorEmulationAgent(BackendDispatcher& backendDispatcher, WebPageProxy& page)
 | |
| +    : InspectorAgentBase("Emulation"_s)
 | |
| +    , m_backendDispatcher(EmulationBackendDispatcher::create(backendDispatcher, this))
 | |
| +    , m_page(page)
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +WebPageInspectorEmulationAgent::~WebPageInspectorEmulationAgent()
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +void WebPageInspectorEmulationAgent::didCreateFrontendAndBackend(FrontendRouter*, BackendDispatcher*)
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +void WebPageInspectorEmulationAgent::willDestroyFrontendAndBackend(DisconnectReason)
 | |
| +{
 | |
| +   m_commandsToRunWhenShown.clear();
 | |
| +}
 | |
| +
 | |
| +void WebPageInspectorEmulationAgent::setDeviceMetricsOverride(int width, int height, bool fixedlayout, std::optional<double>&& deviceScaleFactor, Ref<SetDeviceMetricsOverrideCallback>&& callback)
 | |
| +{
 | |
| +#if PLATFORM(GTK)
 | |
| +    // On gtk, fixed layout doesn't work with compositing enabled
 | |
| +    // FIXME: This turns off compositing forever, even if fixedLayout is disabled.
 | |
| +    if (fixedlayout) {
 | |
| +        auto copy = m_page.preferences().copy();
 | |
| +        copy->setAcceleratedCompositingEnabled(false);
 | |
| +        m_page.setPreferences(copy);
 | |
| +    }
 | |
| +#endif
 | |
| +
 | |
| +    if (deviceScaleFactor)
 | |
| +        m_page.setCustomDeviceScaleFactor(deviceScaleFactor.value());
 | |
| +    m_page.setUseFixedLayout(fixedlayout);
 | |
| +    if (!m_page.pageClient().isViewVisible() && m_page.configuration().relatedPage()) {
 | |
| +        m_commandsToRunWhenShown.append([this, width, height, callback = WTFMove(callback)]() mutable {
 | |
| +            setSize(width, height, WTFMove(callback));
 | |
| +        });
 | |
| +    } else {
 | |
| +        setSize(width, height, WTFMove(callback));
 | |
| +    }
 | |
| +}
 | |
| +
 | |
| +void WebPageInspectorEmulationAgent::setSize(int width, int height, Ref<SetDeviceMetricsOverrideCallback>&& callback)
 | |
| +{
 | |
| +    platformSetSize(width, height, [callback = WTFMove(callback)](const String& error) {
 | |
| +        if (error.isEmpty())
 | |
| +            callback->sendSuccess();
 | |
| +        else
 | |
| +            callback->sendFailure(error);
 | |
| +    });
 | |
| +}
 | |
| +
 | |
| +Inspector::Protocol::ErrorStringOr<void> WebPageInspectorEmulationAgent::setJavaScriptEnabled(bool enabled)
 | |
| +{
 | |
| +    auto copy = m_page.preferences().copy();
 | |
| +    copy->setJavaScriptEnabled(enabled);
 | |
| +    m_page.setPreferences(copy);
 | |
| +    return { };
 | |
| +}
 | |
| +
 | |
| +Inspector::Protocol::ErrorStringOr<void> WebPageInspectorEmulationAgent::setAuthCredentials(const String& username, const String& password)
 | |
| +{
 | |
| +    if (!!username && !!password)
 | |
| +        m_page.setAuthCredentialsForAutomation(WebCore::Credential(username, password, CredentialPersistencePermanent));
 | |
| +    else
 | |
| +        m_page.setAuthCredentialsForAutomation(std::optional<WebCore::Credential>());
 | |
| +    return { };
 | |
| +}
 | |
| +
 | |
| +Inspector::Protocol::ErrorStringOr<void> WebPageInspectorEmulationAgent::setActiveAndFocused(std::optional<bool>&& active)
 | |
| +{
 | |
| +    m_page.setActiveForAutomation(WTFMove(active));
 | |
| +    return { };
 | |
| +}
 | |
| +
 | |
| +Inspector::Protocol::ErrorStringOr<void> WebPageInspectorEmulationAgent::grantPermissions(const String& origin, Ref<JSON::Array>&& values)
 | |
| +{
 | |
| +    HashSet<String> set;
 | |
| +    for (const auto& value : values.get()) {
 | |
| +        String name;
 | |
| +        if (!value->asString(name))
 | |
| +            return makeUnexpected("Permission must be a string"_s);
 | |
| +
 | |
| +        set.add(name);
 | |
| +    }
 | |
| +    m_permissions.set(origin, WTFMove(set));
 | |
| +    m_page.setPermissionsForAutomation(m_permissions);
 | |
| +    return { };
 | |
| +}
 | |
| +
 | |
| +Inspector::Protocol::ErrorStringOr<void> WebPageInspectorEmulationAgent::resetPermissions()
 | |
| +{
 | |
| +    m_permissions.clear();
 | |
| +    m_page.setPermissionsForAutomation(m_permissions);
 | |
| +    return { };
 | |
| +}
 | |
| +
 | |
| +void WebPageInspectorEmulationAgent::didShowPage()
 | |
| +{
 | |
| +    for (auto& command : m_commandsToRunWhenShown)
 | |
| +        command();
 | |
| +    m_commandsToRunWhenShown.clear();
 | |
| +}
 | |
| +
 | |
| +} // namespace WebKit
 | |
| diff --git a/Source/WebKit/UIProcess/WebPageInspectorEmulationAgent.h b/Source/WebKit/UIProcess/WebPageInspectorEmulationAgent.h
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..b3bb4880a866ee6132b8b26acf8dad81afe14d85
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/UIProcess/WebPageInspectorEmulationAgent.h
 | |
| @@ -0,0 +1,75 @@
 | |
| +/*
 | |
| + * Copyright (C) 2019 Microsoft Corporation.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
| + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#pragma once
 | |
| +
 | |
| +#include <JavaScriptCore/InspectorAgentBase.h>
 | |
| +#include <JavaScriptCore/InspectorBackendDispatchers.h>
 | |
| +
 | |
| +#include <wtf/Forward.h>
 | |
| +#include <wtf/Function.h>
 | |
| +#include <wtf/Noncopyable.h>
 | |
| +#include <wtf/Vector.h>
 | |
| +
 | |
| +namespace Inspector {
 | |
| +class BackendDispatcher;
 | |
| +class FrontendChannel;
 | |
| +class FrontendRouter;
 | |
| +}
 | |
| +
 | |
| +namespace WebKit {
 | |
| +
 | |
| +class WebPageProxy;
 | |
| +
 | |
| +class WebPageInspectorEmulationAgent : public Inspector::InspectorAgentBase, public Inspector::EmulationBackendDispatcherHandler {
 | |
| +    WTF_MAKE_NONCOPYABLE(WebPageInspectorEmulationAgent);
 | |
| +    WTF_MAKE_FAST_ALLOCATED;
 | |
| +public:
 | |
| +    WebPageInspectorEmulationAgent(Inspector::BackendDispatcher& backendDispatcher, WebPageProxy& page);
 | |
| +    ~WebPageInspectorEmulationAgent() override;
 | |
| +
 | |
| +    void didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*) override;
 | |
| +    void willDestroyFrontendAndBackend(Inspector::DisconnectReason) override;
 | |
| +
 | |
| +    void setDeviceMetricsOverride(int width, int height, bool fixedlayout, std::optional<double>&& deviceScaleFactor, Ref<SetDeviceMetricsOverrideCallback>&&) override;
 | |
| +    Inspector::Protocol::ErrorStringOr<void> setJavaScriptEnabled(bool enabled) override;
 | |
| +    Inspector::Protocol::ErrorStringOr<void> setAuthCredentials(const String&, const String&) override;
 | |
| +    Inspector::Protocol::ErrorStringOr<void> setActiveAndFocused(std::optional<bool>&&) override;
 | |
| +    Inspector::Protocol::ErrorStringOr<void> grantPermissions(const String& origin, Ref<JSON::Array>&& permissions) override;
 | |
| +    Inspector::Protocol::ErrorStringOr<void> resetPermissions() override;
 | |
| +
 | |
| +    void didShowPage();
 | |
| +
 | |
| +private:
 | |
| +    void setSize(int width, int height, Ref<SetDeviceMetricsOverrideCallback>&& callback);
 | |
| +    void platformSetSize(int width, int height, Function<void (const String& error)>&&);
 | |
| +
 | |
| +    Ref<Inspector::EmulationBackendDispatcher> m_backendDispatcher;
 | |
| +    WebPageProxy& m_page;
 | |
| +    Vector<Function<void()>> m_commandsToRunWhenShown;
 | |
| +    HashMap<String, HashSet<String>> m_permissions;
 | |
| +};
 | |
| +
 | |
| +} // namespace WebKit
 | |
| diff --git a/Source/WebKit/UIProcess/WebPageInspectorInputAgent.cpp b/Source/WebKit/UIProcess/WebPageInspectorInputAgent.cpp
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..3349b5d961f1308e201782358e8b3a7354d11a97
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/UIProcess/WebPageInspectorInputAgent.cpp
 | |
| @@ -0,0 +1,332 @@
 | |
| +/*
 | |
| + * Copyright (C) 2019 Microsoft Corporation.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
| + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#include "config.h"
 | |
| +#include "WebPageInspectorInputAgent.h"
 | |
| +
 | |
| +#include "NativeWebKeyboardEvent.h"
 | |
| +#include "NativeWebMouseEvent.h"
 | |
| +#include "NativeWebWheelEvent.h"
 | |
| +#include "WebWheelEvent.h"
 | |
| +#include "WebPageProxy.h"
 | |
| +#include <wtf/MathExtras.h>
 | |
| +#include <wtf/HexNumber.h>
 | |
| +
 | |
| +#include "WebPageMessages.h"
 | |
| +
 | |
| +namespace WebKit {
 | |
| +
 | |
| +using namespace Inspector;
 | |
| +
 | |
| +namespace {
 | |
| +
 | |
| +template<class T>
 | |
| +class CallbackList {
 | |
| +    WTF_MAKE_FAST_ALLOCATED;
 | |
| +public:
 | |
| +    ~CallbackList()
 | |
| +    {
 | |
| +        for (const auto& callback : m_callbacks)
 | |
| +            callback->sendFailure("Page closed"_s);
 | |
| +    }
 | |
| +
 | |
| +    void append(Ref<T>&& callback)
 | |
| +    {
 | |
| +        m_callbacks.append(WTFMove(callback));
 | |
| +    }
 | |
| +
 | |
| +    void sendSuccess()
 | |
| +    {
 | |
| +        for (const auto& callback : m_callbacks)
 | |
| +            callback->sendSuccess();
 | |
| +        m_callbacks.clear();
 | |
| +    }
 | |
| +
 | |
| +private:
 | |
| +    Vector<Ref<T>> m_callbacks;
 | |
| +};
 | |
| +
 | |
| +} // namespace
 | |
| +
 | |
| +class WebPageInspectorInputAgent::KeyboardCallbacks : public CallbackList<Inspector::InputBackendDispatcherHandler::DispatchKeyEventCallback> {
 | |
| +};
 | |
| +
 | |
| +class WebPageInspectorInputAgent::MouseCallbacks : public CallbackList<Inspector::InputBackendDispatcherHandler::DispatchMouseEventCallback> {
 | |
| +};
 | |
| +
 | |
| +class WebPageInspectorInputAgent::WheelCallbacks : public CallbackList<Inspector::InputBackendDispatcherHandler::DispatchWheelEventCallback> {
 | |
| +};
 | |
| +
 | |
| +WebPageInspectorInputAgent::WebPageInspectorInputAgent(Inspector::BackendDispatcher& backendDispatcher, WebPageProxy& page)
 | |
| +    : InspectorAgentBase("Input"_s)
 | |
| +    , m_backendDispatcher(InputBackendDispatcher::create(backendDispatcher, this))
 | |
| +    , m_page(page)
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +WebPageInspectorInputAgent::~WebPageInspectorInputAgent() = default;
 | |
| +
 | |
| +void WebPageInspectorInputAgent::didProcessAllPendingKeyboardEvents()
 | |
| +{
 | |
| +    m_keyboardCallbacks->sendSuccess();
 | |
| +}
 | |
| +
 | |
| +void WebPageInspectorInputAgent::didProcessAllPendingMouseEvents()
 | |
| +{
 | |
| +    m_page.setInterceptDrags(false);
 | |
| +    m_mouseCallbacks->sendSuccess();
 | |
| +}
 | |
| +
 | |
| +void WebPageInspectorInputAgent::didProcessAllPendingWheelEvents()
 | |
| +{
 | |
| +    m_wheelCallbacks->sendSuccess();
 | |
| +}
 | |
| +
 | |
| +void WebPageInspectorInputAgent::didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*)
 | |
| +{
 | |
| +    m_keyboardCallbacks = makeUnique<KeyboardCallbacks>();
 | |
| +    m_mouseCallbacks = makeUnique<MouseCallbacks>();
 | |
| +    m_wheelCallbacks = makeUnique<WheelCallbacks>();
 | |
| +}
 | |
| +
 | |
| +void WebPageInspectorInputAgent::willDestroyFrontendAndBackend(Inspector::DisconnectReason)
 | |
| +{
 | |
| +    m_keyboardCallbacks = nullptr;
 | |
| +    m_mouseCallbacks = nullptr;
 | |
| +    m_wheelCallbacks = nullptr;
 | |
| +}
 | |
| +
 | |
| +static String keyIdentifierForKey(const String& key)
 | |
| +{
 | |
| +    if (key.length() == 1)
 | |
| +        return makeString("U+", hex(toASCIIUpper(key.characterAt(0)), 4));
 | |
| +    if (key == "Delete")
 | |
| +        return "U+007F"_s;
 | |
| +    if (key == "Backspace")
 | |
| +        return "U+0008"_s;
 | |
| +    if (key == "ArrowUp")
 | |
| +        return "Up"_s;
 | |
| +    if (key == "ArrowDown")
 | |
| +        return "Down"_s;
 | |
| +    if (key == "ArrowLeft")
 | |
| +        return "Left"_s;
 | |
| +    if (key == "ArrowRight")
 | |
| +        return "Right"_s;
 | |
| +    if (key == "Tab")
 | |
| +        return "U+0009"_s;
 | |
| +    if (key == "Pause")
 | |
| +        return "Pause"_s;
 | |
| +    if (key == "ScrollLock")
 | |
| +        return "Scroll"_s;
 | |
| +    return key;
 | |
| +}
 | |
| +
 | |
| +void WebPageInspectorInputAgent::dispatchKeyEvent(const String& type, std::optional<int>&& modifiers, const String& text, const String& unmodifiedText, const String& code, const String& key, std::optional<int>&& windowsVirtualKeyCode, std::optional<int>&& nativeVirtualKeyCode, std::optional<bool>&& autoRepeat, std::optional<bool>&& isKeypad, std::optional<bool>&& isSystemKey, RefPtr<JSON::Array>&& commands, Ref<Inspector::InputBackendDispatcherHandler::DispatchKeyEventCallback>&& callback)
 | |
| +{
 | |
| +    WebKit::WebEvent::Type eventType;
 | |
| +    if (type == "keyDown") {
 | |
| +        eventType = WebKit::WebEvent::KeyDown;
 | |
| +    } else if (type == "keyUp") {
 | |
| +        eventType = WebKit::WebEvent::KeyUp;
 | |
| +    } else {
 | |
| +        callback->sendFailure("Unsupported event type."_s);
 | |
| +        return;
 | |
| +    }
 | |
| +    OptionSet<WebEvent::Modifier> eventModifiers;
 | |
| +    if (modifiers)
 | |
| +        eventModifiers = eventModifiers.fromRaw(*modifiers);
 | |
| +    int eventWindowsVirtualKeyCode = 0;
 | |
| +    if (windowsVirtualKeyCode)
 | |
| +        eventWindowsVirtualKeyCode = *windowsVirtualKeyCode;
 | |
| +    int eventNativeVirtualKeyCode = 0;
 | |
| +    if (nativeVirtualKeyCode)
 | |
| +        eventNativeVirtualKeyCode = *nativeVirtualKeyCode;
 | |
| +    Vector<String> eventCommands;
 | |
| +    if (commands) {
 | |
| +      for (const auto& value : *commands) {
 | |
| +        String command;
 | |
| +        if (!value->asString(command)) {
 | |
| +          callback->sendFailure("Command must be string"_s);
 | |
| +          return;
 | |
| +        }
 | |
| +        eventCommands.append(command);
 | |
| +      }
 | |
| +    }
 | |
| +
 | |
| +    String keyIdentifier = keyIdentifierForKey(key);
 | |
| +
 | |
| +    bool eventIsAutoRepeat = false;
 | |
| +    if (autoRepeat)
 | |
| +        eventIsAutoRepeat = *autoRepeat;
 | |
| +    bool eventIsKeypad = false;
 | |
| +    if (isKeypad)
 | |
| +        eventIsKeypad = *isKeypad;
 | |
| +    bool eventIsSystemKey = false;
 | |
| +    if (isSystemKey)
 | |
| +        eventIsSystemKey = *isSystemKey;
 | |
| +    WallTime timestamp = WallTime::now();
 | |
| +
 | |
| +    // cancel any active drag on Escape
 | |
| +    if (eventType == WebKit::WebEvent::KeyDown && key == "Escape" && m_page.cancelDragIfNeeded()) {
 | |
| +        callback->sendSuccess();
 | |
| +        return;
 | |
| +    }
 | |
| +
 | |
| +    m_keyboardCallbacks->append(WTFMove(callback));
 | |
| +    platformDispatchKeyEvent(
 | |
| +        eventType,
 | |
| +        text,
 | |
| +        unmodifiedText,
 | |
| +        key,
 | |
| +        code,
 | |
| +        keyIdentifier,
 | |
| +        eventWindowsVirtualKeyCode,
 | |
| +        eventNativeVirtualKeyCode,
 | |
| +        eventIsAutoRepeat,
 | |
| +        eventIsKeypad,
 | |
| +        eventIsSystemKey,
 | |
| +        eventModifiers,
 | |
| +        eventCommands,
 | |
| +        timestamp);
 | |
| +}
 | |
| +
 | |
| +void WebPageInspectorInputAgent::dispatchMouseEvent(const String& type, int x, int y, std::optional<int>&& modifiers, const String& button, std::optional<int>&& buttons, std::optional<int>&& clickCount, std::optional<int>&& deltaX, std::optional<int>&& deltaY, Ref<DispatchMouseEventCallback>&& callback)
 | |
| +{
 | |
| +    WebEvent::Type eventType = WebEvent::NoType;
 | |
| +    if (type == "down")
 | |
| +        eventType = WebEvent::MouseDown;
 | |
| +    else if (type == "up")
 | |
| +        eventType = WebEvent::MouseUp;
 | |
| +    else if (type == "move")
 | |
| +        eventType = WebEvent::MouseMove;
 | |
| +    else {
 | |
| +        callback->sendFailure("Unsupported event type"_s);
 | |
| +        return;
 | |
| +    }
 | |
| +
 | |
| +    OptionSet<WebEvent::Modifier> eventModifiers;
 | |
| +    if (modifiers)
 | |
| +        eventModifiers = eventModifiers.fromRaw(*modifiers);
 | |
| +
 | |
| +    WebMouseEvent::Button eventButton = WebMouseEvent::NoButton;
 | |
| +    if (!!button) {
 | |
| +        if (button == "left")
 | |
| +            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"_s);
 | |
| +            return;
 | |
| +        }
 | |
| +    }
 | |
| +
 | |
| +    unsigned short eventButtons = 0;
 | |
| +    if (buttons)
 | |
| +        eventButtons = *buttons;
 | |
| +
 | |
| +    int eventClickCount = 0;
 | |
| +    if (clickCount)
 | |
| +        eventClickCount = *clickCount;
 | |
| +    int eventDeltaX = 0;
 | |
| +    if (deltaX)
 | |
| +        eventDeltaX = *deltaX;
 | |
| +    int eventDeltaY = 0;
 | |
| +    if (deltaY)
 | |
| +        eventDeltaY = *deltaY;
 | |
| +    m_mouseCallbacks->append(WTFMove(callback));
 | |
| +
 | |
| +    // Convert css coordinates to view coordinates (dip).
 | |
| +    double totalScale = m_page.pageScaleFactor() * m_page.viewScaleFactor();
 | |
| +    x = clampToInteger(roundf(x * totalScale));
 | |
| +    y = clampToInteger(roundf(y * totalScale));
 | |
| +    eventDeltaX = clampToInteger(roundf(eventDeltaX * totalScale));
 | |
| +    eventDeltaY = clampToInteger(roundf(eventDeltaY * totalScale));
 | |
| +
 | |
| +    // We intercept any drags generated by this mouse event
 | |
| +    // to prevent them from creating actual drags in the host
 | |
| +    // operating system. This is turned off in the callback.
 | |
| +    m_page.setInterceptDrags(true);
 | |
| +#if PLATFORM(MAC)
 | |
| +    ASSERT_UNUSED(eventType, 1);
 | |
| +    ASSERT_UNUSED(eventButton, 1);
 | |
| +    ASSERT_UNUSED(eventClickCount, 1);
 | |
| +    platformDispatchMouseEvent(type, x, y, WTFMove(modifiers), button, WTFMove(clickCount), eventButtons);
 | |
| +#elif PLATFORM(GTK) || PLATFORM(WPE) || PLATFORM(WIN)
 | |
| +    WallTime timestamp = WallTime::now();
 | |
| +    NativeWebMouseEvent event(
 | |
| +        eventType,
 | |
| +        eventButton,
 | |
| +        eventButtons,
 | |
| +        {x, y},
 | |
| +        WebCore::IntPoint(),
 | |
| +        eventDeltaX,
 | |
| +        eventDeltaY,
 | |
| +        0,
 | |
| +        eventClickCount,
 | |
| +        eventModifiers,
 | |
| +        timestamp);
 | |
| +    m_page.handleMouseEvent(event);
 | |
| +#endif
 | |
| +}
 | |
| +
 | |
| +void WebPageInspectorInputAgent::dispatchTapEvent(int x, int y, std::optional<int>&& modifiers, Ref<DispatchTapEventCallback>&& callback) {
 | |
| +    m_page.sendWithAsyncReply(Messages::WebPage::FakeTouchTap(WebCore::IntPoint(x, y), modifiers ? *modifiers : 0), [callback]() {
 | |
| +        callback->sendSuccess();
 | |
| +    });
 | |
| +}
 | |
| +
 | |
| +void WebPageInspectorInputAgent::dispatchWheelEvent(int x, int y, std::optional<int>&& modifiers, std::optional<int>&& deltaX, std::optional<int>&& deltaY, Ref<DispatchWheelEventCallback>&& callback)
 | |
| +{
 | |
| +    OptionSet<WebEvent::Modifier> eventModifiers;
 | |
| +    if (modifiers)
 | |
| +        eventModifiers = eventModifiers.fromRaw(*modifiers);
 | |
| +
 | |
| +    float eventDeltaX = 0.0f;
 | |
| +    if (deltaX)
 | |
| +        eventDeltaX = *deltaX;
 | |
| +    float eventDeltaY = 0.0f;
 | |
| +    if (deltaY)
 | |
| +        eventDeltaY = *deltaY;
 | |
| +    m_wheelCallbacks->append(WTFMove(callback));
 | |
| +
 | |
| +    // Convert css coordinates to view coordinates (dip).
 | |
| +    double totalScale = m_page.pageScaleFactor() * m_page.viewScaleFactor();
 | |
| +    x = clampToInteger(roundf(x * totalScale));
 | |
| +    y = clampToInteger(roundf(y * totalScale));
 | |
| +
 | |
| +    WallTime timestamp = WallTime::now();
 | |
| +    WebCore::FloatSize delta = {-eventDeltaX, -eventDeltaY};
 | |
| +    WebCore::FloatSize wheelTicks = delta;
 | |
| +    wheelTicks.scale(1.0f / WebCore::Scrollbar::pixelsPerLineStep());
 | |
| +    WebWheelEvent webEvent(WebEvent::Wheel, {x, y}, {x, y}, delta, wheelTicks, WebWheelEvent::ScrollByPixelWheelEvent, eventModifiers, timestamp);
 | |
| +    NativeWebWheelEvent event(webEvent);
 | |
| +    m_page.handleWheelEvent(event);
 | |
| +}
 | |
| +
 | |
| +} // namespace WebKit
 | |
| diff --git a/Source/WebKit/UIProcess/WebPageInspectorInputAgent.h b/Source/WebKit/UIProcess/WebPageInspectorInputAgent.h
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..48c9ccc420c1b4ae3259e1d5ba17fd8fbea24b96
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/UIProcess/WebPageInspectorInputAgent.h
 | |
| @@ -0,0 +1,86 @@
 | |
| +/*
 | |
| + * Copyright (C) 2019 Microsoft Corporation.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
| + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#pragma once
 | |
| +
 | |
| +#include "WebEvent.h"
 | |
| +#include "WebKeyboardEvent.h"
 | |
| +#include "WebMouseEvent.h"
 | |
| +#include <JavaScriptCore/InspectorAgentBase.h>
 | |
| +#include <JavaScriptCore/InspectorBackendDispatchers.h>
 | |
| +#include <wtf/Forward.h>
 | |
| +#include <wtf/Noncopyable.h>
 | |
| +
 | |
| +namespace Inspector {
 | |
| +class BackendDispatcher;
 | |
| +class FrontendChannel;
 | |
| +class FrontendRouter;
 | |
| +}
 | |
| +
 | |
| +namespace WebKit {
 | |
| +
 | |
| +class NativeWebKeyboardEvent;
 | |
| +class WebPageProxy;
 | |
| +
 | |
| +class WebPageInspectorInputAgent : public Inspector::InspectorAgentBase, public Inspector::InputBackendDispatcherHandler {
 | |
| +    WTF_MAKE_NONCOPYABLE(WebPageInspectorInputAgent);
 | |
| +    WTF_MAKE_FAST_ALLOCATED;
 | |
| +public:
 | |
| +    WebPageInspectorInputAgent(Inspector::BackendDispatcher& backendDispatcher, WebPageProxy& page);
 | |
| +    ~WebPageInspectorInputAgent() override;
 | |
| +
 | |
| +    void didProcessAllPendingKeyboardEvents();
 | |
| +    void didProcessAllPendingMouseEvents();
 | |
| +    void didProcessAllPendingWheelEvents();
 | |
| +
 | |
| +    void didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*) override;
 | |
| +    void willDestroyFrontendAndBackend(Inspector::DisconnectReason) override;
 | |
| +
 | |
| +    // Protocol handler
 | |
| +    void dispatchKeyEvent(const String& type, std::optional<int>&& modifiers, const String& text, const String& unmodifiedText, const String& code, const String& key, std::optional<int>&& windowsVirtualKeyCode, std::optional<int>&& nativeVirtualKeyCode, std::optional<bool>&& autoRepeat, std::optional<bool>&& isKeypad, std::optional<bool>&& isSystemKey, RefPtr<JSON::Array>&&, Ref<DispatchKeyEventCallback>&& callback) override;
 | |
| +    void dispatchMouseEvent(const String& type, int x, int y, std::optional<int>&& modifiers, const String& button, std::optional<int>&& buttons, std::optional<int>&& clickCount, std::optional<int>&& deltaX, std::optional<int>&& deltaY, Ref<DispatchMouseEventCallback>&& callback) override;
 | |
| +    void dispatchTapEvent(int x, int y, std::optional<int>&& modifiers, Ref<DispatchTapEventCallback>&& callback) override;
 | |
| +    void dispatchWheelEvent(int x, int y, std::optional<int>&& modifiers, std::optional<int>&& deltaX, std::optional<int>&& deltaY, Ref<DispatchWheelEventCallback>&& callback) override;
 | |
| +
 | |
| +private:
 | |
| +    void platformDispatchKeyEvent(WebKeyboardEvent::Type type, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<WebEvent::Modifier> modifiers, Vector<String>& commands, WallTime timestamp);
 | |
| +#if PLATFORM(MAC)
 | |
| +    void platformDispatchMouseEvent(const String& type, int x, int y, std::optional<int>&& modifier, const String& button, std::optional<int>&& clickCount, unsigned short buttons);
 | |
| +#endif
 | |
| +
 | |
| +    Ref<Inspector::InputBackendDispatcher> m_backendDispatcher;
 | |
| +    WebPageProxy& m_page;
 | |
| +    // Keep track of currently active modifiers across multiple keystrokes.
 | |
| +    // Most platforms do not track current modifiers from synthesized events.
 | |
| +    unsigned m_currentModifiers { 0 };
 | |
| +    class KeyboardCallbacks;
 | |
| +    std::unique_ptr<KeyboardCallbacks> m_keyboardCallbacks;
 | |
| +    class MouseCallbacks;
 | |
| +    std::unique_ptr<MouseCallbacks> m_mouseCallbacks;
 | |
| +    class WheelCallbacks;
 | |
| +    std::unique_ptr<WheelCallbacks> m_wheelCallbacks;
 | |
| +};
 | |
| +
 | |
| +} // namespace WebKit
 | |
| diff --git a/Source/WebKit/UIProcess/WebPageProxy.cpp b/Source/WebKit/UIProcess/WebPageProxy.cpp
 | |
| index 3deeeaede89b454ee88cb750f237b92ba3946561..c3a181861a11ce9d78e2b26f02ed8805042f0747 100644
 | |
| --- a/Source/WebKit/UIProcess/WebPageProxy.cpp
 | |
| +++ b/Source/WebKit/UIProcess/WebPageProxy.cpp
 | |
| @@ -247,6 +247,9 @@
 | |
|  
 | |
|  #if PLATFORM(GTK)
 | |
|  #include "GtkSettingsManager.h"
 | |
| +#endif
 | |
| +
 | |
| +#if PLATFORM(GTK) || PLATFORM(WPE)
 | |
|  #include <WebCore/SelectionData.h>
 | |
|  #endif
 | |
|  
 | |
| @@ -625,6 +628,10 @@ WebPageProxy::~WebPageProxy()
 | |
|      if (m_preferences->mediaSessionCoordinatorEnabled())
 | |
|          GroupActivitiesSessionNotifier::sharedNotifier().removeWebPage(*this);
 | |
|  #endif
 | |
| +
 | |
| +#if PLATFORM(COCOA)
 | |
| +    releaseInspectorDragPasteboard();
 | |
| +#endif
 | |
|  }
 | |
|  
 | |
|  void WebPageProxy::addAllMessageReceivers()
 | |
| @@ -1041,6 +1048,7 @@ void WebPageProxy::finishAttachingToWebProcess(ProcessLaunchReason reason)
 | |
|      m_pageLoadState.didSwapWebProcesses();
 | |
|      if (reason != ProcessLaunchReason::InitialProcess)
 | |
|          m_drawingArea->waitForBackingStoreUpdateOnNextPaint();
 | |
| +    m_inspectorController->didFinishAttachingToWebProcess();
 | |
|  }
 | |
|  
 | |
|  void WebPageProxy::didAttachToRunningProcess()
 | |
| @@ -1394,6 +1402,21 @@ WebProcessProxy& WebPageProxy::ensureRunningProcess()
 | |
|      return m_process;
 | |
|  }
 | |
|  
 | |
| +RefPtr<API::Navigation> WebPageProxy::loadRequestForInspector(WebCore::ResourceRequest&& request, WebFrameProxy* frame)
 | |
| +{
 | |
| +    if (!frame || frame == mainFrame())
 | |
| +        return loadRequest(WTFMove(request), WebCore::ShouldOpenExternalURLsPolicy::ShouldNotAllow);
 | |
| +
 | |
| +    auto navigation = m_navigationState->createLoadRequestNavigation(ResourceRequest(request), m_backForwardList->currentItem());
 | |
| +    LoadParameters loadParameters;
 | |
| +    loadParameters.navigationID = navigation->navigationID();
 | |
| +    loadParameters.request = WTFMove(request);
 | |
| +    loadParameters.shouldOpenExternalURLsPolicy = WebCore::ShouldOpenExternalURLsPolicy::ShouldNotAllow;
 | |
| +    loadParameters.shouldTreatAsContinuingLoad = ShouldTreatAsContinuingLoad::No;
 | |
| +    m_process->send(Messages::WebPage::LoadRequestInFrameForInspector(loadParameters, frame->frameID()),  m_webPageID);
 | |
| +    return navigation;
 | |
| +}
 | |
| +
 | |
|  RefPtr<API::Navigation> WebPageProxy::loadRequest(ResourceRequest&& request, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy, API::Object* userData)
 | |
|  {
 | |
|      if (m_isClosed)
 | |
| @@ -1945,6 +1968,31 @@ void WebPageProxy::setControlledByAutomation(bool controlled)
 | |
|      websiteDataStore().networkProcess().send(Messages::NetworkProcess::SetSessionIsControlledByAutomation(m_websiteDataStore->sessionID(), m_controlledByAutomation), 0);
 | |
|  }
 | |
|  
 | |
| +void WebPageProxy::setAuthCredentialsForAutomation(std::optional<WebCore::Credential>&& credentials)
 | |
| +{
 | |
| +    m_credentialsForAutomation = WTFMove(credentials);
 | |
| +}
 | |
| +
 | |
| +void WebPageProxy::setPermissionsForAutomation(const HashMap<String, HashSet<String>>& permissions)
 | |
| +{
 | |
| +    m_permissionsForAutomation = permissions;
 | |
| +}
 | |
| +
 | |
| +void WebPageProxy::setActiveForAutomation(std::optional<bool> active) {
 | |
| +    m_activeForAutomation = active;
 | |
| +    OptionSet<ActivityState::Flag> state;
 | |
| +    state.add(ActivityState::IsFocused);
 | |
| +    state.add(ActivityState::WindowIsActive);
 | |
| +    state.add(ActivityState::IsVisible);
 | |
| +    state.add(ActivityState::IsVisibleOrOccluded);
 | |
| +    activityStateDidChange(state);
 | |
| +}
 | |
| +
 | |
| +void WebPageProxy::logToStderr(const String& str)
 | |
| +{
 | |
| +    fprintf(stderr, "RENDERER: %s\n", str.utf8().data());
 | |
| +}
 | |
| +
 | |
|  void WebPageProxy::createInspectorTarget(const String& targetId, Inspector::InspectorTargetType type)
 | |
|  {
 | |
|      MESSAGE_CHECK(m_process, !targetId.isEmpty());
 | |
| @@ -2135,6 +2183,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())
 | |
| @@ -2729,6 +2796,8 @@ void WebPageProxy::performDragControllerAction(DragControllerAction action, Drag
 | |
|  {
 | |
|      if (!hasRunningProcess())
 | |
|          return;
 | |
| +    if (action == DragControllerAction::Entered || action == DragControllerAction::Updated)
 | |
| +        m_dragEventsQueued++;
 | |
|  #if PLATFORM(GTK)
 | |
|      UNUSED_PARAM(dragStorageName);
 | |
|      UNUSED_PARAM(sandboxExtensionHandle);
 | |
| @@ -2739,6 +2808,8 @@ void WebPageProxy::performDragControllerAction(DragControllerAction action, Drag
 | |
|          m_process->assumeReadAccessToBaseURL(*this, url);
 | |
|  
 | |
|      ASSERT(dragData.platformData());
 | |
| +#endif
 | |
| +#if PLATFORM(GTK) || PLATFORM(WPE)
 | |
|      send(Messages::WebPage::PerformDragControllerAction(action, dragData.clientPosition(), dragData.globalPosition(), dragData.draggingSourceOperationMask(), *dragData.platformData(), dragData.flags()));
 | |
|  #else
 | |
|      send(Messages::WebPage::PerformDragControllerAction(action, dragData, sandboxExtensionHandle, sandboxExtensionsForUpload));
 | |
| @@ -2754,18 +2825,41 @@ void WebPageProxy::didPerformDragControllerAction(std::optional<WebCore::DragOpe
 | |
|      m_currentDragCaretEditableElementRect = editableElementRect;
 | |
|      setDragCaretRect(insertionRect);
 | |
|      pageClient().didPerformDragControllerAction();
 | |
| +    m_dragEventsQueued--;
 | |
| +    if (m_dragEventsQueued == 0 && m_mouseEventQueue.isEmpty())
 | |
| +        m_inspectorController->didProcessAllPendingMouseEvents();
 | |
| +
 | |
|  }
 | |
|  
 | |
| -#if PLATFORM(GTK)
 | |
| +#if PLATFORM(GTK) || PLATFORM(WPE)
 | |
|  void WebPageProxy::startDrag(SelectionData&& selectionData, OptionSet<WebCore::DragOperation> dragOperationMask, const ShareableBitmap::Handle& dragImageHandle, IntPoint&& dragImageHotspot)
 | |
|  {
 | |
| -    RefPtr<ShareableBitmap> dragImage = !dragImageHandle.isNull() ? ShareableBitmap::create(dragImageHandle) : nullptr;
 | |
| -    pageClient().startDrag(WTFMove(selectionData), dragOperationMask, WTFMove(dragImage), WTFMove(dragImageHotspot));
 | |
| +    if (m_interceptDrags) {
 | |
| +        m_dragSelectionData = WTFMove(selectionData);
 | |
| +        m_dragSourceOperationMask = dragOperationMask;
 | |
| +    } else {
 | |
| +#if PLATFORM(GTK)
 | |
| +        RefPtr<ShareableBitmap> dragImage = !dragImageHandle.isNull() ? ShareableBitmap::create(dragImageHandle) : nullptr;
 | |
| +        pageClient().startDrag(WTFMove(selectionData), dragOperationMask, WTFMove(dragImage), WTFMove(dragImageHotspot));
 | |
| +#endif
 | |
| +    }
 | |
| +
 | |
| +    didStartDrag();
 | |
| +}
 | |
| +#endif
 | |
|  
 | |
| +#if PLATFORM(WIN) && ENABLE(DRAG_SUPPORT)
 | |
| +void WebPageProxy::startDrag(WebCore::DragDataMap&& dragDataMap)
 | |
| +{
 | |
| +    if (m_interceptDrags) {
 | |
| +        m_dragSelectionData = WTFMove(dragDataMap);
 | |
| +        m_dragSourceOperationMask = WebCore::anyDragOperation();
 | |
| +    }
 | |
|      didStartDrag();
 | |
|  }
 | |
|  #endif
 | |
|  
 | |
| +
 | |
|  void WebPageProxy::dragEnded(const IntPoint& clientPosition, const IntPoint& globalPosition, OptionSet<WebCore::DragOperation> dragOperationMask)
 | |
|  {
 | |
|      if (!hasRunningProcess())
 | |
| @@ -2774,6 +2868,24 @@ void WebPageProxy::dragEnded(const IntPoint& clientPosition, const IntPoint& glo
 | |
|      setDragCaretRect({ });
 | |
|  }
 | |
|  
 | |
| +bool WebPageProxy::cancelDragIfNeeded() {
 | |
| +    if (!m_dragSelectionData)
 | |
| +        return false;
 | |
| +    m_dragSelectionData = std::nullopt;
 | |
| +#if PLATFORM(COCOA)
 | |
| +    releaseInspectorDragPasteboard();
 | |
| +#endif
 | |
| +
 | |
| +    dragEnded(m_lastMousePositionForDrag, IntPoint(), m_dragSourceOperationMask);
 | |
| +    return true;
 | |
| +}
 | |
| +
 | |
| +#if !PLATFORM(COCOA)
 | |
| +void WebPageProxy::setInterceptDrags(bool shouldIntercept) {
 | |
| +    m_interceptDrags = shouldIntercept;
 | |
| +}
 | |
| +#endif
 | |
| +
 | |
|  void WebPageProxy::didPerformDragOperation(bool handled)
 | |
|  {
 | |
|      pageClient().didPerformDragOperation(handled);
 | |
| @@ -2786,8 +2898,18 @@ void WebPageProxy::didStartDrag()
 | |
|  
 | |
|      discardQueuedMouseEvents();
 | |
|      send(Messages::WebPage::DidStartDrag());
 | |
| +
 | |
| +    if (m_interceptDrags) {
 | |
| +#if PLATFORM(WIN) || PLATFORM(COCOA)
 | |
| +        DragData dragData(*m_dragSelectionData, m_lastMousePositionForDrag, WebCore::IntPoint(), m_dragSourceOperationMask);
 | |
| +#else
 | |
| +        DragData dragData(&*m_dragSelectionData, m_lastMousePositionForDrag, WebCore::IntPoint(), m_dragSourceOperationMask);
 | |
| +#endif
 | |
| +        dragEntered(dragData);
 | |
| +        dragUpdated(dragData);
 | |
| +    }
 | |
|  }
 | |
| -    
 | |
| +
 | |
|  void WebPageProxy::dragCancelled()
 | |
|  {
 | |
|      if (hasRunningProcess())
 | |
| @@ -2892,16 +3014,38 @@ void WebPageProxy::processNextQueuedMouseEvent()
 | |
|          m_process->startResponsivenessTimer();
 | |
|      }
 | |
|  
 | |
| -    std::optional<Vector<SandboxExtension::Handle>> sandboxExtensions;
 | |
| +    m_lastMousePositionForDrag = event.position();
 | |
| +    if (!m_dragSelectionData) {
 | |
| +        std::optional<Vector<SandboxExtension::Handle>> sandboxExtensions;
 | |
|  
 | |
|  #if PLATFORM(MAC)
 | |
| -    bool eventMayStartDrag = !m_currentDragOperation && eventType == WebEvent::MouseMove && event.button() != WebMouseEvent::Button::NoButton;
 | |
| -    if (eventMayStartDrag)
 | |
| -        sandboxExtensions = SandboxExtension::createHandlesForMachLookup({ "com.apple.iconservices"_s, "com.apple.iconservices.store"_s }, process().auditToken(), SandboxExtension::MachBootstrapOptions::EnableMachBootstrap);
 | |
| +        bool eventMayStartDrag = !m_currentDragOperation && eventType == WebEvent::MouseMove && event.button() != WebMouseEvent::Button::NoButton;
 | |
| +        if (eventMayStartDrag)
 | |
| +            sandboxExtensions = SandboxExtension::createHandlesForMachLookup({ "com.apple.iconservices"_s, "com.apple.iconservices.store"_s }, process().auditToken(), SandboxExtension::MachBootstrapOptions::EnableMachBootstrap);
 | |
| +#endif
 | |
| +
 | |
| +        LOG(MouseHandling, "UIProcess: sent mouse event %s (queue size %zu)", webMouseEventTypeString(eventType), m_mouseEventQueue.size());
 | |
| +        send(Messages::WebPage::MouseEvent(event, sandboxExtensions));
 | |
| +    } else {
 | |
| +#if PLATFORM(WIN) || PLATFORM(COCOA)
 | |
| +        DragData dragData(*m_dragSelectionData, event.position(), event.globalPosition(), m_dragSourceOperationMask);
 | |
| +#else
 | |
| +        DragData dragData(&*m_dragSelectionData, event.position(), event.globalPosition(), m_dragSourceOperationMask);
 | |
|  #endif
 | |
| +        if (eventType == WebEvent::MouseMove) {
 | |
| +            dragUpdated(dragData);
 | |
| +        } else if (eventType == WebEvent::MouseUp) {
 | |
| +            if (m_currentDragOperation && m_dragSourceOperationMask.containsAny(m_currentDragOperation.value())) {
 | |
| +                SandboxExtension::Handle sandboxExtensionHandle;
 | |
| +                Vector<SandboxExtension::Handle> sandboxExtensionsForUpload;
 | |
|  
 | |
| -    LOG(MouseHandling, "UIProcess: sent mouse event %s (queue size %zu)", webMouseEventTypeString(eventType), m_mouseEventQueue.size());
 | |
| -    send(Messages::WebPage::MouseEvent(event, sandboxExtensions));
 | |
| +                performDragOperation(dragData, ""_s, WTFMove(sandboxExtensionHandle), WTFMove(sandboxExtensionsForUpload));
 | |
| +            }
 | |
| +            m_dragSelectionData = std::nullopt;
 | |
| +            dragEnded(event.position(), event.globalPosition(), m_dragSourceOperationMask);
 | |
| +        }
 | |
| +        didReceiveEvent(eventType, true);
 | |
| +    }
 | |
|  }
 | |
|  
 | |
|  void WebPageProxy::doAfterProcessingAllPendingMouseEvents(WTF::Function<void ()>&& action)
 | |
| @@ -3065,7 +3209,7 @@ static TrackingType mergeTrackingTypes(TrackingType a, TrackingType b)
 | |
|  
 | |
|  void WebPageProxy::updateTouchEventTracking(const WebTouchEvent& touchStartEvent)
 | |
|  {
 | |
| -#if ENABLE(ASYNC_SCROLLING) && PLATFORM(COCOA)
 | |
| +#if ENABLE(ASYNC_SCROLLING) && PLATFORM(IOS_FAMILY)
 | |
|      for (auto& touchPoint : touchStartEvent.touchPoints()) {
 | |
|          IntPoint location = touchPoint.location();
 | |
|          auto updateTrackingType = [this, location](TrackingType& trackingType, EventTrackingRegions::EventType eventType) {
 | |
| @@ -3097,7 +3241,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
 | |
| @@ -3486,6 +3630,8 @@ void WebPageProxy::receivedNavigationPolicyDecision(PolicyAction policyAction, A
 | |
|          policyAction = PolicyAction::Download;
 | |
|  
 | |
|      if (policyAction != PolicyAction::Use || !frame.isMainFrame() || !navigation) {
 | |
| +        if (policyAction == PolicyAction::Download && navigation)
 | |
| +            m_decidePolicyForResponseRequest = navigation->currentRequest();
 | |
|          receivedPolicyDecision(policyAction, navigation, navigation->websitePolicies(), WTFMove(navigationAction), WTFMove(sender));
 | |
|          return;
 | |
|      }
 | |
| @@ -3556,6 +3702,7 @@ void WebPageProxy::receivedNavigationPolicyDecision(PolicyAction policyAction, A
 | |
|  
 | |
|  void WebPageProxy::receivedPolicyDecision(PolicyAction action, API::Navigation* navigation, RefPtr<API::WebsitePolicies>&& websitePolicies, std::variant<Ref<API::NavigationResponse>, Ref<API::NavigationAction>>&& navigationActionOrResponse, Ref<PolicyDecisionSender>&& sender, WillContinueLoadInNewProcess willContinueLoadInNewProcess, std::optional<SandboxExtension::Handle> sandboxExtensionHandle)
 | |
|  {
 | |
| +    m_inspectorController->didReceivePolicyDecision(action, navigation ? navigation->navigationID() : 0);
 | |
|      if (!hasRunningProcess()) {
 | |
|          sender->send(PolicyDecision { sender->identifier(), isNavigatingToAppBoundDomain(), PolicyAction::Ignore, 0, std::nullopt, std::nullopt });
 | |
|          return;
 | |
| @@ -4330,6 +4477,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;
 | |
| @@ -4724,6 +4876,7 @@ void WebPageProxy::didDestroyNavigation(uint64_t navigationID)
 | |
|          return;
 | |
|  
 | |
|      m_navigationState->didDestroyNavigation(navigationID);
 | |
| +    m_inspectorController->didDestroyNavigation(navigationID);
 | |
|  }
 | |
|  
 | |
|  void WebPageProxy::didStartProvisionalLoadForFrame(FrameIdentifier frameID, FrameInfoData&& frameInfo, ResourceRequest&& request, uint64_t navigationID, URL&& url, URL&& unreachableURL, const UserData& userData)
 | |
| @@ -4949,6 +5102,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;
 | |
| @@ -5428,7 +5583,14 @@ void WebPageProxy::decidePolicyForNavigationActionAsync(FrameIdentifier frameID,
 | |
|      NavigationActionData&& navigationActionData, FrameInfoData&& originatingFrameInfo, std::optional<WebPageProxyIdentifier> originatingPageID, const WebCore::ResourceRequest& originalRequest, WebCore::ResourceRequest&& request,
 | |
|      IPC::FormDataReference&& requestBody, WebCore::ResourceResponse&& redirectResponse, const UserData& userData, uint64_t listenerID)
 | |
|  {
 | |
| -    decidePolicyForNavigationActionAsyncShared(m_process.copyRef(), m_webPageID, frameID, WTFMove(frameInfo), identifier, navigationID, WTFMove(navigationActionData), WTFMove(originatingFrameInfo), originatingPageID, originalRequest, WTFMove(request), WTFMove(requestBody), WTFMove(redirectResponse), userData, listenerID);
 | |
| +    if (m_inspectorController->shouldPauseLoading()) {
 | |
| +        m_inspectorController->setContinueLoadingCallback([this, protectedThis = Ref { *this }, frameID, frameInfo = WTFMove(frameInfo), identifier, navigationID, navigationActionData = WTFMove(navigationActionData),
 | |
| +                originatingFrameInfo = WTFMove(originatingFrameInfo), originatingPageID, originalRequest, request = WTFMove(request), requestBody = WTFMove(requestBody), redirectResponse = WTFMove(redirectResponse), userData, listenerID] () mutable {
 | |
| +            decidePolicyForNavigationActionAsyncShared(m_process.copyRef(), m_webPageID, frameID, WTFMove(frameInfo), identifier, navigationID, WTFMove(navigationActionData), WTFMove(originatingFrameInfo), originatingPageID, originalRequest, WTFMove(request), WTFMove(requestBody), WTFMove(redirectResponse), userData, listenerID);
 | |
| +        });
 | |
| +    } else {
 | |
| +        decidePolicyForNavigationActionAsyncShared(m_process.copyRef(), m_webPageID, frameID, WTFMove(frameInfo), identifier, navigationID, WTFMove(navigationActionData), WTFMove(originatingFrameInfo), originatingPageID, originalRequest, WTFMove(request), WTFMove(requestBody), WTFMove(redirectResponse), userData, listenerID);
 | |
| +    }
 | |
|  }
 | |
|  
 | |
|  void WebPageProxy::decidePolicyForNavigationActionAsyncShared(Ref<WebProcessProxy>&& process, PageIdentifier webPageID, FrameIdentifier frameID, FrameInfoData&& frameInfo,
 | |
| @@ -6015,6 +6177,7 @@ void WebPageProxy::createNewPage(FrameInfoData&& originatingFrameInfoData, WebPa
 | |
|      if (originatingPage)
 | |
|          openerAppInitiatedState = originatingPage->lastNavigationWasAppInitiated();
 | |
|  
 | |
| +    m_inspectorController->willCreateNewPage(windowFeatures, request.url());
 | |
|      auto completionHandler = [this, protectedThis = Ref { *this }, mainFrameURL, request, reply = WTFMove(reply), privateClickMeasurement = navigationActionData.privateClickMeasurement, openerAppInitiatedState = WTFMove(openerAppInitiatedState)] (RefPtr<WebPageProxy> newPage) mutable {
 | |
|          if (!newPage) {
 | |
|              reply(std::nullopt, std::nullopt);
 | |
| @@ -6061,6 +6224,7 @@ void WebPageProxy::createNewPage(FrameInfoData&& originatingFrameInfoData, WebPa
 | |
|  void WebPageProxy::showPage()
 | |
|  {
 | |
|      m_uiClient->showPage(this);
 | |
| +    m_inspectorController->didShowPage();
 | |
|  }
 | |
|  
 | |
|  void WebPageProxy::exitFullscreenImmediately()
 | |
| @@ -6118,6 +6282,10 @@ void WebPageProxy::closePage()
 | |
|      if (isClosed())
 | |
|          return;
 | |
|  
 | |
| +#if ENABLE(CONTEXT_MENUS)
 | |
| +    if (m_activeContextMenu)
 | |
| +        m_activeContextMenu->hide();
 | |
| +#endif
 | |
|      WEBPAGEPROXY_RELEASE_LOG(Process, "closePage:");
 | |
|      pageClient().clearAllEditCommands();
 | |
|      m_uiClient->close(this);
 | |
| @@ -6154,6 +6322,8 @@ void WebPageProxy::runJavaScriptAlert(FrameIdentifier frameID, FrameInfoData&& f
 | |
|      }
 | |
|  
 | |
|      runModalJavaScriptDialog(WTFMove(frame), WTFMove(frameInfo), message, [reply = WTFMove(reply)](WebPageProxy& page, WebFrameProxy* frame, FrameInfoData&& frameInfo, const String& message, CompletionHandler<void()>&& completion) mutable {
 | |
| +        if (page.m_inspectorDialogAgent)
 | |
| +            page.m_inspectorDialogAgent->javascriptDialogOpening("alert"_s, message);
 | |
|          page.m_uiClient->runJavaScriptAlert(page, message, frame, WTFMove(frameInfo), [reply = WTFMove(reply), completion = WTFMove(completion)]() mutable {
 | |
|              reply();
 | |
|              completion();
 | |
| @@ -6175,6 +6345,8 @@ void WebPageProxy::runJavaScriptConfirm(FrameIdentifier frameID, FrameInfoData&&
 | |
|          if (auto* automationSession = process().processPool().automationSession())
 | |
|              automationSession->willShowJavaScriptDialog(*this);
 | |
|      }
 | |
| +    if (m_inspectorDialogAgent)
 | |
| +        m_inspectorDialogAgent->javascriptDialogOpening("confirm"_s, message);
 | |
|  
 | |
|      runModalJavaScriptDialog(WTFMove(frame), WTFMove(frameInfo), message, [reply = WTFMove(reply)](WebPageProxy& page, WebFrameProxy* frame, FrameInfoData&& frameInfo, const String& message, CompletionHandler<void()>&& completion) mutable {
 | |
|          page.m_uiClient->runJavaScriptConfirm(page, message, frame, WTFMove(frameInfo), [reply = WTFMove(reply), completion = WTFMove(completion)](bool result) mutable {
 | |
| @@ -6198,6 +6370,8 @@ void WebPageProxy::runJavaScriptPrompt(FrameIdentifier frameID, FrameInfoData&&
 | |
|          if (auto* automationSession = process().processPool().automationSession())
 | |
|              automationSession->willShowJavaScriptDialog(*this);
 | |
|      }
 | |
| +    if (m_inspectorDialogAgent)
 | |
| +        m_inspectorDialogAgent->javascriptDialogOpening("prompt"_s, message, defaultValue);
 | |
|  
 | |
|      runModalJavaScriptDialog(WTFMove(frame), WTFMove(frameInfo), message, [reply = WTFMove(reply), defaultValue](WebPageProxy& page, WebFrameProxy* frame, FrameInfoData&& frameInfo, const String& message, CompletionHandler<void()>&& completion) mutable {
 | |
|          page.m_uiClient->runJavaScriptPrompt(page, message, defaultValue, frame, WTFMove(frameInfo), [reply = WTFMove(reply), completion = WTFMove(completion)](auto& result) mutable {
 | |
| @@ -6325,6 +6499,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();
 | |
| @@ -7589,6 +7765,8 @@ void WebPageProxy::didReceiveEvent(uint32_t opaqueType, bool handled)
 | |
|              if (auto* automationSession = process().processPool().automationSession())
 | |
|                  automationSession->mouseEventsFlushedForPage(*this);
 | |
|              didFinishProcessingAllPendingMouseEvents();
 | |
| +            if (m_dragEventsQueued == 0)
 | |
| +                m_inspectorController->didProcessAllPendingMouseEvents();
 | |
|          }
 | |
|          break;
 | |
|      }
 | |
| @@ -7603,10 +7781,13 @@ void WebPageProxy::didReceiveEvent(uint32_t opaqueType, bool handled)
 | |
|              pageClient().wheelEventWasNotHandledByWebCore(oldestProcessedEvent);
 | |
|          }
 | |
|  
 | |
| -        if (auto eventToSend = wheelEventCoalescer().nextEventToDispatch())
 | |
| +        if (auto eventToSend = wheelEventCoalescer().nextEventToDispatch()) {
 | |
|              sendWheelEvent(*eventToSend);
 | |
| -        else if (auto* automationSession = process().processPool().automationSession())
 | |
| -            automationSession->wheelEventsFlushedForPage(*this);
 | |
| +        } else {
 | |
| +            if (auto* automationSession = process().processPool().automationSession())
 | |
| +                automationSession->wheelEventsFlushedForPage(*this);
 | |
| +            m_inspectorController->didProcessAllPendingWheelEvents();
 | |
| +        }
 | |
|          break;
 | |
|      }
 | |
|  
 | |
| @@ -7615,7 +7796,6 @@ void WebPageProxy::didReceiveEvent(uint32_t opaqueType, bool handled)
 | |
|      case WebEvent::RawKeyDown:
 | |
|      case WebEvent::Char: {
 | |
|          LOG(KeyHandling, "WebPageProxy::didReceiveEvent: %s (queue empty %d)", webKeyboardEventTypeString(type), m_keyEventQueue.isEmpty());
 | |
| -
 | |
|          MESSAGE_CHECK(m_process, !m_keyEventQueue.isEmpty());
 | |
|          auto event = m_keyEventQueue.takeFirst();
 | |
|          MESSAGE_CHECK(m_process, type == event.type());
 | |
| @@ -7634,7 +7814,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);
 | |
| @@ -7643,6 +7822,7 @@ void WebPageProxy::didReceiveEvent(uint32_t opaqueType, bool handled)
 | |
|          if (!canProcessMoreKeyEvents) {
 | |
|              if (auto* automationSession = process().processPool().automationSession())
 | |
|                  automationSession->keyboardEventsFlushedForPage(*this);
 | |
| +            m_inspectorController->didProcessAllPendingKeyboardEvents();
 | |
|          }
 | |
|          break;
 | |
|      }
 | |
| @@ -7976,7 +8156,10 @@ void WebPageProxy::dispatchProcessDidTerminate(ProcessTerminationReason reason)
 | |
|  {
 | |
|      WEBPAGEPROXY_RELEASE_LOG_ERROR(Loading, "dispatchProcessDidTerminate: reason=%{public}s", processTerminationReasonToString(reason));
 | |
|  
 | |
| -    bool handledByClient = false;
 | |
| +    bool handledByClient = m_inspectorController->pageCrashed(reason);
 | |
| +    if (handledByClient)
 | |
| +        return;
 | |
| +
 | |
|      if (m_loaderClient)
 | |
|          handledByClient = reason != ProcessTerminationReason::RequestedByClient && m_loaderClient->processDidCrash(*this);
 | |
|      else
 | |
| @@ -8310,6 +8493,7 @@ static Span<const ASCIILiteral> gpuMachServices()
 | |
|  
 | |
|  WebPageCreationParameters WebPageProxy::creationParameters(WebProcessProxy& process, DrawingAreaProxy& drawingArea, RefPtr<API::WebsitePolicies>&& websitePolicies)
 | |
|  {
 | |
| +
 | |
|      WebPageCreationParameters parameters;
 | |
|  
 | |
|      parameters.processDisplayName = configuration().processDisplayName();
 | |
| @@ -8502,6 +8686,8 @@ WebPageCreationParameters WebPageProxy::creationParameters(WebProcessProxy& proc
 | |
|  
 | |
|      parameters.httpsUpgradeEnabled = preferences().upgradeKnownHostsToHTTPSEnabled() ? m_configuration->httpsUpgradeEnabled() : false;
 | |
|  
 | |
| +    parameters.shouldPauseInInspectorWhenShown = m_inspectorController->shouldPauseLoading();
 | |
| +
 | |
|  #if PLATFORM(IOS)
 | |
|      // FIXME: This is also being passed over the to WebProcess via the PreferencesStore.
 | |
|      parameters.allowsDeprecatedSynchronousXMLHttpRequestDuringUnload = allowsDeprecatedSynchronousXMLHttpRequestDuringUnload();
 | |
| @@ -8574,6 +8760,14 @@ void WebPageProxy::gamepadActivity(const Vector<GamepadData>& gamepadDatas, Even
 | |
|  
 | |
|  void WebPageProxy::didReceiveAuthenticationChallengeProxy(Ref<AuthenticationChallengeProxy>&& authenticationChallenge, NegotiatedLegacyTLS negotiatedLegacyTLS)
 | |
|  {
 | |
| +    if (m_credentialsForAutomation.has_value()) {
 | |
| +        if (m_credentialsForAutomation->isEmpty() || authenticationChallenge->core().previousFailureCount()) {
 | |
| +            authenticationChallenge->listener().completeChallenge(AuthenticationChallengeDisposition::PerformDefaultHandling);
 | |
| +            return;
 | |
| +        }
 | |
| +        authenticationChallenge->listener().completeChallenge(AuthenticationChallengeDisposition::UseCredential, *m_credentialsForAutomation);
 | |
| +        return;
 | |
| +    }
 | |
|      if (negotiatedLegacyTLS == NegotiatedLegacyTLS::Yes) {
 | |
|          m_navigationClient->shouldAllowLegacyTLS(*this, authenticationChallenge.get(), [this, protectedThis = Ref { *this }, authenticationChallenge] (bool shouldAllowLegacyTLS) {
 | |
|              if (shouldAllowLegacyTLS)
 | |
| @@ -8667,6 +8861,15 @@ void WebPageProxy::requestGeolocationPermissionForFrame(GeolocationIdentifier ge
 | |
|              request->deny();
 | |
|      };
 | |
|  
 | |
| +    auto securityOrigin = frameInfo.securityOrigin.securityOrigin();
 | |
| +    auto permissions = m_permissionsForAutomation.find(securityOrigin->toString());
 | |
| +    if (permissions == m_permissionsForAutomation.end())
 | |
| +      permissions = m_permissionsForAutomation.find("*"_s);
 | |
| +    if (permissions != m_permissionsForAutomation.end()) {
 | |
| +        completionHandler(permissions->value.contains("geolocation"_s));
 | |
| +        return;
 | |
| +    }
 | |
| +
 | |
|      // FIXME: Once iOS migrates to the new WKUIDelegate SPI, clean this up
 | |
|      // and make it one UIClient call that calls the completionHandler with false
 | |
|      // if there is no delegate instead of returning the completionHandler
 | |
| diff --git a/Source/WebKit/UIProcess/WebPageProxy.h b/Source/WebKit/UIProcess/WebPageProxy.h
 | |
| index 3e3bbb22e6de573ce2490d6255c04b825ad46448..978ccc20f6e1ef2c1c503293d7fdfaf4dda6b7ae 100644
 | |
| --- a/Source/WebKit/UIProcess/WebPageProxy.h
 | |
| +++ b/Source/WebKit/UIProcess/WebPageProxy.h
 | |
| @@ -39,6 +39,7 @@
 | |
|  #include "GeolocationPermissionRequestManagerProxy.h"
 | |
|  #include "HiddenPageThrottlingAutoIncreasesCounter.h"
 | |
|  #include "IdentifierTypes.h"
 | |
| +#include "InspectorDialogAgent.h"
 | |
|  #include "LayerTreeContext.h"
 | |
|  #include "MediaKeySystemPermissionRequestManagerProxy.h"
 | |
|  #include "MediaPlaybackState.h"
 | |
| @@ -148,8 +149,11 @@
 | |
|  #include "EndowmentStateTracker.h"
 | |
|  #endif
 | |
|  
 | |
| +OBJC_CLASS NSPasteboard;
 | |
| +
 | |
|  #if ENABLE(DRAG_SUPPORT)
 | |
|  #include <WebCore/DragActions.h>
 | |
| +#include <WebCore/DragData.h>
 | |
|  #endif
 | |
|  
 | |
|  #if ENABLE(TOUCH_EVENTS)
 | |
| @@ -171,6 +175,14 @@
 | |
|  #include "ArgumentCodersGtk.h"
 | |
|  #endif
 | |
|  
 | |
| +#if PLATFORM(WPE)
 | |
| +#include "ArgumentCodersWPE.h"
 | |
| +#endif
 | |
| +
 | |
| +#if PLATFORM(GTK) || PLATFORM(WPE)
 | |
| +#include <WebCore/SelectionData.h>
 | |
| +#endif
 | |
| +
 | |
|  #if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS_FAMILY)
 | |
|  #include <WebCore/MediaPlaybackTargetPicker.h>
 | |
|  #include <WebCore/WebMediaSessionManagerClient.h>
 | |
| @@ -249,6 +261,7 @@ class AuthenticationChallenge;
 | |
|  class CertificateInfo;
 | |
|  class Cursor;
 | |
|  class DragData;
 | |
| +typedef HashMap<unsigned, Vector<String>> DragDataMap;
 | |
|  class FloatRect;
 | |
|  class FontAttributeChanges;
 | |
|  class FontChanges;
 | |
| @@ -256,7 +269,6 @@ class GraphicsLayer;
 | |
|  class IntSize;
 | |
|  class ProtectionSpace;
 | |
|  class RunLoopObserver;
 | |
| -class SelectionData;
 | |
|  class SharedBuffer;
 | |
|  class SpeechRecognitionRequest;
 | |
|  class TextIndicator;
 | |
| @@ -546,6 +558,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();
 | |
| @@ -656,6 +670,11 @@ public:
 | |
|  
 | |
|      void setPageLoadStateObserver(std::unique_ptr<PageLoadState::Observer>&&);
 | |
|  
 | |
| +    void setAuthCredentialsForAutomation(std::optional<WebCore::Credential>&&);
 | |
| +    void setPermissionsForAutomation(const HashMap<String, HashSet<String>>&);
 | |
| +    void setActiveForAutomation(std::optional<bool> active);
 | |
| +    void logToStderr(const String& str);
 | |
| +
 | |
|      void initializeWebPage();
 | |
|      void setDrawingArea(std::unique_ptr<DrawingAreaProxy>&&);
 | |
|  
 | |
| @@ -683,6 +702,7 @@ public:
 | |
|      void closePage();
 | |
|  
 | |
|      void addPlatformLoadParameters(WebProcessProxy&, LoadParameters&);
 | |
| +    RefPtr<API::Navigation> loadRequestForInspector(WebCore::ResourceRequest&&, WebFrameProxy*);
 | |
|      RefPtr<API::Navigation> loadRequest(WebCore::ResourceRequest&&, WebCore::ShouldOpenExternalURLsPolicy = WebCore::ShouldOpenExternalURLsPolicy::ShouldAllowExternalSchemesButNotAppLinks, API::Object* userData = nullptr);
 | |
|      RefPtr<API::Navigation> loadFile(const String& fileURL, const String& resourceDirectoryURL, bool isAppInitiated = true, API::Object* userData = nullptr);
 | |
|      RefPtr<API::Navigation> loadData(const IPC::DataReference&, const String& MIMEType, const String& encoding, const String& baseURL, API::Object* userData = nullptr, WebCore::ShouldOpenExternalURLsPolicy = WebCore::ShouldOpenExternalURLsPolicy::ShouldNotAllow);
 | |
| @@ -1211,6 +1231,7 @@ public:
 | |
|  #endif
 | |
|  
 | |
|      void pageScaleFactorDidChange(double);
 | |
| +    void viewScaleFactorDidChange(double);
 | |
|      void pluginScaleFactorDidChange(double);
 | |
|      void pluginZoomFactorDidChange(double);
 | |
|  
 | |
| @@ -1298,14 +1319,20 @@ public:
 | |
|      void didStartDrag();
 | |
|      void dragCancelled();
 | |
|      void setDragCaretRect(const WebCore::IntRect&);
 | |
| +    void setInterceptDrags(bool shouldIntercept);
 | |
| +    bool cancelDragIfNeeded();
 | |
|  #if PLATFORM(COCOA)
 | |
|      void startDrag(const WebCore::DragItem&, const ShareableBitmap::Handle& dragImageHandle);
 | |
|      void setPromisedDataForImage(const String& pasteboardName, const SharedMemory::IPCHandle& imageHandle, const String& filename, const String& extension,
 | |
|          const String& title, const String& url, const String& visibleURL, const SharedMemory::IPCHandle& archiveHandle, const String& originIdentifier);
 | |
| +    void releaseInspectorDragPasteboard();
 | |
|  #endif
 | |
| -#if PLATFORM(GTK)
 | |
| +#if PLATFORM(GTK) || PLATFORM(WPE)
 | |
|      void startDrag(WebCore::SelectionData&&, OptionSet<WebCore::DragOperation>, const ShareableBitmap::Handle& dragImage, WebCore::IntPoint&& dragImageHotspot);
 | |
|  #endif
 | |
| +#if PLATFORM(WIN)
 | |
| +    void startDrag(WebCore::DragDataMap&& dragDataMap);
 | |
| +#endif
 | |
|  #endif
 | |
|  
 | |
|      void processDidBecomeUnresponsive();
 | |
| @@ -1556,6 +1583,8 @@ public:
 | |
|  
 | |
|  #if PLATFORM(COCOA) || PLATFORM(GTK)
 | |
|      RefPtr<ViewSnapshot> takeViewSnapshot(std::optional<WebCore::IntRect>&&);
 | |
| +#elif PLATFORM(WPE)
 | |
| +    RefPtr<ViewSnapshot> takeViewSnapshot(std::optional<WebCore::IntRect>&&) { return nullptr; }
 | |
|  #endif
 | |
|  
 | |
|  #if ENABLE(WEB_CRYPTO)
 | |
| @@ -2726,6 +2755,7 @@ private:
 | |
|      String m_overrideContentSecurityPolicy;
 | |
|  
 | |
|      RefPtr<WebInspectorUIProxy> m_inspector;
 | |
| +    InspectorDialogAgent* m_inspectorDialogAgent { nullptr };
 | |
|  
 | |
|  #if PLATFORM(COCOA)
 | |
|      WeakObjCPtr<WKWebView> m_cocoaView;
 | |
| @@ -2995,6 +3025,20 @@ private:
 | |
|      unsigned m_currentDragNumberOfFilesToBeAccepted { 0 };
 | |
|      WebCore::IntRect m_currentDragCaretRect;
 | |
|      WebCore::IntRect m_currentDragCaretEditableElementRect;
 | |
| +    bool m_interceptDrags { false };
 | |
| +    OptionSet<WebCore::DragOperation> m_dragSourceOperationMask;
 | |
| +    WebCore::IntPoint m_lastMousePositionForDrag;
 | |
| +    int m_dragEventsQueued = 0;
 | |
| +#if PLATFORM(COCOA)
 | |
| +    std::optional<String> m_dragSelectionData;
 | |
| +    String m_overrideDragPasteboardName;
 | |
| +#endif
 | |
| +#if PLATFORM(GTK) || PLATFORM(WPE)
 | |
| +    std::optional<WebCore::SelectionData> m_dragSelectionData;
 | |
| +#endif
 | |
| +#if PLATFORM(WIN)
 | |
| +    std::optional<WebCore::DragDataMap> m_dragSelectionData;
 | |
| +#endif
 | |
|  #endif
 | |
|  
 | |
|      PageLoadState m_pageLoadState;
 | |
| @@ -3205,6 +3249,9 @@ private:
 | |
|          RefPtr<API::Object> messageBody;
 | |
|      };
 | |
|      Vector<InjectedBundleMessage> m_pendingInjectedBundleMessages;
 | |
| +    std::optional<WebCore::Credential> m_credentialsForAutomation;
 | |
| +    HashMap<String, HashSet<String>> m_permissionsForAutomation;
 | |
| +    std::optional<bool> m_activeForAutomation;
 | |
|          
 | |
|  #if PLATFORM(IOS_FAMILY) && ENABLE(DEVICE_ORIENTATION)
 | |
|      std::unique_ptr<WebDeviceOrientationUpdateProviderProxy> m_webDeviceOrientationUpdateProviderProxy;
 | |
| diff --git a/Source/WebKit/UIProcess/WebPageProxy.messages.in b/Source/WebKit/UIProcess/WebPageProxy.messages.in
 | |
| index d9ca6d6dbcf65948c6d8ad56ae10f0678d043ce2..c35b74dbdbe4e64e1c54dfcfe817e8a08528961d 100644
 | |
| --- a/Source/WebKit/UIProcess/WebPageProxy.messages.in
 | |
| +++ b/Source/WebKit/UIProcess/WebPageProxy.messages.in
 | |
| @@ -29,6 +29,7 @@ messages -> WebPageProxy {
 | |
|      RunJavaScriptConfirm(WebCore::FrameIdentifier frameID, struct WebKit::FrameInfoData frameInfo, String message) -> (bool result) Synchronous
 | |
|      RunJavaScriptPrompt(WebCore::FrameIdentifier frameID, struct WebKit::FrameInfoData frameInfo, String message, String defaultValue) -> (String result) Synchronous
 | |
|      MouseDidMoveOverElement(struct WebKit::WebHitTestResultData hitTestResultData, uint32_t modifiers, WebKit::UserData userData)
 | |
| +    LogToStderr(String text)
 | |
|  
 | |
|  #if ENABLE(WEBGL)
 | |
|      WebGLPolicyForURL(URL url) -> (enum:uint8_t WebCore::WebGLLoadPolicy loadPolicy) Synchronous
 | |
| @@ -175,6 +176,7 @@ messages -> WebPageProxy {
 | |
|  #endif
 | |
|  
 | |
|      PageScaleFactorDidChange(double scaleFactor)
 | |
| +    ViewScaleFactorDidChange(double scaleFactor)
 | |
|      PluginScaleFactorDidChange(double zoomFactor)
 | |
|      PluginZoomFactorDidChange(double zoomFactor)
 | |
|  
 | |
| @@ -303,10 +305,12 @@ messages -> WebPageProxy {
 | |
|      StartDrag(struct WebCore::DragItem dragItem, WebKit::ShareableBitmap::Handle dragImage)
 | |
|      SetPromisedDataForImage(String pasteboardName, WebKit::SharedMemory::IPCHandle imageHandle, String filename, String extension, String title, String url, String visibleURL, WebKit::SharedMemory::IPCHandle archiveHandle, String originIdentifier)
 | |
|  #endif
 | |
| -#if PLATFORM(GTK) && ENABLE(DRAG_SUPPORT)
 | |
| +#if (PLATFORM(GTK) || PLATFORM(WPE)) && ENABLE(DRAG_SUPPORT)
 | |
|      StartDrag(WebCore::SelectionData selectionData, OptionSet<WebCore::DragOperation> dragOperationMask, WebKit::ShareableBitmap::Handle dragImage, WebCore::IntPoint dragImageHotspot)
 | |
|  #endif
 | |
| -
 | |
| +#if PLATFORM(WIN) && ENABLE(DRAG_SUPPORT)
 | |
| +    StartDrag(HashMap<unsigned, Vector<String>> dragDataMap)
 | |
| +#endif
 | |
|  #if ENABLE(DRAG_SUPPORT)
 | |
|      DidPerformDragOperation(bool handled)
 | |
|  #endif
 | |
| diff --git a/Source/WebKit/UIProcess/WebProcessPool.cpp b/Source/WebKit/UIProcess/WebProcessPool.cpp
 | |
| index 41d83535f3c22dd28b675a0a8627f48faf010e71..e0986f8f7146ff023c14167d351e8ab5922f44d7 100644
 | |
| --- a/Source/WebKit/UIProcess/WebProcessPool.cpp
 | |
| +++ b/Source/WebKit/UIProcess/WebProcessPool.cpp
 | |
| @@ -535,6 +535,14 @@ void WebProcessPool::establishRemoteWorkerContextConnectionToNetworkProcess(Remo
 | |
|  
 | |
|      RefPtr<WebProcessProxy> requestingProcess = requestingProcessIdentifier ? WebProcessProxy::processForIdentifier(*requestingProcessIdentifier) : nullptr;
 | |
|      WebProcessPool* processPool = requestingProcess ? &requestingProcess->processPool() : processPools()[0];
 | |
| +    // Playwright begin
 | |
| +    for (auto& process : websiteDataStore->processes()) {
 | |
| +        if (process.processPoolIfExists()) {
 | |
| +            processPool = process.processPoolIfExists();
 | |
| +            break;
 | |
| +        }
 | |
| +    }
 | |
| +    // Playwright end
 | |
|      ASSERT(processPool);
 | |
|  
 | |
|      WebProcessProxy* remoteWorkerProcessProxy { nullptr };
 | |
| diff --git a/Source/WebKit/UIProcess/WebProcessProxy.cpp b/Source/WebKit/UIProcess/WebProcessProxy.cpp
 | |
| index 9fe8eb6b044af9eb049d6d4e53cd8bbac84f4572..ecb7771c1036fa31ffc7ea506afcec4c1d3e4ebc 100644
 | |
| --- a/Source/WebKit/UIProcess/WebProcessProxy.cpp
 | |
| +++ b/Source/WebKit/UIProcess/WebProcessProxy.cpp
 | |
| @@ -147,6 +147,11 @@ HashMap<ProcessIdentifier, WebProcessProxy*>& WebProcessProxy::allProcesses()
 | |
|      return map;
 | |
|  }
 | |
|  
 | |
| +Vector<WebProcessProxy*> WebProcessProxy::allProcessesForInspector()
 | |
| +{
 | |
| +    return copyToVector(allProcesses().values());
 | |
| +}
 | |
| +
 | |
|  WebProcessProxy* WebProcessProxy::processForIdentifier(ProcessIdentifier identifier)
 | |
|  {
 | |
|      return allProcesses().get(identifier);
 | |
| diff --git a/Source/WebKit/UIProcess/WebProcessProxy.h b/Source/WebKit/UIProcess/WebProcessProxy.h
 | |
| index 2aa8191e96ca3c1a5d8a3fba591aa489e9a49e31..a1c55d31db11eee237c5a558bcaf9b54735c69ca 100644
 | |
| --- a/Source/WebKit/UIProcess/WebProcessProxy.h
 | |
| +++ b/Source/WebKit/UIProcess/WebProcessProxy.h
 | |
| @@ -146,6 +146,7 @@ public:
 | |
|      ~WebProcessProxy();
 | |
|  
 | |
|      static void forWebPagesWithOrigin(PAL::SessionID, const WebCore::SecurityOriginData&, const Function<void(WebPageProxy&)>&);
 | |
| +    static Vector<WebProcessProxy*> allProcessesForInspector();
 | |
|  
 | |
|      WebConnection* webConnection() const { return m_webConnection.get(); }
 | |
|  
 | |
| diff --git a/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp b/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp
 | |
| index 154a03874cb9830e7c28a09c967f5597bb99352b..66064b55bbda6f37480e6ac0ed3e62e41d5d16d4 100644
 | |
| --- a/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp
 | |
| +++ b/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp
 | |
| @@ -2032,6 +2032,12 @@ void WebsiteDataStore::originDirectoryForTesting(URL&& origin, URL&& topOrigin,
 | |
|      networkProcess().websiteDataOriginDirectoryForTesting(m_sessionID, WTFMove(origin), WTFMove(topOrigin), type, WTFMove(completionHandler));
 | |
|  }
 | |
|  
 | |
| +void WebsiteDataStore::setDownloadForAutomation(std::optional<bool> allow, const String& downloadPath)
 | |
| +{
 | |
| +    m_allowDownloadForAutomation = allow;
 | |
| +    m_downloadPathForAutomation = downloadPath;
 | |
| +}
 | |
| +
 | |
|  #if ENABLE(APP_BOUND_DOMAINS)
 | |
|  void WebsiteDataStore::hasAppBoundSession(CompletionHandler<void(bool)>&& completionHandler) const
 | |
|  {
 | |
| diff --git a/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h b/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h
 | |
| index 25168b66cf572db53d9ef07f164df342556dcb0a..ab572b41015b971272341be81820766c4dd617e2 100644
 | |
| --- a/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h
 | |
| +++ b/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h
 | |
| @@ -89,6 +89,7 @@ class SecKeyProxyStore;
 | |
|  class DeviceIdHashSaltStorage;
 | |
|  class NetworkProcessProxy;
 | |
|  class SOAuthorizationCoordinator;
 | |
| +class DownloadProxy;
 | |
|  class VirtualAuthenticatorManager;
 | |
|  class WebPageProxy;
 | |
|  class WebProcessPool;
 | |
| @@ -98,6 +99,7 @@ enum class CacheModel : uint8_t;
 | |
|  enum class WebsiteDataFetchOption : uint8_t;
 | |
|  enum class WebsiteDataType : uint32_t;
 | |
|  
 | |
| +struct FrameInfoData;
 | |
|  struct NetworkProcessConnectionInfo;
 | |
|  struct WebsiteDataRecord;
 | |
|  struct WebsiteDataStoreParameters;
 | |
| @@ -108,6 +110,14 @@ enum class StorageAccessStatus : uint8_t;
 | |
|  enum class StorageAccessPromptStatus;
 | |
|  #endif
 | |
|  
 | |
| +class DownloadInstrumentation {
 | |
| +public:
 | |
| +    virtual void downloadCreated(const String& uuid, const WebCore::ResourceRequest&, const FrameInfoData& frameInfoData, WebPageProxy* page, RefPtr<DownloadProxy> download) = 0;
 | |
| +    virtual void downloadFilenameSuggested(const String& uuid, const String& suggestedFilename) = 0;
 | |
| +    virtual void downloadFinished(const String& uuid, const String& error) = 0;
 | |
| +    virtual ~DownloadInstrumentation() = default;
 | |
| +};
 | |
| +
 | |
|  class WebsiteDataStore : public API::ObjectImpl<API::Object::Type::WebsiteDataStore>, public Identified<WebsiteDataStore>, public CanMakeWeakPtr<WebsiteDataStore>  {
 | |
|  public:
 | |
|      static Ref<WebsiteDataStore> defaultDataStore();
 | |
| @@ -295,11 +305,13 @@ public:
 | |
|      const WebCore::CurlProxySettings& networkProxySettings() const { return m_proxySettings; }
 | |
|  #endif
 | |
|  
 | |
| -#if USE(SOUP)
 | |
| +#if USE(SOUP) || PLATFORM(COCOA) || PLATFORM(WIN)
 | |
|      void setPersistentCredentialStorageEnabled(bool);
 | |
|      bool persistentCredentialStorageEnabled() const { return m_persistentCredentialStorageEnabled && isPersistent(); }
 | |
|      void setIgnoreTLSErrors(bool);
 | |
|      bool ignoreTLSErrors() const { return m_ignoreTLSErrors; }
 | |
| +#endif
 | |
| +#if USE(SOUP)
 | |
|      void setNetworkProxySettings(WebCore::SoupNetworkProxySettings&&);
 | |
|      const WebCore::SoupNetworkProxySettings& networkProxySettings() const { return m_networkProxySettings; }
 | |
|      void setCookiePersistentStorage(const String&, SoupCookiePersistentStorageType);
 | |
| @@ -363,6 +375,12 @@ public:
 | |
|      static constexpr uint64_t defaultPerOriginQuota() { return 1000 * MB; }
 | |
|      static bool defaultShouldUseCustomStoragePaths();
 | |
|  
 | |
| +    void setDownloadForAutomation(std::optional<bool> allow, const String& downloadPath);
 | |
| +    std::optional<bool> allowDownloadForAutomation() { return m_allowDownloadForAutomation; };
 | |
| +    String downloadPathForAutomation() { return m_downloadPathForAutomation; };
 | |
| +    void setDownloadInstrumentation(DownloadInstrumentation* instrumentation) { m_downloadInstrumentation = instrumentation; };
 | |
| +    DownloadInstrumentation* downloadInstrumentation() { return m_downloadInstrumentation; };
 | |
| +
 | |
|      void resetQuota(CompletionHandler<void()>&&);
 | |
|      void clearStorage(CompletionHandler<void()>&&);
 | |
|  
 | |
| @@ -457,9 +475,11 @@ private:
 | |
|      WebCore::CurlProxySettings m_proxySettings;
 | |
|  #endif
 | |
|  
 | |
| -#if USE(SOUP)
 | |
| +#if USE(SOUP) || PLATFORM(COCOA) || PLATFORM(WIN)
 | |
|      bool m_persistentCredentialStorageEnabled { true };
 | |
|      bool m_ignoreTLSErrors { true };
 | |
| +#endif
 | |
| +#if USE(SOUP)
 | |
|      WebCore::SoupNetworkProxySettings m_networkProxySettings;
 | |
|      String m_cookiePersistentStoragePath;
 | |
|      SoupCookiePersistentStorageType m_cookiePersistentStorageType { SoupCookiePersistentStorageType::SQLite };
 | |
| @@ -487,6 +507,10 @@ private:
 | |
|      RefPtr<API::HTTPCookieStore> m_cookieStore;
 | |
|      RefPtr<NetworkProcessProxy> m_networkProcess;
 | |
|  
 | |
| +    std::optional<bool> m_allowDownloadForAutomation;
 | |
| +    String m_downloadPathForAutomation;
 | |
| +    DownloadInstrumentation* m_downloadInstrumentation { nullptr };
 | |
| +
 | |
|  #if HAVE(APP_SSO)
 | |
|      UniqueRef<SOAuthorizationCoordinator> m_soAuthorizationCoordinator;
 | |
|  #endif
 | |
| diff --git a/Source/WebKit/UIProcess/cairo/BackingStoreCairo.cpp b/Source/WebKit/UIProcess/cairo/BackingStoreCairo.cpp
 | |
| index 0b2fc0019ffa2c05383dc4b4e480b4d380aa9fd5..79773452d246f3bcdf42122a3bf8f67685e45fdc 100644
 | |
| --- a/Source/WebKit/UIProcess/cairo/BackingStoreCairo.cpp
 | |
| +++ b/Source/WebKit/UIProcess/cairo/BackingStoreCairo.cpp
 | |
| @@ -27,9 +27,11 @@
 | |
|  #include "config.h"
 | |
|  #include "BackingStore.h"
 | |
|  
 | |
| +#include "DrawingAreaProxyCoordinatedGraphics.h"
 | |
|  #include "ShareableBitmap.h"
 | |
|  #include "UpdateInfo.h"
 | |
|  #include "WebPageProxy.h"
 | |
| +#include "WebPageInspectorController.h"
 | |
|  #include <WebCore/BackingStoreBackendCairoImpl.h>
 | |
|  #include <WebCore/CairoUtilities.h>
 | |
|  #include <WebCore/GraphicsContextCairo.h>
 | |
| @@ -61,6 +63,13 @@ std::unique_ptr<BackingStoreBackendCairo> BackingStore::createBackend()
 | |
|      return makeUnique<BackingStoreBackendCairoImpl>(m_size, m_deviceScaleFactor);
 | |
|  }
 | |
|  
 | |
| +cairo_surface_t* BackingStore::surface() const {
 | |
| +    if (!m_backend)
 | |
| +        return nullptr;
 | |
| +
 | |
| +    return m_backend->surface();
 | |
| +}
 | |
| +
 | |
|  void BackingStore::paint(cairo_t* context, const IntRect& rect)
 | |
|  {
 | |
|      ASSERT(m_backend);
 | |
| diff --git a/Source/WebKit/UIProcess/geoclue/GeoclueGeolocationProvider.cpp b/Source/WebKit/UIProcess/geoclue/GeoclueGeolocationProvider.cpp
 | |
| index 692a45a48fa027f9221338d74f5351bef4baf00f..db8c761c71cc7009be66255c2668de4eff36dee0 100644
 | |
| --- a/Source/WebKit/UIProcess/geoclue/GeoclueGeolocationProvider.cpp
 | |
| +++ b/Source/WebKit/UIProcess/geoclue/GeoclueGeolocationProvider.cpp
 | |
| @@ -60,6 +60,8 @@ void GeoclueGeolocationProvider::start(UpdateNotifyFunction&& updateNotifyFuncti
 | |
|      m_isRunning = true;
 | |
|      m_cancellable = adoptGRef(g_cancellable_new());
 | |
|      if (!m_manager) {
 | |
| +        g_cancellable_cancel(m_cancellable_start.get());
 | |
| +        m_cancellable_start = adoptGRef(g_cancellable_new());
 | |
|          g_dbus_proxy_new_for_bus(G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, nullptr,
 | |
|              "org.freedesktop.GeoClue2", "/org/freedesktop/GeoClue2/Manager", "org.freedesktop.GeoClue2.Manager", m_cancellable.get(),
 | |
|              [](GObject*, GAsyncResult* result, gpointer userData) {
 | |
| @@ -91,6 +93,12 @@ void GeoclueGeolocationProvider::stop()
 | |
|      g_cancellable_cancel(m_cancellable.get());
 | |
|      m_cancellable = nullptr;
 | |
|      stopClient();
 | |
| +    g_cancellable_cancel(m_cancellable_start.get());
 | |
| +    m_cancellable_start = nullptr;
 | |
| +    g_cancellable_cancel(m_cancellable_setup.get());
 | |
| +    m_cancellable_setup = nullptr;
 | |
| +    g_cancellable_cancel(m_cancellable_create.get());
 | |
| +    m_cancellable_create = nullptr;
 | |
|      destroyManagerLater();
 | |
|  }
 | |
|  
 | |
| @@ -153,6 +161,8 @@ void GeoclueGeolocationProvider::createClient(const char* clientPath)
 | |
|          return;
 | |
|      }
 | |
|  
 | |
| +    g_cancellable_cancel(m_cancellable_create.get());
 | |
| +    m_cancellable_create = adoptGRef(g_cancellable_new());
 | |
|      g_dbus_proxy_new_for_bus(G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, nullptr,
 | |
|          "org.freedesktop.GeoClue2", clientPath, "org.freedesktop.GeoClue2.Client", m_cancellable.get(),
 | |
|          [](GObject*, GAsyncResult* result, gpointer userData) {
 | |
| diff --git a/Source/WebKit/UIProcess/geoclue/GeoclueGeolocationProvider.h b/Source/WebKit/UIProcess/geoclue/GeoclueGeolocationProvider.h
 | |
| index b5e48e6c61a8a3f4b40b84112c4010101c4d5f41..46747b1d78bfe0270178609867c0d710807fa668 100644
 | |
| --- a/Source/WebKit/UIProcess/geoclue/GeoclueGeolocationProvider.h
 | |
| +++ b/Source/WebKit/UIProcess/geoclue/GeoclueGeolocationProvider.h
 | |
| @@ -71,6 +71,9 @@ private:
 | |
|      GRefPtr<GDBusProxy> m_manager;
 | |
|      GRefPtr<GDBusProxy> m_client;
 | |
|      GRefPtr<GCancellable> m_cancellable;
 | |
| +    GRefPtr<GCancellable> m_cancellable_start;
 | |
| +    GRefPtr<GCancellable> m_cancellable_setup;
 | |
| +    GRefPtr<GCancellable> m_cancellable_create;
 | |
|      UpdateNotifyFunction m_updateNotifyFunction;
 | |
|      RunLoop::Timer<GeoclueGeolocationProvider> m_destroyManagerLaterTimer;
 | |
|  };
 | |
| diff --git a/Source/WebKit/UIProcess/glib/InspectorPlaywrightAgentClientGLib.cpp b/Source/WebKit/UIProcess/glib/InspectorPlaywrightAgentClientGLib.cpp
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..20a7cd2c65be39b3bcab356f6eee0b82d084c6bf
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/UIProcess/glib/InspectorPlaywrightAgentClientGLib.cpp
 | |
| @@ -0,0 +1,152 @@
 | |
| +/*
 | |
| + * Copyright (C) 2019 Microsoft Corporation.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
| + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#include "config.h"
 | |
| +#include "InspectorPlaywrightAgentClientGLib.h"
 | |
| +
 | |
| +#if ENABLE(REMOTE_INSPECTOR)
 | |
| +
 | |
| +#include "InspectorPlaywrightAgent.h"
 | |
| +#include "WebKitBrowserInspectorPrivate.h"
 | |
| +#include "WebKitWebContextPrivate.h"
 | |
| +#include "WebKitWebsiteDataManagerPrivate.h"
 | |
| +#include "WebKitWebViewPrivate.h"
 | |
| +#include "WebPageProxy.h"
 | |
| +#include <wtf/HashMap.h>
 | |
| +#include <wtf/RefPtr.h>
 | |
| +#include <wtf/text/StringView.h>
 | |
| +#include <wtf/text/WTFString.h>
 | |
| +
 | |
| +namespace WebKit {
 | |
| +
 | |
| +static WebCore::SoupNetworkProxySettings parseRawProxySettings(const String& proxyServer, const char* const* ignoreHosts)
 | |
| +{
 | |
| +    WebCore::SoupNetworkProxySettings settings;
 | |
| +    if (proxyServer.isEmpty())
 | |
| +        return settings;
 | |
| +
 | |
| +    settings.mode = WebCore::SoupNetworkProxySettings::Mode::Custom;
 | |
| +    settings.defaultProxyURL = proxyServer.utf8();
 | |
| +    settings.ignoreHosts.reset(g_strdupv(const_cast<char**>(ignoreHosts)));
 | |
| +    return settings;
 | |
| +}
 | |
| +
 | |
| +static WebCore::SoupNetworkProxySettings parseProxySettings(const String& proxyServer, const String& proxyBypassList)
 | |
| +{
 | |
| +    Vector<const char*> ignoreHosts;
 | |
| +    if (!proxyBypassList.isEmpty()) {
 | |
| +        Vector<String> tokens = proxyBypassList.split(',');
 | |
| +        Vector<CString> protectTokens;
 | |
| +        for (String token : tokens) {
 | |
| +            CString cstr = token.utf8();
 | |
| +            ignoreHosts.append(cstr.data());
 | |
| +            protectTokens.append(WTFMove(cstr));
 | |
| +        }
 | |
| +    }
 | |
| +    ignoreHosts.append(nullptr);
 | |
| +    return parseRawProxySettings(proxyServer, ignoreHosts.data());
 | |
| +}
 | |
| +
 | |
| +InspectorPlaywrightAgentClientGlib::InspectorPlaywrightAgentClientGlib(const WTF::String& proxyURI, const char* const* ignoreHosts)
 | |
| +    : m_proxySettings(parseRawProxySettings(proxyURI, ignoreHosts))
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +RefPtr<WebPageProxy> InspectorPlaywrightAgentClientGlib::createPage(WTF::String& error, const BrowserContext& browserContext)
 | |
| +{
 | |
| +    auto sessionID = browserContext.dataStore->sessionID();
 | |
| +    WebKitWebContext* context = m_idToContext.get(sessionID);
 | |
| +    if (!context && !browserContext.dataStore->isPersistent()) {
 | |
| +        ASSERT_NOT_REACHED();
 | |
| +        error = "Context with provided id not found"_s;
 | |
| +        return nullptr;
 | |
| +    }
 | |
| +
 | |
| +    RefPtr<WebPageProxy> page = webkitBrowserInspectorCreateNewPageInContext(context);
 | |
| +    if (page == nullptr) {
 | |
| +        error = "Failed to create new page in the context"_s;
 | |
| +        return nullptr;
 | |
| +    }
 | |
| +
 | |
| +    if (context == nullptr && sessionID != page->sessionID()) {
 | |
| +        ASSERT_NOT_REACHED();
 | |
| +        error = " Failed to create new page in default context"_s;
 | |
| +        return nullptr;
 | |
| +    }
 | |
| +
 | |
| +    return page;
 | |
| +}
 | |
| +
 | |
| +void InspectorPlaywrightAgentClientGlib::closeBrowser()
 | |
| +{
 | |
| +    m_idToContext.clear();
 | |
| +    webkitBrowserInspectorQuitApplication();
 | |
| +    if (webkitWebContextExistingCount() > 1)
 | |
| +        fprintf(stderr, "LEAK: %d contexts are still alive when closing browser\n", webkitWebContextExistingCount());
 | |
| +}
 | |
| +
 | |
| +static PAL::SessionID sessionIDFromContext(WebKitWebContext* context)
 | |
| +{
 | |
| +    WebKitWebsiteDataManager* data_manager = webkit_web_context_get_website_data_manager(context);
 | |
| +    WebsiteDataStore& websiteDataStore = webkitWebsiteDataManagerGetDataStore(data_manager);
 | |
| +    return websiteDataStore.sessionID();
 | |
| +}
 | |
| +
 | |
| +std::unique_ptr<BrowserContext> InspectorPlaywrightAgentClientGlib::createBrowserContext(WTF::String& error, const WTF::String& proxyServer, const WTF::String& proxyBypassList)
 | |
| +{
 | |
| +    GRefPtr<WebKitWebsiteDataManager> data_manager = adoptGRef(webkit_website_data_manager_new_ephemeral());
 | |
| +    GRefPtr<WebKitWebContext> context = adoptGRef(WEBKIT_WEB_CONTEXT(g_object_new(WEBKIT_TYPE_WEB_CONTEXT, "website-data-manager", data_manager.get(),
 | |
| +    // WPE has PSON enabled by default and doesn't have such parameter.
 | |
| +#if PLATFORM(GTK)
 | |
| +        "process-swap-on-cross-site-navigation-enabled", true,
 | |
| +#endif
 | |
| +        nullptr)));
 | |
| +    if (!context) {
 | |
| +        error = "Failed to create GLib ephemeral context"_s;
 | |
| +        return nullptr;
 | |
| +    }
 | |
| +    auto browserContext = std::make_unique<BrowserContext>();
 | |
| +    browserContext->processPool = &webkitWebContextGetProcessPool(context.get());
 | |
| +    browserContext->dataStore = &webkitWebsiteDataManagerGetDataStore(data_manager.get());
 | |
| +    PAL::SessionID sessionID = sessionIDFromContext(context.get());
 | |
| +    m_idToContext.set(sessionID, WTFMove(context));
 | |
| +
 | |
| +    if (!proxyServer.isEmpty()) {
 | |
| +        WebCore::SoupNetworkProxySettings contextProxySettings = parseProxySettings(proxyServer, proxyBypassList);
 | |
| +        browserContext->dataStore->setNetworkProxySettings(WTFMove(contextProxySettings));
 | |
| +    } else {
 | |
| +        browserContext->dataStore->setNetworkProxySettings(WebCore::SoupNetworkProxySettings(m_proxySettings));
 | |
| +    }
 | |
| +    return browserContext;
 | |
| +}
 | |
| +
 | |
| +void InspectorPlaywrightAgentClientGlib::deleteBrowserContext(WTF::String& error, PAL::SessionID sessionID)
 | |
| +{
 | |
| +    m_idToContext.remove(sessionID);
 | |
| +}
 | |
| +
 | |
| +} // namespace WebKit
 | |
| +
 | |
| +#endif // ENABLE(REMOTE_INSPECTOR)
 | |
| diff --git a/Source/WebKit/UIProcess/glib/InspectorPlaywrightAgentClientGLib.h b/Source/WebKit/UIProcess/glib/InspectorPlaywrightAgentClientGLib.h
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..8006336003a4512b4c63bc8272d4b3507bb63159
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/UIProcess/glib/InspectorPlaywrightAgentClientGLib.h
 | |
| @@ -0,0 +1,60 @@
 | |
| +/*
 | |
| + * Copyright (C) 2019 Microsoft Corporation.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
| + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#pragma once
 | |
| +
 | |
| +#if ENABLE(REMOTE_INSPECTOR)
 | |
| +
 | |
| +#include "InspectorPlaywrightAgentClient.h"
 | |
| +#include <WebCore/SoupNetworkProxySettings.h>
 | |
| +#include "WebKitWebContext.h"
 | |
| +#include <wtf/Forward.h>
 | |
| +#include <wtf/HashMap.h>
 | |
| +#include <wtf/glib/GRefPtr.h>
 | |
| +#include <wtf/text/StringHash.h>
 | |
| +
 | |
| +namespace WebKit {
 | |
| +
 | |
| +class InspectorPlaywrightAgentClientGlib : public InspectorPlaywrightAgentClient {
 | |
| +    WTF_MAKE_FAST_ALLOCATED;
 | |
| +public:
 | |
| +    InspectorPlaywrightAgentClientGlib(const WTF::String& proxyURI, const char* const* ignoreHosts);
 | |
| +    ~InspectorPlaywrightAgentClientGlib() override = default;
 | |
| +
 | |
| +    RefPtr<WebPageProxy> createPage(WTF::String& error, const BrowserContext&) override;
 | |
| +    void closeBrowser() override;
 | |
| +    std::unique_ptr<BrowserContext> createBrowserContext(WTF::String& error, const WTF::String& proxyServer, const WTF::String& proxyBypassList) override;
 | |
| +    void deleteBrowserContext(WTF::String& error, PAL::SessionID) override;
 | |
| +
 | |
| +private:
 | |
| +    WebKitWebContext* findContext(WTF::String& error, PAL::SessionID);
 | |
| +
 | |
| +    HashMap<PAL::SessionID, GRefPtr<WebKitWebContext>> m_idToContext;
 | |
| +    WebCore::SoupNetworkProxySettings m_proxySettings;
 | |
| +};
 | |
| +
 | |
| +} // namespace API
 | |
| +
 | |
| +#endif // ENABLE(REMOTE_INSPECTOR)
 | |
| diff --git a/Source/WebKit/UIProcess/glib/WebPageProxyGLib.cpp b/Source/WebKit/UIProcess/glib/WebPageProxyGLib.cpp
 | |
| index 521df7840ab6d376c25130e87ea500942398c8b6..da198916beb0d0b46661f5209db3967ba5f9f776 100644
 | |
| --- a/Source/WebKit/UIProcess/glib/WebPageProxyGLib.cpp
 | |
| +++ b/Source/WebKit/UIProcess/glib/WebPageProxyGLib.cpp
 | |
| @@ -57,4 +57,34 @@ void WebPageProxy::loadRecentSearches(const String&, CompletionHandler<void(Vect
 | |
|      completionHandler({ });
 | |
|  }
 | |
|  
 | |
| +#if ENABLE(SPEECH_SYNTHESIS)
 | |
| +void WebPageProxy::didStartSpeaking(WebCore::PlatformSpeechSynthesisUtterance&)
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +void WebPageProxy::didFinishSpeaking(WebCore::PlatformSpeechSynthesisUtterance&)
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +void WebPageProxy::didPauseSpeaking(WebCore::PlatformSpeechSynthesisUtterance&)
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +void WebPageProxy::didResumeSpeaking(WebCore::PlatformSpeechSynthesisUtterance&)
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +void WebPageProxy::speakingErrorOccurred(WebCore::PlatformSpeechSynthesisUtterance&)
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +void WebPageProxy::boundaryEventOccurred(WebCore::PlatformSpeechSynthesisUtterance&, WebCore::SpeechBoundary speechBoundary, unsigned charIndex, unsigned charLength)
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +void WebPageProxy::voicesDidChange()
 | |
| +{
 | |
| +}
 | |
| +#endif // ENABLE(SPEECH_SYNTHESIS)
 | |
| +
 | |
|  }
 | |
| diff --git a/Source/WebKit/UIProcess/gtk/AcceleratedBackingStore.h b/Source/WebKit/UIProcess/gtk/AcceleratedBackingStore.h
 | |
| index 39aeff71fe05354cf63d3b3701d363642d63aca4..32e96cdd0bdbd8c5dcde43fdf60052ac13a226f7 100644
 | |
| --- a/Source/WebKit/UIProcess/gtk/AcceleratedBackingStore.h
 | |
| +++ b/Source/WebKit/UIProcess/gtk/AcceleratedBackingStore.h
 | |
| @@ -28,6 +28,7 @@
 | |
|  #include <wtf/Noncopyable.h>
 | |
|  
 | |
|  typedef struct _cairo cairo_t;
 | |
| +typedef struct _cairo_surface cairo_surface_t;
 | |
|  
 | |
|  #if USE(GTK4)
 | |
|  typedef struct _GdkSnapshot GdkSnapshot;
 | |
| @@ -56,6 +57,8 @@ public:
 | |
|  #else
 | |
|      virtual bool paint(cairo_t*, const WebCore::IntRect&) = 0;
 | |
|  #endif
 | |
| +    virtual cairo_surface_t* surface() { return nullptr; }
 | |
| +
 | |
|      virtual void realize() { };
 | |
|      virtual void unrealize() { };
 | |
|      virtual bool makeContextCurrent() { return false; }
 | |
| diff --git a/Source/WebKit/UIProcess/gtk/AcceleratedBackingStoreX11.h b/Source/WebKit/UIProcess/gtk/AcceleratedBackingStoreX11.h
 | |
| index 054e80bd900cf16d69801e8102ca989ff0563e1d..8245d7ed58008dbb6152e55e619e4331d30ae674 100644
 | |
| --- a/Source/WebKit/UIProcess/gtk/AcceleratedBackingStoreX11.h
 | |
| +++ b/Source/WebKit/UIProcess/gtk/AcceleratedBackingStoreX11.h
 | |
| @@ -52,6 +52,7 @@ private:
 | |
|  #else
 | |
|      bool paint(cairo_t*, const WebCore::IntRect&) override;
 | |
|  #endif
 | |
| +    cairo_surface_t* surface() override { return m_surface.get(); }
 | |
|  
 | |
|      RefPtr<cairo_surface_t> m_surface;
 | |
|      WebCore::XUniqueDamage m_damage;
 | |
| diff --git a/Source/WebKit/UIProcess/gtk/InspectorTargetProxyGtk.cpp b/Source/WebKit/UIProcess/gtk/InspectorTargetProxyGtk.cpp
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..f5f811ced4eafef530d101c4e397fe2780ac3071
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/UIProcess/gtk/InspectorTargetProxyGtk.cpp
 | |
| @@ -0,0 +1,44 @@
 | |
| +/*
 | |
| + * Copyright (C) 2019 Microsoft Corporation.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
| + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#include "config.h"
 | |
| +#include "InspectorTargetProxy.h"
 | |
| +
 | |
| +#include "WebPageProxy.h"
 | |
| +#include <WebCore/GtkUtilities.h>
 | |
| +#include <gtk/gtk.h>
 | |
| +
 | |
| +namespace WebKit {
 | |
| +
 | |
| +void InspectorTargetProxy::platformActivate(String& error) const
 | |
| +{
 | |
| +    GtkWidget* parent = gtk_widget_get_toplevel(m_page.viewWidget());
 | |
| +    if (WebCore::widgetIsOnscreenToplevelWindow(parent))
 | |
| +        gtk_window_present(GTK_WINDOW(parent));
 | |
| +    else
 | |
| +        error = "The view is not on screen"_s;
 | |
| +}
 | |
| +
 | |
| +} // namespace WebKit
 | |
| diff --git a/Source/WebKit/UIProcess/gtk/WebDateTimePickerGtk.cpp b/Source/WebKit/UIProcess/gtk/WebDateTimePickerGtk.cpp
 | |
| index ce0b10ec8d07762bb1b19ff1eb05fc17de129c2c..275ab45bc83e9ab3011023ec3cf999472e8ab8b0 100644
 | |
| --- a/Source/WebKit/UIProcess/gtk/WebDateTimePickerGtk.cpp
 | |
| +++ b/Source/WebKit/UIProcess/gtk/WebDateTimePickerGtk.cpp
 | |
| @@ -34,6 +34,8 @@
 | |
|  #include <wtf/SetForScope.h>
 | |
|  #include <wtf/glib/GRefPtr.h>
 | |
|  
 | |
| +using namespace WebCore;
 | |
| +
 | |
|  namespace WebKit {
 | |
|  
 | |
|  Ref<WebDateTimePickerGtk> WebDateTimePickerGtk::create(WebPageProxy& page)
 | |
| diff --git a/Source/WebKit/UIProcess/gtk/WebPageInspectorEmulationAgentGtk.cpp b/Source/WebKit/UIProcess/gtk/WebPageInspectorEmulationAgentGtk.cpp
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..e5e25acebabb76a05a77db02a99f1267bd99a3af
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/UIProcess/gtk/WebPageInspectorEmulationAgentGtk.cpp
 | |
| @@ -0,0 +1,69 @@
 | |
| +/*
 | |
| + * Copyright (C) 2019 Microsoft Corporation.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
| + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#include "config.h"
 | |
| +#include "DrawingAreaProxyCoordinatedGraphics.h"
 | |
| +#include "WebPageInspectorEmulationAgent.h"
 | |
| +#include "WebPageProxy.h"
 | |
| +#include <WebCore/IntSize.h>
 | |
| +#include <gtk/gtk.h>
 | |
| +
 | |
| +namespace WebKit {
 | |
| +void WebPageInspectorEmulationAgent::platformSetSize(int width, int height, Function<void (const String& error)>&& callback)
 | |
| +{
 | |
| +    GtkWidget* viewWidget = m_page.viewWidget();
 | |
| +    GtkWidget* window = gtk_widget_get_toplevel(viewWidget);
 | |
| +    if (!window) {
 | |
| +        callback("Cannot find parent window"_s);
 | |
| +        return;
 | |
| +    }
 | |
| +    if (!GTK_IS_WINDOW(window)) {
 | |
| +        callback("Toplevel is not a window"_s);
 | |
| +        return;
 | |
| +    }
 | |
| +    GtkAllocation viewAllocation;
 | |
| +    gtk_widget_get_allocation(viewWidget, &viewAllocation);
 | |
| +    if (viewAllocation.width == width && viewAllocation.height == height) {
 | |
| +        callback(String());
 | |
| +        return;
 | |
| +    }
 | |
| +
 | |
| +    GtkAllocation windowAllocation;
 | |
| +    gtk_widget_get_allocation(window, &windowAllocation);
 | |
| +
 | |
| +    width += windowAllocation.width - viewAllocation.width;
 | |
| +    height += windowAllocation.height - viewAllocation.height;
 | |
| +
 | |
| +    if (auto* drawingArea = static_cast<DrawingAreaProxyCoordinatedGraphics*>(m_page.drawingArea())) {
 | |
| +        drawingArea->waitForSizeUpdate([callback = WTFMove(callback)]() {
 | |
| +            callback(String());
 | |
| +        });
 | |
| +    } else {
 | |
| +        callback("No backing store for window"_s);
 | |
| +    }
 | |
| +    gtk_window_resize(GTK_WINDOW(window), width, height);
 | |
| +}
 | |
| +
 | |
| +} // namespace WebKit
 | |
| diff --git a/Source/WebKit/UIProcess/gtk/WebPageInspectorInputAgentGtk.cpp b/Source/WebKit/UIProcess/gtk/WebPageInspectorInputAgentGtk.cpp
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..d0f9827544994e450e24e3f7a427c35eeff94d67
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/UIProcess/gtk/WebPageInspectorInputAgentGtk.cpp
 | |
| @@ -0,0 +1,105 @@
 | |
| +/*
 | |
| + * Copyright (C) 2019 Microsoft Corporation.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
| + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#include "config.h"
 | |
| +#include "WebPageInspectorInputAgent.h"
 | |
| +
 | |
| +#include "KeyBindingTranslator.h"
 | |
| +#include "NativeWebKeyboardEvent.h"
 | |
| +#include "WebPageProxy.h"
 | |
| +#include <WebCore/PlatformKeyboardEvent.h>
 | |
| +
 | |
| +namespace WebKit {
 | |
| +
 | |
| +static Vector<String> commandsForKeyEvent(GdkEventType type, unsigned keyVal, unsigned state)
 | |
| +{
 | |
| +    ASSERT(type == GDK_KEY_PRESS || type == GDK_KEY_RELEASE);
 | |
| +
 | |
| +    GUniquePtr<GdkEvent> event(gdk_event_new(type));
 | |
| +    event->key.keyval = keyVal;
 | |
| +    event->key.time = GDK_CURRENT_TIME;
 | |
| +    event->key.state = state;
 | |
| +    // When synthesizing an event, an invalid hardware_keycode value can cause it to be badly processed by GTK+.
 | |
| +    GUniqueOutPtr<GdkKeymapKey> keys;
 | |
| +    int keysCount;
 | |
| +    if (gdk_keymap_get_entries_for_keyval(gdk_keymap_get_default(), keyVal, &keys.outPtr(), &keysCount) && keysCount)
 | |
| +        event->key.hardware_keycode = keys.get()[0].keycode;
 | |
| +    return KeyBindingTranslator().commandsForKeyEvent(&event->key);
 | |
| +}
 | |
| +
 | |
| +static unsigned modifiersToEventState(OptionSet<WebEvent::Modifier> modifiers)
 | |
| +{
 | |
| +    unsigned state = 0;
 | |
| +    if (modifiers.contains(WebEvent::Modifier::ControlKey))
 | |
| +        state |= GDK_CONTROL_MASK;
 | |
| +    if (modifiers.contains(WebEvent::Modifier::ShiftKey))
 | |
| +        state |= GDK_SHIFT_MASK;
 | |
| +    if (modifiers.contains(WebEvent::Modifier::AltKey))
 | |
| +        state |= GDK_META_MASK;
 | |
| +    if (modifiers.contains(WebEvent::Modifier::CapsLockKey))
 | |
| +        state |= GDK_LOCK_MASK;
 | |
| +    return state;
 | |
| +}
 | |
| +
 | |
| +void WebPageInspectorInputAgent::platformDispatchKeyEvent(WebKeyboardEvent::Type type, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<WebEvent::Modifier> modifiers, Vector<String>& macCommands, WallTime timestamp)
 | |
| +{
 | |
| +    Vector<String> commands;
 | |
| +    const guint keyVal = WebCore::PlatformKeyboardEvent::gdkKeyCodeForWindowsKeyCode(windowsVirtualKeyCode);
 | |
| +    if (keyVal) {
 | |
| +        GdkEventType event = GDK_NOTHING;
 | |
| +        switch (type)
 | |
| +        {
 | |
| +        case WebKeyboardEvent::KeyDown:
 | |
| +            event = GDK_KEY_PRESS;
 | |
| +            break;
 | |
| +        case WebKeyboardEvent::KeyUp:
 | |
| +            event = GDK_KEY_RELEASE;
 | |
| +            break;
 | |
| +        default:
 | |
| +            fprintf(stderr, "Unsupported event type = %d\n", type);
 | |
| +            break;
 | |
| +        }
 | |
| +        unsigned state = modifiersToEventState(modifiers);
 | |
| +        commands = commandsForKeyEvent(event, keyVal, state);
 | |
| +    }
 | |
| +    NativeWebKeyboardEvent event(
 | |
| +        type,
 | |
| +        text,
 | |
| +        unmodifiedText,
 | |
| +        key,
 | |
| +        code,
 | |
| +        keyIdentifier,
 | |
| +        windowsVirtualKeyCode,
 | |
| +        nativeVirtualKeyCode,
 | |
| +        isAutoRepeat,
 | |
| +        isKeypad,
 | |
| +        isSystemKey,
 | |
| +        modifiers,
 | |
| +        timestamp,
 | |
| +        WTFMove(commands));
 | |
| +    m_page.handleKeyboardEvent(event);
 | |
| +}
 | |
| +
 | |
| +} // namespace WebKit
 | |
| diff --git a/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm b/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm
 | |
| index f31db8d38d19e975216c941d13802bc2b3fb592d..abc38b6ae330112e486c753dce217ab3cf3752fc 100644
 | |
| --- a/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm
 | |
| +++ b/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm
 | |
| @@ -439,6 +439,8 @@ IntRect PageClientImpl::rootViewToAccessibilityScreen(const IntRect& rect)
 | |
|      
 | |
|  void PageClientImpl::doneWithKeyEvent(const NativeWebKeyboardEvent& event, bool eventWasHandled)
 | |
|  {
 | |
| +    if (!event.nativeEvent())
 | |
| +        return;
 | |
|      [m_contentView _didHandleKeyEvent:event.nativeEvent() eventWasHandled:eventWasHandled];
 | |
|  }
 | |
|  
 | |
| diff --git a/Source/WebKit/UIProcess/mac/InspectorPlaywrightAgentClientMac.h b/Source/WebKit/UIProcess/mac/InspectorPlaywrightAgentClientMac.h
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..a16815a6759da61a6a61e3d79058228af887fd7c
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/UIProcess/mac/InspectorPlaywrightAgentClientMac.h
 | |
| @@ -0,0 +1,51 @@
 | |
| +/*
 | |
| + * Copyright (C) 2019 Microsoft Corporation.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
| + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#pragma once
 | |
| +
 | |
| +#include "InspectorPlaywrightAgentClient.h"
 | |
| +#include <wtf/Forward.h>
 | |
| +
 | |
| +OBJC_PROTOCOL(_WKBrowserInspectorDelegate);
 | |
| +
 | |
| +namespace WebKit {
 | |
| +
 | |
| +class InspectorPlaywrightAgentClientMac : public InspectorPlaywrightAgentClient {
 | |
| +    WTF_MAKE_FAST_ALLOCATED;
 | |
| +public:
 | |
| +    InspectorPlaywrightAgentClientMac(_WKBrowserInspectorDelegate* delegate);
 | |
| +    ~InspectorPlaywrightAgentClientMac() override = default;
 | |
| +
 | |
| +    RefPtr<WebPageProxy> createPage(WTF::String& error, const BrowserContext&) override;
 | |
| +    void closeBrowser() override;
 | |
| +    std::unique_ptr<BrowserContext> createBrowserContext(WTF::String& error, const WTF::String& proxyServer, const WTF::String& proxyBypassList) override;
 | |
| +    void deleteBrowserContext(WTF::String& error, PAL::SessionID) override;
 | |
| +
 | |
| +private:
 | |
| +    _WKBrowserInspectorDelegate* delegate_;
 | |
| +};
 | |
| +
 | |
| +
 | |
| +} // namespace API
 | |
| diff --git a/Source/WebKit/UIProcess/mac/InspectorPlaywrightAgentClientMac.mm b/Source/WebKit/UIProcess/mac/InspectorPlaywrightAgentClientMac.mm
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..8e588f7b8c8c29fb53dd37ea41d46f3d753077fd
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/UIProcess/mac/InspectorPlaywrightAgentClientMac.mm
 | |
| @@ -0,0 +1,77 @@
 | |
| +/*
 | |
| + * Copyright (C) 2019 Microsoft Corporation.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
| + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#import "config.h"
 | |
| +#import "InspectorPlaywrightAgentClientMac.h"
 | |
| +
 | |
| +#import <wtf/RefPtr.h>
 | |
| +#import <wtf/text/WTFString.h>
 | |
| +#import "WebPageProxy.h"
 | |
| +#import "WebProcessPool.h"
 | |
| +#import "WebsiteDataStore.h"
 | |
| +#import "_WKBrowserInspector.h"
 | |
| +#import "WKProcessPoolInternal.h"
 | |
| +#import "WKWebsiteDataStoreInternal.h"
 | |
| +#import "WKWebView.h"
 | |
| +#import "WKWebViewInternal.h"
 | |
| +
 | |
| +namespace WebKit {
 | |
| +
 | |
| +InspectorPlaywrightAgentClientMac::InspectorPlaywrightAgentClientMac(_WKBrowserInspectorDelegate* delegate)
 | |
| +  : delegate_(delegate)
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +RefPtr<WebPageProxy> InspectorPlaywrightAgentClientMac::createPage(WTF::String& error, const BrowserContext& browserContext)
 | |
| +{
 | |
| +    auto sessionID = browserContext.dataStore->sessionID();
 | |
| +    WKWebView *webView = [delegate_ createNewPage:sessionID.toUInt64()];
 | |
| +    if (!webView) {
 | |
| +        error = "Internal error: can't create page in given context"_s;
 | |
| +        return nil;
 | |
| +    }
 | |
| +    return [webView _page].get();
 | |
| +}
 | |
| +
 | |
| +void InspectorPlaywrightAgentClientMac::closeBrowser()
 | |
| +{
 | |
| +    [delegate_ quit];
 | |
| +}
 | |
| +
 | |
| +std::unique_ptr<BrowserContext> InspectorPlaywrightAgentClientMac::createBrowserContext(WTF::String& error, const WTF::String& proxyServer, const WTF::String& proxyBypassList)
 | |
| +{
 | |
| +    _WKBrowserContext* wkBrowserContext = [[delegate_ createBrowserContext:proxyServer WithBypassList:proxyBypassList] autorelease];
 | |
| +    auto browserContext = std::make_unique<BrowserContext>();
 | |
| +    browserContext->processPool = &static_cast<WebProcessPool&>([[wkBrowserContext processPool] _apiObject]);
 | |
| +    browserContext->dataStore = &static_cast<WebsiteDataStore&>([[wkBrowserContext dataStore] _apiObject]);
 | |
| +    return browserContext;
 | |
| +}
 | |
| +
 | |
| +void InspectorPlaywrightAgentClientMac::deleteBrowserContext(WTF::String& error, PAL::SessionID sessionID)
 | |
| +{
 | |
| +    [delegate_ deleteBrowserContext:sessionID.toUInt64()];
 | |
| +}
 | |
| +
 | |
| +} // namespace WebKit
 | |
| diff --git a/Source/WebKit/UIProcess/mac/InspectorTargetProxyMac.mm b/Source/WebKit/UIProcess/mac/InspectorTargetProxyMac.mm
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..721826c8c98fc85b68a4f45deaee69c1219a7254
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/UIProcess/mac/InspectorTargetProxyMac.mm
 | |
| @@ -0,0 +1,42 @@
 | |
| +/*
 | |
| + * Copyright (C) 2019 Microsoft Corporation.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
| + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#import "config.h"
 | |
| +#import "InspectorTargetProxy.h"
 | |
| +#import "WebPageProxy.h"
 | |
| +
 | |
| +#if PLATFORM(MAC)
 | |
| +
 | |
| +namespace WebKit {
 | |
| +
 | |
| +void InspectorTargetProxy::platformActivate(String& error) const
 | |
| +{
 | |
| +    NSWindow* window = m_page.platformWindow();
 | |
| +    [window makeKeyAndOrderFront:nil];
 | |
| +}
 | |
| +
 | |
| +} // namespace WebKit
 | |
| +
 | |
| +#endif
 | |
| diff --git a/Source/WebKit/UIProcess/mac/PageClientImplMac.h b/Source/WebKit/UIProcess/mac/PageClientImplMac.h
 | |
| index d5953b04a4c8277264664c36e106fa26a704b44a..42623b410edd37d926d630d09af1b02c90d17964 100644
 | |
| --- a/Source/WebKit/UIProcess/mac/PageClientImplMac.h
 | |
| +++ b/Source/WebKit/UIProcess/mac/PageClientImplMac.h
 | |
| @@ -53,6 +53,8 @@ class PageClientImpl final : public PageClientImplCocoa
 | |
|  #endif
 | |
|      {
 | |
|  public:
 | |
| +    static void setHeadless(bool headless);
 | |
| +
 | |
|      PageClientImpl(NSView *, WKWebView *);
 | |
|      virtual ~PageClientImpl();
 | |
|  
 | |
| @@ -165,6 +167,9 @@ private:
 | |
|      void updateAcceleratedCompositingMode(const LayerTreeContext&) override;
 | |
|      void didFirstLayerFlush(const LayerTreeContext&) override;
 | |
|  
 | |
| +// Paywright begin
 | |
| +    RetainPtr<CGImageRef> takeSnapshotForAutomation() override;
 | |
| +// Paywright end
 | |
|      RefPtr<ViewSnapshot> takeViewSnapshot(std::optional<WebCore::IntRect>&&) override;
 | |
|      void wheelEventWasNotHandledByWebCore(const NativeWebWheelEvent&) override;
 | |
|  #if ENABLE(MAC_GESTURE_EVENTS)
 | |
| @@ -216,6 +221,10 @@ private:
 | |
|      void beganExitFullScreen(const WebCore::IntRect& initialFrame, const WebCore::IntRect& finalFrame) override;
 | |
|  #endif
 | |
|  
 | |
| +#if ENABLE(TOUCH_EVENTS)
 | |
| +    void doneWithTouchEvent(const NativeWebTouchEvent&, bool wasEventHandled) override;
 | |
| +#endif
 | |
| +
 | |
|      void navigationGestureDidBegin() override;
 | |
|      void navigationGestureWillEnd(bool willNavigate, WebBackForwardListItem&) override;
 | |
|      void navigationGestureDidEnd(bool willNavigate, WebBackForwardListItem&) override;
 | |
| diff --git a/Source/WebKit/UIProcess/mac/PageClientImplMac.mm b/Source/WebKit/UIProcess/mac/PageClientImplMac.mm
 | |
| index 656a0e89b254d505e4a03f39edb3b8a6b3939832..293aea77bf9c24193a188f943f8c7c7c55207c08 100644
 | |
| --- a/Source/WebKit/UIProcess/mac/PageClientImplMac.mm
 | |
| +++ b/Source/WebKit/UIProcess/mac/PageClientImplMac.mm
 | |
| @@ -81,6 +81,7 @@
 | |
|  #import <WebCore/TextUndoInsertionMarkupMac.h>
 | |
|  #import <WebCore/ValidationBubble.h>
 | |
|  #import <WebCore/WebCoreCALayerExtras.h>
 | |
| +#import <WebCore/NotImplemented.h>
 | |
|  #import <pal/spi/mac/NSApplicationSPI.h>
 | |
|  #import <wtf/ProcessPrivilege.h>
 | |
|  #import <wtf/RetainPtr.h>
 | |
| @@ -107,6 +108,13 @@ namespace WebKit {
 | |
|  
 | |
|  using namespace WebCore;
 | |
|  
 | |
| +static bool _headless = false;
 | |
| +
 | |
| +// static
 | |
| +void PageClientImpl::setHeadless(bool headless) {
 | |
| +    _headless = headless;
 | |
| +}
 | |
| +
 | |
|  PageClientImpl::PageClientImpl(NSView *view, WKWebView *webView)
 | |
|      : PageClientImplCocoa(webView)
 | |
|      , m_view(view)
 | |
| @@ -160,6 +168,9 @@ NSWindow *PageClientImpl::activeWindow() const
 | |
|  
 | |
|  bool PageClientImpl::isViewWindowActive()
 | |
|  {
 | |
| +    if (_headless)
 | |
| +        return true;
 | |
| +
 | |
|      ASSERT(hasProcessPrivilege(ProcessPrivilege::CanCommunicateWithWindowServer));
 | |
|      NSWindow *activeViewWindow = activeWindow();
 | |
|      return activeViewWindow.isKeyWindow || (activeViewWindow && [NSApp keyWindow] == activeViewWindow);
 | |
| @@ -167,6 +178,9 @@ bool PageClientImpl::isViewWindowActive()
 | |
|  
 | |
|  bool PageClientImpl::isViewFocused()
 | |
|  {
 | |
| +    if (_headless)
 | |
| +        return true;
 | |
| +
 | |
|      // FIXME: This is called from the WebPageProxy constructor before we have a WebViewImpl.
 | |
|      // Once WebViewImpl and PageClient merge, this won't be a problem.
 | |
|      if (!m_impl)
 | |
| @@ -190,6 +204,9 @@ void PageClientImpl::makeFirstResponder()
 | |
|      
 | |
|  bool PageClientImpl::isViewVisible()
 | |
|  {
 | |
| +    if (_headless)
 | |
| +        return true;
 | |
| +
 | |
|      NSView *activeView = this->activeView();
 | |
|      NSWindow *activeViewWindow = activeWindow();
 | |
|  
 | |
| @@ -273,7 +290,8 @@ void PageClientImpl::didRelaunchProcess()
 | |
|  
 | |
|  void PageClientImpl::preferencesDidChange()
 | |
|  {
 | |
| -    m_impl->preferencesDidChange();
 | |
| +    if (m_impl)
 | |
| +        m_impl->preferencesDidChange();
 | |
|  }
 | |
|  
 | |
|  void PageClientImpl::toolTipChanged(const String& oldToolTip, const String& newToolTip)
 | |
| @@ -479,6 +497,8 @@ IntRect PageClientImpl::rootViewToAccessibilityScreen(const IntRect& rect)
 | |
|  
 | |
|  void PageClientImpl::doneWithKeyEvent(const NativeWebKeyboardEvent& event, bool eventWasHandled)
 | |
|  {
 | |
| +    if (!event.nativeEvent())
 | |
| +        return;
 | |
|      m_impl->doneWithKeyEvent(event.nativeEvent(), eventWasHandled);
 | |
|  }
 | |
|  
 | |
| @@ -498,6 +518,8 @@ void PageClientImpl::computeHasVisualSearchResults(const URL& imageURL, Shareabl
 | |
|  
 | |
|  RefPtr<WebPopupMenuProxy> PageClientImpl::createPopupMenuProxy(WebPageProxy& page)
 | |
|  {
 | |
| +    if (_headless)
 | |
| +        return nullptr;
 | |
|      return WebPopupMenuProxyMac::create(m_view, page);
 | |
|  }
 | |
|  
 | |
| @@ -629,6 +651,12 @@ CALayer *PageClientImpl::acceleratedCompositingRootLayer() const
 | |
|      return m_impl->acceleratedCompositingRootLayer();
 | |
|  }
 | |
|  
 | |
| +// Paywright begin
 | |
| +RetainPtr<CGImageRef> PageClientImpl::takeSnapshotForAutomation() {
 | |
| +    return m_impl->takeSnapshotForAutomation();
 | |
| +}
 | |
| +// Paywright begin
 | |
| +
 | |
|  RefPtr<ViewSnapshot> PageClientImpl::takeViewSnapshot(std::optional<WebCore::IntRect>&&)
 | |
|  {
 | |
|      return m_impl->takeViewSnapshot();
 | |
| @@ -796,6 +824,13 @@ void PageClientImpl::beganExitFullScreen(const IntRect& initialFrame, const IntR
 | |
|  
 | |
|  #endif // ENABLE(FULLSCREEN_API)
 | |
|  
 | |
| +#if ENABLE(TOUCH_EVENTS)
 | |
| +void PageClientImpl::doneWithTouchEvent(const NativeWebTouchEvent& event, bool wasEventHandled)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +}
 | |
| +#endif // ENABLE(TOUCH_EVENTS)
 | |
| +
 | |
|  void PageClientImpl::navigationGestureDidBegin()
 | |
|  {
 | |
|      m_impl->dismissContentRelativeChildWindowsWithAnimation(true);
 | |
| @@ -973,6 +1008,9 @@ void PageClientImpl::requestScrollToRect(const WebCore::FloatRect& targetRect, c
 | |
|  
 | |
|  bool PageClientImpl::windowIsFrontWindowUnderMouse(const NativeWebMouseEvent& event)
 | |
|  {
 | |
| +    // Simulated event.
 | |
| +    if (!event.nativeEvent())
 | |
| +        return false;
 | |
|      return m_impl->windowIsFrontWindowUnderMouse(event.nativeEvent());
 | |
|  }
 | |
|  
 | |
| diff --git a/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.h b/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.h
 | |
| index 1a2c89022fd23b5dc5976500d9a3943d6daaffb8..9f66ad2c714018be74e669df4c650d42c6ae9ffe 100644
 | |
| --- a/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.h
 | |
| +++ b/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.h
 | |
| @@ -68,6 +68,7 @@ private:
 | |
|      void show() override;
 | |
|      void showContextMenuWithItems(Vector<Ref<WebContextMenuItem>>&&) override;
 | |
|      void useContextMenuItems(Vector<Ref<WebContextMenuItem>>&&) override;
 | |
| +    void hide() override;
 | |
|  
 | |
|      void getContextMenuItem(const WebContextMenuItemData&, CompletionHandler<void(NSMenuItem *)>&&);
 | |
|      void getContextMenuFromItems(const Vector<WebContextMenuItemData>&, CompletionHandler<void(NSMenu *)>&&);
 | |
| diff --git a/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.mm b/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.mm
 | |
| index f0edd9660e699ab411fda40d77c27ecde396a281..76c8fe9c3d2add36272307c5bd367d55d9114464 100644
 | |
| --- a/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.mm
 | |
| +++ b/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.mm
 | |
| @@ -465,6 +465,12 @@ void WebContextMenuProxyMac::getShareMenuItem(CompletionHandler<void(NSMenuItem
 | |
|  }
 | |
|  #endif
 | |
|  
 | |
| +void WebContextMenuProxyMac::hide()
 | |
| +{
 | |
| +    if (m_menu)
 | |
| +        [m_menu cancelTracking];
 | |
| +}
 | |
| +
 | |
|  void WebContextMenuProxyMac::show()
 | |
|  {
 | |
|  #if ENABLE(SERVICE_CONTROLS)
 | |
| diff --git a/Source/WebKit/UIProcess/mac/WebPageInspectorEmulationAgentMac.mm b/Source/WebKit/UIProcess/mac/WebPageInspectorEmulationAgentMac.mm
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..6113f4cd60a5d72b8ead61176cb43200803478ed
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/UIProcess/mac/WebPageInspectorEmulationAgentMac.mm
 | |
| @@ -0,0 +1,44 @@
 | |
| +/*
 | |
| + * Copyright (C) 2019 Microsoft Corporation.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
| + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#import "config.h"
 | |
| +#import "WebPageInspectorEmulationAgent.h"
 | |
| +
 | |
| +#import "WebPageProxy.h"
 | |
| +
 | |
| +namespace WebKit {
 | |
| +
 | |
| +void WebPageInspectorEmulationAgent::platformSetSize(int width, int height, Function<void (const String& error)>&& callback)
 | |
| +{
 | |
| +    NSWindow* window = m_page.platformWindow();
 | |
| +    NSRect windowRect = [window frame];
 | |
| +    NSRect viewRect = window.contentLayoutRect;
 | |
| +    windowRect.size.width += width - viewRect.size.width;
 | |
| +    windowRect.size.height += height - viewRect.size.height;
 | |
| +    [window setFrame:windowRect display:YES animate:NO];
 | |
| +    callback(String());
 | |
| +}
 | |
| +
 | |
| +} // namespace WebKit
 | |
| diff --git a/Source/WebKit/UIProcess/mac/WebPageInspectorInputAgentMac.mm b/Source/WebKit/UIProcess/mac/WebPageInspectorInputAgentMac.mm
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..104dadb7af05fbf837465614e66c2c0068753b03
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/UIProcess/mac/WebPageInspectorInputAgentMac.mm
 | |
| @@ -0,0 +1,125 @@
 | |
| +/*
 | |
| + * Copyright (C) 2019 Microsoft Corporation.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
| + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#import "config.h"
 | |
| +#import "NativeWebMouseEvent.h"
 | |
| +#import "WebPageInspectorInputAgent.h"
 | |
| +#import "WebPageProxy.h"
 | |
| +#import <WebCore/IntPoint.h>
 | |
| +#import <WebCore/IntSize.h>
 | |
| +#import "NativeWebKeyboardEvent.h"
 | |
| +
 | |
| +namespace WebKit {
 | |
| +
 | |
| +using namespace WebCore;
 | |
| +
 | |
| +void WebPageInspectorInputAgent::platformDispatchMouseEvent(const String& type, int x, int y, std::optional<int>&& optionalModifiers, const String& button, std::optional<int>&& optionalClickCount, unsigned short buttons) {
 | |
| +    IntPoint locationInWindow(x, y);
 | |
| +
 | |
| +    NSEventModifierFlags modifiers = 0;
 | |
| +    if (optionalModifiers) {
 | |
| +        int inputModifiers = *optionalModifiers;
 | |
| +        if (inputModifiers & 1)
 | |
| +            modifiers |= NSEventModifierFlagShift;
 | |
| +        if (inputModifiers & 2)
 | |
| +            modifiers |= NSEventModifierFlagControl;
 | |
| +        if (inputModifiers & 4)
 | |
| +            modifiers |= NSEventModifierFlagOption;
 | |
| +        if (inputModifiers & 8)
 | |
| +            modifiers |= NSEventModifierFlagCommand;
 | |
| +    }
 | |
| +    int clickCount = optionalClickCount ? *optionalClickCount : 0;
 | |
| +
 | |
| +    NSTimeInterval timestamp = [NSDate timeIntervalSinceReferenceDate];
 | |
| +    NSWindow *window = m_page.platformWindow();
 | |
| +    NSInteger windowNumber = window.windowNumber;
 | |
| +
 | |
| +    NSEventType downEventType = (NSEventType)0;
 | |
| +    NSEventType dragEventType = (NSEventType)0;
 | |
| +    NSEventType upEventType = (NSEventType)0;
 | |
| +
 | |
| +    if (!button || button == "none") {
 | |
| +        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]);
 | |
| +        nativeEvent.playwrightSetButtons(buttons);
 | |
| +        m_page.handleMouseEvent(nativeEvent);
 | |
| +    }
 | |
| +}
 | |
| +
 | |
| +void WebPageInspectorInputAgent::platformDispatchKeyEvent(WebKeyboardEvent::Type type, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<WebEvent::Modifier> modifiers, Vector<String>& commands, WallTime timestamp)
 | |
| +{
 | |
| +    Vector<WebCore::KeypressCommand> macCommands;
 | |
| +    for (const String& command : commands) {
 | |
| +      m_page.registerKeypressCommandName(command);
 | |
| +      macCommands.append(WebCore::KeypressCommand(command));
 | |
| +    }
 | |
| +    if (text.length() > 0 && macCommands.size() == 0)
 | |
| +      macCommands.append(WebCore::KeypressCommand("insertText:"_s, text));
 | |
| +    NativeWebKeyboardEvent event(
 | |
| +        type,
 | |
| +        text,
 | |
| +        unmodifiedText,
 | |
| +        key,
 | |
| +        code,
 | |
| +        keyIdentifier,
 | |
| +        windowsVirtualKeyCode,
 | |
| +        nativeVirtualKeyCode,
 | |
| +        isAutoRepeat,
 | |
| +        isKeypad,
 | |
| +        isSystemKey,
 | |
| +        modifiers,
 | |
| +        timestamp,
 | |
| +        WTFMove(macCommands));
 | |
| +    m_page.handleKeyboardEvent(event);
 | |
| +}
 | |
| +
 | |
| +} // namespace WebKit
 | |
| diff --git a/Source/WebKit/UIProcess/win/InspectorPlaywrightAgentClientWin.cpp b/Source/WebKit/UIProcess/win/InspectorPlaywrightAgentClientWin.cpp
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..dd7fe0604188bb025f361f1c44685e38bbf935ca
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/UIProcess/win/InspectorPlaywrightAgentClientWin.cpp
 | |
| @@ -0,0 +1,90 @@
 | |
| +/*
 | |
| + * Copyright (C) 2020 Microsoft Corporation.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
| + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#include "config.h"
 | |
| +#include "InspectorPlaywrightAgentClientWin.h"
 | |
| +
 | |
| +#if ENABLE(REMOTE_INSPECTOR)
 | |
| +
 | |
| +#include "APIPageConfiguration.h"
 | |
| +#include "APIProcessPoolConfiguration.h"
 | |
| +#include "InspectorPlaywrightAgent.h"
 | |
| +#include "WebPageProxy.h"
 | |
| +#include "WebsiteDataStore.h"
 | |
| +#include "WebPreferences.h"
 | |
| +#include "WebProcessPool.h"
 | |
| +#include "WebView.h"
 | |
| +#include "WKAPICast.h"
 | |
| +#include <WebCore/CurlProxySettings.h>
 | |
| +#include <wtf/HashMap.h>
 | |
| +#include <wtf/RefPtr.h>
 | |
| +#include <wtf/text/StringView.h>
 | |
| +#include <wtf/text/WTFString.h>
 | |
| +
 | |
| +namespace WebKit {
 | |
| +
 | |
| +InspectorPlaywrightAgentClientWin::InspectorPlaywrightAgentClientWin(ConfigureDataStoreCallback configureDataStore, CreatePageCallback createPage, QuitCallback quit)
 | |
| +    : m_configureDataStore(configureDataStore)
 | |
| +    , m_createPage(createPage)
 | |
| +    , m_quit(quit)
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +RefPtr<WebPageProxy> InspectorPlaywrightAgentClientWin::createPage(WTF::String& error, const BrowserContext& context)
 | |
| +{
 | |
| +    auto conf = API::PageConfiguration::create();
 | |
| +    conf->setProcessPool(context.processPool.get());
 | |
| +    conf->setWebsiteDataStore(context.dataStore.get());
 | |
| +    return toImpl(m_createPage(toAPI(&conf.get())));
 | |
| +}
 | |
| +
 | |
| +void InspectorPlaywrightAgentClientWin::closeBrowser()
 | |
| +{
 | |
| +    m_quit();
 | |
| +}
 | |
| +
 | |
| +std::unique_ptr<BrowserContext> InspectorPlaywrightAgentClientWin::createBrowserContext(WTF::String& error, const WTF::String& proxyServer, const WTF::String& proxyBypassList)
 | |
| +{
 | |
| +    auto config = API::ProcessPoolConfiguration::create();
 | |
| +    auto browserContext = std::make_unique<BrowserContext>();
 | |
| +    browserContext->processPool = WebKit::WebProcessPool::create(config);
 | |
| +    browserContext->dataStore = WebKit::WebsiteDataStore::createNonPersistent();
 | |
| +    m_configureDataStore(toAPI(browserContext->dataStore.get()));
 | |
| +    if (!proxyServer.isEmpty()) {
 | |
| +        URL proxyURL = URL(URL(), proxyServer);
 | |
| +        WebCore::CurlProxySettings settings(WTFMove(proxyURL), String(proxyBypassList));
 | |
| +        browserContext->dataStore->setNetworkProxySettings(WTFMove(settings));
 | |
| +    }
 | |
| +    PAL::SessionID sessionID = browserContext->dataStore->sessionID();
 | |
| +    return browserContext;
 | |
| +}
 | |
| +
 | |
| +void InspectorPlaywrightAgentClientWin::deleteBrowserContext(WTF::String& error, PAL::SessionID sessionID)
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +} // namespace WebKit
 | |
| +
 | |
| +#endif // ENABLE(REMOTE_INSPECTOR)
 | |
| diff --git a/Source/WebKit/UIProcess/win/InspectorPlaywrightAgentClientWin.h b/Source/WebKit/UIProcess/win/InspectorPlaywrightAgentClientWin.h
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..df18883b2b7d22d73540cb084d3dd5291231097d
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/UIProcess/win/InspectorPlaywrightAgentClientWin.h
 | |
| @@ -0,0 +1,60 @@
 | |
| +/*
 | |
| + * Copyright (C) 2020 Microsoft Corporation.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
| + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#pragma once
 | |
| +
 | |
| +#if ENABLE(REMOTE_INSPECTOR)
 | |
| +
 | |
| +#include "InspectorPlaywrightAgentClient.h"
 | |
| +#include <WebKit/WKInspector.h>
 | |
| +#include <wtf/Forward.h>
 | |
| +#include <wtf/text/StringHash.h>
 | |
| +
 | |
| +typedef void (*ConfigureDataStoreCallback)(WKWebsiteDataStoreRef dataStore);
 | |
| +typedef WKPageRef (*CreatePageCallback)(WKPageConfigurationRef configuration);
 | |
| +typedef void (*QuitCallback)();
 | |
| +
 | |
| +namespace WebKit {
 | |
| +
 | |
| +class InspectorPlaywrightAgentClientWin : public InspectorPlaywrightAgentClient {
 | |
| +    WTF_MAKE_FAST_ALLOCATED;
 | |
| +public:
 | |
| +    InspectorPlaywrightAgentClientWin(ConfigureDataStoreCallback, CreatePageCallback, QuitCallback);
 | |
| +    ~InspectorPlaywrightAgentClientWin() override = default;
 | |
| +
 | |
| +    RefPtr<WebPageProxy> createPage(WTF::String& error, const BrowserContext&) override;
 | |
| +    void closeBrowser() override;
 | |
| +    std::unique_ptr<BrowserContext> createBrowserContext(WTF::String& error, const WTF::String& proxyServer, const WTF::String& proxyBypassList) override;
 | |
| +    void deleteBrowserContext(WTF::String& error, PAL::SessionID) override;
 | |
| +
 | |
| +private:
 | |
| +    ConfigureDataStoreCallback m_configureDataStore;
 | |
| +    CreatePageCallback m_createPage;
 | |
| +    QuitCallback m_quit;
 | |
| +};
 | |
| +
 | |
| +} // namespace API
 | |
| +
 | |
| +#endif // ENABLE(REMOTE_INSPECTOR)
 | |
| diff --git a/Source/WebKit/UIProcess/win/InspectorTargetProxyWin.cpp b/Source/WebKit/UIProcess/win/InspectorTargetProxyWin.cpp
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..135a60361fa8fbf907382625e7c8dd4ea64ceb94
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/UIProcess/win/InspectorTargetProxyWin.cpp
 | |
| @@ -0,0 +1,36 @@
 | |
| +/*
 | |
| + * Copyright (C) 2020 Microsoft Corporation.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
| + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#include "config.h"
 | |
| +#include "InspectorTargetProxy.h"
 | |
| +#include "WebPageProxy.h"
 | |
| +
 | |
| +namespace WebKit {
 | |
| +
 | |
| +void InspectorTargetProxy::platformActivate(String& error) const
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +} // namespace WebKit
 | |
| diff --git a/Source/WebKit/UIProcess/win/WebContextMenuProxyWin.cpp b/Source/WebKit/UIProcess/win/WebContextMenuProxyWin.cpp
 | |
| index 3dcd0ec35c92e37239208a8f5d4f461fbeaac3ce..84ba07c57f2abac1bd0ca5d0af2e7366ad036892 100644
 | |
| --- a/Source/WebKit/UIProcess/win/WebContextMenuProxyWin.cpp
 | |
| +++ b/Source/WebKit/UIProcess/win/WebContextMenuProxyWin.cpp
 | |
| @@ -112,5 +112,11 @@ WebContextMenuProxyWin::~WebContextMenuProxyWin()
 | |
|          ::DestroyMenu(m_menu);
 | |
|  }
 | |
|  
 | |
| +void WebContextMenuProxyWin::hide()
 | |
| +{
 | |
| +    if (m_menu)
 | |
| +        ::EndMenu();
 | |
| +}
 | |
| +
 | |
|  } // namespace WebKit
 | |
|  #endif // ENABLE(CONTEXT_MENUS)
 | |
| diff --git a/Source/WebKit/UIProcess/win/WebContextMenuProxyWin.h b/Source/WebKit/UIProcess/win/WebContextMenuProxyWin.h
 | |
| index 0c80d970c3f9a987faf620081c909f6c7021970d..1467e5481f7417913c0d12a1cb492d02b2a7d1b7 100644
 | |
| --- a/Source/WebKit/UIProcess/win/WebContextMenuProxyWin.h
 | |
| +++ b/Source/WebKit/UIProcess/win/WebContextMenuProxyWin.h
 | |
| @@ -47,6 +47,7 @@ public:
 | |
|  private:
 | |
|      WebContextMenuProxyWin(WebPageProxy&, ContextMenuContextData&&, const UserData&);
 | |
|      void showContextMenuWithItems(Vector<Ref<WebContextMenuItem>>&&) override;
 | |
| +    void hide() override;
 | |
|  
 | |
|      HMENU m_menu;
 | |
|  };
 | |
| diff --git a/Source/WebKit/UIProcess/win/WebPageInspectorEmulationAgentWin.cpp b/Source/WebKit/UIProcess/win/WebPageInspectorEmulationAgentWin.cpp
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..0f95bc9549b3a00f9b976b4fe9140ea8e61a3513
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/UIProcess/win/WebPageInspectorEmulationAgentWin.cpp
 | |
| @@ -0,0 +1,58 @@
 | |
| +/*
 | |
| + * Copyright (C) 2020 Microsoft Corporation.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
| + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#include "config.h"
 | |
| +#include "WebPageInspectorEmulationAgent.h"
 | |
| +#include "WebPageProxy.h"
 | |
| +
 | |
| +namespace WebKit {
 | |
| +
 | |
| +void WebPageInspectorEmulationAgent::platformSetSize(int width, int height, Function<void (const String& error)>&& callback)
 | |
| +{
 | |
| +    HWND viewHwnd = m_page.viewWidget();
 | |
| +    HWND windowHwnd = GetAncestor(viewHwnd, GA_ROOT);
 | |
| +    RECT viewRect;
 | |
| +    RECT windowRect;
 | |
| +
 | |
| +    if (!windowHwnd || !GetWindowRect(windowHwnd, &windowRect)) {
 | |
| +        callback("Could not retrieve window size"_s);
 | |
| +        return;
 | |
| +    }
 | |
| +    if (!GetWindowRect(viewHwnd, &viewRect)) {
 | |
| +        callback("Could retrieve view size"_s);
 | |
| +        return;
 | |
| +    }
 | |
| +
 | |
| +    width += windowRect.right - windowRect.left - viewRect.right + viewRect.left;
 | |
| +    height += windowRect.bottom - windowRect.top - viewRect.bottom + viewRect.top;
 | |
| +
 | |
| +    if (!SetWindowPos(windowHwnd, 0, 0, 0, width, height, SWP_NOCOPYBITS | SWP_NOSENDCHANGING | SWP_NOMOVE)) {
 | |
| +        callback("Could not resize window"_s);
 | |
| +        return;
 | |
| +    }
 | |
| +    callback(String());
 | |
| +}
 | |
| +
 | |
| +} // namespace WebKit
 | |
| diff --git a/Source/WebKit/UIProcess/win/WebPageInspectorInputAgentWin.cpp b/Source/WebKit/UIProcess/win/WebPageInspectorInputAgentWin.cpp
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..5cf8a010e9809e6a95741cdb7c2cbeb445ab638b
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/UIProcess/win/WebPageInspectorInputAgentWin.cpp
 | |
| @@ -0,0 +1,55 @@
 | |
| +/*
 | |
| + * Copyright (C) 2020 Microsoft Corporation.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
| + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +
 | |
| +#include "config.h"
 | |
| +#include "WebPageInspectorInputAgent.h"
 | |
| +
 | |
| +#include "NativeWebKeyboardEvent.h"
 | |
| +#include "WebPageProxy.h"
 | |
| +#include <WebCore/PlatformKeyboardEvent.h>
 | |
| +
 | |
| +namespace WebKit {
 | |
| +
 | |
| +void WebPageInspectorInputAgent::platformDispatchKeyEvent(WebKeyboardEvent::Type type, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<WebEvent::Modifier> modifiers, Vector<String>& macCommands, WallTime timestamp)
 | |
| +{
 | |
| +    NativeWebKeyboardEvent event(
 | |
| +        type,
 | |
| +        text,
 | |
| +        unmodifiedText,
 | |
| +        key,
 | |
| +        code,
 | |
| +        keyIdentifier,
 | |
| +        windowsVirtualKeyCode,
 | |
| +        nativeVirtualKeyCode,
 | |
| +        isAutoRepeat,
 | |
| +        isKeypad,
 | |
| +        isSystemKey,
 | |
| +        modifiers,
 | |
| +        timestamp);
 | |
| +    m_page.handleKeyboardEvent(event);
 | |
| +}
 | |
| +
 | |
| +} // namespace WebKit
 | |
| diff --git a/Source/WebKit/UIProcess/wpe/InspectorTargetProxyWPE.cpp b/Source/WebKit/UIProcess/wpe/InspectorTargetProxyWPE.cpp
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..7453194ca6f032ba86a4c67f5bf12688ab6ec1be
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/UIProcess/wpe/InspectorTargetProxyWPE.cpp
 | |
| @@ -0,0 +1,40 @@
 | |
| +/*
 | |
| + * Copyright (C) 2019 Microsoft Corporation.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
| + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#include "config.h"
 | |
| +#include "InspectorTargetProxy.h"
 | |
| +
 | |
| +#include "WebPageProxy.h"
 | |
| +#include <wpe/wpe.h>
 | |
| +
 | |
| +namespace WebKit {
 | |
| +
 | |
| +void InspectorTargetProxy::platformActivate(String& error) const
 | |
| +{
 | |
| +    struct wpe_view_backend* backend = m_page.viewBackend();
 | |
| +    wpe_view_backend_add_activity_state(backend, wpe_view_activity_state_visible | wpe_view_activity_state_focused | wpe_view_activity_state_in_window);
 | |
| +}
 | |
| +
 | |
| +} // namespace WebKit
 | |
| diff --git a/Source/WebKit/UIProcess/wpe/WebColorPickerWPE.cpp b/Source/WebKit/UIProcess/wpe/WebColorPickerWPE.cpp
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..2433afca5cdbac71d11ae1fce223766091b5c843
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/UIProcess/wpe/WebColorPickerWPE.cpp
 | |
| @@ -0,0 +1,61 @@
 | |
| +/*
 | |
| + * Copyright (C) 2015 Igalia S.L.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS AS IS''
 | |
| + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 | |
| + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 | |
| + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 | |
| + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 | |
| + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 | |
| + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 | |
| + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 | |
| + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 | |
| + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 | |
| + * THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#include "config.h"
 | |
| +#include "WebColorPickerWPE.h"
 | |
| +
 | |
| +#if ENABLE(INPUT_TYPE_COLOR)
 | |
| +
 | |
| +#include "WebPageProxy.h"
 | |
| +
 | |
| +namespace WebKit {
 | |
| +using namespace WebCore;
 | |
| +
 | |
| +Ref<WebColorPickerWPE> WebColorPickerWPE::create(WebPageProxy& page, const Color& initialColor, const IntRect& rect)
 | |
| +{
 | |
| +    return adoptRef(*new WebColorPickerWPE(page, initialColor, rect));
 | |
| +}
 | |
| +
 | |
| +WebColorPickerWPE::WebColorPickerWPE(WebPageProxy& page, const Color& initialColor, const IntRect&)
 | |
| +    : WebColorPicker(&page)
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +WebColorPickerWPE::~WebColorPickerWPE()
 | |
| +{
 | |
| +    endPicker();
 | |
| +}
 | |
| +
 | |
| +void WebColorPickerWPE::endPicker()
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +void WebColorPickerWPE::showColorPicker(const Color& color)
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +} // namespace WebKit
 | |
| +
 | |
| +#endif // ENABLE(INPUT_TYPE_COLOR)
 | |
| diff --git a/Source/WebKit/UIProcess/wpe/WebColorPickerWPE.h b/Source/WebKit/UIProcess/wpe/WebColorPickerWPE.h
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..7edc93b3873dd42a7f877626551ec994395baae9
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/UIProcess/wpe/WebColorPickerWPE.h
 | |
| @@ -0,0 +1,57 @@
 | |
| +/*
 | |
| + * Copyright (C) 2015 Igalia S.L.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS AS IS''
 | |
| + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 | |
| + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 | |
| + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 | |
| + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 | |
| + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 | |
| + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 | |
| + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 | |
| + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 | |
| + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 | |
| + * THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#ifndef WebColorPickerWPE_h
 | |
| +#define WebColorPickerWPE_h
 | |
| +
 | |
| +#if ENABLE(INPUT_TYPE_COLOR)
 | |
| +
 | |
| +#include "WebColorPicker.h"
 | |
| +
 | |
| +typedef struct _GtkColorChooser GtkColorChooser;
 | |
| +
 | |
| +namespace WebCore {
 | |
| +class Color;
 | |
| +class IntRect;
 | |
| +}
 | |
| +
 | |
| +namespace WebKit {
 | |
| +
 | |
| +class WebColorPickerWPE : public WebColorPicker {
 | |
| +public:
 | |
| +    static Ref<WebColorPickerWPE> create(WebPageProxy&, const WebCore::Color&, const WebCore::IntRect&);
 | |
| +    virtual ~WebColorPickerWPE();
 | |
| +
 | |
| +    void endPicker() override;
 | |
| +    void showColorPicker(const WebCore::Color&) override;
 | |
| +
 | |
| +protected:
 | |
| +    WebColorPickerWPE(WebPageProxy&, const WebCore::Color&, const WebCore::IntRect&);
 | |
| +};
 | |
| +
 | |
| +} // namespace WebKit
 | |
| +
 | |
| +#endif // ENABLE(INPUT_TYPE_COLOR)
 | |
| +#endif // WebColorPickerWPE_h
 | |
| diff --git a/Source/WebKit/UIProcess/wpe/WebDateTimePickerWPE.cpp b/Source/WebKit/UIProcess/wpe/WebDateTimePickerWPE.cpp
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..a44463faf011fbab08f87bb7007a5e71c2a73758
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/UIProcess/wpe/WebDateTimePickerWPE.cpp
 | |
| @@ -0,0 +1,56 @@
 | |
| +/*
 | |
| + * Copyright (C) 2020 Apple Inc. All rights reserved.
 | |
| + * Copyright (C) 2021 Igalia S.L.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 | |
| + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 | |
| + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 | |
| + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 | |
| + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 | |
| + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 | |
| + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 | |
| + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 | |
| + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 | |
| + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 | |
| + * THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#include "config.h"
 | |
| +#include "WebDateTimePickerWPE.h"
 | |
| +
 | |
| +#if ENABLE(DATE_AND_TIME_INPUT_TYPES)
 | |
| +
 | |
| +using namespace WebCore;
 | |
| +
 | |
| +namespace WebKit {
 | |
| +
 | |
| +Ref<WebDateTimePickerWPE> WebDateTimePickerWPE::create(WebPageProxy& page)
 | |
| +{
 | |
| +    return adoptRef(*new WebDateTimePickerWPE(page));
 | |
| +}
 | |
| +
 | |
| +WebDateTimePickerWPE::~WebDateTimePickerWPE()
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +WebDateTimePickerWPE::WebDateTimePickerWPE(WebPageProxy& page)
 | |
| +    : WebDateTimePicker(page)
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +void WebDateTimePickerWPE::showDateTimePicker(WebCore::DateTimeChooserParameters&& params)
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +} // namespace WebKit
 | |
| +
 | |
| +#endif // ENABLE(DATE_AND_TIME_INPUT_TYPES)
 | |
| diff --git a/Source/WebKit/UIProcess/wpe/WebDateTimePickerWPE.h b/Source/WebKit/UIProcess/wpe/WebDateTimePickerWPE.h
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..0c0e3fce33b06ee72c4c29d2a4abe9644f4cc895
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/UIProcess/wpe/WebDateTimePickerWPE.h
 | |
| @@ -0,0 +1,50 @@
 | |
| +/*
 | |
| + * Copyright (C) 2020 Apple Inc. All rights reserved.
 | |
| + * Copyright (C) 2021 Igalia S.L.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 | |
| + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 | |
| + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 | |
| + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 | |
| + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 | |
| + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 | |
| + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 | |
| + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 | |
| + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 | |
| + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 | |
| + * THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#pragma once
 | |
| +
 | |
| +#if ENABLE(DATE_AND_TIME_INPUT_TYPES)
 | |
| +
 | |
| +#include "WebDateTimePicker.h"
 | |
| +#include <WebCore/DateComponents.h>
 | |
| +#include <WebCore/DateTimeChooserParameters.h>
 | |
| +
 | |
| +namespace WebKit {
 | |
| +
 | |
| +class WebDateTimePickerWPE final : public WebDateTimePicker {
 | |
| +public:
 | |
| +    static Ref<WebDateTimePickerWPE> create(WebPageProxy&);
 | |
| +    ~WebDateTimePickerWPE();
 | |
| +
 | |
| +private:
 | |
| +    WebDateTimePickerWPE(WebPageProxy&);
 | |
| +
 | |
| +    void showDateTimePicker(WebCore::DateTimeChooserParameters&&) final;
 | |
| +};
 | |
| +
 | |
| +} // namespace WebKit
 | |
| +
 | |
| +#endif // ENABLE(DATE_AND_TIME_INPUT_TYPES)
 | |
| diff --git a/Source/WebKit/UIProcess/wpe/WebPageInspectorEmulationAgentWPE.cpp b/Source/WebKit/UIProcess/wpe/WebPageInspectorEmulationAgentWPE.cpp
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..5dc76aa302cb574307059e66a1b73730efe920da
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/UIProcess/wpe/WebPageInspectorEmulationAgentWPE.cpp
 | |
| @@ -0,0 +1,41 @@
 | |
| +/*
 | |
| + * Copyright (C) 2019 Microsoft Corporation.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
| + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#include "config.h"
 | |
| +#include "WebPageInspectorEmulationAgent.h"
 | |
| +
 | |
| +#include "WebPageProxy.h"
 | |
| +#include <wpe/wpe.h>
 | |
| +
 | |
| +namespace WebKit {
 | |
| +
 | |
| +void WebPageInspectorEmulationAgent::platformSetSize(int width, int height, Function<void (const String& error)>&& callback)
 | |
| +{
 | |
| +    struct wpe_view_backend* backend = m_page.viewBackend();
 | |
| +    wpe_view_backend_dispatch_set_size(backend, width, height);
 | |
| +    callback(String());
 | |
| +}
 | |
| +
 | |
| +} // namespace WebKit
 | |
| diff --git a/Source/WebKit/UIProcess/wpe/WebPageInspectorInputAgentWPE.cpp b/Source/WebKit/UIProcess/wpe/WebPageInspectorInputAgentWPE.cpp
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..c3d7cacea987ba2b094d5022c670705ef6ced129
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/UIProcess/wpe/WebPageInspectorInputAgentWPE.cpp
 | |
| @@ -0,0 +1,55 @@
 | |
| +/*
 | |
| + * Copyright (C) 2019 Microsoft Corporation.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
| + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#include "config.h"
 | |
| +#include "WebPageInspectorInputAgent.h"
 | |
| +
 | |
| +#include "NativeWebKeyboardEvent.h"
 | |
| +#include "WebPageProxy.h"
 | |
| +#include <WebCore/PlatformKeyboardEvent.h>
 | |
| +#include <wpe/wpe.h>
 | |
| +
 | |
| +namespace WebKit {
 | |
| +
 | |
| +void WebPageInspectorInputAgent::platformDispatchKeyEvent(WebKeyboardEvent::Type type, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<WebEvent::Modifier> modifiers, Vector<String>& macCommands, WallTime timestamp)
 | |
| +{
 | |
| +    NativeWebKeyboardEvent event(
 | |
| +        type,
 | |
| +        text,
 | |
| +        unmodifiedText,
 | |
| +        key,
 | |
| +        code,
 | |
| +        keyIdentifier,
 | |
| +        windowsVirtualKeyCode,
 | |
| +        nativeVirtualKeyCode,
 | |
| +        isAutoRepeat,
 | |
| +        isKeypad,
 | |
| +        isSystemKey,
 | |
| +        modifiers,
 | |
| +        timestamp);
 | |
| +    m_page.handleKeyboardEvent(event);
 | |
| +}
 | |
| + 
 | |
| +} // namespace WebKit
 | |
| diff --git a/Source/WebKit/WebKit.xcodeproj/project.pbxproj b/Source/WebKit/WebKit.xcodeproj/project.pbxproj
 | |
| index 55039213dbb3268e7074aa4bfaedc5617df8a756..be3c2225ce686e6911f782c51a6a974c08fd41a6 100644
 | |
| --- a/Source/WebKit/WebKit.xcodeproj/project.pbxproj
 | |
| +++ b/Source/WebKit/WebKit.xcodeproj/project.pbxproj
 | |
| @@ -1251,6 +1251,7 @@
 | |
|  		5CABDC8722C40FED001EDE8E /* APIMessageListener.h in Headers */ = {isa = PBXBuildFile; fileRef = 5CABDC8322C40FA7001EDE8E /* APIMessageListener.h */; };
 | |
|  		5CADDE05215046BD0067D309 /* WKWebProcess.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C74300E21500492004BFA17 /* WKWebProcess.h */; settings = {ATTRIBUTES = (Private, ); }; };
 | |
|  		5CAECB6627465AE400AB78D0 /* UnifiedSource115.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5CAECB5E27465AE300AB78D0 /* UnifiedSource115.cpp */; };
 | |
| +		BF2C49ED7AD83CB7BC93CC92 /* UnifiedSource116.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1D7178FBC4EDB168CDB0B04D /* UnifiedSource116.cpp */; };
 | |
|  		5CAF7AA726F93AB00003F19E /* adattributiond.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5CAF7AA526F93A950003F19E /* adattributiond.cpp */; };
 | |
|  		5CAFDE452130846300B1F7E1 /* _WKInspector.h in Headers */ = {isa = PBXBuildFile; fileRef = 5CAFDE422130843500B1F7E1 /* _WKInspector.h */; settings = {ATTRIBUTES = (Private, ); }; };
 | |
|  		5CAFDE472130846A00B1F7E1 /* _WKInspectorInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 5CAFDE442130843600B1F7E1 /* _WKInspectorInternal.h */; };
 | |
| @@ -2228,6 +2229,18 @@
 | |
|  		DF0C5F28252ECB8E00D921DB /* WKDownload.h in Headers */ = {isa = PBXBuildFile; fileRef = DF0C5F24252ECB8D00D921DB /* WKDownload.h */; settings = {ATTRIBUTES = (Public, ); }; };
 | |
|  		DF0C5F2A252ECB8E00D921DB /* WKDownloadDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = DF0C5F26252ECB8E00D921DB /* WKDownloadDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; };
 | |
|  		DF0C5F2B252ED44000D921DB /* WKDownloadInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = DF0C5F25252ECB8E00D921DB /* WKDownloadInternal.h */; };
 | |
| +		D71A94322370E025002C4D9E /* InspectorPlaywrightAgentClientMac.h in Headers */ = {isa = PBXBuildFile; fileRef = D71A94302370E025002C4D9E /* InspectorPlaywrightAgentClientMac.h */; };
 | |
| +		D71A94342370E07A002C4D9E /* InspectorPlaywrightAgentClient.h in Headers */ = {isa = PBXBuildFile; fileRef = D71A94332370E07A002C4D9E /* InspectorPlaywrightAgentClient.h */; };
 | |
| +		D71A943A2370F061002C4D9E /* RemoteInspectorPipe.h in Headers */ = {isa = PBXBuildFile; fileRef = D71A94392370F060002C4D9E /* RemoteInspectorPipe.h */; };
 | |
| +		D71A94422371F67E002C4D9E /* WebPageInspectorEmulationAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = D71A943F2371F67E002C4D9E /* WebPageInspectorEmulationAgent.h */; };
 | |
| +		D71A94432371F67E002C4D9E /* WebPageInspectorInputAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = D71A94402371F67E002C4D9E /* WebPageInspectorInputAgent.h */; };
 | |
| +		D71A944A2372290B002C4D9E /* _WKBrowserInspector.h in Headers */ = {isa = PBXBuildFile; fileRef = D71A94492372290B002C4D9E /* _WKBrowserInspector.h */; settings = {ATTRIBUTES = (Private, ); }; };
 | |
| +		D71A944C237239FB002C4D9E /* BrowserInspectorPipe.h in Headers */ = {isa = PBXBuildFile; fileRef = D71A944B237239FB002C4D9E /* BrowserInspectorPipe.h */; };
 | |
| +		D76D6888238DBD81008D314B /* InspectorDialogAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = D76D6887238DBD80008D314B /* InspectorDialogAgent.h */; };
 | |
| +		D79902B1236E9404005D6F7E /* WebPageInspectorEmulationAgentMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = D79902AE236E9404005D6F7E /* WebPageInspectorEmulationAgentMac.mm */; };
 | |
| +		D79902B2236E9404005D6F7E /* InspectorTargetProxyMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = D79902AF236E9404005D6F7E /* InspectorTargetProxyMac.mm */; };
 | |
| +		D79902B3236E9404005D6F7E /* WebPageInspectorInputAgentMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = D79902B0236E9404005D6F7E /* WebPageInspectorInputAgentMac.mm */; };
 | |
| +		D7EB04E72372A73B00F744CE /* InspectorPlaywrightAgentClientMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = D7EB04E62372A73B00F744CE /* InspectorPlaywrightAgentClientMac.mm */; };
 | |
|  		DF462E0F23F22F5500EFF35F /* WKHTTPCookieStorePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = DF462E0E23F22F5300EFF35F /* WKHTTPCookieStorePrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
 | |
|  		DF462E1223F338BE00EFF35F /* WKContentWorldPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = DF462E1123F338AD00EFF35F /* WKContentWorldPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
 | |
|  		DF84CEE4249AA24D009096F6 /* WKPDFHUDView.mm in Sources */ = {isa = PBXBuildFile; fileRef = DF84CEE2249AA21F009096F6 /* WKPDFHUDView.mm */; };
 | |
| @@ -2289,6 +2302,8 @@
 | |
|  		E5BEF6822130C48000F31111 /* WebDataListSuggestionsDropdownIOS.h in Headers */ = {isa = PBXBuildFile; fileRef = E5BEF6802130C47F00F31111 /* WebDataListSuggestionsDropdownIOS.h */; };
 | |
|  		E5CB07DC20E1678F0022C183 /* WKFormColorControl.h in Headers */ = {isa = PBXBuildFile; fileRef = E5CB07DA20E1678F0022C183 /* WKFormColorControl.h */; };
 | |
|  		E5CBA76427A318E100DF7858 /* UnifiedSource120.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5CBA75F27A3187800DF7858 /* UnifiedSource120.cpp */; };
 | |
| +		E5CBA77427A318E100DF7858 /* UnifiedSource121.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5CBA76F27A3187800DF7858 /* UnifiedSource121.cpp */; };
 | |
| +		E5CBA78427A318E100DF7858 /* UnifiedSource122.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5CBA77F27A3187800DF7858 /* UnifiedSource122.cpp */; };
 | |
|  		E5CBA76527A318E100DF7858 /* UnifiedSource118.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5CBA76127A3187900DF7858 /* UnifiedSource118.cpp */; };
 | |
|  		E5CBA76627A318E100DF7858 /* UnifiedSource116.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5CBA76327A3187B00DF7858 /* UnifiedSource116.cpp */; };
 | |
|  		E5CBA76727A318E100DF7858 /* UnifiedSource119.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5CBA76027A3187900DF7858 /* UnifiedSource119.cpp */; };
 | |
| @@ -2305,6 +2320,9 @@
 | |
|  		EBA8D3B627A5E33F00CB7900 /* MockPushServiceConnection.mm in Sources */ = {isa = PBXBuildFile; fileRef = EBA8D3B027A5E33F00CB7900 /* MockPushServiceConnection.mm */; };
 | |
|  		EBA8D3B727A5E33F00CB7900 /* PushServiceConnection.mm in Sources */ = {isa = PBXBuildFile; fileRef = EBA8D3B127A5E33F00CB7900 /* PushServiceConnection.mm */; };
 | |
|  		ED82A7F2128C6FAF004477B3 /* WKBundlePageOverlay.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A22F0FF1289FCD90085E74F /* WKBundlePageOverlay.h */; settings = {ATTRIBUTES = (Private, ); }; };
 | |
| +		F303B849249A8D640031DE5C /* ScreencastEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = F303B848249A8D3A0031DE5C /* ScreencastEncoder.h */; };
 | |
| +		F33C7AC7249AD79C0018BE41 /* libwebrtc.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F33C7AC6249AD79C0018BE41 /* libwebrtc.dylib */; };
 | |
| +		F3867F0A24607D4E008F0F31 /* InspectorScreencastAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = F3867F0424607D2B008F0F31 /* InspectorScreencastAgent.h */; };
 | |
|  		F409BA181E6E64BC009DA28E /* WKDragDestinationAction.h in Headers */ = {isa = PBXBuildFile; fileRef = F409BA171E6E64B3009DA28E /* WKDragDestinationAction.h */; settings = {ATTRIBUTES = (Private, ); }; };
 | |
|  		F4299507270E234D0032298B /* StreamMessageReceiver.h in Headers */ = {isa = PBXBuildFile; fileRef = F4299506270E234C0032298B /* StreamMessageReceiver.h */; };
 | |
|  		F42D634122A0EFDF00D2FB3A /* WebAutocorrectionData.h in Headers */ = {isa = PBXBuildFile; fileRef = F42D633F22A0EFD300D2FB3A /* WebAutocorrectionData.h */; };
 | |
| @@ -5303,6 +5321,7 @@
 | |
|  		5CABDC8522C40FCC001EDE8E /* WKMessageListener.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKMessageListener.h; sourceTree = "<group>"; };
 | |
|  		5CADDE0D2151AA010067D309 /* AuthenticationChallengeDisposition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AuthenticationChallengeDisposition.h; sourceTree = "<group>"; };
 | |
|  		5CAECB5E27465AE300AB78D0 /* UnifiedSource115.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = UnifiedSource115.cpp; path = "DerivedSources/WebKit/unified-sources/UnifiedSource115.cpp"; sourceTree = BUILT_PRODUCTS_DIR; };
 | |
| +		1D7178FBC4EDB168CDB0B04D /* UnifiedSource116.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = UnifiedSource116.cpp; path = "DerivedSources/WebKit/unified-sources/UnifiedSource116.cpp"; sourceTree = BUILT_PRODUCTS_DIR; };
 | |
|  		5CAF7AA426F93A750003F19E /* adattributiond */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = adattributiond; sourceTree = BUILT_PRODUCTS_DIR; };
 | |
|  		5CAF7AA526F93A950003F19E /* adattributiond.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = adattributiond.cpp; sourceTree = "<group>"; };
 | |
|  		5CAF7AA626F93AA50003F19E /* adattributiond.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = adattributiond.xcconfig; sourceTree = "<group>"; };
 | |
| @@ -7010,6 +7029,19 @@
 | |
|  		DF0C5F24252ECB8D00D921DB /* WKDownload.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKDownload.h; sourceTree = "<group>"; };
 | |
|  		DF0C5F25252ECB8E00D921DB /* WKDownloadInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKDownloadInternal.h; sourceTree = "<group>"; };
 | |
|  		DF0C5F26252ECB8E00D921DB /* WKDownloadDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKDownloadDelegate.h; sourceTree = "<group>"; };
 | |
| +		D71A942C2370DF81002C4D9E /* WKBrowserInspector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKBrowserInspector.h; sourceTree = "<group>"; };
 | |
| +		D71A94302370E025002C4D9E /* InspectorPlaywrightAgentClientMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorPlaywrightAgentClientMac.h; sourceTree = "<group>"; };
 | |
| +		D71A94332370E07A002C4D9E /* InspectorPlaywrightAgentClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorPlaywrightAgentClient.h; sourceTree = "<group>"; };
 | |
| +		D71A94392370F060002C4D9E /* RemoteInspectorPipe.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RemoteInspectorPipe.h; sourceTree = "<group>"; };
 | |
| +		D71A943F2371F67E002C4D9E /* WebPageInspectorEmulationAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebPageInspectorEmulationAgent.h; sourceTree = "<group>"; };
 | |
| +		D71A94402371F67E002C4D9E /* WebPageInspectorInputAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebPageInspectorInputAgent.h; sourceTree = "<group>"; };
 | |
| +		D71A94492372290B002C4D9E /* _WKBrowserInspector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _WKBrowserInspector.h; sourceTree = "<group>"; };
 | |
| +		D71A944B237239FB002C4D9E /* BrowserInspectorPipe.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BrowserInspectorPipe.h; sourceTree = "<group>"; };
 | |
| +		D76D6887238DBD80008D314B /* InspectorDialogAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorDialogAgent.h; sourceTree = "<group>"; };
 | |
| +		D79902AE236E9404005D6F7E /* WebPageInspectorEmulationAgentMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebPageInspectorEmulationAgentMac.mm; sourceTree = "<group>"; };
 | |
| +		D79902AF236E9404005D6F7E /* InspectorTargetProxyMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = InspectorTargetProxyMac.mm; sourceTree = "<group>"; };
 | |
| +		D79902B0236E9404005D6F7E /* WebPageInspectorInputAgentMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebPageInspectorInputAgentMac.mm; sourceTree = "<group>"; };
 | |
| +		D7EB04E62372A73B00F744CE /* InspectorPlaywrightAgentClientMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = InspectorPlaywrightAgentClientMac.mm; sourceTree = "<group>"; };
 | |
|  		DF462E0E23F22F5300EFF35F /* WKHTTPCookieStorePrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKHTTPCookieStorePrivate.h; sourceTree = "<group>"; };
 | |
|  		DF462E1123F338AD00EFF35F /* WKContentWorldPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKContentWorldPrivate.h; sourceTree = "<group>"; };
 | |
|  		DF58C6311371AC5800F9A37C /* NativeWebWheelEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NativeWebWheelEvent.h; sourceTree = "<group>"; };
 | |
| @@ -7138,6 +7170,8 @@
 | |
|  		E5CB07DA20E1678F0022C183 /* WKFormColorControl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = WKFormColorControl.h; path = ios/forms/WKFormColorControl.h; sourceTree = "<group>"; };
 | |
|  		E5CB07DB20E1678F0022C183 /* WKFormColorControl.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = WKFormColorControl.mm; path = ios/forms/WKFormColorControl.mm; sourceTree = "<group>"; };
 | |
|  		E5CBA75F27A3187800DF7858 /* UnifiedSource120.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = UnifiedSource120.cpp; path = "DerivedSources/WebKit/unified-sources/UnifiedSource120.cpp"; sourceTree = BUILT_PRODUCTS_DIR; };
 | |
| +		E5CBA76F27A3187800DF7858 /* UnifiedSource121.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = UnifiedSource121.cpp; path = "DerivedSources/WebKit/unified-sources/UnifiedSource121.cpp"; sourceTree = BUILT_PRODUCTS_DIR; };
 | |
| +		E5CBA77F27A3187800DF7858 /* UnifiedSource122.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = UnifiedSource122.cpp; path = "DerivedSources/WebKit/unified-sources/UnifiedSource122.cpp"; sourceTree = BUILT_PRODUCTS_DIR; };
 | |
|  		E5CBA76027A3187900DF7858 /* UnifiedSource119.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = UnifiedSource119.cpp; path = "DerivedSources/WebKit/unified-sources/UnifiedSource119.cpp"; sourceTree = BUILT_PRODUCTS_DIR; };
 | |
|  		E5CBA76127A3187900DF7858 /* UnifiedSource118.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = UnifiedSource118.cpp; path = "DerivedSources/WebKit/unified-sources/UnifiedSource118.cpp"; sourceTree = BUILT_PRODUCTS_DIR; };
 | |
|  		E5CBA76227A3187900DF7858 /* UnifiedSource117.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = UnifiedSource117.cpp; path = "DerivedSources/WebKit/unified-sources/UnifiedSource117.cpp"; sourceTree = BUILT_PRODUCTS_DIR; };
 | |
| @@ -7159,6 +7193,14 @@
 | |
|  		ECA680D31E6904B500731D20 /* ExtraPrivateSymbolsForTAPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExtraPrivateSymbolsForTAPI.h; sourceTree = "<group>"; };
 | |
|  		ECBFC1DB1E6A4D66000300C7 /* ExtraPublicSymbolsForTAPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ExtraPublicSymbolsForTAPI.h; sourceTree = "<group>"; };
 | |
|  		F036978715F4BF0500C3A80E /* WebColorPicker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebColorPicker.cpp; sourceTree = "<group>"; };
 | |
| +		F303B847249A8D3A0031DE5C /* ScreencastEncoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScreencastEncoder.cpp; sourceTree = "<group>"; };
 | |
| +		F303B848249A8D3A0031DE5C /* ScreencastEncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScreencastEncoder.h; sourceTree = "<group>"; };
 | |
| +		F31E2DA424C76E4B004B2775 /* WebMFileWriter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebMFileWriter.cpp; sourceTree = "<group>"; };
 | |
| +		F31E2DA524C76E4C004B2775 /* WebMFileWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebMFileWriter.h; sourceTree = "<group>"; };
 | |
| +		F33C7AC6249AD79C0018BE41 /* libwebrtc.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; path = libwebrtc.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
 | |
| +		F3867F0324607D2B008F0F31 /* InspectorScreencastAgent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorScreencastAgent.cpp; sourceTree = "<group>"; };
 | |
| +		F3867F0424607D2B008F0F31 /* InspectorScreencastAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorScreencastAgent.h; sourceTree = "<group>"; };
 | |
| +		F3970344249BD4CE003E1A22 /* ScreencastEncoderMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ScreencastEncoderMac.mm; sourceTree = "<group>"; };
 | |
|  		F409BA171E6E64B3009DA28E /* WKDragDestinationAction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKDragDestinationAction.h; sourceTree = "<group>"; };
 | |
|  		F40D1B68220BDC0F00B49A01 /* WebAutocorrectionContext.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = WebAutocorrectionContext.h; path = ios/WebAutocorrectionContext.h; sourceTree = "<group>"; };
 | |
|  		F41056612130699A0092281D /* APIAttachmentCocoa.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = APIAttachmentCocoa.mm; sourceTree = "<group>"; };
 | |
| @@ -7295,6 +7337,7 @@
 | |
|  				3766F9EF189A1244003CF19B /* QuartzCore.framework in Frameworks */,
 | |
|  				37694525184FC6B600CDE21F /* Security.framework in Frameworks */,
 | |
|  				37BEC4DD1948FC6A008B4286 /* WebCore.framework in Frameworks */,
 | |
| +				F33C7AC7249AD79C0018BE41 /* libwebrtc.dylib in Frameworks */,
 | |
|  			);
 | |
|  			runOnlyForDeploymentPostprocessing = 0;
 | |
|  		};
 | |
| @@ -9401,6 +9444,7 @@
 | |
|  		37C4C08318149C2A003688B9 /* Cocoa */ = {
 | |
|  			isa = PBXGroup;
 | |
|  			children = (
 | |
| +				D71A94492372290B002C4D9E /* _WKBrowserInspector.h */,
 | |
|  				1A43E826188F38E2009E4D30 /* Deprecated */,
 | |
|  				37A5E01218BBF937000A081E /* _WKActivatedElementInfo.h */,
 | |
|  				37A5E01118BBF937000A081E /* _WKActivatedElementInfo.mm */,
 | |
| @@ -10525,6 +10569,7 @@
 | |
|  				E34B110F27C46D09006D2F2E /* libWebCoreTestSupport.dylib */,
 | |
|  				DDE992F4278D06D900F60D26 /* libWebKitAdditions.a */,
 | |
|  				57A9FF15252C6AEF006A2040 /* libWTF.a */,
 | |
| +				F33C7AC6249AD79C0018BE41 /* libwebrtc.dylib */,
 | |
|  				5750F32A2032D4E500389347 /* LocalAuthentication.framework */,
 | |
|  				570DAAB0230273D200E8FC04 /* NearField.framework */,
 | |
|  				51F7BB7E274564A100C45A72 /* Security.framework */,
 | |
| @@ -11051,6 +11096,12 @@
 | |
|  			children = (
 | |
|  				9197940423DBC4BB00257892 /* InspectorBrowserAgent.cpp */,
 | |
|  				9197940323DBC4BB00257892 /* InspectorBrowserAgent.h */,
 | |
| +				F3867F0324607D2B008F0F31 /* InspectorScreencastAgent.cpp */,
 | |
| +				F3867F0424607D2B008F0F31 /* InspectorScreencastAgent.h */,
 | |
| +				F303B847249A8D3A0031DE5C /* ScreencastEncoder.cpp */,
 | |
| +				F303B848249A8D3A0031DE5C /* ScreencastEncoder.h */,
 | |
| +				F31E2DA424C76E4B004B2775 /* WebMFileWriter.cpp */,
 | |
| +				F31E2DA524C76E4C004B2775 /* WebMFileWriter.h */,
 | |
|  			);
 | |
|  			path = Agents;
 | |
|  			sourceTree = "<group>";
 | |
| @@ -11059,6 +11110,7 @@
 | |
|  			isa = PBXGroup;
 | |
|  			children = (
 | |
|  				A5D3504D1D78F0D2005124A9 /* RemoteWebInspectorUIProxyMac.mm */,
 | |
| +				F3970344249BD4CE003E1A22 /* ScreencastEncoderMac.mm */,
 | |
|  				1CA8B935127C774E00576C2B /* WebInspectorUIProxyMac.mm */,
 | |
|  				99A7ACE326012919006D57FD /* WKInspectorResourceURLSchemeHandler.h */,
 | |
|  				99A7ACE42601291A006D57FD /* WKInspectorResourceURLSchemeHandler.mm */,
 | |
| @@ -11601,6 +11653,12 @@
 | |
|  		BC032DC310F438260058C15A /* UIProcess */ = {
 | |
|  			isa = PBXGroup;
 | |
|  			children = (
 | |
| +				D76D6887238DBD80008D314B /* InspectorDialogAgent.h */,
 | |
| +				D71A944B237239FB002C4D9E /* BrowserInspectorPipe.h */,
 | |
| +				D71A943F2371F67E002C4D9E /* WebPageInspectorEmulationAgent.h */,
 | |
| +				D71A94402371F67E002C4D9E /* WebPageInspectorInputAgent.h */,
 | |
| +				D71A94392370F060002C4D9E /* RemoteInspectorPipe.h */,
 | |
| +				D71A94332370E07A002C4D9E /* InspectorPlaywrightAgentClient.h */,
 | |
|  				BC032DC410F4387C0058C15A /* API */,
 | |
|  				512F588D12A8836F00629530 /* Authentication */,
 | |
|  				9955A6E81C79809000EB6A93 /* Automation */,
 | |
| @@ -11912,6 +11970,7 @@
 | |
|  		BC0C376610F807660076D7CB /* C */ = {
 | |
|  			isa = PBXGroup;
 | |
|  			children = (
 | |
| +				D71A942C2370DF81002C4D9E /* WKBrowserInspector.h */,
 | |
|  				5123CF18133D25E60056F800 /* cg */,
 | |
|  				6EE849C41368D9040038D481 /* mac */,
 | |
|  				BCB63477116BF10600603215 /* WebKit2_C.h */,
 | |
| @@ -12502,6 +12561,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 */,
 | |
|  				07EF07592745A8160066EA04 /* DisplayCaptureSessionManager.h */,
 | |
| @@ -13721,6 +13785,7 @@
 | |
|  				99788ACB1F421DDA00C08000 /* _WKAutomationSessionConfiguration.h in Headers */,
 | |
|  				990D28AC1C6420CF00986977 /* _WKAutomationSessionDelegate.h in Headers */,
 | |
|  				990D28B11C65208D00986977 /* _WKAutomationSessionInternal.h in Headers */,
 | |
| +				D71A944A2372290B002C4D9E /* _WKBrowserInspector.h in Headers */,
 | |
|  				5C4609E7224317B4009943C2 /* _WKContentRuleListAction.h in Headers */,
 | |
|  				5C4609E8224317BB009943C2 /* _WKContentRuleListActionInternal.h in Headers */,
 | |
|  				1A5704F81BE01FF400874AF1 /* _WKContextMenuElementInfo.h in Headers */,
 | |
| @@ -14188,6 +14253,7 @@
 | |
|  				1A14F8E21D74C834006CBEC6 /* FrameInfoData.h in Headers */,
 | |
|  				1AE00D611831792100087DD7 /* FrameLoadState.h in Headers */,
 | |
|  				5C121E842410208D00486F9B /* FrameTreeNodeData.h in Headers */,
 | |
| +				F303B849249A8D640031DE5C /* ScreencastEncoder.h in Headers */,
 | |
|  				2D4AF0892044C3C4006C8817 /* FrontBoardServicesSPI.h in Headers */,
 | |
|  				CD78E1151DB7D7ED0014A2DE /* FullscreenClient.h in Headers */,
 | |
|  				CD19D2EA2046406F0017074A /* FullscreenTouchSecheuristic.h in Headers */,
 | |
| @@ -14202,6 +14268,7 @@
 | |
|  				2DA944A41884E4F000ED86DB /* GestureTypes.h in Headers */,
 | |
|  				4614F13225DED875007006E7 /* GPUProcessConnectionParameters.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 */,
 | |
| @@ -14360,6 +14427,7 @@
 | |
|  				413075AC1DE85F370039EC69 /* NetworkRTCMonitor.h in Headers */,
 | |
|  				41DC45961E3D6E2200B11F51 /* NetworkRTCProvider.h in Headers */,
 | |
|  				5C20CBA01BB1ECD800895BB1 /* NetworkSession.h in Headers */,
 | |
| +				D71A94422371F67E002C4D9E /* WebPageInspectorEmulationAgent.h in Headers */,
 | |
|  				532159551DBAE7290054AA3C /* NetworkSessionCocoa.h in Headers */,
 | |
|  				417915B92257046F00D6F97E /* NetworkSocketChannel.h in Headers */,
 | |
|  				93085DE026E5BCFD000EC6A7 /* NetworkStorageManager.h in Headers */,
 | |
| @@ -14425,6 +14493,7 @@
 | |
|  				93E05E40282CD560000B69EB /* ProcessStateMonitor.h in Headers */,
 | |
|  				463FD4821EB94EC000A2982C /* ProcessTerminationReason.h in Headers */,
 | |
|  				86E67A251910B9D100004AB7 /* ProcessThrottler.h in Headers */,
 | |
| +				D71A944C237239FB002C4D9E /* BrowserInspectorPipe.h in Headers */,
 | |
|  				83048AE61ACA45DC0082C832 /* ProcessThrottlerClient.h in Headers */,
 | |
|  				2D279E1926955768004B3EEB /* PrototypeToolsSPI.h in Headers */,
 | |
|  				517B5F81275E97B6002DC22D /* PushAppBundle.h in Headers */,
 | |
| @@ -14456,6 +14525,7 @@
 | |
|  				CDAC20CA23FC2F750021DEE3 /* RemoteCDMInstanceSession.h in Headers */,
 | |
|  				CDAC20C923FC2F750021DEE3 /* RemoteCDMInstanceSessionIdentifier.h in Headers */,
 | |
|  				F451C0FE2703B263002BA03B /* RemoteDisplayListRecorderProxy.h in Headers */,
 | |
| +				D71A943A2370F061002C4D9E /* RemoteInspectorPipe.h in Headers */,
 | |
|  				2D47B56D1810714E003A3AEE /* RemoteLayerBackingStore.h in Headers */,
 | |
|  				2DDF731518E95060004F5A66 /* RemoteLayerBackingStoreCollection.h in Headers */,
 | |
|  				1AB16AEA164B3A8800290D62 /* RemoteLayerTreeContext.h in Headers */,
 | |
| @@ -14871,6 +14941,7 @@
 | |
|  				A543E30D215C8A9000279CD9 /* WebPageInspectorTargetController.h in Headers */,
 | |
|  				A543E307215AD13700279CD9 /* WebPageInspectorTargetFrontendChannel.h in Headers */,
 | |
|  				C0CE72A11247E71D00BC0EC4 /* WebPageMessages.h in Headers */,
 | |
| +				F3867F0A24607D4E008F0F31 /* InspectorScreencastAgent.h in Headers */,
 | |
|  				2D5C9D0619C81D8F00B3C5C1 /* WebPageOverlay.h in Headers */,
 | |
|  				46C392292316EC4D008EED9B /* WebPageProxyIdentifier.h in Headers */,
 | |
|  				BCBD3915125BB1A800D2C29F /* WebPageProxyMessages.h in Headers */,
 | |
| @@ -15052,6 +15123,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 */,
 | |
| @@ -15106,6 +15178,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 */,
 | |
| @@ -15264,6 +15337,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 */,
 | |
| @@ -16814,6 +16888,8 @@
 | |
|  				51E9049727BCB3D900929E7E /* ICAppBundle.mm in Sources */,
 | |
|  				2749F6442146561B008380BF /* InjectedBundleNodeHandle.cpp in Sources */,
 | |
|  				2749F6452146561E008380BF /* InjectedBundleRangeHandle.cpp in Sources */,
 | |
| +				D7EB04E72372A73B00F744CE /* InspectorPlaywrightAgentClientMac.mm in Sources */,
 | |
| +				D79902B2236E9404005D6F7E /* InspectorTargetProxyMac.mm in Sources */,
 | |
|  				C14D37FE24ACE086007FF014 /* LaunchServicesDatabaseManager.mm in Sources */,
 | |
|  				C1710CF724AA643200D7C112 /* LaunchServicesDatabaseObserver.mm in Sources */,
 | |
|  				2984F588164BA095004BC0C6 /* LegacyCustomProtocolManagerMessageReceiver.cpp in Sources */,
 | |
| @@ -17149,6 +17225,8 @@
 | |
|  				E3816B3D27E2463A005EAFC0 /* WebMockContentFilterManager.cpp in Sources */,
 | |
|  				31BA924D148831260062EDB5 /* WebNotificationManagerMessageReceiver.cpp in Sources */,
 | |
|  				2DF6FE52212E110900469030 /* WebPage.cpp in Sources */,
 | |
| +				D79902B1236E9404005D6F7E /* WebPageInspectorEmulationAgentMac.mm in Sources */,
 | |
| +				D79902B3236E9404005D6F7E /* WebPageInspectorInputAgentMac.mm in Sources */,
 | |
|  				C0CE72A01247E71D00BC0EC4 /* WebPageMessageReceiver.cpp in Sources */,
 | |
|  				BCBD3914125BB1A800D2C29F /* WebPageProxyMessageReceiver.cpp in Sources */,
 | |
|  				7CE9CE101FA0767A000177DE /* WebPageUpdatePreferences.cpp in Sources */,
 | |
| diff --git a/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp b/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp
 | |
| index 3803681aa73b7b97072341be579d520b93c6c3ac..69b5e9f5da2d950c02cf79895514bdda44db48e6 100644
 | |
| --- a/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp
 | |
| +++ b/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp
 | |
| @@ -232,6 +232,11 @@ void WebLoaderStrategy::scheduleLoad(ResourceLoader& resourceLoader, CachedResou
 | |
|      }
 | |
|  #endif
 | |
|  
 | |
| +    if (m_emulateOfflineState) {
 | |
| +        scheduleInternallyFailedLoad(resourceLoader);
 | |
| +        return;
 | |
| +    }
 | |
| +
 | |
|  #if ENABLE(PDFJS)
 | |
|      if (tryLoadingUsingPDFJSHandler(resourceLoader, trackingParameters))
 | |
|          return;
 | |
| @@ -314,7 +319,8 @@ static void addParametersShared(const Frame* frame, NetworkResourceLoadParameter
 | |
|      }
 | |
|  }
 | |
|  
 | |
| -void WebLoaderStrategy::scheduleLoadFromNetworkProcess(ResourceLoader& resourceLoader, const ResourceRequest& request, const WebResourceLoader::TrackingParameters& trackingParameters, bool shouldClearReferrerOnHTTPSToHTTPRedirect, Seconds maximumBufferingTime)
 | |
| +// static
 | |
| +bool WebLoaderStrategy::fillParametersForNetworkProcessLoad(ResourceLoader& resourceLoader, const ResourceRequest& request, const WebResourceLoader::TrackingParameters& trackingParameters, bool shouldClearReferrerOnHTTPSToHTTPRedirect, Seconds maximumBufferingTime, NetworkResourceLoadParameters& loadParameters)
 | |
|  {
 | |
|      auto identifier = resourceLoader.identifier();
 | |
|      ASSERT(identifier);
 | |
| @@ -330,7 +336,7 @@ void WebLoaderStrategy::scheduleLoadFromNetworkProcess(ResourceLoader& resourceL
 | |
|              RunLoop::main().dispatch([resourceLoader = Ref { resourceLoader }, error = blockedError(request)] {
 | |
|                  resourceLoader->didFail(error);
 | |
|              });
 | |
| -            return;
 | |
| +            return false;
 | |
|          }
 | |
|      }
 | |
|  
 | |
| @@ -340,7 +346,6 @@ void WebLoaderStrategy::scheduleLoadFromNetworkProcess(ResourceLoader& resourceL
 | |
|  
 | |
|      LOG(NetworkScheduling, "(WebProcess) WebLoaderStrategy::scheduleLoad, url '%s' will be scheduled with the NetworkProcess with priority %d, storedCredentialsPolicy %i", resourceLoader.url().string().latin1().data(), static_cast<int>(resourceLoader.request().priority()), (int)storedCredentialsPolicy);
 | |
|  
 | |
| -    NetworkResourceLoadParameters loadParameters;
 | |
|      loadParameters.identifier = identifier;
 | |
|      loadParameters.webPageProxyID = trackingParameters.webPageProxyID;
 | |
|      loadParameters.webPageID = trackingParameters.pageID;
 | |
| @@ -425,14 +430,11 @@ void WebLoaderStrategy::scheduleLoadFromNetworkProcess(ResourceLoader& resourceL
 | |
|  
 | |
|      if (loadParameters.options.mode != FetchOptions::Mode::Navigate) {
 | |
|          ASSERT(loadParameters.sourceOrigin);
 | |
| -        if (!loadParameters.sourceOrigin) {
 | |
| -            WEBLOADERSTRATEGY_RELEASE_LOG_ERROR("scheduleLoad: no sourceOrigin (priority=%d)", static_cast<int>(resourceLoader.request().priority()));
 | |
| -            scheduleInternallyFailedLoad(resourceLoader);
 | |
| -            return;
 | |
| -        }
 | |
| +        if (!loadParameters.sourceOrigin)
 | |
| +            return false;
 | |
|      }
 | |
|  
 | |
| -    loadParameters.shouldRestrictHTTPResponseAccess = shouldPerformSecurityChecks();
 | |
| +    loadParameters.shouldRestrictHTTPResponseAccess = RuntimeEnabledFeatures::sharedFeatures().restrictedHTTPResponseAccess();
 | |
|  
 | |
|      loadParameters.isMainFrameNavigation = resourceLoader.frame() && resourceLoader.frame()->isMainFrame() && resourceLoader.options().mode == FetchOptions::Mode::Navigate;
 | |
|      if (loadParameters.isMainFrameNavigation && document)
 | |
| @@ -464,6 +466,17 @@ void WebLoaderStrategy::scheduleLoadFromNetworkProcess(ResourceLoader& resourceL
 | |
|      }
 | |
|  
 | |
|      ASSERT((loadParameters.webPageID && loadParameters.webFrameID) || loadParameters.clientCredentialPolicy == ClientCredentialPolicy::CannotAskClientForCredentials);
 | |
| +    return true;
 | |
| +}
 | |
| +
 | |
| +void WebLoaderStrategy::scheduleLoadFromNetworkProcess(ResourceLoader& resourceLoader, const ResourceRequest& request, const WebResourceLoader::TrackingParameters& trackingParameters, bool shouldClearReferrerOnHTTPSToHTTPRedirect, Seconds maximumBufferingTime)
 | |
| +{
 | |
| +    NetworkResourceLoadParameters loadParameters;
 | |
| +    if (!fillParametersForNetworkProcessLoad(resourceLoader, request, trackingParameters, shouldClearReferrerOnHTTPSToHTTPRedirect, maximumBufferingTime, loadParameters)) {
 | |
| +        WEBLOADERSTRATEGY_RELEASE_LOG_ERROR("scheduleLoad: no sourceOrigin (priority=%d)", static_cast<int>(resourceLoader.request().priority()));
 | |
| +        scheduleInternallyFailedLoad(resourceLoader);
 | |
| +        return;
 | |
| +    }
 | |
|  
 | |
|      std::optional<NetworkResourceLoadIdentifier> existingNetworkResourceLoadIdentifierToResume;
 | |
|      if (loadParameters.isMainFrameNavigation)
 | |
| @@ -478,7 +491,7 @@ void WebLoaderStrategy::scheduleLoadFromNetworkProcess(ResourceLoader& resourceL
 | |
|      }
 | |
|  
 | |
|      auto loader = WebResourceLoader::create(resourceLoader, trackingParameters);
 | |
| -    m_webResourceLoaders.set(identifier, WTFMove(loader));
 | |
| +    m_webResourceLoaders.set(resourceLoader.identifier(), WTFMove(loader));
 | |
|  }
 | |
|  
 | |
|  void WebLoaderStrategy::scheduleInternallyFailedLoad(WebCore::ResourceLoader& resourceLoader)
 | |
| @@ -888,7 +901,7 @@ void WebLoaderStrategy::didFinishPreconnection(WebCore::ResourceLoaderIdentifier
 | |
|  
 | |
|  bool WebLoaderStrategy::isOnLine() const
 | |
|  {
 | |
| -    return m_isOnLine;
 | |
| +    return m_emulateOfflineState ? false : m_isOnLine;
 | |
|  }
 | |
|  
 | |
|  void WebLoaderStrategy::addOnlineStateChangeListener(Function<void(bool)>&& listener)
 | |
| @@ -908,6 +921,11 @@ void WebLoaderStrategy::isResourceLoadFinished(CachedResource& resource, Complet
 | |
|  
 | |
|  void WebLoaderStrategy::setOnLineState(bool isOnLine)
 | |
|  {
 | |
| +    if (m_emulateOfflineState) {
 | |
| +        m_isOnLine = isOnLine;
 | |
| +        return;
 | |
| +    }
 | |
| +
 | |
|      if (m_isOnLine == isOnLine)
 | |
|          return;
 | |
|  
 | |
| @@ -916,6 +934,12 @@ void WebLoaderStrategy::setOnLineState(bool isOnLine)
 | |
|          listener(isOnLine);
 | |
|  }
 | |
|  
 | |
| +void WebLoaderStrategy::setEmulateOfflineState(bool offline) {
 | |
| +    m_emulateOfflineState = offline;
 | |
| +    for (auto& listener : m_onlineStateChangeListeners)
 | |
| +        listener(offline ? false : m_isOnLine);
 | |
| +}
 | |
| +
 | |
|  void WebLoaderStrategy::setCaptureExtraNetworkLoadMetricsEnabled(bool enabled)
 | |
|  {
 | |
|      WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::NetworkConnectionToWebProcess::SetCaptureExtraNetworkLoadMetricsEnabled(enabled), 0);
 | |
| diff --git a/Source/WebKit/WebProcess/Network/WebLoaderStrategy.h b/Source/WebKit/WebProcess/Network/WebLoaderStrategy.h
 | |
| index cfa563b7d34056c9375d4382ff42d55dab3daa14..baf0bdc4f441721d085ff86bd152a7ccb638d21c 100644
 | |
| --- a/Source/WebKit/WebProcess/Network/WebLoaderStrategy.h
 | |
| +++ b/Source/WebKit/WebProcess/Network/WebLoaderStrategy.h
 | |
| @@ -41,6 +41,7 @@ struct FetchOptions;
 | |
|  namespace WebKit {
 | |
|  
 | |
|  class NetworkProcessConnection;
 | |
| +class NetworkResourceLoadParameters;
 | |
|  class WebFrame;
 | |
|  class WebPage;
 | |
|  class WebURLSchemeTaskProxy;
 | |
| @@ -88,6 +89,9 @@ public:
 | |
|      bool isOnLine() const final;
 | |
|      void addOnlineStateChangeListener(Function<void(bool)>&&) final;
 | |
|      void setOnLineState(bool);
 | |
| +    void setEmulateOfflineState(bool) final;
 | |
| +
 | |
| +    static bool fillParametersForNetworkProcessLoad(WebCore::ResourceLoader&, const WebCore::ResourceRequest&, const WebResourceLoader::TrackingParameters&, bool shouldClearReferrerOnHTTPSToHTTPRedirect, Seconds maximumBufferingTime, NetworkResourceLoadParameters&);
 | |
|  
 | |
|      void setExistingNetworkResourceLoadIdentifierToResume(std::optional<NetworkResourceLoadIdentifier> existingNetworkResourceLoadIdentifierToResume) { m_existingNetworkResourceLoadIdentifierToResume = existingNetworkResourceLoadIdentifierToResume; }
 | |
|  
 | |
| @@ -140,6 +144,7 @@ private:
 | |
|      Vector<Function<void(bool)>> m_onlineStateChangeListeners;
 | |
|      std::optional<NetworkResourceLoadIdentifier> m_existingNetworkResourceLoadIdentifierToResume;
 | |
|      bool m_isOnLine { true };
 | |
| +    bool m_emulateOfflineState { false };
 | |
|  };
 | |
|  
 | |
|  } // namespace WebKit
 | |
| diff --git a/Source/WebKit/WebProcess/Network/WebResourceLoader.cpp b/Source/WebKit/WebProcess/Network/WebResourceLoader.cpp
 | |
| index 0b6804754decb67ec52996d7ac0df4eb627d6d57..bc70fec1cef6f3df5927fabb68b9c71d8882e105 100644
 | |
| --- a/Source/WebKit/WebProcess/Network/WebResourceLoader.cpp
 | |
| +++ b/Source/WebKit/WebProcess/Network/WebResourceLoader.cpp
 | |
| @@ -195,9 +195,6 @@ void WebResourceLoader::didReceiveResponse(ResourceResponse&& response, PrivateR
 | |
|              }
 | |
|  
 | |
|              m_coreLoader->didReceiveResponse(inspectorResponse, [this, protectedThis = WTFMove(protectedThis), interceptedRequestIdentifier, policyDecisionCompletionHandler = WTFMove(policyDecisionCompletionHandler), overrideData = WTFMove(overrideData)]() mutable {
 | |
| -                if (policyDecisionCompletionHandler)
 | |
| -                    policyDecisionCompletionHandler();
 | |
| -
 | |
|                  if (!m_coreLoader || !m_coreLoader->identifier()) {
 | |
|                      m_interceptController.continueResponse(interceptedRequestIdentifier);
 | |
|                      return;
 | |
| @@ -215,6 +212,8 @@ void WebResourceLoader::didReceiveResponse(ResourceResponse&& response, PrivateR
 | |
|                  }
 | |
|              });
 | |
|          });
 | |
| +        if (policyDecisionCompletionHandler)
 | |
| +          policyDecisionCompletionHandler();
 | |
|          return;
 | |
|      }
 | |
|  
 | |
| diff --git a/Source/WebKit/WebProcess/Notifications/NotificationPermissionRequestManager.cpp b/Source/WebKit/WebProcess/Notifications/NotificationPermissionRequestManager.cpp
 | |
| index e00c722c2be5d505243d45f46001839d4eb8a977..33c0832cde6c292230397a13e70d90fb5984302d 100644
 | |
| --- a/Source/WebKit/WebProcess/Notifications/NotificationPermissionRequestManager.cpp
 | |
| +++ b/Source/WebKit/WebProcess/Notifications/NotificationPermissionRequestManager.cpp
 | |
| @@ -88,7 +88,7 @@ void NotificationPermissionRequestManager::startRequest(const SecurityOriginData
 | |
|  
 | |
|      m_page->sendWithAsyncReply(Messages::WebPageProxy::RequestNotificationPermission(securityOrigin.toString()), [this, protectedThis = Ref { *this }, securityOrigin, permissionHandler = WTFMove(permissionHandler)](bool allowed) mutable {
 | |
|  
 | |
| -        auto innerPermissionHandler = [this, protectedThis = Ref { *this }, securityOrigin, permissionHandler = WTFMove(permissionHandler)] (bool allowed) mutable {
 | |
| +        auto innerPermissionHandler = [this, protectedThis, securityOrigin, permissionHandler = WTFMove(permissionHandler)] (bool allowed) mutable {
 | |
|              WebProcess::singleton().supplement<WebNotificationManager>()->didUpdateNotificationDecision(securityOrigin.toString(), allowed);
 | |
|  
 | |
|              auto permissionHandlers = m_requestsPerOrigin.take(securityOrigin);
 | |
| diff --git a/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp b/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp
 | |
| index 227a0cf82d4a12fc70bea861d490e3eb7bdc9277..88f5973dc20b4da6119568ad977eba11241aa02c 100644
 | |
| --- a/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp
 | |
| +++ b/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp
 | |
| @@ -415,6 +415,8 @@ void WebChromeClient::setResizable(bool resizable)
 | |
|  
 | |
|  void WebChromeClient::addMessageToConsole(MessageSource source, MessageLevel level, const String& message, unsigned lineNumber, unsigned columnNumber, const String& sourceID)
 | |
|  {
 | |
| +    if (level == MessageLevel::Error)
 | |
| +        m_page.send(Messages::WebPageProxy::LogToStderr(message));
 | |
|      // Notify the bundle client.
 | |
|      m_page.injectedBundleUIClient().willAddMessageToConsole(&m_page, source, level, message, lineNumber, columnNumber, sourceID);
 | |
|  }
 | |
| @@ -843,6 +845,13 @@ std::unique_ptr<DateTimeChooser> WebChromeClient::createDateTimeChooser(DateTime
 | |
|  
 | |
|  #endif
 | |
|  
 | |
| +#if ENABLE(ORIENTATION_EVENTS) && !PLATFORM(IOS_FAMILY)
 | |
| +int WebChromeClient::deviceOrientation() const {
 | |
| +    // Only overrides are supported for non-iOS platforms.
 | |
| +    return 0;
 | |
| +}
 | |
| +#endif
 | |
| +
 | |
|  void WebChromeClient::runOpenPanel(Frame& frame, FileChooser& fileChooser)
 | |
|  {
 | |
|      if (m_page.activeOpenPanelResultListener())
 | |
| diff --git a/Source/WebKit/WebProcess/WebCoreSupport/WebDragClient.cpp b/Source/WebKit/WebProcess/WebCoreSupport/WebDragClient.cpp
 | |
| index 2eb0886f13ed035a53b8eaa60605de4dfe53fbe3..c46393209cb4f80704bbc9268fad4371347d5b30 100644
 | |
| --- a/Source/WebKit/WebProcess/WebCoreSupport/WebDragClient.cpp
 | |
| +++ b/Source/WebKit/WebProcess/WebCoreSupport/WebDragClient.cpp
 | |
| @@ -29,6 +29,13 @@
 | |
|  #if ENABLE(DRAG_SUPPORT)
 | |
|  
 | |
|  #include "WebPage.h"
 | |
| +#include <WebCore/DataTransfer.h>
 | |
| +#include <WebCore/Pasteboard.h>
 | |
| +#include "ShareableBitmap.h"
 | |
| +
 | |
| +#if PLATFORM(WPE)
 | |
| +#include "ArgumentCodersWPE.h"
 | |
| +#endif
 | |
|  
 | |
|  namespace WebKit {
 | |
|  using namespace WebCore;
 | |
| @@ -50,7 +57,7 @@ OptionSet<DragSourceAction> WebDragClient::dragSourceActionMaskForPoint(const In
 | |
|      return m_page->allowedDragSourceActions();
 | |
|  }
 | |
|  
 | |
| -#if !PLATFORM(COCOA) && !PLATFORM(GTK)
 | |
| +#if !PLATFORM(COCOA) && !PLATFORM(GTK) && !PLATFORM(WPE) && !PLATFORM(WIN)
 | |
|  void WebDragClient::startDrag(DragItem, DataTransfer&, Frame&)
 | |
|  {
 | |
|  }
 | |
| diff --git a/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp b/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp
 | |
| index 1592d5cdb478aa77c5f4991dc79b11301851c5c0..e91a8e3ef026b34ca57fb2a0a529f51e9b8bfc21 100644
 | |
| --- a/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp
 | |
| +++ b/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp
 | |
| @@ -1612,13 +1612,6 @@ void WebFrameLoaderClient::transitionToCommittedForNewPage()
 | |
|      if (webPage->scrollPinningBehavior() != DoNotPin)
 | |
|          view->setScrollPinningBehavior(webPage->scrollPinningBehavior());
 | |
|  
 | |
| -#if USE(COORDINATED_GRAPHICS)
 | |
| -    if (shouldUseFixedLayout) {
 | |
| -        view->setDelegatesScrolling(shouldUseFixedLayout);
 | |
| -        view->setPaintsEntireContents(shouldUseFixedLayout);
 | |
| -        return;
 | |
| -    }
 | |
| -#endif
 | |
|  }
 | |
|  
 | |
|  void WebFrameLoaderClient::didRestoreFromBackForwardCache()
 | |
| diff --git a/Source/WebKit/WebProcess/WebCoreSupport/mac/WebDragClientMac.mm b/Source/WebKit/WebProcess/WebCoreSupport/mac/WebDragClientMac.mm
 | |
| index b14358c2cc29604a50265281c8d215246ed820a3..8bd7365cba12adb5c5a59ea2f3bbc526fbc44ee8 100644
 | |
| --- a/Source/WebKit/WebProcess/WebCoreSupport/mac/WebDragClientMac.mm
 | |
| +++ b/Source/WebKit/WebProcess/WebCoreSupport/mac/WebDragClientMac.mm
 | |
| @@ -127,7 +127,8 @@ static WebCore::CachedImage* cachedImage(Element& element)
 | |
|  void WebDragClient::declareAndWriteDragImage(const String& pasteboardName, Element& element, const URL& url, const String& label, Frame*)
 | |
|  {
 | |
|      ALLOW_DEPRECATED_DECLARATIONS_BEGIN
 | |
| -    ASSERT(pasteboardName == String(NSDragPboard));
 | |
| +    if (pasteboardName != String(NSDragPboard))
 | |
| +        return;
 | |
|      ALLOW_DEPRECATED_DECLARATIONS_END
 | |
|  
 | |
|      WebCore::CachedImage* image = cachedImage(element);
 | |
| diff --git a/Source/WebKit/WebProcess/WebCoreSupport/win/WebDragClientWin.cpp b/Source/WebKit/WebProcess/WebCoreSupport/win/WebDragClientWin.cpp
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..2606914d22e85affd9b2f71c361c9db3a14da4f3
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/WebProcess/WebCoreSupport/win/WebDragClientWin.cpp
 | |
| @@ -0,0 +1,58 @@
 | |
| +/*
 | |
| + * Copyright (C) 2011 Igalia S.L.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 | |
| + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 | |
| + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 | |
| + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 | |
| + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 | |
| + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 | |
| + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 | |
| + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 | |
| + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 | |
| + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 | |
| + * THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#include "config.h"
 | |
| +#include "WebDragClient.h"
 | |
| +
 | |
| +#if ENABLE(DRAG_SUPPORT)
 | |
| +
 | |
| +//#include "ArgumentCodersWPE.h"
 | |
| +#include "ShareableBitmap.h"
 | |
| +#include "WebPage.h"
 | |
| +#include "WebPageProxyMessages.h"
 | |
| +#include <WebCore/DataTransfer.h>
 | |
| +#include <WebCore/DragData.h>
 | |
| +#include <WebCore/Pasteboard.h>
 | |
| +#include <wtf/win/GDIObject.h>
 | |
| +#include <WebCore/Frame.h>
 | |
| +
 | |
| +//#include <WebCore/SelectionData.h>
 | |
| +
 | |
| +namespace WebKit {
 | |
| +using namespace WebCore;
 | |
| +
 | |
| +void WebDragClient::didConcludeEditDrag()
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +void WebDragClient::startDrag(DragItem, DataTransfer& dataTransfer, Frame& frame)
 | |
| +{
 | |
| +    m_page->willStartDrag();
 | |
| +    m_page->send(Messages::WebPageProxy::StartDrag(dataTransfer.pasteboard().createDragDataMap()));
 | |
| +}
 | |
| +
 | |
| +}; // namespace WebKit.
 | |
| +
 | |
| +#endif // ENABLE(DRAG_SUPPORT)
 | |
| diff --git a/Source/WebKit/WebProcess/WebCoreSupport/wpe/WebDragClientWPE.cpp b/Source/WebKit/WebProcess/WebCoreSupport/wpe/WebDragClientWPE.cpp
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..6d1dab390782a6c88d387bc94a36ecf07397902f
 | |
| --- /dev/null
 | |
| +++ b/Source/WebKit/WebProcess/WebCoreSupport/wpe/WebDragClientWPE.cpp
 | |
| @@ -0,0 +1,57 @@
 | |
| +/*
 | |
| + * Copyright (C) 2011 Igalia S.L.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 | |
| + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 | |
| + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 | |
| + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 | |
| + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 | |
| + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 | |
| + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 | |
| + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 | |
| + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 | |
| + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 | |
| + * THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#include "config.h"
 | |
| +#include "WebDragClient.h"
 | |
| +
 | |
| +#if ENABLE(DRAG_SUPPORT)
 | |
| +
 | |
| +#include "ArgumentCodersWPE.h"
 | |
| +#include "ShareableBitmap.h"
 | |
| +#include "WebPage.h"
 | |
| +#include "WebPageProxyMessages.h"
 | |
| +#include <WebCore/DataTransfer.h>
 | |
| +#include <WebCore/DragData.h>
 | |
| +#include <WebCore/Pasteboard.h>
 | |
| +#include <WebCore/SelectionData.h>
 | |
| +
 | |
| +namespace WebKit {
 | |
| +using namespace WebCore;
 | |
| +
 | |
| +void WebDragClient::didConcludeEditDrag()
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +void WebDragClient::startDrag(DragItem, DataTransfer& dataTransfer, Frame&)
 | |
| +{
 | |
| +    m_page->willStartDrag();
 | |
| +
 | |
| +    ShareableBitmap::Handle handle;
 | |
| +    m_page->send(Messages::WebPageProxy::StartDrag(dataTransfer.pasteboard().selectionData(), dataTransfer.sourceOperationMask(), handle, dataTransfer.dragLocation()));
 | |
| +}
 | |
| +
 | |
| +}; // namespace WebKit.
 | |
| +
 | |
| +#endif // ENABLE(DRAG_SUPPORT)
 | |
| diff --git a/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/DrawingAreaCoordinatedGraphics.cpp b/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/DrawingAreaCoordinatedGraphics.cpp
 | |
| index 6bc7442b28ed5ee475d603975bee65cf32df39f4..21fb325d26bfe3819c62e9ad181c6c02c0490fb4 100644
 | |
| --- a/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/DrawingAreaCoordinatedGraphics.cpp
 | |
| +++ b/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/DrawingAreaCoordinatedGraphics.cpp
 | |
| @@ -38,6 +38,7 @@
 | |
|  #include <WebCore/Frame.h>
 | |
|  #include <WebCore/FrameView.h>
 | |
|  #include <WebCore/GraphicsContext.h>
 | |
| +#include <WebCore/InspectorController.h>
 | |
|  #include <WebCore/Page.h>
 | |
|  #include <WebCore/PageOverlayController.h>
 | |
|  #include <WebCore/Region.h>
 | |
| @@ -116,6 +117,16 @@ void DrawingAreaCoordinatedGraphics::scroll(const IntRect& scrollRect, const Int
 | |
|          ASSERT(m_scrollRect.isEmpty());
 | |
|          ASSERT(m_scrollOffset.isEmpty());
 | |
|          ASSERT(m_dirtyRegion.isEmpty());
 | |
| +// Playwright begin
 | |
| +#if !PLATFORM(WIN)
 | |
| +        if (m_webPage.mainFrameView() && m_webPage.mainFrameView()->useFixedLayout()) {
 | |
| +            IntRect visibleRect = IntRect(m_layerTreeHost->viewportController().visibleContentsRect());
 | |
| +            visibleRect.move(-scrollDelta.width(), -scrollDelta.height());
 | |
| +            m_layerTreeHost->scrollNonCompositedContents(visibleRect);
 | |
| +            return;
 | |
| +        }
 | |
| +#endif
 | |
| +// Playwright end
 | |
|          m_layerTreeHost->scrollNonCompositedContents(scrollRect);
 | |
|          return;
 | |
|      }
 | |
| @@ -248,6 +259,7 @@ void DrawingAreaCoordinatedGraphics::updatePreferences(const WebPreferencesStore
 | |
|          settings.setAcceleratedCompositingEnabled(false);
 | |
|      }
 | |
|  #endif
 | |
| +
 | |
|      settings.setForceCompositingMode(store.getBoolValueForKey(WebPreferencesKey::forceCompositingModeKey()));
 | |
|      // Fixed position elements need to be composited and create stacking contexts
 | |
|      // in order to be scrolled by the ScrollingCoordinator.
 | |
| @@ -670,6 +682,11 @@ void DrawingAreaCoordinatedGraphics::enterAcceleratedCompositingMode(GraphicsLay
 | |
|      m_scrollOffset = IntSize();
 | |
|      m_displayTimer.stop();
 | |
|      m_isWaitingForDidUpdate = false;
 | |
| +// Playwright begin
 | |
| +#if PLATFORM(WIN)
 | |
| +    didChangeAcceleratedCompositingMode(true);
 | |
| +#endif
 | |
| +// Playwright end
 | |
|  }
 | |
|  
 | |
|  void DrawingAreaCoordinatedGraphics::exitAcceleratedCompositingMode()
 | |
| @@ -719,6 +736,11 @@ void DrawingAreaCoordinatedGraphics::exitAcceleratedCompositingMode()
 | |
|          // UI process, we still need to let it know about the new contents, so send an Update message.
 | |
|          send(Messages::DrawingAreaProxy::Update(m_backingStoreStateID, updateInfo));
 | |
|      }
 | |
| +// Playwright begin
 | |
| +#if PLATFORM(WIN)
 | |
| +    didChangeAcceleratedCompositingMode(false);
 | |
| +#endif
 | |
| +// Playwright end
 | |
|  }
 | |
|  
 | |
|  void DrawingAreaCoordinatedGraphics::scheduleDisplay()
 | |
| diff --git a/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/LayerTreeHost.cpp b/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/LayerTreeHost.cpp
 | |
| index 60d596ec08c0b3550a328ae715e180ae3669676b..be272bed2f5cf15d3b5b195ab5e7a90a9b33db34 100644
 | |
| --- a/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/LayerTreeHost.cpp
 | |
| +++ b/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/LayerTreeHost.cpp
 | |
| @@ -183,8 +183,16 @@ void LayerTreeHost::setViewOverlayRootLayer(GraphicsLayer* viewOverlayRootLayer)
 | |
|  void LayerTreeHost::scrollNonCompositedContents(const IntRect& rect)
 | |
|  {
 | |
|      auto* frameView = m_webPage.mainFrameView();
 | |
| +
 | |
| +// Playwright begin
 | |
| +#if PLATFORM(WIN)
 | |
|      if (!frameView || !frameView->delegatesScrolling())
 | |
| +        return
 | |
| +#else
 | |
| +    if (!frameView)
 | |
|          return;
 | |
| +#endif
 | |
| +// Playwright end
 | |
|  
 | |
|      m_viewportController.didScroll(rect.location());
 | |
|      if (m_isDiscardable)
 | |
| @@ -318,6 +326,10 @@ void LayerTreeHost::didChangeViewport()
 | |
|  
 | |
|          if (!view->useFixedLayout())
 | |
|              view->notifyScrollPositionChanged(m_lastScrollPosition);
 | |
| +// Playwright begin
 | |
| +        else
 | |
| +            m_viewportController.didScroll(m_lastScrollPosition);
 | |
| +// Playwright end
 | |
|      }
 | |
|  
 | |
|      if (m_lastPageScaleFactor != pageScale) {
 | |
| diff --git a/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/LayerTreeHost.h b/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/LayerTreeHost.h
 | |
| index 293c2e5de26e3612217e7f44ea43dfd589cc657e..659558a1e666cd099800c5291d06acbe5ac101e3 100644
 | |
| --- a/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/LayerTreeHost.h
 | |
| +++ b/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/LayerTreeHost.h
 | |
| @@ -105,6 +105,13 @@ public:
 | |
|      void adjustTransientZoom(double, WebCore::FloatPoint);
 | |
|      void commitTransientZoom(double, WebCore::FloatPoint);
 | |
|  #endif
 | |
| +
 | |
| +// Playwright begin
 | |
| +#if USE(COORDINATED_GRAPHICS)
 | |
| +    const SimpleViewportController& viewportController() const { return m_viewportController; }
 | |
| +#endif
 | |
| +// Playwright end
 | |
| +
 | |
|  private:
 | |
|  #if USE(COORDINATED_GRAPHICS)
 | |
|      void layerFlushTimerFired();
 | |
| diff --git a/Source/WebKit/WebProcess/WebPage/DrawingArea.cpp b/Source/WebKit/WebProcess/WebPage/DrawingArea.cpp
 | |
| index db2e5d686e6ffff8f5299903c4d42fb3a64607ac..8a4d23bdebe6a7b2f7dea87517de8f0cea62093d 100644
 | |
| --- a/Source/WebKit/WebProcess/WebPage/DrawingArea.cpp
 | |
| +++ b/Source/WebKit/WebProcess/WebPage/DrawingArea.cpp
 | |
| @@ -27,6 +27,7 @@
 | |
|  #include "DrawingArea.h"
 | |
|  
 | |
|  #include "DrawingAreaMessages.h"
 | |
| +#include "DrawingAreaProxyMessages.h"
 | |
|  #include "WebPage.h"
 | |
|  #include "WebPageCreationParameters.h"
 | |
|  #include "WebProcess.h"
 | |
| @@ -94,6 +95,13 @@ void DrawingArea::tryMarkLayersVolatile(CompletionHandler<void(bool)>&& completi
 | |
|      completionFunction(true);
 | |
|  }
 | |
|  
 | |
| +#if PLATFORM(WIN)
 | |
| +void DrawingArea::didChangeAcceleratedCompositingMode(bool enabled)
 | |
| +{
 | |
| +    send(Messages::DrawingAreaProxy::DidChangeAcceleratedCompositingMode(enabled));
 | |
| +}
 | |
| +#endif
 | |
| +
 | |
|  void DrawingArea::removeMessageReceiverIfNeeded()
 | |
|  {
 | |
|      if (m_hasRemovedMessageReceiver)
 | |
| diff --git a/Source/WebKit/WebProcess/WebPage/DrawingArea.h b/Source/WebKit/WebProcess/WebPage/DrawingArea.h
 | |
| index 3f6b9304dd08fbcc1fba7086163c753f0ad50785..165f22b4c3043cff7c9fbfb70fdc56f141b6bd6c 100644
 | |
| --- a/Source/WebKit/WebProcess/WebPage/DrawingArea.h
 | |
| +++ b/Source/WebKit/WebProcess/WebPage/DrawingArea.h
 | |
| @@ -148,6 +148,9 @@ public:
 | |
|      virtual void didChangeViewportAttributes(WebCore::ViewportAttributes&&) = 0;
 | |
|      virtual void deviceOrPageScaleFactorChanged() = 0;
 | |
|  #endif
 | |
| +#if PLATFORM(WIN)
 | |
| +    void didChangeAcceleratedCompositingMode(bool enabled);
 | |
| +#endif
 | |
|  
 | |
|      virtual void adoptLayersFromDrawingArea(DrawingArea&) { }
 | |
|      virtual void adoptDisplayRefreshMonitorsFromDrawingArea(DrawingArea&) { }
 | |
| diff --git a/Source/WebKit/WebProcess/WebPage/WebCookieJar.cpp b/Source/WebKit/WebProcess/WebPage/WebCookieJar.cpp
 | |
| index 1c0857116c24ebfc0fd30360431f97c52e39ab0f..5e608356e81976de094729d6b4b4674acb633675 100644
 | |
| --- a/Source/WebKit/WebProcess/WebPage/WebCookieJar.cpp
 | |
| +++ b/Source/WebKit/WebProcess/WebPage/WebCookieJar.cpp
 | |
| @@ -38,6 +38,7 @@
 | |
|  #include <WebCore/FrameDestructionObserverInlines.h>
 | |
|  #include <WebCore/FrameLoader.h>
 | |
|  #include <WebCore/FrameLoaderClient.h>
 | |
| +#include <WebCore/ResourceLoader.h>
 | |
|  #include <WebCore/Settings.h>
 | |
|  #include <WebCore/StorageSessionProvider.h>
 | |
|  
 | |
| @@ -256,4 +257,10 @@ void WebCookieJar::deleteCookie(const WebCore::Document& document, const URL& ur
 | |
|      WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::NetworkConnectionToWebProcess::DeleteCookie(url, cookieName), 0);
 | |
|  }
 | |
|  
 | |
| +void WebCookieJar::setCookieFromResponse(ResourceLoader& loader, const String& setCookieValue)
 | |
| +{
 | |
| +    const auto& request = loader.request();
 | |
| +    WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::NetworkConnectionToWebProcess::SetCookieFromResponse(request.firstPartyForCookies(), SameSiteInfo::create(request), request.url(), setCookieValue), 0);
 | |
| +}
 | |
| +
 | |
|  } // namespace WebKit
 | |
| diff --git a/Source/WebKit/WebProcess/WebPage/WebCookieJar.h b/Source/WebKit/WebProcess/WebPage/WebCookieJar.h
 | |
| index bc78502b18b994a3ffa47b933273ebdb84fafde9..f4c95fcbc0a1d618cc51f748a0df82b7ebe20cab 100644
 | |
| --- a/Source/WebKit/WebProcess/WebPage/WebCookieJar.h
 | |
| +++ b/Source/WebKit/WebProcess/WebPage/WebCookieJar.h
 | |
| @@ -52,6 +52,8 @@ public:
 | |
|      void cookiesDeleted(const String& host, const Vector<WebCore::Cookie>&);
 | |
|      void allCookiesDeleted();
 | |
|  
 | |
| +    void setCookieFromResponse(WebCore::ResourceLoader&, const String& setCookieValue);
 | |
| +
 | |
|  private:
 | |
|      WebCookieJar();
 | |
|  
 | |
| diff --git a/Source/WebKit/WebProcess/WebPage/WebDocumentLoader.cpp b/Source/WebKit/WebProcess/WebPage/WebDocumentLoader.cpp
 | |
| index 16f522fe281f8174b254b0a18626ace238229fd8..86e9489334107fbeb10df041f04eadc4bfb05657 100644
 | |
| --- a/Source/WebKit/WebProcess/WebPage/WebDocumentLoader.cpp
 | |
| +++ b/Source/WebKit/WebProcess/WebPage/WebDocumentLoader.cpp
 | |
| @@ -49,6 +49,14 @@ void WebDocumentLoader::detachFromFrame()
 | |
|      DocumentLoader::detachFromFrame();
 | |
|  }
 | |
|  
 | |
| +void WebDocumentLoader::replacedByFragmentNavigation(Frame& frame)
 | |
| +{
 | |
| +    ASSERT(!this->frame());
 | |
| +    // Notify WebPageProxy that the navigation has been converted into same page navigation.
 | |
| +    if (m_navigationID)
 | |
| +        WebFrame::fromCoreFrame(frame)->documentLoaderDetached(m_navigationID);
 | |
| +}
 | |
| +
 | |
|  void WebDocumentLoader::setNavigationID(uint64_t navigationID)
 | |
|  {
 | |
|      ASSERT(navigationID);
 | |
| diff --git a/Source/WebKit/WebProcess/WebPage/WebDocumentLoader.h b/Source/WebKit/WebProcess/WebPage/WebDocumentLoader.h
 | |
| index f127d64d005ab7b93875591b94a5899205e91579..df0de26e4dc449a0fbf93e7037444df4e5365822 100644
 | |
| --- a/Source/WebKit/WebProcess/WebPage/WebDocumentLoader.h
 | |
| +++ b/Source/WebKit/WebProcess/WebPage/WebDocumentLoader.h
 | |
| @@ -43,7 +43,10 @@ public:
 | |
|  private:
 | |
|      WebDocumentLoader(const WebCore::ResourceRequest&, const WebCore::SubstituteData&);
 | |
|  
 | |
| +    uint64_t loaderIDForInspector() override { return navigationID(); }
 | |
| +
 | |
|      void detachFromFrame() override;
 | |
| +    void replacedByFragmentNavigation(WebCore::Frame&) override;
 | |
|  
 | |
|      uint64_t m_navigationID;
 | |
|  };
 | |
| diff --git a/Source/WebKit/WebProcess/WebPage/WebPage.cpp b/Source/WebKit/WebProcess/WebPage/WebPage.cpp
 | |
| index 03ba5d5c9cd397e235ff653b62644f61cfb56241..337d6659acafe3b77a5524f318d09c3de2fa0e4f 100644
 | |
| --- a/Source/WebKit/WebProcess/WebPage/WebPage.cpp
 | |
| +++ b/Source/WebKit/WebProcess/WebPage/WebPage.cpp
 | |
| @@ -934,6 +934,9 @@ WebPage::WebPage(PageIdentifier pageID, WebPageCreationParameters&& parameters)
 | |
|          CFPreferencesGetAppIntegerValue(CFSTR("key"), CFSTR("com.apple.WebKit.WebContent.BlockIOKitInWebContentSandbox"), nullptr);
 | |
|  #endif
 | |
|  
 | |
| +    if (parameters.shouldPauseInInspectorWhenShown)
 | |
| +        m_page->inspectorController().pauseWhenShown();
 | |
| +
 | |
|      updateThrottleState();
 | |
|  }
 | |
|  
 | |
| @@ -1708,6 +1711,22 @@ void WebPage::platformDidReceiveLoadParameters(const LoadParameters& loadParamet
 | |
|  }
 | |
|  #endif
 | |
|  
 | |
| +void WebPage::loadRequestInFrameForInspector(LoadParameters&& loadParameters, WebCore::FrameIdentifier frameID)
 | |
| +{
 | |
| +    WebFrame* frame = WebProcess::singleton().webFrame(frameID);
 | |
| +    if (!frame) {
 | |
| +        send(Messages::WebPageProxy::DidDestroyNavigation(loadParameters.navigationID));
 | |
| +        return;
 | |
| +    }
 | |
| +
 | |
| +    // FIXME: use m_pendingNavigationID instead?
 | |
| +    m_pendingFrameNavigationID = loadParameters.navigationID;
 | |
| +
 | |
| +    FrameLoadRequest frameLoadRequest { *frame->coreFrame(), loadParameters.request };
 | |
| +    frame->coreFrame()->loader().load(WTFMove(frameLoadRequest));
 | |
| +    ASSERT(!m_pendingFrameNavigationID);
 | |
| +}
 | |
| +
 | |
|  void WebPage::loadRequest(LoadParameters&& loadParameters)
 | |
|  {
 | |
|      WEBPAGE_RELEASE_LOG(Loading, "loadRequest: navigationID=%" PRIu64 ", shouldTreatAsContinuingLoad=%u, lastNavigationWasAppInitiated=%d, existingNetworkResourceLoadIdentifierToResume=%" PRIu64, loadParameters.navigationID, static_cast<unsigned>(loadParameters.shouldTreatAsContinuingLoad), loadParameters.request.isAppInitiated(), valueOrDefault(loadParameters.existingNetworkResourceLoadIdentifierToResume).toUInt64());
 | |
| @@ -1980,17 +1999,13 @@ void WebPage::setSize(const WebCore::IntSize& viewSize)
 | |
|      view->resize(viewSize);
 | |
|      m_drawingArea->setNeedsDisplay();
 | |
|  
 | |
| -#if USE(COORDINATED_GRAPHICS)
 | |
|      if (view->useFixedLayout())
 | |
|          sendViewportAttributesChanged(m_page->viewportArguments());
 | |
| -#endif
 | |
|  }
 | |
|  
 | |
| -#if USE(COORDINATED_GRAPHICS)
 | |
|  void WebPage::sendViewportAttributesChanged(const ViewportArguments& viewportArguments)
 | |
|  {
 | |
| -    FrameView* view = m_page->mainFrame().view();
 | |
| -    ASSERT(view && view->useFixedLayout());
 | |
| +    ASSERT(m_page->mainFrame().view() && m_page->mainFrame().view()->useFixedLayout());
 | |
|  
 | |
|      // Viewport properties have no impact on zero sized fixed viewports.
 | |
|      if (m_viewSize.isEmpty())
 | |
| @@ -2007,20 +2022,18 @@ void WebPage::sendViewportAttributesChanged(const ViewportArguments& viewportArg
 | |
|  
 | |
|      ViewportAttributes attr = computeViewportAttributes(viewportArguments, minimumLayoutFallbackWidth, deviceWidth, deviceHeight, 1, m_viewSize);
 | |
|  
 | |
| -    // If no layout was done yet set contentFixedOrigin to (0,0).
 | |
| -    IntPoint contentFixedOrigin = view->didFirstLayout() ? view->fixedVisibleContentRect().location() : IntPoint();
 | |
| -
 | |
| -    // Put the width and height to the viewport width and height. In css units however.
 | |
| -    // Use FloatSize to avoid truncated values during scale.
 | |
| -    FloatSize contentFixedSize = m_viewSize;
 | |
| -
 | |
| -    contentFixedSize.scale(1 / attr.initialScale);
 | |
| -    view->setFixedVisibleContentRect(IntRect(contentFixedOrigin, roundedIntSize(contentFixedSize)));
 | |
| +#if ENABLE(CSS_DEVICE_ADAPTATION)
 | |
| +    FrameView* view = m_page->mainFrame().view();
 | |
| +    // CSS viewport descriptors might be applied to already affected viewport size
 | |
| +    // if the page enables/disables stylesheets, so need to keep initial viewport size.
 | |
| +    view->setInitialViewportSize(roundedIntSize(m_viewSize));
 | |
| +#endif
 | |
|  
 | |
|      attr.initialScale = m_page->viewportArguments().zoom; // Resets auto (-1) if no value was set by user.
 | |
|  
 | |
|      // This also takes care of the relayout.
 | |
|      setFixedLayoutSize(roundedIntSize(attr.layoutSize));
 | |
| +    scaleView(deviceWidth / attr.layoutSize.width());
 | |
|  
 | |
|  #if USE(COORDINATED_GRAPHICS)
 | |
|      m_drawingArea->didChangeViewportAttributes(WTFMove(attr));
 | |
| @@ -2028,7 +2041,6 @@ void WebPage::sendViewportAttributesChanged(const ViewportArguments& viewportArg
 | |
|      send(Messages::WebPageProxy::DidChangeViewportProperties(attr));
 | |
|  #endif
 | |
|  }
 | |
| -#endif
 | |
|  
 | |
|  void WebPage::scrollMainFrameIfNotAtMaxScrollPosition(const IntSize& scrollOffset)
 | |
|  {
 | |
| @@ -2313,6 +2325,7 @@ void WebPage::scaleView(double scale)
 | |
|      }
 | |
|  
 | |
|      m_page->setViewScaleFactor(scale);
 | |
| +    send(Messages::WebPageProxy::ViewScaleFactorDidChange(scale));
 | |
|      scalePage(pageScale, scrollPositionAtNewScale);
 | |
|  }
 | |
|  
 | |
| @@ -2492,17 +2505,13 @@ void WebPage::viewportPropertiesDidChange(const ViewportArguments& viewportArgum
 | |
|          viewportConfigurationChanged();
 | |
|  #endif
 | |
|  
 | |
| -#if USE(COORDINATED_GRAPHICS)
 | |
|      FrameView* view = m_page->mainFrame().view();
 | |
|      if (view && view->useFixedLayout())
 | |
|          sendViewportAttributesChanged(viewportArguments);
 | |
| +#if USE(COORDINATED_GRAPHICS)
 | |
|      else
 | |
|          m_drawingArea->didChangeViewportAttributes(ViewportAttributes());
 | |
|  #endif
 | |
| -
 | |
| -#if !PLATFORM(IOS_FAMILY) && !USE(COORDINATED_GRAPHICS)
 | |
| -    UNUSED_PARAM(viewportArguments);
 | |
| -#endif
 | |
|  }
 | |
|  
 | |
|  void WebPage::listenForLayoutMilestones(OptionSet<WebCore::LayoutMilestone> milestones)
 | |
| @@ -3416,6 +3425,104 @@ void WebPage::touchEvent(const WebTouchEvent& touchEvent)
 | |
|  
 | |
|      send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(touchEvent.type()), handled));
 | |
|  }
 | |
| +
 | |
| +void WebPage::fakeTouchTap(const WebCore::IntPoint& position, uint8_t modifiers, CompletionHandler<void()>&& completionHandler)
 | |
| +{
 | |
| +    SetForScope<bool> userIsInteractingChange { m_userIsInteracting, true };
 | |
| +
 | |
| +    bool handled = false;
 | |
| +
 | |
| +    uint32_t id = 0;
 | |
| +    float radiusX = 1.0;
 | |
| +    float radiusY = 1.0;
 | |
| +    float rotationAngle = 0.0;
 | |
| +    float force = 1.0;
 | |
| +    const WebCore::IntSize radius(radiusX,radiusY);
 | |
| +    const WebCore::IntPoint screenPosition = position;
 | |
| +    OptionSet<WebEvent::Modifier> eventModifiers;
 | |
| +    eventModifiers = eventModifiers.fromRaw(modifiers);
 | |
| +
 | |
| +    {
 | |
| +        Vector<WebPlatformTouchPoint> touchPoints;
 | |
| +        WebPlatformTouchPoint::TouchPointState state = WebPlatformTouchPoint::TouchPointState::TouchPressed;
 | |
| +        touchPoints.append(WebPlatformTouchPoint(id, state, screenPosition, position, radius, rotationAngle, force));
 | |
| +
 | |
| +        WebTouchEvent touchEvent(WebEvent::TouchStart, WTFMove(touchPoints), eventModifiers, WallTime::now());
 | |
| +
 | |
| +        CurrentEvent currentEvent(touchEvent);
 | |
| +        handled = handleTouchEvent(touchEvent, m_page.get());
 | |
| +    }
 | |
| +    {
 | |
| +        Vector<WebPlatformTouchPoint> touchPoints;
 | |
| +        WebPlatformTouchPoint::TouchPointState state = WebPlatformTouchPoint::TouchPointState::TouchReleased;
 | |
| +        touchPoints.append(WebPlatformTouchPoint(id, state, screenPosition, position, radius, rotationAngle, force));
 | |
| +
 | |
| +        WebTouchEvent touchEvent(WebEvent::TouchEnd, WTFMove(touchPoints), eventModifiers, WallTime::now());
 | |
| +
 | |
| +        CurrentEvent currentEvent(touchEvent);
 | |
| +        handled = handleTouchEvent(touchEvent, m_page.get()) || handled;
 | |
| +    }
 | |
| +    if (!handled) {
 | |
| +        FloatPoint adjustedPoint;
 | |
| +        Node* nodeRespondingToClick = m_page->mainFrame().nodeRespondingToClickEvents(position, adjustedPoint);
 | |
| +        Frame* frameRespondingToClick = nodeRespondingToClick ? nodeRespondingToClick->document().frame() : nullptr;
 | |
| +        IntPoint adjustedIntPoint = roundedIntPoint(adjustedPoint);
 | |
| +        if (!frameRespondingToClick) {
 | |
| +            completionHandler();
 | |
| +            return;
 | |
| +        }
 | |
| +        bool shiftKey = eventModifiers.contains(WebEvent::Modifier::ShiftKey);
 | |
| +        bool ctrlKey = eventModifiers.contains(WebEvent::Modifier::ControlKey);
 | |
| +        bool altKey = eventModifiers.contains(WebEvent::Modifier::AltKey);
 | |
| +        bool metaKey = eventModifiers.contains(WebEvent::Modifier::MetaKey);
 | |
| +        double force = 0.0;
 | |
| +        SyntheticClickType syntheticClickType = SyntheticClickType::OneFingerTap;
 | |
| +
 | |
| +        m_page->mainFrame().eventHandler().mouseMoved(PlatformMouseEvent(
 | |
| +            adjustedIntPoint,
 | |
| +            adjustedIntPoint,
 | |
| +            MouseButton::NoButton,
 | |
| +            PlatformEvent::Type::MouseMoved,
 | |
| +            0,
 | |
| +            shiftKey,
 | |
| +            ctrlKey,
 | |
| +            altKey,
 | |
| +            metaKey,
 | |
| +            WallTime::now(),
 | |
| +            force,
 | |
| +            syntheticClickType
 | |
| +        ));
 | |
| +        m_page->mainFrame().eventHandler().handleMousePressEvent(PlatformMouseEvent(
 | |
| +            adjustedIntPoint,
 | |
| +            adjustedIntPoint,
 | |
| +            MouseButton::LeftButton,
 | |
| +            PlatformEvent::Type::MousePressed,
 | |
| +            1,
 | |
| +            shiftKey,
 | |
| +            ctrlKey,
 | |
| +            altKey,
 | |
| +            metaKey,
 | |
| +            WallTime::now(),
 | |
| +            force,
 | |
| +            syntheticClickType
 | |
| +        ));
 | |
| +        m_page->mainFrame().eventHandler().handleMouseReleaseEvent(PlatformMouseEvent(
 | |
| +            adjustedIntPoint,
 | |
| +            adjustedIntPoint,
 | |
| +            MouseButton::LeftButton,
 | |
| +            PlatformEvent::Type::MouseReleased,
 | |
| +            1,
 | |
| +            shiftKey,
 | |
| +            ctrlKey,
 | |
| +            altKey,
 | |
| +            metaKey,
 | |
| +            WallTime::now(),
 | |
| +            force,
 | |
| +            syntheticClickType
 | |
| +        ));
 | |
| +    }
 | |
| +    completionHandler();
 | |
| +}
 | |
|  #endif
 | |
|  
 | |
|  void WebPage::cancelPointer(WebCore::PointerID pointerId, const WebCore::IntPoint& documentPoint)
 | |
| @@ -3492,6 +3599,11 @@ void WebPage::sendMessageToTargetBackend(const String& targetId, const String& m
 | |
|      m_inspectorTargetController->sendMessageToTargetBackend(targetId, message);
 | |
|  }
 | |
|  
 | |
| +void WebPage::resumeInspectorIfPausedInNewWindow()
 | |
| +{
 | |
| +    m_page->inspectorController().resumeIfPausedInNewWindow();
 | |
| +}
 | |
| +
 | |
|  void WebPage::insertNewlineInQuotedContent()
 | |
|  {
 | |
|      Ref frame = CheckedRef(m_page->focusController())->focusedOrMainFrame();
 | |
| @@ -3732,6 +3844,7 @@ void WebPage::didCompletePageTransition()
 | |
|  void WebPage::show()
 | |
|  {
 | |
|      send(Messages::WebPageProxy::ShowPage());
 | |
| +    m_page->inspectorController().didShowNewWindow();
 | |
|  }
 | |
|  
 | |
|  void WebPage::setIsTakingSnapshotsForApplicationSuspension(bool isTakingSnapshotsForApplicationSuspension)
 | |
| @@ -4584,7 +4697,7 @@ NotificationPermissionRequestManager* WebPage::notificationPermissionRequestMana
 | |
|  
 | |
|  #if ENABLE(DRAG_SUPPORT)
 | |
|  
 | |
| -#if PLATFORM(GTK)
 | |
| +#if PLATFORM(GTK) || PLATFORM(WPE)
 | |
|  void WebPage::performDragControllerAction(DragControllerAction action, const IntPoint& clientPosition, const IntPoint& globalPosition, OptionSet<DragOperation> draggingSourceOperationMask, SelectionData&& selectionData, OptionSet<DragApplicationFlags> flags)
 | |
|  {
 | |
|      if (!m_page) {
 | |
| @@ -6999,6 +7112,9 @@ Ref<DocumentLoader> WebPage::createDocumentLoader(Frame& frame, const ResourceRe
 | |
|              WebsitePoliciesData::applyToDocumentLoader(WTFMove(*m_pendingWebsitePolicies), documentLoader);
 | |
|              m_pendingWebsitePolicies = std::nullopt;
 | |
|          }
 | |
| +    } else if (m_pendingFrameNavigationID) {
 | |
| +        documentLoader->setNavigationID(m_pendingFrameNavigationID);
 | |
| +        m_pendingFrameNavigationID = 0;
 | |
|      }
 | |
|  
 | |
|      return documentLoader;
 | |
| diff --git a/Source/WebKit/WebProcess/WebPage/WebPage.h b/Source/WebKit/WebProcess/WebPage/WebPage.h
 | |
| index ee2a47b0d78053faf0426e8f0f171181eca78227..a3077d5cf7d7f847d120fb707dc955418356f5f8 100644
 | |
| --- a/Source/WebKit/WebProcess/WebPage/WebPage.h
 | |
| +++ b/Source/WebKit/WebProcess/WebPage/WebPage.h
 | |
| @@ -117,6 +117,10 @@
 | |
|  #include "WebPrintOperationGtk.h"
 | |
|  #endif
 | |
|  
 | |
| +#if PLATFORM(WPE)
 | |
| +#include "ArgumentCodersWPE.h"
 | |
| +#endif
 | |
| +
 | |
|  #if PLATFORM(GTK) || PLATFORM(WPE)
 | |
|  #include "InputMethodState.h"
 | |
|  #endif
 | |
| @@ -1014,11 +1018,11 @@ public:
 | |
|      void clearSelection();
 | |
|      void restoreSelectionInFocusedEditableElement();
 | |
|  
 | |
| -#if ENABLE(DRAG_SUPPORT) && PLATFORM(GTK)
 | |
| +#if ENABLE(DRAG_SUPPORT) && (PLATFORM(GTK) || PLATFORM(WPE))
 | |
|      void performDragControllerAction(DragControllerAction, const WebCore::IntPoint& clientPosition, const WebCore::IntPoint& globalPosition, OptionSet<WebCore::DragOperation> draggingSourceOperationMask, WebCore::SelectionData&&, OptionSet<WebCore::DragApplicationFlags>);
 | |
|  #endif
 | |
|  
 | |
| -#if ENABLE(DRAG_SUPPORT) && !PLATFORM(GTK)
 | |
| +#if ENABLE(DRAG_SUPPORT) && !PLATFORM(GTK) && !PLATFORM(WPE)
 | |
|      void performDragControllerAction(DragControllerAction, const WebCore::DragData&, SandboxExtension::Handle&&, Vector<SandboxExtension::Handle>&&);
 | |
|  #endif
 | |
|  
 | |
| @@ -1032,6 +1036,9 @@ public:
 | |
|      void didStartDrag();
 | |
|      void dragCancelled();
 | |
|      OptionSet<WebCore::DragSourceAction> allowedDragSourceActions() const { return m_allowedDragSourceActions; }
 | |
| +#if PLATFORM(MAC)
 | |
| +    void setDragPasteboardName(const String& pasteboardName) { m_page->setDragPasteboardName(pasteboardName); }
 | |
| +#endif
 | |
|  #endif
 | |
|  
 | |
|      void beginPrinting(WebCore::FrameIdentifier, const PrintInfo&);
 | |
| @@ -1266,6 +1273,7 @@ public:
 | |
|      void connectInspector(const String& targetId, Inspector::FrontendChannel::ConnectionType);
 | |
|      void disconnectInspector(const String& targetId);
 | |
|      void sendMessageToTargetBackend(const String& targetId, const String& message);
 | |
| +    void resumeInspectorIfPausedInNewWindow();
 | |
|  
 | |
|      void insertNewlineInQuotedContent();
 | |
|  
 | |
| @@ -1653,6 +1661,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&&);
 | |
| @@ -1690,6 +1699,7 @@ private:
 | |
|      void updatePotentialTapSecurityOrigin(const WebTouchEvent&, bool wasHandled);
 | |
|  #elif ENABLE(TOUCH_EVENTS)
 | |
|      void touchEvent(const WebTouchEvent&);
 | |
| +    void fakeTouchTap(const WebCore::IntPoint& position, uint8_t modifiers, CompletionHandler<void()>&& completionHandler);
 | |
|  #endif
 | |
|  
 | |
|      void cancelPointer(WebCore::PointerID, const WebCore::IntPoint&);
 | |
| @@ -1833,9 +1843,7 @@ private:
 | |
|  
 | |
|      void requestRectForFoundTextRange(const WebFoundTextRange&, CompletionHandler<void(WebCore::FloatRect)>&&);
 | |
|  
 | |
| -#if USE(COORDINATED_GRAPHICS)
 | |
|      void sendViewportAttributesChanged(const WebCore::ViewportArguments&);
 | |
| -#endif
 | |
|  
 | |
|      void didChangeSelectedIndexForActivePopupMenu(int32_t newIndex);
 | |
|      void setTextForActivePopupMenu(int32_t index);
 | |
| @@ -2378,6 +2386,7 @@ private:
 | |
|      UserActivity m_userActivity;
 | |
|  
 | |
|      uint64_t m_pendingNavigationID { 0 };
 | |
| +    uint64_t m_pendingFrameNavigationID { 0 };
 | |
|      std::optional<WebsitePoliciesData> m_pendingWebsitePolicies;
 | |
|  
 | |
|      bool m_mainFrameProgressCompleted { false };
 | |
| diff --git a/Source/WebKit/WebProcess/WebPage/WebPage.messages.in b/Source/WebKit/WebProcess/WebPage/WebPage.messages.in
 | |
| index e8fd0c51f2643c4627cb16cbb7d54a1535095378..da18a34c41cbc2ed0d1587d321d19d68aa696729 100644
 | |
| --- a/Source/WebKit/WebProcess/WebPage/WebPage.messages.in
 | |
| +++ b/Source/WebKit/WebProcess/WebPage/WebPage.messages.in
 | |
| @@ -139,6 +139,7 @@ GenerateSyntheticEditingCommand(enum:uint8_t WebKit::SyntheticEditingCommandType
 | |
|      ConnectInspector(String targetId, Inspector::FrontendChannel::ConnectionType connectionType)
 | |
|      DisconnectInspector(String targetId)
 | |
|      SendMessageToTargetBackend(String targetId, String message)
 | |
| +    ResumeInspectorIfPausedInNewWindow();
 | |
|  
 | |
|  #if ENABLE(REMOTE_INSPECTOR)
 | |
|      SetIndicating(bool indicating);
 | |
| @@ -150,6 +151,7 @@ GenerateSyntheticEditingCommand(enum:uint8_t WebKit::SyntheticEditingCommandType
 | |
|  #endif
 | |
|  #if !ENABLE(IOS_TOUCH_EVENTS) && ENABLE(TOUCH_EVENTS)
 | |
|      TouchEvent(WebKit::WebTouchEvent event)
 | |
| +    FakeTouchTap(WebCore::IntPoint position, uint8_t modifiers) -> () Async
 | |
|  #endif
 | |
|  
 | |
|      CancelPointer(WebCore::PointerID pointerId, WebCore::IntPoint documentPoint)
 | |
| @@ -179,6 +181,7 @@ GenerateSyntheticEditingCommand(enum:uint8_t WebKit::SyntheticEditingCommandType
 | |
|      LoadURLInFrame(URL url, String referrer, WebCore::FrameIdentifier frameID)
 | |
|      LoadDataInFrame(IPC::DataReference data, String MIMEType, String encodingName, URL baseURL, WebCore::FrameIdentifier frameID)
 | |
|      LoadRequest(struct WebKit::LoadParameters loadParameters)
 | |
| +    LoadRequestInFrameForInspector(struct WebKit::LoadParameters loadParameters, WebCore::FrameIdentifier frameID)
 | |
|      LoadRequestWaitingForProcessLaunch(struct WebKit::LoadParameters loadParameters, URL resourceDirectoryURL, WebKit::WebPageProxyIdentifier pageID, bool checkAssumedReadAccessToResourceURL)
 | |
|      LoadData(struct WebKit::LoadParameters loadParameters)
 | |
|      LoadSimulatedRequestAndResponse(struct WebKit::LoadParameters loadParameters, WebCore::ResourceResponse simulatedResponse)
 | |
| @@ -343,10 +346,10 @@ GenerateSyntheticEditingCommand(enum:uint8_t WebKit::SyntheticEditingCommandType
 | |
|      AddMIMETypeWithCustomContentProvider(String mimeType)
 | |
|  
 | |
|      # Drag and drop.
 | |
| -#if PLATFORM(GTK) && ENABLE(DRAG_SUPPORT)
 | |
| +#if (PLATFORM(GTK) || PLATFORM(WPE)) && ENABLE(DRAG_SUPPORT)
 | |
|      PerformDragControllerAction(enum:uint8_t WebKit::DragControllerAction action, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, OptionSet<WebCore::DragOperation> draggingSourceOperationMask, WebCore::SelectionData selection, OptionSet<WebCore::DragApplicationFlags> flags)
 | |
|  #endif
 | |
| -#if !PLATFORM(GTK) && ENABLE(DRAG_SUPPORT)
 | |
| +#if !PLATFORM(GTK) && !PLATFORM(WPE) && ENABLE(DRAG_SUPPORT)
 | |
|      PerformDragControllerAction(enum:uint8_t WebKit::DragControllerAction action, WebCore::DragData dragData, WebKit::SandboxExtension::Handle sandboxExtensionHandle, Vector<WebKit::SandboxExtension::Handle> sandboxExtensionsForUpload)
 | |
|  #endif
 | |
|  #if ENABLE(DRAG_SUPPORT)
 | |
| @@ -355,6 +358,10 @@ GenerateSyntheticEditingCommand(enum:uint8_t WebKit::SyntheticEditingCommandType
 | |
|      DragCancelled()
 | |
|  #endif
 | |
|  
 | |
| +#if PLATFORM(MAC) && ENABLE(DRAG_SUPPORT)
 | |
| +    SetDragPasteboardName(String pasteboardName)
 | |
| +#endif
 | |
| +
 | |
|  #if PLATFORM(IOS_FAMILY) && ENABLE(DRAG_SUPPORT)
 | |
|      RequestDragStart(WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, OptionSet<WebCore::DragSourceAction> allowedActionsMask)
 | |
|      RequestAdditionalItemsForDragSession(WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, OptionSet<WebCore::DragSourceAction> allowedActionsMask)
 | |
| diff --git a/Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm b/Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm
 | |
| index 3dcbe78f4693a89c426cbf6f469f790208d55410..14cb073b4464dcef3a8271da603cd27fdfad5c10 100644
 | |
| --- a/Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm
 | |
| +++ b/Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm
 | |
| @@ -806,21 +806,37 @@ String WebPage::platformUserAgent(const URL&) const
 | |
|  
 | |
|  bool WebPage::hoverSupportedByPrimaryPointingDevice() const
 | |
|  {
 | |
| +#if ENABLE(TOUCH_EVENTS)
 | |
| +    return !screenIsTouchPrimaryInputDevice();
 | |
| +#else
 | |
|      return true;
 | |
| +#endif
 | |
|  }
 | |
|  
 | |
|  bool WebPage::hoverSupportedByAnyAvailablePointingDevice() const
 | |
|  {
 | |
| +#if ENABLE(TOUCH_EVENTS)
 | |
| +    return !screenHasTouchDevice();
 | |
| +#else
 | |
|      return true;
 | |
| +#endif
 | |
|  }
 | |
|  
 | |
|  std::optional<PointerCharacteristics> WebPage::pointerCharacteristicsOfPrimaryPointingDevice() const
 | |
|  {
 | |
| +#if ENABLE(TOUCH_EVENTS)
 | |
| +    if (screenIsTouchPrimaryInputDevice())
 | |
| +        return PointerCharacteristics::Coarse;
 | |
| +#endif
 | |
|      return PointerCharacteristics::Fine;
 | |
|  }
 | |
|  
 | |
|  OptionSet<PointerCharacteristics> WebPage::pointerCharacteristicsOfAllAvailablePointingDevices() const
 | |
|  {
 | |
| +#if ENABLE(TOUCH_EVENTS)
 | |
| +    if (screenHasTouchDevice())
 | |
| +        return PointerCharacteristics::Coarse;
 | |
| +#endif
 | |
|      return PointerCharacteristics::Fine;
 | |
|  }
 | |
|  
 | |
| diff --git a/Source/WebKit/WebProcess/WebPage/win/WebPageWin.cpp b/Source/WebKit/WebProcess/WebPage/win/WebPageWin.cpp
 | |
| index c77ff78cd3cd9627d1ae7b930c81457094645200..88746359159a76b169b7e6dcbee4fb34db5f246a 100644
 | |
| --- a/Source/WebKit/WebProcess/WebPage/win/WebPageWin.cpp
 | |
| +++ b/Source/WebKit/WebProcess/WebPage/win/WebPageWin.cpp
 | |
| @@ -43,6 +43,7 @@
 | |
|  #include <WebCore/NotImplemented.h>
 | |
|  #include <WebCore/Page.h>
 | |
|  #include <WebCore/PlatformKeyboardEvent.h>
 | |
| +#include <WebCore/PlatformScreen.h>
 | |
|  #include <WebCore/PointerCharacteristics.h>
 | |
|  #include <WebCore/Settings.h>
 | |
|  #include <WebCore/SharedBuffer.h>
 | |
| @@ -118,21 +119,37 @@ String WebPage::platformUserAgent(const URL&) const
 | |
|  
 | |
|  bool WebPage::hoverSupportedByPrimaryPointingDevice() const
 | |
|  {
 | |
| +#if ENABLE(TOUCH_EVENTS)
 | |
| +    return !screenIsTouchPrimaryInputDevice();
 | |
| +#else
 | |
|      return true;
 | |
| +#endif
 | |
|  }
 | |
|  
 | |
|  bool WebPage::hoverSupportedByAnyAvailablePointingDevice() const
 | |
|  {
 | |
| +#if ENABLE(TOUCH_EVENTS)
 | |
| +    return !screenHasTouchDevice();
 | |
| +#else
 | |
|      return true;
 | |
| +#endif
 | |
|  }
 | |
|  
 | |
|  std::optional<PointerCharacteristics> WebPage::pointerCharacteristicsOfPrimaryPointingDevice() const
 | |
|  {
 | |
| +#if ENABLE(TOUCH_EVENTS)
 | |
| +    if (screenIsTouchPrimaryInputDevice())
 | |
| +        return PointerCharacteristics::Coarse;
 | |
| +#endif
 | |
|      return PointerCharacteristics::Fine;
 | |
|  }
 | |
|  
 | |
|  OptionSet<PointerCharacteristics> WebPage::pointerCharacteristicsOfAllAvailablePointingDevices() const
 | |
|  {
 | |
| +#if ENABLE(TOUCH_EVENTS)
 | |
| +    if (screenHasTouchDevice())
 | |
| +        return PointerCharacteristics::Coarse;
 | |
| +#endif
 | |
|      return PointerCharacteristics::Fine;
 | |
|  }
 | |
|  
 | |
| diff --git a/Source/WebKit/WebProcess/WebProcess.cpp b/Source/WebKit/WebProcess/WebProcess.cpp
 | |
| index 2f12cefa501042fd7b7a43261a62390d9b2e39b2..141e72e5f2168a29d7fde4ee89e6cc3f1156a69b 100644
 | |
| --- a/Source/WebKit/WebProcess/WebProcess.cpp
 | |
| +++ b/Source/WebKit/WebProcess/WebProcess.cpp
 | |
| @@ -92,6 +92,7 @@
 | |
|  #include "WebsiteData.h"
 | |
|  #include "WebsiteDataStoreParameters.h"
 | |
|  #include "WebsiteDataType.h"
 | |
| +#include <JavaScriptCore/IdentifiersFactory.h>
 | |
|  #include <JavaScriptCore/JSLock.h>
 | |
|  #include <JavaScriptCore/MemoryStatistics.h>
 | |
|  #include <JavaScriptCore/WasmFaultSignalHandler.h>
 | |
| @@ -368,6 +369,8 @@ void WebProcess::initializeProcess(const AuxiliaryProcessInitializationParameter
 | |
|      
 | |
|      platformInitializeProcess(parameters);
 | |
|      updateCPULimit();
 | |
| +
 | |
| +    Inspector::IdentifiersFactory::initializeWithProcessID(parameters.processIdentifier->toUInt64());
 | |
|  }
 | |
|  
 | |
|  void WebProcess::initializeConnection(IPC::Connection* connection)
 | |
| diff --git a/Source/WebKit/WebProcess/win/WebProcessMainWin.cpp b/Source/WebKit/WebProcess/win/WebProcessMainWin.cpp
 | |
| index 8987c3964a9308f2454759de7f8972215a3ae416..bcac0afeb94ed8123d1f9fb0b932c8497d157b49 100644
 | |
| --- a/Source/WebKit/WebProcess/win/WebProcessMainWin.cpp
 | |
| +++ b/Source/WebKit/WebProcess/win/WebProcessMainWin.cpp
 | |
| @@ -42,7 +42,9 @@ public:
 | |
|      bool platformInitialize() override
 | |
|      {
 | |
|          if (SetProcessDpiAwarenessContextPtr())
 | |
| -            SetProcessDpiAwarenessContextPtr()(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
 | |
| +            // Playwright begin
 | |
| +            SetProcessDpiAwarenessContextPtr()(DPI_AWARENESS_CONTEXT_UNAWARE);
 | |
| +            // Playwright end
 | |
|          else
 | |
|              SetProcessDPIAware();
 | |
|          return true;
 | |
| diff --git a/Source/WebKitLegacy/mac/WebView/WebHTMLView.mm b/Source/WebKitLegacy/mac/WebView/WebHTMLView.mm
 | |
| index 9f9c67523b8fac9025d2cec101adf452631ffc61..737d8dab4f7aa1fe446b2dcfdc32fe83e02a4555 100644
 | |
| --- a/Source/WebKitLegacy/mac/WebView/WebHTMLView.mm
 | |
| +++ b/Source/WebKitLegacy/mac/WebView/WebHTMLView.mm
 | |
| @@ -4189,7 +4189,7 @@ static BOOL currentScrollIsBlit(NSView *clipView)
 | |
|      _private->handlingMouseDownEvent = NO;
 | |
|  }
 | |
|  
 | |
| -#if ENABLE(TOUCH_EVENTS)
 | |
| +#if ENABLE(IOS_TOUCH_EVENTS)
 | |
|  
 | |
|  - (void)touch:(WebEvent *)event
 | |
|  {
 | |
| diff --git a/Source/WebKitLegacy/mac/WebView/WebView.mm b/Source/WebKitLegacy/mac/WebView/WebView.mm
 | |
| index 09748e5cf07408ec620bb0a151378dbf6590733d..824b2efbfe7c6821ab0913cc7ebeaf960ea79784 100644
 | |
| --- a/Source/WebKitLegacy/mac/WebView/WebView.mm
 | |
| +++ b/Source/WebKitLegacy/mac/WebView/WebView.mm
 | |
| @@ -4043,7 +4043,7 @@ IGNORE_WARNINGS_END
 | |
|  }
 | |
|  #endif // PLATFORM(IOS_FAMILY)
 | |
|  
 | |
| -#if ENABLE(TOUCH_EVENTS)
 | |
| +#if ENABLE(IOS_TOUCH_EVENTS)
 | |
|  
 | |
|  - (NSArray *)_touchEventRegions
 | |
|  {
 | |
| @@ -4085,7 +4085,7 @@ IGNORE_WARNINGS_END
 | |
|      }).autorelease();
 | |
|  }
 | |
|  
 | |
| -#endif // ENABLE(TOUCH_EVENTS)
 | |
| +#endif // ENABLE(IOS_TOUCH_EVENTS)
 | |
|  
 | |
|  // For backwards compatibility with the WebBackForwardList API, we honor both
 | |
|  // a per-WebView and a per-preferences setting for whether to use the back/forward cache.
 | |
| diff --git a/Source/cmake/FindLibVPX.cmake b/Source/cmake/FindLibVPX.cmake
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..dd6a53e2d57318489b7e49dd7373706d5d9dc387
 | |
| --- /dev/null
 | |
| +++ b/Source/cmake/FindLibVPX.cmake
 | |
| @@ -0,0 +1,25 @@
 | |
| +# Find LibVPX
 | |
| +
 | |
| +find_package(PkgConfig QUIET)
 | |
| +pkg_check_modules(PC_LIBVPX REQUIRED vpx)
 | |
| +
 | |
| +find_path(LIBVPX_INCLUDE_DIRS
 | |
| +    NAMES vpx/vp8.h
 | |
| +    HINTS ${PC_LIBVPX_INCLUDEDIR}
 | |
| +          ${PC_LIBVPX_INCLUDE_DIRS}
 | |
| +)
 | |
| +
 | |
| +find_library(LIBVPX_LIBRARIES
 | |
| +    NAMES vpx
 | |
| +    HINTS ${PC_LIBVPX_LIBDIR}
 | |
| +          ${PC_LIBVPX_LIBRARY_DIRS}
 | |
| +)
 | |
| +
 | |
| +include(FindPackageHandleStandardArgs)
 | |
| +FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibVPX REQUIRED_VARS LIBVPX_INCLUDE_DIRS LIBVPX_LIBRARIES
 | |
| +                                         VERSION_VAR   PC_LIBVPX_VERSION)
 | |
| +
 | |
| +mark_as_advanced(
 | |
| +    LIBVPX_INCLUDE_DIRS
 | |
| +    LIBVPX_LIBRARIES
 | |
| +)
 | |
| diff --git a/Source/cmake/OptionsGTK.cmake b/Source/cmake/OptionsGTK.cmake
 | |
| index 8dc57e7d0395edee5667eceada38bd3b56668151..e944f55214844cf35e6a80a600a9773cf5d49ef6 100644
 | |
| --- a/Source/cmake/OptionsGTK.cmake
 | |
| +++ b/Source/cmake/OptionsGTK.cmake
 | |
| @@ -11,6 +11,8 @@ if (${CMAKE_VERSION} VERSION_LESS "3.20" AND NOT ${CMAKE_GENERATOR} STREQUAL "Ni
 | |
|      message(FATAL_ERROR "Building with Makefiles requires CMake 3.20 or newer. Either enable Ninja by passing -GNinja, or upgrade CMake.")
 | |
|  endif ()
 | |
|  
 | |
| +set(ENABLE_WEBKIT_LEGACY OFF)
 | |
| +
 | |
|  set(USER_AGENT_BRANDING "" CACHE STRING "Branding to add to user agent string")
 | |
|  
 | |
|  find_package(Cairo 1.14.0 REQUIRED)
 | |
| @@ -32,6 +34,10 @@ find_package(EGL)
 | |
|  find_package(OpenGL)
 | |
|  find_package(OpenGLES2)
 | |
|  
 | |
| +# Playwright begin
 | |
| +find_package(LibVPX REQUIRED)
 | |
| +# Playwright end
 | |
| +
 | |
|  include(GStreamerDefinitions)
 | |
|  
 | |
|  SET_AND_EXPOSE_TO_BUILD(USE_CAIRO TRUE)
 | |
| @@ -65,16 +71,16 @@ WEBKIT_OPTION_DEFINE(ENABLE_QUARTZ_TARGET "Whether to enable support for the Qua
 | |
|  WEBKIT_OPTION_DEFINE(ENABLE_WAYLAND_TARGET "Whether to enable support for the Wayland windowing target." PUBLIC ON)
 | |
|  WEBKIT_OPTION_DEFINE(ENABLE_X11_TARGET "Whether to enable support for the X11 windowing target." PUBLIC ON)
 | |
|  WEBKIT_OPTION_DEFINE(USE_ANGLE_WEBGL "Whether to use ANGLE as WebGL backend." PUBLIC OFF)
 | |
| -WEBKIT_OPTION_DEFINE(USE_AVIF "Whether to enable support for AVIF images." PUBLIC ${ENABLE_EXPERIMENTAL_FEATURES})
 | |
| +WEBKIT_OPTION_DEFINE(USE_AVIF "Whether to enable support for AVIF images." PUBLIC OFF)
 | |
|  WEBKIT_OPTION_DEFINE(USE_GTK4 "Whether to enable usage of GTK4 instead of GTK3." PUBLIC OFF)
 | |
| -WEBKIT_OPTION_DEFINE(USE_JPEGXL "Whether to enable support for JPEG-XL images." PUBLIC ${ENABLE_EXPERIMENTAL_FEATURES})
 | |
| +WEBKIT_OPTION_DEFINE(USE_JPEGXL "Whether to enable support for JPEG-XL images." PUBLIC OFF)
 | |
|  WEBKIT_OPTION_DEFINE(USE_LCMS "Whether to enable support for image color management using libcms2." PUBLIC ON)
 | |
|  WEBKIT_OPTION_DEFINE(USE_LIBHYPHEN "Whether to enable the default automatic hyphenation implementation." PUBLIC ON)
 | |
|  WEBKIT_OPTION_DEFINE(USE_LIBNOTIFY "Whether to enable the default web notification implementation." PUBLIC ON)
 | |
|  WEBKIT_OPTION_DEFINE(USE_LIBSECRET "Whether to enable the persistent credential storage using libsecret." PUBLIC ON)
 | |
|  WEBKIT_OPTION_DEFINE(USE_OPENGL_OR_ES "Whether to use OpenGL or ES." PUBLIC ON)
 | |
|  WEBKIT_OPTION_DEFINE(USE_OPENJPEG "Whether to enable support for JPEG2000 images." PUBLIC ON)
 | |
| -WEBKIT_OPTION_DEFINE(USE_SOUP2 "Whether to enable usage of Soup 2 instead of Soup 3." PUBLIC OFF)
 | |
| +WEBKIT_OPTION_DEFINE(USE_SOUP2 "Whether to enable usage of Soup 2 instead of Soup 3." PUBLIC ON)
 | |
|  WEBKIT_OPTION_DEFINE(USE_WOFF2 "Whether to enable support for WOFF2 Web Fonts." PUBLIC ON)
 | |
|  WEBKIT_OPTION_DEFINE(USE_WPE_RENDERER "Whether to enable WPE rendering" PUBLIC ON)
 | |
|  
 | |
| @@ -124,7 +130,7 @@ endif ()
 | |
|  # without approval from a GTK reviewer. There must be strong reason to support
 | |
|  # changing the value of the option.
 | |
|  WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_DRAG_SUPPORT PUBLIC ON)
 | |
| -WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_GAMEPAD PUBLIC ON)
 | |
| +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_GAMEPAD PUBLIC OFF)
 | |
|  WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MINIBROWSER PUBLIC ON)
 | |
|  WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_PDFJS PUBLIC ON)
 | |
|  WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_SPELLCHECK PUBLIC ON)
 | |
| @@ -158,10 +164,10 @@ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_INPUT_TYPE_WEEK PRIVATE ON)
 | |
|  WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_INTELLIGENT_TRACKING_PREVENTION PRIVATE ON)
 | |
|  WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_LAYER_BASED_SVG_ENGINE PRIVATE ON)
 | |
|  WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_LAYOUT_FORMATTING_CONTEXT PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
 | |
| -WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_RECORDER PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
 | |
| +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_RECORDER PRIVATE OFF)
 | |
|  WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_SESSION PRIVATE ON)
 | |
|  WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_SESSION_PLAYLIST PRIVATE OFF)
 | |
| -WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_STREAM PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
 | |
| +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_STREAM PRIVATE ON)
 | |
|  WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MHTML PRIVATE ON)
 | |
|  WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MOUSE_CURSOR_SCALE PRIVATE ON)
 | |
|  WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_NETSCAPE_PLUGIN_API PRIVATE OFF)
 | |
| @@ -169,7 +175,7 @@ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_NETWORK_CACHE_SPECULATIVE_REVALIDATION P
 | |
|  WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_NETWORK_CACHE_STALE_WHILE_REVALIDATE PRIVATE ON)
 | |
|  WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_OFFSCREEN_CANVAS PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
 | |
|  WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_OFFSCREEN_CANVAS_IN_WORKERS PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
 | |
| -WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_THUNDER PRIVATE ${ENABLE_DEVELOPER_MODE})
 | |
| +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_THUNDER PRIVATE OFF)
 | |
|  WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_PERIODIC_MEMORY_MONITOR PRIVATE ON)
 | |
|  WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_POINTER_LOCK PRIVATE ON)
 | |
|  WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_SERVICE_WORKER PRIVATE ON)
 | |
| @@ -177,6 +183,15 @@ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_SHAREABLE_RESOURCE PRIVATE ON)
 | |
|  WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEB_API_STATISTICS PRIVATE ON)
 | |
|  WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEB_RTC PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
 | |
|  
 | |
| +# Playwright
 | |
| +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_APPLICATION_MANIFEST PRIVATE ON)
 | |
| +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_CURSOR_VISIBILITY PRIVATE ON)
 | |
| +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_DOWNLOAD_ATTRIBUTE PRIVATE ON)
 | |
| +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_DEVICE_ORIENTATION PRIVATE ON)
 | |
| +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_GAMEPAD PRIVATE ON)
 | |
| +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_SPEECH_SYNTHESIS PRIVATE ON)
 | |
| +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_POINTER_LOCK PRIVATE ON)
 | |
| +
 | |
|  include(GStreamerDependencies)
 | |
|  
 | |
|  # Finalize the value for all options. Do not attempt to use an option before
 | |
| @@ -277,7 +292,8 @@ if (NOT EXISTS "${TOOLS_DIR}/glib/apply-build-revision-to-files.py")
 | |
|      set(BUILD_REVISION "tarball")
 | |
|  endif ()
 | |
|  
 | |
| -SET_AND_EXPOSE_TO_BUILD(USE_ATSPI ${ENABLE_ACCESSIBILITY})
 | |
| +SET_AND_EXPOSE_TO_BUILD(USE_ATSPI FALSE)
 | |
| +
 | |
|  SET_AND_EXPOSE_TO_BUILD(HAVE_GTK_UNIX_PRINTING ${GTK_UNIX_PRINT_FOUND})
 | |
|  SET_AND_EXPOSE_TO_BUILD(HAVE_OS_DARK_MODE_SUPPORT 1)
 | |
|  
 | |
| diff --git a/Source/cmake/OptionsWPE.cmake b/Source/cmake/OptionsWPE.cmake
 | |
| index 9cae317e38d9725896a5c42c4fbbcf09954248a3..257012c2d99cd1b43999ce40b996eb35fc6833ef 100644
 | |
| --- a/Source/cmake/OptionsWPE.cmake
 | |
| +++ b/Source/cmake/OptionsWPE.cmake
 | |
| @@ -9,6 +9,8 @@ if (${CMAKE_VERSION} VERSION_LESS "3.20" AND NOT ${CMAKE_GENERATOR} STREQUAL "Ni
 | |
|      message(FATAL_ERROR "Building with Makefiles requires CMake 3.20 or newer. Either enable Ninja by passing -GNinja, or upgrade CMake.")
 | |
|  endif ()
 | |
|  
 | |
| +set(ENABLE_WEBKIT_LEGACY OFF)
 | |
| +
 | |
|  set(USER_AGENT_BRANDING "" CACHE STRING "Branding to add to user agent string")
 | |
|  
 | |
|  find_package(Cairo 1.14.0 REQUIRED)
 | |
| @@ -61,10 +63,10 @@ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_GPU_PROCESS PRIVATE OFF)
 | |
|  WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_INTELLIGENT_TRACKING_PREVENTION PRIVATE ON)
 | |
|  WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_LAYER_BASED_SVG_ENGINE PRIVATE ON)
 | |
|  WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_LAYOUT_FORMATTING_CONTEXT PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
 | |
| -WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_RECORDER PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
 | |
| +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_RECORDER PRIVATE OFF)
 | |
|  WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_SESSION PRIVATE ON)
 | |
|  WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_SESSION_PLAYLIST PRIVATE OFF)
 | |
| -WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_STREAM PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
 | |
| +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_STREAM PRIVATE ON)
 | |
|  WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MHTML PRIVATE ON)
 | |
|  WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_NETSCAPE_PLUGIN_API PRIVATE OFF)
 | |
|  WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_NOTIFICATIONS PRIVATE ON)
 | |
| @@ -74,24 +76,42 @@ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_OFFSCREEN_CANVAS_IN_WORKERS PRIVATE ${EN
 | |
|  WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_PERIODIC_MEMORY_MONITOR PRIVATE ON)
 | |
|  WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_SERVICE_WORKER PRIVATE ON)
 | |
|  WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_SHAREABLE_RESOURCE PRIVATE ON)
 | |
| -WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_THUNDER PRIVATE ${ENABLE_DEVELOPER_MODE})
 | |
| +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_THUNDER PRIVATE OFF)
 | |
|  WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_TOUCH_EVENTS PRIVATE ON)
 | |
|  WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEB_RTC PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
 | |
|  WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEBXR PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
 | |
|  
 | |
| +# Playwright
 | |
| +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_APPLICATION_MANIFEST PRIVATE ON)
 | |
| +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_CURSOR_VISIBILITY PRIVATE ON)
 | |
| +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_DARK_MODE_CSS PRIVATE ON)
 | |
| +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_DATALIST_ELEMENT PRIVATE ON)
 | |
| +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_DOWNLOAD_ATTRIBUTE PRIVATE ON)
 | |
| +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_DRAG_SUPPORT PRIVATE ON)
 | |
| +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_DEVICE_ORIENTATION PRIVATE ON)
 | |
| +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_GAMEPAD PRIVATE ON)
 | |
| +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_INPUT_TYPE_COLOR PRIVATE ON)
 | |
| +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_INPUT_TYPE_DATE PRIVATE ON)
 | |
| +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_INPUT_TYPE_DATETIMELOCAL PRIVATE ON)
 | |
| +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_INPUT_TYPE_MONTH PRIVATE ON)
 | |
| +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_INPUT_TYPE_TIME PRIVATE ON)
 | |
| +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_INPUT_TYPE_WEEK PRIVATE ON)
 | |
| +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_SPEECH_SYNTHESIS PRIVATE ON)
 | |
| +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_POINTER_LOCK PRIVATE ON)
 | |
| +
 | |
|  # Public options specific to the WPE port. Do not add any options here unless
 | |
|  # there is a strong reason we should support changing the value of the option,
 | |
|  # and the option is not relevant to any other WebKit ports.
 | |
|  WEBKIT_OPTION_DEFINE(ENABLE_DOCUMENTATION "Whether to generate documentation." PUBLIC ON)
 | |
|  WEBKIT_OPTION_DEFINE(ENABLE_INTROSPECTION "Whether to enable GObject introspection." PUBLIC ON)
 | |
|  WEBKIT_OPTION_DEFINE(ENABLE_JOURNALD_LOG "Whether to enable journald logging" PUBLIC ON)
 | |
| -WEBKIT_OPTION_DEFINE(ENABLE_WPE_QT_API "Whether to enable support for the Qt5/QML plugin" PUBLIC ${ENABLE_DEVELOPER_MODE})
 | |
| +WEBKIT_OPTION_DEFINE(ENABLE_WPE_QT_API "Whether to enable support for the Qt5/QML plugin" PUBLIC OFF)
 | |
|  WEBKIT_OPTION_DEFINE(USE_ANGLE_WEBGL "Whether to use ANGLE as WebGL backend." PUBLIC OFF)
 | |
| -WEBKIT_OPTION_DEFINE(USE_AVIF "Whether to enable support for AVIF images." PUBLIC ${ENABLE_EXPERIMENTAL_FEATURES})
 | |
| -WEBKIT_OPTION_DEFINE(USE_JPEGXL "Whether to enable support for JPEG-XL images." PUBLIC ${ENABLE_EXPERIMENTAL_FEATURES})
 | |
| +WEBKIT_OPTION_DEFINE(USE_AVIF "Whether to enable support for AVIF images." PUBLIC OFF)
 | |
| +WEBKIT_OPTION_DEFINE(USE_JPEGXL "Whether to enable support for JPEG-XL images." PUBLIC OFF)
 | |
|  WEBKIT_OPTION_DEFINE(USE_LCMS "Whether to enable support for image color management using libcms2." PUBLIC ON)
 | |
|  WEBKIT_OPTION_DEFINE(USE_OPENJPEG "Whether to enable support for JPEG2000 images." PUBLIC ON)
 | |
| -WEBKIT_OPTION_DEFINE(USE_SOUP2 "Whether to enable usage of Soup 2 instead of Soup 3." PUBLIC OFF)
 | |
| +WEBKIT_OPTION_DEFINE(USE_SOUP2 "Whether to enable usage of Soup 2 instead of Soup 3." PUBLIC ON)
 | |
|  WEBKIT_OPTION_DEFINE(USE_WOFF2 "Whether to enable support for WOFF2 Web Fonts." PUBLIC ON)
 | |
|  
 | |
|  # Private options specific to the WPE port.
 | |
| @@ -297,7 +317,7 @@ if (NOT EXISTS "${TOOLS_DIR}/glib/apply-build-revision-to-files.py")
 | |
|  endif ()
 | |
|  
 | |
|  SET_AND_EXPOSE_TO_BUILD(HAVE_ACCESSIBILITY ${ENABLE_ACCESSIBILITY})
 | |
| -SET_AND_EXPOSE_TO_BUILD(USE_ATSPI ${ENABLE_ACCESSIBILITY})
 | |
| +SET_AND_EXPOSE_TO_BUILD(USE_ATSPI FALSE)
 | |
|  SET_AND_EXPOSE_TO_BUILD(USE_CAIRO TRUE)
 | |
|  SET_AND_EXPOSE_TO_BUILD(USE_EGL TRUE)
 | |
|  SET_AND_EXPOSE_TO_BUILD(USE_GCRYPT TRUE)
 | |
| diff --git a/Source/cmake/OptionsWin.cmake b/Source/cmake/OptionsWin.cmake
 | |
| index 113f0203c76d1e589f086d719bde700c487050e6..f96a2b304b153d74dcafc616271d7b0823eae177 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 ()
 | |
|  
 | |
| @@ -27,11 +28,9 @@ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_CSS_BOX_DECORATION_BREAK PUBLIC ON)
 | |
|  WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_CSS_SELECTORS_LEVEL4 PUBLIC ON)
 | |
|  WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_CURSOR_VISIBILITY PUBLIC ON)
 | |
|  WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_DATALIST_ELEMENT PUBLIC OFF)
 | |
| -WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_DEVICE_ORIENTATION PUBLIC OFF)
 | |
|  WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_DRAG_SUPPORT PUBLIC ON)
 | |
|  WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_FTL_JIT PUBLIC OFF)
 | |
|  WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_FULLSCREEN_API PUBLIC ON)
 | |
| -WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_GAMEPAD PUBLIC OFF)
 | |
|  WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_GEOLOCATION PUBLIC ON)
 | |
|  WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_INPUT_TYPE_COLOR PUBLIC OFF)
 | |
|  WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_INPUT_TYPE_DATE PUBLIC OFF)
 | |
| @@ -47,7 +46,6 @@ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_CONTROLS_SCRIPT PUBLIC ON)
 | |
|  WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_SOURCE PUBLIC OFF)
 | |
|  WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_STATISTICS PUBLIC ON)
 | |
|  WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MOUSE_CURSOR_SCALE PUBLIC ON)
 | |
| -WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_NOTIFICATIONS PUBLIC OFF)
 | |
|  WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_VIDEO PUBLIC ON)
 | |
|  WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEBASSEMBLY PRIVATE OFF)
 | |
|  WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEB_AUDIO PUBLIC OFF)
 | |
| @@ -91,6 +89,16 @@ if (${WTF_PLATFORM_WIN_CAIRO})
 | |
|      # No support planned
 | |
|      WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_FTPDIR PRIVATE OFF)
 | |
|  
 | |
| +    # Playwright
 | |
| +    WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_CSS_CONIC_GRADIENTS PRIVATE ON)
 | |
| +    WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_DARK_MODE_CSS PRIVATE ON)
 | |
| +    WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_DEVICE_ORIENTATION PRIVATE ON)
 | |
| +    WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_DOWNLOAD_ATTRIBUTE PRIVATE ON)
 | |
| +    WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_GAMEPAD PRIVATE ON)
 | |
| +    WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_NOTIFICATIONS PRIVATE ON)
 | |
| +    WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_POINTER_LOCK PRIVATE ON)
 | |
| +    WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_TOUCH_EVENTS PRIVATE ON)
 | |
| +
 | |
|      # FIXME: Implement plugin process on Modern WebKit. https://bugs.webkit.org/show_bug.cgi?id=185313
 | |
|      WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_NETSCAPE_PLUGIN_API PRIVATE OFF)
 | |
|  else ()
 | |
| diff --git a/Source/cmake/OptionsWinCairo.cmake b/Source/cmake/OptionsWinCairo.cmake
 | |
| index 62b4bc6e91b180abe8ca0f749ce76bf1aba98d4d..23216d79747d514c53e965618d5bf7ade8beb659 100644
 | |
| --- a/Source/cmake/OptionsWinCairo.cmake
 | |
| +++ b/Source/cmake/OptionsWinCairo.cmake
 | |
| @@ -37,20 +37,42 @@ if (OpenJPEG_FOUND)
 | |
|  endif ()
 | |
|  
 | |
|  find_package(WOFF2 1.0.2 COMPONENTS dec)
 | |
| -if (WOFF2_FOUND)
 | |
| -    SET_AND_EXPOSE_TO_BUILD(USE_WOFF2 ON)
 | |
| -endif ()
 | |
| +SET_AND_EXPOSE_TO_BUILD(USE_WOFF2 ON)
 | |
|  
 | |
|  find_package(WebP COMPONENTS demux)
 | |
|  if (WebP_FOUND)
 | |
|      SET_AND_EXPOSE_TO_BUILD(USE_WEBP ON)
 | |
|  endif ()
 | |
|  
 | |
| +# Playwright begin
 | |
| +if (NOT LIBVPX_PACKAGE_PATH)
 | |
| +    set(LIBVPX_PACKAGE_PATH "C:\\vcpkg\\packages\\libvpx_x64-windows")
 | |
| +endif()
 | |
| +file(TO_CMAKE_PATH "${LIBVPX_PACKAGE_PATH}" LIBVPX_PACKAGE_PATH)
 | |
| +message(STATUS "Using LIBVPX_PACKAGE_PATH = ${LIBVPX_PACKAGE_PATH}")
 | |
| +
 | |
| +find_library(LIBVPX_CUSTOM_LIBRARY vpxmd.lib
 | |
| +    HINTS ${LIBVPX_PACKAGE_PATH}/lib
 | |
| +    REQIRED
 | |
| +    NO_DEFAULT_PATH
 | |
| +)
 | |
| +message(STATUS "Found LIBVPX_CUSTOM_LIBRARY = ${LIBVPX_CUSTOM_LIBRARY}")
 | |
| +
 | |
| +find_path(LIBVPX_CUSTOM_INCLUDE_DIR
 | |
| +    NAMES vpx/vp8.h
 | |
| +    HINTS ${LIBVPX_PACKAGE_PATH}/include
 | |
| +    REQUIRED
 | |
| +    NO_DEFAULT_PATH
 | |
| +)
 | |
| +message(STATUS "Found LIBVPX_CUSTOM_INCLUDE_DIR = ${LIBVPX_CUSTOM_INCLUDE_DIR}")
 | |
| +# Playwright end
 | |
| +
 | |
|  set(USE_ANGLE_EGL ON)
 | |
|  set(USE_ANGLE_WEBGL ON)
 | |
|  
 | |
|  SET_AND_EXPOSE_TO_BUILD(USE_ANGLE ON)
 | |
|  SET_AND_EXPOSE_TO_BUILD(USE_CAIRO ON)
 | |
| +SET_AND_EXPOSE_TO_BUILD(USE_CF ON)
 | |
|  SET_AND_EXPOSE_TO_BUILD(USE_CURL ON)
 | |
|  SET_AND_EXPOSE_TO_BUILD(USE_GRAPHICS_LAYER_TEXTURE_MAPPER ON)
 | |
|  SET_AND_EXPOSE_TO_BUILD(USE_GRAPHICS_LAYER_WC ON)
 | |
| @@ -67,11 +89,7 @@ SET_AND_EXPOSE_TO_BUILD(ENABLE_DEVELOPER_MODE ${DEVELOPER_MODE})
 | |
|  
 | |
|  SET_AND_EXPOSE_TO_BUILD(HAVE_OS_DARK_MODE_SUPPORT 1)
 | |
|  
 | |
| -# CoreFoundation is required when building WebKitLegacy
 | |
| -if (ENABLE_WEBKIT_LEGACY)
 | |
| -    SET_AND_EXPOSE_TO_BUILD(USE_CF ON)
 | |
| -    set(COREFOUNDATION_LIBRARY CFlite)
 | |
| -endif ()
 | |
| +set(COREFOUNDATION_LIBRARY CFlite)
 | |
|  
 | |
|  add_definitions(-DWTF_PLATFORM_WIN_CAIRO=1)
 | |
|  add_definitions(-DNOCRYPT)
 | |
| diff --git a/Tools/MiniBrowser/gtk/BrowserTab.c b/Tools/MiniBrowser/gtk/BrowserTab.c
 | |
| index 1c84f30b2ea96dd0c168918f9d63773b8e2548a3..55603437900a65de7bef70563c9ec0399c5f563c 100644
 | |
| --- a/Tools/MiniBrowser/gtk/BrowserTab.c
 | |
| +++ b/Tools/MiniBrowser/gtk/BrowserTab.c
 | |
| @@ -161,6 +161,11 @@ static void loadChanged(WebKitWebView *webView, WebKitLoadEvent loadEvent, Brows
 | |
|  #endif
 | |
|  }
 | |
|  
 | |
| +static gboolean loadFailed()
 | |
| +{
 | |
| +    return TRUE;
 | |
| +}
 | |
| +
 | |
|  static GtkWidget *createInfoBarQuestionMessage(const char *title, const char *text)
 | |
|  {
 | |
|      GtkWidget *dialog = gtk_info_bar_new_with_buttons("No", GTK_RESPONSE_NO, "Yes", GTK_RESPONSE_YES, NULL);
 | |
| @@ -708,6 +713,7 @@ static void browserTabConstructed(GObject *gObject)
 | |
|      g_signal_connect(tab->webView, "notify::is-loading", G_CALLBACK(isLoadingChanged), tab);
 | |
|      g_signal_connect(tab->webView, "decide-policy", G_CALLBACK(decidePolicy), tab);
 | |
|      g_signal_connect(tab->webView, "load-changed", G_CALLBACK(loadChanged), tab);
 | |
| +    g_signal_connect(tab->webView, "load-failed", G_CALLBACK(loadFailed), tab);
 | |
|      g_signal_connect(tab->webView, "load-failed-with-tls-errors", G_CALLBACK(loadFailedWithTLSerrors), tab);
 | |
|      g_signal_connect(tab->webView, "permission-request", G_CALLBACK(decidePermissionRequest), tab);
 | |
|      g_signal_connect(tab->webView, "run-color-chooser", G_CALLBACK(runColorChooserCallback), tab);
 | |
| @@ -758,6 +764,9 @@ static char *getInternalURI(const char *uri)
 | |
|      if (g_str_has_prefix(uri, "about:") && !g_str_equal(uri, "about:blank"))
 | |
|          return g_strconcat(BROWSER_ABOUT_SCHEME, uri + strlen ("about"), NULL);
 | |
|  
 | |
| +    if (!g_str_has_prefix(uri, "http://") && !g_str_has_prefix(uri, "https://") && !g_str_has_prefix(uri, "file://"))
 | |
| +        return g_strconcat("http://", uri, NULL);
 | |
| +
 | |
|      return g_strdup(uri);
 | |
|  }
 | |
|  
 | |
| diff --git a/Tools/MiniBrowser/gtk/BrowserWindow.c b/Tools/MiniBrowser/gtk/BrowserWindow.c
 | |
| index 881609c9fe8f2b5ed6158a5972438c14fd650cf5..566568382a2983a8a823cf0a0cf2634a9848d607 100644
 | |
| --- a/Tools/MiniBrowser/gtk/BrowserWindow.c
 | |
| +++ b/Tools/MiniBrowser/gtk/BrowserWindow.c
 | |
| @@ -70,7 +70,7 @@ struct _BrowserWindowClass {
 | |
|      GtkApplicationWindowClass parent;
 | |
|  };
 | |
|  
 | |
| -static const char *defaultWindowTitle = "WebKitGTK MiniBrowser";
 | |
| +static const char *defaultWindowTitle = "🎭 Playwright";
 | |
|  static const gdouble minimumZoomLevel = 0.5;
 | |
|  static const gdouble maximumZoomLevel = 3;
 | |
|  static const gdouble defaultZoomLevel = 1;
 | |
| @@ -154,13 +154,11 @@ static void webViewURIChanged(WebKitWebView *webView, GParamSpec *pspec, Browser
 | |
|  static void webViewTitleChanged(WebKitWebView *webView, GParamSpec *pspec, BrowserWindow *window)
 | |
|  {
 | |
|      const char *title = webkit_web_view_get_title(webView);
 | |
| +    char *privateTitle = NULL;
 | |
|      if (!title)
 | |
|          title = defaultWindowTitle;
 | |
| -    char *privateTitle = NULL;
 | |
| -    if (webkit_web_view_is_controlled_by_automation(webView))
 | |
| -        privateTitle = g_strdup_printf("[Automation] %s", title);
 | |
| -    else if (webkit_web_view_is_ephemeral(webView))
 | |
| -        privateTitle = g_strdup_printf("[Private] %s", title);
 | |
| +    else
 | |
| +        privateTitle = g_strdup_printf("🎭 Playwright: %s", title);
 | |
|      gtk_window_set_title(GTK_WINDOW(window), privateTitle ? privateTitle : title);
 | |
|      g_free(privateTitle);
 | |
|  }
 | |
| @@ -493,8 +491,12 @@ static gboolean webViewDecidePolicy(WebKitWebView *webView, WebKitPolicyDecision
 | |
|          return FALSE;
 | |
|  
 | |
|      WebKitNavigationAction *navigationAction = webkit_navigation_policy_decision_get_navigation_action(WEBKIT_NAVIGATION_POLICY_DECISION(decision));
 | |
| -    if (webkit_navigation_action_get_navigation_type(navigationAction) != WEBKIT_NAVIGATION_TYPE_LINK_CLICKED
 | |
| -        || webkit_navigation_action_get_mouse_button(navigationAction) != GDK_BUTTON_MIDDLE)
 | |
| +    if (webkit_navigation_action_get_navigation_type(navigationAction) != WEBKIT_NAVIGATION_TYPE_LINK_CLICKED)
 | |
| +        return FALSE;
 | |
| +
 | |
| +    guint modifiers = webkit_navigation_action_get_modifiers(navigationAction);
 | |
| +    if (webkit_navigation_action_get_mouse_button(navigationAction) != GDK_BUTTON_MIDDLE &&
 | |
| +        (webkit_navigation_action_get_mouse_button(navigationAction) != GDK_BUTTON_PRIMARY || (modifiers & (GDK_CONTROL_MASK | GDK_SHIFT_MASK)) == 0))
 | |
|          return FALSE;
 | |
|  
 | |
|      /* Multiple tabs are not allowed in editor mode. */
 | |
| @@ -1445,6 +1447,12 @@ static gboolean browserWindowDeleteEvent(GtkWidget *widget, GdkEventAny* event)
 | |
|  }
 | |
|  #endif
 | |
|  
 | |
| +static void zeroPreferredSize(GtkWidget* widget, gint* minimumSize, gint* naturalSize)
 | |
| +{
 | |
| +    *minimumSize = 10;
 | |
| +    *naturalSize = 10;
 | |
| +}
 | |
| +
 | |
|  static void browser_window_class_init(BrowserWindowClass *klass)
 | |
|  {
 | |
|      GObjectClass *gobjectClass = G_OBJECT_CLASS(klass);
 | |
| @@ -1458,6 +1466,14 @@ static void browser_window_class_init(BrowserWindowClass *klass)
 | |
|      GtkWidgetClass *widgetClass = GTK_WIDGET_CLASS(klass);
 | |
|      widgetClass->delete_event = browserWindowDeleteEvent;
 | |
|  #endif
 | |
| +
 | |
| +// Playwrigth begin
 | |
| +    // Override preferred (which is minimum :-) size to 0 so that we can
 | |
| +    // emulate arbitrary resolution.
 | |
| +    GtkWidgetClass* browserWidgetClass = GTK_WIDGET_CLASS(klass);
 | |
| +    browserWidgetClass->get_preferred_width = zeroPreferredSize;
 | |
| +    browserWidgetClass->get_preferred_height = zeroPreferredSize;
 | |
| +// Playwrigth end
 | |
|  }
 | |
|  
 | |
|  /* Public API. */
 | |
| diff --git a/Tools/MiniBrowser/gtk/BrowserWindow.h b/Tools/MiniBrowser/gtk/BrowserWindow.h
 | |
| index 62629b4c1c25ae82bd797b39bbf9de0331f8eed2..5de7900a29b0e629f1ac404bbb0dc5b4e605294d 100644
 | |
| --- a/Tools/MiniBrowser/gtk/BrowserWindow.h
 | |
| +++ b/Tools/MiniBrowser/gtk/BrowserWindow.h
 | |
| @@ -37,7 +37,7 @@ G_BEGIN_DECLS
 | |
|  #define BROWSER_IS_WINDOW(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), BROWSER_TYPE_WINDOW))
 | |
|  #define BROWSER_IS_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),  BROWSER_TYPE_WINDOW))
 | |
|  #define BROWSER_WINDOW_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj),  BROWSER_TYPE_WINDOW, BrowserWindowClass))
 | |
| -#define BROWSER_DEFAULT_URL            "http://www.webkitgtk.org/"
 | |
| +#define BROWSER_DEFAULT_URL            "about:blank"
 | |
|  #define BROWSER_ABOUT_SCHEME           "minibrowser-about"
 | |
|  
 | |
|  typedef struct _BrowserWindow        BrowserWindow;
 | |
| diff --git a/Tools/MiniBrowser/gtk/main.c b/Tools/MiniBrowser/gtk/main.c
 | |
| index 817e8fec7e18b3fbde85aa534263def60458b1a8..e722f02eeb891538d2d5b1c2b7d4cd1c54046827 100644
 | |
| --- a/Tools/MiniBrowser/gtk/main.c
 | |
| +++ b/Tools/MiniBrowser/gtk/main.c
 | |
| @@ -57,7 +57,12 @@ static gboolean enableITP;
 | |
|  static gboolean enableSandbox;
 | |
|  static gboolean exitAfterLoad;
 | |
|  static gboolean webProcessCrashed;
 | |
| +static gboolean inspectorPipe;
 | |
| +static gboolean headless;
 | |
| +static gboolean noStartupWindow;
 | |
| +static const char *userDataDir;
 | |
|  static gboolean printVersion;
 | |
| +static GtkApplication *browserApplication = NULL;
 | |
|  
 | |
|  typedef enum {
 | |
|      MINI_BROWSER_ERROR_INVALID_ABOUT_PATH
 | |
| @@ -152,6 +157,10 @@ static const GOptionEntry commandLineOptions[] =
 | |
|      { "exit-after-load", 0, 0, G_OPTION_ARG_NONE, &exitAfterLoad, "Quit the browser after the load finishes", NULL },
 | |
|      { "time-zone", 't', 0, G_OPTION_ARG_STRING, &timeZone, "Set time zone", "TIMEZONE" },
 | |
|      { "version", 'v', 0, G_OPTION_ARG_NONE, &printVersion, "Print the WebKitGTK version", NULL },
 | |
| +    { "inspector-pipe", 0, 0, G_OPTION_ARG_NONE, &inspectorPipe, "Open pipe connection to the remote inspector", NULL },
 | |
| +    { "user-data-dir", 0, 0, G_OPTION_ARG_STRING, &userDataDir, "Default profile persistence folder location", NULL },
 | |
| +    { "headless", 0, 0, G_OPTION_ARG_NONE, &headless, "Noop headless operation", NULL },
 | |
| +    { "no-startup-window", 0, 0, G_OPTION_ARG_NONE, &noStartupWindow, "Do not open default page", NULL },
 | |
|      { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &uriArguments, 0, "[URL…]" },
 | |
|      { 0, 0, 0, 0, 0, 0, 0 }
 | |
|  };
 | |
| @@ -620,6 +629,57 @@ static void filterSavedCallback(WebKitUserContentFilterStore *store, GAsyncResul
 | |
|      g_main_loop_quit(data->mainLoop);
 | |
|  }
 | |
|  
 | |
| +static WebKitSettings* createPlaywrightSettings() {
 | |
| +    WebKitSettings* webkitSettings = webkit_settings_new();
 | |
| +    // Playwright: revert to the default state before https://github.com/WebKit/WebKit/commit/a73a25b9ea9229987c8fa7b2e092e6324cb17913
 | |
| +    webkit_settings_set_hardware_acceleration_policy(webkitSettings, WEBKIT_HARDWARE_ACCELERATION_POLICY_NEVER);
 | |
| +    webkit_settings_set_hardware_acceleration_policy(webkitSettings, WEBKIT_HARDWARE_ACCELERATION_POLICY_ON_DEMAND);
 | |
| +    return webkitSettings;
 | |
| +}
 | |
| +
 | |
| +static WebKitWebContext *persistentWebContext = NULL;
 | |
| +
 | |
| +static WebKitWebView *createNewPage(WebKitBrowserInspector *browser_inspector, WebKitWebContext *context)
 | |
| +{
 | |
| +    if (context == NULL)
 | |
| +        context = persistentWebContext;
 | |
| +
 | |
| +    WebKitWebView *newWebView = WEBKIT_WEB_VIEW(g_object_new(WEBKIT_TYPE_WEB_VIEW,
 | |
| +        "web-context", context,
 | |
| +        "settings", createPlaywrightSettings(),
 | |
| +        "is-ephemeral", webkit_web_context_is_ephemeral(context),
 | |
| +        "is-controlled-by-automation", TRUE,
 | |
| +        NULL));
 | |
| +    GtkWidget *newWindow = browser_window_new(NULL, context);
 | |
| +    gtk_window_set_application(GTK_WINDOW(newWindow), browserApplication);
 | |
| +    browser_window_append_view(BROWSER_WINDOW(newWindow), newWebView);
 | |
| +    gtk_widget_grab_focus(GTK_WIDGET(newWebView));
 | |
| +    gtk_widget_show(GTK_WIDGET(newWindow));
 | |
| +    webkit_web_view_load_uri(newWebView, "about:blank");
 | |
| +    return newWebView;
 | |
| +}
 | |
| +
 | |
| +static void quitBroserApplication(WebKitBrowserInspector* browser_inspector)
 | |
| +{
 | |
| +    g_application_release(G_APPLICATION(browserApplication));
 | |
| +}
 | |
| +
 | |
| +static void keepApplicationAliveUntilQuit(GApplication *application)
 | |
| +{
 | |
| +    // Reference the application, it will be released in quitBroserApplication.
 | |
| +    g_application_hold(application);
 | |
| +    WebKitBrowserInspector* browserInspector = webkit_browser_inspector_get_default();
 | |
| +    g_signal_connect(browserInspector, "quit-application", G_CALLBACK(quitBroserApplication), NULL);
 | |
| +}
 | |
| +
 | |
| +static void configureBrowserInspectorPipe()
 | |
| +{
 | |
| +    WebKitBrowserInspector* browserInspector = webkit_browser_inspector_get_default();
 | |
| +    g_signal_connect(browserInspector, "create-new-page", G_CALLBACK(createNewPage), NULL);
 | |
| + 
 | |
| +    webkit_browser_inspector_initialize_pipe(proxy, ignoreHosts);
 | |
| +}
 | |
| +
 | |
|  static void startup(GApplication *application)
 | |
|  {
 | |
|      const char *actionAccels[] = {
 | |
| @@ -650,10 +710,22 @@ static void startup(GApplication *application)
 | |
|  
 | |
|  static void activate(GApplication *application, WebKitSettings *webkitSettings)
 | |
|  {
 | |
| +    if (inspectorPipe)
 | |
| +        configureBrowserInspectorPipe();
 | |
| +
 | |
| +    if (noStartupWindow) {
 | |
| +        keepApplicationAliveUntilQuit(application);
 | |
| +        g_clear_object(&webkitSettings);
 | |
| +        return;
 | |
| +    }
 | |
| +
 | |
|      WebKitWebsiteDataManager *manager;
 | |
| -    if (privateMode || automationMode)
 | |
| +    if (userDataDir) {
 | |
| +        manager = webkit_website_data_manager_new("base-data-directory", userDataDir, "base-cache-directory", userDataDir, NULL);
 | |
| +        cookiesFile = g_build_filename(userDataDir, "cookies.txt", NULL);
 | |
| +    } else if (inspectorPipe || privateMode || automationMode) {
 | |
|          manager = webkit_website_data_manager_new_ephemeral();
 | |
| -    else {
 | |
| +    } else {
 | |
|          char *dataDirectory = g_build_filename(g_get_user_data_dir(), "webkitgtk-" WEBKITGTK_API_VERSION_STRING, "MiniBrowser", NULL);
 | |
|          char *cacheDirectory = g_build_filename(g_get_user_cache_dir(), "webkitgtk-" WEBKITGTK_API_VERSION_STRING, "MiniBrowser", NULL);
 | |
|          manager = webkit_website_data_manager_new("base-data-directory", dataDirectory, "base-cache-directory", cacheDirectory, NULL);
 | |
| @@ -678,6 +750,7 @@ static void activate(GApplication *application, WebKitSettings *webkitSettings)
 | |
|  #endif
 | |
|          "time-zone-override", timeZone,
 | |
|          NULL);
 | |
| +    persistentWebContext = webContext;
 | |
|      g_object_unref(manager);
 | |
|  
 | |
|      if (enableSandbox)
 | |
| @@ -759,9 +832,7 @@ static void activate(GApplication *application, WebKitSettings *webkitSettings)
 | |
|                  if (exitAfterLoad)
 | |
|                      exitAfterWebViewLoadFinishes(webView, application);
 | |
|              }
 | |
| -            gchar *url = argumentToURL(uriArguments[i]);
 | |
| -            webkit_web_view_load_uri(webView, url);
 | |
| -            g_free(url);
 | |
| +            webkit_web_view_load_uri(webView, uriArguments[i]);
 | |
|          }
 | |
|      } else {
 | |
|          WebKitWebView *webView = createBrowserTab(mainWindow, webkitSettings, userContentManager, defaultWebsitePolicies);
 | |
| @@ -805,7 +876,7 @@ int main(int argc, char *argv[])
 | |
|      g_option_context_add_group(context, gtk_get_option_group(TRUE));
 | |
|  #endif
 | |
|  
 | |
| -    WebKitSettings *webkitSettings = webkit_settings_new();
 | |
| +    WebKitSettings *webkitSettings = createPlaywrightSettings();
 | |
|      webkit_settings_set_enable_developer_extras(webkitSettings, TRUE);
 | |
|      webkit_settings_set_enable_webgl(webkitSettings, TRUE);
 | |
|      webkit_settings_set_enable_media_stream(webkitSettings, TRUE);
 | |
| @@ -837,9 +908,11 @@ int main(int argc, char *argv[])
 | |
|      }
 | |
|  
 | |
|      GtkApplication *application = gtk_application_new("org.webkitgtk.MiniBrowser", G_APPLICATION_NON_UNIQUE);
 | |
| +    browserApplication = application;
 | |
|      g_signal_connect(application, "startup", G_CALLBACK(startup), NULL);
 | |
|      g_signal_connect(application, "activate", G_CALLBACK(activate), webkitSettings);
 | |
|      g_application_run(G_APPLICATION(application), 0, NULL);
 | |
| +    browserApplication = NULL;
 | |
|      g_object_unref(application);
 | |
|  
 | |
|      return exitAfterLoad && webProcessCrashed ? 1 : 0;
 | |
| diff --git a/Tools/MiniBrowser/wpe/main.cpp b/Tools/MiniBrowser/wpe/main.cpp
 | |
| index cd1d3647c8bfaa6cc9642ce63060a5aa6c594791..1e0516b437d01e8af70da1e8865b7840514522e7 100644
 | |
| --- a/Tools/MiniBrowser/wpe/main.cpp
 | |
| +++ b/Tools/MiniBrowser/wpe/main.cpp
 | |
| @@ -41,6 +41,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;
 | |
| @@ -66,6 +69,9 @@ static const GOptionEntry commandLineOptions[] =
 | |
|      { "enable-itp", 0, 0, G_OPTION_ARG_NONE, &enableITP, "Enable Intelligent Tracking Prevention (ITP)", nullptr },
 | |
|      { "time-zone", 't', 0, G_OPTION_ARG_STRING, &timeZone, "Set time zone", "TIMEZONE" },
 | |
|      { "version", 'v', 0, G_OPTION_ARG_NONE, &printVersion, "Print the WPE version", nullptr },
 | |
| +    { "inspector-pipe", 'v', 0, G_OPTION_ARG_NONE, &inspectorPipe, "Expose remote debugging protocol over pipe", nullptr },
 | |
| +    { "user-data-dir", 0, 0, G_OPTION_ARG_STRING, &userDataDir, "Default profile persistence folder location", "FILE" },
 | |
| +    { "no-startup-window", 0, 0, G_OPTION_ARG_NONE, &noStartupWindow, "Do not open default page", nullptr },
 | |
|      { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &uriArguments, nullptr, "[URL]" },
 | |
|      { nullptr, 0, 0, G_OPTION_ARG_NONE, nullptr, nullptr, nullptr }
 | |
|  };
 | |
| @@ -150,13 +156,36 @@ static void filterSavedCallback(WebKitUserContentFilterStore *store, GAsyncResul
 | |
|      g_main_loop_quit(data->mainLoop);
 | |
|  }
 | |
|  
 | |
| +static gboolean webViewLoadFailed()
 | |
| +{
 | |
| +    return TRUE;
 | |
| +}
 | |
| +
 | |
|  static void webViewClose(WebKitWebView* webView, gpointer)
 | |
|  {
 | |
|      // Hash table key delete func takes care of unref'ing the view
 | |
|      g_hash_table_remove(openViews, webView);
 | |
|  }
 | |
|  
 | |
| -static WebKitWebView* createWebView(WebKitWebView* webView, WebKitNavigationAction*, gpointer)
 | |
| +static gboolean scriptDialog(WebKitWebView*, WebKitScriptDialog* dialog, gpointer)
 | |
| +{
 | |
| +    if (inspectorPipe)
 | |
| +        webkit_script_dialog_ref(dialog);
 | |
| +    return TRUE;
 | |
| +}
 | |
| +
 | |
| +static gboolean scriptDialogHandled(WebKitWebView*, WebKitScriptDialog* dialog, gpointer)
 | |
| +{
 | |
| +    if (inspectorPipe)
 | |
| +        webkit_script_dialog_unref(dialog);
 | |
| +    return TRUE;
 | |
| +}
 | |
| +
 | |
| +static gboolean webViewDecidePolicy(WebKitWebView *webView, WebKitPolicyDecision *decision, WebKitPolicyDecisionType decisionType, gpointer);
 | |
| +
 | |
| +static WebKitWebView* createWebView(WebKitWebView* webView, WebKitNavigationAction*, gpointer);
 | |
| +
 | |
| +static WebKitWebView* createWebViewImpl(WebKitWebView* webView, WebKitWebContext *webContext)
 | |
|  {
 | |
|      auto backend = createViewBackend(1280, 720);
 | |
|      struct wpe_view_backend* wpeBackend = backend->backend();
 | |
| @@ -168,17 +197,88 @@ static WebKitWebView* createWebView(WebKitWebView* webView, WebKitNavigationActi
 | |
|              delete static_cast<WPEToolingBackends::ViewBackend*>(data);
 | |
|          }, backend.release());
 | |
|  
 | |
| -    auto* newWebView = webkit_web_view_new_with_related_view(viewBackend, webView);
 | |
| -    webkit_web_view_set_settings(newWebView, webkit_web_view_get_settings(webView));
 | |
| +// Playwright begin
 | |
| +    if (headlessMode) {
 | |
| +        webkit_web_view_backend_set_screenshot_callback(viewBackend,
 | |
| +            [](gpointer data) {
 | |
| +                return static_cast<WPEToolingBackends::HeadlessViewBackend*>(data)->snapshot();
 | |
| +            });
 | |
| +    }
 | |
| +// Playwright end
 | |
| +    WebKitWebView* newWebView;
 | |
| +    if (webView) {
 | |
| +        newWebView = webkit_web_view_new_with_related_view(viewBackend, webView);
 | |
| +    } else {
 | |
| +        newWebView = WEBKIT_WEB_VIEW(g_object_new(WEBKIT_TYPE_WEB_VIEW,
 | |
| +            "backend", viewBackend,
 | |
| +            "web-context", webContext,
 | |
| +            nullptr));
 | |
| +    }
 | |
|  
 | |
|      g_signal_connect(newWebView, "create", G_CALLBACK(createWebView), nullptr);
 | |
|      g_signal_connect(newWebView, "close", G_CALLBACK(webViewClose), nullptr);
 | |
|  
 | |
|      g_hash_table_add(openViews, newWebView);
 | |
|  
 | |
| +    g_signal_connect(newWebView, "load-failed", G_CALLBACK(webViewLoadFailed), nullptr);
 | |
| +    g_signal_connect(newWebView, "script-dialog", G_CALLBACK(scriptDialog), nullptr);
 | |
| +    g_signal_connect(newWebView, "script-dialog-handled", G_CALLBACK(scriptDialogHandled), nullptr);
 | |
| +    g_signal_connect(newWebView, "decide-policy", G_CALLBACK(webViewDecidePolicy), nullptr);
 | |
|      return newWebView;
 | |
|  }
 | |
|  
 | |
| +static WebKitWebView* createWebView(WebKitWebView* webView, WebKitNavigationAction*, gpointer)
 | |
| +{
 | |
| +    return createWebViewImpl(webView, nullptr);
 | |
| +}
 | |
| +
 | |
| +static gboolean webViewDecidePolicy(WebKitWebView *webView, WebKitPolicyDecision *decision, WebKitPolicyDecisionType decisionType, gpointer)
 | |
| +{
 | |
| +    if (decisionType != WEBKIT_POLICY_DECISION_TYPE_NAVIGATION_ACTION)
 | |
| +        return FALSE;
 | |
| +
 | |
| +    WebKitNavigationAction *navigationAction = webkit_navigation_policy_decision_get_navigation_action(WEBKIT_NAVIGATION_POLICY_DECISION(decision));
 | |
| +    if (webkit_navigation_action_get_navigation_type(navigationAction) != WEBKIT_NAVIGATION_TYPE_LINK_CLICKED)
 | |
| +        return FALSE;
 | |
| +
 | |
| +    guint modifiers = webkit_navigation_action_get_modifiers(navigationAction);
 | |
| +    if (webkit_navigation_action_get_mouse_button(navigationAction) != 2 /* GDK_BUTTON_MIDDLE */ &&
 | |
| +        (webkit_navigation_action_get_mouse_button(navigationAction) != 1 /* GDK_BUTTON_PRIMARY */ || (modifiers & (wpe_input_keyboard_modifier_control | wpe_input_keyboard_modifier_shift)) == 0))
 | |
| +        return FALSE;
 | |
| +
 | |
| +    /* Open a new tab if link clicked with the middle button, shift+click or ctrl+click. */
 | |
| +    WebKitWebView* newWebView = createWebViewImpl(nullptr, webkit_web_view_get_context(webView));
 | |
| +    webkit_web_view_load_request(newWebView, webkit_navigation_action_get_request(navigationAction));
 | |
| +
 | |
| +    webkit_policy_decision_ignore(decision);
 | |
| +    return TRUE;
 | |
| +}
 | |
| +
 | |
| +static WebKitWebContext *persistentWebContext = NULL;
 | |
| +
 | |
| +static WebKitWebView* createNewPage(WebKitBrowserInspector*, WebKitWebContext *webContext)
 | |
| +{
 | |
| +    if (!webContext)
 | |
| +        webContext = persistentWebContext;
 | |
| +    WebKitWebView* webView = createWebViewImpl(nullptr, webContext);
 | |
| +    webkit_web_view_load_uri(webView, "about:blank");
 | |
| +    return webView;
 | |
| +}
 | |
| +
 | |
| +static void quitBroserApplication(WebKitBrowserInspector* browser_inspector, gpointer data)
 | |
| +{
 | |
| +    GMainLoop* mainLoop = static_cast<GMainLoop*>(data);
 | |
| +    g_main_loop_quit(mainLoop);
 | |
| +}
 | |
| +
 | |
| +static void configureBrowserInspector(GMainLoop* mainLoop)
 | |
| +{
 | |
| +    WebKitBrowserInspector* browserInspector = webkit_browser_inspector_get_default();
 | |
| +    g_signal_connect(browserInspector, "create-new-page", G_CALLBACK(createNewPage), NULL);
 | |
| +    g_signal_connect(browserInspector, "quit-application", G_CALLBACK(quitBroserApplication), mainLoop);
 | |
| +    webkit_browser_inspector_initialize_pipe(proxy, ignoreHosts);
 | |
| +}
 | |
| +
 | |
|  int main(int argc, char *argv[])
 | |
|  {
 | |
|  #if ENABLE_DEVELOPER_MODE
 | |
| @@ -210,6 +310,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 +329,15 @@ int main(int argc, char *argv[])
 | |
|          return 1;
 | |
|      }
 | |
|  
 | |
| -    auto* manager = (privateMode || automationMode) ? webkit_website_data_manager_new_ephemeral() : webkit_website_data_manager_new(nullptr);
 | |
| +    WebKitWebsiteDataManager *manager;
 | |
| +    if (userDataDir) {
 | |
| +        manager = webkit_website_data_manager_new("base-data-directory", userDataDir, "base-cache-directory", userDataDir, NULL);
 | |
| +        cookiesFile = g_build_filename(userDataDir, "cookies.txt", NULL);
 | |
| +    } else if (inspectorPipe || privateMode || automationMode) {
 | |
| +        manager = webkit_website_data_manager_new_ephemeral();
 | |
| +    } else {
 | |
| +        manager = webkit_website_data_manager_new(NULL);
 | |
| +    }
 | |
|      webkit_website_data_manager_set_itp_enabled(manager, enableITP);
 | |
|  
 | |
|      if (proxy) {
 | |
| @@ -232,6 +350,7 @@ int main(int argc, char *argv[])
 | |
|          webkit_website_data_manager_set_tls_errors_policy(manager, WEBKIT_TLS_ERRORS_POLICY_IGNORE);
 | |
|  
 | |
|      auto* webContext = WEBKIT_WEB_CONTEXT(g_object_new(WEBKIT_TYPE_WEB_CONTEXT, "website-data-manager", manager, "time-zone-override", timeZone, nullptr));
 | |
| +    persistentWebContext = webContext;
 | |
|      g_object_unref(manager);
 | |
|  
 | |
|      if (cookiesPolicy) {
 | |
| @@ -290,7 +409,14 @@ int main(int argc, char *argv[])
 | |
|      auto* viewBackend = webkit_web_view_backend_new(wpeBackend, [](gpointer data) {
 | |
|          delete static_cast<WPEToolingBackends::ViewBackend*>(data);
 | |
|      }, backend.release());
 | |
| -
 | |
| +// Playwright begin
 | |
| +    if (headlessMode) {
 | |
| +        webkit_web_view_backend_set_screenshot_callback(viewBackend,
 | |
| +            [](gpointer data) {
 | |
| +                return static_cast<WPEToolingBackends::HeadlessViewBackend*>(data)->snapshot();
 | |
| +            });
 | |
| +    }
 | |
| +// Playwright end
 | |
|      auto* webView = WEBKIT_WEB_VIEW(g_object_new(WEBKIT_TYPE_WEB_VIEW,
 | |
|          "backend", viewBackend,
 | |
|          "web-context", webContext,
 | |
| @@ -307,8 +433,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);
 | |
| @@ -321,16 +445,9 @@ int main(int argc, char *argv[])
 | |
|          webkit_web_view_set_background_color(webView, &color);
 | |
|  
 | |
|      if (uriArguments) {
 | |
| -        const char* uri = uriArguments[0];
 | |
| -        if (g_str_equal(uri, "about:gpu"))
 | |
| -            uri = "webkit://gpu";
 | |
| -
 | |
| -        GFile* file = g_file_new_for_commandline_arg(uri);
 | |
| -        char* url = g_file_get_uri(file);
 | |
| -        g_object_unref(file);
 | |
| -        webkit_web_view_load_uri(webView, url);
 | |
| -        g_free(url);
 | |
| -    } else if (automationMode)
 | |
| +        // Playwright: avoid weird url transformation like http://trac.webkit.org/r240840
 | |
| +        webkit_web_view_load_uri(webView, uriArguments[0]);
 | |
| +    } else if (automationMode || inspectorPipe)
 | |
|          webkit_web_view_load_uri(webView, "about:blank");
 | |
|      else
 | |
|          webkit_web_view_load_uri(webView, "https://wpewebkit.org");
 | |
| @@ -340,8 +457,7 @@ int main(int argc, char *argv[])
 | |
|      g_hash_table_destroy(openViews);
 | |
|  
 | |
|  
 | |
| -    if (privateMode || automationMode)
 | |
| -        g_object_unref(webContext);
 | |
| +    g_object_unref(webContext);
 | |
|      g_main_loop_unref(loop);
 | |
|  
 | |
|      return 0;
 | |
| diff --git a/Tools/PlatformWin.cmake b/Tools/PlatformWin.cmake
 | |
| index ef4407cfc114e602d98ed81724da504f453e258f..448dd483715162baba484f756fbcc1d72de4ba0c 100644
 | |
| --- a/Tools/PlatformWin.cmake
 | |
| +++ b/Tools/PlatformWin.cmake
 | |
| @@ -12,4 +12,5 @@ endif ()
 | |
|  
 | |
|  if (ENABLE_WEBKIT)
 | |
|      add_subdirectory(WebKitTestRunner)
 | |
| +    add_subdirectory(Playwright/win)
 | |
|  endif ()
 | |
| diff --git a/Tools/Scripts/build-webkit b/Tools/Scripts/build-webkit
 | |
| index 00664ad09f902ba55d79426ac3c3a472670529d0..1c12f1969fcc5bc0ce9bbd0931febbc01aa60d49 100755
 | |
| --- a/Tools/Scripts/build-webkit
 | |
| +++ b/Tools/Scripts/build-webkit
 | |
| @@ -252,7 +252,7 @@ if (isAppleCocoaWebKit()) {
 | |
|          push @projects, ("Source/WebKit");
 | |
|  
 | |
|          if (!isEmbeddedWebKit()) {
 | |
| -            push @projects, ("Tools/MiniBrowser");
 | |
| +            push @projects, ("Tools/Playwright");
 | |
|  
 | |
|              # WebInspectorUI must come after JavaScriptCore and WebCore but before WebKit and WebKit2
 | |
|              my $webKitIndex = first { $projects[$_] eq "Source/WebKitLegacy" } 0..$#projects;
 | |
| diff --git a/Tools/WebKitTestRunner/InjectedBundle/empty/AccessibilityControllerEmpty.cpp b/Tools/WebKitTestRunner/InjectedBundle/empty/AccessibilityControllerEmpty.cpp
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..3618075f10824beb0bc6cd8070772ab88f4e51c8
 | |
| --- /dev/null
 | |
| +++ b/Tools/WebKitTestRunner/InjectedBundle/empty/AccessibilityControllerEmpty.cpp
 | |
| @@ -0,0 +1,84 @@
 | |
| +/*
 | |
| + * Copyright (C) 2022 Microsoft Corporation.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
| + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#include "config.h"
 | |
| +
 | |
| +#if !USE(ATSPI) && !USE(ATK)
 | |
| +
 | |
| +#include "AccessibilityController.h"
 | |
| +#include "AccessibilityUIElement.h"
 | |
| +#include <WebCore/NotImplemented.h>
 | |
| +
 | |
| +namespace WTR {
 | |
| +
 | |
| +void AccessibilityController::resetToConsistentState()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +}
 | |
| +
 | |
| +RefPtr<AccessibilityUIElement> AccessibilityController::accessibleElementById(JSStringRef id)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityController::platformName()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +void AccessibilityController::injectAccessibilityPreference(JSStringRef domain, JSStringRef key, JSStringRef value)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +}
 | |
| +
 | |
| +Ref<AccessibilityUIElement> AccessibilityController::rootElement()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return AccessibilityUIElement::create(nullptr);
 | |
| +}
 | |
| +
 | |
| +RefPtr<AccessibilityUIElement> AccessibilityController::focusedElement()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +bool AccessibilityController::addNotificationListener(JSValueRef)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return false;
 | |
| +}
 | |
| +
 | |
| +bool AccessibilityController::removeNotificationListener()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return false;
 | |
| +}
 | |
| +
 | |
| +} // namespace WTR
 | |
| +
 | |
| +#endif // USE(ATSPI)
 | |
| diff --git a/Tools/WebKitTestRunner/InjectedBundle/empty/AccessibilityUIElementEmpty.cpp b/Tools/WebKitTestRunner/InjectedBundle/empty/AccessibilityUIElementEmpty.cpp
 | |
| new file mode 100644
 | |
| index 0000000000000000000000000000000000000000..b52141c28ad89e0486d3bbdae5f9f86dc88f5f3f
 | |
| --- /dev/null
 | |
| +++ b/Tools/WebKitTestRunner/InjectedBundle/empty/AccessibilityUIElementEmpty.cpp
 | |
| @@ -0,0 +1,1026 @@
 | |
| +/*
 | |
| + * Copyright (C) 2022 Microsoft Corporation.
 | |
| + *
 | |
| + * Redistribution and use in source and binary forms, with or without
 | |
| + * modification, are permitted provided that the following conditions
 | |
| + * are met:
 | |
| + * 1. Redistributions of source code must retain the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer.
 | |
| + * 2. Redistributions in binary form must reproduce the above copyright
 | |
| + *    notice, this list of conditions and the following disclaimer in the
 | |
| + *    documentation and/or other materials provided with the distribution.
 | |
| + *
 | |
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
| + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| + */
 | |
| +
 | |
| +#include "config.h"
 | |
| +#include "AccessibilityUIElement.h"
 | |
| +
 | |
| +#if !USE(ATSPI) && !USE(ATK)
 | |
| +
 | |
| +#include <WebCore/NotImplemented.h>
 | |
| +
 | |
| +namespace WTR {
 | |
| +
 | |
| +AccessibilityUIElement::AccessibilityUIElement(PlatformUIElement)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +}
 | |
| +
 | |
| +AccessibilityUIElement::AccessibilityUIElement(const AccessibilityUIElement&)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +}
 | |
| +
 | |
| +AccessibilityUIElement::~AccessibilityUIElement()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +}
 | |
| +
 | |
| +bool AccessibilityUIElement::isEqual(AccessibilityUIElement*)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return false;
 | |
| +}
 | |
| +
 | |
| +void AccessibilityUIElement::getChildren(Vector<RefPtr<AccessibilityUIElement>>&)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +}
 | |
| +
 | |
| +void AccessibilityUIElement::getChildrenWithRange(Vector<RefPtr<AccessibilityUIElement>>&, unsigned, unsigned)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +}
 | |
| +
 | |
| +int AccessibilityUIElement::childrenCount()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return 0;
 | |
| +}
 | |
| +
 | |
| +RefPtr<AccessibilityUIElement> AccessibilityUIElement::elementAtPoint(int, int)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +unsigned AccessibilityUIElement::indexOfChild(AccessibilityUIElement*)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return 0;
 | |
| +}
 | |
| +
 | |
| +
 | |
| +RefPtr<AccessibilityUIElement> AccessibilityUIElement::childAtIndex(unsigned)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +RefPtr<AccessibilityUIElement> AccessibilityUIElement::linkedUIElementAtIndex(unsigned)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +RefPtr<AccessibilityUIElement> AccessibilityUIElement::ariaOwnsElementAtIndex(unsigned)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +RefPtr<AccessibilityUIElement> AccessibilityUIElement::ariaFlowToElementAtIndex(unsigned)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +RefPtr<AccessibilityUIElement> AccessibilityUIElement::ariaControlsElementAtIndex(unsigned)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +RefPtr<AccessibilityUIElement> AccessibilityUIElement::disclosedRowAtIndex(unsigned)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +RefPtr<AccessibilityUIElement> AccessibilityUIElement::rowAtIndex(unsigned)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +RefPtr<AccessibilityUIElement> AccessibilityUIElement::selectedChildAtIndex(unsigned) const
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +unsigned AccessibilityUIElement::selectedChildrenCount() const
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return 0;
 | |
| +}
 | |
| +
 | |
| +RefPtr<AccessibilityUIElement> AccessibilityUIElement::selectedRowAtIndex(unsigned)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +RefPtr<AccessibilityUIElement> AccessibilityUIElement::titleUIElement()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +RefPtr<AccessibilityUIElement> AccessibilityUIElement::parentElement()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +RefPtr<AccessibilityUIElement> AccessibilityUIElement::disclosedByRow()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfLinkedUIElements()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfDocumentLinks()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfChildren()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::allAttributes()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::stringAttributeValue(JSStringRef)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::currentStateValue() const
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::stringDescriptionOfAttributeValue(JSStringRef)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +double AccessibilityUIElement::numberAttributeValue(JSStringRef attribute)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return 0;
 | |
| +}
 | |
| +
 | |
| +JSValueRef AccessibilityUIElement::uiElementArrayAttributeValue(JSStringRef attribute) const
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +JSValueRef AccessibilityUIElement::rowHeaders() const
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +JSValueRef AccessibilityUIElement::columnHeaders() const
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +RefPtr<AccessibilityUIElement> AccessibilityUIElement::uiElementAttributeValue(JSStringRef attribute) const
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +bool AccessibilityUIElement::boolAttributeValue(JSStringRef attribute)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return false;
 | |
| +}
 | |
| +
 | |
| +bool AccessibilityUIElement::isAttributeSettable(JSStringRef attribute)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return false;
 | |
| +}
 | |
| +
 | |
| +bool AccessibilityUIElement::isAttributeSupported(JSStringRef attribute)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return false;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::parameterizedAttributeNames()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::role()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::subrole()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::roleDescription()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::computedRoleString()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::title()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::description()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::orientation() const
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::stringValue()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::language()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::helpText() const
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +double AccessibilityUIElement::x()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return 0;
 | |
| +}
 | |
| +
 | |
| +double AccessibilityUIElement::y()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return 0;
 | |
| +}
 | |
| +
 | |
| +double AccessibilityUIElement::width()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return 0;
 | |
| +}
 | |
| +
 | |
| +double AccessibilityUIElement::height()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return 0;
 | |
| +}
 | |
| +
 | |
| +double AccessibilityUIElement::clickPointX()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return 0;
 | |
| +}
 | |
| +
 | |
| +double AccessibilityUIElement::clickPointY()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return 0;
 | |
| +}
 | |
| +
 | |
| +double AccessibilityUIElement::intValue() const
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return 0;
 | |
| +}
 | |
| +
 | |
| +double AccessibilityUIElement::minValue()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return 0;
 | |
| +}
 | |
| +
 | |
| +double AccessibilityUIElement::maxValue()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return 0;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::valueDescription()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +int AccessibilityUIElement::insertionPointLineNumber()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return 0;
 | |
| +}
 | |
| +
 | |
| +bool AccessibilityUIElement::isPressActionSupported()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return false;
 | |
| +}
 | |
| +
 | |
| +bool AccessibilityUIElement::isIncrementActionSupported()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return false;
 | |
| +}
 | |
| +
 | |
| +bool AccessibilityUIElement::isDecrementActionSupported()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return false;
 | |
| +}
 | |
| +
 | |
| +bool AccessibilityUIElement::isBusy() const
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return false;
 | |
| +}
 | |
| +
 | |
| +bool AccessibilityUIElement::isEnabled()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return false;
 | |
| +}
 | |
| +
 | |
| +bool AccessibilityUIElement::isRequired() const
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return false;
 | |
| +}
 | |
| +
 | |
| +bool AccessibilityUIElement::isFocused() const
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return false;
 | |
| +}
 | |
| +
 | |
| +bool AccessibilityUIElement::isSelected() const
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return false;
 | |
| +}
 | |
| +
 | |
| +bool AccessibilityUIElement::isSelectedOptionActive() const
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return false;
 | |
| +}
 | |
| +
 | |
| +bool AccessibilityUIElement::isExpanded() const
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return false;
 | |
| +}
 | |
| +
 | |
| +bool AccessibilityUIElement::isChecked() const
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return false;
 | |
| +}
 | |
| +
 | |
| +bool AccessibilityUIElement::isIndeterminate() const
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return false;
 | |
| +}
 | |
| +
 | |
| +int AccessibilityUIElement::hierarchicalLevel() const
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return 0;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::speakAs()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +bool AccessibilityUIElement::ariaIsGrabbed() const
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return false;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::ariaDropEffects() const
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +int AccessibilityUIElement::lineForIndex(int)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return 0;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::rangeForLine(int)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::rangeForPosition(int, int)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::boundsForRange(unsigned, unsigned)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::stringForRange(unsigned, unsigned)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::attributedStringForRange(unsigned, unsigned)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +bool AccessibilityUIElement::attributedStringRangeIsMisspelled(unsigned, unsigned)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return false;
 | |
| +}
 | |
| +
 | |
| +unsigned AccessibilityUIElement::uiElementCountForSearchPredicate(JSContextRef, AccessibilityUIElement*, bool, JSValueRef, JSStringRef, bool, bool)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return 0;
 | |
| +}
 | |
| +
 | |
| +RefPtr<AccessibilityUIElement> AccessibilityUIElement::uiElementForSearchPredicate(JSContextRef, AccessibilityUIElement*, bool, JSValueRef, JSStringRef, bool, bool)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::selectTextWithCriteria(JSContextRef, JSStringRef, JSValueRef, JSStringRef, JSStringRef)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfColumnHeaders()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfRowHeaders()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfColumns()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfRows()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfVisibleCells()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfHeader()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +int AccessibilityUIElement::rowCount()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return 0;
 | |
| +}
 | |
| +
 | |
| +int AccessibilityUIElement::columnCount()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return 0;
 | |
| +}
 | |
| +
 | |
| +int AccessibilityUIElement::indexInTable()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return 0;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::rowIndexRange()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::columnIndexRange()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +RefPtr<AccessibilityUIElement> AccessibilityUIElement::cellForColumnAndRow(unsigned, unsigned)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +RefPtr<AccessibilityUIElement> AccessibilityUIElement::horizontalScrollbar() const
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +RefPtr<AccessibilityUIElement> AccessibilityUIElement::verticalScrollbar() const
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::selectedTextRange()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +bool AccessibilityUIElement::setSelectedTextRange(unsigned, unsigned)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return false;
 | |
| +}
 | |
| +
 | |
| +void AccessibilityUIElement::increment()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +}
 | |
| +
 | |
| +void AccessibilityUIElement::decrement()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +}
 | |
| +
 | |
| +void AccessibilityUIElement::showMenu()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +}
 | |
| +
 | |
| +void AccessibilityUIElement::press()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +}
 | |
| +
 | |
| +void AccessibilityUIElement::setSelectedChild(AccessibilityUIElement* element) const
 | |
| +{
 | |
| +    notImplemented();
 | |
| +}
 | |
| +
 | |
| +void AccessibilityUIElement::setSelectedChildAtIndex(unsigned index) const
 | |
| +{
 | |
| +    notImplemented();
 | |
| +}
 | |
| +
 | |
| +void AccessibilityUIElement::removeSelectionAtIndex(unsigned index) const
 | |
| +{
 | |
| +    notImplemented();
 | |
| +}
 | |
| +
 | |
| +void AccessibilityUIElement::clearSelectedChildren() const
 | |
| +{
 | |
| +    notImplemented();
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::accessibilityValue() const
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::documentEncoding()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::documentURI()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::url()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +bool AccessibilityUIElement::addNotificationListener(JSValueRef functionCallback)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return false;
 | |
| +}
 | |
| +
 | |
| +bool AccessibilityUIElement::removeNotificationListener()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return false;
 | |
| +}
 | |
| +
 | |
| +bool AccessibilityUIElement::isFocusable() const
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return false;
 | |
| +}
 | |
| +
 | |
| +bool AccessibilityUIElement::isSelectable() const
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return false;
 | |
| +}
 | |
| +
 | |
| +bool AccessibilityUIElement::isMultiSelectable() const
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return false;
 | |
| +}
 | |
| +
 | |
| +bool AccessibilityUIElement::isVisible() const
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return false;
 | |
| +}
 | |
| +
 | |
| +bool AccessibilityUIElement::isOffScreen() const
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return false;
 | |
| +}
 | |
| +
 | |
| +bool AccessibilityUIElement::isCollapsed() const
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return false;
 | |
| +}
 | |
| +
 | |
| +bool AccessibilityUIElement::isIgnored() const
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return false;
 | |
| +}
 | |
| +
 | |
| +bool AccessibilityUIElement::isSingleLine() const
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return false;
 | |
| +}
 | |
| +
 | |
| +bool AccessibilityUIElement::isMultiLine() const
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return false;
 | |
| +}
 | |
| +
 | |
| +bool AccessibilityUIElement::hasPopup() const
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return false;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::popupValue() const
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +void AccessibilityUIElement::takeFocus()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +}
 | |
| +
 | |
| +void AccessibilityUIElement::takeSelection()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +}
 | |
| +
 | |
| +void AccessibilityUIElement::addSelection()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +}
 | |
| +
 | |
| +void AccessibilityUIElement::removeSelection()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +}
 | |
| +
 | |
| +RefPtr<AccessibilityTextMarkerRange> AccessibilityUIElement::lineTextMarkerRangeForTextMarker(AccessibilityTextMarker*)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +RefPtr<AccessibilityTextMarkerRange> AccessibilityUIElement::textMarkerRangeForElement(AccessibilityUIElement*)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +int AccessibilityUIElement::textMarkerRangeLength(AccessibilityTextMarkerRange*)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return 0;
 | |
| +}
 | |
| +
 | |
| +RefPtr<AccessibilityTextMarker> AccessibilityUIElement::previousTextMarker(AccessibilityTextMarker*)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +RefPtr<AccessibilityTextMarker> AccessibilityUIElement::nextTextMarker(AccessibilityTextMarker*)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::rectsForTextMarkerRange(AccessibilityTextMarkerRange*, JSStringRef)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::stringForTextMarkerRange(AccessibilityTextMarkerRange*)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +RefPtr<AccessibilityTextMarkerRange> AccessibilityUIElement::textMarkerRangeForMarkers(AccessibilityTextMarker*, AccessibilityTextMarker*)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +RefPtr<AccessibilityTextMarker> AccessibilityUIElement::startTextMarkerForTextMarkerRange(AccessibilityTextMarkerRange*)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +RefPtr<AccessibilityTextMarker> AccessibilityUIElement::endTextMarkerForTextMarkerRange(AccessibilityTextMarkerRange*)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +RefPtr<AccessibilityTextMarker> AccessibilityUIElement::endTextMarkerForBounds(int, int, int, int)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +RefPtr<AccessibilityTextMarker> AccessibilityUIElement::startTextMarkerForBounds(int, int, int, int)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +RefPtr<AccessibilityTextMarker> AccessibilityUIElement::textMarkerForPoint(int, int)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +RefPtr<AccessibilityUIElement> AccessibilityUIElement::accessibilityElementForTextMarker(AccessibilityTextMarker*)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::attributedStringForTextMarkerRange(AccessibilityTextMarkerRange*)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::attributedStringForTextMarkerRangeWithOptions(AccessibilityTextMarkerRange*, bool)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +bool AccessibilityUIElement::attributedStringForTextMarkerRangeContainsAttribute(JSStringRef, AccessibilityTextMarkerRange*)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return false;
 | |
| +}
 | |
| +
 | |
| +int AccessibilityUIElement::indexForTextMarker(AccessibilityTextMarker*)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return 0;
 | |
| +}
 | |
| +
 | |
| +bool AccessibilityUIElement::isTextMarkerValid(AccessibilityTextMarker*)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return false;
 | |
| +}
 | |
| +
 | |
| +RefPtr<AccessibilityTextMarker> AccessibilityUIElement::textMarkerForIndex(int)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +RefPtr<AccessibilityTextMarker> AccessibilityUIElement::startTextMarker()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +RefPtr<AccessibilityTextMarker> AccessibilityUIElement::endTextMarker()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +bool AccessibilityUIElement::setSelectedTextMarkerRange(AccessibilityTextMarkerRange*)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return false;
 | |
| +}
 | |
| +
 | |
| +void AccessibilityUIElement::scrollToMakeVisible()
 | |
| +{
 | |
| +    notImplemented();
 | |
| +}
 | |
| +
 | |
| +void AccessibilityUIElement::scrollToGlobalPoint(int, int)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +}
 | |
| +
 | |
| +void AccessibilityUIElement::scrollToMakeVisibleWithSubFocus(int, int, int, int)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::supportedActions() const
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::pathDescription() const
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::mathPostscriptsDescription() const
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::mathPrescriptsDescription() const
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::classList() const
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::characterAtOffset(int)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::wordAtOffset(int)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::lineAtOffset(int)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::sentenceAtOffset(int)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +bool AccessibilityUIElement::replaceTextInRange(JSStringRef, int, int)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return false;
 | |
| +}
 | |
| +
 | |
| +bool AccessibilityUIElement::insertText(JSStringRef)
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return false;
 | |
| +}
 | |
| +
 | |
| +JSRetainPtr<JSStringRef> AccessibilityUIElement::domIdentifier() const
 | |
| +{
 | |
| +    notImplemented();
 | |
| +    return nullptr;
 | |
| +}
 | |
| +
 | |
| +} // namespace  WTF
 | |
| +
 | |
| +#endif // !USE(ATSPI) && !USE(ATK)
 | |
| diff --git a/Tools/WebKitTestRunner/PlatformGTK.cmake b/Tools/WebKitTestRunner/PlatformGTK.cmake
 | |
| index a87adedcc0e1b67220f04e517097aae8fc640340..497777c13d0d083bee65710ced9fc6f03eac3778 100644
 | |
| --- a/Tools/WebKitTestRunner/PlatformGTK.cmake
 | |
| +++ b/Tools/WebKitTestRunner/PlatformGTK.cmake
 | |
| @@ -25,6 +25,7 @@ list(APPEND WebKitTestRunner_LIBRARIES
 | |
|      ${GLIB_LIBRARIES}
 | |
|      Cairo::Cairo
 | |
|      GTK::GTK
 | |
| +    stdc++fs
 | |
|  )
 | |
|  
 | |
|  list(APPEND WebKitTestRunnerInjectedBundle_LIBRARIES
 | |
| @@ -42,6 +43,9 @@ list(APPEND WebKitTestRunnerInjectedBundle_SOURCES
 | |
|      InjectedBundle/atspi/AccessibilityNotificationHandler.cpp
 | |
|      InjectedBundle/atspi/AccessibilityUIElementAtspi.cpp
 | |
|  
 | |
| +    InjectedBundle/empty/AccessibilityControllerEmpty.cpp
 | |
| +    InjectedBundle/empty/AccessibilityUIElementEmpty.cpp 
 | |
| +
 | |
|      InjectedBundle/gtk/ActivateFontsGtk.cpp
 | |
|      InjectedBundle/gtk/InjectedBundleGtk.cpp
 | |
|      InjectedBundle/gtk/InjectedBundleUtilities.cpp
 | |
| diff --git a/Tools/WebKitTestRunner/PlatformWPE.cmake b/Tools/WebKitTestRunner/PlatformWPE.cmake
 | |
| index 4f3640a8b93897d69604ee8ba38cd07561720ad2..00b657a8a585d104afc346dc1126fb718564be3e 100644
 | |
| --- a/Tools/WebKitTestRunner/PlatformWPE.cmake
 | |
| +++ b/Tools/WebKitTestRunner/PlatformWPE.cmake
 | |
| @@ -30,6 +30,7 @@ list(APPEND WebKitTestRunner_LIBRARIES
 | |
|      ${WPEBACKEND_FDO_LIBRARIES}
 | |
|      Cairo::Cairo
 | |
|      WebKit::WPEToolingBackends
 | |
| +    stdc++fs
 | |
|  )
 | |
|  
 | |
|  list(APPEND WebKitTestRunnerInjectedBundle_LIBRARIES
 | |
| @@ -43,6 +44,9 @@ list(APPEND WebKitTestRunnerInjectedBundle_SOURCES
 | |
|      InjectedBundle/atspi/AccessibilityNotificationHandler.cpp
 | |
|      InjectedBundle/atspi/AccessibilityUIElementAtspi.cpp
 | |
|  
 | |
| +    InjectedBundle/empty/AccessibilityControllerEmpty.cpp
 | |
| +    InjectedBundle/empty/AccessibilityUIElementEmpty.cpp
 | |
| +
 | |
|      InjectedBundle/wpe/ActivateFontsWPE.cpp
 | |
|      InjectedBundle/wpe/InjectedBundleWPE.cpp
 | |
|      InjectedBundle/wpe/TestRunnerWPE.cpp
 | |
| diff --git a/Tools/WebKitTestRunner/TestController.cpp b/Tools/WebKitTestRunner/TestController.cpp
 | |
| index ed6495356fa6ccd4ea2b2ffb9ac4a8d134a90e31..f686947a5b708b517c7e01f81f11c2f4c5b670dc 100644
 | |
| --- a/Tools/WebKitTestRunner/TestController.cpp
 | |
| +++ b/Tools/WebKitTestRunner/TestController.cpp
 | |
| @@ -874,6 +874,7 @@ void TestController::createWebViewWithOptions(const TestOptions& options)
 | |
|          0, // requestStorageAccessConfirm
 | |
|          shouldAllowDeviceOrientationAndMotionAccess,
 | |
|          runWebAuthenticationPanel,
 | |
| +        0, // handleJavaScriptDialog
 | |
|          decidePolicyForSpeechRecognitionPermissionRequest,
 | |
|          decidePolicyForMediaKeySystemPermissionRequest,
 | |
|          nullptr, // requestWebAuthenticationNoGesture
 | |
| diff --git a/Tools/WebKitTestRunner/mac/EventSenderProxy.mm b/Tools/WebKitTestRunner/mac/EventSenderProxy.mm
 | |
| index 3a231b168583cfc378fb67ff42b108c747dd0733..2b0971a411f87be622cf53536f107a446a6d659f 100644
 | |
| --- a/Tools/WebKitTestRunner/mac/EventSenderProxy.mm
 | |
| +++ b/Tools/WebKitTestRunner/mac/EventSenderProxy.mm
 | |
| @@ -896,4 +896,51 @@ void EventSenderProxy::scaleGestureEnd(double scale)
 | |
|  
 | |
|  #endif // ENABLE(MAC_GESTURE_EVENTS)
 | |
|  
 | |
| +#if ENABLE(TOUCH_EVENTS)
 | |
| +void EventSenderProxy::addTouchPoint(int, int)
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +void EventSenderProxy::updateTouchPoint(int, int, int)
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +void EventSenderProxy::touchStart()
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +void EventSenderProxy::touchMove()
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +void EventSenderProxy::touchEnd()
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +void EventSenderProxy::touchCancel()
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +void EventSenderProxy::clearTouchPoints()
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +void EventSenderProxy::releaseTouchPoint(int)
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +void EventSenderProxy::cancelTouchPoint(int)
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +void EventSenderProxy::setTouchPointRadius(int, int)
 | |
| +{
 | |
| +}
 | |
| +
 | |
| +void EventSenderProxy::setTouchModifier(WKEventModifiers, bool)
 | |
| +{
 | |
| +}
 | |
| +#endif // ENABLE(TOUCH_EVENTS)
 | |
| +
 | |
| +
 | |
|  } // namespace WTR
 | |
| diff --git a/Tools/glib/dependencies/apt b/Tools/glib/dependencies/apt
 | |
| index 017c992209e39859a0b56c1145bb79d9fdc6e939..5bf0744cfdcca58f6ecab6a9838abacfdea24fdb 100644
 | |
| --- a/Tools/glib/dependencies/apt
 | |
| +++ b/Tools/glib/dependencies/apt
 | |
| @@ -45,9 +45,11 @@ PACKAGES=(
 | |
|      libwayland-dev
 | |
|      libwebp-dev
 | |
|      libwoff-dev
 | |
| +    libxcb-glx0-dev
 | |
|      libxslt1-dev
 | |
|      ninja-build
 | |
|      patch
 | |
| +    patchelf
 | |
|      ruby
 | |
|  
 | |
|      # These are dependencies necessary for running tests.
 | |
| diff --git a/Tools/jhbuild/jhbuild-minimal.modules b/Tools/jhbuild/jhbuild-minimal.modules
 | |
| index 77755b7fa816283c5e738c4e82c9a822499ef353..348eb67028791bf13e333299f521de2fc7a020c1 100644
 | |
| --- a/Tools/jhbuild/jhbuild-minimal.modules
 | |
| +++ b/Tools/jhbuild/jhbuild-minimal.modules
 | |
| @@ -175,7 +175,8 @@
 | |
|      </branch>
 | |
|    </meson>
 | |
|  
 | |
| -  <meson id="glib-networking">
 | |
| +  <meson id="glib-networking"
 | |
| +         mesonargs="-Dgnutls=disabled -Dopenssl=enabled">
 | |
|      <dependencies>
 | |
|        <dep package="glib"/>
 | |
|      </dependencies>
 | |
| diff --git a/Tools/win/DLLLauncher/DLLLauncherMain.cpp b/Tools/win/DLLLauncher/DLLLauncherMain.cpp
 | |
| index 52605867b9302d1afcc56c5e9b0c54acf0827900..6edf24ab60249241ba2969531ef55f4b495dce9e 100644
 | |
| --- a/Tools/win/DLLLauncher/DLLLauncherMain.cpp
 | |
| +++ b/Tools/win/DLLLauncher/DLLLauncherMain.cpp
 | |
| @@ -99,11 +99,9 @@ static bool prependPath(const std::wstring& directoryToPrepend)
 | |
|  static int fatalError(const std::wstring& programName, const std::wstring& message)
 | |
|  {
 | |
|      std::wstring caption = programName + L" can't open.";
 | |
| -#if USE_CONSOLE_ENTRY_POINT
 | |
| +// Playwright begin
 | |
|      fwprintf(stderr, L"%s\n%s\n", caption.c_str(), message.c_str());
 | |
| -#else
 | |
| -    ::MessageBoxW(0, message.c_str(), caption.c_str(), MB_ICONERROR);
 | |
| -#endif
 | |
| +// Playwright end
 | |
|      return 1;
 | |
|  }
 | |
|  
 | |
| diff --git a/Tools/wpe/backends/HeadlessViewBackend.cpp b/Tools/wpe/backends/HeadlessViewBackend.cpp
 | |
| index f648e718b51dcc4afe433c812956ea8960232b3c..b849dd178d0d463c0a8afff9bfe0b7aacb74fa67 100644
 | |
| --- a/Tools/wpe/backends/HeadlessViewBackend.cpp
 | |
| +++ b/Tools/wpe/backends/HeadlessViewBackend.cpp
 | |
| @@ -52,3 +52,4 @@ void HeadlessViewBackend::dispatchFullscreenEvent()
 | |
|  #endif
 | |
|  
 | |
|  } // namespace WPEToolingBackends
 | |
| +
 | |
| diff --git a/Tools/wpe/backends/fdo/HeadlessViewBackendFdo.cpp b/Tools/wpe/backends/fdo/HeadlessViewBackendFdo.cpp
 | |
| index 4b3d262528d33800ac46e4e9fc342b11f2744979..39d72bd2c04e79b94a5c7634b6abc9b227d5c148 100644
 | |
| --- a/Tools/wpe/backends/fdo/HeadlessViewBackendFdo.cpp
 | |
| +++ b/Tools/wpe/backends/fdo/HeadlessViewBackendFdo.cpp
 | |
| @@ -149,27 +149,25 @@ void HeadlessViewBackend::updateSnapshot(PlatformBuffer exportedBuffer)
 | |
|              return;
 | |
|      }
 | |
|  
 | |
| -    uint32_t bufferStride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, m_width);
 | |
| -    uint8_t* buffer = new uint8_t[bufferStride * m_height];
 | |
| -    memset(buffer, 0, bufferStride * m_height);
 | |
| +    uint32_t width = std::max(0, wl_shm_buffer_get_width(shmBuffer));
 | |
| +    uint32_t height = std::max(0, wl_shm_buffer_get_height(shmBuffer));
 | |
| +    if (!width || !height) {
 | |
| +        fprintf(stderr, "HeadlessViewBackend::updateSnapshot shmBuffer is empty: %ux%u\n", width, height);
 | |
| +        return;
 | |
| +    }
 | |
|  
 | |
| +    uint32_t bufferStride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width);
 | |
| +    uint32_t stride = std::max(0, wl_shm_buffer_get_stride(shmBuffer));
 | |
| +    if (bufferStride != stride) {
 | |
| +        fprintf(stderr, "bufferStride != stride: %u != %u\n", bufferStride, stride);
 | |
| +        return;
 | |
| +    }
 | |
| +    uint8_t* buffer = new uint8_t[bufferStride * height];
 | |
|      {
 | |
| -        uint32_t width = std::min<uint32_t>(m_width, std::max(0, wl_shm_buffer_get_width(shmBuffer)));
 | |
| -        uint32_t height = std::min<uint32_t>(m_height, std::max(0, wl_shm_buffer_get_height(shmBuffer)));
 | |
| -        uint32_t stride = std::max(0, wl_shm_buffer_get_stride(shmBuffer));
 | |
| -
 | |
|          wl_shm_buffer_begin_access(shmBuffer);
 | |
|          auto* data = static_cast<uint8_t*>(wl_shm_buffer_get_data(shmBuffer));
 | |
|  
 | |
| -        for (uint32_t y = 0; y < height; ++y) {
 | |
| -            for (uint32_t x = 0; x < width; ++x) {
 | |
| -                buffer[bufferStride * y + 4 * x + 0] = data[stride * y + 4 * x + 0];
 | |
| -                buffer[bufferStride * y + 4 * x + 1] = data[stride * y + 4 * x + 1];
 | |
| -                buffer[bufferStride * y + 4 * x + 2] = data[stride * y + 4 * x + 2];
 | |
| -                buffer[bufferStride * y + 4 * x + 3] = data[stride * y + 4 * x + 3];
 | |
| -            }
 | |
| -        }
 | |
| -
 | |
| +        memcpy(buffer, data, bufferStride * height);
 | |
|          wl_shm_buffer_end_access(shmBuffer);
 | |
|      }
 | |
|  
 | |
| @@ -177,7 +175,7 @@ void HeadlessViewBackend::updateSnapshot(PlatformBuffer exportedBuffer)
 | |
|          cairo_surface_destroy(m_snapshot);
 | |
|  
 | |
|      m_snapshot = cairo_image_surface_create_for_data(buffer, CAIRO_FORMAT_ARGB32,
 | |
| -        m_width, m_height, cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, m_width));
 | |
| +        width, height, cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width));
 | |
|  
 | |
|      static cairo_user_data_key_t bufferKey;
 | |
|      cairo_surface_set_user_data(m_snapshot, &bufferKey, buffer,
 |