diff --git a/content/base/public/nsIDocumentObserver.h b/content/base/public/nsIDocumentObserver.h
index 79f98bdf0532..74c69c4bca52 100644
--- a/content/base/public/nsIDocumentObserver.h
+++ b/content/base/public/nsIDocumentObserver.h
@@ -331,4 +331,62 @@ public:
NS_IMETHOD DocumentWillBeDestroyed(nsIDocument *aDocument) = 0;
};
+#define NS_DECL_NSIDOCUMENTOBSERVER \
+ NS_IMETHOD BeginUpdate(nsIDocument* aDocument); \
+ NS_IMETHOD EndUpdate(nsIDocument* aDocument); \
+ NS_IMETHOD BeginLoad(nsIDocument* aDocument); \
+ NS_IMETHOD EndLoad(nsIDocument* aDocument); \
+ NS_IMETHOD BeginReflow(nsIDocument* aDocument, \
+ nsIPresShell* aShell); \
+ NS_IMETHOD EndReflow(nsIDocument* aDocument, \
+ nsIPresShell* aShell); \
+ NS_IMETHOD ContentChanged(nsIDocument* aDocument, \
+ nsIContent* aContent, \
+ nsISupports* aSubContent); \
+ NS_IMETHOD ContentStatesChanged(nsIDocument* aDocument, \
+ nsIContent* aContent1, \
+ nsIContent* aContent2, \
+ PRInt32 aStateMask); \
+ NS_IMETHOD AttributeChanged(nsIDocument* aDocument, \
+ nsIContent* aContent, \
+ PRInt32 aNameSpaceID, \
+ nsIAtom* aAttribute, \
+ PRInt32 aModType, \
+ nsChangeHint aHint); \
+ NS_IMETHOD ContentAppended(nsIDocument* aDocument, \
+ nsIContent* aContainer, \
+ PRInt32 aNewIndexInContainer); \
+ NS_IMETHOD ContentInserted(nsIDocument* aDocument, \
+ nsIContent* aContainer, \
+ nsIContent* aChild, \
+ PRInt32 aIndexInContainer); \
+ NS_IMETHOD ContentReplaced(nsIDocument* aDocument, \
+ nsIContent* aContainer, \
+ nsIContent* aOldChild, \
+ nsIContent* aNewChild, \
+ PRInt32 aIndexInContainer); \
+ NS_IMETHOD ContentRemoved(nsIDocument* aDocument, \
+ nsIContent* aContainer, \
+ nsIContent* aChild, \
+ PRInt32 aIndexInContainer); \
+ NS_IMETHOD StyleSheetAdded(nsIDocument* aDocument, \
+ nsIStyleSheet* aStyleSheet); \
+ NS_IMETHOD StyleSheetRemoved(nsIDocument* aDocument, \
+ nsIStyleSheet* aStyleSheet); \
+ NS_IMETHOD StyleSheetDisabledStateChanged(nsIDocument* aDocument, \
+ nsIStyleSheet* aStyleSheet, \
+ PRBool aDisabled); \
+ NS_IMETHOD StyleRuleChanged(nsIDocument* aDocument, \
+ nsIStyleSheet* aStyleSheet, \
+ nsIStyleRule* aStyleRule, \
+ nsChangeHint aHint); \
+ NS_IMETHOD StyleRuleAdded(nsIDocument* aDocument, \
+ nsIStyleSheet* aStyleSheet, \
+ nsIStyleRule* aStyleRule); \
+ NS_IMETHOD StyleRuleRemoved(nsIDocument* aDocument, \
+ nsIStyleSheet* aStyleSheet, \
+ nsIStyleRule* aStyleRule); \
+ NS_IMETHOD DocumentWillBeDestroyed(nsIDocument* aDocument); \
+
+
#endif /* nsIDocumentObserver_h___ */
diff --git a/content/macbuild/content.xml b/content/macbuild/content.xml
index d0207035fb10..82444d78e3aa 100644
--- a/content/macbuild/content.xml
+++ b/content/macbuild/content.xml
@@ -1435,6 +1435,13 @@
Text
Debug
+
+ Name
+ nsXMLPrettyPrinter.cpp
+ MacOS
+ Text
+ Debug
+
Name
nsXMLDocument.cpp
@@ -2879,6 +2886,11 @@
nsXMLContentSink.cpp
MacOS
+
+ Name
+ nsXMLPrettyPrinter.cpp
+ MacOS
+
Name
nsXMLDocument.cpp
@@ -5008,6 +5020,13 @@
Text
Debug
+
+ Name
+ nsXMLPrettyPrinter.cpp
+ MacOS
+ Text
+ Debug
+
Name
nsXMLDocument.cpp
@@ -6497,6 +6516,11 @@
nsXMLContentSink.cpp
MacOS
+
+ Name
+ nsXMLPrettyPrinter.cpp
+ MacOS
+
Name
nsXMLDocument.cpp
@@ -8280,6 +8304,12 @@
nsXMLContentSink.cpp
MacOS
+
+ content.shlb
+ Name
+ nsXMLPrettyPrinter.cpp
+ MacOS
+
content.shlb
Name
diff --git a/content/xbl/src/nsBindingManager.cpp b/content/xbl/src/nsBindingManager.cpp
index 8a8e708be7cd..f288c1bb2d10 100644
--- a/content/xbl/src/nsBindingManager.cpp
+++ b/content/xbl/src/nsBindingManager.cpp
@@ -794,38 +794,65 @@ nsBindingManager::AddLayeredBinding(nsIContent* aContent, const nsAString& aURL)
NS_IMETHODIMP
nsBindingManager::RemoveLayeredBinding(nsIContent* aContent, const nsAString& aURL)
{
- /*
nsCOMPtr binding;
- GetBinding(aParent, getter_AddRefs(binding));
+ GetBinding(aContent, getter_AddRefs(binding));
- nsCOMPtr prevBinding;
-
- while (binding) {
- nsCOMPtr nextBinding;
- binding->GetBaseBinding(getter_AddRefs(nextBinding));
-
- PRBool style;
- binding->IsStyleBinding(&style);
- if (!style) {
- // Remove only our binding.
- if (prevBinding) {
- prevBinding->SetBaseBinding(nextBinding);
-
- // XXX Unhooking the binding should kill event handlers and
- // fix up the prototype chain.
- // e.g., binding->UnhookEventHandlers();
- // binding->FixupPrototypeChain();
- // or maybe just binding->Unhook();
-
- }
- else SetBinding(aContent, nextBinding);
- }
-
- prevBinding = binding;
- binding = nextBinding;
+ if (!binding) {
+ return NS_OK;
}
-*/
- return NS_OK;
+
+ // For now we can only handle removing a binding if it's the only one
+ nsCOMPtr nextBinding;
+ binding->GetBaseBinding(getter_AddRefs(nextBinding));
+ NS_ENSURE_FALSE(nextBinding, NS_ERROR_FAILURE);
+
+ // Make sure that the binding has the URI that is requested to be removed
+ nsCAutoString bindingUriStr;
+ binding->GetBindingURI(bindingUriStr);
+ nsCOMPtr bindingUri;
+ nsresult rv = NS_NewURI(getter_AddRefs(bindingUri), bindingUriStr);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr uri;
+ rv = NS_NewURI(getter_AddRefs(uri), aURL);
+ NS_ENSURE_SUCCESS(rv, rv);
+ PRBool equalUri;
+ rv = uri->Equals(bindingUri, &equalUri);
+ NS_ENSURE_SUCCESS(rv, rv);
+ if (!equalUri) {
+ return NS_OK;
+ }
+
+ // Make sure it isn't a style binding
+ PRBool style;
+ binding->IsStyleBinding(&style);
+ if (style) {
+ return NS_OK;
+ }
+
+ // Get to the document, this way is safer then using nsIContent::GetDocument
+ nsCOMPtr node = do_QueryInterface(aContent);
+ NS_ASSERTION(node, "uh? RemoveLayeredBinding called on non-node");
+ nsCOMPtr domDoc;
+ node->GetOwnerDocument(getter_AddRefs(domDoc));
+ NS_ENSURE_TRUE(domDoc, NS_ERROR_UNEXPECTED);
+ nsCOMPtr doc = do_QueryInterface(domDoc);
+ NS_ASSERTION(doc, "document doesn't implement nsIDocument");
+
+ // Finally remove the binding...
+ binding->UnhookEventHandlers();
+ binding->ChangeDocument(doc, nsnull);
+ SetBinding(aContent, nsnull);
+ binding->MarkForDeath();
+
+ // ...and recreate it's frames. We need to do this since the frames may have
+ // been removed and style may have changed due to the removal of the
+ // anonymous children.
+ nsCOMPtr presShell;
+ rv = doc->GetShellAt(0, getter_AddRefs(presShell));
+ NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
+
+ return presShell->RecreateFramesFor(aContent);;
}
NS_IMETHODIMP
diff --git a/content/xml/document/resources/XMLPrettyPrint.css b/content/xml/document/resources/XMLPrettyPrint.css
index c1cde22ef492..6847033eb740 100644
--- a/content/xml/document/resources/XMLPrettyPrint.css
+++ b/content/xml/document/resources/XMLPrettyPrint.css
@@ -79,3 +79,8 @@ td {
.expander-closed > * > .expander-content {
display: none;
}
+
+.comment {
+ font-family: monospace;
+ white-space: pre;
+}
diff --git a/content/xml/document/resources/XMLPrettyPrint.xml b/content/xml/document/resources/XMLPrettyPrint.xml
index 7402e6bc3933..4fb59ce421e7 100644
--- a/content/xml/document/resources/XMLPrettyPrint.xml
+++ b/content/xml/document/resources/XMLPrettyPrint.xml
@@ -65,11 +65,11 @@
if (par.nodeName == 'td' && par.className == 'expander') {
if (par.parentNode.className == 'expander-closed') {
par.parentNode.className = '';
- event.originalTarget.src = 'chrome://global/skin/tree/twisty-open.gif';
+ event.originalTarget.data = '-';
}
else {
par.parentNode.className = 'expander-closed';
- event.originalTarget.src = 'chrome://global/skin/tree/twisty-clsd.gif';
+ event.originalTarget.data = '+';
}
}
} catch (e) {
diff --git a/content/xml/document/resources/XMLPrettyPrint.xsl b/content/xml/document/resources/XMLPrettyPrint.xsl
index 99bddf54dfab..fe8f8cb9859a 100644
--- a/content/xml/document/resources/XMLPrettyPrint.xsl
+++ b/content/xml/document/resources/XMLPrettyPrint.xsl
@@ -155,7 +155,7 @@
- ![](chrome://global/skin/tree/twisty-open.gif) |
+ - |
diff --git a/content/xml/document/src/Makefile.in b/content/xml/document/src/Makefile.in
index f5b73c52d28d..674b318a2675 100644
--- a/content/xml/document/src/Makefile.in
+++ b/content/xml/document/src/Makefile.in
@@ -56,6 +56,7 @@ REQUIRES = xpcom \
CPPSRCS = \
nsXMLContentSink.cpp \
nsXMLDocument.cpp \
+ nsXMLPrettyPrinter.cpp \
nsFIXptr.cpp \
$(NULL)
diff --git a/content/xml/document/src/nsXMLContentSink.cpp b/content/xml/document/src/nsXMLContentSink.cpp
index fab6f87c5f81..356ef78db39b 100644
--- a/content/xml/document/src/nsXMLContentSink.cpp
+++ b/content/xml/document/src/nsXMLContentSink.cpp
@@ -107,18 +107,8 @@
#include "nsIPrincipal.h"
#include "nsIAggregatePrincipal.h"
#include "nsICodebasePrincipal.h"
-#include "nsIDOMDocumentView.h"
-#include "nsIDOMAbstractView.h"
-#include "nsIDOMCSSStyleDeclaration.h"
-#include "nsIDOMViewCSS.h"
#include "nsXBLAtoms.h"
-#include "nsIPref.h"
-#include "nsIDOMDocumentXBL.h"
-#include "nsIBindingManager.h"
-#include "nsIObserver.h"
-#include "nsIDocumentTransformer.h"
-#include "nsISyncLoadDOMService.h"
-#include "nsIXSLTProcessor.h"
+#include "nsXMLPrettyPrinter.h"
// XXX misnamed header file, but oh well
#include "nsHTMLTokens.h"
@@ -364,121 +354,20 @@ nsXMLContentSink::MaybePrettyPrint()
return NS_OK;
}
- // Check for correct load-command or if we're in a display:none iframe
+ // Check for correct load-command
nsAutoString command;
mParser->GetCommand(command);
- if (!command.Equals(NS_LITERAL_STRING("view")) ||
- !mDocument->GetNumberOfShells()) {
+ if (!command.Equals(NS_LITERAL_STRING("view"))) {
mPrettyPrintXML = PR_FALSE;
return NS_OK;
}
- // check if we're in an invisible iframe
- nsCOMPtr sgo;
- mDocument->GetScriptGlobalObject(getter_AddRefs(sgo));
- nsCOMPtr internalWin = do_QueryInterface(sgo);
- nsCOMPtr frameElem;
- if (internalWin) {
- internalWin->GetFrameElement(getter_AddRefs(frameElem));
- }
-
- if (frameElem) {
- nsCOMPtr computedStyle;
- nsCOMPtr frameOwnerDoc;
- frameElem->GetOwnerDocument(getter_AddRefs(frameOwnerDoc));
- nsCOMPtr docView = do_QueryInterface(frameOwnerDoc);
- if (docView) {
- nsCOMPtr defaultView;
- docView->GetDefaultView(getter_AddRefs(defaultView));
- nsCOMPtr defaultCSSView = do_QueryInterface(defaultView);
- if (defaultCSSView) {
- defaultCSSView->GetComputedStyle(frameElem, NS_LITERAL_STRING(""),
- getter_AddRefs(computedStyle));
- }
- }
-
- if (computedStyle) {
- nsAutoString visibility;
- computedStyle->GetPropertyValue(NS_LITERAL_STRING("visibility"), visibility);
- if (!visibility.Equals(NS_LITERAL_STRING("visible"))) {
- mPrettyPrintXML = PR_FALSE;
-
- return NS_OK;
- }
- }
- }
-
- // check the pref
- nsCOMPtr prefs = do_GetService(NS_PREF_CONTRACTID);
- if (prefs) {
- PRBool pref = PR_FALSE;
- prefs->GetBoolPref("layout.xml.prettyprint", &pref);
- if (!pref) {
- mPrettyPrintXML = PR_FALSE;
-
- return NS_OK;
- }
- }
-
-
- // Ok, we should prettyprint. Let's do it!
- nsresult rv = NS_OK;
-
- // Load the XSLT
- nsCOMPtr xslUri;
- rv = NS_NewURI(getter_AddRefs(xslUri),
- NS_LITERAL_CSTRING("chrome://communicator/content/xml/XMLPrettyPrint.xsl"));
+ nsCOMPtr printer;
+ nsresult rv = NS_NewXMLPrettyPrinter(getter_AddRefs(printer));
NS_ENSURE_SUCCESS(rv, rv);
- nsCOMPtr channel;
- rv = NS_NewChannel(getter_AddRefs(channel), xslUri, nsnull, nsnull);
- NS_ENSURE_SUCCESS(rv, rv);
-
- nsCOMPtr xslDocument;
- nsCOMPtr loader =
- do_GetService("@mozilla.org/content/syncload-dom-service;1", &rv);
- NS_ENSURE_SUCCESS(rv, rv);
- rv = loader->LoadLocalDocument(channel, nsnull, getter_AddRefs(xslDocument));
- NS_ENSURE_SUCCESS(rv, rv);
-
- // Transform the document
- nsCOMPtr transformer =
- do_CreateInstance("@mozilla.org/document-transformer;1?type=text/xsl", &rv);
- NS_ENSURE_SUCCESS(rv, rv);
-
- rv = transformer->ImportStylesheet(xslDocument);
- NS_ENSURE_SUCCESS(rv, rv);
-
- nsCOMPtr resultFragment;
- nsCOMPtr sourceDocument = do_QueryInterface(mDocument);
- rv = transformer->TransformToFragment(sourceDocument, xslDocument,
- getter_AddRefs(resultFragment));
- NS_ENSURE_SUCCESS(rv, rv);
-
- // Add the binding
- nsCOMPtr xblDoc = do_QueryInterface(mDocument);
- NS_ASSERTION(xblDoc, "xml document doesn't implement nsIDOMDocumentXBL");
- NS_ENSURE_TRUE(xblDoc, NS_ERROR_FAILURE);
-
- nsCOMPtr dummy;
- xblDoc->LoadBindingDocument(NS_LITERAL_STRING("chrome://communicator/content/xml/XMLPrettyPrint.xml"), getter_AddRefs(dummy));
-
- nsCOMPtr rootElem = do_QueryInterface(mDocElement);
- NS_ASSERTION(rootElem, "No root element");
-
- rv = xblDoc->AddBinding(rootElem, NS_LITERAL_STRING("chrome://communicator/content/xml/XMLPrettyPrint.xml#prettyprint"));
- NS_ENSURE_SUCCESS(rv, rv);
-
- // Hand the result document to the binding
- nsCOMPtr manager;
- mDocument->GetBindingManager(getter_AddRefs(manager));
- nsCOMPtr binding;
- manager->GetBindingImplementation(mDocElement, NS_GET_IID(nsIObserver), (void**)getter_AddRefs(binding));
- NS_ASSERTION(binding, "Prettyprint binding doesn't implement nsIObserver");
- NS_ENSURE_TRUE(binding, NS_ERROR_UNEXPECTED);
-
- return binding->Observe(resultFragment, "prettyprint-dom-created", NS_LITERAL_STRING("").get());
+ return printer->PrettyPrint(mDocument);
}
@@ -2186,6 +2075,8 @@ nsXMLContentSink::ReportError(const PRUnichar* aErrorText,
const PRUnichar* aSourceText)
{
nsresult rv = NS_OK;
+
+ mPrettyPrintXML = PR_FALSE;
mState = eXMLContentSinkState_InProlog;
diff --git a/content/xml/document/src/nsXMLPrettyPrinter.cpp b/content/xml/document/src/nsXMLPrettyPrinter.cpp
new file mode 100644
index 000000000000..5050c782d121
--- /dev/null
+++ b/content/xml/document/src/nsXMLPrettyPrinter.cpp
@@ -0,0 +1,408 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2002
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Jonas Sicking (Original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsXMLPrettyPrinter.h"
+#include "nsIDOMDocumentView.h"
+#include "nsIDOMAbstractView.h"
+#include "nsIDOMCSSStyleDeclaration.h"
+#include "nsIDOMViewCSS.h"
+#include "nsIPrefService.h"
+#include "nsIDOMDocumentXBL.h"
+#include "nsIBindingManager.h"
+#include "nsIObserver.h"
+#include "nsIXSLTProcessor.h"
+#include "nsISyncLoadDOMService.h"
+#include "nsIScriptGlobalObject.h"
+#include "nsIDOMWindowInternal.h"
+#include "nsIDOMElement.h"
+#include "nsIDOMDocument.h"
+#include "nsIServiceManager.h"
+#include "nsNetUtil.h"
+#include "nsIContent.h"
+#include "nsIDOMDocumentFragment.h"
+
+NS_IMPL_ISUPPORTS1(nsXMLPrettyPrinter,
+ nsIDocumentObserver)
+
+nsXMLPrettyPrinter::nsXMLPrettyPrinter() : mUnhookPending(PR_FALSE),
+ mDocument(nsnull),
+ mUpdateDepth(0)
+{
+ NS_INIT_ISUPPORTS();
+}
+
+nsXMLPrettyPrinter::~nsXMLPrettyPrinter()
+{
+ NS_ASSERTION(!mDocument, "we shouldn't be referencing the document still");
+}
+
+nsresult
+nsXMLPrettyPrinter::PrettyPrint(nsIDocument* aDocument)
+{
+ // Check for iframe with display:none. Such iframes don't have presshells
+ if (!aDocument->GetNumberOfShells()) {
+ return NS_OK;
+ }
+
+ // check if we're in an invisible iframe
+ nsCOMPtr sgo;
+ aDocument->GetScriptGlobalObject(getter_AddRefs(sgo));
+ nsCOMPtr internalWin = do_QueryInterface(sgo);
+ nsCOMPtr frameElem;
+ if (internalWin) {
+ internalWin->GetFrameElement(getter_AddRefs(frameElem));
+ }
+
+ if (frameElem) {
+ nsCOMPtr computedStyle;
+ nsCOMPtr frameOwnerDoc;
+ frameElem->GetOwnerDocument(getter_AddRefs(frameOwnerDoc));
+ nsCOMPtr docView = do_QueryInterface(frameOwnerDoc);
+ if (docView) {
+ nsCOMPtr defaultView;
+ docView->GetDefaultView(getter_AddRefs(defaultView));
+ nsCOMPtr defaultCSSView =
+ do_QueryInterface(defaultView);
+ if (defaultCSSView) {
+ defaultCSSView->GetComputedStyle(frameElem,
+ NS_LITERAL_STRING(""),
+ getter_AddRefs(computedStyle));
+ }
+ }
+
+ if (computedStyle) {
+ nsAutoString visibility;
+ computedStyle->GetPropertyValue(NS_LITERAL_STRING("visibility"),
+ visibility);
+ if (!visibility.Equals(NS_LITERAL_STRING("visible"))) {
+
+ return NS_OK;
+ }
+ }
+ }
+
+ // check the pref
+ nsCOMPtr prefBranch =
+ do_GetService(NS_PREFSERVICE_CONTRACTID);
+ if (prefBranch) {
+ PRBool pref = PR_TRUE;
+ prefBranch->GetBoolPref("layout.xml.prettyprint", &pref);
+ if (!pref) {
+ return NS_OK;
+ }
+ }
+
+
+ // Ok, we should prettyprint. Let's do it!
+ nsresult rv = NS_OK;
+
+ // Load the XSLT
+ nsCOMPtr xslUri;
+ rv = NS_NewURI(getter_AddRefs(xslUri),
+ NS_LITERAL_CSTRING("chrome://communicator/content/xml/XMLPrettyPrint.xsl"));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr channel;
+ rv = NS_NewChannel(getter_AddRefs(channel), xslUri, nsnull, nsnull);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr xslDocument;
+ nsCOMPtr loader =
+ do_GetService("@mozilla.org/content/syncload-dom-service;1", &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = loader->LoadLocalDocument(channel, nsnull, getter_AddRefs(xslDocument));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // Transform the document
+ nsCOMPtr transformer =
+ do_CreateInstance("@mozilla.org/document-transformer;1?type=text/xsl", &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = transformer->ImportStylesheet(xslDocument);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr resultFragment;
+ nsCOMPtr sourceDocument = do_QueryInterface(aDocument);
+ rv = transformer->TransformToFragment(sourceDocument, xslDocument,
+ getter_AddRefs(resultFragment));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // Add the binding
+ nsCOMPtr xblDoc = do_QueryInterface(aDocument);
+ NS_ASSERTION(xblDoc, "xml document doesn't implement nsIDOMDocumentXBL");
+ NS_ENSURE_TRUE(xblDoc, NS_ERROR_FAILURE);
+
+ nsCOMPtr dummy;
+ xblDoc->LoadBindingDocument(NS_LITERAL_STRING("chrome://communicator/content/xml/XMLPrettyPrint.xml"),
+ getter_AddRefs(dummy));
+
+ nsCOMPtr rootElem;
+ sourceDocument->GetDocumentElement(getter_AddRefs(rootElem));
+ NS_ENSURE_TRUE(rootElem, NS_ERROR_UNEXPECTED);
+
+ rv = xblDoc->AddBinding(rootElem,
+ NS_LITERAL_STRING("chrome://communicator/content/xml/XMLPrettyPrint.xml#prettyprint"));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // Hand the result document to the binding
+ nsCOMPtr manager;
+ aDocument->GetBindingManager(getter_AddRefs(manager));
+ nsCOMPtr binding;
+ nsCOMPtr rootCont = do_QueryInterface(rootElem);
+ NS_ASSERTION(rootCont, "Element doesn't implement nsIContent");
+ manager->GetBindingImplementation(rootCont, NS_GET_IID(nsIObserver),
+ (void**)getter_AddRefs(binding));
+ NS_ASSERTION(binding, "Prettyprint binding doesn't implement nsIObserver");
+ NS_ENSURE_TRUE(binding, NS_ERROR_UNEXPECTED);
+
+ rv = binding->Observe(resultFragment, "prettyprint-dom-created", NS_LITERAL_STRING("").get());
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // 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)
+{
+ nsCOMPtr bindingParent;
+ if (aContent) {
+ aContent->GetBindingParent(getter_AddRefs(bindingParent));
+ }
+ // If there either aContent is null (the document-node was modified) or
+ // there isn't a binding parent we know it's non-anonymous content.
+ if (!bindingParent) {
+ mUnhookPending = PR_TRUE;
+ }
+}
+
+// nsIDocumentObserver implementation
+NS_IMETHODIMP
+nsXMLPrettyPrinter::BeginUpdate(nsIDocument* aDocument)
+{
+ mUpdateDepth++;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsXMLPrettyPrinter::EndUpdate(nsIDocument* aDocument)
+{
+ mUpdateDepth--;
+
+ // Only remove the binding once we're outside all updates. This protects us
+ // from nasty surprices of elements being removed from the document in the
+ // midst of setting attributes etc.
+ if (mUnhookPending && mUpdateDepth == 0) {
+ mDocument->RemoveObserver(this);
+ nsCOMPtr document = do_QueryInterface(mDocument);
+ nsCOMPtr rootElem;
+ document->GetDocumentElement(getter_AddRefs(rootElem));
+ nsCOMPtr xblDoc = do_QueryInterface(mDocument);
+ xblDoc->RemoveBinding(rootElem,
+ NS_LITERAL_STRING("chrome://communicator/content/xml/XMLPrettyPrint.xml#prettyprint"));
+
+ mDocument = nsnull;
+
+ NS_RELEASE_THIS();
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsXMLPrettyPrinter::BeginLoad(nsIDocument* aDocument)
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsXMLPrettyPrinter::EndLoad(nsIDocument* aDocument)
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsXMLPrettyPrinter::BeginReflow(nsIDocument* aDocument,
+ nsIPresShell* aShell)
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsXMLPrettyPrinter::EndReflow(nsIDocument* aDocument,
+ nsIPresShell* aShell)
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsXMLPrettyPrinter::ContentChanged(nsIDocument* aDocument,
+ nsIContent *aContent,
+ nsISupports *aSubContent)
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsXMLPrettyPrinter::ContentStatesChanged(nsIDocument* aDocument,
+ nsIContent* aContent1,
+ nsIContent* aContent2,
+ PRInt32 aStateMask)
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsXMLPrettyPrinter::AttributeChanged(nsIDocument* aDocument,
+ nsIContent* aContent,
+ PRInt32 aNameSpaceID,
+ nsIAtom* aAttribute,
+ PRInt32 aModType,
+ nsChangeHint aHint)
+{
+ MaybeUnhook(aContent);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsXMLPrettyPrinter::ContentAppended(nsIDocument* aDocument,
+ nsIContent* aContainer,
+ PRInt32 aNewIndexInContainer)
+{
+ MaybeUnhook(aContainer);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsXMLPrettyPrinter::ContentInserted(nsIDocument* aDocument,
+ nsIContent* aContainer,
+ nsIContent* aChild,
+ PRInt32 aIndexInContainer)
+{
+ MaybeUnhook(aContainer);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsXMLPrettyPrinter::ContentReplaced(nsIDocument* aDocument,
+ nsIContent* aContainer,
+ nsIContent* aOldChild,
+ nsIContent* aNewChild,
+ PRInt32 aIndexInContainer)
+{
+ MaybeUnhook(aContainer);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsXMLPrettyPrinter::ContentRemoved(nsIDocument* aDocument,
+ nsIContent* aContainer,
+ nsIContent* aChild,
+ PRInt32 aIndexInContainer)
+{
+ MaybeUnhook(aContainer);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsXMLPrettyPrinter::StyleSheetAdded(nsIDocument* aDocument,
+ nsIStyleSheet* aStyleSheet)
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsXMLPrettyPrinter::StyleSheetRemoved(nsIDocument* aDocument,
+ nsIStyleSheet* aStyleSheet)
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsXMLPrettyPrinter::StyleSheetDisabledStateChanged(nsIDocument* aDocument,
+ nsIStyleSheet* aStyleSheet,
+ PRBool aDisabled)
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsXMLPrettyPrinter::StyleRuleChanged(nsIDocument* aDocument,
+ nsIStyleSheet* aStyleSheet,
+ nsIStyleRule* aStyleRule,
+ nsChangeHint aHint)
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsXMLPrettyPrinter::StyleRuleAdded(nsIDocument* aDocument,
+ nsIStyleSheet* aStyleSheet,
+ nsIStyleRule* aStyleRule)
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsXMLPrettyPrinter::StyleRuleRemoved(nsIDocument* aDocument,
+ nsIStyleSheet* aStyleSheet,
+ nsIStyleRule* aStyleRule)
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsXMLPrettyPrinter::DocumentWillBeDestroyed(nsIDocument* aDocument)
+{
+ mDocument = nsnull;
+ NS_RELEASE_THIS();
+
+ return NS_OK;
+}
+
+
+nsresult NS_NewXMLPrettyPrinter(nsXMLPrettyPrinter** aPrinter)
+{
+ *aPrinter = new nsXMLPrettyPrinter;
+ NS_ENSURE_TRUE(*aPrinter, NS_ERROR_OUT_OF_MEMORY);
+ NS_ADDREF(*aPrinter);
+ return NS_OK;
+}
diff --git a/content/xml/document/src/nsXMLPrettyPrinter.h b/content/xml/document/src/nsXMLPrettyPrinter.h
new file mode 100644
index 000000000000..0ba17a729e09
--- /dev/null
+++ b/content/xml/document/src/nsXMLPrettyPrinter.h
@@ -0,0 +1,78 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2002
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Jonas Sicking (Original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nsXMLPrettyPrinter_h__
+#define nsXMLPrettyPrinter_h__
+
+#include "nsIDocumentObserver.h"
+#include "nsIDocument.h"
+#include "nsCOMPtr.h"
+
+class nsXMLPrettyPrinter : public nsIDocumentObserver
+{
+public:
+ nsXMLPrettyPrinter();
+ ~nsXMLPrettyPrinter();
+
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIDOCUMENTOBSERVER
+
+ /**
+ * This will prettyprint the document if the document is loaded in a
+ * displayed window.
+ *
+ * @param aDocument document to prettyprint
+ */
+ nsresult PrettyPrint(nsIDocument* aDocument);
+
+private:
+ /**
+ * Signals for unhooking by setting mUnhookPending if the node changed is
+ * non-anonymous content.
+ *
+ * @param aContent content that has changed
+ */
+ void MaybeUnhook(nsIContent* aContent);
+
+ nsIDocument* mDocument; //weak. Set as long as we're observing the document
+ PRUint32 mUpdateDepth;
+ PRPackedBool mUnhookPending;
+};
+
+nsresult NS_NewXMLPrettyPrinter(nsXMLPrettyPrinter** aPrinter);
+
+#endif //nsXMLPrettyPrinter_h__