Implemented actuate=onLoad for simple XLinks. r=nisheeth.

This commit is contained in:
heikki%citec.fi 2000-05-09 07:30:21 +00:00
Родитель 02ef367e2b
Коммит 14cbdd72a2
16 изменённых файлов: 420 добавлений и 24 удалений

Просмотреть файл

@ -27,6 +27,7 @@
#include "nsIContent.h"
class nsINameSpace;
class nsIWebShell;
#define NS_IXMLCONTENT_IID \
{ 0xa6cf90cb, 0x15b3, 0x11d2, \
@ -46,8 +47,29 @@ public:
NS_IMETHOD GetNameSpacePrefix(nsIAtom*& aNameSpace) const = 0;
NS_IMETHOD SetNameSpaceID(PRInt32 aNSIdentifier) = 0;
/**
* Give this element a change to fire its links that should be fired
* automatically when loaded. If the element was an autoloading link
* and it was succesfully handled, we will return informal return value.
* If the return value is NS_XML_AUTOLINK_REPLACE, the caller should
* stop processing the current document because it will be replaced.
* We normally treat NS_XML_AUTOLINK_UNDEFINED the same way as replace
* links, so processing should usually stop after that as well.
*/
NS_IMETHOD MaybeTriggerAutoLink(nsIWebShell *aShell) = 0;
};
// Some return values for MaybeTriggerAutoLink
#define NS_XML_AUTOLINK_EMBED \
NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_LAYOUT, 4)
#define NS_XML_AUTOLINK_NEW \
NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_LAYOUT, 5)
#define NS_XML_AUTOLINK_REPLACE \
NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_LAYOUT, 6)
#define NS_XML_AUTOLINK_UNDEFINED \
NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_LAYOUT, 7)
extern nsresult
NS_NewXMLElement(nsIXMLContent** aResult, nsIAtom* aTag);

Просмотреть файл

@ -26,7 +26,7 @@
#include "nsIAtom.h"
#include "nsIEventListenerManager.h"
#include "nsIDOMScriptObjectFactory.h"
#include "nsIWebShell.h"
#include "nsIEventStateManager.h"
#include "nsDOMEvent.h"
#include "nsINameSpace.h"
@ -35,6 +35,10 @@
#include "nsIIOService.h"
#include "nsIServiceManager.h"
#include "nsXPIDLString.h"
#include "nsIDocShell.h"
#include "nsIScriptSecurityManager.h"
#include "nsIRefreshURI.h"
//static NS_DEFINE_IID(kIDOMElementIID, NS_IDOMELEMENT_IID);
static NS_DEFINE_IID(kIXMLContentIID, NS_IXMLCONTENT_IID);
@ -58,6 +62,9 @@ static nsIAtom* kHrefAtom;
static nsIAtom* kShowAtom;
static nsIAtom* kTypeAtom;
static nsIAtom* kBaseAtom;
static nsIAtom* kActuateAtom;
static nsIAtom* kOnLoadAtom;
static nsIAtom* kEmbedAtom;
static PRUint32 kElementCount;
nsXMLElement::nsXMLElement(nsIAtom *aTag)
@ -73,6 +80,9 @@ nsXMLElement::nsXMLElement(nsIAtom *aTag)
kShowAtom = NS_NewAtom("show");
kTypeAtom = NS_NewAtom("type");
kBaseAtom = NS_NewAtom("base");
kActuateAtom = NS_NewAtom("actuate");
kOnLoadAtom = NS_NewAtom("onLoad");
kEmbedAtom = NS_NewAtom("embed");
}
}
@ -84,6 +94,9 @@ nsXMLElement::~nsXMLElement()
NS_RELEASE(kShowAtom);
NS_RELEASE(kTypeAtom);
NS_RELEASE(kBaseAtom);
NS_RELEASE(kActuateAtom);
NS_RELEASE(kOnLoadAtom);
NS_RELEASE(kEmbedAtom);
}
}
@ -140,8 +153,6 @@ nsXMLElement::GetXMLBaseURI(nsIURI **aURI)
rv = content->GetAttribute(kNameSpaceID_XML,kBaseAtom,value);
PRInt32 value_len;
if (rv == NS_CONTENT_ATTR_HAS_VALUE) {
// XXX Need to convert unicode to ???
// XXX Need to URL-escape string
PRInt32 colon = value.FindChar(':',PR_FALSE);
PRInt32 slash = value.FindChar('/',PR_FALSE);
if (colon > 0 && !( slash >= 0 && slash < colon)) {
@ -149,6 +160,7 @@ nsXMLElement::GetXMLBaseURI(nsIURI **aURI)
// The complex looking if above is to make sure that we do not erroneously
// think a value of "./this:that" would have a scheme of "./that"
// XXX URL escape?
nsCAutoString str; str.AssignWithConversion(value);
rv = MakeURI(str,nsnull,aURI);
@ -156,6 +168,7 @@ nsXMLElement::GetXMLBaseURI(nsIURI **aURI)
break;
if (!base.IsEmpty()) {
// XXX URL escape?
str.AssignWithConversion(base.GetUnicode());
nsXPIDLCString resolvedStr;
rv = (*aURI)->Resolve(str, getter_Copies(resolvedStr));
@ -193,8 +206,7 @@ nsXMLElement::GetXMLBaseURI(nsIURI **aURI)
*aURI = docBase.get();
NS_IF_ADDREF(*aURI); // nsCOMPtr releases this once
} else {
// XXX Need to convert unicode to ???
// XXX Need to URL-escape string
// XXX URL escape?
nsCAutoString str; str.AssignWithConversion(base);
rv = MakeURI(str,docBase,aURI);
}
@ -211,9 +223,6 @@ nsXMLElement::SetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName,
const nsString& aValue,
PRBool aNotify)
{
// XXX It sucks that we have to do a strcmp for
// every attribute set. It might be a bit more expensive
// to create an atom.
if ((kNameSpaceID_XLink == aNameSpaceID) &&
(kTypeAtom == aName)) {
if (aValue.EqualsAtom(kSimpleAtom, PR_FALSE)) {
@ -228,14 +237,138 @@ nsXMLElement::SetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName,
} else {
mIsLink = PR_FALSE;
}
// We will check for actuate="onLoad" in MaybeTriggerAutoLink
}
// XXX If the XLink actuate attribute is present and its value is
// onLoad, we should obey that too [XLink 3.6.2].
return mInner.SetAttribute(aNameSpaceID, aName, aValue, aNotify);
}
static nsresult WebShellToPresContext(nsIWebShell *aShell, nsIPresContext **aPresContext)
{
*aPresContext = nsnull;
nsresult rv;
nsCOMPtr<nsIDocShell> ds = do_QueryInterface(aShell,&rv);
if (NS_FAILED(rv))
return rv;
return ds->GetPresContext(aPresContext);
}
static nsresult CheckLoadURI(nsIURI *aBaseURI, const nsString& aURI, nsIURI **aAbsURI)
{
// XXX URL escape?
nsCAutoString str; str.AssignWithConversion(aURI);
*aAbsURI = nsnull;
nsresult rv;
rv = MakeURI(str,aBaseURI,aAbsURI);
if (NS_SUCCEEDED(rv)) {
NS_WITH_SERVICE(nsIScriptSecurityManager,
securityManager,
NS_SCRIPTSECURITYMANAGER_PROGID,
&rv);
if (NS_SUCCEEDED(rv)) {
rv= securityManager->CheckLoadURI(aBaseURI,
*aAbsURI,
PR_TRUE);
}
}
if (NS_FAILED(rv)) {
NS_IF_RELEASE(*aAbsURI);
}
return rv;
}
static inline nsresult SpecialAutoLoadReturn(nsresult aRv, nsLinkVerb aVerb)
{
if (NS_SUCCEEDED(aRv)) {
switch(aVerb) {
case eLinkVerb_Embed:
aRv = NS_XML_AUTOLINK_EMBED;
break;
case eLinkVerb_New:
aRv = NS_XML_AUTOLINK_NEW;
break;
case eLinkVerb_Replace:
aRv = NS_XML_AUTOLINK_REPLACE;
break;
default:
aRv = NS_XML_AUTOLINK_UNDEFINED;
break;
}
}
return aRv;
}
NS_IMETHODIMP
nsXMLElement::MaybeTriggerAutoLink(nsIWebShell *aShell)
{
NS_ABORT_IF_FALSE(aShell,"null ptr");
if (!aShell)
return NS_ERROR_NULL_POINTER;
nsresult rv = NS_OK;
if (mIsLink) {
do {
// actuate="onLoad" ?
nsAutoString value;
rv = GetAttribute(kNameSpaceID_XLink,kActuateAtom,value);
if (rv == NS_CONTENT_ATTR_HAS_VALUE &&
value.EqualsAtom(kOnLoadAtom,PR_FALSE)) {
// show= ?
nsLinkVerb verb = eLinkVerb_Undefined;
rv = GetAttribute(kNameSpaceID_XLink, kShowAtom, value);
if (NS_FAILED(rv))
break;
// XXX Should probably do this using atoms
if (value.EqualsWithConversion("new")) {
verb = eLinkVerb_New;
} else if (value.EqualsWithConversion("replace")) {
// We want to actually stop processing the current document now.
// We do this by returning the correct value so that the one
// that called us knows to stop processing.
verb = eLinkVerb_Replace;
} else if (value.EqualsWithConversion("embed")) {
// XXX TODO
break;
}
// base
nsCOMPtr<nsIURI> base;
rv = GetXMLBaseURI(getter_AddRefs(base));
if (NS_FAILED(rv))
break;
// href= ?
rv = GetAttribute(kNameSpaceID_XLink,kHrefAtom,value);
if (rv == NS_CONTENT_ATTR_HAS_VALUE && !value.IsEmpty()) {
nsCOMPtr<nsIURI> uri;
rv = CheckLoadURI(base,value,getter_AddRefs(uri));
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIPresContext> pc;
rv = WebShellToPresContext(aShell,getter_AddRefs(pc));
if (NS_SUCCEEDED(rv)) {
rv = mInner.TriggerLink(pc, verb, base, value, nsAutoString(), PR_TRUE);
return SpecialAutoLoadReturn(rv,verb);
}
}
} // href
}
} while (0);
}
return rv;
}
NS_IMETHODIMP
nsXMLElement::HandleDOMEvent(nsIPresContext* aPresContext,
nsEvent* aEvent,

Просмотреть файл

@ -38,6 +38,7 @@ class nsIAtom;
class nsIEventListenerManager;
class nsIHTMLAttributes;
class nsIURI;
class nsIWebShell;
class nsXMLElement : public nsIDOMElement,
public nsIXMLContent,
@ -206,6 +207,7 @@ public:
NS_IMETHOD SetNameSpaceID(PRInt32 aNameSpaceId) {
return mInner.SetNameSpaceID(aNameSpaceId);
}
NS_IMETHOD MaybeTriggerAutoLink(nsIWebShell *aShell);
// nsIBindableContent
NS_IMETHOD SetBinding(nsIXBLBinding* aBinding);

Просмотреть файл

@ -584,6 +584,21 @@ nsXMLContentSink::AddAttributes(const nsIParserNode& aNode,
NS_RELEASE(nameAtom);
NS_IF_RELEASE(nameSpacePrefix);
}
// Give autoloading links a chance to fire
if (mWebShell) {
nsCOMPtr<nsIXMLContent> xmlcontent(do_QueryInterface(aContent));
if (xmlcontent) {
nsresult rv = xmlcontent->MaybeTriggerAutoLink(mWebShell);
if (rv == NS_XML_AUTOLINK_REPLACE ||
rv == NS_XML_AUTOLINK_UNDEFINED) {
// If we do not terminate the parse, we just keep generating link trigger
// events. We want to parse only up to the first replace link, and stop.
mParser->Terminate();
}
}
}
return NS_OK;
}

Просмотреть файл

@ -1,4 +1,4 @@
<?xml version="1.0"?>
<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet href="xmlbase.css" type="text/css"?>
<root xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Root: no xml:base</title>
@ -59,4 +59,14 @@
<xlink:link xlink:type="simple" xlink:href="k.xml">k.xml</xlink:link>
<p>Expected: file:///not/k.xml</p>
</sect1>
<sect1 xml:base="http://foobar.com/ä ö/">
<title>Sect1: xml:base="http://foobar.com/ä ö/"</title>
<xlink:link xlink:type="simple" xlink:href="l.xml">l.xml</xlink:link>
<p>Expected: http://foobar.com/%E4%20%F6/l.xml</p>
</sect1>
<sect1 xml:base="http://foobar.com/ /%20/">
<title>Sect1: xml:base="http://foobar.com/ /%20/"</title>
<xlink:link xlink:type="simple" xlink:href="m.xml">m.xml</xlink:link>
<p>Expected: http://foobar.com/%20/%20/m.xml</p>
</sect1>
</root>

Просмотреть файл

@ -131,6 +131,8 @@
#include "nsISizeOfHandler.h"
class nsIWebShell;
// XXX This is sure to change. Copied from mozilla/layout/xul/content/src/nsXULAtoms.cpp
#define XUL_NAMESPACE_URI "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
static const char kXULNameSpaceURI[] = XUL_NAMESPACE_URI;
@ -1689,6 +1691,12 @@ nsXULElement::SetNameSpaceID(PRInt32 aNameSpaceID)
return NS_OK;
}
NS_IMETHODIMP
nsXULElement::MaybeTriggerAutoLink(nsIWebShell *aShell)
{
return NS_OK;
}
//----------------------------------------------------------------------
// nsIXULContent interface

Просмотреть файл

@ -73,6 +73,7 @@ class nsRDFDOMNodeList;
class nsString;
class nsVoidArray;
class nsXULAttributes;
class nsIWebShell;
////////////////////////////////////////////////////////////////////////
@ -436,6 +437,7 @@ public:
NS_IMETHOD SetNameSpacePrefix(nsIAtom* aNameSpace);
NS_IMETHOD GetNameSpacePrefix(nsIAtom*& aNameSpace) const;
NS_IMETHOD SetNameSpaceID(PRInt32 aNameSpaceID);
NS_IMETHOD MaybeTriggerAutoLink(nsIWebShell *aShell);
// nsIXULContent
NS_IMETHOD PeekChildCount(PRInt32& aCount) const;

Просмотреть файл

@ -27,6 +27,7 @@
#include "nsIContent.h"
class nsINameSpace;
class nsIWebShell;
#define NS_IXMLCONTENT_IID \
{ 0xa6cf90cb, 0x15b3, 0x11d2, \
@ -46,8 +47,29 @@ public:
NS_IMETHOD GetNameSpacePrefix(nsIAtom*& aNameSpace) const = 0;
NS_IMETHOD SetNameSpaceID(PRInt32 aNSIdentifier) = 0;
/**
* Give this element a change to fire its links that should be fired
* automatically when loaded. If the element was an autoloading link
* and it was succesfully handled, we will return informal return value.
* If the return value is NS_XML_AUTOLINK_REPLACE, the caller should
* stop processing the current document because it will be replaced.
* We normally treat NS_XML_AUTOLINK_UNDEFINED the same way as replace
* links, so processing should usually stop after that as well.
*/
NS_IMETHOD MaybeTriggerAutoLink(nsIWebShell *aShell) = 0;
};
// Some return values for MaybeTriggerAutoLink
#define NS_XML_AUTOLINK_EMBED \
NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_LAYOUT, 4)
#define NS_XML_AUTOLINK_NEW \
NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_LAYOUT, 5)
#define NS_XML_AUTOLINK_REPLACE \
NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_LAYOUT, 6)
#define NS_XML_AUTOLINK_UNDEFINED \
NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_LAYOUT, 7)
extern nsresult
NS_NewXMLElement(nsIXMLContent** aResult, nsIAtom* aTag);

Просмотреть файл

@ -48,6 +48,8 @@
#include "prprf.h"
#include "prmem.h"
class nsIWebShell;
static NS_DEFINE_IID(kIDOMAttrIID, NS_IDOMATTR_IID);
static NS_DEFINE_IID(kIDOMNamedNodeMapIID, NS_IDOMNAMEDNODEMAP_IID);
static NS_DEFINE_IID(kIDOMNodeListIID, NS_IDOMNODELIST_IID);
@ -229,6 +231,13 @@ nsGenericXMLElement::GetNameSpaceID(PRInt32& aNameSpaceID) const
return NS_OK;
}
nsresult
nsGenericXMLElement::MaybeTriggerAutoLink(nsIWebShell *aShell)
{
// Implement in subclass
return NS_ERROR_NOT_IMPLEMENTED;
}
nsresult
nsGenericXMLElement::SetContainingNameSpace(nsINameSpace* aNameSpace)
{

Просмотреть файл

@ -30,6 +30,8 @@
#include "nsINameSpaceManager.h" // for kNameSpaceID_HTML
#include "nsINameSpace.h"
class nsIWebShell;
class nsGenericXMLElement : public nsGenericContainerElement {
public:
nsGenericXMLElement();
@ -85,6 +87,7 @@ public:
nsresult GetNameSpacePrefix(nsIAtom*& aNameSpace) const;
nsresult SetNameSpaceID(PRInt32 aNameSpaceId);
nsresult GetNameSpaceID(PRInt32& aNameSpaceID) const;
nsresult MaybeTriggerAutoLink(nsIWebShell *aShell);
// nsIScriptObjectOwner
nsresult GetScriptObject(nsIScriptContext* aContext,

Просмотреть файл

@ -26,7 +26,7 @@
#include "nsIAtom.h"
#include "nsIEventListenerManager.h"
#include "nsIDOMScriptObjectFactory.h"
#include "nsIWebShell.h"
#include "nsIEventStateManager.h"
#include "nsDOMEvent.h"
#include "nsINameSpace.h"
@ -35,6 +35,10 @@
#include "nsIIOService.h"
#include "nsIServiceManager.h"
#include "nsXPIDLString.h"
#include "nsIDocShell.h"
#include "nsIScriptSecurityManager.h"
#include "nsIRefreshURI.h"
//static NS_DEFINE_IID(kIDOMElementIID, NS_IDOMELEMENT_IID);
static NS_DEFINE_IID(kIXMLContentIID, NS_IXMLCONTENT_IID);
@ -58,6 +62,9 @@ static nsIAtom* kHrefAtom;
static nsIAtom* kShowAtom;
static nsIAtom* kTypeAtom;
static nsIAtom* kBaseAtom;
static nsIAtom* kActuateAtom;
static nsIAtom* kOnLoadAtom;
static nsIAtom* kEmbedAtom;
static PRUint32 kElementCount;
nsXMLElement::nsXMLElement(nsIAtom *aTag)
@ -73,6 +80,9 @@ nsXMLElement::nsXMLElement(nsIAtom *aTag)
kShowAtom = NS_NewAtom("show");
kTypeAtom = NS_NewAtom("type");
kBaseAtom = NS_NewAtom("base");
kActuateAtom = NS_NewAtom("actuate");
kOnLoadAtom = NS_NewAtom("onLoad");
kEmbedAtom = NS_NewAtom("embed");
}
}
@ -84,6 +94,9 @@ nsXMLElement::~nsXMLElement()
NS_RELEASE(kShowAtom);
NS_RELEASE(kTypeAtom);
NS_RELEASE(kBaseAtom);
NS_RELEASE(kActuateAtom);
NS_RELEASE(kOnLoadAtom);
NS_RELEASE(kEmbedAtom);
}
}
@ -140,8 +153,6 @@ nsXMLElement::GetXMLBaseURI(nsIURI **aURI)
rv = content->GetAttribute(kNameSpaceID_XML,kBaseAtom,value);
PRInt32 value_len;
if (rv == NS_CONTENT_ATTR_HAS_VALUE) {
// XXX Need to convert unicode to ???
// XXX Need to URL-escape string
PRInt32 colon = value.FindChar(':',PR_FALSE);
PRInt32 slash = value.FindChar('/',PR_FALSE);
if (colon > 0 && !( slash >= 0 && slash < colon)) {
@ -149,6 +160,7 @@ nsXMLElement::GetXMLBaseURI(nsIURI **aURI)
// The complex looking if above is to make sure that we do not erroneously
// think a value of "./this:that" would have a scheme of "./that"
// XXX URL escape?
nsCAutoString str; str.AssignWithConversion(value);
rv = MakeURI(str,nsnull,aURI);
@ -156,6 +168,7 @@ nsXMLElement::GetXMLBaseURI(nsIURI **aURI)
break;
if (!base.IsEmpty()) {
// XXX URL escape?
str.AssignWithConversion(base.GetUnicode());
nsXPIDLCString resolvedStr;
rv = (*aURI)->Resolve(str, getter_Copies(resolvedStr));
@ -193,8 +206,7 @@ nsXMLElement::GetXMLBaseURI(nsIURI **aURI)
*aURI = docBase.get();
NS_IF_ADDREF(*aURI); // nsCOMPtr releases this once
} else {
// XXX Need to convert unicode to ???
// XXX Need to URL-escape string
// XXX URL escape?
nsCAutoString str; str.AssignWithConversion(base);
rv = MakeURI(str,docBase,aURI);
}
@ -211,9 +223,6 @@ nsXMLElement::SetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName,
const nsString& aValue,
PRBool aNotify)
{
// XXX It sucks that we have to do a strcmp for
// every attribute set. It might be a bit more expensive
// to create an atom.
if ((kNameSpaceID_XLink == aNameSpaceID) &&
(kTypeAtom == aName)) {
if (aValue.EqualsAtom(kSimpleAtom, PR_FALSE)) {
@ -228,14 +237,138 @@ nsXMLElement::SetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName,
} else {
mIsLink = PR_FALSE;
}
// We will check for actuate="onLoad" in MaybeTriggerAutoLink
}
// XXX If the XLink actuate attribute is present and its value is
// onLoad, we should obey that too [XLink 3.6.2].
return mInner.SetAttribute(aNameSpaceID, aName, aValue, aNotify);
}
static nsresult WebShellToPresContext(nsIWebShell *aShell, nsIPresContext **aPresContext)
{
*aPresContext = nsnull;
nsresult rv;
nsCOMPtr<nsIDocShell> ds = do_QueryInterface(aShell,&rv);
if (NS_FAILED(rv))
return rv;
return ds->GetPresContext(aPresContext);
}
static nsresult CheckLoadURI(nsIURI *aBaseURI, const nsString& aURI, nsIURI **aAbsURI)
{
// XXX URL escape?
nsCAutoString str; str.AssignWithConversion(aURI);
*aAbsURI = nsnull;
nsresult rv;
rv = MakeURI(str,aBaseURI,aAbsURI);
if (NS_SUCCEEDED(rv)) {
NS_WITH_SERVICE(nsIScriptSecurityManager,
securityManager,
NS_SCRIPTSECURITYMANAGER_PROGID,
&rv);
if (NS_SUCCEEDED(rv)) {
rv= securityManager->CheckLoadURI(aBaseURI,
*aAbsURI,
PR_TRUE);
}
}
if (NS_FAILED(rv)) {
NS_IF_RELEASE(*aAbsURI);
}
return rv;
}
static inline nsresult SpecialAutoLoadReturn(nsresult aRv, nsLinkVerb aVerb)
{
if (NS_SUCCEEDED(aRv)) {
switch(aVerb) {
case eLinkVerb_Embed:
aRv = NS_XML_AUTOLINK_EMBED;
break;
case eLinkVerb_New:
aRv = NS_XML_AUTOLINK_NEW;
break;
case eLinkVerb_Replace:
aRv = NS_XML_AUTOLINK_REPLACE;
break;
default:
aRv = NS_XML_AUTOLINK_UNDEFINED;
break;
}
}
return aRv;
}
NS_IMETHODIMP
nsXMLElement::MaybeTriggerAutoLink(nsIWebShell *aShell)
{
NS_ABORT_IF_FALSE(aShell,"null ptr");
if (!aShell)
return NS_ERROR_NULL_POINTER;
nsresult rv = NS_OK;
if (mIsLink) {
do {
// actuate="onLoad" ?
nsAutoString value;
rv = GetAttribute(kNameSpaceID_XLink,kActuateAtom,value);
if (rv == NS_CONTENT_ATTR_HAS_VALUE &&
value.EqualsAtom(kOnLoadAtom,PR_FALSE)) {
// show= ?
nsLinkVerb verb = eLinkVerb_Undefined;
rv = GetAttribute(kNameSpaceID_XLink, kShowAtom, value);
if (NS_FAILED(rv))
break;
// XXX Should probably do this using atoms
if (value.EqualsWithConversion("new")) {
verb = eLinkVerb_New;
} else if (value.EqualsWithConversion("replace")) {
// We want to actually stop processing the current document now.
// We do this by returning the correct value so that the one
// that called us knows to stop processing.
verb = eLinkVerb_Replace;
} else if (value.EqualsWithConversion("embed")) {
// XXX TODO
break;
}
// base
nsCOMPtr<nsIURI> base;
rv = GetXMLBaseURI(getter_AddRefs(base));
if (NS_FAILED(rv))
break;
// href= ?
rv = GetAttribute(kNameSpaceID_XLink,kHrefAtom,value);
if (rv == NS_CONTENT_ATTR_HAS_VALUE && !value.IsEmpty()) {
nsCOMPtr<nsIURI> uri;
rv = CheckLoadURI(base,value,getter_AddRefs(uri));
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIPresContext> pc;
rv = WebShellToPresContext(aShell,getter_AddRefs(pc));
if (NS_SUCCEEDED(rv)) {
rv = mInner.TriggerLink(pc, verb, base, value, nsAutoString(), PR_TRUE);
return SpecialAutoLoadReturn(rv,verb);
}
}
} // href
}
} while (0);
}
return rv;
}
NS_IMETHODIMP
nsXMLElement::HandleDOMEvent(nsIPresContext* aPresContext,
nsEvent* aEvent,

Просмотреть файл

@ -38,6 +38,7 @@ class nsIAtom;
class nsIEventListenerManager;
class nsIHTMLAttributes;
class nsIURI;
class nsIWebShell;
class nsXMLElement : public nsIDOMElement,
public nsIXMLContent,
@ -206,6 +207,7 @@ public:
NS_IMETHOD SetNameSpaceID(PRInt32 aNameSpaceId) {
return mInner.SetNameSpaceID(aNameSpaceId);
}
NS_IMETHOD MaybeTriggerAutoLink(nsIWebShell *aShell);
// nsIBindableContent
NS_IMETHOD SetBinding(nsIXBLBinding* aBinding);

Просмотреть файл

@ -584,6 +584,21 @@ nsXMLContentSink::AddAttributes(const nsIParserNode& aNode,
NS_RELEASE(nameAtom);
NS_IF_RELEASE(nameSpacePrefix);
}
// Give autoloading links a chance to fire
if (mWebShell) {
nsCOMPtr<nsIXMLContent> xmlcontent(do_QueryInterface(aContent));
if (xmlcontent) {
nsresult rv = xmlcontent->MaybeTriggerAutoLink(mWebShell);
if (rv == NS_XML_AUTOLINK_REPLACE ||
rv == NS_XML_AUTOLINK_UNDEFINED) {
// If we do not terminate the parse, we just keep generating link trigger
// events. We want to parse only up to the first replace link, and stop.
mParser->Terminate();
}
}
}
return NS_OK;
}

Просмотреть файл

@ -1,4 +1,4 @@
<?xml version="1.0"?>
<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet href="xmlbase.css" type="text/css"?>
<root xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Root: no xml:base</title>
@ -59,4 +59,14 @@
<xlink:link xlink:type="simple" xlink:href="k.xml">k.xml</xlink:link>
<p>Expected: file:///not/k.xml</p>
</sect1>
<sect1 xml:base="http://foobar.com/ä ö/">
<title>Sect1: xml:base="http://foobar.com/ä ö/"</title>
<xlink:link xlink:type="simple" xlink:href="l.xml">l.xml</xlink:link>
<p>Expected: http://foobar.com/%E4%20%F6/l.xml</p>
</sect1>
<sect1 xml:base="http://foobar.com/ /%20/">
<title>Sect1: xml:base="http://foobar.com/ /%20/"</title>
<xlink:link xlink:type="simple" xlink:href="m.xml">m.xml</xlink:link>
<p>Expected: http://foobar.com/%20/%20/m.xml</p>
</sect1>
</root>

Просмотреть файл

@ -131,6 +131,8 @@
#include "nsISizeOfHandler.h"
class nsIWebShell;
// XXX This is sure to change. Copied from mozilla/layout/xul/content/src/nsXULAtoms.cpp
#define XUL_NAMESPACE_URI "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
static const char kXULNameSpaceURI[] = XUL_NAMESPACE_URI;
@ -1689,6 +1691,12 @@ nsXULElement::SetNameSpaceID(PRInt32 aNameSpaceID)
return NS_OK;
}
NS_IMETHODIMP
nsXULElement::MaybeTriggerAutoLink(nsIWebShell *aShell)
{
return NS_OK;
}
//----------------------------------------------------------------------
// nsIXULContent interface

Просмотреть файл

@ -73,6 +73,7 @@ class nsRDFDOMNodeList;
class nsString;
class nsVoidArray;
class nsXULAttributes;
class nsIWebShell;
////////////////////////////////////////////////////////////////////////
@ -436,6 +437,7 @@ public:
NS_IMETHOD SetNameSpacePrefix(nsIAtom* aNameSpace);
NS_IMETHOD GetNameSpacePrefix(nsIAtom*& aNameSpace) const;
NS_IMETHOD SetNameSpaceID(PRInt32 aNameSpaceID);
NS_IMETHOD MaybeTriggerAutoLink(nsIWebShell *aShell);
// nsIXULContent
NS_IMETHOD PeekChildCount(PRInt32& aCount) const;