diff --git a/mozilla/content/events/public/nsIEventStateManager.h b/mozilla/content/events/public/nsIEventStateManager.h index ec2b6dfa637..cb0887226a9 100644 --- a/mozilla/content/events/public/nsIEventStateManager.h +++ b/mozilla/content/events/public/nsIEventStateManager.h @@ -61,6 +61,8 @@ public: NS_IMETHOD GetContentState(nsIContent *aContent, PRInt32& aState) = 0; NS_IMETHOD SetContentState(nsIContent *aContent, PRInt32 aState) = 0; + + NS_IMETHOD GetFocusedContent(nsIContent **aContent) = 0; }; #define NS_EVENT_STATE_UNSPECIFIED 0x0000 diff --git a/mozilla/content/events/src/nsEventStateManager.cpp b/mozilla/content/events/src/nsEventStateManager.cpp index 807f23387cc..29eabd2ad3b 100644 --- a/mozilla/content/events/src/nsEventStateManager.cpp +++ b/mozilla/content/events/src/nsEventStateManager.cpp @@ -1171,6 +1171,14 @@ nsEventStateManager::SendFocusBlur(nsIContent *aContent) return NS_OK; } +NS_IMETHODIMP +nsEventStateManager::GetFocusedContent(nsIContent** aContent) +{ + *aContent = mCurrentFocus; + NS_IF_ADDREF(*aContent); + return NS_OK; +} + nsresult NS_NewEventStateManager(nsIEventStateManager** aInstancePtrResult) { NS_PRECONDITION(nsnull != aInstancePtrResult, "nsnull ptr"); diff --git a/mozilla/content/events/src/nsEventStateManager.h b/mozilla/content/events/src/nsEventStateManager.h index f00cc6d880a..b661465ade3 100644 --- a/mozilla/content/events/src/nsEventStateManager.h +++ b/mozilla/content/events/src/nsEventStateManager.h @@ -55,6 +55,7 @@ public: NS_IMETHOD GetContentState(nsIContent *aContent, PRInt32& aState); NS_IMETHOD SetContentState(nsIContent *aContent, PRInt32 aState); + NS_IMETHOD GetFocusedContent(nsIContent **aContent); protected: void UpdateCursor(nsIPresContext& aPresContext, nsPoint& aPoint, nsIFrame* aTargetFrame, nsEventStatus& aStatus); diff --git a/mozilla/content/html/content/src/nsHTMLAnchorElement.cpp b/mozilla/content/html/content/src/nsHTMLAnchorElement.cpp index 6b824d06946..19ff500731b 100644 --- a/mozilla/content/html/content/src/nsHTMLAnchorElement.cpp +++ b/mozilla/content/html/content/src/nsHTMLAnchorElement.cpp @@ -307,19 +307,30 @@ nsHTMLAnchorElement::HandleDOMEvent(nsIPresContext& aPresContext, break; case NS_MOUSE_LEFT_CLICK: + case NS_KEY_PRESS: { if (nsEventStatus_eConsumeNoDefault != aEventStatus) { - nsAutoString target; - nsIURI* baseURL = nsnull; - GetBaseURL(baseURL); - GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::target, target); - if (target.Length() == 0) { - GetBaseTarget(target); + + 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); + } + mInner.TriggerLink(aPresContext, eLinkVerb_Replace, + baseURL, href, target, PR_TRUE); + NS_IF_RELEASE(baseURL); + aEventStatus = nsEventStatus_eConsumeDoDefault; } - mInner.TriggerLink(aPresContext, eLinkVerb_Replace, - baseURL, href, target, PR_TRUE); - NS_IF_RELEASE(baseURL); - aEventStatus = nsEventStatus_eConsumeDoDefault; } } break; diff --git a/mozilla/content/html/content/src/nsHTMLInputElement.cpp b/mozilla/content/html/content/src/nsHTMLInputElement.cpp index e10aa4aed08..198c86a8c44 100644 --- a/mozilla/content/html/content/src/nsHTMLInputElement.cpp +++ b/mozilla/content/html/content/src/nsHTMLInputElement.cpp @@ -449,8 +449,38 @@ nsHTMLInputElement::Select() NS_IMETHODIMP nsHTMLInputElement::Click() { - //XXX TBI - return NS_ERROR_NOT_IMPLEMENTED; + PRInt32 type; + GetType(&type); + switch(type) { + case NS_FORM_INPUT_CHECKBOX: + { + PRBool checked; + GetChecked(&checked); + SetChecked(!checked); + } + break; + + case NS_FORM_INPUT_RADIO: + SetChecked(PR_TRUE); + break; + +#if 0 + case NS_FORM_INPUT_BUTTON: + case NS_FORM_INPUT_RESET: + case NS_FORM_INPUT_SUBMIT: + { + nsIFormControlFrame* formControlFrame = nsnull; + if (NS_OK == nsGenericHTMLElement::GetPrimaryFrame(this, formControlFrame)) { + if (formControlFrame) { + formControlFrame->MouseClicked(XXXpresContextXXX); + } + } + } + break; +#endif + } + + return NS_OK; } NS_IMETHODIMP @@ -460,10 +490,51 @@ nsHTMLInputElement::HandleDOMEvent(nsIPresContext& aPresContext, PRUint32 aFlags, nsEventStatus& aEventStatus) { - return mInner.HandleDOMEvent(aPresContext, aEvent, aDOMEvent, + // Try script event handlers first + nsresult ret = mInner.HandleDOMEvent(aPresContext, aEvent, aDOMEvent, aFlags, aEventStatus); + + if ((NS_OK == ret) && (nsEventStatus_eIgnore == aEventStatus)) { + switch (aEvent->message) { + case NS_KEY_PRESS: + { + nsKeyEvent * keyEvent = (nsKeyEvent *)aEvent; + if (keyEvent->keyCode == NS_VK_RETURN || keyEvent->charCode == 0x20) { + PRInt32 type; + GetType(&type); + switch(type) { + case NS_FORM_INPUT_CHECKBOX: + case NS_FORM_INPUT_RADIO: + ret = Click(); + break; + case NS_FORM_INPUT_BUTTON: + case NS_FORM_INPUT_RESET: + case NS_FORM_INPUT_SUBMIT: + { + //Checkboxes and radio trigger off return or space but buttons + //just trigger of of space, go figure. + if (keyEvent->charCode == 0x20) { + //XXX We should just be able to call Click() here but then + //Click wouldn't have a PresContext. + nsIFormControlFrame* formControlFrame = nsnull; + if (NS_OK == nsGenericHTMLElement::GetPrimaryFrame(this, formControlFrame)) { + if (formControlFrame) { + formControlFrame->MouseClicked(&aPresContext); + } + } + } + } + break; + } + } + } + } + } + + return ret; } + // nsIHTMLContent static nsGenericHTMLElement::EnumTable kInputTypeTable[] = { diff --git a/mozilla/dom/src/base/nsGlobalWindow.cpp b/mozilla/dom/src/base/nsGlobalWindow.cpp index 57374b10237..79efc65e9d0 100644 --- a/mozilla/dom/src/base/nsGlobalWindow.cpp +++ b/mozilla/dom/src/base/nsGlobalWindow.cpp @@ -737,12 +737,27 @@ GlobalWindowImpl::SetStatus(const nsString& aStatus) NS_IMETHODIMP GlobalWindowImpl::GetDefaultStatus(nsString& aDefaultStatus) { + nsIBrowserWindow *mBrowser; + if (NS_OK == GetBrowserWindowInterface(mBrowser)) { + const PRUnichar *status; + mBrowser->GetDefaultStatus(&status); + aDefaultStatus = status; + NS_RELEASE(mBrowser); + } + else { + aDefaultStatus.Truncate(); + } return NS_OK; } NS_IMETHODIMP GlobalWindowImpl::SetDefaultStatus(const nsString& aDefaultStatus) { + nsIBrowserWindow *mBrowser; + if (NS_OK == GetBrowserWindowInterface(mBrowser)) { + mBrowser->SetDefaultStatus(aDefaultStatus.GetUnicode()); + NS_RELEASE(mBrowser); + } return NS_OK; } diff --git a/mozilla/layout/base/nsPresShell.cpp b/mozilla/layout/base/nsPresShell.cpp index a24e05f322d..807cd5c2131 100644 --- a/mozilla/layout/base/nsPresShell.cpp +++ b/mozilla/layout/base/nsPresShell.cpp @@ -2218,38 +2218,50 @@ PresShell::HandleEvent(nsIView *aView, mSelection->EnableFrameNotification(PR_TRUE); //prevents secondary reset selection called since //we are a listener now. } - frame->GetFrameForPoint(aEvent->point, &mCurrentEventFrame); - NS_IF_RELEASE(mCurrentEventContent); - if (nsnull != GetCurrentEventFrame()) { + nsIEventStateManager *manager; + nsIContent* focusContent = nsnull; + if (NS_OK == mPresContext->GetEventStateManager(&manager)) { + if (NS_IS_KEY_EVENT(aEvent)) { + //Key events go to the focused frame, not point based. + manager->GetFocusedContent(&focusContent); + } + frame->GetFrameForPoint(aEvent->point, &mCurrentEventFrame); + NS_IF_RELEASE(mCurrentEventContent); + if (GetCurrentEventFrame() || focusContent) { //Once we have the targetFrame, handle the event in this order - nsIEventStateManager *manager; - if (NS_OK == mPresContext->GetEventStateManager(&manager)) { //1. Give event to event manager for pre event state changes and generation of synthetic events. rv = manager->PreHandleEvent(*mPresContext, aEvent, mCurrentEventFrame, aEventStatus, aView); //2. Give event to the DOM for third party and JS use. - if (nsnull != GetCurrentEventFrame() && NS_OK == rv) { - nsIContent* targetContent; - if (NS_OK == mCurrentEventFrame->GetContent(&targetContent) && nsnull != targetContent) { - rv = targetContent->HandleDOMEvent(*mPresContext, (nsEvent*)aEvent, nsnull, + if ((GetCurrentEventFrame() || focusContent) && NS_OK == rv) { + if (focusContent) { + rv = focusContent->HandleDOMEvent(*mPresContext, (nsEvent*)aEvent, nsnull, NS_EVENT_FLAG_INIT, aEventStatus); - NS_RELEASE(targetContent); + } + else { + nsIContent* targetContent; + if (NS_OK == mCurrentEventFrame->GetContent(&targetContent) && nsnull != targetContent) { + rv = targetContent->HandleDOMEvent(*mPresContext, (nsEvent*)aEvent, nsnull, + NS_EVENT_FLAG_INIT, aEventStatus); + NS_RELEASE(targetContent); + } } //3. Give event to the Frames for browser default processing. // XXX The event isn't translated into the local coordinate space // of the frame... - if (nsnull != GetCurrentEventFrame() && NS_OK == rv) { + if (GetCurrentEventFrame() && NS_OK == rv) { rv = mCurrentEventFrame->HandleEvent(*mPresContext, aEvent, aEventStatus); + } - //4. Give event to event manager for post event state changes and generation of synthetic events. - if (nsnull != GetCurrentEventFrame() && NS_OK == rv) { - rv = manager->PostHandleEvent(*mPresContext, aEvent, mCurrentEventFrame, aEventStatus, aView); - } + //4. Give event to event manager for post event state changes and generation of synthetic events. + if ((GetCurrentEventFrame() || focusContent) && NS_OK == rv) { + rv = manager->PostHandleEvent(*mPresContext, aEvent, mCurrentEventFrame, aEventStatus, aView); } } - NS_RELEASE(manager); } + NS_RELEASE(manager); + NS_IF_RELEASE(focusContent); } NS_IF_RELEASE(webShell); } diff --git a/mozilla/layout/events/public/nsIEventStateManager.h b/mozilla/layout/events/public/nsIEventStateManager.h index ec2b6dfa637..cb0887226a9 100644 --- a/mozilla/layout/events/public/nsIEventStateManager.h +++ b/mozilla/layout/events/public/nsIEventStateManager.h @@ -61,6 +61,8 @@ public: NS_IMETHOD GetContentState(nsIContent *aContent, PRInt32& aState) = 0; NS_IMETHOD SetContentState(nsIContent *aContent, PRInt32 aState) = 0; + + NS_IMETHOD GetFocusedContent(nsIContent **aContent) = 0; }; #define NS_EVENT_STATE_UNSPECIFIED 0x0000 diff --git a/mozilla/layout/events/src/nsEventStateManager.cpp b/mozilla/layout/events/src/nsEventStateManager.cpp index 807f23387cc..29eabd2ad3b 100644 --- a/mozilla/layout/events/src/nsEventStateManager.cpp +++ b/mozilla/layout/events/src/nsEventStateManager.cpp @@ -1171,6 +1171,14 @@ nsEventStateManager::SendFocusBlur(nsIContent *aContent) return NS_OK; } +NS_IMETHODIMP +nsEventStateManager::GetFocusedContent(nsIContent** aContent) +{ + *aContent = mCurrentFocus; + NS_IF_ADDREF(*aContent); + return NS_OK; +} + nsresult NS_NewEventStateManager(nsIEventStateManager** aInstancePtrResult) { NS_PRECONDITION(nsnull != aInstancePtrResult, "nsnull ptr"); diff --git a/mozilla/layout/events/src/nsEventStateManager.h b/mozilla/layout/events/src/nsEventStateManager.h index f00cc6d880a..b661465ade3 100644 --- a/mozilla/layout/events/src/nsEventStateManager.h +++ b/mozilla/layout/events/src/nsEventStateManager.h @@ -55,6 +55,7 @@ public: NS_IMETHOD GetContentState(nsIContent *aContent, PRInt32& aState); NS_IMETHOD SetContentState(nsIContent *aContent, PRInt32 aState); + NS_IMETHOD GetFocusedContent(nsIContent **aContent); protected: void UpdateCursor(nsIPresContext& aPresContext, nsPoint& aPoint, nsIFrame* aTargetFrame, nsEventStatus& aStatus); diff --git a/mozilla/layout/forms/nsFormControlFrame.cpp b/mozilla/layout/forms/nsFormControlFrame.cpp index d470a1ca60c..4dff9feb9e0 100644 --- a/mozilla/layout/forms/nsFormControlFrame.cpp +++ b/mozilla/layout/forms/nsFormControlFrame.cpp @@ -388,12 +388,23 @@ nsFormControlFrame::PostCreateWidget(nsIPresContext* aPresContext, nscoord& aWid { } -// native widgets don't unset focus explicitly and don't need to repaint +// native widgets don't need to repaint void nsFormControlFrame::SetFocus(PRBool aOn, PRBool aRepaint) { - if (mWidget && aOn) { - mWidget->SetFocus(); + if (mWidget) { + if (aOn) { + mWidget->SetFocus(); + } + else { + //Unsetting of focus on native widget is accomplised + //by pushing focus up to its parent + nsIWidget *parentWidget = mWidget->GetParent(); + if (parentWidget) { + parentWidget->SetFocus(); + NS_RELEASE(parentWidget); + } + } } } diff --git a/mozilla/layout/html/base/src/nsPresShell.cpp b/mozilla/layout/html/base/src/nsPresShell.cpp index a24e05f322d..807cd5c2131 100644 --- a/mozilla/layout/html/base/src/nsPresShell.cpp +++ b/mozilla/layout/html/base/src/nsPresShell.cpp @@ -2218,38 +2218,50 @@ PresShell::HandleEvent(nsIView *aView, mSelection->EnableFrameNotification(PR_TRUE); //prevents secondary reset selection called since //we are a listener now. } - frame->GetFrameForPoint(aEvent->point, &mCurrentEventFrame); - NS_IF_RELEASE(mCurrentEventContent); - if (nsnull != GetCurrentEventFrame()) { + nsIEventStateManager *manager; + nsIContent* focusContent = nsnull; + if (NS_OK == mPresContext->GetEventStateManager(&manager)) { + if (NS_IS_KEY_EVENT(aEvent)) { + //Key events go to the focused frame, not point based. + manager->GetFocusedContent(&focusContent); + } + frame->GetFrameForPoint(aEvent->point, &mCurrentEventFrame); + NS_IF_RELEASE(mCurrentEventContent); + if (GetCurrentEventFrame() || focusContent) { //Once we have the targetFrame, handle the event in this order - nsIEventStateManager *manager; - if (NS_OK == mPresContext->GetEventStateManager(&manager)) { //1. Give event to event manager for pre event state changes and generation of synthetic events. rv = manager->PreHandleEvent(*mPresContext, aEvent, mCurrentEventFrame, aEventStatus, aView); //2. Give event to the DOM for third party and JS use. - if (nsnull != GetCurrentEventFrame() && NS_OK == rv) { - nsIContent* targetContent; - if (NS_OK == mCurrentEventFrame->GetContent(&targetContent) && nsnull != targetContent) { - rv = targetContent->HandleDOMEvent(*mPresContext, (nsEvent*)aEvent, nsnull, + if ((GetCurrentEventFrame() || focusContent) && NS_OK == rv) { + if (focusContent) { + rv = focusContent->HandleDOMEvent(*mPresContext, (nsEvent*)aEvent, nsnull, NS_EVENT_FLAG_INIT, aEventStatus); - NS_RELEASE(targetContent); + } + else { + nsIContent* targetContent; + if (NS_OK == mCurrentEventFrame->GetContent(&targetContent) && nsnull != targetContent) { + rv = targetContent->HandleDOMEvent(*mPresContext, (nsEvent*)aEvent, nsnull, + NS_EVENT_FLAG_INIT, aEventStatus); + NS_RELEASE(targetContent); + } } //3. Give event to the Frames for browser default processing. // XXX The event isn't translated into the local coordinate space // of the frame... - if (nsnull != GetCurrentEventFrame() && NS_OK == rv) { + if (GetCurrentEventFrame() && NS_OK == rv) { rv = mCurrentEventFrame->HandleEvent(*mPresContext, aEvent, aEventStatus); + } - //4. Give event to event manager for post event state changes and generation of synthetic events. - if (nsnull != GetCurrentEventFrame() && NS_OK == rv) { - rv = manager->PostHandleEvent(*mPresContext, aEvent, mCurrentEventFrame, aEventStatus, aView); - } + //4. Give event to event manager for post event state changes and generation of synthetic events. + if ((GetCurrentEventFrame() || focusContent) && NS_OK == rv) { + rv = manager->PostHandleEvent(*mPresContext, aEvent, mCurrentEventFrame, aEventStatus, aView); } } - NS_RELEASE(manager); } + NS_RELEASE(manager); + NS_IF_RELEASE(focusContent); } NS_IF_RELEASE(webShell); } diff --git a/mozilla/layout/html/content/src/nsHTMLAnchorElement.cpp b/mozilla/layout/html/content/src/nsHTMLAnchorElement.cpp index 6b824d06946..19ff500731b 100644 --- a/mozilla/layout/html/content/src/nsHTMLAnchorElement.cpp +++ b/mozilla/layout/html/content/src/nsHTMLAnchorElement.cpp @@ -307,19 +307,30 @@ nsHTMLAnchorElement::HandleDOMEvent(nsIPresContext& aPresContext, break; case NS_MOUSE_LEFT_CLICK: + case NS_KEY_PRESS: { if (nsEventStatus_eConsumeNoDefault != aEventStatus) { - nsAutoString target; - nsIURI* baseURL = nsnull; - GetBaseURL(baseURL); - GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::target, target); - if (target.Length() == 0) { - GetBaseTarget(target); + + 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); + } + mInner.TriggerLink(aPresContext, eLinkVerb_Replace, + baseURL, href, target, PR_TRUE); + NS_IF_RELEASE(baseURL); + aEventStatus = nsEventStatus_eConsumeDoDefault; } - mInner.TriggerLink(aPresContext, eLinkVerb_Replace, - baseURL, href, target, PR_TRUE); - NS_IF_RELEASE(baseURL); - aEventStatus = nsEventStatus_eConsumeDoDefault; } } break; diff --git a/mozilla/layout/html/content/src/nsHTMLInputElement.cpp b/mozilla/layout/html/content/src/nsHTMLInputElement.cpp index e10aa4aed08..198c86a8c44 100644 --- a/mozilla/layout/html/content/src/nsHTMLInputElement.cpp +++ b/mozilla/layout/html/content/src/nsHTMLInputElement.cpp @@ -449,8 +449,38 @@ nsHTMLInputElement::Select() NS_IMETHODIMP nsHTMLInputElement::Click() { - //XXX TBI - return NS_ERROR_NOT_IMPLEMENTED; + PRInt32 type; + GetType(&type); + switch(type) { + case NS_FORM_INPUT_CHECKBOX: + { + PRBool checked; + GetChecked(&checked); + SetChecked(!checked); + } + break; + + case NS_FORM_INPUT_RADIO: + SetChecked(PR_TRUE); + break; + +#if 0 + case NS_FORM_INPUT_BUTTON: + case NS_FORM_INPUT_RESET: + case NS_FORM_INPUT_SUBMIT: + { + nsIFormControlFrame* formControlFrame = nsnull; + if (NS_OK == nsGenericHTMLElement::GetPrimaryFrame(this, formControlFrame)) { + if (formControlFrame) { + formControlFrame->MouseClicked(XXXpresContextXXX); + } + } + } + break; +#endif + } + + return NS_OK; } NS_IMETHODIMP @@ -460,10 +490,51 @@ nsHTMLInputElement::HandleDOMEvent(nsIPresContext& aPresContext, PRUint32 aFlags, nsEventStatus& aEventStatus) { - return mInner.HandleDOMEvent(aPresContext, aEvent, aDOMEvent, + // Try script event handlers first + nsresult ret = mInner.HandleDOMEvent(aPresContext, aEvent, aDOMEvent, aFlags, aEventStatus); + + if ((NS_OK == ret) && (nsEventStatus_eIgnore == aEventStatus)) { + switch (aEvent->message) { + case NS_KEY_PRESS: + { + nsKeyEvent * keyEvent = (nsKeyEvent *)aEvent; + if (keyEvent->keyCode == NS_VK_RETURN || keyEvent->charCode == 0x20) { + PRInt32 type; + GetType(&type); + switch(type) { + case NS_FORM_INPUT_CHECKBOX: + case NS_FORM_INPUT_RADIO: + ret = Click(); + break; + case NS_FORM_INPUT_BUTTON: + case NS_FORM_INPUT_RESET: + case NS_FORM_INPUT_SUBMIT: + { + //Checkboxes and radio trigger off return or space but buttons + //just trigger of of space, go figure. + if (keyEvent->charCode == 0x20) { + //XXX We should just be able to call Click() here but then + //Click wouldn't have a PresContext. + nsIFormControlFrame* formControlFrame = nsnull; + if (NS_OK == nsGenericHTMLElement::GetPrimaryFrame(this, formControlFrame)) { + if (formControlFrame) { + formControlFrame->MouseClicked(&aPresContext); + } + } + } + } + break; + } + } + } + } + } + + return ret; } + // nsIHTMLContent static nsGenericHTMLElement::EnumTable kInputTypeTable[] = { diff --git a/mozilla/layout/html/forms/src/nsFormControlFrame.cpp b/mozilla/layout/html/forms/src/nsFormControlFrame.cpp index d470a1ca60c..4dff9feb9e0 100644 --- a/mozilla/layout/html/forms/src/nsFormControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsFormControlFrame.cpp @@ -388,12 +388,23 @@ nsFormControlFrame::PostCreateWidget(nsIPresContext* aPresContext, nscoord& aWid { } -// native widgets don't unset focus explicitly and don't need to repaint +// native widgets don't need to repaint void nsFormControlFrame::SetFocus(PRBool aOn, PRBool aRepaint) { - if (mWidget && aOn) { - mWidget->SetFocus(); + if (mWidget) { + if (aOn) { + mWidget->SetFocus(); + } + else { + //Unsetting of focus on native widget is accomplised + //by pushing focus up to its parent + nsIWidget *parentWidget = mWidget->GetParent(); + if (parentWidget) { + parentWidget->SetFocus(); + NS_RELEASE(parentWidget); + } + } } } diff --git a/mozilla/webshell/embed/ActiveX/WebShellContainer.cpp b/mozilla/webshell/embed/ActiveX/WebShellContainer.cpp index 44223f25dae..930ed54def2 100644 --- a/mozilla/webshell/embed/ActiveX/WebShellContainer.cpp +++ b/mozilla/webshell/embed/ActiveX/WebShellContainer.cpp @@ -224,6 +224,21 @@ CWebShellContainer::GetStatus(const PRUnichar** aResult) return NS_OK; } +NS_IMETHODIMP +CWebShellContainer::SetDefaultStatus(const PRUnichar* aStatus) +{ + NG_TRACE_METHOD(CWebShellContainer::SetDefaultStatus); + return NS_OK; +} + + +NS_IMETHODIMP +CWebShellContainer::GetDefaultStatus(const PRUnichar** aResult) +{ + NG_TRACE_METHOD(CWebShellContainer::GetDefaultStatus); + *aResult = nsnull; + return NS_OK; +} NS_IMETHODIMP CWebShellContainer::SetProgress(PRInt32 aProgress, PRInt32 aProgressMax) diff --git a/mozilla/webshell/embed/ActiveX/WebShellContainer.h b/mozilla/webshell/embed/ActiveX/WebShellContainer.h index 82f27dcee64..f74744b9de1 100644 --- a/mozilla/webshell/embed/ActiveX/WebShellContainer.h +++ b/mozilla/webshell/embed/ActiveX/WebShellContainer.h @@ -67,6 +67,8 @@ public: NS_IMETHOD GetTitle(const PRUnichar** aResult); NS_IMETHOD SetStatus(const PRUnichar* aStatus); NS_IMETHOD GetStatus(const PRUnichar** aResult); + NS_IMETHOD SetDefaultStatus(const PRUnichar* aStatus); + NS_IMETHOD GetDefaultStatus(const PRUnichar** aResult); NS_IMETHOD SetProgress(PRInt32 aProgress, PRInt32 aProgressMax); NS_IMETHOD ShowMenuBar(PRBool aShow); NS_IMETHOD GetWebShell(nsIWebShell*& aResult); diff --git a/mozilla/webshell/public/nsIBrowserWindow.h b/mozilla/webshell/public/nsIBrowserWindow.h index ae5f116f34d..ff67eb41194 100644 --- a/mozilla/webshell/public/nsIBrowserWindow.h +++ b/mozilla/webshell/public/nsIBrowserWindow.h @@ -95,6 +95,10 @@ public: NS_IMETHOD GetStatus(const PRUnichar** aResult) = 0; + NS_IMETHOD SetDefaultStatus(const PRUnichar* aStatus) = 0; + + NS_IMETHOD GetDefaultStatus(const PRUnichar** aResult) = 0; + NS_IMETHOD SetProgress(PRInt32 aProgress, PRInt32 aProgressMax) = 0; NS_IMETHOD ShowMenuBar(PRBool aShow) = 0; diff --git a/mozilla/webshell/tests/viewer/nsBrowserWindow.cpp b/mozilla/webshell/tests/viewer/nsBrowserWindow.cpp index cf1a48a1854..064b12d5bb3 100644 --- a/mozilla/webshell/tests/viewer/nsBrowserWindow.cpp +++ b/mozilla/webshell/tests/viewer/nsBrowserWindow.cpp @@ -1676,6 +1676,18 @@ nsBrowserWindow::GetStatus(const PRUnichar** aResult) return NS_OK; } +NS_IMETHODIMP +nsBrowserWindow::SetDefaultStatus(const PRUnichar* aStatus) +{ + return NS_OK; +} + +NS_IMETHODIMP +nsBrowserWindow::GetDefaultStatus(const PRUnichar** aResult) +{ + return NS_OK; +} + NS_IMETHODIMP nsBrowserWindow::SetProgress(PRInt32 aProgress, PRInt32 aProgressMax) { diff --git a/mozilla/webshell/tests/viewer/nsBrowserWindow.h b/mozilla/webshell/tests/viewer/nsBrowserWindow.h index 3ef8b488e60..12c602a1fb8 100644 --- a/mozilla/webshell/tests/viewer/nsBrowserWindow.h +++ b/mozilla/webshell/tests/viewer/nsBrowserWindow.h @@ -102,6 +102,8 @@ public: NS_IMETHOD GetTitle(const PRUnichar** aResult); NS_IMETHOD SetStatus(const PRUnichar* aStatus); NS_IMETHOD GetStatus(const PRUnichar** aResult); + NS_IMETHOD SetDefaultStatus(const PRUnichar* aStatus); + NS_IMETHOD GetDefaultStatus(const PRUnichar** aResult); NS_IMETHOD SetProgress(PRInt32 aProgress, PRInt32 aProgressMax); NS_IMETHOD ShowMenuBar(PRBool aShow); NS_IMETHOD GetWebShell(nsIWebShell*& aResult); diff --git a/mozilla/xpfe/appshell/src/nsWebShellWindow.cpp b/mozilla/xpfe/appshell/src/nsWebShellWindow.cpp index 058ace1c7d5..381aeb7a077 100644 --- a/mozilla/xpfe/appshell/src/nsWebShellWindow.cpp +++ b/mozilla/xpfe/appshell/src/nsWebShellWindow.cpp @@ -1815,6 +1815,16 @@ nsWebShellWindow::OnEndDocumentLoad(nsIDocumentLoader* loader, if (mCreatedVisible) Show(PR_TRUE); + nsCOMPtr contentShell; + GetContentWebShell(getter_AddRefs(contentShell)); + if (contentShell) { + nsCOMPtr domWindow; + if (NS_SUCCEEDED(ConvertWebShellToDOMWindow(contentShell, + getter_AddRefs(domWindow)))) { + domWindow->Focus(); + } + } + return NS_OK; } @@ -2687,8 +2697,11 @@ nsWebShellWindow::NotifyObservers( const nsString &aTopic, const nsString &someD NS_IMETHODIMP nsWebShellWindow::SetStatus(const PRUnichar* aStatus) { nsresult rv = NS_OK; - // Store status text. + // Store status text unless empty string was set, then use defaultStatus mStatus = aStatus; + if (mStatus.Length() == 0) { + mStatus = mDefaultStatus; + } // Broadcast status text change to interested parties. rv = NotifyObservers( "status", aStatus ); return rv; @@ -2706,6 +2719,28 @@ NS_IMETHODIMP nsWebShellWindow::GetStatus(const PRUnichar** aResult) return rv; } +NS_IMETHODIMP nsWebShellWindow::SetDefaultStatus(const PRUnichar* aStatus) +{ + nsresult rv = NS_OK; + // Store status text. + mDefaultStatus = aStatus; + // Broadcast status text change to interested parties. + rv = NotifyObservers( "defaultStatus", aStatus ); + return rv; +} + +NS_IMETHODIMP nsWebShellWindow::GetDefaultStatus(const PRUnichar** aResult) +{ + nsresult rv = NS_OK; + if ( aResult ) { + // Semantics are ill-defined: How to allocate? Who frees it? + *aResult = mDefaultStatus.ToNewUnicode(); + } else { + rv = NS_ERROR_NULL_POINTER; + } + return rv; +} + NS_IMETHODIMP nsWebShellWindow::SetProgress(PRInt32 aProgress, PRInt32 aProgressMax) { nsresult rv = NS_OK; diff --git a/mozilla/xpfe/appshell/src/nsWebShellWindow.h b/mozilla/xpfe/appshell/src/nsWebShellWindow.h index 87ac2a65181..89af81d7669 100644 --- a/mozilla/xpfe/appshell/src/nsWebShellWindow.h +++ b/mozilla/xpfe/appshell/src/nsWebShellWindow.h @@ -242,6 +242,8 @@ public: NS_IMETHOD GetTitle(const PRUnichar** aResult); NS_IMETHOD SetStatus(const PRUnichar* aStatus); NS_IMETHOD GetStatus(const PRUnichar** aResult); + NS_IMETHOD SetDefaultStatus(const PRUnichar* aStatus); + NS_IMETHOD GetDefaultStatus(const PRUnichar** aResult); NS_IMETHOD SetProgress(PRInt32 aProgress, PRInt32 aProgressMax); NS_IMETHOD ShowMenuBar(PRBool aShow); @@ -293,6 +295,7 @@ protected: nsIDOMNode * contextMenuTest; nsString mStatus; + nsString mDefaultStatus; PRBool mIntrinsicallySized; // Whether or not this window gets sized to its content.