Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Firefox/dom/xml/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 6 kB image not shown  

Quelle  nsXMLPrettyPrinter.cpp   Sprache: C

 
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */


#include "nsXMLPrettyPrinter.h"
#include "nsContentUtils.h"
#include "nsICSSDeclaration.h"
#include "nsSyncLoadService.h"
#include "nsPIDOMWindow.h"
#include "nsNetUtil.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/ShadowRoot.h"
#include "mozilla/Preferences.h"
#include "mozilla/dom/Document.h"
#include "nsVariant.h"
#include "mozilla/dom/CustomEvent.h"
#include "mozilla/dom/DocumentFragment.h"
#include "mozilla/dom/DocumentL10n.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/dom/ToJSValue.h"
#include "mozilla/dom/txMozillaXSLTProcessor.h"

using namespace mozilla;
using namespace mozilla::dom;

NS_IMPL_ISUPPORTS(nsXMLPrettyPrinter, nsIDocumentObserver, nsIMutationObserver)

nsXMLPrettyPrinter::nsXMLPrettyPrinter()
    : mDocument(nullptr), mUnhookPending(false) {}

nsXMLPrettyPrinter::~nsXMLPrettyPrinter() {
  NS_ASSERTION(!mDocument, "we shouldn't be referencing the document still");
}

nsresult nsXMLPrettyPrinter::PrettyPrint(Document* aDocument,
                                         bool* aDidPrettyPrint) {
  *aDidPrettyPrint = false;

  // check the pref
  if (!Preferences::GetBool("layout.xml.prettyprint"true)) {
    return NS_OK;
  }

  // Find the root element
  RefPtr<Element> rootElement = aDocument->GetRootElement();
  NS_ENSURE_TRUE(rootElement, NS_ERROR_UNEXPECTED);

  // nsXMLContentSink should not ask us to pretty print an XML doc that comes
  // with a CanAttachShadowDOM() == true root element, but just in case:
  if (rootElement->CanAttachShadowDOM()) {
    MOZ_DIAGNOSTIC_CRASH("We shouldn't be getting this root element");
    return NS_ERROR_UNEXPECTED;
  }

  // Ok, we should prettyprint. Let's do it!
  *aDidPrettyPrint = true;
  nsresult rv = NS_OK;

  // Load the XSLT
  nsCOMPtr<nsIURI> xslUri;
  rv = NS_NewURI(getter_AddRefs(xslUri),
                 "chrome://global/content/xml/XMLPrettyPrint.xsl"_ns);
  NS_ENSURE_SUCCESS(rv, rv);

  nsCOMPtr<Document> xslDocument;
  rv = nsSyncLoadService::LoadDocument(
      xslUri, nsIContentPolicy::TYPE_XSLT, nsContentUtils::GetSystemPrincipal(),
      nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL, nullptr,
      aDocument->CookieJarSettings(), true, ReferrerPolicy::_empty,
      getter_AddRefs(xslDocument));
  NS_ENSURE_SUCCESS(rv, rv);

  // Transform the document
  RefPtr<txMozillaXSLTProcessor> transformer = new txMozillaXSLTProcessor();
  ErrorResult err;
  transformer->ImportStylesheet(*xslDocument, err);
  if (NS_WARN_IF(err.Failed())) {
    return err.StealNSResult();
  }

  RefPtr<DocumentFragment> resultFragment =
      transformer->TransformToFragment(*aDocument, *aDocument, err);
  if (NS_WARN_IF(err.Failed())) {
    return err.StealNSResult();
  }

  // Attach an UA Widget Shadow Root on it.
  rootElement->AttachAndSetUAShadowRoot(Element::NotifyUAWidgetSetup::No);
  RefPtr<ShadowRoot> shadowRoot = rootElement->GetShadowRoot();
  MOZ_RELEASE_ASSERT(shadowRoot && shadowRoot->IsUAWidget(),
                     "There should be a UA Shadow Root here.");

  // Append the document fragment to the shadow dom.
  shadowRoot->AppendChild(*resultFragment, err);
  if (NS_WARN_IF(err.Failed())) {
    return err.StealNSResult();
  }

  // Create a DocumentL10n, as the XML document is not allowed to have one.
  // Make it sync so that the test for bug 590812 does not require a setTimeout.
  RefPtr<DocumentL10n> l10n = DocumentL10n::Create(aDocument, true);
  NS_ENSURE_TRUE(l10n, NS_ERROR_UNEXPECTED);
  l10n->AddResourceId("dom/XMLPrettyPrint.ftl"_ns);

  // Localize the shadow DOM header
  Element* l10nRoot = shadowRoot->GetElementById(u"header"_ns);
  NS_ENSURE_TRUE(l10nRoot, NS_ERROR_UNEXPECTED);
  l10n->SetRootInfo(l10nRoot);
  l10n->ConnectRoot(*l10nRoot, true, err);
  if (NS_WARN_IF(err.Failed())) {
    return err.StealNSResult();
  }
  RefPtr<Promise> promise = l10n->TranslateRoots(err);
  if (NS_WARN_IF(err.Failed())) {
    return err.StealNSResult();
  }

  // Observe the document so we know when to switch to "normal" view
  aDocument->AddObserver(this);
  mDocument = aDocument;

  NS_ADDREF_THIS();

  return NS_OK;
}

void nsXMLPrettyPrinter::MaybeUnhook(nsIContent* aContent) {
  // If aContent is null, the document-node was modified.
  // If it is not null but in the shadow tree or the <scrollbar> NACs,
  // the change was in the generated content, and it should be ignored.
  bool isGeneratedContent =
      aContent &&
      (aContent->IsInNativeAnonymousSubtree() || aContent->IsInShadowTree());

  if (!isGeneratedContent && !mUnhookPending) {
    // Can't blindly to mUnhookPending after AddScriptRunner,
    // since AddScriptRunner _could_ in theory run us
    // synchronously
    mUnhookPending = true;
    nsContentUtils::AddScriptRunner(NewRunnableMethod(
        "nsXMLPrettyPrinter::Unhook"this, &nsXMLPrettyPrinter::Unhook));
  }
}

void nsXMLPrettyPrinter::Unhook() {
  mDocument->RemoveObserver(this);
  nsCOMPtr<Element> element = mDocument->GetDocumentElement();

  if (element) {
    // Remove the shadow root
    element->UnattachShadow();
  }

  mDocument = nullptr;

  NS_RELEASE_THIS();
}

void nsXMLPrettyPrinter::AttributeChanged(Element* aElement,
                                          int32_t aNameSpaceID,
                                          nsAtom* aAttribute, int32_t aModType,
                                          const nsAttrValue* aOldValue) {
  MaybeUnhook(aElement);
}

void nsXMLPrettyPrinter::ContentAppended(nsIContent* aFirstNewContent) {
  MaybeUnhook(aFirstNewContent->GetParent());
}

void nsXMLPrettyPrinter::ContentInserted(nsIContent* aChild) {
  MaybeUnhook(aChild->GetParent());
}

void nsXMLPrettyPrinter::ContentWillBeRemoved(nsIContent* aChild,
                                              const BatchRemovalState*) {
  MaybeUnhook(aChild->GetParent());
}

void nsXMLPrettyPrinter::NodeWillBeDestroyed(nsINode* aNode) {
  mDocument = nullptr;
  NS_RELEASE_THIS();
}

nsresult NS_NewXMLPrettyPrinter(nsXMLPrettyPrinter** aPrinter) {
  *aPrinter = new nsXMLPrettyPrinter;
  NS_ADDREF(*aPrinter);
  return NS_OK;
}

100%


¤ Dauer der Verarbeitung: 0.1 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung ist noch experimentell.