bug 1289802 - Replace 'install flash' content with click to play UI when flash is click to play r=mconley

This commit is contained in:
Brad Lassey 2016-07-26 22:16:37 -04:00
Родитель 726beea43f
Коммит 5c6b1c9a7e
6 изменённых файлов: 102 добавлений и 19 удалений

Просмотреть файл

@ -27,6 +27,9 @@ this.PluginContent = function (global) {
this.init(global);
}
const FLASH_MIME_TYPE = "application/x-shockwave-flash";
const REPLACEMENT_STYLE_SHEET = Services.io.newURI("chrome://pluginproblem/content/pluginReplaceBinding.css", null, null);
PluginContent.prototype = {
init: function (global) {
this.global = global;
@ -39,6 +42,7 @@ PluginContent.prototype = {
// Note that the XBL binding is untrusted
global.addEventListener("PluginBindingAttached", this, true, true);
global.addEventListener("PluginPlaceholderReplaced", this, true, true);
global.addEventListener("PluginCrashed", this, true);
global.addEventListener("PluginOutdated", this, true);
global.addEventListener("PluginInstantiated", this, true);
@ -62,6 +66,7 @@ PluginContent.prototype = {
let global = this.global;
global.removeEventListener("PluginBindingAttached", this, true);
global.removeEventListener("PluginPlaceholderReplaced", this, true, true);
global.removeEventListener("PluginCrashed", this, true);
global.removeEventListener("PluginOutdated", this, true);
global.removeEventListener("PluginInstantiated", this, true);
@ -174,6 +179,15 @@ PluginContent.prototype = {
},
_getPluginInfo: function (pluginElement) {
if (pluginElement instanceof Ci.nsIDOMHTMLAnchorElement) {
// Anchor elements are our place holders, and we only have them for Flash
let pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
return {
pluginName: "Shockwave Flash",
mimetype: FLASH_MIME_TYPE,
permissionString: pluginHost.getPermissionStringForType(FLASH_MIME_TYPE)
};
}
let pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
pluginElement.QueryInterface(Ci.nsIObjectLoadingContent);
@ -421,16 +435,38 @@ PluginContent.prototype = {
}
if (eventType == "HiddenPlugin") {
let pluginTag = event.tag.QueryInterface(Ci.nsIPluginTag);
if (event.target.defaultView.top.document != this.content.document) {
return;
let win = event.target.defaultView;
if (!win.mozHiddenPluginTouched) {
let pluginTag = event.tag.QueryInterface(Ci.nsIPluginTag);
if (win.top.document != this.content.document) {
return;
}
this._showClickToPlayNotification(pluginTag, false);
let winUtils = win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
try {
winUtils.loadSheet(REPLACEMENT_STYLE_SHEET, win.AGENT_SHEET);
win.mozHiddenPluginTouched = true;
} catch (e) {
Cu.reportError("Error adding plugin replacement style sheet: " + e);
}
}
this._showClickToPlayNotification(pluginTag, false);
}
let plugin = event.target;
let doc = plugin.ownerDocument;
if (eventType == "PluginPlaceholderReplaced") {
plugin.removeAttribute("href");
let overlay = this.getPluginUI(plugin, "main");
this.setVisibility(plugin, overlay, true);
let inIDOMUtils = Cc["@mozilla.org/inspector/dom-utils;1"]
.getService(Ci.inIDOMUtils);
// Add psuedo class so our styling will take effect
inIDOMUtils.addPseudoClassLock(plugin, "-moz-handler-clicktoplay");
overlay.addEventListener("click", this, true);
return;
}
if (!(plugin instanceof Ci.nsIObjectLoadingContent))
return;
@ -509,7 +545,7 @@ PluginContent.prototype = {
break;
}
if (this._getPluginInfo(plugin).mimetype === "application/x-shockwave-flash") {
if (this._getPluginInfo(plugin).mimetype === FLASH_MIME_TYPE) {
this._recordFlashPluginTelemetry(eventType, plugin);
}
@ -661,12 +697,19 @@ PluginContent.prototype = {
_handleClickToPlayEvent: function (plugin) {
let doc = plugin.ownerDocument;
let pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
// guard against giving pluginHost.getPermissionStringForType a type
// not associated with any known plugin
if (!this.isKnownPlugin(objLoadingContent))
return;
let permissionString = pluginHost.getPermissionStringForType(objLoadingContent.actualType);
let permissionString;
if (plugin instanceof Ci.nsIDOMHTMLAnchorElement) {
// We only have replacement content for Flash installs
permissionString = pluginHost.getPermissionStringForType(FLASH_MIME_TYPE);
} else {
let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
// guard against giving pluginHost.getPermissionStringForType a type
// not associated with any known plugin
if (!this.isKnownPlugin(objLoadingContent))
return;
permissionString = pluginHost.getPermissionStringForType(objLoadingContent.actualType);
}
let principal = doc.defaultView.top.document.nodePrincipal;
let pluginPermission = Services.perms.testPermissionFromPrincipal(principal, permissionString);
@ -688,7 +731,6 @@ PluginContent.prototype = {
let document = event.target.ownerDocument;
let plugin = document.getBindingParent(event.target);
let contentWindow = plugin.ownerGlobal.top;
let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
let overlay = this.getPluginUI(plugin, "main");
// Have to check that the target is not the link to update the plugin
if (!(event.originalTarget instanceof contentWindow.HTMLAnchorElement) &&
@ -729,6 +771,7 @@ PluginContent.prototype = {
let pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
let pluginFound = false;
let placeHolderFound = false;
for (let plugin of plugins) {
plugin.QueryInterface(Ci.nsIObjectLoadingContent);
if (!this.isKnownPlugin(plugin)) {
@ -736,7 +779,11 @@ PluginContent.prototype = {
}
if (pluginInfo.permissionString == pluginHost.getPermissionStringForType(plugin.actualType)) {
let overlay = this.getPluginUI(plugin, "main");
pluginFound = true;
if (plugin instanceof Ci.nsIDOMHTMLAnchorElement) {
placeHolderFound = true;
} else {
pluginFound = true;
}
if (newState == "block") {
if (overlay) {
overlay.addEventListener("click", this, true);
@ -751,11 +798,12 @@ PluginContent.prototype = {
}
}
// If there are no instances of the plugin on the page any more or if we've
// noted that the content needs to be reloaded due to replacing HLS, what the
// user probably needs is for us to allow and then refresh.
// If there are no instances of the plugin on the page any more, what the
// user probably needs is for us to allow and then refresh. Additionally, if
// this is content that requires HLS or we replaced the placeholder the page
// needs to be refreshed for it to insert its plugins
if (newState != "block" &&
(!pluginFound || contentWindow.pluginRequiresReload)) {
(!pluginFound || placeHolderFound || contentWindow.pluginRequiresReload)) {
this.reloadPage();
}
this.updateNotificationUI();

Просмотреть файл

@ -78,4 +78,13 @@
</constructor>
</implementation>
</binding>
<binding id="replacement" extends="chrome://pluginproblem/content/pluginProblem.xml#pluginProblem" inheritstyle="false" chromeOnlyContent="true" bindToUntrustedContent="true">
<implementation>
<constructor>
this.dispatchEvent(new CustomEvent("PluginPlaceholderReplaced"));
</constructor>
</implementation>
</binding>
</bindings>

Просмотреть файл

@ -20,6 +20,7 @@ html|applet:not([height]), html|applet[height=""] {
height: 200px;
}
a .mainBox,
:-moz-type-unsupported .mainBox,
:-moz-type-unsupported-platform .mainBox,
:-moz-handler-clicktoplay .mainBox,
@ -29,6 +30,7 @@ html|applet:not([height]), html|applet[height=""] {
:-moz-handler-blocked .mainBox {
-moz-user-focus: normal;
}
a .mainBox:focus,
:-moz-type-unsupported .mainBox:focus,
:-moz-type-unsupported-platform .mainBox:focus,
:-moz-handler-clicktoplay .mainBox:focus,
@ -71,6 +73,7 @@ html|applet:not([height]), html|applet[height=""] {
direction: rtl;
}
a .hoverBox,
:-moz-handler-clicktoplay .hoverBox,
:-moz-handler-vulnerable-updatable .hoverBox,
:-moz-handler-vulnerable-no-update .hoverBox {
@ -88,6 +91,8 @@ html|applet:not([height]), html|applet[height=""] {
display: none;
}
a .msgClickToPlay,
a .msgTapToPlay,
:-moz-type-unsupported .msgUnsupported,
:-moz-type-unsupported-platform .msgUnsupportedPlatform,
:-moz-handler-clicktoplay .msgClickToPlay,

Просмотреть файл

@ -0,0 +1,17 @@
/* 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/. */
@namespace url(http://www.w3.org/1999/xhtml); /* set default namespace to HTML */
a[href='https://get.adobe.com/flashplayer/'],
a[href='http://get.adobe.com/flashplayer/'],
a[href='https://get.adobe.com/flashplayer'],
a[href='http://get.adobe.com/flashplayer'],
a[href='https://www.adobe.com/go/getflash/'],
a[href='http://www.adobe.com/go/getflash/'] {
display: inline-block;
overflow: hidden;
opacity: 1 !important;
-moz-binding: url('chrome://pluginproblem/content/pluginProblem.xml#replacement') !important;
}

Просмотреть файл

@ -7,4 +7,5 @@ toolkit.jar:
pluginproblem/pluginProblem.xml (content/pluginProblem.xml)
pluginproblem/pluginProblemContent.css (content/pluginProblemContent.css)
pluginproblem/pluginProblemBinding.css (content/pluginProblemBinding.css)
pluginproblem/pluginReplaceBinding.css (content/pluginReplaceBinding.css)
pluginproblem/pluginFinderBinding.css (content/pluginFinderBinding.css)

Просмотреть файл

@ -78,6 +78,7 @@ html|a {
:-moz-handler-blocked .icon {
background-image: url(chrome://mozapps/skin/plugins/contentPluginBlocked.png);
}
a .icon,
:-moz-handler-clicktoplay .icon {
background-image: url(chrome://mozapps/skin/plugins/contentPluginActivate.png);
-moz-user-focus: normal;
@ -108,13 +109,15 @@ html|a {
}
@media not all and (-moz-touch-enabled) {
:-moz-handler-clicktoplay .msgTapToPlay {
:-moz-handler-clicktoplay .msgTapToPlay,
a .msgTapToPlay {
display: none;
}
}
@media (-moz-touch-enabled) {
:-moz-handler-clicktoplay .msgClickToPlay {
:-moz-handler-clicktoplay .msgClickToPlay,
a .msgClickToPlay {
display: none;
}
}