--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -2095,63 +2095,91 @@ function loadURI(uri, referrer, postData
openLinkIn(uri, "current",
{ referrerURI: referrer,
referrerPolicy: referrerPolicy,
postData: postData,
allowThirdPartyFixup: allowThirdPartyFixup });
} catch (e) {}
}
-function getShortcutOrURIAndPostData(aURL, aCallback) {
- let mayInheritPrincipal = false;
- let postData = null;
- let shortcutURL = null;
- let keyword = aURL;
- let param = "";
-
- // XXX Bug 1100294 will remove this little hack by using an async version of
- // PlacesUtils.getURLAndPostDataForKeyword(). For now we simulate an async
- // execution with at least a setTimeout(fn, 0).
- let originalCallback = aCallback;
- aCallback = data => setTimeout(() => originalCallback(data));
-
- let offset = aURL.indexOf(" ");
- if (offset > 0) {
- keyword = aURL.substr(0, offset);
- param = aURL.substr(offset + 1);
- }
-
- let engine = Services.search.getEngineByAlias(keyword);
- if (engine) {
- let submission = engine.getSubmission(param, null, "keyword");
- postData = submission.postData;
- aCallback({ postData: submission.postData, url: submission.uri.spec,
- mayInheritPrincipal: mayInheritPrincipal });
- return;
- }
-
- [shortcutURL, postData] =
- PlacesUtils.getURLAndPostDataForKeyword(keyword);
-
- if (!shortcutURL) {
- aCallback({ postData: postData, url: aURL,
- mayInheritPrincipal: mayInheritPrincipal });
- return;
- }
-
- let escapedPostData = "";
- if (postData)
- escapedPostData = unescape(postData);
-
- if (/%s/i.test(shortcutURL) || /%s/i.test(escapedPostData)) {
- let charset = "";
- const re = /^(.*)\&mozcharset=([a-zA-Z][_\-a-zA-Z0-9]+)\s*$/;
- let matches = shortcutURL.match(re);
-
- let continueOperation = function () {
+/**
+ * Given a urlbar value, discerns between URIs, keywords and aliases.
+ *
+ * @param url
+ * The urlbar value.
+ * @param callback (optional, deprecated)
+ * The callback function invoked when done. This parameter is
+ * deprecated, please use the Promise that is returned.
+ *
+ * @return Promise<{ postData, url, mayInheritPrincipal }>
+ */
+function getShortcutOrURIAndPostData(url, callback = null) {
+ if (callback) {
+ Deprecated.warning("Please use the Promise returned by " +
+ "getShortcutOrURIAndPostData() instead of passing a " +
+ "callback",
+ "https://bugzilla.mozilla.org/show_bug.cgi?id=1100294");
+ }
+
+ return Task.spawn(function* () {
+ let mayInheritPrincipal = false;
+ let postData = null;
+ let shortcutURL = null;
+ let keyword = url;
+ let param = "";
+
+ let offset = url.indexOf(" ");
+ if (offset > 0) {
+ keyword = url.substr(0, offset);
+ param = url.substr(offset + 1);
+ }
+
+ let engine = Services.search.getEngineByAlias(keyword);
+ if (engine) {
+ let submission = engine.getSubmission(param, null, "keyword");
+ postData = submission.postData;
+ return { postData: submission.postData, url: submission.uri.spec,
+ mayInheritPrincipal };
+ }
+
+ let entry = yield PlacesUtils.keywords.fetch(keyword);
+ if (entry) {
+ shortcutURL = entry.url.href;
+ postData = entry.postData;
+ }
+
+ if (!shortcutURL) {
+ return { postData, url, mayInheritPrincipal };
+ }
+
+ let escapedPostData = "";
+ if (postData)
+ escapedPostData = unescape(postData);
+
+ if (/%s/i.test(shortcutURL) || /%s/i.test(escapedPostData)) {
+ let charset = "";
+ const re = /^(.*)\&mozcharset=([a-zA-Z][_\-a-zA-Z0-9]+)\s*$/;
+ let matches = shortcutURL.match(re);
+
+ if (matches) {
+ [, shortcutURL, charset] = matches;
+ } else {
+ let uri;
+ try {
+ // makeURI() throws if URI is invalid.
+ uri = makeURI(shortcutURL);
+ } catch (ex) {}
+
+ if (uri) {
+ // Try to get the saved character-set.
+ // Will return an empty string if character-set is not found.
+ charset = yield PlacesUtils.getCharsetForURI(uri);
+ }
+ }
+
// encodeURIComponent produces UTF-8, and cannot be used for other charsets.
// escape() works in those cases, but it doesn't uri-encode +, @, and /.
// Therefore we need to manually replace these ASCII characters by their
// encodeURIComponent result, to match the behavior of nsEscape() with
// url_XPAlphas
let encodedParam = "";
if (charset && charset != "UTF-8")
encodedParam = escape(convertFromUnicode(charset, param)).
@@ -2164,50 +2192,39 @@ function getShortcutOrURIAndPostData(aUR
if (/%s/i.test(escapedPostData)) // POST keyword
postData = getPostDataStream(escapedPostData, param, encodedParam,
"application/x-www-form-urlencoded");
// This URL came from a bookmark, so it's safe to let it inherit the current
// document's principal.
mayInheritPrincipal = true;
- aCallback({ postData: postData, url: shortcutURL,
- mayInheritPrincipal: mayInheritPrincipal });
- }
-
- if (matches) {
- [, shortcutURL, charset] = matches;
- continueOperation();
- } else {
- // Try to get the saved character-set.
- // makeURI throws if URI is invalid.
- // Will return an empty string if character-set is not found.
- try {
- PlacesUtils.getCharsetForURI(makeURI(shortcutURL))
- .then(c => { charset = c; continueOperation(); });
- } catch (ex) {
- continueOperation();
- }
- }
- }
- else if (param) {
- // This keyword doesn't take a parameter, but one was provided. Just return
- // the original URL.
- postData = null;
-
- aCallback({ postData: postData, url: aURL,
- mayInheritPrincipal: mayInheritPrincipal });
- } else {
+ return { postData, url: shortcutURL, mayInheritPrincipal };
+ }
+
+ if (param) {
+ // This keyword doesn't take a parameter, but one was provided. Just return
+ // the original URL.
+ postData = null;
+
+ return { postData, url, mayInheritPrincipal };
+ }
+
// This URL came from a bookmark, so it's safe to let it inherit the current
// document's principal.
mayInheritPrincipal = true;
- aCallback({ postData: postData, url: shortcutURL,
- mayInheritPrincipal: mayInheritPrincipal });
- }
+ return { postData, url: shortcutURL, mayInheritPrincipal };
+ }).then(data => {
+ if (callback) {
+ callback(data);
+ }
+
+ return data;
+ });
}
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);
dataStream.data = aStringData;
@@ -3247,17 +3264,17 @@ var newTabButtonObserver = {
onDragExit: function (aEvent)
{
},
onDrop: function (aEvent)
{
let url = browserDragAndDrop.drop(aEvent, { });
- getShortcutOrURIAndPostData(url, data => {
+ getShortcutOrURIAndPostData(url).then(data => {
if (data.url) {
// allow third-party services to fixup this URL
openNewTabWith(data.url, null, data.postData, aEvent, true);
}
});
}
}
@@ -3267,17 +3284,17 @@ var newWindowButtonObserver = {
browserDragAndDrop.dragOver(aEvent);
},
onDragExit: function (aEvent)
{
},
onDrop: function (aEvent)
{
let url = browserDragAndDrop.drop(aEvent, { });
- getShortcutOrURIAndPostData(url, data => {
+ getShortcutOrURIAndPostData(url).then(data => {
if (data.url) {
// allow third-party services to fixup this URL
openNewWindowWith(data.url, null, data.postData, true);
}
});
}
}
@@ -5603,17 +5620,17 @@ function middleMousePaste(event) {
// if it's not the current tab, we don't need to do anything because the
// browser doesn't exist.
let where = whereToOpenLink(event, true, false);
let lastLocationChange;
if (where == "current") {
lastLocationChange = gBrowser.selectedBrowser.lastLocationChange;
}
- getShortcutOrURIAndPostData(clipboard, data => {
+ getShortcutOrURIAndPostData(clipboard).then(data => {
try {
makeURI(data.url);
} catch (ex) {
// Not a valid URI.
return;
}
try {
@@ -5640,17 +5657,17 @@ function stripUnsafeProtocolOnPaste(past
// LOAD_FLAGS_DISALLOW_INHERIT_OWNER for those.
return pasteData.replace(/^(?:\s*javascript:)+/i, "");
}
function handleDroppedLink(event, url, name)
{
let lastLocationChange = gBrowser.selectedBrowser.lastLocationChange;
- getShortcutOrURIAndPostData(url, data => {
+ getShortcutOrURIAndPostData(url).then(data => {
if (data.url &&
lastLocationChange == gBrowser.selectedBrowser.lastLocationChange)
loadURI(data.url, null, data.postData, false);
});
// Keep the event from being handled by the dragDrop listeners
// built-in to gecko if they happen to be above us.
event.preventDefault();