OLD | NEW |
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 13 matching lines...) Expand all Loading... |
24 #include "core/html/HTMLPlugInElement.h" | 24 #include "core/html/HTMLPlugInElement.h" |
25 | 25 |
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/Node.h" | 31 #include "core/dom/Node.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/FrameView.h" |
34 #include "core/frame/LocalFrame.h" | 35 #include "core/frame/LocalFrame.h" |
35 #include "core/frame/csp/ContentSecurityPolicy.h" | 36 #include "core/frame/csp/ContentSecurityPolicy.h" |
36 #include "core/html/HTMLContentElement.h" | 37 #include "core/html/HTMLContentElement.h" |
37 #include "core/html/HTMLImageLoader.h" | 38 #include "core/html/HTMLImageLoader.h" |
38 #include "core/html/PluginDocument.h" | 39 #include "core/html/PluginDocument.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" |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
109 m_imageLoader->elementDidMoveToNewDocument(); | 110 m_imageLoader->elementDidMoveToNewDocument(); |
110 HTMLFrameOwnerElement::didMoveToNewDocument(oldDocument); | 111 HTMLFrameOwnerElement::didMoveToNewDocument(oldDocument); |
111 } | 112 } |
112 | 113 |
113 void HTMLPlugInElement::attach(const AttachContext& context) | 114 void HTMLPlugInElement::attach(const AttachContext& context) |
114 { | 115 { |
115 HTMLFrameOwnerElement::attach(context); | 116 HTMLFrameOwnerElement::attach(context); |
116 | 117 |
117 if (!renderer() || useFallbackContent()) | 118 if (!renderer() || useFallbackContent()) |
118 return; | 119 return; |
| 120 |
119 if (isImageType()) { | 121 if (isImageType()) { |
120 if (!m_imageLoader) | 122 if (!m_imageLoader) |
121 m_imageLoader = adoptPtr(new HTMLImageLoader(this)); | 123 m_imageLoader = adoptPtr(new HTMLImageLoader(this)); |
122 m_imageLoader->updateFromElement(); | 124 m_imageLoader->updateFromElement(); |
123 } else if (needsWidgetUpdate() | 125 } else if (needsWidgetUpdate() |
124 && renderEmbeddedObject() | 126 && renderEmbeddedObject() |
125 && !renderEmbeddedObject()->showsUnavailablePluginIndicator() | 127 && !renderEmbeddedObject()->showsUnavailablePluginIndicator() |
126 && !wouldLoadAsNetscapePlugin(m_url, m_serviceType) | 128 && !wouldLoadAsNetscapePlugin(m_url, m_serviceType) |
127 && !m_isDelayingLoadEvent) { | 129 && !m_isDelayingLoadEvent) { |
128 m_isDelayingLoadEvent = true; | 130 m_isDelayingLoadEvent = true; |
129 document().incrementLoadEventDelayCount(); | 131 document().incrementLoadEventDelayCount(); |
130 document().loadPluginsSoon(); | 132 document().loadPluginsSoon(); |
131 } | 133 } |
132 } | 134 } |
133 | 135 |
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 // Only try to persist a plugin widget we actually own. |
| 187 Widget* plugin = ownedWidget(); |
| 188 if (plugin && plugin->pluginShouldPersist()) |
| 189 m_persistedPluginWidget = plugin; |
155 resetInstance(); | 190 resetInstance(); |
| 191 // FIXME - is this next line necessary? |
| 192 setWidget(nullptr); |
156 | 193 |
157 if (m_isCapturingMouseEvents) { | 194 if (m_isCapturingMouseEvents) { |
158 if (LocalFrame* frame = document().frame()) | 195 if (LocalFrame* frame = document().frame()) |
159 frame->eventHandler().setCapturingMouseEventsNode(nullptr); | 196 frame->eventHandler().setCapturingMouseEventsNode(nullptr); |
160 m_isCapturingMouseEvents = false; | 197 m_isCapturingMouseEvents = false; |
161 } | 198 } |
162 | 199 |
163 if (m_NPObject) { | 200 if (m_NPObject) { |
164 _NPN_ReleaseObject(m_NPObject); | 201 _NPN_ReleaseObject(m_NPObject); |
165 m_NPObject = 0; | 202 m_NPObject = 0; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
211 SharedPersistent<v8::Object>* HTMLPlugInElement::pluginWrapper() | 248 SharedPersistent<v8::Object>* HTMLPlugInElement::pluginWrapper() |
212 { | 249 { |
213 LocalFrame* frame = document().frame(); | 250 LocalFrame* frame = document().frame(); |
214 if (!frame) | 251 if (!frame) |
215 return 0; | 252 return 0; |
216 | 253 |
217 // 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 |
218 // return the cached allocated Bindings::Instance. Not supporting this | 255 // return the cached allocated Bindings::Instance. Not supporting this |
219 // edge-case is OK. | 256 // edge-case is OK. |
220 if (!m_pluginWrapper) { | 257 if (!m_pluginWrapper) { |
221 if (Widget* widget = pluginWidget()) | 258 Widget* plugin; |
222 m_pluginWrapper = frame->script().createPluginWrapper(widget); | 259 |
| 260 if (m_persistedPluginWidget) |
| 261 plugin = m_persistedPluginWidget.get(); |
| 262 else |
| 263 plugin = pluginWidget(); |
| 264 |
| 265 if (plugin) |
| 266 m_pluginWrapper = frame->script().createPluginWrapper(plugin); |
223 } | 267 } |
224 return m_pluginWrapper.get(); | 268 return m_pluginWrapper.get(); |
225 } | 269 } |
226 | 270 |
227 Widget* HTMLPlugInElement::pluginWidget() const | 271 Widget* HTMLPlugInElement::pluginWidget() const |
228 { | 272 { |
229 if (RenderWidget* renderWidget = renderWidgetForJSBindings()) | 273 if (RenderWidget* renderWidget = renderWidgetForJSBindings()) |
230 return renderWidget->widget(); | 274 return renderWidget->widget(); |
231 return 0; | 275 return 0; |
232 } | 276 } |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
392 RenderEmbeddedObject* renderer = renderEmbeddedObject(); | 436 RenderEmbeddedObject* renderer = renderEmbeddedObject(); |
393 ASSERT(renderer); | 437 ASSERT(renderer); |
394 if (!renderer) | 438 if (!renderer) |
395 return false; | 439 return false; |
396 | 440 |
397 KURL completedURL = document().completeURL(url); | 441 KURL completedURL = document().completeURL(url); |
398 if (!pluginIsLoadable(completedURL, mimeType)) | 442 if (!pluginIsLoadable(completedURL, mimeType)) |
399 return false; | 443 return false; |
400 | 444 |
401 bool useFallback; | 445 bool useFallback; |
| 446 bool requireRenderer = true; |
402 if (shouldUsePlugin(completedURL, mimeType, renderer->hasFallbackContent(),
useFallback)) | 447 if (shouldUsePlugin(completedURL, mimeType, renderer->hasFallbackContent(),
useFallback)) |
403 return loadPlugin(completedURL, mimeType, paramNames, paramValues, useFa
llback); | 448 return loadPlugin(completedURL, mimeType, paramNames, paramValues, useFa
llback, requireRenderer); |
404 | 449 |
405 // If the plug-in element already contains a subframe, | 450 // If the plug-in element already contains a subframe, |
406 // loadOrRedirectSubframe will re-use it. Otherwise, it will create a new | 451 // loadOrRedirectSubframe will re-use it. Otherwise, it will create a new |
407 // frame and set it as the RenderPart's widget, causing what was previously | 452 // frame and set it as the RenderPart's widget, causing what was previously |
408 // in the widget to be torn down. | 453 // in the widget to be torn down. |
409 return loadOrRedirectSubframe(completedURL, getNameAttribute(), true); | 454 return loadOrRedirectSubframe(completedURL, getNameAttribute(), true); |
410 } | 455 } |
411 | 456 |
412 bool HTMLPlugInElement::loadPlugin(const KURL& url, const String& mimeType, cons
t Vector<String>& paramNames, const Vector<String>& paramValues, bool useFallbac
k) | 457 bool HTMLPlugInElement::loadPlugin(const KURL& url, const String& mimeType, cons
t Vector<String>& paramNames, const Vector<String>& paramValues, bool useFallbac
k, bool requireRenderer) |
413 { | 458 { |
414 LocalFrame* frame = document().frame(); | 459 LocalFrame* frame = document().frame(); |
415 | 460 |
416 if (!frame->loader().allowPlugins(AboutToInstantiatePlugin)) | 461 if (!frame->loader().allowPlugins(AboutToInstantiatePlugin)) |
417 return false; | 462 return false; |
418 | 463 |
419 RenderEmbeddedObject* renderer = renderEmbeddedObject(); | 464 RenderEmbeddedObject* renderer = renderEmbeddedObject(); |
420 // FIXME: This code should not depend on renderer! | 465 // FIXME: This code should not depend on renderer! |
421 if (!renderer || useFallback) | 466 if ((!renderer && requireRenderer) || useFallback) |
422 return false; | 467 return false; |
423 | 468 |
424 WTF_LOG(Plugins, "%p Plug-in URL: %s", this, m_url.utf8().data()); | 469 WTF_LOG(Plugins, "%p Plug-in URL: %s", this, m_url.utf8().data()); |
425 WTF_LOG(Plugins, " Loaded URL: %s", url.string().utf8().data()); | 470 WTF_LOG(Plugins, " Loaded URL: %s", url.string().utf8().data()); |
426 m_loadedUrl = url; | 471 m_loadedUrl = url; |
427 | 472 |
428 bool loadManually = document().isPluginDocument() && !document().containsPlu
gins() && toPluginDocument(document()).shouldLoadPluginManually(); | 473 RefPtr<Widget> widget = m_persistedPluginWidget; |
429 RefPtr<Widget> widget = frame->loader().client()->createPlugin(this, url, pa
ramNames, paramValues, mimeType, loadManually, FrameLoaderClient::FailOnDetached
Plugin); | 474 if (!widget) { |
| 475 bool loadManually = document().isPluginDocument() && !document().contain
sPlugins() && toPluginDocument(document()).shouldLoadPluginManually(); |
| 476 FrameLoaderClient::DetachedPluginPolicy policy = requireRenderer ? Frame
LoaderClient::FailOnDetachedPlugin : FrameLoaderClient::AllowDetachedPlugin; |
| 477 widget = frame->loader().client()->createPlugin(this, url, paramNames, p
aramValues, mimeType, loadManually, policy); |
| 478 } |
430 | 479 |
431 if (!widget) { | 480 if (!widget) { |
432 if (!renderer->showsUnavailablePluginIndicator()) | 481 if (renderer && !renderer->showsUnavailablePluginIndicator()) |
433 renderer->setPluginUnavailabilityReason(RenderEmbeddedObject::Plugin
Missing); | 482 renderer->setPluginUnavailabilityReason(RenderEmbeddedObject::Plugin
Missing); |
434 return false; | 483 return false; |
435 } | 484 } |
436 | 485 |
437 renderer->setWidget(widget); | 486 if (renderer) { |
| 487 setWidget(widget); |
| 488 m_persistedPluginWidget = nullptr; |
| 489 } else if (widget != m_persistedPluginWidget) { |
| 490 m_persistedPluginWidget = widget; |
| 491 } |
438 document().setContainsPlugins(); | 492 document().setContainsPlugins(); |
439 scheduleLayerUpdate(); | 493 scheduleLayerUpdate(); |
440 return true; | 494 return true; |
441 } | 495 } |
442 | 496 |
443 bool HTMLPlugInElement::shouldUsePlugin(const KURL& url, const String& mimeType,
bool hasFallback, bool& useFallback) | 497 bool HTMLPlugInElement::shouldUsePlugin(const KURL& url, const String& mimeType,
bool hasFallback, bool& useFallback) |
444 { | 498 { |
445 // Allow other plug-ins to win over QuickTime because if the user has | 499 // Allow other plug-ins to win over QuickTime because if the user has |
446 // installed a plug-in that can handle TIFF (which QuickTime can also | 500 // installed a plug-in that can handle TIFF (which QuickTime can also |
447 // handle) they probably intended to override QT. | 501 // handle) they probably intended to override QT. |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
508 if (root.isOldestAuthorShadowRoot()) | 562 if (root.isOldestAuthorShadowRoot()) |
509 lazyReattachIfAttached(); | 563 lazyReattachIfAttached(); |
510 } | 564 } |
511 | 565 |
512 bool HTMLPlugInElement::useFallbackContent() const | 566 bool HTMLPlugInElement::useFallbackContent() const |
513 { | 567 { |
514 return hasAuthorShadowRoot(); | 568 return hasAuthorShadowRoot(); |
515 } | 569 } |
516 | 570 |
517 } | 571 } |
OLD | NEW |