зеркало из https://github.com/mozilla/pjs.git
Improve performance of testing for visited links CSS selector matching by reducing string conversion and by caching the state of the link on the link element. r=waterson b=25963
This commit is contained in:
Родитель
8f5f2da417
Коммит
a394eeee27
|
@ -27,6 +27,7 @@
|
|||
#include "nsIDOMEventReceiver.h"
|
||||
#include "nsIHTMLContent.h"
|
||||
#include "nsGenericHTMLElement.h"
|
||||
#include "nsILink.h"
|
||||
#include "nsHTMLAtoms.h"
|
||||
#include "nsHTMLIIDs.h"
|
||||
#include "nsIStyleContext.h"
|
||||
|
@ -56,6 +57,7 @@ static NS_DEFINE_IID(kIDOMHTMLAnchorElementIID, NS_IDOMHTMLANCHORELEMENT_IID);
|
|||
class nsHTMLAnchorElement : public nsIDOMHTMLAnchorElement,
|
||||
public nsIDOMNSHTMLAnchorElement,
|
||||
public nsIJSScriptObject,
|
||||
public nsILink,
|
||||
public nsIHTMLContent
|
||||
{
|
||||
public:
|
||||
|
@ -115,6 +117,11 @@ public:
|
|||
// nsIJSScriptObject
|
||||
NS_IMPL_IJSSCRIPTOBJECT_USING_GENERIC(mInner)
|
||||
|
||||
// nsILink
|
||||
NS_IMETHOD GetLinkState(nsLinkState &aState);
|
||||
NS_IMETHOD SetLinkState(nsLinkState aState);
|
||||
NS_IMETHOD GetHrefCString(char* &aBuf);
|
||||
|
||||
// nsIContent
|
||||
//NS_IMPL_ICONTENT_NO_FOCUS_USING_GENERIC(mInner)
|
||||
NS_IMPL_ICONTENT_NO_SETPARENT_NO_SETDOCUMENT_NO_FOCUS_USING_GENERIC(mInner)
|
||||
|
@ -126,10 +133,8 @@ protected:
|
|||
nsresult RegUnRegAccessKey(PRBool aDoReg);
|
||||
nsGenericHTMLContainerElement mInner;
|
||||
|
||||
// The "cached" canonical URL that the anchor really points to. This
|
||||
// value is derived on-demand when someone asks for the ".href"
|
||||
// property.
|
||||
char* mCanonicalHref;
|
||||
// The cached visited state
|
||||
nsLinkState mLinkState;
|
||||
};
|
||||
|
||||
nsresult
|
||||
|
@ -147,19 +152,16 @@ NS_NewHTMLAnchorElement(nsIHTMLContent** aInstancePtrResult,
|
|||
}
|
||||
|
||||
nsHTMLAnchorElement::nsHTMLAnchorElement(nsINodeInfo *aNodeInfo)
|
||||
: mCanonicalHref(nsnull)
|
||||
: mLinkState(eLinkState_Unknown)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
mInner.Init(this, aNodeInfo);
|
||||
nsHTMLUtils::AddRef();
|
||||
nsHTMLUtils::AddRef(); // for GetHrefCString
|
||||
}
|
||||
|
||||
nsHTMLAnchorElement::~nsHTMLAnchorElement()
|
||||
{
|
||||
if (mCanonicalHref)
|
||||
nsCRT::free(mCanonicalHref);
|
||||
|
||||
nsHTMLUtils::Release();
|
||||
nsHTMLUtils::Release(); // for GetHrefCString
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF(nsHTMLAnchorElement)
|
||||
|
@ -181,6 +183,11 @@ nsHTMLAnchorElement::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
|||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
else if (aIID.Equals(NS_GET_IID(nsILink))) {
|
||||
*aInstancePtr = (void*)(nsILink*) this;
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
|
||||
|
@ -415,46 +422,23 @@ nsHTMLAnchorElement::HandleDOMEvent(nsIPresContext* aPresContext,
|
|||
NS_IMETHODIMP
|
||||
nsHTMLAnchorElement::GetHref(nsString& aValue)
|
||||
{
|
||||
// Return the canonical URI that this link refers to.
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (! mCanonicalHref) {
|
||||
// We don't have a cached value: compute it from scratch.
|
||||
|
||||
// Get href= attribute (relative URL).
|
||||
nsAutoString relURLSpec;
|
||||
mInner.GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::href, relURLSpec);
|
||||
|
||||
if (relURLSpec.Length()) {
|
||||
// Get base URL.
|
||||
nsCOMPtr<nsIURI> baseURL;
|
||||
mInner.GetBaseURL(*getter_AddRefs(baseURL));
|
||||
|
||||
if (baseURL) {
|
||||
// Get absolute URL.
|
||||
NS_MakeAbsoluteURIWithCharset(&mCanonicalHref, relURLSpec, mInner.mDocument, baseURL,
|
||||
nsHTMLUtils::IOService, nsHTMLUtils::CharsetMgr);
|
||||
}
|
||||
else {
|
||||
// Absolute URL is same as relative URL.
|
||||
mCanonicalHref = relURLSpec.ToNewUTF8String();
|
||||
}
|
||||
}
|
||||
char *buf;
|
||||
nsresult rv = GetHrefCString(buf);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (buf) {
|
||||
aValue.AssignWithConversion(buf);
|
||||
nsCRT::free(buf);
|
||||
}
|
||||
|
||||
aValue.AssignWithConversion(mCanonicalHref);
|
||||
return rv;
|
||||
// NS_IMPL_STRING_ATTR does nothing where we have (buf == null)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLAnchorElement::SetHref(const nsString& aValue)
|
||||
{
|
||||
if (mCanonicalHref) {
|
||||
// Clobber our "cache", so we'll recompute it the next time
|
||||
// somebody asks for it.
|
||||
nsCRT::free(mCanonicalHref);
|
||||
mCanonicalHref = nsnull;
|
||||
}
|
||||
// Clobber our "cache", so we'll recompute it the next time
|
||||
// somebody asks for it.
|
||||
mLinkState = eLinkState_Unknown;
|
||||
|
||||
return mInner.SetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::href, aValue, PR_TRUE);
|
||||
}
|
||||
|
@ -679,3 +663,46 @@ nsHTMLAnchorElement::GetText(nsString& aText)
|
|||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLAnchorElement::GetLinkState(nsLinkState &aState)
|
||||
{
|
||||
aState = mLinkState;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLAnchorElement::SetLinkState(nsLinkState aState)
|
||||
{
|
||||
mLinkState = aState;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLAnchorElement::GetHrefCString(char* &aBuf)
|
||||
{
|
||||
// Get href= attribute (relative URL).
|
||||
nsAutoString relURLSpec;
|
||||
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE ==
|
||||
mInner.GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::href, relURLSpec)) {
|
||||
// Get base URL.
|
||||
nsCOMPtr<nsIURI> baseURL;
|
||||
mInner.GetBaseURL(*getter_AddRefs(baseURL));
|
||||
|
||||
if (baseURL) {
|
||||
// Get absolute URL.
|
||||
NS_MakeAbsoluteURIWithCharset(&aBuf, relURLSpec, mInner.mDocument, baseURL,
|
||||
nsHTMLUtils::IOService, nsHTMLUtils::CharsetMgr);
|
||||
}
|
||||
else {
|
||||
// Absolute URL is same as relative URL.
|
||||
aBuf = relURLSpec.ToNewUTF8String();
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Absolute URL is null to say we have no HREF.
|
||||
aBuf = nsnull;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
#include "nsIDOMEventReceiver.h"
|
||||
#include "nsIHTMLContent.h"
|
||||
#include "nsGenericHTMLElement.h"
|
||||
#include "nsILink.h"
|
||||
#include "nsHTMLAtoms.h"
|
||||
#include "nsHTMLUtils.h"
|
||||
#include "nsHTMLIIDs.h"
|
||||
#include "nsIStyleContext.h"
|
||||
#include "nsIMutableStyleContext.h"
|
||||
|
@ -35,12 +35,14 @@
|
|||
#include "nsIEventStateManager.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsHTMLUtils.h"
|
||||
|
||||
static NS_DEFINE_IID(kIDOMHTMLAreaElementIID, NS_IDOMHTMLAREAELEMENT_IID);
|
||||
|
||||
class nsHTMLAreaElement : public nsIDOMHTMLAreaElement,
|
||||
public nsIDOMNSHTMLAreaElement,
|
||||
public nsIJSScriptObject,
|
||||
public nsILink,
|
||||
public nsIHTMLContent
|
||||
{
|
||||
public:
|
||||
|
@ -89,6 +91,11 @@ public:
|
|||
// nsIJSScriptObject
|
||||
NS_IMPL_IJSSCRIPTOBJECT_USING_GENERIC(mInner)
|
||||
|
||||
// nsILink
|
||||
NS_IMETHOD GetLinkState(nsLinkState &aState);
|
||||
NS_IMETHOD SetLinkState(nsLinkState aState);
|
||||
NS_IMETHOD GetHrefCString(char* &aBuf);
|
||||
|
||||
// nsIContent
|
||||
NS_IMPL_ICONTENT_NO_FOCUS_USING_GENERIC(mInner)
|
||||
|
||||
|
@ -97,6 +104,9 @@ public:
|
|||
|
||||
protected:
|
||||
nsGenericHTMLLeafElement mInner;
|
||||
|
||||
// The cached visited state
|
||||
nsLinkState mLinkState;
|
||||
};
|
||||
|
||||
nsresult
|
||||
|
@ -115,13 +125,16 @@ NS_NewHTMLAreaElement(nsIHTMLContent** aInstancePtrResult,
|
|||
|
||||
|
||||
nsHTMLAreaElement::nsHTMLAreaElement(nsINodeInfo *aNodeInfo)
|
||||
: mLinkState(eLinkState_Unknown)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
mInner.Init(this, aNodeInfo);
|
||||
nsHTMLUtils::AddRef(); // for GetHrefCString
|
||||
}
|
||||
|
||||
nsHTMLAreaElement::~nsHTMLAreaElement()
|
||||
{
|
||||
nsHTMLUtils::Release(); // for GetHrefCString
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF(nsHTMLAreaElement)
|
||||
|
@ -144,6 +157,11 @@ nsHTMLAreaElement::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
|||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
else if (aIID.Equals(NS_GET_IID(nsILink))) {
|
||||
*aInstancePtr = (void*)(nsILink*) this;
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
|
||||
|
@ -257,42 +275,28 @@ nsHTMLAreaElement::RemoveFocus(nsIPresContext* aPresContext)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLAreaElement::GetHref(nsString& aValue)
|
||||
{
|
||||
// Return the canonical URI that this link refers to.
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
// Get href= attribute (relative URL).
|
||||
nsAutoString relURLSpec;
|
||||
mInner.GetAttribute(kNameSpaceID_None, nsHTMLAtoms::href, relURLSpec);
|
||||
|
||||
if (relURLSpec.Length()) {
|
||||
// Get base URL.
|
||||
nsCOMPtr<nsIURI> baseURL;
|
||||
mInner.GetBaseURL(*getter_AddRefs(baseURL));
|
||||
|
||||
if (baseURL) {
|
||||
// Get absolute URL.
|
||||
nsXPIDLCString absURI;
|
||||
NS_MakeAbsoluteURIWithCharset(getter_Copies(absURI), relURLSpec, mInner.mDocument, baseURL,
|
||||
nsHTMLUtils::IOService, nsHTMLUtils::CharsetMgr);
|
||||
aValue.AssignWithConversion(absURI);
|
||||
}
|
||||
else {
|
||||
// Absolute URL is same as relative URL.
|
||||
aValue = relURLSpec;
|
||||
}
|
||||
char *buf;
|
||||
nsresult rv = GetHrefCString(buf);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (buf) {
|
||||
aValue.AssignWithConversion(buf);
|
||||
nsCRT::free(buf);
|
||||
}
|
||||
|
||||
return rv;
|
||||
// NS_IMPL_STRING_ATTR does nothing where we have (buf == null)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLAreaElement::SetHref(const nsString& aValue)
|
||||
{
|
||||
return mInner.SetAttribute(kNameSpaceID_None, nsHTMLAtoms::href, aValue, PR_TRUE);
|
||||
// Clobber our "cache", so we'll recompute it the next time
|
||||
// somebody asks for it.
|
||||
mLinkState = eLinkState_Unknown;
|
||||
|
||||
return mInner.SetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::href, aValue, PR_TRUE);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -498,3 +502,47 @@ nsHTMLAreaElement::GetHash(nsString& aHash)
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLAreaElement::GetLinkState(nsLinkState &aState)
|
||||
{
|
||||
aState = mLinkState;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLAreaElement::SetLinkState(nsLinkState aState)
|
||||
{
|
||||
mLinkState = aState;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLAreaElement::GetHrefCString(char* &aBuf)
|
||||
{
|
||||
// Get href= attribute (relative URL).
|
||||
nsAutoString relURLSpec;
|
||||
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE ==
|
||||
mInner.GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::href, relURLSpec)) {
|
||||
// Get base URL.
|
||||
nsCOMPtr<nsIURI> baseURL;
|
||||
mInner.GetBaseURL(*getter_AddRefs(baseURL));
|
||||
|
||||
if (baseURL) {
|
||||
// Get absolute URL.
|
||||
NS_MakeAbsoluteURIWithCharset(&aBuf, relURLSpec, mInner.mDocument, baseURL,
|
||||
nsHTMLUtils::IOService, nsHTMLUtils::CharsetMgr);
|
||||
}
|
||||
else {
|
||||
// Absolute URL is same as relative URL.
|
||||
aBuf = relURLSpec.ToNewUTF8String();
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Absolute URL is empty because we have no HREF.
|
||||
aBuf = PL_strdup(""); // use a dummy empty string
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "nsIDOMEventReceiver.h"
|
||||
#include "nsIHTMLContent.h"
|
||||
#include "nsGenericHTMLElement.h"
|
||||
#include "nsILink.h"
|
||||
#include "nsHTMLAtoms.h"
|
||||
#include "nsHTMLIIDs.h"
|
||||
#include "nsIStyleContext.h"
|
||||
|
@ -33,6 +34,8 @@
|
|||
#include "nsIDOMStyleSheet.h"
|
||||
#include "nsIStyleSheet.h"
|
||||
#include "nsIStyleSheetLinkingElement.h"
|
||||
#include "nsHTMLUtils.h"
|
||||
#include "nsIURL.h"
|
||||
|
||||
static NS_DEFINE_IID(kIDOMHTMLLinkElementIID, NS_IDOMHTMLLINKELEMENT_IID);
|
||||
static NS_DEFINE_IID(kIStyleSheetLinkingElementIID, NS_ISTYLESHEETLINKINGELEMENT_IID);
|
||||
|
@ -40,6 +43,7 @@ static NS_DEFINE_IID(kIDOMStyleSheetIID, NS_IDOMSTYLESHEET_IID);
|
|||
|
||||
class nsHTMLLinkElement : public nsIDOMHTMLLinkElement,
|
||||
public nsIJSScriptObject,
|
||||
public nsILink,
|
||||
public nsIHTMLContent,
|
||||
public nsIStyleSheetLinkingElement
|
||||
{
|
||||
|
@ -82,6 +86,11 @@ public:
|
|||
// nsIJSScriptObject
|
||||
NS_IMPL_IJSSCRIPTOBJECT_USING_GENERIC(mInner)
|
||||
|
||||
// nsILink
|
||||
NS_IMETHOD GetLinkState(nsLinkState &aState);
|
||||
NS_IMETHOD SetLinkState(nsLinkState aState);
|
||||
NS_IMETHOD GetHrefCString(char* &aBuf);
|
||||
|
||||
// nsIContent
|
||||
NS_IMPL_ICONTENT_USING_GENERIC(mInner)
|
||||
|
||||
|
@ -95,6 +104,9 @@ public:
|
|||
protected:
|
||||
nsGenericHTMLLeafElement mInner;
|
||||
nsIStyleSheet* mStyleSheet;
|
||||
|
||||
// The cached visited state
|
||||
nsLinkState mLinkState;
|
||||
};
|
||||
|
||||
nsresult
|
||||
|
@ -113,15 +125,18 @@ NS_NewHTMLLinkElement(nsIHTMLContent** aInstancePtrResult,
|
|||
|
||||
|
||||
nsHTMLLinkElement::nsHTMLLinkElement(nsINodeInfo *aNodeInfo)
|
||||
: mLinkState(eLinkState_Unknown)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
mInner.Init(this, aNodeInfo);
|
||||
mStyleSheet = nsnull;
|
||||
nsHTMLUtils::AddRef(); // for GetHrefCString
|
||||
}
|
||||
|
||||
nsHTMLLinkElement::~nsHTMLLinkElement()
|
||||
{
|
||||
NS_IF_RELEASE(mStyleSheet);
|
||||
nsHTMLUtils::Release(); // for GetHrefCString
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF(nsHTMLLinkElement)
|
||||
|
@ -144,6 +159,11 @@ nsHTMLLinkElement::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
|||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
if (aIID.Equals(NS_GET_IID(nsILink))) {
|
||||
*aInstancePtr = (void*)(nsILink*) this;
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
|
||||
|
@ -198,7 +218,6 @@ nsHTMLLinkElement::SetDisabled(PRBool aDisabled)
|
|||
}
|
||||
|
||||
NS_IMPL_STRING_ATTR(nsHTMLLinkElement, Charset, charset)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLLinkElement, Href, href)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLLinkElement, Hreflang, hreflang)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLLinkElement, Media, media)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLLinkElement, Rel, rel)
|
||||
|
@ -206,6 +225,30 @@ NS_IMPL_STRING_ATTR(nsHTMLLinkElement, Rev, rev)
|
|||
NS_IMPL_STRING_ATTR(nsHTMLLinkElement, Target, target)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLLinkElement, Type, type)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLLinkElement::GetHref(nsString& aValue)
|
||||
{
|
||||
char *buf;
|
||||
nsresult rv = GetHrefCString(buf);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (buf) {
|
||||
aValue.AssignWithConversion(buf);
|
||||
nsCRT::free(buf);
|
||||
}
|
||||
// NS_IMPL_STRING_ATTR does nothing where we have (buf == null)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLLinkElement::SetHref(const nsString& aValue)
|
||||
{
|
||||
// Clobber our "cache", so we'll recompute it the next time
|
||||
// somebody asks for it.
|
||||
mLinkState = eLinkState_Unknown;
|
||||
|
||||
return mInner.SetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::href, aValue, PR_TRUE);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLLinkElement::SetStyleSheet(nsIStyleSheet* aStyleSheet)
|
||||
{
|
||||
|
@ -289,3 +332,47 @@ nsHTMLLinkElement::SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const
|
|||
{
|
||||
return mInner.SizeOf(aSizer, aResult, sizeof(*this));
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLLinkElement::GetLinkState(nsLinkState &aState)
|
||||
{
|
||||
aState = mLinkState;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLLinkElement::SetLinkState(nsLinkState aState)
|
||||
{
|
||||
mLinkState = aState;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLLinkElement::GetHrefCString(char* &aBuf)
|
||||
{
|
||||
// Get href= attribute (relative URL).
|
||||
nsAutoString relURLSpec;
|
||||
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE ==
|
||||
mInner.GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::href, relURLSpec)) {
|
||||
// Get base URL.
|
||||
nsCOMPtr<nsIURI> baseURL;
|
||||
mInner.GetBaseURL(*getter_AddRefs(baseURL));
|
||||
|
||||
if (baseURL) {
|
||||
// Get absolute URL.
|
||||
NS_MakeAbsoluteURIWithCharset(&aBuf, relURLSpec, mInner.mDocument, baseURL,
|
||||
nsHTMLUtils::IOService, nsHTMLUtils::CharsetMgr);
|
||||
}
|
||||
else {
|
||||
// Absolute URL is same as relative URL.
|
||||
aBuf = relURLSpec.ToNewUTF8String();
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Absolute URL is empty because we have no HREF.
|
||||
aBuf = PL_strdup(""); // use a dummy empty string
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -27,11 +27,7 @@
|
|||
#include "nsCRT.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsIIOService.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsNetUtil.h"
|
||||
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
|
||||
#include "nsISupportsArray.h"
|
||||
#include "nsHashtable.h"
|
||||
#include "nsICSSStyleRuleProcessor.h"
|
||||
|
@ -41,7 +37,6 @@ static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
|
|||
#include "nsIHTMLContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIPresContext.h"
|
||||
#include "nsILinkHandler.h"
|
||||
#include "nsIEventStateManager.h"
|
||||
#include "nsHTMLAtoms.h"
|
||||
#include "nsLayoutAtoms.h"
|
||||
|
@ -67,10 +62,10 @@ static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
|
|||
#include "nsINameSpace.h"
|
||||
#include "nsITextContent.h"
|
||||
#include "prlog.h"
|
||||
#include "nsIXMLContent.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIStyleSet.h"
|
||||
#include "nsISizeOfHandler.h"
|
||||
#include "nsStyleUtil.h"
|
||||
|
||||
//#define DEBUG_RULES
|
||||
//#define EVENT_DEBUG
|
||||
|
@ -83,9 +78,6 @@ static NS_DEFINE_IID(kIDOMCSSStyleSheetIID, NS_IDOMCSSSTYLESHEET_IID);
|
|||
static NS_DEFINE_IID(kIDOMCSSStyleRuleIID, NS_IDOMCSSSTYLERULE_IID);
|
||||
static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID);
|
||||
|
||||
static PRBool IsValidLink(nsIContent *aContent,nsString &aHREF);
|
||||
static PRBool IsSimpleXlink(nsIContent *aContent, nsString &aHREF);
|
||||
|
||||
// ----------------------
|
||||
// Rule hash key
|
||||
//
|
||||
|
@ -458,9 +450,6 @@ public:
|
|||
nsINameSpace* mNameSpace;
|
||||
PRInt32 mDefaultNameSpaceID;
|
||||
nsHashtable mRelevantAttributes;
|
||||
|
||||
static nsIIOService* gIOService;
|
||||
static nsrefcnt gRefcnt;
|
||||
};
|
||||
|
||||
|
||||
|
@ -1090,9 +1079,6 @@ static PRBool SetStyleSheetReference(nsISupports* aElement, void* aSheet)
|
|||
return PR_TRUE;
|
||||
}
|
||||
|
||||
nsIIOService* CSSStyleSheetInner::gIOService = nsnull;
|
||||
nsrefcnt CSSStyleSheetInner::gRefcnt = 0;
|
||||
|
||||
CSSStyleSheetInner::CSSStyleSheetInner(nsICSSStyleSheet* aParentSheet)
|
||||
: mSheets(),
|
||||
mURL(nsnull),
|
||||
|
@ -1102,13 +1088,6 @@ CSSStyleSheetInner::CSSStyleSheetInner(nsICSSStyleSheet* aParentSheet)
|
|||
mRelevantAttributes()
|
||||
{
|
||||
MOZ_COUNT_CTOR(CSSStyleSheetInner);
|
||||
if (gRefcnt++ == 0) {
|
||||
nsresult rv;
|
||||
rv = nsServiceManager::GetService(kIOServiceCID,
|
||||
NS_GET_IID(nsIIOService),
|
||||
(nsISupports**)&gIOService);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "can't get nsIOService");
|
||||
}
|
||||
mSheets.AppendElement(aParentSheet);
|
||||
}
|
||||
|
||||
|
@ -1146,13 +1125,6 @@ CSSStyleSheetInner::CSSStyleSheetInner(CSSStyleSheetInner& aCopy,
|
|||
mRelevantAttributes()
|
||||
{
|
||||
MOZ_COUNT_CTOR(CSSStyleSheetInner);
|
||||
if (gRefcnt++ == 0) {
|
||||
nsresult rv;
|
||||
rv = nsServiceManager::GetService(kIOServiceCID,
|
||||
NS_GET_IID(nsIIOService),
|
||||
(nsISupports**)&gIOService);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "can't get nsIOService");
|
||||
}
|
||||
mSheets.AppendElement(aParentSheet);
|
||||
NS_IF_ADDREF(mURL);
|
||||
if (aCopy.mOrderedRules) {
|
||||
|
@ -1179,12 +1151,6 @@ CSSStyleSheetInner::~CSSStyleSheetInner(void)
|
|||
NS_RELEASE(mOrderedRules);
|
||||
}
|
||||
NS_IF_RELEASE(mNameSpace);
|
||||
if (--gRefcnt == 0) {
|
||||
nsresult rv;
|
||||
rv = nsServiceManager::ReleaseService(kIOServiceCID, gIOService);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "can't release nsIOService");
|
||||
gIOService = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
CSSStyleSheetInner*
|
||||
|
@ -2831,8 +2797,6 @@ static PRBool SelectorMatches(nsIPresContext* aPresContext,
|
|||
PRBool aTestState)
|
||||
{
|
||||
PRBool result = PR_FALSE;
|
||||
PRBool tagset = PR_FALSE;
|
||||
nsIAtom* contentTag = NULL; // Make sure this is NULL for NS_IF_RELEASE
|
||||
|
||||
// Bail out early if we can
|
||||
if(kNameSpaceID_Unknown != aSelector->mNameSpace) {
|
||||
|
@ -2843,10 +2807,11 @@ static PRBool SelectorMatches(nsIPresContext* aPresContext,
|
|||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAtom> contentTag;
|
||||
|
||||
if (((nsnull == aSelector->mTag) || (
|
||||
aContent->GetTag(contentTag),
|
||||
tagset=PR_TRUE,
|
||||
aSelector->mTag == contentTag))) {
|
||||
aContent->GetTag(*getter_AddRefs(contentTag)),
|
||||
aSelector->mTag == contentTag.get()))) {
|
||||
|
||||
result = PR_TRUE;
|
||||
// namespace/tag match
|
||||
|
@ -2916,7 +2881,6 @@ static PRBool SelectorMatches(nsIPresContext* aPresContext,
|
|||
nsAtomList* pseudoClass = aSelector->mPseudoClassList;
|
||||
PRInt32 eventState = NS_EVENT_STATE_UNSPECIFIED;
|
||||
nsLinkState linkState = nsLinkState(-1); // not a link
|
||||
nsILinkHandler* linkHandler = nsnull;
|
||||
nsIEventStateManager* eventStateManager = nsnull;
|
||||
|
||||
while ((PR_TRUE == result) && (nsnull != pseudoClass)) {
|
||||
|
@ -3008,9 +2972,7 @@ static PRBool SelectorMatches(nsIPresContext* aPresContext,
|
|||
else if (IsEventPseudo(pseudoClass->mAtom)) {
|
||||
// check if the element is event-sensitive
|
||||
if (!contentTag) {
|
||||
if (aContent) {
|
||||
aContent->GetTag(contentTag);
|
||||
}
|
||||
aContent->GetTag(*getter_AddRefs(contentTag));
|
||||
}
|
||||
|
||||
#ifdef EVENT_DEBUG
|
||||
|
@ -3041,7 +3003,7 @@ static PRBool SelectorMatches(nsIPresContext* aPresContext,
|
|||
nsAutoString strPseudo, strTag;
|
||||
pseudoClass->mAtom->ToString(strPseudo);
|
||||
if (!contentTag) {
|
||||
if (aContent) aContent->GetTag(contentTag);
|
||||
aContent->GetTag(*getter_AddRefs(contentTag));
|
||||
}
|
||||
if (contentTag) {
|
||||
contentTag->ToString(strTag);
|
||||
|
@ -3065,26 +3027,10 @@ static PRBool SelectorMatches(nsIPresContext* aPresContext,
|
|||
}
|
||||
}
|
||||
else if (IsLinkPseudo(pseudoClass->mAtom)) {
|
||||
if(!tagset) {
|
||||
tagset=PR_TRUE;
|
||||
aContent->GetTag(contentTag);
|
||||
}
|
||||
|
||||
nsAutoString href;
|
||||
if (IsValidLink(aContent,href)) {
|
||||
// Now 'href' will contain a canonical URI that we can
|
||||
// look up in global history.
|
||||
if (!contentTag) aContent->GetTag(*getter_AddRefs(contentTag));
|
||||
if (nsStyleUtil::IsHTMLLink(aContent, contentTag, aPresContext, &linkState) ||
|
||||
nsStyleUtil::IsSimpleXlink(aContent, aPresContext, &linkState)) {
|
||||
if ((PR_FALSE != result) && (aTestState)) {
|
||||
if (! linkHandler) {
|
||||
aPresContext->GetLinkHandler(&linkHandler);
|
||||
if (linkHandler) {
|
||||
linkHandler->GetLinkState(href, linkState);
|
||||
}
|
||||
else {
|
||||
// no link handler? then all links are unvisited
|
||||
linkState = eLinkState_Unvisited;
|
||||
}
|
||||
}
|
||||
if (nsCSSAtoms::linkPseudo == pseudoClass->mAtom) {
|
||||
result = PRBool(eLinkState_Unvisited == linkState);
|
||||
}
|
||||
|
@ -3106,11 +3052,9 @@ static PRBool SelectorMatches(nsIPresContext* aPresContext,
|
|||
pseudoClass = pseudoClass->mNext;
|
||||
}
|
||||
|
||||
NS_IF_RELEASE(linkHandler);
|
||||
NS_IF_RELEASE(eventStateManager);
|
||||
}
|
||||
}
|
||||
NS_IF_RELEASE(contentTag);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -3769,105 +3713,3 @@ CSSRuleProcessor::GetRuleCascade(nsIAtom* aMedium)
|
|||
}
|
||||
return cascade;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
PRBool IsValidLink(nsIContent *aContent,nsString &aHREF)
|
||||
{
|
||||
NS_ASSERTION(aContent, "null arg in IsValidLink");
|
||||
|
||||
// check for:
|
||||
// - HTML ANCHOR with valid HREF
|
||||
// - HTML LINK with valid HREF
|
||||
// - HTML AREA with valid HREF
|
||||
// - Simple XLink
|
||||
|
||||
// if the content is a valid link, set the href to the canonicalized form and return TRUE
|
||||
|
||||
PRBool result = PR_FALSE;
|
||||
PRBool bIsXLink = PR_FALSE;
|
||||
nsCOMPtr<nsIDOMHTMLAnchorElement> anchor;
|
||||
nsCOMPtr<nsIDOMHTMLAreaElement> area;
|
||||
nsCOMPtr<nsIDOMHTMLLinkElement> link;
|
||||
|
||||
if ((anchor = do_QueryInterface(aContent)) ||
|
||||
(area = do_QueryInterface(aContent)) ||
|
||||
(link = do_QueryInterface(aContent))) {
|
||||
// if it is an anchor, area or link then check the href attribute
|
||||
nsresult attrState = 0;
|
||||
// make sure this anchor has a link even if we are not testing state
|
||||
// if there is no link, then this anchor is not really a linkpseudo.
|
||||
// bug=23209
|
||||
attrState = aContent->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::href, aHREF);
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE != attrState) {
|
||||
result = PR_FALSE;
|
||||
}
|
||||
else {
|
||||
if (anchor) {
|
||||
anchor->GetHref(aHREF);
|
||||
result = PR_TRUE;
|
||||
}
|
||||
else if (area) {
|
||||
area->GetHref(aHREF);
|
||||
result = PR_TRUE;
|
||||
}
|
||||
else if (link) {
|
||||
link->GetHref(aHREF);
|
||||
result = PR_TRUE;
|
||||
}
|
||||
}
|
||||
} // if anchor, area, link
|
||||
|
||||
else if ((bIsXLink = IsSimpleXlink(aContent,aHREF))) {
|
||||
// It's an XLink. Resolve it relative to its document.
|
||||
nsCOMPtr<nsIURI> baseURI = nsnull;
|
||||
nsCOMPtr<nsIHTMLContent> htmlContent = do_QueryInterface(aContent);
|
||||
if (htmlContent) {
|
||||
// XXX why do this? will nsIHTMLContent's
|
||||
// GetBaseURL() may return something different
|
||||
// than the URL of the document it lives in?
|
||||
htmlContent->GetBaseURL(*getter_AddRefs(baseURI));
|
||||
}
|
||||
else {
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
aContent->GetDocument(*getter_AddRefs(doc));
|
||||
if (doc) {
|
||||
doc->GetBaseURL(*getter_AddRefs(baseURI));
|
||||
}
|
||||
}
|
||||
|
||||
nsAutoString linkURI;
|
||||
(void) NS_MakeAbsoluteURI(linkURI, aHREF, baseURI, CSSStyleSheetInner::gIOService);
|
||||
aHREF = linkURI;
|
||||
result = PR_TRUE;
|
||||
} // if xlink
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
PRBool IsSimpleXlink(nsIContent *aContent, nsString &aHREF)
|
||||
{
|
||||
NS_ASSERTION(aContent, "invalid call to IsXlink with null content");
|
||||
|
||||
PRBool rv = PR_FALSE;
|
||||
|
||||
// set the out-param to default / empty
|
||||
aHREF.Truncate(0);
|
||||
|
||||
if (aContent) {
|
||||
// first see if we have an XML element
|
||||
nsCOMPtr<nsIXMLContent> xml(do_QueryInterface(aContent));
|
||||
if (xml) {
|
||||
// see if it is type=simple (we don't deal with other types)
|
||||
nsAutoString val;
|
||||
aContent->GetAttribute(kNameSpaceID_XLink, nsHTMLAtoms::type, val);
|
||||
if (val == NS_LITERAL_STRING("simple")) {
|
||||
// see if there is an xlink namespace'd href attribute:
|
||||
// - get it if there is, if not no big deal, it is not required for xlinks
|
||||
aContent->GetAttribute(kNameSpaceID_XLink, nsHTMLAtoms::href, aHREF);
|
||||
rv = PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
|
|
@ -33,15 +33,13 @@
|
|||
#include "nsCRT.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsIIOService.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsNetUtil.h"
|
||||
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
|
||||
#include "nsISupportsArray.h"
|
||||
#include "nsHashtable.h"
|
||||
#include "nsIHTMLContent.h"
|
||||
#include "nsIHTMLAttributes.h"
|
||||
#include "nsILink.h"
|
||||
#include "nsStyleUtil.h"
|
||||
#include "nsIStyleRuleProcessor.h"
|
||||
#include "nsIStyleRule.h"
|
||||
#include "nsIFrame.h"
|
||||
|
@ -49,7 +47,6 @@ static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
|
|||
#include "nsIMutableStyleContext.h"
|
||||
#include "nsHTMLAtoms.h"
|
||||
#include "nsIPresContext.h"
|
||||
#include "nsILinkHandler.h"
|
||||
#include "nsIEventStateManager.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsHTMLIIDs.h"
|
||||
|
@ -850,69 +847,40 @@ HTMLStyleSheetImpl::RulesMatching(nsIPresContext* aPresContext,
|
|||
styledContent->GetTag(tag);
|
||||
// if we have anchor colors, check if this is an anchor with an href
|
||||
if (tag == nsHTMLAtoms::a) {
|
||||
if ((nsnull != mLinkRule) || (nsnull != mVisitedRule)) {
|
||||
// test link state
|
||||
nsILinkHandler* linkHandler;
|
||||
|
||||
if (NS_OK == aPresContext->GetLinkHandler(&linkHandler)) {
|
||||
nsAutoString base, href;
|
||||
nsresult attrState = styledContent->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::href, href);
|
||||
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == attrState) {
|
||||
|
||||
if (! linkHandler) {
|
||||
if (mLinkRule || mVisitedRule || mActiveRule) {
|
||||
nsLinkState state;
|
||||
if (nsStyleUtil::IsHTMLLink(aContent, tag, aPresContext, &state)) {
|
||||
switch (state) {
|
||||
case eLinkState_Unvisited:
|
||||
if (nsnull != mLinkRule) {
|
||||
aResults->AppendElement(mLinkRule);
|
||||
}
|
||||
}
|
||||
else {
|
||||
nsIHTMLContent* htmlContent;
|
||||
if (NS_SUCCEEDED(styledContent->QueryInterface(kIHTMLContentIID, (void**)&htmlContent))) {
|
||||
|
||||
nsCOMPtr<nsIURI> baseURI;
|
||||
htmlContent->GetBaseURL(*getter_AddRefs(baseURI));
|
||||
|
||||
nsAutoString linkURI;
|
||||
(void) NS_MakeAbsoluteURI(linkURI, href, baseURI);
|
||||
|
||||
nsLinkState state;
|
||||
if (NS_OK == linkHandler->GetLinkState(linkURI, state)) {
|
||||
switch (state) {
|
||||
case eLinkState_Unvisited:
|
||||
if (nsnull != mLinkRule) {
|
||||
aResults->AppendElement(mLinkRule);
|
||||
}
|
||||
break;
|
||||
case eLinkState_Visited:
|
||||
if (nsnull != mVisitedRule) {
|
||||
aResults->AppendElement(mVisitedRule);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
NS_RELEASE(htmlContent);
|
||||
break;
|
||||
case eLinkState_Visited:
|
||||
if (nsnull != mVisitedRule) {
|
||||
aResults->AppendElement(mVisitedRule);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
NS_IF_RELEASE(linkHandler);
|
||||
} // end link/visited rules
|
||||
if (nsnull != mActiveRule) { // test active state of link
|
||||
nsIEventStateManager* eventStateManager;
|
||||
// No need to add to the active rule if it's not a link
|
||||
if (mActiveRule) { // test active state of link
|
||||
nsIEventStateManager* eventStateManager;
|
||||
|
||||
if ((NS_OK == aPresContext->GetEventStateManager(&eventStateManager)) &&
|
||||
(nsnull != eventStateManager)) {
|
||||
PRInt32 state;
|
||||
if (NS_OK == eventStateManager->GetContentState(aContent, state)) {
|
||||
if (0 != (state & NS_EVENT_STATE_ACTIVE)) {
|
||||
aResults->AppendElement(mActiveRule);
|
||||
if ((NS_OK == aPresContext->GetEventStateManager(&eventStateManager)) &&
|
||||
(nsnull != eventStateManager)) {
|
||||
PRInt32 state;
|
||||
if (NS_OK == eventStateManager->GetContentState(aContent, state)) {
|
||||
if (0 != (state & NS_EVENT_STATE_ACTIVE)) {
|
||||
aResults->AppendElement(mActiveRule);
|
||||
}
|
||||
}
|
||||
NS_RELEASE(eventStateManager);
|
||||
}
|
||||
}
|
||||
NS_RELEASE(eventStateManager);
|
||||
} // end active rule
|
||||
}
|
||||
} // end active rule
|
||||
} // end link/visited/active rules
|
||||
} // end A tag
|
||||
// add the quirks background compatibility rule if in quirks mode
|
||||
// and/or the Table TH rule for handling <TH> differently than <TD>
|
||||
|
|
|
@ -28,6 +28,16 @@
|
|||
#include "nsStyleConsts.h"
|
||||
#include "nsUnitConversion.h"
|
||||
|
||||
#include "nsHTMLAtoms.h"
|
||||
#include "nsILinkHandler.h"
|
||||
#include "nsILink.h"
|
||||
#include "nsIXMLContent.h"
|
||||
#include "nsIHTMLContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIPref.h"
|
||||
|
||||
|
@ -476,6 +486,129 @@ const nsStyleColor* nsStyleUtil::FindNonTransparentBackground(nsIStyleContext* a
|
|||
return result;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
PRBool nsStyleUtil::IsHTMLLink(nsIContent *aContent, nsIAtom *aTag, nsIPresContext *aPresContext, nsLinkState *aState)
|
||||
{
|
||||
NS_ASSERTION(aContent && aState, "null arg in IsHTMLLink");
|
||||
|
||||
// check for:
|
||||
// - HTML ANCHOR with valid HREF
|
||||
// - HTML LINK with valid HREF
|
||||
// - HTML AREA with valid HREF
|
||||
|
||||
PRBool result = PR_FALSE;
|
||||
|
||||
if ((aTag == nsHTMLAtoms::a) ||
|
||||
(aTag == nsHTMLAtoms::link) ||
|
||||
(aTag == nsHTMLAtoms::area)) {
|
||||
|
||||
nsCOMPtr<nsILink> link( do_QueryInterface(aContent) );
|
||||
// In XML documents, this can be null.
|
||||
if (link) {
|
||||
nsLinkState linkState;
|
||||
link->GetLinkState(linkState);
|
||||
if (linkState == eLinkState_Unknown) {
|
||||
// if it is an anchor, area or link then check the href attribute
|
||||
// make sure this anchor has a link even if we are not testing state
|
||||
// if there is no link, then this anchor is not really a linkpseudo.
|
||||
// bug=23209
|
||||
|
||||
char* href;
|
||||
link->GetHrefCString(href);
|
||||
|
||||
if (href) {
|
||||
nsILinkHandler *linkHandler = nsnull;
|
||||
aPresContext->GetLinkHandler(&linkHandler);
|
||||
if (linkHandler) {
|
||||
linkHandler->GetLinkState(href, linkState);
|
||||
NS_RELEASE(linkHandler);
|
||||
}
|
||||
else {
|
||||
// no link handler? then all links are unvisited
|
||||
linkState = eLinkState_Unvisited;
|
||||
}
|
||||
nsCRT::free(href);
|
||||
} else {
|
||||
linkState = eLinkState_NotLink;
|
||||
}
|
||||
link->SetLinkState(linkState);
|
||||
}
|
||||
if (linkState != eLinkState_NotLink) {
|
||||
*aState = linkState;
|
||||
result = PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
PRBool nsStyleUtil::IsSimpleXlink(nsIContent *aContent, nsIPresContext *aPresContext, nsLinkState *aState)
|
||||
{
|
||||
// XXX PERF This function will cause serious performance problems on
|
||||
// pages with lots of XLinks. We should be caching the visited
|
||||
// state of the XLinks. Where???
|
||||
|
||||
NS_ASSERTION(aContent && aState, "invalid call to IsXlink with null content");
|
||||
|
||||
PRBool rv = PR_FALSE;
|
||||
|
||||
if (aContent && aState) {
|
||||
// first see if we have an XML element
|
||||
nsCOMPtr<nsIXMLContent> xml(do_QueryInterface(aContent));
|
||||
if (xml) {
|
||||
// see if it is type=simple (we don't deal with other types)
|
||||
nsAutoString val;
|
||||
aContent->GetAttribute(kNameSpaceID_XLink, nsHTMLAtoms::type, val);
|
||||
if (val == NS_LITERAL_STRING("simple")) {
|
||||
// see if there is an xlink namespace'd href attribute:
|
||||
// - get it if there is, if not no big deal, it is not required for xlinks
|
||||
// is it bad to re-use val here?
|
||||
aContent->GetAttribute(kNameSpaceID_XLink, nsHTMLAtoms::href, val);
|
||||
|
||||
// It's an XLink. Resolve it relative to its document.
|
||||
nsCOMPtr<nsIURI> baseURI;
|
||||
nsCOMPtr<nsIHTMLContent> htmlContent = do_QueryInterface(aContent);
|
||||
if (htmlContent) {
|
||||
// XXX why do this? will nsIHTMLContent's
|
||||
// GetBaseURL() may return something different
|
||||
// than the URL of the document it lives in?
|
||||
htmlContent->GetBaseURL(*getter_AddRefs(baseURI));
|
||||
}
|
||||
else {
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
aContent->GetDocument(*getter_AddRefs(doc));
|
||||
if (doc) {
|
||||
doc->GetBaseURL(*getter_AddRefs(baseURI));
|
||||
}
|
||||
}
|
||||
|
||||
// convert here, rather than twice in NS_MakeAbsoluteURI and
|
||||
// back again
|
||||
char * href = val.ToNewCString();
|
||||
char * absHREF = nsnull;
|
||||
(void) NS_MakeAbsoluteURI(&absHREF, href, baseURI);
|
||||
nsCRT::free(href);
|
||||
|
||||
nsILinkHandler *linkHandler = nsnull;
|
||||
aPresContext->GetLinkHandler(&linkHandler);
|
||||
if (linkHandler) {
|
||||
linkHandler->GetLinkState(absHREF, *aState);
|
||||
NS_RELEASE(linkHandler);
|
||||
}
|
||||
else {
|
||||
// no link handler? then all links are unvisited
|
||||
*aState = eLinkState_Unvisited;
|
||||
}
|
||||
nsCRT::free(absHREF);
|
||||
|
||||
rv = PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
|
|
|
@ -28,6 +28,16 @@
|
|||
#include "nsStyleConsts.h"
|
||||
#include "nsUnitConversion.h"
|
||||
|
||||
#include "nsHTMLAtoms.h"
|
||||
#include "nsILinkHandler.h"
|
||||
#include "nsILink.h"
|
||||
#include "nsIXMLContent.h"
|
||||
#include "nsIHTMLContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIPref.h"
|
||||
|
||||
|
@ -476,6 +486,129 @@ const nsStyleColor* nsStyleUtil::FindNonTransparentBackground(nsIStyleContext* a
|
|||
return result;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
PRBool nsStyleUtil::IsHTMLLink(nsIContent *aContent, nsIAtom *aTag, nsIPresContext *aPresContext, nsLinkState *aState)
|
||||
{
|
||||
NS_ASSERTION(aContent && aState, "null arg in IsHTMLLink");
|
||||
|
||||
// check for:
|
||||
// - HTML ANCHOR with valid HREF
|
||||
// - HTML LINK with valid HREF
|
||||
// - HTML AREA with valid HREF
|
||||
|
||||
PRBool result = PR_FALSE;
|
||||
|
||||
if ((aTag == nsHTMLAtoms::a) ||
|
||||
(aTag == nsHTMLAtoms::link) ||
|
||||
(aTag == nsHTMLAtoms::area)) {
|
||||
|
||||
nsCOMPtr<nsILink> link( do_QueryInterface(aContent) );
|
||||
// In XML documents, this can be null.
|
||||
if (link) {
|
||||
nsLinkState linkState;
|
||||
link->GetLinkState(linkState);
|
||||
if (linkState == eLinkState_Unknown) {
|
||||
// if it is an anchor, area or link then check the href attribute
|
||||
// make sure this anchor has a link even if we are not testing state
|
||||
// if there is no link, then this anchor is not really a linkpseudo.
|
||||
// bug=23209
|
||||
|
||||
char* href;
|
||||
link->GetHrefCString(href);
|
||||
|
||||
if (href) {
|
||||
nsILinkHandler *linkHandler = nsnull;
|
||||
aPresContext->GetLinkHandler(&linkHandler);
|
||||
if (linkHandler) {
|
||||
linkHandler->GetLinkState(href, linkState);
|
||||
NS_RELEASE(linkHandler);
|
||||
}
|
||||
else {
|
||||
// no link handler? then all links are unvisited
|
||||
linkState = eLinkState_Unvisited;
|
||||
}
|
||||
nsCRT::free(href);
|
||||
} else {
|
||||
linkState = eLinkState_NotLink;
|
||||
}
|
||||
link->SetLinkState(linkState);
|
||||
}
|
||||
if (linkState != eLinkState_NotLink) {
|
||||
*aState = linkState;
|
||||
result = PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
PRBool nsStyleUtil::IsSimpleXlink(nsIContent *aContent, nsIPresContext *aPresContext, nsLinkState *aState)
|
||||
{
|
||||
// XXX PERF This function will cause serious performance problems on
|
||||
// pages with lots of XLinks. We should be caching the visited
|
||||
// state of the XLinks. Where???
|
||||
|
||||
NS_ASSERTION(aContent && aState, "invalid call to IsXlink with null content");
|
||||
|
||||
PRBool rv = PR_FALSE;
|
||||
|
||||
if (aContent && aState) {
|
||||
// first see if we have an XML element
|
||||
nsCOMPtr<nsIXMLContent> xml(do_QueryInterface(aContent));
|
||||
if (xml) {
|
||||
// see if it is type=simple (we don't deal with other types)
|
||||
nsAutoString val;
|
||||
aContent->GetAttribute(kNameSpaceID_XLink, nsHTMLAtoms::type, val);
|
||||
if (val == NS_LITERAL_STRING("simple")) {
|
||||
// see if there is an xlink namespace'd href attribute:
|
||||
// - get it if there is, if not no big deal, it is not required for xlinks
|
||||
// is it bad to re-use val here?
|
||||
aContent->GetAttribute(kNameSpaceID_XLink, nsHTMLAtoms::href, val);
|
||||
|
||||
// It's an XLink. Resolve it relative to its document.
|
||||
nsCOMPtr<nsIURI> baseURI;
|
||||
nsCOMPtr<nsIHTMLContent> htmlContent = do_QueryInterface(aContent);
|
||||
if (htmlContent) {
|
||||
// XXX why do this? will nsIHTMLContent's
|
||||
// GetBaseURL() may return something different
|
||||
// than the URL of the document it lives in?
|
||||
htmlContent->GetBaseURL(*getter_AddRefs(baseURI));
|
||||
}
|
||||
else {
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
aContent->GetDocument(*getter_AddRefs(doc));
|
||||
if (doc) {
|
||||
doc->GetBaseURL(*getter_AddRefs(baseURI));
|
||||
}
|
||||
}
|
||||
|
||||
// convert here, rather than twice in NS_MakeAbsoluteURI and
|
||||
// back again
|
||||
char * href = val.ToNewCString();
|
||||
char * absHREF = nsnull;
|
||||
(void) NS_MakeAbsoluteURI(&absHREF, href, baseURI);
|
||||
nsCRT::free(href);
|
||||
|
||||
nsILinkHandler *linkHandler = nsnull;
|
||||
aPresContext->GetLinkHandler(&linkHandler);
|
||||
if (linkHandler) {
|
||||
linkHandler->GetLinkState(absHREF, *aState);
|
||||
NS_RELEASE(linkHandler);
|
||||
}
|
||||
else {
|
||||
// no link handler? then all links are unvisited
|
||||
*aState = eLinkState_Unvisited;
|
||||
}
|
||||
nsCRT::free(absHREF);
|
||||
|
||||
rv = PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
|
|
|
@ -855,17 +855,14 @@ nsWebShell::OnOverLink(nsIContent* aContent,
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWebShell::GetLinkState(const nsString& aLinkURI, nsLinkState& aState)
|
||||
nsWebShell::GetLinkState(const char* aLinkURI, nsLinkState& aState)
|
||||
{
|
||||
aState = eLinkState_Unvisited;
|
||||
|
||||
if(mGlobalHistory)
|
||||
{
|
||||
nsCAutoString url;
|
||||
url.AssignWithConversion(aLinkURI.GetUnicode());
|
||||
|
||||
PRInt64 lastVisitDate;
|
||||
NS_ENSURE_SUCCESS(mGlobalHistory->GetLastVisitDate(url.GetBuffer(),
|
||||
NS_ENSURE_SUCCESS(mGlobalHistory->GetLastVisitDate(aLinkURI,
|
||||
&lastVisitDate), NS_ERROR_FAILURE);
|
||||
|
||||
// a last-visit-date of zero means we've never seen it before; so
|
||||
|
|
|
@ -92,7 +92,7 @@ public:
|
|||
NS_IMETHOD OnOverLink(nsIContent* aContent,
|
||||
const PRUnichar* aURLSpec,
|
||||
const PRUnichar* aTargetSpec);
|
||||
NS_IMETHOD GetLinkState(const nsString& aLinkURI, nsLinkState& aState);
|
||||
NS_IMETHOD GetLinkState(const char* aLinkURI, nsLinkState& aState);
|
||||
|
||||
|
||||
NS_IMETHOD FindNext(const PRUnichar * aSearchStr, PRBool aMatchCase, PRBool aSearchDown, PRBool &aIsFound);
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "nsIDOMEventReceiver.h"
|
||||
#include "nsIHTMLContent.h"
|
||||
#include "nsGenericHTMLElement.h"
|
||||
#include "nsILink.h"
|
||||
#include "nsHTMLAtoms.h"
|
||||
#include "nsHTMLIIDs.h"
|
||||
#include "nsIStyleContext.h"
|
||||
|
@ -56,6 +57,7 @@ static NS_DEFINE_IID(kIDOMHTMLAnchorElementIID, NS_IDOMHTMLANCHORELEMENT_IID);
|
|||
class nsHTMLAnchorElement : public nsIDOMHTMLAnchorElement,
|
||||
public nsIDOMNSHTMLAnchorElement,
|
||||
public nsIJSScriptObject,
|
||||
public nsILink,
|
||||
public nsIHTMLContent
|
||||
{
|
||||
public:
|
||||
|
@ -115,6 +117,11 @@ public:
|
|||
// nsIJSScriptObject
|
||||
NS_IMPL_IJSSCRIPTOBJECT_USING_GENERIC(mInner)
|
||||
|
||||
// nsILink
|
||||
NS_IMETHOD GetLinkState(nsLinkState &aState);
|
||||
NS_IMETHOD SetLinkState(nsLinkState aState);
|
||||
NS_IMETHOD GetHrefCString(char* &aBuf);
|
||||
|
||||
// nsIContent
|
||||
//NS_IMPL_ICONTENT_NO_FOCUS_USING_GENERIC(mInner)
|
||||
NS_IMPL_ICONTENT_NO_SETPARENT_NO_SETDOCUMENT_NO_FOCUS_USING_GENERIC(mInner)
|
||||
|
@ -126,10 +133,8 @@ protected:
|
|||
nsresult RegUnRegAccessKey(PRBool aDoReg);
|
||||
nsGenericHTMLContainerElement mInner;
|
||||
|
||||
// The "cached" canonical URL that the anchor really points to. This
|
||||
// value is derived on-demand when someone asks for the ".href"
|
||||
// property.
|
||||
char* mCanonicalHref;
|
||||
// The cached visited state
|
||||
nsLinkState mLinkState;
|
||||
};
|
||||
|
||||
nsresult
|
||||
|
@ -147,19 +152,16 @@ NS_NewHTMLAnchorElement(nsIHTMLContent** aInstancePtrResult,
|
|||
}
|
||||
|
||||
nsHTMLAnchorElement::nsHTMLAnchorElement(nsINodeInfo *aNodeInfo)
|
||||
: mCanonicalHref(nsnull)
|
||||
: mLinkState(eLinkState_Unknown)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
mInner.Init(this, aNodeInfo);
|
||||
nsHTMLUtils::AddRef();
|
||||
nsHTMLUtils::AddRef(); // for GetHrefCString
|
||||
}
|
||||
|
||||
nsHTMLAnchorElement::~nsHTMLAnchorElement()
|
||||
{
|
||||
if (mCanonicalHref)
|
||||
nsCRT::free(mCanonicalHref);
|
||||
|
||||
nsHTMLUtils::Release();
|
||||
nsHTMLUtils::Release(); // for GetHrefCString
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF(nsHTMLAnchorElement)
|
||||
|
@ -181,6 +183,11 @@ nsHTMLAnchorElement::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
|||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
else if (aIID.Equals(NS_GET_IID(nsILink))) {
|
||||
*aInstancePtr = (void*)(nsILink*) this;
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
|
||||
|
@ -415,46 +422,23 @@ nsHTMLAnchorElement::HandleDOMEvent(nsIPresContext* aPresContext,
|
|||
NS_IMETHODIMP
|
||||
nsHTMLAnchorElement::GetHref(nsString& aValue)
|
||||
{
|
||||
// Return the canonical URI that this link refers to.
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (! mCanonicalHref) {
|
||||
// We don't have a cached value: compute it from scratch.
|
||||
|
||||
// Get href= attribute (relative URL).
|
||||
nsAutoString relURLSpec;
|
||||
mInner.GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::href, relURLSpec);
|
||||
|
||||
if (relURLSpec.Length()) {
|
||||
// Get base URL.
|
||||
nsCOMPtr<nsIURI> baseURL;
|
||||
mInner.GetBaseURL(*getter_AddRefs(baseURL));
|
||||
|
||||
if (baseURL) {
|
||||
// Get absolute URL.
|
||||
NS_MakeAbsoluteURIWithCharset(&mCanonicalHref, relURLSpec, mInner.mDocument, baseURL,
|
||||
nsHTMLUtils::IOService, nsHTMLUtils::CharsetMgr);
|
||||
}
|
||||
else {
|
||||
// Absolute URL is same as relative URL.
|
||||
mCanonicalHref = relURLSpec.ToNewUTF8String();
|
||||
}
|
||||
}
|
||||
char *buf;
|
||||
nsresult rv = GetHrefCString(buf);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (buf) {
|
||||
aValue.AssignWithConversion(buf);
|
||||
nsCRT::free(buf);
|
||||
}
|
||||
|
||||
aValue.AssignWithConversion(mCanonicalHref);
|
||||
return rv;
|
||||
// NS_IMPL_STRING_ATTR does nothing where we have (buf == null)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLAnchorElement::SetHref(const nsString& aValue)
|
||||
{
|
||||
if (mCanonicalHref) {
|
||||
// Clobber our "cache", so we'll recompute it the next time
|
||||
// somebody asks for it.
|
||||
nsCRT::free(mCanonicalHref);
|
||||
mCanonicalHref = nsnull;
|
||||
}
|
||||
// Clobber our "cache", so we'll recompute it the next time
|
||||
// somebody asks for it.
|
||||
mLinkState = eLinkState_Unknown;
|
||||
|
||||
return mInner.SetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::href, aValue, PR_TRUE);
|
||||
}
|
||||
|
@ -679,3 +663,46 @@ nsHTMLAnchorElement::GetText(nsString& aText)
|
|||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLAnchorElement::GetLinkState(nsLinkState &aState)
|
||||
{
|
||||
aState = mLinkState;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLAnchorElement::SetLinkState(nsLinkState aState)
|
||||
{
|
||||
mLinkState = aState;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLAnchorElement::GetHrefCString(char* &aBuf)
|
||||
{
|
||||
// Get href= attribute (relative URL).
|
||||
nsAutoString relURLSpec;
|
||||
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE ==
|
||||
mInner.GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::href, relURLSpec)) {
|
||||
// Get base URL.
|
||||
nsCOMPtr<nsIURI> baseURL;
|
||||
mInner.GetBaseURL(*getter_AddRefs(baseURL));
|
||||
|
||||
if (baseURL) {
|
||||
// Get absolute URL.
|
||||
NS_MakeAbsoluteURIWithCharset(&aBuf, relURLSpec, mInner.mDocument, baseURL,
|
||||
nsHTMLUtils::IOService, nsHTMLUtils::CharsetMgr);
|
||||
}
|
||||
else {
|
||||
// Absolute URL is same as relative URL.
|
||||
aBuf = relURLSpec.ToNewUTF8String();
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Absolute URL is null to say we have no HREF.
|
||||
aBuf = nsnull;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
#include "nsIDOMEventReceiver.h"
|
||||
#include "nsIHTMLContent.h"
|
||||
#include "nsGenericHTMLElement.h"
|
||||
#include "nsILink.h"
|
||||
#include "nsHTMLAtoms.h"
|
||||
#include "nsHTMLUtils.h"
|
||||
#include "nsHTMLIIDs.h"
|
||||
#include "nsIStyleContext.h"
|
||||
#include "nsIMutableStyleContext.h"
|
||||
|
@ -35,12 +35,14 @@
|
|||
#include "nsIEventStateManager.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsHTMLUtils.h"
|
||||
|
||||
static NS_DEFINE_IID(kIDOMHTMLAreaElementIID, NS_IDOMHTMLAREAELEMENT_IID);
|
||||
|
||||
class nsHTMLAreaElement : public nsIDOMHTMLAreaElement,
|
||||
public nsIDOMNSHTMLAreaElement,
|
||||
public nsIJSScriptObject,
|
||||
public nsILink,
|
||||
public nsIHTMLContent
|
||||
{
|
||||
public:
|
||||
|
@ -89,6 +91,11 @@ public:
|
|||
// nsIJSScriptObject
|
||||
NS_IMPL_IJSSCRIPTOBJECT_USING_GENERIC(mInner)
|
||||
|
||||
// nsILink
|
||||
NS_IMETHOD GetLinkState(nsLinkState &aState);
|
||||
NS_IMETHOD SetLinkState(nsLinkState aState);
|
||||
NS_IMETHOD GetHrefCString(char* &aBuf);
|
||||
|
||||
// nsIContent
|
||||
NS_IMPL_ICONTENT_NO_FOCUS_USING_GENERIC(mInner)
|
||||
|
||||
|
@ -97,6 +104,9 @@ public:
|
|||
|
||||
protected:
|
||||
nsGenericHTMLLeafElement mInner;
|
||||
|
||||
// The cached visited state
|
||||
nsLinkState mLinkState;
|
||||
};
|
||||
|
||||
nsresult
|
||||
|
@ -115,13 +125,16 @@ NS_NewHTMLAreaElement(nsIHTMLContent** aInstancePtrResult,
|
|||
|
||||
|
||||
nsHTMLAreaElement::nsHTMLAreaElement(nsINodeInfo *aNodeInfo)
|
||||
: mLinkState(eLinkState_Unknown)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
mInner.Init(this, aNodeInfo);
|
||||
nsHTMLUtils::AddRef(); // for GetHrefCString
|
||||
}
|
||||
|
||||
nsHTMLAreaElement::~nsHTMLAreaElement()
|
||||
{
|
||||
nsHTMLUtils::Release(); // for GetHrefCString
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF(nsHTMLAreaElement)
|
||||
|
@ -144,6 +157,11 @@ nsHTMLAreaElement::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
|||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
else if (aIID.Equals(NS_GET_IID(nsILink))) {
|
||||
*aInstancePtr = (void*)(nsILink*) this;
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
|
||||
|
@ -257,42 +275,28 @@ nsHTMLAreaElement::RemoveFocus(nsIPresContext* aPresContext)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLAreaElement::GetHref(nsString& aValue)
|
||||
{
|
||||
// Return the canonical URI that this link refers to.
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
// Get href= attribute (relative URL).
|
||||
nsAutoString relURLSpec;
|
||||
mInner.GetAttribute(kNameSpaceID_None, nsHTMLAtoms::href, relURLSpec);
|
||||
|
||||
if (relURLSpec.Length()) {
|
||||
// Get base URL.
|
||||
nsCOMPtr<nsIURI> baseURL;
|
||||
mInner.GetBaseURL(*getter_AddRefs(baseURL));
|
||||
|
||||
if (baseURL) {
|
||||
// Get absolute URL.
|
||||
nsXPIDLCString absURI;
|
||||
NS_MakeAbsoluteURIWithCharset(getter_Copies(absURI), relURLSpec, mInner.mDocument, baseURL,
|
||||
nsHTMLUtils::IOService, nsHTMLUtils::CharsetMgr);
|
||||
aValue.AssignWithConversion(absURI);
|
||||
}
|
||||
else {
|
||||
// Absolute URL is same as relative URL.
|
||||
aValue = relURLSpec;
|
||||
}
|
||||
char *buf;
|
||||
nsresult rv = GetHrefCString(buf);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (buf) {
|
||||
aValue.AssignWithConversion(buf);
|
||||
nsCRT::free(buf);
|
||||
}
|
||||
|
||||
return rv;
|
||||
// NS_IMPL_STRING_ATTR does nothing where we have (buf == null)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLAreaElement::SetHref(const nsString& aValue)
|
||||
{
|
||||
return mInner.SetAttribute(kNameSpaceID_None, nsHTMLAtoms::href, aValue, PR_TRUE);
|
||||
// Clobber our "cache", so we'll recompute it the next time
|
||||
// somebody asks for it.
|
||||
mLinkState = eLinkState_Unknown;
|
||||
|
||||
return mInner.SetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::href, aValue, PR_TRUE);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -498,3 +502,47 @@ nsHTMLAreaElement::GetHash(nsString& aHash)
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLAreaElement::GetLinkState(nsLinkState &aState)
|
||||
{
|
||||
aState = mLinkState;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLAreaElement::SetLinkState(nsLinkState aState)
|
||||
{
|
||||
mLinkState = aState;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLAreaElement::GetHrefCString(char* &aBuf)
|
||||
{
|
||||
// Get href= attribute (relative URL).
|
||||
nsAutoString relURLSpec;
|
||||
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE ==
|
||||
mInner.GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::href, relURLSpec)) {
|
||||
// Get base URL.
|
||||
nsCOMPtr<nsIURI> baseURL;
|
||||
mInner.GetBaseURL(*getter_AddRefs(baseURL));
|
||||
|
||||
if (baseURL) {
|
||||
// Get absolute URL.
|
||||
NS_MakeAbsoluteURIWithCharset(&aBuf, relURLSpec, mInner.mDocument, baseURL,
|
||||
nsHTMLUtils::IOService, nsHTMLUtils::CharsetMgr);
|
||||
}
|
||||
else {
|
||||
// Absolute URL is same as relative URL.
|
||||
aBuf = relURLSpec.ToNewUTF8String();
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Absolute URL is empty because we have no HREF.
|
||||
aBuf = PL_strdup(""); // use a dummy empty string
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "nsIDOMEventReceiver.h"
|
||||
#include "nsIHTMLContent.h"
|
||||
#include "nsGenericHTMLElement.h"
|
||||
#include "nsILink.h"
|
||||
#include "nsHTMLAtoms.h"
|
||||
#include "nsHTMLIIDs.h"
|
||||
#include "nsIStyleContext.h"
|
||||
|
@ -33,6 +34,8 @@
|
|||
#include "nsIDOMStyleSheet.h"
|
||||
#include "nsIStyleSheet.h"
|
||||
#include "nsIStyleSheetLinkingElement.h"
|
||||
#include "nsHTMLUtils.h"
|
||||
#include "nsIURL.h"
|
||||
|
||||
static NS_DEFINE_IID(kIDOMHTMLLinkElementIID, NS_IDOMHTMLLINKELEMENT_IID);
|
||||
static NS_DEFINE_IID(kIStyleSheetLinkingElementIID, NS_ISTYLESHEETLINKINGELEMENT_IID);
|
||||
|
@ -40,6 +43,7 @@ static NS_DEFINE_IID(kIDOMStyleSheetIID, NS_IDOMSTYLESHEET_IID);
|
|||
|
||||
class nsHTMLLinkElement : public nsIDOMHTMLLinkElement,
|
||||
public nsIJSScriptObject,
|
||||
public nsILink,
|
||||
public nsIHTMLContent,
|
||||
public nsIStyleSheetLinkingElement
|
||||
{
|
||||
|
@ -82,6 +86,11 @@ public:
|
|||
// nsIJSScriptObject
|
||||
NS_IMPL_IJSSCRIPTOBJECT_USING_GENERIC(mInner)
|
||||
|
||||
// nsILink
|
||||
NS_IMETHOD GetLinkState(nsLinkState &aState);
|
||||
NS_IMETHOD SetLinkState(nsLinkState aState);
|
||||
NS_IMETHOD GetHrefCString(char* &aBuf);
|
||||
|
||||
// nsIContent
|
||||
NS_IMPL_ICONTENT_USING_GENERIC(mInner)
|
||||
|
||||
|
@ -95,6 +104,9 @@ public:
|
|||
protected:
|
||||
nsGenericHTMLLeafElement mInner;
|
||||
nsIStyleSheet* mStyleSheet;
|
||||
|
||||
// The cached visited state
|
||||
nsLinkState mLinkState;
|
||||
};
|
||||
|
||||
nsresult
|
||||
|
@ -113,15 +125,18 @@ NS_NewHTMLLinkElement(nsIHTMLContent** aInstancePtrResult,
|
|||
|
||||
|
||||
nsHTMLLinkElement::nsHTMLLinkElement(nsINodeInfo *aNodeInfo)
|
||||
: mLinkState(eLinkState_Unknown)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
mInner.Init(this, aNodeInfo);
|
||||
mStyleSheet = nsnull;
|
||||
nsHTMLUtils::AddRef(); // for GetHrefCString
|
||||
}
|
||||
|
||||
nsHTMLLinkElement::~nsHTMLLinkElement()
|
||||
{
|
||||
NS_IF_RELEASE(mStyleSheet);
|
||||
nsHTMLUtils::Release(); // for GetHrefCString
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF(nsHTMLLinkElement)
|
||||
|
@ -144,6 +159,11 @@ nsHTMLLinkElement::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
|||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
if (aIID.Equals(NS_GET_IID(nsILink))) {
|
||||
*aInstancePtr = (void*)(nsILink*) this;
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
|
||||
|
@ -198,7 +218,6 @@ nsHTMLLinkElement::SetDisabled(PRBool aDisabled)
|
|||
}
|
||||
|
||||
NS_IMPL_STRING_ATTR(nsHTMLLinkElement, Charset, charset)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLLinkElement, Href, href)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLLinkElement, Hreflang, hreflang)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLLinkElement, Media, media)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLLinkElement, Rel, rel)
|
||||
|
@ -206,6 +225,30 @@ NS_IMPL_STRING_ATTR(nsHTMLLinkElement, Rev, rev)
|
|||
NS_IMPL_STRING_ATTR(nsHTMLLinkElement, Target, target)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLLinkElement, Type, type)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLLinkElement::GetHref(nsString& aValue)
|
||||
{
|
||||
char *buf;
|
||||
nsresult rv = GetHrefCString(buf);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (buf) {
|
||||
aValue.AssignWithConversion(buf);
|
||||
nsCRT::free(buf);
|
||||
}
|
||||
// NS_IMPL_STRING_ATTR does nothing where we have (buf == null)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLLinkElement::SetHref(const nsString& aValue)
|
||||
{
|
||||
// Clobber our "cache", so we'll recompute it the next time
|
||||
// somebody asks for it.
|
||||
mLinkState = eLinkState_Unknown;
|
||||
|
||||
return mInner.SetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::href, aValue, PR_TRUE);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLLinkElement::SetStyleSheet(nsIStyleSheet* aStyleSheet)
|
||||
{
|
||||
|
@ -289,3 +332,47 @@ nsHTMLLinkElement::SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const
|
|||
{
|
||||
return mInner.SizeOf(aSizer, aResult, sizeof(*this));
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLLinkElement::GetLinkState(nsLinkState &aState)
|
||||
{
|
||||
aState = mLinkState;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLLinkElement::SetLinkState(nsLinkState aState)
|
||||
{
|
||||
mLinkState = aState;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLLinkElement::GetHrefCString(char* &aBuf)
|
||||
{
|
||||
// Get href= attribute (relative URL).
|
||||
nsAutoString relURLSpec;
|
||||
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE ==
|
||||
mInner.GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::href, relURLSpec)) {
|
||||
// Get base URL.
|
||||
nsCOMPtr<nsIURI> baseURL;
|
||||
mInner.GetBaseURL(*getter_AddRefs(baseURL));
|
||||
|
||||
if (baseURL) {
|
||||
// Get absolute URL.
|
||||
NS_MakeAbsoluteURIWithCharset(&aBuf, relURLSpec, mInner.mDocument, baseURL,
|
||||
nsHTMLUtils::IOService, nsHTMLUtils::CharsetMgr);
|
||||
}
|
||||
else {
|
||||
// Absolute URL is same as relative URL.
|
||||
aBuf = relURLSpec.ToNewUTF8String();
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Absolute URL is empty because we have no HREF.
|
||||
aBuf = PL_strdup(""); // use a dummy empty string
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -1,63 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
#ifndef nsStyleUtil_h___
|
||||
#define nsStyleUtil_h___
|
||||
|
||||
#include "nslayout.h"
|
||||
#include "nsCoord.h"
|
||||
#include "nsIPresContext.h"
|
||||
|
||||
class nsIStyleContext;
|
||||
struct nsStyleColor;
|
||||
|
||||
enum nsFontSizeType {
|
||||
eFontSize_HTML = 1,
|
||||
eFontSize_CSS = 2
|
||||
};
|
||||
|
||||
|
||||
// Style utility functions
|
||||
class nsStyleUtil {
|
||||
public:
|
||||
|
||||
static float GetScalingFactor(PRInt32 aScaler);
|
||||
|
||||
static nscoord CalcFontPointSize(PRInt32 aHTMLSize, PRInt32 aBasePointSize,
|
||||
float aScalingFactor, nsIPresContext* aPresContext,
|
||||
nsFontSizeType aFontSizeType = eFontSize_HTML);
|
||||
|
||||
static PRInt32 FindNextSmallerFontSize(nscoord aFontSize, PRInt32 aBasePointSize,
|
||||
float aScalingFactor, nsIPresContext* aPresContext,
|
||||
nsFontSizeType aFontSizeType = eFontSize_HTML);
|
||||
|
||||
static PRInt32 FindNextLargerFontSize(nscoord aFontSize, PRInt32 aBasePointSize,
|
||||
float aScalingFactor, nsIPresContext* aPresContext,
|
||||
nsFontSizeType aFontSizeType = eFontSize_HTML);
|
||||
|
||||
static PRInt32 ConstrainFontWeight(PRInt32 aWeight);
|
||||
|
||||
static const nsStyleColor* FindNonTransparentBackground(nsIStyleContext* aContext,
|
||||
PRBool aStartAtParent = PR_FALSE);
|
||||
};
|
||||
|
||||
|
||||
#endif /* nsStyleUtil_h___ */
|
|
@ -27,11 +27,7 @@
|
|||
#include "nsCRT.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsIIOService.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsNetUtil.h"
|
||||
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
|
||||
#include "nsISupportsArray.h"
|
||||
#include "nsHashtable.h"
|
||||
#include "nsICSSStyleRuleProcessor.h"
|
||||
|
@ -41,7 +37,6 @@ static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
|
|||
#include "nsIHTMLContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIPresContext.h"
|
||||
#include "nsILinkHandler.h"
|
||||
#include "nsIEventStateManager.h"
|
||||
#include "nsHTMLAtoms.h"
|
||||
#include "nsLayoutAtoms.h"
|
||||
|
@ -67,10 +62,10 @@ static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
|
|||
#include "nsINameSpace.h"
|
||||
#include "nsITextContent.h"
|
||||
#include "prlog.h"
|
||||
#include "nsIXMLContent.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIStyleSet.h"
|
||||
#include "nsISizeOfHandler.h"
|
||||
#include "nsStyleUtil.h"
|
||||
|
||||
//#define DEBUG_RULES
|
||||
//#define EVENT_DEBUG
|
||||
|
@ -83,9 +78,6 @@ static NS_DEFINE_IID(kIDOMCSSStyleSheetIID, NS_IDOMCSSSTYLESHEET_IID);
|
|||
static NS_DEFINE_IID(kIDOMCSSStyleRuleIID, NS_IDOMCSSSTYLERULE_IID);
|
||||
static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID);
|
||||
|
||||
static PRBool IsValidLink(nsIContent *aContent,nsString &aHREF);
|
||||
static PRBool IsSimpleXlink(nsIContent *aContent, nsString &aHREF);
|
||||
|
||||
// ----------------------
|
||||
// Rule hash key
|
||||
//
|
||||
|
@ -458,9 +450,6 @@ public:
|
|||
nsINameSpace* mNameSpace;
|
||||
PRInt32 mDefaultNameSpaceID;
|
||||
nsHashtable mRelevantAttributes;
|
||||
|
||||
static nsIIOService* gIOService;
|
||||
static nsrefcnt gRefcnt;
|
||||
};
|
||||
|
||||
|
||||
|
@ -1090,9 +1079,6 @@ static PRBool SetStyleSheetReference(nsISupports* aElement, void* aSheet)
|
|||
return PR_TRUE;
|
||||
}
|
||||
|
||||
nsIIOService* CSSStyleSheetInner::gIOService = nsnull;
|
||||
nsrefcnt CSSStyleSheetInner::gRefcnt = 0;
|
||||
|
||||
CSSStyleSheetInner::CSSStyleSheetInner(nsICSSStyleSheet* aParentSheet)
|
||||
: mSheets(),
|
||||
mURL(nsnull),
|
||||
|
@ -1102,13 +1088,6 @@ CSSStyleSheetInner::CSSStyleSheetInner(nsICSSStyleSheet* aParentSheet)
|
|||
mRelevantAttributes()
|
||||
{
|
||||
MOZ_COUNT_CTOR(CSSStyleSheetInner);
|
||||
if (gRefcnt++ == 0) {
|
||||
nsresult rv;
|
||||
rv = nsServiceManager::GetService(kIOServiceCID,
|
||||
NS_GET_IID(nsIIOService),
|
||||
(nsISupports**)&gIOService);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "can't get nsIOService");
|
||||
}
|
||||
mSheets.AppendElement(aParentSheet);
|
||||
}
|
||||
|
||||
|
@ -1146,13 +1125,6 @@ CSSStyleSheetInner::CSSStyleSheetInner(CSSStyleSheetInner& aCopy,
|
|||
mRelevantAttributes()
|
||||
{
|
||||
MOZ_COUNT_CTOR(CSSStyleSheetInner);
|
||||
if (gRefcnt++ == 0) {
|
||||
nsresult rv;
|
||||
rv = nsServiceManager::GetService(kIOServiceCID,
|
||||
NS_GET_IID(nsIIOService),
|
||||
(nsISupports**)&gIOService);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "can't get nsIOService");
|
||||
}
|
||||
mSheets.AppendElement(aParentSheet);
|
||||
NS_IF_ADDREF(mURL);
|
||||
if (aCopy.mOrderedRules) {
|
||||
|
@ -1179,12 +1151,6 @@ CSSStyleSheetInner::~CSSStyleSheetInner(void)
|
|||
NS_RELEASE(mOrderedRules);
|
||||
}
|
||||
NS_IF_RELEASE(mNameSpace);
|
||||
if (--gRefcnt == 0) {
|
||||
nsresult rv;
|
||||
rv = nsServiceManager::ReleaseService(kIOServiceCID, gIOService);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "can't release nsIOService");
|
||||
gIOService = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
CSSStyleSheetInner*
|
||||
|
@ -2831,8 +2797,6 @@ static PRBool SelectorMatches(nsIPresContext* aPresContext,
|
|||
PRBool aTestState)
|
||||
{
|
||||
PRBool result = PR_FALSE;
|
||||
PRBool tagset = PR_FALSE;
|
||||
nsIAtom* contentTag = NULL; // Make sure this is NULL for NS_IF_RELEASE
|
||||
|
||||
// Bail out early if we can
|
||||
if(kNameSpaceID_Unknown != aSelector->mNameSpace) {
|
||||
|
@ -2843,10 +2807,11 @@ static PRBool SelectorMatches(nsIPresContext* aPresContext,
|
|||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAtom> contentTag;
|
||||
|
||||
if (((nsnull == aSelector->mTag) || (
|
||||
aContent->GetTag(contentTag),
|
||||
tagset=PR_TRUE,
|
||||
aSelector->mTag == contentTag))) {
|
||||
aContent->GetTag(*getter_AddRefs(contentTag)),
|
||||
aSelector->mTag == contentTag.get()))) {
|
||||
|
||||
result = PR_TRUE;
|
||||
// namespace/tag match
|
||||
|
@ -2916,7 +2881,6 @@ static PRBool SelectorMatches(nsIPresContext* aPresContext,
|
|||
nsAtomList* pseudoClass = aSelector->mPseudoClassList;
|
||||
PRInt32 eventState = NS_EVENT_STATE_UNSPECIFIED;
|
||||
nsLinkState linkState = nsLinkState(-1); // not a link
|
||||
nsILinkHandler* linkHandler = nsnull;
|
||||
nsIEventStateManager* eventStateManager = nsnull;
|
||||
|
||||
while ((PR_TRUE == result) && (nsnull != pseudoClass)) {
|
||||
|
@ -3008,9 +2972,7 @@ static PRBool SelectorMatches(nsIPresContext* aPresContext,
|
|||
else if (IsEventPseudo(pseudoClass->mAtom)) {
|
||||
// check if the element is event-sensitive
|
||||
if (!contentTag) {
|
||||
if (aContent) {
|
||||
aContent->GetTag(contentTag);
|
||||
}
|
||||
aContent->GetTag(*getter_AddRefs(contentTag));
|
||||
}
|
||||
|
||||
#ifdef EVENT_DEBUG
|
||||
|
@ -3041,7 +3003,7 @@ static PRBool SelectorMatches(nsIPresContext* aPresContext,
|
|||
nsAutoString strPseudo, strTag;
|
||||
pseudoClass->mAtom->ToString(strPseudo);
|
||||
if (!contentTag) {
|
||||
if (aContent) aContent->GetTag(contentTag);
|
||||
aContent->GetTag(*getter_AddRefs(contentTag));
|
||||
}
|
||||
if (contentTag) {
|
||||
contentTag->ToString(strTag);
|
||||
|
@ -3065,26 +3027,10 @@ static PRBool SelectorMatches(nsIPresContext* aPresContext,
|
|||
}
|
||||
}
|
||||
else if (IsLinkPseudo(pseudoClass->mAtom)) {
|
||||
if(!tagset) {
|
||||
tagset=PR_TRUE;
|
||||
aContent->GetTag(contentTag);
|
||||
}
|
||||
|
||||
nsAutoString href;
|
||||
if (IsValidLink(aContent,href)) {
|
||||
// Now 'href' will contain a canonical URI that we can
|
||||
// look up in global history.
|
||||
if (!contentTag) aContent->GetTag(*getter_AddRefs(contentTag));
|
||||
if (nsStyleUtil::IsHTMLLink(aContent, contentTag, aPresContext, &linkState) ||
|
||||
nsStyleUtil::IsSimpleXlink(aContent, aPresContext, &linkState)) {
|
||||
if ((PR_FALSE != result) && (aTestState)) {
|
||||
if (! linkHandler) {
|
||||
aPresContext->GetLinkHandler(&linkHandler);
|
||||
if (linkHandler) {
|
||||
linkHandler->GetLinkState(href, linkState);
|
||||
}
|
||||
else {
|
||||
// no link handler? then all links are unvisited
|
||||
linkState = eLinkState_Unvisited;
|
||||
}
|
||||
}
|
||||
if (nsCSSAtoms::linkPseudo == pseudoClass->mAtom) {
|
||||
result = PRBool(eLinkState_Unvisited == linkState);
|
||||
}
|
||||
|
@ -3106,11 +3052,9 @@ static PRBool SelectorMatches(nsIPresContext* aPresContext,
|
|||
pseudoClass = pseudoClass->mNext;
|
||||
}
|
||||
|
||||
NS_IF_RELEASE(linkHandler);
|
||||
NS_IF_RELEASE(eventStateManager);
|
||||
}
|
||||
}
|
||||
NS_IF_RELEASE(contentTag);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -3769,105 +3713,3 @@ CSSRuleProcessor::GetRuleCascade(nsIAtom* aMedium)
|
|||
}
|
||||
return cascade;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
PRBool IsValidLink(nsIContent *aContent,nsString &aHREF)
|
||||
{
|
||||
NS_ASSERTION(aContent, "null arg in IsValidLink");
|
||||
|
||||
// check for:
|
||||
// - HTML ANCHOR with valid HREF
|
||||
// - HTML LINK with valid HREF
|
||||
// - HTML AREA with valid HREF
|
||||
// - Simple XLink
|
||||
|
||||
// if the content is a valid link, set the href to the canonicalized form and return TRUE
|
||||
|
||||
PRBool result = PR_FALSE;
|
||||
PRBool bIsXLink = PR_FALSE;
|
||||
nsCOMPtr<nsIDOMHTMLAnchorElement> anchor;
|
||||
nsCOMPtr<nsIDOMHTMLAreaElement> area;
|
||||
nsCOMPtr<nsIDOMHTMLLinkElement> link;
|
||||
|
||||
if ((anchor = do_QueryInterface(aContent)) ||
|
||||
(area = do_QueryInterface(aContent)) ||
|
||||
(link = do_QueryInterface(aContent))) {
|
||||
// if it is an anchor, area or link then check the href attribute
|
||||
nsresult attrState = 0;
|
||||
// make sure this anchor has a link even if we are not testing state
|
||||
// if there is no link, then this anchor is not really a linkpseudo.
|
||||
// bug=23209
|
||||
attrState = aContent->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::href, aHREF);
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE != attrState) {
|
||||
result = PR_FALSE;
|
||||
}
|
||||
else {
|
||||
if (anchor) {
|
||||
anchor->GetHref(aHREF);
|
||||
result = PR_TRUE;
|
||||
}
|
||||
else if (area) {
|
||||
area->GetHref(aHREF);
|
||||
result = PR_TRUE;
|
||||
}
|
||||
else if (link) {
|
||||
link->GetHref(aHREF);
|
||||
result = PR_TRUE;
|
||||
}
|
||||
}
|
||||
} // if anchor, area, link
|
||||
|
||||
else if ((bIsXLink = IsSimpleXlink(aContent,aHREF))) {
|
||||
// It's an XLink. Resolve it relative to its document.
|
||||
nsCOMPtr<nsIURI> baseURI = nsnull;
|
||||
nsCOMPtr<nsIHTMLContent> htmlContent = do_QueryInterface(aContent);
|
||||
if (htmlContent) {
|
||||
// XXX why do this? will nsIHTMLContent's
|
||||
// GetBaseURL() may return something different
|
||||
// than the URL of the document it lives in?
|
||||
htmlContent->GetBaseURL(*getter_AddRefs(baseURI));
|
||||
}
|
||||
else {
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
aContent->GetDocument(*getter_AddRefs(doc));
|
||||
if (doc) {
|
||||
doc->GetBaseURL(*getter_AddRefs(baseURI));
|
||||
}
|
||||
}
|
||||
|
||||
nsAutoString linkURI;
|
||||
(void) NS_MakeAbsoluteURI(linkURI, aHREF, baseURI, CSSStyleSheetInner::gIOService);
|
||||
aHREF = linkURI;
|
||||
result = PR_TRUE;
|
||||
} // if xlink
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
PRBool IsSimpleXlink(nsIContent *aContent, nsString &aHREF)
|
||||
{
|
||||
NS_ASSERTION(aContent, "invalid call to IsXlink with null content");
|
||||
|
||||
PRBool rv = PR_FALSE;
|
||||
|
||||
// set the out-param to default / empty
|
||||
aHREF.Truncate(0);
|
||||
|
||||
if (aContent) {
|
||||
// first see if we have an XML element
|
||||
nsCOMPtr<nsIXMLContent> xml(do_QueryInterface(aContent));
|
||||
if (xml) {
|
||||
// see if it is type=simple (we don't deal with other types)
|
||||
nsAutoString val;
|
||||
aContent->GetAttribute(kNameSpaceID_XLink, nsHTMLAtoms::type, val);
|
||||
if (val == NS_LITERAL_STRING("simple")) {
|
||||
// see if there is an xlink namespace'd href attribute:
|
||||
// - get it if there is, if not no big deal, it is not required for xlinks
|
||||
aContent->GetAttribute(kNameSpaceID_XLink, nsHTMLAtoms::href, aHREF);
|
||||
rv = PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
|
|
@ -33,15 +33,13 @@
|
|||
#include "nsCRT.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsIIOService.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsNetUtil.h"
|
||||
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
|
||||
#include "nsISupportsArray.h"
|
||||
#include "nsHashtable.h"
|
||||
#include "nsIHTMLContent.h"
|
||||
#include "nsIHTMLAttributes.h"
|
||||
#include "nsILink.h"
|
||||
#include "nsStyleUtil.h"
|
||||
#include "nsIStyleRuleProcessor.h"
|
||||
#include "nsIStyleRule.h"
|
||||
#include "nsIFrame.h"
|
||||
|
@ -49,7 +47,6 @@ static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
|
|||
#include "nsIMutableStyleContext.h"
|
||||
#include "nsHTMLAtoms.h"
|
||||
#include "nsIPresContext.h"
|
||||
#include "nsILinkHandler.h"
|
||||
#include "nsIEventStateManager.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsHTMLIIDs.h"
|
||||
|
@ -850,69 +847,40 @@ HTMLStyleSheetImpl::RulesMatching(nsIPresContext* aPresContext,
|
|||
styledContent->GetTag(tag);
|
||||
// if we have anchor colors, check if this is an anchor with an href
|
||||
if (tag == nsHTMLAtoms::a) {
|
||||
if ((nsnull != mLinkRule) || (nsnull != mVisitedRule)) {
|
||||
// test link state
|
||||
nsILinkHandler* linkHandler;
|
||||
|
||||
if (NS_OK == aPresContext->GetLinkHandler(&linkHandler)) {
|
||||
nsAutoString base, href;
|
||||
nsresult attrState = styledContent->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::href, href);
|
||||
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == attrState) {
|
||||
|
||||
if (! linkHandler) {
|
||||
if (mLinkRule || mVisitedRule || mActiveRule) {
|
||||
nsLinkState state;
|
||||
if (nsStyleUtil::IsHTMLLink(aContent, tag, aPresContext, &state)) {
|
||||
switch (state) {
|
||||
case eLinkState_Unvisited:
|
||||
if (nsnull != mLinkRule) {
|
||||
aResults->AppendElement(mLinkRule);
|
||||
}
|
||||
}
|
||||
else {
|
||||
nsIHTMLContent* htmlContent;
|
||||
if (NS_SUCCEEDED(styledContent->QueryInterface(kIHTMLContentIID, (void**)&htmlContent))) {
|
||||
|
||||
nsCOMPtr<nsIURI> baseURI;
|
||||
htmlContent->GetBaseURL(*getter_AddRefs(baseURI));
|
||||
|
||||
nsAutoString linkURI;
|
||||
(void) NS_MakeAbsoluteURI(linkURI, href, baseURI);
|
||||
|
||||
nsLinkState state;
|
||||
if (NS_OK == linkHandler->GetLinkState(linkURI, state)) {
|
||||
switch (state) {
|
||||
case eLinkState_Unvisited:
|
||||
if (nsnull != mLinkRule) {
|
||||
aResults->AppendElement(mLinkRule);
|
||||
}
|
||||
break;
|
||||
case eLinkState_Visited:
|
||||
if (nsnull != mVisitedRule) {
|
||||
aResults->AppendElement(mVisitedRule);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
NS_RELEASE(htmlContent);
|
||||
break;
|
||||
case eLinkState_Visited:
|
||||
if (nsnull != mVisitedRule) {
|
||||
aResults->AppendElement(mVisitedRule);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
NS_IF_RELEASE(linkHandler);
|
||||
} // end link/visited rules
|
||||
if (nsnull != mActiveRule) { // test active state of link
|
||||
nsIEventStateManager* eventStateManager;
|
||||
// No need to add to the active rule if it's not a link
|
||||
if (mActiveRule) { // test active state of link
|
||||
nsIEventStateManager* eventStateManager;
|
||||
|
||||
if ((NS_OK == aPresContext->GetEventStateManager(&eventStateManager)) &&
|
||||
(nsnull != eventStateManager)) {
|
||||
PRInt32 state;
|
||||
if (NS_OK == eventStateManager->GetContentState(aContent, state)) {
|
||||
if (0 != (state & NS_EVENT_STATE_ACTIVE)) {
|
||||
aResults->AppendElement(mActiveRule);
|
||||
if ((NS_OK == aPresContext->GetEventStateManager(&eventStateManager)) &&
|
||||
(nsnull != eventStateManager)) {
|
||||
PRInt32 state;
|
||||
if (NS_OK == eventStateManager->GetContentState(aContent, state)) {
|
||||
if (0 != (state & NS_EVENT_STATE_ACTIVE)) {
|
||||
aResults->AppendElement(mActiveRule);
|
||||
}
|
||||
}
|
||||
NS_RELEASE(eventStateManager);
|
||||
}
|
||||
}
|
||||
NS_RELEASE(eventStateManager);
|
||||
} // end active rule
|
||||
}
|
||||
} // end active rule
|
||||
} // end link/visited/active rules
|
||||
} // end A tag
|
||||
// add the quirks background compatibility rule if in quirks mode
|
||||
// and/or the Table TH rule for handling <TH> differently than <TD>
|
||||
|
|
|
@ -28,6 +28,16 @@
|
|||
#include "nsStyleConsts.h"
|
||||
#include "nsUnitConversion.h"
|
||||
|
||||
#include "nsHTMLAtoms.h"
|
||||
#include "nsILinkHandler.h"
|
||||
#include "nsILink.h"
|
||||
#include "nsIXMLContent.h"
|
||||
#include "nsIHTMLContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIPref.h"
|
||||
|
||||
|
@ -476,6 +486,129 @@ const nsStyleColor* nsStyleUtil::FindNonTransparentBackground(nsIStyleContext* a
|
|||
return result;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
PRBool nsStyleUtil::IsHTMLLink(nsIContent *aContent, nsIAtom *aTag, nsIPresContext *aPresContext, nsLinkState *aState)
|
||||
{
|
||||
NS_ASSERTION(aContent && aState, "null arg in IsHTMLLink");
|
||||
|
||||
// check for:
|
||||
// - HTML ANCHOR with valid HREF
|
||||
// - HTML LINK with valid HREF
|
||||
// - HTML AREA with valid HREF
|
||||
|
||||
PRBool result = PR_FALSE;
|
||||
|
||||
if ((aTag == nsHTMLAtoms::a) ||
|
||||
(aTag == nsHTMLAtoms::link) ||
|
||||
(aTag == nsHTMLAtoms::area)) {
|
||||
|
||||
nsCOMPtr<nsILink> link( do_QueryInterface(aContent) );
|
||||
// In XML documents, this can be null.
|
||||
if (link) {
|
||||
nsLinkState linkState;
|
||||
link->GetLinkState(linkState);
|
||||
if (linkState == eLinkState_Unknown) {
|
||||
// if it is an anchor, area or link then check the href attribute
|
||||
// make sure this anchor has a link even if we are not testing state
|
||||
// if there is no link, then this anchor is not really a linkpseudo.
|
||||
// bug=23209
|
||||
|
||||
char* href;
|
||||
link->GetHrefCString(href);
|
||||
|
||||
if (href) {
|
||||
nsILinkHandler *linkHandler = nsnull;
|
||||
aPresContext->GetLinkHandler(&linkHandler);
|
||||
if (linkHandler) {
|
||||
linkHandler->GetLinkState(href, linkState);
|
||||
NS_RELEASE(linkHandler);
|
||||
}
|
||||
else {
|
||||
// no link handler? then all links are unvisited
|
||||
linkState = eLinkState_Unvisited;
|
||||
}
|
||||
nsCRT::free(href);
|
||||
} else {
|
||||
linkState = eLinkState_NotLink;
|
||||
}
|
||||
link->SetLinkState(linkState);
|
||||
}
|
||||
if (linkState != eLinkState_NotLink) {
|
||||
*aState = linkState;
|
||||
result = PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
PRBool nsStyleUtil::IsSimpleXlink(nsIContent *aContent, nsIPresContext *aPresContext, nsLinkState *aState)
|
||||
{
|
||||
// XXX PERF This function will cause serious performance problems on
|
||||
// pages with lots of XLinks. We should be caching the visited
|
||||
// state of the XLinks. Where???
|
||||
|
||||
NS_ASSERTION(aContent && aState, "invalid call to IsXlink with null content");
|
||||
|
||||
PRBool rv = PR_FALSE;
|
||||
|
||||
if (aContent && aState) {
|
||||
// first see if we have an XML element
|
||||
nsCOMPtr<nsIXMLContent> xml(do_QueryInterface(aContent));
|
||||
if (xml) {
|
||||
// see if it is type=simple (we don't deal with other types)
|
||||
nsAutoString val;
|
||||
aContent->GetAttribute(kNameSpaceID_XLink, nsHTMLAtoms::type, val);
|
||||
if (val == NS_LITERAL_STRING("simple")) {
|
||||
// see if there is an xlink namespace'd href attribute:
|
||||
// - get it if there is, if not no big deal, it is not required for xlinks
|
||||
// is it bad to re-use val here?
|
||||
aContent->GetAttribute(kNameSpaceID_XLink, nsHTMLAtoms::href, val);
|
||||
|
||||
// It's an XLink. Resolve it relative to its document.
|
||||
nsCOMPtr<nsIURI> baseURI;
|
||||
nsCOMPtr<nsIHTMLContent> htmlContent = do_QueryInterface(aContent);
|
||||
if (htmlContent) {
|
||||
// XXX why do this? will nsIHTMLContent's
|
||||
// GetBaseURL() may return something different
|
||||
// than the URL of the document it lives in?
|
||||
htmlContent->GetBaseURL(*getter_AddRefs(baseURI));
|
||||
}
|
||||
else {
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
aContent->GetDocument(*getter_AddRefs(doc));
|
||||
if (doc) {
|
||||
doc->GetBaseURL(*getter_AddRefs(baseURI));
|
||||
}
|
||||
}
|
||||
|
||||
// convert here, rather than twice in NS_MakeAbsoluteURI and
|
||||
// back again
|
||||
char * href = val.ToNewCString();
|
||||
char * absHREF = nsnull;
|
||||
(void) NS_MakeAbsoluteURI(&absHREF, href, baseURI);
|
||||
nsCRT::free(href);
|
||||
|
||||
nsILinkHandler *linkHandler = nsnull;
|
||||
aPresContext->GetLinkHandler(&linkHandler);
|
||||
if (linkHandler) {
|
||||
linkHandler->GetLinkState(absHREF, *aState);
|
||||
NS_RELEASE(linkHandler);
|
||||
}
|
||||
else {
|
||||
// no link handler? then all links are unvisited
|
||||
*aState = eLinkState_Unvisited;
|
||||
}
|
||||
nsCRT::free(absHREF);
|
||||
|
||||
rv = PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
|
|
|
@ -27,11 +27,7 @@
|
|||
#include "nsCRT.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsIIOService.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsNetUtil.h"
|
||||
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
|
||||
#include "nsISupportsArray.h"
|
||||
#include "nsHashtable.h"
|
||||
#include "nsICSSStyleRuleProcessor.h"
|
||||
|
@ -41,7 +37,6 @@ static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
|
|||
#include "nsIHTMLContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIPresContext.h"
|
||||
#include "nsILinkHandler.h"
|
||||
#include "nsIEventStateManager.h"
|
||||
#include "nsHTMLAtoms.h"
|
||||
#include "nsLayoutAtoms.h"
|
||||
|
@ -67,10 +62,10 @@ static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
|
|||
#include "nsINameSpace.h"
|
||||
#include "nsITextContent.h"
|
||||
#include "prlog.h"
|
||||
#include "nsIXMLContent.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIStyleSet.h"
|
||||
#include "nsISizeOfHandler.h"
|
||||
#include "nsStyleUtil.h"
|
||||
|
||||
//#define DEBUG_RULES
|
||||
//#define EVENT_DEBUG
|
||||
|
@ -83,9 +78,6 @@ static NS_DEFINE_IID(kIDOMCSSStyleSheetIID, NS_IDOMCSSSTYLESHEET_IID);
|
|||
static NS_DEFINE_IID(kIDOMCSSStyleRuleIID, NS_IDOMCSSSTYLERULE_IID);
|
||||
static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID);
|
||||
|
||||
static PRBool IsValidLink(nsIContent *aContent,nsString &aHREF);
|
||||
static PRBool IsSimpleXlink(nsIContent *aContent, nsString &aHREF);
|
||||
|
||||
// ----------------------
|
||||
// Rule hash key
|
||||
//
|
||||
|
@ -458,9 +450,6 @@ public:
|
|||
nsINameSpace* mNameSpace;
|
||||
PRInt32 mDefaultNameSpaceID;
|
||||
nsHashtable mRelevantAttributes;
|
||||
|
||||
static nsIIOService* gIOService;
|
||||
static nsrefcnt gRefcnt;
|
||||
};
|
||||
|
||||
|
||||
|
@ -1090,9 +1079,6 @@ static PRBool SetStyleSheetReference(nsISupports* aElement, void* aSheet)
|
|||
return PR_TRUE;
|
||||
}
|
||||
|
||||
nsIIOService* CSSStyleSheetInner::gIOService = nsnull;
|
||||
nsrefcnt CSSStyleSheetInner::gRefcnt = 0;
|
||||
|
||||
CSSStyleSheetInner::CSSStyleSheetInner(nsICSSStyleSheet* aParentSheet)
|
||||
: mSheets(),
|
||||
mURL(nsnull),
|
||||
|
@ -1102,13 +1088,6 @@ CSSStyleSheetInner::CSSStyleSheetInner(nsICSSStyleSheet* aParentSheet)
|
|||
mRelevantAttributes()
|
||||
{
|
||||
MOZ_COUNT_CTOR(CSSStyleSheetInner);
|
||||
if (gRefcnt++ == 0) {
|
||||
nsresult rv;
|
||||
rv = nsServiceManager::GetService(kIOServiceCID,
|
||||
NS_GET_IID(nsIIOService),
|
||||
(nsISupports**)&gIOService);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "can't get nsIOService");
|
||||
}
|
||||
mSheets.AppendElement(aParentSheet);
|
||||
}
|
||||
|
||||
|
@ -1146,13 +1125,6 @@ CSSStyleSheetInner::CSSStyleSheetInner(CSSStyleSheetInner& aCopy,
|
|||
mRelevantAttributes()
|
||||
{
|
||||
MOZ_COUNT_CTOR(CSSStyleSheetInner);
|
||||
if (gRefcnt++ == 0) {
|
||||
nsresult rv;
|
||||
rv = nsServiceManager::GetService(kIOServiceCID,
|
||||
NS_GET_IID(nsIIOService),
|
||||
(nsISupports**)&gIOService);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "can't get nsIOService");
|
||||
}
|
||||
mSheets.AppendElement(aParentSheet);
|
||||
NS_IF_ADDREF(mURL);
|
||||
if (aCopy.mOrderedRules) {
|
||||
|
@ -1179,12 +1151,6 @@ CSSStyleSheetInner::~CSSStyleSheetInner(void)
|
|||
NS_RELEASE(mOrderedRules);
|
||||
}
|
||||
NS_IF_RELEASE(mNameSpace);
|
||||
if (--gRefcnt == 0) {
|
||||
nsresult rv;
|
||||
rv = nsServiceManager::ReleaseService(kIOServiceCID, gIOService);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "can't release nsIOService");
|
||||
gIOService = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
CSSStyleSheetInner*
|
||||
|
@ -2831,8 +2797,6 @@ static PRBool SelectorMatches(nsIPresContext* aPresContext,
|
|||
PRBool aTestState)
|
||||
{
|
||||
PRBool result = PR_FALSE;
|
||||
PRBool tagset = PR_FALSE;
|
||||
nsIAtom* contentTag = NULL; // Make sure this is NULL for NS_IF_RELEASE
|
||||
|
||||
// Bail out early if we can
|
||||
if(kNameSpaceID_Unknown != aSelector->mNameSpace) {
|
||||
|
@ -2843,10 +2807,11 @@ static PRBool SelectorMatches(nsIPresContext* aPresContext,
|
|||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAtom> contentTag;
|
||||
|
||||
if (((nsnull == aSelector->mTag) || (
|
||||
aContent->GetTag(contentTag),
|
||||
tagset=PR_TRUE,
|
||||
aSelector->mTag == contentTag))) {
|
||||
aContent->GetTag(*getter_AddRefs(contentTag)),
|
||||
aSelector->mTag == contentTag.get()))) {
|
||||
|
||||
result = PR_TRUE;
|
||||
// namespace/tag match
|
||||
|
@ -2916,7 +2881,6 @@ static PRBool SelectorMatches(nsIPresContext* aPresContext,
|
|||
nsAtomList* pseudoClass = aSelector->mPseudoClassList;
|
||||
PRInt32 eventState = NS_EVENT_STATE_UNSPECIFIED;
|
||||
nsLinkState linkState = nsLinkState(-1); // not a link
|
||||
nsILinkHandler* linkHandler = nsnull;
|
||||
nsIEventStateManager* eventStateManager = nsnull;
|
||||
|
||||
while ((PR_TRUE == result) && (nsnull != pseudoClass)) {
|
||||
|
@ -3008,9 +2972,7 @@ static PRBool SelectorMatches(nsIPresContext* aPresContext,
|
|||
else if (IsEventPseudo(pseudoClass->mAtom)) {
|
||||
// check if the element is event-sensitive
|
||||
if (!contentTag) {
|
||||
if (aContent) {
|
||||
aContent->GetTag(contentTag);
|
||||
}
|
||||
aContent->GetTag(*getter_AddRefs(contentTag));
|
||||
}
|
||||
|
||||
#ifdef EVENT_DEBUG
|
||||
|
@ -3041,7 +3003,7 @@ static PRBool SelectorMatches(nsIPresContext* aPresContext,
|
|||
nsAutoString strPseudo, strTag;
|
||||
pseudoClass->mAtom->ToString(strPseudo);
|
||||
if (!contentTag) {
|
||||
if (aContent) aContent->GetTag(contentTag);
|
||||
aContent->GetTag(*getter_AddRefs(contentTag));
|
||||
}
|
||||
if (contentTag) {
|
||||
contentTag->ToString(strTag);
|
||||
|
@ -3065,26 +3027,10 @@ static PRBool SelectorMatches(nsIPresContext* aPresContext,
|
|||
}
|
||||
}
|
||||
else if (IsLinkPseudo(pseudoClass->mAtom)) {
|
||||
if(!tagset) {
|
||||
tagset=PR_TRUE;
|
||||
aContent->GetTag(contentTag);
|
||||
}
|
||||
|
||||
nsAutoString href;
|
||||
if (IsValidLink(aContent,href)) {
|
||||
// Now 'href' will contain a canonical URI that we can
|
||||
// look up in global history.
|
||||
if (!contentTag) aContent->GetTag(*getter_AddRefs(contentTag));
|
||||
if (nsStyleUtil::IsHTMLLink(aContent, contentTag, aPresContext, &linkState) ||
|
||||
nsStyleUtil::IsSimpleXlink(aContent, aPresContext, &linkState)) {
|
||||
if ((PR_FALSE != result) && (aTestState)) {
|
||||
if (! linkHandler) {
|
||||
aPresContext->GetLinkHandler(&linkHandler);
|
||||
if (linkHandler) {
|
||||
linkHandler->GetLinkState(href, linkState);
|
||||
}
|
||||
else {
|
||||
// no link handler? then all links are unvisited
|
||||
linkState = eLinkState_Unvisited;
|
||||
}
|
||||
}
|
||||
if (nsCSSAtoms::linkPseudo == pseudoClass->mAtom) {
|
||||
result = PRBool(eLinkState_Unvisited == linkState);
|
||||
}
|
||||
|
@ -3106,11 +3052,9 @@ static PRBool SelectorMatches(nsIPresContext* aPresContext,
|
|||
pseudoClass = pseudoClass->mNext;
|
||||
}
|
||||
|
||||
NS_IF_RELEASE(linkHandler);
|
||||
NS_IF_RELEASE(eventStateManager);
|
||||
}
|
||||
}
|
||||
NS_IF_RELEASE(contentTag);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -3769,105 +3713,3 @@ CSSRuleProcessor::GetRuleCascade(nsIAtom* aMedium)
|
|||
}
|
||||
return cascade;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
PRBool IsValidLink(nsIContent *aContent,nsString &aHREF)
|
||||
{
|
||||
NS_ASSERTION(aContent, "null arg in IsValidLink");
|
||||
|
||||
// check for:
|
||||
// - HTML ANCHOR with valid HREF
|
||||
// - HTML LINK with valid HREF
|
||||
// - HTML AREA with valid HREF
|
||||
// - Simple XLink
|
||||
|
||||
// if the content is a valid link, set the href to the canonicalized form and return TRUE
|
||||
|
||||
PRBool result = PR_FALSE;
|
||||
PRBool bIsXLink = PR_FALSE;
|
||||
nsCOMPtr<nsIDOMHTMLAnchorElement> anchor;
|
||||
nsCOMPtr<nsIDOMHTMLAreaElement> area;
|
||||
nsCOMPtr<nsIDOMHTMLLinkElement> link;
|
||||
|
||||
if ((anchor = do_QueryInterface(aContent)) ||
|
||||
(area = do_QueryInterface(aContent)) ||
|
||||
(link = do_QueryInterface(aContent))) {
|
||||
// if it is an anchor, area or link then check the href attribute
|
||||
nsresult attrState = 0;
|
||||
// make sure this anchor has a link even if we are not testing state
|
||||
// if there is no link, then this anchor is not really a linkpseudo.
|
||||
// bug=23209
|
||||
attrState = aContent->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::href, aHREF);
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE != attrState) {
|
||||
result = PR_FALSE;
|
||||
}
|
||||
else {
|
||||
if (anchor) {
|
||||
anchor->GetHref(aHREF);
|
||||
result = PR_TRUE;
|
||||
}
|
||||
else if (area) {
|
||||
area->GetHref(aHREF);
|
||||
result = PR_TRUE;
|
||||
}
|
||||
else if (link) {
|
||||
link->GetHref(aHREF);
|
||||
result = PR_TRUE;
|
||||
}
|
||||
}
|
||||
} // if anchor, area, link
|
||||
|
||||
else if ((bIsXLink = IsSimpleXlink(aContent,aHREF))) {
|
||||
// It's an XLink. Resolve it relative to its document.
|
||||
nsCOMPtr<nsIURI> baseURI = nsnull;
|
||||
nsCOMPtr<nsIHTMLContent> htmlContent = do_QueryInterface(aContent);
|
||||
if (htmlContent) {
|
||||
// XXX why do this? will nsIHTMLContent's
|
||||
// GetBaseURL() may return something different
|
||||
// than the URL of the document it lives in?
|
||||
htmlContent->GetBaseURL(*getter_AddRefs(baseURI));
|
||||
}
|
||||
else {
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
aContent->GetDocument(*getter_AddRefs(doc));
|
||||
if (doc) {
|
||||
doc->GetBaseURL(*getter_AddRefs(baseURI));
|
||||
}
|
||||
}
|
||||
|
||||
nsAutoString linkURI;
|
||||
(void) NS_MakeAbsoluteURI(linkURI, aHREF, baseURI, CSSStyleSheetInner::gIOService);
|
||||
aHREF = linkURI;
|
||||
result = PR_TRUE;
|
||||
} // if xlink
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
PRBool IsSimpleXlink(nsIContent *aContent, nsString &aHREF)
|
||||
{
|
||||
NS_ASSERTION(aContent, "invalid call to IsXlink with null content");
|
||||
|
||||
PRBool rv = PR_FALSE;
|
||||
|
||||
// set the out-param to default / empty
|
||||
aHREF.Truncate(0);
|
||||
|
||||
if (aContent) {
|
||||
// first see if we have an XML element
|
||||
nsCOMPtr<nsIXMLContent> xml(do_QueryInterface(aContent));
|
||||
if (xml) {
|
||||
// see if it is type=simple (we don't deal with other types)
|
||||
nsAutoString val;
|
||||
aContent->GetAttribute(kNameSpaceID_XLink, nsHTMLAtoms::type, val);
|
||||
if (val == NS_LITERAL_STRING("simple")) {
|
||||
// see if there is an xlink namespace'd href attribute:
|
||||
// - get it if there is, if not no big deal, it is not required for xlinks
|
||||
aContent->GetAttribute(kNameSpaceID_XLink, nsHTMLAtoms::href, aHREF);
|
||||
rv = PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
|
|
@ -33,15 +33,13 @@
|
|||
#include "nsCRT.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsIIOService.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsNetUtil.h"
|
||||
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
|
||||
#include "nsISupportsArray.h"
|
||||
#include "nsHashtable.h"
|
||||
#include "nsIHTMLContent.h"
|
||||
#include "nsIHTMLAttributes.h"
|
||||
#include "nsILink.h"
|
||||
#include "nsStyleUtil.h"
|
||||
#include "nsIStyleRuleProcessor.h"
|
||||
#include "nsIStyleRule.h"
|
||||
#include "nsIFrame.h"
|
||||
|
@ -49,7 +47,6 @@ static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
|
|||
#include "nsIMutableStyleContext.h"
|
||||
#include "nsHTMLAtoms.h"
|
||||
#include "nsIPresContext.h"
|
||||
#include "nsILinkHandler.h"
|
||||
#include "nsIEventStateManager.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsHTMLIIDs.h"
|
||||
|
@ -850,69 +847,40 @@ HTMLStyleSheetImpl::RulesMatching(nsIPresContext* aPresContext,
|
|||
styledContent->GetTag(tag);
|
||||
// if we have anchor colors, check if this is an anchor with an href
|
||||
if (tag == nsHTMLAtoms::a) {
|
||||
if ((nsnull != mLinkRule) || (nsnull != mVisitedRule)) {
|
||||
// test link state
|
||||
nsILinkHandler* linkHandler;
|
||||
|
||||
if (NS_OK == aPresContext->GetLinkHandler(&linkHandler)) {
|
||||
nsAutoString base, href;
|
||||
nsresult attrState = styledContent->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::href, href);
|
||||
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == attrState) {
|
||||
|
||||
if (! linkHandler) {
|
||||
if (mLinkRule || mVisitedRule || mActiveRule) {
|
||||
nsLinkState state;
|
||||
if (nsStyleUtil::IsHTMLLink(aContent, tag, aPresContext, &state)) {
|
||||
switch (state) {
|
||||
case eLinkState_Unvisited:
|
||||
if (nsnull != mLinkRule) {
|
||||
aResults->AppendElement(mLinkRule);
|
||||
}
|
||||
}
|
||||
else {
|
||||
nsIHTMLContent* htmlContent;
|
||||
if (NS_SUCCEEDED(styledContent->QueryInterface(kIHTMLContentIID, (void**)&htmlContent))) {
|
||||
|
||||
nsCOMPtr<nsIURI> baseURI;
|
||||
htmlContent->GetBaseURL(*getter_AddRefs(baseURI));
|
||||
|
||||
nsAutoString linkURI;
|
||||
(void) NS_MakeAbsoluteURI(linkURI, href, baseURI);
|
||||
|
||||
nsLinkState state;
|
||||
if (NS_OK == linkHandler->GetLinkState(linkURI, state)) {
|
||||
switch (state) {
|
||||
case eLinkState_Unvisited:
|
||||
if (nsnull != mLinkRule) {
|
||||
aResults->AppendElement(mLinkRule);
|
||||
}
|
||||
break;
|
||||
case eLinkState_Visited:
|
||||
if (nsnull != mVisitedRule) {
|
||||
aResults->AppendElement(mVisitedRule);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
NS_RELEASE(htmlContent);
|
||||
break;
|
||||
case eLinkState_Visited:
|
||||
if (nsnull != mVisitedRule) {
|
||||
aResults->AppendElement(mVisitedRule);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
NS_IF_RELEASE(linkHandler);
|
||||
} // end link/visited rules
|
||||
if (nsnull != mActiveRule) { // test active state of link
|
||||
nsIEventStateManager* eventStateManager;
|
||||
// No need to add to the active rule if it's not a link
|
||||
if (mActiveRule) { // test active state of link
|
||||
nsIEventStateManager* eventStateManager;
|
||||
|
||||
if ((NS_OK == aPresContext->GetEventStateManager(&eventStateManager)) &&
|
||||
(nsnull != eventStateManager)) {
|
||||
PRInt32 state;
|
||||
if (NS_OK == eventStateManager->GetContentState(aContent, state)) {
|
||||
if (0 != (state & NS_EVENT_STATE_ACTIVE)) {
|
||||
aResults->AppendElement(mActiveRule);
|
||||
if ((NS_OK == aPresContext->GetEventStateManager(&eventStateManager)) &&
|
||||
(nsnull != eventStateManager)) {
|
||||
PRInt32 state;
|
||||
if (NS_OK == eventStateManager->GetContentState(aContent, state)) {
|
||||
if (0 != (state & NS_EVENT_STATE_ACTIVE)) {
|
||||
aResults->AppendElement(mActiveRule);
|
||||
}
|
||||
}
|
||||
NS_RELEASE(eventStateManager);
|
||||
}
|
||||
}
|
||||
NS_RELEASE(eventStateManager);
|
||||
} // end active rule
|
||||
}
|
||||
} // end active rule
|
||||
} // end link/visited/active rules
|
||||
} // end A tag
|
||||
// add the quirks background compatibility rule if in quirks mode
|
||||
// and/or the Table TH rule for handling <TH> differently than <TD>
|
||||
|
|
|
@ -28,6 +28,16 @@
|
|||
#include "nsStyleConsts.h"
|
||||
#include "nsUnitConversion.h"
|
||||
|
||||
#include "nsHTMLAtoms.h"
|
||||
#include "nsILinkHandler.h"
|
||||
#include "nsILink.h"
|
||||
#include "nsIXMLContent.h"
|
||||
#include "nsIHTMLContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIPref.h"
|
||||
|
||||
|
@ -476,6 +486,129 @@ const nsStyleColor* nsStyleUtil::FindNonTransparentBackground(nsIStyleContext* a
|
|||
return result;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
PRBool nsStyleUtil::IsHTMLLink(nsIContent *aContent, nsIAtom *aTag, nsIPresContext *aPresContext, nsLinkState *aState)
|
||||
{
|
||||
NS_ASSERTION(aContent && aState, "null arg in IsHTMLLink");
|
||||
|
||||
// check for:
|
||||
// - HTML ANCHOR with valid HREF
|
||||
// - HTML LINK with valid HREF
|
||||
// - HTML AREA with valid HREF
|
||||
|
||||
PRBool result = PR_FALSE;
|
||||
|
||||
if ((aTag == nsHTMLAtoms::a) ||
|
||||
(aTag == nsHTMLAtoms::link) ||
|
||||
(aTag == nsHTMLAtoms::area)) {
|
||||
|
||||
nsCOMPtr<nsILink> link( do_QueryInterface(aContent) );
|
||||
// In XML documents, this can be null.
|
||||
if (link) {
|
||||
nsLinkState linkState;
|
||||
link->GetLinkState(linkState);
|
||||
if (linkState == eLinkState_Unknown) {
|
||||
// if it is an anchor, area or link then check the href attribute
|
||||
// make sure this anchor has a link even if we are not testing state
|
||||
// if there is no link, then this anchor is not really a linkpseudo.
|
||||
// bug=23209
|
||||
|
||||
char* href;
|
||||
link->GetHrefCString(href);
|
||||
|
||||
if (href) {
|
||||
nsILinkHandler *linkHandler = nsnull;
|
||||
aPresContext->GetLinkHandler(&linkHandler);
|
||||
if (linkHandler) {
|
||||
linkHandler->GetLinkState(href, linkState);
|
||||
NS_RELEASE(linkHandler);
|
||||
}
|
||||
else {
|
||||
// no link handler? then all links are unvisited
|
||||
linkState = eLinkState_Unvisited;
|
||||
}
|
||||
nsCRT::free(href);
|
||||
} else {
|
||||
linkState = eLinkState_NotLink;
|
||||
}
|
||||
link->SetLinkState(linkState);
|
||||
}
|
||||
if (linkState != eLinkState_NotLink) {
|
||||
*aState = linkState;
|
||||
result = PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
PRBool nsStyleUtil::IsSimpleXlink(nsIContent *aContent, nsIPresContext *aPresContext, nsLinkState *aState)
|
||||
{
|
||||
// XXX PERF This function will cause serious performance problems on
|
||||
// pages with lots of XLinks. We should be caching the visited
|
||||
// state of the XLinks. Where???
|
||||
|
||||
NS_ASSERTION(aContent && aState, "invalid call to IsXlink with null content");
|
||||
|
||||
PRBool rv = PR_FALSE;
|
||||
|
||||
if (aContent && aState) {
|
||||
// first see if we have an XML element
|
||||
nsCOMPtr<nsIXMLContent> xml(do_QueryInterface(aContent));
|
||||
if (xml) {
|
||||
// see if it is type=simple (we don't deal with other types)
|
||||
nsAutoString val;
|
||||
aContent->GetAttribute(kNameSpaceID_XLink, nsHTMLAtoms::type, val);
|
||||
if (val == NS_LITERAL_STRING("simple")) {
|
||||
// see if there is an xlink namespace'd href attribute:
|
||||
// - get it if there is, if not no big deal, it is not required for xlinks
|
||||
// is it bad to re-use val here?
|
||||
aContent->GetAttribute(kNameSpaceID_XLink, nsHTMLAtoms::href, val);
|
||||
|
||||
// It's an XLink. Resolve it relative to its document.
|
||||
nsCOMPtr<nsIURI> baseURI;
|
||||
nsCOMPtr<nsIHTMLContent> htmlContent = do_QueryInterface(aContent);
|
||||
if (htmlContent) {
|
||||
// XXX why do this? will nsIHTMLContent's
|
||||
// GetBaseURL() may return something different
|
||||
// than the URL of the document it lives in?
|
||||
htmlContent->GetBaseURL(*getter_AddRefs(baseURI));
|
||||
}
|
||||
else {
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
aContent->GetDocument(*getter_AddRefs(doc));
|
||||
if (doc) {
|
||||
doc->GetBaseURL(*getter_AddRefs(baseURI));
|
||||
}
|
||||
}
|
||||
|
||||
// convert here, rather than twice in NS_MakeAbsoluteURI and
|
||||
// back again
|
||||
char * href = val.ToNewCString();
|
||||
char * absHREF = nsnull;
|
||||
(void) NS_MakeAbsoluteURI(&absHREF, href, baseURI);
|
||||
nsCRT::free(href);
|
||||
|
||||
nsILinkHandler *linkHandler = nsnull;
|
||||
aPresContext->GetLinkHandler(&linkHandler);
|
||||
if (linkHandler) {
|
||||
linkHandler->GetLinkState(absHREF, *aState);
|
||||
NS_RELEASE(linkHandler);
|
||||
}
|
||||
else {
|
||||
// no link handler? then all links are unvisited
|
||||
*aState = eLinkState_Unvisited;
|
||||
}
|
||||
nsCRT::free(absHREF);
|
||||
|
||||
rv = PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
|
|
|
@ -34,9 +34,11 @@ struct nsGUIEvent;
|
|||
{ 0xa6cf905b, 0x15b3, 0x11d2,{0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32}}
|
||||
|
||||
enum nsLinkState {
|
||||
eLinkState_Unvisited = 0,
|
||||
eLinkState_Visited = 1,
|
||||
eLinkState_OutOfDate = 2 // visited, but the cache is stale
|
||||
eLinkState_Unknown = 0,
|
||||
eLinkState_Unvisited = 1,
|
||||
eLinkState_Visited = 2,
|
||||
eLinkState_OutOfDate = 3, // visited, but the cache is stale
|
||||
eLinkState_NotLink = 4
|
||||
};
|
||||
|
||||
// XXX Verb to use for link actuation. These are the verbs specified
|
||||
|
@ -82,7 +84,7 @@ public:
|
|||
/**
|
||||
* Get the state of a link to a given absolute URL
|
||||
*/
|
||||
NS_IMETHOD GetLinkState(const nsString& aLinkURI, nsLinkState& aState) = 0;
|
||||
NS_IMETHOD GetLinkState(const char* aLinkURI, nsLinkState& aState) = 0;
|
||||
};
|
||||
|
||||
#endif /* nsILinkHandler_h___ */
|
||||
|
|
Загрузка…
Ссылка в новой задаче