Bug 1976006 - Fix moz- input labels when localisation changes a=RyanVM
Original Revision: https://phabricator.services.mozilla.com/D258995 Differential Revision: https://phabricator.services.mozilla.com/D263495
This commit is contained in:
committed by
rvandermeulen@mozilla.com
parent
b6ae9b266e
commit
cd516e806e
@@ -93,6 +93,29 @@
|
|||||||
"support link created"
|
"support link created"
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
add_task(async function testLabelChange() {
|
||||||
|
let el = await renderTemplate();
|
||||||
|
|
||||||
|
let labelEl = el.shadowRoot.querySelector("label");
|
||||||
|
is(labelEl.innerText.trim(), "Example label!", "Label is correct");
|
||||||
|
is(labelEl.getAttribute("shownaccesskey"), "x", "Accesskey is shown");
|
||||||
|
|
||||||
|
// Test changing the label text, this could happen when the locale changes.
|
||||||
|
el.label = "Example new label!";
|
||||||
|
await el.updateComplete;
|
||||||
|
|
||||||
|
is(
|
||||||
|
labelEl.innerText.trim(),
|
||||||
|
"Example new label!",
|
||||||
|
"Label is updated correctly"
|
||||||
|
);
|
||||||
|
is(
|
||||||
|
labelEl.getAttribute("shownaccesskey"),
|
||||||
|
"x",
|
||||||
|
"Accesskey is still shown"
|
||||||
|
);
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
@@ -48,6 +48,13 @@
|
|||||||
Shownaccesskey highlights the key
|
Shownaccesskey highlights the key
|
||||||
<input type="checkbox" />
|
<input type="checkbox" />
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
|
<label is="moz-label" accesskey="t" class="test-changetext"
|
||||||
|
><span class="text">It has text</span></label
|
||||||
|
>
|
||||||
|
<label is="moz-label" shownaccesskey="t" class="test-changetext"
|
||||||
|
><span class="text">It has text</span></label
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
<script class="testbody" type="application/javascript">
|
<script class="testbody" type="application/javascript">
|
||||||
let labels = document.querySelectorAll("label[is='moz-label']");
|
let labels = document.querySelectorAll("label[is='moz-label']");
|
||||||
@@ -101,7 +108,7 @@
|
|||||||
add_task(async function testAccesskeyFocus() {
|
add_task(async function testAccesskeyFocus() {
|
||||||
labels.forEach(label => {
|
labels.forEach(label => {
|
||||||
let accessKey = label.getAttribute("accesskey");
|
let accessKey = label.getAttribute("accesskey");
|
||||||
if (!accessKey) {
|
if (!accessKey || label.classList.contains("test-changetext")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Find the labelled element via the "for" attr if there's an ID
|
// Find the labelled element via the "for" attr if there's an ID
|
||||||
@@ -206,6 +213,70 @@
|
|||||||
"The associated input is not triggered by accesskey."
|
"The associated input is not triggered by accesskey."
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
add_task(async function testAccesskeyTextContentChange() {
|
||||||
|
const ORIG_TEXT = "It has text";
|
||||||
|
const NEW_TEXT = "New text";
|
||||||
|
const ACCESSKEY = "t";
|
||||||
|
let [accesskeyLabel, shownaccesskeyLabel] =
|
||||||
|
document.querySelectorAll(".test-changetext");
|
||||||
|
|
||||||
|
is(
|
||||||
|
accesskeyLabel.textContent,
|
||||||
|
ORIG_TEXT,
|
||||||
|
"Original text is correct accesskey"
|
||||||
|
);
|
||||||
|
is(
|
||||||
|
shownaccesskeyLabel.textContent,
|
||||||
|
ORIG_TEXT,
|
||||||
|
"Original text is correct shownaccesskey"
|
||||||
|
);
|
||||||
|
|
||||||
|
let getWrapper = label => label.querySelector(".accesskey");
|
||||||
|
is(
|
||||||
|
getWrapper(accesskeyLabel).textContent,
|
||||||
|
ACCESSKEY,
|
||||||
|
"Original accesskey character is wrapped accesskey"
|
||||||
|
);
|
||||||
|
is(
|
||||||
|
getWrapper(shownaccesskeyLabel).textContent,
|
||||||
|
ACCESSKEY,
|
||||||
|
"Original accesskey character is wrapped accesskey"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Set the textContent on the inner span so we don't hit `set textContent`
|
||||||
|
accesskeyLabel.firstElementChild.textContent = NEW_TEXT;
|
||||||
|
is(
|
||||||
|
accesskeyLabel.textContent,
|
||||||
|
NEW_TEXT,
|
||||||
|
"Updated text is correct accesskey"
|
||||||
|
);
|
||||||
|
ok(!getWrapper(accesskeyLabel), "Accesskey span was removed accesskey");
|
||||||
|
// formatAccessKey waits a tick so we don't get infinite observer looping
|
||||||
|
await new Promise(r => queueMicrotask(r));
|
||||||
|
is(
|
||||||
|
getWrapper(accesskeyLabel).textContent,
|
||||||
|
ACCESSKEY,
|
||||||
|
"Updated accesskey character is wrapped accesskey"
|
||||||
|
);
|
||||||
|
shownaccesskeyLabel.firstElementChild.textContent = NEW_TEXT;
|
||||||
|
is(
|
||||||
|
shownaccesskeyLabel.textContent,
|
||||||
|
NEW_TEXT,
|
||||||
|
"Updated text is correct shownaccesskey"
|
||||||
|
);
|
||||||
|
ok(
|
||||||
|
!getWrapper(shownaccesskeyLabel),
|
||||||
|
"Accesskey span was removed shownaccesskey"
|
||||||
|
);
|
||||||
|
// formatAccessKey waits a tick so we don't get infinite observer looping
|
||||||
|
await new Promise(r => queueMicrotask(r));
|
||||||
|
is(
|
||||||
|
getWrapper(shownaccesskeyLabel).textContent,
|
||||||
|
ACCESSKEY,
|
||||||
|
"Updated accesskey character is wrapped accesskey"
|
||||||
|
);
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -419,7 +419,12 @@ export class MozBaseInputElement extends MozLitElement {
|
|||||||
if (!this.label) {
|
if (!this.label) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
return html`${this.iconTemplate()}<span class="text">${this.label}</span>`;
|
return html`<span class="text-container"
|
||||||
|
>${this.iconTemplate()}<span
|
||||||
|
class="text"
|
||||||
|
.textContent=${this.label}
|
||||||
|
></span
|
||||||
|
></span>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
descriptionTemplate() {
|
descriptionTemplate() {
|
||||||
|
|||||||
@@ -65,19 +65,39 @@ class MozTextLabel extends HTMLLabelElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#startMutationObserver() {
|
||||||
|
if (!this.#observer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.#observer.observe(this, {
|
||||||
|
characterData: true,
|
||||||
|
childList: true,
|
||||||
|
subtree: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#stopMutationObserver() {
|
||||||
|
if (!this.#observer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.#observer.disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
connectedCallback() {
|
connectedCallback() {
|
||||||
this.#setStyles();
|
this.#setStyles();
|
||||||
this.formatAccessKey();
|
this.formatAccessKey();
|
||||||
if (!this.#observer) {
|
if (!this.#observer) {
|
||||||
this.#observer = new MutationObserver(() => {
|
this.#observer = new MutationObserver(() => {
|
||||||
|
this.#lastFormattedAccessKey = null;
|
||||||
this.formatAccessKey();
|
this.formatAccessKey();
|
||||||
}).observe(this, { characterData: true, childList: true, subtree: true });
|
});
|
||||||
|
this.#startMutationObserver();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
disconnectedCallback() {
|
disconnectedCallback() {
|
||||||
if (this.#observer) {
|
if (this.#observer) {
|
||||||
this.#observer.disconnect();
|
this.#stopMutationObserver();
|
||||||
this.#observer = null;
|
this.#observer = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -185,6 +205,15 @@ class MozTextLabel extends HTMLLabelElement {
|
|||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
this.#stopMutationObserver();
|
||||||
|
try {
|
||||||
|
this.#formatAccessKey(accessKey);
|
||||||
|
} finally {
|
||||||
|
queueMicrotask(() => this.#startMutationObserver());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#formatAccessKey(accessKey) {
|
||||||
this.#lastFormattedAccessKey = accessKey;
|
this.#lastFormattedAccessKey = accessKey;
|
||||||
if (this.accessKeySpan) {
|
if (this.accessKeySpan) {
|
||||||
// Clear old accesskey
|
// Clear old accesskey
|
||||||
|
|||||||
Reference in New Issue
Block a user