| 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 15 matching lines...) Expand all Loading... |
| 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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 77 ASSERT(!m_isDelayingLoadEvent); | 78 ASSERT(!m_isDelayingLoadEvent); |
| 78 | 79 |
| 79 if (m_NPObject) { | 80 if (m_NPObject) { |
| 80 _NPN_ReleaseObject(m_NPObject); | 81 _NPN_ReleaseObject(m_NPObject); |
| 81 m_NPObject = 0; | 82 m_NPObject = 0; |
| 82 } | 83 } |
| 83 } | 84 } |
| 84 | 85 |
| 85 bool HTMLPlugInElement::canProcessDrag() const | 86 bool HTMLPlugInElement::canProcessDrag() const |
| 86 { | 87 { |
| 87 return pluginWidget() && pluginWidget()->isPluginView() && toPluginView(plug
inWidget())->canProcessDrag(); | 88 return widget() && widget()->isPluginView() && toPluginView(widget())->canPr
ocessDrag(); |
| 88 } | 89 } |
| 89 | 90 |
| 90 bool HTMLPlugInElement::willRespondToMouseClickEvents() | 91 bool HTMLPlugInElement::willRespondToMouseClickEvents() |
| 91 { | 92 { |
| 92 if (isDisabledFormControl()) | 93 if (isDisabledFormControl()) |
| 93 return false; | 94 return false; |
| 94 RenderObject* r = renderer(); | 95 RenderObject* r = renderer(); |
| 95 return r && (r->isEmbeddedObject() || r->isWidget()); | 96 return r && (r->isEmbeddedObject() || r->isWidget()); |
| 96 } | 97 } |
| 97 | 98 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 134 void HTMLPlugInElement::updateWidget() | 135 void HTMLPlugInElement::updateWidget() |
| 135 { | 136 { |
| 136 RefPtr<HTMLPlugInElement> protector(this); | 137 RefPtr<HTMLPlugInElement> protector(this); |
| 137 updateWidgetInternal(); | 138 updateWidgetInternal(); |
| 138 if (m_isDelayingLoadEvent) { | 139 if (m_isDelayingLoadEvent) { |
| 139 m_isDelayingLoadEvent = false; | 140 m_isDelayingLoadEvent = false; |
| 140 document().decrementLoadEventDelayCount(); | 141 document().decrementLoadEventDelayCount(); |
| 141 } | 142 } |
| 142 } | 143 } |
| 143 | 144 |
| 145 void HTMLPlugInElement::requestPluginCreationWithoutRendererIfPossible() |
| 146 { |
| 147 if (m_serviceType.isEmpty()) |
| 148 return; |
| 149 |
| 150 if (!document().frame()->loader().client()->canCreatePluginWithoutRenderer(m
_serviceType)) |
| 151 return; |
| 152 |
| 153 if (renderer() && renderer()->isWidget()) |
| 154 return; |
| 155 |
| 156 createPluginWithoutRenderer(); |
| 157 } |
| 158 |
| 159 void HTMLPlugInElement::createPluginWithoutRenderer() |
| 160 { |
| 161 ASSERT(document().frame()->loader().client()->canCreatePluginWithoutRenderer
(m_serviceType)); |
| 162 |
| 163 KURL url; |
| 164 Vector<String> paramNames; |
| 165 Vector<String> paramValues; |
| 166 |
| 167 paramNames.append("type"); |
| 168 paramValues.append(m_serviceType); |
| 169 |
| 170 bool useFallback = false; |
| 171 loadPlugin(url, m_serviceType, paramNames, paramValues, useFallback, false); |
| 172 } |
| 173 |
| 144 void HTMLPlugInElement::detach(const AttachContext& context) | 174 void HTMLPlugInElement::detach(const AttachContext& context) |
| 145 { | 175 { |
| 146 // Update the widget the next time we attach (detaching destroys the plugin)
. | 176 // Update the widget the next time we attach (detaching destroys the plugin)
. |
| 147 // FIXME: None of this "needsWidgetUpdate" related code looks right. | 177 // FIXME: None of this "needsWidgetUpdate" related code looks right. |
| 148 if (renderer() && !useFallbackContent()) | 178 if (renderer() && !useFallbackContent()) |
| 149 setNeedsWidgetUpdate(true); | 179 setNeedsWidgetUpdate(true); |
| 150 if (m_isDelayingLoadEvent) { | 180 if (m_isDelayingLoadEvent) { |
| 151 m_isDelayingLoadEvent = false; | 181 m_isDelayingLoadEvent = false; |
| 152 document().decrementLoadEventDelayCount(); | 182 document().decrementLoadEventDelayCount(); |
| 153 } | 183 } |
| 154 | 184 |
| 185 Widget* plugin = widget(); |
| 186 if (plugin && plugin->pluginShouldPersist()) |
| 187 m_persistedPluginWidget = plugin; |
| 155 resetInstance(); | 188 resetInstance(); |
| 189 setWidget(0); |
| 190 |
| 156 | 191 |
| 157 if (m_isCapturingMouseEvents) { | 192 if (m_isCapturingMouseEvents) { |
| 158 if (Frame* frame = document().frame()) | 193 if (Frame* frame = document().frame()) |
| 159 frame->eventHandler().setCapturingMouseEventsNode(0); | 194 frame->eventHandler().setCapturingMouseEventsNode(0); |
| 160 m_isCapturingMouseEvents = false; | 195 m_isCapturingMouseEvents = false; |
| 161 } | 196 } |
| 162 | 197 |
| 163 if (m_NPObject) { | 198 if (m_NPObject) { |
| 164 _NPN_ReleaseObject(m_NPObject); | 199 _NPN_ReleaseObject(m_NPObject); |
| 165 m_NPObject = 0; | 200 m_NPObject = 0; |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 211 SharedPersistent<v8::Object>* HTMLPlugInElement::pluginWrapper() | 246 SharedPersistent<v8::Object>* HTMLPlugInElement::pluginWrapper() |
| 212 { | 247 { |
| 213 Frame* frame = document().frame(); | 248 Frame* frame = document().frame(); |
| 214 if (!frame) | 249 if (!frame) |
| 215 return 0; | 250 return 0; |
| 216 | 251 |
| 217 // If the host dynamically turns off JavaScript (or Java) we will still | 252 // If the host dynamically turns off JavaScript (or Java) we will still |
| 218 // return the cached allocated Bindings::Instance. Not supporting this | 253 // return the cached allocated Bindings::Instance. Not supporting this |
| 219 // edge-case is OK. | 254 // edge-case is OK. |
| 220 if (!m_pluginWrapper) { | 255 if (!m_pluginWrapper) { |
| 221 if (Widget* widget = pluginWidget()) | 256 Widget* plugin = widget(); |
| 222 m_pluginWrapper = frame->script().createPluginWrapper(widget); | 257 if (!plugin && m_persistedPluginWidget) |
| 258 plugin = m_persistedPluginWidget.get(); |
| 259 if (!plugin && !m_inBeforeLoadEventHandler) { |
| 260 // If the plugin wasn't created without a renderer, then we can |
| 261 // trigger its creation here. Although widgets are no longer owned |
| 262 // by the renderWidget, the creation of the latter will still lead |
| 263 // to loadPlugin() being called. |
| 264 renderWidgetForJSBindings(); |
| 265 plugin = widget(); |
| 266 } |
| 267 if (plugin) |
| 268 m_pluginWrapper = frame->script().createPluginWrapper(plugin); |
| 223 } | 269 } |
| 224 return m_pluginWrapper.get(); | 270 return m_pluginWrapper.get(); |
| 225 } | 271 } |
| 226 | 272 |
| 227 bool HTMLPlugInElement::dispatchBeforeLoadEvent(const String& sourceURL) | 273 bool HTMLPlugInElement::dispatchBeforeLoadEvent(const String& sourceURL) |
| 228 { | 274 { |
| 229 // FIXME: Our current plug-in loading design can't guarantee the following | 275 // 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, | 276 // assertion is true, since plug-in loading can be initiated during layout, |
| 231 // and synchronous layout can be initiated in a beforeload event handler! | 277 // and synchronous layout can be initiated in a beforeload event handler! |
| 232 // See <http://webkit.org/b/71264>. | 278 // See <http://webkit.org/b/71264>. |
| 233 // ASSERT(!m_inBeforeLoadEventHandler); | 279 // ASSERT(!m_inBeforeLoadEventHandler); |
| 234 m_inBeforeLoadEventHandler = true; | 280 m_inBeforeLoadEventHandler = true; |
| 235 bool beforeLoadAllowedLoad = HTMLFrameOwnerElement::dispatchBeforeLoadEvent(
sourceURL); | 281 bool beforeLoadAllowedLoad = HTMLFrameOwnerElement::dispatchBeforeLoadEvent(
sourceURL); |
| 236 m_inBeforeLoadEventHandler = false; | 282 m_inBeforeLoadEventHandler = false; |
| 237 return beforeLoadAllowedLoad; | 283 return beforeLoadAllowedLoad; |
| 238 } | 284 } |
| 239 | 285 |
| 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 | 286 bool HTMLPlugInElement::isPresentationAttribute(const QualifiedName& name) const |
| 255 { | 287 { |
| 256 if (name == widthAttr || name == heightAttr || name == vspaceAttr || name ==
hspaceAttr || name == alignAttr) | 288 if (name == widthAttr || name == heightAttr || name == vspaceAttr || name ==
hspaceAttr || name == alignAttr) |
| 257 return true; | 289 return true; |
| 258 return HTMLFrameOwnerElement::isPresentationAttribute(name); | 290 return HTMLFrameOwnerElement::isPresentationAttribute(name); |
| 259 } | 291 } |
| 260 | 292 |
| 261 void HTMLPlugInElement::collectStyleForPresentationAttribute(const QualifiedName
& name, const AtomicString& value, MutableStylePropertySet* style) | 293 void HTMLPlugInElement::collectStyleForPresentationAttribute(const QualifiedName
& name, const AtomicString& value, MutableStylePropertySet* style) |
| 262 { | 294 { |
| 263 if (name == widthAttr) { | 295 if (name == widthAttr) { |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 313 // when JavaScript code accesses the plugin. | 345 // when JavaScript code accesses the plugin. |
| 314 // FIXME: Check if dispatching events here is safe. | 346 // FIXME: Check if dispatching events here is safe. |
| 315 document().updateLayoutIgnorePendingStylesheets(Document::RunPostLayoutTasks
Synchronously); | 347 document().updateLayoutIgnorePendingStylesheets(Document::RunPostLayoutTasks
Synchronously); |
| 316 return existingRenderWidget(); | 348 return existingRenderWidget(); |
| 317 } | 349 } |
| 318 | 350 |
| 319 bool HTMLPlugInElement::isKeyboardFocusable() const | 351 bool HTMLPlugInElement::isKeyboardFocusable() const |
| 320 { | 352 { |
| 321 if (!document().isActive()) | 353 if (!document().isActive()) |
| 322 return false; | 354 return false; |
| 323 return pluginWidget() && pluginWidget()->isPluginView() && toPluginView(plug
inWidget())->supportsKeyboardFocus(); | 355 return widget() && widget()->isPluginView() && toPluginView(widget())->suppo
rtsKeyboardFocus(); |
| 324 } | 356 } |
| 325 | 357 |
| 326 bool HTMLPlugInElement::isPluginElement() const | 358 bool HTMLPlugInElement::isPluginElement() const |
| 327 { | 359 { |
| 328 return true; | 360 return true; |
| 329 } | 361 } |
| 330 | 362 |
| 331 bool HTMLPlugInElement::rendererIsFocusable() const | 363 bool HTMLPlugInElement::rendererIsFocusable() const |
| 332 { | 364 { |
| 333 if (HTMLFrameOwnerElement::supportsFocus() && HTMLFrameOwnerElement::rendere
rIsFocusable()) | 365 if (HTMLFrameOwnerElement::supportsFocus() && HTMLFrameOwnerElement::rendere
rIsFocusable()) |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 405 | 437 |
| 406 // FIXME: None of this code should use renderers! | 438 // FIXME: None of this code should use renderers! |
| 407 RenderEmbeddedObject* renderer = renderEmbeddedObject(); | 439 RenderEmbeddedObject* renderer = renderEmbeddedObject(); |
| 408 ASSERT(renderer); | 440 ASSERT(renderer); |
| 409 if (!renderer) | 441 if (!renderer) |
| 410 return false; | 442 return false; |
| 411 | 443 |
| 412 KURL completedURL = document().completeURL(url); | 444 KURL completedURL = document().completeURL(url); |
| 413 | 445 |
| 414 bool useFallback; | 446 bool useFallback; |
| 447 bool requireRenderer = true; |
| 415 if (shouldUsePlugin(completedURL, mimeType, renderer->hasFallbackContent(),
useFallback)) | 448 if (shouldUsePlugin(completedURL, mimeType, renderer->hasFallbackContent(),
useFallback)) |
| 416 return loadPlugin(completedURL, mimeType, paramNames, paramValues, useFa
llback); | 449 return loadPlugin(completedURL, mimeType, paramNames, paramValues, useFa
llback, requireRenderer); |
| 417 | 450 |
| 418 // If the plug-in element already contains a subframe, | 451 // If the plug-in element already contains a subframe, |
| 419 // loadOrRedirectSubframe will re-use it. Otherwise, it will create a new | 452 // 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 | 453 // frame and set it as the RenderPart's widget, causing what was previously |
| 421 // in the widget to be torn down. | 454 // in the widget to be torn down. |
| 422 return loadOrRedirectSubframe(completedURL, getNameAttribute(), true); | 455 return loadOrRedirectSubframe(completedURL, getNameAttribute(), true); |
| 423 } | 456 } |
| 424 | 457 |
| 425 bool HTMLPlugInElement::loadPlugin(const KURL& url, const String& mimeType, cons
t Vector<String>& paramNames, const Vector<String>& paramValues, bool useFallbac
k) | 458 bool HTMLPlugInElement::loadPlugin(const KURL& url, const String& mimeType, cons
t Vector<String>& paramNames, const Vector<String>& paramValues, bool useFallbac
k, bool requireRenderer) |
| 426 { | 459 { |
| 427 Frame* frame = document().frame(); | 460 Frame* frame = document().frame(); |
| 428 | 461 |
| 429 if (!frame->loader().allowPlugins(AboutToInstantiatePlugin)) | 462 if (!frame->loader().allowPlugins(AboutToInstantiatePlugin)) |
| 430 return false; | 463 return false; |
| 431 | 464 |
| 432 if (!pluginIsLoadable(url, mimeType)) | 465 if (!pluginIsLoadable(url, mimeType)) |
| 433 return false; | 466 return false; |
| 434 | 467 |
| 435 RenderEmbeddedObject* renderer = renderEmbeddedObject(); | 468 RenderEmbeddedObject* renderer = renderEmbeddedObject(); |
| 436 // FIXME: This code should not depend on renderer! | 469 // FIXME: This code should not depend on renderer! |
| 437 if (!renderer || useFallback) | 470 if ((!renderer && requireRenderer) || useFallback) |
| 438 return false; | 471 return false; |
| 439 | 472 |
| 473 FrameLoaderClient::PluginLoadType loadType = renderer ? FrameLoaderClient::P
luginLoadRequiresRenderer : FrameLoaderClient::PluginLoadWithoutRenderer; |
| 474 |
| 440 WTF_LOG(Plugins, "%p Plug-in URL: %s", this, m_url.utf8().data()); | 475 WTF_LOG(Plugins, "%p Plug-in URL: %s", this, m_url.utf8().data()); |
| 441 WTF_LOG(Plugins, " Loaded URL: %s", url.string().utf8().data()); | 476 WTF_LOG(Plugins, " Loaded URL: %s", url.string().utf8().data()); |
| 477 |
| 442 m_loadedUrl = url; | 478 m_loadedUrl = url; |
| 443 | 479 |
| 444 IntSize contentSize = roundedIntSize(LayoutSize(renderer->contentWidth(), re
nderer->contentHeight())); | 480 IntSize contentSize; |
| 445 bool loadManually = document().isPluginDocument() && !document().containsPlu
gins() && toPluginDocument(document()).shouldLoadPluginManually(); | 481 if (renderer) |
| 446 RefPtr<Widget> widget = frame->loader().client()->createPlugin(contentSize,
this, url, paramNames, paramValues, mimeType, loadManually); | 482 contentSize = roundedIntSize(LayoutSize(renderer->contentWidth(), render
er->contentHeight())); |
| 483 RefPtr<Widget> plugin = m_persistedPluginWidget; |
| 447 | 484 |
| 448 if (!widget) { | 485 if (!plugin) { |
| 449 if (!renderer->showsUnavailablePluginIndicator()) | 486 bool loadManually = document().isPluginDocument() && !document().contain
sPlugins() && toPluginDocument(document()).shouldLoadPluginManually(); |
| 487 plugin = frame->loader().client()->createPlugin(contentSize, this, url,
paramNames, paramValues, mimeType, loadManually, loadType); |
| 488 } |
| 489 |
| 490 if (!plugin) { |
| 491 if (renderer && !renderer->showsUnavailablePluginIndicator()) |
| 450 renderer->setPluginUnavailabilityReason(RenderEmbeddedObject::Plugin
Missing); | 492 renderer->setPluginUnavailabilityReason(RenderEmbeddedObject::Plugin
Missing); |
| 451 return false; | 493 return false; |
| 452 } | 494 } |
| 453 | 495 |
| 454 renderer->setWidget(widget); | 496 ASSERT(plugin->isPluginContainer()); |
| 497 |
| 498 if (renderer) { |
| 499 setWidget(plugin); |
| 500 m_persistedPluginWidget = 0; |
| 501 } else { |
| 502 if (plugin != m_persistedPluginWidget) |
| 503 m_persistedPluginWidget = plugin; |
| 504 } |
| 455 document().setContainsPlugins(); | 505 document().setContainsPlugins(); |
| 456 setNeedsStyleRecalc(LocalStyleChange, StyleChangeFromRenderer); | |
| 457 return true; | 506 return true; |
| 458 } | 507 } |
| 459 | 508 |
| 460 bool HTMLPlugInElement::shouldUsePlugin(const KURL& url, const String& mimeType,
bool hasFallback, bool& useFallback) | 509 bool HTMLPlugInElement::shouldUsePlugin(const KURL& url, const String& mimeType,
bool hasFallback, bool& useFallback) |
| 461 { | 510 { |
| 462 // Allow other plug-ins to win over QuickTime because if the user has | 511 // 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 | 512 // installed a plug-in that can handle TIFF (which QuickTime can also |
| 464 // handle) they probably intended to override QT. | 513 // handle) they probably intended to override QT. |
| 465 if (document().frame()->page() && (mimeType == "image/tiff" || mimeType == "
image/tif" || mimeType == "image/x-tiff")) { | 514 if (document().frame()->page() && (mimeType == "image/tiff" || mimeType == "
image/tif" || mimeType == "image/x-tiff")) { |
| 466 const PluginData* pluginData = document().frame()->page()->pluginData(); | 515 const PluginData* pluginData = document().frame()->page()->pluginData(); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 517 if (root.isOldestAuthorShadowRoot()) | 566 if (root.isOldestAuthorShadowRoot()) |
| 518 lazyReattachIfAttached(); | 567 lazyReattachIfAttached(); |
| 519 } | 568 } |
| 520 | 569 |
| 521 bool HTMLPlugInElement::useFallbackContent() const | 570 bool HTMLPlugInElement::useFallbackContent() const |
| 522 { | 571 { |
| 523 return hasAuthorShadowRoot(); | 572 return hasAuthorShadowRoot(); |
| 524 } | 573 } |
| 525 | 574 |
| 526 } | 575 } |
| OLD | NEW |