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

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: Fix mac compile issue. 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 15 matching lines...) Expand all
26 #include "CSSPropertyNames.h" 26 #include "CSSPropertyNames.h"
27 #include "HTMLNames.h" 27 #include "HTMLNames.h"
28 #include "bindings/v8/ScriptController.h" 28 #include "bindings/v8/ScriptController.h"
29 #include "bindings/v8/npruntime_impl.h" 29 #include "bindings/v8/npruntime_impl.h"
30 #include "core/dom/Document.h" 30 #include "core/dom/Document.h"
31 #include "core/dom/PostAttachCallbacks.h" 31 #include "core/dom/PostAttachCallbacks.h"
32 #include "core/dom/shadow/ShadowRoot.h" 32 #include "core/dom/shadow/ShadowRoot.h"
33 #include "core/events/Event.h" 33 #include "core/events/Event.h"
34 #include "core/frame/ContentSecurityPolicy.h" 34 #include "core/frame/ContentSecurityPolicy.h"
35 #include "core/frame/Frame.h" 35 #include "core/frame/Frame.h"
36 #include "core/frame/FrameView.h"
36 #include "core/html/HTMLImageLoader.h" 37 #include "core/html/HTMLImageLoader.h"
37 #include "core/html/PluginDocument.h" 38 #include "core/html/PluginDocument.h"
38 #include "core/html/shadow/HTMLContentElement.h" 39 #include "core/html/shadow/HTMLContentElement.h"
39 #include "core/loader/FrameLoaderClient.h" 40 #include "core/loader/FrameLoaderClient.h"
40 #include "core/page/EventHandler.h" 41 #include "core/page/EventHandler.h"
41 #include "core/page/Page.h" 42 #include "core/page/Page.h"
42 #include "core/frame/Settings.h" 43 #include "core/frame/Settings.h"
43 #include "core/plugins/PluginView.h" 44 #include "core/plugins/PluginView.h"
44 #include "core/rendering/RenderEmbeddedObject.h" 45 #include "core/rendering/RenderEmbeddedObject.h"
45 #include "core/rendering/RenderImage.h" 46 #include "core/rendering/RenderImage.h"
(...skipping 14 matching lines...) Expand all
60 , m_NPObject(0) 61 , m_NPObject(0)
61 , m_isCapturingMouseEvents(false) 62 , m_isCapturingMouseEvents(false)
62 , m_inBeforeLoadEventHandler(false) 63 , m_inBeforeLoadEventHandler(false)
63 // m_needsWidgetUpdate(!createdByParser) allows HTMLObjectElement to delay 64 // m_needsWidgetUpdate(!createdByParser) allows HTMLObjectElement to delay
64 // widget updates until after all children are parsed. For HTMLEmbedElement 65 // widget updates until after all children are parsed. For HTMLEmbedElement
65 // this delay is unnecessary, but it is simpler to make both classes share 66 // this delay is unnecessary, but it is simpler to make both classes share
66 // the same codepath in this class. 67 // the same codepath in this class.
67 , m_needsWidgetUpdate(!createdByParser) 68 , m_needsWidgetUpdate(!createdByParser)
68 , m_shouldPreferPlugInsForImages(preferPlugInsForImagesOption == ShouldPrefe rPlugInsForImages) 69 , m_shouldPreferPlugInsForImages(preferPlugInsForImagesOption == ShouldPrefe rPlugInsForImages)
69 , m_displayState(Playing) 70 , m_displayState(Playing)
71 , m_persistedPluginWidget(0)
eseidel 2013/12/18 18:38:18 nit: RefPtr's default construtor sets to 0, no nee
wjmaclean 2013/12/23 23:49:53 Done.
70 { 72 {
71 setHasCustomStyleCallbacks(); 73 setHasCustomStyleCallbacks();
72 } 74 }
73 75
74 HTMLPlugInElement::~HTMLPlugInElement() 76 HTMLPlugInElement::~HTMLPlugInElement()
75 { 77 {
76 ASSERT(!m_pluginWrapper); // cleared in detach() 78 ASSERT(!m_pluginWrapper); // cleared in detach()
77 ASSERT(!m_isDelayingLoadEvent); 79 ASSERT(!m_isDelayingLoadEvent);
78 80
79 if (m_NPObject) { 81 if (m_NPObject) {
80 _NPN_ReleaseObject(m_NPObject); 82 _NPN_ReleaseObject(m_NPObject);
81 m_NPObject = 0; 83 m_NPObject = 0;
82 } 84 }
83 } 85 }
84 86
85 bool HTMLPlugInElement::canProcessDrag() const 87 bool HTMLPlugInElement::canProcessDrag() const
86 { 88 {
87 return pluginWidget() && pluginWidget()->isPluginView() && toPluginView(plug inWidget())->canProcessDrag(); 89 return widget() && widget()->isPluginView() && toPluginView(widget())->canPr ocessDrag();
88 } 90 }
89 91
90 bool HTMLPlugInElement::willRespondToMouseClickEvents() 92 bool HTMLPlugInElement::willRespondToMouseClickEvents()
91 { 93 {
92 if (isDisabledFormControl()) 94 if (isDisabledFormControl())
93 return false; 95 return false;
94 RenderObject* r = renderer(); 96 RenderObject* r = renderer();
95 return r && (r->isEmbeddedObject() || r->isWidget()); 97 return r && (r->isEmbeddedObject() || r->isWidget());
96 } 98 }
97 99
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 void HTMLPlugInElement::updateWidget() 136 void HTMLPlugInElement::updateWidget()
135 { 137 {
136 RefPtr<HTMLPlugInElement> protector(this); 138 RefPtr<HTMLPlugInElement> protector(this);
137 updateWidgetInternal(); 139 updateWidgetInternal();
138 if (m_isDelayingLoadEvent) { 140 if (m_isDelayingLoadEvent) {
139 m_isDelayingLoadEvent = false; 141 m_isDelayingLoadEvent = false;
140 document().decrementLoadEventDelayCount(); 142 document().decrementLoadEventDelayCount();
141 } 143 }
142 } 144 }
143 145
146 void HTMLPlugInElement::requestPluginCreationWithoutRendererIfPossible()
147 {
148 if (m_serviceType.isEmpty())
149 return;
150
151 if (!document().frame()->loader().client()->canCreatePluginWithoutRenderer(m _serviceType))
152 return;
153
154 if (renderer() && renderer()->isWidget())
155 return;
156
157 createPluginWithoutRenderer();
158 }
159
160 void HTMLPlugInElement::createPluginWithoutRenderer()
161 {
162 ASSERT(document().frame()->loader().client()->canCreatePluginWithoutRenderer (m_serviceType));
163
164 KURL url;
165 Vector<String> paramNames;
166 Vector<String> paramValues;
167
168 paramNames.append("type");
169 paramValues.append(m_serviceType);
170
171 bool useFallback = false;
172 loadPlugin(url, m_serviceType, paramNames, paramValues, useFallback, false);
173 }
174
144 void HTMLPlugInElement::detach(const AttachContext& context) 175 void HTMLPlugInElement::detach(const AttachContext& context)
145 { 176 {
146 // Update the widget the next time we attach (detaching destroys the plugin) . 177 // Update the widget the next time we attach (detaching destroys the plugin) .
147 // FIXME: None of this "needsWidgetUpdate" related code looks right. 178 // FIXME: None of this "needsWidgetUpdate" related code looks right.
148 if (renderer() && !useFallbackContent()) 179 if (renderer() && !useFallbackContent())
149 setNeedsWidgetUpdate(true); 180 setNeedsWidgetUpdate(true);
150 if (m_isDelayingLoadEvent) { 181 if (m_isDelayingLoadEvent) {
151 m_isDelayingLoadEvent = false; 182 m_isDelayingLoadEvent = false;
152 document().decrementLoadEventDelayCount(); 183 document().decrementLoadEventDelayCount();
153 } 184 }
154 185
186 Widget* plugin = widget();
187 if (plugin && plugin->pluginShouldPersist())
188 m_persistedPluginWidget = plugin;
155 resetInstance(); 189 resetInstance();
190 setWidget(0);
191
156 192
157 if (m_isCapturingMouseEvents) { 193 if (m_isCapturingMouseEvents) {
158 if (Frame* frame = document().frame()) 194 if (Frame* frame = document().frame())
159 frame->eventHandler().setCapturingMouseEventsNode(0); 195 frame->eventHandler().setCapturingMouseEventsNode(0);
160 m_isCapturingMouseEvents = false; 196 m_isCapturingMouseEvents = false;
161 } 197 }
162 198
163 if (m_NPObject) { 199 if (m_NPObject) {
164 _NPN_ReleaseObject(m_NPObject); 200 _NPN_ReleaseObject(m_NPObject);
165 m_NPObject = 0; 201 m_NPObject = 0;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 SharedPersistent<v8::Object>* HTMLPlugInElement::pluginWrapper() 247 SharedPersistent<v8::Object>* HTMLPlugInElement::pluginWrapper()
212 { 248 {
213 Frame* frame = document().frame(); 249 Frame* frame = document().frame();
214 if (!frame) 250 if (!frame)
215 return 0; 251 return 0;
216 252
217 // If the host dynamically turns off JavaScript (or Java) we will still 253 // If the host dynamically turns off JavaScript (or Java) we will still
218 // return the cached allocated Bindings::Instance. Not supporting this 254 // return the cached allocated Bindings::Instance. Not supporting this
219 // edge-case is OK. 255 // edge-case is OK.
220 if (!m_pluginWrapper) { 256 if (!m_pluginWrapper) {
221 if (Widget* widget = pluginWidget()) 257 Widget* plugin = widget();
222 m_pluginWrapper = frame->script().createPluginWrapper(widget); 258 if (!plugin && m_persistedPluginWidget)
259 plugin = m_persistedPluginWidget.get();
260 if (!plugin && !m_inBeforeLoadEventHandler) {
261 // If the plugin wasn't created without a renderer, then we can
262 // trigger its creation here. Although widgets are no longer owned
263 // by the renderWidget, the creation of the latter will still lead
264 // to loadPlugin() being called.
265 renderWidgetForJSBindings();
266 plugin = widget();
267 }
268 if (plugin)
269 m_pluginWrapper = frame->script().createPluginWrapper(plugin);
223 } 270 }
224 return m_pluginWrapper.get(); 271 return m_pluginWrapper.get();
225 } 272 }
226 273
227 bool HTMLPlugInElement::dispatchBeforeLoadEvent(const String& sourceURL) 274 bool HTMLPlugInElement::dispatchBeforeLoadEvent(const String& sourceURL)
228 { 275 {
229 // FIXME: Our current plug-in loading design can't guarantee the following 276 // FIXME: Our current plug-in loading design can't guarantee the following
230 // assertion is true, since plug-in loading can be initiated during layout, 277 // assertion is true, since plug-in loading can be initiated during layout,
231 // and synchronous layout can be initiated in a beforeload event handler! 278 // and synchronous layout can be initiated in a beforeload event handler!
232 // See <http://webkit.org/b/71264>. 279 // See <http://webkit.org/b/71264>.
233 // ASSERT(!m_inBeforeLoadEventHandler); 280 // ASSERT(!m_inBeforeLoadEventHandler);
234 m_inBeforeLoadEventHandler = true; 281 m_inBeforeLoadEventHandler = true;
235 bool beforeLoadAllowedLoad = HTMLFrameOwnerElement::dispatchBeforeLoadEvent( sourceURL); 282 bool beforeLoadAllowedLoad = HTMLFrameOwnerElement::dispatchBeforeLoadEvent( sourceURL);
236 m_inBeforeLoadEventHandler = false; 283 m_inBeforeLoadEventHandler = false;
237 return beforeLoadAllowedLoad; 284 return beforeLoadAllowedLoad;
238 } 285 }
239 286
240 Widget* HTMLPlugInElement::pluginWidget() const
241 {
242 if (m_inBeforeLoadEventHandler) {
243 // The plug-in hasn't loaded yet, and it makes no sense to try to load
244 // if beforeload handler happened to touch the plug-in element. That
245 // would recursively call beforeload for the same element.
246 return 0;
247 }
248
249 if (RenderWidget* renderWidget = renderWidgetForJSBindings())
250 return renderWidget->widget();
251 return 0;
252 }
253
254 bool HTMLPlugInElement::isPresentationAttribute(const QualifiedName& name) const 287 bool HTMLPlugInElement::isPresentationAttribute(const QualifiedName& name) const
255 { 288 {
256 if (name == widthAttr || name == heightAttr || name == vspaceAttr || name == hspaceAttr || name == alignAttr) 289 if (name == widthAttr || name == heightAttr || name == vspaceAttr || name == hspaceAttr || name == alignAttr)
257 return true; 290 return true;
258 return HTMLFrameOwnerElement::isPresentationAttribute(name); 291 return HTMLFrameOwnerElement::isPresentationAttribute(name);
259 } 292 }
260 293
261 void HTMLPlugInElement::collectStyleForPresentationAttribute(const QualifiedName & name, const AtomicString& value, MutableStylePropertySet* style) 294 void HTMLPlugInElement::collectStyleForPresentationAttribute(const QualifiedName & name, const AtomicString& value, MutableStylePropertySet* style)
262 { 295 {
263 if (name == widthAttr) { 296 if (name == widthAttr) {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
313 // when JavaScript code accesses the plugin. 346 // when JavaScript code accesses the plugin.
314 // FIXME: Check if dispatching events here is safe. 347 // FIXME: Check if dispatching events here is safe.
315 document().updateLayoutIgnorePendingStylesheets(Document::RunPostLayoutTasks Synchronously); 348 document().updateLayoutIgnorePendingStylesheets(Document::RunPostLayoutTasks Synchronously);
316 return existingRenderWidget(); 349 return existingRenderWidget();
317 } 350 }
318 351
319 bool HTMLPlugInElement::isKeyboardFocusable() const 352 bool HTMLPlugInElement::isKeyboardFocusable() const
320 { 353 {
321 if (!document().isActive()) 354 if (!document().isActive())
322 return false; 355 return false;
323 return pluginWidget() && pluginWidget()->isPluginView() && toPluginView(plug inWidget())->supportsKeyboardFocus(); 356 return widget() && widget()->isPluginView() && toPluginView(widget())->suppo rtsKeyboardFocus();
324 } 357 }
325 358
326 bool HTMLPlugInElement::isPluginElement() const 359 bool HTMLPlugInElement::isPluginElement() const
327 { 360 {
328 return true; 361 return true;
329 } 362 }
330 363
331 bool HTMLPlugInElement::rendererIsFocusable() const 364 bool HTMLPlugInElement::rendererIsFocusable() const
332 { 365 {
333 if (HTMLFrameOwnerElement::supportsFocus() && HTMLFrameOwnerElement::rendere rIsFocusable()) 366 if (HTMLFrameOwnerElement::supportsFocus() && HTMLFrameOwnerElement::rendere rIsFocusable())
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
405 438
406 // FIXME: None of this code should use renderers! 439 // FIXME: None of this code should use renderers!
407 RenderEmbeddedObject* renderer = renderEmbeddedObject(); 440 RenderEmbeddedObject* renderer = renderEmbeddedObject();
408 ASSERT(renderer); 441 ASSERT(renderer);
409 if (!renderer) 442 if (!renderer)
410 return false; 443 return false;
411 444
412 KURL completedURL = document().completeURL(url); 445 KURL completedURL = document().completeURL(url);
413 446
414 bool useFallback; 447 bool useFallback;
448 bool requireRenderer = true;
415 if (shouldUsePlugin(completedURL, mimeType, renderer->hasFallbackContent(), useFallback)) 449 if (shouldUsePlugin(completedURL, mimeType, renderer->hasFallbackContent(), useFallback))
416 return loadPlugin(completedURL, mimeType, paramNames, paramValues, useFa llback); 450 return loadPlugin(completedURL, mimeType, paramNames, paramValues, useFa llback, requireRenderer);
417 451
418 // If the plug-in element already contains a subframe, 452 // If the plug-in element already contains a subframe,
419 // loadOrRedirectSubframe will re-use it. Otherwise, it will create a new 453 // loadOrRedirectSubframe will re-use it. Otherwise, it will create a new
420 // frame and set it as the RenderPart's widget, causing what was previously 454 // frame and set it as the RenderPart's widget, causing what was previously
421 // in the widget to be torn down. 455 // in the widget to be torn down.
422 return loadOrRedirectSubframe(completedURL, getNameAttribute(), true); 456 return loadOrRedirectSubframe(completedURL, getNameAttribute(), true);
423 } 457 }
424 458
425 bool HTMLPlugInElement::loadPlugin(const KURL& url, const String& mimeType, cons t Vector<String>& paramNames, const Vector<String>& paramValues, bool useFallbac k) 459 bool HTMLPlugInElement::loadPlugin(const KURL& url, const String& mimeType, cons t Vector<String>& paramNames, const Vector<String>& paramValues, bool useFallbac k, bool requireRenderer)
426 { 460 {
427 Frame* frame = document().frame(); 461 Frame* frame = document().frame();
428 462
429 if (!frame->loader().allowPlugins(AboutToInstantiatePlugin)) 463 if (!frame->loader().allowPlugins(AboutToInstantiatePlugin))
430 return false; 464 return false;
431 465
432 if (!pluginIsLoadable(url, mimeType)) 466 if (!pluginIsLoadable(url, mimeType))
433 return false; 467 return false;
434 468
435 RenderEmbeddedObject* renderer = renderEmbeddedObject(); 469 RenderEmbeddedObject* renderer = renderEmbeddedObject();
436 // FIXME: This code should not depend on renderer! 470 // FIXME: This code should not depend on renderer!
437 if (!renderer || useFallback) 471 if ((!renderer && requireRenderer) || useFallback)
438 return false; 472 return false;
439 473
474 FrameLoaderClient::PluginLoadType loadType = renderer ? FrameLoaderClient::P luginLoadRequiresRenderer : FrameLoaderClient::PluginLoadWithoutRenderer;
475
440 WTF_LOG(Plugins, "%p Plug-in URL: %s", this, m_url.utf8().data()); 476 WTF_LOG(Plugins, "%p Plug-in URL: %s", this, m_url.utf8().data());
441 WTF_LOG(Plugins, " Loaded URL: %s", url.string().utf8().data()); 477 WTF_LOG(Plugins, " Loaded URL: %s", url.string().utf8().data());
478
442 m_loadedUrl = url; 479 m_loadedUrl = url;
443 480
444 IntSize contentSize = roundedIntSize(LayoutSize(renderer->contentWidth(), re nderer->contentHeight())); 481 IntSize contentSize;
445 bool loadManually = document().isPluginDocument() && !document().containsPlu gins() && toPluginDocument(document()).shouldLoadPluginManually(); 482 if (renderer)
446 RefPtr<Widget> widget = frame->loader().client()->createPlugin(contentSize, this, url, paramNames, paramValues, mimeType, loadManually); 483 contentSize = roundedIntSize(LayoutSize(renderer->contentWidth(), render er->contentHeight()));
484 RefPtr<Widget> plugin = m_persistedPluginWidget;
447 485
448 if (!widget) { 486 if (!plugin) {
449 if (!renderer->showsUnavailablePluginIndicator()) 487 bool loadManually = document().isPluginDocument() && !document().contain sPlugins() && toPluginDocument(document()).shouldLoadPluginManually();
488 plugin = frame->loader().client()->createPlugin(contentSize, this, url, paramNames, paramValues, mimeType, loadManually, loadType);
489 }
490
491 if (!plugin) {
492 if (renderer && !renderer->showsUnavailablePluginIndicator())
450 renderer->setPluginUnavailabilityReason(RenderEmbeddedObject::Plugin Missing); 493 renderer->setPluginUnavailabilityReason(RenderEmbeddedObject::Plugin Missing);
451 return false; 494 return false;
452 } 495 }
453 496
454 renderer->setWidget(widget); 497 ASSERT(plugin->isPluginContainer());
498
499 if (renderer) {
500 // FIXME: We assume we don't layout without a renderer, but check this a ssumption.
eseidel 2013/12/18 18:38:18 I'm not sure I understand this comment.
wjmaclean 2013/12/23 23:49:53 This was just a reminder to myself ... removed.
501 setWidget(plugin);
502 m_persistedPluginWidget = 0;
503 } else {
504 if (plugin != m_persistedPluginWidget)
505 m_persistedPluginWidget = plugin;
506 }
507 // FIXME: it may be that nothing has change (we might be continuing to
eseidel 2013/12/18 18:38:18 No, the recalc style is only needed to trigger ren
wjmaclean 2013/12/23 23:49:53 recalc style removed.
508 // persist the same plugin? In that case, would we need to recalc style?
509 setNeedsStyleRecalc(LocalStyleChange, StyleChangeFromRenderer);
455 document().setContainsPlugins(); 510 document().setContainsPlugins();
456 setNeedsStyleRecalc(LocalStyleChange, StyleChangeFromRenderer);
457 return true; 511 return true;
458 } 512 }
459 513
460 bool HTMLPlugInElement::shouldUsePlugin(const KURL& url, const String& mimeType, bool hasFallback, bool& useFallback) 514 bool HTMLPlugInElement::shouldUsePlugin(const KURL& url, const String& mimeType, bool hasFallback, bool& useFallback)
461 { 515 {
462 // Allow other plug-ins to win over QuickTime because if the user has 516 // Allow other plug-ins to win over QuickTime because if the user has
463 // installed a plug-in that can handle TIFF (which QuickTime can also 517 // installed a plug-in that can handle TIFF (which QuickTime can also
464 // handle) they probably intended to override QT. 518 // handle) they probably intended to override QT.
465 if (document().frame()->page() && (mimeType == "image/tiff" || mimeType == " image/tif" || mimeType == "image/x-tiff")) { 519 if (document().frame()->page() && (mimeType == "image/tiff" || mimeType == " image/tif" || mimeType == "image/x-tiff")) {
466 const PluginData* pluginData = document().frame()->page()->pluginData(); 520 const PluginData* pluginData = document().frame()->page()->pluginData();
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
517 if (root.isOldestAuthorShadowRoot()) 571 if (root.isOldestAuthorShadowRoot())
518 lazyReattachIfAttached(); 572 lazyReattachIfAttached();
519 } 573 }
520 574
521 bool HTMLPlugInElement::useFallbackContent() const 575 bool HTMLPlugInElement::useFallbackContent() const
522 { 576 {
523 return hasAuthorShadowRoot(); 577 return hasAuthorShadowRoot();
524 } 578 }
525 579
526 } 580 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698