зеркало из https://github.com/mozilla/pjs.git
Bug 378553 - Expose search engine alias functionality. r=gavin
This commit is contained in:
Родитель
1fa02e7409
Коммит
81b4505d40
|
@ -2003,115 +2003,89 @@ function BrowserLoadURL(aTriggeringEvent, aPostData) {
|
|||
focusElement(content);
|
||||
}
|
||||
|
||||
function getShortcutOrURI(aURL, aPostDataRef)
|
||||
{
|
||||
// rjc: added support for URL shortcuts (3/30/1999)
|
||||
try {
|
||||
function getShortcutOrURI(aURL, aPostDataRef) {
|
||||
var shortcutURL = null;
|
||||
#ifdef MOZ_PLACES_BOOKMARKS
|
||||
var shortcutURI = PlacesUtils.bookmarks.getURIForKeyword(aURL);
|
||||
if (shortcutURI) {
|
||||
shortcutURL = shortcutURI.spec;
|
||||
// get POST data
|
||||
var postData = PlacesUtils.getPostDataForURI(shortcutURI);
|
||||
aPostDataRef.value = postData;
|
||||
var keyword = aURL;
|
||||
var param = "";
|
||||
var searchService = Cc["@mozilla.org/browser/search-service;1"].
|
||||
getService(Ci.nsIBrowserSearchService);
|
||||
|
||||
var offset = aURL.indexOf(" ");
|
||||
if (offset > 0) {
|
||||
keyword = aURL.substr(0, offset);
|
||||
param = aURL.substr(offset + 1);
|
||||
}
|
||||
#else
|
||||
shortcutURL = BMSVC.resolveKeyword(aURL, aPostDataRef);
|
||||
#endif
|
||||
if (!shortcutURL) {
|
||||
// rjc: add support for string substitution with shortcuts (4/4/2000)
|
||||
// (see bug # 29871 for details)
|
||||
var aOffset = aURL.indexOf(" ");
|
||||
if (aOffset > 0) {
|
||||
var cmd = aURL.substr(0, aOffset);
|
||||
var text = aURL.substr(aOffset+1);
|
||||
|
||||
var engine = searchService.getEngineByAlias(keyword);
|
||||
if (engine)
|
||||
return engine.getSubmission(param, null).uri.spec;
|
||||
|
||||
try {
|
||||
#ifdef MOZ_PLACES_BOOKMARKS
|
||||
shortcutURI = PlacesUtils.bookmarks.getURIForKeyword(cmd);
|
||||
if (shortcutURI)
|
||||
var shortcutURI = PlacesUtils.bookmarks.getURIForKeyword(keyword);
|
||||
shortcutURL = shortcutURI.spec;
|
||||
aPostDataRef.value = PlacesUtils.getPostDataForURI(shortcutURI);
|
||||
#else
|
||||
shortcutURL = BMSVC.resolveKeyword(cmd, aPostDataRef);
|
||||
shortcutURL = BMSVC.resolveKeyword(keyword, aPostDataRef);
|
||||
#endif
|
||||
if (shortcutURL && text) {
|
||||
var encodedText = null;
|
||||
} catch(ex) {}
|
||||
|
||||
if (!shortcutURL)
|
||||
return aURL;
|
||||
|
||||
var postData = "";
|
||||
if (aPostDataRef && aPostDataRef.value)
|
||||
postData = unescape(aPostDataRef.value);
|
||||
|
||||
if (/%s/i.test(shortcutURL) || /%s/i.test(postData)) {
|
||||
var charset = "";
|
||||
const re = /^(.*)\&mozcharset=([a-zA-Z][_\-a-zA-Z0-9]+)\s*$/;
|
||||
var matches = shortcutURL.match(re);
|
||||
if (matches) {
|
||||
shortcutURL = matches[1];
|
||||
charset = matches[2];
|
||||
}
|
||||
#ifndef MOZ_PLACES_BOOKMARKS
|
||||
// FIXME: Bug #317472, we don't have last charset in places yet.
|
||||
else if (/%s/.test(shortcutURL) ||
|
||||
(aPostDataRef && /%s/.test(aPostDataRef.value))) {
|
||||
if (matches)
|
||||
[, shortcutURL, charset] = matches;
|
||||
else {
|
||||
try {
|
||||
//XXX Bug 317472 will add lastCharset support to places.
|
||||
#ifndef MOZ_PLACES_BOOKMARKS
|
||||
charset = BMSVC.getLastCharset(shortcutURL);
|
||||
} catch (ex) {
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} catch (ex) {
|
||||
Components.utils.reportError(ex);
|
||||
}
|
||||
}
|
||||
|
||||
var encodedParam = "";
|
||||
if (charset)
|
||||
encodedText = escape(convertFromUnicode(charset, text));
|
||||
else // default case: charset=UTF-8
|
||||
encodedText = encodeURIComponent(text);
|
||||
encodedParam = escape(converFromUnicode(charset, param));
|
||||
else // Default charset is UTF-8
|
||||
encodedParam = encodeURIComponent(param);
|
||||
|
||||
if (aPostDataRef && aPostDataRef.value) {
|
||||
// XXXben - currently we only support "application/x-www-form-urlencoded"
|
||||
// enctypes.
|
||||
aPostDataRef.value = unescape(aPostDataRef.value);
|
||||
if (aPostDataRef.value.match(/%[sS]/)) {
|
||||
aPostDataRef.value = getPostDataStream(aPostDataRef.value,
|
||||
text, encodedText,
|
||||
shortcutURL = shortcutURL.replace(/%s/g, encodedParam).replace(/%S/g, param);
|
||||
|
||||
if (/%s/i.test(postData)) // POST keyword
|
||||
aPostDataRef.value = getPostDataStream(postData, param, encodedParam,
|
||||
"application/x-www-form-urlencoded");
|
||||
}
|
||||
else {
|
||||
shortcutURL = null;
|
||||
aPostDataRef.value = null;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (/%[sS]/.test(shortcutURL))
|
||||
shortcutURL = shortcutURL.replace(/%s/g, encodedText)
|
||||
.replace(/%S/g, text);
|
||||
else
|
||||
shortcutURL = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
aPostDataRef.value = null;
|
||||
|
||||
return shortcutURL;
|
||||
}
|
||||
|
||||
if (shortcutURL)
|
||||
aURL = shortcutURL;
|
||||
|
||||
} catch (ex) {
|
||||
}
|
||||
return aURL;
|
||||
}
|
||||
|
||||
function getPostDataStream(aStringData, aKeyword, aEncKeyword, aType)
|
||||
{
|
||||
var dataStream = Components.classes["@mozilla.org/io/string-input-stream;1"]
|
||||
.createInstance(Components.interfaces.nsIStringInputStream);
|
||||
function getPostDataStream(aStringData, aKeyword, aEncKeyword, aType) {
|
||||
var dataStream = Cc["@mozilla.org/io/string-input-stream;1"].
|
||||
createInstance(Ci.nsIStringInputStream);
|
||||
aStringData = aStringData.replace(/%s/g, aEncKeyword).replace(/%S/g, aKeyword);
|
||||
#ifdef MOZILLA_1_8_BRANCH
|
||||
# bug 318193
|
||||
dataStream.setData(aStringData, aStringData.length);
|
||||
#else
|
||||
dataStream.data = aStringData;
|
||||
#endif
|
||||
|
||||
var mimeStream = Components.classes["@mozilla.org/network/mime-input-stream;1"]
|
||||
.createInstance(Components.interfaces.nsIMIMEInputStream);
|
||||
var mimeStream = Cc["@mozilla.org/network/mime-input-stream;1"].
|
||||
createInstance(Ci.nsIMIMEInputStream);
|
||||
mimeStream.addHeader("Content-Type", aType);
|
||||
mimeStream.addContentLength = true;
|
||||
mimeStream.setData(dataStream);
|
||||
return mimeStream.QueryInterface(Components.interfaces.nsIInputStream);
|
||||
return mimeStream.QueryInterface(Ci.nsIInputStream);
|
||||
}
|
||||
|
||||
|
||||
function readFromClipboard()
|
||||
{
|
||||
var url;
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
# Ben Goodger <beng@google.com> (Original author)
|
||||
# Gavin Sharp <gavin@gavinsharp.com>
|
||||
# Pamela Greene <pamg.bugs@gmail.com>
|
||||
# Ryan Flint <rflint@dslr.net>
|
||||
#
|
||||
# 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
|
||||
|
@ -150,12 +151,79 @@ var gEngineManagerDialog = {
|
|||
document.getElementById("engineList").focus();
|
||||
},
|
||||
|
||||
editKeyword: function engineManager_editKeyword() {
|
||||
var selectedEngine = gEngineView.selectedEngine;
|
||||
if (!selectedEngine)
|
||||
return;
|
||||
|
||||
var prompt = Cc["@mozilla.org/embedcomp/prompt-service;1"].
|
||||
getService(Ci.nsIPromptService);
|
||||
var alias = { value: selectedEngine.alias };
|
||||
var strings = document.getElementById("engineManagerBundle");
|
||||
var title = strings.getString("editTitle");
|
||||
var msg = strings.getFormattedString("editMsg", [selectedEngine.name]);
|
||||
|
||||
while (prompt.prompt(window, title, msg, alias, null, { })) {
|
||||
var searchService = Cc["@mozilla.org/browser/search-service;1"].
|
||||
getService(Ci.nsIBrowserSearchService);
|
||||
var engine = searchService.getEngineByAlias(alias.value);
|
||||
var bduplicate = false;
|
||||
var eduplicate = false;
|
||||
|
||||
if (engine) {
|
||||
if (engine.name != selectedEngine.name)
|
||||
eduplicate = true;
|
||||
} else {
|
||||
try {
|
||||
#ifdef MOZ_PLACES_BOOKMARKS
|
||||
var bmserv = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
|
||||
getService(Ci.nsINavBookmarksService);
|
||||
if (bmserv.getURIForKeyword(alias.value))
|
||||
bduplicate = true;
|
||||
#else
|
||||
var bmserv = Cc["@mozilla.org/browser/bookmarks-service;1"].
|
||||
getService(Ci.nsIBookmarksService);
|
||||
if (bmserv.resolveKeyword(alias.value, {}))
|
||||
bduplicate = true;
|
||||
#endif
|
||||
} catch(ex) {}
|
||||
|
||||
// Check for duplicates in changes we haven't committed yet
|
||||
var engines = gEngineView._engineStore.engines;
|
||||
for each (var engine in engines) {
|
||||
if (engine.alias == alias.value &&
|
||||
engine.name != selectedEngine.name) {
|
||||
eduplicate = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Notify the user if they have chosen an existing engine/bookmark keyword
|
||||
if (eduplicate || bduplicate) {
|
||||
var dtitle = strings.getString("duplicateTitle");
|
||||
var bookmark = strings.getString("duplicateBookmark");
|
||||
var dmsg = strings.getFormattedString("duplicateMsg",
|
||||
[(bduplicate) ? bookmark : '"' +
|
||||
engine.name + '"']);
|
||||
|
||||
prompt.alert(window, dtitle, dmsg);
|
||||
} else {
|
||||
gEngineView._engineStore.changeEngine(selectedEngine, "alias",
|
||||
alias.value);
|
||||
gEngineView.invalidate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
onSelect: function engineManager_onSelect() {
|
||||
// buttons only work if an engine is selected and it's not the last engine
|
||||
var disableButtons = (gEngineView.selectedIndex == -1) ||
|
||||
(gEngineView.lastIndex == 0);
|
||||
var lastSelected = (gEngineView.selectedIndex == gEngineView.lastIndex);
|
||||
var firstSelected = (gEngineView.selectedIndex == 0);
|
||||
var noSelection = (gEngineView.selectedIndex == -1);
|
||||
|
||||
document.getElementById("cmd_remove").setAttribute("disabled",
|
||||
disableButtons);
|
||||
|
@ -165,6 +233,8 @@ var gEngineManagerDialog = {
|
|||
|
||||
document.getElementById("cmd_movedown").setAttribute("disabled",
|
||||
disableButtons || lastSelected);
|
||||
document.getElementById("cmd_editkeyword").setAttribute("disabled",
|
||||
noSelection);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -233,6 +303,23 @@ EngineUnhideOp.prototype = {
|
|||
}
|
||||
}
|
||||
|
||||
function EngineChangeOp(aEngineClone, aProp, aValue) {
|
||||
if (!aEngineClone)
|
||||
throw new Error("bad args to new EngineChangeOp!");
|
||||
|
||||
this._engine = aEngineClone.originalEngine;
|
||||
this._prop = aProp;
|
||||
this._newValue = aValue;
|
||||
}
|
||||
EngineChangeOp.prototype = {
|
||||
_engine: null,
|
||||
_prop: null,
|
||||
_newValue: null,
|
||||
commit: function ECO_commit() {
|
||||
this._engine[this._prop] = this._newValue;
|
||||
}
|
||||
}
|
||||
|
||||
function EngineStore() {
|
||||
var searchService = Cc["@mozilla.org/browser/search-service;1"].
|
||||
getService(Ci.nsIBrowserSearchService);
|
||||
|
@ -349,6 +436,15 @@ EngineStore.prototype = {
|
|||
return added;
|
||||
},
|
||||
|
||||
changeEngine: function ES_changeEngine(aEngine, aProp, aNewValue) {
|
||||
var index = this._getIndexForEngine(aEngine);
|
||||
if (index == -1)
|
||||
throw new Error("invalid engine?");
|
||||
|
||||
this._engines[index][aProp] = aNewValue;
|
||||
this._ops.push(new EngineChangeOp(aEngine, aProp, aNewValue));
|
||||
},
|
||||
|
||||
reloadIcons: function ES_reloadIcons() {
|
||||
this._engines.forEach(function (e) {
|
||||
e.uri = e.originalEngine.uri;
|
||||
|
@ -431,6 +527,8 @@ EngineView.prototype = {
|
|||
getCellText: function(index, column) {
|
||||
if (column.id == "engineName")
|
||||
return this._engineStore.engines[index].name;
|
||||
else if (column.id == "engineKeyword")
|
||||
return this._engineStore.engines[index].alias;
|
||||
return "";
|
||||
},
|
||||
|
||||
|
|
|
@ -71,8 +71,8 @@
|
|||
<command id="cmd_movedown"
|
||||
oncommand="gEngineManagerDialog.bump(-1);"
|
||||
disabled="true"/>
|
||||
<command id="cmd_editalias"
|
||||
oncommand="gEngineManagerDialog.editAlias();"
|
||||
<command id="cmd_editkeyword"
|
||||
oncommand="gEngineManagerDialog.editKeyword();"
|
||||
disabled="true"/>
|
||||
</commandset>
|
||||
|
||||
|
@ -80,6 +80,10 @@
|
|||
<key id="delete" keycode="VK_DELETE" command="cmd_remove"/>
|
||||
</keyset>
|
||||
|
||||
<stringbundleset id="engineManagerBundleset">
|
||||
<stringbundle id="engineManagerBundle" src="chrome://browser/locale/engineManager.properties"/>
|
||||
</stringbundleset>
|
||||
|
||||
<description>&engineManager.intro;</description>
|
||||
<separator class="thin"/>
|
||||
<hbox flex="1">
|
||||
|
@ -88,11 +92,16 @@
|
|||
<treechildren id="engineChildren" flex="1"
|
||||
ondraggesture="nsDragAndDrop.startDrag(event, gDragObserver);"/>
|
||||
<treecols>
|
||||
<treecol id="engineName" flex="1" hideheader="true"/>
|
||||
<treecol id="engineName" flex="4" label="&columnLabel.name;"/>
|
||||
<treecol id="engineKeyword" flex="1" label="&columnLabel.keyword;"/>
|
||||
</treecols>
|
||||
</tree>
|
||||
<vbox>
|
||||
<spacer flex="1"/>
|
||||
<button id="edit"
|
||||
label="&edit.label;"
|
||||
accesskey="&edit.accesskey;"
|
||||
command="cmd_editkeyword"/>
|
||||
<button id="up"
|
||||
label="&up.label;"
|
||||
accesskey="&up.accesskey;"
|
||||
|
|
|
@ -2725,8 +2725,10 @@ SearchService.prototype = {
|
|||
this._currentEngine = null;
|
||||
|
||||
if (engineToRemove._readOnly) {
|
||||
// Just hide it (the "hidden" setter will notify)
|
||||
// Just hide it (the "hidden" setter will notify) and remove its alias to
|
||||
// avoid future conflicts with other engines.
|
||||
engineToRemove.hidden = true;
|
||||
engineToRemove.alias = null;
|
||||
} else {
|
||||
// Remove the engine file from disk (this might throw)
|
||||
engineToRemove._remove();
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
<!ENTITY engineManager.style "min-width: 35em;">
|
||||
<!ENTITY engineManager.intro "You have the following search engines installed:">
|
||||
|
||||
<!ENTITY columnLabel.name "Name">
|
||||
<!ENTITY columnLabel.keyword "Keyword">
|
||||
|
||||
<!-- Buttons -->
|
||||
<!ENTITY up.label "Move Up">
|
||||
<!ENTITY up.accesskey "U">
|
||||
|
@ -9,6 +12,8 @@
|
|||
<!ENTITY dn.accesskey "D">
|
||||
<!ENTITY remove.label "Remove">
|
||||
<!ENTITY remove.accesskey "R">
|
||||
<!ENTITY edit.label "Edit Keyword...">
|
||||
<!ENTITY edit.accesskey "t">
|
||||
|
||||
<!ENTITY addEngine.label "Get more search engines...">
|
||||
<!ENTITY addEngine.accesskey "A">
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
editTitle=Edit Keyword
|
||||
editMsg=Enter a new keyword for "%S":
|
||||
duplicateTitle=Duplicate Keyword
|
||||
# Localization Note: The substitution in duplicateMsg will either be a search
|
||||
# plugin name (e.g. ...in use by "Google".) or the duplicateBookmark string
|
||||
# below (e.g. ...in use by a bookmark.).
|
||||
duplicateMsg=You have chosen a keyword that is currently in use by %S. Please select another.
|
||||
duplicateBookmark=a bookmark
|
Загрузка…
Ссылка в новой задаче