diff --git a/application/palemoon/components/search/content/engineInfoEdit.js b/application/palemoon/components/search/content/engineInfoEdit.js
new file mode 100644
index 000000000..3f57ff0db
--- /dev/null
+++ b/application/palemoon/components/search/content/engineInfoEdit.js
@@ -0,0 +1,247 @@
+/* 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/.
+ * Based on "Add to Search Bar" addon by Malte Kraus and Gavin Sharp */
+const {utils: Cu, classes: Cc, interfaces: Ci} = Components;
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/FileUtils.jsm");
+
+
+////////////////////////////////////////////////////////////////////////////////
+let params = window.arguments[0];
+
+
+////////////////////////////////////////////////////////////////////////////////
+let stringBundle = false;
+
+
+function getStringBundle () {
+ if (!stringBundle) stringBundle = Services.strings.createBundle(bundleUrl);
+ return stringBundle;
+}
+
+
+function getString (name) {
+ return getStringBundle().GetStringFromName(name);
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+function storeChanges (pars) {
+ let eng = params.engine.originalEngine.wrappedJSObject;
+ //if (eng._readOnly && !("_serializeToJSON" in eng)) return;
+
+ params.iconURI = document.getElementById("icon").src;
+
+ let url = eng._getURLOfType("text/html");
+ url.__new_method = pars.method;
+ url.__new_template = pars.url;
+ let newParams = new (Cu.getGlobalForObject(eng)).Array(); // don't leak this window
+ let QueryParameter = Cu.getGlobalForObject(eng).QueryParameter;
+ for (let p of pars.fields) newParams.push(new QueryParameter(p.name, p.value));
+ url.__new_params = newParams;
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+const CANVAS_DATAURL_PREFIX = "data:image/png;base64,";
+const MAX_ICON_SIZE = 10000;
+
+
+function pickIcon (e) {
+ let prefs = Services.prefs.getBranch("extensions.addtosearchbox.");
+ let icon = document.getElementById("icon");
+
+ let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
+ fp.init(window, "", Ci.nsIFilePicker.modeOpen);
+ fp.appendFilters(Ci.nsIFilePicker.filterAll | Ci.nsIFilePicker.filterImages);
+ fp.filterIndex = 1; // images
+ try {
+ fp.displayDirectory = prefs.getComplexValue("lastdir", Ci.nsILocalFile);
+ if (!fp.displayDirectory) throw new Error("jump to catch!");
+ } catch (ex) {
+ fp.displayDirectory = FileUtils.getDir("Home", []);
+ }
+
+ if (icon.file && icon.file instanceof Ci.nsILocalFile) {
+ if (icon.file.parent.exists()) fp.displayDirectory = icon.file.parent;
+ if (icon.file.exists()) fp.defaultString = icon.file.leafName;
+ }
+
+ let rv = fp.show();
+ if (rv != Ci.nsIFilePicker.returnOK) return;
+ let file = fp.file;
+ prefs.setComplexValue("lastdir", Ci.nsILocalFile, file.parent);
+ if (!file.exists() || !file.isReadable() || file.isDirectory()) return;
+ params.iconChanged = true;
+ setIcon(fp.fileURL.spec, true);
+ icon.file = file;
+}
+
+
+function setIcon (url, verbose, fallback) {
+ let image = new Image();
+ image.onload = function () {
+ let icon = document.getElementById("icon");
+ let ctx = icon.getContext("2d");
+ ctx.fillStyle = ctx.strokeStyle = "rgba(0,0,0,0)"; // transparent
+ ctx.clearRect(0, 0, this.width, this.height);
+ ctx.drawImage(image, 0, 0, 16, 16);
+ let size = atob(icon.toDataURL().substr(CANVAS_DATAURL_PREFIX.length)).length;
+ if (size > MAX_ICON_SIZE) {
+ Cu.reportError("Add to Search Bar:pickIcon icon too large ("+url+")\n");
+ if (verbose) {
+ let bundleUrl = "chrome://browser/locale/engineInfos.properties";
+ let stringBundle = Services.strings.createBundle(bundleUrl);
+ let title = getString("iconFileSizeTitle");
+ let sizes = [(MAX_ICON_SIZE/1024).toFixed(2), (size/1024).toFixed(2)];
+ let text = getStringBundle().formatStringFromName("iconFileSizeMessage", sizes, 2);
+ Services.prompt.alert(window, title, text);
+ }
+ if ((fallback || icon.src) != url) setIcon(fallback || icon.src, false);
+ } else {
+ icon.src = icon.toDataURL();
+ icon.setAttribute("tooltiptext", url);
+ }
+ };
+ image.src = url;
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+function alert (msg) {
+ let pps = Cc["@mozilla.org/embedcomp/prompt-service;1"].getService(Ci.nsIPromptService);
+ pps.alert(window, getString(errorAlertTitle), getString(msg));
+}
+
+
+function engEditInfoDlgAccept (e) {
+ function $ (name) document.getElementById(name).value;
+
+ // returns object:
+ // .method
+ // .url
+ // .charset
+ // .fields[]
+ // .name
+ // .value
+ function parseQText (qtext) {
+ let ioSvc = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
+
+ function uriFromUrl (url, base) {
+ let baseUri = null;
+ if (typeof(base) === "string") baseUri = uriFromUrl(base);
+ else if (base) baseUri = base;
+ try {
+ return ioSvc.newURI(url, null, baseUri);
+ } catch (e) {
+ return null;
+ }
+ }
+
+ function unesc (s) {
+ let res = "";
+ let pos = 0;
+ while (pos < s.length) {
+ if (pos+1 < s.length && s[pos] == '\\') {
+ res += s[pos+1];
+ pos += 2;
+ } else {
+ res += s[pos];
+ ++pos;
+ }
+ }
+ return res;
+ }
+
+ let res = {};
+ let lines = [];
+ for (let s of qtext.split("\n")) {
+ s = s.replace(/^\s+/, "").replace(/\s+$/, "");
+ if (s.length != 0 && s[0] != '#') lines.push(s);
+ }
+ if (lines.length < 1) return "invalid query (it's empty)"; // alas
+
+ let qmt = lines[0].match(/^(\S+)\s+(.+)$/);
+ if (!qmt) return "invalid query: "+lines[0];
+
+ res.method = qmt[1];
+ if (res.method != "GET" && res.method != "POST") return "invalid method: "+res.method;
+
+ res.url = qmt[2];
+ if (!uriFromUrl(res.url)) return "invalid URL: "+res.url;
+
+ res.charset = (lines.length > 1 ? lines[1] : "UTF-8");
+
+ let fields = [];
+ for (let s of lines.slice(2)) {
+ if (s[0] == '=') return "invalid field: "+s;
+ // find '=' (but ignore escaped chars)
+ let p = 1;
+ while (p < s.length) {
+ if (s[p] == '\\') {
+ p += 2;
+ } else if (s[p] == '=') {
+ break;
+ } else {
+ ++p;
+ }
+ }
+ if (p >= s.length) return "invalid field: "+s;
+ let fld = {
+ name: unesc(s.substr(0, p)),
+ value: unesc(s.substr(p+1)),
+ };
+ fields.push(fld);
+ }
+ res.fields = fields;
+ return res;
+ }
+
+ params.name = $("name");
+ if (params.name.length == 0) { alert("errorEmptyName"); return false; }
+
+ params.alias = $("alias");
+ if (params.alias.length > 0) {
+ // check if we already has bookmark or engine with such alias
+ try {
+ let bmserv = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].getService(Ci.nsINavBookmarksService);
+ if (bmserv.getURIForKeyword(alias.value)) { alert("errorBookmarkAlias"); return false; }
+ } catch (e) {}
+ let engines = params.estore.engines;
+ for each (let engine in engines) {
+ if (engine.name != params.origName) {
+ if (engine.alias == params.alias) { alert("errorEngineAlias"); return false; }
+ if (engine.name == params.name) { alert("errorEngineName"); return false; }
+ }
+ }
+ }
+
+ // parse query
+ let qp = parseQText($("qtext"));
+ if (typeof(qp) == "string") { alert("errorEngineQuery"); return false; }
+
+ params.qp = qp;
+ params.accepted = true;
+
+ try {
+ storeChanges(params.qp);
+ } catch (e) {
+ Components.utils.reportError(e);
+ }
+
+ return true;
+}
+
+
+function engEditInfoDlgInit () {
+ params.origName = params.name;
+ params.iconChanged = false;
+ document.getElementById("name").value = params.name;
+ document.getElementById("alias").value = params.alias;
+ document.getElementById("qtext").value = params.qtext;
+ setIcon(params.iconURI, false, "moz-icon://stock/gtk-find?size=menu");
+ sizeToContent();
+ //document.getElementById("alias").focus();
+ document.getElementById("alias").select();
+}
diff --git a/application/palemoon/components/search/content/engineInfoEdit.xul b/application/palemoon/components/search/content/engineInfoEdit.xul
new file mode 100644
index 000000000..4210fa544
--- /dev/null
+++ b/application/palemoon/components/search/content/engineInfoEdit.xul
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+ %engInfoEditDTD;
+ %bookmarkDTD;
+]>
+
+
diff --git a/application/palemoon/components/search/content/engineManager.js b/application/palemoon/components/search/content/engineManager.js
index 993d48b06..109dc08d1 100644
--- a/application/palemoon/components/search/content/engineManager.js
+++ b/application/palemoon/components/search/content/engineManager.js
@@ -57,6 +57,20 @@ var gEngineManagerDialog = {
}
},
+ onCancel: function () {
+ // restore engine urls
+ let engines = gEngineView._engineStore.engines;
+ for each (let engine in engines) {
+ let ee = engine.originalEngine.wrappedJSObject;
+ for (let url of ee._urls) {
+ for (let name of ["method", "template", "params"]) {
+ let nn = "__new_"+name;
+ if (nn in url) delete url[nn];
+ }
+ }
+ }
+ },
+
onOK: function engineManager_onOK() {
// Set the preference
var newSuggestEnabled = document.getElementById("enableSuggest").checked;
@@ -64,6 +78,37 @@ var gEngineManagerDialog = {
// Commit the changes
gEngineView._engineStore.commit();
+
+ let engines = gEngineView._engineStore.engines;
+ for each (let engine in engines) {
+ let ee = engine.originalEngine.wrappedJSObject;
+ for (let url of ee._urls) {
+ for (let name of ["method", "template", "params"]) {
+ let nn = "__new_"+name;
+ if (nn in url) {
+ url[name] = url[nn];
+ delete url[nn];
+ }
+ }
+ }
+ if (ee._name != engine.name) {
+ let oldname = ee._name;
+ engine.originalEngine.name = engine.name;
+ ee.__old_name = ee._name;
+ ee._name = engine.name;
+ Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService).notifyObservers(ee, "browser-search-engine-modified", "engine-renamed");
+ }
+ if ("_searchForm" in engine) ee._searchForm = engine._searchForm;
+ if ("_queryCharset" in engine) ee._queryCharset = engine._queryCharset;
+ if (engine.__icon_changed) {
+ Components.utils.reportError("icon for '"+ee._name+"' was changed!");
+ ee._setIcon(engine.iconURI.spec, true);
+ }
+ // inform everybody of the changes, also stores our changes in the cache
+ Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService).notifyObservers(ee, "browser-search-engine-modified", "engine-changed");
+ //Tycho doesn't have this; besides, "engine-changed" will do that for us
+ //if (!ee._readOnly) ee._lazySerializeToFile();
+ }
},
onRestoreDefaults: function engineManager_onRestoreDefaults() {
@@ -112,47 +157,127 @@ var gEngineManagerDialog = {
editKeyword: Task.async(function* engineManager_editKeyword() {
var selectedEngine = gEngineView.selectedEngine;
- if (!selectedEngine)
- return;
+ if (!selectedEngine) return;
- var alias = { value: selectedEngine.alias };
- var strings = document.getElementById("engineManagerBundle");
- var title = strings.getString("editTitle");
- var msg = strings.getFormattedString("editMsg", [selectedEngine.name]);
-
- while (Services.prompt.prompt(window, title, msg, alias, null, {})) {
- var bduplicate = false;
- var eduplicate = false;
- var dupName = "";
-
- if (alias.value != "") {
- // Check for duplicates in Places keywords.
- bduplicate = !!(yield PlacesUtils.keywords.fetch(alias.value));
-
- // Check for duplicates in changes we haven't committed yet
- let engines = gEngineView._engineStore.engines;
- for each (let engine in engines) {
- if (engine.alias == alias.value &&
- engine.name != selectedEngine.name) {
- eduplicate = true;
- dupName = engine.name;
- break;
+ // returns either null or object:
+ // string name
+ // string alias
+ // string qtext
+ // url iconURI
+ function buildParams (engine) {
+ function url2text (ceng, eng, u) {
+ function getUF (name) {
+ let nn = "__new_"+name;
+ return (nn in u ? u[nn] : u[name]);
+ }
+ function getEF (name) {
+ return (name in ceng ? ceng[name] : eng[name]);
+ }
+ let normStr = function (s) { return s.replace(/\\/g, "\\\\").replace(/:/g, "\\:"); };
+ let tpl = getUF("template")||getEF("_searchForm");
+ let s = getUF("method")+" "+tpl+"\n"+(getEF("_queryCharset")||"UTF-8")+"\n";
+ let uparams = getUF("params");
+ if (uparams.length) {
+ s += "\n";
+ for (let p of uparams) {
+ s += p.name+"=";
+ if (p.value == "{searchTerms}") s += p.value; else s += normStr(p.value);
+ s += "\n";
}
}
+ return s;
}
- // Notify the user if they have chosen an existing engine/bookmark keyword
- if (eduplicate || bduplicate) {
- var dtitle = strings.getString("duplicateTitle");
- var bmsg = strings.getString("duplicateBookmarkMsg");
- var emsg = strings.getFormattedString("duplicateEngineMsg", [dupName]);
+ let res = {
+ iconURI: engine.iconURI,
+ name: engine.name,
+ alias: engine.alias,
+ engine: engine,
+ };
+ if (res.iconURI) res.iconURI = res.iconURI.spec;
- Services.prompt.alert(window, dtitle, eduplicate ? emsg : bmsg);
- } else {
- gEngineView._engineStore.changeEngine(selectedEngine, "alias",
- alias.value);
- gEngineView.invalidate();
- break;
+ let ceng = engine;
+ engine = engine.originalEngine.wrappedJSObject;
+
+ //if (engine._readOnly && !("_serializeToJSON" in engine)) {
+ // fallback to keyword editor
+ // return null;
+ //} else {
+ res.qtext = null;
+ let url = engine._getURLOfType("text/html");
+ if (!url) return null;
+ res.qtext = url2text(ceng, engine, url);
+ //}
+
+ return res;
+ }
+
+ let params = buildParams(selectedEngine);
+ if (params) {
+ // use extended dialog
+ //params.engine = selectedEngine;
+ params.estore = gEngineView._engineStore;
+ openDialog("chrome://browser/content/search/engineInfoEdit.xul",
+ "browser-search-info-editor", "chrome,dialog,modal,centerscreen,resizable",
+ params);
+ if (params.accepted) {
+ let inv = false;
+ if (params.alias != selectedEngine.alias) {
+ inv = true;
+ gEngineView._engineStore.changeEngine(selectedEngine, "alias", params.alias);
+ }
+ if (params.name != selectedEngine.name) {
+ inv = true;
+ gEngineView._engineStore.changeEngine(selectedEngine, "name", params.name);
+ //selectedEngine.name = params.name;
+ }
+ if (params.url != selectedEngine._searchForm) selectedEngine._searchForm = params.url;
+ if (params.charset != selectedEngine._queryCharset) selectedEngine._queryCharset = params.charset;
+ if (params.iconURI && params.iconChanged) {
+ let newURI = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService).newURI;
+ selectedEngine.iconURI = newURI(params.iconURI, null, null);
+ selectedEngine.__icon_changed = true;
+ inv = true;
+ }
+ if (inv) gEngineView.invalidate();
+ }
+ } else {
+ // use old dialog, so user can edit at least something
+ var alias = { value: selectedEngine.alias };
+ var strings = document.getElementById("engineManagerBundle");
+ var title = strings.getString("editTitle");
+ var msg = strings.getFormattedString("editMsg", [selectedEngine.name]);
+ while (Services.prompt.prompt(window, title, msg, alias, null, {})) {
+ var bduplicate = false;
+ var eduplicate = false;
+ var dupName = "";
+ if (alias.value != "") {
+ try {
+ let bmserv = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
+ getService(Ci.nsINavBookmarksService);
+ if (bmserv.getURIForKeyword(alias.value)) bduplicate = true;
+ } catch(ex) {}
+ // Check for duplicates in changes we haven't committed yet
+ let engines = gEngineView._engineStore.engines;
+ for each (let engine in engines) {
+ if (engine.alias == alias.value && engine.name != selectedEngine.name) {
+ eduplicate = true;
+ dupName = engine.name;
+ break;
+ }
+ }
+ }
+ // Notify the user if they have chosen an existing engine/bookmark keyword
+ if (eduplicate || bduplicate) {
+ var dtitle = strings.getString("duplicateTitle");
+ var bmsg = strings.getString("duplicateBookmarkMsg");
+ var emsg = strings.getFormattedString("duplicateEngineMsg", [dupName]);
+ Services.prompt.alert(window, dtitle, eduplicate ? emsg : bmsg);
+ } else {
+ gEngineView._engineStore.changeEngine(selectedEngine, "alias", alias.value);
+ gEngineView.invalidate();
+ break;
+ }
}
}
}),
@@ -176,7 +301,11 @@ var gEngineManagerDialog = {
document.getElementById("cmd_editkeyword")
.setAttribute("disabled", noSelection);
- }
+ },
+
+ onDblClick: function () {
+ if (gEngineView.selectedIndex >= 0) gEngineManagerDialog.editKeyword();
+ },
};
function onDragEngineStart(event) {
diff --git a/application/palemoon/components/search/content/engineManager.xul b/application/palemoon/components/search/content/engineManager.xul
index 1152ef8db..8aa8005eb 100644
--- a/application/palemoon/components/search/content/engineManager.xul
+++ b/application/palemoon/components/search/content/engineManager.xul
@@ -16,6 +16,7 @@
onload="gEngineManagerDialog.init();"
onunload="gEngineManagerDialog.destroy();"
ondialogaccept="gEngineManagerDialog.onOK();"
+ ondialogcancel="gEngineManagerDialog.onCancel();"
ondialogextra2="gEngineManagerDialog.onRestoreDefaults();"
title="&engineManager.title;"
style="&engineManager.style;"
@@ -52,7 +53,7 @@
+ seltype="single" onselect="gEngineManagerDialog.onSelect();" ondblclick="gEngineManagerDialog.onDblClick();">
diff --git a/application/palemoon/components/search/jar.mn b/application/palemoon/components/search/jar.mn
index e6c42f97d..a97fc5ccf 100644
--- a/application/palemoon/components/search/jar.mn
+++ b/application/palemoon/components/search/jar.mn
@@ -7,3 +7,5 @@ browser.jar:
content/browser/search/searchbarBindings.css (content/searchbarBindings.css)
content/browser/search/engineManager.xul (content/engineManager.xul)
content/browser/search/engineManager.js (content/engineManager.js)
+ content/browser/search/engineInfoEdit.xul (content/engineInfoEdit.xul)
+ content/browser/search/engineInfoEdit.js (content/engineInfoEdit.js)
diff --git a/application/palemoon/locales/en-US/chrome/browser/engineInfoEdit.dtd b/application/palemoon/locales/en-US/chrome/browser/engineInfoEdit.dtd
new file mode 100644
index 000000000..7668d94dc
--- /dev/null
+++ b/application/palemoon/locales/en-US/chrome/browser/engineInfoEdit.dtd
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
diff --git a/application/palemoon/locales/en-US/chrome/browser/engineInfoEdit.properties b/application/palemoon/locales/en-US/chrome/browser/engineInfoEdit.properties
new file mode 100644
index 000000000..2d248b827
--- /dev/null
+++ b/application/palemoon/locales/en-US/chrome/browser/engineInfoEdit.properties
@@ -0,0 +1,13 @@
+
+
+iconFileSizeTitle=File Size Exceeding Maximum
+iconFileSizeMessage=To avoid delays when starting Firefox the size of an icon must not exceed %1$S KB. The icon you chose is %2$S KB large.\n\nPlease try to reduce the file size or choose another icon.
+errorAlertTitle=Search Engine Specification Error
+errorEmptyName=Search Engine name is empty
+errorBookmarkAlias=You already has Bookmark with the same alias
+errorEngineAlias=You already has Search Engine with the same alias
+errorEngineName=You already has Search Engine with the same name
+errorEngineQuery=Invalid Search Engine query
diff --git a/application/palemoon/locales/en-US/chrome/browser/engineManager.dtd b/application/palemoon/locales/en-US/chrome/browser/engineManager.dtd
index 8ad977205..e18825aa6 100644
--- a/application/palemoon/locales/en-US/chrome/browser/engineManager.dtd
+++ b/application/palemoon/locales/en-US/chrome/browser/engineManager.dtd
@@ -16,7 +16,7 @@
-
+
diff --git a/application/palemoon/locales/jar.mn b/application/palemoon/locales/jar.mn
index 0fc7f2c9b..81d9648ce 100644
--- a/application/palemoon/locales/jar.mn
+++ b/application/palemoon/locales/jar.mn
@@ -36,6 +36,8 @@
locale/browser/searchbar.dtd (%chrome/browser/searchbar.dtd)
locale/browser/engineManager.dtd (%chrome/browser/engineManager.dtd)
locale/browser/engineManager.properties (%chrome/browser/engineManager.properties)
+ locale/browser/engineInfoEdit.dtd (%chrome/browser/engineInfoEdit.dtd)
+ locale/browser/engineInfoEdit.properties (%chrome/browser/engineInfoEdit.properties)
locale/browser/setDesktopBackground.dtd (%chrome/browser/setDesktopBackground.dtd)
locale/browser/shellservice.properties (%chrome/browser/shellservice.properties)
locale/browser/statusbar/statusbar-overlay.dtd (%chrome/browser/statusbar/statusbar-overlay.dtd)
diff --git a/application/palemoon/themes/linux/engineInfoEdit.css b/application/palemoon/themes/linux/engineInfoEdit.css
new file mode 100644
index 000000000..116949be8
--- /dev/null
+++ b/application/palemoon/themes/linux/engineInfoEdit.css
@@ -0,0 +1,22 @@
+/* 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/.
+ Based on "Add to Search Bar" addon by Malte Kraus and Gavin Sharp */
+
+#icon {
+ height: 22px;
+ width: 22px;
+ border: 3px none;
+}
+
+/* do not stretch the icon to the available space */
+/*#icon-row, #icon-row > hbox { -moz-box-align: center; }*/
+
+dialog:root {
+ overflow: auto;
+ min-width: 400px;
+}
+
+#icon-row, #icon-row > hbox {
+ -moz-box-align: center; /* do not stretch the icon to the available space */
+}
diff --git a/application/palemoon/themes/linux/jar.mn b/application/palemoon/themes/linux/jar.mn
index a79487c7f..4f4333841 100644
--- a/application/palemoon/themes/linux/jar.mn
+++ b/application/palemoon/themes/linux/jar.mn
@@ -21,6 +21,7 @@ browser.jar:
* skin/classic/browser/browser.css
skin/classic/browser/click-to-play-warning-stripes.png
* skin/classic/browser/engineManager.css
+* skin/classic/browser/engineInfoEdit.css
skin/classic/browser/Geolocation-16.png
skin/classic/browser/Geolocation-64.png
skin/classic/browser/Go-arrow.png
diff --git a/application/palemoon/themes/osx/engineInfoEdit.css b/application/palemoon/themes/osx/engineInfoEdit.css
new file mode 100644
index 000000000..116949be8
--- /dev/null
+++ b/application/palemoon/themes/osx/engineInfoEdit.css
@@ -0,0 +1,22 @@
+/* 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/.
+ Based on "Add to Search Bar" addon by Malte Kraus and Gavin Sharp */
+
+#icon {
+ height: 22px;
+ width: 22px;
+ border: 3px none;
+}
+
+/* do not stretch the icon to the available space */
+/*#icon-row, #icon-row > hbox { -moz-box-align: center; }*/
+
+dialog:root {
+ overflow: auto;
+ min-width: 400px;
+}
+
+#icon-row, #icon-row > hbox {
+ -moz-box-align: center; /* do not stretch the icon to the available space */
+}
diff --git a/application/palemoon/themes/windows/engineInfoEdit.css b/application/palemoon/themes/windows/engineInfoEdit.css
new file mode 100644
index 000000000..116949be8
--- /dev/null
+++ b/application/palemoon/themes/windows/engineInfoEdit.css
@@ -0,0 +1,22 @@
+/* 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/.
+ Based on "Add to Search Bar" addon by Malte Kraus and Gavin Sharp */
+
+#icon {
+ height: 22px;
+ width: 22px;
+ border: 3px none;
+}
+
+/* do not stretch the icon to the available space */
+/*#icon-row, #icon-row > hbox { -moz-box-align: center; }*/
+
+dialog:root {
+ overflow: auto;
+ min-width: 400px;
+}
+
+#icon-row, #icon-row > hbox {
+ -moz-box-align: center; /* do not stretch the icon to the available space */
+}
diff --git a/toolkit/components/search/current/nsSearchService.js b/toolkit/components/search/current/nsSearchService.js
index 6e8f6da43..dad11ae0e 100644
--- a/toolkit/components/search/current/nsSearchService.js
+++ b/toolkit/components/search/current/nsSearchService.js
@@ -75,6 +75,7 @@ const SEARCH_ENGINE_CHANGED = "engine-changed";
const SEARCH_ENGINE_LOADED = "engine-loaded";
const SEARCH_ENGINE_CURRENT = "engine-current";
const SEARCH_ENGINE_DEFAULT = "engine-default";
+const SEARCH_ENGINE_RENAMED = "engine-renamed";
// The following constants are left undocumented in nsIBrowserSearchService.idl
// For the moment, they are meant for testing/debugging purposes only.
@@ -4603,6 +4604,20 @@ SearchService.prototype = {
// Invalidate the map used to parse URLs to search engines.
this._parseSubmissionMap = null;
break;
+ case SEARCH_ENGINE_RENAMED:
+ if (aEngine && ("wrappedJSObject" in aEngine)) {
+ let wjo = aEngine.wrappedJSObject;
+ if (wjo && ("__old_name" in wjo)) {
+ delete this._engines[wjo.__old_name];
+ this._engines[wjo._name] = wjo;
+ delete wjo.__old_name;
+ this.batchTask.disarm();
+ this.batchTask.arm();
+ // Invalidate the map used to parse URLs to search engines.
+ this._parseSubmissionMap = null;
+ }
+ }
+ break;
}
break;