diff --git a/browser/base/content/browser-plugins.js b/browser/base/content/browser-plugins.js index 675f3c5d759..80c7b928ca4 100644 --- a/browser/base/content/browser-plugins.js +++ b/browser/base/content/browser-plugins.js @@ -150,6 +150,10 @@ var gPluginHandler = { self._handleClickToPlayEvent(plugin); break; + case "PluginPlayPreview": + self._handlePlayPreviewEvent(plugin); + break; + case "PluginDisabled": let manageLink = doc.getAnonymousElementByAttribute(plugin, "class", "managePluginsLink"); self.addLinkClickCallback(manageLink, "managePlugins"); @@ -165,6 +169,11 @@ var gPluginHandler = { } }, + canActivatePlugin: function PH_canActivatePlugin(objLoadingContent) { + return !objLoadingContent.activated && + objLoadingContent.pluginFallbackType !== Ci.nsIObjectLoadingContent.PLUGIN_PLAY_PREVIEW; + }, + activatePlugins: function PH_activatePlugins(aContentWindow) { let browser = gBrowser.getBrowserForDocument(aContentWindow.document); browser._clickToPlayPluginsActivated = true; @@ -173,7 +182,7 @@ var gPluginHandler = { let plugins = cwu.plugins; for (let plugin of plugins) { let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - if (!objLoadingContent.activated) + if (gPluginHandler.canActivatePlugin(objLoadingContent)) objLoadingContent.playPlugin(); } let notification = PopupNotifications.getNotification("click-to-play-plugins", browser); @@ -183,14 +192,14 @@ var gPluginHandler = { activateSinglePlugin: function PH_activateSinglePlugin(aContentWindow, aPlugin) { let objLoadingContent = aPlugin.QueryInterface(Ci.nsIObjectLoadingContent); - if (!objLoadingContent.activated) + if (gPluginHandler.canActivatePlugin(objLoadingContent)) objLoadingContent.playPlugin(); let cwu = aContentWindow.QueryInterface(Ci.nsIInterfaceRequestor) .getInterface(Ci.nsIDOMWindowUtils); let haveUnplayedPlugins = cwu.plugins.some(function(plugin) { let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - return (plugin != aPlugin && !objLoadingContent.activated); + return (plugin != aPlugin && gPluginHandler.canActivatePlugin(objLoadingContent)); }); let browser = gBrowser.getBrowserForDocument(aContentWindow.document); let notification = PopupNotifications.getNotification("click-to-play-plugins", browser); @@ -200,6 +209,17 @@ var gPluginHandler = { } }, + stopPlayPreview: function PH_stopPlayPreview(aPlugin, aPlayPlugin) { + let objLoadingContent = aPlugin.QueryInterface(Ci.nsIObjectLoadingContent); + if (objLoadingContent.activated) + return; + + if (aPlayPlugin) + objLoadingContent.playPlugin(); + else + objLoadingContent.cancelPlayPreview(); + }, + newPluginInstalled : function(event) { // browser elements are anonymous so we can't just use target. var browser = event.originalTarget; @@ -290,6 +310,46 @@ var gPluginHandler = { gPluginHandler._showClickToPlayNotification(browser); }, + _handlePlayPreviewEvent: function PH_handlePlayPreviewEvent(aPlugin) { + let doc = aPlugin.ownerDocument; + let previewContent = doc.getAnonymousElementByAttribute(aPlugin, "class", "previewPluginContent"); + if (!previewContent) { + // the XBL binding is not attached (element is display:none), fallback to click-to-play logic + gPluginHandler.stopPlayPreview(aPlugin, false); + return; + } + let iframe = previewContent.getElementsByClassName("previewPluginContentFrame")[0]; + if (!iframe) { + // lazy initialization of the iframe + iframe = doc.createElementNS("http://www.w3.org/1999/xhtml", "iframe"); + iframe.className = "previewPluginContentFrame"; + previewContent.appendChild(iframe); + + // Force a style flush, so that we ensure our binding is attached. + aPlugin.clientTop; + } + let pluginInfo = getPluginInfo(aPlugin); + let playPreviewUri = "data:application/x-moz-playpreview;," + pluginInfo.mimetype; + iframe.src = playPreviewUri; + + // MozPlayPlugin event can be dispatched from the extension chrome + // code to replace the preview content with the native plugin + previewContent.addEventListener("MozPlayPlugin", function playPluginHandler(aEvent) { + if (!aEvent.isTrusted) + return; + + previewContent.removeEventListener("MozPlayPlugin", playPluginHandler, true); + + let playPlugin = !aEvent.detail; + gPluginHandler.stopPlayPreview(aPlugin, playPlugin); + + // cleaning up: removes overlay iframe from the DOM + let iframe = previewContent.getElementsByClassName("previewPluginContentFrame")[0]; + if (iframe) + previewContent.removeChild(iframe); + }, true); + }, + reshowClickToPlayNotification: function PH_reshowClickToPlayNotification() { if (!Services.prefs.getBoolPref("plugins.click_to_play")) return; diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index f14f649baa9..f8c8d16a9d0 100644 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -1020,6 +1020,7 @@ var gBrowserInit = { gBrowser.addEventListener("PluginOutdated", gPluginHandler, true); gBrowser.addEventListener("PluginDisabled", gPluginHandler, true); gBrowser.addEventListener("PluginClickToPlay", gPluginHandler, true); + gBrowser.addEventListener("PluginPlayPreview", gPluginHandler, true); gBrowser.addEventListener("PluginVulnerableUpdatable", gPluginHandler, true); gBrowser.addEventListener("PluginVulnerableNoUpdate", gPluginHandler, true); gBrowser.addEventListener("NewPluginInstalled", gPluginHandler.newPluginInstalled, true); diff --git a/content/base/public/nsIObjectLoadingContent.idl b/content/base/public/nsIObjectLoadingContent.idl index 9d60efec9b2..600662ced1e 100644 --- a/content/base/public/nsIObjectLoadingContent.idl +++ b/content/base/public/nsIObjectLoadingContent.idl @@ -21,7 +21,7 @@ interface nsIURI; * This interface represents a content node that loads objects. */ -[scriptable, uuid(8ed953b4-5022-4a49-bed4-6818f85dc113)] +[scriptable, uuid(a812424b-4820-4e28-96c8-dd2b69e36496)] interface nsIObjectLoadingContent : nsISupports { /** @@ -55,6 +55,8 @@ interface nsIObjectLoadingContent : nsISupports const unsigned long PLUGIN_VULNERABLE_UPDATABLE = 9; // The plugin is vulnerable (no update available) const unsigned long PLUGIN_VULNERABLE_NO_UPDATE = 10; + // The plugin is in play preview mode + const unsigned long PLUGIN_PLAY_PREVIEW = 11; /** * The actual mime type (the one we got back from the network @@ -113,8 +115,8 @@ interface nsIObjectLoadingContent : nsISupports void playPlugin(); /** - * This attribute will return true if the plugin has been activated - * and false if the plugin is still in the click-to-play state. + * This attribute will return true if the plugin has been activated and + * false if the plugin is still in the click-to-play or play preview state. */ readonly attribute boolean activated; @@ -130,4 +132,9 @@ interface nsIObjectLoadingContent : nsISupports readonly attribute nsIURI srcURI; readonly attribute unsigned long pluginFallbackType; + + /** + * This method will disable the play-preview plugin state. + */ + void cancelPlayPreview(); }; diff --git a/content/base/src/nsObjectLoadingContent.cpp b/content/base/src/nsObjectLoadingContent.cpp index 2216544b2ad..9da9f88e8f8 100644 --- a/content/base/src/nsObjectLoadingContent.cpp +++ b/content/base/src/nsObjectLoadingContent.cpp @@ -188,6 +188,9 @@ nsPluginErrorEvent::Run() case nsObjectLoadingContent::eFallbackClickToPlay: type = NS_LITERAL_STRING("PluginClickToPlay"); break; + case nsObjectLoadingContent::eFallbackPlayPreview: + type = NS_LITERAL_STRING("PluginPlayPreview"); + break; case nsObjectLoadingContent::eFallbackUnsupported: type = NS_LITERAL_STRING("PluginNotFound"); break; @@ -659,6 +662,7 @@ nsObjectLoadingContent::nsObjectLoadingContent() , mInstantiating(false) , mNetworkCreated(true) , mActivated(false) + , mPlayPreviewCanceled(false) , mIsStopping(false) , mIsLoading(false) , mSrcStreamLoading(false) {} @@ -1041,6 +1045,8 @@ nsObjectLoadingContent::ObjectState() const return NS_EVENT_STATE_USERDISABLED; case eFallbackClickToPlay: return NS_EVENT_STATE_TYPE_CLICK_TO_PLAY; + case eFallbackPlayPreview: + return NS_EVENT_STATE_TYPE_PLAY_PREVIEW; case eFallbackDisabled: return NS_EVENT_STATE_BROKEN | NS_EVENT_STATE_HANDLER_DISABLED; case eFallbackBlocklisted: @@ -1427,6 +1433,7 @@ nsObjectLoadingContent::UpdateObjectParameters() if (stateInvalid) { newType = eType_Null; + newMime.Truncate(); } else if (useChannel) { // If useChannel is set above, we considered it in setting newMime newType = GetTypeOfContent(newMime); @@ -1645,6 +1652,15 @@ nsObjectLoadingContent::LoadObject(bool aNotify, } } + // Items resolved as Image/Document will not be checked for previews, as well + // as invalid plugins (they will not have the mContentType set). + if ((mType == eType_Null || mType == eType_Plugin) && ShouldPreview()) { + // If plugin preview exists, we shall use it + LOG(("OBJLC [%p]: Using plugin preview", this)); + mType = eType_Null; + fallbackType = eFallbackPlayPreview; + } + // If we're a plugin but shouldn't start yet, load fallback with // reason click-to-play instead FallbackType clickToPlayReason; @@ -2451,7 +2467,7 @@ NS_IMETHODIMP nsObjectLoadingContent::GetActivated(bool *aActivated) { FallbackType reason; - *aActivated = ShouldPlay(reason); + *aActivated = ShouldPlay(reason) && !ShouldPreview(); return NS_OK; } @@ -2463,6 +2479,31 @@ nsObjectLoadingContent::GetPluginFallbackType(uint32_t* aPluginFallbackType) return NS_OK; } +NS_IMETHODIMP +nsObjectLoadingContent::CancelPlayPreview() +{ + if (!nsContentUtils::IsCallerChrome()) + return NS_ERROR_NOT_AVAILABLE; + + if (mPlayPreviewCanceled || mActivated) + return NS_OK; + + mPlayPreviewCanceled = true; + return LoadObject(true, true); +} + +bool +nsObjectLoadingContent::ShouldPreview() +{ + if (mPlayPreviewCanceled || mActivated) + return false; + + nsRefPtr pluginHost = + already_AddRefed(nsPluginHost::GetInst()); + + return pluginHost->IsPluginPlayPreviewForType(mContentType.get()); +} + bool nsObjectLoadingContent::ShouldPlay(FallbackType &aReason) { diff --git a/content/base/src/nsObjectLoadingContent.h b/content/base/src/nsObjectLoadingContent.h index a41d58c6cbf..0ae8125acef 100644 --- a/content/base/src/nsObjectLoadingContent.h +++ b/content/base/src/nsObjectLoadingContent.h @@ -82,7 +82,10 @@ class nsObjectLoadingContent : public nsImageLoadingContent // The plugin is vulnerable (update available) eFallbackVulnerableUpdatable = nsIObjectLoadingContent::PLUGIN_VULNERABLE_UPDATABLE, // The plugin is vulnerable (no update available) - eFallbackVulnerableNoUpdate = nsIObjectLoadingContent::PLUGIN_VULNERABLE_NO_UPDATE + eFallbackVulnerableNoUpdate = nsIObjectLoadingContent::PLUGIN_VULNERABLE_NO_UPDATE, + // The plugin is disabled and play preview content is displayed until + // the extension code enables it by sending the MozPlayPlugin event + eFallbackPlayPreview = nsIObjectLoadingContent::PLUGIN_PLAY_PREVIEW }; nsObjectLoadingContent(); @@ -290,6 +293,11 @@ class nsObjectLoadingContent : public nsImageLoadingContent */ bool ShouldPlay(FallbackType &aReason); + /** + * If the object should display preview content for the current mContentType + */ + bool ShouldPreview(); + /** * Helper to check if our current URI passes policy * @@ -423,6 +431,9 @@ class nsObjectLoadingContent : public nsImageLoadingContent // activated by PlayPlugin(). (see ShouldPlay()) bool mActivated : 1; + // Used to keep track of whether or not a plugin is blocked by play-preview. + bool mPlayPreviewCanceled : 1; + // Protects DoStopPlugin from reentry (bug 724781). bool mIsStopping : 1; diff --git a/content/events/public/nsEventStates.h b/content/events/public/nsEventStates.h index 2bcaeb7a22c..650f3173822 100644 --- a/content/events/public/nsEventStates.h +++ b/content/events/public/nsEventStates.h @@ -252,6 +252,8 @@ private: #define NS_EVENT_STATE_LTR NS_DEFINE_EVENT_STATE_MACRO(43) // Element is rtl (for :dir pseudo-class) #define NS_EVENT_STATE_RTL NS_DEFINE_EVENT_STATE_MACRO(44) +// Handler for play preview plugin +#define NS_EVENT_STATE_TYPE_PLAY_PREVIEW NS_DEFINE_EVENT_STATE_MACRO(45) /** * NOTE: do not go over 63 without updating nsEventStates::InternalType! diff --git a/dom/plugins/base/nsIPluginHost.idl b/dom/plugins/base/nsIPluginHost.idl index 732863bfbe1..d3a6b8b034e 100644 --- a/dom/plugins/base/nsIPluginHost.idl +++ b/dom/plugins/base/nsIPluginHost.idl @@ -12,7 +12,7 @@ "@mozilla.org/plugin/host;1" %} -[scriptable, uuid(28F1F9E1-CD23-4FE2-BCC8-BBB0B2D49A4A)] +[scriptable, uuid(fdb56ce3-89ac-4293-be64-9f4be88004cc)] interface nsIPluginHost : nsISupports { /** @@ -72,5 +72,14 @@ interface nsIPluginHost : nsISupports * subdomains is found, return true. */ boolean siteHasData(in nsIPluginTag plugin, in AUTF8String domain); + + /** + * Registers the play preview plugin mode for specific mime type + * + * @param mimeType - specified mime type + */ + void registerPlayPreviewMimeType(in AUTF8String mimeType); + + void unregisterPlayPreviewMimeType(in AUTF8String mimeType); }; diff --git a/dom/plugins/base/nsPluginHost.cpp b/dom/plugins/base/nsPluginHost.cpp index 558bd977ab0..49caa409e3c 100644 --- a/dom/plugins/base/nsPluginHost.cpp +++ b/dom/plugins/base/nsPluginHost.cpp @@ -1309,6 +1309,17 @@ nsPluginHost::IsPluginClickToPlayForType(const char* aMimeType) } } +bool +nsPluginHost::IsPluginPlayPreviewForType(const char* aMimeType) +{ + for (uint32_t i = 0; i < mPlayPreviewMimeTypes.Length(); i++) { + nsCString mt = mPlayPreviewMimeTypes[i]; + if (PL_strcasecmp(mt.get(), aMimeType) == 0) + return true; + } + return false; +} + nsresult nsPluginHost::GetBlocklistStateForType(const char *aMimeType, uint32_t *aState) { @@ -1815,6 +1826,27 @@ nsPluginHost::EnumerateSiteData(const nsACString& domain, return NS_OK; } +NS_IMETHODIMP +nsPluginHost::RegisterPlayPreviewMimeType(const nsACString& mimeType) +{ + mPlayPreviewMimeTypes.AppendElement(mimeType); + return NS_OK; +} + +NS_IMETHODIMP +nsPluginHost::UnregisterPlayPreviewMimeType(const nsACString& mimeType) +{ + nsCAutoString mimeTypeToRemove(mimeType); + for (uint32_t i = mPlayPreviewMimeTypes.Length(); i > 0;) { + nsCString mt = mPlayPreviewMimeTypes[--i]; + if (PL_strcasecmp(mt.get(), mimeTypeToRemove.get()) == 0) { + mPlayPreviewMimeTypes.RemoveElementAt(i); + break; + } + } + return NS_OK; +} + NS_IMETHODIMP nsPluginHost::ClearSiteData(nsIPluginTag* plugin, const nsACString& domain, uint64_t flags, int64_t maxAge) diff --git a/dom/plugins/base/nsPluginHost.h b/dom/plugins/base/nsPluginHost.h index f6c1f81ee8b..fdaa76dd902 100644 --- a/dom/plugins/base/nsPluginHost.h +++ b/dom/plugins/base/nsPluginHost.h @@ -86,6 +86,7 @@ public: nsresult IsPluginEnabledForType(const char* aMimeType); nsresult IsPluginEnabledForExtension(const char* aExtension, const char* &aMimeType); bool IsPluginClickToPlayForType(const char *aMimeType); + bool IsPluginPlayPreviewForType(const char *aMimeType); nsresult GetBlocklistStateForType(const char *aMimeType, uint32_t *state); nsresult GetPluginCount(uint32_t* aPluginCount); @@ -281,6 +282,7 @@ private: nsRefPtr mPlugins; nsRefPtr mCachedPlugins; nsRefPtr mInvalidPlugins; + nsTArray mPlayPreviewMimeTypes; bool mPluginsLoaded; bool mDontShowBadPluginMessage; diff --git a/layout/style/nsCSSPseudoClassList.h b/layout/style/nsCSSPseudoClassList.h index 23312179cc1..3e3ec00c9b8 100644 --- a/layout/style/nsCSSPseudoClassList.h +++ b/layout/style/nsCSSPseudoClassList.h @@ -154,6 +154,8 @@ CSS_STATE_PSEUDO_CLASS(mozTypeUnsupportedPlatform, ":-moz-type-unsupported-platf NS_EVENT_STATE_TYPE_UNSUPPORTED_PLATFORM) CSS_STATE_PSEUDO_CLASS(mozHandlerClickToPlay, ":-moz-handler-clicktoplay", NS_EVENT_STATE_TYPE_CLICK_TO_PLAY) +CSS_STATE_PSEUDO_CLASS(mozHandlerPlayPreview, ":-moz-handler-playpreview", + NS_EVENT_STATE_TYPE_PLAY_PREVIEW) CSS_STATE_PSEUDO_CLASS(mozHandlerVulnerableUpdatable, ":-moz-handler-vulnerable-updatable", NS_EVENT_STATE_VULNERABLE_UPDATABLE) CSS_STATE_PSEUDO_CLASS(mozHandlerVulnerableNoUpdate, ":-moz-handler-vulnerable-no-update", diff --git a/mobile/android/chrome/content/browser.js b/mobile/android/chrome/content/browser.js index bd4e62e1965..d2b9b77ff2f 100644 --- a/mobile/android/chrome/content/browser.js +++ b/mobile/android/chrome/content/browser.js @@ -2187,6 +2187,7 @@ Tab.prototype = { this.browser.addEventListener("scroll", this, true); this.browser.addEventListener("MozScrolledAreaChanged", this, true); this.browser.addEventListener("PluginClickToPlay", this, true); + this.browser.addEventListener("PluginPlayPreview", this, true); this.browser.addEventListener("PluginNotFound", this, true); this.browser.addEventListener("pageshow", this, true); @@ -2280,6 +2281,7 @@ Tab.prototype = { this.browser.removeEventListener("DOMWillOpenModalDialog", this, true); this.browser.removeEventListener("scroll", this, true); this.browser.removeEventListener("PluginClickToPlay", this, true); + this.browser.removeEventListener("PluginPlayPreview", this, true); this.browser.removeEventListener("PluginNotFound", this, true); this.browser.removeEventListener("MozScrolledAreaChanged", this, true); @@ -2842,6 +2844,52 @@ Tab.prototype = { break; } + case "PluginPlayPreview": { + let plugin = aEvent.target; + + // Force a style flush, so that we ensure our binding is attached. + plugin.clientTop; + + let doc = plugin.ownerDocument; + let previewContent = doc.getAnonymousElementByAttribute(plugin, "class", "previewPluginContent"); + if (!previewContent) { + // If the plugin is hidden, fallback to click-to-play logic + PluginHelper.stopPlayPreview(plugin, false); + break; + } + let iframe = previewContent.getElementsByClassName("previewPluginContentFrame")[0]; + if (!iframe) { + // lazy initialization of the iframe + iframe = doc.createElementNS("http://www.w3.org/1999/xhtml", "iframe"); + iframe.className = "previewPluginContentFrame"; + previewContent.appendChild(iframe); + + // Force a style flush, so that we ensure our binding is attached. + plugin.clientTop; + } + let mimeType = PluginHelper.getPluginMimeType(plugin); + let playPreviewUri = "data:application/x-moz-playpreview;," + mimeType; + iframe.src = playPreviewUri; + + // MozPlayPlugin event can be dispatched from the extension chrome + // code to replace the preview content with the native plugin + previewContent.addEventListener("MozPlayPlugin", function playPluginHandler(e) { + if (!e.isTrusted) + return; + + previewContent.removeEventListener("MozPlayPlugin", playPluginHandler, true); + + let playPlugin = !aEvent.detail; + PluginHelper.stopPlayPreview(plugin, playPlugin); + + // cleaning up: removes overlay iframe from the DOM + let iframe = previewContent.getElementsByClassName("previewPluginContentFrame")[0]; + if (iframe) + previewContent.removeChild(iframe); + }, true); + break; + } + case "PluginNotFound": { let plugin = aEvent.target; plugin.clientTop; // force style flush @@ -5237,10 +5285,22 @@ var PluginHelper = { playPlugin: function(plugin) { let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - if (!objLoadingContent.activated) + if (!objLoadingContent.activated && + objLoadingContent.pluginFallbackType !== Ci.nsIObjectLoadingContent.PLUGIN_PLAY_PREVIEW) objLoadingContent.playPlugin(); }, + stopPlayPreview: function(plugin, playPlugin) { + let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); + if (objLoadingContent.activated) + return; + + if (playPlugin) + objLoadingContent.playPlugin(); + else + objLoadingContent.cancelPlayPreview(); + }, + getPluginPreference: function getPluginPreference() { let pluginDisable = Services.prefs.getBoolPref("plugin.disable"); if (pluginDisable) @@ -5277,6 +5337,22 @@ var PluginHelper = { (overlay.scrollHeight - 5 > pluginRect.height); return overflows; + }, + + getPluginMimeType: function (plugin) { + var tagMimetype; + if (plugin instanceof HTMLAppletElement) { + tagMimetype = "application/x-java-vm"; + } else { + tagMimetype = plugin.QueryInterface(Components.interfaces.nsIObjectLoadingContent) + .actualType; + + if (tagMimetype == "") { + tagMimetype = plugin.type; + } + } + + return tagMimetype; } }; diff --git a/toolkit/mozapps/plugins/content/pluginProblem.xml b/toolkit/mozapps/plugins/content/pluginProblem.xml index 5c151bf9235..60e7676c55b 100644 --- a/toolkit/mozapps/plugins/content/pluginProblem.xml +++ b/toolkit/mozapps/plugins/content/pluginProblem.xml @@ -56,6 +56,7 @@ + diff --git a/toolkit/mozapps/plugins/content/pluginProblemBinding.css b/toolkit/mozapps/plugins/content/pluginProblemBinding.css index 8744f2b6a4b..8bf05c66f7a 100644 --- a/toolkit/mozapps/plugins/content/pluginProblemBinding.css +++ b/toolkit/mozapps/plugins/content/pluginProblemBinding.css @@ -8,18 +8,21 @@ embed:-moz-handler-disabled, embed:-moz-handler-blocked, embed:-moz-handler-crashed, embed:-moz-handler-clicktoplay, +embed:-moz-handler-playpreview, embed:-moz-handler-vulnerable-updatable, embed:-moz-handler-vulnerable-no-update, applet:-moz-handler-disabled, applet:-moz-handler-blocked, applet:-moz-handler-crashed, applet:-moz-handler-clicktoplay, +applet:-moz-handler-playpreview, applet:-moz-handler-vulnerable-updatable, applet:-moz-handler-vulnerable-no-update, object:-moz-has-handlerref:-moz-handler-disabled, object:-moz-has-handlerref:-moz-handler-blocked, object:-moz-handler-crashed, object:-moz-handler-clicktoplay, +object:-moz-handler-playpreview, object:-moz-handler-vulnerable-updatable, object:-moz-handler-vulnerable-no-update { display: inline-block; diff --git a/toolkit/mozapps/plugins/content/pluginProblemContent.css b/toolkit/mozapps/plugins/content/pluginProblemContent.css index b6cd3180fb5..43b042436c9 100644 --- a/toolkit/mozapps/plugins/content/pluginProblemContent.css +++ b/toolkit/mozapps/plugins/content/pluginProblemContent.css @@ -47,6 +47,27 @@ html|applet:not([height]), html|applet[height=""] { direction: rtl; } +:-moz-handler-playpreview .mainBox { + display: none; +} + +.previewPluginContent { + display: none; +} + +.previewPluginContent > iframe { + width: inherit; + height: inherit; + border: none; +} + +:-moz-handler-playpreview .previewPluginContent { + display: block; + width: inherit; + height: inherit; + overflow: hidden; +} + .msg { display: none; }