-
-
Save kmaglione/c413c704c6a331d263f8 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff -Nur bing-old/bing.xml bing-new/bing.xml | |
--- bing-old/bing.xml 1969-12-31 16:00:00.000000000 -0800 | |
+++ bing-new/bing.xml 2013-02-22 12:59:18.723082667 -0800 | |
@@ -0,0 +1,114 @@ | |
+<?xml version="1.0" encoding="UTF-8"?> | |
+<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/"> | |
+ <!-- FIXME: Trailing space to avoid conflict with the builtin | |
+ - Bing plugin. That should ideally be updated to get tracking | |
+ - parameters from preferences instead. --> | |
+ <ShortName>Bing </ShortName> | |
+ <Description>Bing. Search by Microsoft.</Description> | |
+ <InputEncoding>UTF-8</InputEncoding> | |
+ <Image width="16" height="16" type="image/png">data:image/png;base64, | |
+ AAABAAEAEBAAAAEAGABoAwAAFgAAACgAAAAQAAAAIAAAAAEAGAAAAAAAAAAAABMLAAATCwAAAAAAAAAA | |
+ AAAVpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8V | |
+ pv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8ysf97zf+24//F | |
+ 6f/F6f/F6f+K0/9QvP8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8krP+Z2P/////////w+f/F6f/F6f/i9P////// | |
+ ///T7v9Bt/8Vpv8Vpv8Vpv8Vpv/T7v/////w+f97zf8Vpv8Vpv8Vpv8Vpv9QvP/T7v/////w+f9Bt/8V | |
+ pv8Vpv97zf////////9QvP8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8krP/i9P/////i9P8Vpv8Vpv+24//////i | |
+ 9P8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv+K0/////////8Vpv8Vpv/F6f////////8krP8Vpv8Vpv8V | |
+ pv8Vpv8Vpv8Vpv8Vpv+n3v/////w+f8Vpv8Vpv/F6f////////+n3v8krP8Vpv8Vpv8Vpv8Vpv8Vpv9t | |
+ x/////////+Z2P8Vpv8Vpv/F6f/////////////i9P+K0/9QvP9QvP9tx//F6f////////+n3v8Vpv8V | |
+ pv8Vpv/F6f/////T7v+Z2P/i9P////////////////////+24/9QvP8Vpv8Vpv8Vpv8Vpv/F6f/////F | |
+ 6f8Vpv8Vpv8krP9QvP9QvP9Bt/8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv/F6f/////F6f8Vpv8Vpv8Vpv8V | |
+ pv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv9Bt/9QvP9Bt/8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8V | |
+ pv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8V | |
+ pv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8AAHBsAABhdAAA | |
+ biAAAHJ0AABsaQAAdGkAACBDAABlbgAAUEEAAEVYAAAuQwAAOy4AAEU7AABBVAAAQ00AAC5W | |
+ <!-- Image from the original add-ons. Improperly sized and | |
+ - distorts badly when used as a search icon. | |
+ iVBORw0KGgoAAAANSUhEUgAAAEYAAAAZCAYAAACM9limAAAC7mlDQ1BJQ0MgUHJvZmlsZQAAeAGFVM9r | |
+ E0EU%2FjZuqdAiCFprDrJ4kCJJWatoRdQ2%2FRFiawzbH7ZFkGQzSdZuNuvuJrWliOTi0SreRe2hB%2F | |
+ %2BAHnrwZC9KhVpFKN6rKGKhFy3xzW5MtqXqwM5%2B8943731vdt8ADXLSNPWABOQNx1KiEWlsfEJq%2 | |
+ FIgAjqIJQTQlVdvsTiQGQYNz%2BXvn2HoPgVtWw3v7d7J3rZrStpoHhP1A4Eea2Sqw7xdxClkSAog836 | |
+ Epx3QI3%2BPY8uyPOU55eMG1Dys9xFkifEA1Lc5%2FTbhTzSXTQINIOJT1cVI%2BnNeLlNcdB2luZsbI | |
+ EL1PkKa7zO6rYqGcTvYOkL2d9H5Os94%2BwiHCCxmtP0a4jZ71jNU%2F4mHhpObEhj0cGDX0%2BGAVtx | |
+ qp%2BDXCFF8QTSeiVHHZLg3xmK79VvJKgnCQOMpkYYBzWkhP10xu%2BLqHBX0m1xOv4ndWUeF5jxNn3t | |
+ Td70XaAq8wDh0MGgyaDUhQEEUEYZiwUECGPBoxNLJyPyOrBhuTezJ1JGq7dGJEsUF7Ntw9t1Gk3Tz%2B | |
+ KCJxlEO1CJL8Qf4qr8lP5Xn5y1yw2Fb3lK2bmrry4DvF5Zm5Gh7X08jjc01efJXUdpNXR5aseXq8muwa | |
+ P%2BxXlzHmgjWPxHOw%2B%2FEtX5XMlymMFMXjVfPqS4R1WjE3359sfzs94i7PLrXWc62JizdWm5dn%2 | |
+ FWpI%2B%2B6qvJPmVflPXvXx%2FGfNxGPiKTEmdornIYmXxS7xkthLqwviYG3HCJ2VhinSbZH6JNVgYJ | |
+ q89S9dP1t4vUZ%2FDPVRlBnM0lSJ93%2FCKmQ0nbkOb%2FqP28f8F%2BT3iuefKAIvbODImbptU3HvEK | |
+ FlpW5zrgIXv9F98LZua6N%2BOPwEWDyrFq1SNZ8gvAEcdod6HugpmNOWls05Uocsn5O66cpiUsxQ20NS | |
+ Utcl12VLFrOZVWLpdtiZ0x1uHKE5QvfEp0plk%2Fqv8RGw%2FbBS%2BfmsUtl%2BThrWgZf6b8C8%2FU | |
+ XAeIuJAAAACXBIWXMAAAsTAAALEwEAmpwYAAAMIklEQVRYCdVZe3BcVRn%2Fzrn37iOPJmm7SZAiUl6S | |
+ UFseMkxngCCCgm1e7cYqIPyh5TlYFUUE2cQ%2FENEZQYpa7ExnqpYhS%2FMqpOKoRGCmZcqzTuIASnFs | |
+ Kc2mTdrNY3fvvef4%2B87NJpsm0OA4I5zpzb177jnf4%2Fc9z62INXf5JGwplHdE%2BWJlqrv%2BDdFG | |
+ UidI0YceQhBpvf%2FnK6PlkdGHhBBfAokjQtO9Rbe83kMUvP%2FQZP8PG%2BwP4gk1BLW2QdnjRmtCa0 | |
+ 36uFmiZFxSnPyK6HhrcXlo%2Fdiw6xVHrZPHMv7W8Y3n1xTdrt%2BlNiEpoWeA%2FqH5zGI8PTEfWsEa | |
+ 6NafnNYtGZ%2BUCfq2JmgGMFq7wcL%2BpC3aBjytE1icmA1AAraHVxnCIDgF0kDSrIXar4yNeJniYicC | |
+ 9hhqd5EbGTbiJwJA4U2C4u2S57SO%2B%2B%2FPpw18agRAn%2BZjCM38IwTWxWvECWn1XSa1rvOYLcGK | |
+ s0eg7yQwML8m4Ug7ELQ9nuMN1V%2F4bbEfKSuzwiJMGUyEXOFrmhCWn9bt8dE8YdGStALBAQkULtH6Cd | |
+ omdlOWVmBXuviz9DxdoN18KPF6uBzAIL7olJZkdIKiC22VC1MOHEKWcD3LtUK5Yd2eAJ9gTPOZ9lZj%2 | |
+ FXgSyiYMLV5Z1dBTJcKiKC%2Bz1ORnJ6LDujdxjJAiKluSJcqzL5JKXqwFfRq2CymhHhdKngn5NdC1Ra | |
+ wJOQaAIMcc9t3c8uoopQa98FdI6DpkmRXYWCOdkhAzZCOrXBoQiTcA%2BOsg%2BGfXznUfaY8fNe9Z4f | |
+ a4f8cdO8OP7CleSrtPT9Piw8W0PDWi%2F3TFIWNVeCB7mLjwMadySdUqZYkrSenzQXq5cEoiTIe9TOfS | |
+ 8Faxl%2Flokn9QGaf3cO%2FVx8zrtjbkwIQSk3eeq67fcZqy%2FHXYcxlkP1%2FYRTESFn4K0u4YyPh% | |
+ 2Fx7JdyA77cV9L0qmB3kTSAjtJfuZYvSX0uK%2FFaQj2lQwMrGxhtz8CebZAmqukU1yLi1R2BNO5vXi5 | |
+ D8p4AAmUxBlSOrUyUkHKHQXTibfAdWPKzj3KoLCQZ16zc4EbzTxvS%2FszGlx837v2ne0N29i6DEqsuW | |
+ cdHr4jLOdCGSkn7WUB%2BLGDoPMa6I%2FBH8KQ9mxhR8%2BSoVLIcZTX7MP7hwc7Gx9mHuLyPls%2FW% | |
+ 2BdxSFY2dt8HyneQU7JQ2BFSE0Ps37txDeGCvnQ2OZEaAZ0gL8h4rBdCCQ9AyICn%2FMtTnY19xpuhBw | |
+ Nj8gIIAB84hhVma6URWw8robeVllXs27eljhmZcXL9U0VZ2z0VDvdlyLQBVi4DF7CY6FOudd3QjlUHKp | |
+ q6ysHtObLDy4yXubmvpjpXP84EKpt7HhJ2%2BJsEwLSXYaS64em%2FBuc9%2BzuaDgdcsA7uLn3rXKXl | |
+ NzB3I5TCBlZl%2FEkY4VoYIcfgxMpHfi9CpS1AlpUdh1wP2o7c8i5NHMgbysjs6Fqp1A9hjNVauZ6Qjo | |
+ 37Fu2Ln8BxFtuufONAzyoG0oxCYBSHlPa9AUvTuve6Gv6WX8T3vLUL5xbVb6%2BVtv0EmNSCIQAdf42c | |
+ 3CVOJgqM%2FN2YW8YbfS97%2FVBn4%2B8qm7puF6GSRwAiNFSDyKY3Yb6rkOZcfCobOi7VltwqhHUqQg | |
+ RWH71%2FsKPhHtC7X4RL79a5UfghARRac6ir4Zk8PaYFyWFj%2BOnkqFrTswlOsl4rOIv2U9D1ooOdje | |
+ %2Fwa%2Fa%2B%2FFqTbDGH1GtJUt57MEs9g8LW4MrDxHkwA%2FPAN8S2uOkx53DPmn7hi0bE1CC7qAwv | |
+ WEFe6G4gP44dEiuZHUkpkHh5iBuw1ngmW5ZBYdc1lyEfKDLFh98hFw12Nz%2BHBLqBKwTSKITV1y5as3 | |
+ MJ6F%2Bv3XG0YRHspocYFF6fl5t5G65MG%2FrwMzzjW9rPvm3mQ6UxxP4G8xwUhCkA88Aojk2kxEcPdT | |
+ b%2BE4KGOH65yeOcMHPgNxKf3rTe5XWD3fX%2FAOHfIDyAKzwBie0TazpOBQdO0vgHqeCzsYaeUrz7lL | |
+ GUQk%2Bp9Qu8mFIxwS4f8CnkhWfOWasPmrzlSfUSBDzEIQjESy2duxK7EYGcHl2SivqYHJWeBfmOlxu0 | |
+ OB9BeWM0Ervg5QAZxVfIk3hbPuz4mQcDwyhZ2ke8C%2F9FnqTUAHLwPEbtAPcDGOoFxDcoQQdNS1yPlk | |
+ KUrAEGb32yfeFli%2BE6i40iCmaWCqUCI5aaspL5ffwfNJM8BUEZICMXbBUC3NxS4Dc7u0O%2BFKfxuj | |
+ OiEyhFs4fp5ieLAwiebroFgIyQHufVHAWFu9i92N98IWwLtTxqXqZPCnywcOVcz32QF9ZBWBRryUwgsq | |
+ CMJaxx3HkCu5gUqkDEQoQEa7BIuxo2ntdoAwGA49kC5sMOAEEiJLV6C0L%2FEUn5a8g5zHvDKS3PbP93 | |
+ 79VHjJLcFOYHeyU8hn8iL90IL7mYFPolIUFTJM2ywvWYsMHnVbLs8%2FglXP4G3Hro5fUeE%2BeQ4fm5 | |
+ Brsl9bXCigkW9QYkRpgVsnjegAq5%2FeSFo3BybJ2Wj4ELBmCb9wg8hmwPqAfOwPBrDZiF%2Bi76qs8J | |
+ p2iJ8HM1GS%2BzEyF7m%2B5OIOxmDg77xa5zK6zzIHuYQNeqssc2ovz3mmg33ff0HlsLdR%2B47NCKPd | |
+ 9qrmrqukXrxl%2BxlYzyQJvq6gBQG3YliPr6YPa%2Fkn42wWkd5bf7NjRJqzmUmCH858eD6IqrmrvhjX | |
+ kgphn%2Bb54EvNQvOtjRPBhr7ryC3PHNUPQSK1x8EXqePZVN3b1Q5gUp%2FCFIwBY7K0ahzyMPLuMch% | |
+ 2BSbUn5uI%2FqWH72fPHaqo%2BkpgHEX2ZGfIN5IS%2FollFrqkHpAd8Sn%2BgoDClNJMEh1VL7q6YpQ | |
+ yLsLM3cJDiN2Pjd7z2BXQ%2B%2FClmSZTSEf5XOGw%2BAXhpnEH77%2FNyPYB1flnEOQ%2F014d13l6y | |
+ uu8%2F3sjXDFi1HCrxHSvoZzHsIOMiBdg5%2FKoEE34UyvDo2U3c%2F7uVppHYQZ%2F84PU8JQiR5E95 | |
+ jSUv8MneZChMWduezIOnjDVrTju2Cd%2FcqxU9L1YnBilEnrEsfR62S47JOcxNBHDILg9wHKFiYsRks0 | |
+ RbKccbj65Hnhzs%2B4eLJwumDFCR7zbcZUiHPboDcluB3YyhdXRJU7ukJp6xSErkTnjQD3R1BZqvH%2B | |
+ TgC2CHNXxSqO7q1cu71BP7vmLY6M46uSzfHFwmjdsAVE%2F%2BJm07diqgHt%2BNlA%2FgfcnfJZQ3po | |
+ IKQVttBWm7Y7l%2BZW%2FU1s7fRFaOPh7Vfvn8EACVk6RQDBIsvL2MpH8o3gNxBB71HiSPRN8xpB8tU5 | |
+ 1B3HKmGaKjcWxQknSDjDFcrowAdJVJ13tzf%2FC2T5mjWq13a0Ky%2F7JFnWechL50COJ3FQXqmfuX4s | |
+ yDPT5oLtAtMVKsUtfUjY52jhXSgUnYs8twBcbCx20R6n0R%2FuFb7%2FWk7K%2FuHOxhGWwOSjZAv6Hq | |
+ RFWCDmctdrlyD7i2wo14%2FT32gMJ1p4IzKv8C1X7A0aweluc5YmBROgGVrkW8ulDoUFub6XifTzobJQ | |
+ IW4MjUcCpIKtwWPFUqk3XeAubu48R2q5B%2B4QNccMN%2F29Qx1NPy3U32xgYPIXtbbim0Y7fxKYmjvR | |
+ M6%2FnfSdaN9d7CGAMM9e7%2BcwZeVuRFfmah9z5NTgfdlSu7dV84flx5gVAZ8hickwAKV5Nluf8Rx8z | |
+ XzswOxvka35yADQTJgnmaeTvxoPyPyY%2FMs2cC7wrv2Q%2B95n7De%2BpXDP1begEbYbho%2FkrwQeP | |
+ qVD64GUfzbdVzT03o44uR8XhXuM9HCwfYEnNuYg76tq4nvp8%2Bfaw1C%2Btdysbes5Do7gLy2yEkoX8 | |
+ eTv2PXp8KJ0QuY8iJHkl4C4jVnjBzYAClTmHrranKtVV%2F%2B2Z5Xfq86Vf3di9DF3NNpTsMEBB8Ui% | |
+ 2FWJ4NbTY6Tn3zDTT%2B2HoMhzvCWE1%2B9NosnCjKJQByx19Gct%2BstdqNjn4M51ckZPskKNqIjPZ1 | |
+ AFISVMaxXcp140M74gfMOQpHm0In%2BNgCw0rkjy2LGrtrUDLvRdf0RRkpqyB8cMPHNv4QxvnPQr%2BF | |
+ 4o7Tf2YYPaz7JtZtGhpe8Atz4sanlbn%2Bq%2BhjDYwBp6A5q1779FLlu5fiFH8ByuoZ6LxtRBluGt9G | |
+ 5auYewXNxPP4v7N0AOzcoPC7%2FwBfh%2BUgcZXzvgAAAABJRU5ErkJggg== | |
+ --> | |
+ </Image> | |
+ <Url type="application/x-suggestions+json" template="http://api.bing.com/osjson.aspx"> | |
+ <Param name="query" value="{searchTerms}"/> | |
+ <Param name="form" value="OSDJAS"/> | |
+ </Url> | |
+ <Url type="text/html" method="GET" template="http://www.bing.com/search"> | |
+ <Param name="q" value="{searchTerms}"/> | |
+ <Param name="form" value="MOZHPB"/> | |
+ <MozParam name="pc" condition="pref" pref="ms-pc"/> | |
+ </Url> | |
+ <Url type="application/x-moz-keywordsearch" method="GET" template="http://www.bing.com/search"> | |
+ <Param name="q" value="{searchTerms}"/> | |
+ <Param name="form" value="MOZPLB"/> | |
+ <MozParam name="pc" condition="pref" pref="ms-pc"/> | |
+ </Url> | |
+ <SearchForm>http://www.bing.com/search</SearchForm> | |
+</SearchPlugin> | |
diff -Nur bing-old/bootstrap.js bing-new/bootstrap.js | |
--- bing-old/bootstrap.js 2011-10-18 15:21:50.000000000 -0700 | |
+++ bing-new/bootstrap.js 2013-02-22 12:57:46.540384119 -0800 | |
@@ -19,6 +19,7 @@ | |
* | |
* Contributor(s): | |
* Edward Lee <edilee@mozilla.com> | |
+ * Kris Maglione <kmaglione@mozilla.com> | |
* | |
* Alternatively, the contents of this file may be used under the terms of | |
* either the GNU General Public License Version 2 or later (the "GPL"), or | |
@@ -42,49 +43,27 @@ | |
Cu.import("resource://gre/modules/Services.jsm"); | |
Cu.import("resource://gre/modules/XPCOMUtils.jsm"); | |
+const REASONS = {}; | |
+["APP_STARTUP", "APP_SHUTDOWN", | |
+ "ADDON_ENABLE", "ADDON_DISABLE", | |
+ "ADDON_INSTALL", "ADDON_UNINSTALL", | |
+ "ADDON_UPGRADE", "ADDON_DOWNGRADE"].forEach(function (reason) { | |
+ REASONS[this[reason]] = reason.replace(/.*_/, "").toLowerCase(); | |
+}, this); | |
+ | |
// Remember if we were just installed | |
let justInstalled = false; | |
// Remember if we're on Firefox or Fennec | |
let platform = Services.appinfo.name == "Firefox" ? "desktop" : "mobile"; | |
-// Add a default search engine and move it to the right place | |
-function addSearchEngine() { | |
+function hideOriginalSearchEngine() { | |
// Hide any existing custom searches | |
let origEngine = Services.search.getEngineByName(SEARCH_NAME); | |
if (origEngine != null) { | |
origEngine.hidden = true; | |
unload(function() origEngine.hidden = false); | |
} | |
- | |
- // Add the special search engine if necessary | |
- let engineName = SEARCH_NAME + " "; | |
- try { | |
- Services.search.addEngineWithDetails(engineName, SEARCH_ICON, "", "", | |
- "GET", SEARCH_URL); | |
- } | |
- catch(ex) {} | |
- | |
- // Get the just-added or existing engine | |
- let engine = Services.search.getEngineByName(engineName); | |
- if (engine == null) | |
- return; | |
- | |
- // Move it to the desired position | |
- Services.search.moveEngine(engine, SEARCH_POSITION); | |
- | |
- // Switch to the engine by default if it's first | |
- if (SEARCH_POSITION == 0 && justInstalled) | |
- Services.search.currentEngine = engine; | |
- | |
- // Clean up when disabling | |
- unload(function() Services.search.removeEngine(engine)); | |
-} | |
- | |
-// Customize the default prefs | |
-function setPref(pref, value) { | |
- let branch = Services.prefs.getBranch(""); | |
- branch.setCharPref(pref, value); | |
} | |
// Open a new tab for the landing page and select it | |
@@ -95,8 +74,10 @@ | |
// Do the appropriate thing on each platform | |
if (platform == "desktop") { | |
- // Try again after a short delay if session store is initializing | |
let {__SSi, __SS_restoreID, gBrowser, setTimeout} = window; | |
+ | |
+ // Try again after a short delay if session store is initializing | |
+ // FIXME: Why not use sessionstore-windows-restored? | |
if (__SSi == null || __SS_restoreID != null) { | |
setTimeout(function() showLandingPage(window), 1000); | |
return; | |
@@ -107,22 +88,37 @@ | |
return URI.spec == LANDING_PAGE; | |
}); | |
- // Always remove the landing page when uninstalling | |
- unload(function() gBrowser.removeTab(landingTab)); | |
- | |
// Add the landing page if not open yet | |
- if (landingTab == null) | |
+ if (landingTab == null) { | |
landingTab = gBrowser.loadOneTab(LANDING_PAGE); | |
+ // Prefer not to leak. | |
+ let landingTabMap = WeakMap(); | |
+ landingTabMap.set(window, landingTab); | |
+ | |
+ // Remove the landing page when uninstalling only if the user | |
+ // hasn't navigated away from it yet. | |
+ unload(function(reason) { | |
+ let tab = landingTabMap.get(window); | |
+ | |
+ if (tab && tab.linkedBrowser.currentURI.spec == LANDING_PAGE) | |
+ gBrowser.removeTab(tab); | |
+ }, window); | |
+ } | |
+ | |
// Make sure it's focused | |
gBrowser.selectedTab = landingTab; | |
+ landingTab = null; | |
} | |
else { | |
let {BrowserUI} = window; | |
let tab = BrowserUI.newTab(LANDING_PAGE); | |
- unload(function() BrowserUI.closeTab(tab)); | |
+ unload(function() BrowserUI.closeTab(tab), window); | |
} | |
+ // We're no longer just installed after we get some windows loaded | |
+ justInstalled = false; | |
+ | |
// Only show the landing page once | |
showLandingPage.shown = true; | |
} | |
@@ -130,32 +126,33 @@ | |
/** | |
* Handle the add-on being activated on install/enable | |
*/ | |
-function startup({id}, reason) AddonManager.getAddonByID(id, function(addon) { | |
+function startup(data, reason) { | |
// Load various javascript includes for helper functions | |
["helper", "utils"].forEach(function(fileName) { | |
- let fileURI = addon.getResourceURI("scripts/" + fileName + ".js"); | |
- Services.scriptloader.loadSubScript(fileURI.spec, global); | |
+ let fileURI = data.resourceURI.spec + "/scripts/" + fileName + ".js"; | |
+ Services.scriptloader.loadSubScript(fileURI, global); | |
+ }); | |
+ | |
+ Cu.import(SEARCH_MODULE_URL); | |
+ SearchSettings.init(REASONS[reason]); | |
+ | |
+ unload(function(reason) { | |
+ SearchSettings.cleanup(reason); | |
+ Cu.unload(SEARCH_MODULE_URL); | |
}); | |
- // Add custom search support to the browser | |
- addSearchEngine(); | |
+ hideOriginalSearchEngine(); | |
+ | |
+ // Add custom search support to the browser and set it as default | |
+ SearchSettings.addSearchEngine(ENGINE_URL, true); | |
// Change some prefs to custom search on install | |
- if (justInstalled) { | |
- setPref(PREF_KEYWORD, SEARCH_KEYWORD_URL); | |
- setPref(PREF_HOME, SEARCH_HOME_URL); | |
- setPref(PREF_HOME_RESET, SEARCH_HOME_URL); | |
- } | |
+ for (let [pref, value] in Iterator(PREF_VALUES)) | |
+ SearchSettings.setPref(pref, value); | |
// Open the landing page | |
watchWindows(showLandingPage); | |
- | |
- // We're no longer just installed after we get some windows loaded | |
- watchWindows(function(window) { | |
- if (justInstalled) | |
- window.setTimeout(function() justInstalled = false, 5000); | |
- }); | |
-}) | |
+} | |
/** | |
* Handle the add-on being deactivated on uninstall/disable | |
@@ -163,7 +160,7 @@ | |
function shutdown(data, reason) { | |
// Clean up with unloaders when we're deactivating | |
if (reason != APP_SHUTDOWN) | |
- unload(); | |
+ unload(REASONS[reason]); | |
} | |
/** | |
diff -Nur bing-old/chrome.manifest bing-new/chrome.manifest | |
--- bing-old/chrome.manifest 1969-12-31 16:00:00.000000000 -0800 | |
+++ bing-new/chrome.manifest 2013-02-22 11:53:17.730659827 -0800 | |
@@ -0,0 +1 @@ | |
+content bing-search ./ | |
diff -Nur bing-old/scripts/helper.js bing-new/scripts/helper.js | |
--- bing-old/scripts/helper.js 2011-10-18 15:18:59.000000000 -0700 | |
+++ bing-new/scripts/helper.js 2013-02-22 12:53:41.115409289 -0800 | |
@@ -36,22 +36,20 @@ | |
"use strict"; | |
-const HOME_SEARCH = JSON.stringify({ | |
- name: "Bing", | |
- searchUrl: "http://www.bing.com/search?form=MOZHPB&pc=MOZO&q=_searchTerms_", | |
- image: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEYAAAAZCAYAAACM9limAAAC7mlDQ1BJQ0MgUHJvZmlsZQAAeAGFVM9rE0EU%2FjZuqdAiCFprDrJ4kCJJWatoRdQ2%2FRFiawzbH7ZFkGQzSdZuNuvuJrWliOTi0SreRe2hB%2F%2BAHnrwZC9KhVpFKN6rKGKhFy3xzW5MtqXqwM5%2B8943731vdt8ADXLSNPWABOQNx1KiEWlsfEJq%2FIgAjqIJQTQlVdvsTiQGQYNz%2BXvn2HoPgVtWw3v7d7J3rZrStpoHhP1A4Eea2Sqw7xdxClkSAog836Epx3QI3%2BPY8uyPOU55eMG1Dys9xFkifEA1Lc5%2FTbhTzSXTQINIOJT1cVI%2BnNeLlNcdB2luZsbIEL1PkKa7zO6rYqGcTvYOkL2d9H5Os94%2BwiHCCxmtP0a4jZ71jNU%2F4mHhpObEhj0cGDX0%2BGAVtxqp%2BDXCFF8QTSeiVHHZLg3xmK79VvJKgnCQOMpkYYBzWkhP10xu%2BLqHBX0m1xOv4ndWUeF5jxNn3tTd70XaAq8wDh0MGgyaDUhQEEUEYZiwUECGPBoxNLJyPyOrBhuTezJ1JGq7dGJEsUF7Ntw9t1Gk3Tz%2BKCJxlEO1CJL8Qf4qr8lP5Xn5y1yw2Fb3lK2bmrry4DvF5Zm5Gh7X08jjc01efJXUdpNXR5aseXq8muwaP%2BxXlzHmgjWPxHOw%2B%2FEtX5XMlymMFMXjVfPqS4R1WjE3359sfzs94i7PLrXWc62JizdWm5dn%2FWpI%2B%2B6qvJPmVflPXvXx%2FGfNxGPiKTEmdornIYmXxS7xkthLqwviYG3HCJ2VhinSbZH6JNVgYJq89S9dP1t4vUZ%2FDPVRlBnM0lSJ93%2FCKmQ0nbkOb%2FqP28f8F%2BT3iuefKAIvbODImbptU3HvEKFlpW5zrgIXv9F98LZua6N%2BOPwEWDyrFq1SNZ8gvAEcdod6HugpmNOWls05Uocsn5O66cpiUsxQ20NSUtcl12VLFrOZVWLpdtiZ0x1uHKE5QvfEp0plk%2Fqv8RGw%2FbBS%2BfmsUtl%2BThrWgZf6b8C8%2FUXAeIuJAAAACXBIWXMAAAsTAAALEwEAmpwYAAAMIklEQVRYCdVZe3BcVRn%2Fzrn37iOPJmm7SZAiUl6SUFseMkxngCCCgm1e7cYqIPyh5TlYFUUE2cQ%2FENEZQYpa7ExnqpYhS%2FMqpOKoRGCmZcqzTuIASnFsKc2mTdrNY3fvvef4%2B87NJpsm0OA4I5zpzb177jnf4%2Fc9z62INXf5JGwplHdE%2BWJlqrv%2BDdFGUidI0YceQhBpvf%2FnK6PlkdGHhBBfAokjQtO9Rbe83kMUvP%2FQZP8PG%2BwP4gk1BLW2QdnjRmtCa036uFmiZFxSnPyK6HhrcXlo%2Fdiw6xVHrZPHMv7W8Y3n1xTdrt%2BlNiEpoWeA%2FqH5zGI8PTEfWsEa6NafnNYtGZ%2BUCfq2JmgGMFq7wcL%2BpC3aBjytE1icmA1AAraHVxnCIDgF0kDSrIXar4yNeJniYicC9hhqd5EbGTbiJwJA4U2C4u2S57SO%2B%2B%2FPpw18agRAn%2BZjCM38IwTWxWvECWn1XSa1rvOYLcGKs0eg7yQwML8m4Ug7ELQ9nuMN1V%2F4bbEfKSuzwiJMGUyEXOFrmhCWn9bt8dE8YdGStALBAQkULtH6CdomdlOWVmBXuviz9DxdoN18KPF6uBzAIL7olJZkdIKiC22VC1MOHEKWcD3LtUK5Yd2eAJ9gTPOZ9lZj%2FXgSyiYMLV5Z1dBTJcKiKC%2Bz1ORnJ6LDujdxjJAiKluSJcqzL5JKXqwFfRq2CymhHhdKngn5NdC1RawJOQaAIMcc9t3c8uoopQa98FdI6DpkmRXYWCOdkhAzZCOrXBoQiTcA%2BOsg%2BGfXznUfaY8fNe9Z4fa4f8cdO8OP7CleSrtPT9Piw8W0PDWi%2F3TFIWNVeCB7mLjwMadySdUqZYkrSenzQXq5cEoiTIe9TOfS8Faxl%2Flokn9QGaf3cO%2FVx8zrtjbkwIQSk3eeq67fcZqy%2FHXYcxlkP1%2FYRTESFn4K0u4YyPh%2Fx7JdyA77cV9L0qmB3kTSAjtJfuZYvSX0uK%2FFaQj2lQwMrGxhtz8CebZAmqukU1yLi1R2BNO5vXi5D8p4AAmUxBlSOrUyUkHKHQXTibfAdWPKzj3KoLCQZ16zc4EbzTxvS%2FszGlx837v2ne0N29i6DEqsuWcdHr4jLOdCGSkn7WUB%2BLGDoPMa6I%2FBH8KQ9mxhR8%2BSoVLIcZTX7MP7hwc7Gx9mHuLyPls%2FW%2BdxSFY2dt8HyneQU7JQ2BFSE0Ps37txDeGCvnQ2OZEaAZ0gL8h4rBdCCQ9AyICn%2FMtTnY19xpuhBwNj8gIIAB84hhVma6URWw8robeVllXs27eljhmZcXL9U0VZ2z0VDvdlyLQBVi4DF7CY6FOudd3QjlUHKpq6ysHtObLDy4yXubmvpjpXP84EKpt7HhJ2%2BJsEwLSXYaS64em%2FBuc9%2BzuaDgdcsA7uLn3rXKXlNzB3I5TCBlZl%2FEkY4VoYIcfgxMpHfi9CpS1AlpUdh1wP2o7c8i5NHMgbysjs6Fqp1A9hjNVauZ6Qjo37Fu2Ln8BxFtuufONAzyoG0oxCYBSHlPa9AUvTuve6Gv6WX8T3vLUL5xbVb6%2BVtv0EmNSCIQAdf42c3CVOJgqM%2FN2YW8YbfS97%2FVBn4%2B8qm7puF6GSRwAiNFSDyKY3Yb6rkOZcfCobOi7VltwqhHUqQgRWH71%2FsKPhHtC7X4RL79a5UfghARRac6ir4Zk8PaYFyWFj%2BOnkqFrTswlOsl4rOIv2U9D1ooOdje%2Fwa%2Fa%2B%2FFqTbDGH1GtJUt57MEs9g8LW4MrDxHkwA%2FPAN8S2uOkx53DPmn7hi0bE1CC7qAwvWEFe6G4gP44dEiuZHUkpkHh5iBuw1ngmW5ZBYdc1lyEfKDLFh98hFw12Nz%2BHBLqBKwTSKITV1y5as3MJ6F%2Bv3XG0YRHspocYFF6fl5t5G65MG%2FrwMzzjW9rPvm3mQ6UxxP4G8xwUhCkA88Aojk2kxEcPdTb%2BE4KGOH65yeOcMHPgNxKf3rTe5XWD3fX%2FAOHfIDyAKzwBie0TazpOBQdO0vgHqeCzsYaeUrz7lLGUQk%2Bp9Qu8mFIxwS4f8CnkhWfOWasPmrzlSfUSBDzEIQjESy2duxK7EYGcHl2SivqYHJWeBfmOlxu0OB9BeWM0Ervg5QAZxVfIk3hbPuz4mQcDwyhZ2ke8C%2F9FnqTUAHLwPEbtAPcDGOoFxDcoQQdNS1yPlkKUrAEGb32yfeFli%2BE6i40iCmaWCqUCI5aaspL5ffwfNJM8BUEZICMXbBUC3NxS4Dc7u0O%2BFKfxujOiEyhFs4fp5ieLAwiebroFgIyQHufVHAWFu9i92N98IWwLtTxqXqZPCnywcOVcz32QF9ZBWBRryUwgsqCMJaxx3HkCu5gUqkDEQoQEa7BIuxo2ntdoAwGA49kC5sMOAEEiJLV6C0L%2FEUn5a8g5zHvDKS3PbP9379VHjJLcFOYHeyU8hn8iL90IL7mYFPolIUFTJM2ywvWYsMHnVbLs8%2FglXP4G3Hro5fUeE%2BeQ4fm5Brsl9bXCigkW9QYkRpgVsnjegAq5%2FeSFo3BybJ2Wj4ELBmCb9wg8hmwPqAfOwPBrDZiF%2Bi76qs8Jp2iJ8HM1GS%2BzEyF7m%2B5OIOxmDg77xa5zK6zzIHuYQNeqssc2ovz3mmg33ff0HlsLdR%2B47NCKPd9qrmrqukXrxl%2BxlYzyQJvq6gBQG3YliPr6YPa%2Fkn42wWkd5bf7NjRJqzmUmCH858eD6IqrmrvhjXkgphn%2Bb54EvNQvOtjRPBhr7ryC3PHNUPQSK1x8EXqePZVN3b1Q5gUp%2FCFIwBY7K0ahzyMPLuMch%2BSbUn5uI%2FqWH72fPHaqo%2BkpgHEX2ZGfIN5IS%2FollFrqkHpAd8Sn%2BgoDClNJMEh1VL7q6YpQyLsLM3cJDiN2Pjd7z2BXQ%2B%2FClmSZTSEf5XOGw%2BAXhpnEH77%2FNyPYB1flnEOQ%2F014d13l6yuu8%2F3sjXDFi1HCrxHSvoZzHsIOMiBdg5%2FKoEE34UyvDo2U3c%2F7uVppHYQZ%2F84PU8JQiR5E95jSUv8MneZChMWduezIOnjDVrTju2Cd%2FcqxU9L1YnBilEnrEsfR62S47JOcxNBHDILg9wHKFiYsRks0RbKccbj65Hnhzs%2B4eLJwumDFCR7zbcZUiHPboDcluB3YyhdXRJU7ukJp6xSErkTnjQD3R1BZqvH%2BTgC2CHNXxSqO7q1cu71BP7vmLY6M46uSzfHFwmjdsAVE%2F%2BJm07diqgHt%2BNlA%2FgfcnfJZQ3poIKQVttBWm7Y7l%2BZW%2FU1s7fRFaOPh7Vfvn8EACVk6RQDBIsvL2MpH8o3gNxBB71HiSPRN8xpB8tU51B3HKmGaKjcWxQknSDjDFcrowAdJVJ13tzf%2FC2T5mjWq13a0Ky%2F7JFnWechL50COJ3FQXqmfuX4syDPT5oLtAtMVKsUtfUjY52jhXSgUnYs8twBcbCx20R6n0R%2FuFb7%2FWk7K%2FuHOxhGWwOSjZAv6HqRFWCDmctdrlyD7i2wo14%2FT32gMJ1p4IzKv8C1X7A0aweluc5YmBROgGVrkW8ulDoUFub6XifTzobJQIW4MjUcCpIKtwWPFUqk3XeAubu48R2q5B%2B4QNccMN%2F29Qx1NPy3U32xgYPIXtbbim0Y7fxKYmjvRM6%2FnfSdaN9d7CGAMM9e7%2BcwZeVuRFfmah9z5NTgfdlSu7dV84flx5gVAZ8hickwAKV5Nluf8Rx8zXzswOxvka35yADQTJgnmaeTvxoPyPyY%2FMs2cC7wrv2Q%2B95n7De%2BpXDP1begEbYbho%2FkrwQePqVD64GUfzbdVzT03o44uR8XhXuM9HCwfYEnNuYg76tq4nvp8%2Bfaw1C%2Btdysbes5Do7gLy2yEkoX8eTv2PXp8KJ0QuY8iJHkl4C4jVnjBzYAClTmHrranKtVV%2F%2B2Z5Xfq86Vf3di9DF3NNpTsMEBB8Ui%2FWJ4NbTY6Tn3zDTT%2B2HoMhzvCWE1%2B9NosnCjKJQByx19Gct%2BstdqNjn4M51ckZPskKNqIjPZ1AFISVMaxXcp140M74gfMOQpHm0In%2BNgCw0rkjy2LGrtrUDLvRdf0RRkpqyB8cMPHNv4QxvnPQr%2BF4o7Tf2YYPaz7JtZtGhpe8Atz4sanlbn%2Bq%2BhjDYwBp6A5q1779FLlu5fiFH8ByuoZ6LxtRBluGt9G5auYewXNxPP4v7N0AOzcoPC7%2FwBfh%2BUgcZXzvgAAAABJRU5ErkJggg%3D%3D", | |
-}); | |
-const LANDING_PAGE = "http://bing.com/?pc=MOZO"; | |
-const PREF_HOME = "browser.startup.homepage"; | |
-const PREF_HOME_RESET = "browser.startup.homepage_reset"; | |
-const PREF_KEYWORD = "keyword.URL"; | |
-const SEARCH_DOMAIN = "www.bing.com"; | |
-const SEARCH_ICON = "data:image/x-icon;base64,AAABAAEAEBAAAAEAGABoAwAAFgAAACgAAAAQAAAAIAAAAAEAGAAAAAAAAAAAABMLAAATCwAAAAAAAAAAAAAVpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8ysf97zf%2B24%2F%2FF6f%2FF6f%2FF6f%2BK0%2F9QvP8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8krP%2BZ2P%2F%2F%2F%2F%2F%2F%2F%2F%2Fw%2Bf%2FF6f%2FF6f%2Fi9P%2F%2F%2F%2F%2F%2F%2F%2F%2FT7v9Bt%2F8Vpv8Vpv8Vpv8Vpv%2FT7v%2F%2F%2F%2F%2Fw%2Bf97zf8Vpv8Vpv8Vpv8Vpv9QvP%2FT7v%2F%2F%2F%2F%2Fw%2Bf9Bt%2F8Vpv8Vpv97zf%2F%2F%2F%2F%2F%2F%2F%2F9QvP8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8krP%2Fi9P%2F%2F%2F%2F%2Fi9P8Vpv8Vpv%2B24%2F%2F%2F%2F%2F%2Fi9P8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv%2BK0%2F%2F%2F%2F%2F%2F%2F%2F%2F8Vpv8Vpv%2FF6f%2F%2F%2F%2F%2F%2F%2F%2F8krP8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv%2Bn3v%2F%2F%2F%2F%2Fw%2Bf8Vpv8Vpv%2FF6f%2F%2F%2F%2F%2F%2F%2F%2F%2Bn3v8krP8Vpv8Vpv8Vpv8Vpv8Vpv9tx%2F%2F%2F%2F%2F%2F%2F%2F%2F%2BZ2P8Vpv8Vpv%2FF6f%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2Fi9P%2BK0%2F9QvP9QvP9tx%2F%2FF6f%2F%2F%2F%2F%2F%2F%2F%2F%2Bn3v8Vpv8Vpv8Vpv%2FF6f%2F%2F%2F%2F%2FT7v%2BZ2P%2Fi9P%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2B24%2F9QvP8Vpv8Vpv8Vpv8Vpv%2FF6f%2F%2F%2F%2F%2FF6f8Vpv8Vpv8krP9QvP9QvP9Bt%2F8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv%2FF6f%2F%2F%2F%2F%2FF6f8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv9Bt%2F9QvP9Bt%2F8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8Vpv8AAHBsAABhdAAAbiAAAHJ0AABsaQAAdGkAACBDAABlbgAAUEEAAEVYAAAuQwAAOy4AAEU7AABBVAAAQ00AAC5W"; | |
+const BASE_URL = "chrome://bing-search/content/"; | |
+const ENGINE_URL = BASE_URL + "bing.xml"; | |
+const SEARCH_MODULE_URL = BASE_URL + "search-settings.jsm"; | |
+ | |
+const LANDING_PAGE = "http://www.bing.com/?pc=MOZO"; | |
const SEARCH_HOME_URL = "http://www.bing.com/?pc=MOZO"; | |
-const SEARCH_KEYWORD_URL = "http://www.bing.com/search?form=MOZPLB&pc=MOZO&q="; | |
const SEARCH_NAME = "Bing"; | |
-const SEARCH_POSITION = 0; | |
-const SEARCH_URL = "http://www.bing.com/search?form=MOZPSB&pc=MOZO&q={searchTerms}"; | |
+const SEARCH_PC = "MOZO"; | |
+ | |
+const PREF_VALUES = { | |
+ "browser.search.param.ms-pc": SEARCH_PC, | |
+ "browser.startup.homepage": SEARCH_HOME_URL, | |
+ "browser.startup.homepage_reset": SEARCH_HOME_URL | |
+}; | |
// Look through tabs in the browser to see if any match | |
function findOpenTab(browser, checkTabAndURI) { | |
diff -Nur bing-old/scripts/utils.js bing-new/scripts/utils.js | |
--- bing-old/scripts/utils.js 2011-05-26 18:22:31.000000000 -0700 | |
+++ bing-new/scripts/utils.js 2013-02-22 12:55:37.751271595 -0800 | |
@@ -186,8 +186,8 @@ | |
unloaders = unload.unloaders = []; | |
// Calling with no arguments runs all the unloader callbacks | |
- if (callback == null) { | |
- unloaders.slice().forEach(function(unloader) unloader()); | |
+ if (typeof callback != "function") { | |
+ unloaders.slice().forEach(function(unloader) unloader(callback)); | |
unloaders.length = 0; | |
return; | |
} | |
@@ -206,9 +206,9 @@ | |
} | |
// Wrap the callback in a function that ignores failures | |
- function unloader() { | |
+ function unloader(reason) { | |
try { | |
- callback(); | |
+ callback(reason); | |
} | |
catch(ex) {} | |
} | |
diff -Nur bing-old/search-settings.jsm bing-new/search-settings.jsm | |
--- bing-old/search-settings.jsm 1969-12-31 16:00:00.000000000 -0800 | |
+++ bing-new/search-settings.jsm 2013-02-22 13:05:03.904066794 -0800 | |
@@ -0,0 +1,369 @@ | |
+var EXPORTED_SYMBOLS = ["SearchSettings"]; | |
+ | |
+const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components; | |
+ | |
+// Import the Services module. | |
+Cu.import("resource://gre/modules/Services.jsm"); | |
+ | |
+const XMLHttpRequest = Components.Constructor("@mozilla.org/xmlextras/xmlhttprequest;1"); | |
+ | |
+const SupportsString = Components.Constructor("@mozilla.org/supports-string;1", "nsISupportsString"); | |
+function Prefs(branch, defaults) { | |
+ this.constructor = Prefs; // Ends up Object otherwise... Why? | |
+ | |
+ this.branch = Services.prefs[defaults ? "getDefaultBranch" : "getBranch"](branch || ""); | |
+ if (this.branch instanceof Ci.nsIPrefBranch2) | |
+ this.branch.QueryInterface(Ci.nsIPrefBranch2); | |
+ | |
+ this.defaults = defaults ? this : new this.constructor(branch, true); | |
+} | |
+Prefs.prototype = { | |
+ /** | |
+ * Returns a new Prefs object for the sub-branch *branch* of this | |
+ * object. | |
+ * | |
+ * @param {string} branch The sub-branch to return. | |
+ */ | |
+ Branch: function Branch(branch) new this.constructor(this.root + branch), | |
+ | |
+ /** | |
+ * Returns the full name of this object's preference branch. | |
+ */ | |
+ get root() this.branch.root, | |
+ | |
+ /** | |
+ * Returns the value of the preference *name*, or *defaultValue* if | |
+ * the preference does not exist. | |
+ * | |
+ * @param {string} name The name of the preference to return. | |
+ * @param {*} defaultValue The value to return if the preference has no value. | |
+ * @optional | |
+ */ | |
+ get: function get(name, defaultValue) { | |
+ let type = this.branch.getPrefType(name); | |
+ | |
+ try { | |
+ if (type === Ci.nsIPrefBranch.PREF_STRING) | |
+ return this.branch.getComplexValue(name, Ci.nsISupportsString).data; | |
+ | |
+ if (type === Ci.nsIPrefBranch.PREF_INT) | |
+ return this.branch.getIntPref(name); | |
+ | |
+ if (type === Ci.nsIPrefBranch.PREF_BOOL) | |
+ return this.branch.getBoolPref(name); | |
+ } | |
+ catch (e if e.result == Cr.NS_ERROR_UNEXPECTED) {} | |
+ | |
+ return defaultValue; | |
+ }, | |
+ | |
+ /** | |
+ * Returns true if the given preference exists in this branch. | |
+ * | |
+ * @param {string} name The name of the preference to check. | |
+ */ | |
+ has: function has(name) this.branch.getPrefType(name) !== 0, | |
+ | |
+ /** | |
+ * Returns an array of all preference names in this branch or the | |
+ * given sub-branch. | |
+ * | |
+ * @param {string} branch The sub-branch for which to return preferences. | |
+ * @optional | |
+ */ | |
+ getNames: function getNames(branch) this.branch.getChildList(branch || "", { value: 0 }), | |
+ | |
+ /** | |
+ * Returns true if the given preference is set to its default value. | |
+ * | |
+ * @param {string} name The name of the preference to check. | |
+ */ | |
+ isDefault: function isDefault(name) !this.branch.prefHasUserValue(name), | |
+ | |
+ /** | |
+ * Sets the preference *name* to *value*. If the preference already | |
+ * exists, it must have the same type as the given value. | |
+ * | |
+ * @param {name} name The name of the preference to change. | |
+ * @param {string|number|boolean} value The value to set. | |
+ */ | |
+ set: function set(name, value) { | |
+ let type = typeof value; | |
+ if (type === "string") { | |
+ let string = SupportsString(); | |
+ string.data = value; | |
+ this.branch.setComplexValue(name, Ci.nsISupportsString, string); | |
+ } | |
+ else if (type === "number") | |
+ this.branch.setIntPref(name, value); | |
+ else if (type === "boolean") | |
+ this.branch.setBoolPref(name, value); | |
+ else if (value == null) | |
+ this.reset(name); | |
+ else | |
+ throw TypeError("Unknown preference type: " + type); | |
+ }, | |
+ | |
+ /** | |
+ * Sets the preference *name* to *value* only if it doesn't | |
+ * already have that value. Avoids triggering preference observers | |
+ * when unnecessary. | |
+ */ | |
+ maybeSet: function maybeSet(name, value) { | |
+ if (this.get(name) != value) | |
+ this.set(name, value); | |
+ }, | |
+ | |
+ /** | |
+ * Resets the preference *name* to its default value. | |
+ * | |
+ * @param {string} name The name of the preference to reset. | |
+ */ | |
+ reset: function reset(name) { | |
+ if (this != this.defaults && this.branch.prefHasUserValue(name)) | |
+ this.branch.clearUserPref(name); | |
+ } | |
+}; | |
+ | |
+const hasOwnProperty = Function.call.bind({}.hasOwnProperty); | |
+ | |
+function isString(value) Object.prototype.toString.call(value) == "[object String]"; | |
+ | |
+const SearchSettings = { | |
+ ENGINE_ADDED: "browser-search-engine-modified", | |
+ | |
+ _observers: [], | |
+ | |
+ // Observer called after our engine has been successfully added | |
+ observe: function SS_observe(subject, topic, data) { | |
+ switch (topic) { | |
+ case this.ENGINE_ADDED: | |
+ if (data != "engine-added") | |
+ break; | |
+ | |
+ let engine = subject.QueryInterface(Ci.nsISearchEngine); | |
+ if (!hasOwnProperty(this.engines, engine.name)) | |
+ break; | |
+ | |
+ if (this.engines[engine.name].unprocessed) | |
+ this._processEngine(engine); | |
+ break; | |
+ } | |
+ }, | |
+ | |
+ engines: {}, | |
+ | |
+ _processEngine: function SS__processEngine(engine) { | |
+ let self = this; | |
+ | |
+ let engineDetails = this.engines[engine.name]; | |
+ engineDetails.unprocessed = false; | |
+ | |
+ // If the engine is not hidden and this is the first run, move | |
+ // it to the first position in the engine list and select it | |
+ if (engineDetails.setDefault && !engine.hidden) { | |
+ Services.search.moveEngine(engine, 0); | |
+ if (self.firstRun) | |
+ Services.search.currentEngine = engine; | |
+ | |
+ this.setPref("browser.search.defaultenginename", engine.name, true); | |
+ this.setPref("keyword.URL", ""); | |
+ } | |
+ | |
+ for (let [, engine] in Iterator(this.engines)) | |
+ if (engine.unprocessed) | |
+ return; | |
+ this._removeObserver(); | |
+ }, | |
+ | |
+ _addObserver: function SS__addObserver() { | |
+ if (!~this._observers.indexOf(this.ENGINE_ADDED)) { | |
+ Services.obs.addObserver(this, this.ENGINE_ADDED, false); | |
+ this._observers.push(this.ENGINE_ADDED); | |
+ } | |
+ }, | |
+ | |
+ _removeObserver: function SS__removeObserver() { | |
+ if (~this._observers.indexOf(this.ENGINE_ADDED)) { | |
+ Services.obs.removeObserver(this, this.ENGINE_ADDED); | |
+ this._observers.splice(this._observers.indexOf(this.ENGINE_ADDED), 1); | |
+ } | |
+ }, | |
+ | |
+ /** | |
+ * Adds a new search engine and optionally sets it as the default | |
+ * engine by which about:home and location bar searches will be | |
+ * performed. | |
+ * | |
+ * @param {string|object} details The URL (within the add-on) of an | |
+ * OpenSearch XML search description file, or an object of the | |
+ * form: | |
+ * | |
+ * { | |
+ * name: "Example Engine", | |
+ * iconURL: "data:image/png;base64,...", | |
+ * alias: "example-engine", // Used as a keyword for location bar searches | |
+ * description: "An example search engine", | |
+ * method: "GET", // The HTTP request method | |
+ * url: "https://www.example.com/?q=_searchTerms_" | |
+ * } | |
+ * @param {boolean} default If true, this engine is set as the | |
+ * default search engine. | |
+ */ | |
+ addSearchEngine: function SS_addSearchEngine(details, setDefault) { | |
+ const ENGINE_PROPERTIES = ["name", "iconURL", "alias", "description", "method", "url"]; | |
+ let self = this; | |
+ | |
+ setDefault = Boolean(setDefault); | |
+ | |
+ if (isString(details)) { | |
+ // Search description file URL | |
+ | |
+ let url = details; | |
+ let xhr = XMLHttpRequest(); | |
+ | |
+ xhr.open("GET", url); | |
+ xhr.onload = function () { | |
+ details = { | |
+ name: this.responseXML.querySelector(":root > ShortName").textContent, | |
+ unprocessed: setDefault, | |
+ setDefault: setDefault | |
+ }; | |
+ self.engines[details.name] = details; | |
+ | |
+ // Only add the engine if it doesn't already exist. | |
+ let engine = Services.search.getEngineByName(details.name); | |
+ if (engine) | |
+ self._processEngine(engine); | |
+ else { | |
+ // Register an observer to detect when the engine has been added, if | |
+ // necessary. | |
+ if (setDefault) | |
+ self._addObserver(); | |
+ | |
+ Services.search.addEngine(url, Ci.nsISearchEngine.DATA_XML, | |
+ null, false); | |
+ } | |
+ }; | |
+ xhr.send(); | |
+ } | |
+ else { | |
+ // Search engine details object | |
+ | |
+ let newDetails = { setDefault: setDefault }; | |
+ ENGINE_PROPERTIES.forEach(function (prop) { | |
+ newDetails[prop] = details[prop]; | |
+ }); | |
+ this.engines[newDetails.name] = newDetails; | |
+ | |
+ if (!Services.search.getEngineByName(details.name)) { | |
+ Services.search.addEngineWithDetails.apply(Services.search, | |
+ ENGINE_PROPERTIES.map(function (k) details[k])) | |
+ } | |
+ | |
+ this._processEngine(Services.search.getEngineByName(details.name)); | |
+ } | |
+ }, | |
+ | |
+ prefs: new Prefs(""), | |
+ | |
+ // Stores the original values of changed preferences. | |
+ savedPrefs: {}, | |
+ | |
+ /** | |
+ * Change the default value of the preference *name* to *value*. | |
+ * A default for this preference must exist, and it must be a | |
+ * character preference. | |
+ * | |
+ * The user preference will be reset only on first run, as | |
+ * determined by the value passed to init(). | |
+ * | |
+ * @param {string} name The name of the preference to change. | |
+ * @param {string|boolean|number} value The new value to set. Must | |
+ * be the same type as the original default, if it exists. | |
+ * @param {boolean} localized If true, set the preference as a | |
+ * URL pointing to a property file, as required by the | |
+ * localized preference retrieval process. | |
+ */ | |
+ setPref: function SS_setPref(name, value, localized) { | |
+ // If this is a localized preference, transform the value into an | |
+ // appropriate data: URL. | |
+ if (localized) | |
+ value = "data:text/plain," + encodeURIComponent(name + "=" + value.replace(/ /g, "\\u0020")); | |
+ | |
+ // Save the original and new values. | |
+ this.savedPrefs[name] = [this.prefs.defaults.get(name), value]; | |
+ | |
+ // Change the default | |
+ this.prefs.defaults.set(name, value); | |
+ | |
+ // Clear the user value if this is the first run, or the | |
+ // new default is the same as the user value. | |
+ if (this.firstRun || this.prefs.get(name) == value) | |
+ this.prefs.reset(name); | |
+ }, | |
+ | |
+ /** | |
+ * Must be called at startup. | |
+ * | |
+ * @param {string} reason The reason that initialization is required. Must | |
+ * be one of: | |
+ * | |
+ * startup - The app is starting up. | |
+ * enable - The add-on is being enabled. | |
+ * install - The add-on is being installed. | |
+ * upgrade - The add-on is being upgraded. | |
+ * downgrade - The add-on is being downgraded. | |
+ */ | |
+ init: function SS_cleanup(reason) { | |
+ if (reason == "install") | |
+ this.firstRun = true; | |
+ }, | |
+ | |
+ firstRun: false, | |
+ | |
+ /** | |
+ * Must be called at shutdown or when the add-on is disabled or | |
+ * uninstalled. | |
+ * | |
+ * @param {string} reason The reason that cleanup is required. Must | |
+ * be one of: | |
+ * | |
+ * shutdown - The app is being shutdown. | |
+ * disable - The add-on is being disabled. | |
+ * uninstall - The add-on is being uninstalled. | |
+ * upgrade - The add-on is being upgraded. | |
+ * downgrade - The add-on is being downgraded. | |
+ */ | |
+ cleanup: function SS_cleanup(reason) { | |
+ if (reason == "shutdown") | |
+ return; | |
+ | |
+ this._observers.forEach(function (observer) { | |
+ Services.obs.removeObserver(this, observer); | |
+ }, this); | |
+ | |
+ // Reset our changes if the values have not been changed | |
+ // in the mean time. | |
+ for (let [name, [origValue, value]] in Iterator(this.savedPrefs)) { | |
+ if (this.prefs.defaults.get(name) == value) { | |
+ this.prefs.defaults.set(name, origValue); | |
+ // Clear the user value if it's the same as the default. | |
+ if (this.prefs.get(name) == origValue) | |
+ this.prefs.reset(name); | |
+ } | |
+ } | |
+ | |
+ // Remove our search engines on disable or uninstall | |
+ if (~["disable", "uninstall"].indexOf(reason)) { | |
+ for (let [name, details] in Iterator(this.engines)) { | |
+ let engine = Services.search.getEngineByName(name); | |
+ // Only remove the engine if it appears to be the same one we | |
+ // added. | |
+ if (engine && (!details.url || engine.getSubmission("_searchTerms_") | |
+ .uri.spec == details.url)) | |
+ Services.search.removeEngine(engine); | |
+ } | |
+ } | |
+ } | |
+}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment