Bug 1638822 - convert openpgp strings to Fluent - part 4 - jsm files continue. r=mkmelin a=wsmwk
authorKhushil Mistry <khushil324@gmail.com>
Thu, 18 Jun 2020 13:55:06 +0300
changeset 39437 877b593dafb5fb1f57356482c968aced8c637e79
parent 39436 f001e566656e87a650c6122fe2d838b76701d832
child 39438 ba230614672e3f9ca567e11c4dec35d12bbd2882
push id402
push userclokep@gmail.com
push dateMon, 29 Jun 2020 20:48:04 +0000
reviewersmkmelin, wsmwk
bugs1638822
Bug 1638822 - convert openpgp strings to Fluent - part 4 - jsm files continue. r=mkmelin a=wsmwk
mail/extensions/openpgp/content/modules/cryptoAPI/GnuPGCryptoAPI.jsm
mail/extensions/openpgp/content/modules/cryptoAPI/gnupg-keylist.jsm
mail/extensions/openpgp/content/modules/errorHandling.jsm
mail/extensions/openpgp/content/modules/keyLookupHelper.jsm
mail/extensions/openpgp/content/modules/keyRing.jsm
mail/extensions/openpgp/content/modules/trust.jsm
mail/extensions/openpgp/content/modules/windows.jsm
mail/extensions/openpgp/content/strings/enigmail.ftl
mail/extensions/openpgp/content/strings/enigmail.properties
mail/extensions/openpgp/content/ui/commonWorkflows.js
mail/extensions/openpgp/content/ui/enigmailKeyManager.js
mail/extensions/openpgp/content/ui/enigmailKeygen.js
mail/extensions/openpgp/content/ui/keyDetailsDlg.js
--- a/mail/extensions/openpgp/content/modules/cryptoAPI/GnuPGCryptoAPI.jsm
+++ b/mail/extensions/openpgp/content/modules/cryptoAPI/GnuPGCryptoAPI.jsm
@@ -17,19 +17,18 @@ Services.scriptloader.loadSubScript(
 ); /* global CryptoAPI */
 
 const { EnigmailLog } = ChromeUtils.import(
   "chrome://openpgp/content/modules/log.jsm"
 );
 const { EnigmailConstants } = ChromeUtils.import(
   "chrome://openpgp/content/modules/constants.jsm"
 );
-const { EnigmailLocale } = ChromeUtils.import(
-  "chrome://openpgp/content/modules/locale.jsm"
-);
+
+const l10n = new Localization(["messenger/openpgp/enigmail.ftl"], true);
 
 const {
   obtainKeyList,
   getPhotoFileFromGnuPG,
   getGpgKeyData,
 } = ChromeUtils.import(
   "chrome://openpgp/content/modules/cryptoAPI/gnupg-keylist.jsm"
 );
@@ -137,17 +136,17 @@ class GnuPGCryptoAPI extends CryptoAPI {
    *   - {String} errorMsg:  error message in case exitCode !== 0
    */
 
   async extractSecretKey(keyId, minimalKey) {
     let ret = await GnuPG_extractSecretKey(keyId, minimalKey);
 
     if (ret.exitCode !== 0) {
       ret.errorMsg =
-        EnigmailLocale.getString("failKeyExtract") + "\n" + ret.errorMsg;
+        (await l10n.formatValue("fail-key-extract")) + "\n" + ret.errorMsg;
     }
     return ret;
   }
 
   /**
    *
    * @param {byte} byteData    The encrypted data
    *
--- a/mail/extensions/openpgp/content/modules/cryptoAPI/gnupg-keylist.jsm
+++ b/mail/extensions/openpgp/content/modules/cryptoAPI/gnupg-keylist.jsm
@@ -24,19 +24,16 @@ const { EnigmailLog } = ChromeUtils.impo
   "chrome://openpgp/content/modules/log.jsm"
 );
 const { EnigmailTrust } = ChromeUtils.import(
   "chrome://openpgp/content/modules/trust.jsm"
 );
 const { EnigmailData } = ChromeUtils.import(
   "chrome://openpgp/content/modules/data.jsm"
 );
-const { EnigmailLocale } = ChromeUtils.import(
-  "chrome://openpgp/content/modules/locale.jsm"
-);
 
 var l10n = new Localization(["messenger/openpgp/enigmail.ftl"], true);
 
 // field ID's of key list (as described in the doc/DETAILS file in the GnuPG distribution)
 const ENTRY_ID = 0;
 const KEY_TRUST_ID = 1;
 const KEY_SIZE_ID = 2;
 const KEY_ALGO_ID = 3;
@@ -81,17 +78,17 @@ async function obtainKeyList(onlyKeys = 
  *
  * @param keyListString: array of |string| formatted output from GnuPG for key listing
  * @param keyList:    |object| holding the resulting key list
  *                         obj.keyList:     Array holding key objects
  *                         obj.keySortList: Array holding values to make sorting easier
  *
  * no return value
  */
-function appendKeyItems(keyListString, keyList) {
+async function appendKeyItems(keyListString, keyList) {
   EnigmailLog.DEBUG("gnupg-keylist.jsm: appendKeyItems()\n");
   let keyObj = {};
   let uatNum = 0; // counter for photos (counts per key)
 
   const TRUSTLEVELS_SORTED = EnigmailTrust.trustLevelsSorted();
 
   for (let i = 0; i < keyListString.length; i++) {
     let listRow = keyListString[i].split(/:/);
@@ -158,17 +155,17 @@ function appendKeyItems(keyListString, k
           algoSym: ALGO_SYMBOL[listRow[KEY_ALGO_ID]],
           created: EnigmailTime.getDateTime(listRow[CREATED_ID], true, false),
           keyCreated: Number(listRow[CREATED_ID]),
           type: "sub",
         });
         break;
       case "uat":
         if (listRow[USERID_ID].indexOf("1 ") === 0) {
-          const userId = EnigmailLocale.getString("userAtt.photo");
+          const userId = await l10n.formatValue("user-att-photo");
           keyObj.userIds.push({
             userId,
             keyTrust: listRow[KEY_TRUST_ID],
             uidFpr: listRow[UID_ID],
             type: "uat",
             uatNum,
           });
           keyObj.photoAvailable = true;
--- a/mail/extensions/openpgp/content/modules/errorHandling.jsm
+++ b/mail/extensions/openpgp/content/modules/errorHandling.jsm
@@ -6,33 +6,32 @@
 
 "use strict";
 
 var EXPORTED_SYMBOLS = ["EnigmailErrorHandling"];
 
 const { EnigmailLog } = ChromeUtils.import(
   "chrome://openpgp/content/modules/log.jsm"
 );
-const { EnigmailLocale } = ChromeUtils.import(
-  "chrome://openpgp/content/modules/locale.jsm"
-);
 const { EnigmailLazy } = ChromeUtils.import(
   "chrome://openpgp/content/modules/lazy.jsm"
 );
 
 const getEnigmailKeyRing = EnigmailLazy.loader(
   "enigmail/keyRing.jsm",
   "EnigmailKeyRing"
 );
 const getEnigmailFiles = EnigmailLazy.loader(
   "enigmail/files.jsm",
   "EnigmailFiles"
 );
 const getEnigmailRNG = EnigmailLazy.loader("enigmail/rng.jsm", "EnigmailRNG");
 
+const l10n = new Localization(["messenger/openpgp/enigmail.ftl"], true);
+
 var EnigmailErrorHandling = {
   /**
    * Determin why a given key or userID cannot be used for signing
    *
    * @param keySpec String - key ID or user ID
    *
    * @return String - the reason(s) as message to display to the user
    *                  "" in case the key is valid
@@ -42,36 +41,35 @@ var EnigmailErrorHandling = {
       "errorHandling.jsm: determineInvSignReason: keySpec: " + keySpec + "\n"
     );
 
     let reasonMsg = "";
 
     if (keySpec.search(/^(0x)?[0-9A-F]+$/) === 0) {
       let key = getEnigmailKeyRing().getKeyById(keySpec);
       if (!key) {
-        reasonMsg = EnigmailLocale.getString("keyError.keyIdNotFound", keySpec);
-      } else {
-        let r = key.getSigningValidity();
-        if (!r.keyValid) {
-          reasonMsg = r.reason;
-        }
+        return l10n.formatValueSync("key-error-key-id-not-found", {
+          keySpec,
+        });
+      }
+      let r = key.getSigningValidity();
+      if (!r.keyValid) {
+        reasonMsg = r.reason;
       }
     } else {
       let keys = getEnigmailKeyRing().getKeysByUserId(keySpec);
       if (!keys || keys.length === 0) {
-        reasonMsg = EnigmailLocale.getString(
-          "keyError.keySpecNotFound",
-          keySpec
-        );
-      } else {
-        for (let i in keys) {
-          let r = keys[i].getSigningValidity();
-          if (!r.keyValid) {
-            reasonMsg += r.reason + "\n";
-          }
+        return l10n.formatValueSync("key-error-key-spec-not-found", {
+          keySpec,
+        });
+      }
+      for (let i in keys) {
+        let r = keys[i].getSigningValidity();
+        if (!r.keyValid) {
+          reasonMsg += r.reason + "\n";
         }
       }
     }
 
     return reasonMsg;
   },
 
   /**
@@ -87,36 +85,35 @@ var EnigmailErrorHandling = {
       "errorHandling.jsm: determineInvRcptReason: keySpec: " + keySpec + "\n"
     );
 
     let reasonMsg = "";
 
     if (keySpec.search(/^(0x)?[0-9A-F]+$/) === 0) {
       let key = getEnigmailKeyRing().getKeyById(keySpec);
       if (!key) {
-        reasonMsg = EnigmailLocale.getString("keyError.keyIdNotFound", keySpec);
-      } else {
-        let r = key.getEncryptionValidity();
-        if (!r.keyValid) {
-          reasonMsg = r.reason;
-        }
+        return l10n.formatValueSync("key-error-key-id-not-found", {
+          keySpec,
+        });
+      }
+      let r = key.getEncryptionValidity();
+      if (!r.keyValid) {
+        reasonMsg = r.reason;
       }
     } else {
       let keys = getEnigmailKeyRing().getKeysByUserId(keySpec);
       if (!keys || keys.length === 0) {
-        reasonMsg = EnigmailLocale.getString(
-          "keyError.keySpecNotFound",
-          keySpec
-        );
-      } else {
-        for (let i in keys) {
-          let r = keys[i].getEncryptionValidity();
-          if (!r.keyValid) {
-            reasonMsg += r.reason + "\n";
-          }
+        return l10n.formatValueSync("key-error-key-spec-not-found", {
+          keySpec,
+        });
+      }
+      for (let i in keys) {
+        let r = keys[i].getEncryptionValidity();
+        if (!r.keyValid) {
+          reasonMsg += r.reason + "\n";
         }
       }
     }
 
     return reasonMsg;
   },
 
   /**
--- a/mail/extensions/openpgp/content/modules/keyLookupHelper.jsm
+++ b/mail/extensions/openpgp/content/modules/keyLookupHelper.jsm
@@ -25,16 +25,18 @@ var { EnigmailKeyserverURIs } = ChromeUt
 );
 var EnigmailLocale = ChromeUtils.import(
   "chrome://openpgp/content/modules/locale.jsm"
 ).EnigmailLocale;
 var EnigmailWkdLookup = ChromeUtils.import(
   "chrome://openpgp/content/modules/wkdLookup.jsm"
 ).EnigmailWkdLookup;
 
+const l10n = new Localization(["messenger/openpgp/enigmail.ftl"], true);
+
 var KeyLookupHelper = {
   async lookupAndImportOnKeyserver(
     window,
     identifier,
     giveFeedbackToUser,
     whenDoneCB
   ) {
     let defKs = EnigmailKeyserverURIs.getDefaultKeyServer();
@@ -112,12 +114,14 @@ var KeyLookupHelper = {
         window,
         email,
         giveFeedbackToUser,
         whenDoneCB
       );
     }
 
     if (!somethingWasImported) {
-      EnigmailDialog.alert(window, EnigmailLocale.getString("noKeyFound"));
+      l10n.formatValue("no-key-found").then(value => {
+        EnigmailDialog.alert(window, value);
+      });
     }
   },
 };
--- a/mail/extensions/openpgp/content/modules/keyRing.jsm
+++ b/mail/extensions/openpgp/content/modules/keyRing.jsm
@@ -501,33 +501,33 @@ var EnigmailKeyRing = {
       throw new Error(
         "keyRing.jsm: EnigmailKeyRing.extractKey: multiple IDs not yet implemented"
       );
     }
 
     const cApi = EnigmailCryptoAPI();
     let keyBlock = cApi.sync(cApi.getPublicKey(idArray[0]));
     if (!keyBlock) {
-      errorMsgObj.value = EnigmailLocale.getString("failKeyExtract");
+      errorMsgObj.value = l10n.formatValueSync("fail-key-extract");
       return "";
     }
 
     exitCodeObj.value = 0;
     if (outputFile) {
       if (
         !EnigmailFiles.writeFileContents(
           outputFile,
           keyBlock,
           DEFAULT_FILE_PERMS
         )
       ) {
         exitCodeObj.value = -1;
-        errorMsgObj.value = EnigmailLocale.getString("fileWriteFailed", [
-          outputFile,
-        ]);
+        errorMsgObj.value = l10n.formatValueSync("file-write-failed", {
+          output: outputFile,
+        });
       }
       return "";
     }
     return keyBlock;
   },
 
   /**
    * import key from provided key data (synchronous)
@@ -618,35 +618,35 @@ var EnigmailKeyRing = {
         {}
       );
       if (!blockType) {
         errorMsgObj.value = EnigmailLocale.getString("noPGPblock");
         return 1;
       }
 
       if (blockType.search(/^(PUBLIC|PRIVATE) KEY BLOCK$/) !== 0) {
-        errorMsgObj.value = EnigmailLocale.getString("notFirstBlock");
+        errorMsgObj.value = l10n.formatValueSync("not-first-block");
         return 1;
       }
 
       pgpBlock = keyBlock.substr(
         beginIndexObj.value,
         endIndexObj.value - beginIndexObj.value + 1
       );
     }
 
     if (isInteractive) {
       if (
         !getDialog().confirmDlg(
           parent,
-          EnigmailLocale.getString("importKeyConfirm"),
+          l10n.formatValueSync("import-key-confirm"),
           l10n.formatValueSync("key-man-button-import")
         )
       ) {
-        errorMsgObj.value = EnigmailLocale.getString("failCancel");
+        errorMsgObj.value = l10n.formatValueSync("fail-cancel");
         return -1;
       }
     }
 
     if (limitedUids.length > 0) {
       throw new Error(
         "importKeyAsync with limitedUids: not implemented " + limitedUids
       );
@@ -734,24 +734,25 @@ var EnigmailKeyRing = {
           console.debug(ex);
         }
 
         if (exitStatus === 0) {
           let keyList = preview.map(a => a.id);
           getDialog().keyImportDlg(window, keyList);
           somethingWasImported = true;
         } else {
-          getDialog().alert(
-            window,
-            EnigmailLocale.getString("failKeyImport") + "\n" + errorMsgObj.value
-          );
+          l10n.formatValue("fail-key-import").then(value => {
+            getDialog().alert(window, value + "\n" + errorMsgObj.value);
+          });
         }
       }
     } else {
-      getDialog().alert(window, EnigmailLocale.getString("noKeyFound"));
+      l10n.formatValue("no-key-found").then(value => {
+        getDialog().alert(window, value);
+      });
     }
     return somethingWasImported;
   },
 
   /**
    * Generate a new key pair with GnuPG
    *
    * @name:       String     - name part of UID
--- a/mail/extensions/openpgp/content/modules/trust.jsm
+++ b/mail/extensions/openpgp/content/modules/trust.jsm
@@ -3,19 +3,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at https://mozilla.org/MPL/2.0/.
  */
 
 "use strict";
 
 var EXPORTED_SYMBOLS = ["EnigmailTrust"];
 
-const { EnigmailLocale } = ChromeUtils.import(
-  "chrome://openpgp/content/modules/locale.jsm"
-);
+const l10n = new Localization(["messenger/openpgp/enigmail.ftl"], true);
 
 // trust flags according to GPG documentation:
 // - https://www.gnupg.org/documentation/manuals/gnupg.pdf
 // - sources: doc/DETAILS
 // In the order of trustworthy:
 //  ---------------------------------------------------------
 //  i = The key is invalid (e.g. due to a missing self-signature)
 //  n = The key is not valid / Never trust this key
@@ -69,46 +67,36 @@ var EnigmailTrust = {
 
     return keyObj.keyTrust;
   },
 
   getTrustLabel(trustCode) {
     let keyTrust;
     switch (trustCode) {
       case "q":
-        keyTrust = EnigmailLocale.getString("keyValid.unknown");
-        break;
+        return l10n.formatValueSync("key-valid-unknown");
       case "i":
-        keyTrust = EnigmailLocale.getString("keyValid.invalid");
-        break;
+        return l10n.formatValueSync("key-valid-invalid");
       case "d":
       case "D":
-        keyTrust = EnigmailLocale.getString("keyValid.disabled");
-        break;
+        return l10n.formatValueSync("key-valid-disabled");
       case "r":
-        keyTrust = EnigmailLocale.getString("keyValid.revoked");
-        break;
+        return l10n.formatValueSync("key-valid-revoked");
       case "e":
-        keyTrust = EnigmailLocale.getString("keyValid.expired");
-        break;
+        return l10n.formatValueSync("key-valid-expired");
       case "n":
-        keyTrust = EnigmailLocale.getString("keyTrust.untrusted");
-        break;
+        return l10n.formatValueSync("key-trust-untrusted");
       case "m":
-        keyTrust = EnigmailLocale.getString("keyTrust.marginal");
-        break;
+        return l10n.formatValueSync("key-trust-marginal");
       case "f":
-        keyTrust = EnigmailLocale.getString("keyTrust.full");
-        break;
+        return l10n.formatValueSync("key-trust-full");
       case "u":
-        keyTrust = EnigmailLocale.getString("keyTrust.ultimate");
-        break;
+        return l10n.formatValueSync("key-trust-ultimate");
       case "g":
-        keyTrust = EnigmailLocale.getString("keyTrust.group");
-        break;
+        return l10n.formatValueSync("key-trust-group");
       case "-":
         keyTrust = "-";
         break;
       default:
         keyTrust = "";
     }
     return keyTrust;
   },
--- a/mail/extensions/openpgp/content/modules/windows.jsm
+++ b/mail/extensions/openpgp/content/modules/windows.jsm
@@ -21,16 +21,18 @@ const { EnigmailLocale } = ChromeUtils.i
 );
 const { EnigmailKeyRing } = ChromeUtils.import(
   "chrome://openpgp/content/modules/keyRing.jsm"
 );
 const { EnigmailStdlib } = ChromeUtils.import(
   "chrome://openpgp/content/modules/stdlib.jsm"
 );
 
+const l10n = new Localization(["messenger/openpgp/enigmail.ftl"], true);
+
 var EnigmailWindows = {
   /**
    * Open a window, or focus it if it is already open
    *
    * @winName   : String - name of the window; used to identify if it is already open
    * @spec      : String - window URL (e.g. chrome://openpgp/content/ui/test.xhtml)
    * @winOptions: String - window options as defined in nsIWindow.open
    * @optObj    : any    - an Object, Array, String, etc. that is passed as parameter
@@ -461,17 +463,19 @@ var EnigmailWindows = {
     EnigmailLog.DEBUG(
       "windows.jsm: downloadKeys: searchList=" + inputObj.searchList + "\n"
     );
 
     resultObj.importedKeys = 0;
 
     const ioService = Services.io;
     if (ioService && ioService.offline) {
-      EnigmailWindows.alert(win, EnigmailLocale.getString("needOnline"));
+      l10n.formatValue("need-online").then(value => {
+        EnigmailWindows.alert(win, value);
+      });
       return;
     }
 
     let valueObj = {};
     if (inputObj.searchList) {
       valueObj = {
         keyId: "<" + inputObj.searchList.join("> <") + ">",
       };
--- a/mail/extensions/openpgp/content/strings/enigmail.ftl
+++ b/mail/extensions/openpgp/content/strings/enigmail.ftl
@@ -271,16 +271,27 @@ copy-to-clipbrd-ok = Key(s) copied to cl
 delete-secret-key = WARNING: You are about to delete a secret key!\nIf you delete your secret key, you will no longer be able to decrypt any messages encrypted for that key, nor will you be able to revoke it.\n\nDo you really want to delete BOTH, the secret key and the public key\n'{ $userId }'?
 delete-mix = WARNING: You are about to delete secret keys!\nIf you delete your secret key, you will no longer be able to decrypt any messages encrypted for that key.\n\nDo you really want to delete BOTH, the selected secret and public keys?
 delete-pub-key = Do you want to delete the public key\n'{ $userId }'?
 delete-selected-pub-key = Do you want to delete the public keys?
 refresh-all-question = You did not select any key. Would you like to refresh ALL keys?
 key-man-button-export-sec-key = Export &Secret Keys
 key-man-button-export-pub-key = Export &Public Keys Only
 key-man-button-refresh-all = &Refresh All Keys
+key-man-loading-keys = Loading keys, please wait…
+ascii-armor-file = ASCII Armored Files (*.asc)
+no-key-selected = You should select at least one key in order to perform the selected operation
+export-to-file = Export Public Key To File
+export-keypair-to-file = Export Secret and Public Key To File
+export-secret-key = Do you want to include the secret key in the saved OpenPGP key file?
+save-keys-ok = The keys were successfully saved
+save-keys-failed = Saving the keys failed
+default-pub-key-filename = Exported-public-keys
+default-pub-sec-key-filename = Exported-public-and-secret-keys
+refresh-key-warn = Warning: depending on the number of keys and the connection speed, refreshing all keys could be quite a lengthy process!
 
 # Strings in keyObj.jsm
 key-ring-pub-key-revoked = The key { $userId } (key ID { $keyId }) is revoked.
 key-ring-pub-key-expired = The key { $userId } (key ID { $keyId }) has expired.
 key-ring-key-disabled = The key { $userId } (key ID { $keyId }) is disabled; it cannot be used.
 key-ring-key-invalid = The key { $userId } (key ID { $keyId }) is not valid. Please consider verifying it correctly.
 key-ring-key-not-trusted=The key { $userId } (key ID { $keyId }) is not trusted enough. Please set the trust level of your key to "ultimate" to use it for signing.
 key-ring-no-secret-key = You do not seem to have the secret key for { $userId } (key ID { $keyId }) on your keyring; you cannot use the key for signing.
@@ -290,17 +301,60 @@ key-ring-sign-sub-keys-revoked = All sig
 key-ring-sign-sub-keys-expired = All signing-subkeys of key { $userId } (key ID { $keyId }) have expired.
 key-ring-sign-sub-keys-unusable = All signing-subkeys of key { $userId } (key ID { $keyId }) are revoked, expired or otherwise unusable.
 key-ring-enc-sub-keys-revoked = All encryption subkeys of key { $userId } (key ID { $keyId }) are revoked.
 key-ring-enc-sub-keys-expired = All encryption subkeys of key { $userId } (key ID { $keyId }) have expired.
 key-ring-enc-sub-keys-unusable = All encryption subkeys of key { $userId } (key ID { $keyId }) are revoked, expired or otherwise unusable.
 
 # Strings in gnupg-keylist.jsm
 keyring-photo = Photo
+user-att-photo = User attribute (JPEG image)
 
 # Strings in key.jsm
 revoke-key-question = You are about to revoke the key '{ $userId }'.\n\nYou will no longer be able to sign with this key, and once distributed, others will no longer be able to encrypt with that key. You can still use the key to decrypt old messages.\n\nDo you want to proceed?
 revoke-key-not-present = You have no key (0x{ $keyId }) which matches this revocation certificate!\n\nIf you have lost your key, you must import it (e.g. from a keyserver) before importing the revocation certificate!
 revoke-key-already-revoked = The key 0x{ $keyId } has already been revoked.
 key-man-button-revoke-key = &Revoke Key
 
 # Strings in keyRing.jsm & decryption.jsm
 key-man-button-import = &Import
+
+# Strings used in errorHandling.jsm
+key-error-key-spec-not-found = The email address '{ $keySpec }' cannot be matched to a key on your keyring.
+key-error-key-id-not-found = The configured key ID '{ $keySpec }' cannot be found on your keyring.
+
+# Strings used in enigmailKeyManager.js & windows.jsm
+need-online = The function you have selected is not available in offline mode. Please go online and try again.
+
+# Strings used in keyRing.jsm & keyLookupHelper.jsm
+no-key-found = We could not find any key matching the specified search criteria.
+
+# Strings used in keyRing.jsm & GnuPGCryptoAPI.jsm
+fail-key-extract = Error - key extraction command failed
+
+# Strings used in keyRing.jsm
+fail-cancel = Error - Key receive cancelled by user
+not-first-block = Error - First OpenPGP block not public key block
+import-key-confirm = Import public key(s) embedded in message?
+fail-key-import = Error - key importing failed
+file-write-failed = Failed to write to file { $output }
+
+# Strings used in trust.jsm
+key-valid-unknown = unknown
+key-valid-invalid = invalid
+key-valid-disabled = disabled
+key-valid-revoked = revoked
+key-valid-expired = expired
+key-trust-untrusted = untrusted
+key-trust-marginal = marginal
+key-trust-full = trusted
+key-trust-ultimate = ultimate
+key-trust-group = (group)
+
+# Strings used in commonWorkflows.js
+import-key-file = Import OpenPGP Key File
+gnupg-file = GnuPG Files
+import-keys-failed=Importing the keys failed
+
+# Strings used in enigmailKeygen.js
+save-revoke-cert-as = Create & Save Revocation Certificate
+revoke-cert-ok = The revocation certificate has been successfully created. You can use it to invalidate your public key, e.g. in case you would lose your secret key.
+revoke-cert-failed = The revocation certificate could not be created.
--- a/mail/extensions/openpgp/content/strings/enigmail.properties
+++ b/mail/extensions/openpgp/content/strings/enigmail.properties
@@ -288,34 +288,26 @@ previewFailed=Can't read public key file
 passphrasePrompt=Please enter the passphrase that unlocks the following key: %S
 
 # Strings used in errorHandling.jsm
 ### sc.wrongCardAvailable=The SmartCard %1$S found in your reader cannot be used to process the message.\nPlease insert your SmartCard %2$S and repeat the operation.
 ### sc.insertCard=The operation requires your SmartCard %S.\nPlease insert the required SmartCard and repeat the operation.
 ### sc.removeCard=The operation requires no SmartCard to be in the reader.\nPlease remove your SmartCard and repeat the operation.
 ### sc.noCardAvailable=No SmartCard could be found in your reader\nPlease insert your SmartCard and repeat the operation.
 ### sc.noReaderAvailable=Your SmartCard reader could not be accessed\nPlease attach your SmartCard reader, insert your card, and repeat the operation.
-keyError.keySpecNotFound=The email address '%S' cannot be matched to a key on your keyring.
-keyError.keyIdNotFound=The configured key ID '%S' cannot be found on your keyring.
-keyError.resolutionAction=Please select a valid key in the OpenPGP section of your Account Settings.
+### keyError.resolutionAction=Please select a valid key in the OpenPGP section of your Account Settings.
 ### missingPassphrase=Missing passphrase
 ### errorHandling.gpgAgentInvalid=Your system is running a version of gpg-agent that is not suitable for your GnuPG version.
 ### errorHandling.gpgAgentError=GnuPG reported an error in the communication with gpg-agent (a component of GnuPG).
 ### errorHandling.pinentryError=GnuPG cannot query your passphrase via pinentry.
 
 ### prefGood=Good signature from %S
 ### prefBad=BAD signature from %S
 
-failCancel=Error - Key receive cancelled by user
-failKeyExtract=Error - key extraction command failed
 ### failKeyNoSubkey=No valid (sub-)key
-notFirstBlock=Error - First OpenPGP block not public key block
-importKeyConfirm=Import public key(s) embedded in message?
-failKeyImport=Error - key importing failed
-fileWriteFailed=Failed to write to file %S
 
 ### importKey=Import public key %S from keyserver:
 ### uploadKey=Send public key %S to keyserver:
 ### keyId=Key ID
 ### keyAndSigDate=Key ID: 0x%1$S / Signed on: %2$S
 ### keyFpr=Key fingerprint: %S
 ### noEmailProvided=You did not provide an email address!
 ### keyAlreadySigned=The key is already signed, you cannot sign it twice.
@@ -337,83 +329,49 @@ fileWriteFailed=Failed to write to file 
 ### always=Always
 ### possible=Possible
 ### deleteRule=Really delete the selected rule?
 ### nextRcpt=(Next recipient)
 ### negateRule=Not
 ### addKeyToRule=Add key %1$S (%2$S) to per-recipient rule
 
 # Strings used in enigmailSearchKey.js
-needOnline=The function you have selected is not available in offline mode. Please go online and try again.
 ### noKeyserverConn=Could not connect to keyserver at %S.
 ### internalError=An internal error occurred. The keys could not be downloaded or imported.
-noKeyFound=We could not find any key matching the specified search criteria.
 ### keyDownload.keyUnavailable=The key with ID %S is not available on the keyserver. Most likely, the owner of the key did not upload their key to the keyserver.\n\nPlease ask the sender of the message to send you their public key by email.
 
 # Strings in enigmailEditKeyTrustDlg.xhtml
 ### setKeyTrustFailed=Setting owner trust failed
 
-
 # Strings in enigmailSignKeyDlg.js
 ### signKeyFailed=Key signing failed
 ### alreadySigned.label=Note: the key %S is already signed with the selected secret key.
 ### alreadySignedexportable.label=Note: the key %S is already signed exportable with the selected secret key. A local signature does not make sense.
 ### partlySigned.label=Note: some user IDs of key %S are already signed with the selected secret key.
 ### noTrustedOwnKeys=No eligible key found for signing! You need at least one fully trusted secret key in order to sign keys.
 
 # Strings in enigmailKeyManager.js
-keyMan.loadingKeys=Loading keys, please wait ...
-keyValid.unknown=unknown
-keyValid.invalid=invalid
-keyValid.disabled=disabled
-keyValid.revoked=revoked
-keyValid.expired=expired
 ### keyValid.noSubkey=no valid subkey
 
-keyTrust.untrusted=untrusted
-keyTrust.marginal=marginal
-keyTrust.full=trusted
-keyTrust.ultimate=ultimate
-keyTrust.group=(group)
 ### keyType.public=pub
 ### keyType.publicAndSec=pub/sec
-userAtt.photo=User attribute (JPEG image)
 
-asciiArmorFile=ASCII Armored Files (*.asc)
-importKeyFile=Import OpenPGP Key File
-gnupgFile=GnuPG Files
-saveRevokeCertAs=Create & Save Revocation Certificate
-revokeCertOK=The revocation certificate has been successfully created. You can use it to invalidate your public key, e.g. in case you would lose your secret key.
-revokeCertFailed=The revocation certificate could not be created.
-
-addUidOK=User ID added successfully
-addUidFailed=Adding the User ID failed
-noKeySelected=You should select at least one key in order to perform the selected operation
-exportToFile=Export Public Key To File
-exportKeypairToFile=Export Secret and Public Key To File
-exportSecretKey=Do you want to include the secret key in the saved OpenPGP key file?
-saveKeysOK=The keys were successfully saved
-saveKeysFailed=Saving the keys failed
-importKeysFailed=Importing the keys failed
-specificPubKeyFilename=%1$S (0x%2$S) pub
-specificPubSecKeyFilename=%1$S (0x%2$S) pub-sec
-defaultPubKeyFilename=Exported-public-keys
-defaultPubSecKeyFilename=Exported-public-and-secret-keys
+### addUidOK=User ID added successfully
+### addUidFailed=Adding the User ID failed
 
 ### sendKeysOk=Key(s) sent successfully
 ### sendKeysFailed=Sending of keys failed
 ### receiveKeysOk=Key(s) updated successfully
 ### receiveKeysFailed=Downloading of keys failed
 ### keyUpload.verifyEmails=The keyserver will send you an email for each email address of your uploaded key. To confirm publication of your key, you'll need to click on the link in each of the emails you'll receive.
 
 ### deleteKeyFailed=The key could not be deleted.
 ### revokeKeyOk=The key has been revoked. If your key is available on a key server, it is recommended to re-upload it, so that others can see the revocation.
 ### revokeKeyFailed=The key could not be revoked.
 ### refreshKeyServiceOn.warn=Warning: Your keys are currently being refreshed in the background as safely as possible.\nRefreshing all your keys at once will unnecessarily reveal information about you.\nDo you really want to do this?
-### refreshKey.warn=Warning: depending on the number of keys and the connection speed, refreshing all keys could be quite a lengthy process!
 ### downloadContactsKeys.importFrom=Import contacts from address book '%S'?
 
 ### keylist.noOtherUids=Has no other identities
 ### keylist.hasOtherUids=Also known as
 ### keylist.noPhotos=No photo available
 ### keylist.hasPhotos=Photos
 
 ### keyMan.addphoto.filepicker.title=Select photo to add
--- a/mail/extensions/openpgp/content/ui/commonWorkflows.js
+++ b/mail/extensions/openpgp/content/ui/commonWorkflows.js
@@ -15,16 +15,18 @@ var EnigmailLocale = ChromeUtils.import(
 ).EnigmailLocale;
 var { EnigmailKey } = ChromeUtils.import(
   "chrome://openpgp/content/modules/key.jsm"
 );
 var EnigmailKeyRing = ChromeUtils.import(
   "chrome://openpgp/content/modules/keyRing.jsm"
 ).EnigmailKeyRing;
 
+var l10n = new Localization(["messenger/openpgp/enigmail.ftl"], true);
+
 /**
  * opens a prompt, asking the user to enter passphrase for given key id
  * returns: the passphrase if entered (empty string is allowed)
  * resultFlags.canceled is set to true if the user clicked cancel
  */
 function passphrasePromptCallback(win, keyId, resultFlags) {
   let p = {};
   p.value = "";
@@ -48,22 +50,22 @@ function passphrasePromptCallback(win, k
 }
 
 /**
  * import OpenPGP keys from file
  */
 function EnigmailCommon_importKeysFromFile(secret) {
   let inFile = EnigmailDialog.filePicker(
     window,
-    EnigmailLocale.getString("importKeyFile"),
+    l10n.formatValueSync("import-key-file"),
     "",
     false,
     "*.asc",
     "",
-    [EnigmailLocale.getString("gnupgFile"), "*.asc;*.gpg;*.pgp"]
+    [l10n.formatValueSync("gnupg-file"), "*.asc;*.gpg;*.pgp"]
   );
   if (!inFile) {
     return false;
   }
 
   // infile type: nsIFile
   // RNP.maxImportKeyBlockSize
   if (inFile.fileSize > 5000000) {
@@ -75,20 +77,19 @@ function EnigmailCommon_importKeysFromFi
   let preview = EnigmailKey.getKeyListFromKeyFile(
     inFile,
     errorMsgObj,
     !secret,
     secret
   );
 
   if (!preview || !preview.length || errorMsgObj.value) {
-    EnigmailDialog.alert(
-      window,
-      EnigmailLocale.getString("importKeysFailed") + "\n\n" + errorMsgObj.value
-    );
+    document.l10n.formatValue("import-keys-failed").then(value => {
+      EnigmailDialog.alert(window, value + "\n\n" + errorMsgObj.value);
+    });
     return false;
   }
   let exitStatus = -1;
 
   if (preview.length > 0) {
     if (preview.length == 1) {
       exitStatus = EnigmailDialog.confirmDlg(
         window,
@@ -118,22 +119,19 @@ function EnigmailCommon_importKeysFromFi
         passphrasePromptCallback,
         inFile,
         errorMsgObj,
         resultKeys,
         !secret,
         secret
       );
       if (exitCode !== 0) {
-        EnigmailDialog.alert(
-          window,
-          EnigmailLocale.getString("importKeysFailed") +
-            "\n\n" +
-            errorMsgObj.value
-        );
+        document.l10n.formatValue("import-keys-failed").then(value => {
+          EnigmailDialog.alert(window, value + "\n\n" + errorMsgObj.value);
+        });
       } else {
         console.debug("import final resultKeys: %o", resultKeys.keys);
         EnigmailDialog.keyImportDlg(window, resultKeys.keys);
         return true;
       }
     }
   }
 
--- a/mail/extensions/openpgp/content/ui/enigmailKeyManager.js
+++ b/mail/extensions/openpgp/content/ui/enigmailKeyManager.js
@@ -99,18 +99,19 @@ function enigmailKeyManagerLoad() {
   EnigmailSearchCallback.setup(gSearchInput, gTimeoutId, applyFilter, 200);
 
   if (EnigGetPref("keyManShowAllKeys")) {
     gShowAllKeysElement.setAttribute("checked", "true");
   }
 
   gUserList.addEventListener("click", onListClick, true);
   //document.getElementById("pleaseWait").showPopup(gSearchInput, -1, -1, "tooltip", "after_end", "");
-  document.getElementById("statusText").value = EnigGetString(
-    "keyMan.loadingKeys"
+  document.l10n.setAttributes(
+    document.getElementById("statusText"),
+    "key-man-loading-keys"
   );
   document.getElementById("progressBar").style.visibility = "visible";
   EnigmailEvents.dispatchEvent(loadkeyList, 100, null);
 
   gUserList.view = gKeyListView;
   gSearchInput.focus();
 }
 
@@ -366,17 +367,19 @@ function enigmailDeleteKey() {
 function enigCreateKeyMsg() {
   var enigmailSvc = GetEnigmailSvc();
   if (!enigmailSvc) {
     return;
   }
 
   var keyList = getSelectedKeyIds();
   if (keyList.length === 0) {
-    EnigAlert(EnigGetString("noKeySelected"));
+    document.l10n.formatValue("no-key-selected").then(value => {
+      EnigAlert(value);
+    });
     return;
   }
 
   var tmpDir = EnigGetTempDir();
   var tmpFile;
   try {
     tmpFile = Cc[ENIG_LOCAL_FILE_CONTRACTID].createInstance(
       EnigGetLocalFileApi()
@@ -445,17 +448,19 @@ function enigCreateKeyMsg() {
   msgCompParam.format = Ci.nsIMsgCompFormat.Default;
   msgCompParam.originalMsgURI = "";
   msgCompSvc.OpenComposeWindowWithParams("", msgCompParam);
 }
 
 function createNewMail() {
   var keyList = getSelectedKeys();
   if (keyList.length === 0) {
-    EnigmailDialog.info(window, EnigGetString("noKeySelected"));
+    document.l10n.formatValue("no-key-selected").then(value => {
+      EnigmailDialog.info(window, value);
+    });
     return;
   }
 
   var addresses = [];
   var rangeCount = gUserList.view.selection.getRangeCount();
   var start = {};
   var end = {};
   var keyType, keyNum, r, i;
@@ -572,39 +577,42 @@ function enigmailRevokeKey() {
 
 function enigCreateRevokeCert() {
   var keyList = getSelectedKeys();
 
   EnigCreateRevokeCert(gKeyList[keyList[0]].keyId, gKeyList[keyList[0]].userId);
 }
 */
 
-function enigmailExportKeys() {
+async function enigmailExportKeys() {
   var keyList = getSelectedKeys();
   if (keyList.length === 0) {
-    EnigmailDialog.info(window, EnigGetString("noKeySelected"));
+    EnigmailDialog.info(
+      window,
+      await document.l10n.formatValue("no-key-selected")
+    );
     return;
   }
 
   // check whether we want to export a private key anywhere in the key list
   var secretFound = false;
   for (var i = 0; i < keyList.length && !secretFound; ++i) {
     if (gKeyList[keyList[i]].secretAvailable) {
       secretFound = true;
     }
   }
 
   var exportSecretKey = false;
   if (secretFound) {
     // double check that also the pivate keys shall be exportet
     var r = EnigmailDialog.msgBox(window, {
-      msgtext: EnigGetString("exportSecretKey"),
+      msgtext: await document.l10n.formatValue("export-secret-key"),
       dialogTitle: EnigGetString("enigConfirm2"),
-      button1: l10n.formatValueSync("key-man-button-export-pub-key"),
-      button2: l10n.formatValueSync("key-man-button-export-sec-key"),
+      button1: await document.l10n.formatValue("key-man-button-export-pub-key"),
+      button2: await document.l10n.formatValue("key-man-button-export-sec-key"),
       cancelButton: ":cancel",
       iconType: EnigmailConstants.ICONTYPE_QUESTION,
     });
     switch (r) {
       case 0: // export pub key only
         break;
       case 1: // export secret key
         exportSecretKey = true;
@@ -619,49 +627,52 @@ function enigmailExportKeys() {
   if (!enigmailSvc) {
     return;
   }
   var defaultFileName;
   if (keyList.length == 1) {
     defaultFileName = gKeyList[keyList[0]].userId.replace(/[<>]/g, "");
     if (exportSecretKey) {
       defaultFileName =
-        EnigGetString(
-          "specificPubSecKeyFilename",
-          defaultFileName,
-          gKeyList[keyList[0]].keyId
-        ) + ".asc";
+        defaultFileName +
+        " " +
+        `(0x${gKeyList[keyList[0]].keyId}` +
+        " " +
+        "pub-sec.asc";
     } else {
       defaultFileName =
-        EnigGetString(
-          "specificPubKeyFilename",
-          defaultFileName,
-          gKeyList[keyList[0]].keyId
-        ) + ".asc";
+        defaultFileName +
+        " " +
+        `(0x${gKeyList[keyList[0]].keyId})` +
+        " " +
+        "pub.asc";
     }
   } else if (exportSecretKey) {
-    defaultFileName = EnigGetString("defaultPubSecKeyFilename") + ".asc";
+    defaultFileName =
+      (await document.l10n.formatValue("default-pub-sec-key-filename")) +
+      ".asc";
   } else {
-    defaultFileName = EnigGetString("defaultPubKeyFilename") + ".asc";
+    defaultFileName =
+      (await document.l10n.formatValue("default-pub-key-filename")) + ".asc";
   }
 
   var FilePickerLabel = "";
 
   if (exportSecretKey) {
-    FilePickerLabel = EnigGetString("exportKeypairToFile");
+    FilePickerLabel = await document.l10n.formatValue("export-keypair-to-file");
   } else {
-    FilePickerLabel = EnigGetString("exportToFile");
+    FilePickerLabel = await document.l10n.formatValue("export-to-file");
   }
   var outFile = EnigFilePicker(
     FilePickerLabel,
     "",
     true,
     "*.asc",
     defaultFileName,
-    [EnigGetString("asciiArmorFile"), "*.asc"]
+    [await document.l10n.formatValue("ascii-armor-file"), "*.asc"]
   );
   if (!outFile) {
     return;
   }
 
   var exitCodeObj = {};
   var errorMsgObj = {};
 
@@ -674,19 +685,26 @@ function enigmailExportKeys() {
   EnigmailKeyRing.extractKey(
     exportSecretKey,
     keyIdArray,
     outFile,
     exitCodeObj,
     errorMsgObj
   );
   if (exitCodeObj.value !== 0) {
-    EnigAlert(EnigGetString("saveKeysFailed") + "\n\n" + errorMsgObj.value);
+    EnigAlert(
+      (await document.l10n.formatValue("save-keys-failed")) +
+        "\n\n" +
+        errorMsgObj.value
+    );
   } else {
-    EnigmailDialog.info(window, EnigGetString("saveKeysOK"));
+    EnigmailDialog.info(
+      window,
+      await document.l10n.formatValue("save-keys-ok")
+    );
   }
 }
 
 /*
 function enigmailManageUids() {
   var keyList = getSelectedKeys();
   var inputObj = {
     keyId: gKeyList[keyList[0]].keyId,
@@ -795,17 +813,19 @@ function enigmailImportFromClipbrd() {
 function enigmailCopyToClipbrd() {
   var enigmailSvc = GetEnigmailSvc();
   if (!enigmailSvc) {
     return;
   }
 
   var keyList = getSelectedKeyIds();
   if (keyList.length === 0) {
-    EnigmailDialog.info(window, EnigGetString("noKeySelected"));
+    document.l10n.formatValue("no-key-selected").then(value => {
+      EnigmailDialog.info(window, value);
+    });
     return;
   }
   var exitCodeObj = {};
   var errorMsgObj = {};
 
   var keyIdArray = [];
   for (let id of keyList) {
     keyIdArray.push("0x" + id);
@@ -814,19 +834,19 @@ function enigmailCopyToClipbrd() {
   var keyData = EnigmailKeyRing.extractKey(
     0,
     keyIdArray,
     null,
     exitCodeObj,
     errorMsgObj
   );
   if (exitCodeObj.value !== 0) {
-    EnigAlert(
-      EnigGetString("copyToClipbrdFailed") + "\n\n" + errorMsgObj.value
-    );
+    l10n.formatValue("copy-to-clipbrd-failed").then(value => {
+      EnigAlert(value);
+    });
     return;
   }
   if (EnigmailClipboard.setClipboardContent(keyData)) {
     EnigmailLog.DEBUG(
       "enigmailKeyManager.js: enigmailImportFromClipbrd: set clipboard data\n"
     );
     l10n.formatValue("copy-to-clipbrd-ok").then(value => {
       EnigmailDialog.info(window, value);
@@ -1211,17 +1231,19 @@ function determineHiddenKeys(
 function accessKeyServer(accessType, callbackFunc) {
   var enigmailSvc = GetEnigmailSvc();
   if (!enigmailSvc) {
     return;
   }
 
   const ioService = Services.io;
   if (ioService && ioService.offline) {
-    EnigmailDialog.alert(window, EnigmailLocale.getString("needOnline"));
+    document.l10n.formatValue("need-online").then(value => {
+      EnigmailDialog.alert(window, value);
+    });
     return;
   }
 
   let inputObj = {};
   let resultObj = {};
   let selKeyList = getSelectedKeys();
   let keyList = [];
   for (let i = 0; i < selKeyList.length; i++) {
@@ -1234,17 +1256,17 @@ function accessKeyServer(accessType, cal
         window,
         l10n.formatValueSync("refresh-all-question"),
         l10n.formatValueSync("key-man-button-refresh-all")
       )
     ) {
       accessType = EnigmailConstants.DOWNLOAD_KEY;
       EnigmailDialog.alertPref(
         window,
-        EnigmailLocale.getString("refreshKey.warn"),
+        l10n.formatValueSync("refresh-key-warn"),
         "warnRefreshAll"
       );
     } else {
       return;
     }
   }
 
   let keyServer = EnigmailPrefs.getPref("autoKeyServerSelection")
--- a/mail/extensions/openpgp/content/ui/enigmailKeygen.js
+++ b/mail/extensions/openpgp/content/ui/enigmailKeygen.js
@@ -31,16 +31,18 @@ var { EnigmailFiles } = ChromeUtils.impo
 var OpenPGPMasterpass = ChromeUtils.import(
   "chrome://openpgp/content/modules/masterpass.jsm"
 ).OpenPGPMasterpass;
 var { RNP } = ChromeUtils.import("chrome://openpgp/content/modules/RNP.jsm");
 const { MailServices } = ChromeUtils.import(
   "resource:///modules/MailServices.jsm"
 );
 
+var l10n = new Localization(["messenger/openpgp/enigmail.ftl"], true);
+
 var gUserIdentityList;
 var gUserIdentityListPopup;
 
 var gKeygenRequest;
 var gAllData = "";
 var gGeneratedKey = null;
 var gUsedId;
 
@@ -119,35 +121,38 @@ function enigmailKeygenUnload() {
   EnigmailLog.DEBUG("enigmailKeygen.js: Unload\n");
 
   enigmailKeygenCloseRequest();
 }
 
 /**
  *  create a copy of the revokation cert at a user defined location
  */
-function saveRevCert(inputKeyFile, keyId, uid, resolve, reject) {
+async function saveRevCert(inputKeyFile, keyId, uid, resolve, reject) {
   let defaultFileName = uid.replace(/[\\/<>]/g, "");
   defaultFileName += " (0x" + keyId + ") rev.asc";
 
   let outFile = EnigFilePicker(
-    EnigGetString("saveRevokeCertAs"),
+    await document.l10n.formatValue("save-revoke-cert-as"),
     "",
     true,
     "*.asc",
     defaultFileName,
-    [EnigGetString("asciiArmorFile"), "*.asc"]
+    [await document.l10n.formatValue("ascii-armor-file"), "*.asc"]
   );
 
   if (outFile) {
     try {
       inputKeyFile.copyToFollowingLinks(outFile.parent, outFile.leafName);
-      EnigmailDialog.info(window, EnigGetString("revokeCertOK"));
+      EnigmailDialog.info(
+        window,
+        await document.l10n.formatValue("revoke-cert-ok")
+      );
     } catch (ex) {
-      EnigAlert(EnigGetString("revokeCertFailed"));
+      EnigAlert(await document.l10n.formatValue("revoke-cert-failed"));
       reject(2);
     }
   }
   resolve();
 }
 
 function closeAndReset() {
   EnigmailKeyRing.clearCache();
--- a/mail/extensions/openpgp/content/ui/keyDetailsDlg.js
+++ b/mail/extensions/openpgp/content/ui/keyDetailsDlg.js
@@ -213,17 +213,17 @@ function createUidData(listNode, keyDeta
       }
     }
   }
 }
 
 function getTrustLabel(trustCode) {
   var trustTxt = EnigGetTrustLabel(trustCode);
   if (trustTxt == "-" || trustTxt.length === 0) {
-    trustTxt = EnigmailLocale.getString("keyValid.unknown");
+    return l10n.formatValueSync("key-valid-unknown");
   }
   return trustTxt;
 }
 
 function setAttr(attribute, value) {
   var elem = document.getElementById(attribute);
   if (elem) {
     elem.value = value;