зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1560061
- Make DOMLocalization support ShadowDOM as roots. r=smaug
Differential Revision: https://phabricator.services.mozilla.com/D35584 --HG-- rename : dom/l10n/tests/mochitest/dom_localization/test_connectRoot.html => dom/l10n/tests/mochitest/dom_localization/test_connectRoot_webcomponent.html extra : moz-landing-system : lando
This commit is contained in:
Родитель
f792986565
Коммит
ff1fca971b
|
@ -39,13 +39,13 @@ interface DOMLocalization : Localization {
|
|||
* Adds a node to nodes observed for localization
|
||||
* related changes.
|
||||
*/
|
||||
[Throws] void connectRoot(Element aElement);
|
||||
[Throws] void connectRoot(Node aElement);
|
||||
|
||||
/**
|
||||
* Removes a node from nodes observed for localization
|
||||
* related changes.
|
||||
*/
|
||||
[Throws] void disconnectRoot(Element aElement);
|
||||
[Throws] void disconnectRoot(Node aElement);
|
||||
|
||||
/**
|
||||
* Pauses the MutationObserver set to observe
|
||||
|
|
|
@ -76,7 +76,7 @@ DOMLocalization::~DOMLocalization() { DisconnectMutations(); }
|
|||
* DOMLocalization API
|
||||
*/
|
||||
|
||||
void DOMLocalization::ConnectRoot(Element& aNode, ErrorResult& aRv) {
|
||||
void DOMLocalization::ConnectRoot(nsINode& aNode, ErrorResult& aRv) {
|
||||
nsCOMPtr<nsIGlobalObject> global = aNode.GetOwnerGlobal();
|
||||
if (!global) {
|
||||
return;
|
||||
|
@ -86,7 +86,7 @@ void DOMLocalization::ConnectRoot(Element& aNode, ErrorResult& aRv) {
|
|||
|
||||
#ifdef DEBUG
|
||||
for (auto iter = mRoots.ConstIter(); !iter.Done(); iter.Next()) {
|
||||
Element* root = iter.Get()->GetKey();
|
||||
nsINode* root = iter.Get()->GetKey();
|
||||
|
||||
MOZ_ASSERT(
|
||||
root != &aNode && !root->Contains(&aNode) && !aNode.Contains(root),
|
||||
|
@ -99,7 +99,7 @@ void DOMLocalization::ConnectRoot(Element& aNode, ErrorResult& aRv) {
|
|||
aNode.AddMutationObserverUnlessExists(mMutations);
|
||||
}
|
||||
|
||||
void DOMLocalization::DisconnectRoot(Element& aNode, ErrorResult& aRv) {
|
||||
void DOMLocalization::DisconnectRoot(nsINode& aNode, ErrorResult& aRv) {
|
||||
if (mRoots.Contains(&aNode)) {
|
||||
aNode.RemoveMutationObserver(mMutations);
|
||||
mRoots.RemoveEntry(&aNode);
|
||||
|
@ -357,12 +357,19 @@ already_AddRefed<Promise> DOMLocalization::TranslateRoots(ErrorResult& aRv) {
|
|||
nsTArray<RefPtr<Promise>> promises;
|
||||
|
||||
for (auto iter = mRoots.ConstIter(); !iter.Done(); iter.Next()) {
|
||||
Element* root = iter.Get()->GetKey();
|
||||
nsINode* root = iter.Get()->GetKey();
|
||||
|
||||
RefPtr<Promise> promise = TranslateFragment(*root, aRv);
|
||||
RefPtr<L10nRootTranslationHandler> nativeHandler =
|
||||
new L10nRootTranslationHandler(root);
|
||||
promise->AppendNativeHandler(nativeHandler);
|
||||
|
||||
// If the root is an element, we'll add a native handler
|
||||
// to set root info (language, direction etc.) on it
|
||||
// once the localization finishes.
|
||||
if (root->IsElement()) {
|
||||
RefPtr<L10nRootTranslationHandler> nativeHandler =
|
||||
new L10nRootTranslationHandler(root->AsElement());
|
||||
promise->AppendNativeHandler(nativeHandler);
|
||||
}
|
||||
|
||||
promises.AppendElement(promise);
|
||||
}
|
||||
AutoEntryScript aes(mGlobal, "DOMLocalization TranslateRoots");
|
||||
|
@ -470,9 +477,9 @@ void DOMLocalization::DisconnectMutations() {
|
|||
|
||||
void DOMLocalization::DisconnectRoots() {
|
||||
for (auto iter = mRoots.ConstIter(); !iter.Done(); iter.Next()) {
|
||||
Element* elem = iter.Get()->GetKey();
|
||||
nsINode* node = iter.Get()->GetKey();
|
||||
|
||||
elem->RemoveMutationObserver(mMutations);
|
||||
node->RemoveMutationObserver(mMutations);
|
||||
}
|
||||
mRoots.Clear();
|
||||
}
|
||||
|
|
|
@ -33,8 +33,8 @@ class DOMLocalization : public intl::Localization {
|
|||
* Methods documentation in DOMLocalization.webidl
|
||||
*/
|
||||
|
||||
void ConnectRoot(Element& aNode, ErrorResult& aRv);
|
||||
void DisconnectRoot(Element& aNode, ErrorResult& aRv);
|
||||
void ConnectRoot(nsINode& aNode, ErrorResult& aRv);
|
||||
void DisconnectRoot(nsINode& aNode, ErrorResult& aRv);
|
||||
|
||||
void PauseObserving(ErrorResult& aRv);
|
||||
void ResumeObserving(ErrorResult& aRv);
|
||||
|
@ -87,7 +87,7 @@ class DOMLocalization : public intl::Localization {
|
|||
intl::L10nArgs& aRetVal, ErrorResult& aRv);
|
||||
|
||||
RefPtr<L10nMutations> mMutations;
|
||||
nsTHashtable<nsRefPtrHashKey<Element>> mRoots;
|
||||
nsTHashtable<nsRefPtrHashKey<nsINode>> mRoots;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -34,8 +34,7 @@ void L10nMutations::AttributeChanged(Element* aElement, int32_t aNameSpaceID,
|
|||
if (!mObserving) {
|
||||
return;
|
||||
}
|
||||
Document* uncomposedDoc = aElement->GetUncomposedDoc();
|
||||
if (uncomposedDoc) {
|
||||
if (aElement->IsInComposedDoc()) {
|
||||
if (aNameSpaceID == kNameSpaceID_None &&
|
||||
(aAttribute == nsGkAtoms::datal10nid ||
|
||||
aAttribute == nsGkAtoms::datal10nargs)) {
|
||||
|
@ -56,8 +55,7 @@ void L10nMutations::ContentAppended(nsIContent* aChild) {
|
|||
if (node->IsElement()) {
|
||||
Element* elem = node->AsElement();
|
||||
|
||||
Document* uncomposedDoc = elem->GetUncomposedDoc();
|
||||
if (uncomposedDoc) {
|
||||
if (elem->IsInComposedDoc()) {
|
||||
DOMLocalization::GetTranslatables(*node, elements, rv);
|
||||
}
|
||||
}
|
||||
|
@ -82,8 +80,7 @@ void L10nMutations::ContentInserted(nsIContent* aChild) {
|
|||
}
|
||||
Element* elem = aChild->AsElement();
|
||||
|
||||
Document* uncomposedDoc = elem->GetUncomposedDoc();
|
||||
if (!uncomposedDoc) {
|
||||
if (!elem->IsInComposedDoc()) {
|
||||
return;
|
||||
}
|
||||
DOMLocalization::GetTranslatables(*aChild, elements, rv);
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
[dom_localization/test_translateElements.html]
|
||||
[dom_localization/test_translateFragment.html]
|
||||
[dom_localization/test_connectRoot.html]
|
||||
[dom_localization/test_connectRoot_webcomponent.html]
|
||||
[dom_localization/test_disconnectRoot.html]
|
||||
[dom_localization/test_repeated_l10nid.html]
|
||||
[dom_localization/test_translateRoots.html]
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test DOMLocalization.prototype.connectRoot with Web Components</title>
|
||||
<script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
|
||||
<script type="application/javascript">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
class FluentWidget extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
const shadowRoot = this.attachShadow({mode: 'open'});
|
||||
const t = document.querySelector('#fluent-widget-template');
|
||||
const instance = t.content.cloneNode(true);
|
||||
shadowRoot.appendChild(instance);
|
||||
}
|
||||
connectedCallback() {
|
||||
document.domLoc.connectRoot(this.shadowRoot);
|
||||
ok(true);
|
||||
|
||||
let label = this.shadowRoot.getElementById("label");
|
||||
|
||||
// Test for mutations applied.
|
||||
let verifyL10n = () => {
|
||||
if (label.textContent.length > 0) {
|
||||
window.removeEventListener("MozAfterPaint", verifyL10n);
|
||||
// Notice: In normal tests we do not want to test against any particular
|
||||
// value as per https://firefox-source-docs.mozilla.org/intl/l10n/l10n/fluent_tutorial.html#testing
|
||||
// But in this particular test, since we do not rely on actual real
|
||||
// localization, but instead we mock it in the test, we can test
|
||||
// against the actual value safely.
|
||||
is(label.textContent, "Value for Key 1", "localization content applied to element");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
};
|
||||
window.addEventListener("MozAfterPaint", verifyL10n);
|
||||
|
||||
document.domLoc.setAttributes(label, "key1");
|
||||
}
|
||||
}
|
||||
customElements.define('fluent-widget', FluentWidget);
|
||||
</script>
|
||||
<script type="application/javascript">
|
||||
"use strict";
|
||||
const { FluentBundle } =
|
||||
ChromeUtils.import("resource://gre/modules/Fluent.jsm");
|
||||
|
||||
async function* mockGenerateMessages(locales, resourceIds) {
|
||||
const bundle = new FluentBundle(locales);
|
||||
bundle.addMessages(`
|
||||
key1 = Value for Key 1
|
||||
`);
|
||||
yield bundle;
|
||||
}
|
||||
|
||||
document.domLoc = new DOMLocalization(
|
||||
[],
|
||||
mockGenerateMessages
|
||||
);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<template id="fluent-widget-template">
|
||||
<div>
|
||||
<p id="label"></p>
|
||||
</div>
|
||||
</template>
|
||||
<fluent-widget id="widget1"></fluent-widget>
|
||||
</body>
|
||||
</html>
|
Загрузка…
Ссылка в новой задаче