зеркало из https://github.com/mozilla/gecko-dev.git
Implemented actuate=onLoad for simple XLinks. r=nisheeth.
This commit is contained in:
Родитель
02ef367e2b
Коммит
14cbdd72a2
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче