Bug 1444436: Use DOM APIs rather than HTML string generation for GMP plugin descriptions. r?aswan draft
authorKris Maglione <maglione.k@gmail.com>
Thu, 15 Mar 2018 12:27:34 -0700
changeset 768176 b903e7588e9bc3a66e0abd523742cca3db7599e5
parent 767843 6ed4300a066b74d9f7dc2a8c24062f6691c11edb
push id102815
push usermaglione.k@gmail.com
push dateThu, 15 Mar 2018 19:27:54 +0000
reviewersaswan
bugs1444436
milestone61.0a1
Bug 1444436: Use DOM APIs rather than HTML string generation for GMP plugin descriptions. r?aswan MozReview-Commit-ID: GMBT4OZnQKz
toolkit/mozapps/extensions/content/extensions.js
toolkit/mozapps/extensions/internal/GMPProvider.jsm
--- a/toolkit/mozapps/extensions/content/extensions.js
+++ b/toolkit/mozapps/extensions/content/extensions.js
@@ -2773,27 +2773,22 @@ var gDetailView = {
     } else {
       screenshotbox.hidden = true;
     }
 
     var desc = document.getElementById("detail-desc");
     desc.textContent = aAddon.description;
 
     var fullDesc = document.getElementById("detail-fulldesc");
-    if (aAddon.fullDescription) {
-      // The following is part of an awful hack to include the licenses for GMP
-      // plugins without having bug 624602 fixed yet, and intentionally ignores
-      // localisation.
-      if (aAddon.isGMPlugin) {
-        // eslint-disable-next-line no-unsanitized/property
-        fullDesc.unsafeSetInnerHTML(aAddon.fullDescription);
-      } else {
-        fullDesc.textContent = aAddon.fullDescription;
-      }
-
+    if (aAddon.getFullDescription) {
+      fullDesc.textContent = "";
+      fullDesc.append(aAddon.getFullDescription(document));
+      fullDesc.hidden = false;
+    } else if (aAddon.fullDescription) {
+      fullDesc.textContent = aAddon.fullDescription;
       fullDesc.hidden = false;
     } else {
       fullDesc.hidden = true;
     }
 
     var contributions = document.getElementById("detail-contributions");
     if ("contributionURL" in aAddon && aAddon.contributionURL) {
       contributions.hidden = false;
--- a/toolkit/mozapps/extensions/internal/GMPProvider.jsm
+++ b/toolkit/mozapps/extensions/internal/GMPProvider.jsm
@@ -24,16 +24,18 @@ ChromeUtils.defineModuleGetter(
   this, "setTimeout", "resource://gre/modules/Timer.jsm");
 
 const URI_EXTENSION_STRINGS  = "chrome://mozapps/locale/extensions/extensions.properties";
 
 const SEC_IN_A_DAY           = 24 * 60 * 60;
 // How long to wait after a user enabled EME before attempting to download CDMs.
 const GMP_CHECK_DELAY        = 10 * 1000; // milliseconds
 
+const XHTML = "http://www.w3.org/1999/xhtml";
+
 const NS_GRE_DIR             = "GreD";
 const CLEARKEY_PLUGIN_ID     = "gmp-clearkey";
 const CLEARKEY_VERSION       = "0.1";
 
 const GMP_LICENSE_INFO       = "gmp_license_info";
 const GMP_PRIVACY_INFO       = "gmp_privacy_info";
 const GMP_LEARN_MORE         = "learn_more_label";
 
@@ -90,18 +92,19 @@ function configureLogging() {
 }
 
 
 
 /**
  * The GMPWrapper provides the info for the various GMP plugins to public
  * callers through the API.
  */
-function GMPWrapper(aPluginInfo) {
+function GMPWrapper(aPluginInfo, aRawPluginInfo) {
   this._plugin = aPluginInfo;
+  this._rawPlugin = aRawPluginInfo;
   this._log =
     Log.repository.getLoggerWithMessagePrefix("Toolkit.GMP",
                                               "GMPWrapper(" +
                                               this._plugin.id + ") ");
   Services.prefs.addObserver(GMPPrefs.getPrefKey(GMPPrefs.KEY_PLUGIN_ENABLED,
                                                  this._plugin.id),
                              this, true);
   Services.prefs.addObserver(GMPPrefs.getPrefKey(GMPPrefs.KEY_PLUGIN_VERSION,
@@ -135,17 +138,41 @@ GMPWrapper.prototype = {
   get id() { return this._plugin.id; },
   get type() { return "plugin"; },
   get isGMPlugin() { return true; },
   get name() { return this._plugin.name; },
   get creator() { return null; },
   get homepageURL() { return this._plugin.homepageURL; },
 
   get description() { return this._plugin.description; },
-  get fullDescription() { return this._plugin.fullDescription; },
+  get fullDescription() { return null; },
+
+  getFullDescription(doc) {
+    let plugin = this._rawPlugin;
+
+    let frag = doc.createDocumentFragment();
+    for (let [urlProp, labelId] of [["learnMoreURL", GMP_LEARN_MORE],
+                                    ["licenseURL", this.id == WIDEVINE_ID ?
+                                     GMP_PRIVACY_INFO : GMP_LICENSE_INFO]]) {
+      if (plugin[urlProp]) {
+        let a = doc.createElementNS(XHTML, "a");
+        a.href = plugin[urlProp];
+        a.target = "_blank";
+        a.textContent = pluginsBundle.GetStringFromName(labelId);
+
+        if (frag.childElementCount) {
+          frag.append(doc.createElementNS(XHTML, "br"),
+                      doc.createElementNS(XHTML, "br"));
+        }
+        frag.append(a);
+      }
+    }
+
+    return frag;
+  },
 
   get version() {
     return GMPPrefs.getString(GMPPrefs.KEY_PLUGIN_VERSION, null, this._plugin.id);
   },
 
   get isActive() {
     return !this.appDisabled &&
            !this.userDisabled &&
@@ -628,43 +655,29 @@ var GMPProvider = {
 
     aCallback(results);
   },
 
   get isEnabled() {
     return GMPPrefs.getBool(GMPPrefs.KEY_PROVIDER_ENABLED, false);
   },
 
-  generateFullDescription(aPlugin) {
-    let rv = [];
-    for (let [urlProp, labelId] of [["learnMoreURL", GMP_LEARN_MORE],
-                                    ["licenseURL", aPlugin.id == WIDEVINE_ID ?
-                                     GMP_PRIVACY_INFO : GMP_LICENSE_INFO]]) {
-      if (aPlugin[urlProp]) {
-        let label = pluginsBundle.GetStringFromName(labelId);
-        rv.push(`<xhtml:a href="${aPlugin[urlProp]}" target="_blank">${label}</xhtml:a>.`);
-      }
-    }
-    return rv.length ? rv.join("<xhtml:br /><xhtml:br />") : undefined;
-  },
-
   buildPluginList() {
     this._plugins = new Map();
     for (let aPlugin of GMP_PLUGINS) {
       let plugin = {
         id: aPlugin.id,
         name: pluginsBundle.GetStringFromName(aPlugin.name),
         description: pluginsBundle.GetStringFromName(aPlugin.description),
         homepageURL: aPlugin.homepageURL,
         optionsURL: aPlugin.optionsURL,
         wrapper: null,
         isEME: aPlugin.isEME,
       };
-      plugin.fullDescription = this.generateFullDescription(aPlugin);
-      plugin.wrapper = new GMPWrapper(plugin);
+      plugin.wrapper = new GMPWrapper(plugin, aPlugin);
       this._plugins.set(plugin.id, plugin);
     }
   },
 
   ensureProperCDMInstallState() {
     if (!GMPPrefs.getBool(GMPPrefs.KEY_EME_ENABLED, true)) {
       for (let plugin of this._plugins.values()) {
         if (plugin.isEME && plugin.wrapper.isInstalled) {