mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge to tip
This commit is contained in:
commit
7ae65dfa00
@ -31,10 +31,20 @@
|
||||
<match name="name" exp="^Yahoo Application State Plugin$"/>
|
||||
<match name="description" exp="^Yahoo Application State Plugin$"/>
|
||||
<match name="filename" exp="npYState.dll"/>
|
||||
<versionRange>
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange minVersion="3.0a1" maxVersion="3.*"/>
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</pluginItem>
|
||||
<pluginItem>
|
||||
<match name="name" exp="QuickTime Plug-in 7[.]1[.]"/>
|
||||
<match name="filename" exp="npqtplugin.?[.]dll"/>
|
||||
<versionRange>
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange minVersion="3.0a1" maxVersion="3.*"/>
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</pluginItem>
|
||||
</pluginItems>
|
||||
</blocklist>
|
||||
|
@ -83,7 +83,7 @@ pref("extensions.blocklist.interval", 86400);
|
||||
// Controls what level the blocklist switches from warning about items to forcibly
|
||||
// blocking them.
|
||||
pref("extensions.blocklist.level", 2);
|
||||
pref("extensions.blocklist.url", "https://addons.mozilla.org/blocklist/2/%APP_ID%/%APP_VERSION%/%PRODUCT%/%BUILD_ID%/%BUILD_TARGET%/%LOCALE%/%CHANNEL%/%OS_VERSION%/%DISTRIBUTION%/%DISTRIBUTION_VERSION%/");
|
||||
pref("extensions.blocklist.url", "https://addons.mozilla.org/blocklist/3/%APP_ID%/%APP_VERSION%/%PRODUCT%/%BUILD_ID%/%BUILD_TARGET%/%LOCALE%/%CHANNEL%/%OS_VERSION%/%DISTRIBUTION%/%DISTRIBUTION_VERSION%/");
|
||||
pref("extensions.blocklist.detailsURL", "http://%LOCALE%.www.mozilla.com/%LOCALE%/blocklist/");
|
||||
|
||||
// Dictionary download preference
|
||||
|
@ -902,15 +902,6 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIContent, NS_ICONTENT_IID)
|
||||
nsContentUtils::TraverseListenerManager(tmp, cb); \
|
||||
}
|
||||
|
||||
#define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_PRESERVED_WRAPPER \
|
||||
{ \
|
||||
nsISupports *preservedWrapper = nsnull; \
|
||||
if (tmp->GetOwnerDoc()) \
|
||||
preservedWrapper = tmp->GetOwnerDoc()->GetReference(tmp); \
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "[preserved wrapper]");\
|
||||
cb.NoteXPCOMChild(preservedWrapper); \
|
||||
}
|
||||
|
||||
#define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_USERDATA \
|
||||
if (tmp->HasProperties()) { \
|
||||
nsNodeUtils::TraverseUserData(tmp, cb); \
|
||||
@ -922,10 +913,6 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIContent, NS_ICONTENT_IID)
|
||||
tmp->UnsetFlags(NODE_HAS_LISTENERMANAGER); \
|
||||
}
|
||||
|
||||
#define NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER \
|
||||
if (tmp->GetOwnerDoc()) \
|
||||
tmp->GetOwnerDoc()->RemoveReference(tmp);
|
||||
|
||||
#define NS_IMPL_CYCLE_COLLECTION_UNLINK_USERDATA \
|
||||
if (tmp->HasProperties()) { \
|
||||
nsNodeUtils::UnlinkUserData(tmp); \
|
||||
|
@ -96,8 +96,8 @@ class nsFrameLoader;
|
||||
|
||||
// IID for the nsIDocument interface
|
||||
#define NS_IDOCUMENT_IID \
|
||||
{ 0x6304ae8e, 0x2634, 0x45ed, \
|
||||
{ 0x9e, 0x09, 0x83, 0x09, 0x5b, 0x46, 0x72, 0x8b } }
|
||||
{ 0x92b19d1c, 0x8f37, 0x4d4b, \
|
||||
{ 0xa3, 0x42, 0xb5, 0xc6, 0x8b, 0x54, 0xde, 0x6c } }
|
||||
|
||||
// Flag for AddStyleSheet().
|
||||
#define NS_STYLESHEET_FROM_CATALOG (1 << 0)
|
||||
@ -677,10 +677,6 @@ public:
|
||||
virtual void ResetToURI(nsIURI *aURI, nsILoadGroup* aLoadGroup,
|
||||
nsIPrincipal* aPrincipal) = 0;
|
||||
|
||||
virtual void AddReference(void *aKey, nsISupports *aReference) = 0;
|
||||
virtual nsISupports *GetReference(void *aKey) = 0;
|
||||
virtual void RemoveReference(void *aKey) = 0;
|
||||
|
||||
/**
|
||||
* Set the container (docshell) for this document.
|
||||
*/
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include "nsTObserverArray.h"
|
||||
#include "nsINodeInfo.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsWrapperCache.h"
|
||||
|
||||
class nsIContent;
|
||||
class nsIDocument;
|
||||
@ -150,16 +151,17 @@ inline nsINode* NODE_FROM(C& aContent, D& aDocument)
|
||||
|
||||
// IID for the nsINode interface
|
||||
#define NS_INODE_IID \
|
||||
{ 0x2593b0d5, 0x9a06, 0x4d6b, \
|
||||
{ 0x9a, 0x10, 0xb1, 0x39, 0x9f, 0x1b, 0xa0, 0x8e } }
|
||||
|
||||
{ 0x0f7b2557, 0xa09d, 0x468f, \
|
||||
{ 0x93, 0x92, 0xf1, 0xf1, 0xd1, 0xfa, 0x31, 0x78 } }
|
||||
|
||||
/**
|
||||
* An internal interface that abstracts some DOMNode-related parts that both
|
||||
* nsIContent and nsIDocument share. An instance of this interface has a list
|
||||
* of nsIContent children and provides access to them.
|
||||
*/
|
||||
class nsINode : public nsPIDOMEventTarget {
|
||||
class nsINode : public nsPIDOMEventTarget,
|
||||
public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_INODE_IID)
|
||||
|
||||
@ -850,4 +852,12 @@ extern const nsIID kThisPtrOffsetsSID;
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsINode, NS_INODE_IID)
|
||||
|
||||
|
||||
#define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_PRESERVED_WRAPPER \
|
||||
tmp->TraverseWrapper(cb);
|
||||
|
||||
#define NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER \
|
||||
tmp->ClearWrapper();
|
||||
|
||||
|
||||
#endif /* nsINode_h___ */
|
||||
|
@ -358,6 +358,7 @@ nsContentList::~nsContentList()
|
||||
|
||||
// QueryInterface implementation for nsContentList
|
||||
NS_INTERFACE_TABLE_HEAD(nsContentList)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_NODELIST_OFFSET_AND_INTERFACE_TABLE_BEGIN(nsContentList)
|
||||
NS_CONTENT_LIST_INTERFACES(nsContentList)
|
||||
NS_INTERFACE_TABLE_ENTRY(nsContentList, nsIHTMLCollection)
|
||||
|
@ -54,6 +54,7 @@
|
||||
#include "nsIAtom.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsWrapperCache.h"
|
||||
|
||||
// Magic namespace id that means "match all namespaces". This is
|
||||
// negative so it won't collide with actual namespace constants.
|
||||
@ -182,7 +183,8 @@ protected:
|
||||
class nsContentList : public nsBaseContentList,
|
||||
protected nsContentListKey,
|
||||
public nsIHTMLCollection,
|
||||
public nsStubMutationObserver
|
||||
public nsStubMutationObserver,
|
||||
public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
@ -101,6 +101,8 @@
|
||||
#include "nsIDocumentLoader.h"
|
||||
#include "nsICachingChannel.h"
|
||||
#include "nsICacheEntryDescriptor.h"
|
||||
#include "nsGenericHTMLElement.h"
|
||||
#include "nsHTMLDNSPrefetch.h"
|
||||
|
||||
PRLogModuleInfo* gContentSinkLogModuleInfo;
|
||||
|
||||
@ -721,6 +723,10 @@ nsContentSink::ProcessLink(nsIContent* aElement,
|
||||
PrefetchHref(aHref, aElement, hasPrefetch);
|
||||
}
|
||||
|
||||
if ((!aHref.IsEmpty()) && linkTypes.IndexOf(NS_LITERAL_STRING("dns-prefetch")) != -1) {
|
||||
PrefetchDNS(aHref);
|
||||
}
|
||||
|
||||
// is it a stylesheet link?
|
||||
if (linkTypes.IndexOf(NS_LITERAL_STRING("stylesheet")) == -1) {
|
||||
return NS_OK;
|
||||
@ -852,6 +858,23 @@ nsContentSink::PrefetchHref(const nsAString &aHref,
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsContentSink::PrefetchDNS(const nsAString &aHref)
|
||||
{
|
||||
nsAutoString hostname;
|
||||
|
||||
if (StringBeginsWith(aHref, NS_LITERAL_STRING("//"))) {
|
||||
hostname = Substring(aHref, 2);
|
||||
}
|
||||
else
|
||||
nsGenericHTMLElement::GetHostnameFromHrefString(aHref, hostname);
|
||||
|
||||
nsRefPtr<nsHTMLDNSPrefetch> prefetch = new nsHTMLDNSPrefetch(hostname, mDocument);
|
||||
if (prefetch) {
|
||||
prefetch->PrefetchLow();
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsContentSink::GetChannelCacheKey(nsIChannel* aChannel, nsACString& aCacheKey)
|
||||
{
|
||||
|
@ -192,6 +192,10 @@ protected:
|
||||
void PrefetchHref(const nsAString &aHref, nsIContent *aSource,
|
||||
PRBool aExplicit);
|
||||
|
||||
// aHref can either be the usual URI format or of the form "//www.hostname.com"
|
||||
// without a scheme.
|
||||
void PrefetchDNS(const nsAString &aHref);
|
||||
|
||||
// Gets the cache key (used to identify items in a cache) of the channel.
|
||||
nsresult GetChannelCacheKey(nsIChannel* aChannel, nsACString& aCacheKey);
|
||||
|
||||
|
@ -1119,15 +1119,6 @@ nsContentUtils::doReparentContentWrapper(nsIContent *aNode,
|
||||
getter_AddRefs(old_wrapper));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (aOldDocument) {
|
||||
nsCOMPtr<nsISupports> old_ref = aOldDocument->GetReference(aNode);
|
||||
if (old_ref) {
|
||||
// Transfer the reference from aOldDocument to aNewDocument
|
||||
aOldDocument->RemoveReference(aNode);
|
||||
aNewDocument->AddReference(aNode, old_ref);
|
||||
}
|
||||
}
|
||||
|
||||
// Whether or not aChild is already wrapped we must iterate through
|
||||
// its descendants since there's no guarantee that a descendant isn't
|
||||
// wrapped even if this child is not wrapped. That used to be true
|
||||
|
@ -101,6 +101,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDOMAttribute)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
// QueryInterface implementation for nsDOMAttribute
|
||||
NS_INTERFACE_TABLE_HEAD(nsDOMAttribute)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_NODE_INTERFACE_TABLE7(nsDOMAttribute, nsIDOMAttr, nsIAttribute, nsINode,
|
||||
nsIDOMNode, nsIDOM3Node, nsIDOM3Attr,
|
||||
nsPIDOMEventTarget)
|
||||
|
@ -1567,13 +1567,12 @@ nsDocument::~nsDocument()
|
||||
mBoxObjectTable->EnumerateRead(ClearAllBoxObjects, nsnull);
|
||||
delete mBoxObjectTable;
|
||||
}
|
||||
|
||||
delete mContentWrapperHash;
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsDocument)
|
||||
|
||||
NS_INTERFACE_TABLE_HEAD(nsDocument)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_DOCUMENT_INTERFACE_TABLE_BEGIN(nsDocument)
|
||||
NS_INTERFACE_TABLE_ENTRY(nsDocument, nsINode)
|
||||
NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIDocument)
|
||||
@ -1753,9 +1752,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDocument)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mCatalogSheets)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mVisitednessChangedURIs)
|
||||
|
||||
// Traverse any associated preserved wrapper.
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "[preserved wrapper]");
|
||||
cb.NoteXPCOMChild(tmp->GetReference(tmp));
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_PRESERVED_WRAPPER
|
||||
|
||||
if (tmp->mSubDocuments && tmp->mSubDocuments->ops) {
|
||||
PL_DHashTableEnumerate(tmp->mSubDocuments, SubDocTraverser, &cb);
|
||||
@ -1786,12 +1783,10 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDocument)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_USERDATA
|
||||
|
||||
// Drop the content hash.
|
||||
delete tmp->mContentWrapperHash;
|
||||
tmp->mContentWrapperHash = nsnull;
|
||||
|
||||
tmp->mParentDocument = nsnull;
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
|
||||
|
||||
// nsDocument has a pretty complex destructor, so we're going to
|
||||
// assume that *most* cycles you actually want to break somewhere
|
||||
// else, and not unlink an awful lot here.
|
||||
@ -6228,41 +6223,6 @@ nsDocument::FlushPendingNotifications(mozFlushType aType)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsDocument::AddReference(void *aKey, nsISupports *aReference)
|
||||
{
|
||||
if (mScriptGlobalObject) {
|
||||
if (!mContentWrapperHash) {
|
||||
mContentWrapperHash = new nsInterfaceHashtable<nsVoidPtrHashKey, nsISupports>;
|
||||
if (mContentWrapperHash) {
|
||||
mContentWrapperHash->Init(10);
|
||||
}
|
||||
}
|
||||
|
||||
if (mContentWrapperHash)
|
||||
mContentWrapperHash->Put(aKey, aReference);
|
||||
}
|
||||
}
|
||||
|
||||
nsISupports*
|
||||
nsDocument::GetReference(void *aKey)
|
||||
{
|
||||
// NB: This method is part of content cycle collection,
|
||||
// and must *not* Addref its return value.
|
||||
|
||||
if (mContentWrapperHash)
|
||||
return mContentWrapperHash->GetWeak(aKey);
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
void
|
||||
nsDocument::RemoveReference(void *aKey)
|
||||
{
|
||||
if (mContentWrapperHash) {
|
||||
mContentWrapperHash->Remove(aKey);
|
||||
}
|
||||
}
|
||||
|
||||
nsIScriptEventManager*
|
||||
nsDocument::GetScriptEventManager()
|
||||
{
|
||||
@ -6561,6 +6521,7 @@ nsDocument::RetrieveRelevantHeaders(nsIChannel *aChannel)
|
||||
"content-language",
|
||||
"content-disposition",
|
||||
"refresh",
|
||||
"x-dns-prefetch-control",
|
||||
// add more http headers if you need
|
||||
// XXXbz don't add content-location support without reading bug
|
||||
// 238654 and its dependencies/dups first.
|
||||
@ -6873,13 +6834,6 @@ nsDocument::Destroy()
|
||||
// leak-fixing if we fix DocumentViewerImpl to do cycle-collection, but
|
||||
// tearing down all those frame trees right now is the right thing to do.
|
||||
mExternalResourceMap.Shutdown();
|
||||
|
||||
// XXX We really should let cycle collection do this, but that currently still
|
||||
// leaks (see https://bugzilla.mozilla.org/show_bug.cgi?id=406684).
|
||||
// When we start relying on cycle collection again we should remove the
|
||||
// check for mScriptGlobalObject in AddReference.
|
||||
delete mContentWrapperHash;
|
||||
mContentWrapperHash = nsnull;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -750,9 +750,6 @@ public:
|
||||
nsIStyleRule* aStyleRule);
|
||||
|
||||
virtual void FlushPendingNotifications(mozFlushType aType);
|
||||
virtual void AddReference(void *aKey, nsISupports *aReference);
|
||||
virtual nsISupports *GetReference(void *aKey);
|
||||
virtual void RemoveReference(void *aKey);
|
||||
virtual nsIScriptEventManager* GetScriptEventManager();
|
||||
virtual void SetXMLDeclaration(const PRUnichar *aVersion,
|
||||
const PRUnichar *aEncoding,
|
||||
@ -1158,7 +1155,6 @@ protected:
|
||||
PRUint8 mIdMissCount;
|
||||
|
||||
nsInterfaceHashtable<nsVoidPtrHashKey, nsPIBoxObject> *mBoxObjectTable;
|
||||
nsInterfaceHashtable<nsVoidPtrHashKey, nsISupports> *mContentWrapperHash;
|
||||
|
||||
// The channel that got passed to StartDocumentLoad(), if any
|
||||
nsCOMPtr<nsIChannel> mChannel;
|
||||
|
@ -105,7 +105,9 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGenericDOMDataNode)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsGenericDOMDataNode)
|
||||
NS_INTERFACE_MAP_BEGIN(nsGenericDOMDataNode)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(nsGenericDOMDataNode)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIContent)
|
||||
NS_INTERFACE_MAP_ENTRY(nsINode)
|
||||
NS_INTERFACE_MAP_ENTRY(nsPIDOMEventTarget)
|
||||
|
@ -462,6 +462,7 @@ NS_IMPL_ADDREF(nsChildContentList)
|
||||
NS_IMPL_RELEASE(nsChildContentList)
|
||||
|
||||
NS_INTERFACE_TABLE_HEAD(nsChildContentList)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_NODELIST_OFFSET_AND_INTERFACE_TABLE_BEGIN(nsChildContentList)
|
||||
NS_INTERFACE_TABLE_ENTRY(nsChildContentList, nsINodeList)
|
||||
NS_INTERFACE_TABLE_ENTRY(nsChildContentList, nsIDOMNodeList)
|
||||
@ -1102,7 +1103,7 @@ nsNSElementTearoff::SetScrollTop(PRInt32 aScrollTop)
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = view->ScrollTo(xPos, nsPresContext::CSSPixelsToAppUnits(aScrollTop),
|
||||
NS_VMREFRESH_IMMEDIATE);
|
||||
0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1144,7 +1145,7 @@ nsNSElementTearoff::SetScrollLeft(PRInt32 aScrollLeft)
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = view->ScrollTo(nsPresContext::CSSPixelsToAppUnits(aScrollLeft),
|
||||
yPos, NS_VMREFRESH_IMMEDIATE);
|
||||
yPos, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4066,7 +4067,9 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsGenericElement)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsGenericElement)
|
||||
NS_INTERFACE_MAP_BEGIN(nsGenericElement)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(nsGenericElement)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIContent)
|
||||
NS_INTERFACE_MAP_ENTRY(nsINode)
|
||||
NS_INTERFACE_MAP_ENTRY(nsPIDOMEventTarget)
|
||||
|
@ -89,7 +89,8 @@ typedef unsigned long PtrBits;
|
||||
* and Item to its existing child list.
|
||||
* @see nsIDOMNodeList
|
||||
*/
|
||||
class nsChildContentList : public nsINodeList
|
||||
class nsChildContentList : public nsINodeList,
|
||||
public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
nsChildContentList(nsINode* aNode)
|
||||
@ -110,6 +111,27 @@ public:
|
||||
mNode = nsnull;
|
||||
}
|
||||
|
||||
nsISupports* GetParentObject()
|
||||
{
|
||||
return mNode;
|
||||
}
|
||||
|
||||
static nsChildContentList* FromSupports(nsISupports* aSupports)
|
||||
{
|
||||
nsINodeList* list = static_cast<nsINodeList*>(aSupports);
|
||||
#ifdef DEBUG
|
||||
{
|
||||
nsCOMPtr<nsINodeList> list_qi = do_QueryInterface(aSupports);
|
||||
|
||||
// If this assertion fires the QI implementation for the object in
|
||||
// question doesn't use the nsINodeList pointer as the nsISupports
|
||||
// pointer. That must be fixed, or we'll crash...
|
||||
NS_ASSERTION(list_qi == list, "Uh, fix QI!");
|
||||
}
|
||||
#endif
|
||||
return static_cast<nsChildContentList*>(list);
|
||||
}
|
||||
|
||||
private:
|
||||
// The node whose children make up the list (weak reference)
|
||||
nsINode* mNode;
|
||||
|
@ -987,6 +987,7 @@ GK_ATOM(headerWindowTarget, "window-target")
|
||||
GK_ATOM(withParam, "with-param")
|
||||
GK_ATOM(wizard, "wizard")
|
||||
GK_ATOM(wrap, "wrap")
|
||||
GK_ATOM(headerDNSPrefetchControl,"x-dns-prefetch-control")
|
||||
GK_ATOM(xml, "xml")
|
||||
GK_ATOM(xmlns, "xmlns")
|
||||
GK_ATOM(xmp, "xmp")
|
||||
|
@ -564,26 +564,15 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, PRBool aClone, PRBool aDeep,
|
||||
}
|
||||
}
|
||||
else if (nodeInfoManager) {
|
||||
nsCOMPtr<nsISupports> oldRef;
|
||||
nsIDocument* oldDoc = aNode->GetOwnerDoc();
|
||||
if (oldDoc) {
|
||||
if (aNode->IsNodeOfType(nsINode::eELEMENT)) {
|
||||
oldDoc->ClearBoxObjectFor(static_cast<nsIContent*>(aNode));
|
||||
}
|
||||
oldRef = oldDoc->GetReference(aNode);
|
||||
if (oldRef) {
|
||||
oldDoc->RemoveReference(aNode);
|
||||
}
|
||||
if (oldDoc && aNode->IsNodeOfType(nsINode::eELEMENT)) {
|
||||
oldDoc->ClearBoxObjectFor(static_cast<nsIContent*>(aNode));
|
||||
}
|
||||
|
||||
aNode->mNodeInfo.swap(newNodeInfo);
|
||||
|
||||
nsIDocument* newDoc = aNode->GetOwnerDoc();
|
||||
if (newDoc) {
|
||||
if (oldRef) {
|
||||
newDoc->AddReference(aNode, oldRef);
|
||||
}
|
||||
|
||||
nsPIDOMWindow* window = newDoc->GetInnerWindow();
|
||||
if (window) {
|
||||
nsCOMPtr<nsIEventListenerManager> elm;
|
||||
|
@ -530,13 +530,7 @@ GetDocumentFromScriptContext(nsIScriptContext *aScriptContext)
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsXHREventTarget)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXHREventTarget)
|
||||
if (tmp->mOwner) {
|
||||
nsCOMPtr<nsIDocument> doc =
|
||||
do_QueryInterface(tmp->mOwner->GetExtantDocument());
|
||||
if (doc) {
|
||||
cb.NoteXPCOMChild(doc->GetReference(tmp));
|
||||
}
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_PRESERVED_WRAPPER
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnLoadListener)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnErrorListener)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnAbortListener)
|
||||
@ -548,13 +542,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXHREventTarget)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXHREventTarget)
|
||||
if (tmp->mOwner) {
|
||||
nsCOMPtr<nsIDocument> doc =
|
||||
do_QueryInterface(tmp->mOwner->GetExtantDocument());
|
||||
if (doc) {
|
||||
doc->RemoveReference(tmp);
|
||||
}
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnLoadListener)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnErrorListener)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnAbortListener)
|
||||
@ -565,7 +553,9 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXHREventTarget)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOwner)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsXHREventTarget)
|
||||
NS_INTERFACE_MAP_BEGIN(nsXHREventTarget)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(nsXHREventTarget)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXMLHttpRequestEventTarget)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIXMLHttpRequestEventTarget)
|
||||
NS_INTERFACE_MAP_ENTRY(nsPIDOMEventTarget)
|
||||
|
@ -73,6 +73,7 @@
|
||||
#include "nsITimer.h"
|
||||
#include "nsIPrivateDOMEvent.h"
|
||||
#include "nsDOMProgressEvent.h"
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
|
||||
class nsILoadGroup;
|
||||
|
||||
@ -159,7 +160,8 @@ protected:
|
||||
|
||||
class nsXHREventTarget : public nsIXMLHttpRequestEventTarget,
|
||||
public nsPIDOMEventTarget,
|
||||
public nsIDOMNSEventTarget
|
||||
public nsIDOMNSEventTarget,
|
||||
public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
nsXHREventTarget() : mLang(nsIProgrammingLanguage::JAVASCRIPT) {}
|
||||
@ -207,6 +209,36 @@ public:
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void GetParentObject(nsIScriptGlobalObject **aParentObject)
|
||||
{
|
||||
if (mOwner) {
|
||||
CallQueryInterface(mOwner, aParentObject);
|
||||
}
|
||||
else {
|
||||
*aParentObject = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
static nsXHREventTarget* FromSupports(nsISupports* aSupports)
|
||||
{
|
||||
nsIXMLHttpRequestEventTarget* target =
|
||||
static_cast<nsIXMLHttpRequestEventTarget*>(aSupports);
|
||||
#ifdef DEBUG
|
||||
{
|
||||
nsCOMPtr<nsIXMLHttpRequestEventTarget> target_qi =
|
||||
do_QueryInterface(aSupports);
|
||||
|
||||
// If this assertion fires the QI implementation for the object in
|
||||
// question doesn't use the nsIXMLHttpRequestEventTarget pointer as the
|
||||
// nsISupports pointer. That must be fixed, or we'll crash...
|
||||
NS_ASSERTION(target_qi == target, "Uh, fix QI!");
|
||||
}
|
||||
#endif
|
||||
|
||||
return static_cast<nsXHREventTarget*>(target);
|
||||
}
|
||||
|
||||
protected:
|
||||
nsRefPtr<nsDOMEventListenerWrapper> mOnLoadListener;
|
||||
nsRefPtr<nsDOMEventListenerWrapper> mOnErrorListener;
|
||||
|
@ -83,6 +83,7 @@ EXPORTS = \
|
||||
|
||||
CPPSRCS = \
|
||||
nsClientRect.cpp \
|
||||
nsHTMLDNSPrefetch.cpp \
|
||||
nsGenericHTMLElement.cpp \
|
||||
nsFormSubmission.cpp \
|
||||
nsImageMapUtils.cpp \
|
||||
|
@ -64,6 +64,8 @@
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsIDocument.h"
|
||||
|
||||
#include "nsHTMLDNSPrefetch.h"
|
||||
|
||||
nsresult NS_NewContentIterator(nsIContentIterator** aInstancePtrResult);
|
||||
|
||||
class nsHTMLAnchorElement : public nsGenericHTMLElement,
|
||||
@ -135,11 +137,26 @@ public:
|
||||
protected:
|
||||
// The cached visited state
|
||||
nsLinkState mLinkState;
|
||||
|
||||
void PrefetchDNS();
|
||||
};
|
||||
|
||||
|
||||
NS_IMPL_NS_NEW_HTML_ELEMENT(Anchor)
|
||||
|
||||
void
|
||||
nsHTMLAnchorElement::PrefetchDNS()
|
||||
{
|
||||
nsCOMPtr<nsIURI> hrefURI;
|
||||
GetHrefURI(getter_AddRefs(hrefURI));
|
||||
|
||||
if (hrefURI) {
|
||||
nsRefPtr<nsHTMLDNSPrefetch> prefetch =
|
||||
new nsHTMLDNSPrefetch(hrefURI, GetOwnerDoc());
|
||||
if (prefetch)
|
||||
prefetch->PrefetchLow();
|
||||
}
|
||||
}
|
||||
|
||||
nsHTMLAnchorElement::nsHTMLAnchorElement(nsINodeInfo *aNodeInfo)
|
||||
: nsGenericHTMLElement(aNodeInfo),
|
||||
@ -212,6 +229,7 @@ nsHTMLAnchorElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
RegUnRegAccessKey(PR_TRUE);
|
||||
}
|
||||
|
||||
PrefetchDNS();
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -2950,6 +2950,13 @@ HTMLContentSink::ProcessLINKTag(const nsIParserNode& aNode)
|
||||
PrefetchHref(hrefVal, element, hasPrefetch);
|
||||
}
|
||||
}
|
||||
if (linkTypes.IndexOf(NS_LITERAL_STRING("dns-prefetch")) != -1) {
|
||||
nsAutoString hrefVal;
|
||||
element->GetAttr(kNameSpaceID_None, nsGkAtoms::href, hrefVal);
|
||||
if (!hrefVal.IsEmpty()) {
|
||||
PrefetchDNS(hrefVal);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -490,7 +490,7 @@ nsImageDocument::ScrollImageTo(PRInt32 aX, PRInt32 aY, PRBool restoreImage)
|
||||
nsRect portRect = view->View()->GetBounds();
|
||||
view->ScrollTo(nsPresContext::CSSPixelsToAppUnits(aX/ratio) - portRect.width/2,
|
||||
nsPresContext::CSSPixelsToAppUnits(aY/ratio) - portRect.height/2,
|
||||
NS_VMREFRESH_IMMEDIATE);
|
||||
0);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -56,35 +56,14 @@
|
||||
//----------------------------------------------------------------------
|
||||
// nsISupports methods:
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMathMLElement::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
||||
{
|
||||
NS_PRECONDITION(aInstancePtr, "null out param");
|
||||
|
||||
nsresult rv = nsMathMLElementBase::QueryInterface(aIID, aInstancePtr);
|
||||
|
||||
if (NS_SUCCEEDED(rv))
|
||||
return rv;
|
||||
|
||||
nsISupports *inst = nsnull;
|
||||
|
||||
if (aIID.Equals(NS_GET_IID(nsIDOMNode))) {
|
||||
inst = static_cast<nsIDOMNode *>(this);
|
||||
} else if (aIID.Equals(NS_GET_IID(nsIDOMElement))) {
|
||||
inst = static_cast<nsIDOMElement *>(this);
|
||||
} else if (aIID.Equals(NS_GET_IID(nsIClassInfo))) {
|
||||
inst = NS_GetDOMClassInfoInstance(eDOMClassInfo_Element_id);
|
||||
NS_ENSURE_TRUE(inst, NS_ERROR_OUT_OF_MEMORY);
|
||||
} else {
|
||||
return PostQueryInterface(aIID, aInstancePtr);
|
||||
}
|
||||
|
||||
NS_ADDREF(inst);
|
||||
|
||||
*aInstancePtr = inst;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
NS_INTERFACE_TABLE_HEAD(nsMathMLElement)
|
||||
NS_NODE_OFFSET_AND_INTERFACE_TABLE_BEGIN(nsMathMLElement)
|
||||
NS_INTERFACE_TABLE_ENTRY(nsMathMLElement, nsIDOMNode)
|
||||
NS_INTERFACE_TABLE_ENTRY(nsMathMLElement, nsIDOMElement)
|
||||
NS_OFFSET_AND_INTERFACE_TABLE_END
|
||||
NS_ELEMENT_INTERFACE_TABLE_TO_MAP_SEGUE
|
||||
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(MathMLElement)
|
||||
NS_ELEMENT_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(nsMathMLElement, nsMathMLElementBase)
|
||||
NS_IMPL_RELEASE_INHERITED(nsMathMLElement, nsMathMLElementBase)
|
||||
|
@ -151,13 +151,7 @@ nsXBLProtoImpl::InitTargetObjects(nsXBLPrototypeBinding* aBinding,
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
// Root ourselves in the document.
|
||||
nsIDocument* doc = aBoundElement->GetOwnerDoc();
|
||||
if (doc) {
|
||||
nsCOMPtr<nsIXPConnectWrappedNative> nativeWrapper(do_QueryInterface(wrapper));
|
||||
if (nativeWrapper)
|
||||
doc->AddReference(aBoundElement, nativeWrapper);
|
||||
}
|
||||
aBoundElement->PreserveWrapper();
|
||||
|
||||
wrapper.swap(*aScriptObjectHolder);
|
||||
|
||||
|
@ -657,6 +657,18 @@ nsXMLContentSink::CloseElement(nsIContent* aContent)
|
||||
mScriptLoader->AddExecuteBlocker();
|
||||
}
|
||||
}
|
||||
// Look for <link rel="dns-prefetch" href="hostname">
|
||||
if (nodeInfo->Equals(nsGkAtoms::link, kNameSpaceID_XHTML)) {
|
||||
nsAutoString relVal;
|
||||
aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::rel, relVal);
|
||||
if (relVal.EqualsLiteral("dns-prefetch")) {
|
||||
nsAutoString hrefVal;
|
||||
aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::href, hrefVal);
|
||||
if (!hrefVal.IsEmpty()) {
|
||||
PrefetchDNS(hrefVal);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
@ -4183,7 +4183,7 @@ nsDocShell::SetCurScrollPos(PRInt32 scrollOrientation, PRInt32 curPos)
|
||||
y = 0; // fix compiler warning, not actually executed
|
||||
}
|
||||
|
||||
NS_ENSURE_SUCCESS(scrollView->ScrollTo(x, y, NS_VMREFRESH_IMMEDIATE),
|
||||
NS_ENSURE_SUCCESS(scrollView->ScrollTo(x, y, 0),
|
||||
NS_ERROR_FAILURE);
|
||||
return NS_OK;
|
||||
}
|
||||
@ -4198,8 +4198,7 @@ nsDocShell::SetCurScrollPosEx(PRInt32 curHorizontalPos, PRInt32 curVerticalPos)
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_ENSURE_SUCCESS(scrollView->ScrollTo(curHorizontalPos, curVerticalPos,
|
||||
NS_VMREFRESH_IMMEDIATE),
|
||||
NS_ENSURE_SUCCESS(scrollView->ScrollTo(curHorizontalPos, curVerticalPos, 0),
|
||||
NS_ERROR_FAILURE);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -71,6 +71,7 @@ EXPORTS=nsIScriptContext.h \
|
||||
nsDOMString.h \
|
||||
nsDOMJSUtils.h \
|
||||
nsDOMScriptObjectHolder.h \
|
||||
nsWrapperCache.h \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
@ -454,6 +454,10 @@ enum nsDOMClassInfoID {
|
||||
|
||||
eDOMClassInfo_SimpleGestureEvent_id,
|
||||
|
||||
#ifdef MOZ_MATHML
|
||||
eDOMClassInfo_MathMLElement_id,
|
||||
#endif
|
||||
|
||||
// This one better be the last one in this list
|
||||
eDOMClassInfoIDCount
|
||||
};
|
||||
|
137
dom/public/nsWrapperCache.h
Normal file
137
dom/public/nsWrapperCache.h
Normal file
@ -0,0 +1,137 @@
|
||||
/* ***** 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 Gecko DOM code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Peter Van der Beken <peterv@propagandism.org>
|
||||
*
|
||||
* 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 nsWrapperCache_h___
|
||||
#define nsWrapperCache_h___
|
||||
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
|
||||
typedef unsigned long PtrBits;
|
||||
|
||||
#define NS_WRAPPERCACHE_IID \
|
||||
{ 0x3a51ca81, 0xddab, 0x422c, \
|
||||
{ 0x95, 0x3a, 0x13, 0x06, 0x28, 0x0e, 0xee, 0x14 } }
|
||||
|
||||
/**
|
||||
* Class to store the XPCWrappedNative for an object. This can only be used
|
||||
* with objects that only have one XPCWrappedNative at a time (usually ensured
|
||||
* by setting an explicit parent in the PreCreate hook for the class). This
|
||||
* object can be gotten by calling QueryInterface, note that this breaks XPCOM
|
||||
* rules a bit (this object doesn't derive from nsISupports).
|
||||
*/
|
||||
class nsWrapperCache
|
||||
{
|
||||
public:
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_WRAPPERCACHE_IID)
|
||||
|
||||
nsWrapperCache() : mWrapperPtrBits(0)
|
||||
{
|
||||
}
|
||||
~nsWrapperCache()
|
||||
{
|
||||
if (PreservingWrapper()) {
|
||||
GetWrapper()->Release();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns an nsIXPConnectWrappedNative, but we want to avoid
|
||||
* including nsIXPConnect, because we don't want to make everyone require
|
||||
* JS and XPConnect.
|
||||
*/
|
||||
nsISupports* GetWrapper()
|
||||
{
|
||||
return reinterpret_cast<nsISupports*>(mWrapperPtrBits & ~kWrapperBitMask);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method takes an nsIXPConnectWrappedNative, but we want to avoid
|
||||
* including nsIXPConnect, because we don't want to make everyone require
|
||||
* JS and XPConnect.
|
||||
*/
|
||||
void SetWrapper(nsISupports* aWrapper)
|
||||
{
|
||||
NS_ASSERTION(!mWrapperPtrBits, "Already have a wrapper!");
|
||||
mWrapperPtrBits = reinterpret_cast<PtrBits>(aWrapper);
|
||||
}
|
||||
|
||||
void ClearWrapper()
|
||||
{
|
||||
if (PreservingWrapper()) {
|
||||
GetWrapper()->Release();
|
||||
}
|
||||
mWrapperPtrBits = 0;
|
||||
}
|
||||
|
||||
void PreserveWrapper()
|
||||
{
|
||||
NS_ASSERTION(mWrapperPtrBits, "No wrapper to preserve?");
|
||||
if (!PreservingWrapper()) {
|
||||
NS_ADDREF(reinterpret_cast<nsISupports*>(mWrapperPtrBits));
|
||||
mWrapperPtrBits |= WRAPPER_BIT_PRESERVED;
|
||||
}
|
||||
}
|
||||
|
||||
void TraverseWrapper(nsCycleCollectionTraversalCallback &cb)
|
||||
{
|
||||
if (PreservingWrapper()) {
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mWrapper");
|
||||
cb.NoteXPCOMChild(GetWrapper());
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
PRBool PreservingWrapper()
|
||||
{
|
||||
return mWrapperPtrBits & WRAPPER_BIT_PRESERVED;
|
||||
}
|
||||
|
||||
enum { WRAPPER_BIT_PRESERVED = 1 << 0 };
|
||||
enum { kWrapperBitMask = 0x1 };
|
||||
|
||||
PtrBits mWrapperPtrBits;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsWrapperCache, NS_WRAPPERCACHE_IID)
|
||||
|
||||
#define NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY \
|
||||
if ( aIID.Equals(NS_GET_IID(nsWrapperCache)) ) { \
|
||||
*aInstancePtr = static_cast<nsWrapperCache*>(this); \
|
||||
return NS_OK; \
|
||||
}
|
||||
|
||||
#endif /* nsWrapperCache_h___ */
|
@ -171,6 +171,7 @@
|
||||
|
||||
// ContentList includes
|
||||
#include "nsContentList.h"
|
||||
#include "nsGenericElement.h"
|
||||
|
||||
// Event related includes
|
||||
#include "nsIEventListenerManager.h"
|
||||
@ -212,7 +213,7 @@
|
||||
#include "nsIDOMLSProgressEvent.h"
|
||||
#include "nsIDOMParser.h"
|
||||
#include "nsIDOMSerializer.h"
|
||||
#include "nsIXMLHttpRequest.h"
|
||||
#include "nsXMLHttpRequest.h"
|
||||
|
||||
// includes needed for the prototype chain interfaces
|
||||
#include "nsIDOMNavigator.h"
|
||||
@ -489,7 +490,8 @@ static const char kDOMStringBundleURL[] =
|
||||
((DOM_DEFAULT_SCRIPTABLE_FLAGS | \
|
||||
nsIXPCScriptable::WANT_GETPROPERTY | \
|
||||
nsIXPCScriptable::WANT_ADDPROPERTY | \
|
||||
nsIXPCScriptable::WANT_SETPROPERTY) & \
|
||||
nsIXPCScriptable::WANT_SETPROPERTY | \
|
||||
nsIXPCScriptable::WANT_FINALIZE) & \
|
||||
~nsIXPCScriptable::USE_JSSTUB_FOR_ADDPROPERTY)
|
||||
|
||||
// We need to let JavaScript QI elements to interfaces that are not in
|
||||
@ -513,15 +515,22 @@ static const char kDOMStringBundleURL[] =
|
||||
nsIXPCScriptable::WANT_ADDPROPERTY | \
|
||||
nsIXPCScriptable::WANT_DELPROPERTY | \
|
||||
nsIXPCScriptable::WANT_GETPROPERTY | \
|
||||
nsIXPCScriptable::WANT_ENUMERATE | \
|
||||
nsIXPCScriptable::WANT_POSTCREATE | \
|
||||
nsIXPCScriptable::WANT_FINALIZE)
|
||||
nsIXPCScriptable::WANT_ENUMERATE)
|
||||
|
||||
#define ARRAY_SCRIPTABLE_FLAGS \
|
||||
(DOM_DEFAULT_SCRIPTABLE_FLAGS | \
|
||||
nsIXPCScriptable::WANT_GETPROPERTY | \
|
||||
nsIXPCScriptable::WANT_ENUMERATE)
|
||||
|
||||
#define NODELIST_SCRIPTABLE_FLAGS \
|
||||
(ARRAY_SCRIPTABLE_FLAGS | \
|
||||
nsIXPCScriptable::WANT_FINALIZE)
|
||||
|
||||
#define EVENTTARGET_SCRIPTABLE_FLAGS \
|
||||
(DOM_DEFAULT_SCRIPTABLE_FLAGS | \
|
||||
nsIXPCScriptable::WANT_ADDPROPERTY | \
|
||||
nsIXPCScriptable::WANT_FINALIZE)
|
||||
|
||||
#define DOMCLASSINFO_STANDARD_FLAGS \
|
||||
(nsIClassInfo::MAIN_THREAD_ONLY | nsIClassInfo::DOM_OBJECT)
|
||||
|
||||
@ -632,7 +641,7 @@ static nsDOMClassInfoData sClassInfoData[] = {
|
||||
NS_DEFINE_CLASSINFO_DATA(ProcessingInstruction, nsNodeSH,
|
||||
NODE_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(Notation, nsNodeSH, NODE_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(NodeList, nsNodeListSH, ARRAY_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(NodeList, nsNodeListSH, NODELIST_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(NamedNodeMap, nsNamedNodeMapSH,
|
||||
ARRAY_SCRIPTABLE_FLAGS)
|
||||
|
||||
@ -883,9 +892,7 @@ static nsDOMClassInfoData sClassInfoData[] = {
|
||||
ARRAY_SCRIPTABLE_FLAGS)
|
||||
|
||||
NS_DEFINE_CLASSINFO_DATA_WITH_NAME(ContentList, HTMLCollection,
|
||||
nsContentListSH,
|
||||
ARRAY_SCRIPTABLE_FLAGS |
|
||||
nsIXPCScriptable::WANT_PRECREATE)
|
||||
nsContentListSH, NODELIST_SCRIPTABLE_FLAGS)
|
||||
|
||||
NS_DEFINE_CLASSINFO_DATA(XMLStylesheetProcessingInstruction, nsNodeSH,
|
||||
NODE_SCRIPTABLE_FLAGS)
|
||||
@ -1206,8 +1213,7 @@ static nsDOMClassInfoData sClassInfoData[] = {
|
||||
NS_DEFINE_CLASSINFO_DATA(XMLHttpProgressEvent, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(XMLHttpRequest, nsEventTargetSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS |
|
||||
nsIXPCScriptable::WANT_ADDPROPERTY)
|
||||
EVENTTARGET_SCRIPTABLE_FLAGS)
|
||||
|
||||
NS_DEFINE_CLASSINFO_DATA(ClientRect, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
@ -1278,8 +1284,7 @@ static nsDOMClassInfoData sClassInfoData[] = {
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
|
||||
NS_DEFINE_CLASSINFO_DATA(XMLHttpRequestUpload, nsEventTargetSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS |
|
||||
nsIXPCScriptable::WANT_ADDPROPERTY)
|
||||
EVENTTARGET_SCRIPTABLE_FLAGS)
|
||||
|
||||
// DOM Traversal NodeIterator class
|
||||
NS_DEFINE_CLASSINFO_DATA(NodeIterator, nsDOMGenericSH,
|
||||
@ -1294,6 +1299,11 @@ static nsDOMClassInfoData sClassInfoData[] = {
|
||||
|
||||
NS_DEFINE_CLASSINFO_DATA(SimpleGestureEvent, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
|
||||
#ifdef MOZ_MATHML
|
||||
NS_DEFINE_CLASSINFO_DATA_WITH_NAME(MathMLElement, Element, nsElementSH,
|
||||
ELEMENT_SCRIPTABLE_FLAGS)
|
||||
#endif
|
||||
};
|
||||
|
||||
// Objects that shuld be constructable through |new Name();|
|
||||
@ -3537,6 +3547,16 @@ nsDOMClassInfo::Init()
|
||||
DOM_CLASSINFO_UI_EVENT_MAP_ENTRIES
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
#ifdef MOZ_MATHML
|
||||
DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(MathMLElement, nsIDOMElement)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMElement)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMNSElement)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOM3Node)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMNodeSelector)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
#endif
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
{
|
||||
PRUint32 i = NS_ARRAY_LENGTH(sClassInfoData);
|
||||
@ -4167,28 +4187,14 @@ nsDOMClassInfo::GetClassInfoInstance(nsDOMClassInfoData* aData)
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
void
|
||||
nsDOMClassInfo::PreserveNodeWrapper(nsIXPConnectWrappedNative *aWrapper)
|
||||
{
|
||||
nsISupports *native = aWrapper->Native();
|
||||
nsCOMPtr<nsIDOMNode> node(do_QueryInterface(native));
|
||||
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
if (node) {
|
||||
nsCOMPtr<nsIDOMDocument> domdoc;
|
||||
node->GetOwnerDocument(getter_AddRefs(domdoc));
|
||||
doc = do_QueryInterface(domdoc);
|
||||
nsWrapperCache* cache;
|
||||
CallQueryInterface(aWrapper->Native(), &cache);
|
||||
if (cache) {
|
||||
cache->PreserveWrapper();
|
||||
}
|
||||
|
||||
if (!doc) {
|
||||
doc = do_QueryInterface(native);
|
||||
}
|
||||
|
||||
if (doc) {
|
||||
nsCOMPtr<nsINode> n(do_QueryInterface(node));
|
||||
doc->AddReference(n, aWrapper);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -6910,6 +6916,16 @@ nsNodeSH::PreCreate(nsISupports *nativeObj, JSContext *cx, JSObject *globalObj,
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNodeSH::PostCreate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj)
|
||||
{
|
||||
nsINode* node = static_cast<nsINode*>(wrapper->Native());
|
||||
node->SetWrapper(wrapper);
|
||||
|
||||
return nsEventReceiverSH::PostCreate(wrapper, cx, obj);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNodeSH::AddProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj, jsval id, jsval *vp, PRBool *_retval)
|
||||
@ -6928,6 +6944,13 @@ nsNodeSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
return DefineVoidProp(cx, obj, id, objp);
|
||||
}
|
||||
|
||||
if (id == sOnload_id || id == sOnerror_id) {
|
||||
// Make sure that this node can't go away while waiting for a
|
||||
// network load that could fire an event handler.
|
||||
nsINode* node = static_cast<nsINode*>(wrapper->Native());
|
||||
node->PreserveWrapper();
|
||||
}
|
||||
|
||||
return nsEventReceiverSH::NewResolve(wrapper, cx, obj, id, flags, objp,
|
||||
_retval);
|
||||
}
|
||||
@ -6996,6 +7019,16 @@ nsNodeSH::GetFlags(PRUint32 *aFlags)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNodeSH::Finalize(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj)
|
||||
{
|
||||
nsINode* node = static_cast<nsINode*>(wrapper->Native());
|
||||
node->ClearWrapper();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// EventReceiver helper
|
||||
|
||||
// static
|
||||
@ -7246,12 +7279,6 @@ nsEventReceiverSH::NewResolve(nsIXPConnectWrappedNative *wrapper,
|
||||
JSContext *cx, JSObject *obj, jsval id,
|
||||
PRUint32 flags, JSObject **objp, PRBool *_retval)
|
||||
{
|
||||
if (id == sOnload_id || id == sOnerror_id) {
|
||||
// Make sure that this node can't go away while waiting for a
|
||||
// network load that could fire an event handler.
|
||||
nsDOMClassInfo::PreserveNodeWrapper(wrapper);
|
||||
}
|
||||
|
||||
if (!JSVAL_IS_STRING(id)) {
|
||||
return NS_OK;
|
||||
}
|
||||
@ -7336,6 +7363,30 @@ nsEventReceiverSH::AddProperty(nsIXPConnectWrappedNative *wrapper,
|
||||
|
||||
// EventTarget helper
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsEventTargetSH::PreCreate(nsISupports *nativeObj, JSContext *cx,
|
||||
JSObject *globalObj, JSObject **parentObj)
|
||||
{
|
||||
nsXHREventTarget *target = nsXHREventTarget::FromSupports(nativeObj);
|
||||
|
||||
nsCOMPtr<nsIScriptGlobalObject> native_parent;
|
||||
target->GetParentObject(getter_AddRefs(native_parent));
|
||||
|
||||
*parentObj = native_parent ? native_parent->GetGlobalJSObject() : globalObj;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsEventTargetSH::PostCreate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj)
|
||||
{
|
||||
nsXHREventTarget *target = nsXHREventTarget::FromSupports(wrapper->Native());
|
||||
target->SetWrapper(wrapper);
|
||||
|
||||
return nsDOMGenericSH::PostCreate(wrapper, cx, obj);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsEventTargetSH::NewResolve(nsIXPConnectWrappedNative *wrapper,
|
||||
JSContext *cx, JSObject *obj, jsval id,
|
||||
@ -7358,26 +7409,24 @@ nsEventTargetSH::AddProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
if (id == sAddEventListener_id) {
|
||||
return NS_OK;
|
||||
}
|
||||
nsISupports* native = wrapper->Native();
|
||||
nsCOMPtr<nsPIDOMEventTarget> target = do_QueryInterface(native);
|
||||
if (target) {
|
||||
nsCOMPtr<nsIScriptContext> scriptContext;
|
||||
target->GetContextForEventHandlers(getter_AddRefs(scriptContext));
|
||||
if (scriptContext) {
|
||||
nsCOMPtr<nsPIDOMWindow> window =
|
||||
do_QueryInterface(scriptContext->GetGlobalObject());
|
||||
if (window) {
|
||||
nsCOMPtr<nsIDocument> doc =
|
||||
do_QueryInterface(window->GetExtantDocument());
|
||||
if (doc) {
|
||||
doc->AddReference(native, wrapper);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsXHREventTarget *target = nsXHREventTarget::FromSupports(wrapper->Native());
|
||||
target->PreserveWrapper();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsEventTargetSH::Finalize(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj)
|
||||
{
|
||||
nsXHREventTarget *target = nsXHREventTarget::FromSupports(wrapper->Native());
|
||||
target->ClearWrapper();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
// Element helper
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -7650,6 +7699,49 @@ nsArraySH::GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
|
||||
// NodeList scriptable helper
|
||||
|
||||
nsresult
|
||||
nsNodeListSH::PreCreate(nsISupports *nativeObj, JSContext *cx,
|
||||
JSObject *globalObj, JSObject **parentObj)
|
||||
{
|
||||
nsWrapperCache* cache;
|
||||
CallQueryInterface(nativeObj, &cache);
|
||||
if (!cache) {
|
||||
*parentObj = globalObj;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsChildContentList is the only class that uses nsNodeListSH and has a
|
||||
// cached wrapper.
|
||||
nsChildContentList *list = nsChildContentList::FromSupports(nativeObj);
|
||||
nsISupports *native_parent = list->GetParentObject();
|
||||
if (!native_parent) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
jsval v;
|
||||
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
|
||||
nsresult rv = WrapNative(cx, globalObj, native_parent,
|
||||
NS_GET_IID(nsISupports), &v,
|
||||
getter_AddRefs(holder));
|
||||
|
||||
*parentObj = JSVAL_TO_OBJECT(v);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNodeListSH::PostCreate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj)
|
||||
{
|
||||
nsWrapperCache* cache;
|
||||
CallQueryInterface(wrapper->Native(), &cache);
|
||||
if (cache) {
|
||||
cache->SetWrapper(wrapper);
|
||||
}
|
||||
|
||||
return nsArraySH::PostCreate(wrapper, cx, obj);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNodeListSH::GetLength(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj, PRUint32 *length)
|
||||
@ -7688,6 +7780,19 @@ nsNodeListSH::GetItemAt(nsISupports *aNative, PRUint32 aIndex,
|
||||
return list->GetNodeAt(aIndex);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNodeListSH::Finalize(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj)
|
||||
{
|
||||
nsWrapperCache* cache;
|
||||
CallQueryInterface(wrapper->Native(), &cache);
|
||||
if (cache) {
|
||||
cache->ClearWrapper();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
// StringList scriptable helper
|
||||
|
||||
@ -7825,8 +7930,7 @@ nsContentListSH::PreCreate(nsISupports *nativeObj, JSContext *cx,
|
||||
nsISupports *native_parent = contentList->GetParentObject();
|
||||
|
||||
if (!native_parent) {
|
||||
*parentObj = globalObj;
|
||||
return NS_OK;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
jsval v;
|
||||
@ -7840,6 +7944,16 @@ nsContentListSH::PreCreate(nsISupports *nativeObj, JSContext *cx,
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsContentListSH::PostCreate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj)
|
||||
{
|
||||
nsContentList *list = nsContentList::FromSupports(wrapper->Native());
|
||||
list->SetWrapper(wrapper);
|
||||
|
||||
return nsNamedArraySH::PostCreate(wrapper, cx, obj);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsContentListSH::GetLength(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj, PRUint32 *length)
|
||||
@ -7867,6 +7981,15 @@ nsContentListSH::GetNamedItem(nsISupports *aNative, const nsAString& aName,
|
||||
return list->GetNamedItem(aName, aResult);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsContentListSH::Finalize(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj)
|
||||
{
|
||||
nsContentList *list = nsContentList::FromSupports(wrapper->Native());
|
||||
list->ClearWrapper();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Document helper for document.location and document.on*
|
||||
|
||||
@ -8091,7 +8214,7 @@ nsDocumentSH::Finalize(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
|
||||
doc->SetJSObject(nsnull);
|
||||
|
||||
return NS_OK;
|
||||
return nsNodeSH::Finalize(wrapper, cx, obj);
|
||||
}
|
||||
|
||||
// HTMLDocument helper
|
||||
|
@ -172,7 +172,7 @@ public:
|
||||
::JS_GET_CLASS(cx, obj) == sXPCNativeWrapperClass;
|
||||
}
|
||||
|
||||
static nsresult PreserveNodeWrapper(nsIXPConnectWrappedNative *aWrapper);
|
||||
static void PreserveNodeWrapper(nsIXPConnectWrappedNative *aWrapper);
|
||||
|
||||
protected:
|
||||
friend nsIClassInfo* NS_GetDOMClassInfoInstance(nsDOMClassInfoID aID);
|
||||
@ -400,11 +400,17 @@ protected:
|
||||
{
|
||||
}
|
||||
public:
|
||||
NS_IMETHOD PreCreate(nsISupports *nativeObj, JSContext *cx,
|
||||
JSObject *globalObj, JSObject **parentObj);
|
||||
NS_IMETHOD PostCreate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj);
|
||||
NS_IMETHOD NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj, jsval id, PRUint32 flags,
|
||||
JSObject **objp, PRBool *_retval);
|
||||
NS_IMETHOD AddProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj, jsval id, jsval *vp, PRBool *_retval);
|
||||
NS_IMETHOD Finalize(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj);
|
||||
|
||||
static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
|
||||
{
|
||||
@ -556,6 +562,8 @@ protected:
|
||||
public:
|
||||
NS_IMETHOD PreCreate(nsISupports *nativeObj, JSContext *cx,
|
||||
JSObject *globalObj, JSObject **parentObj);
|
||||
NS_IMETHOD PostCreate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj);
|
||||
NS_IMETHOD AddProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj, jsval id, jsval *vp, PRBool *_retval);
|
||||
NS_IMETHOD NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
@ -566,6 +574,8 @@ public:
|
||||
NS_IMETHOD SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj, jsval id, jsval *vp, PRBool *_retval);
|
||||
NS_IMETHOD GetFlags(PRUint32 *aFlags);
|
||||
NS_IMETHOD Finalize(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj);
|
||||
|
||||
static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
|
||||
{
|
||||
@ -668,6 +678,13 @@ protected:
|
||||
}
|
||||
|
||||
public:
|
||||
NS_IMETHOD PreCreate(nsISupports *nativeObj, JSContext *cx,
|
||||
JSObject *globalObj, JSObject **parentObj);
|
||||
NS_IMETHOD PostCreate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj);
|
||||
NS_IMETHOD Finalize(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj);
|
||||
|
||||
virtual nsresult GetLength(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj, PRUint32 *length);
|
||||
virtual nsISupports* GetItemAt(nsISupports *aNative, PRUint32 aIndex,
|
||||
@ -779,6 +796,10 @@ protected:
|
||||
public:
|
||||
NS_IMETHOD PreCreate(nsISupports *nativeObj, JSContext *cx,
|
||||
JSObject *globalObj, JSObject **parentObj);
|
||||
NS_IMETHOD PostCreate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj);
|
||||
NS_IMETHOD Finalize(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj);
|
||||
|
||||
virtual nsresult GetLength(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj, PRUint32 *length);
|
||||
|
@ -1001,13 +1001,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsGlobalWindow)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mDocumentPrincipal)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mDoc)
|
||||
|
||||
// Traverse any associated preserved wrappers.
|
||||
{
|
||||
if (tmp->mDoc) {
|
||||
cb.NoteXPCOMChild(tmp->mDoc->GetReference(tmp));
|
||||
}
|
||||
}
|
||||
|
||||
// Traverse stuff from nsPIDOMWindow
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mChromeEventHandler)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mDocument)
|
||||
@ -1040,12 +1033,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGlobalWindow)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mApplicationCache)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDocumentPrincipal)
|
||||
|
||||
// Unlink any associated preserved wrapper.
|
||||
if (tmp->mDoc) {
|
||||
tmp->mDoc->RemoveReference(tmp);
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDoc)
|
||||
}
|
||||
|
||||
// Unlink stuff from nsPIDOMWindow
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mChromeEventHandler)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDocument)
|
||||
@ -4597,7 +4584,7 @@ nsGlobalWindow::ScrollTo(PRInt32 aXScroll, PRInt32 aYScroll)
|
||||
|
||||
result = view->ScrollTo(nsPresContext::CSSPixelsToAppUnits(aXScroll),
|
||||
nsPresContext::CSSPixelsToAppUnits(aYScroll),
|
||||
NS_VMREFRESH_IMMEDIATE);
|
||||
0);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -3372,7 +3372,8 @@ nsJSContext::ScriptExecuted()
|
||||
NS_IMETHODIMP
|
||||
nsJSContext::PreserveWrapper(nsIXPConnectWrappedNative *aWrapper)
|
||||
{
|
||||
return nsDOMClassInfo::PreserveNodeWrapper(aWrapper);
|
||||
nsDOMClassInfo::PreserveNodeWrapper(aWrapper);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//static
|
||||
|
@ -209,6 +209,7 @@ nsMimeTypeArray::NamedItem(const nsAString& aName, nsIDOMMimeType** aReturn)
|
||||
|
||||
void nsMimeTypeArray::Clear()
|
||||
{
|
||||
mInited = PR_FALSE;
|
||||
mMimeTypeArray.Clear();
|
||||
mPluginMimeTypeCount = 0;
|
||||
}
|
||||
@ -229,7 +230,7 @@ nsresult nsMimeTypeArray::GetMimeTypes()
|
||||
if (rv == NS_OK) {
|
||||
// count up all possible MimeTypes, and collect them here. Later,
|
||||
// we'll remove duplicates.
|
||||
mPluginMimeTypeCount = 0;
|
||||
PRUint32 pluginMimeTypeCount = 0;
|
||||
PRUint32 pluginCount = 0;
|
||||
rv = pluginArray->GetLength(&pluginCount);
|
||||
if (rv == NS_OK) {
|
||||
@ -240,12 +241,16 @@ nsresult nsMimeTypeArray::GetMimeTypes()
|
||||
plugin) {
|
||||
PRUint32 mimeTypeCount = 0;
|
||||
if (plugin->GetLength(&mimeTypeCount) == NS_OK)
|
||||
mPluginMimeTypeCount += mimeTypeCount;
|
||||
pluginMimeTypeCount += mimeTypeCount;
|
||||
}
|
||||
}
|
||||
// now we know how many there are, start gathering them.
|
||||
if (!mMimeTypeArray.SetCapacity(mPluginMimeTypeCount))
|
||||
if (!mMimeTypeArray.SetCapacity(pluginMimeTypeCount))
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
mPluginMimeTypeCount = pluginMimeTypeCount;
|
||||
mInited = PR_TRUE;
|
||||
|
||||
PRUint32 k;
|
||||
for (k = 0; k < pluginCount; k++) {
|
||||
nsIDOMPlugin* plugin = nsnull;
|
||||
|
@ -8,3 +8,4 @@ load 394810-1.html
|
||||
load 403356-1.html
|
||||
load 418139-1.svg
|
||||
load 420513-1.html
|
||||
load 462926.html
|
||||
|
@ -48,6 +48,7 @@
|
||||
#include "nsIAtom.h"
|
||||
#include "XPCWrapper.h"
|
||||
#include "nsJSPrincipals.h"
|
||||
#include "nsWrapperCache.h"
|
||||
|
||||
//#define STRICT_CHECK_OF_UNICODE
|
||||
#ifdef STRICT_CHECK_OF_UNICODE
|
||||
@ -1091,15 +1092,28 @@ XPCConvert::NativeInterface2JSObject(XPCCallContext& ccx,
|
||||
if(!iface)
|
||||
return JS_FALSE;
|
||||
|
||||
nsresult rv;
|
||||
XPCWrappedNative* wrapper;
|
||||
nsresult rv = XPCWrappedNative::GetNewOrUsed(ccx, src, xpcscope,
|
||||
iface, isGlobal,
|
||||
&wrapper);
|
||||
nsWrapperCache* cache;
|
||||
src->QueryInterface(NS_GET_IID(nsWrapperCache), (void**)&cache);
|
||||
if(cache &&
|
||||
(wrapper = static_cast<XPCWrappedNative*>(cache->GetWrapper())))
|
||||
{
|
||||
NS_ADDREF(wrapper);
|
||||
wrapper->FindTearOff(ccx, iface, JS_FALSE, &rv);
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = XPCWrappedNative::GetNewOrUsed(ccx, src, xpcscope, iface,
|
||||
isGlobal, &wrapper);
|
||||
}
|
||||
|
||||
if(pErr)
|
||||
*pErr = rv;
|
||||
if(NS_SUCCEEDED(rv) && wrapper)
|
||||
{
|
||||
uint32 flags = 0;
|
||||
JSObject *flat = wrapper->GetFlatJSObject();
|
||||
if (allowNativeWrapper && wrapper->GetScope() != xpcscope)
|
||||
{
|
||||
// Cross scope access detected. Check if chrome code
|
||||
@ -1157,7 +1171,6 @@ XPCConvert::NativeInterface2JSObject(XPCCallContext& ccx,
|
||||
|
||||
flags = script ? JS_GetScriptFilenameFlags(script) : 0;
|
||||
NS_ASSERTION(flags != JSFILENAME_NULL, "null script filename");
|
||||
JSObject *flat = wrapper->GetFlatJSObject();
|
||||
|
||||
if(!JS_IsSystemObject(ccx, flat))
|
||||
{
|
||||
@ -1265,7 +1278,6 @@ XPCConvert::NativeInterface2JSObject(XPCCallContext& ccx,
|
||||
}
|
||||
}
|
||||
|
||||
JSObject *flat = wrapper->GetFlatJSObject();
|
||||
const char *name = STOBJ_GET_CLASS(flat)->name;
|
||||
if(allowNativeWrapper &&
|
||||
!(flags & JSFILENAME_SYSTEM) &&
|
||||
|
@ -266,7 +266,7 @@ public:
|
||||
|
||||
struct xpc_qsSelfRef
|
||||
{
|
||||
xpc_qsSelfRef() {}
|
||||
xpc_qsSelfRef() : ptr(nsnull) {}
|
||||
explicit xpc_qsSelfRef(nsISupports *p) : ptr(p) {}
|
||||
~xpc_qsSelfRef() { NS_IF_RELEASE(ptr); }
|
||||
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include "nsCRT.h"
|
||||
#include "XPCNativeWrapper.h"
|
||||
#include "XPCWrapper.h"
|
||||
#include "nsWrapperCache.h"
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
@ -589,27 +590,13 @@ XPCWrappedNative::GetUsedOnly(XPCCallContext& ccx,
|
||||
XPCWrappedNative** resultWrapper)
|
||||
{
|
||||
NS_ASSERTION(Object, "XPCWrappedNative::GetUsedOnly was called with a null Object");
|
||||
nsCOMPtr<nsISupports> identity;
|
||||
#ifdef XPC_IDISPATCH_SUPPORT
|
||||
// XXX See GetNewOrUsed for more info on this
|
||||
if(Interface->GetIID()->Equals(NSID_IDISPATCH))
|
||||
identity = Object;
|
||||
else
|
||||
#endif
|
||||
identity = do_QueryInterface(Object);
|
||||
|
||||
if(!identity)
|
||||
{
|
||||
NS_ERROR("This XPCOM object fails in QueryInterface to nsISupports!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
XPCWrappedNative* wrapper;
|
||||
Native2WrappedNativeMap* map = Scope->GetWrappedNativeMap();
|
||||
|
||||
{ // scoped lock
|
||||
XPCAutoLock lock(Scope->GetRuntime()->GetMapLock());
|
||||
wrapper = map->Find(identity);
|
||||
nsWrapperCache* cache;
|
||||
Object->QueryInterface(NS_GET_IID(nsWrapperCache), (void**)&cache);
|
||||
if(cache)
|
||||
{
|
||||
wrapper = static_cast<XPCWrappedNative*>(cache->GetWrapper());
|
||||
if(!wrapper)
|
||||
{
|
||||
*resultWrapper = nsnull;
|
||||
@ -617,6 +604,36 @@ XPCWrappedNative::GetUsedOnly(XPCCallContext& ccx,
|
||||
}
|
||||
NS_ADDREF(wrapper);
|
||||
}
|
||||
else
|
||||
{
|
||||
nsCOMPtr<nsISupports> identity;
|
||||
#ifdef XPC_IDISPATCH_SUPPORT
|
||||
// XXX See GetNewOrUsed for more info on this
|
||||
if(Interface->GetIID()->Equals(NSID_IDISPATCH))
|
||||
identity = Object;
|
||||
else
|
||||
#endif
|
||||
identity = do_QueryInterface(Object);
|
||||
|
||||
if(!identity)
|
||||
{
|
||||
NS_ERROR("This XPCOM object fails in QueryInterface to nsISupports!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
Native2WrappedNativeMap* map = Scope->GetWrappedNativeMap();
|
||||
|
||||
{ // scoped lock
|
||||
XPCAutoLock lock(Scope->GetRuntime()->GetMapLock());
|
||||
wrapper = map->Find(identity);
|
||||
if(!wrapper)
|
||||
{
|
||||
*resultWrapper = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
NS_ADDREF(wrapper);
|
||||
}
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
if(!wrapper->FindTearOff(ccx, Interface, JS_FALSE, &rv))
|
||||
|
@ -3663,7 +3663,7 @@ DocumentViewerImpl::PrintPreviewNavigate(PRInt16 aType, PRInt32 aPageNum)
|
||||
// Check to see if we can short circut scrolling to the top
|
||||
if (aType == nsIWebBrowserPrint::PRINTPREVIEW_HOME ||
|
||||
(aType == nsIWebBrowserPrint::PRINTPREVIEW_GOTO_PAGENUM && aPageNum == 1)) {
|
||||
scrollableView->ScrollTo(0, 0, PR_TRUE);
|
||||
scrollableView->ScrollTo(0, 0, 0);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -3750,7 +3750,7 @@ DocumentViewerImpl::PrintPreviewNavigate(PRInt16 aType, PRInt32 aPageNum)
|
||||
nscoord newYPosn =
|
||||
nscoord(mPrintEngine->GetPrintPreviewScale() *
|
||||
float(fndPageFrame->GetPosition().y - deadSpaceGap));
|
||||
scrollableView->ScrollTo(0, newYPosn, PR_TRUE);
|
||||
scrollableView->ScrollTo(0, newYPosn, 0);
|
||||
}
|
||||
return NS_OK;
|
||||
|
||||
|
@ -3734,7 +3734,7 @@ PresShell::GoToAnchor(const nsAString& aAnchorName, PRBool aScroll)
|
||||
mViewManager->GetRootScrollableView(&scrollingView);
|
||||
if (scrollingView) {
|
||||
// Scroll to the top of the page
|
||||
scrollingView->ScrollTo(0, 0, NS_VMREFRESH_IMMEDIATE);
|
||||
scrollingView->ScrollTo(0, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3961,8 +3961,7 @@ static void ScrollViewToShowRect(nsIScrollableView* aScrollingView,
|
||||
NSToCoordRound(frameAlignX - visibleRect.width * (aHPercent / 100.0f));
|
||||
}
|
||||
|
||||
aScrollingView->ScrollTo(scrollOffsetX, scrollOffsetY,
|
||||
NS_VMREFRESH_IMMEDIATE);
|
||||
aScrollingView->ScrollTo(scrollOffsetX, scrollOffsetY, 0);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -83,6 +83,7 @@
|
||||
#include "nsXMLHttpRequest.h"
|
||||
#include "nsIFocusEventSuppressor.h"
|
||||
#include "nsDOMThreadService.h"
|
||||
#include "nsHTMLDNSPrefetch.h"
|
||||
|
||||
#ifdef MOZ_XUL
|
||||
#include "nsXULPopupManager.h"
|
||||
@ -185,6 +186,12 @@ nsLayoutStatics::Initialize()
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = nsHTMLDNSPrefetch::Initialize();
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_ERROR("Could not initialize HTML DNS prefetch");
|
||||
return rv;
|
||||
}
|
||||
|
||||
#ifdef MOZ_XUL
|
||||
rv = nsXULContentUtils::Init();
|
||||
if (NS_FAILED(rv)) {
|
||||
@ -280,6 +287,7 @@ nsLayoutStatics::Shutdown()
|
||||
CSSLoaderImpl::Shutdown();
|
||||
nsCSSRuleProcessor::FreeSystemMetrics();
|
||||
nsTextFrameTextRunCache::Shutdown();
|
||||
nsHTMLDNSPrefetch::Shutdown();
|
||||
nsCSSRendering::Shutdown();
|
||||
#ifdef DEBUG
|
||||
nsFrame::DisplayReflowShutdown();
|
||||
|
@ -2324,7 +2324,7 @@ nsListControlFrame::ScrollToFrame(nsIContent* aOptElement)
|
||||
if (scrollableView) {
|
||||
// if null is passed in we scroll to 0,0
|
||||
if (nsnull == aOptElement) {
|
||||
scrollableView->ScrollTo(0, 0, PR_TRUE);
|
||||
scrollableView->ScrollTo(0, 0, 0);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -2382,7 +2382,7 @@ nsListControlFrame::ScrollToFrame(nsIContent* aOptElement)
|
||||
} else {
|
||||
y = fRect.y;
|
||||
}
|
||||
scrollableView->ScrollTo(pnt.x, y, PR_TRUE);
|
||||
scrollableView->ScrollTo(pnt.x, y, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2787,7 +2787,7 @@ nsTextControlFrame::SetValue(const nsAString& aValue)
|
||||
// Scroll the upper left corner of the text control's
|
||||
// content area back into view.
|
||||
|
||||
scrollableView->ScrollTo(0, 0, NS_VMREFRESH_NO_SYNC);
|
||||
scrollableView->ScrollTo(0, 0, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -99,10 +99,10 @@ public:
|
||||
* legal. Updates the display based on aUpdateFlags.
|
||||
* @param aX left edge to scroll to
|
||||
* @param aY top edge to scroll to
|
||||
* @param aUpdateFlags passed onto nsIViewManager->UpdateView()
|
||||
* @param aUpdateFlags indicate smooth or async scrolling
|
||||
* @return error status
|
||||
*/
|
||||
virtual void ScrollTo(nsPoint aScrollPosition, PRUint32 aFlags = NS_VMREFRESH_NO_SYNC)=0;
|
||||
virtual void ScrollTo(nsPoint aScrollPosition, PRUint32 aFlags = 0)=0;
|
||||
|
||||
virtual nsIScrollableView* GetScrollableView() = 0;
|
||||
|
||||
|
@ -5089,8 +5089,7 @@ nsTypedSelection::ScrollPointIntoClipView(nsPresContext *aPresContext, nsIView *
|
||||
|
||||
// Now scroll the view!
|
||||
|
||||
result = scrollableView->ScrollTo(bounds.x + dx, bounds.y + dy,
|
||||
NS_VMREFRESH_NO_SYNC);
|
||||
result = scrollableView->ScrollTo(bounds.x + dx, bounds.y + dy, 0);
|
||||
|
||||
if (NS_FAILED(result))
|
||||
return result;
|
||||
@ -6400,7 +6399,7 @@ nsTypedSelection::ScrollRectIntoView(nsIScrollableView *aScrollableView,
|
||||
}
|
||||
}
|
||||
|
||||
aScrollableView->ScrollTo(scrollOffsetX, scrollOffsetY, NS_VMREFRESH_IMMEDIATE);
|
||||
aScrollableView->ScrollTo(scrollOffsetX, scrollOffsetY, 0);
|
||||
|
||||
if (aScrollParentViews)
|
||||
{
|
||||
|
@ -51,7 +51,7 @@ native PRNetAddr(union PRNetAddr);
|
||||
* NOTE: This is a free-threaded interface, meaning that the methods on
|
||||
* this interface may be called from any thread.
|
||||
*/
|
||||
[scriptable, uuid(66418cc8-5f5d-4f52-a7f9-db8fb3b2cfe6)]
|
||||
[scriptable, uuid(ef3f4993-cfbc-4e5a-9509-16deafe16549)]
|
||||
interface nsISocketTransport : nsITransport
|
||||
{
|
||||
/**
|
||||
@ -134,6 +134,22 @@ interface nsISocketTransport : nsITransport
|
||||
const unsigned long STATUS_SENDING_TO = 0x804b0005;
|
||||
const unsigned long STATUS_WAITING_FOR = 0x804b000a;
|
||||
const unsigned long STATUS_RECEIVING_FROM = 0x804b0006;
|
||||
|
||||
/**
|
||||
* connectionFlags is a bitmask that can be used to modify underlying
|
||||
* behavior of the socket connection.
|
||||
*/
|
||||
attribute unsigned long connectionFlags;
|
||||
|
||||
/**
|
||||
* Values for the connectionFlags
|
||||
*
|
||||
* When making a new connection BYPASS_CACHE will force the Necko DNS
|
||||
* cache entry to be refreshed with a new call to NSPR if it is set before
|
||||
* opening the new stream.
|
||||
*/
|
||||
const unsigned long BYPASS_CACHE = (1 << 0);
|
||||
|
||||
};
|
||||
|
||||
%{C++
|
||||
|
@ -272,6 +272,14 @@
|
||||
#define NS_ERROR_UNKNOWN_HOST \
|
||||
NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 30)
|
||||
|
||||
/**
|
||||
* A low or medium priority DNS lookup failed because the pending
|
||||
* queue was already full. High priorty (the default) always
|
||||
* makes room
|
||||
*/
|
||||
#define NS_ERROR_DNS_LOOKUP_QUEUE_FULL \
|
||||
NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 33)
|
||||
|
||||
/**
|
||||
* The lookup of a proxy hostname failed.
|
||||
*
|
||||
|
@ -93,6 +93,7 @@ CPPSRCS = \
|
||||
nsNetStrings.cpp \
|
||||
nsBase64Encoder.cpp \
|
||||
nsSerializationHelper.cpp \
|
||||
nsDNSPrefetch.cpp \
|
||||
$(NULL)
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),os2)
|
||||
|
@ -707,6 +707,7 @@ nsSocketTransport::nsSocketTransport()
|
||||
, mProxyPort(0)
|
||||
, mProxyTransparent(PR_FALSE)
|
||||
, mProxyTransparentResolvesHost(PR_FALSE)
|
||||
, mConnectionFlags(0)
|
||||
, mState(STATE_CLOSED)
|
||||
, mAttached(PR_FALSE)
|
||||
, mInputClosed(PR_TRUE)
|
||||
@ -946,7 +947,11 @@ nsSocketTransport::ResolveHost()
|
||||
|
||||
mResolving = PR_TRUE;
|
||||
|
||||
rv = dns->AsyncResolve(SocketHost(), 0, this, nsnull,
|
||||
PRUint32 dnsFlags = 0;
|
||||
if (mConnectionFlags & nsSocketTransport::BYPASS_CACHE)
|
||||
dnsFlags = nsIDNSService::RESOLVE_BYPASS_CACHE;
|
||||
|
||||
rv = dns->AsyncResolve(SocketHost(), dnsFlags, this, nsnull,
|
||||
getter_AddRefs(mDNSRequest));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
LOG((" advancing to STATE_RESOLVING\n"));
|
||||
@ -1946,6 +1951,21 @@ nsSocketTransport::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSocketTransport::GetConnectionFlags(PRUint32 *value)
|
||||
{
|
||||
*value = mConnectionFlags;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSocketTransport::SetConnectionFlags(PRUint32 value)
|
||||
{
|
||||
mConnectionFlags = value;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
#ifdef ENABLE_SOCKET_TRACING
|
||||
|
||||
#include <stdio.h>
|
||||
|
@ -202,7 +202,8 @@ private:
|
||||
PRUint16 mProxyPort;
|
||||
PRPackedBool mProxyTransparent;
|
||||
PRPackedBool mProxyTransparentResolvesHost;
|
||||
|
||||
PRUint32 mConnectionFlags;
|
||||
|
||||
PRUint16 SocketPort() { return (!mProxyHost.IsEmpty() && !mProxyTransparent) ? mProxyPort : mPort; }
|
||||
const nsCString &SocketHost() { return (!mProxyHost.IsEmpty() && !mProxyTransparent) ? mProxyHost : mHost; }
|
||||
|
||||
|
@ -59,6 +59,7 @@
|
||||
#include "nsDiskCacheDeviceSQL.h"
|
||||
#include "nsMimeTypes.h"
|
||||
#include "nsNetStrings.h"
|
||||
#include "nsDNSPrefetch.h"
|
||||
|
||||
#include "nsNetCID.h"
|
||||
|
||||
@ -619,10 +620,13 @@ static void nsNetShutdown(nsIModule *neckoModule)
|
||||
#ifdef XP_MACOSX
|
||||
net_ShutdownURLHelperOSX();
|
||||
#endif
|
||||
|
||||
|
||||
// Release necko strings
|
||||
delete gNetStrings;
|
||||
gNetStrings = nsnull;
|
||||
|
||||
// Release DNS service reference.
|
||||
nsDNSPrefetch::Shutdown();
|
||||
}
|
||||
|
||||
static const nsModuleComponentInfo gNetModuleInfo[] = {
|
||||
|
@ -46,7 +46,7 @@ interface nsIDNSListener;
|
||||
/**
|
||||
* nsIDNSService
|
||||
*/
|
||||
[scriptable, uuid(3ac9e611-e6b6-44b5-b312-c040e65b2929)]
|
||||
[scriptable, uuid(ee4d9f1d-4f99-4384-b547-29da735f8b6e)]
|
||||
interface nsIDNSService : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -107,4 +107,11 @@ interface nsIDNSService : nsISupports
|
||||
* if set, the canonical name of the specified host will be queried.
|
||||
*/
|
||||
const unsigned long RESOLVE_CANONICAL_NAME = (1 << 1);
|
||||
|
||||
/**
|
||||
* if set, the query is given lower priority. Medium takes precedence
|
||||
* if both are used.
|
||||
*/
|
||||
const unsigned long RESOLVE_PRIORITY_MEDIUM = (1 << 2);
|
||||
const unsigned long RESOLVE_PRIORITY_LOW = (1 << 3);
|
||||
};
|
||||
|
@ -50,6 +50,7 @@
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsNetCID.h"
|
||||
#include "nsNetError.h"
|
||||
#include "nsDNSPrefetch.h"
|
||||
#include "prsystem.h"
|
||||
#include "prnetdb.h"
|
||||
#include "prmon.h"
|
||||
@ -61,6 +62,7 @@ static const char kPrefDnsCacheExpiration[] = "network.dnsCacheExpiration";
|
||||
static const char kPrefEnableIDN[] = "network.enableIDN";
|
||||
static const char kPrefIPv4OnlyDomains[] = "network.dns.ipv4OnlyDomains";
|
||||
static const char kPrefDisableIPv6[] = "network.dns.disableIPv6";
|
||||
static const char kPrefDisablePrefetch[] = "network.dns.disablePrefetch";
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@ -321,10 +323,12 @@ nsDNSService::Init()
|
||||
PRBool firstTime = (mLock == nsnull);
|
||||
|
||||
// prefs
|
||||
PRUint32 maxCacheEntries = 20;
|
||||
PRUint32 maxCacheLifetime = 1; // minutes
|
||||
PRUint32 maxCacheEntries = 400;
|
||||
PRUint32 maxCacheLifetime = 3; // minutes
|
||||
PRBool enableIDN = PR_TRUE;
|
||||
PRBool disableIPv6 = PR_FALSE;
|
||||
PRBool disablePrefetch = PR_FALSE;
|
||||
|
||||
nsAdoptingCString ipv4OnlyDomains;
|
||||
|
||||
// read prefs
|
||||
@ -340,6 +344,7 @@ nsDNSService::Init()
|
||||
prefs->GetBoolPref(kPrefEnableIDN, &enableIDN);
|
||||
prefs->GetBoolPref(kPrefDisableIPv6, &disableIPv6);
|
||||
prefs->GetCharPref(kPrefIPv4OnlyDomains, getter_Copies(ipv4OnlyDomains));
|
||||
prefs->GetBoolPref(kPrefDisablePrefetch, &disablePrefetch);
|
||||
}
|
||||
|
||||
if (firstTime) {
|
||||
@ -354,6 +359,7 @@ nsDNSService::Init()
|
||||
prefs->AddObserver(kPrefEnableIDN, this, PR_FALSE);
|
||||
prefs->AddObserver(kPrefIPv4OnlyDomains, this, PR_FALSE);
|
||||
prefs->AddObserver(kPrefDisableIPv6, this, PR_FALSE);
|
||||
prefs->AddObserver(kPrefDisablePrefetch, this, PR_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -374,8 +380,10 @@ nsDNSService::Init()
|
||||
mIDN = idn;
|
||||
mIPv4OnlyDomains = ipv4OnlyDomains; // exchanges buffer ownership
|
||||
mDisableIPv6 = disableIPv6;
|
||||
mDisablePrefetch = disablePrefetch;
|
||||
}
|
||||
|
||||
|
||||
nsDNSPrefetch::Initialize(this);
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -406,6 +414,10 @@ nsDNSService::AsyncResolve(const nsACString &hostname,
|
||||
nsCOMPtr<nsIIDNService> idn;
|
||||
{
|
||||
nsAutoLock lock(mLock);
|
||||
|
||||
if (mDisablePrefetch && (flags & (RESOLVE_PRIORITY_LOW | RESOLVE_PRIORITY_MEDIUM)))
|
||||
return NS_ERROR_DNS_LOOKUP_QUEUE_FULL;
|
||||
|
||||
res = mResolver;
|
||||
idn = mIDN;
|
||||
}
|
||||
|
@ -68,4 +68,5 @@ private:
|
||||
// a per-domain basis and work around broken DNS servers. See bug 68796.
|
||||
nsAdoptingCString mIPv4OnlyDomains;
|
||||
PRBool mDisableIPv6;
|
||||
PRBool mDisablePrefetch;
|
||||
};
|
||||
|
@ -68,8 +68,28 @@
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#define MAX_THREADS 8
|
||||
#define IDLE_TIMEOUT PR_SecondsToInterval(60)
|
||||
// Use a persistent thread pool in order to avoid spinning up new threads all the time.
|
||||
// In particular, thread creation results in a res_init() call from libc which is
|
||||
// quite expensive.
|
||||
//
|
||||
// The pool dynamically grows between 0 and MAX_RESOLVER_THREADS in size. New requests
|
||||
// go first to an idle thread. If that cannot be found and there are fewer than MAX_RESOLVER_THREADS
|
||||
// currently in the pool a new thread is created for high priority requests. If
|
||||
// the new request is at a lower priority a new thread will only be created if
|
||||
// there are fewer than HighThreadThreshold currently outstanding. If a thread cannot be
|
||||
// created or an idle thread located for the request it is queued.
|
||||
//
|
||||
// When the pool is greater than HighThreadThreshold in size a thread will be destroyed after
|
||||
// ShortIdleTimeoutSeconds of idle time. Smaller pools use LongIdleTimeoutSeconds for a
|
||||
// timeout period.
|
||||
|
||||
#define MAX_NON_PRIORITY_REQUESTS 150
|
||||
|
||||
#define HighThreadThreshold 4
|
||||
#define LongIdleTimeoutSeconds 300 // for threads 1 -> HighThreadThreshold
|
||||
#define ShortIdleTimeoutSeconds 60 // for threads HighThreadThreshold+1 -> MAX_RESOLVER_THREADS
|
||||
|
||||
PR_STATIC_ASSERT (HighThreadThreshold <= MAX_RESOLVER_THREADS);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
@ -173,7 +193,7 @@ nsHostRecord::Create(const nsHostKey *key, nsHostRecord **result)
|
||||
}
|
||||
|
||||
rec->host = ((char *) rec) + sizeof(nsHostRecord);
|
||||
rec->flags = RES_KEY_FLAGS(key->flags);
|
||||
rec->flags = key->flags;
|
||||
rec->af = key->af;
|
||||
|
||||
rec->_refc = 1; // addref
|
||||
@ -184,6 +204,7 @@ nsHostRecord::Create(const nsHostKey *key, nsHostRecord **result)
|
||||
rec->addr = nsnull;
|
||||
rec->expiration = NowInMinutes();
|
||||
rec->resolving = PR_FALSE;
|
||||
rec->onQueue = PR_FALSE;
|
||||
PR_INIT_CLIST(rec);
|
||||
PR_INIT_CLIST(&rec->callbacks);
|
||||
rec->negative = PR_FALSE;
|
||||
@ -214,7 +235,7 @@ static PLDHashNumber
|
||||
HostDB_HashKey(PLDHashTable *table, const void *key)
|
||||
{
|
||||
const nsHostKey *hk = static_cast<const nsHostKey *>(key);
|
||||
return PL_DHashStringKey(table, hk->host) ^ hk->flags ^ hk->af;
|
||||
return PL_DHashStringKey(table, hk->host) ^ RES_KEY_FLAGS(hk->flags) ^ hk->af;
|
||||
}
|
||||
|
||||
static PRBool
|
||||
@ -226,7 +247,7 @@ HostDB_MatchEntry(PLDHashTable *table,
|
||||
const nsHostKey *hk = static_cast<const nsHostKey *>(key);
|
||||
|
||||
return !strcmp(he->rec->host, hk->host) &&
|
||||
he->rec->flags == hk->flags &&
|
||||
RES_KEY_FLAGS (he->rec->flags) == RES_KEY_FLAGS(hk->flags) &&
|
||||
he->rec->af == hk->af;
|
||||
}
|
||||
|
||||
@ -308,14 +329,26 @@ nsHostResolver::nsHostResolver(PRUint32 maxCacheEntries,
|
||||
, mMaxCacheLifetime(maxCacheLifetime)
|
||||
, mLock(nsnull)
|
||||
, mIdleThreadCV(nsnull)
|
||||
, mHaveIdleThread(PR_FALSE)
|
||||
, mNumIdleThreads(0)
|
||||
, mThreadCount(0)
|
||||
, mAnyPriorityThreadCount(0)
|
||||
, mEvictionQSize(0)
|
||||
, mPendingCount(0)
|
||||
, mShutdown(PR_TRUE)
|
||||
{
|
||||
mCreationTime = PR_Now();
|
||||
PR_INIT_CLIST(&mPendingQ);
|
||||
PR_INIT_CLIST(&mHighQ);
|
||||
PR_INIT_CLIST(&mMediumQ);
|
||||
PR_INIT_CLIST(&mLowQ);
|
||||
PR_INIT_CLIST(&mEvictionQ);
|
||||
|
||||
mHighPriorityInfo.self = this;
|
||||
mHighPriorityInfo.onlyHighPriority = PR_TRUE;
|
||||
mAnyPriorityInfo.self = this;
|
||||
mAnyPriorityInfo.onlyHighPriority = PR_FALSE;
|
||||
|
||||
mLongIdleTimeout = PR_SecondsToInterval(LongIdleTimeoutSeconds);
|
||||
mShortIdleTimeout = PR_SecondsToInterval(ShortIdleTimeoutSeconds);
|
||||
}
|
||||
|
||||
nsHostResolver::~nsHostResolver()
|
||||
@ -359,13 +392,29 @@ nsHostResolver::Init()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsHostResolver::ClearPendingQueue(PRCList *aPendingQ)
|
||||
{
|
||||
// loop through pending queue, erroring out pending lookups.
|
||||
if (!PR_CLIST_IS_EMPTY(aPendingQ)) {
|
||||
PRCList *node = aPendingQ->next;
|
||||
while (node != aPendingQ) {
|
||||
nsHostRecord *rec = static_cast<nsHostRecord *>(node);
|
||||
node = node->next;
|
||||
OnLookupComplete(rec, NS_ERROR_ABORT, nsnull);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHostResolver::Shutdown()
|
||||
{
|
||||
LOG(("nsHostResolver::Shutdown\n"));
|
||||
|
||||
PRCList pendingQ, evictionQ;
|
||||
PR_INIT_CLIST(&pendingQ);
|
||||
PRCList pendingQHigh, pendingQMed, pendingQLow, evictionQ;
|
||||
PR_INIT_CLIST(&pendingQHigh);
|
||||
PR_INIT_CLIST(&pendingQMed);
|
||||
PR_INIT_CLIST(&pendingQLow);
|
||||
PR_INIT_CLIST(&evictionQ);
|
||||
|
||||
{
|
||||
@ -373,26 +422,23 @@ nsHostResolver::Shutdown()
|
||||
|
||||
mShutdown = PR_TRUE;
|
||||
|
||||
MoveCList(mPendingQ, pendingQ);
|
||||
MoveCList(mHighQ, pendingQHigh);
|
||||
MoveCList(mMediumQ, pendingQMed);
|
||||
MoveCList(mLowQ, pendingQLow);
|
||||
MoveCList(mEvictionQ, evictionQ);
|
||||
mEvictionQSize = 0;
|
||||
|
||||
if (mHaveIdleThread)
|
||||
PR_NotifyCondVar(mIdleThreadCV);
|
||||
mPendingCount = 0;
|
||||
|
||||
if (mNumIdleThreads)
|
||||
PR_NotifyAllCondVar(mIdleThreadCV);
|
||||
|
||||
// empty host database
|
||||
PL_DHashTableEnumerate(&mDB, HostDB_RemoveEntry, nsnull);
|
||||
}
|
||||
|
||||
// loop through pending queue, erroring out pending lookups.
|
||||
if (!PR_CLIST_IS_EMPTY(&pendingQ)) {
|
||||
PRCList *node = pendingQ.next;
|
||||
while (node != &pendingQ) {
|
||||
nsHostRecord *rec = static_cast<nsHostRecord *>(node);
|
||||
node = node->next;
|
||||
OnLookupComplete(rec, NS_ERROR_ABORT, nsnull);
|
||||
}
|
||||
}
|
||||
|
||||
ClearPendingQueue(&pendingQHigh);
|
||||
ClearPendingQueue(&pendingQMed);
|
||||
ClearPendingQueue(&pendingQLow);
|
||||
|
||||
if (!PR_CLIST_IS_EMPTY(&evictionQ)) {
|
||||
PRCList *node = evictionQ.next;
|
||||
@ -405,6 +451,33 @@ nsHostResolver::Shutdown()
|
||||
|
||||
}
|
||||
|
||||
static inline PRBool
|
||||
IsHighPriority(PRUint16 flags)
|
||||
{
|
||||
return !(flags & (nsHostResolver::RES_PRIORITY_LOW | nsHostResolver::RES_PRIORITY_MEDIUM));
|
||||
}
|
||||
|
||||
static inline PRBool
|
||||
IsMediumPriority(PRUint16 flags)
|
||||
{
|
||||
return flags & nsHostResolver::RES_PRIORITY_MEDIUM;
|
||||
}
|
||||
|
||||
static inline PRBool
|
||||
IsLowPriority(PRUint16 flags)
|
||||
{
|
||||
return flags & nsHostResolver::RES_PRIORITY_LOW;
|
||||
}
|
||||
|
||||
void
|
||||
nsHostResolver::MoveQueue(nsHostRecord *aRec, PRCList &aDestQ)
|
||||
{
|
||||
NS_ASSERTION(aRec->onQueue, "Moving Host Record Not Currently Queued");
|
||||
|
||||
PR_REMOVE_LINK(aRec);
|
||||
PR_APPEND_LINK(aRec, &aDestQ);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHostResolver::ResolveHost(const char *host,
|
||||
PRUint16 flags,
|
||||
@ -484,16 +557,38 @@ nsHostResolver::ResolveHost(const char *host,
|
||||
// put reference to host record on stack...
|
||||
result = he->rec;
|
||||
}
|
||||
else if (mPendingCount >= MAX_NON_PRIORITY_REQUESTS &&
|
||||
!IsHighPriority(flags) &&
|
||||
!he->rec->resolving) {
|
||||
// This is a lower priority request and we are swamped, so refuse it.
|
||||
rv = NS_ERROR_DNS_LOOKUP_QUEUE_FULL;
|
||||
}
|
||||
// otherwise, hit the resolver...
|
||||
else {
|
||||
// add callback to the list of pending callbacks
|
||||
// Add callback to the list of pending callbacks.
|
||||
PR_APPEND_LINK(callback, &he->rec->callbacks);
|
||||
|
||||
if (!he->rec->resolving) {
|
||||
he->rec->flags = flags;
|
||||
rv = IssueLookup(he->rec);
|
||||
if (NS_FAILED(rv))
|
||||
PR_REMOVE_AND_INIT_LINK(callback);
|
||||
}
|
||||
else if (he->rec->onQueue) {
|
||||
// Consider the case where we are on a pending queue of
|
||||
// lower priority than the request is being made at.
|
||||
// In that case we should upgrade to the higher queue.
|
||||
|
||||
if (IsHighPriority(flags) && !IsHighPriority(he->rec->flags)) {
|
||||
// Move from (low|med) to high.
|
||||
MoveQueue(he->rec, mHighQ);
|
||||
he->rec->flags = flags;
|
||||
} else if (IsMediumPriority(flags) && IsLowPriority(he->rec->flags)) {
|
||||
// Move from low to med.
|
||||
MoveQueue(he->rec, mMediumQ);
|
||||
he->rec->flags = flags;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -542,35 +637,57 @@ nsHostResolver::IssueLookup(nsHostRecord *rec)
|
||||
{
|
||||
NS_ASSERTION(!rec->resolving, "record is already being resolved");
|
||||
|
||||
// add rec to mPendingQ, possibly removing it from mEvictionQ.
|
||||
// if rec is on mEvictionQ, then we can just move the owning
|
||||
// reference over to mPendingQ.
|
||||
// Add rec to one of the pending queues, possibly removing it from mEvictionQ.
|
||||
// If rec is on mEvictionQ, then we can just move the owning
|
||||
// reference over to the new active queue.
|
||||
if (rec->next == rec)
|
||||
NS_ADDREF(rec);
|
||||
else {
|
||||
PR_REMOVE_LINK(rec);
|
||||
mEvictionQSize--;
|
||||
}
|
||||
PR_APPEND_LINK(rec, &mPendingQ);
|
||||
|
||||
if (IsHighPriority(rec->flags))
|
||||
PR_APPEND_LINK(rec, &mHighQ);
|
||||
else if (IsMediumPriority(rec->flags))
|
||||
PR_APPEND_LINK(rec, &mMediumQ);
|
||||
else
|
||||
PR_APPEND_LINK(rec, &mLowQ);
|
||||
mPendingCount++;
|
||||
|
||||
rec->resolving = PR_TRUE;
|
||||
rec->onQueue = PR_TRUE;
|
||||
|
||||
if (mHaveIdleThread) {
|
||||
if (mNumIdleThreads) {
|
||||
// wake up idle thread to process this lookup
|
||||
PR_NotifyCondVar(mIdleThreadCV);
|
||||
}
|
||||
else if (mThreadCount < MAX_THREADS) {
|
||||
else if ((mThreadCount < HighThreadThreshold) ||
|
||||
(IsHighPriority(rec->flags) && mThreadCount < MAX_RESOLVER_THREADS)) {
|
||||
// dispatch new worker thread
|
||||
NS_ADDREF_THIS(); // owning reference passed to thread
|
||||
|
||||
struct nsHostResolverThreadInfo *info;
|
||||
|
||||
if (mAnyPriorityThreadCount < HighThreadThreshold) {
|
||||
info = &mAnyPriorityInfo;
|
||||
mAnyPriorityThreadCount++;
|
||||
}
|
||||
else
|
||||
info = &mHighPriorityInfo;
|
||||
|
||||
mThreadCount++;
|
||||
PRThread *thr = PR_CreateThread(PR_SYSTEM_THREAD,
|
||||
ThreadFunc,
|
||||
this,
|
||||
info,
|
||||
PR_PRIORITY_NORMAL,
|
||||
PR_GLOBAL_THREAD,
|
||||
PR_UNJOINABLE_THREAD,
|
||||
0);
|
||||
if (!thr) {
|
||||
mThreadCount--;
|
||||
if (info == &mAnyPriorityInfo)
|
||||
mAnyPriorityThreadCount--;
|
||||
NS_RELEASE_THIS();
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
@ -583,25 +700,54 @@ nsHostResolver::IssueLookup(nsHostRecord *rec)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsHostResolver::DeQueue(PRCList &aQ, nsHostRecord **aResult)
|
||||
{
|
||||
*aResult = static_cast<nsHostRecord *>(aQ.next);
|
||||
PR_REMOVE_AND_INIT_LINK(*aResult);
|
||||
mPendingCount--;
|
||||
(*aResult)->onQueue = PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsHostResolver::GetHostToLookup(nsHostRecord **result)
|
||||
nsHostResolver::GetHostToLookup(nsHostRecord **result, struct nsHostResolverThreadInfo *aID)
|
||||
{
|
||||
nsAutoLock lock(mLock);
|
||||
|
||||
PRIntervalTime start = PR_IntervalNow(), timeout = IDLE_TIMEOUT;
|
||||
//
|
||||
// wait for one or more of the following to occur:
|
||||
// (1) the pending queue has a host record to process
|
||||
// (2) the shutdown flag has been set
|
||||
// (3) the thread has been idle for too long
|
||||
//
|
||||
// PR_WaitCondVar will return when any of these conditions is true.
|
||||
//
|
||||
while (PR_CLIST_IS_EMPTY(&mPendingQ) && !mHaveIdleThread && !mShutdown) {
|
||||
PRIntervalTime start = PR_IntervalNow(), timeout;
|
||||
|
||||
while (!mShutdown) {
|
||||
// remove next record from Q; hand over owning reference. Check high, then med, then low
|
||||
|
||||
if (!PR_CLIST_IS_EMPTY(&mHighQ)) {
|
||||
DeQueue (mHighQ, result);
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
if (! aID->onlyHighPriority) {
|
||||
if (!PR_CLIST_IS_EMPTY(&mMediumQ)) {
|
||||
DeQueue (mMediumQ, result);
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
if (!PR_CLIST_IS_EMPTY(&mLowQ)) {
|
||||
DeQueue (mLowQ, result);
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
timeout = (mNumIdleThreads >= HighThreadThreshold) ? mShortIdleTimeout : mLongIdleTimeout;
|
||||
// wait for one or more of the following to occur:
|
||||
// (1) the pending queue has a host record to process
|
||||
// (2) the shutdown flag has been set
|
||||
// (3) the thread has been idle for too long
|
||||
//
|
||||
// PR_WaitCondVar will return when any of these conditions is true.
|
||||
// become the idle thread and wait for a lookup
|
||||
mHaveIdleThread = PR_TRUE;
|
||||
|
||||
mNumIdleThreads++;
|
||||
PR_WaitCondVar(mIdleThreadCV, timeout);
|
||||
mHaveIdleThread = PR_FALSE;
|
||||
mNumIdleThreads--;
|
||||
|
||||
PRIntervalTime delta = PR_IntervalNow() - start;
|
||||
if (delta >= timeout)
|
||||
@ -610,15 +756,10 @@ nsHostResolver::GetHostToLookup(nsHostRecord **result)
|
||||
start += delta;
|
||||
}
|
||||
|
||||
if (!PR_CLIST_IS_EMPTY(&mPendingQ)) {
|
||||
// remove next record from mPendingQ; hand over owning reference.
|
||||
*result = static_cast<nsHostRecord *>(mPendingQ.next);
|
||||
PR_REMOVE_AND_INIT_LINK(*result);
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
// tell thread to exit...
|
||||
mThreadCount--;
|
||||
if (!aID->onlyHighPriority)
|
||||
mAnyPriorityThreadCount--;
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
@ -697,11 +838,11 @@ nsHostResolver::ThreadFunc(void *arg)
|
||||
#if defined(RES_RETRY_ON_FAILURE)
|
||||
nsResState rs;
|
||||
#endif
|
||||
|
||||
nsHostResolver *resolver = (nsHostResolver *) arg;
|
||||
struct nsHostResolverThreadInfo *info = (struct nsHostResolverThreadInfo *) arg;
|
||||
nsHostResolver *resolver = info->self;
|
||||
nsHostRecord *rec;
|
||||
PRAddrInfo *ai;
|
||||
while (resolver->GetHostToLookup(&rec)) {
|
||||
while (resolver->GetHostToLookup(&rec, info)) {
|
||||
LOG(("resolving %s ...\n", rec->host));
|
||||
|
||||
PRIntn flags = PR_AI_ADDRCONFIG;
|
||||
|
@ -68,6 +68,11 @@ class nsResolveHostCallback;
|
||||
return n; \
|
||||
}
|
||||
|
||||
#define MAX_RESOLVER_THREADS_FOR_ANY_PRIORITY 5
|
||||
#define MAX_RESOLVER_THREADS_FOR_HIGH_PRIORITY 3
|
||||
#define MAX_RESOLVER_THREADS (MAX_RESOLVER_THREADS_FOR_ANY_PRIORITY + \
|
||||
MAX_RESOLVER_THREADS_FOR_HIGH_PRIORITY)
|
||||
|
||||
struct nsHostKey
|
||||
{
|
||||
const char *host;
|
||||
@ -124,6 +129,9 @@ private:
|
||||
PRBool resolving; /* true if this record is being resolved, which means
|
||||
* that it is either on the pending queue or owned by
|
||||
* one of the worker threads. */
|
||||
|
||||
PRBool onQueue; /* true if pending and on the queue (not yet given to getaddrinfo())*/
|
||||
|
||||
|
||||
~nsHostRecord();
|
||||
};
|
||||
@ -157,6 +165,16 @@ public:
|
||||
nsresult status) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* nsHostResolverThreadInfo structures are passed to the resolver
|
||||
* thread.
|
||||
*/
|
||||
struct nsHostResolverThreadInfo
|
||||
{
|
||||
nsHostResolver *self;
|
||||
PRBool onlyHighPriority;
|
||||
};
|
||||
|
||||
/**
|
||||
* nsHostResolver - an asynchronous host name resolver.
|
||||
*/
|
||||
@ -214,32 +232,47 @@ public:
|
||||
*/
|
||||
enum {
|
||||
RES_BYPASS_CACHE = 1 << 0,
|
||||
RES_CANON_NAME = 1 << 1
|
||||
RES_CANON_NAME = 1 << 1,
|
||||
RES_PRIORITY_MEDIUM = 1 << 2,
|
||||
RES_PRIORITY_LOW = 1 << 3
|
||||
};
|
||||
|
||||
private:
|
||||
nsHostResolver(PRUint32 maxCacheEntries=50, PRUint32 maxCacheLifetime=1);
|
||||
~nsHostResolver();
|
||||
|
||||
// nsHostResolverThreadInfo * is passed to the ThreadFunc
|
||||
struct nsHostResolverThreadInfo mHighPriorityInfo, mAnyPriorityInfo;
|
||||
|
||||
nsresult Init();
|
||||
nsresult IssueLookup(nsHostRecord *);
|
||||
PRBool GetHostToLookup(nsHostRecord **);
|
||||
PRBool GetHostToLookup(nsHostRecord **m, struct nsHostResolverThreadInfo *aID);
|
||||
void OnLookupComplete(nsHostRecord *, nsresult, PRAddrInfo *);
|
||||
void DeQueue(PRCList &aQ, nsHostRecord **aResult);
|
||||
void ClearPendingQueue(PRCList *aPendingQueue);
|
||||
|
||||
static void MoveQueue(nsHostRecord *aRec, PRCList &aDestQ);
|
||||
|
||||
static void ThreadFunc(void *);
|
||||
|
||||
PRUint32 mMaxCacheEntries;
|
||||
PRUint32 mMaxCacheLifetime;
|
||||
PRLock *mLock;
|
||||
PRCondVar *mIdleThreadCV; // non-null if idle thread
|
||||
PRBool mHaveIdleThread;
|
||||
PRUint32 mNumIdleThreads;
|
||||
PRUint32 mThreadCount;
|
||||
PRUint32 mAnyPriorityThreadCount;
|
||||
PLDHashTable mDB;
|
||||
PRCList mPendingQ;
|
||||
PRCList mHighQ;
|
||||
PRCList mMediumQ;
|
||||
PRCList mLowQ;
|
||||
PRCList mEvictionQ;
|
||||
PRUint32 mEvictionQSize;
|
||||
PRUint32 mPendingCount;
|
||||
PRTime mCreationTime;
|
||||
PRBool mShutdown;
|
||||
PRIntervalTime mLongIdleTimeout;
|
||||
PRIntervalTime mShortIdleTimeout;
|
||||
};
|
||||
|
||||
#endif // nsHostResolver_h__
|
||||
|
@ -104,6 +104,10 @@ typedef PRUint8 nsHttpVersion;
|
||||
// preventing it from being reclaimed, even after the transaction completes.
|
||||
#define NS_HTTP_STICKY_CONNECTION (1<<2)
|
||||
|
||||
// a transaction with this caps flag will, upon opening a new connection,
|
||||
// bypass the local DNS cache
|
||||
#define NS_HTTP_REFRESH_DNS (1<<3)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// some default values
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -81,6 +81,7 @@
|
||||
#include "nsIOService.h"
|
||||
#include "nsAuthInformationHolder.h"
|
||||
#include "nsICacheService.h"
|
||||
#include "nsDNSPrefetch.h"
|
||||
|
||||
// True if the local cache should be bypassed when processing a request.
|
||||
#define BYPASS_LOCAL_CACHE(loadFlags) \
|
||||
@ -3993,6 +3994,13 @@ nsHttpChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *context)
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
// Start a DNS lookup very early in case the real open is queued the DNS can
|
||||
// happen in parallel.
|
||||
nsRefPtr<nsDNSPrefetch> prefetch = new nsDNSPrefetch(mURI);
|
||||
if (prefetch) {
|
||||
prefetch->PrefetchMedium();
|
||||
}
|
||||
|
||||
// Remember the cookie header that was set, if any
|
||||
const char *cookieHeader = mRequestHead.PeekHeader(nsHttp::Cookie);
|
||||
if (cookieHeader)
|
||||
@ -4010,6 +4018,10 @@ nsHttpChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *context)
|
||||
if (mRequestHead.HasHeaderValue(nsHttp::Connection, "close"))
|
||||
mCaps &= ~(NS_HTTP_ALLOW_KEEPALIVE | NS_HTTP_ALLOW_PIPELINING);
|
||||
|
||||
if ((mLoadFlags & VALIDATE_ALWAYS) ||
|
||||
(BYPASS_LOCAL_CACHE(mLoadFlags)))
|
||||
mCaps |= NS_HTTP_REFRESH_DNS;
|
||||
|
||||
mIsPending = PR_TRUE;
|
||||
mWasOpened = PR_TRUE;
|
||||
|
||||
|
@ -140,7 +140,7 @@ nsHttpConnection::Activate(nsAHttpTransaction *trans, PRUint8 caps)
|
||||
|
||||
// if we don't have a socket transport then create a new one
|
||||
if (!mSocketTransport) {
|
||||
rv = CreateTransport();
|
||||
rv = CreateTransport(caps);
|
||||
if (NS_FAILED(rv))
|
||||
goto loser;
|
||||
}
|
||||
@ -424,7 +424,7 @@ nsHttpConnection::ResumeRecv()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
nsresult
|
||||
nsHttpConnection::CreateTransport()
|
||||
nsHttpConnection::CreateTransport(PRUint8 caps)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
@ -452,6 +452,9 @@ nsHttpConnection::CreateTransport()
|
||||
getter_AddRefs(strans));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (caps & NS_HTTP_REFRESH_DNS)
|
||||
strans->SetConnectionFlags(nsISocketTransport::BYPASS_CACHE);
|
||||
|
||||
// NOTE: these create cyclical references, which we break inside
|
||||
// nsHttpConnection::Close
|
||||
rv = strans->SetEventSink(this, nsnull);
|
||||
|
@ -125,7 +125,7 @@ private:
|
||||
// called to cause the underlying socket to start speaking SSL
|
||||
nsresult ProxyStartSSL();
|
||||
|
||||
nsresult CreateTransport();
|
||||
nsresult CreateTransport(PRUint8 caps);
|
||||
nsresult OnTransactionDone(nsresult reason);
|
||||
nsresult OnSocketWritable();
|
||||
nsresult OnSocketReadable();
|
||||
|
@ -2668,7 +2668,7 @@ NSEvent* gLastDragEvent = nil;
|
||||
PRInt32 p2a = mGeckoChild->GetDeviceContext()->AppUnitsPerDevPixel();
|
||||
nscoord newX = mHandScrollStartScrollX + NSIntPixelsToAppUnits(deltaX, p2a);
|
||||
nscoord newY = mHandScrollStartScrollY + NSIntPixelsToAppUnits(deltaY, p2a);
|
||||
aScrollableView->ScrollTo(newX, newY, NS_VMREFRESH_IMMEDIATE);
|
||||
aScrollableView->ScrollTo(newX, newY, 0);
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user