Fix for bug 9140. Area elements now have event fired for them. r=joki

This commit is contained in:
vidur%netscape.com 2000-02-11 01:24:59 +00:00
parent 59feaaf183
commit d4b67b3219
28 changed files with 698 additions and 546 deletions

View File

@ -409,7 +409,7 @@ nsEventStateManager::PreHandleEvent(nsIPresContext* aPresContext,
break;
case NS_MOUSE_MOVE:
GenerateDragGesture(aPresContext, aEvent);
UpdateCursor(aPresContext, aEvent->point, aTargetFrame, aStatus);
UpdateCursor(aPresContext, aEvent, aTargetFrame, aStatus);
GenerateMouseEnterExit(aPresContext, aEvent);
break;
case NS_MOUSE_EXIT:
@ -470,7 +470,7 @@ nsEventStateManager::PreHandleEvent(nsIPresContext* aPresContext,
case NS_ACTIVATE:
{
nsIContent* newFocus;
mCurrentTarget->GetContent(&newFocus);
mCurrentTarget->GetContentForEvent(aPresContext, aEvent, &newFocus);
if (newFocus) {
nsIFocusableContent *focusChange;
if (NS_SUCCEEDED(newFocus->QueryInterface(NS_GET_IID(nsIFocusableContent),
@ -517,7 +517,7 @@ nsEventStateManager::PreHandleEvent(nsIPresContext* aPresContext,
case NS_DEACTIVATE:
{
nsIContent* newFocus;
mCurrentTarget->GetContent(&newFocus);
mCurrentTarget->GetContentForEvent(aPresContext, aEvent, &newFocus);
if (newFocus) {
nsIFocusableContent *focusChange;
if (NS_SUCCEEDED(newFocus->QueryInterface(NS_GET_IID(nsIFocusableContent),
@ -655,7 +655,7 @@ nsEventStateManager :: GenerateDragGesture ( nsIPresContext* aPresContext, nsGUI
// dispatch to the DOM
nsCOMPtr<nsIContent> lastContent;
if ( mGestureDownFrame ) {
mGestureDownFrame->GetContent(getter_AddRefs(lastContent));
mGestureDownFrame->GetContentForEvent(aPresContext, aEvent, getter_AddRefs(lastContent));
if ( lastContent )
lastContent->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
}
@ -700,7 +700,7 @@ nsEventStateManager::PostHandleEvent(nsIPresContext* aPresContext,
if (nsEventStatus_eConsumeNoDefault != *aStatus) {
nsCOMPtr<nsIContent> newFocus;
mCurrentTarget->GetContent(getter_AddRefs(newFocus));
mCurrentTarget->GetContentForEvent(aPresContext, aEvent, getter_AddRefs(newFocus));
nsCOMPtr<nsIFocusableContent> focusable;
if (newFocus) {
@ -1090,7 +1090,7 @@ nsEventStateManager::CheckDisabled(nsIContent* aContent)
}
void
nsEventStateManager::UpdateCursor(nsIPresContext* aPresContext, nsPoint& aPoint, nsIFrame* aTargetFrame,
nsEventStateManager::UpdateCursor(nsIPresContext* aPresContext, nsEvent* aEvent, nsIFrame* aTargetFrame,
nsEventStatus* aStatus)
{
PRInt32 cursor;
@ -1107,7 +1107,7 @@ nsEventStateManager::UpdateCursor(nsIPresContext* aPresContext, nsPoint& aPoint,
}
//If not disabled, check for the right cursor.
else {
aTargetFrame->GetCursor(aPresContext, aPoint, cursor);
aTargetFrame->GetCursor(aPresContext, aEvent->point, cursor);
}
switch (cursor) {
@ -1169,13 +1169,12 @@ nsEventStateManager::GenerateMouseEnterExit(nsIPresContext* aPresContext, nsGUIE
switch(aEvent->message) {
case NS_MOUSE_MOVE:
{
if (mLastMouseOverFrame != mCurrentTarget) {
//We'll need the content, too, to check if it changed separately from the frames.
nsCOMPtr<nsIContent> lastContent;
nsCOMPtr<nsIContent> targetContent;
nsCOMPtr<nsIContent> targetContent;
if (mCurrentTarget) {
mCurrentTarget->GetContentForEvent(aPresContext, aEvent, getter_AddRefs(targetContent));
}
if ( mCurrentTarget )
mCurrentTarget->GetContent(getter_AddRefs(targetContent));
if (mLastMouseOverContent.get() != targetContent.get()) {
if (mLastMouseOverFrame) {
//fire mouseout
@ -1192,19 +1191,14 @@ nsEventStateManager::GenerateMouseEnterExit(nsIPresContext* aPresContext, nsGUIE
event.isAlt = ((nsMouseEvent*)aEvent)->isAlt;
event.isMeta = ((nsMouseEvent*)aEvent)->isMeta;
//The frame has change but the content may not have. Check before dispatching to content
mLastMouseOverFrame->GetContent(getter_AddRefs(lastContent));
mCurrentTargetContent = lastContent;
mCurrentTargetContent = mLastMouseOverContent;
NS_IF_ADDREF(mCurrentTargetContent);
mCurrentRelatedContent = targetContent;
NS_IF_ADDREF(mCurrentRelatedContent);
if (lastContent != targetContent) {
//XXX This event should still go somewhere!!
if (nsnull != lastContent) {
lastContent->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
}
//XXX This event should still go somewhere!!
if (nsnull != mLastMouseOverContent) {
mLastMouseOverContent->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
}
//Now dispatch to the frame
@ -1233,19 +1227,16 @@ nsEventStateManager::GenerateMouseEnterExit(nsIPresContext* aPresContext, nsGUIE
mCurrentTargetContent = targetContent;
NS_IF_ADDREF(mCurrentTargetContent);
mCurrentRelatedContent = lastContent;
mCurrentRelatedContent = mLastMouseOverContent;
NS_IF_ADDREF(mCurrentRelatedContent);
//The frame has change but the content may not have. Check before dispatching to content
if (lastContent != targetContent) {
//XXX This event should still go somewhere!!
if (targetContent) {
targetContent->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
}
if (nsEventStatus_eConsumeNoDefault != status) {
SetContentState(targetContent, NS_EVENT_STATE_HOVER);
}
//XXX This event should still go somewhere!!
if (targetContent) {
targetContent->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
}
if (nsEventStatus_eConsumeNoDefault != status) {
SetContentState(targetContent, NS_EVENT_STATE_HOVER);
}
//Now dispatch to the frame
@ -1257,6 +1248,7 @@ nsEventStateManager::GenerateMouseEnterExit(nsIPresContext* aPresContext, nsGUIE
NS_IF_RELEASE(mCurrentTargetContent);
NS_IF_RELEASE(mCurrentRelatedContent);
mLastMouseOverFrame = mCurrentTarget;
mLastMouseOverContent = targetContent;
}
}
break;
@ -1278,15 +1270,12 @@ nsEventStateManager::GenerateMouseEnterExit(nsIPresContext* aPresContext, nsGUIE
event.isAlt = ((nsMouseEvent*)aEvent)->isAlt;
event.isMeta = ((nsMouseEvent*)aEvent)->isMeta;
nsCOMPtr<nsIContent> lastContent;
mLastMouseOverFrame->GetContent(getter_AddRefs(lastContent));
mCurrentTargetContent = lastContent;
mCurrentTargetContent = mLastMouseOverContent;
NS_IF_ADDREF(mCurrentTargetContent);
mCurrentRelatedContent = nsnull;
if (lastContent) {
lastContent->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
if (mLastMouseOverContent) {
mLastMouseOverContent->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
if (nsEventStatus_eConsumeNoDefault != status) {
SetContentState(nsnull, NS_EVENT_STATE_HOVER);
@ -1299,6 +1288,7 @@ nsEventStateManager::GenerateMouseEnterExit(nsIPresContext* aPresContext, nsGUIE
//XXX Get the new frame
mLastMouseOverFrame->HandleEvent(aPresContext, &event, &status);
mLastMouseOverFrame = nsnull;
mLastMouseOverContent = nsnull;
}
NS_IF_RELEASE(mCurrentTargetContent);
@ -1324,7 +1314,7 @@ nsEventStateManager::GenerateDragDropEnterExit(nsIPresContext* aPresContext, nsG
//We'll need the content, too, to check if it changed separately from the frames.
nsCOMPtr<nsIContent> lastContent;
nsCOMPtr<nsIContent> targetContent;
mCurrentTarget->GetContent(getter_AddRefs(targetContent));
mCurrentTarget->GetContentForEvent(aPresContext, aEvent, getter_AddRefs(targetContent));
if ( mLastDragOverFrame ) {
//fire drag exit
@ -1342,7 +1332,7 @@ nsEventStateManager::GenerateDragDropEnterExit(nsIPresContext* aPresContext, nsG
event.isMeta = ((nsMouseEvent*)aEvent)->isMeta;
//The frame has change but the content may not have. Check before dispatching to content
mLastDragOverFrame->GetContent(getter_AddRefs(lastContent));
mLastDragOverFrame->GetContentForEvent(aPresContext, aEvent, getter_AddRefs(lastContent));
mCurrentTargetContent = lastContent;
NS_IF_ADDREF(mCurrentTargetContent);
@ -1434,7 +1424,7 @@ nsEventStateManager::GenerateDragDropEnterExit(nsIPresContext* aPresContext, nsG
// dispatch to content via DOM
nsCOMPtr<nsIContent> lastContent;
mLastDragOverFrame->GetContent(getter_AddRefs(lastContent));
mLastDragOverFrame->GetContentForEvent(aPresContext, aEvent, getter_AddRefs(lastContent));
mCurrentTargetContent = lastContent;
NS_IF_ADDREF(mCurrentTargetContent);
@ -1471,7 +1461,7 @@ nsEventStateManager::SetClickCount(nsIPresContext* aPresContext,
nsresult ret = NS_OK;
nsCOMPtr<nsIContent> mouseContent;
mCurrentTarget->GetContent(getter_AddRefs(mouseContent));
mCurrentTarget->GetContentForEvent(aPresContext, aEvent, getter_AddRefs(mouseContent));
switch (aEvent->message) {
case NS_MOUSE_LEFT_BUTTON_DOWN:
@ -1538,7 +1528,7 @@ nsEventStateManager::CheckForAndDispatchClick(nsIPresContext* aPresContext,
nsMouseEvent event;
nsCOMPtr<nsIContent> mouseContent;
mCurrentTarget->GetContent(getter_AddRefs(mouseContent));
mCurrentTarget->GetContentForEvent(aPresContext, aEvent, getter_AddRefs(mouseContent));
//If mouse is still over same element, clickcount will be > 1.
//If it has moved it will be zero, so no click.
@ -1955,7 +1945,7 @@ nsEventStateManager::GetEventTargetContent(nsEvent* aEvent, nsIContent** aConten
}
if (mCurrentTarget) {
mCurrentTarget->GetContent(aContent);
mCurrentTarget->GetContentForEvent(mPresContext, aEvent, aContent);
return NS_OK;
}
@ -2171,6 +2161,7 @@ nsEventStateManager::SendFocusBlur(nsIPresContext* aPresContext, nsIContent *aCo
// Go ahead and fire a blur on the window.
nsCOMPtr<nsIScriptGlobalObject> globalObject;
gLastFocusedDocument->GetScriptGlobalObject(getter_AddRefs(globalObject));
if (!mDocument) {

View File

@ -91,7 +91,7 @@ public:
NS_IMETHOD UnregisterAccessKey(nsIFrame * aFrame);
protected:
void UpdateCursor(nsIPresContext* aPresContext, nsPoint& aPoint, nsIFrame* aTargetFrame, nsEventStatus* aStatus);
void UpdateCursor(nsIPresContext* aPresContext, nsEvent* aEvent, nsIFrame* aTargetFrame, nsEventStatus* aStatus);
void GenerateMouseEnterExit(nsIPresContext* aPresContext, nsGUIEvent* aEvent);
void GenerateDragDropEnterExit(nsIPresContext* aPresContext, nsGUIEvent* aEvent);
NS_IMETHOD SetClickCount(nsIPresContext* aPresContext, nsMouseEvent *aEvent, nsEventStatus* aStatus);
@ -127,6 +127,7 @@ protected:
nsIContent* mCurrentTargetContent;
nsIContent* mCurrentRelatedContent;
nsIFrame* mLastMouseOverFrame;
nsCOMPtr<nsIContent> mLastMouseOverContent;
nsIFrame* mLastDragOverFrame;
// member variables for the d&d gesture state machine

View File

@ -584,6 +584,121 @@ nsGenericHTMLElement::SetDocumentForFormControls(nsIDocument* aDocument,
return result;
}
nsresult
nsGenericHTMLElement::HandleDOMEventForAnchors(nsIPresContext* aPresContext,
nsEvent* aEvent,
nsIDOMEvent** aDOMEvent,
PRUint32 aFlags,
nsEventStatus* aEventStatus)
{
NS_ENSURE_ARG(aPresContext);
NS_ENSURE_ARG_POINTER(aEventStatus);
// Try script event handlers first
nsresult ret = HandleDOMEvent(aPresContext, aEvent, aDOMEvent,
aFlags, aEventStatus);
if ((NS_OK == ret) && (nsEventStatus_eIgnore == *aEventStatus) &&
!(aFlags & NS_EVENT_FLAG_CAPTURE)) {
// If this anchor element has an HREF then it is sensitive to
// mouse events (otherwise ignore them).
nsAutoString href;
nsresult result = GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::href, href);
if (NS_CONTENT_ATTR_HAS_VALUE == result) {
switch (aEvent->message) {
case NS_MOUSE_LEFT_BUTTON_DOWN:
{
// don't make the link grab the focus if there is no link handler
nsILinkHandler* handler;
nsresult rv = aPresContext->GetLinkHandler(&handler);
if (NS_SUCCEEDED(rv) && (nsnull != handler)) {
nsIEventStateManager *stateManager;
if (NS_OK == aPresContext->GetEventStateManager(&stateManager)) {
stateManager->SetContentState(mContent, NS_EVENT_STATE_ACTIVE | NS_EVENT_STATE_FOCUS);
NS_RELEASE(stateManager);
}
NS_RELEASE(handler);
*aEventStatus = nsEventStatus_eConsumeNoDefault;
}
}
break;
case NS_MOUSE_LEFT_CLICK:
case NS_KEY_PRESS:
{
if (nsEventStatus_eConsumeNoDefault != *aEventStatus) {
nsKeyEvent * keyEvent;
if (aEvent->eventStructType == NS_KEY_EVENT) {
//Handle key commands from keys with char representation here, not on KeyDown
keyEvent = (nsKeyEvent *)aEvent;
}
//Click or return key
if (aEvent->message == NS_MOUSE_LEFT_CLICK || keyEvent->keyCode == NS_VK_RETURN) {
nsAutoString target;
nsIURI* baseURL = nsnull;
GetBaseURL(baseURL);
GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::target, target);
if (target.Length() == 0) {
GetBaseTarget(target);
}
ret = TriggerLink(aPresContext, eLinkVerb_Replace,
baseURL, href, target, PR_TRUE);
NS_IF_RELEASE(baseURL);
*aEventStatus = nsEventStatus_eConsumeDoDefault;
}
}
}
break;
case NS_MOUSE_RIGHT_BUTTON_DOWN:
// XXX Bring up a contextual menu provided by the application
break;
case NS_MOUSE_ENTER:
{
nsIEventStateManager *stateManager;
if (NS_OK == aPresContext->GetEventStateManager(&stateManager)) {
stateManager->SetContentState(mContent, NS_EVENT_STATE_HOVER);
NS_RELEASE(stateManager);
}
nsAutoString target;
nsIURI* baseURL = nsnull;
GetBaseURL(baseURL);
GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::target, target);
if (target.Length() == 0) {
GetBaseTarget(target);
}
ret = TriggerLink(aPresContext, eLinkVerb_Replace,
baseURL, href, target, PR_FALSE);
NS_IF_RELEASE(baseURL);
*aEventStatus = nsEventStatus_eConsumeNoDefault;
}
break;
case NS_MOUSE_EXIT:
{
nsIEventStateManager *stateManager;
if (NS_OK == aPresContext->GetEventStateManager(&stateManager)) {
stateManager->SetContentState(nsnull, NS_EVENT_STATE_HOVER);
NS_RELEASE(stateManager);
}
nsAutoString empty;
ret = TriggerLink(aPresContext, eLinkVerb_Replace, nsnull, empty, empty, PR_FALSE);
*aEventStatus = nsEventStatus_eConsumeNoDefault;
}
break;
default:
break;
}
}
}
return ret;
}
nsresult
nsGenericHTMLElement::GetNameSpaceID(PRInt32& aID) const
{

View File

@ -117,6 +117,11 @@ public:
PRBool aDeep,
nsIFormControl* aControl,
nsIForm* aForm);
nsresult HandleDOMEventForAnchors(nsIPresContext* aPresContext,
nsEvent* aEvent,
nsIDOMEvent** aDOMEvent,
PRUint32 aFlags,
nsEventStatus* aEventStatus);
// Implementation for nsIHTMLContent
nsresult Compact();

View File

@ -334,112 +334,11 @@ nsHTMLAnchorElement::HandleDOMEvent(nsIPresContext* aPresContext,
PRUint32 aFlags,
nsEventStatus* aEventStatus)
{
NS_ENSURE_ARG(aPresContext);
NS_ENSURE_ARG_POINTER(aEventStatus);
// Try script event handlers first
nsresult ret = mInner.HandleDOMEvent(aPresContext, aEvent, aDOMEvent,
aFlags, aEventStatus);
if ((NS_OK == ret) && (nsEventStatus_eIgnore == *aEventStatus) &&
!(aFlags & NS_EVENT_FLAG_CAPTURE)) {
// If this anchor element has an HREF then it is sensitive to
// mouse events (otherwise ignore them).
nsAutoString href;
nsresult result = GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::href, href);
if (NS_CONTENT_ATTR_HAS_VALUE == result) {
switch (aEvent->message) {
case NS_MOUSE_LEFT_BUTTON_DOWN:
{
// don't make the link grab the focus if there is no link handler
nsILinkHandler* handler;
nsresult rv = aPresContext->GetLinkHandler(&handler);
if (NS_SUCCEEDED(rv) && (nsnull != handler)) {
nsIEventStateManager *stateManager;
if (NS_OK == aPresContext->GetEventStateManager(&stateManager)) {
stateManager->SetContentState(this, NS_EVENT_STATE_ACTIVE | NS_EVENT_STATE_FOCUS);
NS_RELEASE(stateManager);
}
NS_RELEASE(handler);
*aEventStatus = nsEventStatus_eConsumeNoDefault;
}
}
break;
case NS_MOUSE_LEFT_CLICK:
case NS_KEY_PRESS:
{
if (nsEventStatus_eConsumeNoDefault != *aEventStatus) {
nsKeyEvent * keyEvent;
if (aEvent->eventStructType == NS_KEY_EVENT) {
//Handle key commands from keys with char representation here, not on KeyDown
keyEvent = (nsKeyEvent *)aEvent;
}
//Click or return key
if (aEvent->message == NS_MOUSE_LEFT_CLICK || keyEvent->keyCode == NS_VK_RETURN) {
nsAutoString target;
nsIURI* baseURL = nsnull;
GetBaseURL(baseURL);
GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::target, target);
if (target.Length() == 0) {
GetBaseTarget(target);
}
ret = mInner.TriggerLink(aPresContext, eLinkVerb_Replace,
baseURL, href, target, PR_TRUE);
NS_IF_RELEASE(baseURL);
*aEventStatus = nsEventStatus_eConsumeDoDefault;
}
}
}
break;
case NS_MOUSE_RIGHT_BUTTON_DOWN:
// XXX Bring up a contextual menu provided by the application
break;
case NS_MOUSE_ENTER:
{
nsIEventStateManager *stateManager;
if (NS_OK == aPresContext->GetEventStateManager(&stateManager)) {
stateManager->SetContentState(this, NS_EVENT_STATE_HOVER);
NS_RELEASE(stateManager);
}
nsAutoString target;
nsIURI* baseURL = nsnull;
GetBaseURL(baseURL);
GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::target, target);
if (target.Length() == 0) {
GetBaseTarget(target);
}
ret = mInner.TriggerLink(aPresContext, eLinkVerb_Replace,
baseURL, href, target, PR_FALSE);
NS_IF_RELEASE(baseURL);
*aEventStatus = nsEventStatus_eConsumeNoDefault;
}
break;
case NS_MOUSE_EXIT:
{
nsIEventStateManager *stateManager;
if (NS_OK == aPresContext->GetEventStateManager(&stateManager)) {
stateManager->SetContentState(nsnull, NS_EVENT_STATE_HOVER);
NS_RELEASE(stateManager);
}
nsAutoString empty;
ret = mInner.TriggerLink(aPresContext, eLinkVerb_Replace, nsnull, empty, empty, PR_FALSE);
*aEventStatus = nsEventStatus_eConsumeNoDefault;
}
break;
default:
break;
}
}
}
return ret;
return mInner.HandleDOMEventForAnchors(aPresContext,
aEvent,
aDOMEvent,
aFlags,
aEventStatus);
}
NS_IMETHODIMP

View File

@ -226,8 +226,11 @@ nsHTMLAreaElement::HandleDOMEvent(nsIPresContext* aPresContext,
PRUint32 aFlags,
nsEventStatus* aEventStatus)
{
return mInner.HandleDOMEvent(aPresContext, aEvent, aDOMEvent,
aFlags, aEventStatus);
return mInner.HandleDOMEventForAnchors(aPresContext,
aEvent,
aDOMEvent,
aFlags,
aEventStatus);
}
NS_IMETHODIMP

View File

@ -2869,7 +2869,7 @@ PresShell::HandleEvent(nsIView *aView,
}
else {
nsIContent* targetContent;
if (NS_OK == mCurrentEventFrame->GetContent(&targetContent) && nsnull != targetContent) {
if (NS_OK == mCurrentEventFrame->GetContentForEvent(mPresContext, aEvent, &targetContent) && nsnull != targetContent) {
rv = targetContent->HandleDOMEvent(mPresContext, (nsEvent*)aEvent, nsnull,
NS_EVENT_FLAG_INIT, aEventStatus);
NS_RELEASE(targetContent);

View File

@ -678,6 +678,10 @@ public:
nsGUIEvent* aEvent,
nsEventStatus* aEventStatus) = 0;
NS_IMETHOD GetContentForEvent(nsIPresContext* aPresContext,
nsEvent* aEvent,
nsIContent** aContent) = 0;
NS_IMETHOD GetContentAndOffsetsFromPoint(nsIPresContext* aCX,
const nsPoint& aPoint,
nsIContent ** aNewContent,

View File

@ -409,7 +409,7 @@ nsEventStateManager::PreHandleEvent(nsIPresContext* aPresContext,
break;
case NS_MOUSE_MOVE:
GenerateDragGesture(aPresContext, aEvent);
UpdateCursor(aPresContext, aEvent->point, aTargetFrame, aStatus);
UpdateCursor(aPresContext, aEvent, aTargetFrame, aStatus);
GenerateMouseEnterExit(aPresContext, aEvent);
break;
case NS_MOUSE_EXIT:
@ -470,7 +470,7 @@ nsEventStateManager::PreHandleEvent(nsIPresContext* aPresContext,
case NS_ACTIVATE:
{
nsIContent* newFocus;
mCurrentTarget->GetContent(&newFocus);
mCurrentTarget->GetContentForEvent(aPresContext, aEvent, &newFocus);
if (newFocus) {
nsIFocusableContent *focusChange;
if (NS_SUCCEEDED(newFocus->QueryInterface(NS_GET_IID(nsIFocusableContent),
@ -517,7 +517,7 @@ nsEventStateManager::PreHandleEvent(nsIPresContext* aPresContext,
case NS_DEACTIVATE:
{
nsIContent* newFocus;
mCurrentTarget->GetContent(&newFocus);
mCurrentTarget->GetContentForEvent(aPresContext, aEvent, &newFocus);
if (newFocus) {
nsIFocusableContent *focusChange;
if (NS_SUCCEEDED(newFocus->QueryInterface(NS_GET_IID(nsIFocusableContent),
@ -655,7 +655,7 @@ nsEventStateManager :: GenerateDragGesture ( nsIPresContext* aPresContext, nsGUI
// dispatch to the DOM
nsCOMPtr<nsIContent> lastContent;
if ( mGestureDownFrame ) {
mGestureDownFrame->GetContent(getter_AddRefs(lastContent));
mGestureDownFrame->GetContentForEvent(aPresContext, aEvent, getter_AddRefs(lastContent));
if ( lastContent )
lastContent->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
}
@ -700,7 +700,7 @@ nsEventStateManager::PostHandleEvent(nsIPresContext* aPresContext,
if (nsEventStatus_eConsumeNoDefault != *aStatus) {
nsCOMPtr<nsIContent> newFocus;
mCurrentTarget->GetContent(getter_AddRefs(newFocus));
mCurrentTarget->GetContentForEvent(aPresContext, aEvent, getter_AddRefs(newFocus));
nsCOMPtr<nsIFocusableContent> focusable;
if (newFocus) {
@ -1090,7 +1090,7 @@ nsEventStateManager::CheckDisabled(nsIContent* aContent)
}
void
nsEventStateManager::UpdateCursor(nsIPresContext* aPresContext, nsPoint& aPoint, nsIFrame* aTargetFrame,
nsEventStateManager::UpdateCursor(nsIPresContext* aPresContext, nsEvent* aEvent, nsIFrame* aTargetFrame,
nsEventStatus* aStatus)
{
PRInt32 cursor;
@ -1107,7 +1107,7 @@ nsEventStateManager::UpdateCursor(nsIPresContext* aPresContext, nsPoint& aPoint,
}
//If not disabled, check for the right cursor.
else {
aTargetFrame->GetCursor(aPresContext, aPoint, cursor);
aTargetFrame->GetCursor(aPresContext, aEvent->point, cursor);
}
switch (cursor) {
@ -1169,13 +1169,12 @@ nsEventStateManager::GenerateMouseEnterExit(nsIPresContext* aPresContext, nsGUIE
switch(aEvent->message) {
case NS_MOUSE_MOVE:
{
if (mLastMouseOverFrame != mCurrentTarget) {
//We'll need the content, too, to check if it changed separately from the frames.
nsCOMPtr<nsIContent> lastContent;
nsCOMPtr<nsIContent> targetContent;
nsCOMPtr<nsIContent> targetContent;
if (mCurrentTarget) {
mCurrentTarget->GetContentForEvent(aPresContext, aEvent, getter_AddRefs(targetContent));
}
if ( mCurrentTarget )
mCurrentTarget->GetContent(getter_AddRefs(targetContent));
if (mLastMouseOverContent.get() != targetContent.get()) {
if (mLastMouseOverFrame) {
//fire mouseout
@ -1192,19 +1191,14 @@ nsEventStateManager::GenerateMouseEnterExit(nsIPresContext* aPresContext, nsGUIE
event.isAlt = ((nsMouseEvent*)aEvent)->isAlt;
event.isMeta = ((nsMouseEvent*)aEvent)->isMeta;
//The frame has change but the content may not have. Check before dispatching to content
mLastMouseOverFrame->GetContent(getter_AddRefs(lastContent));
mCurrentTargetContent = lastContent;
mCurrentTargetContent = mLastMouseOverContent;
NS_IF_ADDREF(mCurrentTargetContent);
mCurrentRelatedContent = targetContent;
NS_IF_ADDREF(mCurrentRelatedContent);
if (lastContent != targetContent) {
//XXX This event should still go somewhere!!
if (nsnull != lastContent) {
lastContent->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
}
//XXX This event should still go somewhere!!
if (nsnull != mLastMouseOverContent) {
mLastMouseOverContent->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
}
//Now dispatch to the frame
@ -1233,19 +1227,16 @@ nsEventStateManager::GenerateMouseEnterExit(nsIPresContext* aPresContext, nsGUIE
mCurrentTargetContent = targetContent;
NS_IF_ADDREF(mCurrentTargetContent);
mCurrentRelatedContent = lastContent;
mCurrentRelatedContent = mLastMouseOverContent;
NS_IF_ADDREF(mCurrentRelatedContent);
//The frame has change but the content may not have. Check before dispatching to content
if (lastContent != targetContent) {
//XXX This event should still go somewhere!!
if (targetContent) {
targetContent->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
}
if (nsEventStatus_eConsumeNoDefault != status) {
SetContentState(targetContent, NS_EVENT_STATE_HOVER);
}
//XXX This event should still go somewhere!!
if (targetContent) {
targetContent->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
}
if (nsEventStatus_eConsumeNoDefault != status) {
SetContentState(targetContent, NS_EVENT_STATE_HOVER);
}
//Now dispatch to the frame
@ -1257,6 +1248,7 @@ nsEventStateManager::GenerateMouseEnterExit(nsIPresContext* aPresContext, nsGUIE
NS_IF_RELEASE(mCurrentTargetContent);
NS_IF_RELEASE(mCurrentRelatedContent);
mLastMouseOverFrame = mCurrentTarget;
mLastMouseOverContent = targetContent;
}
}
break;
@ -1278,15 +1270,12 @@ nsEventStateManager::GenerateMouseEnterExit(nsIPresContext* aPresContext, nsGUIE
event.isAlt = ((nsMouseEvent*)aEvent)->isAlt;
event.isMeta = ((nsMouseEvent*)aEvent)->isMeta;
nsCOMPtr<nsIContent> lastContent;
mLastMouseOverFrame->GetContent(getter_AddRefs(lastContent));
mCurrentTargetContent = lastContent;
mCurrentTargetContent = mLastMouseOverContent;
NS_IF_ADDREF(mCurrentTargetContent);
mCurrentRelatedContent = nsnull;
if (lastContent) {
lastContent->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
if (mLastMouseOverContent) {
mLastMouseOverContent->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
if (nsEventStatus_eConsumeNoDefault != status) {
SetContentState(nsnull, NS_EVENT_STATE_HOVER);
@ -1299,6 +1288,7 @@ nsEventStateManager::GenerateMouseEnterExit(nsIPresContext* aPresContext, nsGUIE
//XXX Get the new frame
mLastMouseOverFrame->HandleEvent(aPresContext, &event, &status);
mLastMouseOverFrame = nsnull;
mLastMouseOverContent = nsnull;
}
NS_IF_RELEASE(mCurrentTargetContent);
@ -1324,7 +1314,7 @@ nsEventStateManager::GenerateDragDropEnterExit(nsIPresContext* aPresContext, nsG
//We'll need the content, too, to check if it changed separately from the frames.
nsCOMPtr<nsIContent> lastContent;
nsCOMPtr<nsIContent> targetContent;
mCurrentTarget->GetContent(getter_AddRefs(targetContent));
mCurrentTarget->GetContentForEvent(aPresContext, aEvent, getter_AddRefs(targetContent));
if ( mLastDragOverFrame ) {
//fire drag exit
@ -1342,7 +1332,7 @@ nsEventStateManager::GenerateDragDropEnterExit(nsIPresContext* aPresContext, nsG
event.isMeta = ((nsMouseEvent*)aEvent)->isMeta;
//The frame has change but the content may not have. Check before dispatching to content
mLastDragOverFrame->GetContent(getter_AddRefs(lastContent));
mLastDragOverFrame->GetContentForEvent(aPresContext, aEvent, getter_AddRefs(lastContent));
mCurrentTargetContent = lastContent;
NS_IF_ADDREF(mCurrentTargetContent);
@ -1434,7 +1424,7 @@ nsEventStateManager::GenerateDragDropEnterExit(nsIPresContext* aPresContext, nsG
// dispatch to content via DOM
nsCOMPtr<nsIContent> lastContent;
mLastDragOverFrame->GetContent(getter_AddRefs(lastContent));
mLastDragOverFrame->GetContentForEvent(aPresContext, aEvent, getter_AddRefs(lastContent));
mCurrentTargetContent = lastContent;
NS_IF_ADDREF(mCurrentTargetContent);
@ -1471,7 +1461,7 @@ nsEventStateManager::SetClickCount(nsIPresContext* aPresContext,
nsresult ret = NS_OK;
nsCOMPtr<nsIContent> mouseContent;
mCurrentTarget->GetContent(getter_AddRefs(mouseContent));
mCurrentTarget->GetContentForEvent(aPresContext, aEvent, getter_AddRefs(mouseContent));
switch (aEvent->message) {
case NS_MOUSE_LEFT_BUTTON_DOWN:
@ -1538,7 +1528,7 @@ nsEventStateManager::CheckForAndDispatchClick(nsIPresContext* aPresContext,
nsMouseEvent event;
nsCOMPtr<nsIContent> mouseContent;
mCurrentTarget->GetContent(getter_AddRefs(mouseContent));
mCurrentTarget->GetContentForEvent(aPresContext, aEvent, getter_AddRefs(mouseContent));
//If mouse is still over same element, clickcount will be > 1.
//If it has moved it will be zero, so no click.
@ -1955,7 +1945,7 @@ nsEventStateManager::GetEventTargetContent(nsEvent* aEvent, nsIContent** aConten
}
if (mCurrentTarget) {
mCurrentTarget->GetContent(aContent);
mCurrentTarget->GetContentForEvent(mPresContext, aEvent, aContent);
return NS_OK;
}
@ -2171,6 +2161,7 @@ nsEventStateManager::SendFocusBlur(nsIPresContext* aPresContext, nsIContent *aCo
// Go ahead and fire a blur on the window.
nsCOMPtr<nsIScriptGlobalObject> globalObject;
gLastFocusedDocument->GetScriptGlobalObject(getter_AddRefs(globalObject));
if (!mDocument) {

View File

@ -91,7 +91,7 @@ public:
NS_IMETHOD UnregisterAccessKey(nsIFrame * aFrame);
protected:
void UpdateCursor(nsIPresContext* aPresContext, nsPoint& aPoint, nsIFrame* aTargetFrame, nsEventStatus* aStatus);
void UpdateCursor(nsIPresContext* aPresContext, nsEvent* aEvent, nsIFrame* aTargetFrame, nsEventStatus* aStatus);
void GenerateMouseEnterExit(nsIPresContext* aPresContext, nsGUIEvent* aEvent);
void GenerateDragDropEnterExit(nsIPresContext* aPresContext, nsGUIEvent* aEvent);
NS_IMETHOD SetClickCount(nsIPresContext* aPresContext, nsMouseEvent *aEvent, nsEventStatus* aStatus);
@ -127,6 +127,7 @@ protected:
nsIContent* mCurrentTargetContent;
nsIContent* mCurrentRelatedContent;
nsIFrame* mLastMouseOverFrame;
nsCOMPtr<nsIContent> mLastMouseOverContent;
nsIFrame* mLastDragOverFrame;
// member variables for the d&d gesture state machine

View File

@ -746,6 +746,17 @@ nsFrame::Paint(nsIPresContext* aPresContext,
return NS_OK;
}
/**
*
*/
NS_IMETHODIMP
nsFrame::GetContentForEvent(nsIPresContext* aPresContext,
nsEvent* aEvent,
nsIContent** aContent)
{
return GetContent(aContent);
}
/**
*
*/

View File

@ -195,6 +195,9 @@ public:
NS_IMETHOD HandleEvent(nsIPresContext* aPresContext,
nsGUIEvent* aEvent,
nsEventStatus* aEventStatus);
NS_IMETHOD GetContentForEvent(nsIPresContext* aPresContext,
nsEvent* aEvent,
nsIContent** aContent);
NS_IMETHOD GetCursor(nsIPresContext* aPresContext,
nsPoint& aPoint,
PRInt32& aCursor);

View File

@ -678,6 +678,10 @@ public:
nsGUIEvent* aEvent,
nsEventStatus* aEventStatus) = 0;
NS_IMETHOD GetContentForEvent(nsIPresContext* aPresContext,
nsEvent* aEvent,
nsIContent** aContent) = 0;
NS_IMETHOD GetContentAndOffsetsFromPoint(nsIPresContext* aCX,
const nsPoint& aPoint,
nsIContent ** aNewContent,

View File

@ -686,6 +686,35 @@ nsImageFrame::GetAnchorHREF(nsString& aResult)
return status;
}
NS_IMETHODIMP
nsImageFrame::GetContentForEvent(nsIPresContext* aPresContext,
nsEvent* aEvent,
nsIContent** aContent)
{
NS_ENSURE_ARG_POINTER(aContent);
nsImageMap* map;
map = GetImageMap();
if (nsnull != map) {
nsPoint p;
TranslateEventCoords(aPresContext, aEvent->point, p);
nsAutoString absURL, target, altText;
PRBool suppress;
PRBool inside = PR_FALSE;
nsCOMPtr<nsIContent> area;
inside = map->IsInside(p.x, p.y, getter_AddRefs(area),
absURL, target, altText,
&suppress);
if (inside && area) {
*aContent = area;
NS_ADDREF(*aContent);
return NS_OK;
}
}
return GetContent(aContent);
}
// XXX what should clicks on transparent pixels do?
NS_METHOD
nsImageFrame::HandleEvent(nsIPresContext* aPresContext,
@ -707,30 +736,15 @@ nsImageFrame::HandleEvent(nsIPresContext* aPresContext,
nsAutoString absURL, target, altText;
PRBool suppress;
PRBool inside = PR_FALSE;
// Even though client-side image map triggering happens
// through content, we need to make sure we're not inside
// (in case we deal with a case of both client-side and
// sever-side on the same image - it happens!)
if (nsnull != map) {
nsIDocument* doc = nsnull;
mContent->GetDocument(doc);
nsIURI* docURL = nsnull;
if (doc) {
docURL = doc->GetDocumentURL();
NS_RELEASE(doc);
}
if (docURL) {
inside = map->IsInside(p.x, p.y, docURL, absURL, target, altText,
&suppress);
NS_RELEASE(docURL);
}
if (inside) {
// We hit a clickable area. Time to go somewhere...
PRBool clicked = PR_FALSE;
if (aEvent->message == NS_MOUSE_LEFT_BUTTON_UP) {
*aEventStatus = nsEventStatus_eConsumeDoDefault;
clicked = PR_TRUE;
}
TriggerLink(aPresContext, absURL, target, clicked);
}
nsCOMPtr<nsIContent> area;
inside = map->IsInside(p.x, p.y, getter_AddRefs(area),
absURL, target, altText,
&suppress);
}
if (!inside && isServerMap) {

View File

@ -53,6 +53,9 @@ public:
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
NS_IMETHOD GetContentForEvent(nsIPresContext* aPresContext,
nsEvent* aEvent,
nsIContent** aContent);
NS_METHOD HandleEvent(nsIPresContext* aPresContext,
nsGUIEvent* aEvent,
nsEventStatus* aEventStatus);

View File

@ -46,9 +46,7 @@
class Area {
public:
Area(const nsString& aBaseURL, const nsString& aHREF,
const nsString& aTarget, const nsString& aAltText,
PRBool aSuppress, PRBool aHasURL);
Area(nsIContent* aArea, PRBool aSuppress, PRBool aHasURL);
virtual ~Area();
void ParseCoords(const nsString& aSpec);
@ -71,21 +69,18 @@ public:
virtual void FinishConvertToXIF(nsXIFConverter& aConverter) const;
const nsString& GetBase() const { return mBase; }
const nsString& GetHREF() const { return mHREF; }
const nsString& GetTarget() const { return mTarget; }
const nsString& GetAltText() const { return mAltText; }
void GetHREF(nsString& aHref) const;
void GetTarget(nsString& aTarget) const;
void GetAltText(nsString& aAltText) const;
PRBool GetSuppress() const { return mSuppressFeedback; }
PRBool GetHasURL() const { return mHasURL; }
void GetArea(nsIContent** aArea) const;
#ifdef DEBUG
virtual void SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const;
#endif
nsString mBase;
nsString mHREF;
nsString mTarget;
nsString mAltText;
nsCOMPtr<nsIContent> mArea;
nscoord* mCoords;
PRInt32 mNumCoords;
PRBool mSuppressFeedback;
@ -94,11 +89,9 @@ public:
MOZ_DECL_CTOR_COUNTER(Area);
Area::Area(const nsString& aBaseURL, const nsString& aHREF,
const nsString& aTarget, const nsString& aAltText,
Area::Area(nsIContent* aArea,
PRBool aSuppress, PRBool aHasURL)
: mBase(aBaseURL), mHREF(aHREF), mTarget(aTarget), mAltText(aAltText),
mSuppressFeedback(aSuppress), mHasURL(aHasURL)
: mArea(aArea), mSuppressFeedback(aSuppress), mHasURL(aHasURL)
{
MOZ_COUNT_CTOR(Area);
mCoords = nsnull;
@ -111,17 +104,46 @@ Area::~Area()
delete [] mCoords;
}
void
Area::GetHREF(nsString& aHref) const
{
aHref.Truncate();
if (mArea) {
mArea->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::href, aHref);
}
}
void
Area::GetTarget(nsString& aTarget) const
{
aTarget.Truncate();
if (mArea) {
mArea->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::target, aTarget);
}
}
void
Area::GetAltText(nsString& aAltText) const
{
aAltText.Truncate();
if (mArea) {
mArea->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::alt, aAltText);
}
}
void
Area::GetArea(nsIContent** aArea) const
{
*aArea = mArea;
NS_IF_ADDREF(*aArea);
}
#ifdef DEBUG
void
Area::SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const
{
if (aResult) {
PRUint32 sum = sizeof(*this);
PRUint32 s;
mBase.SizeOf(aHandler, &s); sum += s;
mHREF.SizeOf(aHandler, &s); sum += s;
mTarget.SizeOf(aHandler, &s); sum += s;
mAltText.SizeOf(aHandler, &s); sum += s;
sum += mNumCoords * sizeof(nscoord);
*aResult = sum;
}
@ -296,6 +318,14 @@ void Area::ParseCoords(const nsString& aSpec)
void Area::ToHTML(nsString& aResult)
{
nsAutoString href, target, altText;
if (mArea) {
mArea->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::href, href);
mArea->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::target, target);
mArea->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::alt, altText);
}
aResult.Truncate();
aResult.Append("<AREA SHAPE=");
nsAutoString shape;
@ -312,16 +342,16 @@ void Area::ToHTML(nsString& aResult)
}
}
aResult.Append("\" HREF=\"");
aResult.Append(mHREF);
aResult.Append(href);
aResult.Append("\"");
if (0 < mTarget.Length()) {
if (0 < target.Length()) {
aResult.Append(" TARGET=\"");
aResult.Append(mTarget);
aResult.Append(target);
aResult.Append("\"");
}
if (0 < mAltText.Length()) {
if (0 < altText.Length()) {
aResult.Append(" ALT=\"");
aResult.Append(mAltText);
aResult.Append(altText);
aResult.Append("\"");
}
if (mSuppressFeedback) {
@ -338,6 +368,14 @@ void Area::ToHTML(nsString& aResult)
void Area::BeginConvertToXIF(nsXIFConverter& aConverter) const
{
nsAutoString href, target, altText;
if (mArea) {
mArea->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::href, href);
mArea->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::target, target);
mArea->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::alt, altText);
}
nsAutoString tag("area");
aConverter.BeginStartTag(tag);
@ -362,16 +400,16 @@ void Area::BeginConvertToXIF(nsXIFConverter& aConverter) const
aConverter.AddAttribute(name,coords);
name.SetString("href");
aConverter.AddAttribute(name,mHREF);
aConverter.AddAttribute(name,href);
if (0 < mTarget.Length()) {
if (0 < target.Length()) {
name.SetString("target");
aConverter.AddAttribute(name,mTarget);
aConverter.AddAttribute(name,target);
}
if (0 < mAltText.Length()) {
if (0 < altText.Length()) {
name.SetString("alt");
aConverter.AddAttribute(name,mTarget);
aConverter.AddAttribute(name,altText);
}
if (mSuppressFeedback) {
name.SetString("suppress");
@ -397,9 +435,7 @@ void Area::ConvertContentToXIF(nsXIFConverter& aConverter) const
class DefaultArea : public Area {
public:
DefaultArea(const nsString& aBaseURL, const nsString& aHREF,
const nsString& aTarget, const nsString& aAltText,
PRBool aSuppress, PRBool aHasURL);
DefaultArea(nsIContent* aArea, PRBool aSuppress, PRBool aHasURL);
~DefaultArea();
virtual PRBool IsInside(nscoord x, nscoord y);
@ -408,10 +444,8 @@ public:
virtual void GetShapeName(nsString& aResult) const;
};
DefaultArea::DefaultArea(const nsString& aBaseURL, const nsString& aHREF,
const nsString& aTarget, const nsString& aAltText,
PRBool aSuppress, PRBool aHasURL)
: Area(aBaseURL, aHREF, aTarget, aAltText, aSuppress, aHasURL)
DefaultArea::DefaultArea(nsIContent* aArea, PRBool aSuppress, PRBool aHasURL)
: Area(aArea, aSuppress, aHasURL)
{
}
@ -437,9 +471,7 @@ void DefaultArea::GetShapeName(nsString& aResult) const
class RectArea : public Area {
public:
RectArea(const nsString& aBaseURL, const nsString& aHREF,
const nsString& aTarget, const nsString& aAltText,
PRBool aSuppress, PRBool aHasURL);
RectArea(nsIContent* aArea, PRBool aSuppress, PRBool aHasURL);
~RectArea();
virtual PRBool IsInside(nscoord x, nscoord y);
@ -448,10 +480,8 @@ public:
virtual void GetShapeName(nsString& aResult) const;
};
RectArea::RectArea(const nsString& aBaseURL, const nsString& aHREF,
const nsString& aTarget, const nsString& aAltText,
PRBool aSuppress, PRBool aHasURL)
: Area(aBaseURL, aHREF, aTarget, aAltText, aSuppress, aHasURL)
RectArea::RectArea(nsIContent* aArea, PRBool aSuppress, PRBool aHasURL)
: Area(aArea, aSuppress, aHasURL)
{
}
@ -502,9 +532,7 @@ void RectArea::GetShapeName(nsString& aResult) const
class PolyArea : public Area {
public:
PolyArea(const nsString& aBaseURL, const nsString& aHREF,
const nsString& aTarget, const nsString& aAltText,
PRBool aSuppress, PRBool aHasURL);
PolyArea(nsIContent* aArea, PRBool aSuppress, PRBool aHasURL);
~PolyArea();
virtual PRBool IsInside(nscoord x, nscoord y);
@ -513,10 +541,8 @@ public:
virtual void GetShapeName(nsString& aResult) const;
};
PolyArea::PolyArea(const nsString& aBaseURL, const nsString& aHREF,
const nsString& aTarget, const nsString& aAltText,
PRBool aSuppress, PRBool aHasURL)
: Area(aBaseURL, aHREF, aTarget, aAltText, aSuppress, aHasURL)
PolyArea::PolyArea(nsIContent* aArea, PRBool aSuppress, PRBool aHasURL)
: Area(aArea, aSuppress, aHasURL)
{
}
@ -616,9 +642,7 @@ void PolyArea::GetShapeName(nsString& aResult) const
class CircleArea : public Area {
public:
CircleArea(const nsString& aBaseURL, const nsString& aHREF,
const nsString& aTarget, const nsString& aAltText,
PRBool aSuppress, PRBool aHasURL);
CircleArea(nsIContent* aArea, PRBool aSuppress, PRBool aHasURL);
~CircleArea();
virtual PRBool IsInside(nscoord x, nscoord y);
@ -627,10 +651,8 @@ public:
virtual void GetShapeName(nsString& aResult) const;
};
CircleArea::CircleArea(const nsString& aBaseURL, const nsString& aHREF,
const nsString& aTarget, const nsString& aAltText,
PRBool aSuppress, PRBool aHasURL)
: Area(aBaseURL, aHREF, aTarget, aAltText, aSuppress, aHasURL)
CircleArea::CircleArea(nsIContent* aArea, PRBool aSuppress, PRBool aHasURL)
: Area(aArea, aSuppress, aHasURL)
{
}
@ -830,31 +852,28 @@ nsImageMap::UpdateAreas()
nsresult
nsImageMap::AddArea(nsIContent* aArea)
{
nsAutoString shape, coords, baseURL, href, target, altText, noHref;
aArea->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::shape, shape);
aArea->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::coords, coords);
aArea->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::href, href);
aArea->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::target, target);
aArea->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::alt, altText);
PRBool hasURL = (PRBool)(NS_CONTENT_ATTR_HAS_VALUE != aArea->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::nohref, noHref));
nsAutoString shape, coords, baseURL, noHref;
aArea->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::shape, shape);
aArea->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::coords, coords);
PRBool hasURL = (PRBool)(NS_CONTENT_ATTR_HAS_VALUE != aArea->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::nohref, noHref));
PRBool suppress = PR_FALSE;/* XXX */
Area* area;
if ((0 == shape.Length()) ||
shape.EqualsIgnoreCase("rect") ||
shape.EqualsIgnoreCase("rectangle")) {
area = new RectArea(baseURL, href, target, altText, suppress, hasURL);
area = new RectArea(aArea, suppress, hasURL);
}
else if (shape.EqualsIgnoreCase("poly") ||
shape.EqualsIgnoreCase("polygon")) {
area = new PolyArea(baseURL, href, target, altText, suppress, hasURL);
area = new PolyArea(aArea, suppress, hasURL);
}
else if (shape.EqualsIgnoreCase("circle") ||
shape.EqualsIgnoreCase("circ")) {
area = new CircleArea(baseURL, href, target, altText, suppress, hasURL);
area = new CircleArea(aArea, suppress, hasURL);
}
else {
area = new DefaultArea(baseURL, href, target, altText, suppress, hasURL);
area = new DefaultArea(aArea, suppress, hasURL);
}
area->ParseCoords(coords);
mAreas.AppendElement(area);
@ -863,7 +882,7 @@ nsImageMap::AddArea(nsIContent* aArea)
PRBool
nsImageMap::IsInside(nscoord aX, nscoord aY,
nsIURI* aDocURL,
nsIContent** aContent,
nsString& aAbsURL,
nsString& aTarget,
nsString& aAltText,
@ -872,32 +891,37 @@ nsImageMap::IsInside(nscoord aX, nscoord aY,
PRInt32 i, n = mAreas.Count();
for (i = 0; i < n; i++) {
Area* area = (Area*) mAreas.ElementAt(i);
if (area->IsInside(aX, aY) && area->mHasURL) {
nsresult rv;
// Set the image loader's source URL and base URL
nsIURI* baseUri = nsnull;
nsIHTMLContent* htmlContent;
if (mMap) {
rv = mMap->QueryInterface(kIHTMLContentIID, (void**)&htmlContent);
if (NS_SUCCEEDED(rv)) {
htmlContent->GetBaseURL(baseUri);
NS_RELEASE(htmlContent);
}
else {
nsIDocument* doc;
rv = mMap->GetDocument(doc);
if (area->IsInside(aX, aY)) {
if (area->GetHasURL()) {
nsresult rv;
// Set the image loader's source URL and base URL
nsIURI* baseUri = nsnull;
nsIHTMLContent* htmlContent;
if (mMap) {
rv = mMap->QueryInterface(kIHTMLContentIID, (void**)&htmlContent);
if (NS_SUCCEEDED(rv)) {
doc->GetBaseURL(baseUri); // Could just use mDocument here...
NS_RELEASE(doc);
htmlContent->GetBaseURL(baseUri);
NS_RELEASE(htmlContent);
}
else {
nsIDocument* doc;
rv = mMap->GetDocument(doc);
if (NS_SUCCEEDED(rv)) {
doc->GetBaseURL(baseUri); // Could just use mDocument here...
NS_RELEASE(doc);
}
}
}
if (NS_FAILED(rv)) return PR_FALSE;
nsAutoString href;
area->GetHREF(href);
NS_MakeAbsoluteURI(href, baseUri, aAbsURL);
NS_RELEASE(baseUri);
}
if (NS_FAILED(rv)) return PR_FALSE;
NS_MakeAbsoluteURI(area->mHREF, baseUri, aAbsURL);
NS_RELEASE(baseUri);
aTarget = area->mTarget;
area->GetTarget(aTarget);
if (mMap && (aTarget.Length() == 0)) {
nsIHTMLContent* content = nsnull;
nsresult result = mMap->QueryInterface(kIHTMLContentIID, (void**)&content);
@ -906,8 +930,9 @@ nsImageMap::IsInside(nscoord aX, nscoord aY,
NS_RELEASE(content);
}
}
aAltText = area->mAltText;
area->GetAltText(aAltText);
*aSuppress = area->mSuppressFeedback;
area->GetArea(aContent);
return PR_TRUE;
}
}
@ -921,7 +946,9 @@ nsImageMap::IsInside(nscoord aX, nscoord aY)
for (i = 0; i < n; i++) {
Area* area = (Area*) mAreas.ElementAt(i);
if (area->IsInside(aX, aY)) {
if ((area->mHREF).Length() > 0) {
nsAutoString href;
area->GetHREF(href);
if (href.Length() > 0) {
return PR_TRUE;
}
}

View File

@ -51,7 +51,7 @@ public:
* then NS_NOT_INSIDE is returned.
*/
PRBool IsInside(nscoord aX, nscoord aY,
nsIURI* aDocURL,
nsIContent** aContent,
nsString& aAbsURL,
nsString& aTarget,
nsString& aAltText,

View File

@ -746,6 +746,17 @@ nsFrame::Paint(nsIPresContext* aPresContext,
return NS_OK;
}
/**
*
*/
NS_IMETHODIMP
nsFrame::GetContentForEvent(nsIPresContext* aPresContext,
nsEvent* aEvent,
nsIContent** aContent)
{
return GetContent(aContent);
}
/**
*
*/

View File

@ -195,6 +195,9 @@ public:
NS_IMETHOD HandleEvent(nsIPresContext* aPresContext,
nsGUIEvent* aEvent,
nsEventStatus* aEventStatus);
NS_IMETHOD GetContentForEvent(nsIPresContext* aPresContext,
nsEvent* aEvent,
nsIContent** aContent);
NS_IMETHOD GetCursor(nsIPresContext* aPresContext,
nsPoint& aPoint,
PRInt32& aCursor);

View File

@ -686,6 +686,35 @@ nsImageFrame::GetAnchorHREF(nsString& aResult)
return status;
}
NS_IMETHODIMP
nsImageFrame::GetContentForEvent(nsIPresContext* aPresContext,
nsEvent* aEvent,
nsIContent** aContent)
{
NS_ENSURE_ARG_POINTER(aContent);
nsImageMap* map;
map = GetImageMap();
if (nsnull != map) {
nsPoint p;
TranslateEventCoords(aPresContext, aEvent->point, p);
nsAutoString absURL, target, altText;
PRBool suppress;
PRBool inside = PR_FALSE;
nsCOMPtr<nsIContent> area;
inside = map->IsInside(p.x, p.y, getter_AddRefs(area),
absURL, target, altText,
&suppress);
if (inside && area) {
*aContent = area;
NS_ADDREF(*aContent);
return NS_OK;
}
}
return GetContent(aContent);
}
// XXX what should clicks on transparent pixels do?
NS_METHOD
nsImageFrame::HandleEvent(nsIPresContext* aPresContext,
@ -707,30 +736,15 @@ nsImageFrame::HandleEvent(nsIPresContext* aPresContext,
nsAutoString absURL, target, altText;
PRBool suppress;
PRBool inside = PR_FALSE;
// Even though client-side image map triggering happens
// through content, we need to make sure we're not inside
// (in case we deal with a case of both client-side and
// sever-side on the same image - it happens!)
if (nsnull != map) {
nsIDocument* doc = nsnull;
mContent->GetDocument(doc);
nsIURI* docURL = nsnull;
if (doc) {
docURL = doc->GetDocumentURL();
NS_RELEASE(doc);
}
if (docURL) {
inside = map->IsInside(p.x, p.y, docURL, absURL, target, altText,
&suppress);
NS_RELEASE(docURL);
}
if (inside) {
// We hit a clickable area. Time to go somewhere...
PRBool clicked = PR_FALSE;
if (aEvent->message == NS_MOUSE_LEFT_BUTTON_UP) {
*aEventStatus = nsEventStatus_eConsumeDoDefault;
clicked = PR_TRUE;
}
TriggerLink(aPresContext, absURL, target, clicked);
}
nsCOMPtr<nsIContent> area;
inside = map->IsInside(p.x, p.y, getter_AddRefs(area),
absURL, target, altText,
&suppress);
}
if (!inside && isServerMap) {

View File

@ -53,6 +53,9 @@ public:
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
NS_IMETHOD GetContentForEvent(nsIPresContext* aPresContext,
nsEvent* aEvent,
nsIContent** aContent);
NS_METHOD HandleEvent(nsIPresContext* aPresContext,
nsGUIEvent* aEvent,
nsEventStatus* aEventStatus);

View File

@ -46,9 +46,7 @@
class Area {
public:
Area(const nsString& aBaseURL, const nsString& aHREF,
const nsString& aTarget, const nsString& aAltText,
PRBool aSuppress, PRBool aHasURL);
Area(nsIContent* aArea, PRBool aSuppress, PRBool aHasURL);
virtual ~Area();
void ParseCoords(const nsString& aSpec);
@ -71,21 +69,18 @@ public:
virtual void FinishConvertToXIF(nsXIFConverter& aConverter) const;
const nsString& GetBase() const { return mBase; }
const nsString& GetHREF() const { return mHREF; }
const nsString& GetTarget() const { return mTarget; }
const nsString& GetAltText() const { return mAltText; }
void GetHREF(nsString& aHref) const;
void GetTarget(nsString& aTarget) const;
void GetAltText(nsString& aAltText) const;
PRBool GetSuppress() const { return mSuppressFeedback; }
PRBool GetHasURL() const { return mHasURL; }
void GetArea(nsIContent** aArea) const;
#ifdef DEBUG
virtual void SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const;
#endif
nsString mBase;
nsString mHREF;
nsString mTarget;
nsString mAltText;
nsCOMPtr<nsIContent> mArea;
nscoord* mCoords;
PRInt32 mNumCoords;
PRBool mSuppressFeedback;
@ -94,11 +89,9 @@ public:
MOZ_DECL_CTOR_COUNTER(Area);
Area::Area(const nsString& aBaseURL, const nsString& aHREF,
const nsString& aTarget, const nsString& aAltText,
Area::Area(nsIContent* aArea,
PRBool aSuppress, PRBool aHasURL)
: mBase(aBaseURL), mHREF(aHREF), mTarget(aTarget), mAltText(aAltText),
mSuppressFeedback(aSuppress), mHasURL(aHasURL)
: mArea(aArea), mSuppressFeedback(aSuppress), mHasURL(aHasURL)
{
MOZ_COUNT_CTOR(Area);
mCoords = nsnull;
@ -111,17 +104,46 @@ Area::~Area()
delete [] mCoords;
}
void
Area::GetHREF(nsString& aHref) const
{
aHref.Truncate();
if (mArea) {
mArea->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::href, aHref);
}
}
void
Area::GetTarget(nsString& aTarget) const
{
aTarget.Truncate();
if (mArea) {
mArea->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::target, aTarget);
}
}
void
Area::GetAltText(nsString& aAltText) const
{
aAltText.Truncate();
if (mArea) {
mArea->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::alt, aAltText);
}
}
void
Area::GetArea(nsIContent** aArea) const
{
*aArea = mArea;
NS_IF_ADDREF(*aArea);
}
#ifdef DEBUG
void
Area::SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const
{
if (aResult) {
PRUint32 sum = sizeof(*this);
PRUint32 s;
mBase.SizeOf(aHandler, &s); sum += s;
mHREF.SizeOf(aHandler, &s); sum += s;
mTarget.SizeOf(aHandler, &s); sum += s;
mAltText.SizeOf(aHandler, &s); sum += s;
sum += mNumCoords * sizeof(nscoord);
*aResult = sum;
}
@ -296,6 +318,14 @@ void Area::ParseCoords(const nsString& aSpec)
void Area::ToHTML(nsString& aResult)
{
nsAutoString href, target, altText;
if (mArea) {
mArea->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::href, href);
mArea->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::target, target);
mArea->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::alt, altText);
}
aResult.Truncate();
aResult.Append("<AREA SHAPE=");
nsAutoString shape;
@ -312,16 +342,16 @@ void Area::ToHTML(nsString& aResult)
}
}
aResult.Append("\" HREF=\"");
aResult.Append(mHREF);
aResult.Append(href);
aResult.Append("\"");
if (0 < mTarget.Length()) {
if (0 < target.Length()) {
aResult.Append(" TARGET=\"");
aResult.Append(mTarget);
aResult.Append(target);
aResult.Append("\"");
}
if (0 < mAltText.Length()) {
if (0 < altText.Length()) {
aResult.Append(" ALT=\"");
aResult.Append(mAltText);
aResult.Append(altText);
aResult.Append("\"");
}
if (mSuppressFeedback) {
@ -338,6 +368,14 @@ void Area::ToHTML(nsString& aResult)
void Area::BeginConvertToXIF(nsXIFConverter& aConverter) const
{
nsAutoString href, target, altText;
if (mArea) {
mArea->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::href, href);
mArea->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::target, target);
mArea->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::alt, altText);
}
nsAutoString tag("area");
aConverter.BeginStartTag(tag);
@ -362,16 +400,16 @@ void Area::BeginConvertToXIF(nsXIFConverter& aConverter) const
aConverter.AddAttribute(name,coords);
name.SetString("href");
aConverter.AddAttribute(name,mHREF);
aConverter.AddAttribute(name,href);
if (0 < mTarget.Length()) {
if (0 < target.Length()) {
name.SetString("target");
aConverter.AddAttribute(name,mTarget);
aConverter.AddAttribute(name,target);
}
if (0 < mAltText.Length()) {
if (0 < altText.Length()) {
name.SetString("alt");
aConverter.AddAttribute(name,mTarget);
aConverter.AddAttribute(name,altText);
}
if (mSuppressFeedback) {
name.SetString("suppress");
@ -397,9 +435,7 @@ void Area::ConvertContentToXIF(nsXIFConverter& aConverter) const
class DefaultArea : public Area {
public:
DefaultArea(const nsString& aBaseURL, const nsString& aHREF,
const nsString& aTarget, const nsString& aAltText,
PRBool aSuppress, PRBool aHasURL);
DefaultArea(nsIContent* aArea, PRBool aSuppress, PRBool aHasURL);
~DefaultArea();
virtual PRBool IsInside(nscoord x, nscoord y);
@ -408,10 +444,8 @@ public:
virtual void GetShapeName(nsString& aResult) const;
};
DefaultArea::DefaultArea(const nsString& aBaseURL, const nsString& aHREF,
const nsString& aTarget, const nsString& aAltText,
PRBool aSuppress, PRBool aHasURL)
: Area(aBaseURL, aHREF, aTarget, aAltText, aSuppress, aHasURL)
DefaultArea::DefaultArea(nsIContent* aArea, PRBool aSuppress, PRBool aHasURL)
: Area(aArea, aSuppress, aHasURL)
{
}
@ -437,9 +471,7 @@ void DefaultArea::GetShapeName(nsString& aResult) const
class RectArea : public Area {
public:
RectArea(const nsString& aBaseURL, const nsString& aHREF,
const nsString& aTarget, const nsString& aAltText,
PRBool aSuppress, PRBool aHasURL);
RectArea(nsIContent* aArea, PRBool aSuppress, PRBool aHasURL);
~RectArea();
virtual PRBool IsInside(nscoord x, nscoord y);
@ -448,10 +480,8 @@ public:
virtual void GetShapeName(nsString& aResult) const;
};
RectArea::RectArea(const nsString& aBaseURL, const nsString& aHREF,
const nsString& aTarget, const nsString& aAltText,
PRBool aSuppress, PRBool aHasURL)
: Area(aBaseURL, aHREF, aTarget, aAltText, aSuppress, aHasURL)
RectArea::RectArea(nsIContent* aArea, PRBool aSuppress, PRBool aHasURL)
: Area(aArea, aSuppress, aHasURL)
{
}
@ -502,9 +532,7 @@ void RectArea::GetShapeName(nsString& aResult) const
class PolyArea : public Area {
public:
PolyArea(const nsString& aBaseURL, const nsString& aHREF,
const nsString& aTarget, const nsString& aAltText,
PRBool aSuppress, PRBool aHasURL);
PolyArea(nsIContent* aArea, PRBool aSuppress, PRBool aHasURL);
~PolyArea();
virtual PRBool IsInside(nscoord x, nscoord y);
@ -513,10 +541,8 @@ public:
virtual void GetShapeName(nsString& aResult) const;
};
PolyArea::PolyArea(const nsString& aBaseURL, const nsString& aHREF,
const nsString& aTarget, const nsString& aAltText,
PRBool aSuppress, PRBool aHasURL)
: Area(aBaseURL, aHREF, aTarget, aAltText, aSuppress, aHasURL)
PolyArea::PolyArea(nsIContent* aArea, PRBool aSuppress, PRBool aHasURL)
: Area(aArea, aSuppress, aHasURL)
{
}
@ -616,9 +642,7 @@ void PolyArea::GetShapeName(nsString& aResult) const
class CircleArea : public Area {
public:
CircleArea(const nsString& aBaseURL, const nsString& aHREF,
const nsString& aTarget, const nsString& aAltText,
PRBool aSuppress, PRBool aHasURL);
CircleArea(nsIContent* aArea, PRBool aSuppress, PRBool aHasURL);
~CircleArea();
virtual PRBool IsInside(nscoord x, nscoord y);
@ -627,10 +651,8 @@ public:
virtual void GetShapeName(nsString& aResult) const;
};
CircleArea::CircleArea(const nsString& aBaseURL, const nsString& aHREF,
const nsString& aTarget, const nsString& aAltText,
PRBool aSuppress, PRBool aHasURL)
: Area(aBaseURL, aHREF, aTarget, aAltText, aSuppress, aHasURL)
CircleArea::CircleArea(nsIContent* aArea, PRBool aSuppress, PRBool aHasURL)
: Area(aArea, aSuppress, aHasURL)
{
}
@ -830,31 +852,28 @@ nsImageMap::UpdateAreas()
nsresult
nsImageMap::AddArea(nsIContent* aArea)
{
nsAutoString shape, coords, baseURL, href, target, altText, noHref;
aArea->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::shape, shape);
aArea->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::coords, coords);
aArea->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::href, href);
aArea->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::target, target);
aArea->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::alt, altText);
PRBool hasURL = (PRBool)(NS_CONTENT_ATTR_HAS_VALUE != aArea->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::nohref, noHref));
nsAutoString shape, coords, baseURL, noHref;
aArea->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::shape, shape);
aArea->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::coords, coords);
PRBool hasURL = (PRBool)(NS_CONTENT_ATTR_HAS_VALUE != aArea->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::nohref, noHref));
PRBool suppress = PR_FALSE;/* XXX */
Area* area;
if ((0 == shape.Length()) ||
shape.EqualsIgnoreCase("rect") ||
shape.EqualsIgnoreCase("rectangle")) {
area = new RectArea(baseURL, href, target, altText, suppress, hasURL);
area = new RectArea(aArea, suppress, hasURL);
}
else if (shape.EqualsIgnoreCase("poly") ||
shape.EqualsIgnoreCase("polygon")) {
area = new PolyArea(baseURL, href, target, altText, suppress, hasURL);
area = new PolyArea(aArea, suppress, hasURL);
}
else if (shape.EqualsIgnoreCase("circle") ||
shape.EqualsIgnoreCase("circ")) {
area = new CircleArea(baseURL, href, target, altText, suppress, hasURL);
area = new CircleArea(aArea, suppress, hasURL);
}
else {
area = new DefaultArea(baseURL, href, target, altText, suppress, hasURL);
area = new DefaultArea(aArea, suppress, hasURL);
}
area->ParseCoords(coords);
mAreas.AppendElement(area);
@ -863,7 +882,7 @@ nsImageMap::AddArea(nsIContent* aArea)
PRBool
nsImageMap::IsInside(nscoord aX, nscoord aY,
nsIURI* aDocURL,
nsIContent** aContent,
nsString& aAbsURL,
nsString& aTarget,
nsString& aAltText,
@ -872,32 +891,37 @@ nsImageMap::IsInside(nscoord aX, nscoord aY,
PRInt32 i, n = mAreas.Count();
for (i = 0; i < n; i++) {
Area* area = (Area*) mAreas.ElementAt(i);
if (area->IsInside(aX, aY) && area->mHasURL) {
nsresult rv;
// Set the image loader's source URL and base URL
nsIURI* baseUri = nsnull;
nsIHTMLContent* htmlContent;
if (mMap) {
rv = mMap->QueryInterface(kIHTMLContentIID, (void**)&htmlContent);
if (NS_SUCCEEDED(rv)) {
htmlContent->GetBaseURL(baseUri);
NS_RELEASE(htmlContent);
}
else {
nsIDocument* doc;
rv = mMap->GetDocument(doc);
if (area->IsInside(aX, aY)) {
if (area->GetHasURL()) {
nsresult rv;
// Set the image loader's source URL and base URL
nsIURI* baseUri = nsnull;
nsIHTMLContent* htmlContent;
if (mMap) {
rv = mMap->QueryInterface(kIHTMLContentIID, (void**)&htmlContent);
if (NS_SUCCEEDED(rv)) {
doc->GetBaseURL(baseUri); // Could just use mDocument here...
NS_RELEASE(doc);
htmlContent->GetBaseURL(baseUri);
NS_RELEASE(htmlContent);
}
else {
nsIDocument* doc;
rv = mMap->GetDocument(doc);
if (NS_SUCCEEDED(rv)) {
doc->GetBaseURL(baseUri); // Could just use mDocument here...
NS_RELEASE(doc);
}
}
}
if (NS_FAILED(rv)) return PR_FALSE;
nsAutoString href;
area->GetHREF(href);
NS_MakeAbsoluteURI(href, baseUri, aAbsURL);
NS_RELEASE(baseUri);
}
if (NS_FAILED(rv)) return PR_FALSE;
NS_MakeAbsoluteURI(area->mHREF, baseUri, aAbsURL);
NS_RELEASE(baseUri);
aTarget = area->mTarget;
area->GetTarget(aTarget);
if (mMap && (aTarget.Length() == 0)) {
nsIHTMLContent* content = nsnull;
nsresult result = mMap->QueryInterface(kIHTMLContentIID, (void**)&content);
@ -906,8 +930,9 @@ nsImageMap::IsInside(nscoord aX, nscoord aY,
NS_RELEASE(content);
}
}
aAltText = area->mAltText;
area->GetAltText(aAltText);
*aSuppress = area->mSuppressFeedback;
area->GetArea(aContent);
return PR_TRUE;
}
}
@ -921,7 +946,9 @@ nsImageMap::IsInside(nscoord aX, nscoord aY)
for (i = 0; i < n; i++) {
Area* area = (Area*) mAreas.ElementAt(i);
if (area->IsInside(aX, aY)) {
if ((area->mHREF).Length() > 0) {
nsAutoString href;
area->GetHREF(href);
if (href.Length() > 0) {
return PR_TRUE;
}
}

View File

@ -51,7 +51,7 @@ public:
* then NS_NOT_INSIDE is returned.
*/
PRBool IsInside(nscoord aX, nscoord aY,
nsIURI* aDocURL,
nsIContent** aContent,
nsString& aAbsURL,
nsString& aTarget,
nsString& aAltText,

View File

@ -2869,7 +2869,7 @@ PresShell::HandleEvent(nsIView *aView,
}
else {
nsIContent* targetContent;
if (NS_OK == mCurrentEventFrame->GetContent(&targetContent) && nsnull != targetContent) {
if (NS_OK == mCurrentEventFrame->GetContentForEvent(mPresContext, aEvent, &targetContent) && nsnull != targetContent) {
rv = targetContent->HandleDOMEvent(mPresContext, (nsEvent*)aEvent, nsnull,
NS_EVENT_FLAG_INIT, aEventStatus);
NS_RELEASE(targetContent);

View File

@ -584,6 +584,121 @@ nsGenericHTMLElement::SetDocumentForFormControls(nsIDocument* aDocument,
return result;
}
nsresult
nsGenericHTMLElement::HandleDOMEventForAnchors(nsIPresContext* aPresContext,
nsEvent* aEvent,
nsIDOMEvent** aDOMEvent,
PRUint32 aFlags,
nsEventStatus* aEventStatus)
{
NS_ENSURE_ARG(aPresContext);
NS_ENSURE_ARG_POINTER(aEventStatus);
// Try script event handlers first
nsresult ret = HandleDOMEvent(aPresContext, aEvent, aDOMEvent,
aFlags, aEventStatus);
if ((NS_OK == ret) && (nsEventStatus_eIgnore == *aEventStatus) &&
!(aFlags & NS_EVENT_FLAG_CAPTURE)) {
// If this anchor element has an HREF then it is sensitive to
// mouse events (otherwise ignore them).
nsAutoString href;
nsresult result = GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::href, href);
if (NS_CONTENT_ATTR_HAS_VALUE == result) {
switch (aEvent->message) {
case NS_MOUSE_LEFT_BUTTON_DOWN:
{
// don't make the link grab the focus if there is no link handler
nsILinkHandler* handler;
nsresult rv = aPresContext->GetLinkHandler(&handler);
if (NS_SUCCEEDED(rv) && (nsnull != handler)) {
nsIEventStateManager *stateManager;
if (NS_OK == aPresContext->GetEventStateManager(&stateManager)) {
stateManager->SetContentState(mContent, NS_EVENT_STATE_ACTIVE | NS_EVENT_STATE_FOCUS);
NS_RELEASE(stateManager);
}
NS_RELEASE(handler);
*aEventStatus = nsEventStatus_eConsumeNoDefault;
}
}
break;
case NS_MOUSE_LEFT_CLICK:
case NS_KEY_PRESS:
{
if (nsEventStatus_eConsumeNoDefault != *aEventStatus) {
nsKeyEvent * keyEvent;
if (aEvent->eventStructType == NS_KEY_EVENT) {
//Handle key commands from keys with char representation here, not on KeyDown
keyEvent = (nsKeyEvent *)aEvent;
}
//Click or return key
if (aEvent->message == NS_MOUSE_LEFT_CLICK || keyEvent->keyCode == NS_VK_RETURN) {
nsAutoString target;
nsIURI* baseURL = nsnull;
GetBaseURL(baseURL);
GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::target, target);
if (target.Length() == 0) {
GetBaseTarget(target);
}
ret = TriggerLink(aPresContext, eLinkVerb_Replace,
baseURL, href, target, PR_TRUE);
NS_IF_RELEASE(baseURL);
*aEventStatus = nsEventStatus_eConsumeDoDefault;
}
}
}
break;
case NS_MOUSE_RIGHT_BUTTON_DOWN:
// XXX Bring up a contextual menu provided by the application
break;
case NS_MOUSE_ENTER:
{
nsIEventStateManager *stateManager;
if (NS_OK == aPresContext->GetEventStateManager(&stateManager)) {
stateManager->SetContentState(mContent, NS_EVENT_STATE_HOVER);
NS_RELEASE(stateManager);
}
nsAutoString target;
nsIURI* baseURL = nsnull;
GetBaseURL(baseURL);
GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::target, target);
if (target.Length() == 0) {
GetBaseTarget(target);
}
ret = TriggerLink(aPresContext, eLinkVerb_Replace,
baseURL, href, target, PR_FALSE);
NS_IF_RELEASE(baseURL);
*aEventStatus = nsEventStatus_eConsumeNoDefault;
}
break;
case NS_MOUSE_EXIT:
{
nsIEventStateManager *stateManager;
if (NS_OK == aPresContext->GetEventStateManager(&stateManager)) {
stateManager->SetContentState(nsnull, NS_EVENT_STATE_HOVER);
NS_RELEASE(stateManager);
}
nsAutoString empty;
ret = TriggerLink(aPresContext, eLinkVerb_Replace, nsnull, empty, empty, PR_FALSE);
*aEventStatus = nsEventStatus_eConsumeNoDefault;
}
break;
default:
break;
}
}
}
return ret;
}
nsresult
nsGenericHTMLElement::GetNameSpaceID(PRInt32& aID) const
{

View File

@ -117,6 +117,11 @@ public:
PRBool aDeep,
nsIFormControl* aControl,
nsIForm* aForm);
nsresult HandleDOMEventForAnchors(nsIPresContext* aPresContext,
nsEvent* aEvent,
nsIDOMEvent** aDOMEvent,
PRUint32 aFlags,
nsEventStatus* aEventStatus);
// Implementation for nsIHTMLContent
nsresult Compact();

View File

@ -334,112 +334,11 @@ nsHTMLAnchorElement::HandleDOMEvent(nsIPresContext* aPresContext,
PRUint32 aFlags,
nsEventStatus* aEventStatus)
{
NS_ENSURE_ARG(aPresContext);
NS_ENSURE_ARG_POINTER(aEventStatus);
// Try script event handlers first
nsresult ret = mInner.HandleDOMEvent(aPresContext, aEvent, aDOMEvent,
aFlags, aEventStatus);
if ((NS_OK == ret) && (nsEventStatus_eIgnore == *aEventStatus) &&
!(aFlags & NS_EVENT_FLAG_CAPTURE)) {
// If this anchor element has an HREF then it is sensitive to
// mouse events (otherwise ignore them).
nsAutoString href;
nsresult result = GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::href, href);
if (NS_CONTENT_ATTR_HAS_VALUE == result) {
switch (aEvent->message) {
case NS_MOUSE_LEFT_BUTTON_DOWN:
{
// don't make the link grab the focus if there is no link handler
nsILinkHandler* handler;
nsresult rv = aPresContext->GetLinkHandler(&handler);
if (NS_SUCCEEDED(rv) && (nsnull != handler)) {
nsIEventStateManager *stateManager;
if (NS_OK == aPresContext->GetEventStateManager(&stateManager)) {
stateManager->SetContentState(this, NS_EVENT_STATE_ACTIVE | NS_EVENT_STATE_FOCUS);
NS_RELEASE(stateManager);
}
NS_RELEASE(handler);
*aEventStatus = nsEventStatus_eConsumeNoDefault;
}
}
break;
case NS_MOUSE_LEFT_CLICK:
case NS_KEY_PRESS:
{
if (nsEventStatus_eConsumeNoDefault != *aEventStatus) {
nsKeyEvent * keyEvent;
if (aEvent->eventStructType == NS_KEY_EVENT) {
//Handle key commands from keys with char representation here, not on KeyDown
keyEvent = (nsKeyEvent *)aEvent;
}
//Click or return key
if (aEvent->message == NS_MOUSE_LEFT_CLICK || keyEvent->keyCode == NS_VK_RETURN) {
nsAutoString target;
nsIURI* baseURL = nsnull;
GetBaseURL(baseURL);
GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::target, target);
if (target.Length() == 0) {
GetBaseTarget(target);
}
ret = mInner.TriggerLink(aPresContext, eLinkVerb_Replace,
baseURL, href, target, PR_TRUE);
NS_IF_RELEASE(baseURL);
*aEventStatus = nsEventStatus_eConsumeDoDefault;
}
}
}
break;
case NS_MOUSE_RIGHT_BUTTON_DOWN:
// XXX Bring up a contextual menu provided by the application
break;
case NS_MOUSE_ENTER:
{
nsIEventStateManager *stateManager;
if (NS_OK == aPresContext->GetEventStateManager(&stateManager)) {
stateManager->SetContentState(this, NS_EVENT_STATE_HOVER);
NS_RELEASE(stateManager);
}
nsAutoString target;
nsIURI* baseURL = nsnull;
GetBaseURL(baseURL);
GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::target, target);
if (target.Length() == 0) {
GetBaseTarget(target);
}
ret = mInner.TriggerLink(aPresContext, eLinkVerb_Replace,
baseURL, href, target, PR_FALSE);
NS_IF_RELEASE(baseURL);
*aEventStatus = nsEventStatus_eConsumeNoDefault;
}
break;
case NS_MOUSE_EXIT:
{
nsIEventStateManager *stateManager;
if (NS_OK == aPresContext->GetEventStateManager(&stateManager)) {
stateManager->SetContentState(nsnull, NS_EVENT_STATE_HOVER);
NS_RELEASE(stateManager);
}
nsAutoString empty;
ret = mInner.TriggerLink(aPresContext, eLinkVerb_Replace, nsnull, empty, empty, PR_FALSE);
*aEventStatus = nsEventStatus_eConsumeNoDefault;
}
break;
default:
break;
}
}
}
return ret;
return mInner.HandleDOMEventForAnchors(aPresContext,
aEvent,
aDOMEvent,
aFlags,
aEventStatus);
}
NS_IMETHODIMP

View File

@ -226,8 +226,11 @@ nsHTMLAreaElement::HandleDOMEvent(nsIPresContext* aPresContext,
PRUint32 aFlags,
nsEventStatus* aEventStatus)
{
return mInner.HandleDOMEvent(aPresContext, aEvent, aDOMEvent,
aFlags, aEventStatus);
return mInner.HandleDOMEventForAnchors(aPresContext,
aEvent,
aDOMEvent,
aFlags,
aEventStatus);
}
NS_IMETHODIMP