diff --git a/browser/base/content/test/Makefile.in b/browser/base/content/test/Makefile.in index f154e68636e..3c1eb8f9ff8 100644 --- a/browser/base/content/test/Makefile.in +++ b/browser/base/content/test/Makefile.in @@ -220,6 +220,7 @@ _BROWSER_FILES = \ browser_tabfocus.js \ browser_tabs_isActive.js \ browser_tabs_owner.js \ + browser_urlbarCopying.js \ browser_urlbarTrimURLs.js \ browser_urlHighlight.js \ browser_visibleFindSelection.js \ diff --git a/browser/base/content/test/browser_urlbarCopying.js b/browser/base/content/test/browser_urlbarCopying.js new file mode 100644 index 00000000000..59e1c4f0175 --- /dev/null +++ b/browser/base/content/test/browser_urlbarCopying.js @@ -0,0 +1,165 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +const trimPref = "browser.urlbar.trimURLs"; + +function test() { + + gBrowser.selectedTab = gBrowser.addTab(); + + registerCleanupFunction(function () { + gBrowser.removeCurrentTab(); + Services.prefs.clearUserPref(trimPref); + URLBarSetURI(); + }); + + Services.prefs.setBoolPref(trimPref, true); + + waitForExplicitFinish(); + + nextTest(); +} + +var tests = [ + // pageproxystate="invalid" + { + setURL: "http://example.com/", + expectedURL: "example.com", + copyExpected: "example.com" + }, + { + copyVal: "xample.com", + copyExpected: "e" + }, + + + // pageproxystate="valid" from this point on (due to the load) + { + loadURL: "http://example.com/", + expectedURL: "example.com", + copyExpected: "http://example.com/" + }, + { + copyVal: "m", + copyExpected: "http://example.co" + }, + { + copyVal: "eample.com", + copyExpected: "x" + }, + { + copyVal: "xample.com", + copyExpected: "http://e" + }, + + // Test escaping + { + loadURL: "http://example.com/()%C3%A9", + expectedURL: "example.com/()\xe9", + copyExpected: "http://example.com/%28%29%C3%A9" + }, + { + copyVal: ")\xe9", + copyExpected: "http://example.com/(" + }, + { + copyVal: "e)\xe9", + copyExpected: "xample.com/(" + }, + + { + loadURL: "http://example.com/%C3%A9%C3%A9", + expectedURL: "example.com/\xe9\xe9", + copyExpected: "http://example.com/%C3%A9%C3%A9" + }, + { + copyVal: "e\xe9", + copyExpected: "xample.com/\xe9" + }, + { + copyVal: "\xe9", + copyExpected: "http://example.com/\xe9" + }, + + // data: and javsacript: URIs shouldn't be encoded + { + loadURL: "javascript:('%C3%A9')", + expectedURL: "javascript:('\xe9')", + copyExpected: "javascript:('\xe9')" + }, + { + copyVal: "'\xe9')", + copyExpected: "javascript:(" + }, + + { + loadURL: "data:text/html,(%C3%A9)", + expectedURL: "data:text/html,(\xe9)", + copyExpected: "data:text/html,(\xe9)" + }, + { + copyVal: "\xe9)", + copyExpected: "data:text/html,(" + }, + { + copyVal: "data:)", + copyExpected: "text/html,(\xe9" + } +]; + +function nextTest() { + let test = tests.shift(); + if (tests.length == 0) + runTest(test, finish); + else + runTest(test, nextTest); +} + +function runTest(test, cb) { + function doCheck() { + if (test.setURL || test.loadURL) + is(gURLBar.value, test.expectedURL, "url bar value set"); + + testCopy(test.copyVal, test.copyExpected, cb); + } + + if (test.loadURL) { + loadURL(test.loadURL, doCheck); + } else { + if (test.setURL) + gURLBar.value = test.setURL; + doCheck(); + } +} + +function testCopy(copyVal, targetValue, cb) { + info("Expecting copy of: " + targetValue); + waitForClipboard(targetValue, function () { + gURLBar.focus(); + if (copyVal) { + let startBracket = copyVal.indexOf("<"); + let endBracket = copyVal.indexOf(">"); + if (startBracket == -1 || endBracket == -1 || + startBracket > endBracket || + copyVal.replace("<", "").replace(">", "") != gURLBar.value) { + ok(false, "invalid copyVal: " + copyVal); + } + gURLBar.selectionStart = startBracket; + gURLBar.selectionEnd = endBracket - 1; + } else { + gURLBar.select(); + } + + goDoCommand("cmd_copy"); + }, cb, cb); +} + +function loadURL(aURL, aCB) { + gBrowser.selectedBrowser.addEventListener("load", function () { + gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true); + is(gBrowser.currentURI.spec, aURL, "loaded expected URL"); + aCB(); + }, true); + + gBrowser.loadURI(aURL); +} diff --git a/browser/base/content/test/browser_urlbarTrimURLs.js b/browser/base/content/test/browser_urlbarTrimURLs.js index d1faf696433..df70890f7b7 100644 --- a/browser/base/content/test/browser_urlbarTrimURLs.js +++ b/browser/base/content/test/browser_urlbarTrimURLs.js @@ -4,7 +4,7 @@ function testVal(originalValue, targetValue) { gURLBar.value = originalValue; - is(gURLBar.value, targetValue || originalValue, "original value: " + originalValue); + is(gURLBar.value, targetValue || originalValue, "url bar value set"); } function test() { @@ -72,7 +72,7 @@ function test() { function testCopy(originalValue, targetValue, cb) { waitForClipboard(targetValue, function () { - is(gURLBar.value, originalValue); + is(gURLBar.value, originalValue, "url bar copy value set"); gURLBar.focus(); gURLBar.select(); diff --git a/browser/base/content/urlbarBindings.xml b/browser/base/content/urlbarBindings.xml index 8cf5333317d..ca4134e519e 100644 --- a/browser/base/content/urlbarBindings.xml +++ b/browser/base/content/urlbarBindings.xml @@ -505,23 +505,40 @@ 0) + return selectedVal; - if (uri && !uri.schemeIs("javascript") && !uri.schemeIs("data")) { - val = uri.spec; + let uri = gBrowser.currentURI; + // If the entire URL is selected, just use the actual loaded URI. + if (inputVal == selectedVal) { + // ... but only if isn't a javascript: or data: URI, since those + // are hard to read when encoded + if (!uri.schemeIs("javascript") && !uri.schemeIs("data")) { // Parentheses are known to confuse third-party applications (bug 458565). - val = val.replace(/[()]/g, function (c) escape(c)); + selectedVal = uri.spec.replace(/[()]/g, function (c) escape(c)); } + + return selectedVal; } - return val; + // Just the beginning of the URL is selected, check for a trimmed + // value + let spec = uri.spec; + let trimmedSpec = this.trimValue(spec); + if (spec != trimmedSpec) { + // Prepend the portion that trimValue removed from the beginning. + // This assumes trimValue will only truncate the URL at + // the beginning or end (or both). + let trimmedSegments = spec.split(trimmedSpec); + selectedVal = trimmedSegments[0] + selectedVal; + } + + return selectedVal; ]]>