Bug 25332 - Plug-in inserted in to DOM of PluginDocument fails to load
Summary: Plug-in inserted in to DOM of PluginDocument fails to load
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Plug-ins (show other bugs)
Version: 528+ (Nightly build)
Hardware: Mac OS X 10.5
: P3 Normal
Assignee: Mark Rowe (bdash)
URL: http://rentzsch.lighthouseapp.com/pro...
Keywords: HasReduction, InRadar
Depends on:
Blocks:
 
Reported: 2009-04-22 14:06 PDT by Simone Manganelli
Modified: 2009-05-06 01:27 PDT (History)
3 users (show)

See Also:


Attachments
reduction of ClickToFlash plugin that loads Flash content and then immediately passes off to Flash plugin (1.30 MB, application/zip)
2009-04-22 18:56 PDT, Simone Manganelli
no flags Details
Reduction that builds (6.07 KB, application/zip)
2009-05-03 17:48 PDT, Mark Rowe (bdash)
no flags Details
Patch (2.55 KB, patch)
2009-05-03 23:33 PDT, Mark Rowe (bdash)
darin: review+
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Simone Manganelli 2009-04-22 14:06:29 PDT
When loading a bare .swf file in a WebKit window or tab, WebKit creates a skeleton DOM around the file before loading it.  This skeleton DOM works correctly when not intercepted by a plug-in.  When it's intercepted by a ClickToFlash plugin, however, which eventually releases the .swf file to the Flash plugin after clicking on it, the skeleton DOM ceases to allow the display of the .swf file.

The source for the latest code of ClickToFlash will demonstrate this problem: http://github.com/rentzsch/clicktoflash/tree/master .  From what I can tell, this is not a ClickToFlash problem, because a file with identical HTML will allow the .swf file to load, but the same exact HTML that's eventually loaded by WebKit after ClickToFlash causes the .swf file *not* to load.


Steps to Reproduce:

1.  Make sure the ClickToFlash plugin is not installed.

2.  Launch WebKit.

3.  Navigate to http://www.somethingawful.com/flash/shmorky/babby.swf .  Note that the .swf file loads and displays immediately.

4.  Install the ClickToFlash plugin.

5.  Navigate to http://www.somethingawful.com/flash/shmorky/babby.swf .  Note that ClickToFlash intercepts the .swf file and displays a ClickToFlash view.

6.  Click on the ClickToFlash view.  Note that ClickToFlash releases the .swf file to the Adobe Flash plugin, but displays nothing.

7.  Control-click on the Flash view.  Note that the contextual menu says "Movie not loaded...".

8.  Select [Develop --> Show Web Inspector].  Look at the HTML of the resultant skeleton DOM that WebKit creates around the .swf file.

9.  Open a new tab.  Navigate to http://homepage.mac.com/simx/test-ctf-flash.html .  Observe that ClickToFlash intercepts the .swf file and displays a ClickToFlash view.

10.  Click on the ClickToFlash view.  Note that ClickToFlash releases the .swf file to the Flash plugin, and this time, it displays *correctly*.

11.  Select [Develop --> Show Web Inspector].  Look at the HTML of the file.  Note that this HTML is *identical* to the HTML observed in step 8, but with different results!  The .swf file plays correctly when linked to from this HTML page, but when WebKit constructs the DOM after ClickToFlash releases the .swf file, WebKit refuses to play it.


Expected Results: I expect identical resultant HTML to result in identical display of the contents.


Actual Results: Identical HTML coming from different sources unexpectedly has different results.  If the HTML is from an HTML file, .swf files play fine.  If the same, identical HTML is constructed by WebKit when loading a bare .swf file after ClickToFlash interception, WebKit refuses to play the .swf file.
Comment 1 Simone Manganelli 2009-04-22 14:08:14 PDT
Please note, this bug can be tracked on ClickToFlash's bug tracking system here: http://rentzsch.lighthouseapp.com/projects/24342/tickets/75-cant-play-local-content 

Also, I have tried to programatically construct an enclosure div and even a separate OBJECT tag to try and load the .swf files after ClickToFlash releases them, but to no avail.  Sample code:

id parent = self.container.parentNode;
[parent removeChild:self.container];
[self.container setAttribute:@"allowscriptaccess" value:@"always"];
DOMElement *newNode = [[self.container ownerDocument] createElement:@"div"];
DOMElement *cloneNode = (DOMElement *)[self.container cloneNode:YES];
DOMElement *objectNode = [[self.container ownerDocument] createElement:@"object"];
[objectNode setAttribute:@"type" value:@"application/futuresplash"];
[objectNode setAttribute:@"data" value:self.src];
DOMElement *paramNode = [[self.container ownerDocument] createElement:@"param"];
[paramNode setAttribute:@"name" value:@"movie"];
[paramNode setAttribute:@"value" value:self.src];
[parent appendChild:newNode];
[newNode appendChild:self.container];
[newNode appendChild:cloneNode];
[newNode appendChild:objectNode];
[objectNode appendChild];
Comment 2 Mark Rowe (bdash) 2009-04-22 15:54:12 PDT
Full-frame plug-ins are handled via instances of the PluginDocument subclass of HTMLDocument, rather than HTMLDocument itself.  The standard HTML tokenizer is entirely bypassed and DOM is explicitly created.  This difference in implementation may be responsible for the difference in behavior.  It may be related to the fact that PluginTokenizer::writeRawData calls FrameLoaderClient::redirectDataToPlugin which seems like it may influence how data is loaded.
Comment 3 Mark Rowe (bdash) 2009-04-22 16:08:15 PDT
<rdar://problem/6818421>
Comment 4 Simone Manganelli 2009-04-22 18:56:18 PDT
Created attachment 29699 [details]
reduction of ClickToFlash plugin that loads Flash content and then immediately passes off to Flash plugin
Comment 5 Mark Rowe (bdash) 2009-05-03 17:48:20 PDT
Created attachment 29969 [details]
Reduction that builds
Comment 6 Mark Rowe (bdash) 2009-05-03 23:22:50 PDT
I spent a little while debugging this tonight.  What's happening is that when creating the Flash plug-in, WebFrameLoaderClient::createPlugin is being called with loadManually=true, indicating that the main resource stream should be used for the data.  However, this stream was already used for the WebKit plug-in that was initially created.  Since loadManually is not false we won't explicitly request the plug-in source URL, resulting in the Flash plug-in never receiving any data.  The code in FrameLoader::loadPlugin currently always sets loadManually=true for plug-ins in a plug-in document, working on the assumption that there will only ever be a single plug-in in the document.  ClickToFlash's behavior clearly violates this assumption.  We can fix this by having FrameLoader::loadPlugin only pass loadManually=true if the plug-in will receive data from the main resource.  I can't see a direct way of determining that, but we can approximate this by checking if this is the first plug-in to be inserted in to the plug-in document (isPluginDocument() && !m_containsPlugIns).  In my tests, this fixes the bug.
Comment 7 Mark Rowe (bdash) 2009-05-03 23:26:32 PDT
Also, is it just me or is loadManually a rather confusing name for the parameter?  When it's set to false, we explicitly load the resource.  If it's true, then we don't load anything…
Comment 8 Mark Rowe (bdash) 2009-05-03 23:33:12 PDT
Created attachment 29986 [details]
Patch
Comment 9 Mark Rowe (bdash) 2009-05-04 08:39:19 PDT
Landed in r43181.
Comment 10 Simone Manganelli 2009-05-06 01:27:15 PDT
Confirmed fixed.