Bug 1893871 - When untrimming the URL adjust partial selection depending on whether the selected text is a valid URL. r=dao

Differential Revision: https://phabricator.services.mozilla.com/D210027
This commit is contained in:
Marco Bonardo 2024-05-14 11:33:57 +00:00
parent 16e69348ae
commit 63eaf27d08
4 changed files with 78 additions and 12 deletions

View file

@ -2519,14 +2519,10 @@ export class UrlbarInput {
}
_getSelectedValueForClipboard() {
let selection = this.editor.selection;
const flags =
Ci.nsIDocumentEncoder.OutputPreformatted |
Ci.nsIDocumentEncoder.OutputRaw;
let selectedVal = selection.toStringWithFormat("text/plain", flags, 0);
let selectedVal = this.#selectedText;
// Handle multiple-range selection as a string for simplicity.
if (selection.rangeCount > 1) {
if (this.editor.selection.rangeCount > 1) {
return selectedVal;
}
@ -3182,10 +3178,26 @@ export class UrlbarInput {
}
selectionStart = selectionEnd += offset;
} else {
// If there's a selection, we must calculate both the initial
// There's a selection, so we must calculate both the initial
// protocol and the eventual trailing slash.
if (selectionStart != 0) {
selectionStart += offset;
} else {
// When selection starts at the beginning, the adjusted selection will
// include the protocol only if the selected text includes the host.
// The port is left out, as one may want to exclude it from the copy.
let prePathMinusPort;
try {
let uri = Services.io.newURI(this._untrimmedValue);
prePathMinusPort = [uri.userPass, uri.displayHost]
.filter(Boolean)
.join("@");
} catch (ex) {
this.logger.error("Should only try to untrim valid URLs");
}
if (!this.#selectedText.startsWith(prePathMinusPort)) {
selectionStart += offset;
}
}
if (selectionEnd == this.value.length) {
offset += 1;
@ -4280,6 +4292,15 @@ export class UrlbarInput {
* TODO: Merge _searchModesByBrowser into this.
*/
#browserStates = new WeakMap();
get #selectedText() {
return this.editor.selection.toStringWithFormat(
"text/plain",
Ci.nsIDocumentEncoder.OutputPreformatted |
Ci.nsIDocumentEncoder.OutputRaw,
0
);
}
}
/**

View file

@ -83,8 +83,27 @@ let tests = [
shouldUntrim: true,
},
{
description: "Test SHIFT+LEFT untrims",
description: "Test SHIFT+LEFT untrims - partial host",
untrimmedValue: BrowserUIUtils.trimURLProtocol + "www.example.com/",
async execute() {
EventUtils.synthesizeKey("l", { accelKey: true });
EventUtils.synthesizeKey("KEY_ArrowLeft", { shiftKey: true });
Assert.equal(
gURLBar.selectionStart,
BrowserUIUtils.trimURLProtocol.length,
"Selection start is 0."
);
Assert.less(
gURLBar.selectionEnd,
gURLBar.value.length,
"Selection skips last characters."
);
},
shouldUntrim: true,
},
{
description: "Test SHIFT+LEFT untrims - full host",
untrimmedValue: BrowserUIUtils.trimURLProtocol + "www.example.com/test",
async execute() {
EventUtils.synthesizeKey("l", { accelKey: true });
EventUtils.synthesizeKey("KEY_ArrowLeft", { shiftKey: true });

View file

@ -91,14 +91,37 @@ const tests = [
},
},
{
description: "Test Drag Selection from the first character",
description: "Test Drag Selection from the first character - Partial host",
async openPanel() {
// Select partial string that doesn't complete to a URL.
this._expectedSelectedText = gURLBar.value.substring(0, 5);
await selectWithMouseDrag(
getTextWidth(gURLBar.value[0]) / 2 - 1,
getTextWidth(gURLBar.value.substring(0, 5))
);
},
get selection() {
// When untrimming is enabled, the behavior differs depending on whether
// the selected text can generate a valid URL, so there may be an offset.
let startOffset = UrlbarPrefs.get("untrimOnUserInteraction.featureGate")
? gURLBar.value.indexOf(this._expectedSelectedText)
: 0;
return [startOffset, startOffset + this._expectedSelectedText.length];
},
},
{
description: "Test Drag Selection from the first character - Full host",
async openPanel() {
// Select partial string that completes to a URL.
let uri = Services.io.newURI(gURLBar._untrimmedValue);
let endOfHost =
gURLBar.value.indexOf(uri.displayHost) + uri.displayHost.length;
this._expectedSelectedText = gURLBar.value.substring(0, endOfHost);
await selectWithMouseDrag(
getTextWidth(gURLBar.value[0]) / 2 - 1,
getTextWidth(this._expectedSelectedText)
);
},
get selection() {
return [
0,
@ -207,13 +230,13 @@ async function doTest(url) {
Assert.deepEqual(
test.selection,
[gURLBar.selectionStart, gURLBar.selectionEnd],
"Check selection"
"Check initial selection"
);
if (test.manipulate) {
await test.manipulate();
info(
`Selected text is <${gURLBar.value.substring(
`Selected text after manipulation is <${gURLBar.value.substring(
gURLBar.selectionStart,
gURLBar.selectionEnd
)}>`
@ -236,5 +259,6 @@ function getTextWidth(inputText) {
context.font = window
.getComputedStyle(gURLBar.inputField)
.getPropertyValue("font");
return context.measureText(inputText).width;
let measure = context.measureText(inputText);
return measure.actualBoundingBoxLeft + measure.actualBoundingBoxRight;
}

View file

@ -5,6 +5,7 @@
ChromeUtils.defineESModuleGetters(this, {
AboutNewTab: "resource:///modules/AboutNewTab.sys.mjs",
BrowsetUIUtils: "resource:///modules/BrowserUIUtils.sys.mjs",
ExperimentAPI: "resource://nimbus/ExperimentAPI.sys.mjs",
ExperimentFakes: "resource://testing-common/NimbusTestUtils.sys.mjs",
ObjectUtils: "resource://gre/modules/ObjectUtils.sys.mjs",
@ -15,6 +16,7 @@ ChromeUtils.defineESModuleGetters(this, {
UrlbarController: "resource:///modules/UrlbarController.sys.mjs",
UrlbarEventBufferer: "resource:///modules/UrlbarEventBufferer.sys.mjs",
UrlbarQueryContext: "resource:///modules/UrlbarUtils.sys.mjs",
UrlbarPrefs: "resource:///modules/UrlbarPrefs.sys.mjs",
UrlbarResult: "resource:///modules/UrlbarResult.sys.mjs",
UrlbarSearchUtils: "resource:///modules/UrlbarSearchUtils.sys.mjs",
UrlbarUtils: "resource:///modules/UrlbarUtils.sys.mjs",