forked from mirrors/gecko-dev
		
	 e930b89c34
			
		
	
	
		e930b89c34
		
	
	
	
	
		
			
			***
Bug 1514594: Part 3a - Change ChromeUtils.import to return an exports object; not pollute global. r=mccr8
This changes the behavior of ChromeUtils.import() to return an exports object,
rather than a module global, in all cases except when `null` is passed as a
second argument, and changes the default behavior not to pollute the global
scope with the module's exports. Thus, the following code written for the old
model:
  ChromeUtils.import("resource://gre/modules/Services.jsm");
is approximately the same as the following, in the new model:
  var {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
Since the two behaviors are mutually incompatible, this patch will land with a
scripted rewrite to update all existing callers to use the new model rather
than the old.
***
Bug 1514594: Part 3b - Mass rewrite all JS code to use the new ChromeUtils.import API. rs=Gijs
This was done using the followng script:
https://bitbucket.org/kmaglione/m-c-rewrites/src/tip/processors/cu-import-exports.jsm
***
Bug 1514594: Part 3c - Update ESLint plugin for ChromeUtils.import API changes. r=Standard8
Differential Revision: https://phabricator.services.mozilla.com/D16747
***
Bug 1514594: Part 3d - Remove/fix hundreds of duplicate imports from sync tests. r=Gijs
Differential Revision: https://phabricator.services.mozilla.com/D16748
***
Bug 1514594: Part 3e - Remove no-op ChromeUtils.import() calls. r=Gijs
Differential Revision: https://phabricator.services.mozilla.com/D16749
***
Bug 1514594: Part 3f.1 - Cleanup various test corner cases after mass rewrite. r=Gijs
***
Bug 1514594: Part 3f.2 - Cleanup various non-test corner cases after mass rewrite. r=Gijs
Differential Revision: https://phabricator.services.mozilla.com/D16750
--HG--
extra : rebase_source : 359574ee3064c90f33bf36c2ebe3159a24cc8895
extra : histedit_source : b93c8f42808b1599f9122d7842d2c0b3e656a594%2C64a3a4e3359dc889e2ab2b49461bab9e27fc10a7
		
	
			
		
			
				
	
	
		
			158 lines
		
	
	
	
		
			5.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			158 lines
		
	
	
	
		
			5.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /* 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/. */
 | |
| "use strict";
 | |
| 
 | |
| var EXPORTED_SYMBOLS = ["AttributionCode"];
 | |
| 
 | |
| const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 | |
| ChromeUtils.defineModuleGetter(this, "AppConstants",
 | |
|   "resource://gre/modules/AppConstants.jsm");
 | |
| ChromeUtils.defineModuleGetter(this, "OS",
 | |
|   "resource://gre/modules/osfile.jsm");
 | |
| ChromeUtils.defineModuleGetter(this, "Services",
 | |
|   "resource://gre/modules/Services.jsm");
 | |
| XPCOMUtils.defineLazyGlobalGetters(this, ["URL"]);
 | |
| 
 | |
| const ATTR_CODE_MAX_LENGTH = 200;
 | |
| const ATTR_CODE_KEYS_REGEX = /^source|medium|campaign|content$/;
 | |
| const ATTR_CODE_VALUE_REGEX = /[a-zA-Z0-9_%\\-\\.\\(\\)]*/;
 | |
| const ATTR_CODE_FIELD_SEPARATOR = "%26"; // URL-encoded &
 | |
| const ATTR_CODE_KEY_VALUE_SEPARATOR = "%3D"; // URL-encoded =
 | |
| const ATTR_CODE_KEYS = ["source", "medium", "campaign", "content"];
 | |
| 
 | |
| let gCachedAttrData = null;
 | |
| 
 | |
| /**
 | |
|  * Returns an nsIFile for the file containing the attribution data.
 | |
|  */
 | |
| function getAttributionFile() {
 | |
|   let file = Services.dirsvc.get("LocalAppData", Ci.nsIFile);
 | |
|   // appinfo does not exist in xpcshell, so we need defaults.
 | |
|   file.append(Services.appinfo.vendor || "mozilla");
 | |
|   file.append(AppConstants.MOZ_APP_NAME);
 | |
|   file.append("postSigningData");
 | |
|   return file;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Returns an object containing a key-value pair for each piece of attribution
 | |
|  * data included in the passed-in attribution code string.
 | |
|  * If the string isn't a valid attribution code, returns an empty object.
 | |
|  */
 | |
| function parseAttributionCode(code) {
 | |
|   if (code.length > ATTR_CODE_MAX_LENGTH) {
 | |
|     return {};
 | |
|   }
 | |
| 
 | |
|   let isValid = true;
 | |
|   let parsed = {};
 | |
|   for (let param of code.split(ATTR_CODE_FIELD_SEPARATOR)) {
 | |
|     let [key, value] = param.split(ATTR_CODE_KEY_VALUE_SEPARATOR, 2);
 | |
|     if (key && ATTR_CODE_KEYS_REGEX.test(key)) {
 | |
|       if (value && ATTR_CODE_VALUE_REGEX.test(value)) {
 | |
|         parsed[key] = value;
 | |
|       }
 | |
|     } else {
 | |
|       isValid = false;
 | |
|       break;
 | |
|     }
 | |
|   }
 | |
|   return isValid ? parsed : {};
 | |
| }
 | |
| 
 | |
| var AttributionCode = {
 | |
|   /**
 | |
|    * Reads the attribution code, either from disk or a cached version.
 | |
|    * Returns a promise that fulfills with an object containing the parsed
 | |
|    * attribution data if the code could be read and is valid,
 | |
|    * or an empty object otherwise.
 | |
|    *
 | |
|    * On windows the attribution service converts utm_* keys, removing "utm_".
 | |
|    * On OSX the attributions are set directly on download and retain "utm_".  We
 | |
|    * strip "utm_" while retrieving the params.
 | |
|    */
 | |
|   getAttrDataAsync() {
 | |
|     return (async function() {
 | |
|       if (gCachedAttrData != null) {
 | |
|         return gCachedAttrData;
 | |
|       }
 | |
| 
 | |
|       gCachedAttrData = {};
 | |
|       if (AppConstants.platform == "win") {
 | |
|         try {
 | |
|           let bytes = await OS.File.read(getAttributionFile().path);
 | |
|           let decoder = new TextDecoder();
 | |
|           let code = decoder.decode(bytes);
 | |
|           gCachedAttrData = parseAttributionCode(code);
 | |
|         } catch (ex) {
 | |
|           // The attribution file may already have been deleted,
 | |
|           // or it may have never been installed at all;
 | |
|           // failure to open or read it isn't an error.
 | |
|         }
 | |
|       } else if (AppConstants.platform == "macosx") {
 | |
|         try {
 | |
|           let appPath = Services.dirsvc.get("GreD", Ci.nsIFile).parent.parent.path;
 | |
|           let attributionSvc = Cc["@mozilla.org/mac-attribution;1"]
 | |
|                                   .getService(Ci.nsIMacAttributionService);
 | |
|           let referrer = attributionSvc.getReferrerUrl(appPath);
 | |
|           let params = new URL(referrer).searchParams;
 | |
|           for (let key of ATTR_CODE_KEYS) {
 | |
|             // We support the key prefixed with utm_ or not, but intentionally
 | |
|             // choose non-utm params over utm params.
 | |
|             for (let paramKey of [`utm_${key}`, key]) {
 | |
|               if (params.has(paramKey)) {
 | |
|                 let value = params.get(paramKey);
 | |
|                 if (value && ATTR_CODE_VALUE_REGEX.test(value)) {
 | |
|                   gCachedAttrData[key] = value;
 | |
|                 }
 | |
|               }
 | |
|             }
 | |
|           }
 | |
|         } catch (ex) {
 | |
|           // No attributions
 | |
|         }
 | |
|       }
 | |
|       return gCachedAttrData;
 | |
|     })();
 | |
|   },
 | |
| 
 | |
|   /**
 | |
|    * Return the cached attribution data synchronously without hitting
 | |
|    * the disk.
 | |
|    * @returns A dictionary with the attribution data if it's available,
 | |
|    *          null otherwise.
 | |
|    */
 | |
|   getCachedAttributionData() {
 | |
|     return gCachedAttrData;
 | |
|   },
 | |
| 
 | |
|   /**
 | |
|    * Deletes the attribution data file.
 | |
|    * Returns a promise that resolves when the file is deleted,
 | |
|    * or if the file couldn't be deleted (the promise is never rejected).
 | |
|    */
 | |
|   deleteFileAsync() {
 | |
|     return (async function() {
 | |
|       try {
 | |
|         await OS.File.remove(getAttributionFile().path);
 | |
|       } catch (ex) {
 | |
|         // The attribution file may already have been deleted,
 | |
|         // or it may have never been installed at all;
 | |
|         // failure to delete it isn't an error.
 | |
|       }
 | |
|     })();
 | |
|   },
 | |
| 
 | |
|   /**
 | |
|    * Clears the cached attribution code value, if any.
 | |
|    * Does nothing if called from outside of an xpcshell test.
 | |
|    */
 | |
|   _clearCache() {
 | |
|     let env = Cc["@mozilla.org/process/environment;1"]
 | |
|               .getService(Ci.nsIEnvironment);
 | |
|     if (env.exists("XPCSHELL_TEST_PROFILE_DIR")) {
 | |
|       gCachedAttrData = null;
 | |
|     }
 | |
|   },
 | |
| };
 |