Search provider edit patch
parent
e00ad2c8d4
commit
ae278366f9
|
@ -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();
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- 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 -->
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin/"?>
|
||||
<?xml-stylesheet href="chrome://browser/skin/engineInfoEdit.css"?>
|
||||
|
||||
<!DOCTYPE dialog [
|
||||
<!ENTITY % engInfoEditDTD SYSTEM "chrome://browser/locale/engineInfoEdit.dtd">
|
||||
<!ENTITY % bookmarkDTD SYSTEM "chrome://browser/locale/places/editBookmarkOverlay.dtd">
|
||||
%engInfoEditDTD;
|
||||
%bookmarkDTD;
|
||||
]>
|
||||
|
||||
<dialog id="engineInfoEdit"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
buttons="accept,cancel"
|
||||
ondialogaccept="return engEditInfoDlgAccept(event);"
|
||||
onload="engEditInfoDlgInit();"
|
||||
title="&title;"
|
||||
persist="screenX screenY width height"
|
||||
windowtype="Browser:SearchInfoEditor">
|
||||
<script type="application/javascript" src="chrome://browser/content/search/engineInfoEdit.js"/>
|
||||
|
||||
<vbox flex="1">
|
||||
<grid>
|
||||
<columns>
|
||||
<column flex="0"/>
|
||||
<column flex="1"/>
|
||||
</columns>
|
||||
|
||||
<rows id="rows">
|
||||
<row id="name-row">
|
||||
<label control="name" accesskey="&name.accesskey;">&name.label;</label>
|
||||
<textbox value="" id="name" />
|
||||
</row>
|
||||
|
||||
<row id="icon-row">
|
||||
<label control="alias" id="alias-label" accesskey="&editBookmarkOverlay.keyword.accesskey;" value="&editBookmarkOverlay.keyword.label;" />
|
||||
<hbox>
|
||||
<textbox value="" id="alias" flex="1" />
|
||||
<html:canvas id="icon" width="16" height="16" />
|
||||
<button label="&browse.label;" oncommand="pickIcon(event);" id="icon-picker" accesskey="&browse.accesskey;" />
|
||||
</hbox>
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
<textbox id="qtext" multiline="true" rows="8" flex="1" />
|
||||
</vbox>
|
||||
|
||||
</dialog>
|
|
@ -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) {
|
||||
|
|
|
@ -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 @@
|
|||
<separator class="thin"/>
|
||||
<hbox flex="1">
|
||||
<tree id="engineList" flex="1" rows="10" hidecolumnpicker="true"
|
||||
seltype="single" onselect="gEngineManagerDialog.onSelect();">
|
||||
seltype="single" onselect="gEngineManagerDialog.onSelect();" ondblclick="gEngineManagerDialog.onDblClick();">
|
||||
<treechildren id="engineChildren" flex="1"
|
||||
ondragstart="onDragEngineStart(event);"/>
|
||||
<treecols>
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
<!-- 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 -->
|
||||
|
||||
<!ENTITY title "Edit Search Engine Parameters">
|
||||
<!ENTITY name.label "Name:">
|
||||
<!ENTITY name.accesskey "N">
|
||||
<!ENTITY browse.label "Browse…">
|
||||
<!ENTITY browse.accesskey "B">
|
|
@ -0,0 +1,13 @@
|
|||
<!-- 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 -->
|
||||
|
||||
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
|
|
@ -16,7 +16,7 @@
|
|||
<!ENTITY dn.accesskey "D">
|
||||
<!ENTITY remove.label "Remove">
|
||||
<!ENTITY remove.accesskey "R">
|
||||
<!ENTITY edit.label "Edit Keyword…">
|
||||
<!ENTITY edit.label "Edit engine…">
|
||||
<!ENTITY edit.accesskey "t">
|
||||
|
||||
<!ENTITY addEngine.label "Get more search engines…">
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 */
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
}
|
|
@ -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 */
|
||||
}
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue