Et2VfsPath: Fix Enter would not accept typed value in Firefox

This commit is contained in:
nathan 2024-12-20 09:04:16 -07:00
parent fd52a2fee5
commit 46c4d20623
2 changed files with 83 additions and 9 deletions

View File

@ -118,9 +118,14 @@ export class Et2VfsPath extends Et2InputWidget(LitElement)
public blur()
{
const oldEditing = this.editing;
this.editing = false;
this.requestUpdate("editing", oldEditing);
if(!this._edit)
{
return;
}
this.requestUpdate("editing");
let oldValue = this.value;
this.value = this._edit.value;
@ -149,7 +154,7 @@ export class Et2VfsPath extends Et2InputWidget(LitElement)
{
const wrapper = this.shadowRoot.querySelector(".vfs-path__scroll");
const path = wrapper?.querySelector("sl-breadcrumb");
const scroll = path?.shadowRoot.querySelector("nav");
const scroll = path?.shadowRoot?.querySelector("nav");
if(!wrapper || !scroll)
{
return;
@ -183,14 +188,21 @@ export class Et2VfsPath extends Et2InputWidget(LitElement)
switch(event.key)
{
case "Enter":
event.stopPropagation();
event.preventDefault();
this.editing = !this.editing;
this.requestUpdate("editing");
break;
const oldValue = this.value;
this.value = this._edit.value;
this.requestUpdate("value", oldValue);
if(oldValue != this.value)
{
this.updateComplete.then(() =>
{
this.dispatchEvent(new Event("change"));
});
}
// Fall through
case "Escape":
event.stopPropagation();
event.preventDefault();
this._edit.value = this.value;
this.blur();
break;
}
@ -372,7 +384,6 @@ export class Et2VfsPath extends Et2InputWidget(LitElement)
?required=${this.required}
.value=${this.value}
tabindex="-1"
aria-hidden="true"
@blur=${() => this.blur()}
@keydown=${this.handleKeyDown}
/>

View File

@ -1,7 +1,8 @@
import {assert, elementUpdated, fixture, html} from '@open-wc/testing';
import {assert, elementUpdated, expect, fixture, html, oneEvent} from '@open-wc/testing';
import * as sinon from 'sinon';
import {inputBasicTests} from "../../Et2InputWidget/test/InputBasicTests";
import {Et2VfsPath} from "../Et2VfsPath";
import {sendKeys} from "@web/test-runner-commands";
/**
* Test file for Etemplate webComponent VfsPath
@ -64,18 +65,80 @@ describe("Path widget basics", () =>
await elementUpdated(element);
assert.equal(element.shadowRoot.activeElement, element._edit, "Editable path did not get focus when widget got focus");
});
});
describe("User interactions", () =>
{
// Setup run before each test
beforeEach(before);
it("blurring widget accepts current text", async() =>
{
const changeListener = oneEvent(element, "change");
const value = "/home/test/directory";
// Enter new value
element.focus();
await elementUpdated(element);
element._edit.value = value;
// Lose focus
element.blur();
await elementUpdated(element);
assert.equal(element.value, value, "Path was not accepted on blur");
// Make sure change event is fired
return changeListener;
});
it("[Enter] accepts current path", async() =>
{
const originalValue = "/home/different/directory";
const changedValue = "/home/test/directory";
element.value = originalValue;
element.focus();
await elementUpdated(element);
const changeListener = oneEvent(element, "change");
// Enter field, "type" a new value
element._edit.focus();
element._edit.value = changedValue;
// Press Enter to accept new value
await sendKeys({down: "Enter"});
// Wait for change event
const event = await changeListener;
expect(event).to.exist;
// Check value
assert.equal(element.value, changedValue, "Value did not change on [Enter]");
});
it("[Esc] rejects current path", async() =>
{
const originalValue = "/home/different/directory";
const changedValue = "/home/changed/directory";
element.value = originalValue;
element.focus();
await elementUpdated(element);
// Set up spy for change event
const handler = sinon.spy();
element.addEventListener("change", handler);
// Change the value
element._edit.focus();
element._edit.value = changedValue;
// Press Escape, cancel edit
await sendKeys({down: "Escape"});
// Check value
assert.equal(element.value, originalValue, "Value was changed when [Esc] was pressed");
// No change event
sinon.assert.notCalled(handler);
})
});
inputBasicTests(async() =>