Changeset 222602 in webkit
- Timestamp:
- Sep 27, 2017 10:43:39 PM (7 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 32 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r222597 r222602 1 2017-09-27 Alex Christensen <achristensen@webkit.org> 2 3 Add WKContentRuleList notify action type 4 https://bugs.webkit.org/show_bug.cgi?id=177013 5 <rdar://problem/31073936> 6 7 Reviewed by Darin Adler. 8 9 Covered by new API tests. 10 11 * contentextensions/ContentExtensionActions.h: 12 (WebCore::ContentExtensions::hasStringArgument): 13 * contentextensions/ContentExtensionCompiler.cpp: 14 (WebCore::ContentExtensions::resolvePendingDisplayNoneActions): 15 (WebCore::ContentExtensions::serializeActions): 16 * contentextensions/ContentExtensionError.cpp: 17 (WebCore::ContentExtensions::contentExtensionErrorCategory): 18 * contentextensions/ContentExtensionError.h: 19 * contentextensions/ContentExtensionParser.cpp: 20 (WebCore::ContentExtensions::loadAction): 21 * contentextensions/ContentExtensionRule.cpp: 22 (WebCore::ContentExtensions::Action::deserialize): 23 (WebCore::ContentExtensions::Action::deserializeType): 24 (WebCore::ContentExtensions::Action::serializedLength): 25 * contentextensions/ContentExtensionRule.h: 26 (WebCore::ContentExtensions::Action::Action): 27 * contentextensions/ContentExtensionsBackend.cpp: 28 (WebCore::ContentExtensions::ContentExtensionsBackend::processContentExtensionRulesForLoad): 29 (WebCore::ContentExtensions::ContentExtensionsBackend::processContentExtensionRulesForPingLoad): 30 (WebCore::ContentExtensions::applyBlockedStatusToRequest): 31 * loader/FrameLoader.cpp: 32 (WebCore::FrameLoader::loadResourceSynchronously): 33 * loader/PingLoader.cpp: 34 (WebCore::processContentExtensionRulesForLoad): 35 * loader/ResourceLoader.cpp: 36 (WebCore::ResourceLoader::willSendRequestInternal): 37 * loader/cache/CachedResourceLoader.cpp: 38 (WebCore::CachedResourceLoader::requestResource): 39 * loader/cache/CachedResourceRequest.cpp: 40 (WebCore::CachedResourceRequest::applyBlockedStatus): 41 * loader/cache/CachedResourceRequest.h: 42 * page/ChromeClient.h: 43 1 44 2017-09-27 Wenson Hsieh <wenson_hsieh@apple.com> 2 45 -
trunk/Source/WebCore/contentextensions/ContentExtensionActions.h
r222462 r222602 28 28 #if ENABLE(CONTENT_EXTENSIONS) 29 29 30 #include <wtf/HashSet.h> 31 #include <wtf/text/WTFString.h> 32 30 33 namespace WebCore { 31 34 35 class Page; 32 36 class ResourceRequest; 33 37 … … 40 44 BlockCookies, 41 45 CSSDisplayNoneSelector, 42 IgnorePreviousRules = 3, 43 MakeHTTPS = 4, 46 Notify, 47 IgnorePreviousRules, 48 MakeHTTPS, 44 49 }; 50 51 static inline bool hasStringArgument(ActionType actionType) 52 { 53 switch (actionType) { 54 case ActionType::CSSDisplayNoneSelector: 55 case ActionType::Notify: 56 return true; 57 case ActionType::BlockLoad: 58 case ActionType::BlockCookies: 59 case ActionType::IgnorePreviousRules: 60 case ActionType::MakeHTTPS: 61 return false; 62 } 63 ASSERT_NOT_REACHED(); 64 return false; 65 } 45 66 46 67 struct BlockedStatus { … … 48 69 bool blockedCookies { false }; 49 70 bool madeHTTPS { false }; 71 HashSet<std::pair<String, String>> notifications; 50 72 }; 51 73 52 WEBCORE_EXPORT void applyBlockedStatusToRequest(const BlockedStatus&, ResourceRequest&);74 WEBCORE_EXPORT void applyBlockedStatusToRequest(const BlockedStatus&, Page*, ResourceRequest&); 53 75 54 76 } // namespace ContentExtensions -
trunk/Source/WebCore/contentextensions/ContentExtensionCompiler.cpp
r222462 r222602 69 69 } 70 70 71 // css-display-none combining is special because we combine the string arguments with commas because we know they are css selectors. 71 72 struct PendingDisplayNoneActions { 72 Vector<String> selectors;73 Vector<u nsigned> clientLocations;73 StringBuilder combinedSelectors; 74 Vector<uint32_t> clientLocations; 74 75 }; 76 75 77 using PendingDisplayNoneActionsMap = HashMap<Trigger, PendingDisplayNoneActions, TriggerHash, TriggerHashTraits>; 76 78 77 static void resolvePendingDisplayNoneActions(Vector<SerializedActionByte>& actions, Vector<unsigned>& actionLocations, PendingDisplayNoneActionsMap& pendingDisplayNoneActionsMap) 78 { 79 for (auto& slot : pendingDisplayNoneActionsMap) { 80 PendingDisplayNoneActions& pendingActions = slot.value; 81 82 StringBuilder combinedSelectors; 83 for (unsigned i = 0; i < pendingActions.selectors.size(); ++i) { 84 if (i) 85 combinedSelectors.append(','); 86 combinedSelectors.append(pendingActions.selectors[i]); 87 } 88 89 unsigned actionLocation = actions.size(); 79 static void resolvePendingDisplayNoneActions(Vector<SerializedActionByte>& actions, Vector<uint32_t>& actionLocations, PendingDisplayNoneActionsMap& map) 80 { 81 for (auto& pendingDisplayNoneActions : map.values()) { 82 uint32_t actionLocation = actions.size(); 90 83 actions.append(static_cast<SerializedActionByte>(ActionType::CSSDisplayNoneSelector)); 91 serializeString(actions, combinedSelectors.toString());92 for (u nsigned clientLocation : pendingActions.clientLocations)84 serializeString(actions, pendingDisplayNoneActions.combinedSelectors.toString()); 85 for (uint32_t clientLocation : pendingDisplayNoneActions.clientLocations) 93 86 actionLocations[clientLocation] = actionLocation; 94 87 } 95 pendingDisplayNoneActionsMap.clear();88 map.clear(); 96 89 } 97 90 … … 100 93 ASSERT(!actions.size()); 101 94 102 Vector<unsigned> actionLocations; 103 104 // Order only matters because of IgnorePreviousRules. All other identical actions can be combined between each IgnorePreviousRules 105 // and CSSDisplayNone strings can be combined if their triggers are identical. 95 Vector<uint32_t> actionLocations; 96 106 97 using ActionLocation = uint32_t; 107 98 using ActionMap = HashMap<ResourceFlags, ActionLocation, DefaultHash<ResourceFlags>::Hash, WTF::UnsignedWithZeroKeyHashTraits<ResourceFlags>>; 99 using StringActionMap = HashMap<std::pair<String, ResourceFlags>, ActionLocation, DefaultHash<std::pair<String, ResourceFlags>>::Hash, PairHashTraits<HashTraits<String>, WTF::UnsignedWithZeroKeyHashTraits<ResourceFlags>>>; 108 100 ActionMap blockLoadActionsMap; 109 101 ActionMap blockCookiesActionsMap; … … 111 103 ActionMap ignorePreviousRuleActionsMap; 112 104 ActionMap makeHTTPSActionsMap; 105 StringActionMap notifyActionsMap; 113 106 114 107 for (unsigned ruleIndex = 0; ruleIndex < ruleList.size(); ++ruleIndex) { … … 123 116 cssDisplayNoneActionsMap.clear(); 124 117 makeHTTPSActionsMap.clear(); 118 notifyActionsMap.clear(); 125 119 } else 126 120 ignorePreviousRuleActionsMap.clear(); … … 132 126 133 127 actions.append(static_cast<SerializedActionByte>(actionType)); 134 if ( actionType == ActionType::CSSDisplayNoneSelector)128 if (hasStringArgument(actionType)) 135 129 serializeString(actions, rule.action().stringArgument()); 130 else 131 ASSERT(rule.action().stringArgument().isNull()); 136 132 continue; 137 133 } … … 140 136 unsigned actionLocation = std::numeric_limits<unsigned>::max(); 141 137 142 auto findOrMakeActionLocation = [&] (ActionMap& map) 143 { 138 auto findOrMakeActionLocation = [&] (ActionMap& map) { 144 139 const auto existingAction = map.find(flags); 145 140 if (existingAction == map.end()) { … … 150 145 actionLocation = existingAction->value; 151 146 }; 147 148 auto findOrMakeStringActionLocation = [&] (StringActionMap& map) { 149 const String& argument = rule.action().stringArgument(); 150 auto existingAction = map.find(std::make_pair(argument, flags)); 151 if (existingAction == map.end()) { 152 actionLocation = actions.size(); 153 actions.append(static_cast<SerializedActionByte>(actionType)); 154 serializeString(actions, argument); 155 map.set(std::make_pair(argument, flags), actionLocation); 156 } else 157 actionLocation = existingAction->value; 158 }; 152 159 153 160 switch (actionType) { 154 161 case ActionType::CSSDisplayNoneSelector: { 155 162 const auto addResult = cssDisplayNoneActionsMap.add(rule.trigger(), PendingDisplayNoneActions()); 156 PendingDisplayNoneActions& pendingDisplayNoneActions = addResult.iterator->value; 157 pendingDisplayNoneActions.selectors.append(rule.action().stringArgument()); 158 pendingDisplayNoneActions.clientLocations.append(actionLocations.size()); 163 auto& pendingStringActions = addResult.iterator->value; 164 if (!pendingStringActions.combinedSelectors.isEmpty()) 165 pendingStringActions.combinedSelectors.append(','); 166 pendingStringActions.combinedSelectors.append(rule.action().stringArgument()); 167 pendingStringActions.clientLocations.append(actionLocations.size()); 159 168 160 169 actionLocation = std::numeric_limits<unsigned>::max(); … … 172 181 case ActionType::MakeHTTPS: 173 182 findOrMakeActionLocation(makeHTTPSActionsMap); 183 break; 184 case ActionType::Notify: 185 findOrMakeStringActionLocation(notifyActionsMap); 174 186 break; 175 187 } -
trunk/Source/WebCore/contentextensions/ContentExtensionError.cpp
r222462 r222602 88 88 case ContentExtensionError::JSONTopURLAndDomainConditions: 89 89 return "A list cannot have if-domain and unless-domain mixed with if-top-url and unless-top-url"; 90 case ContentExtensionError::JSONInvalidNotification: 91 return "A notify action must have a string notification"; 90 92 } 91 93 -
trunk/Source/WebCore/contentextensions/ContentExtensionError.h
r222462 r222602 59 59 JSONInvalidActionType, 60 60 JSONInvalidCSSDisplayNoneActionType, 61 JSONInvalidNotification, 61 62 JSONInvalidRegex, 62 63 }; -
trunk/Source/WebCore/contentextensions/ContentExtensionParser.cpp
r222462 r222602 249 249 250 250 const JSValue actionObject = ruleObject.get(&exec, Identifier::fromString(&exec, "action")); 251 if ( !actionObject ||scope.exception() || !actionObject.isObject())251 if (scope.exception() || !actionObject.isObject()) 252 252 return makeUnexpected(ContentExtensionError::JSONInvalidAction); 253 253 254 254 const JSValue typeObject = actionObject.get(&exec, Identifier::fromString(&exec, "type")); 255 if ( !typeObject ||scope.exception() || !typeObject.isString())255 if (scope.exception() || !typeObject.isString()) 256 256 return makeUnexpected(ContentExtensionError::JSONInvalidActionType); 257 257 … … 266 266 if (actionType == "css-display-none") { 267 267 JSValue selector = actionObject.get(&exec, Identifier::fromString(&exec, "selector")); 268 if ( !selector ||scope.exception() || !selector.isString())268 if (scope.exception() || !selector.isString()) 269 269 return makeUnexpected(ContentExtensionError::JSONInvalidCSSDisplayNoneActionType); 270 270 … … 278 278 if (actionType == "make-https") 279 279 return {{ ActionType::MakeHTTPS }}; 280 if (actionType == "notify") { 281 JSValue notification = actionObject.get(&exec, Identifier::fromString(&exec, "notification")); 282 if (scope.exception() || !notification.isString()) 283 return makeUnexpected(ContentExtensionError::JSONInvalidNotification); 284 return { Action(ActionType::Notify, asString(notification)->value(&exec)) }; 285 } 280 286 return makeUnexpected(ContentExtensionError::JSONInvalidActionType); 281 287 } -
trunk/Source/WebCore/contentextensions/ContentExtensionRule.cpp
r222462 r222602 67 67 return Action(actionType, location); 68 68 case ActionType::CSSDisplayNoneSelector: 69 case ActionType::Notify: 69 70 return Action(actionType, deserializeString(actions, actionsLength, location + sizeof(ActionType)), location); 70 71 } … … 79 80 case ActionType::BlockCookies: 80 81 case ActionType::BlockLoad: 82 case ActionType::Notify: 81 83 case ActionType::IgnorePreviousRules: 82 84 case ActionType::CSSDisplayNoneSelector: … … 96 98 case ActionType::MakeHTTPS: 97 99 return sizeof(ActionType); 100 case ActionType::Notify: 98 101 case ActionType::CSSDisplayNoneSelector: { 99 102 uint32_t prefixLength = sizeof(ActionType) + sizeof(uint32_t) + sizeof(bool); -
trunk/Source/WebCore/contentextensions/ContentExtensionRule.h
r222462 r222602 136 136 , m_stringArgument(stringArgument) 137 137 { 138 ASSERT( type == ActionType::CSSDisplayNoneSelector);138 ASSERT(hasStringArgument(type)); 139 139 } 140 140 … … 143 143 , m_actionID(actionID) 144 144 { 145 ASSERT( type != ActionType::CSSDisplayNoneSelector);145 ASSERT(!hasStringArgument(type)); 146 146 } 147 147 -
trunk/Source/WebCore/contentextensions/ContentExtensionsBackend.cpp
r222462 r222602 29 29 #if ENABLE(CONTENT_EXTENSIONS) 30 30 31 #include "Chrome.h" 32 #include "ChromeClient.h" 31 33 #include "CompiledContentExtension.h" 32 34 #include "ContentExtension.h" … … 39 41 #include "FrameLoaderClient.h" 40 42 #include "MainFrame.h" 43 #include "Page.h" 41 44 #include "ResourceLoadInfo.h" 42 45 #include "URL.h" … … 171 174 bool willBlockCookies = false; 172 175 bool willMakeHTTPS = false; 176 HashSet<std::pair<String, String>> notifications; 173 177 for (const auto& action : actions.first) { 174 178 switch (action.type()) { … … 184 188 else if (currentDocument) 185 189 currentDocument->extensionStyleSheets().addDisplayNoneSelector(action.extensionIdentifier(), action.stringArgument(), action.actionID()); 190 break; 191 case ContentExtensions::ActionType::Notify: 192 notifications.add(std::make_pair(action.extensionIdentifier(), action.stringArgument())); 186 193 break; 187 194 case ContentExtensions::ActionType::MakeHTTPS: { … … 214 221 currentDocument->addConsoleMessage(MessageSource::ContentBlocker, MessageLevel::Info, makeString("Content blocker prevented frame displaying ", mainDocumentURL.string(), " from loading a resource from ", url.string())); 215 222 } 216 return { willBlockLoad, willBlockCookies, willMakeHTTPS };223 return { willBlockLoad, willBlockCookies, willMakeHTTPS, WTFMove(notifications) }; 217 224 } 218 225 … … 241 248 break; 242 249 case ContentExtensions::ActionType::CSSDisplayNoneSelector: 250 case ContentExtensions::ActionType::Notify: 243 251 break; 244 252 case ContentExtensions::ActionType::IgnorePreviousRules: … … 247 255 } 248 256 249 return { willBlockLoad, willBlockCookies, willMakeHTTPS };257 return { willBlockLoad, willBlockCookies, willMakeHTTPS, { } }; 250 258 } 251 259 … … 256 264 } 257 265 258 void applyBlockedStatusToRequest(const BlockedStatus& status, ResourceRequest& request) 259 { 266 void applyBlockedStatusToRequest(const BlockedStatus& status, Page* page, ResourceRequest& request) 267 { 268 if (page && !status.notifications.isEmpty()) 269 page->chrome().client().contentRuleListNotification(request.url(), status.notifications); 270 260 271 if (status.blockedCookies) 261 272 request.setAllowCookies(false); -
trunk/Source/WebCore/loader/FrameLoader.cpp
r222472 r222602 2782 2782 if (m_documentLoader) { 2783 2783 auto blockedStatus = page->userContentProvider().processContentExtensionRulesForLoad(newRequest.url(), ResourceType::Raw, *m_documentLoader); 2784 applyBlockedStatusToRequest(blockedStatus, newRequest);2784 applyBlockedStatusToRequest(blockedStatus, page, newRequest); 2785 2785 if (blockedStatus.blockedLoad) { 2786 2786 newRequest = { }; -
trunk/Source/WebCore/loader/PingLoader.cpp
r222462 r222602 76 76 return false; 77 77 auto status = page->userContentProvider().processContentExtensionRulesForLoad(request.url(), resourceType, *documentLoader); 78 applyBlockedStatusToRequest(status, request);78 applyBlockedStatusToRequest(status, page, request); 79 79 return status.blockedLoad; 80 80 } -
trunk/Source/WebCore/loader/ResourceLoader.cpp
r222467 r222602 346 346 347 347 #if ENABLE(CONTENT_EXTENSIONS) 348 if ( frameLoader()) {348 if (!redirectResponse.isNull() && frameLoader()) { 349 349 Page* page = frameLoader()->frame().page(); 350 350 if (page && m_documentLoader) { 351 351 auto blockedStatus = page->userContentProvider().processContentExtensionRulesForLoad(request.url(), m_resourceType, *m_documentLoader); 352 applyBlockedStatusToRequest(blockedStatus, request);352 applyBlockedStatusToRequest(blockedStatus, page, request); 353 353 if (blockedStatus.blockedLoad) { 354 354 request = { }; -
trunk/Source/WebCore/loader/cache/CachedResourceLoader.cpp
r222467 r222602 726 726 if (frame() && frame()->mainFrame().page() && m_documentLoader) { 727 727 const auto& resourceRequest = request.resourceRequest(); 728 auto blockedStatus = frame()->mainFrame().page()->userContentProvider().processContentExtensionRulesForLoad(resourceRequest.url(), toResourceType(type), *m_documentLoader); 729 request.applyBlockedStatus(blockedStatus); 728 auto* page = frame()->mainFrame().page(); 729 auto blockedStatus = page->userContentProvider().processContentExtensionRulesForLoad(resourceRequest.url(), toResourceType(type), *m_documentLoader); 730 request.applyBlockedStatus(blockedStatus, page); 730 731 if (blockedStatus.blockedLoad) { 731 732 RELEASE_LOG_IF_ALLOWED("requestResource: Resource blocked by content blocker (frame = %p)", frame()); -
trunk/Source/WebCore/loader/cache/CachedResourceRequest.cpp
r222467 r222602 213 213 #if ENABLE(CONTENT_EXTENSIONS) 214 214 215 void CachedResourceRequest::applyBlockedStatus(const ContentExtensions::BlockedStatus& blockedStatus )216 { 217 ContentExtensions::applyBlockedStatusToRequest(blockedStatus, m_resourceRequest);215 void CachedResourceRequest::applyBlockedStatus(const ContentExtensions::BlockedStatus& blockedStatus, Page* page) 216 { 217 ContentExtensions::applyBlockedStatusToRequest(blockedStatus, page, m_resourceRequest); 218 218 } 219 219 -
trunk/Source/WebCore/loader/cache/CachedResourceRequest.h
r222462 r222602 77 77 void removeFragmentIdentifierIfNeeded(); 78 78 #if ENABLE(CONTENT_EXTENSIONS) 79 void applyBlockedStatus(const ContentExtensions::BlockedStatus& );79 void applyBlockedStatus(const ContentExtensions::BlockedStatus&, Page*); 80 80 #endif 81 81 void setDomainForCachePartition(Document&); -
trunk/Source/WebCore/page/ChromeClient.h
r222462 r222602 371 371 virtual void disableSuddenTermination() { } 372 372 373 virtual void contentRuleListNotification(const WebCore::URL&, const HashSet<std::pair<String, String>>&) { }; 374 373 375 #if PLATFORM(WIN) 374 376 virtual void setLastSetCursorToCurrentCursor() = 0; -
trunk/Source/WebKit/ChangeLog
r222595 r222602 1 2017-09-27 Alex Christensen <achristensen@webkit.org> 2 3 Add WKContentRuleList notify action type 4 https://bugs.webkit.org/show_bug.cgi?id=177013 5 <rdar://problem/31073936> 6 7 Reviewed by Darin Adler. 8 9 * NetworkProcess/PingLoad.cpp: 10 (WebKit::PingLoad::processContentExtensionRulesForLoad): 11 * UIProcess/API/APINavigationClient.h: 12 (API::NavigationClient::contentRuleListNotification): 13 * UIProcess/API/C/WKPage.cpp: 14 (WKPageSetPageNavigationClient): 15 * UIProcess/API/C/WKPageNavigationClient.h: 16 * UIProcess/API/Cocoa/WKNavigationDelegatePrivate.h: 17 * UIProcess/Cocoa/NavigationState.h: 18 * UIProcess/Cocoa/NavigationState.mm: 19 (WebKit::NavigationState::setNavigationDelegate): 20 (WebKit::NavigationState::NavigationClient::contentRuleListNotification): 21 * UIProcess/WebPageProxy.cpp: 22 (WebKit::WebPageProxy::contentRuleListNotification): 23 * UIProcess/WebPageProxy.h: 24 * UIProcess/WebPageProxy.messages.in: 25 * WebProcess/WebCoreSupport/WebChromeClient.cpp: 26 (WebKit::WebChromeClient::contentRuleListNotification): 27 * WebProcess/WebCoreSupport/WebChromeClient.h: 28 1 29 2017-09-27 Wenson Hsieh <wenson_hsieh@apple.com> 2 30 -
trunk/Source/WebKit/NetworkProcess/PingLoad.cpp
r222570 r222602 324 324 { 325 325 auto status = contentExtensionsBackend().processContentExtensionRulesForPingLoad(request.url(), m_parameters.mainDocumentURL); 326 applyBlockedStatusToRequest(status, request);326 applyBlockedStatusToRequest(status, nullptr, request); 327 327 return status; 328 328 } -
trunk/Source/WebKit/UIProcess/API/APINavigationClient.h
r222583 r222602 107 107 } 108 108 109 virtual void contentRuleListNotification(WebKit::WebPageProxy&, WebCore::URL&&, Vector<WTF::String>&&, Vector<WTF::String>&&) { }; 110 109 111 #if ENABLE(NETSCAPE_PLUGIN_API) 110 112 virtual WebKit::PluginModuleLoadPolicy decidePolicyForPluginLoad(WebKit::WebPageProxy&, WebKit::PluginModuleLoadPolicy currentPluginLoadPolicy, Dictionary*, WTF::String&) -
trunk/Source/WebKit/UIProcess/API/C/WKPage.cpp
r222583 r222602 103 103 104 104 template<> struct ClientTraits<WKPageNavigationClientBase> { 105 typedef std::tuple<WKPageNavigationClientV0, WKPageNavigationClientV1 > Versions;105 typedef std::tuple<WKPageNavigationClientV0, WKPageNavigationClientV1, WKPageNavigationClientV2> Versions; 106 106 }; 107 107 … … 2296 2296 } 2297 2297 2298 void contentRuleListNotification(WebPageProxy& page, URL&& url, Vector<String>&& listIdentifiers, Vector<String>&& notifications) final 2299 { 2300 if (!m_client.contentRuleListNotification) 2301 return; 2302 2303 Vector<RefPtr<API::Object>> apiListIdentifiers; 2304 for (const auto& identifier : listIdentifiers) 2305 apiListIdentifiers.append(API::String::create(identifier)); 2306 2307 Vector<RefPtr<API::Object>> apiNotifications; 2308 for (const auto& notification : notifications) 2309 apiNotifications.append(API::String::create(notification)); 2310 2311 m_client.contentRuleListNotification(toAPI(&page), toURLRef(url.string().impl()), toAPI(API::Array::create(WTFMove(apiListIdentifiers)).ptr()), toAPI(API::Array::create(WTFMove(apiNotifications)).ptr()), m_client.base.clientInfo); 2312 } 2298 2313 #if ENABLE(NETSCAPE_PLUGIN_API) 2299 2314 PluginModuleLoadPolicy decidePolicyForPluginLoad(WebPageProxy& page, PluginModuleLoadPolicy currentPluginLoadPolicy, API::Dictionary* pluginInformation, String& unavailabilityDescription) override -
trunk/Source/WebKit/UIProcess/API/C/WKPageNavigationClient.h
r222462 r222602 81 81 typedef void (*WKPageNavigationDidRemoveNavigationGestureSnapshot)(WKPageRef page, const void* clientInfo); 82 82 83 typedef void (*WKPageNavigationContentRuleListNotificationCallback)(WKPageRef, WKURLRef, WKArrayRef, WKArrayRef, const void* clientInfo); 83 84 84 85 typedef struct WKPageNavigationClientBase { … … 144 145 } WKPageNavigationClientV1; 145 146 147 typedef struct WKPageNavigationClientV2 { 148 WKPageNavigationClientBase base; 149 150 // Version 0. 151 WKPageNavigationDecidePolicyForNavigationActionCallback decidePolicyForNavigationAction; 152 WKPageNavigationDecidePolicyForNavigationResponseCallback decidePolicyForNavigationResponse; 153 WKPageNavigationDecidePolicyForPluginLoadCallback decidePolicyForPluginLoad; 154 WKPageNavigationDidStartProvisionalNavigationCallback didStartProvisionalNavigation; 155 WKPageNavigationDidReceiveServerRedirectForProvisionalNavigationCallback didReceiveServerRedirectForProvisionalNavigation; 156 WKPageNavigationDidFailProvisionalNavigationCallback didFailProvisionalNavigation; 157 WKPageNavigationDidCommitNavigationCallback didCommitNavigation; 158 WKPageNavigationDidFinishNavigationCallback didFinishNavigation; 159 WKPageNavigationDidFailNavigationCallback didFailNavigation; 160 WKPageNavigationDidFailProvisionalLoadInSubframeCallback didFailProvisionalLoadInSubframe; 161 WKPageNavigationDidFinishDocumentLoadCallback didFinishDocumentLoad; 162 WKPageNavigationDidSameDocumentNavigationCallback didSameDocumentNavigation; 163 WKPageNavigationRenderingProgressDidChangeCallback renderingProgressDidChange; 164 WKPageNavigationCanAuthenticateAgainstProtectionSpaceCallback canAuthenticateAgainstProtectionSpace; 165 WKPageNavigationDidReceiveAuthenticationChallengeCallback didReceiveAuthenticationChallenge; 166 WKPageNavigationWebProcessDidCrashCallback webProcessDidCrash; 167 WKPageNavigationCopyWebCryptoMasterKeyCallback copyWebCryptoMasterKey; 168 WKPageNavigationDidBeginNavigationGesture didBeginNavigationGesture; 169 WKPageNavigationWillEndNavigationGesture willEndNavigationGesture; 170 WKPageNavigationDidEndNavigationGesture didEndNavigationGesture; 171 WKPageNavigationDidRemoveNavigationGestureSnapshot didRemoveNavigationGestureSnapshot; 172 173 // Version 1. 174 WKPageNavigationWebProcessDidTerminateCallback webProcessDidTerminate; 175 176 // Version 2. 177 WKPageNavigationContentRuleListNotificationCallback contentRuleListNotification; 178 } WKPageNavigationClientV2; 179 146 180 #ifdef __cplusplus 147 181 } -
trunk/Source/WebKit/UIProcess/API/Cocoa/WKNavigationDelegatePrivate.h
r222462 r222602 79 79 - (void)_webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy, _WKWebsitePolicies *))decisionHandler WK_API_AVAILABLE(macosx(10.12.3), ios(10.3)); 80 80 81 - (void)_webView:(WKWebView *)webView URL:(NSURL *)url contentRuleListIdentifiers:(NSArray<NSString *> *)identifiers notifications:(NSArray<NSString *> *)notifications WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA)); 82 81 83 #if TARGET_OS_IPHONE 82 84 - (void)_webView:(WKWebView *)webView didStartLoadForQuickLookDocumentInMainFrameWithFileName:(NSString *)fileName uti:(NSString *)uti; -
trunk/Source/WebKit/UIProcess/Cocoa/NavigationState.h
r222583 r222602 122 122 #endif 123 123 124 void contentRuleListNotification(WebPageProxy&, WebCore::URL&&, Vector<String>&&, Vector<String>&&) final; 124 125 void decidePolicyForNavigationAction(WebPageProxy&, Ref<API::NavigationAction>&&, Ref<WebFramePolicyListenerProxy>&&, API::Object* userData) override; 125 126 void decidePolicyForNavigationResponse(WebPageProxy&, API::NavigationResponse&, Ref<WebFramePolicyListenerProxy>&&, API::Object* userData) override; … … 202 203 bool webViewWillSnapshotBackForwardListItem : 1; 203 204 bool webViewNavigationGestureSnapshotWasRemoved : 1; 205 bool webViewURLContentRuleListIdentifiersNotifications : 1; 204 206 #if USE(QUICK_LOOK) 205 207 bool webViewDidStartLoadForQuickLookDocumentInMainFrame : 1; -
trunk/Source/WebKit/UIProcess/Cocoa/NavigationState.mm
r222583 r222602 169 169 m_navigationDelegateMethods.webViewWillSnapshotBackForwardListItem = [delegate respondsToSelector:@selector(_webView:willSnapshotBackForwardListItem:)]; 170 170 m_navigationDelegateMethods.webViewNavigationGestureSnapshotWasRemoved = [delegate respondsToSelector:@selector(_webViewDidRemoveNavigationGestureSnapshot:)]; 171 m_navigationDelegateMethods.webViewURLContentRuleListIdentifiersNotifications = [delegate respondsToSelector:@selector(_webView:URL:contentRuleListIdentifiers:notifications:)]; 171 172 #if USE(QUICK_LOOK) 172 173 m_navigationDelegateMethods.webViewDidStartLoadForQuickLookDocumentInMainFrame = [delegate respondsToSelector:@selector(_webView:didStartLoadForQuickLookDocumentInMainFrameWithFileName:uti:)]; … … 459 460 } 460 461 462 void NavigationState::NavigationClient::contentRuleListNotification(WebPageProxy&, WebCore::URL&& url, Vector<String>&& listIdentifiers, Vector<String>&& notifications) 463 { 464 if (!m_navigationState.m_navigationDelegateMethods.webViewURLContentRuleListIdentifiersNotifications) 465 return; 466 467 auto navigationDelegate = m_navigationState.m_navigationDelegate.get(); 468 if (!navigationDelegate) 469 return; 470 471 ASSERT(listIdentifiers.size() == notifications.size()); 472 473 auto identifiers = adoptNS([[NSMutableArray alloc] initWithCapacity:listIdentifiers.size()]); 474 for (auto& identifier : listIdentifiers) 475 [identifiers addObject:identifier]; 476 477 auto nsNotifications = adoptNS([[NSMutableArray alloc] initWithCapacity:notifications.size()]); 478 for (auto& notification : notifications) 479 [nsNotifications addObject:notification]; 480 481 [(id <WKNavigationDelegatePrivate>)navigationDelegate _webView:m_navigationState.m_webView URL:url contentRuleListIdentifiers:identifiers.get() notifications:nsNotifications.get()]; 482 } 483 461 484 void NavigationState::NavigationClient::decidePolicyForNavigationResponse(WebPageProxy&, API::NavigationResponse& navigationResponse, Ref<WebFramePolicyListenerProxy>&& listener, API::Object* userData) 462 485 { -
trunk/Source/WebKit/UIProcess/WebPageProxy.cpp
r222583 r222602 3800 3800 } 3801 3801 3802 void WebPageProxy::contentRuleListNotification(WebCore::URL&& url, Vector<String>&& identifiers, Vector<String>&& notifications) 3803 { 3804 if (m_navigationClient) 3805 m_navigationClient->contentRuleListNotification(*this, WTFMove(url), WTFMove(identifiers), WTFMove(notifications)); 3806 } 3807 3802 3808 void WebPageProxy::didNavigateWithNavigationData(const WebNavigationDataStore& store, uint64_t frameID) 3803 3809 { -
trunk/Source/WebKit/UIProcess/WebPageProxy.h
r222583 r222602 1291 1291 1292 1292 void willSubmitForm(uint64_t frameID, uint64_t sourceFrameID, const Vector<std::pair<String, String>>& textFieldValues, uint64_t listenerID, const UserData&); 1293 1294 void contentRuleListNotification(WebCore::URL&&, Vector<String>&& identifiers, Vector<String>&& notifications); 1293 1295 1294 1296 // History client -
trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in
r222492 r222602 459 459 460 460 HandleAutoFillButtonClick(WebKit::UserData userData); 461 ContentRuleListNotification(WebCore::URL url, Vector<String> identifiers, Vector<String> notifications) 461 462 462 463 #if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS) -
trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp
r222462 r222602 875 875 } 876 876 877 void WebChromeClient::contentRuleListNotification(const URL& url, const HashSet<std::pair<String, String>>& notificationPairs) 878 { 879 Vector<String> identifiers; 880 Vector<String> notifications; 881 identifiers.reserveInitialCapacity(notificationPairs.size()); 882 notifications.reserveInitialCapacity(notificationPairs.size()); 883 for (auto& notification : notificationPairs) { 884 identifiers.uncheckedAppend(notification.first); 885 notifications.uncheckedAppend(notification.second); 886 } 887 888 m_page.send(Messages::WebPageProxy::ContentRuleListNotification(url, identifiers, notifications)); 889 } 890 877 891 bool WebChromeClient::adjustLayerFlushThrottling(LayerFlushThrottleState::Flags flags) 878 892 { -
trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h
r222462 r222602 209 209 bool adjustLayerFlushThrottling(WebCore::LayerFlushThrottleState::Flags) final; 210 210 211 void contentRuleListNotification(const WebCore::URL&, const HashSet<std::pair<String, String>>&) final; 212 211 213 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR) 212 214 RefPtr<WebCore::DisplayRefreshMonitor> createDisplayRefreshMonitor(WebCore::PlatformDisplayID) const final; -
trunk/Tools/ChangeLog
r222595 r222602 1 2017-09-27 Alex Christensen <achristensen@webkit.org> 2 3 Add WKContentRuleList notify action type 4 https://bugs.webkit.org/show_bug.cgi?id=177013 5 <rdar://problem/31073936> 6 7 Reviewed by Darin Adler. 8 9 * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: 10 * TestWebKitAPI/Tests/WebCore/ContentExtensions.cpp: 11 (WebCore::ContentExtensions::operator<<): 12 (TestWebKitAPI::InMemoryCompiledContentExtension::create): 13 (TestWebKitAPI::InMemoryCompiledContentExtension::data): 14 (TestWebKitAPI::InMemoryCompiledContentExtension::InMemoryCompiledContentExtension): 15 (TestWebKitAPI::makeBackend): 16 (TestWebKitAPI::TEST_F): 17 (TestWebKitAPI::actionsEqual): 18 (TestWebKitAPI::sequenceInstances): 19 (TestWebKitAPI::InMemoryCompiledContentExtension::createFromFilter): Deleted. 20 (TestWebKitAPI::InMemoryCompiledContentExtension::~InMemoryCompiledContentExtension): Deleted. 21 * TestWebKitAPI/Tests/WebKitCocoa/ContentRuleListNotification.mm: Added. 22 (-[ContentRuleListNotificationDelegate _webView:URL:contentRuleListIdentifiers:notifications:]): 23 (-[ContentRuleListNotificationDelegate webView:startURLSchemeTask:]): 24 (-[ContentRuleListNotificationDelegate webView:stopURLSchemeTask:]): 25 (-[ContentRuleListNotificationDelegate webView:runJavaScriptAlertPanelWithMessage:initiatedByFrame:completionHandler:]): 26 (makeWarnContentRuleList): 27 (TEST): 28 1 29 2017-09-27 Wenson Hsieh <wenson_hsieh@apple.com> 2 30 -
trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
r222595 r222602 239 239 5C9E59431D3EB5AC00E3C62E /* ApplicationCache.db-wal in Copy Resources */ = {isa = PBXBuildFile; fileRef = 5C9E59401D3EB1DE00E3C62E /* ApplicationCache.db-wal */; }; 240 240 5CA1DEC81F71F70100E71BD3 /* HTTPHeaderField.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5CA1DEC71F71F40700E71BD3 /* HTTPHeaderField.cpp */; }; 241 5CA1DED91F74A91A00E71BD3 /* ContentRuleListNotification.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5CA1DED81F74A87100E71BD3 /* ContentRuleListNotification.mm */; }; 241 242 5CB18BA81F5645E300EE23C4 /* ClickAutoFillButton.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5CB18BA71F5645B200EE23C4 /* ClickAutoFillButton.mm */; }; 242 243 5CB40B4E1F4B98D3007DC7B9 /* UIDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5CB40B4D1F4B98BE007DC7B9 /* UIDelegate.mm */; }; … … 1342 1343 5C9E59401D3EB1DE00E3C62E /* ApplicationCache.db-wal */ = {isa = PBXFileReference; lastKnownFileType = file; path = "ApplicationCache.db-wal"; sourceTree = "<group>"; }; 1343 1344 5CA1DEC71F71F40700E71BD3 /* HTTPHeaderField.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTTPHeaderField.cpp; sourceTree = "<group>"; }; 1345 5CA1DED81F74A87100E71BD3 /* ContentRuleListNotification.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ContentRuleListNotification.mm; sourceTree = "<group>"; }; 1344 1346 5CB18BA71F5645B200EE23C4 /* ClickAutoFillButton.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ClickAutoFillButton.mm; sourceTree = "<group>"; }; 1345 1347 5CB40B4D1F4B98BE007DC7B9 /* UIDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = UIDelegate.mm; sourceTree = "<group>"; }; … … 1948 1950 A14FC5861B8991B600D107EB /* ContentFiltering.mm */, 1949 1951 A14FC5891B89927100D107EB /* ContentFilteringPlugIn.mm */, 1952 5CA1DED81F74A87100E71BD3 /* ContentRuleListNotification.mm */, 1950 1953 5C2936911D5BF63E00DEAB1E /* CookieAcceptPolicy.mm */, 1951 1954 9999108A1F393C8B008AD455 /* Copying.mm */, … … 3171 3174 A1146A8D1D2D7115000FE710 /* ContentFiltering.mm in Sources */, 3172 3175 A14FC5881B8991BF00D107EB /* ContentFiltering.mm in Sources */, 3176 5CA1DED91F74A91A00E71BD3 /* ContentRuleListNotification.mm in Sources */, 3173 3177 7CCE7EB81A411A7E00447C4C /* ContextMenuCanCopyURL.mm in Sources */, 3174 3178 37FB72971DB2E82F00E41BE4 /* ContextMenuDefaultItemsHaveTags.mm in Sources */, -
trunk/Tools/TestWebKitAPI/Tests/WebCore/ContentExtensions.cpp
r222462 r222602 57 57 case ActionType::CSSDisplayNoneSelector: 58 58 return os << "ActionType::CSSDisplayNone"; 59 case ActionType::Notify: 60 return os << "ActionType::Notify"; 59 61 case ActionType::IgnorePreviousRules: 60 62 return os << "ActionType::IgnorePreviousRules"; … … 98 100 } 99 101 102 private: 100 103 void writeSource(const String&) final { } 101 104 … … 138 141 } 139 142 140 private:141 143 CompiledContentExtensionData& m_data; 142 144 bool finalized { false }; … … 145 147 class InMemoryCompiledContentExtension : public ContentExtensions::CompiledContentExtension { 146 148 public: 147 static Ref<InMemoryCompiledContentExtension> create FromFilter(String&& filter)149 static Ref<InMemoryCompiledContentExtension> create(String&& filter) 148 150 { 149 151 CompiledContentExtensionData extensionData; 150 152 InMemoryContentExtensionCompilationClient client(extensionData); 151 153 auto compilerError = ContentExtensions::compileRuleList(client, WTFMove(filter)); 152 if (compilerError) { 153 // Compiling should always succeed here. We have other tests for compile failures. 154 EXPECT_TRUE(false); 155 } 156 157 return InMemoryCompiledContentExtension::create(WTFMove(extensionData)); 154 155 // Compiling should always succeed here. We have other tests for compile failures. 156 EXPECT_FALSE(compilerError); 157 158 return adoptRef(*new InMemoryCompiledContentExtension(WTFMove(extensionData))); 158 159 } 159 160 160 static Ref<InMemoryCompiledContentExtension> create(CompiledContentExtensionData&& data) 161 { 162 return adoptRef(*new InMemoryCompiledContentExtension(WTFMove(data))); 163 } 164 165 virtual ~InMemoryCompiledContentExtension() 166 { 167 } 168 161 const CompiledContentExtensionData& data() { return m_data; }; 162 163 private: 169 164 const ContentExtensions::SerializedActionByte* actions() const final { return m_data.actions.data(); } 170 165 unsigned actionsLength() const final { return m_data.actions.size(); } … … 177 172 bool conditionsApplyOnlyToDomain() const final { return m_data.conditionsApplyOnlyToDomain; } 178 173 179 private:180 174 InMemoryCompiledContentExtension(CompiledContentExtensionData&& data) 181 175 : m_data(WTFMove(data)) 182 { 183 } 176 { } 184 177 185 178 CompiledContentExtensionData m_data; … … 212 205 { 213 206 AtomicString::init(); 214 auto extension = InMemoryCompiledContentExtension::create FromFilter(json);207 auto extension = InMemoryCompiledContentExtension::create(json); 215 208 ContentExtensions::ContentExtensionsBackend backend; 216 209 backend.addContentExtension("testFilter", WTFMove(extension)); … … 857 850 TEST_F(ContentExtensionTest, MultipleExtensions) 858 851 { 859 auto extension1 = InMemoryCompiledContentExtension::create FromFilter("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"block_load\"}}]");860 auto extension2 = InMemoryCompiledContentExtension::create FromFilter("[{\"action\":{\"type\":\"block-cookies\"},\"trigger\":{\"url-filter\":\"block_cookies\"}}]");852 auto extension1 = InMemoryCompiledContentExtension::create("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"block_load\"}}]"); 853 auto extension2 = InMemoryCompiledContentExtension::create("[{\"action\":{\"type\":\"block-cookies\"},\"trigger\":{\"url-filter\":\"block_cookies\"}}]"); 861 854 ContentExtensions::ContentExtensionsBackend backend; 862 855 backend.addContentExtension("testFilter1", WTFMove(extension1)); … … 869 862 testRequest(backend, mainDocumentRequest("http://webkit.org/block_cookies/block_load.html"), { ContentExtensions::ActionType::BlockCookies, ContentExtensions::ActionType::BlockLoad }, 2); 870 863 871 auto ignoreExtension1 = InMemoryCompiledContentExtension::create FromFilter("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"block_load\"}},"864 auto ignoreExtension1 = InMemoryCompiledContentExtension::create("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"block_load\"}}," 872 865 "{\"action\":{\"type\":\"ignore-previous-rules\"},\"trigger\":{\"url-filter\":\"ignore1\"}}]"); 873 auto ignoreExtension2 = InMemoryCompiledContentExtension::create FromFilter("[{\"action\":{\"type\":\"block-cookies\"},\"trigger\":{\"url-filter\":\"block_cookies\"}},"866 auto ignoreExtension2 = InMemoryCompiledContentExtension::create("[{\"action\":{\"type\":\"block-cookies\"},\"trigger\":{\"url-filter\":\"block_cookies\"}}," 874 867 "{\"action\":{\"type\":\"ignore-previous-rules\"},\"trigger\":{\"url-filter\":\"ignore2\"}}]"); 875 868 ContentExtensions::ContentExtensionsBackend backendWithIgnore; … … 883 876 testRequest(backendWithIgnore, mainDocumentRequest("http://webkit.org/block_cookies/ignore2.html"), { }, 1); 884 877 testRequest(backendWithIgnore, mainDocumentRequest("http://webkit.org/block_load/block_cookies/ignore1/ignore2.html"), { }, 0); 878 } 879 880 static bool actionsEqual(const std::pair<Vector<WebCore::ContentExtensions::Action>, Vector<String>>& actual, Vector<WebCore::ContentExtensions::Action>&& expected, bool ignorePreviousRules = false) 881 { 882 if (ignorePreviousRules) { 883 if (actual.second.size()) 884 return false; 885 } else { 886 if (actual.second.size() != 1) 887 return false; 888 if (actual.second[0] != "testFilter") 889 return false; 890 } 891 892 if (actual.first.size() != expected.size()) 893 return false; 894 for (size_t i = 0; i < expected.size(); ++i) { 895 if (actual.first[i].type() != expected[i].type()) 896 return false; 897 if (actual.first[i].stringArgument() != expected[i].stringArgument()) 898 return false; 899 } 900 return true; 901 } 902 903 static const char* jsonWithStringsToCombine = "[" 904 "{\"action\":{\"type\":\"notify\",\"notification\":\"AAA\"},\"trigger\":{\"url-filter\":\"A\"}}," 905 "{\"action\":{\"type\":\"notify\",\"notification\":\"AAA\"},\"trigger\":{\"url-filter\":\"A\"}}," 906 "{\"action\":{\"type\":\"notify\",\"notification\":\"BBB\"},\"trigger\":{\"url-filter\":\"B\"}}," 907 "{\"action\":{\"type\":\"css-display-none\",\"selector\":\"CCC\"},\"trigger\":{\"url-filter\":\"C\"}}," 908 "{\"action\":{\"type\":\"css-display-none\",\"selector\":\"selectorCombinedWithC\"},\"trigger\":{\"url-filter\":\"C\"}}," 909 "{\"action\":{\"type\":\"css-display-none\",\"selector\":\"DDD\"},\"trigger\":{\"url-filter\":\"D\"}}," 910 "{\"action\":{\"type\":\"ignore-previous-rules\"},\"trigger\":{\"url-filter\":\"E\"}}," 911 "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"F\"}}," 912 "{\"action\":{\"type\":\"notify\",\"notification\":\"GGG\"},\"trigger\":{\"url-filter\":\"G\"}}," 913 "{\"action\":{\"type\":\"notify\",\"notification\":\"GGG\"},\"trigger\":{\"url-filter\":\"I\"}}," 914 "{\"action\":{\"type\":\"notify\",\"notification\":\"AAA\"},\"trigger\":{\"url-filter\":\"J\"}}," 915 "{\"action\":{\"type\":\"notify\",\"notification\":\"GGG\"},\"trigger\":{\"url-filter\":\"K\"}}" 916 "]"; 917 918 TEST_F(ContentExtensionTest, StringParameters) 919 { 920 auto backend1 = makeBackend("[{\"action\":{\"type\":\"notify\",\"notification\":\"testnotification\"},\"trigger\":{\"url-filter\":\"matches\"}}]"); 921 ASSERT_TRUE(actionsEqual(backend1.actionsForResourceLoad(mainDocumentRequest("test:///matches")), {{ ContentExtensions::ActionType::Notify, "testnotification" }})); 922 923 auto backend2 = makeBackend(jsonWithStringsToCombine); 924 ASSERT_TRUE(actionsEqual(backend2.actionsForResourceLoad(mainDocumentRequest("http://A")), {{ ContentExtensions::ActionType::Notify, "AAA" }})); 925 ASSERT_TRUE(actionsEqual(backend2.actionsForResourceLoad(mainDocumentRequest("http://B")), {{ ContentExtensions::ActionType::Notify, "BBB" }})); 926 ASSERT_TRUE(actionsEqual(backend2.actionsForResourceLoad(mainDocumentRequest("http://C")), {{ ContentExtensions::ActionType::CSSDisplayNoneSelector, "CCC,selectorCombinedWithC" }})); 927 ASSERT_TRUE(actionsEqual(backend2.actionsForResourceLoad(mainDocumentRequest("http://D")), {{ ContentExtensions::ActionType::CSSDisplayNoneSelector, "DDD" }})); 928 ASSERT_TRUE(actionsEqual(backend2.actionsForResourceLoad(mainDocumentRequest("http://E")), { }, true)); 929 ASSERT_TRUE(actionsEqual(backend2.actionsForResourceLoad(mainDocumentRequest("http://F")), { ContentExtensions::ActionType::BlockLoad })); 930 ASSERT_TRUE(actionsEqual(backend2.actionsForResourceLoad(mainDocumentRequest("http://G")), {{ ContentExtensions::ActionType::Notify, "GGG" }})); 931 ASSERT_TRUE(actionsEqual(backend2.actionsForResourceLoad(mainDocumentRequest("http://GIK")), {{ ContentExtensions::ActionType::Notify, "GGG" }})); 932 ASSERT_TRUE(actionsEqual(backend2.actionsForResourceLoad(mainDocumentRequest("http://AJ")), { 933 { ContentExtensions::ActionType::Notify, "AAA" }, 934 { ContentExtensions::ActionType::Notify, "AAA" } // ignore-previous-rules makes the AAA actions need to be unique. 935 })); 936 // FIXME: Add a test that matches actions with AAA with ignore-previous-rules between them and makes sure we only get one notification. 937 ASSERT_TRUE(actionsEqual(backend2.actionsForResourceLoad(mainDocumentRequest("http://AE")), { }, true)); 938 ASSERT_TRUE(actionsEqual(backend2.actionsForResourceLoad(mainDocumentRequest("http://ABCDE")), { }, true)); 939 ASSERT_TRUE(actionsEqual(backend2.actionsForResourceLoad(mainDocumentRequest("http://ABCDEFG")), { 940 { ContentExtensions::ActionType::Notify, "GGG" }, 941 { ContentExtensions::ActionType::BlockLoad } 942 }, true)); 943 ASSERT_TRUE(actionsEqual(backend2.actionsForResourceLoad(mainDocumentRequest("http://FG")), { 944 { ContentExtensions::ActionType::Notify, "GGG" }, 945 { ContentExtensions::ActionType::BlockLoad } 946 })); 947 ASSERT_TRUE(actionsEqual(backend2.actionsForResourceLoad(mainDocumentRequest("http://EFG")), { 948 { ContentExtensions::ActionType::Notify, "GGG" }, 949 { ContentExtensions::ActionType::BlockLoad } 950 }, true)); 951 } 952 953 template<typename T, size_t cStringLength> 954 static int sequenceInstances(const Vector<T> vector, const char (&sequence)[cStringLength]) 955 { 956 static_assert(sizeof(T) == sizeof(char), "sequenceInstances should only be used for various byte vectors."); 957 958 size_t sequenceLength = cStringLength - 1; 959 size_t instances = 0; 960 for (size_t i = 0; i <= vector.size() - sequenceLength; ++i) { 961 for (size_t j = 0; j < sequenceLength; j++) { 962 if (vector[i + j] != sequence[j]) 963 break; 964 if (j == sequenceLength - 1) 965 instances++; 966 } 967 } 968 return instances; 969 } 970 971 TEST_F(ContentExtensionTest, StringCombining) 972 { 973 auto extension = InMemoryCompiledContentExtension::create(jsonWithStringsToCombine); 974 const auto& data = extension->data(); 975 976 ASSERT_EQ(sequenceInstances(data.actions, "AAA"), 2); 977 ASSERT_EQ(sequenceInstances(data.actions, "GGG"), 1); 978 979 ASSERT_EQ(data.actions.size(), 78u); 980 ASSERT_EQ(data.filtersWithoutConditions.size(), 313u); 981 ASSERT_EQ(data.filtersWithConditions.size(), 5u); 982 ASSERT_EQ(data.topURLFilters.size(), 5u); 983 ASSERT_FALSE(data.conditionsApplyOnlyToDomain); 984 985 auto extensionWithFlags = InMemoryCompiledContentExtension::create("[" 986 "{\"action\":{\"type\":\"notify\",\"notification\":\"AAA\"},\"trigger\":{\"url-filter\":\"A\"}}," 987 "{\"action\":{\"type\":\"notify\",\"notification\":\"AAA\"},\"trigger\":{\"url-filter\":\"C\"}}," 988 "{\"action\":{\"type\":\"notify\",\"notification\":\"AAA\"},\"trigger\":{\"url-filter\":\"A\",\"resource-type\":[\"document\"]}}," 989 "{\"action\":{\"type\":\"notify\",\"notification\":\"AAA\"},\"trigger\":{\"url-filter\":\"A\",\"resource-type\":[\"document\",\"font\"]}}," 990 "{\"action\":{\"type\":\"notify\",\"notification\":\"AAA\"},\"trigger\":{\"url-filter\":\"B\",\"resource-type\":[\"document\"]}}" 991 "]"); 992 ASSERT_EQ(sequenceInstances(extensionWithFlags->data().actions, "AAA"), 3); // There are 3 sets of unique flags for AAA actions. 885 993 } 886 994 … … 1377 1485 checkCompilerError("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"webkit.org\",\"resource-type\":false}}]", 1378 1486 ContentExtensions::ContentExtensionError::JSONInvalidTriggerFlagsArray); 1487 1488 checkCompilerError("[{\"action\":{\"type\":\"notify\"},\"trigger\":{\"url-filter\":\".*\"}}]", ContentExtensions::ContentExtensionError::JSONInvalidNotification); 1489 checkCompilerError("[{\"action\":{\"type\":\"notify\",\"notification\":5},\"trigger\":{\"url-filter\":\".*\"}}]", ContentExtensions::ContentExtensionError::JSONInvalidNotification); 1490 checkCompilerError("[{\"action\":{\"type\":\"notify\",\"notification\":[]},\"trigger\":{\"url-filter\":\".*\"}}]", ContentExtensions::ContentExtensionError::JSONInvalidNotification); 1491 checkCompilerError("[{\"action\":{\"type\":\"notify\",\"notification\":\"here's my notification\"},\"trigger\":{\"url-filter\":\".*\"}}]", { }); 1492 checkCompilerError("[{\"action\":{\"type\":\"notify\",\"notification\":\"\\u1234\"},\"trigger\":{\"url-filter\":\".*\"}}]", { }); 1379 1493 1380 1494 StringBuilder rules;
Note: See TracChangeset
for help on using the changeset viewer.