diff --git a/mozilla/content/html/content/src/nsHTMLAnchorElement.cpp b/mozilla/content/html/content/src/nsHTMLAnchorElement.cpp
index e8978ee2d12..17fffa23ad4 100644
--- a/mozilla/content/html/content/src/nsHTMLAnchorElement.cpp
+++ b/mozilla/content/html/content/src/nsHTMLAnchorElement.cpp
@@ -279,7 +279,7 @@ nsHTMLAnchorElement::HandleDOMEvent(nsIPresContext& aPresContext,
if (target.Length() == 0) {
GetAttribute(nsString(NS_HTML_BASE_TARGET), target);
}
- mInner.TriggerLink(aPresContext, base, href, target, PR_TRUE);
+ mInner.TriggerLink(aPresContext, eLinkVerb_Replace, base, href, target, PR_TRUE);
aEventStatus = nsEventStatus_eConsumeNoDefault;
}
}
@@ -300,7 +300,7 @@ nsHTMLAnchorElement::HandleDOMEvent(nsIPresContext& aPresContext,
if (target.Length() == 0) {
GetAttribute(nsString(NS_HTML_BASE_TARGET), target);
}
- mInner.TriggerLink(aPresContext, base, href, target, PR_FALSE);
+ mInner.TriggerLink(aPresContext, eLinkVerb_Replace, base, href, target, PR_FALSE);
aEventStatus = nsEventStatus_eConsumeDoDefault;
}
break;
@@ -309,7 +309,7 @@ nsHTMLAnchorElement::HandleDOMEvent(nsIPresContext& aPresContext,
case NS_MOUSE_EXIT:
{
nsAutoString empty;
- mInner.TriggerLink(aPresContext, empty, empty, empty, PR_FALSE);
+ mInner.TriggerLink(aPresContext, eLinkVerb_Replace, empty, empty, empty, PR_FALSE);
aEventStatus = nsEventStatus_eConsumeDoDefault;
}
break;
diff --git a/mozilla/content/html/content/src/nsHTMLButtonElement.cpp b/mozilla/content/html/content/src/nsHTMLButtonElement.cpp
index 364cb900f5d..5e3a5b4f96c 100644
--- a/mozilla/content/html/content/src/nsHTMLButtonElement.cpp
+++ b/mozilla/content/html/content/src/nsHTMLButtonElement.cpp
@@ -327,7 +327,7 @@ nsHTMLButtonElement::HandleDOMEvent(nsIPresContext& aPresContext,
if (target.Length() == 0) {
GetAttribute(nsString(NS_HTML_BASE_TARGET), target);
}
- mInner.TriggerLink(aPresContext, base, href, target, PR_TRUE);
+ mInner.TriggerLink(aPresContext, eLinkVerb_Replace, base, href, target, PR_TRUE);
aEventStatus = nsEventStatus_eConsumeNoDefault;
}
}
@@ -348,7 +348,7 @@ nsHTMLButtonElement::HandleDOMEvent(nsIPresContext& aPresContext,
if (target.Length() == 0) {
GetAttribute(nsString(NS_HTML_BASE_TARGET), target);
}
- mInner.TriggerLink(aPresContext, base, href, target, PR_FALSE);
+ mInner.TriggerLink(aPresContext, eLinkVerb_Replace, base, href, target, PR_FALSE);
aEventStatus = nsEventStatus_eConsumeDoDefault;
}
break;
@@ -357,7 +357,7 @@ nsHTMLButtonElement::HandleDOMEvent(nsIPresContext& aPresContext,
case NS_MOUSE_EXIT:
{
nsAutoString empty;
- mInner.TriggerLink(aPresContext, empty, empty, empty, PR_FALSE);
+ mInner.TriggerLink(aPresContext, eLinkVerb_Replace, empty, empty, empty, PR_FALSE);
aEventStatus = nsEventStatus_eConsumeDoDefault;
}
break;
diff --git a/mozilla/content/xml/content/src/nsXMLElement.cpp b/mozilla/content/xml/content/src/nsXMLElement.cpp
index 4d19c70dae4..949548076f9 100644
--- a/mozilla/content/xml/content/src/nsXMLElement.cpp
+++ b/mozilla/content/xml/content/src/nsXMLElement.cpp
@@ -24,6 +24,9 @@
#include "nsIHTMLAttributes.h"
#include "nsIDOMScriptObjectFactory.h"
+#include "nsIEventStateManager.h"
+#include "nsDOMEvent.h"
+
//static NS_DEFINE_IID(kIDOMElementIID, NS_IDOMELEMENT_IID);
static NS_DEFINE_IID(kIXMLContentIID, NS_IXMLCONTENT_IID);
@@ -48,6 +51,7 @@ nsXMLElement::nsXMLElement(nsIAtom *aTag)
mNameSpace = nsnull;
mNameSpaceId = gNameSpaceId_Unknown;
mScriptObject = nsnull;
+ mIsLink = PR_FALSE;
}
nsXMLElement::~nsXMLElement()
@@ -160,6 +164,21 @@ nsXMLElement::GetNameSpaceIdentifier(PRInt32& aNameSpaceId)
return NS_OK;
}
+NS_IMETHODIMP
+nsXMLElement::SetAttribute(const nsString& aName,
+ const nsString& aValue,
+ PRBool aNotify)
+{
+ // XXX It sucks that we have to do a couple of strcmps for
+ // every attribute set. It might be a bit more expensive
+ // to create an atom.
+ if (aName.Equals("xml:link") && (aValue.Equals("simple"))) {
+ mIsLink = PR_TRUE;
+ }
+
+ return mInner.SetAttribute(aName, aValue, aNotify);
+}
+
NS_IMETHODIMP
nsXMLElement::HandleDOMEvent(nsIPresContext& aPresContext,
nsEvent* aEvent,
@@ -167,8 +186,90 @@ nsXMLElement::HandleDOMEvent(nsIPresContext& aPresContext,
PRUint32 aFlags,
nsEventStatus& aEventStatus)
{
- return mInner.HandleDOMEvent(aPresContext, aEvent, aDOMEvent,
- aFlags, aEventStatus);
+ // Try script event handlers first
+ nsresult ret = mInner.HandleDOMEvent(aPresContext, aEvent, aDOMEvent,
+ aFlags, aEventStatus);
+
+ if (mIsLink && (NS_OK == ret) && (nsEventStatus_eIgnore == aEventStatus)) {
+ switch (aEvent->message) {
+ case NS_MOUSE_LEFT_BUTTON_DOWN:
+ {
+ nsIEventStateManager *stateManager;
+ if (NS_OK == aPresContext.GetEventStateManager(&stateManager)) {
+ stateManager->SetActiveLink(this);
+ NS_RELEASE(stateManager);
+ }
+ aEventStatus = nsEventStatus_eConsumeNoDefault;
+ }
+ break;
+
+ case NS_MOUSE_LEFT_BUTTON_UP:
+ {
+ nsIEventStateManager *stateManager;
+ nsIContent *activeLink;
+ if (NS_OK == aPresContext.GetEventStateManager(&stateManager)) {
+ stateManager->GetActiveLink(&activeLink);
+ NS_RELEASE(stateManager);
+ }
+
+ if (activeLink == this) {
+ nsEventStatus status;
+ nsMouseEvent event;
+ event.eventStructType = NS_MOUSE_EVENT;
+ event.message = NS_MOUSE_LEFT_CLICK;
+ HandleDOMEvent(aPresContext, &event, nsnull, DOM_EVENT_INIT, status);
+
+ if (nsEventStatus_eConsumeNoDefault != status) {
+ nsAutoString show, href, base, target;
+ nsLinkVerb verb = eLinkVerb_Replace;
+ base.Truncate();
+ target.Truncate();
+ GetAttribute(nsString("href"), href);
+ GetAttribute(nsString("show"), show);
+ // XXX Should probably do this using atoms
+ if (show.Equals("new")) {
+ verb = eLinkVerb_New;
+ }
+ else if (show.Equals("embed")) {
+ verb = eLinkVerb_Embed;
+ }
+ mInner.TriggerLink(aPresContext, verb, base, href, target, PR_TRUE);
+ aEventStatus = nsEventStatus_eConsumeNoDefault;
+ }
+ }
+ }
+ break;
+
+ case NS_MOUSE_RIGHT_BUTTON_DOWN:
+ // XXX Bring up a contextual menu provided by the application
+ break;
+
+ case NS_MOUSE_ENTER:
+ //mouse enter doesn't work yet. Use move until then.
+ {
+ nsAutoString base, href, target;
+ base.Truncate();
+ target.Truncate();
+ GetAttribute(nsString("href"), href);
+ mInner.TriggerLink(aPresContext, eLinkVerb_Replace, base, href, target, PR_FALSE);
+ aEventStatus = nsEventStatus_eConsumeDoDefault;
+ }
+ break;
+
+ // XXX this doesn't seem to do anything yet
+ case NS_MOUSE_EXIT:
+ {
+ nsAutoString empty;
+ mInner.TriggerLink(aPresContext, eLinkVerb_Replace, empty, empty, empty, PR_FALSE);
+ aEventStatus = nsEventStatus_eConsumeDoDefault;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ return ret;
}
NS_IMETHODIMP
diff --git a/mozilla/content/xml/content/src/nsXMLElement.h b/mozilla/content/xml/content/src/nsXMLElement.h
index 03f50e9e782..bbb134476dc 100644
--- a/mozilla/content/xml/content/src/nsXMLElement.h
+++ b/mozilla/content/xml/content/src/nsXMLElement.h
@@ -56,7 +56,86 @@ public:
NS_IMETHOD SetScriptObject(void *aScriptObject);
// nsIContent
- NS_IMPL_ICONTENT_USING_GENERIC(mInner)
+ NS_IMETHOD GetDocument(nsIDocument*& aResult) const {
+ return mInner.GetDocument(aResult);
+ }
+ NS_IMETHOD SetDocument(nsIDocument* aDocument, PRBool aDeep) {
+ return mInner.SetDocument(aDocument, aDeep);
+ }
+ NS_IMETHOD GetParent(nsIContent*& aResult) const {
+ return mInner.GetParent(aResult);
+ }
+ NS_IMETHOD SetParent(nsIContent* aParent) {
+ return mInner.SetParent(aParent);
+ }
+ NS_IMETHOD CanContainChildren(PRBool& aResult) const {
+ return mInner.CanContainChildren(aResult);
+ }
+ NS_IMETHOD ChildCount(PRInt32& aResult) const {
+ return mInner.ChildCount(aResult);
+ }
+ NS_IMETHOD ChildAt(PRInt32 aIndex, nsIContent*& aResult) const {
+ return mInner.ChildAt(aIndex, aResult);
+ }
+ NS_IMETHOD IndexOf(nsIContent* aPossibleChild, PRInt32& aResult) const {
+ return mInner.IndexOf(aPossibleChild, aResult);
+ }
+ NS_IMETHOD InsertChildAt(nsIContent* aKid, PRInt32 aIndex,
+ PRBool aNotify) {
+ return mInner.InsertChildAt(aKid, aIndex, aNotify);
+ }
+ NS_IMETHOD ReplaceChildAt(nsIContent* aKid, PRInt32 aIndex,
+ PRBool aNotify) {
+ return mInner.ReplaceChildAt(aKid, aIndex, aNotify);
+ }
+ NS_IMETHOD AppendChildTo(nsIContent* aKid, PRBool aNotify) {
+ return mInner.AppendChildTo(aKid, aNotify);
+ }
+ NS_IMETHOD RemoveChildAt(PRInt32 aIndex, PRBool aNotify) {
+ return mInner.RemoveChildAt(aIndex, aNotify);
+ }
+ NS_IMETHOD IsSynthetic(PRBool& aResult) {
+ return mInner.IsSynthetic(aResult);
+ }
+ NS_IMETHOD GetTag(nsIAtom*& aResult) const {
+ return mInner.GetTag(aResult);
+ }
+ NS_IMETHOD SetAttribute(const nsString& aName, const nsString& aValue,
+ PRBool aNotify);
+ NS_IMETHOD GetAttribute(const nsString& aName,
+ nsString& aResult) const {
+ return mInner.GetAttribute(aName, aResult);
+ }
+ NS_IMETHOD UnsetAttribute(nsIAtom* aAttribute, PRBool aNotify) {
+ return mInner.UnsetAttribute(aAttribute, aNotify);
+ }
+ NS_IMETHOD GetAllAttributeNames(nsISupportsArray* aArray,
+ PRInt32& aResult) const {
+ return mInner.GetAllAttributeNames(aArray, aResult);
+ }
+ NS_IMETHOD GetAttributeCount(PRInt32& aResult) const {
+ return mInner.GetAttributeCount(aResult);
+ }
+ NS_IMETHOD List(FILE* out, PRInt32 aIndent) const {
+ return mInner.List(out, aIndent);
+ }
+ NS_IMETHOD BeginConvertToXIF(nsXIFConverter& aConverter) const {
+ return mInner.BeginConvertToXIF(aConverter);
+ }
+ NS_IMETHOD ConvertContentToXIF(nsXIFConverter& aConverter) const {
+ return mInner.ConvertContentToXIF(aConverter);
+ }
+ NS_IMETHOD FinishConvertToXIF(nsXIFConverter& aConverter) const {
+ return mInner.FinishConvertToXIF(aConverter);
+ }
+ NS_IMETHOD SizeOf(nsISizeOfHandler* aHandler) const {
+ return mInner.SizeOf(aHandler);
+ }
+ NS_IMETHOD HandleDOMEvent(nsIPresContext& aPresContext,
+ nsEvent* aEvent,
+ nsIDOMEvent** aDOMEvent,
+ PRUint32 aFlags,
+ nsEventStatus& aEventStatus);
// nsIXMLContent
NS_IMETHOD SetNameSpace(nsIAtom* aNameSpace);
@@ -99,6 +178,7 @@ protected:
nsIAtom* mNameSpace;
PRInt32 mNameSpaceId;
void *mScriptObject;
+ PRBool mIsLink;
};
#endif // nsXMLElement_h___
diff --git a/mozilla/content/xml/document/src/nsXMLContentSink.cpp b/mozilla/content/xml/document/src/nsXMLContentSink.cpp
index 8253254214c..f5ad2ce3d39 100644
--- a/mozilla/content/xml/document/src/nsXMLContentSink.cpp
+++ b/mozilla/content/xml/document/src/nsXMLContentSink.cpp
@@ -60,6 +60,20 @@ static NS_DEFINE_IID(kIScrollableViewIID, NS_ISCROLLABLEVIEW_IID);
#define XML_PSEUDO_ELEMENT 0
+// XXX Open Issues:
+// 1) html:style - Should we allow inline style? If so, the content
+// sink needs to process the tag and invoke the CSS parser.
+// 2) html:base - Should we allow a base tag? If so, the content
+// sink needs to maintain the base when resolving URLs for
+// loaded scripts and style sheets. Should it be allowed anywhere?
+// 3) what's not allowed - We need to figure out which HTML tags
+// (prefixed with a HTML namespace qualifier) are explicitly not
+// allowed (if any).
+// 4) factoring code with nsHTMLContentSink - There's some amount of
+// common code between this and the HTML content sink. This will
+// increase as we support more and more HTML elements. How can code
+// from the code be factored?
+
nsresult
NS_NewXMLContentSink(nsIXMLContentSink** aResult,
nsIDocument* aDoc,
diff --git a/mozilla/docshell/base/nsWebShell.cpp b/mozilla/docshell/base/nsWebShell.cpp
index 1d0e989f930..b104a17ebbc 100644
--- a/mozilla/docshell/base/nsWebShell.cpp
+++ b/mozilla/docshell/base/nsWebShell.cpp
@@ -47,7 +47,7 @@
#include "nsITimerCallback.h"
#include "jsurl.h"
#include "nsIBrowserWindow.h"
-
+#include "nsIContent.h"
#include "prlog.h"
@@ -206,11 +206,12 @@ public:
NS_IMETHOD FocusAvailable(nsIWebShell* aFocusedWebShell);
// nsILinkHandler
- NS_IMETHOD OnLinkClick(nsIFrame* aFrame,
+ NS_IMETHOD OnLinkClick(nsIContent* aContent,
+ nsLinkVerb aVerb,
const PRUnichar* aURLSpec,
const PRUnichar* aTargetSpec,
nsIPostData* aPostData = 0);
- NS_IMETHOD OnOverLink(nsIFrame* aFrame,
+ NS_IMETHOD OnOverLink(nsIContent* aContent,
const PRUnichar* aURLSpec,
const PRUnichar* aTargetSpec);
NS_IMETHOD GetLinkState(const PRUnichar* aURLSpec, nsLinkState& aState);
@@ -260,7 +261,9 @@ public:
NS_IMETHOD FindNext(const PRUnichar * aSearchStr, PRBool aMatchCase, PRBool aSearchDown, PRBool &aIsFound);
// nsWebShell
- void HandleLinkClickEvent(const PRUnichar* aURLSpec,
+ void HandleLinkClickEvent(nsIContent *aContent,
+ nsLinkVerb aVerb,
+ const PRUnichar* aURLSpec,
const PRUnichar* aTargetSpec,
nsIPostData* aPostDat = 0);
@@ -1459,18 +1462,22 @@ nsWebShell::FocusAvailable(nsIWebShell* aFocusedWebShell)
// WebShell link handling
struct OnLinkClickEvent : public PLEvent {
- OnLinkClickEvent(nsWebShell* aHandler, const PRUnichar* aURLSpec,
+ OnLinkClickEvent(nsWebShell* aHandler, nsIContent* aContent,
+ nsLinkVerb aVerb, const PRUnichar* aURLSpec,
const PRUnichar* aTargetSpec, nsIPostData* aPostData = 0);
~OnLinkClickEvent();
void HandleEvent() {
- mHandler->HandleLinkClickEvent(*mURLSpec, *mTargetSpec, mPostData);
+ mHandler->HandleLinkClickEvent(mContent, mVerb, *mURLSpec, *
+ mTargetSpec, mPostData);
}
nsWebShell* mHandler;
nsString* mURLSpec;
nsString* mTargetSpec;
nsIPostData* mPostData;
+ nsIContent* mContent;
+ nsLinkVerb mVerb;
};
static void PR_CALLBACK HandlePLEvent(OnLinkClickEvent* aEvent)
@@ -1484,6 +1491,8 @@ static void PR_CALLBACK DestroyPLEvent(OnLinkClickEvent* aEvent)
}
OnLinkClickEvent::OnLinkClickEvent(nsWebShell* aHandler,
+ nsIContent *aContent,
+ nsLinkVerb aVerb,
const PRUnichar* aURLSpec,
const PRUnichar* aTargetSpec,
nsIPostData* aPostData)
@@ -1494,7 +1503,10 @@ OnLinkClickEvent::OnLinkClickEvent(nsWebShell* aHandler,
mTargetSpec = new nsString(aTargetSpec);
mPostData = aPostData;
NS_IF_ADDREF(mPostData);
-
+ mContent = aContent;
+ NS_IF_ADDREF(mContent);
+ mVerb = aVerb;
+
#ifdef XP_PC
PL_InitEvent(this, nsnull,
(PLHandleEventProc) ::HandlePLEvent,
@@ -1516,16 +1528,19 @@ OnLinkClickEvent::OnLinkClickEvent(nsWebShell* aHandler,
OnLinkClickEvent::~OnLinkClickEvent()
{
+ NS_IF_RELEASE(mContent);
NS_IF_RELEASE(mHandler);
NS_IF_RELEASE(mPostData);
if (nsnull != mURLSpec) delete mURLSpec;
if (nsnull != mTargetSpec) delete mTargetSpec;
+
}
//----------------------------------------
NS_IMETHODIMP
-nsWebShell::OnLinkClick(nsIFrame* aFrame,
+nsWebShell::OnLinkClick(nsIContent* aContent,
+ nsLinkVerb aVerb,
const PRUnichar* aURLSpec,
const PRUnichar* aTargetSpec,
nsIPostData* aPostData)
@@ -1533,7 +1548,8 @@ nsWebShell::OnLinkClick(nsIFrame* aFrame,
OnLinkClickEvent* ev;
nsresult rv = NS_OK;
- ev = new OnLinkClickEvent(this, aURLSpec, aTargetSpec, aPostData);
+ ev = new OnLinkClickEvent(this, aContent, aVerb, aURLSpec,
+ aTargetSpec, aPostData);
if (nsnull == ev) {
rv = NS_ERROR_OUT_OF_MEMORY;
}
@@ -1603,19 +1619,36 @@ nsWebShell::GetTarget(const PRUnichar* aName)
}
void
-nsWebShell::HandleLinkClickEvent(const PRUnichar* aURLSpec,
+nsWebShell::HandleLinkClickEvent(nsIContent *aContent,
+ nsLinkVerb aVerb,
+ const PRUnichar* aURLSpec,
const PRUnichar* aTargetSpec,
nsIPostData* aPostData)
{
- nsIWebShell* shell = GetTarget(aTargetSpec);
- if (nsnull != shell) {
- shell->LoadURL(aURLSpec, aPostData);
- NS_RELEASE(shell);
+ nsAutoString target(aTargetSpec);
+
+ switch(aVerb) {
+ case eLinkVerb_New:
+ target.SetString("_blank");
+ // Fall into replace case
+ case eLinkVerb_Replace:
+ {
+ nsIWebShell* shell = GetTarget(target.GetUnicode());
+ if (nsnull != shell) {
+ shell->LoadURL(aURLSpec, aPostData);
+ NS_RELEASE(shell);
+ }
+ }
+ break;
+ case eLinkVerb_Embed:
+ default:
+ ;
+ // XXX Need to do this
}
}
NS_IMETHODIMP
-nsWebShell::OnOverLink(nsIFrame* aFrame,
+nsWebShell::OnOverLink(nsIContent* aContent,
const PRUnichar* aURLSpec,
const PRUnichar* aTargetSpec)
{
diff --git a/mozilla/layout/generic/nsImageFrame.cpp b/mozilla/layout/generic/nsImageFrame.cpp
index 603c0108931..60d7fcaef7d 100644
--- a/mozilla/layout/generic/nsImageFrame.cpp
+++ b/mozilla/layout/generic/nsImageFrame.cpp
@@ -719,10 +719,10 @@ ImageFrame::TriggerLink(nsIPresContext& aPresContext,
aPresContext.GetLinkHandler(&handler);
if (nsnull != handler) {
if (aClick) {
- handler->OnLinkClick(this, aURLSpec, aTargetSpec);
+ handler->OnLinkClick(mContent, eLinkVerb_Replace, aURLSpec, aTargetSpec);
}
else {
- handler->OnOverLink(this, aURLSpec, aTargetSpec);
+ handler->OnOverLink(mContent, aURLSpec, aTargetSpec);
}
}
}
diff --git a/mozilla/layout/generic/nsObjectFrame.cpp b/mozilla/layout/generic/nsObjectFrame.cpp
index 4c73e907d95..9f3ec856c5e 100644
--- a/mozilla/layout/generic/nsObjectFrame.cpp
+++ b/mozilla/layout/generic/nsObjectFrame.cpp
@@ -983,9 +983,12 @@ NS_IMETHODIMP nsPluginInstanceOwner :: GetURL(const char *aURL, const char *aTar
NS_RELEASE(docURL);
NS_RELEASE(doc);
- if (NS_OK == rv)
- rv = lh->OnLinkClick(mOwner, fullurl.GetUnicode(), unitarget.GetUnicode(), nsnull);
-
+ if (NS_OK == rv) {
+ nsIContent* content = nsnull;
+ mOwner->GetContent(content);
+ rv = lh->OnLinkClick(content, eLinkVerb_Replace, fullurl.GetUnicode(), unitarget.GetUnicode(), nsnull);
+ NS_IF_RELEASE(content);
+ }
NS_RELEASE(lh);
}
diff --git a/mozilla/layout/html/base/src/nsImageFrame.cpp b/mozilla/layout/html/base/src/nsImageFrame.cpp
index 603c0108931..60d7fcaef7d 100644
--- a/mozilla/layout/html/base/src/nsImageFrame.cpp
+++ b/mozilla/layout/html/base/src/nsImageFrame.cpp
@@ -719,10 +719,10 @@ ImageFrame::TriggerLink(nsIPresContext& aPresContext,
aPresContext.GetLinkHandler(&handler);
if (nsnull != handler) {
if (aClick) {
- handler->OnLinkClick(this, aURLSpec, aTargetSpec);
+ handler->OnLinkClick(mContent, eLinkVerb_Replace, aURLSpec, aTargetSpec);
}
else {
- handler->OnOverLink(this, aURLSpec, aTargetSpec);
+ handler->OnOverLink(mContent, aURLSpec, aTargetSpec);
}
}
}
diff --git a/mozilla/layout/html/base/src/nsObjectFrame.cpp b/mozilla/layout/html/base/src/nsObjectFrame.cpp
index 4c73e907d95..9f3ec856c5e 100644
--- a/mozilla/layout/html/base/src/nsObjectFrame.cpp
+++ b/mozilla/layout/html/base/src/nsObjectFrame.cpp
@@ -983,9 +983,12 @@ NS_IMETHODIMP nsPluginInstanceOwner :: GetURL(const char *aURL, const char *aTar
NS_RELEASE(docURL);
NS_RELEASE(doc);
- if (NS_OK == rv)
- rv = lh->OnLinkClick(mOwner, fullurl.GetUnicode(), unitarget.GetUnicode(), nsnull);
-
+ if (NS_OK == rv) {
+ nsIContent* content = nsnull;
+ mOwner->GetContent(content);
+ rv = lh->OnLinkClick(content, eLinkVerb_Replace, fullurl.GetUnicode(), unitarget.GetUnicode(), nsnull);
+ NS_IF_RELEASE(content);
+ }
NS_RELEASE(lh);
}
diff --git a/mozilla/layout/html/content/src/nsGenericElement.cpp b/mozilla/layout/html/content/src/nsGenericElement.cpp
index 7e57da630eb..bbd1dd8de96 100644
--- a/mozilla/layout/html/content/src/nsGenericElement.cpp
+++ b/mozilla/layout/html/content/src/nsGenericElement.cpp
@@ -1303,10 +1303,11 @@ nsGenericElement::Release()
void
nsGenericElement::TriggerLink(nsIPresContext& aPresContext,
- const nsString& aBase,
- const nsString& aURLSpec,
- const nsString& aTargetSpec,
- PRBool aClick)
+ nsLinkVerb aVerb,
+ const nsString& aBase,
+ const nsString& aURLSpec,
+ const nsString& aTargetSpec,
+ PRBool aClick)
{
nsILinkHandler* handler;
nsresult rv = aPresContext.GetLinkHandler(&handler);
@@ -1332,10 +1333,10 @@ nsGenericElement::TriggerLink(nsIPresContext& aPresContext,
// Now pass on absolute url to the click handler
if (aClick) {
- handler->OnLinkClick(nsnull, absURLSpec, aTargetSpec);
+ handler->OnLinkClick(mContent, aVerb, absURLSpec, aTargetSpec);
}
else {
- handler->OnOverLink(nsnull, absURLSpec, aTargetSpec);
+ handler->OnOverLink(mContent, absURLSpec, aTargetSpec);
}
NS_RELEASE(handler);
}
diff --git a/mozilla/layout/html/content/src/nsGenericElement.h b/mozilla/layout/html/content/src/nsGenericElement.h
index 88efb34440e..f92b0fe2d4e 100644
--- a/mozilla/layout/html/content/src/nsGenericElement.h
+++ b/mozilla/layout/html/content/src/nsGenericElement.h
@@ -27,6 +27,7 @@
#include "nsVoidArray.h"
#include "nsIScriptObjectOwner.h"
#include "nsIJSScriptObject.h"
+#include "nsILinkHandler.h"
extern const nsIID kIDOMNodeIID;
extern const nsIID kIDOMElementIID;
@@ -238,6 +239,7 @@ public:
REFNSIID aIID);
void TriggerLink(nsIPresContext& aPresContext,
+ nsLinkVerb aVerb,
const nsString& aBase,
const nsString& aURLSpec,
const nsString& aTargetSpec,
diff --git a/mozilla/layout/html/content/src/nsHTMLAnchorElement.cpp b/mozilla/layout/html/content/src/nsHTMLAnchorElement.cpp
index e8978ee2d12..17fffa23ad4 100644
--- a/mozilla/layout/html/content/src/nsHTMLAnchorElement.cpp
+++ b/mozilla/layout/html/content/src/nsHTMLAnchorElement.cpp
@@ -279,7 +279,7 @@ nsHTMLAnchorElement::HandleDOMEvent(nsIPresContext& aPresContext,
if (target.Length() == 0) {
GetAttribute(nsString(NS_HTML_BASE_TARGET), target);
}
- mInner.TriggerLink(aPresContext, base, href, target, PR_TRUE);
+ mInner.TriggerLink(aPresContext, eLinkVerb_Replace, base, href, target, PR_TRUE);
aEventStatus = nsEventStatus_eConsumeNoDefault;
}
}
@@ -300,7 +300,7 @@ nsHTMLAnchorElement::HandleDOMEvent(nsIPresContext& aPresContext,
if (target.Length() == 0) {
GetAttribute(nsString(NS_HTML_BASE_TARGET), target);
}
- mInner.TriggerLink(aPresContext, base, href, target, PR_FALSE);
+ mInner.TriggerLink(aPresContext, eLinkVerb_Replace, base, href, target, PR_FALSE);
aEventStatus = nsEventStatus_eConsumeDoDefault;
}
break;
@@ -309,7 +309,7 @@ nsHTMLAnchorElement::HandleDOMEvent(nsIPresContext& aPresContext,
case NS_MOUSE_EXIT:
{
nsAutoString empty;
- mInner.TriggerLink(aPresContext, empty, empty, empty, PR_FALSE);
+ mInner.TriggerLink(aPresContext, eLinkVerb_Replace, empty, empty, empty, PR_FALSE);
aEventStatus = nsEventStatus_eConsumeDoDefault;
}
break;
diff --git a/mozilla/layout/html/content/src/nsHTMLButtonElement.cpp b/mozilla/layout/html/content/src/nsHTMLButtonElement.cpp
index 364cb900f5d..5e3a5b4f96c 100644
--- a/mozilla/layout/html/content/src/nsHTMLButtonElement.cpp
+++ b/mozilla/layout/html/content/src/nsHTMLButtonElement.cpp
@@ -327,7 +327,7 @@ nsHTMLButtonElement::HandleDOMEvent(nsIPresContext& aPresContext,
if (target.Length() == 0) {
GetAttribute(nsString(NS_HTML_BASE_TARGET), target);
}
- mInner.TriggerLink(aPresContext, base, href, target, PR_TRUE);
+ mInner.TriggerLink(aPresContext, eLinkVerb_Replace, base, href, target, PR_TRUE);
aEventStatus = nsEventStatus_eConsumeNoDefault;
}
}
@@ -348,7 +348,7 @@ nsHTMLButtonElement::HandleDOMEvent(nsIPresContext& aPresContext,
if (target.Length() == 0) {
GetAttribute(nsString(NS_HTML_BASE_TARGET), target);
}
- mInner.TriggerLink(aPresContext, base, href, target, PR_FALSE);
+ mInner.TriggerLink(aPresContext, eLinkVerb_Replace, base, href, target, PR_FALSE);
aEventStatus = nsEventStatus_eConsumeDoDefault;
}
break;
@@ -357,7 +357,7 @@ nsHTMLButtonElement::HandleDOMEvent(nsIPresContext& aPresContext,
case NS_MOUSE_EXIT:
{
nsAutoString empty;
- mInner.TriggerLink(aPresContext, empty, empty, empty, PR_FALSE);
+ mInner.TriggerLink(aPresContext, eLinkVerb_Replace, empty, empty, empty, PR_FALSE);
aEventStatus = nsEventStatus_eConsumeDoDefault;
}
break;
diff --git a/mozilla/layout/html/forms/src/nsFormFrame.cpp b/mozilla/layout/html/forms/src/nsFormFrame.cpp
index 0c72eeaf9c3..9f42e145b96 100644
--- a/mozilla/layout/html/forms/src/nsFormFrame.cpp
+++ b/mozilla/layout/html/forms/src/nsFormFrame.cpp
@@ -457,8 +457,8 @@ nsFormFrame::OnSubmit(nsIPresContext* aPresContext, nsIFrame* aFrame)
}
/* The postBuffer is now owned by the IPostData instance */
- }
- handler->OnLinkClick(aFrame, absURLSpec, target, postData);
+ }
+ handler->OnLinkClick(mContent, eLinkVerb_Replace, absURLSpec, target, postData);
NS_IF_RELEASE(postData);
NS_RELEASE(handler);
diff --git a/mozilla/layout/xml/content/src/nsXMLElement.cpp b/mozilla/layout/xml/content/src/nsXMLElement.cpp
index 4d19c70dae4..949548076f9 100644
--- a/mozilla/layout/xml/content/src/nsXMLElement.cpp
+++ b/mozilla/layout/xml/content/src/nsXMLElement.cpp
@@ -24,6 +24,9 @@
#include "nsIHTMLAttributes.h"
#include "nsIDOMScriptObjectFactory.h"
+#include "nsIEventStateManager.h"
+#include "nsDOMEvent.h"
+
//static NS_DEFINE_IID(kIDOMElementIID, NS_IDOMELEMENT_IID);
static NS_DEFINE_IID(kIXMLContentIID, NS_IXMLCONTENT_IID);
@@ -48,6 +51,7 @@ nsXMLElement::nsXMLElement(nsIAtom *aTag)
mNameSpace = nsnull;
mNameSpaceId = gNameSpaceId_Unknown;
mScriptObject = nsnull;
+ mIsLink = PR_FALSE;
}
nsXMLElement::~nsXMLElement()
@@ -160,6 +164,21 @@ nsXMLElement::GetNameSpaceIdentifier(PRInt32& aNameSpaceId)
return NS_OK;
}
+NS_IMETHODIMP
+nsXMLElement::SetAttribute(const nsString& aName,
+ const nsString& aValue,
+ PRBool aNotify)
+{
+ // XXX It sucks that we have to do a couple of strcmps for
+ // every attribute set. It might be a bit more expensive
+ // to create an atom.
+ if (aName.Equals("xml:link") && (aValue.Equals("simple"))) {
+ mIsLink = PR_TRUE;
+ }
+
+ return mInner.SetAttribute(aName, aValue, aNotify);
+}
+
NS_IMETHODIMP
nsXMLElement::HandleDOMEvent(nsIPresContext& aPresContext,
nsEvent* aEvent,
@@ -167,8 +186,90 @@ nsXMLElement::HandleDOMEvent(nsIPresContext& aPresContext,
PRUint32 aFlags,
nsEventStatus& aEventStatus)
{
- return mInner.HandleDOMEvent(aPresContext, aEvent, aDOMEvent,
- aFlags, aEventStatus);
+ // Try script event handlers first
+ nsresult ret = mInner.HandleDOMEvent(aPresContext, aEvent, aDOMEvent,
+ aFlags, aEventStatus);
+
+ if (mIsLink && (NS_OK == ret) && (nsEventStatus_eIgnore == aEventStatus)) {
+ switch (aEvent->message) {
+ case NS_MOUSE_LEFT_BUTTON_DOWN:
+ {
+ nsIEventStateManager *stateManager;
+ if (NS_OK == aPresContext.GetEventStateManager(&stateManager)) {
+ stateManager->SetActiveLink(this);
+ NS_RELEASE(stateManager);
+ }
+ aEventStatus = nsEventStatus_eConsumeNoDefault;
+ }
+ break;
+
+ case NS_MOUSE_LEFT_BUTTON_UP:
+ {
+ nsIEventStateManager *stateManager;
+ nsIContent *activeLink;
+ if (NS_OK == aPresContext.GetEventStateManager(&stateManager)) {
+ stateManager->GetActiveLink(&activeLink);
+ NS_RELEASE(stateManager);
+ }
+
+ if (activeLink == this) {
+ nsEventStatus status;
+ nsMouseEvent event;
+ event.eventStructType = NS_MOUSE_EVENT;
+ event.message = NS_MOUSE_LEFT_CLICK;
+ HandleDOMEvent(aPresContext, &event, nsnull, DOM_EVENT_INIT, status);
+
+ if (nsEventStatus_eConsumeNoDefault != status) {
+ nsAutoString show, href, base, target;
+ nsLinkVerb verb = eLinkVerb_Replace;
+ base.Truncate();
+ target.Truncate();
+ GetAttribute(nsString("href"), href);
+ GetAttribute(nsString("show"), show);
+ // XXX Should probably do this using atoms
+ if (show.Equals("new")) {
+ verb = eLinkVerb_New;
+ }
+ else if (show.Equals("embed")) {
+ verb = eLinkVerb_Embed;
+ }
+ mInner.TriggerLink(aPresContext, verb, base, href, target, PR_TRUE);
+ aEventStatus = nsEventStatus_eConsumeNoDefault;
+ }
+ }
+ }
+ break;
+
+ case NS_MOUSE_RIGHT_BUTTON_DOWN:
+ // XXX Bring up a contextual menu provided by the application
+ break;
+
+ case NS_MOUSE_ENTER:
+ //mouse enter doesn't work yet. Use move until then.
+ {
+ nsAutoString base, href, target;
+ base.Truncate();
+ target.Truncate();
+ GetAttribute(nsString("href"), href);
+ mInner.TriggerLink(aPresContext, eLinkVerb_Replace, base, href, target, PR_FALSE);
+ aEventStatus = nsEventStatus_eConsumeDoDefault;
+ }
+ break;
+
+ // XXX this doesn't seem to do anything yet
+ case NS_MOUSE_EXIT:
+ {
+ nsAutoString empty;
+ mInner.TriggerLink(aPresContext, eLinkVerb_Replace, empty, empty, empty, PR_FALSE);
+ aEventStatus = nsEventStatus_eConsumeDoDefault;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ return ret;
}
NS_IMETHODIMP
diff --git a/mozilla/layout/xml/content/src/nsXMLElement.h b/mozilla/layout/xml/content/src/nsXMLElement.h
index 03f50e9e782..bbb134476dc 100644
--- a/mozilla/layout/xml/content/src/nsXMLElement.h
+++ b/mozilla/layout/xml/content/src/nsXMLElement.h
@@ -56,7 +56,86 @@ public:
NS_IMETHOD SetScriptObject(void *aScriptObject);
// nsIContent
- NS_IMPL_ICONTENT_USING_GENERIC(mInner)
+ NS_IMETHOD GetDocument(nsIDocument*& aResult) const {
+ return mInner.GetDocument(aResult);
+ }
+ NS_IMETHOD SetDocument(nsIDocument* aDocument, PRBool aDeep) {
+ return mInner.SetDocument(aDocument, aDeep);
+ }
+ NS_IMETHOD GetParent(nsIContent*& aResult) const {
+ return mInner.GetParent(aResult);
+ }
+ NS_IMETHOD SetParent(nsIContent* aParent) {
+ return mInner.SetParent(aParent);
+ }
+ NS_IMETHOD CanContainChildren(PRBool& aResult) const {
+ return mInner.CanContainChildren(aResult);
+ }
+ NS_IMETHOD ChildCount(PRInt32& aResult) const {
+ return mInner.ChildCount(aResult);
+ }
+ NS_IMETHOD ChildAt(PRInt32 aIndex, nsIContent*& aResult) const {
+ return mInner.ChildAt(aIndex, aResult);
+ }
+ NS_IMETHOD IndexOf(nsIContent* aPossibleChild, PRInt32& aResult) const {
+ return mInner.IndexOf(aPossibleChild, aResult);
+ }
+ NS_IMETHOD InsertChildAt(nsIContent* aKid, PRInt32 aIndex,
+ PRBool aNotify) {
+ return mInner.InsertChildAt(aKid, aIndex, aNotify);
+ }
+ NS_IMETHOD ReplaceChildAt(nsIContent* aKid, PRInt32 aIndex,
+ PRBool aNotify) {
+ return mInner.ReplaceChildAt(aKid, aIndex, aNotify);
+ }
+ NS_IMETHOD AppendChildTo(nsIContent* aKid, PRBool aNotify) {
+ return mInner.AppendChildTo(aKid, aNotify);
+ }
+ NS_IMETHOD RemoveChildAt(PRInt32 aIndex, PRBool aNotify) {
+ return mInner.RemoveChildAt(aIndex, aNotify);
+ }
+ NS_IMETHOD IsSynthetic(PRBool& aResult) {
+ return mInner.IsSynthetic(aResult);
+ }
+ NS_IMETHOD GetTag(nsIAtom*& aResult) const {
+ return mInner.GetTag(aResult);
+ }
+ NS_IMETHOD SetAttribute(const nsString& aName, const nsString& aValue,
+ PRBool aNotify);
+ NS_IMETHOD GetAttribute(const nsString& aName,
+ nsString& aResult) const {
+ return mInner.GetAttribute(aName, aResult);
+ }
+ NS_IMETHOD UnsetAttribute(nsIAtom* aAttribute, PRBool aNotify) {
+ return mInner.UnsetAttribute(aAttribute, aNotify);
+ }
+ NS_IMETHOD GetAllAttributeNames(nsISupportsArray* aArray,
+ PRInt32& aResult) const {
+ return mInner.GetAllAttributeNames(aArray, aResult);
+ }
+ NS_IMETHOD GetAttributeCount(PRInt32& aResult) const {
+ return mInner.GetAttributeCount(aResult);
+ }
+ NS_IMETHOD List(FILE* out, PRInt32 aIndent) const {
+ return mInner.List(out, aIndent);
+ }
+ NS_IMETHOD BeginConvertToXIF(nsXIFConverter& aConverter) const {
+ return mInner.BeginConvertToXIF(aConverter);
+ }
+ NS_IMETHOD ConvertContentToXIF(nsXIFConverter& aConverter) const {
+ return mInner.ConvertContentToXIF(aConverter);
+ }
+ NS_IMETHOD FinishConvertToXIF(nsXIFConverter& aConverter) const {
+ return mInner.FinishConvertToXIF(aConverter);
+ }
+ NS_IMETHOD SizeOf(nsISizeOfHandler* aHandler) const {
+ return mInner.SizeOf(aHandler);
+ }
+ NS_IMETHOD HandleDOMEvent(nsIPresContext& aPresContext,
+ nsEvent* aEvent,
+ nsIDOMEvent** aDOMEvent,
+ PRUint32 aFlags,
+ nsEventStatus& aEventStatus);
// nsIXMLContent
NS_IMETHOD SetNameSpace(nsIAtom* aNameSpace);
@@ -99,6 +178,7 @@ protected:
nsIAtom* mNameSpace;
PRInt32 mNameSpaceId;
void *mScriptObject;
+ PRBool mIsLink;
};
#endif // nsXMLElement_h___
diff --git a/mozilla/layout/xml/document/src/nsXMLContentSink.cpp b/mozilla/layout/xml/document/src/nsXMLContentSink.cpp
index 8253254214c..f5ad2ce3d39 100644
--- a/mozilla/layout/xml/document/src/nsXMLContentSink.cpp
+++ b/mozilla/layout/xml/document/src/nsXMLContentSink.cpp
@@ -60,6 +60,20 @@ static NS_DEFINE_IID(kIScrollableViewIID, NS_ISCROLLABLEVIEW_IID);
#define XML_PSEUDO_ELEMENT 0
+// XXX Open Issues:
+// 1) html:style - Should we allow inline style? If so, the content
+// sink needs to process the tag and invoke the CSS parser.
+// 2) html:base - Should we allow a base tag? If so, the content
+// sink needs to maintain the base when resolving URLs for
+// loaded scripts and style sheets. Should it be allowed anywhere?
+// 3) what's not allowed - We need to figure out which HTML tags
+// (prefixed with a HTML namespace qualifier) are explicitly not
+// allowed (if any).
+// 4) factoring code with nsHTMLContentSink - There's some amount of
+// common code between this and the HTML content sink. This will
+// increase as we support more and more HTML elements. How can code
+// from the code be factored?
+
nsresult
NS_NewXMLContentSink(nsIXMLContentSink** aResult,
nsIDocument* aDoc,
diff --git a/mozilla/webshell/public/nsILinkHandler.h b/mozilla/webshell/public/nsILinkHandler.h
index 35b4eb53fee..ec8a6a7c916 100644
--- a/mozilla/webshell/public/nsILinkHandler.h
+++ b/mozilla/webshell/public/nsILinkHandler.h
@@ -22,8 +22,8 @@
#include "nsweb.h"
#include "nsISupports.h"
-class nsIFrame;
class nsIPostData;
+class nsIContent;
struct nsGUIEvent;
// Interface ID for nsILinkHandler
@@ -38,29 +38,40 @@ enum nsLinkState {
eLinkState_Hover = 4 // mouse is hovering over link
};
+// XXX Verb to use for link actuation. These are the verbs specified
+// in the current XLink draft. We may actually want to support more
+// (especially for extended links).
+enum nsLinkVerb {
+ eLinkVerb_Replace = 0,
+ eLinkVerb_New = 1,
+ eLinkVerb_Embed = 2
+};
+
/**
* Interface used for handling clicks on links
*/
class nsILinkHandler : public nsISupports {
public:
/**
- * Process a click on a link. aFrame is the frame that contains the
- * linked content. aURLSpec is an absolute url spec that defines the
- * destination for the link. aTargetSpec indicates where the link is
- * targeted (it may be an empty string).
+ * Process a click on a link. aContent is the content for the frame
+ * that generated the trigger. aURLSpec is an absolute url spec that
+ * defines the destination for the link. aTargetSpec indicates where
+ * the link is targeted (it may be an empty string). aVerb indicates
+ * the verb to use when the link is triggered.
*/
- NS_IMETHOD OnLinkClick(nsIFrame* aFrame,
+ NS_IMETHOD OnLinkClick(nsIContent* aContent,
+ nsLinkVerb aVerb,
const PRUnichar* aURLSpec,
const PRUnichar* aTargetSpec,
nsIPostData* aPostData = 0) = 0;
/**
- * Process a mouse-over a link. aFrame is the frame that contains the
+ * Process a mouse-over a link. aContent is the
* linked content. aURLSpec is an absolute url spec that defines the
* destination for the link. aTargetSpec indicates where the link is
* targeted (it may be an empty string).
*/
- NS_IMETHOD OnOverLink(nsIFrame* aFrame,
+ NS_IMETHOD OnOverLink(nsIContent* aContent,
const PRUnichar* aURLSpec,
const PRUnichar* aTargetSpec) = 0;
diff --git a/mozilla/webshell/src/nsPluginViewer.cpp b/mozilla/webshell/src/nsPluginViewer.cpp
index 4e7b9db4c50..4359b3c77e4 100644
--- a/mozilla/webshell/src/nsPluginViewer.cpp
+++ b/mozilla/webshell/src/nsPluginViewer.cpp
@@ -29,6 +29,7 @@
#include "nsILinkHandler.h"
#include "nsIWebShell.h"
#include "nsIBrowserWindow.h"
+#include "nsIContent.h"
// Class IDs
static NS_DEFINE_IID(kChildWindowCID, NS_CHILD_CID);
@@ -631,7 +632,7 @@ NS_IMETHODIMP pluginInstanceOwner :: GetURL(const char *aURL, const char *aTarge
rv = NS_MakeAbsoluteURL(url, base, uniurl, fullurl);
if (NS_OK == rv)
- rv = lh->OnLinkClick(nsnull, fullurl.GetUnicode(), unitarget.GetUnicode(), nsnull);
+ rv = lh->OnLinkClick(nsnull, eLinkVerb_Replace, fullurl.GetUnicode(), unitarget.GetUnicode(), nsnull);
NS_RELEASE(url);
}
diff --git a/mozilla/webshell/src/nsWebShell.cpp b/mozilla/webshell/src/nsWebShell.cpp
index 1d0e989f930..b104a17ebbc 100644
--- a/mozilla/webshell/src/nsWebShell.cpp
+++ b/mozilla/webshell/src/nsWebShell.cpp
@@ -47,7 +47,7 @@
#include "nsITimerCallback.h"
#include "jsurl.h"
#include "nsIBrowserWindow.h"
-
+#include "nsIContent.h"
#include "prlog.h"
@@ -206,11 +206,12 @@ public:
NS_IMETHOD FocusAvailable(nsIWebShell* aFocusedWebShell);
// nsILinkHandler
- NS_IMETHOD OnLinkClick(nsIFrame* aFrame,
+ NS_IMETHOD OnLinkClick(nsIContent* aContent,
+ nsLinkVerb aVerb,
const PRUnichar* aURLSpec,
const PRUnichar* aTargetSpec,
nsIPostData* aPostData = 0);
- NS_IMETHOD OnOverLink(nsIFrame* aFrame,
+ NS_IMETHOD OnOverLink(nsIContent* aContent,
const PRUnichar* aURLSpec,
const PRUnichar* aTargetSpec);
NS_IMETHOD GetLinkState(const PRUnichar* aURLSpec, nsLinkState& aState);
@@ -260,7 +261,9 @@ public:
NS_IMETHOD FindNext(const PRUnichar * aSearchStr, PRBool aMatchCase, PRBool aSearchDown, PRBool &aIsFound);
// nsWebShell
- void HandleLinkClickEvent(const PRUnichar* aURLSpec,
+ void HandleLinkClickEvent(nsIContent *aContent,
+ nsLinkVerb aVerb,
+ const PRUnichar* aURLSpec,
const PRUnichar* aTargetSpec,
nsIPostData* aPostDat = 0);
@@ -1459,18 +1462,22 @@ nsWebShell::FocusAvailable(nsIWebShell* aFocusedWebShell)
// WebShell link handling
struct OnLinkClickEvent : public PLEvent {
- OnLinkClickEvent(nsWebShell* aHandler, const PRUnichar* aURLSpec,
+ OnLinkClickEvent(nsWebShell* aHandler, nsIContent* aContent,
+ nsLinkVerb aVerb, const PRUnichar* aURLSpec,
const PRUnichar* aTargetSpec, nsIPostData* aPostData = 0);
~OnLinkClickEvent();
void HandleEvent() {
- mHandler->HandleLinkClickEvent(*mURLSpec, *mTargetSpec, mPostData);
+ mHandler->HandleLinkClickEvent(mContent, mVerb, *mURLSpec, *
+ mTargetSpec, mPostData);
}
nsWebShell* mHandler;
nsString* mURLSpec;
nsString* mTargetSpec;
nsIPostData* mPostData;
+ nsIContent* mContent;
+ nsLinkVerb mVerb;
};
static void PR_CALLBACK HandlePLEvent(OnLinkClickEvent* aEvent)
@@ -1484,6 +1491,8 @@ static void PR_CALLBACK DestroyPLEvent(OnLinkClickEvent* aEvent)
}
OnLinkClickEvent::OnLinkClickEvent(nsWebShell* aHandler,
+ nsIContent *aContent,
+ nsLinkVerb aVerb,
const PRUnichar* aURLSpec,
const PRUnichar* aTargetSpec,
nsIPostData* aPostData)
@@ -1494,7 +1503,10 @@ OnLinkClickEvent::OnLinkClickEvent(nsWebShell* aHandler,
mTargetSpec = new nsString(aTargetSpec);
mPostData = aPostData;
NS_IF_ADDREF(mPostData);
-
+ mContent = aContent;
+ NS_IF_ADDREF(mContent);
+ mVerb = aVerb;
+
#ifdef XP_PC
PL_InitEvent(this, nsnull,
(PLHandleEventProc) ::HandlePLEvent,
@@ -1516,16 +1528,19 @@ OnLinkClickEvent::OnLinkClickEvent(nsWebShell* aHandler,
OnLinkClickEvent::~OnLinkClickEvent()
{
+ NS_IF_RELEASE(mContent);
NS_IF_RELEASE(mHandler);
NS_IF_RELEASE(mPostData);
if (nsnull != mURLSpec) delete mURLSpec;
if (nsnull != mTargetSpec) delete mTargetSpec;
+
}
//----------------------------------------
NS_IMETHODIMP
-nsWebShell::OnLinkClick(nsIFrame* aFrame,
+nsWebShell::OnLinkClick(nsIContent* aContent,
+ nsLinkVerb aVerb,
const PRUnichar* aURLSpec,
const PRUnichar* aTargetSpec,
nsIPostData* aPostData)
@@ -1533,7 +1548,8 @@ nsWebShell::OnLinkClick(nsIFrame* aFrame,
OnLinkClickEvent* ev;
nsresult rv = NS_OK;
- ev = new OnLinkClickEvent(this, aURLSpec, aTargetSpec, aPostData);
+ ev = new OnLinkClickEvent(this, aContent, aVerb, aURLSpec,
+ aTargetSpec, aPostData);
if (nsnull == ev) {
rv = NS_ERROR_OUT_OF_MEMORY;
}
@@ -1603,19 +1619,36 @@ nsWebShell::GetTarget(const PRUnichar* aName)
}
void
-nsWebShell::HandleLinkClickEvent(const PRUnichar* aURLSpec,
+nsWebShell::HandleLinkClickEvent(nsIContent *aContent,
+ nsLinkVerb aVerb,
+ const PRUnichar* aURLSpec,
const PRUnichar* aTargetSpec,
nsIPostData* aPostData)
{
- nsIWebShell* shell = GetTarget(aTargetSpec);
- if (nsnull != shell) {
- shell->LoadURL(aURLSpec, aPostData);
- NS_RELEASE(shell);
+ nsAutoString target(aTargetSpec);
+
+ switch(aVerb) {
+ case eLinkVerb_New:
+ target.SetString("_blank");
+ // Fall into replace case
+ case eLinkVerb_Replace:
+ {
+ nsIWebShell* shell = GetTarget(target.GetUnicode());
+ if (nsnull != shell) {
+ shell->LoadURL(aURLSpec, aPostData);
+ NS_RELEASE(shell);
+ }
+ }
+ break;
+ case eLinkVerb_Embed:
+ default:
+ ;
+ // XXX Need to do this
}
}
NS_IMETHODIMP
-nsWebShell::OnOverLink(nsIFrame* aFrame,
+nsWebShell::OnOverLink(nsIContent* aContent,
const PRUnichar* aURLSpec,
const PRUnichar* aTargetSpec)
{