--- a/browser/base/content/test/test_contextmenu.html
+++ b/browser/base/content/test/test_contextmenu.html
@@ -1,13 +1,13 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Tests for browser context menu</title>
- <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
Browser context menu tests.
<p id="display"></p>
<div id="content">
@@ -23,39 +23,31 @@ Components.utils.import("resource://gre/
const Cc = Components.classes;
const Ci = Components.interfaces;
function openContextMenuFor(element, shiftkey, shouldWaitForFocus) {
// Context menu should be closed before we open it again.
is(contextMenu.state, "closed", "checking if popup is closed");
- //Some elements need time to focus and spellcheck before any tests are
- //run on them.
- if(shouldWaitForFocus)
- {
- if (lastElement)
- lastElement.blur();
- element.focus();
-
- SimpleTest.executeSoon(function() {
- lastElement = element;
- var eventDetails = { type : "contextmenu", button : 2, shiftKey : shiftkey };
- synthesizeMouse(element, 2, 2, eventDetails, element.ownerDocument.defaultView);
- });
- }
- else
- {
- if (lastElement)
- lastElement.blur();
- element.focus();
+ if (lastElement)
+ lastElement.blur();
+ element.focus();
+
+ // Some elements need time to focus and spellcheck before any tests are
+ // run on them.
+ function actuallyOpenContextMenuFor() {
lastElement = element;
var eventDetails = { type : "contextmenu", button : 2, shiftKey : shiftkey };
synthesizeMouse(element, 2, 2, eventDetails, element.ownerDocument.defaultView);
}
+ if (shouldWaitForFocus)
+ SimpleTest.executeSoon(actuallyOpenContextMenuFor);
+ else
+ actuallyOpenContextMenuFor();
}
function closeContextMenu() {
contextMenu.hidePopup();
}
function executeCopyCommand(command, expectedValue)
{
@@ -72,17 +64,17 @@ function executeCopyCommand(command, exp
}
function invokeItemAction(generatedItemId)
{
var item = contextMenu.getElementsByAttribute("generateditemid",
generatedItemId)[0];
ok(item, "Got generated XUL menu item");
item.doCommand();
- is(pagemenu.hasAttribute("hopeless"), false, "attribute got removed");
+ ok(!pagemenu.hasAttribute("hopeless"), "attribute got removed");
}
function getVisibleMenuItems(aMenu, aData) {
var items = [];
var accessKeys = {};
for (var i = 0; i < aMenu.childNodes.length; i++) {
var item = aMenu.childNodes[i];
if (item.hidden)
@@ -173,32 +165,36 @@ function checkContextMenu(expectedItems)
* expectedItems is a array of (1) item IDs and (2) a boolean specifying if
* the item is enabled or not (or null to ignore it). Submenus can be checked
* by providing a nested array entry after the expected <menu> ID.
* For example: ["blah", true, // item enabled
* "submenu", null, // submenu
* ["sub1", true, // submenu contents
* "sub2", false], null, // submenu contents
* "lol", false] // item disabled
- *
+ *
*/
function checkMenu(menu, expectedItems, data) {
var actualItems = getVisibleMenuItems(menu, data);
//ok(false, "Items are: " + actualItems);
for (var i = 0; i < expectedItems.length; i+=2) {
var actualItem = actualItems[i];
var actualEnabled = actualItems[i + 1];
var expectedItem = expectedItems[i];
var expectedEnabled = expectedItems[i + 1];
if (expectedItem instanceof Array) {
ok(true, "Checking submenu...");
var menuID = expectedItems[i - 2]; // The last item was the menu ID.
var submenu = menu.getElementsByAttribute("id", menuID)[0];
- ok(submenu && submenu.nodeName == "menu", "got expected submenu element");
- checkMenu(submenu.menupopup, expectedItem, data);
+ ok(submenu, "got a submenu element of id='" + menuID + "'");
+ if (submenu) {
+ is(submenu.nodeName, "menu", "submenu element of id='" + menuID +
+ "' has expected nodeName");
+ checkMenu(submenu.menupopup, expectedItem, data);
+ }
} else {
is(actualItem, expectedItem,
"checking item #" + i/2 + " (" + expectedItem + ") name");
if (typeof expectedEnabled == "object" && expectedEnabled != null ||
typeof actualEnabled == "object" && actualEnabled != null) {
ok(!(actualEnabled == null), "actualEnabled is not null");
@@ -508,17 +504,17 @@ function runTest(testNum) {
"context-delete", false,
"---", null,
"context-selectall", true,
"---", null,
"spell-check-enabled", true,
"spell-dictionaries", true,
["spell-check-dictionary-en-US", true,
"---", null,
- "spell-add-dictionaries", true], null,
+ "spell-add-dictionaries", true], null
].concat(inspectItems));
contextMenu.ownerDocument.getElementById("spell-add-to-dictionary").doCommand(); // Add to dictionary
closeContextMenu();
openContextMenuFor(textarea, false, true); // Invoke context menu for next test.
break;
case 15:
// Context menu for textarea after a word has been added
@@ -532,17 +528,17 @@ function runTest(testNum) {
"context-delete", false,
"---", null,
"context-selectall", true,
"---", null,
"spell-check-enabled", true,
"spell-dictionaries", true,
["spell-check-dictionary-en-US", true,
"---", null,
- "spell-add-dictionaries", true], null,
+ "spell-add-dictionaries", true], null
].concat(inspectItems));
contextMenu.ownerDocument.getElementById("spell-undo-add-to-dictionary").doCommand(); // Undo add to dictionary
closeContextMenu();
openContextMenuFor(contenteditable);
break;
case 16:
// Context menu for contenteditable
@@ -656,16 +652,17 @@ function runTest(testNum) {
"context-sendpage", true,
"---", null,
"context-viewbgimage", false,
"context-selectall", true,
"---", null,
"context-viewsource", true,
"context-viewinfo", true
].concat(inspectItems));
+ closeContextMenu();
subwindow.close();
SimpleTest.finish();
return;
/*
* Other things that would be nice to test:
* - selected text
@@ -698,16 +695,17 @@ function startTest() {
.rootTreeItem
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindow)
.QueryInterface(Ci.nsIDOMChromeWindow);
contextMenu = chromeWin.document.getElementById("contentAreaContextMenu");
ok(contextMenu, "Got context menu XUL");
if (chromeWin.document.getElementById("Browser:Stop").getAttribute("disabled") != "true") {
+ todo(false, "Wait for subwindow to load... (This should usually happen once.)");
SimpleTest.executeSoon(startTest);
return;
}
lastElement = null;
text = subwindow.document.getElementById("test-text");
link = subwindow.document.getElementById("test-link");
--- a/browser/components/migration/src/nsIEProfileMigrator.cpp
+++ b/browser/components/migration/src/nsIEProfileMigrator.cpp
@@ -94,16 +94,18 @@
#include "nsBrowserCompsCID.h"
#include "nsIStringBundle.h"
#include "nsNetUtil.h"
#include "nsToolkitCompsCID.h"
#include "nsUnicharUtils.h"
#include "nsIWindowsRegKey.h"
#include "nsISupportsPrimitives.h"
+#define kNotFound -1
+
#define TRIDENTPROFILE_BUNDLE "chrome://browser/locale/migration/migration.properties"
#define REGISTRY_IE_MAIN_KEY \
NS_LITERAL_STRING("Software\\Microsoft\\Internet Explorer\\Main")
#define REGISTRY_IE_TYPEDURL_KEY \
NS_LITERAL_STRING("Software\\Microsoft\\Internet Explorer\\TypedURLs")
#define REGISTRY_IE_TOOLBAR_KEY \
NS_LITERAL_STRING("Software\\Microsoft\\Internet Explorer\\Toolbar")
@@ -597,37 +599,41 @@ nsIEProfileMigrator::TestForIE7()
if (!::ExpandEnvironmentStringsW(iePath.get(),
destination,
bufLength))
return false;
iePath = destination;
+ // Check if the path is enclosed in quotation marks.
if (StringBeginsWith(iePath, NS_LITERAL_STRING("\""))) {
iePath.Cut(0,1);
- PRUint32 index = iePath.FindChar('\"', 0);
+ PRInt32 index = iePath.FindChar('\"', 0);
+
+ // After removing the opening quoation mark,
+ // remove the closing one and everything after it.
if (index > 0)
iePath.Cut(index,iePath.Length());
}
nsCOMPtr<nsILocalFile> lf;
NS_NewLocalFile(iePath, true, getter_AddRefs(lf));
nsCOMPtr<nsILocalFileWin> lfw = do_QueryInterface(lf);
if (!lfw)
return false;
nsAutoString ieVersion;
if (NS_FAILED(lfw->GetVersionInfoField("FileVersion", ieVersion)))
return false;
if (ieVersion.Length() > 2) {
- PRUint32 index = ieVersion.FindChar('.', 0);
- if (index < 0)
+ PRInt32 index = ieVersion.FindChar('.', 0);
+ if (index == kNotFound)
return false;
ieVersion.Cut(index, ieVersion.Length());
PRInt32 ver = wcstol(ieVersion.get(), nsnull, 0);
if (ver >= 7) // Found 7 or greater major version
return true;
}
return false;
--- a/content/base/public/nsDOMEventTargetWrapperCache.h
+++ b/content/base/public/nsDOMEventTargetWrapperCache.h
@@ -85,17 +85,17 @@ public:
return static_cast<nsDOMEventTargetWrapperCache*>(target);
}
void Init(JSContext* aCx = nsnull);
protected:
nsDOMEventTargetWrapperCache() : nsDOMEventTargetHelper(), nsWrapperCache() {}
- virtual ~nsDOMEventTargetWrapperCache() {}
+ virtual ~nsDOMEventTargetWrapperCache();
};
#define NS_DECL_EVENT_HANDLER(_event) \
protected: \
nsRefPtr<nsDOMEventListenerWrapper> mOn##_event##Listener; \
public:
#define NS_DECL_AND_IMPL_EVENT_HANDLER(_event) \
--- a/content/base/src/nsDOMEventTargetWrapperCache.cpp
+++ b/content/base/src/nsDOMEventTargetWrapperCache.cpp
@@ -88,8 +88,13 @@ nsDOMEventTargetWrapperCache::Init(JSCon
if (context) {
mScriptContext = context;
nsCOMPtr<nsPIDOMWindow> window =
do_QueryInterface(context->GetGlobalObject());
if (window)
mOwner = window->GetCurrentInnerWindow();
}
}
+
+nsDOMEventTargetWrapperCache::~nsDOMEventTargetWrapperCache()
+{
+ nsContentUtils::ReleaseWrapper(this, this);
+}
--- a/content/base/src/nsFrameLoader.cpp
+++ b/content/base/src/nsFrameLoader.cpp
@@ -1198,23 +1198,29 @@ nsFrameLoader::SwapWithOtherLoader(nsFra
otherTabChild->SetOwner(ourContent);
otherTabChild->SetChromeMessageManager(ourMessageManager);
}
// Swap and setup things in parent message managers.
nsFrameMessageManager* ourParentManager = mMessageManager ?
mMessageManager->GetParentManager() : nsnull;
nsFrameMessageManager* otherParentManager = aOther->mMessageManager ?
aOther->mMessageManager->GetParentManager() : nsnull;
+ JSContext* thisCx =
+ mMessageManager ? mMessageManager->GetJSContext() : nsnull;
+ JSContext* otherCx =
+ aOther->mMessageManager ? aOther->mMessageManager->GetJSContext() : nsnull;
if (mMessageManager) {
- mMessageManager->Disconnect();
+ mMessageManager->RemoveFromParent();
+ mMessageManager->SetJSContext(otherCx);
mMessageManager->SetParentManager(otherParentManager);
mMessageManager->SetCallbackData(aOther, false);
}
if (aOther->mMessageManager) {
- aOther->mMessageManager->Disconnect();
+ aOther->mMessageManager->RemoveFromParent();
+ aOther->mMessageManager->SetJSContext(thisCx);
aOther->mMessageManager->SetParentManager(ourParentManager);
aOther->mMessageManager->SetCallbackData(this, false);
}
mMessageManager.swap(aOther->mMessageManager);
aFirstToSwap.swap(aSecondToSwap);
// Drop any cached content viewers in the two session histories.
--- a/content/base/src/nsFrameMessageManager.cpp
+++ b/content/base/src/nsFrameMessageManager.cpp
@@ -341,31 +341,53 @@ nsFrameMessageManager::Btoa(const nsAStr
NS_IMETHODIMP
nsFrameMessageManager::Atob(const nsAString& aAsciiString,
nsAString& aBinaryData)
{
return NS_OK;
}
+class MMListenerRemover
+{
+public:
+ MMListenerRemover(nsFrameMessageManager* aMM)
+ : mMM(aMM), mWasHandlingMessage(aMM->mHandlingMessage)
+ {
+ mMM->mHandlingMessage = true;
+ }
+ ~MMListenerRemover()
+ {
+ if (!mWasHandlingMessage) {
+ mMM->mHandlingMessage = false;
+ if (mMM->mDisconnected) {
+ mMM->mListeners.Clear();
+ }
+ }
+ }
+
+ bool mWasHandlingMessage;
+ nsRefPtr<nsFrameMessageManager> mMM;
+};
+
nsresult
nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
const nsAString& aMessage,
bool aSync, const nsAString& aJSON,
JSObject* aObjectsArray,
InfallibleTArray<nsString>* aJSONRetVal,
JSContext* aContext)
{
JSContext* ctx = mContext ? mContext : aContext;
if (!ctx) {
nsContentUtils::ThreadJSContextStack()->GetSafeJSContext(&ctx);
}
if (mListeners.Length()) {
nsCOMPtr<nsIAtom> name = do_GetAtom(aMessage);
- nsRefPtr<nsFrameMessageManager> kungfuDeathGrip(this);
+ MMListenerRemover lr(this);
for (PRUint32 i = 0; i < mListeners.Length(); ++i) {
if (mListeners[i].mMessage == name) {
nsCOMPtr<nsIXPConnectWrappedJS> wrappedJS =
do_QueryInterface(mListeners[i].mListener);
if (!wrappedJS) {
continue;
}
@@ -526,24 +548,39 @@ nsFrameMessageManager::SetCallbackData(v
for (PRUint32 i = 0; i < mPendingScripts.Length(); ++i) {
LoadFrameScript(mPendingScripts[i], false);
}
}
}
}
void
+nsFrameMessageManager::RemoveFromParent()
+{
+ if (mParentManager) {
+ mParentManager->RemoveChildManager(this);
+ }
+ mParentManager = nsnull;
+ mCallbackData = nsnull;
+ mContext = nsnull;
+}
+
+void
nsFrameMessageManager::Disconnect(bool aRemoveFromParent)
{
if (mParentManager && aRemoveFromParent) {
mParentManager->RemoveChildManager(this);
}
+ mDisconnected = true;
mParentManager = nsnull;
mCallbackData = nsnull;
mContext = nsnull;
+ if (!mHandlingMessage) {
+ mListeners.Clear();
+ }
}
nsresult
NS_NewGlobalMessageManager(nsIChromeFrameMessageManager** aResult)
{
NS_ENSURE_TRUE(IsChromeProcess(), NS_ERROR_NOT_AVAILABLE);
nsFrameMessageManager* mm = new nsFrameMessageManager(true,
nsnull,
--- a/content/base/src/nsFrameMessageManager.h
+++ b/content/base/src/nsFrameMessageManager.h
@@ -87,17 +87,17 @@ public:
nsAsyncMessageCallback aAsyncCallback,
nsLoadScriptCallback aLoadScriptCallback,
void* aCallbackData,
nsFrameMessageManager* aParentManager,
JSContext* aContext,
bool aGlobal = false,
bool aProcessManager = false)
: mChrome(aChrome), mGlobal(aGlobal), mIsProcessManager(aProcessManager),
- mParentManager(aParentManager),
+ mHandlingMessage(false), mDisconnected(false), mParentManager(aParentManager),
mSyncCallback(aSyncCallback), mAsyncCallback(aAsyncCallback),
mLoadScriptCallback(aLoadScriptCallback), mCallbackData(aCallbackData),
mContext(aContext)
{
NS_ASSERTION(mContext || (aChrome && !aParentManager) || aProcessManager,
"Should have mContext in non-global/non-process manager!");
NS_ASSERTION(aChrome || !aParentManager, "Should not set parent manager!");
// This is a bit hackish. When parent manager is global, we want
@@ -157,16 +157,18 @@ public:
void Disconnect(bool aRemoveFromParent = true);
void SetCallbackData(void* aData, bool aLoadScripts = true);
void GetParamsForMessage(const jsval& aObject,
JSContext* aCx,
nsAString& aJSON);
nsresult SendAsyncMessageInternal(const nsAString& aMessage,
const nsAString& aJSON);
JSContext* GetJSContext() { return mContext; }
+ void SetJSContext(JSContext* aCx) { mContext = aCx; }
+ void RemoveFromParent();
nsFrameMessageManager* GetParentManager() { return mParentManager; }
void SetParentManager(nsFrameMessageManager* aParent)
{
NS_ASSERTION(!mParentManager, "We have parent manager already!");
NS_ASSERTION(mChrome, "Should not set parent manager!");
mParentManager = aParent;
}
bool IsGlobal() { return mGlobal; }
@@ -176,21 +178,24 @@ public:
{
return sParentProcessManager;
}
static nsFrameMessageManager* GetChildProcessManager()
{
return sChildProcessManager;
}
protected:
+ friend class MMListenerRemover;
nsTArray<nsMessageListenerInfo> mListeners;
nsCOMArray<nsIContentFrameMessageManager> mChildManagers;
bool mChrome;
bool mGlobal;
bool mIsProcessManager;
+ bool mHandlingMessage;
+ bool mDisconnected;
nsFrameMessageManager* mParentManager;
nsSyncMessageCallback mSyncCallback;
nsAsyncMessageCallback mAsyncCallback;
nsLoadScriptCallback mLoadScriptCallback;
void* mCallbackData;
JSContext* mContext;
nsTArray<nsString> mPendingScripts;
public:
--- a/content/base/src/nsInProcessTabChildGlobal.cpp
+++ b/content/base/src/nsInProcessTabChildGlobal.cpp
@@ -245,16 +245,18 @@ nsInProcessTabChildGlobal::DelayedDiscon
static_cast<nsFrameMessageManager*>(mMessageManager.get())->Disconnect();
mMessageManager = nsnull;
}
if (mListenerManager) {
mListenerManager->Disconnect();
}
if (!mLoadingScript) {
+ nsContentUtils::ReleaseWrapper(static_cast<nsIDOMEventTarget*>(this),
+ this);
if (mCx) {
DestroyCx();
}
} else {
mDelayedDisconnect = true;
}
}
--- a/content/base/src/nsNodeInfoManager.cpp
+++ b/content/base/src/nsNodeInfoManager.cpp
@@ -49,16 +49,17 @@
#include "nsIURI.h"
#include "nsContentUtils.h"
#include "nsReadableUtils.h"
#include "nsGkAtoms.h"
#include "nsComponentManagerUtils.h"
#include "nsLayoutStatics.h"
#include "nsBindingManager.h"
#include "nsHashKeys.h"
+#include "nsCCUncollectableMarker.h"
#ifdef MOZ_LOGGING
// so we can get logging even in release builds
#define FORCE_PR_LOG 1
#endif
#include "prlog.h"
#ifdef PR_LOGGING
@@ -156,16 +157,21 @@ nsNodeInfoManager::~nsNodeInfoManager()
}
NS_IMPL_CYCLE_COLLECTION_CLASS(nsNodeInfoManager)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(nsNodeInfoManager, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(nsNodeInfoManager, Release)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NATIVE_0(nsNodeInfoManager)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_BEGIN(nsNodeInfoManager)
+ if (tmp->mDocument &&
+ nsCCUncollectableMarker::InGeneration(cb,
+ tmp->mDocument->GetMarkedCCGeneration())) {
+ return NS_SUCCESS_INTERRUPTED_TRAVERSE;
+ }
if (tmp->mNonDocumentNodeInfos) {
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_RAWPTR(mDocument)
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_RAWPTR(mBindingManager)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
nsresult
nsNodeInfoManager::Init(nsIDocument *aDocument)
--- a/content/base/src/nsXMLHttpRequest.cpp
+++ b/content/base/src/nsXMLHttpRequest.cpp
@@ -445,24 +445,16 @@ nsXMLHttpRequest::~nsXMLHttpRequest()
XML_HTTP_REQUEST_SENT |
XML_HTTP_REQUEST_LOADING)) {
Abort();
}
NS_ABORT_IF_FALSE(!(mState & XML_HTTP_REQUEST_SYNCLOOPING), "we rather crash than hang");
mState &= ~XML_HTTP_REQUEST_SYNCLOOPING;
- // This can happen if the XHR was only used by C++ (and so never created a JS
- // wrapper) that also made an ArrayBuffer.
- if (PreservingWrapper()) {
- nsContentUtils::ReleaseWrapper(
- static_cast<nsIDOMEventTarget*>(
- static_cast<nsDOMEventTargetHelper*>(this)), this);
- }
-
nsLayoutStatics::Release();
}
void
nsXMLHttpRequest::RootResultArrayBuffer()
{
nsContentUtils::PreserveWrapper(
static_cast<nsIDOMEventTarget*>(
--- a/content/html/content/src/nsHTMLTableElement.cpp
+++ b/content/html/content/src/nsHTMLTableElement.cpp
@@ -118,16 +118,17 @@ TableRowsCollection::~TableRowsCollectio
// release it! this is to avoid circular references. The
// instantiator who provided mParent is responsible for managing our
// reference for us.
}
NS_IMPL_CYCLE_COLLECTION_CLASS(TableRowsCollection)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(TableRowsCollection)
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
+ NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOrphanRows)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(TableRowsCollection)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mOrphanRows,
nsIDOMNodeList)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(TableRowsCollection)
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
@@ -339,16 +340,23 @@ nsHTMLTableElement::~nsHTMLTableElement(
if (mRows) {
mRows->ParentDestroyed();
}
ReleaseInheritedAttributes();
}
NS_IMPL_CYCLE_COLLECTION_CLASS(nsHTMLTableElement)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsHTMLTableElement, nsGenericHTMLElement)
+ NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mTBodies)
+ if (tmp->mRows) {
+ tmp->mRows->ParentDestroyed();
+ }
+ NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mRows)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsHTMLTableElement,
nsGenericHTMLElement)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mTBodies,
nsIDOMNodeList)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mRows)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_ADDREF_INHERITED(nsHTMLTableElement, nsGenericElement)
--- a/content/html/content/src/nsHTMLTableElement.h
+++ b/content/html/content/src/nsHTMLTableElement.h
@@ -86,18 +86,18 @@ public:
virtual nsresult BeforeSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
const nsAString* aValue, bool aNotify);
/**
* Called when an attribute has just been changed
*/
virtual nsresult AfterSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
const nsAString* aValue, bool aNotify);
- NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(nsHTMLTableElement,
- nsGenericHTMLElement)
+ NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsHTMLTableElement,
+ nsGenericHTMLElement)
nsMappedAttributes* GetAttributesMappedForCell();
already_AddRefed<nsIDOMHTMLTableSectionElement> GetTHead() {
return GetSection(nsGkAtoms::thead);
}
already_AddRefed<nsIDOMHTMLTableSectionElement> GetTFoot() {
return GetSection(nsGkAtoms::tfoot);
}
already_AddRefed<nsIDOMHTMLTableCaptionElement> GetCaption();
--- a/content/html/document/src/ImageDocument.cpp
+++ b/content/html/document/src/ImageDocument.cpp
@@ -376,16 +376,20 @@ ImageDocument::SetScriptGlobalObject(nsI
target = do_QueryInterface(mImageContent);
target->AddEventListener(NS_LITERAL_STRING("click"), this, false);
}
target = do_QueryInterface(aScriptGlobalObject);
target->AddEventListener(NS_LITERAL_STRING("resize"), this, false);
target->AddEventListener(NS_LITERAL_STRING("keypress"), this, false);
+
+ if (!nsContentUtils::IsChildOfSameType(this)) {
+ LinkStylesheet(NS_LITERAL_STRING("resource://gre/res/TopLevelImageDocument.css"));
+ }
}
}
void
ImageDocument::OnPageShow(bool aPersisted,
nsIDOMEventTarget* aDispatchStartTarget)
{
if (aPersisted) {
@@ -660,18 +664,16 @@ ImageDocument::CreateSyntheticDocument()
kNameSpaceID_XHTML,
nsIDOMNode::ELEMENT_NODE);
NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
nsRefPtr<nsGenericHTMLElement> styleContent = NS_NewHTMLStyleElement(nodeInfo.forget());
NS_ENSURE_TRUE(styleContent, NS_ERROR_OUT_OF_MEMORY);
styleContent->SetTextContent(NS_LITERAL_STRING("img { display: block; }"));
head->AppendChildTo(styleContent, false);
- } else {
- LinkStylesheet(NS_LITERAL_STRING("resource://gre/res/TopLevelImageDocument.css"));
}
// Add the image element
Element* body = GetBodyElement();
if (!body) {
NS_WARNING("no body on image document!");
return NS_ERROR_FAILURE;
}
--- a/content/html/document/src/VideoDocument.cpp
+++ b/content/html/document/src/VideoDocument.cpp
@@ -52,16 +52,17 @@ class VideoDocument : public MediaDocume
public:
virtual nsresult StartDocumentLoad(const char* aCommand,
nsIChannel* aChannel,
nsILoadGroup* aLoadGroup,
nsISupports* aContainer,
nsIStreamListener** aDocListener,
bool aReset = true,
nsIContentSink* aSink = nsnull);
+ virtual void SetScriptGlobalObject(nsIScriptGlobalObject* aScriptGlobalObject);
protected:
// Sets document <title> to reflect the file name and description.
void UpdateTitle(nsIChannel* aChannel);
nsresult CreateSyntheticVideoDocument(nsIChannel* aChannel,
nsIStreamListener** aListener);
@@ -89,16 +90,28 @@ VideoDocument::StartDocumentLoad(const c
rv = CreateSyntheticVideoDocument(aChannel,
getter_AddRefs(mStreamListener->mNextStream));
NS_ENSURE_SUCCESS(rv, rv);
NS_ADDREF(*aDocListener = mStreamListener);
return rv;
}
+void
+VideoDocument::SetScriptGlobalObject(nsIScriptGlobalObject* aScriptGlobalObject)
+{
+ // Set the script global object on the superclass before doing
+ // anything that might require it....
+ MediaDocument::SetScriptGlobalObject(aScriptGlobalObject);
+
+ if (aScriptGlobalObject && !nsContentUtils::IsChildOfSameType(this)) {
+ LinkStylesheet(NS_LITERAL_STRING("resource://gre/res/TopLevelVideoDocument.css"));
+ }
+}
+
nsresult
VideoDocument::CreateSyntheticVideoDocument(nsIChannel* aChannel,
nsIStreamListener** aListener)
{
// make our generic document
nsresult rv = MediaDocument::CreateSyntheticDocument();
NS_ENSURE_SUCCESS(rv, rv);
@@ -126,18 +139,16 @@ VideoDocument::CreateSyntheticVideoDocum
UpdateTitle(aChannel);
if (nsContentUtils::IsChildOfSameType(this)) {
// Video documents that aren't toplevel should fill their frames and
// not have margins
element->SetAttr(kNameSpaceID_None, nsGkAtoms::style,
NS_LITERAL_STRING("position:absolute; top:0; left:0; width:100%; height:100%"),
true);
- } else {
- LinkStylesheet(NS_LITERAL_STRING("resource://gre/res/TopLevelVideoDocument.css"));
}
return body->AppendChildTo(element, false);
}
void
VideoDocument::UpdateTitle(nsIChannel* aChannel)
{