Commit 43e7482f authored by Zibi Braniecki's avatar Zibi Braniecki
Browse files

Bug 1681984 - Remove elements from L10nMutation pendingElements when they're...

Bug 1681984 - Remove elements from L10nMutation pendingElements when they're removed from observed roots. r=nordzilla,smaug

Differential Revision: https://phabricator.services.mozilla.com/D131292
parent c48f585f
Loading
Loading
Loading
Loading
+27 −1
Original line number Diff line number Diff line
@@ -89,8 +89,30 @@ void L10nMutations::ContentInserted(nsIContent* aChild) {
  if (!mObserving) {
    return;
  }

  if (!aChild->IsElement()) {
    return;
  }
  Element* elem = aChild->AsElement();

  if (!IsInRoots(elem)) {
    return;
  }

  ErrorResult rv;
  Sequence<OwningNonNull<Element>> elements;
  DOMLocalization::GetTranslatables(*aChild, elements, rv);

  for (auto& elem : elements) {
    L10nElementChanged(elem);
  }
}

void L10nMutations::ContentRemoved(nsIContent* aChild,
                                   nsIContent* aPreviousSibling) {
  if (!mObserving) {
    return;
  }

  if (!aChild->IsElement()) {
    return;
@@ -100,10 +122,14 @@ void L10nMutations::ContentInserted(nsIContent* aChild) {
  if (!IsInRoots(elem)) {
    return;
  }

  ErrorResult rv;
  Sequence<OwningNonNull<Element>> elements;
  DOMLocalization::GetTranslatables(*aChild, elements, rv);

  for (auto& elem : elements) {
    L10nElementChanged(elem);
    mPendingElements.RemoveElement(elem);
    mPendingElementsHash.EnsureRemoved(elem);
  }
}

+1 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ class L10nMutations final : public nsStubMutationObserver,
  NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(L10nMutations, nsIMutationObserver)
  NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
  NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
  NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
  NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED

  explicit L10nMutations(DOMLocalization* aDOMLocalization);
+2 −0
Original line number Diff line number Diff line
@@ -14,6 +14,8 @@
[l10n_mutations/test_set_attributes.html]
[l10n_mutations/test_pause_observing.html]
[l10n_mutations/test_template.html]
[l10n_mutations/test_remove_element.html]
[l10n_mutations/test_remove_fragment.html]

[dom_localization/test_attr_sanitized.html]
[dom_localization/test_getAttributes.html]
+70 −0
Original line number Diff line number Diff line
<!DOCTYPE HTML>
<html>
<head>
  <meta charset="utf-8">
  <title>Test L10n Mutations for removing element</title>
  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
  <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
  <link rel="localization" href="crashreporter/aboutcrashes.ftl"/>
  <script type="application/javascript">
  "use strict";
  SimpleTest.waitForExplicitFinish();

  document.addEventListener("DOMContentLoaded", function() {
    // This element will be added to DOM and expected to be localized.
    let elem = document.createElement("div");

    // This element will be added to DOM, then immediatelly removed and
    // expected *not* to be localized.
    let elem2 = document.createElement("div");

    // This element will be added to DOM, then immediatelly removed and
    // and then immediatelly re-added, and expected to be localized.
    let elem3 = document.createElement("div");

    // This element will be added to DOM, then immediatelly removed and
    // and then re-added later, and expected to be localized.
    let elem4 = document.createElement("div");

    document.l10n.setAttributes(elem, "crash-reports-title");
    document.l10n.setAttributes(elem2, "crash-reports-title");
    document.l10n.setAttributes(elem3, "crash-reports-title");
    document.l10n.setAttributes(elem4, "crash-reports-title");

    document.body.appendChild(elem);
    document.body.appendChild(elem2);
    document.body.appendChild(elem3);
    document.body.appendChild(elem4);

    is(elem.textContent.length, 0);
    is(elem2.textContent.length, 0);
    is(elem3.textContent.length, 0);
    is(elem4.textContent.length, 0);

    document.body.removeChild(elem2);
    document.body.removeChild(elem3);
    document.body.removeChild(elem4);

    document.body.appendChild(elem3);

    // It's really tricky to test if no change happened in result
    // of an operation. This test will just check if the element
    // was not localized within 100ms.
    setTimeout(async () => {
      is(elem.textContent.length > 0, true);
      is(elem2.textContent.length, 0);
      is(elem3.textContent.length > 0, true);
      is(elem4.textContent.length, 0);

      document.body.appendChild(elem4);
      await SimpleTest.waitForCondition(() => {
        return elem4.textContent.length > 0;
      });
      SimpleTest.finish();
    }, 100);
  });
  </script>
</head>
<body>
</body>
</html>
+66 −0
Original line number Diff line number Diff line
<!DOCTYPE HTML>
<html>
<head>
  <meta charset="utf-8">
  <title>Test L10n Mutations for removing fragment</title>
  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
  <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
  <link rel="localization" href="crashreporter/aboutcrashes.ftl"/>
  <script type="application/javascript">
  "use strict";
  SimpleTest.waitForExplicitFinish();

  document.addEventListener("DOMContentLoaded", function() {
    let div = document.createElement("div");
    let div2 = document.createElement("div");

    let elem = document.createElement("p");
    let elem2 = document.createElement("p");
    let elem3 = document.createElement("p");
    let elem4 = document.createElement("p");

    document.l10n.setAttributes(elem, "crash-reports-title");
    document.l10n.setAttributes(elem2, "crash-reports-title");
    document.l10n.setAttributes(elem3, "crash-reports-title");
    document.l10n.setAttributes(elem4, "crash-reports-title");

    div.appendChild(elem);
    div.appendChild(elem2);
    div.appendChild(elem3);
    div.appendChild(elem4);

    document.body.appendChild(div);

    is(elem.textContent.length, 0);
    is(elem2.textContent.length, 0);
    is(elem3.textContent.length, 0);
    is(elem4.textContent.length, 0);

    document.body.removeChild(div);

    div2.appendChild(elem2);
    div2.appendChild(elem3);

    document.body.appendChild(div2);

    // It's really tricky to test if no change happened in result
    // of an operation. This test will just check if the element
    // was not localized within 100ms.
    setTimeout(async () => {
      is(elem.textContent.length, 0);
      is(elem2.textContent.length > 0, true);
      is(elem3.textContent.length > 0, true);
      is(elem4.textContent.length, 0);

      document.body.appendChild(div);
      await SimpleTest.waitForCondition(() => {
        return elem4.textContent.length > 0;
      });
      SimpleTest.finish();
    }, 100);
  });
  </script>
</head>
<body>
</body>
</html>