Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(17)

Side by Side Diff: Source/core/html/HTMLPlugInElement.cpp

Issue 23618022: BrowserPlugin/WebView - Move plugin lifetime to DOM (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Revised method for widget lifetime management. Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /** 1 /**
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2000 Stefan Schimanski (1Stein@gmx.de) 4 * (C) 2000 Stefan Schimanski (1Stein@gmx.de)
5 * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc. 5 * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
6 * 6 *
7 * This library is free software; you can redistribute it and/or 7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public 8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either 9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version. 10 * version 2 of the License, or (at your option) any later version.
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
75 ASSERT(!m_pluginWrapper); // cleared in detach() 75 ASSERT(!m_pluginWrapper); // cleared in detach()
76 76
77 if (m_NPObject) { 77 if (m_NPObject) {
78 _NPN_ReleaseObject(m_NPObject); 78 _NPN_ReleaseObject(m_NPObject);
79 m_NPObject = 0; 79 m_NPObject = 0;
80 } 80 }
81 } 81 }
82 82
83 bool HTMLPlugInElement::canProcessDrag() const 83 bool HTMLPlugInElement::canProcessDrag() const
84 { 84 {
85 return pluginWidget() && pluginWidget()->isPluginView() && toPluginView(plug inWidget())->canProcessDrag(); 85 return widget() && widget()->isPluginView() && toPluginView(widget())->canPr ocessDrag();
86 } 86 }
87 87
88 bool HTMLPlugInElement::willRespondToMouseClickEvents() 88 bool HTMLPlugInElement::willRespondToMouseClickEvents()
89 { 89 {
90 if (isDisabledFormControl()) 90 if (isDisabledFormControl())
91 return false; 91 return false;
92 RenderObject* r = renderer(); 92 RenderObject* r = renderer();
93 return r && (r->isEmbeddedObject() || r->isWidget()); 93 return r && (r->isEmbeddedObject() || r->isWidget());
94 } 94 }
95 95
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 { 129 {
130 toHTMLPlugInElement(n)->updateWidgetIfNecessary(); 130 toHTMLPlugInElement(n)->updateWidgetIfNecessary();
131 } 131 }
132 132
133 void HTMLPlugInElement::updateWidgetIfNecessary() 133 void HTMLPlugInElement::updateWidgetIfNecessary()
134 { 134 {
135 document().updateStyleIfNeeded(); 135 document().updateStyleIfNeeded();
136 136
137 if (!needsWidgetUpdate() || useFallbackContent() || isImageType()) 137 if (!needsWidgetUpdate() || useFallbackContent() || isImageType())
138 return; 138 return;
139
140 if (!renderEmbeddedObject() && !m_serviceType.isEmpty()) {
141 createPluginWithoutRenderer(m_serviceType);
142 return;
143 }
144
139 if (!renderEmbeddedObject() || renderEmbeddedObject()->showsUnavailablePlugi nIndicator()) 145 if (!renderEmbeddedObject() || renderEmbeddedObject()->showsUnavailablePlugi nIndicator())
140 return; 146 return;
141 147
142 updateWidget(CreateOnlyNonNetscapePlugins); 148 updateWidget(CreateOnlyNonNetscapePlugins);
143 } 149 }
144 150
151 void HTMLPlugInElement::createPluginWithoutRenderer(const String& mimeType)
152 {
153 KURL url;
154 Vector<String> paramNames;
155 Vector<String> paramValues;
156
157 paramNames.append("type");
158 paramValues.append(mimeType);
159
160 bool useFallback = false;
161 if (loadPlugin(url, mimeType, paramNames, paramValues, useFallback)) {
162 // Register the bindings with V8 as a scriptable object; normally this
163 // as done in getInstance(), but that is only called after a renderer
164 // has been assigned.
165 // If we've created a plugin without a renderer, it may want to be able
166 // to configure itself before attach, so make sure it has a script
167 // object.
168 // FIXME: Do we need a new script object and plugin wrapper when we
169 // create a plugin? Or can we re-use any existing ones?
170 Widget* plugin = widget();
171 ASSERT(plugin);
172 Frame* frame = document().frame();
173 if (!m_NPObject)
174 m_NPObject = frame->script().createScriptObjectForPluginElement(this );
175 m_pluginWrapper = frame->script().createPluginWrapper(plugin);
176 }
177 }
178
145 void HTMLPlugInElement::detach(const AttachContext& context) 179 void HTMLPlugInElement::detach(const AttachContext& context)
146 { 180 {
147 // Update the widget the next time we attach (detaching destroys the plugin) . 181 // Update the widget the next time we attach (detaching destroys the plugin) .
148 // FIXME: None of this "needsWidgetUpdate" related code looks right. 182 // FIXME: None of this "needsWidgetUpdate" related code looks right.
149 if (renderer() && !useFallbackContent()) 183 if (renderer() && !useFallbackContent())
150 setNeedsWidgetUpdate(true); 184 setNeedsWidgetUpdate(true);
151 185
152 resetInstance(); 186 Widget* plugin = widget();
187 if (plugin) {
eseidel 2013/12/02 16:28:34 Just combine these two ifs into one line?
wjmaclean 2013/12/02 21:51:55 This disappears in the new patch :-)
188 if (!plugin->pluginShouldPersist()) {
189 setWidget(0);
190 resetInstance();
191 }
192 }
153 193
154 if (m_isCapturingMouseEvents) { 194 if (m_isCapturingMouseEvents) {
155 if (Frame* frame = document().frame()) 195 if (Frame* frame = document().frame())
156 frame->eventHandler().setCapturingMouseEventsNode(0); 196 frame->eventHandler().setCapturingMouseEventsNode(0);
157 m_isCapturingMouseEvents = false; 197 m_isCapturingMouseEvents = false;
158 } 198 }
159 199
160 if (m_NPObject) { 200 if (m_NPObject) {
161 _NPN_ReleaseObject(m_NPObject); 201 _NPN_ReleaseObject(m_NPObject);
162 m_NPObject = 0; 202 m_NPObject = 0;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 SharedPersistent<v8::Object>* HTMLPlugInElement::pluginWrapper() 248 SharedPersistent<v8::Object>* HTMLPlugInElement::pluginWrapper()
209 { 249 {
210 Frame* frame = document().frame(); 250 Frame* frame = document().frame();
211 if (!frame) 251 if (!frame)
212 return 0; 252 return 0;
213 253
214 // If the host dynamically turns off JavaScript (or Java) we will still 254 // If the host dynamically turns off JavaScript (or Java) we will still
215 // return the cached allocated Bindings::Instance. Not supporting this 255 // return the cached allocated Bindings::Instance. Not supporting this
216 // edge-case is OK. 256 // edge-case is OK.
217 if (!m_pluginWrapper) { 257 if (!m_pluginWrapper) {
218 if (Widget* widget = pluginWidget()) 258 if (Widget* plugin = widget())
219 m_pluginWrapper = frame->script().createPluginWrapper(widget); 259 m_pluginWrapper = frame->script().createPluginWrapper(plugin);
220 } 260 }
221 return m_pluginWrapper.get(); 261 return m_pluginWrapper.get();
222 } 262 }
223 263
224 bool HTMLPlugInElement::dispatchBeforeLoadEvent(const String& sourceURL) 264 bool HTMLPlugInElement::dispatchBeforeLoadEvent(const String& sourceURL)
225 { 265 {
226 // FIXME: Our current plug-in loading design can't guarantee the following 266 // FIXME: Our current plug-in loading design can't guarantee the following
227 // assertion is true, since plug-in loading can be initiated during layout, 267 // assertion is true, since plug-in loading can be initiated during layout,
228 // and synchronous layout can be initiated in a beforeload event handler! 268 // and synchronous layout can be initiated in a beforeload event handler!
229 // See <http://webkit.org/b/71264>. 269 // See <http://webkit.org/b/71264>.
230 // ASSERT(!m_inBeforeLoadEventHandler); 270 // ASSERT(!m_inBeforeLoadEventHandler);
231 m_inBeforeLoadEventHandler = true; 271 m_inBeforeLoadEventHandler = true;
232 bool beforeLoadAllowedLoad = HTMLFrameOwnerElement::dispatchBeforeLoadEvent( sourceURL); 272 bool beforeLoadAllowedLoad = HTMLFrameOwnerElement::dispatchBeforeLoadEvent( sourceURL);
233 m_inBeforeLoadEventHandler = false; 273 m_inBeforeLoadEventHandler = false;
234 return beforeLoadAllowedLoad; 274 return beforeLoadAllowedLoad;
235 } 275 }
236 276
237 Widget* HTMLPlugInElement::pluginWidget() const
238 {
239 if (m_inBeforeLoadEventHandler) {
240 // The plug-in hasn't loaded yet, and it makes no sense to try to load
241 // if beforeload handler happened to touch the plug-in element. That
242 // would recursively call beforeload for the same element.
243 return 0;
244 }
245
246 if (RenderWidget* renderWidget = renderWidgetForJSBindings())
247 return renderWidget->widget();
248 return 0;
249 }
250
251 bool HTMLPlugInElement::isPresentationAttribute(const QualifiedName& name) const 277 bool HTMLPlugInElement::isPresentationAttribute(const QualifiedName& name) const
252 { 278 {
253 if (name == widthAttr || name == heightAttr || name == vspaceAttr || name == hspaceAttr || name == alignAttr) 279 if (name == widthAttr || name == heightAttr || name == vspaceAttr || name == hspaceAttr || name == alignAttr)
254 return true; 280 return true;
255 return HTMLFrameOwnerElement::isPresentationAttribute(name); 281 return HTMLFrameOwnerElement::isPresentationAttribute(name);
256 } 282 }
257 283
258 void HTMLPlugInElement::collectStyleForPresentationAttribute(const QualifiedName & name, const AtomicString& value, MutableStylePropertySet* style) 284 void HTMLPlugInElement::collectStyleForPresentationAttribute(const QualifiedName & name, const AtomicString& value, MutableStylePropertySet* style)
259 { 285 {
260 if (name == widthAttr) { 286 if (name == widthAttr) {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 // when JavaScript code accesses the plugin. 336 // when JavaScript code accesses the plugin.
311 // FIXME: Check if dispatching events here is safe. 337 // FIXME: Check if dispatching events here is safe.
312 document().updateLayoutIgnorePendingStylesheets(Document::RunPostLayoutTasks Synchronously); 338 document().updateLayoutIgnorePendingStylesheets(Document::RunPostLayoutTasks Synchronously);
313 return existingRenderWidget(); 339 return existingRenderWidget();
314 } 340 }
315 341
316 bool HTMLPlugInElement::isKeyboardFocusable() const 342 bool HTMLPlugInElement::isKeyboardFocusable() const
317 { 343 {
318 if (!document().page()) 344 if (!document().page())
319 return false; 345 return false;
320 return pluginWidget() && pluginWidget()->isPluginView() && toPluginView(plug inWidget())->supportsKeyboardFocus(); 346 return widget() && widget()->isPluginView() && toPluginView(widget())->suppo rtsKeyboardFocus();
321 } 347 }
322 348
323 bool HTMLPlugInElement::isPluginElement() const 349 bool HTMLPlugInElement::isPluginElement() const
324 { 350 {
325 return true; 351 return true;
326 } 352 }
327 353
328 bool HTMLPlugInElement::rendererIsFocusable() const 354 bool HTMLPlugInElement::rendererIsFocusable() const
329 { 355 {
330 if (HTMLFrameOwnerElement::supportsFocus() && HTMLFrameOwnerElement::rendere rIsFocusable()) 356 if (HTMLFrameOwnerElement::supportsFocus() && HTMLFrameOwnerElement::rendere rIsFocusable())
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
422 bool HTMLPlugInElement::loadPlugin(const KURL& url, const String& mimeType, cons t Vector<String>& paramNames, const Vector<String>& paramValues, bool useFallbac k) 448 bool HTMLPlugInElement::loadPlugin(const KURL& url, const String& mimeType, cons t Vector<String>& paramNames, const Vector<String>& paramValues, bool useFallbac k)
423 { 449 {
424 Frame* frame = document().frame(); 450 Frame* frame = document().frame();
425 451
426 if (!frame->loader().allowPlugins(AboutToInstantiatePlugin)) 452 if (!frame->loader().allowPlugins(AboutToInstantiatePlugin))
427 return false; 453 return false;
428 454
429 if (!pluginIsLoadable(url, mimeType)) 455 if (!pluginIsLoadable(url, mimeType))
430 return false; 456 return false;
431 457
458 bool canCreateWithoutRenderer = frame->loader().client()->canCreatePluginWit houtRenderer(mimeType);
459
432 RenderEmbeddedObject* renderer = renderEmbeddedObject(); 460 RenderEmbeddedObject* renderer = renderEmbeddedObject();
433 // FIXME: This code should not depend on renderer! 461 // FIXME: This code should not depend on renderer!
434 if (!renderer || useFallback) 462 if ((!renderer && !canCreateWithoutRenderer) || useFallback)
435 return false; 463 return false;
436 464
465 FrameLoaderClient::PluginLoadType loadType = renderer ? FrameLoaderClient::P luginLoadRequiresRenderer : FrameLoaderClient::PluginLoadWithoutRenderer;
466
437 LOG(Plugins, "%p Plug-in URL: %s", this, m_url.utf8().data()); 467 LOG(Plugins, "%p Plug-in URL: %s", this, m_url.utf8().data());
438 LOG(Plugins, " Loaded URL: %s", url.string().utf8().data()); 468 LOG(Plugins, " Loaded URL: %s", url.string().utf8().data());
439 m_loadedUrl = url; 469 m_loadedUrl = url;
440 470
441 IntSize contentSize = roundedIntSize(LayoutSize(renderer->contentWidth(), re nderer->contentHeight())); 471 IntSize contentSize;
442 bool loadManually = document().isPluginDocument() && !document().containsPlu gins() && toPluginDocument(document()).shouldLoadPluginManually(); 472 if (renderer)
443 RefPtr<Widget> widget = frame->loader().client()->createPlugin(contentSize, this, url, paramNames, paramValues, mimeType, loadManually); 473 contentSize = roundedIntSize(LayoutSize(renderer->contentWidth(), render er->contentHeight()));
474 RefPtr<Widget> plugin = widget();
444 475
445 if (!widget) { 476 if (!plugin) {
446 if (!renderer->showsUnavailablePluginIndicator()) 477 bool loadManually = document().isPluginDocument() && !document().contain sPlugins() && toPluginDocument(document()).shouldLoadPluginManually();
478 plugin = frame->loader().client()->createPlugin(contentSize, this, url, paramNames, paramValues, mimeType, loadManually, loadType);
479 }
480
481 if (!plugin) {
482 if (renderer && !renderer->showsUnavailablePluginIndicator())
447 renderer->setPluginUnavailabilityReason(RenderEmbeddedObject::Plugin Missing); 483 renderer->setPluginUnavailabilityReason(RenderEmbeddedObject::Plugin Missing);
448 return false; 484 return false;
449 } 485 }
450 486
451 renderer->setWidget(widget); 487 ASSERT(plugin->isPluginContainer());
488 setWidget(plugin);
489
490 if (renderer) {
491 // FIXME: We assume we don't layout without a renderer, but check this a ssumption.
eseidel 2013/12/02 16:28:34 style recalc creates/destroys renderers. I doubt
wjmaclean 2013/12/02 21:51:55 Thanks, that's useful to know. I'll remove the if(
492 setNeedsStyleRecalc(LocalStyleChange, StyleChangeFromRenderer);
493 }
452 document().setContainsPlugins(); 494 document().setContainsPlugins();
453 setNeedsStyleRecalc(LocalStyleChange, StyleChangeFromRenderer);
454 return true; 495 return true;
455 } 496 }
456 497
457 bool HTMLPlugInElement::shouldUsePlugin(const KURL& url, const String& mimeType, bool hasFallback, bool& useFallback) 498 bool HTMLPlugInElement::shouldUsePlugin(const KURL& url, const String& mimeType, bool hasFallback, bool& useFallback)
458 { 499 {
459 // Allow other plug-ins to win over QuickTime because if the user has 500 // Allow other plug-ins to win over QuickTime because if the user has
460 // installed a plug-in that can handle TIFF (which QuickTime can also 501 // installed a plug-in that can handle TIFF (which QuickTime can also
461 // handle) they probably intended to override QT. 502 // handle) they probably intended to override QT.
462 if (document().frame()->page() && (mimeType == "image/tiff" || mimeType == " image/tif" || mimeType == "image/x-tiff")) { 503 if (document().frame()->page() && (mimeType == "image/tiff" || mimeType == " image/tif" || mimeType == "image/x-tiff")) {
463 const PluginData* pluginData = document().frame()->page()->pluginData(); 504 const PluginData* pluginData = document().frame()->page()->pluginData();
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
498 if (!document().contentSecurityPolicy()->allowObjectFromSource(url) 539 if (!document().contentSecurityPolicy()->allowObjectFromSource(url)
499 || !document().contentSecurityPolicy()->allowPluginType(mimeType, declar edMimeType, url)) { 540 || !document().contentSecurityPolicy()->allowPluginType(mimeType, declar edMimeType, url)) {
500 renderEmbeddedObject()->setPluginUnavailabilityReason(RenderEmbeddedObje ct::PluginBlockedByContentSecurityPolicy); 541 renderEmbeddedObject()->setPluginUnavailabilityReason(RenderEmbeddedObje ct::PluginBlockedByContentSecurityPolicy);
501 return false; 542 return false;
502 } 543 }
503 544
504 return frame->loader().mixedContentChecker()->canRunInsecureContent(document ().securityOrigin(), url); 545 return frame->loader().mixedContentChecker()->canRunInsecureContent(document ().securityOrigin(), url);
505 } 546 }
506 547
507 } 548 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698