Commit bc77f97e authored by Adam Vandolder's avatar Adam Vandolder
Browse files

Bug 1890428 - Add serialization support for Declarative Shadow DOM. r=webidl,smaug

parent be70f57b
Loading
Loading
Loading
Loading
+17 −3
Original line number Diff line number Diff line
@@ -1286,12 +1286,14 @@ already_AddRefed<ShadowRoot> Element::AttachShadow(const ShadowRootInit& aInit,

  return AttachShadowWithoutNameChecks(
      aInit.mMode, DelegatesFocus(aInit.mDelegatesFocus), aInit.mSlotAssignment,
      ShadowRootClonable(aInit.mClonable));
      ShadowRootClonable(aInit.mClonable),
      ShadowRootSerializable(aInit.mSerializable));
}

already_AddRefed<ShadowRoot> Element::AttachShadowWithoutNameChecks(
    ShadowRootMode aMode, DelegatesFocus aDelegatesFocus,
    SlotAssignmentMode aSlotAssignment, ShadowRootClonable aClonable) {
    SlotAssignmentMode aSlotAssignment, ShadowRootClonable aClonable,
    ShadowRootSerializable aSerializable) {
  nsAutoScriptBlocker scriptBlocker;

  auto* nim = mNodeInfo->NodeInfoManager();
@@ -1317,7 +1319,7 @@ already_AddRefed<ShadowRoot> Element::AttachShadowWithoutNameChecks(
   */
  RefPtr<ShadowRoot> shadowRoot = new (nim)
      ShadowRoot(this, aMode, aDelegatesFocus, aSlotAssignment, aClonable,
                 ShadowRootDeclarative::No, nodeInfo.forget());
                 aSerializable, ShadowRootDeclarative::No, nodeInfo.forget());

  if (NodeOrAncestorHasDirAuto()) {
    shadowRoot->SetAncestorHasDirAuto();
@@ -5061,6 +5063,18 @@ void Element::SetHTML(const nsAString& aInnerHTML,
                                                     oldChildCount);
}

void Element::GetHTML(const GetHTMLOptions& aOptions, nsAString& aResult) {
  if (aOptions.mSerializableShadowRoots || !aOptions.mShadowRoots.IsEmpty()) {
    nsContentUtils::SerializeNodeToMarkup<SerializeShadowRoots::Yes>(
        this, true, aResult, aOptions.mSerializableShadowRoots,
        aOptions.mShadowRoots);
  } else {
    nsContentUtils::SerializeNodeToMarkup<SerializeShadowRoots::No>(
        this, true, aResult, aOptions.mSerializableShadowRoots,
        aOptions.mShadowRoots);
  }
}

bool Element::Translate() const {
  if (const auto* parent = Element::FromNodeOrNull(mParent)) {
    return parent->Translate();
+5 −1
Original line number Diff line number Diff line
@@ -120,6 +120,7 @@ namespace dom {
struct CheckVisibilityOptions;
struct CustomElementData;
struct SetHTMLOptions;
struct GetHTMLOptions;
struct GetAnimationsOptions;
struct ScrollIntoViewOptions;
struct ScrollToOptions;
@@ -1359,11 +1360,13 @@ class Element : public FragmentOrElement {

  enum class DelegatesFocus : bool { No, Yes };
  enum class ShadowRootClonable : bool { No, Yes };
  enum class ShadowRootSerializable : bool { No, Yes };

  already_AddRefed<ShadowRoot> AttachShadowWithoutNameChecks(
      ShadowRootMode aMode, DelegatesFocus = DelegatesFocus::No,
      SlotAssignmentMode aSlotAssignmentMode = SlotAssignmentMode::Named,
      ShadowRootClonable aClonable = ShadowRootClonable::No);
      ShadowRootClonable aClonable = ShadowRootClonable::No,
      ShadowRootSerializable aSerializable = ShadowRootSerializable::No);

  // Attach UA Shadow Root if it is not attached.
  enum class NotifyUAWidgetSetup : bool { No, Yes };
@@ -1543,6 +1546,7 @@ class Element : public FragmentOrElement {

  void SetHTML(const nsAString& aInnerHTML, const SetHTMLOptions& aOptions,
               ErrorResult& aError);
  void GetHTML(const GetHTMLOptions& aOptions, nsAString& aResult);

  //----------------------------------------

+2 −1
Original line number Diff line number Diff line
@@ -1870,7 +1870,8 @@ void FragmentOrElement::GetMarkup(bool aIncludeSelf, nsAString& aMarkup) {

  Document* doc = OwnerDoc();
  if (IsInHTMLDocument()) {
    nsContentUtils::SerializeNodeToMarkup(this, !aIncludeSelf, aMarkup);
    nsContentUtils::SerializeNodeToMarkup(this, !aIncludeSelf, aMarkup, false,
                                          {});
    return;
  }

+11 −2
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@
#include "nsWindowSizes.h"
#include "mozilla/dom/DirectionalityUtils.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/ElementBinding.h"
#include "mozilla/dom/HTMLDetailsElement.h"
#include "mozilla/dom/HTMLSlotElement.h"
#include "mozilla/dom/HTMLSummaryElement.h"
@@ -52,7 +53,8 @@ NS_IMPL_RELEASE_INHERITED(ShadowRoot, DocumentFragment)
ShadowRoot::ShadowRoot(Element* aElement, ShadowRootMode aMode,
                       Element::DelegatesFocus aDelegatesFocus,
                       SlotAssignmentMode aSlotAssignment,
                       IsClonable aIsClonable, Declarative aDeclarative,
                       IsClonable aIsClonable, IsSerializable aIsSerializable,
                       Declarative aDeclarative,
                       already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
    : DocumentFragment(std::move(aNodeInfo)),
      DocumentOrShadowRoot(this),
@@ -62,7 +64,8 @@ ShadowRoot::ShadowRoot(Element* aElement, ShadowRootMode aMode,
      mIsDetailsShadowTree(aElement->IsHTMLElement(nsGkAtoms::details)),
      mIsAvailableToElementInternals(false),
      mIsDeclarative(aDeclarative),
      mIsClonable(aIsClonable) {
      mIsClonable(aIsClonable),
      mIsSerializable(aIsSerializable) {
  // nsINode.h relies on this.
  MOZ_ASSERT(static_cast<nsINode*>(this) == reinterpret_cast<nsINode*>(this));
  MOZ_ASSERT(static_cast<nsIContent*>(this) ==
@@ -885,3 +888,9 @@ void ShadowRoot::SetHTMLUnsafe(const nsAString& aHTML) {
  RefPtr<Element> host = GetHost();
  nsContentUtils::SetHTMLUnsafe(this, host, aHTML);
}

void ShadowRoot::GetHTML(const GetHTMLOptions& aOptions, nsAString& aResult) {
  nsContentUtils::SerializeNodeToMarkup<SerializeShadowRoots::Yes>(
      this, true, aResult, aOptions.mSerializableShadowRoots,
      aOptions.mShadowRoots);
}
+8 −1
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ class ShadowRoot final : public DocumentFragment, public DocumentOrShadowRoot {

  using Declarative = Element::ShadowRootDeclarative;
  using IsClonable = Element::ShadowRootClonable;
  using IsSerializable = Element::ShadowRootSerializable;

 public:
  NS_IMPL_FROMNODE_HELPER(ShadowRoot, IsShadowRoot());
@@ -54,7 +55,7 @@ class ShadowRoot final : public DocumentFragment, public DocumentOrShadowRoot {
  ShadowRoot(Element* aElement, ShadowRootMode aMode,
             Element::DelegatesFocus aDelegatesFocus,
             SlotAssignmentMode aSlotAssignment, IsClonable aClonable,
             Declarative aDeclarative,
             IsSerializable aIsSerializable, Declarative aDeclarative,
             already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);

  void AddSizeOfExcludingThis(nsWindowSizes&, size_t* aNodeSize) const final;
@@ -83,6 +84,7 @@ class ShadowRoot final : public DocumentFragment, public DocumentOrShadowRoot {
  SlotAssignmentMode SlotAssignment() const { return mSlotAssignment; }
  bool Clonable() const { return mIsClonable == IsClonable::Yes; }
  bool IsClosed() const { return mMode == ShadowRootMode::Closed; }
  bool Serializable() const { return mIsSerializable == IsSerializable::Yes; }

  void RemoveSheetFromStyles(StyleSheet&);
  void RuleAdded(StyleSheet&, css::Rule&);
@@ -247,6 +249,8 @@ class ShadowRoot final : public DocumentFragment, public DocumentOrShadowRoot {
  MOZ_CAN_RUN_SCRIPT
  void SetHTMLUnsafe(const nsAString& aHTML);

  void GetHTML(const GetHTMLOptions& aOptions, nsAString& aResult);

 protected:
  // FIXME(emilio): This will need to become more fine-grained.
  void ApplicableRulesChanged();
@@ -290,6 +294,9 @@ class ShadowRoot final : public DocumentFragment, public DocumentOrShadowRoot {
  // https://dom.spec.whatwg.org/#shadowroot-clonable
  const IsClonable mIsClonable;

  // https://dom.spec.whatwg.org/#shadowroot-serializable
  const IsSerializable mIsSerializable;

  nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
};

Loading