Diff
Modified: trunk/Source/WebCore/ChangeLog (286083 => 286084)
--- trunk/Source/WebCore/ChangeLog 2021-11-19 23:19:44 UTC (rev 286083)
+++ trunk/Source/WebCore/ChangeLog 2021-11-19 23:52:41 UTC (rev 286084)
@@ -1,3 +1,29 @@
+2021-11-19 Alex Christensen <[email protected]>
+
+ Implement extension-path variant of redirect action in WKContentRuleList
+ https://bugs.webkit.org/show_bug.cgi?id=233351
+
+ Reviewed by Tim Hatcher.
+
+ Because the extension path changes each time you relaunch Safari but the compiled bytecode does not,
+ we need a way to pass in the extension base URL when adding the looked-up or compiled WKContentRuleList
+ to the WKUserContentController.
+
+ * contentextensions/ContentExtension.cpp:
+ (WebCore::ContentExtensions::ContentExtension::create):
+ (WebCore::ContentExtensions::ContentExtension::ContentExtension):
+ * contentextensions/ContentExtension.h:
+ (WebCore::ContentExtensions::ContentExtension::extensionBaseURL const):
+ * contentextensions/ContentExtensionActions.cpp:
+ (WebCore::ContentExtensions::RedirectAction::applyToRequest):
+ * contentextensions/ContentExtensionActions.h:
+ * contentextensions/ContentExtensionsBackend.cpp:
+ (WebCore::ContentExtensions::ContentExtensionsBackend::addContentExtension):
+ (WebCore::ContentExtensions::ContentExtensionsBackend::processContentRuleListsForLoad):
+ (WebCore::ContentExtensions::applyResultsToRequest):
+ * contentextensions/ContentExtensionsBackend.h:
+ * contentextensions/ContentRuleListResults.h:
+
2021-11-19 Myles C. Maxfield <[email protected]>
[WebGPU] Add converters from serializable descriptors to interface descriptors
Modified: trunk/Source/WebCore/contentextensions/ContentExtension.cpp (286083 => 286084)
--- trunk/Source/WebCore/contentextensions/ContentExtension.cpp 2021-11-19 23:19:44 UTC (rev 286083)
+++ trunk/Source/WebCore/contentextensions/ContentExtension.cpp 2021-11-19 23:52:41 UTC (rev 286084)
@@ -36,14 +36,15 @@
namespace WebCore {
namespace ContentExtensions {
-Ref<ContentExtension> ContentExtension::create(const String& identifier, Ref<CompiledContentExtension>&& compiledExtension, ShouldCompileCSS shouldCompileCSS)
+Ref<ContentExtension> ContentExtension::create(const String& identifier, Ref<CompiledContentExtension>&& compiledExtension, URL&& extensionBaseURL, ShouldCompileCSS shouldCompileCSS)
{
- return adoptRef(*new ContentExtension(identifier, WTFMove(compiledExtension), shouldCompileCSS));
+ return adoptRef(*new ContentExtension(identifier, WTFMove(compiledExtension), WTFMove(extensionBaseURL), shouldCompileCSS));
}
-ContentExtension::ContentExtension(const String& identifier, Ref<CompiledContentExtension>&& compiledExtension, ShouldCompileCSS shouldCompileCSS)
+ContentExtension::ContentExtension(const String& identifier, Ref<CompiledContentExtension>&& compiledExtension, URL&& extensionBaseURL, ShouldCompileCSS shouldCompileCSS)
: m_identifier(identifier)
, m_compiledExtension(WTFMove(compiledExtension))
+ , m_extensionBaseURL(WTFMove(extensionBaseURL))
{
DFABytecodeInterpreter withoutConditions(m_compiledExtension->filtersWithoutConditionsBytecode(), m_compiledExtension->filtersWithoutConditionsBytecodeLength());
DFABytecodeInterpreter withConditions(m_compiledExtension->filtersWithConditionsBytecode(), m_compiledExtension->filtersWithConditionsBytecodeLength());
Modified: trunk/Source/WebCore/contentextensions/ContentExtension.h (286083 => 286084)
--- trunk/Source/WebCore/contentextensions/ContentExtension.h 2021-11-19 23:19:44 UTC (rev 286083)
+++ trunk/Source/WebCore/contentextensions/ContentExtension.h 2021-11-19 23:52:41 UTC (rev 286084)
@@ -42,9 +42,10 @@
class ContentExtension : public RefCounted<ContentExtension> {
public:
enum class ShouldCompileCSS { No, Yes };
- static Ref<ContentExtension> create(const String& identifier, Ref<CompiledContentExtension>&&, ShouldCompileCSS = ShouldCompileCSS::Yes);
+ static Ref<ContentExtension> create(const String& identifier, Ref<CompiledContentExtension>&&, URL&&, ShouldCompileCSS);
const String& identifier() const { return m_identifier; }
+ const URL& extensionBaseURL() const { return m_extensionBaseURL; }
const CompiledContentExtension& compiledExtension() const { return m_compiledExtension.get(); }
StyleSheetContents* globalDisplayNoneStyleSheet();
const DFABytecodeInterpreter::Actions& topURLActions(const URL& topURL);
@@ -52,11 +53,12 @@
const Vector<uint32_t>& universalActionsWithConditions(const URL& topURL);
private:
- ContentExtension(const String& identifier, Ref<CompiledContentExtension>&&, ShouldCompileCSS);
+ ContentExtension(const String& identifier, Ref<CompiledContentExtension>&&, URL&&, ShouldCompileCSS);
uint32_t findFirstIgnorePreviousRules() const;
String m_identifier;
Ref<CompiledContentExtension> m_compiledExtension;
+ URL m_extensionBaseURL;
RefPtr<StyleSheetContents> m_globalDisplayNoneStyleSheet;
void compileGlobalDisplayNoneStyleSheet();
Modified: trunk/Source/WebCore/contentextensions/ContentExtensionActions.cpp (286083 => 286084)
--- trunk/Source/WebCore/contentextensions/ContentExtensionActions.cpp 2021-11-19 23:19:44 UTC (rev 286083)
+++ trunk/Source/WebCore/contentextensions/ContentExtensionActions.cpp 2021-11-19 23:52:41 UTC (rev 286084)
@@ -368,10 +368,12 @@
return deserializeLength(span, 0);
}
-void RedirectAction::applyToRequest(ResourceRequest& request)
+void RedirectAction::applyToRequest(ResourceRequest& request, const URL& extensionBaseURL)
{
- std::visit(WTF::makeVisitor([](const ExtensionPathAction&) {
- // FIXME: Implement. We need to know the base URL of the extension here from new SPI.
+ std::visit(WTF::makeVisitor([&](const ExtensionPathAction& action) {
+ auto url = ""
+ url.setPath(action.extensionPath);
+ request.setURL(WTFMove(url));
}, [&] (const RegexSubstitutionAction&) {
// FIXME: Implement, ideally in a way that doesn't require making a new VM and global object for each redirect operation.
}, [&] (const URLTransformAction& action) {
Modified: trunk/Source/WebCore/contentextensions/ContentExtensionActions.h (286083 => 286084)
--- trunk/Source/WebCore/contentextensions/ContentExtensionActions.h 2021-11-19 23:19:44 UTC (rev 286083)
+++ trunk/Source/WebCore/contentextensions/ContentExtensionActions.h 2021-11-19 23:52:41 UTC (rev 286084)
@@ -244,7 +244,7 @@
void serialize(Vector<uint8_t>&) const;
static RedirectAction deserialize(Span<const uint8_t>);
static size_t serializedLength(Span<const uint8_t>);
- void applyToRequest(ResourceRequest&);
+ void applyToRequest(ResourceRequest&, const URL&);
};
using ActionData = std::variant<
Modified: trunk/Source/WebCore/contentextensions/ContentExtensionsBackend.cpp (286083 => 286084)
--- trunk/Source/WebCore/contentextensions/ContentExtensionsBackend.cpp 2021-11-19 23:19:44 UTC (rev 286083)
+++ trunk/Source/WebCore/contentextensions/ContentExtensionsBackend.cpp 2021-11-19 23:52:41 UTC (rev 286084)
@@ -78,13 +78,13 @@
return results.summary.madeHTTPS;
}
-void ContentExtensionsBackend::addContentExtension(const String& identifier, Ref<CompiledContentExtension> compiledContentExtension, ContentExtension::ShouldCompileCSS shouldCompileCSS)
+void ContentExtensionsBackend::addContentExtension(const String& identifier, Ref<CompiledContentExtension> compiledContentExtension, URL&& extensionBaseURL, ContentExtension::ShouldCompileCSS shouldCompileCSS)
{
ASSERT(!identifier.isEmpty());
if (identifier.isEmpty())
return;
- auto contentExtension = ContentExtension::create(identifier, WTFMove(compiledContentExtension), shouldCompileCSS);
+ auto contentExtension = ContentExtension::create(identifier, WTFMove(compiledContentExtension), WTFMove(extensionBaseURL), shouldCompileCSS);
m_contentExtensions.set(identifier, WTFMove(contentExtension));
}
@@ -231,9 +231,9 @@
}, [&] (const ModifyHeadersAction& action) {
if (initiatingDocumentLoader.allowsActiveContentRuleListActionsForURL(url))
results.summary.modifyHeadersActions.append(action);
- }, [&] (const RedirectAction& action) {
+ }, [&] (const RedirectAction& redirectAction) {
if (initiatingDocumentLoader.allowsActiveContentRuleListActionsForURL(url))
- results.summary.redirectActions.append(action);
+ results.summary.redirectActions.append({ redirectAction, m_contentExtensions.get(actionsFromContentRuleList.contentRuleListIdentifier)->extensionBaseURL() });
}), action.data());
}
@@ -330,8 +330,8 @@
for (auto& action : results.summary.modifyHeadersActions)
action.applyToRequest(request);
- for (auto& action : results.summary.redirectActions)
- action.applyToRequest(request);
+ for (auto& pair : results.summary.redirectActions)
+ pair.first.applyToRequest(request, pair.second);
if (page && results.shouldNotifyApplication()) {
results.results.removeAllMatching([](const auto& pair) {
Modified: trunk/Source/WebCore/contentextensions/ContentExtensionsBackend.h (286083 => 286084)
--- trunk/Source/WebCore/contentextensions/ContentExtensionsBackend.h 2021-11-19 23:19:44 UTC (rev 286083)
+++ trunk/Source/WebCore/contentextensions/ContentExtensionsBackend.h 2021-11-19 23:52:41 UTC (rev 286084)
@@ -57,7 +57,7 @@
// Set a list of rules for a given name. If there were existing rules for the name, they are overridden.
// The identifier cannot be empty.
- WEBCORE_EXPORT void addContentExtension(const String& identifier, Ref<CompiledContentExtension>, ContentExtension::ShouldCompileCSS = ContentExtension::ShouldCompileCSS::Yes);
+ WEBCORE_EXPORT void addContentExtension(const String& identifier, Ref<CompiledContentExtension>, URL&& extensionBaseURL, ContentExtension::ShouldCompileCSS = ContentExtension::ShouldCompileCSS::Yes);
WEBCORE_EXPORT void removeContentExtension(const String& identifier);
WEBCORE_EXPORT void removeAllContentExtensions();
Modified: trunk/Source/WebCore/contentextensions/ContentRuleListResults.h (286083 => 286084)
--- trunk/Source/WebCore/contentextensions/ContentRuleListResults.h 2021-11-19 23:19:44 UTC (rev 286083)
+++ trunk/Source/WebCore/contentextensions/ContentRuleListResults.h 2021-11-19 23:52:41 UTC (rev 286084)
@@ -58,7 +58,7 @@
bool blockedCookies { false };
bool hasNotifications { false };
Vector<ContentExtensions::ModifyHeadersAction> modifyHeadersActions;
- Vector<ContentExtensions::RedirectAction> redirectActions;
+ Vector<std::pair<ContentExtensions::RedirectAction, URL>> redirectActions;
template<class Encoder> void encode(Encoder&) const;
template<class Decoder> static std::optional<Summary> decode(Decoder&);
Modified: trunk/Source/WebKit/ChangeLog (286083 => 286084)
--- trunk/Source/WebKit/ChangeLog 2021-11-19 23:19:44 UTC (rev 286083)
+++ trunk/Source/WebKit/ChangeLog 2021-11-19 23:52:41 UTC (rev 286084)
@@ -1,3 +1,49 @@
+2021-11-19 Alex Christensen <[email protected]>
+
+ Implement extension-path variant of redirect action in WKContentRuleList
+ https://bugs.webkit.org/show_bug.cgi?id=233351
+
+ Reviewed by Tim Hatcher.
+
+ * NetworkProcess/NetworkContentRuleListManager.cpp:
+ (WebKit::NetworkContentRuleListManager::addContentRuleLists):
+ * NetworkProcess/NetworkContentRuleListManager.h:
+ * NetworkProcess/NetworkContentRuleListManager.messages.in:
+ * Shared/ServiceWorkerInitializationData.cpp:
+ (WebKit::ServiceWorkerInitializationData::decode):
+ * Shared/ServiceWorkerInitializationData.h:
+ * Shared/UserContentControllerParameters.cpp:
+ (WebKit::UserContentControllerParameters::decode):
+ * Shared/UserContentControllerParameters.h:
+ * Shared/WebCompiledContentRuleListData.cpp:
+ (WebKit::WebCompiledContentRuleListData::encode const):
+ (WebKit::WebCompiledContentRuleListData::decode):
+ * Shared/WebCompiledContentRuleListData.h:
+ (WebKit::WebCompiledContentRuleListData::WebCompiledContentRuleListData):
+ * UIProcess/API/APIContentRuleList.cpp:
+ (API::ContentRuleList::ContentRuleList):
+ (API::ContentRuleList::name const):
+ * UIProcess/API/APIContentRuleList.h:
+ * UIProcess/API/APIContentRuleListStore.cpp:
+ (API::createExtension):
+ * UIProcess/API/Cocoa/WKUserContentController.mm:
+ (-[WKUserContentController _addContentRuleList:extensionBaseURL:]):
+ * UIProcess/API/Cocoa/WKUserContentControllerPrivate.h:
+ * UIProcess/Network/NetworkProcessProxy.cpp:
+ (WebKit::NetworkProcessProxy::contentExtensionRules):
+ * UIProcess/UserContent/WebUserContentControllerProxy.cpp:
+ (WebKit::WebUserContentControllerProxy::contentRuleListData const):
+ (WebKit::WebUserContentControllerProxy::addContentRuleList):
+ * UIProcess/UserContent/WebUserContentControllerProxy.h:
+ (WebKit::WebUserContentControllerProxy::addContentRuleList):
+ (WebKit::WebUserContentControllerProxy::contentExtensionRules):
+ * UIProcess/WebProcessProxy.cpp:
+ (WebKit::contentRuleListsFromIdentifier):
+ * WebProcess/UserContent/WebUserContentController.cpp:
+ (WebKit::WebUserContentController::addContentRuleLists):
+ * WebProcess/UserContent/WebUserContentController.h:
+ * WebProcess/UserContent/WebUserContentController.messages.in:
+
2021-11-19 Antoine Quint <[email protected]>
[Model] Use RefPtr across ARKitInlinePreviewModelPlayer when creating strong pointers
Modified: trunk/Source/WebKit/NetworkProcess/NetworkContentRuleListManager.cpp (286083 => 286084)
--- trunk/Source/WebKit/NetworkProcess/NetworkContentRuleListManager.cpp 2021-11-19 23:19:44 UTC (rev 286083)
+++ trunk/Source/WebKit/NetworkProcess/NetworkContentRuleListManager.cpp 2021-11-19 23:52:41 UTC (rev 286084)
@@ -66,15 +66,17 @@
m_networkProcess.parentProcessConnection()->send(Messages::NetworkProcessProxy::ContentExtensionRules { identifier }, 0);
}
-void NetworkContentRuleListManager::addContentRuleLists(UserContentControllerIdentifier identifier, Vector<std::pair<String, WebCompiledContentRuleListData>>&& contentRuleLists)
+void NetworkContentRuleListManager::addContentRuleLists(UserContentControllerIdentifier identifier, Vector<std::pair<WebCompiledContentRuleListData, URL>>&& contentRuleLists)
{
auto& backend = *m_contentExtensionBackends.ensure(identifier, [] {
return makeUnique<WebCore::ContentExtensions::ContentExtensionsBackend>();
}).iterator->value;
- for (auto&& contentRuleList : contentRuleLists) {
- auto compiledContentRuleList = WebCompiledContentRuleList::create(WTFMove(contentRuleList.second));
- backend.addContentExtension(contentRuleList.first, WTFMove(compiledContentRuleList), ContentExtensions::ContentExtension::ShouldCompileCSS::No);
+ for (auto&& pair : contentRuleLists) {
+ auto&& contentRuleList = WTFMove(pair.first);
+ String identifier = contentRuleList.identifier;
+ auto compiledContentRuleList = WebCompiledContentRuleList::create(WTFMove(contentRuleList));
+ backend.addContentExtension(identifier, WTFMove(compiledContentRuleList), WTFMove(pair.second), ContentExtensions::ContentExtension::ShouldCompileCSS::No);
}
auto pendingCallbacks = m_pendingCallbacks.take(identifier);
Modified: trunk/Source/WebKit/NetworkProcess/NetworkContentRuleListManager.h (286083 => 286084)
--- trunk/Source/WebKit/NetworkProcess/NetworkContentRuleListManager.h 2021-11-19 23:19:44 UTC (rev 286083)
+++ trunk/Source/WebKit/NetworkProcess/NetworkContentRuleListManager.h 2021-11-19 23:52:41 UTC (rev 286084)
@@ -51,7 +51,7 @@
void contentExtensionsBackend(UserContentControllerIdentifier, BackendCallback&&);
private:
- void addContentRuleLists(UserContentControllerIdentifier, Vector<std::pair<String, WebCompiledContentRuleListData>>&&);
+ void addContentRuleLists(UserContentControllerIdentifier, Vector<std::pair<WebCompiledContentRuleListData, URL>>&&);
void removeContentRuleList(UserContentControllerIdentifier, const String& name);
void removeAllContentRuleLists(UserContentControllerIdentifier);
void remove(UserContentControllerIdentifier);
Modified: trunk/Source/WebKit/NetworkProcess/NetworkContentRuleListManager.messages.in (286083 => 286084)
--- trunk/Source/WebKit/NetworkProcess/NetworkContentRuleListManager.messages.in 2021-11-19 23:19:44 UTC (rev 286083)
+++ trunk/Source/WebKit/NetworkProcess/NetworkContentRuleListManager.messages.in 2021-11-19 23:52:41 UTC (rev 286084)
@@ -24,7 +24,7 @@
messages -> NetworkContentRuleListManager NotRefCounted {
Remove(WebKit::UserContentControllerIdentifier identifier)
- AddContentRuleLists(WebKit::UserContentControllerIdentifier identifier, Vector<std::pair<String, WebKit::WebCompiledContentRuleListData>> contentFilters)
+ AddContentRuleLists(WebKit::UserContentControllerIdentifier identifier, Vector<std::pair<WebKit::WebCompiledContentRuleListData, URL>> contentFilters)
RemoveContentRuleList(WebKit::UserContentControllerIdentifier identifier, String name)
RemoveAllContentRuleLists(WebKit::UserContentControllerIdentifier identifier)
}
Modified: trunk/Source/WebKit/Shared/ServiceWorkerInitializationData.cpp (286083 => 286084)
--- trunk/Source/WebKit/Shared/ServiceWorkerInitializationData.cpp 2021-11-19 23:19:44 UTC (rev 286083)
+++ trunk/Source/WebKit/Shared/ServiceWorkerInitializationData.cpp 2021-11-19 23:52:41 UTC (rev 286084)
@@ -30,6 +30,7 @@
#include "Decoder.h"
#include "Encoder.h"
#include "WebCompiledContentRuleListData.h"
+#include <wtf/URL.h>
namespace WebKit {
@@ -49,7 +50,7 @@
return std::nullopt;
#if ENABLE(CONTENT_EXTENSIONS)
- std::optional<Vector<std::pair<String, WebCompiledContentRuleListData>>> contentRuleLists;
+ std::optional<Vector<std::pair<WebCompiledContentRuleListData, URL>>> contentRuleLists;
decoder >> contentRuleLists;
if (!contentRuleLists)
return std::nullopt;
Modified: trunk/Source/WebKit/Shared/ServiceWorkerInitializationData.h (286083 => 286084)
--- trunk/Source/WebKit/Shared/ServiceWorkerInitializationData.h 2021-11-19 23:19:44 UTC (rev 286083)
+++ trunk/Source/WebKit/Shared/ServiceWorkerInitializationData.h 2021-11-19 23:52:41 UTC (rev 286084)
@@ -44,7 +44,7 @@
UserContentControllerIdentifier userContentControllerIdentifier;
#if ENABLE(CONTENT_EXTENSIONS)
- Vector<std::pair<String, WebCompiledContentRuleListData>> contentRuleLists;
+ Vector<std::pair<WebCompiledContentRuleListData, URL>> contentRuleLists;
#endif
};
Modified: trunk/Source/WebKit/Shared/UserContentControllerParameters.cpp (286083 => 286084)
--- trunk/Source/WebKit/Shared/UserContentControllerParameters.cpp 2021-11-19 23:19:44 UTC (rev 286083)
+++ trunk/Source/WebKit/Shared/UserContentControllerParameters.cpp 2021-11-19 23:52:41 UTC (rev 286084)
@@ -72,7 +72,7 @@
return std::nullopt;
#if ENABLE(CONTENT_EXTENSIONS)
- std::optional<Vector<std::pair<String, WebCompiledContentRuleListData>>> contentRuleLists;
+ std::optional<Vector<std::pair<WebCompiledContentRuleListData, URL>>> contentRuleLists;
decoder >> contentRuleLists;
if (!contentRuleLists)
return std::nullopt;
Modified: trunk/Source/WebKit/Shared/UserContentControllerParameters.h (286083 => 286084)
--- trunk/Source/WebKit/Shared/UserContentControllerParameters.h 2021-11-19 23:19:44 UTC (rev 286083)
+++ trunk/Source/WebKit/Shared/UserContentControllerParameters.h 2021-11-19 23:52:41 UTC (rev 286084)
@@ -44,7 +44,7 @@
Vector<WebUserStyleSheetData> userStyleSheets;
Vector<WebScriptMessageHandlerData> messageHandlers;
#if ENABLE(CONTENT_EXTENSIONS)
- Vector<std::pair<String, WebCompiledContentRuleListData>> contentRuleLists;
+ Vector<std::pair<WebCompiledContentRuleListData, URL>> contentRuleLists;
#endif
void encode(IPC::Encoder&) const;
Modified: trunk/Source/WebKit/Shared/WebCompiledContentRuleListData.cpp (286083 => 286084)
--- trunk/Source/WebKit/Shared/WebCompiledContentRuleListData.cpp 2021-11-19 23:19:44 UTC (rev 286083)
+++ trunk/Source/WebKit/Shared/WebCompiledContentRuleListData.cpp 2021-11-19 23:52:41 UTC (rev 286084)
@@ -36,6 +36,8 @@
void WebCompiledContentRuleListData::encode(IPC::Encoder& encoder) const
{
+ encoder << identifier;
+
SharedMemory::Handle handle;
data->createHandle(handle, SharedMemory::Protection::ReadOnly);
@@ -60,10 +62,17 @@
std::optional<WebCompiledContentRuleListData> WebCompiledContentRuleListData::decode(IPC::Decoder& decoder)
{
+ std::optional<String> identifier;
+ decoder >> identifier;
+ if (!identifier)
+ return std::nullopt;
+
SharedMemory::IPCHandle ipcHandle;
if (!decoder.decode(ipcHandle))
return std::nullopt;
- RefPtr<SharedMemory> data = "" SharedMemory::Protection::ReadOnly);
+ auto data = "" SharedMemory::Protection::ReadOnly);
+ if (!data)
+ return std::nullopt;
std::optional<unsigned> conditionsApplyOnlyToDomainOffset;
decoder >> conditionsApplyOnlyToDomainOffset;
@@ -111,7 +120,8 @@
return std::nullopt;
return {{
- WTFMove(data),
+ WTFMove(*identifier),
+ data.releaseNonNull(),
WTFMove(*conditionsApplyOnlyToDomainOffset),
WTFMove(*actionsOffset),
WTFMove(*actionsSize),
Modified: trunk/Source/WebKit/Shared/WebCompiledContentRuleListData.h (286083 => 286084)
--- trunk/Source/WebKit/Shared/WebCompiledContentRuleListData.h 2021-11-19 23:19:44 UTC (rev 286083)
+++ trunk/Source/WebKit/Shared/WebCompiledContentRuleListData.h 2021-11-19 23:52:41 UTC (rev 286084)
@@ -41,8 +41,9 @@
class WebCompiledContentRuleListData {
public:
- WebCompiledContentRuleListData(RefPtr<SharedMemory>&& data, unsigned conditionsApplyOnlyToDomainOffset, unsigned actionsOffset, unsigned actionsSize, unsigned filtersWithoutConditionsBytecodeOffset, unsigned filtersWithoutConditionsBytecodeSize, unsigned filtersWithConditionsBytecodeOffset, unsigned filtersWithConditionsBytecodeSize, unsigned topURLFiltersBytecodeOffset, unsigned topURLFiltersBytecodeSize)
- : data(WTFMove(data))
+ WebCompiledContentRuleListData(String&& identifier, Ref<SharedMemory>&& data, unsigned conditionsApplyOnlyToDomainOffset, unsigned actionsOffset, unsigned actionsSize, unsigned filtersWithoutConditionsBytecodeOffset, unsigned filtersWithoutConditionsBytecodeSize, unsigned filtersWithConditionsBytecodeOffset, unsigned filtersWithConditionsBytecodeSize, unsigned topURLFiltersBytecodeOffset, unsigned topURLFiltersBytecodeSize)
+ : identifier(WTFMove(identifier))
+ , data(WTFMove(data))
, conditionsApplyOnlyToDomainOffset(conditionsApplyOnlyToDomainOffset)
, actionsOffset(actionsOffset)
, actionsSize(actionsSize)
@@ -58,7 +59,8 @@
void encode(IPC::Encoder&) const;
static std::optional<WebCompiledContentRuleListData> decode(IPC::Decoder&);
- RefPtr<SharedMemory> data;
+ String identifier;
+ Ref<SharedMemory> data;
unsigned conditionsApplyOnlyToDomainOffset { 0 };
unsigned actionsOffset { 0 };
unsigned actionsSize { 0 };
Modified: trunk/Source/WebKit/UIProcess/API/APIContentRuleList.cpp (286083 => 286084)
--- trunk/Source/WebKit/UIProcess/API/APIContentRuleList.cpp 2021-11-19 23:19:44 UTC (rev 286083)
+++ trunk/Source/WebKit/UIProcess/API/APIContentRuleList.cpp 2021-11-19 23:52:41 UTC (rev 286084)
@@ -34,9 +34,8 @@
namespace API {
-ContentRuleList::ContentRuleList(const WTF::String& name, Ref<WebKit::WebCompiledContentRuleList>&& contentRuleList, WebKit::NetworkCache::Data&& mappedFile)
- : m_name(name)
- , m_compiledRuleList(WTFMove(contentRuleList))
+ContentRuleList::ContentRuleList(Ref<WebKit::WebCompiledContentRuleList>&& contentRuleList, WebKit::NetworkCache::Data&& mappedFile)
+ : m_compiledRuleList(WTFMove(contentRuleList))
, m_mappedFile(WTFMove(mappedFile))
{
}
@@ -45,6 +44,11 @@
{
}
+const WTF::String& ContentRuleList::name() const
+{
+ return m_compiledRuleList->data().identifier;
+}
+
bool ContentRuleList::supportsRegularExpression(const WTF::String& regex)
{
using namespace WebCore::ContentExtensions;
Modified: trunk/Source/WebKit/UIProcess/API/APIContentRuleList.h (286083 => 286084)
--- trunk/Source/WebKit/UIProcess/API/APIContentRuleList.h 2021-11-19 23:19:44 UTC (rev 286083)
+++ trunk/Source/WebKit/UIProcess/API/APIContentRuleList.h 2021-11-19 23:52:41 UTC (rev 286084)
@@ -38,21 +38,20 @@
class ContentRuleList final : public ObjectImpl<Object::Type::ContentRuleList> {
public:
#if ENABLE(CONTENT_EXTENSIONS)
- static Ref<ContentRuleList> create(const WTF::String& name, Ref<WebKit::WebCompiledContentRuleList>&& contentRuleList, WebKit::NetworkCache::Data&& mappedFile)
+ static Ref<ContentRuleList> create(Ref<WebKit::WebCompiledContentRuleList>&& contentRuleList, WebKit::NetworkCache::Data&& mappedFile)
{
- return adoptRef(*new ContentRuleList(name, WTFMove(contentRuleList), WTFMove(mappedFile)));
+ return adoptRef(*new ContentRuleList(WTFMove(contentRuleList), WTFMove(mappedFile)));
}
- ContentRuleList(const WTF::String& name, Ref<WebKit::WebCompiledContentRuleList>&&, WebKit::NetworkCache::Data&&);
+ ContentRuleList(Ref<WebKit::WebCompiledContentRuleList>&&, WebKit::NetworkCache::Data&&);
virtual ~ContentRuleList();
- const WTF::String& name() const { return m_name; }
+ const WTF::String& name() const;
const WebKit::WebCompiledContentRuleList& compiledRuleList() const { return m_compiledRuleList.get(); }
static bool supportsRegularExpression(const WTF::String&);
private:
- WTF::String m_name;
Ref<WebKit::WebCompiledContentRuleList> m_compiledRuleList;
WebKit::NetworkCache::Data m_mappedFile;
#endif // ENABLE(CONTENT_EXTENSIONS)
Modified: trunk/Source/WebKit/UIProcess/API/APIContentRuleListStore.cpp (286083 => 286084)
--- trunk/Source/WebKit/UIProcess/API/APIContentRuleListStore.cpp 2021-11-19 23:19:44 UTC (rev 286083)
+++ trunk/Source/WebKit/UIProcess/API/APIContentRuleListStore.cpp 2021-11-19 23:52:41 UTC (rev 286084)
@@ -408,11 +408,12 @@
// Content extensions are always compiled to files, and at this point the file
// has been already mapped, therefore tryCreateSharedMemory() cannot fail.
- ASSERT(sharedMemory);
+ RELEASE_ASSERT(sharedMemory);
const size_t headerAndSourceSize = ContentRuleListFileHeaderSize + data.metaData.sourceSize;
auto compiledContentRuleListData = WebKit::WebCompiledContentRuleListData(
- WTFMove(sharedMemory),
+ WTF::String(identifier),
+ sharedMemory.releaseNonNull(),
ConditionsApplyOnlyToDomainOffset,
headerAndSourceSize,
data.metaData.actionsSize,
@@ -430,7 +431,7 @@
data.metaData.conditionedFiltersBytecodeSize
);
auto compiledContentRuleList = WebKit::WebCompiledContentRuleList::create(WTFMove(compiledContentRuleListData));
- return API::ContentRuleList::create(identifier, WTFMove(compiledContentRuleList), WTFMove(data.data));
+ return API::ContentRuleList::create(WTFMove(compiledContentRuleList), WTFMove(data.data));
}
static WTF::String getContentRuleListSourceFromMappedFile(const MappedData& mappedData)
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKUserContentController.mm (286083 => 286084)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKUserContentController.mm 2021-11-19 23:19:44 UTC (rev 286083)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKUserContentController.mm 2021-11-19 23:52:41 UTC (rev 286084)
@@ -285,6 +285,13 @@
#endif
}
+- (void)_addContentRuleList:(WKContentRuleList *)contentRuleList extensionBaseURL:(NSURL *)extensionBaseURL
+{
+#if ENABLE(CONTENT_EXTENSIONS)
+ _userContentControllerProxy->addContentRuleList(*contentRuleList->_contentRuleList, extensionBaseURL);
+#endif
+}
+
- (void)_removeUserContentFilter:(NSString *)userContentFilterName
{
#if ENABLE(CONTENT_EXTENSIONS)
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKUserContentControllerPrivate.h (286083 => 286084)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKUserContentControllerPrivate.h 2021-11-19 23:19:44 UTC (rev 286083)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKUserContentControllerPrivate.h 2021-11-19 23:52:41 UTC (rev 286084)
@@ -41,6 +41,7 @@
- (void)_addUserContentFilter:(_WKUserContentFilter *)userContentFilter WK_API_AVAILABLE(macos(10.11), ios(9.0));
- (void)_removeUserContentFilter:(NSString *)userContentFilterName WK_API_AVAILABLE(macos(10.11), ios(9.0));
- (void)_removeAllUserContentFilters WK_API_AVAILABLE(macos(10.11), ios(9.0));
+- (void)_addContentRuleList:(WKContentRuleList *)contentRuleList extensionBaseURL:(NSURL *)extensionBaseURL WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
@property (nonatomic, readonly, copy) NSArray<_WKUserStyleSheet *> *_userStyleSheets WK_API_AVAILABLE(macos(10.12), ios(10.0));
- (void)_addUserStyleSheet:(_WKUserStyleSheet *)userStyleSheet WK_API_AVAILABLE(macos(10.12), ios(10.0));
Modified: trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp (286083 => 286084)
--- trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp 2021-11-19 23:19:44 UTC (rev 286083)
+++ trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp 2021-11-19 23:52:41 UTC (rev 286084)
@@ -1388,8 +1388,8 @@
m_webUserContentControllerProxies.add(webUserContentControllerProxy);
webUserContentControllerProxy->addNetworkProcess(*this);
- auto rules = WTF::map(webUserContentControllerProxy->contentExtensionRules(), [](auto&& keyValue) -> std::pair<String, WebCompiledContentRuleListData> {
- return std::make_pair(keyValue.value->name(), keyValue.value->compiledRuleList().data());
+ auto rules = WTF::map(webUserContentControllerProxy->contentExtensionRules(), [](auto&& keyValue) -> std::pair<WebCompiledContentRuleListData, URL> {
+ return { keyValue.value.first->compiledRuleList().data(), keyValue.value.second };
});
send(Messages::NetworkContentRuleListManager::AddContentRuleLists { identifier, rules }, 0);
return;
Modified: trunk/Source/WebKit/UIProcess/UserContent/WebUserContentControllerProxy.cpp (286083 => 286084)
--- trunk/Source/WebKit/UIProcess/UserContent/WebUserContentControllerProxy.cpp 2021-11-19 23:19:44 UTC (rev 286083)
+++ trunk/Source/WebKit/UIProcess/UserContent/WebUserContentControllerProxy.cpp 2021-11-19 23:52:41 UTC (rev 286084)
@@ -140,13 +140,11 @@
}
#if ENABLE(CONTENT_EXTENSIONS)
-Vector<std::pair<String, WebCompiledContentRuleListData>> WebUserContentControllerProxy::contentRuleListData() const
+Vector<std::pair<WebCompiledContentRuleListData, URL>> WebUserContentControllerProxy::contentRuleListData() const
{
- Vector<std::pair<String, WebCompiledContentRuleListData>> data;
- data.reserveInitialCapacity(m_contentRuleLists.size());
- for (const auto& contentRuleList : m_contentRuleLists.values())
- data.uncheckedAppend(std::make_pair(contentRuleList->name(), contentRuleList->compiledRuleList().data()));
- return data;
+ return WTF::map(m_contentRuleLists, [](const auto& keyValue) -> std::pair<WebCompiledContentRuleListData, URL> {
+ return { keyValue.value.first->compiledRuleList().data(), keyValue.value.second };
+ });
}
#endif
@@ -362,17 +360,17 @@
}
#if ENABLE(CONTENT_EXTENSIONS)
-void WebUserContentControllerProxy::addContentRuleList(API::ContentRuleList& contentRuleList)
+void WebUserContentControllerProxy::addContentRuleList(API::ContentRuleList& contentRuleList, const WTF::URL& extensionBaseURL)
{
- m_contentRuleLists.set(contentRuleList.name(), &contentRuleList);
+ m_contentRuleLists.set(contentRuleList.name(), std::make_pair(Ref { contentRuleList }, extensionBaseURL));
- auto pair = std::make_pair(contentRuleList.name(), contentRuleList.compiledRuleList().data());
+ auto& data = ""
for (auto& process : m_processes)
- process.send(Messages::WebUserContentController::AddContentRuleLists({ pair }), identifier());
+ process.send(Messages::WebUserContentController::AddContentRuleLists({ { data, extensionBaseURL } }), identifier());
for (auto& process : m_networkProcesses)
- process.send(Messages::NetworkContentRuleListManager::AddContentRuleLists { identifier(), { pair } }, 0);
+ process.send(Messages::NetworkContentRuleListManager::AddContentRuleLists { identifier(), { { data, extensionBaseURL } } }, 0);
}
void WebUserContentControllerProxy::removeContentRuleList(const String& name)
Modified: trunk/Source/WebKit/UIProcess/UserContent/WebUserContentControllerProxy.h (286083 => 286084)
--- trunk/Source/WebKit/UIProcess/UserContent/WebUserContentControllerProxy.h 2021-11-19 23:19:44 UTC (rev 286083)
+++ trunk/Source/WebKit/UIProcess/UserContent/WebUserContentControllerProxy.h 2021-11-19 23:52:41 UTC (rev 286084)
@@ -38,6 +38,8 @@
#include <wtf/HashMap.h>
#include <wtf/Ref.h>
#include <wtf/RefCounted.h>
+#include <wtf/URL.h>
+#include <wtf/URLHash.h>
#include <wtf/WeakHashSet.h>
#include <wtf/text/StringHash.h>
@@ -102,11 +104,11 @@
void addNetworkProcess(NetworkProcessProxy&);
void removeNetworkProcess(NetworkProcessProxy&);
- void addContentRuleList(API::ContentRuleList&);
+ void addContentRuleList(API::ContentRuleList&, const WTF::URL& extensionBaseURL = { });
void removeContentRuleList(const String&);
void removeAllContentRuleLists();
- const HashMap<String, RefPtr<API::ContentRuleList>>& contentExtensionRules() { return m_contentRuleLists; }
- Vector<std::pair<String, WebCompiledContentRuleListData>> contentRuleListData() const;
+ const HashMap<String, std::pair<Ref<API::ContentRuleList>, URL>>& contentExtensionRules() { return m_contentRuleLists; }
+ Vector<std::pair<WebCompiledContentRuleListData, URL>> contentRuleListData() const;
#endif
UserContentControllerIdentifier identifier() const { return m_identifier; }
@@ -130,7 +132,7 @@
#if ENABLE(CONTENT_EXTENSIONS)
WeakHashSet<NetworkProcessProxy> m_networkProcesses;
- HashMap<String, RefPtr<API::ContentRuleList>> m_contentRuleLists;
+ HashMap<String, std::pair<Ref<API::ContentRuleList>, URL>> m_contentRuleLists;
#endif
};
Modified: trunk/Source/WebKit/UIProcess/WebProcessProxy.cpp (286083 => 286084)
--- trunk/Source/WebKit/UIProcess/WebProcessProxy.cpp 2021-11-19 23:19:44 UTC (rev 286083)
+++ trunk/Source/WebKit/UIProcess/WebProcessProxy.cpp 2021-11-19 23:52:41 UTC (rev 286084)
@@ -1983,7 +1983,7 @@
}
#if ENABLE(CONTENT_EXTENSIONS)
-static Vector<std::pair<String, WebCompiledContentRuleListData>> contentRuleListsFromIdentifier(const std::optional<UserContentControllerIdentifier>& userContentControllerIdentifier)
+static Vector<std::pair<WebCompiledContentRuleListData, URL>> contentRuleListsFromIdentifier(const std::optional<UserContentControllerIdentifier>& userContentControllerIdentifier)
{
if (!userContentControllerIdentifier) {
ASSERT_NOT_REACHED();
Modified: trunk/Source/WebKit/WebProcess/UserContent/WebUserContentController.cpp (286083 => 286084)
--- trunk/Source/WebKit/WebProcess/UserContent/WebUserContentController.cpp 2021-11-19 23:19:44 UTC (rev 286083)
+++ trunk/Source/WebKit/WebProcess/UserContent/WebUserContentController.cpp 2021-11-19 23:52:41 UTC (rev 286084)
@@ -385,12 +385,14 @@
#endif
#if ENABLE(CONTENT_EXTENSIONS)
-void WebUserContentController::addContentRuleLists(Vector<std::pair<String, WebCompiledContentRuleListData>>&& contentRuleLists)
+void WebUserContentController::addContentRuleLists(Vector<std::pair<WebCompiledContentRuleListData, URL>>&& contentRuleLists)
{
- for (auto&& contentRuleList : contentRuleLists) {
- auto compiledContentRuleList = WebCompiledContentRuleList::create(WTFMove(contentRuleList.second));
+ for (auto&& pair : contentRuleLists) {
+ auto&& contentRuleList = WTFMove(pair.first);
+ String identifier = contentRuleList.identifier;
+ auto compiledContentRuleList = WebCompiledContentRuleList::create(WTFMove(contentRuleList));
- m_contentExtensionBackend.addContentExtension(contentRuleList.first, WTFMove(compiledContentRuleList));
+ m_contentExtensionBackend.addContentExtension(identifier, WTFMove(compiledContentRuleList), WTFMove(pair.second));
}
}
Modified: trunk/Source/WebKit/WebProcess/UserContent/WebUserContentController.h (286083 => 286084)
--- trunk/Source/WebKit/WebProcess/UserContent/WebUserContentController.h 2021-11-19 23:19:44 UTC (rev 286083)
+++ trunk/Source/WebKit/WebProcess/UserContent/WebUserContentController.h 2021-11-19 23:52:41 UTC (rev 286084)
@@ -72,7 +72,7 @@
void addUserStyleSheets(const Vector<WebUserStyleSheetData>&);
void addUserScriptMessageHandlers(const Vector<WebScriptMessageHandlerData>&);
#if ENABLE(CONTENT_EXTENSIONS)
- void addContentRuleLists(Vector<std::pair<String, WebCompiledContentRuleListData>>&&);
+ void addContentRuleLists(Vector<std::pair<WebCompiledContentRuleListData, URL>>&&);
#endif
private:
Modified: trunk/Source/WebKit/WebProcess/UserContent/WebUserContentController.messages.in (286083 => 286084)
--- trunk/Source/WebKit/WebProcess/UserContent/WebUserContentController.messages.in 2021-11-19 23:19:44 UTC (rev 286083)
+++ trunk/Source/WebKit/WebProcess/UserContent/WebUserContentController.messages.in 2021-11-19 23:52:41 UTC (rev 286084)
@@ -41,7 +41,7 @@
RemoveAllUserScriptMessageHandlers();
#if ENABLE(CONTENT_EXTENSIONS)
- AddContentRuleLists(Vector<std::pair<String, WebKit::WebCompiledContentRuleListData>> contentFilters);
+ AddContentRuleLists(Vector<std::pair<WebKit::WebCompiledContentRuleListData, URL>> contentFilters);
RemoveContentRuleList(String name);
RemoveAllContentRuleLists();
#endif
Modified: trunk/Tools/ChangeLog (286083 => 286084)
--- trunk/Tools/ChangeLog 2021-11-19 23:19:44 UTC (rev 286083)
+++ trunk/Tools/ChangeLog 2021-11-19 23:52:41 UTC (rev 286084)
@@ -1,3 +1,16 @@
+2021-11-19 Alex Christensen <[email protected]>
+
+ Implement extension-path variant of redirect action in WKContentRuleList
+ https://bugs.webkit.org/show_bug.cgi?id=233351
+
+ Reviewed by Tim Hatcher.
+
+ * TestWebKitAPI/Tests/WebCore/ContentExtensions.cpp:
+ (TestWebKitAPI::makeBackend):
+ (TestWebKitAPI::TEST_F):
+ * TestWebKitAPI/Tests/WebKitCocoa/WKContentExtensionStore.mm:
+ (TEST_F):
+
2021-11-19 J Pascoe <[email protected]>
[WebAuthn] Add headers for [_WKWebAuthenticationPanel makeCredentialWithClientDataHash] and [_WKWebAuthenticationPanel getAssertionWithClientDataHash]
Modified: trunk/Tools/TestWebKitAPI/Tests/WebCore/ContentExtensions.cpp (286083 => 286084)
--- trunk/Tools/TestWebKitAPI/Tests/WebCore/ContentExtensions.cpp 2021-11-19 23:19:44 UTC (rev 286083)
+++ trunk/Tools/TestWebKitAPI/Tests/WebCore/ContentExtensions.cpp 2021-11-19 23:52:41 UTC (rev 286084)
@@ -201,7 +201,7 @@
AtomString::init();
auto extension = InMemoryCompiledContentExtension::create(json);
ContentExtensions::ContentExtensionsBackend backend;
- backend.addContentExtension("testFilter", WTFMove(extension));
+ backend.addContentExtension("testFilter", WTFMove(extension), { });
return backend;
}
@@ -848,8 +848,8 @@
auto extension1 = InMemoryCompiledContentExtension::create("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"block_load\"}}]");
auto extension2 = InMemoryCompiledContentExtension::create("[{\"action\":{\"type\":\"block-cookies\"},\"trigger\":{\"url-filter\":\"block_cookies\"}}]");
ContentExtensions::ContentExtensionsBackend backend;
- backend.addContentExtension("testFilter1", WTFMove(extension1));
- backend.addContentExtension("testFilter2", WTFMove(extension2));
+ backend.addContentExtension("testFilter1", WTFMove(extension1), { });
+ backend.addContentExtension("testFilter2", WTFMove(extension2), { });
testRequest(backend, mainDocumentRequest("http://webkit.org"), { }, 2);
testRequest(backend, mainDocumentRequest("http://webkit.org/block_load.html"), { variantIndex<ContentExtensions::BlockLoadAction> }, 2);
@@ -862,8 +862,8 @@
auto ignoreExtension2 = InMemoryCompiledContentExtension::create("[{\"action\":{\"type\":\"block-cookies\"},\"trigger\":{\"url-filter\":\"block_cookies\"}},"
"{\"action\":{\"type\":\"ignore-previous-rules\"},\"trigger\":{\"url-filter\":\"ignore2\"}}]");
ContentExtensions::ContentExtensionsBackend backendWithIgnore;
- backendWithIgnore.addContentExtension("testFilter1", WTFMove(ignoreExtension1));
- backendWithIgnore.addContentExtension("testFilter2", WTFMove(ignoreExtension2));
+ backendWithIgnore.addContentExtension("testFilter1", WTFMove(ignoreExtension1), { });
+ backendWithIgnore.addContentExtension("testFilter2", WTFMove(ignoreExtension2), { });
testRequest(backendWithIgnore, mainDocumentRequest("http://webkit.org"), { }, 2);
testRequest(backendWithIgnore, mainDocumentRequest("http://webkit.org/block_load/ignore1.html"), { }, 1);
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKContentExtensionStore.mm (286083 => 286084)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKContentExtensionStore.mm 2021-11-19 23:19:44 UTC (rev 286083)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKContentExtensionStore.mm 2021-11-19 23:52:41 UTC (rev 286084)
@@ -32,6 +32,7 @@
#import "TestURLSchemeHandler.h"
#import <WebKit/WKContentRuleList.h>
#import <WebKit/WKContentRuleListStorePrivate.h>
+#import <WebKit/WKUserContentControllerPrivate.h>
#import <WebKit/WKWebpagePreferencesPrivate.h>
#import <WebKit/_WKUserContentExtensionStore.h>
#import <WebKit/_WKUserContentFilter.h>
@@ -751,3 +752,40 @@
EXPECT_FALSE(getRedirectResult(DelegateAction::AllowNone));
EXPECT_TRUE(getRedirectResult(DelegateAction::AllowTestHost));
}
+
+TEST_F(WKContentRuleListStoreTest, ExtensionPath)
+{
+ auto list = compileContentRuleList(R"JSON(
+ [ {
+ "action": { "type": "redirect", "redirect": {
+ "extension-path": "/redirected-to-extension?no-query#no-fragment"
+ } },
+ "trigger": { "url-filter": "main.html" }
+ } ]
+ )JSON");
+
+ __block RetainPtr<NSURL> redirectedURL;
+ auto handler = adoptNS([TestURLSchemeHandler new]);
+ handler.get().startURLSchemeTaskHandler = ^(WKWebView *, id <WKURLSchemeTask> task) {
+ redirectedURL = task.request.URL;
+ respond(task, "");
+ };
+
+ auto delegate = adoptNS([TestNavigationDelegate new]);
+ delegate.get().decidePolicyForNavigationActionWithPreferences = ^(WKNavigationAction *, WKWebpagePreferences *preferences, void (^decisionHandler)(WKNavigationActionPolicy, WKWebpagePreferences *)) {
+ preferences._activeContentRuleListActionPatterns = nil;
+ decisionHandler(WKNavigationActionPolicyAllow, preferences);
+ };
+
+ auto configuration = adoptNS([WKWebViewConfiguration new]);
+ [[configuration userContentController] _addContentRuleList:list.get() extensionBaseURL:[NSURL URLWithString:@"extension-scheme://extension-host/"]];
+ [configuration setURLSchemeHandler:handler.get() forURLScheme:@"testscheme"];
+ [configuration setURLSchemeHandler:handler.get() forURLScheme:@"extension-scheme"];
+ auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSZeroRect configuration:configuration.get()]);
+ webView.get().navigationDelegate = delegate.get();
+
+ [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"testscheme://testhost/main.html"]]];
+ while (!redirectedURL)
+ TestWebKitAPI::Util::spinRunLoop();
+ EXPECT_WK_STREQ([redirectedURL absoluteString], "extension-scheme://extension-host/redirected-to-extension%3Fno-query%23no-fragment");
+}