2009-12-27 Maciej Stachowiak <mjs@apple.com>
authormjs@apple.com <mjs@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 29 Dec 2009 13:52:57 +0000 (13:52 +0000)
committermjs@apple.com <mjs@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 29 Dec 2009 13:52:57 +0000 (13:52 +0000)
        Reviewed by Alexey Proskuryakov.

        plugins/get-url-with-iframe-target.html fails on SnowLeopard (64-bit)
        https://bugs.webkit.org/show_bug.cgi?id=32982

        This test has been failing on SnowLeopard since it was landed.

        The problem is that we never delivered the notification for
        NPN_GetURLNotify, in the frame-targeting case, for out-of-process
        plugins on Mac.

        I implemented support for this based on how in-process Mac plugins
        do it.

        * Plugins/Hosted/HostedNetscapePluginStream.h:
        * Plugins/Hosted/HostedNetscapePluginStream.mm:
        (WebKit::HostedNetscapePluginStream::reasonForError):
        * Plugins/Hosted/NetscapePluginInstanceProxy.h:
        * Plugins/Hosted/NetscapePluginInstanceProxy.mm:
        (WebKit::NetscapePluginInstanceProxy::PluginRequest::create):
        (WebKit::NetscapePluginInstanceProxy::PluginRequest::PluginRequest):
        (WebKit::NetscapePluginInstanceProxy::destroy):
        (WebKit::NetscapePluginInstanceProxy::performRequest):
        (WebKit::NetscapePluginInstanceProxy::webFrameDidFinishLoadWithReason):
        (WebKit::NetscapePluginInstanceProxy::requestTimerFired):
        (WebKit::NetscapePluginInstanceProxy::loadRequest):
        * Plugins/Hosted/WebHostedNetscapePluginView.h:
        * Plugins/Hosted/WebHostedNetscapePluginView.mm:
        (-[WebHostedNetscapePluginView webFrame:didFinishLoadWithReason:]):
        (-[WebHostedNetscapePluginView webFrame:didFinishLoadWithError:]):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@52619 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebKit/mac/ChangeLog
WebKit/mac/Plugins/Hosted/HostedNetscapePluginStream.h
WebKit/mac/Plugins/Hosted/HostedNetscapePluginStream.mm
WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.h
WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.mm
WebKit/mac/Plugins/Hosted/WebHostedNetscapePluginView.h
WebKit/mac/Plugins/Hosted/WebHostedNetscapePluginView.mm

index 500133938ac813fb4c7732a7b72622988be442b7..ba250b69bd8647aa7ee062c02d2ffc69dd77b3e7 100644 (file)
@@ -1,3 +1,36 @@
+2009-12-27  Maciej Stachowiak  <mjs@apple.com>
+
+        Reviewed by Alexey Proskuryakov.
+
+        plugins/get-url-with-iframe-target.html fails on SnowLeopard (64-bit)
+        https://bugs.webkit.org/show_bug.cgi?id=32982
+        
+        This test has been failing on SnowLeopard since it was landed.
+        
+        The problem is that we never delivered the notification for
+        NPN_GetURLNotify, in the frame-targeting case, for out-of-process
+        plugins on Mac.
+        
+        I implemented support for this based on how in-process Mac plugins
+        do it.
+
+        * Plugins/Hosted/HostedNetscapePluginStream.h:
+        * Plugins/Hosted/HostedNetscapePluginStream.mm:
+        (WebKit::HostedNetscapePluginStream::reasonForError):
+        * Plugins/Hosted/NetscapePluginInstanceProxy.h:
+        * Plugins/Hosted/NetscapePluginInstanceProxy.mm:
+        (WebKit::NetscapePluginInstanceProxy::PluginRequest::create):
+        (WebKit::NetscapePluginInstanceProxy::PluginRequest::PluginRequest):
+        (WebKit::NetscapePluginInstanceProxy::destroy):
+        (WebKit::NetscapePluginInstanceProxy::performRequest):
+        (WebKit::NetscapePluginInstanceProxy::webFrameDidFinishLoadWithReason):
+        (WebKit::NetscapePluginInstanceProxy::requestTimerFired):
+        (WebKit::NetscapePluginInstanceProxy::loadRequest):
+        * Plugins/Hosted/WebHostedNetscapePluginView.h:
+        * Plugins/Hosted/WebHostedNetscapePluginView.mm:
+        (-[WebHostedNetscapePluginView webFrame:didFinishLoadWithReason:]):
+        (-[WebHostedNetscapePluginView webFrame:didFinishLoadWithError:]):
+
 2009-12-22  Darin Adler  <darin@apple.com>
 
         Reviewed by Mark Rowe.
index 946c8aca76b42a2e2bab3dc62c8c5fd973553c59..34cea323add20fb8e5de97bad8b71781992318a8 100644 (file)
@@ -70,6 +70,8 @@ public:
 
     void cancelLoad(NPReason reason);
 
+    static NPReason reasonForError(NSError* error);
+
 private:
     NSError *errorForReason(NPReason) const;
     void cancelLoad(NSError *);
index 5c25ef784f62a4691c594335b5dee2d8d0aa5d1d..98b5a7e734a4e3ffb66d77b3be8dfade4d2f588d 100644 (file)
@@ -183,7 +183,7 @@ void HostedNetscapePluginStream::didReceiveResponse(NetscapePlugInStreamLoader*,
     startStream([r URL], expectedContentLength, WKGetNSURLResponseLastModifiedDate(r), [r MIMEType], theHeaders);
 }
 
-static NPReason reasonForError(NSError *error)
+NPReason HostedNetscapePluginStream::reasonForError(NSError *error)
 {
     if (!error)
         return NPRES_DONE;
index c950ab758b2fee46545f68b3b3fc56f35b55f476..bad8751e6b515f727a547e875f23212a2d54d598 100644 (file)
@@ -49,11 +49,13 @@ namespace JSC {
     }
 }
 @class WebHostedNetscapePluginView;
+@class WebFrame;
 
 namespace WebKit {
 
 class HostedNetscapePluginStream;
 class NetscapePluginHostProxy;
+class PluginRequest;
 class ProxyInstance;
     
 class NetscapePluginInstanceProxy : public RefCounted<NetscapePluginInstanceProxy> {
@@ -257,10 +259,12 @@ public:
         return std::auto_ptr<T>(static_cast<T*>(reply));
     }
     
+    void webFrameDidFinishLoadWithReason(WebFrame*, NPReason);
+
 private:
-    NetscapePluginInstanceProxy(NetscapePluginHostProxy*, WebHostedNetscapePluginView *, bool fullFramePlugin);
+    NetscapePluginInstanceProxy(NetscapePluginHostProxy*, WebHostedNetscapePluginView*, bool fullFramePlugin);
 
-    NPError loadRequest(NSURLRequest *, const char* cTarget, bool currentEventIsUserGesture, uint32_t& streamID);
+    NPError loadRequest(NSURLRequest*, const char* cTarget, bool currentEventIsUserGesture, uint32_t& streamID);
     
     class PluginRequest;
     void performRequest(PluginRequest*);
@@ -274,7 +278,7 @@ private:
 
     void requestTimerFired(WebCore::Timer<NetscapePluginInstanceProxy>*);
     WebCore::Timer<NetscapePluginInstanceProxy> m_requestTimer;
-    Deque<PluginRequest*> m_pluginRequests;
+    Deque<RefPtr<PluginRequest> > m_pluginRequests;
     
     HashMap<uint32_t, RefPtr<HostedNetscapePluginStream> > m_streams;
 
@@ -313,6 +317,9 @@ private:
     bool m_pluginIsWaitingForDraw;
     
     RefPtr<HostedNetscapePluginStream> m_manualStream;
+
+    typedef HashMap<WebFrame*, RefPtr<PluginRequest> > FrameLoadMap;
+    FrameLoadMap m_pendingFrameLoads;
 };
     
 } // namespace WebKit
index 4ae0220acc9839b55fccfc70178cb76f32a3d8bd..c3d99aeffaba2f305ff598284495c4dd4050c19d 100644 (file)
@@ -72,9 +72,20 @@ using namespace WebCore;
 
 namespace WebKit {
 
-class NetscapePluginInstanceProxy::PluginRequest {
+class NetscapePluginInstanceProxy::PluginRequest : public RefCounted<NetscapePluginInstanceProxy::PluginRequest> {
 public:
-    PluginRequest(uint32_t requestID, NSURLRequest *request, NSString *frameName, bool allowPopups)
+    static PassRefPtr<PluginRequest> create(uint32_t requestID, NSURLRequest* request, NSString* frameName, bool allowPopups)
+    {
+        return adoptRef(new PluginRequest(requestID, request, frameName, allowPopups));
+    }
+
+    uint32_t requestID() const { return m_requestID; }
+    NSURLRequest* request() const { return m_request.get(); }
+    NSString* frameName() const { return m_frameName.get(); }
+    bool allowPopups() const { return m_allowPopups; }
+    
+private:
+    PluginRequest(uint32_t requestID, NSURLRequest* request, NSString* frameName, bool allowPopups)
         : m_requestID(requestID)
         , m_request(request)
         , m_frameName(frameName)
@@ -82,15 +93,9 @@ public:
     {
     }
     
-    uint32_t requestID() const { return m_requestID; }
-    NSURLRequest *request() const { return m_request.get(); }
-    NSString *frameName() const { return m_frameName.get(); }
-    bool allowPopups() const { return m_allowPopups; }
-    
-private:
     uint32_t m_requestID;
-    RetainPtr<NSURLRequest *> m_request;
-    RetainPtr<NSString *> m_frameName;
+    RetainPtr<NSURLRequest*> m_request;
+    RetainPtr<NSString*> m_frameName;
     bool m_allowPopups;
 };
 
@@ -212,6 +217,10 @@ void NetscapePluginInstanceProxy::destroy()
     
     m_inDestroy = true;
     
+    FrameLoadMap::iterator end = m_pendingFrameLoads.end();
+    for (FrameLoadMap::iterator it = m_pendingFrameLoads.begin(); it != end; ++it)
+        [(it->first) _setInternalLoadDelegate:nil];
+
     _WKPHDestroyPluginInstance(m_pluginHostProxy->port(), m_pluginID, requestID);
  
     // If the plug-in host crashes while we're waiting for a reply, the last reference to the instance proxy
@@ -517,8 +526,33 @@ void NetscapePluginInstanceProxy::performRequest(PluginRequest* pluginRequest)
     if (JSString) {
         ASSERT(!frame || [m_pluginView webFrame] == frame);
         evaluateJavaScript(pluginRequest);
-    } else
+    } else {
         [frame loadRequest:request];
+
+        // Check if another plug-in view or even this view is waiting for the frame to load.
+        // If it is, tell it that the load was cancelled because it will be anyway.
+        WebHostedNetscapePluginView *view = [frame _internalLoadDelegate];
+        if (view != nil) {
+            ASSERT([view isKindOfClass:[WebHostedNetscapePluginView class]]);
+            [view webFrame:frame didFinishLoadWithReason:NPRES_USER_BREAK];
+        }
+        m_pendingFrameLoads.set(frame, pluginRequest);
+        [frame _setInternalLoadDelegate:m_pluginView];
+    }
+
+}
+
+void NetscapePluginInstanceProxy::webFrameDidFinishLoadWithReason(WebFrame* webFrame, NPReason reason)
+{
+    FrameLoadMap::iterator it = m_pendingFrameLoads.find(webFrame);
+    ASSERT(it != m_pendingFrameLoads.end());
+        
+    PluginRequest* pluginRequest = it->second.get();
+    _WKPHLoadURLNotify(m_pluginHostProxy->port(), m_pluginID, pluginRequest->requestID(), reason);
+    m_pendingFrameLoads.remove(it);
+
+    [webFrame _setInternalLoadDelegate:nil];
 }
 
 void NetscapePluginInstanceProxy::evaluateJavaScript(PluginRequest* pluginRequest)
@@ -557,14 +591,13 @@ void NetscapePluginInstanceProxy::requestTimerFired(Timer<NetscapePluginInstance
     ASSERT(!m_pluginRequests.isEmpty());
     ASSERT(m_pluginView);
     
-    PluginRequest* request = m_pluginRequests.first();
+    RefPtr<PluginRequest> request = m_pluginRequests.first();
     m_pluginRequests.removeFirst();
     
     if (!m_pluginRequests.isEmpty())
         m_requestTimer.startOneShot(0);
     
-    performRequest(request);
-    delete request;
+    performRequest(request.get());
 }
     
 NPError NetscapePluginInstanceProxy::loadRequest(NSURLRequest *request, const char* cTarget, bool allowPopups, uint32_t& requestID)
@@ -616,8 +649,8 @@ NPError NetscapePluginInstanceProxy::loadRequest(NSURLRequest *request, const ch
             return NPERR_INVALID_PARAM;
         }
 
-        PluginRequest* pluginRequest = new PluginRequest(requestID, request, target, allowPopups);
-        m_pluginRequests.append(pluginRequest);
+        RefPtr<PluginRequest> pluginRequest = PluginRequest::create(requestID, request, target, allowPopups);
+        m_pluginRequests.append(pluginRequest.release());
         m_requestTimer.startOneShot(0);
     } else {
         RefPtr<HostedNetscapePluginStream> stream = HostedNetscapePluginStream::create(this, requestID, request);
index 4ff5abaf10ba11443a1e24e451691127a4f10e5e..323350d9597cf87c170022bcdb02206e731b8a8d 100644 (file)
@@ -59,6 +59,9 @@ namespace WebKit {
             element:(PassRefPtr<WebCore::HTMLPlugInElement>)element;
 
 - (void)pluginHostDied;
+
+- (void)webFrame:(WebFrame *)webFrame didFinishLoadWithReason:(NPReason)reason;
+
 @end
 
 #endif // USE(PLUGIN_HOST_PROCESS)
index 8de2aa63ab1200c5f66eee858c0ec6d734b56ceb..9a161601f966305b7a8e30979c9f22eeec9716ff 100644 (file)
@@ -441,6 +441,20 @@ extern "C" {
     _proxy->checkIfAllowedToLoadURLResult(checkID, (policy == PolicyUse));
 }
 
+- (void)webFrame:(WebFrame *)webFrame didFinishLoadWithReason:(NPReason)reason
+{
+    if (_isStarted && _proxy)
+        _proxy->webFrameDidFinishLoadWithReason(webFrame, reason);
+}
+
+- (void)webFrame:(WebFrame *)webFrame didFinishLoadWithError:(NSError *)error
+{
+    NPReason reason = NPRES_DONE;
+    if (error)
+        reason = HostedNetscapePluginStream::reasonForError(error);
+    [self webFrame:webFrame didFinishLoadWithReason:reason];
+}
+
 @end
 
 #endif