Display a URL relative to the currently displayed page if possible, to make it easier to see the relationship to the URL.
This patch defines a new utility function, compute_relative_url, using the getRelativeSpec method of the nsiURL interface. Unfortunately that method is not very satisfactory and it might be better to forgo its use. Some problems of the method are shown below; it appears that not all components of the base URL are being used in the comparison. A test suite is provided which includes examples from RFC 1808 "Relative Uniform Resource Locators". The problems below are illustrated with examples from the test suite. 1) The value can be longer than necessary. With a base URI of "http://a/b/c/d;p?q#f" and a given URI of "http://a/b/c/d;p?q#s" the shortest relative URL is "#s", but the value given is "d;p?q#s". 2) The value is a relative path where an absolute path would be better. With the base URL above and a given URI of "http://a/g" it would be better to display an absolute path; "/g". Instead the less readable relative path "../../g" is given. 3) Empty string output is ambiguous. The empty string is supposed to indicate that the input URL is identical to the base URL. But, for instance, when the base URL is "http://foo/bar", both "http://foo/bar" and "http://foo" will give an empty string. This implementation works around case (3) by stripping the fileName, ref and query components of the base URL. This removes the ambiguity and doesn't cause further problems than were already evidenced in case (1). Note that the param field is not touched because the nsiURL documentation explains that is not valid to use and also because it causes an error in xulrunner 1.9.1. --- modules/hints.js | 6 ++-- modules/utils.js | 10 +++++ tests/simple/utils.js | 89 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+), 3 deletions(-) diff --git a/modules/hints.js b/modules/hints.js index 41e73c9..f173358 100644 --- a/modules/hints.js +++ b/modules/hints.js @@ -424,6 +424,7 @@ hint_manager.prototype = { function hints_minibuffer_annotation (hints, window) { this.hints = hints; this.input = window.minibuffer.input_element; + this.current_uri = window.buffers.current.current_uri; } hints_minibuffer_annotation.prototype = { constructor: hints_minibuffer_annotation, @@ -445,10 +446,9 @@ hints_minibuffer_annotation.prototype = { elem.form.action); } else { try { - var spec = load_spec(elem); - var uri = load_spec_uri_string(spec); + var uri = load_spec_uri(load_spec(elem)); if (uri) - s.push(uri); + s.push(compute_relative_url(this.current_uri, uri)); } catch (e) {} } } diff --git a/modules/utils.js b/modules/utils.js index ceea810..0d92e99 100644 --- a/modules/utils.js +++ b/modules/utils.js @@ -525,6 +525,16 @@ function url_path_trim (url) { return uri.spec; } + +function compute_relative_url (base, url) { + base = base.clone().QueryInterface(Ci.nsIURL); + for (let [k, p] in Iterator(["ref", "query", "fileName"])) + if (p in base) + base[p] = ""; + return base.getRelativeSpec(make_uri(url)) || "./"; +} + + /** * possibly_valid_url returns true if its argument is an url-like string, * meaning likely a valid thing to pass to nsIWebNavigation.loadURI. diff --git a/tests/simple/utils.js b/tests/simple/utils.js index 4d2e9ea..5ef39e3 100644 --- a/tests/simple/utils.js +++ b/tests/simple/utils.js @@ -81,3 +81,92 @@ walnut_run({ assert(possibly_valid_url("/")); } }); + +{ + function test (base, url, want, expect) { + expect = expect || want; + var get = compute_relative_url(make_uri(base), url); + assert_equals(get, expect); + }; + + walnut_run ({ + test_compute_relative_url_1: function () { + test("http://foo", "http://foo/bar", "bar"); + }, + test_compute_relative_url_2: function () { + test("http://foo", "http://foo", "./"); + }, + test_compute_relative_url_3: function () { + test("http://foo/bar", "http://foo", "./"); + }, + test_compute_relative_url_4: function () { + test("http://foo/bar/", "http://foo", "../"); + }, + test_compute_relative_url_5: function () { + test("http://foo/bar", "http://foo/bar", "bar"); + }, + test_compute_relative_url_6: function () { + test("http://foo/bar/baz", "http://foo", "../"); + }, + test_compute_relative_url_7: function () { + test("http://foo/bar", "http://foo/bar/baz", "bar/baz"); + }, + test_compute_relative_url_8: function () { + test("http://foo/bar", "http://bar", "http://bar/"); + } + }); + + var base = "http://a/b/c/d;p?q#f"; + + walnut_run ({ + // These examples from RFC 1808 "Relative Uniform Resource Locators" + test_compute_relative_url_rfc_1: function () { + test(base, "http://a/b/c/g", "g"); + }, + test_compute_relative_url_rfc_2: function () { + test(base, "http://a/b/c/g/", "g/"); + }, + test_compute_relative_url_rfc_3: function () { + test(base, "http://a/g", "/g", "../../g"); + }, + test_compute_relative_url_rfc_4: function () { + test(base, "http://a/b/c/d;p?y", "?y", "d;p?y"); + }, + test_compute_relative_url_rfc_5: function () { + test(base, "http://a/b/c/g?y", "g?y"); + }, + test_compute_relative_url_rfc_6: function () { + test(base, "http://a/b/c/g?y/./x", "g?y/./x"); + }, + test_compute_relative_url_rfc_7: function () { + test(base, "http://a/b/c/d;p?q#s", "#s", "d;p?q#s"); + }, + test_compute_relative_url_rfc_8: function () { + test(base, "http://a/b/c/g#s", "g#s"); + }, + test_compute_relative_url_rfc_9: function () { + test(base, "http://a/b/c/g#s/./x", "g#s/./x"); + }, + test_compute_relative_url_rfc_10: function () { + test(base, "http://a/b/c/g?y#s", "g?y#s"); + }, + test_compute_relative_url_rfc_11: function () { + test(base, "http://a/b/c/d;x", ";x", "d;x"); + }, + test_compute_relative_url_rfc_12: function () { + test(base, "http://a/b/c/g;x", "g;x"); + }, + test_compute_relative_url_rfc_13: function () { + test(base, "http://a/b/c/g;x?y#s", "g;x?y#s"); + }, + test_compute_relative_url_rfc_14: function () { + test(base, "http://a/b/c/", "./"); + }, + test_compute_relative_url_rfc_15: function () { + test(base, "http://a/b/", "../"); + }, + test_compute_relative_url_rfc_16: function () { + test(base, "http://a/b/g", "../g"); + } + }); +} -- 1.7.9.1 _______________________________________________ Conkeror mailing list [email protected] https://www.mozdev.org/mailman/listinfo/conkeror
