mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 839714 - Extend PlayPreview API. r=jschoenick, r=jwein
This commit is contained in:
parent
f5026d4a7a
commit
0d6cb92088
@ -304,10 +304,19 @@ var gPluginHandler = {
|
||||
let browser = gBrowser.getBrowserForDocument(objLoadingContent.ownerDocument.defaultView.top.document);
|
||||
let pluginPermission = Services.perms.testPermission(browser.currentURI, permissionString);
|
||||
|
||||
let isFallbackTypeValid =
|
||||
objLoadingContent.pluginFallbackType >= Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY &&
|
||||
objLoadingContent.pluginFallbackType <= Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_NO_UPDATE;
|
||||
|
||||
if (objLoadingContent.pluginFallbackType == Ci.nsIObjectLoadingContent.PLUGIN_PLAY_PREVIEW) {
|
||||
// checking if play preview is subject to CTP rules
|
||||
let playPreviewInfo = pluginHost.getPlayPreviewInfo(objLoadingContent.actualType);
|
||||
isFallbackTypeValid = !playPreviewInfo.ignoreCTP;
|
||||
}
|
||||
|
||||
return !objLoadingContent.activated &&
|
||||
pluginPermission != Ci.nsIPermissionManager.DENY_ACTION &&
|
||||
objLoadingContent.pluginFallbackType >= Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY &&
|
||||
objLoadingContent.pluginFallbackType <= Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_NO_UPDATE;
|
||||
isFallbackTypeValid;
|
||||
},
|
||||
|
||||
activatePlugins: function PH_activatePlugins(aContentWindow) {
|
||||
@ -472,6 +481,21 @@ var gPluginHandler = {
|
||||
|
||||
_handlePlayPreviewEvent: function PH_handlePlayPreviewEvent(aPlugin) {
|
||||
let doc = aPlugin.ownerDocument;
|
||||
let browser = gBrowser.getBrowserForDocument(doc.defaultView.top.document);
|
||||
let pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
|
||||
let pluginInfo = this._getPluginInfo(aPlugin);
|
||||
let playPreviewInfo = pluginHost.getPlayPreviewInfo(pluginInfo.mimetype);
|
||||
|
||||
if (!playPreviewInfo.ignoreCTP) {
|
||||
// if click-to-play rules used, play plugin at once if plugins were
|
||||
// activated for this window
|
||||
if (browser._clickToPlayAllPluginsActivated ||
|
||||
browser._clickToPlayPluginsActivated.get(pluginInfo.pluginName)) {
|
||||
objLoadingContent.playPlugin();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let previewContent = doc.getAnonymousElementByAttribute(aPlugin, "class", "previewPluginContent");
|
||||
let iframe = previewContent.getElementsByClassName("previewPluginContentFrame")[0];
|
||||
if (!iframe) {
|
||||
@ -483,9 +507,7 @@ var gPluginHandler = {
|
||||
// Force a style flush, so that we ensure our binding is attached.
|
||||
aPlugin.clientTop;
|
||||
}
|
||||
let pluginInfo = this._getPluginInfo(aPlugin);
|
||||
let playPreviewUri = "data:application/x-moz-playpreview;," + pluginInfo.mimetype;
|
||||
iframe.src = playPreviewUri;
|
||||
iframe.src = playPreviewInfo.redirectURL;
|
||||
|
||||
// MozPlayPlugin event can be dispatched from the extension chrome
|
||||
// code to replace the preview content with the native plugin
|
||||
@ -503,6 +525,10 @@ var gPluginHandler = {
|
||||
if (iframe)
|
||||
previewContent.removeChild(iframe);
|
||||
}, true);
|
||||
|
||||
if (!playPreviewInfo.ignoreCTP) {
|
||||
gPluginHandler._showClickToPlayNotification(browser);
|
||||
}
|
||||
},
|
||||
|
||||
reshowClickToPlayNotification: function PH_reshowClickToPlayNotification() {
|
||||
|
@ -186,6 +186,7 @@ _BROWSER_FILES = \
|
||||
browser_plugins_added_dynamically.js \
|
||||
browser_CTPScriptPlugin.js \
|
||||
browser_pluginplaypreview.js \
|
||||
browser_pluginplaypreview2.js \
|
||||
browser_private_browsing_window.js \
|
||||
browser_relatedTabs.js \
|
||||
browser_sanitize-passwordDisabledHosts.js \
|
||||
|
@ -111,7 +111,7 @@ function registerPlayPreview(mimeType, targetUrl) {
|
||||
};
|
||||
|
||||
var ph = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
|
||||
ph.registerPlayPreviewMimeType(mimeType);
|
||||
ph.registerPlayPreviewMimeType(mimeType, true); // ignoring CTP rules
|
||||
|
||||
var factory = new StreamConverterFactory();
|
||||
factory.register(OverlayStreamConverter);
|
||||
|
173
browser/base/content/test/browser_pluginplaypreview2.js
Normal file
173
browser/base/content/test/browser_pluginplaypreview2.js
Normal file
@ -0,0 +1,173 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
var rootDir = getRootDirectory(gTestPath);
|
||||
const gTestRoot = rootDir;
|
||||
|
||||
var gTestBrowser = null;
|
||||
var gNextTest = null;
|
||||
var gNextTestSkip = 0;
|
||||
var gPlayPreviewPluginActualEvents = 0;
|
||||
var gPlayPreviewPluginExpectedEvents = 1;
|
||||
|
||||
var gPlayPreviewRegistration = null;
|
||||
|
||||
function registerPlayPreview(mimeType, targetUrl) {
|
||||
var ph = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
|
||||
ph.registerPlayPreviewMimeType(mimeType, false, targetUrl);
|
||||
|
||||
return (gPlayPreviewRegistration = {
|
||||
unregister: function() {
|
||||
ph.unregisterPlayPreviewMimeType(mimeType);
|
||||
gPlayPreviewRegistration = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function unregisterPlayPreview() {
|
||||
gPlayPreviewRegistration.unregister();
|
||||
}
|
||||
|
||||
Components.utils.import('resource://gre/modules/XPCOMUtils.jsm');
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
registerCleanupFunction(function() {
|
||||
if (gPlayPreviewRegistration)
|
||||
gPlayPreviewRegistration.unregister();
|
||||
Services.prefs.clearUserPref("plugins.click_to_play");
|
||||
});
|
||||
|
||||
var newTab = gBrowser.addTab();
|
||||
gBrowser.selectedTab = newTab;
|
||||
gTestBrowser = gBrowser.selectedBrowser;
|
||||
gTestBrowser.addEventListener("load", pageLoad, true);
|
||||
gTestBrowser.addEventListener("PluginBindingAttached", handleBindingAttached, true, true);
|
||||
|
||||
Services.prefs.setBoolPref("plugins.click_to_play", true);
|
||||
|
||||
registerPlayPreview('application/x-test', 'about:');
|
||||
prepareTest(test1a, gTestRoot + "plugin_test.html", 1);
|
||||
}
|
||||
|
||||
function finishTest() {
|
||||
gTestBrowser.removeEventListener("load", pageLoad, true);
|
||||
gTestBrowser.removeEventListener("PluginBindingAttached", handleBindingAttached, true, true);
|
||||
gBrowser.removeCurrentTab();
|
||||
window.focus();
|
||||
finish();
|
||||
}
|
||||
|
||||
function handleBindingAttached(evt) {
|
||||
if (evt.target instanceof Ci.nsIObjectLoadingContent &&
|
||||
evt.target.pluginFallbackType == Ci.nsIObjectLoadingContent.PLUGIN_PLAY_PREVIEW)
|
||||
gPlayPreviewPluginActualEvents++;
|
||||
}
|
||||
|
||||
function pageLoad() {
|
||||
// The plugin events are async dispatched and can come after the load event
|
||||
// This just allows the events to fire before we then go on to test the states
|
||||
|
||||
// iframe might triggers load event as well, making sure we skip some to let
|
||||
// all iframes on the page be loaded as well
|
||||
if (gNextTestSkip) {
|
||||
gNextTestSkip--;
|
||||
return;
|
||||
}
|
||||
executeSoon(gNextTest);
|
||||
}
|
||||
|
||||
function prepareTest(nextTest, url, skip) {
|
||||
gNextTest = nextTest;
|
||||
gNextTestSkip = skip;
|
||||
gTestBrowser.contentWindow.location = url;
|
||||
}
|
||||
|
||||
// Tests a page with normal play preview registration (1/2)
|
||||
function test1a() {
|
||||
var notificationBox = gBrowser.getNotificationBox(gTestBrowser);
|
||||
ok(!notificationBox.getNotificationWithValue("missing-plugins"), "Test 1a, Should not have displayed the missing plugin notification");
|
||||
ok(!notificationBox.getNotificationWithValue("blocked-plugins"), "Test 1a, Should not have displayed the blocked plugin notification");
|
||||
|
||||
var pluginInfo = getTestPlugin();
|
||||
ok(pluginInfo, "Should have a test plugin");
|
||||
|
||||
var doc = gTestBrowser.contentDocument;
|
||||
var plugin = doc.getElementById("test");
|
||||
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
is(objLoadingContent.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_PLAY_PREVIEW, "Test 1a, plugin fallback type should be PLUGIN_PLAY_PREVIEW");
|
||||
ok(!objLoadingContent.activated, "Test 1a, Plugin should not be activated");
|
||||
|
||||
var overlay = doc.getAnonymousElementByAttribute(plugin, "class", "previewPluginContent");
|
||||
ok(overlay, "Test 1a, the overlay div is expected");
|
||||
|
||||
var iframe = overlay.getElementsByClassName("previewPluginContentFrame")[0];
|
||||
ok(iframe && iframe.localName == "iframe", "Test 1a, the overlay iframe is expected");
|
||||
var iframeHref = iframe.contentWindow.location.href;
|
||||
ok(iframeHref == "about:", "Test 1a, the overlay about: content is expected");
|
||||
|
||||
var rect = iframe.getBoundingClientRect();
|
||||
ok(rect.width == 200, "Test 1a, Plugin with id=" + plugin.id + " overlay rect should have 200px width before being replaced by actual plugin");
|
||||
ok(rect.height == 200, "Test 1a, Plugin with id=" + plugin.id + " overlay rect should have 200px height before being replaced by actual plugin");
|
||||
|
||||
var e = overlay.ownerDocument.createEvent("CustomEvent");
|
||||
e.initCustomEvent("MozPlayPlugin", true, true, null);
|
||||
overlay.dispatchEvent(e);
|
||||
var condition = function() objLoadingContent.activated;
|
||||
waitForCondition(condition, test1b, "Test 1a, Waited too long for plugin to stop play preview");
|
||||
}
|
||||
|
||||
// Tests that activating via MozPlayPlugin through the notification works (part 2/2)
|
||||
function test1b() {
|
||||
var plugin = gTestBrowser.contentDocument.getElementById("test");
|
||||
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
ok(objLoadingContent.activated, "Test 1b, Plugin should be activated");
|
||||
|
||||
is(gPlayPreviewPluginActualEvents, gPlayPreviewPluginExpectedEvents,
|
||||
"There should be exactly one PluginPlayPreview event");
|
||||
|
||||
unregisterPlayPreview();
|
||||
|
||||
prepareTest(test2, gTestRoot + "plugin_test.html");
|
||||
}
|
||||
|
||||
// Tests a page with a working plugin in it -- the mime type was just unregistered.
|
||||
function test2() {
|
||||
var doc = gTestBrowser.contentDocument;
|
||||
var plugin = doc.getElementById("test");
|
||||
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
ok(objLoadingContent.pluginFallbackType != Ci.nsIObjectLoadingContent.PLUGIN_PLAY_PREVIEW, "Test 2, plugin fallback type should not be PLUGIN_PLAY_PREVIEW");
|
||||
ok(!objLoadingContent.activated, "Test 2, Plugin should not be activated");
|
||||
|
||||
registerPlayPreview('application/x-unknown', 'about:');
|
||||
|
||||
prepareTest(test3, gTestRoot + "plugin_test.html");
|
||||
}
|
||||
|
||||
// Tests a page with a working plugin in it -- diffent play preview type is reserved.
|
||||
function test3() {
|
||||
var doc = gTestBrowser.contentDocument;
|
||||
var plugin = doc.getElementById("test");
|
||||
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
ok(objLoadingContent.pluginFallbackType != Ci.nsIObjectLoadingContent.PLUGIN_PLAY_PREVIEW, "Test 3, plugin fallback type should not be PLUGIN_PLAY_PREVIEW");
|
||||
ok(!objLoadingContent.activated, "Test 3, Plugin should not be activated");
|
||||
|
||||
unregisterPlayPreview();
|
||||
|
||||
registerPlayPreview('application/x-test', 'about:');
|
||||
Services.prefs.setBoolPref("plugins.click_to_play", false);
|
||||
prepareTest(test4, gTestRoot + "plugin_test.html");
|
||||
}
|
||||
|
||||
// Tests a page with a working plugin in it -- click-to-play is off
|
||||
function test4() {
|
||||
var plugin = gTestBrowser.contentDocument.getElementById("test");
|
||||
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
ok(objLoadingContent.activated, "Test 4, Plugin should be activated");
|
||||
|
||||
finishTest();
|
||||
}
|
||||
|
@ -1758,26 +1758,20 @@ 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
|
||||
// reason click-to-play instead. Items resolved as Image/Document
|
||||
// will not be checked for previews, as well as invalid plugins
|
||||
// (they will not have the mContentType set).
|
||||
FallbackType clickToPlayReason;
|
||||
if (mType == eType_Plugin && !ShouldPlay(clickToPlayReason)) {
|
||||
if ((mType == eType_Null || mType == eType_Plugin) &&
|
||||
!ShouldPlay(clickToPlayReason)) {
|
||||
LOG(("OBJLC [%p]: Marking plugin as click-to-play", this));
|
||||
mType = eType_Null;
|
||||
fallbackType = clickToPlayReason;
|
||||
}
|
||||
|
||||
if (!mActivated && mType == eType_Plugin) {
|
||||
// Object passed ShouldPlay and !ShouldPreview, so it should be considered
|
||||
// Object passed ShouldPlay, so it should be considered
|
||||
// activated until it changes content type
|
||||
LOG(("OBJLC [%p]: Object implicitly activated", this));
|
||||
mActivated = true;
|
||||
@ -2649,18 +2643,6 @@ nsObjectLoadingContent::CancelPlayPreview()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
nsObjectLoadingContent::ShouldPreview()
|
||||
{
|
||||
if (mPlayPreviewCanceled || mActivated)
|
||||
return false;
|
||||
|
||||
nsRefPtr<nsPluginHost> pluginHost =
|
||||
already_AddRefed<nsPluginHost>(nsPluginHost::GetInst());
|
||||
|
||||
return pluginHost->IsPluginPlayPreviewForType(mContentType.get());
|
||||
}
|
||||
|
||||
bool
|
||||
nsObjectLoadingContent::ShouldPlay(FallbackType &aReason)
|
||||
{
|
||||
@ -2671,6 +2653,25 @@ nsObjectLoadingContent::ShouldPlay(FallbackType &aReason)
|
||||
nsRefPtr<nsPluginHost> pluginHost =
|
||||
already_AddRefed<nsPluginHost>(nsPluginHost::GetInst());
|
||||
|
||||
nsCOMPtr<nsIPluginPlayPreviewInfo> playPreviewInfo;
|
||||
bool isPlayPreviewSpecified = NS_SUCCEEDED(pluginHost->GetPlayPreviewInfo(
|
||||
mContentType, getter_AddRefs(playPreviewInfo)));
|
||||
bool ignoreCTP = false;
|
||||
if (isPlayPreviewSpecified) {
|
||||
playPreviewInfo->GetIgnoreCTP(&ignoreCTP);
|
||||
}
|
||||
if (isPlayPreviewSpecified && !mPlayPreviewCanceled && !mActivated &&
|
||||
ignoreCTP) {
|
||||
// play preview in ignoreCTP mode is shown even if the native plugin
|
||||
// is not present/installed
|
||||
aReason = eFallbackPlayPreview;
|
||||
return false;
|
||||
}
|
||||
// at this point if it's not a plugin, we let it play/fallback
|
||||
if (mType != eType_Plugin) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isCTP;
|
||||
nsresult rv = pluginHost->IsPluginClickToPlayForType(mContentType, &isCTP);
|
||||
if (NS_FAILED(rv)) {
|
||||
@ -2735,6 +2736,12 @@ nsObjectLoadingContent::ShouldPlay(FallbackType &aReason)
|
||||
allowPerm = permission == nsIPermissionManager::ALLOW_ACTION;
|
||||
}
|
||||
|
||||
if (aReason == eFallbackClickToPlay && isPlayPreviewSpecified &&
|
||||
!mPlayPreviewCanceled && !ignoreCTP) {
|
||||
// play preview in click-to-play mode is shown instead of standard CTP UI
|
||||
aReason = eFallbackPlayPreview;
|
||||
}
|
||||
|
||||
return allowPerm;
|
||||
}
|
||||
|
||||
|
@ -301,11 +301,6 @@ 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
|
||||
*
|
||||
|
@ -45,6 +45,7 @@ EXPORTS = \
|
||||
nsPluginDirServiceProvider.h \
|
||||
nsPluginHost.h \
|
||||
nsPluginInstanceOwner.h \
|
||||
nsPluginPlayPreviewInfo.h \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS_mozilla = \
|
||||
@ -62,6 +63,7 @@ CPPSRCS = \
|
||||
nsPluginTags.cpp \
|
||||
PluginPRLibrary.cpp \
|
||||
nsPluginInstanceOwner.cpp \
|
||||
nsPluginPlayPreviewInfo.cpp \
|
||||
$(NULL)
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),android)
|
||||
|
@ -12,7 +12,15 @@
|
||||
"@mozilla.org/plugin/host;1"
|
||||
%}
|
||||
|
||||
[scriptable, uuid(3ac8fe33-c38c-4123-b2f0-0e8a2824b9c5)]
|
||||
[scriptable, uuid(f89e7679-0adf-4a30-bda9-1afe1ee270d6)]
|
||||
interface nsIPluginPlayPreviewInfo : nsISupports
|
||||
{
|
||||
readonly attribute AUTF8String mimeType;
|
||||
readonly attribute boolean ignoreCTP;
|
||||
readonly attribute AUTF8String redirectURL;
|
||||
};
|
||||
|
||||
[scriptable, uuid(67ebff01-0dce-48f7-b6a5-6235fc78382b)]
|
||||
interface nsIPluginHost : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -76,12 +84,20 @@ interface nsIPluginHost : nsISupports
|
||||
/**
|
||||
* Registers the play preview plugin mode for specific mime type
|
||||
*
|
||||
* @param mimeType - specified mime type
|
||||
* @param mimeType: specifies plugin mime type.
|
||||
* @param ignoreCTP: if true, the play preview ignores CTP rules, e.g.
|
||||
whitelisted websites, will not notify about plugin
|
||||
presence in the address bar.
|
||||
* @param redirectURL: specifies url for the overlay iframe
|
||||
*/
|
||||
void registerPlayPreviewMimeType(in AUTF8String mimeType);
|
||||
void registerPlayPreviewMimeType(in AUTF8String mimeType,
|
||||
[optional] in boolean ignoreCTP,
|
||||
[optional] in AUTF8String redirectURL);
|
||||
|
||||
void unregisterPlayPreviewMimeType(in AUTF8String mimeType);
|
||||
|
||||
nsIPluginPlayPreviewInfo getPlayPreviewInfo(in AUTF8String mimeType);
|
||||
|
||||
ACString getPermissionStringForType(in AUTF8String mimeType);
|
||||
|
||||
bool isPluginClickToPlayForType(in AUTF8String mimeType);
|
||||
|
@ -1154,17 +1154,6 @@ nsPluginHost::IsPluginClickToPlayForType(const nsACString &aMimeType, bool *aRes
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@ -1648,9 +1637,21 @@ nsPluginHost::EnumerateSiteData(const nsACString& domain,
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPluginHost::RegisterPlayPreviewMimeType(const nsACString& mimeType)
|
||||
nsPluginHost::RegisterPlayPreviewMimeType(const nsACString& mimeType,
|
||||
bool ignoreCTP,
|
||||
const nsACString& redirectURL)
|
||||
{
|
||||
mPlayPreviewMimeTypes.AppendElement(mimeType);
|
||||
nsAutoCString mt(mimeType);
|
||||
nsAutoCString url(redirectURL);
|
||||
if (url.Length() == 0) {
|
||||
// using default play preview iframe URL, if redirectURL is not specified
|
||||
url.Assign("data:application/x-moz-playpreview;,");
|
||||
url.Append(mimeType);
|
||||
}
|
||||
|
||||
nsRefPtr<nsPluginPlayPreviewInfo> playPreview =
|
||||
new nsPluginPlayPreviewInfo(mt.get(), ignoreCTP, url.get());
|
||||
mPlayPreviewMimeTypes.AppendElement(playPreview);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1658,16 +1659,33 @@ NS_IMETHODIMP
|
||||
nsPluginHost::UnregisterPlayPreviewMimeType(const nsACString& mimeType)
|
||||
{
|
||||
nsAutoCString 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);
|
||||
for (uint32_t i = mPlayPreviewMimeTypes.Length(); i > 0; i--) {
|
||||
nsRefPtr<nsPluginPlayPreviewInfo> pp = mPlayPreviewMimeTypes[i - 1];
|
||||
if (PL_strcasecmp(pp.get()->mMimeType.get(), mimeTypeToRemove.get()) == 0) {
|
||||
mPlayPreviewMimeTypes.RemoveElementAt(i - 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPluginHost::GetPlayPreviewInfo(const nsACString& mimeType,
|
||||
nsIPluginPlayPreviewInfo** aResult)
|
||||
{
|
||||
nsAutoCString mimeTypeToFind(mimeType);
|
||||
for (uint32_t i = 0; i < mPlayPreviewMimeTypes.Length(); i++) {
|
||||
nsRefPtr<nsPluginPlayPreviewInfo> pp = mPlayPreviewMimeTypes[i];
|
||||
if (PL_strcasecmp(pp.get()->mMimeType.get(), mimeTypeToFind.get()) == 0) {
|
||||
*aResult = new nsPluginPlayPreviewInfo(pp.get());
|
||||
NS_ADDREF(*aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
*aResult = nullptr;
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPluginHost::ClearSiteData(nsIPluginTag* plugin, const nsACString& domain,
|
||||
uint64_t flags, int64_t maxAge)
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "nsTObserverArray.h"
|
||||
#include "nsITimer.h"
|
||||
#include "nsPluginTags.h"
|
||||
#include "nsPluginPlayPreviewInfo.h"
|
||||
#include "nsIEffectiveTLDService.h"
|
||||
#include "nsIIDNService.h"
|
||||
#include "nsCRT.h"
|
||||
@ -80,7 +81,6 @@ public:
|
||||
nsPluginInstanceOwner *aOwner);
|
||||
nsresult IsPluginEnabledForType(const char* aMimeType);
|
||||
nsresult IsPluginEnabledForExtension(const char* aExtension, const char* &aMimeType);
|
||||
bool IsPluginPlayPreviewForType(const char *aMimeType);
|
||||
nsresult GetBlocklistStateForType(const char *aMimeType, uint32_t *state);
|
||||
|
||||
nsresult GetPluginCount(uint32_t* aPluginCount);
|
||||
@ -262,7 +262,7 @@ private:
|
||||
nsRefPtr<nsPluginTag> mPlugins;
|
||||
nsRefPtr<nsPluginTag> mCachedPlugins;
|
||||
nsRefPtr<nsInvalidPluginTag> mInvalidPlugins;
|
||||
nsTArray<nsCString> mPlayPreviewMimeTypes;
|
||||
nsTArray< nsRefPtr<nsPluginPlayPreviewInfo> > mPlayPreviewMimeTypes;
|
||||
bool mPluginsLoaded;
|
||||
|
||||
// set by pref plugin.override_internal_types
|
||||
|
50
dom/plugins/base/nsPluginPlayPreviewInfo.cpp
Normal file
50
dom/plugins/base/nsPluginPlayPreviewInfo.cpp
Normal file
@ -0,0 +1,50 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsPluginPlayPreviewInfo.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
nsPluginPlayPreviewInfo::nsPluginPlayPreviewInfo(const char* aMimeType,
|
||||
bool aIgnoreCTP,
|
||||
const char* aRedirectURL)
|
||||
: mMimeType(aMimeType), mIgnoreCTP(aIgnoreCTP), mRedirectURL(aRedirectURL) {}
|
||||
|
||||
nsPluginPlayPreviewInfo::nsPluginPlayPreviewInfo(
|
||||
const nsPluginPlayPreviewInfo* aSource)
|
||||
{
|
||||
MOZ_ASSERT(aSource);
|
||||
|
||||
mMimeType = aSource->mMimeType;
|
||||
mIgnoreCTP = aSource->mIgnoreCTP;
|
||||
mRedirectURL = aSource->mRedirectURL;
|
||||
}
|
||||
|
||||
nsPluginPlayPreviewInfo::~nsPluginPlayPreviewInfo()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsPluginPlayPreviewInfo, nsIPluginPlayPreviewInfo)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPluginPlayPreviewInfo::GetMimeType(nsACString& aMimeType)
|
||||
{
|
||||
aMimeType = mMimeType;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPluginPlayPreviewInfo::GetIgnoreCTP(bool* aIgnoreCTP)
|
||||
{
|
||||
*aIgnoreCTP = mIgnoreCTP;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPluginPlayPreviewInfo::GetRedirectURL(nsACString& aRedirectURL)
|
||||
{
|
||||
aRedirectURL = mRedirectURL;
|
||||
return NS_OK;
|
||||
}
|
30
dom/plugins/base/nsPluginPlayPreviewInfo.h
Normal file
30
dom/plugins/base/nsPluginPlayPreviewInfo.h
Normal file
@ -0,0 +1,30 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef nsPluginPlayPreviewInfo_h_
|
||||
#define nsPluginPlayPreviewInfo_h_
|
||||
|
||||
#include "nsString.h"
|
||||
#include "nsIPluginHost.h"
|
||||
|
||||
class nsPluginPlayPreviewInfo : public nsIPluginPlayPreviewInfo
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIPLUGINPLAYPREVIEWINFO
|
||||
|
||||
nsPluginPlayPreviewInfo(const char* aMimeType,
|
||||
bool aIgnoreCTP,
|
||||
const char* aRedirectURL);
|
||||
nsPluginPlayPreviewInfo(const nsPluginPlayPreviewInfo* aSource);
|
||||
virtual ~nsPluginPlayPreviewInfo();
|
||||
|
||||
nsCString mMimeType;
|
||||
bool mIgnoreCTP;
|
||||
nsCString mRedirectURL;
|
||||
};
|
||||
|
||||
|
||||
#endif // nsPluginPlayPreviewInfo_h_
|
@ -6167,6 +6167,19 @@ var PluginHelper = {
|
||||
NativeWindow.doorhanger.show(message, "ask-to-play-plugins", buttons, aTab.id, options);
|
||||
},
|
||||
|
||||
delayAndShowDoorHanger: function(aTab) {
|
||||
// To avoid showing the doorhanger if there are also visible plugin
|
||||
// overlays on the page, delay showing the doorhanger to check if
|
||||
// visible plugins get added in the near future.
|
||||
if (!aTab.pluginDoorhangerTimeout) {
|
||||
aTab.pluginDoorhangerTimeout = setTimeout(function() {
|
||||
if (this.shouldShowPluginDoorhanger) {
|
||||
PluginHelper.showDoorHanger(this);
|
||||
}
|
||||
}.bind(aTab), 500);
|
||||
}
|
||||
},
|
||||
|
||||
playAllPlugins: function(aContentWindow) {
|
||||
let cwu = aContentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils);
|
||||
@ -6180,8 +6193,7 @@ var PluginHelper = {
|
||||
|
||||
playPlugin: function(plugin) {
|
||||
let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
if (!objLoadingContent.activated &&
|
||||
objLoadingContent.pluginFallbackType !== Ci.nsIObjectLoadingContent.PLUGIN_PLAY_PREVIEW)
|
||||
if (!objLoadingContent.activated)
|
||||
objLoadingContent.playPlugin();
|
||||
},
|
||||
|
||||
@ -6279,17 +6291,7 @@ var PluginHelper = {
|
||||
// If the plugin is hidden, or if the overlay is too small, show a
|
||||
// doorhanger notification
|
||||
if (PluginHelper.isTooSmall(plugin, overlay)) {
|
||||
// To avoid showing the doorhanger if there are also visible plugin
|
||||
// overlays on the page, delay showing the doorhanger to check if
|
||||
// visible plugins get added in the near future.
|
||||
if (!aTab.pluginDoorhangerTimeout) {
|
||||
aTab.pluginDoorhangerTimeout = setTimeout(function() {
|
||||
if (this.shouldShowPluginDoorhanger) {
|
||||
PluginHelper.showDoorHanger(this);
|
||||
}
|
||||
}.bind(aTab), 500);
|
||||
}
|
||||
|
||||
PluginHelper.delayAndShowDoorHanger(aTab);
|
||||
} else {
|
||||
// There's a large enough visible overlay that we don't need to show
|
||||
// the doorhanger.
|
||||
@ -6313,6 +6315,24 @@ var PluginHelper = {
|
||||
|
||||
case "PluginPlayPreview": {
|
||||
let previewContent = doc.getAnonymousElementByAttribute(plugin, "class", "previewPluginContent");
|
||||
let pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
|
||||
let mimeType = PluginHelper.getPluginMimeType(plugin);
|
||||
let playPreviewInfo = pluginHost.getPlayPreviewInfo(mimeType);
|
||||
|
||||
if (!playPreviewInfo.ignoreCTP) {
|
||||
// Check if plugins have already been activated for this page, or if
|
||||
// the user has set a permission to always play plugins on the site
|
||||
if (aTab.clickToPlayPluginsActivated ||
|
||||
Services.perms.testPermission(aTab.browser.currentURI, "plugins") ==
|
||||
Services.perms.ALLOW_ACTION) {
|
||||
PluginHelper.playPlugin(plugin);
|
||||
return;
|
||||
}
|
||||
|
||||
// Always show door hanger for play preview plugins
|
||||
PluginHelper.delayAndShowDoorHanger(aTab);
|
||||
}
|
||||
|
||||
let iframe = previewContent.getElementsByClassName("previewPluginContentFrame")[0];
|
||||
if (!iframe) {
|
||||
// lazy initialization of the iframe
|
||||
@ -6320,9 +6340,7 @@ var PluginHelper = {
|
||||
iframe.className = "previewPluginContentFrame";
|
||||
previewContent.appendChild(iframe);
|
||||
}
|
||||
let mimeType = PluginHelper.getPluginMimeType(plugin);
|
||||
let playPreviewUri = "data:application/x-moz-playpreview;," + mimeType;
|
||||
iframe.src = playPreviewUri;
|
||||
iframe.src = playPreviewInfo.redirectURL;
|
||||
|
||||
// MozPlayPlugin event can be dispatched from the extension chrome
|
||||
// code to replace the preview content with the native plugin
|
||||
|
Loading…
Reference in New Issue
Block a user