diff --git a/content/base/src/nsGenericElement.cpp b/content/base/src/nsGenericElement.cpp index 95cb1ba28d7..61066a7ad13 100644 --- a/content/base/src/nsGenericElement.cpp +++ b/content/base/src/nsGenericElement.cpp @@ -26,12 +26,12 @@ #include "nsIAtom.h" #include "nsINodeInfo.h" #include "nsIDocument.h" -#include "nsIDOMEventReceiver.h" #include "nsIDOMNodeList.h" #include "nsIDOMDocument.h" #include "nsIDOMDocumentFragment.h" #include "nsIDOMRange.h" #include "nsIDOMText.h" +#include "nsIDOMEventReceiver.h" #include "nsRange.h" #include "nsIEventListenerManager.h" #include "nsILinkHandler.h" @@ -71,7 +71,7 @@ #include "nsLayoutAtoms.h" #include "nsHTMLAtoms.h" #include "nsLayoutUtils.h" - +#include "nsIJSContextStack.h" #include "nsIServiceManager.h" #include "nsIPref.h" // Used by the temp pref, should be removed! @@ -81,8 +81,8 @@ static PRBool kStrictDOMLevel2 = PR_FALSE; NS_DEFINE_IID(kIDOMNodeIID, NS_IDOMNODE_IID); NS_DEFINE_IID(kIDOMElementIID, NS_IDOMELEMENT_IID); NS_DEFINE_IID(kIDOMTextIID, NS_IDOMTEXT_IID); -NS_DEFINE_IID(kIDOMEventReceiverIID, NS_IDOMEVENTRECEIVER_IID); NS_DEFINE_IID(kIDOMEventTargetIID, NS_IDOMEVENTTARGET_IID); +NS_DEFINE_IID(kIDOMEventReceiverIID, NS_IDOMEVENTRECEIVER_IID); NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID); NS_DEFINE_IID(kIJSScriptObjectIID, NS_IJSSCRIPTOBJECT_IID); NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); @@ -2358,44 +2358,56 @@ nsGenericElement::AddScriptEventListener(nsIAtom* aAttribute, REFNSIID aIID) { nsresult ret = NS_OK; - nsIScriptContext* context; + nsCOMPtr context = nsnull; + nsCOMPtr global = nsnull; + JSContext* cx = nsnull; - if (nsnull != mDocument) { - nsCOMPtr global; - mDocument->GetScriptGlobalObject(getter_AddRefs(global)); - if (global) { - if (NS_OK == global->GetContext(&context)) { - if (mNodeInfo->Equals(nsHTMLAtoms::body) || - mNodeInfo->Equals(nsHTMLAtoms::frameset)) { - nsIDOMEventReceiver *receiver; + //Try to get context from doc + if (mDocument) { + if (NS_SUCCEEDED(mDocument->GetScriptGlobalObject(getter_AddRefs(global))) && global) { + NS_ENSURE_SUCCESS(global->GetContext(getter_AddRefs(context)), NS_ERROR_FAILURE); + } + } - if (nsnull != global && NS_OK == global->QueryInterface(kIDOMEventReceiverIID, (void**)&receiver)) { - nsIEventListenerManager *manager; - if (NS_OK == receiver->GetListenerManager(&manager)) { - nsIScriptObjectOwner *mObjectOwner; - if (NS_OK == global->QueryInterface(kIScriptObjectOwnerIID, (void**)&mObjectOwner)) { - ret = manager->AddScriptEventListener(context, mObjectOwner, aAttribute, aValue, aIID, PR_FALSE); - NS_RELEASE(mObjectOwner); - } - NS_RELEASE(manager); - } - NS_RELEASE(receiver); - } - } - else { - nsIEventListenerManager *manager; - if (NS_OK == GetListenerManager(&manager)) { - nsIScriptObjectOwner* cowner; - if (NS_OK == mContent->QueryInterface(kIScriptObjectOwnerIID, - (void**) &cowner)) { - ret = manager->AddScriptEventListener(context, cowner, - aAttribute, aValue, aIID, PR_TRUE); - NS_RELEASE(cowner); - } - NS_RELEASE(manager); - } - } - NS_RELEASE(context); + if (!context) { + // Get JSContext from stack. + nsCOMPtr stack(do_GetService("nsThreadJSContextStack")); + NS_ENSURE_TRUE(stack, NS_ERROR_FAILURE); + NS_ENSURE_SUCCESS(stack->Peek(&cx), NS_ERROR_FAILURE); + + if(!cx) { + stack->GetSafeJSContext(&cx); + NS_ENSURE_TRUE(cx, NS_ERROR_FAILURE); + } + + nsLayoutUtils::GetDynamicScriptContext(cx, getter_AddRefs(context)); + NS_ENSURE_TRUE(context, NS_ERROR_FAILURE); + } + + //Attributes on the body and frameset tags get set on the global object + if (mNodeInfo->Equals(nsHTMLAtoms::body) || + mNodeInfo->Equals(nsHTMLAtoms::frameset)) { + if (!global) { + if (cx) { + nsLayoutUtils::GetDynamicScriptGlobal(cx, getter_AddRefs(global)); + } + NS_ENSURE_TRUE(global, NS_ERROR_FAILURE); + } + nsCOMPtr receiver(do_QueryInterface(global)); + nsCOMPtr manager; + if (receiver && NS_SUCCEEDED(receiver->GetListenerManager(getter_AddRefs(manager)))) { + nsCOMPtr objOwner(do_QueryInterface(global)); + if (objOwner) { + ret = manager->AddScriptEventListener(context, objOwner, aAttribute, aValue, aIID, PR_FALSE); + } + } + } + else { + nsCOMPtr manager; + if (NS_SUCCEEDED(GetListenerManager(getter_AddRefs(manager)))) { + nsCOMPtr objOwner(do_QueryInterface(mContent)); + if (objOwner) { + ret = manager->AddScriptEventListener(context, objOwner, aAttribute, aValue, aIID, PR_TRUE); } } } diff --git a/content/base/src/nsRange.cpp b/content/base/src/nsRange.cpp index 1c75b2dc6ff..7c7ec19457b 100644 --- a/content/base/src/nsRange.cpp +++ b/content/base/src/nsRange.cpp @@ -425,7 +425,7 @@ nsRange::IntersectsNode(nsIDOMNode* aNode, PRBool* aReturn) // HOW does the node intersect the range? NS_IMETHODIMP -nsRange::CompareNode(nsIDOMNode* aNode, PRInt16* aReturn) +nsRange::CompareNode(nsIDOMNode* aNode, PRUint16* aReturn) { if (!aReturn) return NS_ERROR_NULL_POINTER; diff --git a/content/base/src/nsRange.h b/content/base/src/nsRange.h index e118bf16044..709bd1187b2 100644 --- a/content/base/src/nsRange.h +++ b/content/base/src/nsRange.h @@ -100,7 +100,7 @@ public: NS_IMETHOD ComparePoint(nsIDOMNode* aParent, PRInt32 aOffset, PRInt16* aResult); NS_IMETHOD IntersectsNode(nsIDOMNode* aNode, PRBool* aReturn); - NS_IMETHOD CompareNode(nsIDOMNode* aNode, PRInt16* aReturn); + NS_IMETHOD CompareNode(nsIDOMNode* aNode, PRUint16* aReturn); /*END nsIDOMNSRange interface implementations*/ NS_IMETHOD GetHasGeneratedBefore(PRBool *aBool); diff --git a/content/events/public/nsIPrivateDOMEvent.h b/content/events/public/nsIPrivateDOMEvent.h index a0fb3a03144..de3bf0e8838 100644 --- a/content/events/public/nsIPrivateDOMEvent.h +++ b/content/events/public/nsIPrivateDOMEvent.h @@ -49,6 +49,7 @@ public: NS_IMETHOD SetCurrentTarget(nsIDOMEventTarget* aTarget) = 0; NS_IMETHOD IsDispatchStopped(PRBool* aIsDispatchPrevented) = 0; NS_IMETHOD GetInternalNSEvent(nsEvent** aNSEvent) = 0; + NS_IMETHOD GetRealTarget(nsIDOMEventTarget** aRealTarget) = 0; }; extern nsresult NS_NewDOMEvent(nsIDOMEvent** aInstancePtrResult, nsIPresContext* aPresContext, nsEvent *aEvent); diff --git a/content/events/src/nsDOMEvent.cpp b/content/events/src/nsDOMEvent.cpp index 8776982f0cb..c8a2881f1a5 100644 --- a/content/events/src/nsDOMEvent.cpp +++ b/content/events/src/nsDOMEvent.cpp @@ -85,7 +85,7 @@ nsDOMEvent::nsDOMEvent(nsIPresContext* aPresContext, nsEvent* aEvent, const nsSt mText = nsnull; mTextRange = nsnull; - if (aEvent->eventStructType == NS_TEXT_EVENT) { + if (aEvent && aEvent->eventStructType == NS_TEXT_EVENT) { // // extract the IME composition string // @@ -164,6 +164,8 @@ NS_METHOD nsDOMEvent::GetTarget(nsIDOMEventTarget** aTarget) return NS_OK; } + *aTarget = nsnull; + nsIEventStateManager *manager; nsIContent *targetContent; @@ -181,19 +183,15 @@ NS_METHOD nsDOMEvent::GetTarget(nsIDOMEventTarget** aTarget) } else { //Always want a target. Use document if nothing else. - nsIPresShell* presShell; - nsIDocument* doc; - if (NS_SUCCEEDED(mPresContext->GetShell(&presShell))) { - presShell->GetDocument(&doc); - NS_RELEASE(presShell); - } - - if (doc) { - if (NS_OK == doc->QueryInterface(NS_GET_IID(nsIDOMEventTarget), (void**)&mTarget)) { - *aTarget = mTarget; - NS_ADDREF(mTarget); - } - NS_RELEASE(doc); + nsCOMPtr doc; + nsCOMPtr presShell; + if (NS_SUCCEEDED(mPresContext->GetShell(getter_AddRefs(presShell))) && presShell) { + if (NS_SUCCEEDED(presShell->GetDocument(getter_AddRefs(doc))) && doc) { + if (NS_SUCCEEDED(doc->QueryInterface(NS_GET_IID(nsIDOMEventTarget), (void**)&mTarget))) { + *aTarget = mTarget; + NS_ADDREF(mTarget); + } + } } } @@ -456,18 +454,13 @@ NS_METHOD nsDOMEvent::GetClientX(PRInt32* aClientX) } //My god, man, there *must* be a better way to do this. - nsIPresShell* shell; + nsCOMPtr presShell; nsIWidget* rootWidget = nsnull; - mPresContext->GetShell(&shell); - - if (shell) { - nsIViewManager* vm; - shell->GetViewManager(&vm); - if (vm) { + if (NS_SUCCEEDED(mPresContext->GetShell(getter_AddRefs(presShell))) && presShell) { + nsCOMPtr vm; + if (NS_SUCCEEDED(presShell->GetViewManager(getter_AddRefs(vm))) && vm) { vm->GetWidget(&rootWidget); - NS_RELEASE(vm); } - NS_RELEASE(shell); } @@ -501,18 +494,13 @@ NS_METHOD nsDOMEvent::GetClientY(PRInt32* aClientY) } //My god, man, there *must* be a better way to do this. - nsIPresShell* shell; + nsCOMPtr presShell; nsIWidget* rootWidget = nsnull; - mPresContext->GetShell(&shell); - - if (shell) { - nsIViewManager* vm; - shell->GetViewManager(&vm); - if (vm) { + if (NS_SUCCEEDED(mPresContext->GetShell(getter_AddRefs(presShell))) && presShell) { + nsCOMPtr vm; + if (NS_SUCCEEDED(presShell->GetViewManager(getter_AddRefs(vm))) && vm) { vm->GetWidget(&rootWidget); - NS_RELEASE(vm); } - NS_RELEASE(shell); } @@ -696,8 +684,7 @@ nsresult nsDOMEvent::GetScrollInfo(nsIScrollableView** aScrollableView, mPresContext->GetTwipsToPixels(aT2P); nsCOMPtr presShell; - mPresContext->GetShell(getter_AddRefs(presShell)); - if(presShell) { + if (NS_SUCCEEDED(mPresContext->GetShell(getter_AddRefs(presShell))) && presShell) { nsCOMPtr vm; presShell->GetViewManager(getter_AddRefs(vm)); if(vm) { @@ -761,7 +748,15 @@ NS_METHOD nsDOMEvent::GetWhich(PRUint32* aWhich) { switch (mEvent->eventStructType) { case NS_KEY_EVENT: - return GetKeyCode(aWhich); + switch (mEvent->message) { + case NS_KEY_UP: + case NS_KEY_DOWN: + return GetKeyCode(aWhich); + case NS_KEY_PRESS: + return GetCharCode(aWhich); + default: + break; + } case NS_MOUSE_EVENT: { PRUint16 button; @@ -1037,6 +1032,12 @@ nsDOMEvent::IsDispatchStopped(PRBool* aIsDispatchStopped) return NS_OK; } +NS_IMETHODIMP +nsDOMEvent::GetRealTarget(nsIDOMEventTarget** aRealTarget) +{ + return NS_OK; +} + NS_IMETHODIMP nsDOMEvent::IsHandled(PRBool* aIsHandled) { diff --git a/content/events/src/nsDOMEvent.h b/content/events/src/nsDOMEvent.h index 18361a20638..2a81f574be5 100644 --- a/content/events/src/nsDOMEvent.h +++ b/content/events/src/nsDOMEvent.h @@ -149,6 +149,7 @@ public: NS_IMETHOD SetCurrentTarget(nsIDOMEventTarget* aCurrentTarget); NS_IMETHOD IsDispatchStopped(PRBool* aIsDispatchStopped); NS_IMETHOD GetInternalNSEvent(nsEvent** aNSEvent); + NS_IMETHOD GetRealTarget(nsIDOMEventTarget** aTarget); NS_IMETHOD IsHandled(PRBool* aHandled); NS_IMETHOD SetHandled(PRBool aHandled); diff --git a/content/events/src/nsEventListenerManager.cpp b/content/events/src/nsEventListenerManager.cpp index 362085205b9..4d58a57a5ba 100644 --- a/content/events/src/nsEventListenerManager.cpp +++ b/content/events/src/nsEventListenerManager.cpp @@ -247,9 +247,8 @@ nsresult nsEventListenerManager::AddEventListener(nsIDOMEventListener *aListener PRBool found = PR_FALSE; nsListenerStruct* ls; - nsIScriptEventListener* sel = nsnull; - - aListener->QueryInterface(kIScriptEventListenerIID, (void**)&sel); + nsresult rv; + nsCOMPtr sel = do_QueryInterface(aListener, &rv); for (int i=0; i<(*listeners)->Count(); i++) { ls = (nsListenerStruct*)(*listeners)->ElementAt(i); @@ -259,10 +258,12 @@ nsresult nsEventListenerManager::AddEventListener(nsIDOMEventListener *aListener break; } else if (sel) { - nsresult rv; + //Listener is an nsIScriptEventListener so we need to use its CheckIfEqual + //method to verify equality. nsCOMPtr regSel = do_QueryInterface(ls->mListener, &rv); if (NS_SUCCEEDED(rv) && regSel) { - if (NS_OK == regSel->CheckIfEqual(sel)) { + PRBool equal; + if (NS_SUCCEEDED(regSel->CheckIfEqual(sel, &equal)) && equal) { if (ls->mFlags & aFlags && ls->mSubType & aSubType) { found = PR_TRUE; break; @@ -272,8 +273,6 @@ nsresult nsEventListenerManager::AddEventListener(nsIDOMEventListener *aListener } } - NS_IF_RELEASE(sel); - if (!found) { ls = PR_NEW(nsListenerStruct); if (ls) { @@ -302,6 +301,8 @@ nsresult nsEventListenerManager::RemoveEventListener(nsIDOMEventListener *aListe } nsListenerStruct* ls; + nsresult rv; + nsCOMPtr sel = do_QueryInterface(aListener, &rv); for (int i=0; i<(*listeners)->Count(); i++) { ls = (nsListenerStruct*)(*listeners)->ElementAt(i); @@ -315,6 +316,21 @@ nsresult nsEventListenerManager::RemoveEventListener(nsIDOMEventListener *aListe } break; } + else if (sel) { + //Listener is an nsIScriptEventListener so we need to use its CheckIfEqual + //method to verify equality. + nsCOMPtr regSel = do_QueryInterface(ls->mListener, &rv); + if (NS_SUCCEEDED(rv) && regSel) { + PRBool equal; + if (NS_SUCCEEDED(regSel->CheckIfEqual(sel, &equal)) && equal) { + if (ls->mFlags & aFlags && ls->mSubType & aSubType) { + NS_RELEASE(ls->mListener); + (*listeners)->RemoveElement((void*)ls); + PR_DELETE(ls); + } + } + } + } } return NS_OK; diff --git a/content/events/src/nsEventStateManager.cpp b/content/events/src/nsEventStateManager.cpp index e375a05482f..5b834fdd64f 100644 --- a/content/events/src/nsEventStateManager.cpp +++ b/content/events/src/nsEventStateManager.cpp @@ -40,6 +40,9 @@ #include "nsIDOMHTMLAreaElement.h" #include "nsIDOMHTMLButtonElement.h" #include "nsIDOMHTMLObjectElement.h" +#include "nsIDOMHTMLImageElement.h" +#include "nsIDOMHTMLMapElement.h" +#include "nsIHTMLDocument.h" #include "nsINameSpaceManager.h" // for kNameSpaceID_HTML #include "nsIWebShell.h" #include "nsIBaseWindow.h" @@ -590,7 +593,10 @@ nsEventStateManager::PreHandleEvent(nsIPresContext* aPresContext, //Alt key is down, we may need to do an accesskey if (mAccessKeys) { //Someone registered an accesskey. Find and activate it. - nsVoidKey key((void*)keyEvent->charCode); + nsAutoString accKey((char)keyEvent->charCode); + accKey.ToLowerCase(); + + nsVoidKey key((void*)accKey.First()); if (mAccessKeys->Exists(&key)) { nsCOMPtr content = getter_AddRefs(NS_STATIC_CAST(nsIContent*, mAccessKeys->Get(&key))); @@ -1467,9 +1473,8 @@ nsEventStateManager::GenerateMouseEnterExit(nsIPresContext* aPresContext, nsGUIE targetContent->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status); } - if (nsEventStatus_eConsumeNoDefault != status) { + if ( status != nsEventStatus_eConsumeNoDefault ) SetContentState(targetContent, NS_EVENT_STATE_HOVER); - } //Now dispatch to the frame if (mCurrentTarget) { @@ -1519,9 +1524,8 @@ nsEventStateManager::GenerateMouseEnterExit(nsIPresContext* aPresContext, nsGUIE if (mLastMouseOverContent) { mLastMouseOverContent->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status); - if (nsEventStatus_eConsumeNoDefault != status) { - SetContentState(nsnull, NS_EVENT_STATE_HOVER); - } + if ( status != nsEventStatus_eConsumeNoDefault ) + SetContentState(nsnull, NS_EVENT_STATE_HOVER); } @@ -1872,20 +1876,28 @@ nsEventStateManager::ShiftFocus(PRBool forward) if (mPresContext) { nsresult rv = mPresContext->GetShell(getter_AddRefs(shell)); if (NS_SUCCEEDED(rv) && shell){ - shell->GetPrimaryFrameFor(mCurrentFocus, &primaryFrame); + if (topOfDoc) { + primaryFrame = nsnull; + } + else { + shell->GetPrimaryFrameFor(mCurrentFocus, &primaryFrame); + } } } nsCOMPtr rootContent = getter_AddRefs(mDocument->GetRootContent()); nsCOMPtr next; + //Get the next tab item. This takes tabIndex into account GetNextTabbableContent(rootContent, primaryFrame, forward, getter_AddRefs(next)); + //Either no tabbable items or the end of the document if (!next) { PRBool focusTaken = PR_FALSE; SetContentState(nsnull, NS_EVENT_STATE_FOCUS); + //Offer focus upwards to allow shifting focus to UI controls nsCOMPtr container; mPresContext->GetContainer(getter_AddRefs(container)); nsCOMPtr docShellAsWin(do_QueryInterface(container)); @@ -1893,9 +1905,12 @@ nsEventStateManager::ShiftFocus(PRBool forward) docShellAsWin->FocusAvailable(docShellAsWin, &focusTaken); } + //No one took focus and we're not already at the top of the doc + //so calling ShiftFocus will start at the top of the doc again. if (!focusTaken && !topOfDoc) { ShiftFocus(forward); } + return; } @@ -1913,26 +1928,66 @@ nsEventStateManager::ShiftFocus(PRBool forward) NS_IF_ADDREF(mCurrentFocus); } -/* - * At some point this will need to be linked into HTML 4.0 tabindex - */ - NS_IMETHODIMP nsEventStateManager::GetNextTabbableContent(nsIContent* aRootContent, nsIFrame* aFrame, PRBool forward, nsIContent** aResult) { *aResult = nsnull; + PRBool keepFirstFrame = PR_FALSE; nsCOMPtr frameTraversal; + + if (!aFrame) { + //No frame means we need to start with the root content again. + nsCOMPtr presShell; + if (mPresContext) { + nsIFrame* result = nsnull; + if (NS_SUCCEEDED(mPresContext->GetShell(getter_AddRefs(presShell))) && presShell) { + presShell->GetPrimaryFrameFor(aRootContent, &result); + } + if (result) { + while(NS_SUCCEEDED(result->FirstChild(mPresContext, nsnull, &result)) && result) { + aFrame = result; + } + } + } + if (!aFrame) { + return NS_ERROR_FAILURE; + } + keepFirstFrame = PR_TRUE; + } + + //Need to do special check in case we're in an imagemap which has multiple content per frame + if (mCurrentFocus) { + nsCOMPtr tag; + mCurrentFocus->GetTag(*getter_AddRefs(tag)); + if(nsHTMLAtoms::area==tag.get()) { + //Focus is in an imagemap area + nsCOMPtr presShell; + if (mPresContext) { + nsIFrame* result = nsnull; + if (NS_SUCCEEDED(mPresContext->GetShell(getter_AddRefs(presShell))) && presShell) { + presShell->GetPrimaryFrameFor(mCurrentFocus, &result); + } + if (result == aFrame) { + //The current focus map area is in the current frame, don't skip over it. + keepFirstFrame = PR_TRUE; + } + } + } + } + nsresult result = NS_NewFrameTraversal(getter_AddRefs(frameTraversal), EXTENSIVE, mPresContext, aFrame); if (NS_FAILED(result)) return NS_OK; - if (forward) - frameTraversal->Next(); - else frameTraversal->Prev(); + if (!keepFirstFrame) { + if (forward) + frameTraversal->Next(); + else frameTraversal->Prev(); + } nsISupports* currentItem; frameTraversal->CurrentItem(¤tItem); @@ -2009,11 +2064,69 @@ nsEventStateManager::GetNextTabbableContent(nsIContent* aRootContent, nsIFrame* nextButton->GetDisabled(&disabled); } } - else if(nsHTMLAtoms::area==tag.get()) { - nsCOMPtr nextArea(do_QueryInterface(child)); - if (nextArea) - nextArea->GetTabIndex(&tabIndex); - disabled = PR_FALSE; + else if(nsHTMLAtoms::img==tag.get()) { + nsCOMPtr nextImage(do_QueryInterface(child)); + nsAutoString usemap; + if (nextImage) { + nextImage->GetAttribute(NS_ConvertASCIItoUCS2("usemap"), usemap); + if (usemap.Length()) { + //Image is an imagemap. We need to get its maps and walk its children. + usemap.StripWhitespace(); + + nsCOMPtr doc; + if (NS_SUCCEEDED(child->GetDocument(*getter_AddRefs(doc))) && doc) { + if (usemap.First() == '#') { + usemap.Cut(0, 1); + } + + nsCOMPtr hdoc(do_QueryInterface(doc)); + if (hdoc) { + nsCOMPtr hmap; + if (NS_SUCCEEDED(hdoc->GetImageMap(usemap, getter_AddRefs(hmap))) && hmap) { + nsCOMPtr map(do_QueryInterface(hmap)); + if (map) { + nsCOMPtr childArea; + PRInt32 count, index; + map->ChildCount(count); + //First see if mCurrentFocus is in this map + for (index = 0; index < count; index++) { + map->ChildAt(index, *getter_AddRefs(childArea)); + if (childArea.get() == mCurrentFocus) { + nsAutoString tabIndexStr; + childArea->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::tabindex, tabIndexStr); + PRInt32 ec, val = tabIndexStr.ToInteger(&ec); + if (NS_OK == ec && mCurrentTabIndex == val) { + //mCurrentFocus is in this map so we must start iterating past it. + //We skip the case where mCurrentFocus has the same tab index + //as mCurrentTabIndex since the next tab ordered element might + //be before it (or after for backwards) in the child list. + break; + } + } + } + PRInt32 increment = forward ? 1 : - 1; + PRInt32 start = index < count ? index + increment : (forward ? 0 : count - 1); + for (index = start; index < count && index >= 0; index += increment) { + //Iterate over the children. + map->ChildAt(index, *getter_AddRefs(childArea)); + + //Got the map area, check its tabindex. + nsAutoString tabIndexStr; + childArea->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::tabindex, tabIndexStr); + PRInt32 ec, val = tabIndexStr.ToInteger(&ec); + if (NS_OK == ec && mCurrentTabIndex == val) { + //tabindex == the current one, use it. + *aResult = childArea; + NS_IF_ADDREF(*aResult); + return NS_OK; + } + } + } + } + } + } + } + } } else if(nsHTMLAtoms::object==tag.get()) { nsCOMPtr nextObject(do_QueryInterface(child)); @@ -2061,7 +2174,7 @@ nsEventStateManager::GetNextTabbableContent(nsIContent* aRootContent, nsIFrame* } //else continue looking for next highest priority tab mCurrentTabIndex = GetNextTabIndex(aRootContent, forward); - return GetNextTabbableContent(aRootContent, aFrame, forward, aResult); + return GetNextTabbableContent(aRootContent, nsnull, forward, aResult); } PRInt32 @@ -2566,7 +2679,10 @@ nsEventStateManager::RegisterAccessKey(nsIFrame * aFrame, nsIContent* aContent, } if (content) { - nsVoidKey key((void*)aKey); + nsAutoString accKey((char)aKey); + accKey.ToLowerCase(); + + nsVoidKey key((void*)accKey.First()); mAccessKeys->Put(&key, content); } @@ -2589,7 +2705,10 @@ nsEventStateManager::UnregisterAccessKey(nsIFrame * aFrame, nsIContent* aContent content = aContent; } if (content) { - nsVoidKey key((void*)aKey); + nsAutoString accKey((char)aKey); + accKey.ToLowerCase(); + + nsVoidKey key((void*)accKey.First()); nsCOMPtr oldContent = getter_AddRefs(NS_STATIC_CAST(nsIContent*, mAccessKeys->Get(&key))); if (oldContent != content) { diff --git a/content/html/content/src/nsGenericHTMLElement.cpp b/content/html/content/src/nsGenericHTMLElement.cpp index 904a0026ab7..ae6d2adcad2 100644 --- a/content/html/content/src/nsGenericHTMLElement.cpp +++ b/content/html/content/src/nsGenericHTMLElement.cpp @@ -1178,7 +1178,10 @@ nsGenericHTMLElement::HandleDOMEventForAnchors(nsIContent* aOuter, stateManager->SetContentState(mContent, NS_EVENT_STATE_HOVER); NS_RELEASE(stateManager); } - + } + // Set the status bar the same for focus and mouseover + case NS_FOCUS_CONTENT: + { nsAutoString target; nsIURI* baseURL = nsnull; GetBaseURL(baseURL); diff --git a/content/html/content/src/nsHTMLAreaElement.cpp b/content/html/content/src/nsHTMLAreaElement.cpp index 5bf9b314b47..22b4903fddc 100644 --- a/content/html/content/src/nsHTMLAreaElement.cpp +++ b/content/html/content/src/nsHTMLAreaElement.cpp @@ -263,15 +263,17 @@ nsHTMLAreaElement::SetFocus(nsIPresContext* aPresContext) esm->SetContentState(this, NS_EVENT_STATE_FOCUS); NS_RELEASE(esm); } - - // XXX write me return NS_OK; } NS_IMETHODIMP nsHTMLAreaElement::RemoveFocus(nsIPresContext* aPresContext) { - // XXX write me + nsIEventStateManager* esm; + if (NS_OK == aPresContext->GetEventStateManager(&esm)) { + esm->SetContentState(nsnull, NS_EVENT_STATE_FOCUS); + NS_RELEASE(esm); + } return NS_OK; } diff --git a/content/html/content/src/nsHTMLImageElement.cpp b/content/html/content/src/nsHTMLImageElement.cpp index 1a87ddcdc3b..43b233c8a95 100644 --- a/content/html/content/src/nsHTMLImageElement.cpp +++ b/content/html/content/src/nsHTMLImageElement.cpp @@ -723,12 +723,19 @@ nsHTMLImageElement::SetProperty(JSContext *aContext, JSObject *aObj, jsval aID, } } } + else { + result = mInner.SetProperty(aContext, aObj, aID, aVp); + } } else { result = mInner.SetProperty(aContext, aObj, aID, aVp); } - return (result == NS_OK); + if (NS_FAILED(result)) { + return PR_FALSE; + } + + return PR_TRUE; } PRBool diff --git a/content/html/document/src/nsHTMLDocument.cpp b/content/html/document/src/nsHTMLDocument.cpp index 9c3ffa81847..a6abc13e0a4 100644 --- a/content/html/document/src/nsHTMLDocument.cpp +++ b/content/html/document/src/nsHTMLDocument.cpp @@ -1938,6 +1938,15 @@ nsHTMLDocument::OpenCommon(nsIURI* aSourceURL) result = NS_OpenURI(getter_AddRefs(channel), aSourceURL, nsnull, group); if (NS_FAILED(result)) return result; + + //Before we reset the doc notify the globalwindow of the change. + if (mScriptGlobalObject) { + //Hold onto ourselves on the offchance that we're down to one ref + nsCOMPtr kungFuDeathGrip (do_QueryInterface((nsIHTMLDocument*)this)); + result = mScriptGlobalObject->SetNewDocument(kungFuDeathGrip); + if (NS_FAILED(result)) return result; + } + result = Reset(channel, group); if (NS_FAILED(result)) return result; if (NS_OK == result) { diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index f1c7fa44575..fd9eb327200 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -1833,8 +1833,18 @@ NS_IMETHODIMP nsDocShell::FocusAvailable(nsIBaseWindow* aCurrentFocus, if(aCurrentFocus == NS_STATIC_CAST(nsIBaseWindow*, this)) { if(nextCallWin) - return nextCallWin->FocusAvailable(aCurrentFocus, aTookFocus); - return NS_OK; + { + nsresult ret = nextCallWin->FocusAvailable(aCurrentFocus, aTookFocus); + if (NS_SUCCEEDED(ret) && *aTookFocus) + return NS_OK; + } + + if (!mChildren.Count()) + { + //If we don't have children and our parent didn't want + //the focus then we should just stop now. + return NS_OK; + } } //Otherwise, check the chilren and offer it to the next sibling. @@ -1844,7 +1854,22 @@ NS_IMETHODIMP nsDocShell::FocusAvailable(nsIBaseWindow* aCurrentFocus, { nsCOMPtr child(do_QueryInterface((nsISupports*)mChildren.ElementAt(i))); - if(child.get() == aCurrentFocus) + //If we have focus we offer it to our first child. + if(aCurrentFocus == NS_STATIC_CAST(nsIBaseWindow*, this)) + { + if(NS_SUCCEEDED(child->SetFocus())) + { + *aTookFocus = PR_TRUE; + return NS_OK; + } + else + { + return NS_ERROR_FAILURE; + } + } + //If we don't have focus, find the child that does then + //offer focus to the next one. + if (child.get() == aCurrentFocus) { while(++i < n) { @@ -1854,12 +1879,18 @@ NS_IMETHODIMP nsDocShell::FocusAvailable(nsIBaseWindow* aCurrentFocus, *aTookFocus = PR_TRUE; return NS_OK; } + else + { + return NS_ERROR_FAILURE; + } } } } - if(nextCallWin) - return nextCallWin->FocusAvailable(aCurrentFocus, aTookFocus); - return NS_OK; + + //Reached the end of our child list. Call again to offer focus + //upwards and to start at the beginning of our child list if + //no one above us wants focus. + return FocusAvailable(this, aTookFocus); } NS_IMETHODIMP nsDocShell::GetTitle(PRUnichar** aTitle) diff --git a/editor/ui/composer/content/sb-bookmarks.js b/editor/ui/composer/content/sb-bookmarks.js index f4121e430a9..afe45deab1b 100644 --- a/editor/ui/composer/content/sb-bookmarks.js +++ b/editor/ui/composer/content/sb-bookmarks.js @@ -303,12 +303,12 @@ function CloseEditNode(saveChangeFlag) function EditNodeKeyPress(event) { - if (event.which == 27) + if (event.keyCode == 27) { CloseEditNode(false); return(false); } - else if (event.which == 13 || event.which == 10) + else if (event.keyCode == 13 || event.keyCode == 10) { CloseEditNode(true); return(false); diff --git a/editor/ui/composer/content/sb-file-panel.js b/editor/ui/composer/content/sb-file-panel.js index dd614b9bd51..0ddc4918fd7 100644 --- a/editor/ui/composer/content/sb-file-panel.js +++ b/editor/ui/composer/content/sb-file-panel.js @@ -331,12 +331,12 @@ function CloseEditNode(saveChangeFlag) function EditNodeKeyPress(event) { - if (event.which == 27) + if (event.keyCode == 27) { CloseEditNode(false); return(false); } - else if (event.which == 13 || event.which == 10) + else if (event.keyCode == 13 || event.keyCode == 10) { CloseEditNode(true); return(false); diff --git a/editor/ui/dialogs/content/EdAdvancedEdit.xul b/editor/ui/dialogs/content/EdAdvancedEdit.xul index c8a79874521..e99745f608e 100644 --- a/editor/ui/dialogs/content/EdAdvancedEdit.xul +++ b/editor/ui/dialogs/content/EdAdvancedEdit.xul @@ -105,9 +105,9 @@ <text value="&AddHTMLAttributeLabel.label;"/> - + - +