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) {