Reviewed by Geoff.
authortomernic <tomernic@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 26 Apr 2006 20:18:03 +0000 (20:18 +0000)
committertomernic <tomernic@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 26 Apr 2006 20:18:03 +0000 (20:18 +0000)
        <rdar://problem/4525105> Repro TOT crash in [WebBaseNetscapePluginView dealloc] at coachella.com
        <http://bugzilla.opendarwin.org/show_bug.cgi?id=8564> crashed when closing a tab

        * WebView/WebFrame.m:
        (-[WebFramePrivate dealloc]):
        Assert that plugInViews has been released.
        (-[WebFrame _addPlugInView:]):
        New method.  Adds the plug-in view to the plugInViews set and calls -setWebFrame: on it.
        (-[WebFrame _removeAllPlugInViews]):
        New method.  Calls -setWebFrame:nil on all plug-in views and releases the plugInViews set.
        (-[WebFrame _willCloseURL]):
        New method.  Dispose of plug-in views when leaving a page (or closing the WebView).

        * WebView/WebFrameInternal.h:
        Declared -_addPlugInView:, -_removeAllPlugInViews, -_willCloseURL

        * WebCoreSupport/WebFrameBridge.m:
        (-[WebFrameBridge viewForPluginWithURL:attributeNames:attributeValues:MIMEType:]):
        Call -[WebFrame _addPlugInView:] instead of directly setting plug-in views' frames.  This
        allows us to keep track of them so that we can explicitly dispose of them when leaving the page.
        (-[WebFrameBridge closeURL]):
        Override -[WebCoreFrameBridge closeURL] so that we can perform our own teardown when leaving
        a page or closing the WebView.

        * Plugins/WebBaseNetscapePluginView.h:
        Declared -stop so that subclass WebNetscapePluginEmbeddedView can call it.

        * Plugins/WebNetscapePluginEmbeddedView.m:
        (-[WebNetscapePluginEmbeddedView setWebFrame:]):
        Stop the plug-in when it is removed from its WebFrame.

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

WebKit/ChangeLog
WebKit/Plugins/WebBaseNetscapePluginView.h
WebKit/Plugins/WebNetscapePluginEmbeddedView.m
WebKit/WebCoreSupport/WebFrameBridge.m
WebKit/WebView/WebFrame.m
WebKit/WebView/WebFrameInternal.h

index 3ed3a30eb1c07f638c8ac224dfb83040bd40ff33..fdde37853f27bfd791a60d07eadacb7408eec8d7 100644 (file)
@@ -1,3 +1,38 @@
+2006-04-26  Tim Omernick  <timo@apple.com>
+
+        Reviewed by Geoff.
+
+        <rdar://problem/4525105> Repro TOT crash in [WebBaseNetscapePluginView dealloc] at coachella.com
+        <http://bugzilla.opendarwin.org/show_bug.cgi?id=8564> crashed when closing a tab
+
+        * WebView/WebFrame.m:
+        (-[WebFramePrivate dealloc]):
+        Assert that plugInViews has been released.
+        (-[WebFrame _addPlugInView:]):
+        New method.  Adds the plug-in view to the plugInViews set and calls -setWebFrame: on it.
+        (-[WebFrame _removeAllPlugInViews]):
+        New method.  Calls -setWebFrame:nil on all plug-in views and releases the plugInViews set.
+        (-[WebFrame _willCloseURL]):
+        New method.  Dispose of plug-in views when leaving a page (or closing the WebView).
+
+        * WebView/WebFrameInternal.h:
+        Declared -_addPlugInView:, -_removeAllPlugInViews, -_willCloseURL
+
+        * WebCoreSupport/WebFrameBridge.m:
+        (-[WebFrameBridge viewForPluginWithURL:attributeNames:attributeValues:MIMEType:]):
+        Call -[WebFrame _addPlugInView:] instead of directly setting plug-in views' frames.  This
+        allows us to keep track of them so that we can explicitly dispose of them when leaving the page.
+        (-[WebFrameBridge closeURL]):
+        Override -[WebCoreFrameBridge closeURL] so that we can perform our own teardown when leaving
+        a page or closing the WebView.
+
+        * Plugins/WebBaseNetscapePluginView.h:
+        Declared -stop so that subclass WebNetscapePluginEmbeddedView can call it.
+
+        * Plugins/WebNetscapePluginEmbeddedView.m:
+        (-[WebNetscapePluginEmbeddedView setWebFrame:]):
+        Stop the plug-in when it is removed from its WebFrame.
+
 2006-04-25  Tim Omernick  <timo@apple.com>
 
         Reviewed by John Sullivan.
index 893506db9876c4527a63a743e128383173b8f9df..2ffcab60c7438a58abcc4e69c3cea5412208ec0f 100644 (file)
@@ -93,6 +93,7 @@
 
 - (BOOL)start;
 - (BOOL)isStarted;
+- (void)stop;
 
 - (WebFrame *)webFrame;
 - (WebDataSource *)dataSource;
index 66fc52ac3fe485e7a471a1c2ba726398799e6ae1..226da8fc54df6fce2893631e3029b2968fffd100 100644 (file)
 
 - (void)setWebFrame:(WebFrame *)webFrame
 {
+    if (webFrame == _webFrame)
+        return;
+        
     _webFrame = webFrame;
+    
+    if (!_webFrame)
+        [self stop];
 }
 
 - (WebDataSource *)dataSource
index 533a1088da63fa9be9269a5e5e16de73511de3be..b44d7a6487080e39492023a6cc966a9e425d7397 100644 (file)
@@ -990,7 +990,7 @@ NSString *WebPluginContainerKey =   @"WebPluginContainer";
                                                            attributeKeys:attributeNames
                                                          attributeValues:attributeValues] autorelease];
             view = embeddedView;
-            [embeddedView setWebFrame:_frame];
+            [_frame _addPlugInView:embeddedView];
         } else
             ASSERT_NOT_REACHED();
     } else
@@ -1008,7 +1008,7 @@ NSString *WebPluginContainerKey =   @"WebPluginContainer";
                                                         pluginName:[pluginPackage name]
                                                           MIMEType:MIMEType];
         WebNullPluginView *nullView = [[[WebNullPluginView alloc] initWithFrame:NSZeroRect error:error] autorelease];
-        [nullView setWebFrame:_frame];
+        [_frame _addPlugInView:nullView];
         view = nullView;
         [error release];
     }
@@ -1611,4 +1611,10 @@ static id <WebFormDelegate> formDelegate(WebFrameBridge *self)
     [_frame _handledOnloadEvents];
 }
 
+- (void)closeURL
+{
+    [_frame _willCloseURL];
+    [super closeURL];
+}
+
 @end
index 6afa4e30d74c06b80e1b7f1f95977c57ae5d77d3..5a6a9943280f51a8a3aac01770f172b4a556368f 100644 (file)
@@ -166,6 +166,10 @@ NSString *WebPageCacheDocumentViewKey = @"WebPageCacheDocumentViewKey";
 - (WebFrame *)_traverseNextFrameStayWithin:(WebFrame *)stayWithin;
 @end
 
+@interface NSView (WebFramePluginHosting)
+- (void)setWebFrame:(WebFrame *)webFrame;
+@end
+
 @interface WebFramePrivate : NSObject
 {
 @public
@@ -202,6 +206,8 @@ NSString *WebPageCacheDocumentViewKey = @"WebPageCacheDocumentViewKey";
     WebScriptDebugger *scriptDebugger;
 
     NSString *frameNamespace;
+    
+    NSMutableSet *plugInViews;
 }
 
 - (void)setWebFrameView:(WebFrameView *)v;
@@ -256,7 +262,8 @@ NSString *WebPageCacheDocumentViewKey = @"WebPageCacheDocumentViewKey";
     ASSERT(policyFormState == nil);
     ASSERT(policyDataSource == nil);
     ASSERT(frameNamespace == nil);
-
+    ASSERT(plugInViews == nil);
+    
     [super dealloc];
 }
 
@@ -2771,6 +2778,34 @@ static CFAbsoluteTime _timeOfLastCompletedLoad;
     return frame != nil;
 }
 
+- (void)_addPlugInView:(NSView *)plugInView
+{
+    ASSERT([plugInView respondsToSelector:@selector(setWebFrame:)]);
+    ASSERT(![_private->plugInViews containsObject:plugInView]);
+    
+    if (!_private->plugInViews)
+        _private->plugInViews = [[NSMutableSet alloc] init];
+        
+    [plugInView setWebFrame:self];
+    [_private->plugInViews addObject:plugInView];
+}
+
+- (void)_removeAllPlugInViews
+{
+    if (!_private->plugInViews)
+        return;
+    
+    [_private->plugInViews makeObjectsPerformSelector:@selector(setWebFrame:) withObject:nil];
+    [_private->plugInViews release];
+    _private->plugInViews = nil;
+}
+
+// This is called when leaving a page or closing the WebView
+- (void)_willCloseURL
+{
+    [self _removeAllPlugInViews];
+}
+
 @end
 
 @implementation WebFormState : NSObject
index c2923244cddbeec5c24a20de07cad5394f9d779d..3abb5cd10034723a0881625291ea1dd5a2b97c49 100644 (file)
 - (BOOL)_subframeIsLoading;
 - (id)_initWithWebFrameView:(WebFrameView *)fv webView:(WebView *)v bridge:(WebFrameBridge *)bridge;
 
+- (void)_addPlugInView:(NSView *)plugInView;
+- (void)_removeAllPlugInViews;
+
+// This should be called when leaving a page or closing the WebView
+- (void)_willCloseURL;
+
 @end
 
 @interface NSObject (WebInternalFrameLoadDelegate)