<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[194995] branches/safari-601.1.46-branch</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/194995">194995</a></dd>
<dt>Author</dt> <dd>matthew_hanson@apple.com</dd>
<dt>Date</dt> <dd>2016-01-13 15:11:02 -0800 (Wed, 13 Jan 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Merge <a href="http://trac.webkit.org/projects/webkit/changeset/194950">r194950</a>. rdar://problem/23270886</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#branchessafari601146branchSourceWTFChangeLog">branches/safari-601.1.46-branch/Source/WTF/ChangeLog</a></li>
<li><a href="#branchessafari601146branchSourceWTFwtfPlatformh">branches/safari-601.1.46-branch/Source/WTF/wtf/Platform.h</a></li>
<li><a href="#branchessafari601146branchSourceWebCoreChangeLog">branches/safari-601.1.46-branch/Source/WebCore/ChangeLog</a></li>
<li><a href="#branchessafari601146branchSourceWebCoreloaderContentFiltercpp">branches/safari-601.1.46-branch/Source/WebCore/loader/ContentFilter.cpp</a></li>
<li><a href="#branchessafari601146branchSourceWebCoreloaderContentFilterh">branches/safari-601.1.46-branch/Source/WebCore/loader/ContentFilter.h</a></li>
<li><a href="#branchessafari601146branchSourceWebCoreloaderDocumentLoadercpp">branches/safari-601.1.46-branch/Source/WebCore/loader/DocumentLoader.cpp</a></li>
<li><a href="#branchessafari601146branchSourceWebCoreloaderDocumentLoaderh">branches/safari-601.1.46-branch/Source/WebCore/loader/DocumentLoader.h</a></li>
<li><a href="#branchessafari601146branchSourceWebCoreplatformcocoaNetworkExtensionContentFilterh">branches/safari-601.1.46-branch/Source/WebCore/platform/cocoa/NetworkExtensionContentFilter.h</a></li>
<li><a href="#branchessafari601146branchSourceWebCoreplatformcocoaNetworkExtensionContentFiltermm">branches/safari-601.1.46-branch/Source/WebCore/platform/cocoa/NetworkExtensionContentFilter.mm</a></li>
<li><a href="#branchessafari601146branchSourceWebCoreplatformcocoaParentalControlsContentFilterh">branches/safari-601.1.46-branch/Source/WebCore/platform/cocoa/ParentalControlsContentFilter.h</a></li>
<li><a href="#branchessafari601146branchSourceWebCoreplatformcocoaParentalControlsContentFiltermm">branches/safari-601.1.46-branch/Source/WebCore/platform/cocoa/ParentalControlsContentFilter.mm</a></li>
<li><a href="#branchessafari601146branchSourceWebCoretestingMockContentFiltercpp">branches/safari-601.1.46-branch/Source/WebCore/testing/MockContentFilter.cpp</a></li>
<li><a href="#branchessafari601146branchSourceWebCoretestingMockContentFilterh">branches/safari-601.1.46-branch/Source/WebCore/testing/MockContentFilter.h</a></li>
<li><a href="#branchessafari601146branchToolsChangeLog">branches/safari-601.1.46-branch/Tools/ChangeLog</a></li>
<li><a href="#branchessafari601146branchToolsTestWebKitAPITestWebKitAPIxcodeprojprojectpbxproj">branches/safari-601.1.46-branch/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj</a></li>
<li><a href="#branchessafari601146branchToolsTestWebKitAPITestsCustomProtocolsSyncXHRTestmm">branches/safari-601.1.46-branch/Tools/TestWebKitAPI/Tests/CustomProtocolsSyncXHRTest.mm</a></li>
<li><a href="#branchessafari601146branchToolsTestWebKitAPITestsWebKit2CocoaContentFilteringmm">branches/safari-601.1.46-branch/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/ContentFiltering.mm</a></li>
<li><a href="#branchessafari601146branchToolsTestWebKitAPITestsWebKit2CocoaContentFilteringPlugInmm">branches/safari-601.1.46-branch/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/ContentFilteringPlugIn.mm</a></li>
<li><a href="#branchessafari601146branchToolsTestWebKitAPITestsWebKit2ObjCCustomProtocolsTestmm">branches/safari-601.1.46-branch/Tools/TestWebKitAPI/Tests/WebKit2ObjC/CustomProtocolsTest.mm</a></li>
<li><a href="#branchessafari601146branchToolsTestWebKitAPITestsWebKit2ObjCPreventImageLoadWithAutoResizingmm">branches/safari-601.1.46-branch/Tools/TestWebKitAPI/Tests/WebKit2ObjC/PreventImageLoadWithAutoResizing.mm</a></li>
<li><a href="#branchessafari601146branchToolsTestWebKitAPIcocoaTestProtocolh">branches/safari-601.1.46-branch/Tools/TestWebKitAPI/cocoa/TestProtocol.h</a></li>
<li><a href="#branchessafari601146branchToolsTestWebKitAPIcocoaTestProtocolmm">branches/safari-601.1.46-branch/Tools/TestWebKitAPI/cocoa/TestProtocol.mm</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#branchessafari601146branchToolsTestWebKitAPITestsWebKit2CocoaContentFilteringh">branches/safari-601.1.46-branch/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/ContentFiltering.h</a></li>
<li><a href="#branchessafari601146branchToolsTestWebKitAPITestsWebKit2CocoaContentFilteringhtml">branches/safari-601.1.46-branch/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/ContentFiltering.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="branchessafari601146branchSourceWTFChangeLog"></a>
<div class="modfile"><h4>Modified: branches/safari-601.1.46-branch/Source/WTF/ChangeLog (194994 => 194995)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601.1.46-branch/Source/WTF/ChangeLog        2016-01-13 23:10:53 UTC (rev 194994)
+++ branches/safari-601.1.46-branch/Source/WTF/ChangeLog        2016-01-13 23:11:02 UTC (rev 194995)
</span><span class="lines">@@ -1,4 +1,18 @@
</span><ins>+2016-01-13  Matthew Hanson  &lt;matthew_hanson@apple.com&gt;
</ins><span class="cx"> 
</span><ins>+        Merge r194950. rdar://problem/23270886
+
+    2016-01-08  Andy Estes  &lt;aestes@apple.com&gt;
+
+            [Content Filtering] Lazily load platform frameworks
+            https://bugs.webkit.org/show_bug.cgi?id=152881
+            rdar://problem/23270886
+
+            Reviewed by Brady Eidson.
+
+            * wtf/Platform.h: Moved definition of HAVE_NETWORK_EXTENSION to here from WebCore/platform/cocoa/NetworkExtensionContentFilter.h.
+
+
</ins><span class="cx"> 2015-09-11  Keith Miller  &lt;keith_miller@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         cryptographicallyRandomValuesFromOS should use CCRandomCopyBytes when available.
</span></span></pre></div>
<a id="branchessafari601146branchSourceWTFwtfPlatformh"></a>
<div class="modfile"><h4>Modified: branches/safari-601.1.46-branch/Source/WTF/wtf/Platform.h (194994 => 194995)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601.1.46-branch/Source/WTF/wtf/Platform.h        2016-01-13 23:10:53 UTC (rev 194994)
+++ branches/safari-601.1.46-branch/Source/WTF/wtf/Platform.h        2016-01-13 23:11:02 UTC (rev 194995)
</span><span class="lines">@@ -534,6 +534,7 @@
</span><span class="cx"> #define HAVE_SEC_KEYCHAIN 1
</span><span class="cx"> 
</span><span class="cx"> #if CPU(X86_64)
</span><ins>+#define HAVE_NETWORK_EXTENSION 1
</ins><span class="cx"> #define USE_PLUGIN_HOST_PROCESS 1
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="lines">@@ -547,6 +548,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(IOS)
</span><span class="cx"> 
</span><ins>+#define HAVE_NETWORK_EXTENSION 1
</ins><span class="cx"> #define HAVE_READLINE 1
</span><span class="cx"> #if USE(APPLE_INTERNAL_SDK)
</span><span class="cx"> #define USE_CFNETWORK 1
</span></span></pre></div>
<a id="branchessafari601146branchSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: branches/safari-601.1.46-branch/Source/WebCore/ChangeLog (194994 => 194995)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601.1.46-branch/Source/WebCore/ChangeLog        2016-01-13 23:10:53 UTC (rev 194994)
+++ branches/safari-601.1.46-branch/Source/WebCore/ChangeLog        2016-01-13 23:11:02 UTC (rev 194995)
</span><span class="lines">@@ -1,5 +1,102 @@
</span><span class="cx"> 2016-01-13  Matthew Hanson  &lt;matthew_hanson@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        Merge r194950. rdar://problem/23270886
+
+    2016-01-08  Andy Estes  &lt;aestes@apple.com&gt;
+
+            [Content Filtering] Lazily load platform frameworks
+            https://bugs.webkit.org/show_bug.cgi?id=152881
+            rdar://problem/23270886
+
+            Reviewed by Brady Eidson.
+
+            On Cocoa platforms, ContentFilter soft-links two frameworks that perform the underlying filtering operations.
+            There is a one-time cost associated with the soft-linking, and the current design requires all clients to pay
+            this cost whether or not they ever load a resource that is subject to filtering.
+
+            Addressed this by deferring the loading of frameworks until it is known that a resource will require filtering.
+            It is rather simple to defer the soft-linking at the PlatformContentFilter level, but doing this alone would
+            mean that every CachedRawResourceClient callback would be routed through ContentFilter, even in the very common
+            case where both platform content filters are disabled. This is because checking if a platform content filter is
+            enabled involves loading its framework, so creating a ContentFilter (which DocumentLoader will add as the
+            CachedRawResource client in place of itself) cannot be avoided by checking that all its platform content filters
+            are disabled.
+
+            Resolved this by inverting the relationship between ContentFilter and DocumentLoader. Instead of ContentFilter
+            being the CachedRawResource's client and forwarding callbacks to DocumentLoader when one or more platform
+            filters are enabled, DocumentLoader is now always the client and it forwards callbacks to ContentFilter.
+            ContentFilter then returns a boolean value indicating whether or not DocumentLoader should proceed with each
+            callback.
+
+            New API test: ContentFiltering.LazilyLoadPlatformFrameworks
+
+            * loader/ContentFilter.cpp:
+            (WebCore::ContentFilter::create): Renamed from createIfEnabled(). Since the enabled check causes frameworks to
+            be loaded, the check is skipped here and all types are always created.
+            (WebCore::ContentFilter::continueAfterWillSendRequest): Renamed from willSendRequest(). Renamed requestCopy to
+            originalRequest, and only created it for logging purposes. Since the copy was only used for logging purposes,
+            request is now modified directly. Returned false if request is null.
+            (WebCore::ContentFilter::continueAfterResponseReceived): Renamed from responseReceived(). Stopped asserting that
+            resource is non-null, since it will be null in the case of substitute data loads. Stopped asserting that m_state
+            is not Initialized, since that state was removed and the function can now be called in all states. Only logged
+            if m_state is Filtering. Returned false if m_state is Blocked.
+            (WebCore::ContentFilter::continueAfterDataReceived): Renamed from dataReceived(). Stopped asserting that
+            resource is non-null and that m_state is Initialized, and moved the logging, for the same reasons as above.
+            Returned false if m_state is Filtering or Blocked.
+            (WebCore::ContentFilter::continueAfterNotifyFinished): Renamed from notifyFinished(). Stopped asserting that
+            resource is non-null and that m_state is not Initialized, and moved the logging, for the same reasons as above.
+            If m_state is not Blocked at this point, set m_state to Allowed in order for deliverResourceData() to not get
+            caught in continueAfterDataReceived(). Returned false if m_state is Blocked or Stopped after delivering data.
+            (WebCore::ContentFilter::createIfEnabled): Renamed to create().
+            (WebCore::ContentFilter::~ContentFilter): Stopped removing ourself as m_mainResource's client.
+            (WebCore::ContentFilter::willSendRequest): Renamed to continueAfterWillSendRequest().
+            (WebCore::ContentFilter::startFilteringMainResource): Stopped adding ourself as m_mainResource's client. Stopped
+            asserting that m_state is not Initialized and instead returned early if m_state is not Stopped.
+            (WebCore::ContentFilter::stopFilteringMainResource): Stopped removing ourself as m_mainResource's client.
+            (WebCore::ContentFilter::responseReceived): Renamed to continueAfterResponseReceived().
+            (WebCore::ContentFilter::dataReceived): Renamed to continueAfterDataReceived().
+            (WebCore::ContentFilter::redirectReceived): Removed. DocumentLoader now calls continueAfterWillSendRequest()
+            directly on redirects.
+            (WebCore::ContentFilter::notifyFinished): Renamed to continueAfterNotifyFinished().
+            (WebCore::ContentFilter::didDecide): Instead of calling DocumentLoader::contentFilterDidDecide(), called
+            DocumentLoader::contentFilterDidBlock() when m_state is Blocked.
+            (WebCore::ContentFilter::deliverResourceData): Asserted that m_state is Allowed.
+            * loader/ContentFilter.h: Stopped inheriting from CachedRawResourceClient. Redeclared the
+            CachedRawResourceClient virtual functions as the continue* functions mentioned above. Made State enum private
+            and removed Initialized. Initialized m_state to Stopped and removed its getter.
+            (WebCore::ContentFilter::type): Returned a ContentFilter::Type that does not include an enabled function.
+            * loader/DocumentLoader.cpp:
+            (WebCore::DocumentLoader::notifyFinished): Returned early if ContentFilter::continueAfterNotifyFinished()
+            returned false.
+            (WebCore::DocumentLoader::willSendRequest): Called ContentFilter::continueAfterWillSendRequest() even for
+            redirects, since ContentFilter is no longer a CachedRawResourceClient and so will no longer receive
+            redirectReceived(). Returned early if continueAfterWillSendRequest() returns false.
+            (WebCore::DocumentLoader::responseReceived): Returned early if ContentFilter::continueAfterResponseReceived()
+            returned false.
+            (WebCore::DocumentLoader::dataReceived): Ditto for ContentFilter::continueAfterDataReceived().
+            (WebCore::DocumentLoader::startLoadingMainResource): Called ContentFilter::create(), not createIfEnabled().
+            (WebCore::DocumentLoader::becomeMainResourceClient): Called ContentFilter::startFilteringMainResource() even if
+            m_state is not Initialized. Added ourself as a client of m_mainResource unconditionally.
+            (WebCore::DocumentLoader::contentFilterDidBlock): Renamed from contentFilterDidDecide. Removed assertions and
+            the early return when m_state is Allowed, since the state is guaranteed to be Blocked.
+            (WebCore::DocumentLoader::contentFilterDidDecide): Renamed to contentFilterDidBlock.
+            * platform/cocoa/NetworkExtensionContentFilter.h: Moved definition of HAVE_NETWORK_EXTENSION to Platform.h so
+            that this file doesn't need to become a Private header. Made enabled() private, and declared initialize().
+            * platform/cocoa/NetworkExtensionContentFilter.mm:
+            (WebCore::NetworkExtensionContentFilter::initialize): Added a function to lazily initialize the object.
+            (WebCore::NetworkExtensionContentFilter::willSendRequest): For the modern NEFilterSource, checked if it is
+            enabled only after checking if the request is HTTP(S). If both checks pass, then called initialize().
+            (WebCore::NetworkExtensionContentFilter::responseReceived): Ditto for the legacy NEFilterSource.
+            * platform/cocoa/ParentalControlsContentFilter.h: Made enabled() private.
+            * platform/cocoa/ParentalControlsContentFilter.mm:
+            (WebCore::ParentalControlsContentFilter::responseReceived): Checked if WebFilterEvaluator is enabled only after
+            checking if the response is from a protocol that can be handled.
+            * testing/MockContentFilter.cpp:
+            (WebCore::MockContentFilter::willSendRequest): Immediately set m_status to Status::Allowed if !enabled().
+            * testing/MockContentFilter.h: Made enabled() private.
+
+2016-01-13  Matthew Hanson  &lt;matthew_hanson@apple.com&gt;
+
</ins><span class="cx">         Merge r194927. rdar://problem/24101173
</span><span class="cx"> 
</span><span class="cx">     2016-01-12  Daniel Bates  &lt;dabates@apple.com&gt;
</span></span></pre></div>
<a id="branchessafari601146branchSourceWebCoreloaderContentFiltercpp"></a>
<div class="modfile"><h4>Modified: branches/safari-601.1.46-branch/Source/WebCore/loader/ContentFilter.cpp (194994 => 194995)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601.1.46-branch/Source/WebCore/loader/ContentFilter.cpp        2016-01-13 23:10:53 UTC (rev 194994)
+++ branches/safari-601.1.46-branch/Source/WebCore/loader/ContentFilter.cpp        2016-01-13 23:11:02 UTC (rev 194995)
</span><span class="lines">@@ -59,13 +59,10 @@
</span><span class="cx">     return types;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-std::unique_ptr&lt;ContentFilter&gt; ContentFilter::createIfEnabled(DocumentLoader&amp; documentLoader)
</del><ins>+std::unique_ptr&lt;ContentFilter&gt; ContentFilter::create(DocumentLoader&amp; documentLoader)
</ins><span class="cx"> {
</span><span class="cx">     Container filters;
</span><span class="cx">     for (auto&amp; type : types()) {
</span><del>-        if (!type.enabled())
-            continue;
-
</del><span class="cx">         auto filter = type.create();
</span><span class="cx">         ASSERT(filter);
</span><span class="cx">         filters.append(WTF::move(filter));
</span><span class="lines">@@ -88,48 +85,41 @@
</span><span class="cx"> ContentFilter::~ContentFilter()
</span><span class="cx"> {
</span><span class="cx">     LOG(ContentFiltering, &quot;Destroying ContentFilter.\n&quot;);
</span><del>-    if (!m_mainResource)
-        return;
-    ASSERT(m_mainResource-&gt;hasClient(this));
-    m_mainResource-&gt;removeClient(this);
</del><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ContentFilter::willSendRequest(ResourceRequest&amp; request, const ResourceResponse&amp; redirectResponse)
</del><ins>+bool ContentFilter::continueAfterWillSendRequest(ResourceRequest&amp; request, const ResourceResponse&amp; redirectResponse)
</ins><span class="cx"> {
</span><span class="cx">     LOG(ContentFiltering, &quot;ContentFilter received request for &lt;%s&gt; with redirect response from &lt;%s&gt;.\n&quot;, request.url().string().ascii().data(), redirectResponse.url().string().ascii().data());
</span><del>-    ResourceRequest requestCopy { request };
-    ASSERT(m_state == State::Initialized || m_state == State::Filtering);
-    forEachContentFilterUntilBlocked([&amp;requestCopy, &amp;redirectResponse](PlatformContentFilter&amp; contentFilter) {
-        contentFilter.willSendRequest(requestCopy, redirectResponse);
-        if (contentFilter.didBlockData())
-            requestCopy = ResourceRequest();
</del><ins>+#if !LOG_DISABLED
+    ResourceRequest originalRequest { request };
+#endif
+    ASSERT(m_state == State::Stopped || m_state == State::Filtering);
+    forEachContentFilterUntilBlocked([&amp;request, &amp;redirectResponse](PlatformContentFilter&amp; contentFilter) {
+        contentFilter.willSendRequest(request, redirectResponse);
</ins><span class="cx">     });
</span><ins>+    if (m_state == State::Blocked)
+        request = ResourceRequest();
</ins><span class="cx"> #if !LOG_DISABLED
</span><del>-    if (request != requestCopy)
-        LOG(ContentFiltering, &quot;ContentFilter changed request url to &lt;%s&gt;.\n&quot;, requestCopy.url().string().ascii().data());
</del><ins>+    if (request != originalRequest)
+        LOG(ContentFiltering, &quot;ContentFilter changed request url to &lt;%s&gt;.\n&quot;, originalRequest.url().string().ascii().data());
</ins><span class="cx"> #endif
</span><del>-    request = requestCopy;
</del><ins>+    return !request.isNull();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ContentFilter::startFilteringMainResource(CachedRawResource&amp; resource)
</span><span class="cx"> {
</span><ins>+    if (m_state != State::Stopped)
+        return;
+
</ins><span class="cx">     LOG(ContentFiltering, &quot;ContentFilter will start filtering main resource at &lt;%s&gt;.\n&quot;, resource.url().string().ascii().data());
</span><del>-    ASSERT(m_state == State::Initialized);
</del><span class="cx">     m_state = State::Filtering;
</span><span class="cx">     ASSERT(!m_mainResource);
</span><span class="cx">     m_mainResource = &amp;resource;
</span><del>-    ASSERT(!m_mainResource-&gt;hasClient(this));
-    m_mainResource-&gt;addClient(this);
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ContentFilter::stopFilteringMainResource()
</span><span class="cx"> {
</span><span class="cx">     m_state = State::Stopped;
</span><del>-    if (!m_mainResource)
-        return;
-
-    ASSERT(m_mainResource-&gt;hasClient(this));
-    m_mainResource-&gt;removeClient(this);
</del><span class="cx">     m_mainResource = nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -157,83 +147,61 @@
</span><span class="cx">     return m_blockingContentFilter-&gt;unblockRequestDeniedScript();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ContentFilter::responseReceived(CachedResource* resource, const ResourceResponse&amp; response)
</del><ins>+bool ContentFilter::continueAfterResponseReceived(CachedResource* resource, const ResourceResponse&amp; response)
</ins><span class="cx"> {
</span><del>-    ASSERT(resource);
-    ASSERT(resource == m_mainResource);
-    ASSERT(m_state != State::Initialized);
-    LOG(ContentFiltering, &quot;ContentFilter received response from &lt;%s&gt;.\n&quot;, response.url().string().ascii().data());
</del><ins>+    ASSERT_UNUSED(resource, resource == m_mainResource);
</ins><span class="cx"> 
</span><span class="cx">     if (m_state == State::Filtering) {
</span><ins>+        LOG(ContentFiltering, &quot;ContentFilter received response from &lt;%s&gt;.\n&quot;, response.url().string().ascii().data());
</ins><span class="cx">         forEachContentFilterUntilBlocked([&amp;response](PlatformContentFilter&amp; contentFilter) {
</span><span class="cx">             contentFilter.responseReceived(response);
</span><span class="cx">         });
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (m_state != State::Blocked)
-        m_documentLoader.responseReceived(resource, response);
</del><ins>+    return m_state != State::Blocked;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ContentFilter::dataReceived(CachedResource* resource, const char* data, int length)
</del><ins>+bool ContentFilter::continueAfterDataReceived(CachedResource* resource, const char* data, int length)
</ins><span class="cx"> {
</span><del>-    ASSERT(resource);
</del><span class="cx">     ASSERT(resource == m_mainResource);
</span><del>-    ASSERT(m_state != State::Initialized);
-    LOG(ContentFiltering, &quot;ContentFilter received %d bytes of data from &lt;%s&gt;.\n&quot;, length, resource-&gt;url().string().ascii().data());
</del><span class="cx"> 
</span><span class="cx">     if (m_state == State::Filtering) {
</span><ins>+        LOG(ContentFiltering, &quot;ContentFilter received %d bytes of data from &lt;%s&gt;.\n&quot;, length, resource-&gt;url().string().ascii().data());
</ins><span class="cx">         forEachContentFilterUntilBlocked([data, length](PlatformContentFilter&amp; contentFilter) {
</span><span class="cx">             contentFilter.addData(data, length);
</span><span class="cx">         });
</span><span class="cx"> 
</span><span class="cx">         if (m_state == State::Allowed)
</span><span class="cx">             deliverResourceData(*resource);
</span><del>-        return;
</del><ins>+        return false;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (m_state == State::Allowed)
-        m_documentLoader.dataReceived(resource, data, length);
</del><ins>+    return m_state != State::Blocked;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ContentFilter::redirectReceived(CachedResource* resource, ResourceRequest&amp; request, const ResourceResponse&amp; redirectResponse)
</del><ins>+bool ContentFilter::continueAfterNotifyFinished(CachedResource* resource)
</ins><span class="cx"> {
</span><del>-    ASSERT(resource);
</del><span class="cx">     ASSERT(resource == m_mainResource);
</span><del>-    ASSERT(m_state != State::Initialized);
</del><span class="cx"> 
</span><del>-    if (m_state == State::Filtering)
-        willSendRequest(request, redirectResponse);
</del><ins>+    if (resource-&gt;errorOccurred())
+        return true;
</ins><span class="cx"> 
</span><del>-    if (m_state != State::Blocked)
-        m_documentLoader.redirectReceived(resource, request, redirectResponse);
-}
-
-void ContentFilter::notifyFinished(CachedResource* resource)
-{
-    ASSERT(resource);
-    ASSERT(resource == m_mainResource);
-    ASSERT(m_state != State::Initialized);
-    LOG(ContentFiltering, &quot;ContentFilter will finish filtering main resource at &lt;%s&gt;.\n&quot;, resource-&gt;url().string().ascii().data());
-
-    if (resource-&gt;errorOccurred()) {
-        m_documentLoader.notifyFinished(resource);
-        return;
-    }
-
</del><span class="cx">     if (m_state == State::Filtering) {
</span><ins>+        LOG(ContentFiltering, &quot;ContentFilter will finish filtering main resource at &lt;%s&gt;.\n&quot;, resource-&gt;url().string().ascii().data());
</ins><span class="cx">         forEachContentFilterUntilBlocked([](PlatformContentFilter&amp; contentFilter) {
</span><span class="cx">             contentFilter.finishedAddingData();
</span><span class="cx">         });
</span><span class="cx"> 
</span><del>-        if (m_state != State::Blocked)
</del><ins>+        if (m_state != State::Blocked) {
+            m_state = State::Allowed;
</ins><span class="cx">             deliverResourceData(*resource);
</span><del>-        
</del><ins>+        }
+
</ins><span class="cx">         if (m_state == State::Stopped)
</span><del>-            return;
</del><ins>+            return false;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (m_state != State::Blocked)
-        m_documentLoader.notifyFinished(resource);
</del><ins>+    return m_state != State::Blocked;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ContentFilter::forEachContentFilterUntilBlocked(std::function&lt;void(PlatformContentFilter&amp;)&gt; function)
</span><span class="lines">@@ -267,11 +235,13 @@
</span><span class="cx">     ASSERT(state == State::Allowed || state == State::Blocked);
</span><span class="cx">     LOG(ContentFiltering, &quot;ContentFilter decided load should be %s for main resource at &lt;%s&gt;.\n&quot;, state == State::Allowed ? &quot;allowed&quot; : &quot;blocked&quot;, m_mainResource ? m_mainResource-&gt;url().string().ascii().data() : &quot;&quot;);
</span><span class="cx">     m_state = state;
</span><del>-    m_documentLoader.contentFilterDidDecide();
</del><ins>+    if (m_state == State::Blocked)
+        m_documentLoader.contentFilterDidBlock();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ContentFilter::deliverResourceData(CachedResource&amp; resource)
</span><span class="cx"> {
</span><ins>+    ASSERT(m_state == State::Allowed);
</ins><span class="cx">     ASSERT(resource.dataBufferingPolicy() == BufferData);
</span><span class="cx">     if (auto* resourceBuffer = resource.resourceBuffer())
</span><span class="cx">         m_documentLoader.dataReceived(&amp;resource, resourceBuffer-&gt;data(), resourceBuffer-&gt;size());
</span></span></pre></div>
<a id="branchessafari601146branchSourceWebCoreloaderContentFilterh"></a>
<div class="modfile"><h4>Modified: branches/safari-601.1.46-branch/Source/WebCore/loader/ContentFilter.h (194994 => 194995)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601.1.46-branch/Source/WebCore/loader/ContentFilter.h        2016-01-13 23:10:53 UTC (rev 194994)
+++ branches/safari-601.1.46-branch/Source/WebCore/loader/ContentFilter.h        2016-01-13 23:11:02 UTC (rev 194995)
</span><span class="lines">@@ -28,7 +28,6 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(CONTENT_FILTERING)
</span><span class="cx"> 
</span><del>-#include &quot;CachedRawResourceClient.h&quot;
</del><span class="cx"> #include &quot;CachedResourceHandle.h&quot;
</span><span class="cx"> #include &lt;functional&gt;
</span><span class="cx"> #include &lt;wtf/Vector.h&gt;
</span><span class="lines">@@ -39,39 +38,43 @@
</span><span class="cx"> class ContentFilterUnblockHandler;
</span><span class="cx"> class DocumentLoader;
</span><span class="cx"> class PlatformContentFilter;
</span><ins>+class ResourceRequest;
+class ResourceResponse;
</ins><span class="cx"> class SharedBuffer;
</span><span class="cx"> 
</span><del>-class ContentFilter final : private CachedRawResourceClient {
</del><ins>+class ContentFilter {
</ins><span class="cx">     WTF_MAKE_FAST_ALLOCATED;
</span><span class="cx">     WTF_MAKE_NONCOPYABLE(ContentFilter);
</span><span class="cx"> 
</span><span class="cx"> public:
</span><span class="cx">     template &lt;typename T&gt; static void addType() { types().append(type&lt;T&gt;()); }
</span><span class="cx"> 
</span><del>-    static std::unique_ptr&lt;ContentFilter&gt; createIfEnabled(DocumentLoader&amp;);
-    ~ContentFilter() override;
</del><ins>+    static std::unique_ptr&lt;ContentFilter&gt; create(DocumentLoader&amp;);
+    ~ContentFilter();
</ins><span class="cx"> 
</span><span class="cx">     static const char* urlScheme() { return &quot;x-apple-content-filter&quot;; }
</span><span class="cx"> 
</span><del>-    void willSendRequest(ResourceRequest&amp;, const ResourceResponse&amp;);
</del><span class="cx">     void startFilteringMainResource(CachedRawResource&amp;);
</span><span class="cx">     void stopFilteringMainResource();
</span><span class="cx"> 
</span><ins>+    bool continueAfterWillSendRequest(ResourceRequest&amp;, const ResourceResponse&amp;);
+    bool continueAfterResponseReceived(CachedResource*, const ResourceResponse&amp;);
+    bool continueAfterDataReceived(CachedResource*, const char* data, int length);
+    bool continueAfterNotifyFinished(CachedResource*);
+
+    ContentFilterUnblockHandler unblockHandler() const;
+    Ref&lt;SharedBuffer&gt; replacementData() const;
+    String unblockRequestDeniedScript() const;
+
+private:
</ins><span class="cx">     enum class State {
</span><del>-        Initialized,
</del><ins>+        Stopped,
</ins><span class="cx">         Filtering,
</span><span class="cx">         Allowed,
</span><span class="cx">         Blocked,
</span><del>-        Stopped
</del><span class="cx">     };
</span><del>-    State state() const { return m_state; }
-    ContentFilterUnblockHandler unblockHandler() const;
-    Ref&lt;SharedBuffer&gt; replacementData() const;
-    String unblockRequestDeniedScript() const;
</del><span class="cx"> 
</span><del>-private:
</del><span class="cx">     struct Type {
</span><del>-        const std::function&lt;bool()&gt; enabled;
</del><span class="cx">         const std::function&lt;std::unique_ptr&lt;PlatformContentFilter&gt;()&gt; create;
</span><span class="cx">     };
</span><span class="cx">     template &lt;typename T&gt; static Type type();
</span><span class="lines">@@ -81,14 +84,6 @@
</span><span class="cx">     friend std::unique_ptr&lt;ContentFilter&gt; std::make_unique&lt;ContentFilter&gt;(Container&amp;&amp;, DocumentLoader&amp;);
</span><span class="cx">     ContentFilter(Container, DocumentLoader&amp;);
</span><span class="cx"> 
</span><del>-    // CachedRawResourceClient
-    void responseReceived(CachedResource*, const ResourceResponse&amp;) override;
-    void dataReceived(CachedResource*, const char* data, int length) override;
-    void redirectReceived(CachedResource*, ResourceRequest&amp;, const ResourceResponse&amp;) override;
-
-    // CachedResourceClient
-    void notifyFinished(CachedResource*) override;
-
</del><span class="cx">     void forEachContentFilterUntilBlocked(std::function&lt;void(PlatformContentFilter&amp;)&gt;);
</span><span class="cx">     void didDecide(State);
</span><span class="cx">     void deliverResourceData(CachedResource&amp;);
</span><span class="lines">@@ -97,14 +92,14 @@
</span><span class="cx">     DocumentLoader&amp; m_documentLoader;
</span><span class="cx">     CachedResourceHandle&lt;CachedRawResource&gt; m_mainResource;
</span><span class="cx">     PlatformContentFilter* m_blockingContentFilter { nullptr };
</span><del>-    State m_state { State::Initialized };
</del><ins>+    State m_state { State::Stopped };
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> template &lt;typename T&gt;
</span><span class="cx"> ContentFilter::Type ContentFilter::type()
</span><span class="cx"> {
</span><span class="cx">     static_assert(std::is_base_of&lt;PlatformContentFilter, T&gt;::value, &quot;Type must be a PlatformContentFilter.&quot;);
</span><del>-    return { T::enabled, T::create };
</del><ins>+    return { T::create };
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="branchessafari601146branchSourceWebCoreloaderDocumentLoadercpp"></a>
<div class="modfile"><h4>Modified: branches/safari-601.1.46-branch/Source/WebCore/loader/DocumentLoader.cpp (194994 => 194995)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601.1.46-branch/Source/WebCore/loader/DocumentLoader.cpp        2016-01-13 23:10:53 UTC (rev 194994)
+++ branches/safari-601.1.46-branch/Source/WebCore/loader/DocumentLoader.cpp        2016-01-13 23:11:02 UTC (rev 194995)
</span><span class="lines">@@ -141,7 +141,7 @@
</span><span class="cx">     , m_subresourceLoadersArePageCacheAcceptable(false)
</span><span class="cx">     , m_applicationCacheHost(std::make_unique&lt;ApplicationCacheHost&gt;(*this))
</span><span class="cx"> #if ENABLE(CONTENT_FILTERING)
</span><del>-    , m_contentFilter(!substituteData.isValid() ? ContentFilter::createIfEnabled(*this) : nullptr)
</del><ins>+    , m_contentFilter(!substituteData.isValid() ? ContentFilter::create(*this) : nullptr)
</ins><span class="cx"> #endif
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="lines">@@ -371,6 +371,11 @@
</span><span class="cx"> 
</span><span class="cx"> void DocumentLoader::notifyFinished(CachedResource* resource)
</span><span class="cx"> {
</span><ins>+#if ENABLE(CONTENT_FILTERING)
+    if (m_contentFilter &amp;&amp; !m_contentFilter-&gt;continueAfterNotifyFinished(resource))
+        return;
+#endif
+
</ins><span class="cx">     ASSERT_UNUSED(resource, m_mainResource == resource);
</span><span class="cx">     ASSERT(m_mainResource);
</span><span class="cx">     if (!m_mainResource-&gt;errorOccurred() &amp;&amp; !m_mainResource-&gt;wasCanceled()) {
</span><span class="lines">@@ -541,11 +546,8 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(CONTENT_FILTERING)
</span><del>-    if (m_contentFilter &amp;&amp; redirectResponse.isNull()) {
-        m_contentFilter-&gt;willSendRequest(newRequest, redirectResponse);
-        if (newRequest.isNull())
-            return;
-    }
</del><ins>+    if (m_contentFilter &amp;&amp; !m_contentFilter-&gt;continueAfterWillSendRequest(newRequest, redirectResponse))
+        return;
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     setRequest(newRequest);
</span><span class="lines">@@ -607,6 +609,11 @@
</span><span class="cx"> 
</span><span class="cx"> void DocumentLoader::responseReceived(CachedResource* resource, const ResourceResponse&amp; response)
</span><span class="cx"> {
</span><ins>+#if ENABLE(CONTENT_FILTERING)
+    if (m_contentFilter &amp;&amp; !m_contentFilter-&gt;continueAfterResponseReceived(resource, response))
+        return;
+#endif
+
</ins><span class="cx">     ASSERT_UNUSED(resource, m_mainResource == resource);
</span><span class="cx">     Ref&lt;DocumentLoader&gt; protect(*this);
</span><span class="cx">     bool willLoadFallback = m_applicationCacheHost-&gt;maybeLoadFallbackForMainResponse(request(), response);
</span><span class="lines">@@ -868,6 +875,11 @@
</span><span class="cx"> 
</span><span class="cx"> void DocumentLoader::dataReceived(CachedResource* resource, const char* data, int length)
</span><span class="cx"> {
</span><ins>+#if ENABLE(CONTENT_FILTERING)
+    if (m_contentFilter &amp;&amp; !m_contentFilter-&gt;continueAfterDataReceived(resource, data, length))
+        return;
+#endif
+
</ins><span class="cx">     ASSERT(data);
</span><span class="cx">     ASSERT(length);
</span><span class="cx">     ASSERT_UNUSED(resource, resource == m_mainResource);
</span><span class="lines">@@ -1604,11 +1616,8 @@
</span><span class="cx"> void DocumentLoader::becomeMainResourceClient()
</span><span class="cx"> {
</span><span class="cx"> #if ENABLE(CONTENT_FILTERING)
</span><del>-    if (m_contentFilter &amp;&amp; m_contentFilter-&gt;state() == ContentFilter::State::Initialized) {
-        // ContentFilter will synthesize CachedRawResourceClient callbacks.
</del><ins>+    if (m_contentFilter)
</ins><span class="cx">         m_contentFilter-&gt;startFilteringMainResource(*m_mainResource);
</span><del>-        return;
-    }
</del><span class="cx"> #endif
</span><span class="cx">     m_mainResource-&gt;addClient(this);
</span><span class="cx"> }
</span><span class="lines">@@ -1646,13 +1655,9 @@
</span><span class="cx">     frameLoader()-&gt;client().contentFilterDidBlockLoad(WTF::move(unblockHandler));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void DocumentLoader::contentFilterDidDecide()
</del><ins>+void DocumentLoader::contentFilterDidBlock()
</ins><span class="cx"> {
</span><del>-    using State = ContentFilter::State;
</del><span class="cx">     ASSERT(m_contentFilter);
</span><del>-    ASSERT(m_contentFilter-&gt;state() == State::Blocked || m_contentFilter-&gt;state() == State::Allowed);
-    if (m_contentFilter-&gt;state() == State::Allowed)
-        return;
</del><span class="cx"> 
</span><span class="cx">     installContentFilterUnblockHandler(*m_contentFilter);
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchessafari601146branchSourceWebCoreloaderDocumentLoaderh"></a>
<div class="modfile"><h4>Modified: branches/safari-601.1.46-branch/Source/WebCore/loader/DocumentLoader.h (194994 => 194995)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601.1.46-branch/Source/WebCore/loader/DocumentLoader.h        2016-01-13 23:10:53 UTC (rev 194994)
+++ branches/safari-601.1.46-branch/Source/WebCore/loader/DocumentLoader.h        2016-01-13 23:11:02 UTC (rev 194995)
</span><span class="lines">@@ -344,7 +344,7 @@
</span><span class="cx"> #if ENABLE(CONTENT_FILTERING)
</span><span class="cx">         friend class ContentFilter;
</span><span class="cx">         void installContentFilterUnblockHandler(ContentFilter&amp;);
</span><del>-        void contentFilterDidDecide();
</del><ins>+        void contentFilterDidBlock();
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">         Frame* m_frame;
</span></span></pre></div>
<a id="branchessafari601146branchSourceWebCoreplatformcocoaNetworkExtensionContentFilterh"></a>
<div class="modfile"><h4>Modified: branches/safari-601.1.46-branch/Source/WebCore/platform/cocoa/NetworkExtensionContentFilter.h (194994 => 194995)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601.1.46-branch/Source/WebCore/platform/cocoa/NetworkExtensionContentFilter.h        2016-01-13 23:10:53 UTC (rev 194994)
+++ branches/safari-601.1.46-branch/Source/WebCore/platform/cocoa/NetworkExtensionContentFilter.h        2016-01-13 23:11:02 UTC (rev 194995)
</span><span class="lines">@@ -32,8 +32,6 @@
</span><span class="cx"> #include &lt;wtf/OSObjectPtr.h&gt;
</span><span class="cx"> #include &lt;wtf/RetainPtr.h&gt;
</span><span class="cx"> 
</span><del>-#define HAVE_NETWORK_EXTENSION PLATFORM(IOS) || (PLATFORM(MAC) &amp;&amp; __MAC_OS_X_VERSION_MIN_REQUIRED &gt;= 101000 &amp;&amp; CPU(X86_64))
-
</del><span class="cx"> enum NEFilterSourceStatus : NSInteger;
</span><span class="cx"> 
</span><span class="cx"> OBJC_CLASS NEFilterSource;
</span><span class="lines">@@ -41,11 +39,12 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><ins>+class URL;
+
</ins><span class="cx"> class NetworkExtensionContentFilter final : public PlatformContentFilter {
</span><span class="cx">     friend std::unique_ptr&lt;NetworkExtensionContentFilter&gt; std::make_unique&lt;NetworkExtensionContentFilter&gt;();
</span><span class="cx"> 
</span><span class="cx"> public:
</span><del>-    static bool enabled();
</del><span class="cx">     static std::unique_ptr&lt;NetworkExtensionContentFilter&gt; create();
</span><span class="cx"> 
</span><span class="cx">     void willSendRequest(ResourceRequest&amp;, const ResourceResponse&amp;) override;
</span><span class="lines">@@ -58,7 +57,10 @@
</span><span class="cx">     ContentFilterUnblockHandler unblockHandler() const override;
</span><span class="cx"> 
</span><span class="cx"> private:
</span><ins>+    static bool enabled();
+
</ins><span class="cx">     NetworkExtensionContentFilter();
</span><ins>+    void initialize(const URL* = nullptr);
</ins><span class="cx">     void handleDecision(NEFilterSourceStatus, NSData *replacementData);
</span><span class="cx"> 
</span><span class="cx">     NEFilterSourceStatus m_status;
</span></span></pre></div>
<a id="branchessafari601146branchSourceWebCoreplatformcocoaNetworkExtensionContentFiltermm"></a>
<div class="modfile"><h4>Modified: branches/safari-601.1.46-branch/Source/WebCore/platform/cocoa/NetworkExtensionContentFilter.mm (194994 => 194995)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601.1.46-branch/Source/WebCore/platform/cocoa/NetworkExtensionContentFilter.mm        2016-01-13 23:10:53 UTC (rev 194994)
+++ branches/safari-601.1.46-branch/Source/WebCore/platform/cocoa/NetworkExtensionContentFilter.mm        2016-01-13 23:11:02 UTC (rev 194995)
</span><span class="lines">@@ -65,24 +65,36 @@
</span><span class="cx"> 
</span><span class="cx"> NetworkExtensionContentFilter::NetworkExtensionContentFilter()
</span><span class="cx">     : m_status { NEFilterSourceStatusNeedsMoreData }
</span><del>-    , m_queue { adoptOSObject(dispatch_queue_create(&quot;com.apple.WebCore.NEFilterSourceQueue&quot;, DISPATCH_QUEUE_SERIAL)) }
-    , m_semaphore { adoptOSObject(dispatch_semaphore_create(0)) }
</del><ins>+{
+}
+
+void NetworkExtensionContentFilter::initialize(const URL* url)
+{
+    ASSERT(!m_queue);
+    ASSERT(!m_semaphore);
+    ASSERT(!m_neFilterSource);
+    m_queue = adoptOSObject(dispatch_queue_create(&quot;com.apple.WebCore.NEFilterSourceQueue&quot;, DISPATCH_QUEUE_SERIAL));
+    m_semaphore = adoptOSObject(dispatch_semaphore_create(0));
</ins><span class="cx"> #if HAVE(MODERN_NE_FILTER_SOURCE)
</span><del>-    , m_neFilterSource { adoptNS([allocNEFilterSourceInstance() initWithDecisionQueue:m_queue.get()]) }
</del><ins>+    ASSERT_UNUSED(url, !url);
+    m_neFilterSource = adoptNS([allocNEFilterSourceInstance() initWithDecisionQueue:m_queue.get()]);
+#else
+    ASSERT_ARG(url, url);
+    m_neFilterSource = adoptNS([allocNEFilterSourceInstance() initWithURL:*url direction:NEFilterSourceDirectionInbound socketIdentifier:0]);
</ins><span class="cx"> #endif
</span><del>-{
-    ASSERT([getNEFilterSourceClass() filterRequired]);
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void NetworkExtensionContentFilter::willSendRequest(ResourceRequest&amp; request, const ResourceResponse&amp; redirectResponse)
</span><span class="cx"> {
</span><span class="cx"> #if HAVE(MODERN_NE_FILTER_SOURCE)
</span><span class="cx">     ASSERT(!request.isNull());
</span><del>-    if (!request.url().protocolIsInHTTPFamily()) {
</del><ins>+    if (!request.url().protocolIsInHTTPFamily() || !enabled()) {
</ins><span class="cx">         m_status = NEFilterSourceStatusPass;
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    initialize();
+
</ins><span class="cx">     if (!redirectResponse.isNull()) {
</span><span class="cx">         responseReceived(redirectResponse);
</span><span class="cx">         if (!needsMoreData())
</span><span class="lines">@@ -125,8 +137,12 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx"> #if !HAVE(MODERN_NE_FILTER_SOURCE)
</span><del>-    ASSERT(!m_neFilterSource);
-    m_neFilterSource = adoptNS([allocNEFilterSourceInstance() initWithURL:response.url() direction:NEFilterSourceDirectionInbound socketIdentifier:0]);
</del><ins>+    if (!enabled()) {
+        m_status = NEFilterSourceStatusPass;
+        return;
+    }
+
+    initialize(&amp;response.url());
</ins><span class="cx"> #else
</span><span class="cx">     [m_neFilterSource receivedResponse:response.nsURLResponse() decisionHandler:[this](NEFilterSourceStatus status, NSDictionary *decisionInfo) {
</span><span class="cx">         handleDecision(status, replacementDataFromDecisionInfo(decisionInfo));
</span></span></pre></div>
<a id="branchessafari601146branchSourceWebCoreplatformcocoaParentalControlsContentFilterh"></a>
<div class="modfile"><h4>Modified: branches/safari-601.1.46-branch/Source/WebCore/platform/cocoa/ParentalControlsContentFilter.h (194994 => 194995)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601.1.46-branch/Source/WebCore/platform/cocoa/ParentalControlsContentFilter.h        2016-01-13 23:10:53 UTC (rev 194994)
+++ branches/safari-601.1.46-branch/Source/WebCore/platform/cocoa/ParentalControlsContentFilter.h        2016-01-13 23:11:02 UTC (rev 194995)
</span><span class="lines">@@ -39,7 +39,6 @@
</span><span class="cx">     friend std::unique_ptr&lt;ParentalControlsContentFilter&gt; std::make_unique&lt;ParentalControlsContentFilter&gt;();
</span><span class="cx"> 
</span><span class="cx"> public:
</span><del>-    static bool enabled();
</del><span class="cx">     static std::unique_ptr&lt;ParentalControlsContentFilter&gt; create();
</span><span class="cx"> 
</span><span class="cx">     void willSendRequest(ResourceRequest&amp;, const ResourceResponse&amp;) override { }
</span><span class="lines">@@ -52,6 +51,8 @@
</span><span class="cx">     ContentFilterUnblockHandler unblockHandler() const override;
</span><span class="cx"> 
</span><span class="cx"> private:
</span><ins>+    static bool enabled();
+
</ins><span class="cx">     ParentalControlsContentFilter();
</span><span class="cx">     void updateFilterState();
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchessafari601146branchSourceWebCoreplatformcocoaParentalControlsContentFiltermm"></a>
<div class="modfile"><h4>Modified: branches/safari-601.1.46-branch/Source/WebCore/platform/cocoa/ParentalControlsContentFilter.mm (194994 => 194995)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601.1.46-branch/Source/WebCore/platform/cocoa/ParentalControlsContentFilter.mm        2016-01-13 23:10:53 UTC (rev 194994)
+++ branches/safari-601.1.46-branch/Source/WebCore/platform/cocoa/ParentalControlsContentFilter.mm        2016-01-13 23:11:02 UTC (rev 194995)
</span><span class="lines">@@ -56,7 +56,6 @@
</span><span class="cx"> ParentalControlsContentFilter::ParentalControlsContentFilter()
</span><span class="cx">     : m_filterState { kWFEStateBuffering }
</span><span class="cx"> {
</span><del>-    ASSERT([getWebFilterEvaluatorClass() isManagedSession]);
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static inline bool canHandleResponse(const ResourceResponse&amp; response)
</span><span class="lines">@@ -72,7 +71,7 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(!m_webFilterEvaluator);
</span><span class="cx"> 
</span><del>-    if (!canHandleResponse(response)) {
</del><ins>+    if (!canHandleResponse(response) || !enabled()) {
</ins><span class="cx">         m_filterState = kWFEStateAllowed;
</span><span class="cx">         return;
</span><span class="cx">     }
</span></span></pre></div>
<a id="branchessafari601146branchSourceWebCoretestingMockContentFiltercpp"></a>
<div class="modfile"><h4>Modified: branches/safari-601.1.46-branch/Source/WebCore/testing/MockContentFilter.cpp (194994 => 194995)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601.1.46-branch/Source/WebCore/testing/MockContentFilter.cpp        2016-01-13 23:10:53 UTC (rev 194994)
+++ branches/safari-601.1.46-branch/Source/WebCore/testing/MockContentFilter.cpp        2016-01-13 23:11:02 UTC (rev 194995)
</span><span class="lines">@@ -70,6 +70,11 @@
</span><span class="cx"> 
</span><span class="cx"> void MockContentFilter::willSendRequest(ResourceRequest&amp; request, const ResourceResponse&amp; redirectResponse)
</span><span class="cx"> {
</span><ins>+    if (!enabled()) {
+        m_status = Status::Allowed;
+        return;
+    }
+
</ins><span class="cx">     if (redirectResponse.isNull())
</span><span class="cx">         maybeDetermineStatus(DecisionPoint::AfterWillSendRequest);
</span><span class="cx">     else
</span></span></pre></div>
<a id="branchessafari601146branchSourceWebCoretestingMockContentFilterh"></a>
<div class="modfile"><h4>Modified: branches/safari-601.1.46-branch/Source/WebCore/testing/MockContentFilter.h (194994 => 194995)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601.1.46-branch/Source/WebCore/testing/MockContentFilter.h        2016-01-13 23:10:53 UTC (rev 194994)
+++ branches/safari-601.1.46-branch/Source/WebCore/testing/MockContentFilter.h        2016-01-13 23:11:02 UTC (rev 194995)
</span><span class="lines">@@ -36,7 +36,6 @@
</span><span class="cx"> 
</span><span class="cx"> public:
</span><span class="cx">     static void ensureInstalled();
</span><del>-    static bool enabled();
</del><span class="cx">     static std::unique_ptr&lt;MockContentFilter&gt; create();
</span><span class="cx"> 
</span><span class="cx">     void willSendRequest(ResourceRequest&amp;, const ResourceResponse&amp;) override;
</span><span class="lines">@@ -56,6 +55,8 @@
</span><span class="cx">         Blocked
</span><span class="cx">     };
</span><span class="cx"> 
</span><ins>+    static bool enabled();
+
</ins><span class="cx">     MockContentFilter() = default;
</span><span class="cx">     void maybeDetermineStatus(MockContentFilterSettings::DecisionPoint);
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchessafari601146branchToolsChangeLog"></a>
<div class="modfile"><h4>Modified: branches/safari-601.1.46-branch/Tools/ChangeLog (194994 => 194995)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601.1.46-branch/Tools/ChangeLog        2016-01-13 23:10:53 UTC (rev 194994)
+++ branches/safari-601.1.46-branch/Tools/ChangeLog        2016-01-13 23:11:02 UTC (rev 194995)
</span><span class="lines">@@ -1,3 +1,51 @@
</span><ins>+2016-01-13  Matthew Hanson  &lt;matthew_hanson@apple.com&gt;
+
+        Merge r194950. rdar://problem/23270886
+
+    2016-01-08  Andy Estes  &lt;aestes@apple.com&gt;
+
+            [Content Filtering] Lazily load platform frameworks
+            https://bugs.webkit.org/show_bug.cgi?id=152881
+            rdar://problem/23270886
+
+            Reviewed by Brady Eidson.
+
+            Added an API test that verifies that the Parental Controls and Network Extension frameworks are loaded at the
+            expected times. The test verifies that they are not loaded after creating a WKWebView, loading an HTML string,
+            loading NSData, loading a file, or loading from a custom protocol. It verifies that Network Extension on Mac/iOS
+            and Parental Controls on iOS are loaded after an HTTP request. It finally verifies that Parental Controls on Mac
+            is loaded after an HTTPS request.
+
+            To accomplish this, TestProtocol was generalized to allow tests to specify the scheme they wish to use.
+            Other tests that used TestProtocol were updated to account for this change. TestProtocol was removed from
+            WebKit2.PreventImageLoadWithAutoResizingTest, which didn't actually need to use it. ContentFiltering tests were
+            also re-enabled on iOS after mistakenly being disabled by r188892.
+
+            * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+            * TestWebKitAPI/Tests/CustomProtocolsSyncXHRTest.mm:
+            (TestWebKitAPI::TEST):
+            * TestWebKitAPI/Tests/WebKit2Cocoa/ContentFiltering.h: Added.
+            * TestWebKitAPI/Tests/WebKit2Cocoa/ContentFiltering.html: Added.
+            * TestWebKitAPI/Tests/WebKit2Cocoa/ContentFiltering.mm:
+            (TEST):
+            (downloadTest):
+            (-[LazilyLoadPlatformFrameworksController init]):
+            (-[LazilyLoadPlatformFrameworksController webView]):
+            (-[LazilyLoadPlatformFrameworksController expectParentalControlsLoaded:networkExtensionLoaded:]):
+            (-[LazilyLoadPlatformFrameworksController webView:didFinishNavigation:]):
+            * TestWebKitAPI/Tests/WebKit2Cocoa/ContentFilteringPlugIn.mm:
+            (-[ContentFilteringPlugIn webProcessPlugIn:didCreateBrowserContextController:]):
+            (-[ContentFilteringPlugIn observeValueForKeyPath:ofObject:change:context:]):
+            (-[ContentFilteringPlugIn checkIfPlatformFrameworksAreLoaded:]):
+            * TestWebKitAPI/Tests/WebKit2ObjC/CustomProtocolsTest.mm:
+            (TestWebKitAPI::TEST):
+            * TestWebKitAPI/Tests/WebKit2ObjC/PreventImageLoadWithAutoResizing.mm:
+            (TestWebKitAPI::TEST): Deleted.
+            * TestWebKitAPI/cocoa/TestProtocol.h:
+            * TestWebKitAPI/cocoa/TestProtocol.mm:
+            (+[TestProtocol registerWithScheme:]):
+            (+[TestProtocol unregister]):
+
</ins><span class="cx"> 2015-12-06  Matthew Hanson  &lt;matthew_hanson@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Merge r191032. rdar://problem/23769702
</span></span></pre></div>
<a id="branchessafari601146branchToolsTestWebKitAPITestWebKitAPIxcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: branches/safari-601.1.46-branch/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (194994 => 194995)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601.1.46-branch/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj        2016-01-13 23:10:53 UTC (rev 194994)
+++ branches/safari-601.1.46-branch/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj        2016-01-13 23:11:02 UTC (rev 194995)
</span><span class="lines">@@ -269,6 +269,7 @@
</span><span class="cx">                 A14FC5881B8991BF00D107EB /* ContentFiltering.mm in Sources */ = {isa = PBXBuildFile; fileRef = A14FC5861B8991B600D107EB /* ContentFiltering.mm */; };
</span><span class="cx">                 A14FC58B1B89927100D107EB /* ContentFilteringPlugIn.mm in Sources */ = {isa = PBXBuildFile; fileRef = A14FC5891B89927100D107EB /* ContentFilteringPlugIn.mm */; };
</span><span class="cx">                 A14FC5901B8AE36F00D107EB /* TestProtocol.mm in Sources */ = {isa = PBXBuildFile; fileRef = A14FC58E1B8AE36500D107EB /* TestProtocol.mm */; };
</span><ins>+                A16F66BA1C40EB4F00BD4D24 /* ContentFiltering.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = A16F66B91C40EA2000BD4D24 /* ContentFiltering.html */; };
</ins><span class="cx">                 A57A34F216AF6B2B00C2501F /* PageVisibilityStateWithWindowChanges.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = A57A34F116AF69E200C2501F /* PageVisibilityStateWithWindowChanges.html */; };
</span><span class="cx">                 A5E2027515B21F6E00C13E14 /* WindowlessWebViewWithMedia.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = A5E2027015B2180600C13E14 /* WindowlessWebViewWithMedia.html */; };
</span><span class="cx">                 B55AD1D5179F3B3000AC1494 /* PreventImageLoadWithAutoResizing_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B55AD1D3179F3ABF00AC1494 /* PreventImageLoadWithAutoResizing_Bundle.cpp */; };
</span><span class="lines">@@ -361,6 +362,7 @@
</span><span class="cx">                         dstPath = TestWebKitAPI.resources;
</span><span class="cx">                         dstSubfolderSpec = 7;
</span><span class="cx">                         files = (
</span><ins>+                                A16F66BA1C40EB4F00BD4D24 /* ContentFiltering.html in Copy Resources */,
</ins><span class="cx">                                 A1C4FB731BACD1CA003742D0 /* pages.pages in Copy Resources */,
</span><span class="cx">                                 51CD1C721B38D48400142CA5 /* modal-alerts-in-new-about-blank-window.html in Copy Resources */,
</span><span class="cx">                                 7AE9E5091AE5AE8B00CF874B /* test.pdf in Copy Resources */,
</span><span class="lines">@@ -638,6 +640,8 @@
</span><span class="cx">                 A14FC5891B89927100D107EB /* ContentFilteringPlugIn.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ContentFilteringPlugIn.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 A14FC58D1B8AE36500D107EB /* TestProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TestProtocol.h; path = cocoa/TestProtocol.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 A14FC58E1B8AE36500D107EB /* TestProtocol.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = TestProtocol.mm; path = cocoa/TestProtocol.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                A16F66B91C40EA2000BD4D24 /* ContentFiltering.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = ContentFiltering.html; sourceTree = &quot;&lt;group&gt;&quot;; };
+                A18AA8CC1C3FA218009B2B97 /* ContentFiltering.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContentFiltering.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 A1A4FE5D18DD3DB700B5EA8A /* Download.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = Download.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 A1C4FB6C1BACCE50003742D0 /* QuickLook.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = QuickLook.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 A1C4FB721BACD1B7003742D0 /* pages.pages */ = {isa = PBXFileReference; lastKnownFileType = file; name = pages.pages; path = ios/pages.pages; sourceTree = SOURCE_ROOT; };
</span><span class="lines">@@ -889,9 +893,11 @@
</span><span class="cx">                 1ABC3DEC1899BE55004F0626 /* WebKit2 Cocoa */ = {
</span><span class="cx">                         isa = PBXGroup;
</span><span class="cx">                         children = (
</span><ins>+                                A16F66B81C40E9E100BD4D24 /* Resources */,
</ins><span class="cx">                                 7CEFA9641AC0B9E200B910FD /* _WKUserContentExtensionStore.mm */,
</span><span class="cx">                                 A13EBBAC1B87436F00097110 /* BundleParameters.mm */,
</span><span class="cx">                                 A13EBBAE1B87436F00097110 /* BundleParametersPlugIn.mm */,
</span><ins>+                                A18AA8CC1C3FA218009B2B97 /* ContentFiltering.h */,
</ins><span class="cx">                                 A14FC5861B8991B600D107EB /* ContentFiltering.mm */,
</span><span class="cx">                                 A14FC5891B89927100D107EB /* ContentFilteringPlugIn.mm */,
</span><span class="cx">                                 A1A4FE5D18DD3DB700B5EA8A /* Download.mm */,
</span><span class="lines">@@ -982,6 +988,14 @@
</span><span class="cx">                         path = cocoa/WebProcessPlugIn;
</span><span class="cx">                         sourceTree = &quot;&lt;group&gt;&quot;;
</span><span class="cx">                 };
</span><ins>+                A16F66B81C40E9E100BD4D24 /* Resources */ = {
+                        isa = PBXGroup;
+                        children = (
+                                A16F66B91C40EA2000BD4D24 /* ContentFiltering.html */,
+                        );
+                        name = Resources;
+                        sourceTree = &quot;&lt;group&gt;&quot;;
+                };
</ins><span class="cx">                 BC029B1A1486B23800817DA9 /* ns */ = {
</span><span class="cx">                         isa = PBXGroup;
</span><span class="cx">                         children = (
</span></span></pre></div>
<a id="branchessafari601146branchToolsTestWebKitAPITestsCustomProtocolsSyncXHRTestmm"></a>
<div class="modfile"><h4>Modified: branches/safari-601.1.46-branch/Tools/TestWebKitAPI/Tests/CustomProtocolsSyncXHRTest.mm (194994 => 194995)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601.1.46-branch/Tools/TestWebKitAPI/Tests/CustomProtocolsSyncXHRTest.mm        2016-01-13 23:10:53 UTC (rev 194994)
+++ branches/safari-601.1.46-branch/Tools/TestWebKitAPI/Tests/CustomProtocolsSyncXHRTest.mm        2016-01-13 23:11:02 UTC (rev 194995)
</span><span class="lines">@@ -48,8 +48,7 @@
</span><span class="cx"> 
</span><span class="cx"> TEST(WebKit2CustomProtocolsTest, SyncXHR)
</span><span class="cx"> {
</span><del>-    [NSURLProtocol registerClass:[TestProtocol class]];
-    [WKBrowsingContextController registerSchemeForCustomProtocol:[TestProtocol scheme]];
</del><ins>+    [TestProtocol registerWithScheme:@&quot;http&quot;];
</ins><span class="cx"> 
</span><span class="cx">     RetainPtr&lt;WKProcessGroup&gt; processGroup = adoptNS([[WKProcessGroup alloc] init]);
</span><span class="cx">     RetainPtr&lt;WKBrowsingContextGroup&gt; browsingContextGroup = adoptNS([[WKBrowsingContextGroup alloc] initWithIdentifier:@&quot;TestIdentifier&quot;]);
</span><span class="lines">@@ -69,8 +68,7 @@
</span><span class="cx">     WKPageLoadURL(wkView.get().pageRef, Util::createURLForResource(&quot;custom-protocol-sync-xhr&quot;, &quot;html&quot;));
</span><span class="cx"> 
</span><span class="cx">     TestWebKitAPI::Util::run(&amp;testFinished);
</span><del>-    [NSURLProtocol unregisterClass:[TestProtocol class]];
-    [WKBrowsingContextController unregisterSchemeForCustomProtocol:[TestProtocol scheme]];
</del><ins>+    [TestProtocol unregister];
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // namespace TestWebKitAPI
</span></span></pre></div>
<a id="branchessafari601146branchToolsTestWebKitAPITestsWebKit2CocoaContentFilteringhfromrev194994branchessafari601146branchToolsTestWebKitAPIcocoaTestProtocolh"></a>
<div class="copfile"><h4>Copied: branches/safari-601.1.46-branch/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/ContentFiltering.h (from rev 194994, branches/safari-601.1.46-branch/Tools/TestWebKitAPI/cocoa/TestProtocol.h) (0 => 194995)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601.1.46-branch/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/ContentFiltering.h                                (rev 0)
+++ branches/safari-601.1.46-branch/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/ContentFiltering.h        2016-01-13 23:11:02 UTC (rev 194995)
</span><span class="lines">@@ -0,0 +1,28 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+@protocol ContentFilteringProtocol &lt;NSObject&gt;
+- (void)checkIfPlatformFrameworksAreLoaded:(void (^)(BOOL parentalControlsLoaded, BOOL networkExtensionLoaded))completionHandler;
+@end
</ins></span></pre></div>
<a id="branchessafari601146branchToolsTestWebKitAPITestsWebKit2CocoaContentFilteringhtml"></a>
<div class="addfile"><h4>Added: branches/safari-601.1.46-branch/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/ContentFiltering.html (0 => 194995)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601.1.46-branch/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/ContentFiltering.html                                (rev 0)
+++ branches/safari-601.1.46-branch/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/ContentFiltering.html        2016-01-13 23:11:02 UTC (rev 194995)
</span><span class="lines">@@ -0,0 +1,6 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;body&gt;
+PASS
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="branchessafari601146branchToolsTestWebKitAPITestsWebKit2CocoaContentFilteringmm"></a>
<div class="modfile"><h4>Modified: branches/safari-601.1.46-branch/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/ContentFiltering.mm (194994 => 194995)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601.1.46-branch/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/ContentFiltering.mm        2016-01-13 23:10:53 UTC (rev 194994)
+++ branches/safari-601.1.46-branch/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/ContentFiltering.mm        2016-01-13 23:11:02 UTC (rev 194995)
</span><span class="lines">@@ -27,15 +27,17 @@
</span><span class="cx"> 
</span><span class="cx"> #if WK_API_ENABLED
</span><span class="cx"> 
</span><ins>+#import &quot;ContentFiltering.h&quot;
</ins><span class="cx"> #import &quot;MockContentFilterSettings.h&quot;
</span><span class="cx"> #import &quot;PlatformUtilities.h&quot;
</span><span class="cx"> #import &quot;TestProtocol.h&quot;
</span><span class="cx"> #import &quot;WKWebViewConfigurationExtras.h&quot;
</span><del>-#import &lt;WebKit/WKBrowsingContextController.h&gt;
</del><span class="cx"> #import &lt;WebKit/WKNavigationDelegatePrivate.h&gt;
</span><span class="cx"> #import &lt;WebKit/WKProcessPoolPrivate.h&gt;
</span><span class="cx"> #import &lt;WebKit/WKWebView.h&gt;
</span><span class="cx"> #import &lt;WebKit/_WKDownloadDelegate.h&gt;
</span><ins>+#import &lt;WebKit/_WKRemoteObjectInterface.h&gt;
+#import &lt;WebKit/_WKRemoteObjectRegistry.h&gt;
</ins><span class="cx"> #import &lt;wtf/RetainPtr.h&gt;
</span><span class="cx"> 
</span><span class="cx"> using Decision = WebCore::MockContentFilterSettings::Decision;
</span><span class="lines">@@ -118,8 +120,7 @@
</span><span class="cx"> TEST(ContentFiltering, URLAfterServerRedirect)
</span><span class="cx"> {
</span><span class="cx">     @autoreleasepool {
</span><del>-        [NSURLProtocol registerClass:[TestProtocol class]];
-        [WKBrowsingContextController registerSchemeForCustomProtocol:[TestProtocol scheme]];
</del><ins>+        [TestProtocol registerWithScheme:@&quot;http&quot;];
</ins><span class="cx"> 
</span><span class="cx">         auto configuration = configurationWithContentFilterSettings(Decision::Allow, DecisionPoint::AfterAddData);
</span><span class="cx">         auto webView = adoptNS([[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration.get()]);
</span><span class="lines">@@ -128,8 +129,7 @@
</span><span class="cx">         [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@&quot;http://redirect?pass&quot;]]];
</span><span class="cx">         TestWebKitAPI::Util::run(&amp;isDone);
</span><span class="cx"> 
</span><del>-        [WKBrowsingContextController unregisterSchemeForCustomProtocol:[TestProtocol scheme]];
-        [NSURLProtocol unregisterClass:[TestProtocol class]];
</del><ins>+        [TestProtocol unregister];
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -172,8 +172,7 @@
</span><span class="cx"> static void downloadTest(Decision decision, DecisionPoint decisionPoint)
</span><span class="cx"> {
</span><span class="cx">     @autoreleasepool {
</span><del>-        [NSURLProtocol registerClass:[TestProtocol class]];
-        [WKBrowsingContextController registerSchemeForCustomProtocol:[TestProtocol scheme]];
</del><ins>+        [TestProtocol registerWithScheme:@&quot;http&quot;];
</ins><span class="cx"> 
</span><span class="cx">         auto configuration = configurationWithContentFilterSettings(decision, decisionPoint);
</span><span class="cx">         auto downloadDelegate = adoptNS([[ContentFilteringDownloadDelegate alloc] init]);
</span><span class="lines">@@ -193,8 +192,7 @@
</span><span class="cx"> 
</span><span class="cx">         EXPECT_EQ(downloadShouldStart, downloadDidStart);
</span><span class="cx"> 
</span><del>-        [WKBrowsingContextController unregisterSchemeForCustomProtocol:[TestProtocol scheme]];
-        [NSURLProtocol unregisterClass:[TestProtocol class]];
</del><ins>+        [TestProtocol unregister];
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -258,4 +256,107 @@
</span><span class="cx">     downloadTest(Decision::Block, DecisionPoint::Never);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+@interface LazilyLoadPlatformFrameworksController : NSObject &lt;WKNavigationDelegate&gt;
+@property (nonatomic, readonly) WKWebView *webView;
+- (void)expectParentalControlsLoaded:(BOOL)parentalControlsShouldBeLoaded networkExtensionLoaded:(BOOL)networkExtensionShouldBeLoaded;
+@end
+
+@implementation LazilyLoadPlatformFrameworksController {
+    RetainPtr&lt;WKWebView&gt; _webView;
+    RetainPtr&lt;id &lt;ContentFilteringProtocol&gt;&gt; _remoteObjectProxy;
+}
+
+- (instancetype)init
+{
+    if (!(self = [super init]))
+        return nil;
+
+    WKWebViewConfiguration *configuration = [WKWebViewConfiguration testwebkitapi_configurationWithTestPlugInClassName:@&quot;ContentFilteringPlugIn&quot;];
+    _webView = adoptNS([[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration]);
+    [_webView setNavigationDelegate:self];
+
+    _WKRemoteObjectInterface *interface = [_WKRemoteObjectInterface remoteObjectInterfaceWithProtocol:@protocol(ContentFilteringProtocol)];
+    _remoteObjectProxy = [[_webView _remoteObjectRegistry] remoteObjectProxyWithInterface:interface];
+
+    return self;
+}
+
+- (WKWebView *)webView
+{
+    return _webView.get();
+}
+
+- (void)expectParentalControlsLoaded:(BOOL)parentalControlsShouldBeLoaded networkExtensionLoaded:(BOOL)networkExtensionShouldBeLoaded
+{
+    isDone = false;
+    [_remoteObjectProxy checkIfPlatformFrameworksAreLoaded:^(BOOL parentalControlsLoaded, BOOL networkExtensionLoaded) {
+#if HAVE(PARENTAL_CONTROLS)
+        EXPECT_EQ(static_cast&lt;bool&gt;(parentalControlsShouldBeLoaded), static_cast&lt;bool&gt;(parentalControlsLoaded));
+#endif
+#if HAVE(NETWORK_EXTENSION)
+        EXPECT_EQ(static_cast&lt;bool&gt;(networkExtensionShouldBeLoaded), static_cast&lt;bool&gt;(networkExtensionLoaded));
+#endif
+        isDone = true;
+    }];
+    TestWebKitAPI::Util::run(&amp;isDone);
+}
+
+- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
+{
+    isDone = true;
+}
+
+@end
+
+TEST(ContentFiltering, LazilyLoadPlatformFrameworks)
+{
+    @autoreleasepool {
+        auto controller = adoptNS([[LazilyLoadPlatformFrameworksController alloc] init]);
+        [controller expectParentalControlsLoaded:NO networkExtensionLoaded:NO];
+
+        isDone = false;
+        [[controller webView] loadHTMLString:@&quot;PASS&quot; baseURL:[NSURL URLWithString:@&quot;about:blank&quot;]];
+        TestWebKitAPI::Util::run(&amp;isDone);
+        [controller expectParentalControlsLoaded:NO networkExtensionLoaded:NO];
+
+        isDone = false;
+        [[controller webView] loadData:[NSData dataWithBytes:&quot;PASS&quot; length:4] MIMEType:@&quot;text/html&quot; characterEncodingName:@&quot;UTF-8&quot; baseURL:[NSURL URLWithString:@&quot;about:blank&quot;]];
+        TestWebKitAPI::Util::run(&amp;isDone);
+        [controller expectParentalControlsLoaded:NO networkExtensionLoaded:NO];
+
+        isDone = false;
+        NSURL *fileURL = [[NSBundle mainBundle] URLForResource:@&quot;ContentFiltering&quot; withExtension:@&quot;html&quot; subdirectory:@&quot;TestWebKitAPI.resources&quot;];
+        [[controller webView] loadFileURL:fileURL allowingReadAccessToURL:fileURL];
+        TestWebKitAPI::Util::run(&amp;isDone);
+        [controller expectParentalControlsLoaded:NO networkExtensionLoaded:NO];
+
+        isDone = false;
+        [TestProtocol registerWithScheme:@&quot;custom&quot;];
+        [[controller webView] loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@&quot;custom://test&quot;]]];
+        TestWebKitAPI::Util::run(&amp;isDone);
+        [controller expectParentalControlsLoaded:NO networkExtensionLoaded:NO];
+        [TestProtocol unregister];
+
+        isDone = false;
+        [TestProtocol registerWithScheme:@&quot;http&quot;];
+        [[controller webView] loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@&quot;http://test&quot;]]];
+        TestWebKitAPI::Util::run(&amp;isDone);
+#if PLATFORM(MAC)
+        [controller expectParentalControlsLoaded:NO networkExtensionLoaded:YES];
+#else
+        [controller expectParentalControlsLoaded:YES networkExtensionLoaded:YES];
+#endif
+        [TestProtocol unregister];
+
+#if PLATFORM(MAC)
+        isDone = false;
+        [TestProtocol registerWithScheme:@&quot;https&quot;];
+        [[controller webView] loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@&quot;https://test&quot;]]];
+        TestWebKitAPI::Util::run(&amp;isDone);
+        [controller expectParentalControlsLoaded:YES networkExtensionLoaded:YES];
+        [TestProtocol unregister];
+#endif
+    }
+}
+
</ins><span class="cx"> #endif // WK_API_ENABLED
</span></span></pre></div>
<a id="branchessafari601146branchToolsTestWebKitAPITestsWebKit2CocoaContentFilteringPlugInmm"></a>
<div class="modfile"><h4>Modified: branches/safari-601.1.46-branch/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/ContentFilteringPlugIn.mm (194994 => 194995)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601.1.46-branch/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/ContentFilteringPlugIn.mm        2016-01-13 23:10:53 UTC (rev 194994)
+++ branches/safari-601.1.46-branch/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/ContentFilteringPlugIn.mm        2016-01-13 23:11:02 UTC (rev 194995)
</span><span class="lines">@@ -27,8 +27,13 @@
</span><span class="cx"> 
</span><span class="cx"> #if WK_API_ENABLED
</span><span class="cx"> 
</span><ins>+#import &quot;ContentFiltering.h&quot;
</ins><span class="cx"> #import &quot;MockContentFilterSettings.h&quot;
</span><span class="cx"> #import &lt;WebKit/WKWebProcessPlugIn.h&gt;
</span><ins>+#import &lt;WebKit/WKWebProcessPlugInBrowserContextControllerPrivate.h&gt;
+#import &lt;WebKit/_WKRemoteObjectInterface.h&gt;
+#import &lt;WebKit/_WKRemoteObjectRegistry.h&gt;
+#import &lt;mach-o/dyld.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> using MockContentFilterSettings = WebCore::MockContentFilterSettings;
</span><span class="cx"> using Decision = MockContentFilterSettings::Decision;
</span><span class="lines">@@ -73,7 +78,7 @@
</span><span class="cx"> 
</span><span class="cx"> @end
</span><span class="cx"> 
</span><del>-@interface ContentFilteringPlugIn : NSObject &lt;WKWebProcessPlugIn&gt;
</del><ins>+@interface ContentFilteringPlugIn : NSObject &lt;ContentFilteringProtocol, WKWebProcessPlugIn&gt;
</ins><span class="cx"> @end
</span><span class="cx"> 
</span><span class="cx"> @implementation ContentFilteringPlugIn {
</span><span class="lines">@@ -88,6 +93,12 @@
</span><span class="cx">     [plugInController.parameters addObserver:self forKeyPath:NSStringFromClass([MockContentFilterEnabler class]) options:NSKeyValueObservingOptionInitial context:NULL];
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+- (void)webProcessPlugIn:(WKWebProcessPlugInController *)plugInController didCreateBrowserContextController:(WKWebProcessPlugInBrowserContextController *)browserContextController
+{
+    _WKRemoteObjectInterface *interface = [_WKRemoteObjectInterface remoteObjectInterfaceWithProtocol:@protocol(ContentFilteringProtocol)];
+    [[browserContextController _remoteObjectRegistry] registerExportedObject:self interface:interface];
+}
+
</ins><span class="cx"> - (void)dealloc
</span><span class="cx"> {
</span><span class="cx">     [[_plugInController parameters] removeObserver:self forKeyPath:NSStringFromClass([MockContentFilterEnabler class])];
</span><span class="lines">@@ -97,10 +108,24 @@
</span><span class="cx"> - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
</span><span class="cx"> {
</span><span class="cx">     id contentFilterEnabler = [object valueForKeyPath:keyPath];
</span><del>-    ASSERT([contentFilterEnabler isKindOfClass:[MockContentFilterEnabler class]]);
</del><ins>+    ASSERT(!contentFilterEnabler || [contentFilterEnabler isKindOfClass:[MockContentFilterEnabler class]]);
</ins><span class="cx">     _contentFilterEnabler = contentFilterEnabler;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+- (void)checkIfPlatformFrameworksAreLoaded:(void (^)(BOOL parentalControlsLoaded, BOOL networkExtensionLoaded))completionHandler
+{
+    bool parentalControlsLoaded = false;
+#if HAVE(PARENTAL_CONTROLS)
+    parentalControlsLoaded = NSVersionOfRunTimeLibrary(&quot;WebContentAnalysis&quot;) != -1;
+#endif
+    
+    bool networkExtensionLoaded = false;
+#if HAVE(NETWORK_EXTENSION)
+    networkExtensionLoaded = NSVersionOfRunTimeLibrary(&quot;NetworkExtension&quot;) != -1;
+#endif
+    completionHandler(parentalControlsLoaded, networkExtensionLoaded);
+}
+
</ins><span class="cx"> @end
</span><span class="cx"> 
</span><span class="cx"> #endif // WK_API_ENABLED
</span></span></pre></div>
<a id="branchessafari601146branchToolsTestWebKitAPITestsWebKit2ObjCCustomProtocolsTestmm"></a>
<div class="modfile"><h4>Modified: branches/safari-601.1.46-branch/Tools/TestWebKitAPI/Tests/WebKit2ObjC/CustomProtocolsTest.mm (194994 => 194995)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601.1.46-branch/Tools/TestWebKitAPI/Tests/WebKit2ObjC/CustomProtocolsTest.mm        2016-01-13 23:10:53 UTC (rev 194994)
+++ branches/safari-601.1.46-branch/Tools/TestWebKitAPI/Tests/WebKit2ObjC/CustomProtocolsTest.mm        2016-01-13 23:11:02 UTC (rev 194995)
</span><span class="lines">@@ -71,8 +71,7 @@
</span><span class="cx"> 
</span><span class="cx"> TEST(WebKit2CustomProtocolsTest, MainResource)
</span><span class="cx"> {
</span><del>-    [NSURLProtocol registerClass:[TestProtocol class]];
-    [WKBrowsingContextController registerSchemeForCustomProtocol:[TestProtocol scheme]];
</del><ins>+    [TestProtocol registerWithScheme:@&quot;http&quot;];
</ins><span class="cx"> 
</span><span class="cx">     RetainPtr&lt;WKProcessGroup&gt; processGroup = adoptNS([[WKProcessGroup alloc] init]);
</span><span class="cx">     RetainPtr&lt;WKBrowsingContextGroup&gt; browsingContextGroup = adoptNS([[WKBrowsingContextGroup alloc] initWithIdentifier:@&quot;TestIdentifier&quot;]);
</span><span class="lines">@@ -82,8 +81,7 @@
</span><span class="cx">     [[wkView browsingContextController] loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@&quot;%@://redirect?test&quot;, [TestProtocol scheme]]]]];
</span><span class="cx"> 
</span><span class="cx">     Util::run(&amp;testFinished);
</span><del>-    [NSURLProtocol unregisterClass:[TestProtocol class]];
-    [WKBrowsingContextController unregisterSchemeForCustomProtocol:[TestProtocol scheme]];
</del><ins>+    [TestProtocol unregister];
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // namespace TestWebKitAPI
</span></span></pre></div>
<a id="branchessafari601146branchToolsTestWebKitAPITestsWebKit2ObjCPreventImageLoadWithAutoResizingmm"></a>
<div class="modfile"><h4>Modified: branches/safari-601.1.46-branch/Tools/TestWebKitAPI/Tests/WebKit2ObjC/PreventImageLoadWithAutoResizing.mm (194994 => 194995)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601.1.46-branch/Tools/TestWebKitAPI/Tests/WebKit2ObjC/PreventImageLoadWithAutoResizing.mm        2016-01-13 23:10:53 UTC (rev 194994)
+++ branches/safari-601.1.46-branch/Tools/TestWebKitAPI/Tests/WebKit2ObjC/PreventImageLoadWithAutoResizing.mm        2016-01-13 23:11:02 UTC (rev 194995)
</span><span class="lines">@@ -32,7 +32,6 @@
</span><span class="cx"> #import &quot;PlatformUtilities.h&quot;
</span><span class="cx"> #import &quot;PlatformWebView.h&quot;
</span><span class="cx"> #import &quot;TestBrowsingContextLoadDelegate.h&quot;
</span><del>-#import &quot;TestProtocol.h&quot;
</del><span class="cx"> #import &lt;WebKit/WebKit2.h&gt;
</span><span class="cx"> #import &lt;WebKit/WKViewPrivate.h&gt;
</span><span class="cx"> 
</span><span class="lines">@@ -44,9 +43,6 @@
</span><span class="cx"> 
</span><span class="cx"> TEST(WebKit2, PreventImageLoadWithAutoResizingTest)
</span><span class="cx"> {
</span><del>-    [NSURLProtocol registerClass:[TestProtocol class]];
-    [WKBrowsingContextController registerSchemeForCustomProtocol:[TestProtocol scheme]];
-
</del><span class="cx">     WKRetainPtr&lt;WKContextRef&gt; context = adoptWK(Util::createContextForInjectedBundleTest(&quot;DenyWillSendRequestTest&quot;));
</span><span class="cx">     PlatformWebView webView(context.get());
</span><span class="cx"> 
</span><span class="lines">@@ -57,8 +53,6 @@
</span><span class="cx">     [webView.platformView().browsingContextController loadHTMLString:@&quot;&lt;html&gt;&lt;body style='background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAFZJREFUeF59z4EJADEIQ1F36k7u5E7ZKXeUQPACJ3wK7UNokVxVk9kHnQH7bY9hbDyDhNXgjpRLqFlo4M2GgfyJHhjq8V4agfrgPQX3JtJQGbofmCHgA/nAKks+JAjFAAAAAElFTkSuQmCC);'&gt;&lt;/body&gt;&lt;/html&gt;&quot; baseURL:[NSURL URLWithString:@&quot;about:blank&quot;]];
</span><span class="cx"> 
</span><span class="cx">     Util::run(&amp;testFinished);
</span><del>-    [NSURLProtocol unregisterClass:[TestProtocol class]];
-    [WKBrowsingContextController unregisterSchemeForCustomProtocol:[TestProtocol scheme]];
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // namespace TestWebKitAPI
</span></span></pre></div>
<a id="branchessafari601146branchToolsTestWebKitAPIcocoaTestProtocolh"></a>
<div class="modfile"><h4>Modified: branches/safari-601.1.46-branch/Tools/TestWebKitAPI/cocoa/TestProtocol.h (194994 => 194995)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601.1.46-branch/Tools/TestWebKitAPI/cocoa/TestProtocol.h        2016-01-13 23:10:53 UTC (rev 194994)
+++ branches/safari-601.1.46-branch/Tools/TestWebKitAPI/cocoa/TestProtocol.h        2016-01-13 23:11:02 UTC (rev 194995)
</span><span class="lines">@@ -28,6 +28,8 @@
</span><span class="cx"> 
</span><span class="cx"> @interface TestProtocol : NSURLProtocol {
</span><span class="cx"> }
</span><ins>++ (void)registerWithScheme:(NSString *)scheme;
++ (void)unregister;
</ins><span class="cx"> + (NSString *)scheme;
</span><span class="cx"> @end
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchessafari601146branchToolsTestWebKitAPIcocoaTestProtocolmm"></a>
<div class="modfile"><h4>Modified: branches/safari-601.1.46-branch/Tools/TestWebKitAPI/cocoa/TestProtocol.mm (194994 => 194995)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601.1.46-branch/Tools/TestWebKitAPI/cocoa/TestProtocol.mm        2016-01-13 23:10:53 UTC (rev 194994)
+++ branches/safari-601.1.46-branch/Tools/TestWebKitAPI/cocoa/TestProtocol.mm        2016-01-13 23:11:02 UTC (rev 194995)
</span><span class="lines">@@ -26,11 +26,10 @@
</span><span class="cx"> #import &quot;config.h&quot;
</span><span class="cx"> #import &quot;TestProtocol.h&quot;
</span><span class="cx"> 
</span><ins>+#import &lt;WebKit/WKBrowsingContextController.h&gt;
</ins><span class="cx"> #import &lt;wtf/RetainPtr.h&gt;
</span><span class="cx"> 
</span><del>-// Even though NSURLProtocol is capable of generating redirect responses for any protocol, WebCore asserts if a redirect is not in the http family.
-// See http://webkit.org/b/147870 for details.
-static NSString *testScheme = @&quot;http&quot;;
</del><ins>+static NSString *testScheme;
</ins><span class="cx"> 
</span><span class="cx"> @implementation TestProtocol
</span><span class="cx"> 
</span><span class="lines">@@ -54,6 +53,25 @@
</span><span class="cx">     return testScheme;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>++ (void)registerWithScheme:(NSString *)scheme
+{
+    testScheme = [scheme retain];
+    [NSURLProtocol registerClass:[self class]];
+#if WK_API_ENABLED
+    [WKBrowsingContextController registerSchemeForCustomProtocol:testScheme];
+#endif
+}
+
++ (void)unregister
+{
+#if WK_API_ENABLED
+    [WKBrowsingContextController unregisterSchemeForCustomProtocol:testScheme];
+#endif
+    [NSURLProtocol unregisterClass:[self class]];
+    [testScheme release];
+    testScheme = nil;
+}
+
</ins><span class="cx"> - (void)startLoading
</span><span class="cx"> {
</span><span class="cx">     NSURL *requestURL = self.request.URL;
</span></span></pre>
</div>
</div>

</body>
</html>