Bug 722428: Fix leaks in mochitest by reworking SpecialPowers and nsDOMWindowUtils. r=mounir,ctalbert

This commit is contained in:
Kyle Huey 2012-04-01 19:23:51 -07:00
parent 8a52e3998a
commit 03a553e469
7 changed files with 132 additions and 80 deletions

View File

@ -107,29 +107,21 @@ static bool IsUniversalXPConnectCapable()
DOMCI_DATA(WindowUtils, nsDOMWindowUtils)
NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMWindowUtils)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDOMWindowUtils)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mWindow)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMWindowUtils)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mWindow,
nsIScriptGlobalObject)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMWindowUtils)
NS_INTERFACE_MAP_BEGIN(nsDOMWindowUtils)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMWindowUtils)
NS_INTERFACE_MAP_ENTRY(nsIDOMWindowUtils)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(WindowUtils)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMWindowUtils)
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMWindowUtils)
NS_IMPL_ADDREF(nsDOMWindowUtils)
NS_IMPL_RELEASE(nsDOMWindowUtils)
nsDOMWindowUtils::nsDOMWindowUtils(nsGlobalWindow *aWindow)
: mWindow(aWindow)
{
NS_ASSERTION(mWindow->IsOuterWindow(), "How did that happen?");
nsCOMPtr<nsISupports> supports = do_QueryObject(aWindow);
mWindow = do_GetWeakReference(supports);
NS_ASSERTION(aWindow->IsOuterWindow(), "How did that happen?");
}
nsDOMWindowUtils::~nsDOMWindowUtils()
@ -139,10 +131,11 @@ nsDOMWindowUtils::~nsDOMWindowUtils()
nsIPresShell*
nsDOMWindowUtils::GetPresShell()
{
if (!mWindow)
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
if (!window)
return nsnull;
nsIDocShell *docShell = mWindow->GetDocShell();
nsIDocShell *docShell = window->GetDocShell();
if (!docShell)
return nsnull;
@ -154,9 +147,10 @@ nsDOMWindowUtils::GetPresShell()
nsPresContext*
nsDOMWindowUtils::GetPresContext()
{
if (!mWindow)
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
if (!window)
return nsnull;
nsIDocShell *docShell = mWindow->GetDocShell();
nsIDocShell *docShell = window->GetDocShell();
if (!docShell)
return nsnull;
nsRefPtr<nsPresContext> presContext;
@ -197,8 +191,9 @@ nsDOMWindowUtils::GetDocCharsetIsForced(bool *aIsForced)
return NS_ERROR_DOM_SECURITY_ERR;
}
if (mWindow) {
nsCOMPtr<nsIDocument> doc(do_QueryInterface(mWindow->GetExtantDocument()));
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
if (window) {
nsCOMPtr<nsIDocument> doc(do_QueryInterface(window->GetExtantDocument()));
*aIsForced = doc &&
doc->GetDocumentCharacterSetSource() >= kCharsetFromParentForced;
}
@ -213,8 +208,9 @@ nsDOMWindowUtils::GetDocumentMetadata(const nsAString& aName,
return NS_ERROR_DOM_SECURITY_ERR;
}
if (mWindow) {
nsCOMPtr<nsIDocument> doc(do_QueryInterface(mWindow->GetExtantDocument()));
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
if (window) {
nsCOMPtr<nsIDocument> doc(do_QueryInterface(window->GetExtantDocument()));
if (doc) {
nsCOMPtr<nsIAtom> name = do_GetAtom(aName);
doc->GetHeaderData(name, aValue);
@ -810,8 +806,9 @@ nsDOMWindowUtils::ForceUpdateNativeMenuAt(const nsAString& indexString)
nsIWidget*
nsDOMWindowUtils::GetWidget(nsPoint* aOffset)
{
if (mWindow) {
nsIDocShell *docShell = mWindow->GetDocShell();
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
if (window) {
nsIDocShell *docShell = window->GetDocShell();
if (docShell) {
nsCOMPtr<nsIPresShell> presShell;
docShell->GetPresShell(getter_AddRefs(presShell));
@ -855,12 +852,13 @@ nsDOMWindowUtils::Focus(nsIDOMElement* aElement)
return NS_ERROR_DOM_SECURITY_ERR;
}
nsCOMPtr<nsIDOMWindow> window = do_QueryReferent(mWindow);
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
if (fm) {
if (aElement)
fm->SetFocus(aElement, 0);
else
fm->ClearFocus(mWindow);
fm->ClearFocus(window);
}
return NS_OK;
@ -968,7 +966,10 @@ nsDOMWindowUtils::ElementFromPoint(float aX, float aY,
bool aFlushLayout,
nsIDOMElement** aReturn)
{
nsCOMPtr<nsIDocument> doc(do_QueryInterface(mWindow->GetExtantDocument()));
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_STATE(window);
nsCOMPtr<nsIDocument> doc(do_QueryInterface(window->GetExtantDocument()));
NS_ENSURE_STATE(doc);
return doc->ElementFromPointHelper(aX, aY, aIgnoreRootScrollFrame, aFlushLayout,
@ -987,7 +988,10 @@ nsDOMWindowUtils::NodesFromRect(float aX, float aY,
return NS_ERROR_DOM_SECURITY_ERR;
}
nsCOMPtr<nsIDocument> doc(do_QueryInterface(mWindow->GetExtantDocument()));
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_STATE(window);
nsCOMPtr<nsIDocument> doc(do_QueryInterface(window->GetExtantDocument()));
NS_ENSURE_STATE(doc);
return doc->NodesFromRectHelper(aX, aY, aTopSize, aRightSize, aBottomSize, aLeftSize,
@ -1110,8 +1114,9 @@ nsDOMWindowUtils::DisableNonTestMouseEvents(bool aDisable)
return NS_ERROR_DOM_SECURITY_ERR;
}
NS_ENSURE_TRUE(mWindow, NS_ERROR_FAILURE);
nsIDocShell *docShell = mWindow->GetDocShell();
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
nsIDocShell *docShell = window->GetDocShell();
NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
nsCOMPtr<nsIPresShell> presShell;
docShell->GetPresShell(getter_AddRefs(presShell));
@ -1127,7 +1132,10 @@ nsDOMWindowUtils::SuppressEventHandling(bool aSuppress)
return NS_ERROR_DOM_SECURITY_ERR;
}
nsCOMPtr<nsIDocument> doc(do_QueryInterface(mWindow->GetExtantDocument()));
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_STATE(window);
nsCOMPtr<nsIDocument> doc(do_QueryInterface(window->GetExtantDocument()));
NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
if (aSuppress) {
@ -1142,7 +1150,10 @@ nsDOMWindowUtils::SuppressEventHandling(bool aSuppress)
NS_IMETHODIMP
nsDOMWindowUtils::GetScrollXY(bool aFlushLayout, PRInt32* aScrollX, PRInt32* aScrollY)
{
nsCOMPtr<nsIDocument> doc(do_QueryInterface(mWindow->GetExtantDocument()));
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_STATE(window);
nsCOMPtr<nsIDocument> doc(do_QueryInterface(window->GetExtantDocument()));
NS_ENSURE_STATE(doc);
if (aFlushLayout) {
@ -1421,9 +1432,10 @@ nsDOMWindowUtils::SendQueryContentEvent(PRUint32 aType,
return NS_ERROR_DOM_SECURITY_ERR;
}
NS_ENSURE_TRUE(mWindow, NS_ERROR_FAILURE);
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
nsIDocShell *docShell = mWindow->GetDocShell();
nsIDocShell *docShell = window->GetDocShell();
NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
nsCOMPtr<nsIPresShell> presShell;
@ -1603,9 +1615,12 @@ nsDOMWindowUtils::GetVisitedDependentComputedStyle(
return NS_ERROR_DOM_SECURITY_ERR;
}
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_STATE(window);
nsCOMPtr<nsIDOMCSSStyleDeclaration> decl;
nsresult rv =
mWindow->GetComputedStyle(aElement, aPseudoElement, getter_AddRefs(decl));
window->GetComputedStyle(aElement, aPseudoElement, getter_AddRefs(decl));
NS_ENSURE_SUCCESS(rv, rv);
static_cast<nsComputedDOMStyle*>(decl.get())->SetExposeVisitedStyle(true);
@ -1618,21 +1633,30 @@ nsDOMWindowUtils::GetVisitedDependentComputedStyle(
NS_IMETHODIMP
nsDOMWindowUtils::EnterModalState()
{
mWindow->EnterModalState();
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_STATE(window);
window->EnterModalState();
return NS_OK;
}
NS_IMETHODIMP
nsDOMWindowUtils::LeaveModalState()
{
mWindow->LeaveModalState(nsnull);
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_STATE(window);
window->LeaveModalState(nsnull);
return NS_OK;
}
NS_IMETHODIMP
nsDOMWindowUtils::EnterModalStateWithWindow(nsIDOMWindow **aWindow)
{
*aWindow = mWindow->EnterModalState();
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_STATE(window);
*aWindow = window->EnterModalState();
NS_IF_ADDREF(*aWindow);
return NS_OK;
}
@ -1640,15 +1664,21 @@ nsDOMWindowUtils::EnterModalStateWithWindow(nsIDOMWindow **aWindow)
NS_IMETHODIMP
nsDOMWindowUtils::LeaveModalStateWithWindow(nsIDOMWindow *aWindow)
{
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_STATE(window);
NS_ENSURE_ARG_POINTER(aWindow);
mWindow->LeaveModalState(aWindow);
window->LeaveModalState(aWindow);
return NS_OK;
}
NS_IMETHODIMP
nsDOMWindowUtils::IsInModalState(bool *retval)
{
*retval = mWindow->IsInModalState();
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_STATE(window);
*retval = static_cast<nsGlobalWindow*>(window.get())->IsInModalState();
return NS_OK;
}
@ -1683,16 +1713,23 @@ nsDOMWindowUtils::GetParent(const JS::Value& aObject,
NS_IMETHODIMP
nsDOMWindowUtils::GetOuterWindowID(PRUint64 *aWindowID)
{
NS_ASSERTION(mWindow->IsOuterWindow(), "How did that happen?");
*aWindowID = mWindow->WindowID();
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_STATE(window);
NS_ASSERTION(window->IsOuterWindow(), "How did that happen?");
*aWindowID = window->WindowID();
return NS_OK;
}
NS_IMETHODIMP
nsDOMWindowUtils::GetCurrentInnerWindowID(PRUint64 *aWindowID)
{
NS_ASSERTION(mWindow->IsOuterWindow(), "How did that happen?");
nsGlobalWindow* inner = mWindow->GetCurrentInnerWindowInternal();
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_TRUE(window, NS_ERROR_NOT_AVAILABLE);
NS_ASSERTION(window->IsOuterWindow(), "How did that happen?");
nsGlobalWindow* inner =
static_cast<nsGlobalWindow*>(window.get())->GetCurrentInnerWindowInternal();
if (!inner) {
return NS_ERROR_NOT_AVAILABLE;
}
@ -1707,7 +1744,10 @@ nsDOMWindowUtils::SuspendTimeouts()
return NS_ERROR_DOM_SECURITY_ERR;
}
mWindow->SuspendTimeouts();
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
window->SuspendTimeouts();
return NS_OK;
}
@ -1719,7 +1759,10 @@ nsDOMWindowUtils::ResumeTimeouts()
return NS_ERROR_DOM_SECURITY_ERR;
}
mWindow->ResumeTimeouts();
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
window->ResumeTimeouts();
return NS_OK;
}
@ -1888,10 +1931,13 @@ nsDOMWindowUtils::RenderDocument(const nsRect& aRect,
nscolor aBackgroundColor,
gfxContext* aThebesContext)
{
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
// Get DOM Document
nsresult rv;
nsCOMPtr<nsIDOMDocument> ddoc;
rv = mWindow->GetDocument(getter_AddRefs(ddoc));
rv = window->GetDocument(getter_AddRefs(ddoc));
NS_ENSURE_SUCCESS(rv, rv);
// Get Document
@ -1911,8 +1957,11 @@ nsDOMWindowUtils::GetCursorType(PRInt16 *aCursor)
{
NS_ENSURE_ARG_POINTER(aCursor);
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
bool isSameDoc = false;
nsCOMPtr<nsIDocument> doc(do_QueryInterface(mWindow->GetExtantDocument()));
nsCOMPtr<nsIDocument> doc(do_QueryInterface(window->GetExtantDocument()));
NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
@ -1943,8 +1992,9 @@ nsDOMWindowUtils::GoOnline()
{
// This is only allowed from about:neterror, which is unprivileged, so it
// can't access the io-service itself.
NS_ENSURE_TRUE(mWindow, NS_ERROR_FAILURE);
nsCOMPtr<nsIDocument> doc(do_QueryInterface(mWindow->GetExtantDocument()));
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
nsCOMPtr<nsIDocument> doc(do_QueryInterface(window->GetExtantDocument()));
NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
nsCOMPtr<nsIURI> documentURI;
documentURI = doc->GetDocumentURI();
@ -2068,7 +2118,10 @@ nsDOMWindowUtils::GetMayHaveTouchEventListeners(bool* aResult)
return NS_ERROR_DOM_SECURITY_ERR;
}
nsPIDOMWindow* innerWindow = mWindow->GetCurrentInnerWindow();
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
nsPIDOMWindow* innerWindow = window->GetCurrentInnerWindow();
*aResult = innerWindow ? innerWindow->HasTouchEventListeners() : false;
return NS_OK;
}
@ -2116,11 +2169,12 @@ nsDOMWindowUtils::GetFileReferences(const nsAString& aDatabaseName,
return NS_ERROR_DOM_SECURITY_ERR;
}
NS_ENSURE_TRUE(mWindow, NS_ERROR_FAILURE);
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
nsCString origin;
nsresult rv = indexedDB::IndexedDatabaseManager::GetASCIIOriginFromWindow(
mWindow, origin);
window, origin);
NS_ENSURE_SUCCESS(rv, rv);
nsRefPtr<indexedDB::IndexedDatabaseManager> mgr =
@ -2220,8 +2274,9 @@ nsDOMWindowUtils::GetPCCountScriptContents(PRInt32 script, JSContext* cx, nsAStr
NS_IMETHODIMP
nsDOMWindowUtils::GetPaintingSuppressed(bool *aPaintingSuppressed)
{
NS_ENSURE_TRUE(mWindow, NS_ERROR_FAILURE);
nsIDocShell *docShell = mWindow->GetDocShell();
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
nsIDocShell *docShell = window->GetDocShell();
NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
nsCOMPtr<nsIPresShell> presShell;
@ -2239,7 +2294,10 @@ nsDOMWindowUtils::GetPlugins(JSContext* cx, jsval* aPlugins)
return NS_ERROR_DOM_SECURITY_ERR;
}
nsIDOMDocument* ddoc = mWindow->GetExtantDocument();
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_STATE(window);
nsIDOMDocument* ddoc = window->GetExtantDocument();
nsresult rv;
nsCOMPtr<nsIDocument> doc = do_QueryInterface(ddoc, &rv);

View File

@ -49,13 +49,11 @@ class nsDOMWindowUtils : public nsIDOMWindowUtils,
public:
nsDOMWindowUtils(nsGlobalWindow *aWindow);
~nsDOMWindowUtils();
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsDOMWindowUtils,
nsIDOMWindowUtils)
NS_DECL_ISUPPORTS
NS_DECL_NSIDOMWINDOWUTILS
protected:
nsRefPtr<nsGlobalWindow> mWindow;
nsWeakPtr mWindow;
// If aOffset is non-null, it gets filled in with the offset of the root
// frame of our window to the nearest widget in the app units of our window.

View File

@ -1224,6 +1224,7 @@ nsGlobalWindow::CleanUp(bool aIgnoreModalDialog)
mLocation = nsnull;
mHistory = nsnull;
mFrames = nsnull;
mWindowUtils = nsnull;
mApplicationCache = nsnull;
mIndexedDB = nsnull;
mPendingStorageEventsObsolete = nsnull;
@ -8368,20 +8369,12 @@ nsGlobalWindow::GetInterface(const nsIID & aIID, void **aSink)
else if (aIID.Equals(NS_GET_IID(nsIDOMWindowUtils))) {
FORWARD_TO_OUTER(GetInterface, (aIID, aSink), NS_ERROR_NOT_INITIALIZED);
nsCOMPtr<nsISupports> utils(do_QueryReferent(mWindowUtils));
if (utils) {
*aSink = utils;
NS_ADDREF(((nsISupports *) *aSink));
} else {
nsDOMWindowUtils *utilObj = new nsDOMWindowUtils(this);
nsCOMPtr<nsISupports> utilsIfc =
NS_ISUPPORTS_CAST(nsIDOMWindowUtils *, utilObj);
if (utilsIfc) {
mWindowUtils = do_GetWeakReference(utilsIfc);
*aSink = utilsIfc;
NS_ADDREF(((nsISupports *) *aSink));
}
if (!mWindowUtils) {
mWindowUtils = new nsDOMWindowUtils(this);
}
*aSink = mWindowUtils;
NS_ADDREF(((nsISupports *) *aSink));
}
else {
return QueryInterface(aIID, aSink);

View File

@ -136,6 +136,7 @@ class nsRunnable;
class nsDOMEventTargetHelper;
class nsDOMOfflineResourceList;
class nsDOMMozURLProperty;
class nsDOMWindowUtils;
#ifdef MOZ_DISABLE_DOMCRYPTO
class nsIDOMCrypto;
@ -896,7 +897,7 @@ protected:
nsRefPtr<nsBarProp> mPersonalbar;
nsRefPtr<nsBarProp> mStatusbar;
nsRefPtr<nsBarProp> mScrollbars;
nsCOMPtr<nsIWeakReference> mWindowUtils;
nsRefPtr<nsDOMWindowUtils> mWindowUtils;
nsString mStatus;
nsString mDefaultStatus;
// index 0->language_id 1, so index MAX-1 == language_id MAX

View File

@ -39,7 +39,7 @@
*/
function SpecialPowers(window) {
this.window = window;
this.window = Components.utils.getWeakReference(window);
this._encounteredCrashDumpFiles = [];
this._unexpectedCrashDumpFiles = { };
this._crashDumpDir = null;

View File

@ -36,13 +36,13 @@
* ***** END LICENSE BLOCK ***** */
function ChromePowers(window) {
this.window = window;
this.window = Components.utils.getWeakReference(window);
// In the case of browser-chrome tests, we are running as a [ChromeWindow]
// and we have no window.QueryInterface available, content.window is what we need
if (typeof(window) == "ChromeWindow" && typeof(content.window) == "Window") {
this.DOMWindowUtils = bindDOMWindowUtils(content.window);
this.window = content.window
this.window = Components.utils.getWeakReference(content.window);
} else {
this.DOMWindowUtils = bindDOMWindowUtils(window);
}

View File

@ -77,7 +77,9 @@ function bindDOMWindowUtils(aWindow) {
if (prop in desc && typeof(desc[prop]) == "function") {
var oldval = desc[prop];
try {
desc[prop] = function() { return oldval.apply(util, arguments); };
desc[prop] = function() {
return oldval.apply(util, arguments);
};
} catch (ex) {
dump("WARNING: Special Powers failed to rebind function: " + desc + "::" + prop + "\n");
}
@ -387,7 +389,7 @@ SpecialPowersAPI.prototype = {
},
getDOMWindowUtils: function(aWindow) {
if (aWindow == this.window && this.DOMWindowUtils != null)
if (aWindow == this.window.get() && this.DOMWindowUtils != null)
return this.DOMWindowUtils;
return bindDOMWindowUtils(aWindow);
@ -774,7 +776,7 @@ SpecialPowersAPI.prototype = {
},
snapshotWindow: function (win, withCaret) {
var el = this.window.document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
var el = this.window.get().document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
el.width = win.innerWidth;
el.height = win.innerHeight;
var ctx = el.getContext("2d");
@ -1002,7 +1004,7 @@ SpecialPowersAPI.prototype = {
},
snapshotWindow: function (win, withCaret) {
var el = this.window.document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
var el = this.window.get().document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
el.width = win.innerWidth;
el.height = win.innerHeight;
var ctx = el.getContext("2d");