summaryrefslogtreecommitdiffstats
path: root/layout/tools/layout-debug/src
diff options
context:
space:
mode:
Diffstat (limited to 'layout/tools/layout-debug/src')
-rw-r--r--layout/tools/layout-debug/src/moz.build25
-rw-r--r--layout/tools/layout-debug/src/nsDebugFactory.cpp50
-rw-r--r--layout/tools/layout-debug/src/nsILayoutDebuggingTools.idl52
-rw-r--r--layout/tools/layout-debug/src/nsILayoutRegressionTester.idl46
-rw-r--r--layout/tools/layout-debug/src/nsLayoutDebugCIID.h24
-rw-r--r--layout/tools/layout-debug/src/nsLayoutDebugCLH.cpp82
-rw-r--r--layout/tools/layout-debug/src/nsLayoutDebugCLH.h29
-rw-r--r--layout/tools/layout-debug/src/nsLayoutDebuggingTools.cpp543
-rw-r--r--layout/tools/layout-debug/src/nsLayoutDebuggingTools.h44
-rw-r--r--layout/tools/layout-debug/src/nsRegressionTester.cpp138
-rw-r--r--layout/tools/layout-debug/src/nsRegressionTester.h32
11 files changed, 1065 insertions, 0 deletions
diff --git a/layout/tools/layout-debug/src/moz.build b/layout/tools/layout-debug/src/moz.build
new file mode 100644
index 000000000..be7abcab0
--- /dev/null
+++ b/layout/tools/layout-debug/src/moz.build
@@ -0,0 +1,25 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/.
+
+XPIDL_SOURCES += [
+ 'nsILayoutDebuggingTools.idl',
+ 'nsILayoutRegressionTester.idl',
+]
+
+XPIDL_MODULE = 'layout_debug'
+
+EXPORTS += [
+ 'nsLayoutDebugCIID.h',
+]
+
+UNIFIED_SOURCES += [
+ 'nsDebugFactory.cpp',
+ 'nsLayoutDebugCLH.cpp',
+ 'nsLayoutDebuggingTools.cpp',
+ 'nsRegressionTester.cpp',
+]
+
+FINAL_LIBRARY = 'xul'
diff --git a/layout/tools/layout-debug/src/nsDebugFactory.cpp b/layout/tools/layout-debug/src/nsDebugFactory.cpp
new file mode 100644
index 000000000..c9b7caca4
--- /dev/null
+++ b/layout/tools/layout-debug/src/nsDebugFactory.cpp
@@ -0,0 +1,50 @@
+/* -*- Mode: C++; tab-width: 2; 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 "nscore.h"
+#include "nsLayoutDebugCIID.h"
+#include "mozilla/ModuleUtils.h"
+#include "nsIFactory.h"
+#include "nsISupports.h"
+#include "nsRegressionTester.h"
+#include "nsLayoutDebuggingTools.h"
+#include "nsLayoutDebugCLH.h"
+#include "nsIServiceManager.h"
+
+NS_GENERIC_FACTORY_CONSTRUCTOR(nsRegressionTester)
+NS_GENERIC_FACTORY_CONSTRUCTOR(nsLayoutDebuggingTools)
+NS_GENERIC_FACTORY_CONSTRUCTOR(nsLayoutDebugCLH)
+
+NS_DEFINE_NAMED_CID(NS_REGRESSION_TESTER_CID);
+NS_DEFINE_NAMED_CID(NS_LAYOUT_DEBUGGINGTOOLS_CID);
+NS_DEFINE_NAMED_CID(NS_LAYOUTDEBUGCLH_CID);
+
+static const mozilla::Module::CIDEntry kLayoutDebugCIDs[] = {
+ { &kNS_REGRESSION_TESTER_CID, false, nullptr, nsRegressionTesterConstructor },
+ { &kNS_LAYOUT_DEBUGGINGTOOLS_CID, false, nullptr, nsLayoutDebuggingToolsConstructor },
+ { &kNS_LAYOUTDEBUGCLH_CID, false, nullptr, nsLayoutDebugCLHConstructor },
+ { nullptr }
+};
+
+static const mozilla::Module::ContractIDEntry kLayoutDebugContracts[] = {
+ { "@mozilla.org/layout-debug/regressiontester;1", &kNS_REGRESSION_TESTER_CID },
+ { NS_LAYOUT_DEBUGGINGTOOLS_CONTRACTID, &kNS_LAYOUT_DEBUGGINGTOOLS_CID },
+ { "@mozilla.org/commandlinehandler/general-startup;1?type=layoutdebug", &kNS_LAYOUTDEBUGCLH_CID },
+ { nullptr }
+};
+
+static const mozilla::Module::CategoryEntry kLayoutDebugCategories[] = {
+ { "command-line-handler", "m-layoutdebug", "@mozilla.org/commandlinehandler/general-startup;1?type=layoutdebug" },
+ { nullptr }
+};
+
+static const mozilla::Module kLayoutDebugModule = {
+ mozilla::Module::kVersion,
+ kLayoutDebugCIDs,
+ kLayoutDebugContracts,
+ kLayoutDebugCategories
+};
+
+NSMODULE_DEFN(nsLayoutDebugModule) = &kLayoutDebugModule;
diff --git a/layout/tools/layout-debug/src/nsILayoutDebuggingTools.idl b/layout/tools/layout-debug/src/nsILayoutDebuggingTools.idl
new file mode 100644
index 000000000..18c535e53
--- /dev/null
+++ b/layout/tools/layout-debug/src/nsILayoutDebuggingTools.idl
@@ -0,0 +1,52 @@
+/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+// vim:cindent:tabstop=4:expandtab:shiftwidth=4:
+/* 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 "nsISupports.idl"
+
+interface mozIDOMWindow;
+
+/**
+ * A series of hooks into non-IDL-ized layout code to allow all the
+ * layout debugging functions to be used from chrome.
+ */
+
+[scriptable, uuid(f336d8d3-9721-4ad3-85d0-a7018c0a3383)]
+interface nsILayoutDebuggingTools : nsISupports
+{
+
+ /*
+ * Initialize debugger object to act on a docshell.
+ */
+ void init(in mozIDOMWindow win);
+
+ /*
+ * Notify the debugger that the docshell has been told to load a new
+ * URI.
+ */
+ void newURILoaded();
+
+ /* Toggle various debugging states */
+ attribute boolean visualDebugging;
+ attribute boolean visualEventDebugging;
+ attribute boolean paintFlashing;
+ attribute boolean paintDumping;
+ attribute boolean invalidateDumping;
+ attribute boolean eventDumping;
+ attribute boolean motionEventDumping;
+ attribute boolean crossingEventDumping;
+ attribute boolean reflowCounts;
+
+ /* Run various tests. */
+ void dumpWebShells();
+ void dumpContent();
+ void dumpFrames();
+ void dumpViews();
+
+ void dumpStyleSheets();
+ void dumpStyleContexts();
+
+ void dumpReflowStats();
+};
diff --git a/layout/tools/layout-debug/src/nsILayoutRegressionTester.idl b/layout/tools/layout-debug/src/nsILayoutRegressionTester.idl
new file mode 100644
index 000000000..2899a4b77
--- /dev/null
+++ b/layout/tools/layout-debug/src/nsILayoutRegressionTester.idl
@@ -0,0 +1,46 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* 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 "nsISupports.idl"
+
+interface mozIDOMWindow;
+interface nsIFile;
+
+[scriptable, uuid(0a065e41-3a55-4b5c-bb41-1e848bb2d10c)]
+interface nsILayoutRegressionTester : nsISupports
+{
+ /**
+ * Dumps the content of a window
+ * @param aWindowToDump the window to dump (may be an iframe etc)
+ * @param aFile the file to dump to. It will be created if necessary, otherwise
+ truncated. If nil, write to stdout.
+ * @param aFlagsMask some flags that determine what to dump
+ * @param aFlagsMask some flags that determine what to dump
+ * @param aResult a status value indicating whether the dump happened,
+ whether the page was still loading, or whether some other error happened.
+ */
+ const short DUMP_FLAGS_MASK_DEFAULT = 0;
+ const short DUMP_FLAGS_MASK_PRINT_MODE = 1;
+
+ const long DUMP_RESULT_COMPLETED = 0; // loaded OK
+ const long DUMP_RESULT_LOADING = 1; // still loading
+ const long DUMP_RESULT_ERROR = 2; // an error occurred
+
+ long dumpFrameModel(in mozIDOMWindow aWindowToDump,
+ in nsIFile aFile,
+ in unsigned long aFlagsMask);
+
+ /**
+ * Compares the contents of frame model files
+ * @param aBaseFile the baseline file, opened with read permissions
+ * @param aVerFile file containing the results to verify, opened with read permissions
+ * @param aFlags flags specifying output verbosity
+ * @param aResult result of the comparison: zero if the files are same, non-zero if different
+ */
+ const short COMPARE_FLAGS_VERBOSE = 0;
+ const short COMPARE_FLAGS_BRIEF = 1;
+ boolean compareFrameModels(in nsIFile aBaseFile, in nsIFile aVerFile, in unsigned long aFlags);
+};
+
diff --git a/layout/tools/layout-debug/src/nsLayoutDebugCIID.h b/layout/tools/layout-debug/src/nsLayoutDebugCIID.h
new file mode 100644
index 000000000..ceff68355
--- /dev/null
+++ b/layout/tools/layout-debug/src/nsLayoutDebugCIID.h
@@ -0,0 +1,24 @@
+/* -*- Mode: C++; tab-width: 2; 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/. */
+
+#ifndef nsFrameDebugCIID_h__
+#define nsFrameDebugCIID_h__
+
+#include "nsISupports.h"
+#include "nsIFactory.h"
+#include "nsIComponentManager.h"
+
+#define NS_REGRESSION_TESTER_CID \
+{ 0x698c54f4, 0x4ea9, 0x11d7, \
+{ 0x85, 0x9f, 0x00, 0x03, 0x93, 0x63, 0x65, 0x92 } }
+
+#define NS_LAYOUT_DEBUGGINGTOOLS_CONTRACTID \
+ "@mozilla.org/layout-debug/layout-debuggingtools;1"
+// 3f4c3b63-e640-4712-abbf-fff1301ceb60
+#define NS_LAYOUT_DEBUGGINGTOOLS_CID { 0x3f4c3b68, 0xe640, 0x4712, \
+ { 0xab, 0xbf, 0xff, 0xf1, 0x30, 0x1c, 0xeb, 0x60}}
+
+#endif // nsFrameDebugCIID_h__
+
diff --git a/layout/tools/layout-debug/src/nsLayoutDebugCLH.cpp b/layout/tools/layout-debug/src/nsLayoutDebugCLH.cpp
new file mode 100644
index 000000000..52a0d4555
--- /dev/null
+++ b/layout/tools/layout-debug/src/nsLayoutDebugCLH.cpp
@@ -0,0 +1,82 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+// vim:cindent:tabstop=4:expandtab:shiftwidth=4:
+/* 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 "nsLayoutDebugCLH.h"
+#include "nsArray.h"
+#include "nsString.h"
+#include "plstr.h"
+#include "nsCOMPtr.h"
+#include "nsIWindowWatcher.h"
+#include "nsIServiceManager.h"
+#include "nsIDOMWindow.h"
+#include "nsISupportsPrimitives.h"
+#include "nsICommandLine.h"
+
+nsLayoutDebugCLH::nsLayoutDebugCLH()
+{
+}
+
+nsLayoutDebugCLH::~nsLayoutDebugCLH()
+{
+}
+
+NS_IMPL_ISUPPORTS(nsLayoutDebugCLH, ICOMMANDLINEHANDLER)
+
+NS_IMETHODIMP
+nsLayoutDebugCLH::Handle(nsICommandLine* aCmdLine)
+{
+ nsresult rv;
+
+ int32_t idx;
+ rv = aCmdLine->FindFlag(NS_LITERAL_STRING("layoutdebug"), false, &idx);
+ NS_ENSURE_SUCCESS(rv, rv);
+ if (idx < 0)
+ return NS_OK;
+
+ int32_t length;
+ aCmdLine->GetLength(&length);
+
+ nsAutoString url;
+ if (idx + 1 < length) {
+ rv = aCmdLine->GetArgument(idx + 1, url);
+ NS_ENSURE_SUCCESS(rv, rv);
+ if (!url.IsEmpty() && url.CharAt(0) == '-')
+ url.Truncate();
+ }
+
+ aCmdLine->RemoveArguments(idx, idx + !url.IsEmpty());
+
+ nsCOMPtr<nsIMutableArray> argsArray = nsArray::Create();
+
+ if (!url.IsEmpty())
+ {
+ nsCOMPtr<nsISupportsString> scriptableURL =
+ do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID);
+ NS_ENSURE_TRUE(scriptableURL, NS_ERROR_FAILURE);
+
+ scriptableURL->SetData(url);
+ argsArray->AppendElement(scriptableURL, /*weak =*/ false);
+ }
+
+ nsCOMPtr<nsIWindowWatcher> wwatch =
+ do_GetService(NS_WINDOWWATCHER_CONTRACTID);
+ NS_ENSURE_TRUE(wwatch, NS_ERROR_FAILURE);
+
+ nsCOMPtr<mozIDOMWindowProxy> opened;
+ wwatch->OpenWindow(nullptr, "chrome://layoutdebug/content/",
+ "_blank", "chrome,dialog=no,all", argsArray,
+ getter_AddRefs(opened));
+ aCmdLine->SetPreventDefault(true);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsLayoutDebugCLH::GetHelpInfo(nsACString& aResult)
+{
+ aResult.AssignLiteral(" -layoutdebug [<url>] Start with Layout Debugger\n");
+ return NS_OK;
+}
+
diff --git a/layout/tools/layout-debug/src/nsLayoutDebugCLH.h b/layout/tools/layout-debug/src/nsLayoutDebugCLH.h
new file mode 100644
index 000000000..c79c8d697
--- /dev/null
+++ b/layout/tools/layout-debug/src/nsLayoutDebugCLH.h
@@ -0,0 +1,29 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+// vim:cindent:tabstop=4:expandtab:shiftwidth=4:
+/* 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/. */
+
+#ifndef nsLayoutDebugCLH_h_
+#define nsLayoutDebugCLH_h_
+
+#include "nsICommandLineHandler.h"
+#define ICOMMANDLINEHANDLER nsICommandLineHandler
+
+#define NS_LAYOUTDEBUGCLH_CID \
+ { 0xa8f52633, 0x5ecf, 0x424a, \
+ { 0xa1, 0x47, 0x47, 0xc3, 0x22, 0xf7, 0xbc, 0xe2 }}
+
+class nsLayoutDebugCLH : public ICOMMANDLINEHANDLER
+{
+public:
+ nsLayoutDebugCLH();
+
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSICOMMANDLINEHANDLER
+
+protected:
+ virtual ~nsLayoutDebugCLH();
+};
+
+#endif /* !defined(nsLayoutDebugCLH_h_) */
diff --git a/layout/tools/layout-debug/src/nsLayoutDebuggingTools.cpp b/layout/tools/layout-debug/src/nsLayoutDebuggingTools.cpp
new file mode 100644
index 000000000..4eb57ed9c
--- /dev/null
+++ b/layout/tools/layout-debug/src/nsLayoutDebuggingTools.cpp
@@ -0,0 +1,543 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+// vim:cindent:tabstop=4:expandtab:shiftwidth=4:
+/* 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 "nsLayoutDebuggingTools.h"
+
+#include "nsIDocShell.h"
+#include "nsPIDOMWindow.h"
+#include "nsIContentViewer.h"
+
+#include "nsIServiceManager.h"
+#include "nsIAtom.h"
+#include "nsQuickSort.h"
+
+#include "nsIContent.h"
+#include "nsIDocument.h"
+#include "nsIDOMDocument.h"
+
+#include "nsIPresShell.h"
+#include "nsViewManager.h"
+#include "nsIFrame.h"
+
+#include "nsILayoutDebugger.h"
+#include "nsLayoutCID.h"
+static NS_DEFINE_CID(kLayoutDebuggerCID, NS_LAYOUT_DEBUGGER_CID);
+
+#include "nsISelectionController.h"
+#include "mozilla/dom/Element.h"
+#include "mozilla/Preferences.h"
+
+using namespace mozilla;
+
+static already_AddRefed<nsIContentViewer>
+doc_viewer(nsIDocShell *aDocShell)
+{
+ if (!aDocShell)
+ return nullptr;
+ nsCOMPtr<nsIContentViewer> result;
+ aDocShell->GetContentViewer(getter_AddRefs(result));
+ return result.forget();
+}
+
+static already_AddRefed<nsIPresShell>
+pres_shell(nsIDocShell *aDocShell)
+{
+ nsCOMPtr<nsIContentViewer> cv = doc_viewer(aDocShell);
+ if (!cv)
+ return nullptr;
+ nsCOMPtr<nsIPresShell> result;
+ cv->GetPresShell(getter_AddRefs(result));
+ return result.forget();
+}
+
+static nsViewManager*
+view_manager(nsIDocShell *aDocShell)
+{
+ nsCOMPtr<nsIPresShell> shell(pres_shell(aDocShell));
+ if (!shell)
+ return nullptr;
+ return shell->GetViewManager();
+}
+
+#ifdef DEBUG
+static already_AddRefed<nsIDocument>
+document(nsIDocShell *aDocShell)
+{
+ nsCOMPtr<nsIContentViewer> cv(doc_viewer(aDocShell));
+ if (!cv)
+ return nullptr;
+ nsCOMPtr<nsIDOMDocument> domDoc;
+ cv->GetDOMDocument(getter_AddRefs(domDoc));
+ if (!domDoc)
+ return nullptr;
+ nsCOMPtr<nsIDocument> result = do_QueryInterface(domDoc);
+ return result.forget();
+}
+#endif
+
+nsLayoutDebuggingTools::nsLayoutDebuggingTools()
+ : mPaintFlashing(false),
+ mPaintDumping(false),
+ mInvalidateDumping(false),
+ mEventDumping(false),
+ mMotionEventDumping(false),
+ mCrossingEventDumping(false),
+ mReflowCounts(false)
+{
+ NewURILoaded();
+}
+
+nsLayoutDebuggingTools::~nsLayoutDebuggingTools()
+{
+}
+
+NS_IMPL_ISUPPORTS(nsLayoutDebuggingTools, nsILayoutDebuggingTools)
+
+NS_IMETHODIMP
+nsLayoutDebuggingTools::Init(mozIDOMWindow* aWin)
+{
+ if (!Preferences::GetService()) {
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ {
+ if (!aWin)
+ return NS_ERROR_UNEXPECTED;
+ auto* window = nsPIDOMWindowInner::From(aWin);
+ mDocShell = window->GetDocShell();
+ }
+ NS_ENSURE_TRUE(mDocShell, NS_ERROR_UNEXPECTED);
+
+ mPaintFlashing =
+ Preferences::GetBool("nglayout.debug.paint_flashing", mPaintFlashing);
+ mPaintDumping =
+ Preferences::GetBool("nglayout.debug.paint_dumping", mPaintDumping);
+ mInvalidateDumping =
+ Preferences::GetBool("nglayout.debug.invalidate_dumping", mInvalidateDumping);
+ mEventDumping =
+ Preferences::GetBool("nglayout.debug.event_dumping", mEventDumping);
+ mMotionEventDumping =
+ Preferences::GetBool("nglayout.debug.motion_event_dumping",
+ mMotionEventDumping);
+ mCrossingEventDumping =
+ Preferences::GetBool("nglayout.debug.crossing_event_dumping",
+ mCrossingEventDumping);
+ mReflowCounts =
+ Preferences::GetBool("layout.reflow.showframecounts", mReflowCounts);
+
+ {
+ nsCOMPtr<nsILayoutDebugger> ld = do_GetService(kLayoutDebuggerCID);
+ if (ld) {
+ ld->GetShowFrameBorders(&mVisualDebugging);
+ ld->GetShowEventTargetFrameBorder(&mVisualEventDebugging);
+ }
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsLayoutDebuggingTools::NewURILoaded()
+{
+ NS_ENSURE_TRUE(mDocShell, NS_ERROR_NOT_INITIALIZED);
+ // Reset all the state that should be reset between pages.
+
+ // XXX Some of these should instead be transferred between pages!
+ mEditorMode = false;
+ mVisualDebugging = false;
+ mVisualEventDebugging = false;
+
+ mReflowCounts = false;
+
+ ForceRefresh();
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsLayoutDebuggingTools::GetVisualDebugging(bool *aVisualDebugging)
+{
+ *aVisualDebugging = mVisualDebugging;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsLayoutDebuggingTools::SetVisualDebugging(bool aVisualDebugging)
+{
+ nsCOMPtr<nsILayoutDebugger> ld = do_GetService(kLayoutDebuggerCID);
+ if (!ld)
+ return NS_ERROR_UNEXPECTED;
+ mVisualDebugging = aVisualDebugging;
+ ld->SetShowFrameBorders(aVisualDebugging);
+ ForceRefresh();
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsLayoutDebuggingTools::GetVisualEventDebugging(bool *aVisualEventDebugging)
+{
+ *aVisualEventDebugging = mVisualEventDebugging;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsLayoutDebuggingTools::SetVisualEventDebugging(bool aVisualEventDebugging)
+{
+ nsCOMPtr<nsILayoutDebugger> ld = do_GetService(kLayoutDebuggerCID);
+ if (!ld)
+ return NS_ERROR_UNEXPECTED;
+ mVisualEventDebugging = aVisualEventDebugging;
+ ld->SetShowEventTargetFrameBorder(aVisualEventDebugging);
+ ForceRefresh();
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsLayoutDebuggingTools::GetPaintFlashing(bool *aPaintFlashing)
+{
+ *aPaintFlashing = mPaintFlashing;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsLayoutDebuggingTools::SetPaintFlashing(bool aPaintFlashing)
+{
+ mPaintFlashing = aPaintFlashing;
+ return SetBoolPrefAndRefresh("nglayout.debug.paint_flashing", mPaintFlashing);
+}
+
+NS_IMETHODIMP
+nsLayoutDebuggingTools::GetPaintDumping(bool *aPaintDumping)
+{
+ *aPaintDumping = mPaintDumping;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsLayoutDebuggingTools::SetPaintDumping(bool aPaintDumping)
+{
+ mPaintDumping = aPaintDumping;
+ return SetBoolPrefAndRefresh("nglayout.debug.paint_dumping", mPaintDumping);
+}
+
+NS_IMETHODIMP
+nsLayoutDebuggingTools::GetInvalidateDumping(bool *aInvalidateDumping)
+{
+ *aInvalidateDumping = mInvalidateDumping;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsLayoutDebuggingTools::SetInvalidateDumping(bool aInvalidateDumping)
+{
+ mInvalidateDumping = aInvalidateDumping;
+ return SetBoolPrefAndRefresh("nglayout.debug.invalidate_dumping", mInvalidateDumping);
+}
+
+NS_IMETHODIMP
+nsLayoutDebuggingTools::GetEventDumping(bool *aEventDumping)
+{
+ *aEventDumping = mEventDumping;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsLayoutDebuggingTools::SetEventDumping(bool aEventDumping)
+{
+ mEventDumping = aEventDumping;
+ return SetBoolPrefAndRefresh("nglayout.debug.event_dumping", mEventDumping);
+}
+
+NS_IMETHODIMP
+nsLayoutDebuggingTools::GetMotionEventDumping(bool *aMotionEventDumping)
+{
+ *aMotionEventDumping = mMotionEventDumping;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsLayoutDebuggingTools::SetMotionEventDumping(bool aMotionEventDumping)
+{
+ mMotionEventDumping = aMotionEventDumping;
+ return SetBoolPrefAndRefresh("nglayout.debug.motion_event_dumping", mMotionEventDumping);
+}
+
+NS_IMETHODIMP
+nsLayoutDebuggingTools::GetCrossingEventDumping(bool *aCrossingEventDumping)
+{
+ *aCrossingEventDumping = mCrossingEventDumping;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsLayoutDebuggingTools::SetCrossingEventDumping(bool aCrossingEventDumping)
+{
+ mCrossingEventDumping = aCrossingEventDumping;
+ return SetBoolPrefAndRefresh("nglayout.debug.crossing_event_dumping", mCrossingEventDumping);
+}
+
+NS_IMETHODIMP
+nsLayoutDebuggingTools::GetReflowCounts(bool* aShow)
+{
+ *aShow = mReflowCounts;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsLayoutDebuggingTools::SetReflowCounts(bool aShow)
+{
+ NS_ENSURE_TRUE(mDocShell, NS_ERROR_NOT_INITIALIZED);
+ nsCOMPtr<nsIPresShell> shell(pres_shell(mDocShell));
+ if (shell) {
+#ifdef MOZ_REFLOW_PERF
+ shell->SetPaintFrameCount(aShow);
+ SetBoolPrefAndRefresh("layout.reflow.showframecounts", aShow);
+ mReflowCounts = aShow;
+#else
+ printf("************************************************\n");
+ printf("Sorry, you have not built with MOZ_REFLOW_PERF=1\n");
+ printf("************************************************\n");
+#endif
+ }
+ return NS_OK;
+}
+
+static void DumpAWebShell(nsIDocShellTreeItem* aShellItem, FILE* out, int32_t aIndent)
+{
+ nsString name;
+ nsCOMPtr<nsIDocShellTreeItem> parent;
+ int32_t i, n;
+
+ for (i = aIndent; --i >= 0; )
+ fprintf(out, " ");
+
+ fprintf(out, "%p '", static_cast<void*>(aShellItem));
+ aShellItem->GetName(name);
+ aShellItem->GetSameTypeParent(getter_AddRefs(parent));
+ fputs(NS_LossyConvertUTF16toASCII(name).get(), out);
+ fprintf(out, "' parent=%p <\n", static_cast<void*>(parent));
+
+ ++aIndent;
+ aShellItem->GetChildCount(&n);
+ for (i = 0; i < n; ++i) {
+ nsCOMPtr<nsIDocShellTreeItem> child;
+ aShellItem->GetChildAt(i, getter_AddRefs(child));
+ if (child) {
+ DumpAWebShell(child, out, aIndent);
+ }
+ }
+ --aIndent;
+ for (i = aIndent; --i >= 0; )
+ fprintf(out, " ");
+ fputs(">\n", out);
+}
+
+NS_IMETHODIMP
+nsLayoutDebuggingTools::DumpWebShells()
+{
+ NS_ENSURE_TRUE(mDocShell, NS_ERROR_NOT_INITIALIZED);
+ DumpAWebShell(mDocShell, stdout, 0);
+ return NS_OK;
+}
+
+static
+void
+DumpContentRecur(nsIDocShell* aDocShell, FILE* out)
+{
+#ifdef DEBUG
+ if (nullptr != aDocShell) {
+ fprintf(out, "docshell=%p \n", static_cast<void*>(aDocShell));
+ nsCOMPtr<nsIDocument> doc(document(aDocShell));
+ if (doc) {
+ dom::Element *root = doc->GetRootElement();
+ if (root) {
+ root->List(out);
+ }
+ }
+ else {
+ fputs("no document\n", out);
+ }
+ // dump the frames of the sub documents
+ int32_t i, n;
+ aDocShell->GetChildCount(&n);
+ for (i = 0; i < n; ++i) {
+ nsCOMPtr<nsIDocShellTreeItem> child;
+ aDocShell->GetChildAt(i, getter_AddRefs(child));
+ nsCOMPtr<nsIDocShell> childAsShell(do_QueryInterface(child));
+ if (child) {
+ DumpContentRecur(childAsShell, out);
+ }
+ }
+ }
+#endif
+}
+
+NS_IMETHODIMP
+nsLayoutDebuggingTools::DumpContent()
+{
+ NS_ENSURE_TRUE(mDocShell, NS_ERROR_NOT_INITIALIZED);
+ DumpContentRecur(mDocShell, stdout);
+ return NS_OK;
+}
+
+static void
+DumpFramesRecur(nsIDocShell* aDocShell, FILE* out)
+{
+#ifdef DEBUG
+ fprintf(out, "webshell=%p \n", static_cast<void*>(aDocShell));
+ nsCOMPtr<nsIPresShell> shell(pres_shell(aDocShell));
+ if (shell) {
+ nsIFrame* root = shell->GetRootFrame();
+ if (root) {
+ root->List(out);
+ }
+ }
+ else {
+ fputs("null pres shell\n", out);
+ }
+
+ // dump the frames of the sub documents
+ int32_t i, n;
+ aDocShell->GetChildCount(&n);
+ for (i = 0; i < n; ++i) {
+ nsCOMPtr<nsIDocShellTreeItem> child;
+ aDocShell->GetChildAt(i, getter_AddRefs(child));
+ nsCOMPtr<nsIDocShell> childAsShell(do_QueryInterface(child));
+ if (childAsShell) {
+ DumpFramesRecur(childAsShell, out);
+ }
+ }
+#endif
+}
+
+NS_IMETHODIMP
+nsLayoutDebuggingTools::DumpFrames()
+{
+ NS_ENSURE_TRUE(mDocShell, NS_ERROR_NOT_INITIALIZED);
+ DumpFramesRecur(mDocShell, stdout);
+ return NS_OK;
+}
+
+static
+void
+DumpViewsRecur(nsIDocShell* aDocShell, FILE* out)
+{
+#ifdef DEBUG
+ fprintf(out, "docshell=%p \n", static_cast<void*>(aDocShell));
+ RefPtr<nsViewManager> vm(view_manager(aDocShell));
+ if (vm) {
+ nsView* root = vm->GetRootView();
+ if (root) {
+ root->List(out);
+ }
+ }
+ else {
+ fputs("null view manager\n", out);
+ }
+
+ // dump the views of the sub documents
+ int32_t i, n;
+ aDocShell->GetChildCount(&n);
+ for (i = 0; i < n; i++) {
+ nsCOMPtr<nsIDocShellTreeItem> child;
+ aDocShell->GetChildAt(i, getter_AddRefs(child));
+ nsCOMPtr<nsIDocShell> childAsShell(do_QueryInterface(child));
+ if (childAsShell) {
+ DumpViewsRecur(childAsShell, out);
+ }
+ }
+#endif // DEBUG
+}
+
+NS_IMETHODIMP
+nsLayoutDebuggingTools::DumpViews()
+{
+ NS_ENSURE_TRUE(mDocShell, NS_ERROR_NOT_INITIALIZED);
+ DumpViewsRecur(mDocShell, stdout);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsLayoutDebuggingTools::DumpStyleSheets()
+{
+ NS_ENSURE_TRUE(mDocShell, NS_ERROR_NOT_INITIALIZED);
+#ifdef DEBUG
+ FILE *out = stdout;
+ nsCOMPtr<nsIPresShell> shell(pres_shell(mDocShell));
+ if (shell)
+ shell->ListStyleSheets(out);
+ else
+ fputs("null pres shell\n", out);
+#endif
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsLayoutDebuggingTools::DumpStyleContexts()
+{
+ NS_ENSURE_TRUE(mDocShell, NS_ERROR_NOT_INITIALIZED);
+#ifdef DEBUG
+ FILE *out = stdout;
+ nsCOMPtr<nsIPresShell> shell(pres_shell(mDocShell));
+ if (shell) {
+ nsIFrame* root = shell->GetRootFrame();
+ if (!root) {
+ fputs("null root frame\n", out);
+ } else {
+ shell->ListStyleContexts(root, out);
+ }
+ } else {
+ fputs("null pres shell\n", out);
+ }
+#endif
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsLayoutDebuggingTools::DumpReflowStats()
+{
+ NS_ENSURE_TRUE(mDocShell, NS_ERROR_NOT_INITIALIZED);
+#ifdef DEBUG
+ nsCOMPtr<nsIPresShell> shell(pres_shell(mDocShell));
+ if (shell) {
+#ifdef MOZ_REFLOW_PERF
+ shell->DumpReflows();
+#else
+ printf("************************************************\n");
+ printf("Sorry, you have not built with MOZ_REFLOW_PERF=1\n");
+ printf("************************************************\n");
+#endif
+ }
+#endif
+ return NS_OK;
+}
+
+void nsLayoutDebuggingTools::ForceRefresh()
+{
+ RefPtr<nsViewManager> vm(view_manager(mDocShell));
+ if (!vm)
+ return;
+ nsView* root = vm->GetRootView();
+ if (root) {
+ vm->InvalidateView(root);
+ }
+}
+
+nsresult
+nsLayoutDebuggingTools::SetBoolPrefAndRefresh(const char * aPrefName,
+ bool aNewVal)
+{
+ NS_ENSURE_TRUE(mDocShell, NS_ERROR_NOT_INITIALIZED);
+
+ nsIPrefService* prefService = Preferences::GetService();
+ NS_ENSURE_TRUE(prefService && aPrefName, NS_OK);
+
+ Preferences::SetBool(aPrefName, aNewVal);
+ prefService->SavePrefFile(nullptr);
+
+ ForceRefresh();
+
+ return NS_OK;
+}
diff --git a/layout/tools/layout-debug/src/nsLayoutDebuggingTools.h b/layout/tools/layout-debug/src/nsLayoutDebuggingTools.h
new file mode 100644
index 000000000..6d57c1fa1
--- /dev/null
+++ b/layout/tools/layout-debug/src/nsLayoutDebuggingTools.h
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+// vim:cindent:tabstop=4:expandtab:shiftwidth=4:
+/* 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/. */
+
+#ifndef nsLayoutDebuggingTools_h
+#define nsLayoutDebuggingTools_h
+
+#include "nsILayoutDebuggingTools.h"
+#include "nsIDocShell.h"
+#include "nsCOMPtr.h"
+
+class nsLayoutDebuggingTools : public nsILayoutDebuggingTools {
+
+public:
+ nsLayoutDebuggingTools();
+
+ NS_DECL_ISUPPORTS
+
+ NS_DECL_NSILAYOUTDEBUGGINGTOOLS
+
+protected:
+ virtual ~nsLayoutDebuggingTools();
+
+ void ForceRefresh();
+ nsresult GetBoolPref(const char * aPrefName, bool *aValue);
+ nsresult SetBoolPrefAndRefresh(const char * aPrefName, bool aNewValue);
+
+ nsCOMPtr<nsIDocShell> mDocShell;
+
+ bool mEditorMode;
+ bool mVisualDebugging;
+ bool mVisualEventDebugging;
+ bool mPaintFlashing;
+ bool mPaintDumping;
+ bool mInvalidateDumping;
+ bool mEventDumping;
+ bool mMotionEventDumping;
+ bool mCrossingEventDumping;
+ bool mReflowCounts;
+};
+
+#endif
diff --git a/layout/tools/layout-debug/src/nsRegressionTester.cpp b/layout/tools/layout-debug/src/nsRegressionTester.cpp
new file mode 100644
index 000000000..3ac7bddca
--- /dev/null
+++ b/layout/tools/layout-debug/src/nsRegressionTester.cpp
@@ -0,0 +1,138 @@
+/* -*- 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 "nsISupports.h"
+#include "nsRegressionTester.h"
+
+#include "nsXPIDLString.h"
+#include "nsReadableUtils.h"
+#include "nsIWindowWatcher.h"
+#include "nsPIDOMWindow.h"
+#include "nsIPresShell.h"
+#include "nsIURI.h"
+#include "nsISimpleEnumerator.h"
+#include "nsIDocShell.h"
+#include "nsIContentViewer.h"
+#include "nsIContentViewerFile.h"
+#include "nsIFrame.h"
+#include "nsStyleStruct.h"
+#include "nsIFrameUtil.h"
+#include "nsLayoutCID.h"
+#include "nsIFile.h"
+#include "nsViewManager.h"
+#include "nsView.h"
+
+
+
+static NS_DEFINE_CID(kFrameUtilCID, NS_FRAME_UTIL_CID);
+
+
+nsRegressionTester::nsRegressionTester()
+{
+}
+
+nsRegressionTester::~nsRegressionTester()
+{
+}
+
+NS_IMPL_ISUPPORTS(nsRegressionTester, nsILayoutRegressionTester)
+
+NS_IMETHODIMP
+nsRegressionTester::DumpFrameModel(mozIDOMWindow* aWindowToDump,
+ nsIFile *aDestFile,
+ uint32_t aFlagsMask, int32_t *aResult)
+{
+ NS_ENSURE_ARG(aWindowToDump);
+ NS_ENSURE_ARG_POINTER(aResult);
+
+ *aResult = DUMP_RESULT_ERROR;
+
+#ifndef DEBUG
+ return NS_ERROR_NOT_AVAILABLE;
+#else
+ nsresult rv = NS_ERROR_NOT_AVAILABLE;
+ uint32_t busyFlags;
+ bool stillLoading;
+
+ auto* windowToDump = nsPIDOMWindowInner::From(aWindowToDump);
+
+ nsCOMPtr<nsIDocShell> docShell = windowToDump->GetDocShell();
+
+ // find out if the document is loaded
+ docShell->GetBusyFlags(&busyFlags);
+ stillLoading = busyFlags & (nsIDocShell::BUSY_FLAGS_BUSY |
+ nsIDocShell::BUSY_FLAGS_PAGE_LOADING);
+ if (stillLoading)
+ {
+ *aResult = DUMP_RESULT_LOADING;
+ return NS_OK;
+ }
+
+ nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell();
+
+ nsIFrame* root = presShell->GetRootFrame();
+
+ FILE* fp = stdout;
+ if (aDestFile)
+ {
+ rv = aDestFile->OpenANSIFileDesc("w", &fp);
+ if (NS_FAILED(rv)) return rv;
+ }
+ if (aFlagsMask & DUMP_FLAGS_MASK_PRINT_MODE) {
+ nsCOMPtr <nsIContentViewer> viewer;
+ docShell->GetContentViewer(getter_AddRefs(viewer));
+ if (viewer){
+ nsCOMPtr<nsIContentViewerFile> viewerFile = do_QueryInterface(viewer);
+ if (viewerFile) {
+ viewerFile->Print(true, fp, nullptr);
+ }
+ }
+ }
+ else {
+ root->DumpRegressionData(presShell->GetPresContext(), fp, 0);
+ }
+ if (fp != stdout)
+ fclose(fp);
+ *aResult = DUMP_RESULT_COMPLETED;
+ return NS_OK;
+#endif
+}
+
+NS_IMETHODIMP
+nsRegressionTester::CompareFrameModels(nsIFile *aBaseFile, nsIFile *aVerFile,
+ uint32_t aFlags, bool *aResult)
+{
+ NS_ENSURE_ARG(aBaseFile);
+ NS_ENSURE_ARG(aVerFile);
+ NS_ENSURE_ARG_POINTER(aResult);
+
+ *aResult = false;
+
+ nsresult rv;
+ FILE* baseFile;
+ rv = aBaseFile->OpenANSIFileDesc("r", &baseFile);
+ if (NS_FAILED(rv)) return rv;
+
+ FILE* verFile;
+ rv = aVerFile->OpenANSIFileDesc("r", &verFile);
+ if (NS_FAILED(rv)) {
+ fclose(baseFile);
+ return rv;
+ }
+
+ nsCOMPtr<nsIFrameUtil> frameUtil = do_CreateInstance(kFrameUtilCID, &rv);
+ if (NS_SUCCEEDED(rv))
+ {
+ int32_t outputLevel = (aFlags == COMPARE_FLAGS_VERBOSE) ? 0 : 1;
+ rv = frameUtil->CompareRegressionData(baseFile, verFile, outputLevel);
+ // CompareRegressionData closes |baseFile| and |verFile|.
+ } else {
+ fclose(verFile);
+ fclose(baseFile);
+ }
+
+ *aResult = NS_FAILED(rv);
+ return NS_OK;
+}
diff --git a/layout/tools/layout-debug/src/nsRegressionTester.h b/layout/tools/layout-debug/src/nsRegressionTester.h
new file mode 100644
index 000000000..b0f36f9b5
--- /dev/null
+++ b/layout/tools/layout-debug/src/nsRegressionTester.h
@@ -0,0 +1,32 @@
+/* -*- Mode: IDL; 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/. */
+
+#ifndef nsRegressionTester_h__
+#define nsRegressionTester_h__
+
+#include "nsCOMPtr.h"
+
+#include "nsILayoutRegressionTester.h"
+#include "nsILayoutDebugger.h"
+
+//*****************************************************************************
+//*** nsRegressionTester
+//*****************************************************************************
+class nsRegressionTester : public nsILayoutRegressionTester
+{
+public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSILAYOUTREGRESSIONTESTER
+
+ nsRegressionTester();
+
+protected:
+ virtual ~nsRegressionTester();
+};
+
+
+
+#endif /* nsRegressionTester_h__ */