Bug 989984 - getShortcutOrURIAndPostData should have a synchronous callback behavior

Issue #112
This commit is contained in:
janekptacijarabaci 2018-04-15 09:46:17 +02:00 • committed by Roy Tam
commit 6b4c0ab0f1
2 changed files with 152 additions and 135 deletions

View file

@ -1898,8 +1898,7 @@ function loadURI(uri, referrer, postData, allowThirdPartyFixup) {
} catch (e) {} } catch (e) {}
} }
function getShortcutOrURIAndPostData(aURL) { function getShortcutOrURIAndPostData(aURL, aCallback) {
return Task.spawn(function() {
let mayInheritPrincipal = false; let mayInheritPrincipal = false;
let postData = null; let postData = null;
let shortcutURL = null; let shortcutURL = null;
@ -1916,17 +1915,19 @@ function getShortcutOrURIAndPostData(aURL) {
if (engine) { if (engine) {
let submission = engine.getSubmission(param); let submission = engine.getSubmission(param);
postData = submission.postData; postData = submission.postData;
throw new Task.Result({ postData: submission.postData, aCallback({ postData: submission.postData, url: submission.uri.spec,
url: submission.uri.spec,
mayInheritPrincipal: mayInheritPrincipal }); mayInheritPrincipal: mayInheritPrincipal });
return;
} }
[shortcutURL, postData] = [shortcutURL, postData] =
PlacesUtils.getURLAndPostDataForKeyword(keyword); PlacesUtils.getURLAndPostDataForKeyword(keyword);
if (!shortcutURL) if (!shortcutURL) {
throw new Task.Result({ postData: postData, url: aURL, aCallback({ postData: postData, url: aURL,
mayInheritPrincipal: mayInheritPrincipal }); mayInheritPrincipal: mayInheritPrincipal });
return;
}
let escapedPostData = ""; let escapedPostData = "";
if (postData) if (postData)
@ -1936,17 +1937,8 @@ function getShortcutOrURIAndPostData(aURL) {
let charset = ""; let charset = "";
const re = /^(.*)\&mozcharset=([a-zA-Z][_\-a-zA-Z0-9]+)\s*$/; const re = /^(.*)\&mozcharset=([a-zA-Z][_\-a-zA-Z0-9]+)\s*$/;
let matches = shortcutURL.match(re); let matches = shortcutURL.match(re);
if (matches)
[, shortcutURL, charset] = matches;
else {
// Try to get the saved character-set.
try {
// makeURI throws if URI is invalid.
// Will return an empty string if character-set is not found.
charset = yield PlacesUtils.getCharsetForURI(makeURI(shortcutURL));
} catch (e) {}
}
let continueOperation = function () {
// encodeURIComponent produces UTF-8, and cannot be used for other charsets. // encodeURIComponent produces UTF-8, and cannot be used for other charsets.
// escape() works in those cases, but it doesn't uri-encode +, @, and /. // escape() works in those cases, but it doesn't uri-encode +, @, and /.
// Therefore we need to manually replace these ASCII characters by their // Therefore we need to manually replace these ASCII characters by their
@ -1964,23 +1956,45 @@ function getShortcutOrURIAndPostData(aURL) {
if (/%s/i.test(escapedPostData)) // POST keyword if (/%s/i.test(escapedPostData)) // POST keyword
postData = getPostDataStream(escapedPostData, param, encodedParam, postData = getPostDataStream(escapedPostData, param, encodedParam,
"application/x-www-form-urlencoded"); "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) { else if (param) {
// This keyword doesn't take a parameter, but one was provided. Just return // This keyword doesn't take a parameter, but one was provided. Just return
// the original URL. // the original URL.
postData = null; postData = null;
throw new Task.Result({ postData: postData, url: aURL, aCallback({ postData: postData, url: aURL,
mayInheritPrincipal: mayInheritPrincipal }); mayInheritPrincipal: mayInheritPrincipal });
} } else {
// This URL came from a bookmark, so it's safe to let it inherit the current // This URL came from a bookmark, so it's safe to let it inherit the current
// document's principal. // document's principal.
mayInheritPrincipal = true; mayInheritPrincipal = true;
throw new Task.Result({ postData: postData, url: shortcutURL, aCallback({ postData: postData, url: shortcutURL,
mayInheritPrincipal: mayInheritPrincipal }); mayInheritPrincipal: mayInheritPrincipal });
}); }
} }
function getPostDataStream(aStringData, aKeyword, aEncKeyword, aType) { function getPostDataStream(aStringData, aKeyword, aEncKeyword, aType) {
@ -2725,8 +2739,7 @@ var newTabButtonObserver = {
onDrop: function (aEvent) onDrop: function (aEvent)
{ {
let url = browserDragAndDrop.drop(aEvent, { }); let url = browserDragAndDrop.drop(aEvent, { });
Task.spawn(function() { getShortcutOrURIAndPostData(url, data => {
let data = yield getShortcutOrURIAndPostData(url);
if (data.url) { if (data.url) {
// allow third-party services to fixup this URL // allow third-party services to fixup this URL
openNewTabWith(data.url, null, data.postData, aEvent, true); openNewTabWith(data.url, null, data.postData, aEvent, true);
@ -2746,8 +2759,7 @@ var newWindowButtonObserver = {
onDrop: function (aEvent) onDrop: function (aEvent)
{ {
let url = browserDragAndDrop.drop(aEvent, { }); let url = browserDragAndDrop.drop(aEvent, { });
Task.spawn(function() { getShortcutOrURIAndPostData(url, data => {
let data = yield getShortcutOrURIAndPostData(url);
if (data.url) { if (data.url) {
// allow third-party services to fixup this URL // allow third-party services to fixup this URL
openNewWindowWith(data.url, null, data.postData, true); openNewWindowWith(data.url, null, data.postData, true);
@ -5048,8 +5060,7 @@ function middleMousePaste(event) {
lastLocationChange = gBrowser.selectedBrowser.lastLocationChange; lastLocationChange = gBrowser.selectedBrowser.lastLocationChange;
} }
Task.spawn(function() { getShortcutOrURIAndPostData(clipboard, data => {
let data = yield getShortcutOrURIAndPostData(clipboard);
try { try {
makeURI(data.url); makeURI(data.url);
} catch (ex) { } catch (ex) {
@ -5080,8 +5091,7 @@ function handleDroppedLink(event, url, name)
{ {
let lastLocationChange = gBrowser.selectedBrowser.lastLocationChange; let lastLocationChange = gBrowser.selectedBrowser.lastLocationChange;
Task.spawn(function() { getShortcutOrURIAndPostData(url, data => {
let data = yield getShortcutOrURIAndPostData(url);
if (data.url && if (data.url &&
lastLocationChange == gBrowser.selectedBrowser.lastLocationChange) lastLocationChange == gBrowser.selectedBrowser.lastLocationChange)
loadURI(data.url, null, data.postData, false); loadURI(data.url, null, data.postData, false);

View file

@ -264,7 +264,7 @@
var action = this._parseActionUrl(url); var action = this._parseActionUrl(url);
let lastLocationChange = gBrowser.selectedBrowser.lastLocationChange; let lastLocationChange = gBrowser.selectedBrowser.lastLocationChange;
Task.spawn(function() {
let matchLastLocationChange = true; let matchLastLocationChange = true;
if (action) { if (action) {
url = action.param; url = action.param;
@ -278,15 +278,21 @@
} }
return; return;
} }
continueOperation.call(this);
} }
else { else {
[url, postData, mayInheritPrincipal] = yield this._canonizeURL(aTriggeringEvent); this._canonizeURL(aTriggeringEvent, response => {
[url, postData, mayInheritPrincipal] = response;
if (url) {
matchLastLocationChange = (lastLocationChange == matchLastLocationChange = (lastLocationChange ==
gBrowser.selectedBrowser.lastLocationChange); gBrowser.selectedBrowser.lastLocationChange);
if (!url) continueOperation.call(this);
return; }
});
} }
function continueOperation()
{
this.value = url; this.value = url;
gBrowser.userTypedValue = url; gBrowser.userTypedValue = url;
try { try {
@ -355,17 +361,19 @@
loadCurrent(); loadCurrent();
} }
} }
}.bind(this)); }
]]></body> ]]></body>
</method> </method>
<method name="_canonizeURL"> <method name="_canonizeURL">
<parameter name="aTriggeringEvent"/> <parameter name="aTriggeringEvent"/>
<parameter name="aCallback"/>
<body><![CDATA[ <body><![CDATA[
return Task.spawn(function() {
var url = this.value; var url = this.value;
if (!url) if (!url) {
throw new Task.Result(["", null, false]); aCallback(["", null, false]);
return;
}
// Only add the suffix when the URL bar value isn't already "URL-like", // Only add the suffix when the URL bar value isn't already "URL-like",
// and only if we get a keyboard event, to match user expectations. // and only if we get a keyboard event, to match user expectations.
@ -418,10 +426,9 @@
} }
} }
let data = yield getShortcutOrURIAndPostData(url); getShortcutOrURIAndPostData(url, data => {
aCallback([data.url, data.postData, data.mayInheritPrincipal]);
throw new Task.Result([data.url, data.postData, data.mayInheritPrincipal]); });
}.bind(this));
]]></body> ]]></body>
</method> </method>