зеркало из https://github.com/mozilla/pjs.git
Bug 959: add support for accesskeys to XUL. r=hewitt, r=attinasi for changes to layout/html, sr=hyatt, a=asa
This commit is contained in:
Родитель
039def32af
Коммит
183bc5b700
|
@ -86,6 +86,7 @@
|
|||
#include "nsIFocusController.h"
|
||||
|
||||
#include "nsXULAtoms.h"
|
||||
#include "nsIDOMXULElement.h"
|
||||
#include "nsIDOMXULDocument.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIDocShell.h"
|
||||
|
@ -308,10 +309,10 @@ NS_IMPL_ISUPPORTS3(nsEventStateManager, nsIEventStateManager, nsIObserver, nsISu
|
|||
|
||||
NS_IMETHODIMP
|
||||
nsEventStateManager::PreHandleEvent(nsIPresContext* aPresContext,
|
||||
nsEvent *aEvent,
|
||||
nsIFrame* aTargetFrame,
|
||||
nsEventStatus* aStatus,
|
||||
nsIView* aView)
|
||||
nsEvent *aEvent,
|
||||
nsIFrame* aTargetFrame,
|
||||
nsEventStatus* aStatus,
|
||||
nsIView* aView)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aStatus);
|
||||
NS_ENSURE_ARG(aPresContext);
|
||||
|
@ -514,11 +515,11 @@ nsEventStateManager::PreHandleEvent(nsIPresContext* aPresContext,
|
|||
if (gLastFocusedContent) {
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
gLastFocusedContent->GetDocument(*getter_AddRefs(doc));
|
||||
if(doc)
|
||||
if(doc)
|
||||
doc->GetScriptGlobalObject(getter_AddRefs(ourGlobal));
|
||||
else {
|
||||
mDocument->GetScriptGlobalObject(getter_AddRefs(ourGlobal));
|
||||
NS_RELEASE(gLastFocusedContent);
|
||||
mDocument->GetScriptGlobalObject(getter_AddRefs(ourGlobal));
|
||||
NS_RELEASE(gLastFocusedContent);
|
||||
}
|
||||
}
|
||||
else mDocument->GetScriptGlobalObject(getter_AddRefs(ourGlobal));
|
||||
|
@ -606,7 +607,7 @@ nsEventStateManager::PreHandleEvent(nsIPresContext* aPresContext,
|
|||
focusController->SetActive(PR_TRUE);
|
||||
}
|
||||
|
||||
if (!focusedWindow) {
|
||||
if (!focusedWindow) {
|
||||
nsCOMPtr<nsIScriptGlobalObject> globalObject;
|
||||
mDocument->GetScriptGlobalObject(getter_AddRefs(globalObject));
|
||||
focusedWindow = do_QueryInterface(globalObject);
|
||||
|
@ -756,37 +757,131 @@ 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.
|
||||
nsAutoString accKey((char)keyEvent->charCode);
|
||||
ToLowerCase(accKey);
|
||||
PRUnichar accKey = nsCRT::ToLower((char)keyEvent->charCode);
|
||||
|
||||
nsVoidKey key((void*)accKey.First());
|
||||
nsVoidKey key((void*)accKey);
|
||||
if (mAccessKeys->Exists(&key)) {
|
||||
nsCOMPtr<nsIContent> content = getter_AddRefs(NS_STATIC_CAST(nsIContent*, mAccessKeys->Get(&key)));
|
||||
nsCOMPtr<nsIContent> content = dont_AddRef(NS_STATIC_CAST(nsIContent*, mAccessKeys->Get(&key)));
|
||||
|
||||
//Its hard to say what HTML4 wants us to do in all cases. So for now we'll settle for
|
||||
//A) Set focus
|
||||
ChangeFocus(content);
|
||||
PRBool isXUL = content->IsContentOfType(nsIContent::eXUL);
|
||||
|
||||
nsresult rv = getPrefService();
|
||||
PRBool activate = PR_TRUE;
|
||||
// if it's a XUL element...
|
||||
if (isXUL) {
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mPrefService->GetBoolPref("accessibility.accesskeycausesactivation", &activate);
|
||||
}
|
||||
// find out what type of content node this is
|
||||
nsCOMPtr<nsIAtom> atom;
|
||||
nsresult rv = content->GetTag(*getter_AddRefs(atom));
|
||||
if (NS_SUCCEEDED(rv) && atom) {
|
||||
if (atom == nsXULAtoms::label) {
|
||||
// If anything fails, this will be null ...
|
||||
nsCOMPtr<nsIDOMElement> element;
|
||||
|
||||
nsAutoString control;
|
||||
content->GetAttr(kNameSpaceID_None, nsXULAtoms::control, control);
|
||||
if (!control.IsEmpty()) {
|
||||
nsCOMPtr<nsIDocument> document;
|
||||
content->GetDocument(*getter_AddRefs(document));
|
||||
nsCOMPtr<nsIDOMDocument> domDocument = do_QueryInterface(document);
|
||||
if (domDocument)
|
||||
domDocument->GetElementById(control, getter_AddRefs(element));
|
||||
}
|
||||
// ... that here we'll either change |content| to the element
|
||||
// referenced by |element|, or clear it.
|
||||
content = do_QueryInterface(element);
|
||||
}
|
||||
}
|
||||
|
||||
if (!content)
|
||||
break;
|
||||
|
||||
nsCOMPtr<nsIPresShell> presShell;
|
||||
aPresContext->GetShell(getter_AddRefs(presShell));
|
||||
|
||||
nsIFrame* frame = nsnull;
|
||||
presShell->GetPrimaryFrameFor(content, &frame);
|
||||
|
||||
if (frame) {
|
||||
const nsStyleVisibility* vis;
|
||||
frame->GetStyleData(eStyleStruct_Visibility,
|
||||
((const nsStyleStruct *&)vis));
|
||||
PRBool viewShown = PR_TRUE;
|
||||
|
||||
nsIView* frameView = nsnull;
|
||||
frame->GetView(mPresContext, &frameView);
|
||||
|
||||
if (!frameView) {
|
||||
nsIFrame* parentWithView = nsnull;
|
||||
frame->GetParentWithView(mPresContext, &parentWithView);
|
||||
|
||||
if (parentWithView)
|
||||
parentWithView->GetView(mPresContext, &frameView);
|
||||
}
|
||||
|
||||
while (frameView) {
|
||||
nsViewVisibility visib;
|
||||
frameView->GetVisibility(visib);
|
||||
|
||||
if (visib == nsViewVisibility_kHide) {
|
||||
viewShown = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
frameView->GetParent(frameView);
|
||||
}
|
||||
|
||||
// get the XUL element
|
||||
nsCOMPtr<nsIDOMXULElement> element = do_QueryInterface(content);
|
||||
|
||||
// if collapsed or hidden, we don't get tabbed into.
|
||||
if (viewShown &&
|
||||
vis->mVisible != NS_STYLE_VISIBILITY_COLLAPSE &&
|
||||
vis->mVisible != NS_STYLE_VISIBILITY_HIDDEN &&
|
||||
element) {
|
||||
|
||||
// find out what type of content node this is
|
||||
nsCOMPtr<nsIAtom> atom;
|
||||
nsresult rv = content->GetTag(*getter_AddRefs(atom));
|
||||
|
||||
if (NS_SUCCEEDED(rv) && atom) {
|
||||
// define behavior for each type of XUL element:
|
||||
if (atom == nsXULAtoms::textbox) {
|
||||
// if it's a text box, give it focus
|
||||
element->Focus();
|
||||
} else {
|
||||
// otherwise, focus and click in it
|
||||
element->Focus();
|
||||
element->Click();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else { // otherwise, it must be HTML
|
||||
// It's hard to say what HTML4 wants us to do in all cases.
|
||||
// So for now we'll settle for A) Set focus
|
||||
ChangeFocus(content);
|
||||
|
||||
nsresult rv = getPrefService();
|
||||
PRBool activate = PR_TRUE;
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mPrefService->GetBoolPref("accessibility.accesskeycausesactivation", &activate);
|
||||
}
|
||||
|
||||
if (activate) {
|
||||
//B) Click on it if the users prefs indicate to do so.
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsMouseEvent event;
|
||||
event.eventStructType = NS_MOUSE_EVENT;
|
||||
event.message = NS_MOUSE_LEFT_CLICK;
|
||||
event.isShift = PR_FALSE;
|
||||
event.isControl = PR_FALSE;
|
||||
event.isAlt = PR_FALSE;
|
||||
event.isMeta = PR_FALSE;
|
||||
event.clickCount = 0;
|
||||
event.widget = nsnull;
|
||||
content->HandleDOMEvent(mPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
||||
}
|
||||
|
||||
if (activate) {
|
||||
//B) Click on it if the users prefs indicate to do so.
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsMouseEvent event;
|
||||
event.eventStructType = NS_MOUSE_EVENT;
|
||||
event.message = NS_MOUSE_LEFT_CLICK;
|
||||
event.isShift = PR_FALSE;
|
||||
event.isControl = PR_FALSE;
|
||||
event.isAlt = PR_FALSE;
|
||||
event.isMeta = PR_FALSE;
|
||||
event.clickCount = 0;
|
||||
event.widget = nsnull;
|
||||
content->HandleDOMEvent(mPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
||||
}
|
||||
|
||||
*aStatus = nsEventStatus_eConsumeNoDefault;
|
||||
|
@ -1754,8 +1849,8 @@ nsEventStateManager::PostHandleEvent(nsIPresContext* aPresContext,
|
|||
// force the update to happen now, otherwise multiple scrolls can
|
||||
// occur before the update is processed. (bug #7354)
|
||||
nsIViewManager* vm = nsnull;
|
||||
if (NS_OK == aView->GetViewManager(vm) && nsnull != vm) {
|
||||
// I'd use Composite here, but it doesn't always work.
|
||||
if (NS_OK == aView->GetViewManager(vm) && nsnull != vm) {
|
||||
// I'd use Composite here, but it doesn't always work.
|
||||
// vm->Composite();
|
||||
vm->ForceUpdate();
|
||||
NS_RELEASE(vm);
|
||||
|
@ -1774,8 +1869,8 @@ nsEventStateManager::PostHandleEvent(nsIPresContext* aPresContext,
|
|||
// force the update to happen now, otherwise multiple scrolls can
|
||||
// occur before the update is processed. (bug #7354)
|
||||
nsIViewManager* vm = nsnull;
|
||||
if (NS_OK == aView->GetViewManager(vm) && nsnull != vm) {
|
||||
// I'd use Composite here, but it doesn't always work.
|
||||
if (NS_OK == aView->GetViewManager(vm) && nsnull != vm) {
|
||||
// I'd use Composite here, but it doesn't always work.
|
||||
// vm->Composite();
|
||||
vm->ForceUpdate();
|
||||
NS_RELEASE(vm);
|
||||
|
@ -3147,11 +3242,11 @@ nsEventStateManager::GetEventTarget(nsIFrame **aFrame)
|
|||
}
|
||||
|
||||
if (!mCurrentTarget) {
|
||||
nsCOMPtr<nsIPresShell> presShell;
|
||||
mPresContext->GetShell(getter_AddRefs(presShell));
|
||||
if (presShell) {
|
||||
presShell->GetEventTargetFrame(&mCurrentTarget);
|
||||
}
|
||||
nsCOMPtr<nsIPresShell> presShell;
|
||||
mPresContext->GetShell(getter_AddRefs(presShell));
|
||||
if (presShell) {
|
||||
presShell->GetEventTargetFrame(&mCurrentTarget);
|
||||
}
|
||||
}
|
||||
|
||||
*aFrame = mCurrentTarget;
|
||||
|
@ -3176,11 +3271,11 @@ nsEventStateManager::GetEventTargetContent(nsEvent* aEvent, nsIContent** aConten
|
|||
}
|
||||
|
||||
if (!mCurrentTarget) {
|
||||
nsCOMPtr<nsIPresShell> presShell;
|
||||
mPresContext->GetShell(getter_AddRefs(presShell));
|
||||
if (presShell) {
|
||||
presShell->GetEventTargetFrame(&mCurrentTarget);
|
||||
}
|
||||
nsCOMPtr<nsIPresShell> presShell;
|
||||
mPresContext->GetShell(getter_AddRefs(presShell));
|
||||
if (presShell) {
|
||||
presShell->GetEventTargetFrame(&mCurrentTarget);
|
||||
}
|
||||
}
|
||||
|
||||
if (mCurrentTarget) {
|
||||
|
@ -3219,10 +3314,10 @@ nsEventStateManager::GetContentState(nsIContent *aContent, PRInt32& aState)
|
|||
nsCOMPtr<nsIContent> parent = mHoverContent;
|
||||
nsIContent* child;
|
||||
while (parent) {
|
||||
if (aContent == parent.get()) {
|
||||
aState |= NS_EVENT_STATE_HOVER;
|
||||
if (aContent == parent.get()) {
|
||||
aState |= NS_EVENT_STATE_HOVER;
|
||||
break;
|
||||
}
|
||||
}
|
||||
child = parent;
|
||||
child->GetParent(*getter_AddRefs(parent));
|
||||
}
|
||||
|
@ -3291,13 +3386,13 @@ nsEventStateManager::SetContentState(nsIContent *aContent, PRInt32 aState)
|
|||
while (parent1) {
|
||||
parent2 = aContent;
|
||||
while (parent2) {
|
||||
if (parent1 == parent2) {
|
||||
if (parent1 == parent2) {
|
||||
commonHoverParent = parent1;
|
||||
break;
|
||||
}
|
||||
nsIContent* child2 = parent2;
|
||||
child2->GetParent(*getter_AddRefs(parent2));
|
||||
}
|
||||
}
|
||||
if (commonHoverParent) {
|
||||
break;
|
||||
}
|
||||
|
@ -3564,7 +3659,7 @@ nsEventStateManager::SendFocusBlur(nsIPresContext* aPresContext, nsIContent *aCo
|
|||
if(newWindow)
|
||||
newWindow->GetRootFocusController(getter_AddRefs(newFocusController));
|
||||
if(oldWindow)
|
||||
oldWindow->GetRootFocusController(getter_AddRefs(oldFocusController));
|
||||
oldWindow->GetRootFocusController(getter_AddRefs(oldFocusController));
|
||||
if(oldFocusController && oldFocusController != newFocusController)
|
||||
oldFocusController->SetSuppressFocus(PR_TRUE, "SendFocusBlur Window Switch");
|
||||
}
|
||||
|
@ -3599,25 +3694,25 @@ nsEventStateManager::SendFocusBlur(nsIPresContext* aPresContext, nsIContent *aCo
|
|||
event.eventStructType = NS_EVENT;
|
||||
event.message = NS_BLUR_CONTENT;
|
||||
|
||||
// Make sure we're not switching command dispatchers, if so, surpress the blurred one
|
||||
if(mDocument) {
|
||||
nsCOMPtr<nsIFocusController> newFocusController;
|
||||
nsCOMPtr<nsIFocusController> oldFocusController;
|
||||
nsCOMPtr<nsPIDOMWindow> oldPIDOMWindow;
|
||||
nsCOMPtr<nsPIDOMWindow> newPIDOMWindow;
|
||||
nsCOMPtr<nsIScriptGlobalObject> oldGlobal;
|
||||
nsCOMPtr<nsIScriptGlobalObject> newGlobal;
|
||||
gLastFocusedDocument->GetScriptGlobalObject(getter_AddRefs(oldGlobal));
|
||||
mDocument->GetScriptGlobalObject(getter_AddRefs(newGlobal));
|
||||
nsCOMPtr<nsPIDOMWindow> newWindow = do_QueryInterface(newGlobal);
|
||||
nsCOMPtr<nsPIDOMWindow> oldWindow = do_QueryInterface(oldGlobal);
|
||||
// Make sure we're not switching command dispatchers, if so, surpress the blurred one
|
||||
if (mDocument) {
|
||||
nsCOMPtr<nsIFocusController> newFocusController;
|
||||
nsCOMPtr<nsIFocusController> oldFocusController;
|
||||
nsCOMPtr<nsPIDOMWindow> oldPIDOMWindow;
|
||||
nsCOMPtr<nsPIDOMWindow> newPIDOMWindow;
|
||||
nsCOMPtr<nsIScriptGlobalObject> oldGlobal;
|
||||
nsCOMPtr<nsIScriptGlobalObject> newGlobal;
|
||||
gLastFocusedDocument->GetScriptGlobalObject(getter_AddRefs(oldGlobal));
|
||||
mDocument->GetScriptGlobalObject(getter_AddRefs(newGlobal));
|
||||
nsCOMPtr<nsPIDOMWindow> newWindow = do_QueryInterface(newGlobal);
|
||||
nsCOMPtr<nsPIDOMWindow> oldWindow = do_QueryInterface(oldGlobal);
|
||||
|
||||
if (newWindow)
|
||||
newWindow->GetRootFocusController(getter_AddRefs(newFocusController));
|
||||
oldWindow->GetRootFocusController(getter_AddRefs(oldFocusController));
|
||||
if(oldFocusController && oldFocusController != newFocusController)
|
||||
oldFocusController->SetSuppressFocus(PR_TRUE, "SendFocusBlur Window Switch #2");
|
||||
}
|
||||
oldWindow->GetRootFocusController(getter_AddRefs(oldFocusController));
|
||||
if(oldFocusController && oldFocusController != newFocusController)
|
||||
oldFocusController->SetSuppressFocus(PR_TRUE, "SendFocusBlur Window Switch #2");
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIEventStateManager> esm;
|
||||
gLastFocusedPresContext->GetEventStateManager(getter_AddRefs(esm));
|
||||
|
@ -3701,11 +3796,11 @@ nsEventStateManager::SendFocusBlur(nsIPresContext* aPresContext, nsIContent *aCo
|
|||
while (nsnull != ancestor) {
|
||||
ancestor->GetWidget(window); // addrefs
|
||||
if (nsnull != window) {
|
||||
window->SetFocus();
|
||||
NS_RELEASE(window); // releases. Duh.
|
||||
break;
|
||||
}
|
||||
ancestor->GetParent(ancestor);
|
||||
window->SetFocus();
|
||||
NS_RELEASE(window); // releases. Duh.
|
||||
break;
|
||||
}
|
||||
ancestor->GetParent(ancestor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3783,11 +3878,14 @@ nsEventStateManager::RegisterAccessKey(nsIFrame * aFrame, nsIContent* aContent,
|
|||
}
|
||||
|
||||
if (content) {
|
||||
nsAutoString accKey((char)aKey);
|
||||
ToLowerCase(accKey);
|
||||
PRUnichar accKey = nsCRT::ToLower((char)aKey);
|
||||
|
||||
nsVoidKey key((void*)accKey.First());
|
||||
nsVoidKey key((void*)accKey);
|
||||
|
||||
#ifdef DEBUG_jag
|
||||
nsCOMPtr<nsIContent> oldContent = dont_AddRef(NS_STATIC_CAST(nsIContent*, mAccessKeys->Get(&key)));
|
||||
NS_ASSERTION(!oldContent, "Overwriting accesskey registration");
|
||||
#endif
|
||||
mAccessKeys->Put(&key, content);
|
||||
}
|
||||
|
||||
|
@ -3809,15 +3907,17 @@ nsEventStateManager::UnregisterAccessKey(nsIFrame * aFrame, nsIContent* aContent
|
|||
content = aContent;
|
||||
}
|
||||
if (content) {
|
||||
nsAutoString accKey((char)aKey);
|
||||
ToLowerCase(accKey);
|
||||
PRUnichar accKey = nsCRT::ToLower((char)aKey);
|
||||
|
||||
nsVoidKey key((void*)accKey.First());
|
||||
nsVoidKey key((void*)accKey);
|
||||
|
||||
nsCOMPtr<nsIContent> oldContent = getter_AddRefs(NS_STATIC_CAST(nsIContent*, mAccessKeys->Get(&key)));
|
||||
if (oldContent != content) {
|
||||
nsCOMPtr<nsIContent> oldContent = dont_AddRef(NS_STATIC_CAST(nsIContent*, mAccessKeys->Get(&key)));
|
||||
#ifdef DEBUG_jag
|
||||
NS_ASSERTION(oldContent == content, "Trying to unregister wrong content");
|
||||
#endif
|
||||
if (oldContent != content)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mAccessKeys->Remove(&key);
|
||||
}
|
||||
return NS_OK;
|
||||
|
|
|
@ -234,6 +234,7 @@ XUL_ATOM(editor, "editor")
|
|||
|
||||
//
|
||||
|
||||
XUL_ATOM(control, "control")
|
||||
XUL_ATOM(checkbox, "checkbox")
|
||||
XUL_ATOM(radio, "radio")
|
||||
XUL_ATOM(radiogroup, "radiogroup")
|
||||
|
|
|
@ -2528,6 +2528,45 @@ nsXULElement::NormalizeAttrString(const nsAReadableString& aStr,
|
|||
return nimgr->GetNodeInfo(aStr, nsnull, kNameSpaceID_None, aNodeInfo);
|
||||
}
|
||||
|
||||
void
|
||||
nsXULElement::UnregisterAccessKey(const nsAString& aOldValue)
|
||||
{
|
||||
// If someone changes the accesskey, unregister the old one
|
||||
//
|
||||
if (mDocument && !aOldValue.IsEmpty()) {
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
mDocument->GetShellAt(0, getter_AddRefs(shell));
|
||||
|
||||
if (shell) {
|
||||
PRBool validElement = PR_TRUE;
|
||||
|
||||
// find out what type of content node this is
|
||||
nsCOMPtr<nsIAtom> atom;
|
||||
nsresult rv = GetTag(*getter_AddRefs(atom));
|
||||
if (NS_SUCCEEDED(rv) && atom) {
|
||||
if (atom == nsXULAtoms::label) {
|
||||
// XXXjag a side-effect is that we filter out anonymous <label>s
|
||||
// in e.g. <menu>, <menuitem>, <button>. These <label>s inherit
|
||||
// |accesskey| and would otherwise register themselves, overwriting
|
||||
// the content we really meant to be registered.
|
||||
if (!HasAttr(kNameSpaceID_None, nsXULAtoms::control))
|
||||
validElement = PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (validElement) {
|
||||
nsCOMPtr<nsIPresContext> presContext;
|
||||
shell->GetPresContext(getter_AddRefs(presContext));
|
||||
|
||||
nsCOMPtr<nsIEventStateManager> esm;
|
||||
presContext->GetEventStateManager(getter_AddRefs(esm));
|
||||
|
||||
nsIContent* content = NS_STATIC_CAST(nsIContent*, this);
|
||||
esm->UnregisterAccessKey(nsnull, content, aOldValue.First());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// XXX attribute code swiped from nsGenericContainerElement
|
||||
// this class could probably just use nsGenericContainerElement
|
||||
|
@ -2640,6 +2679,12 @@ nsXULElement::SetAttr(nsINodeInfo* aNodeInfo,
|
|||
// Add popup and event listeners
|
||||
AddListenerFor(aNodeInfo, PR_TRUE);
|
||||
|
||||
// If the accesskey attribute changes, unregister it here.
|
||||
// It will be registered for the new value in the relevant frames.
|
||||
// Also see nsAreaFrame, nsBoxFrame and nsTextBoxFrame's AttributeChanged
|
||||
if (aNodeInfo->Equals(nsXULAtoms::accesskey, kNameSpaceID_None))
|
||||
UnregisterAccessKey(oldValue);
|
||||
|
||||
if (mDocument) {
|
||||
nsCOMPtr<nsIBindingManager> bindingManager;
|
||||
mDocument->GetBindingManager(getter_AddRefs(bindingManager));
|
||||
|
@ -2664,9 +2709,9 @@ nsXULElement::SetAttr(nsINodeInfo* aNodeInfo,
|
|||
|
||||
mutation.mAttrName = attrName;
|
||||
if (!oldValue.IsEmpty())
|
||||
mutation.mPrevAttrValue = getter_AddRefs(NS_NewAtom(oldValue));
|
||||
mutation.mPrevAttrValue = dont_AddRef(NS_NewAtom(oldValue));
|
||||
if (!aValue.IsEmpty())
|
||||
mutation.mNewAttrValue = getter_AddRefs(NS_NewAtom(aValue));
|
||||
mutation.mNewAttrValue = dont_AddRef(NS_NewAtom(aValue));
|
||||
if (modification)
|
||||
mutation.mAttrChange = nsIDOMMutationEvent::MODIFICATION;
|
||||
else
|
||||
|
@ -2889,6 +2934,12 @@ nsXULElement::UnsetAttr(PRInt32 aNameSpaceID,
|
|||
nsAutoString oldValue;
|
||||
attr->GetValue(oldValue);
|
||||
|
||||
// If the accesskey attribute is removed, unregister it here
|
||||
// Also see nsAreaFrame, nsBoxFrame and nsTextBoxFrame's AttributeChanged
|
||||
if (aNameSpaceID == kNameSpaceID_None &&
|
||||
(aName == nsXULAtoms::accesskey || aName == nsXULAtoms::control))
|
||||
UnregisterAccessKey(oldValue);
|
||||
|
||||
// Fire mutation listeners
|
||||
if (HasMutationListeners(NS_STATIC_CAST(nsIStyledContent*, this),
|
||||
NS_EVENT_BITS_MUTATION_ATTRMODIFIED)) {
|
||||
|
|
|
@ -618,6 +618,8 @@ protected:
|
|||
nsIControllers *Controllers() const { return mSlots ? mSlots->mControllers.get() : nsnull; }
|
||||
nsXULAttributes *Attributes() const { return mSlots ? mSlots->GetAttributes() : nsnull; }
|
||||
|
||||
void UnregisterAccessKey(const nsAString& aOldValue);
|
||||
|
||||
static nsIXBLService *gXBLService;
|
||||
};
|
||||
|
||||
|
|
|
@ -48,6 +48,12 @@
|
|||
#include "nsLayoutAtoms.h"
|
||||
#include "nsISizeOfHandler.h"
|
||||
|
||||
#ifdef INCLUDE_XUL
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsXULAtoms.h"
|
||||
#include "nsIEventStateManager.h"
|
||||
#endif
|
||||
|
||||
#undef NOISY_MAX_ELEMENT_SIZE
|
||||
#undef NOISY_FINAL_SIZE
|
||||
|
||||
|
@ -71,9 +77,118 @@ nsAreaFrame::nsAreaFrame()
|
|||
{
|
||||
}
|
||||
|
||||
#ifdef INCLUDE_XUL
|
||||
|
||||
// If you make changes to this function, check its counterparts
|
||||
// in nsBoxFrame and nsTextBoxFrame
|
||||
nsresult
|
||||
nsAreaFrame::RegUnregAccessKey(nsIPresContext* aPresContext,
|
||||
PRBool aDoReg)
|
||||
{
|
||||
// if we have no content, we can't do anything
|
||||
if (!mContent)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
PRBool isXUL = mContent->IsContentOfType(nsIContent::eXUL);
|
||||
if (!isXUL)
|
||||
return NS_OK;
|
||||
|
||||
// find out what type of element this is
|
||||
nsCOMPtr<nsIAtom> atom;
|
||||
nsresult rv = mContent->GetTag(*getter_AddRefs(atom));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
// only support accesskeys for the following elements
|
||||
if (atom != nsXULAtoms::label)
|
||||
return NS_OK;
|
||||
|
||||
// To filter out <label>s without a control attribute.
|
||||
// XXXjag a side-effect is that we filter out anonymous <label>s
|
||||
// in e.g. <menu>, <menuitem>, <button>. These <label>s inherit
|
||||
// |accesskey| and would otherwise register themselves, overwriting
|
||||
// the content we really meant to be registered.
|
||||
if (!mContent->HasAttr(kNameSpaceID_None, nsXULAtoms::control))
|
||||
return NS_OK;
|
||||
|
||||
nsAutoString accessKey;
|
||||
mContent->GetAttr(kNameSpaceID_None, nsXULAtoms::accesskey, accessKey);
|
||||
|
||||
if (accessKey.IsEmpty())
|
||||
return NS_OK;
|
||||
|
||||
// With a valid PresContext we can get the ESM
|
||||
// and register the access key
|
||||
nsCOMPtr<nsIEventStateManager> esm;
|
||||
aPresContext->GetEventStateManager(getter_AddRefs(esm));
|
||||
|
||||
rv = NS_OK;
|
||||
|
||||
if (esm) {
|
||||
PRUint32 key = accessKey.First();
|
||||
if (aDoReg)
|
||||
rv = esm->RegisterAccessKey(nsnull, mContent, key);
|
||||
else
|
||||
rv = esm->UnregisterAccessKey(nsnull, mContent, key);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// nsIFrame
|
||||
|
||||
#ifdef INCLUDE_XUL
|
||||
NS_IMETHODIMP
|
||||
nsAreaFrame::Init(nsIPresContext* aPresContext,
|
||||
nsIContent* aContent,
|
||||
nsIFrame* aParent,
|
||||
nsIStyleContext* aContext,
|
||||
nsIFrame* aPrevInFlow)
|
||||
{
|
||||
nsresult rv = nsBlockFrame::Init(aPresContext,
|
||||
aContent,
|
||||
aParent,
|
||||
aContext,
|
||||
aPrevInFlow);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
// register access key
|
||||
return RegUnregAccessKey(aPresContext, PR_TRUE);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAreaFrame::Destroy(nsIPresContext* aPresContext)
|
||||
{
|
||||
// unregister access key
|
||||
RegUnregAccessKey(aPresContext, PR_FALSE);
|
||||
|
||||
return nsBlockFrame::Destroy(aPresContext);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAreaFrame::AttributeChanged(nsIPresContext* aPresContext,
|
||||
nsIContent* aChild,
|
||||
PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
PRInt32 aModType,
|
||||
PRInt32 aHint)
|
||||
{
|
||||
nsresult rv = nsBlockFrame::AttributeChanged(aPresContext, aChild,
|
||||
aNameSpaceID, aAttribute,
|
||||
aModType, aHint);
|
||||
|
||||
// If the accesskey changed, register for the new value
|
||||
// The old value has been unregistered in nsXULElement::SetAttr
|
||||
if (aAttribute == nsXULAtoms::accesskey || aAttribute == nsXULAtoms::control)
|
||||
RegUnregAccessKey(aPresContext, PR_TRUE);
|
||||
|
||||
return rv;
|
||||
}
|
||||
#endif
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAreaFrame::GetFrameType(nsIAtom** aType) const
|
||||
{
|
||||
|
|
|
@ -58,6 +58,23 @@ public:
|
|||
|
||||
// nsIFrame
|
||||
|
||||
#ifdef INCLUDE_XUL
|
||||
NS_IMETHOD Init(nsIPresContext* aPresContext,
|
||||
nsIContent* aContent,
|
||||
nsIFrame* aParent,
|
||||
nsIStyleContext* aContext,
|
||||
nsIFrame* aPrevInFlow);
|
||||
|
||||
NS_IMETHOD Destroy(nsIPresContext* aPresContext);
|
||||
|
||||
NS_IMETHOD AttributeChanged(nsIPresContext* aPresContext,
|
||||
nsIContent* aChild,
|
||||
PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
PRInt32 aModType,
|
||||
PRInt32 aHint);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Get the "type" of the frame
|
||||
*
|
||||
|
@ -73,6 +90,10 @@ public:
|
|||
protected:
|
||||
nsAreaFrame();
|
||||
|
||||
#ifdef INCLUDE_XUL
|
||||
nsresult RegUnregAccessKey(nsIPresContext* aPresContext,
|
||||
PRBool aDoReg);
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif /* nsAreaFrame_h___ */
|
||||
|
|
|
@ -48,6 +48,12 @@
|
|||
#include "nsLayoutAtoms.h"
|
||||
#include "nsISizeOfHandler.h"
|
||||
|
||||
#ifdef INCLUDE_XUL
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsXULAtoms.h"
|
||||
#include "nsIEventStateManager.h"
|
||||
#endif
|
||||
|
||||
#undef NOISY_MAX_ELEMENT_SIZE
|
||||
#undef NOISY_FINAL_SIZE
|
||||
|
||||
|
@ -71,9 +77,118 @@ nsAreaFrame::nsAreaFrame()
|
|||
{
|
||||
}
|
||||
|
||||
#ifdef INCLUDE_XUL
|
||||
|
||||
// If you make changes to this function, check its counterparts
|
||||
// in nsBoxFrame and nsTextBoxFrame
|
||||
nsresult
|
||||
nsAreaFrame::RegUnregAccessKey(nsIPresContext* aPresContext,
|
||||
PRBool aDoReg)
|
||||
{
|
||||
// if we have no content, we can't do anything
|
||||
if (!mContent)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
PRBool isXUL = mContent->IsContentOfType(nsIContent::eXUL);
|
||||
if (!isXUL)
|
||||
return NS_OK;
|
||||
|
||||
// find out what type of element this is
|
||||
nsCOMPtr<nsIAtom> atom;
|
||||
nsresult rv = mContent->GetTag(*getter_AddRefs(atom));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
// only support accesskeys for the following elements
|
||||
if (atom != nsXULAtoms::label)
|
||||
return NS_OK;
|
||||
|
||||
// To filter out <label>s without a control attribute.
|
||||
// XXXjag a side-effect is that we filter out anonymous <label>s
|
||||
// in e.g. <menu>, <menuitem>, <button>. These <label>s inherit
|
||||
// |accesskey| and would otherwise register themselves, overwriting
|
||||
// the content we really meant to be registered.
|
||||
if (!mContent->HasAttr(kNameSpaceID_None, nsXULAtoms::control))
|
||||
return NS_OK;
|
||||
|
||||
nsAutoString accessKey;
|
||||
mContent->GetAttr(kNameSpaceID_None, nsXULAtoms::accesskey, accessKey);
|
||||
|
||||
if (accessKey.IsEmpty())
|
||||
return NS_OK;
|
||||
|
||||
// With a valid PresContext we can get the ESM
|
||||
// and register the access key
|
||||
nsCOMPtr<nsIEventStateManager> esm;
|
||||
aPresContext->GetEventStateManager(getter_AddRefs(esm));
|
||||
|
||||
rv = NS_OK;
|
||||
|
||||
if (esm) {
|
||||
PRUint32 key = accessKey.First();
|
||||
if (aDoReg)
|
||||
rv = esm->RegisterAccessKey(nsnull, mContent, key);
|
||||
else
|
||||
rv = esm->UnregisterAccessKey(nsnull, mContent, key);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// nsIFrame
|
||||
|
||||
#ifdef INCLUDE_XUL
|
||||
NS_IMETHODIMP
|
||||
nsAreaFrame::Init(nsIPresContext* aPresContext,
|
||||
nsIContent* aContent,
|
||||
nsIFrame* aParent,
|
||||
nsIStyleContext* aContext,
|
||||
nsIFrame* aPrevInFlow)
|
||||
{
|
||||
nsresult rv = nsBlockFrame::Init(aPresContext,
|
||||
aContent,
|
||||
aParent,
|
||||
aContext,
|
||||
aPrevInFlow);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
// register access key
|
||||
return RegUnregAccessKey(aPresContext, PR_TRUE);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAreaFrame::Destroy(nsIPresContext* aPresContext)
|
||||
{
|
||||
// unregister access key
|
||||
RegUnregAccessKey(aPresContext, PR_FALSE);
|
||||
|
||||
return nsBlockFrame::Destroy(aPresContext);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAreaFrame::AttributeChanged(nsIPresContext* aPresContext,
|
||||
nsIContent* aChild,
|
||||
PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
PRInt32 aModType,
|
||||
PRInt32 aHint)
|
||||
{
|
||||
nsresult rv = nsBlockFrame::AttributeChanged(aPresContext, aChild,
|
||||
aNameSpaceID, aAttribute,
|
||||
aModType, aHint);
|
||||
|
||||
// If the accesskey changed, register for the new value
|
||||
// The old value has been unregistered in nsXULElement::SetAttr
|
||||
if (aAttribute == nsXULAtoms::accesskey || aAttribute == nsXULAtoms::control)
|
||||
RegUnregAccessKey(aPresContext, PR_TRUE);
|
||||
|
||||
return rv;
|
||||
}
|
||||
#endif
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAreaFrame::GetFrameType(nsIAtom** aType) const
|
||||
{
|
||||
|
|
|
@ -58,6 +58,23 @@ public:
|
|||
|
||||
// nsIFrame
|
||||
|
||||
#ifdef INCLUDE_XUL
|
||||
NS_IMETHOD Init(nsIPresContext* aPresContext,
|
||||
nsIContent* aContent,
|
||||
nsIFrame* aParent,
|
||||
nsIStyleContext* aContext,
|
||||
nsIFrame* aPrevInFlow);
|
||||
|
||||
NS_IMETHOD Destroy(nsIPresContext* aPresContext);
|
||||
|
||||
NS_IMETHOD AttributeChanged(nsIPresContext* aPresContext,
|
||||
nsIContent* aChild,
|
||||
PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
PRInt32 aModType,
|
||||
PRInt32 aHint);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Get the "type" of the frame
|
||||
*
|
||||
|
@ -73,6 +90,10 @@ public:
|
|||
protected:
|
||||
nsAreaFrame();
|
||||
|
||||
#ifdef INCLUDE_XUL
|
||||
nsresult RegUnregAccessKey(nsIPresContext* aPresContext,
|
||||
PRBool aDoReg);
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif /* nsAreaFrame_h___ */
|
||||
|
|
|
@ -95,6 +95,9 @@
|
|||
#include "nsIScrollableView.h"
|
||||
#include "nsHTMLContainerFrame.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "nsIEventStateManager.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsITheme.h"
|
||||
|
||||
// Needed for Print Preview
|
||||
|
@ -391,6 +394,9 @@ nsBoxFrame::Init(nsIPresContext* aPresContext,
|
|||
|
||||
mInner->UpdateMouseThrough();
|
||||
|
||||
// register access key
|
||||
rv = RegUnregAccessKey(aPresContext, PR_TRUE);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -1219,6 +1225,9 @@ nsBoxFrame::Destroy(nsIPresContext* aPresContext)
|
|||
if (mState & NS_STATE_IS_ROOT)
|
||||
mInner->GetDebugPref(aPresContext);
|
||||
|
||||
// unregister access key
|
||||
RegUnregAccessKey(aPresContext, PR_FALSE);
|
||||
|
||||
SetLayoutManager(nsnull);
|
||||
|
||||
// recycle the Inner via the shell's arena.
|
||||
|
@ -1359,109 +1368,117 @@ nsBoxFrame::AppendFrames(nsIPresContext* aPresContext,
|
|||
|
||||
NS_IMETHODIMP
|
||||
nsBoxFrame::AttributeChanged(nsIPresContext* aPresContext,
|
||||
nsIContent* aChild,
|
||||
PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
PRInt32 aModType,
|
||||
PRInt32 aHint)
|
||||
nsIContent* aChild,
|
||||
PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
PRInt32 aModType,
|
||||
PRInt32 aHint)
|
||||
{
|
||||
nsresult rv = nsContainerFrame::AttributeChanged(aPresContext, aChild,
|
||||
aNameSpaceID, aAttribute, aModType, aHint);
|
||||
nsresult rv = nsContainerFrame::AttributeChanged(aPresContext, aChild,
|
||||
aNameSpaceID, aAttribute,
|
||||
aModType, aHint);
|
||||
|
||||
if (aAttribute == nsXULAtoms::mousethrough) {
|
||||
mInner->UpdateMouseThrough();
|
||||
}
|
||||
if (aAttribute == nsHTMLAtoms::width ||
|
||||
aAttribute == nsHTMLAtoms::height ||
|
||||
aAttribute == nsHTMLAtoms::align ||
|
||||
aAttribute == nsHTMLAtoms::valign ||
|
||||
aAttribute == nsHTMLAtoms::left ||
|
||||
aAttribute == nsHTMLAtoms::top ||
|
||||
aAttribute == nsXULAtoms::flex ||
|
||||
aAttribute == nsXULAtoms::orient ||
|
||||
aAttribute == nsXULAtoms::pack ||
|
||||
aAttribute == nsXULAtoms::dir ||
|
||||
aAttribute == nsXULAtoms::mousethrough ||
|
||||
aAttribute == nsXULAtoms::equalsize) {
|
||||
|
||||
if (aAttribute == nsXULAtoms::ordinal) {
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
aPresContext->GetShell(getter_AddRefs(shell));
|
||||
nsBoxLayoutState state(shell);
|
||||
|
||||
nsIBox* parent;
|
||||
GetParentBox(&parent);
|
||||
parent->RelayoutChildAtOrdinal(state, this);
|
||||
nsIFrame* parentFrame;
|
||||
parent->GetFrame(&parentFrame);
|
||||
nsBoxFrame* parentBoxFrame = (nsBoxFrame*) parentFrame;
|
||||
if (parentBoxFrame)
|
||||
parentBoxFrame->CheckFrameOrder();
|
||||
parent->MarkDirty(state);
|
||||
} else if (aAttribute == nsHTMLAtoms::width ||
|
||||
aAttribute == nsHTMLAtoms::height ||
|
||||
aAttribute == nsHTMLAtoms::align ||
|
||||
if (aAttribute == nsHTMLAtoms::align ||
|
||||
aAttribute == nsHTMLAtoms::valign ||
|
||||
aAttribute == nsHTMLAtoms::left ||
|
||||
aAttribute == nsHTMLAtoms::top ||
|
||||
aAttribute == nsXULAtoms::flex ||
|
||||
aAttribute == nsXULAtoms::orient ||
|
||||
aAttribute == nsXULAtoms::pack ||
|
||||
aAttribute == nsXULAtoms::dir ||
|
||||
aAttribute == nsXULAtoms::equalsize) {
|
||||
aAttribute == nsXULAtoms::orient ||
|
||||
aAttribute == nsXULAtoms::pack ||
|
||||
aAttribute == nsXULAtoms::dir ||
|
||||
aAttribute == nsXULAtoms::debug) {
|
||||
|
||||
if (aAttribute == nsXULAtoms::orient || aAttribute == nsXULAtoms::dir ||
|
||||
aAttribute == nsXULAtoms::debug || aAttribute == nsHTMLAtoms::align ||
|
||||
aAttribute == nsHTMLAtoms::valign || aAttribute == nsXULAtoms::pack) {
|
||||
mInner->mValign = nsBoxFrame::vAlign_Top;
|
||||
mInner->mHalign = nsBoxFrame::hAlign_Left;
|
||||
mInner->mValign = nsBoxFrame::vAlign_Top;
|
||||
mInner->mHalign = nsBoxFrame::hAlign_Left;
|
||||
|
||||
PRBool orient = PR_TRUE;
|
||||
GetInitialOrientation(orient);
|
||||
if (orient)
|
||||
mState |= NS_STATE_IS_HORIZONTAL;
|
||||
else
|
||||
mState &= ~NS_STATE_IS_HORIZONTAL;
|
||||
PRBool orient = PR_TRUE;
|
||||
GetInitialOrientation(orient);
|
||||
if (orient)
|
||||
mState |= NS_STATE_IS_HORIZONTAL;
|
||||
else
|
||||
mState &= ~NS_STATE_IS_HORIZONTAL;
|
||||
|
||||
PRBool normal = PR_TRUE;
|
||||
GetInitialDirection(normal);
|
||||
if (normal)
|
||||
mState |= NS_STATE_IS_DIRECTION_NORMAL;
|
||||
else
|
||||
mState &= ~NS_STATE_IS_DIRECTION_NORMAL;
|
||||
PRBool normal = PR_TRUE;
|
||||
GetInitialDirection(normal);
|
||||
if (normal)
|
||||
mState |= NS_STATE_IS_DIRECTION_NORMAL;
|
||||
else
|
||||
mState &= ~NS_STATE_IS_DIRECTION_NORMAL;
|
||||
|
||||
GetInitialVAlignment(mInner->mValign);
|
||||
GetInitialHAlignment(mInner->mHalign);
|
||||
|
||||
PRBool equalSize = PR_FALSE;
|
||||
GetInitialEqualSize(equalSize);
|
||||
if (equalSize)
|
||||
mState |= NS_STATE_EQUAL_SIZE;
|
||||
else
|
||||
mState &= ~NS_STATE_EQUAL_SIZE;
|
||||
|
||||
PRBool debug = mState & NS_STATE_SET_TO_DEBUG;
|
||||
PRBool debugSet = mInner->GetInitialDebug(debug);
|
||||
if (debugSet) {
|
||||
mState |= NS_STATE_DEBUG_WAS_SET;
|
||||
if (debug)
|
||||
mState |= NS_STATE_SET_TO_DEBUG;
|
||||
else
|
||||
mState &= ~NS_STATE_SET_TO_DEBUG;
|
||||
} else {
|
||||
mState &= ~NS_STATE_DEBUG_WAS_SET;
|
||||
}
|
||||
GetInitialVAlignment(mInner->mValign);
|
||||
GetInitialHAlignment(mInner->mHalign);
|
||||
|
||||
PRBool equalSize = PR_FALSE;
|
||||
GetInitialEqualSize(equalSize);
|
||||
if (equalSize)
|
||||
mState |= NS_STATE_EQUAL_SIZE;
|
||||
else
|
||||
mState &= ~NS_STATE_EQUAL_SIZE;
|
||||
|
||||
PRBool autostretch = mState & NS_STATE_AUTO_STRETCH;
|
||||
GetInitialAutoStretch(autostretch);
|
||||
if (autostretch)
|
||||
mState |= NS_STATE_AUTO_STRETCH;
|
||||
else
|
||||
mState &= ~NS_STATE_AUTO_STRETCH;
|
||||
}
|
||||
PRBool debug = mState & NS_STATE_SET_TO_DEBUG;
|
||||
PRBool debugSet = mInner->GetInitialDebug(debug);
|
||||
if (debugSet) {
|
||||
mState |= NS_STATE_DEBUG_WAS_SET;
|
||||
|
||||
if (aAttribute == nsHTMLAtoms::left || aAttribute == nsHTMLAtoms::top)
|
||||
mState &= ~NS_STATE_STACK_NOT_POSITIONED;
|
||||
if (debug)
|
||||
mState |= NS_STATE_SET_TO_DEBUG;
|
||||
else
|
||||
mState &= ~NS_STATE_SET_TO_DEBUG;
|
||||
} else {
|
||||
mState &= ~NS_STATE_DEBUG_WAS_SET;
|
||||
}
|
||||
|
||||
PRBool autostretch = mState & NS_STATE_AUTO_STRETCH;
|
||||
GetInitialAutoStretch(autostretch);
|
||||
if (autostretch)
|
||||
mState |= NS_STATE_AUTO_STRETCH;
|
||||
else
|
||||
mState &= ~NS_STATE_AUTO_STRETCH;
|
||||
}
|
||||
|
||||
|
||||
|
||||
else if (aAttribute == nsHTMLAtoms::left ||
|
||||
aAttribute == nsHTMLAtoms::top) {
|
||||
mState &= ~NS_STATE_STACK_NOT_POSITIONED;
|
||||
}
|
||||
else if (aAttribute == nsXULAtoms::mousethrough) {
|
||||
mInner->UpdateMouseThrough();
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
aPresContext->GetShell(getter_AddRefs(shell));
|
||||
nsBoxLayoutState state(aPresContext);
|
||||
MarkDirty(state);
|
||||
}
|
||||
else if (aAttribute == nsXULAtoms::ordinal) {
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
aPresContext->GetShell(getter_AddRefs(shell));
|
||||
nsBoxLayoutState state(shell);
|
||||
|
||||
nsIBox* parent;
|
||||
GetParentBox(&parent);
|
||||
parent->RelayoutChildAtOrdinal(state, this);
|
||||
nsIFrame* parentFrame;
|
||||
parent->GetFrame(&parentFrame);
|
||||
nsBoxFrame* parentBoxFrame = (nsBoxFrame*) parentFrame;
|
||||
if (parentBoxFrame)
|
||||
parentBoxFrame->CheckFrameOrder();
|
||||
parent->MarkDirty(state);
|
||||
}
|
||||
// If the accesskey changed, register for the new value
|
||||
// The old value has been unregistered in nsXULElement::SetAttr
|
||||
else if (aAttribute == nsXULAtoms::accesskey) {
|
||||
RegUnregAccessKey(aPresContext, PR_TRUE);
|
||||
}
|
||||
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -2801,4 +2818,52 @@ nsBoxFrame::CreateViewForFrame(nsIPresContext* aPresContext,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// If you make changes to this function, check its counterparts
|
||||
// in nsTextBoxFrame and nsAreaFrame
|
||||
nsresult
|
||||
nsBoxFrame::RegUnregAccessKey(nsIPresContext* aPresContext,
|
||||
PRBool aDoReg)
|
||||
{
|
||||
// if we have no content, we can't do anything
|
||||
if (!mContent)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// find out what type of element this is
|
||||
nsCOMPtr<nsIAtom> atom;
|
||||
nsresult rv = mContent->GetTag(*getter_AddRefs(atom));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
// only support accesskeys for the following elements
|
||||
if (atom != nsXULAtoms::button &&
|
||||
atom != nsXULAtoms::checkbox &&
|
||||
atom != nsXULAtoms::radio) {
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsAutoString accessKey;
|
||||
mContent->GetAttr(kNameSpaceID_None, nsXULAtoms::accesskey, accessKey);
|
||||
|
||||
if (accessKey.IsEmpty())
|
||||
return NS_OK;
|
||||
|
||||
// With a valid PresContext we can get the ESM
|
||||
// and register the access key
|
||||
nsCOMPtr<nsIEventStateManager> esm;
|
||||
aPresContext->GetEventStateManager(getter_AddRefs(esm));
|
||||
|
||||
rv = NS_OK;
|
||||
|
||||
if (esm) {
|
||||
PRUint32 key = accessKey.First();
|
||||
if (aDoReg)
|
||||
rv = esm->RegisterAccessKey(nsnull, mContent, key);
|
||||
else
|
||||
rv = esm->UnregisterAccessKey(nsnull, mContent, key);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -250,8 +250,11 @@ protected:
|
|||
nscoord mFlex;
|
||||
nscoord mAscent;
|
||||
|
||||
private:
|
||||
protected:
|
||||
nsresult RegUnregAccessKey(nsIPresContext* aPresContext,
|
||||
PRBool aDoReg);
|
||||
|
||||
private:
|
||||
friend class nsBoxFrameInner;
|
||||
friend class nsBoxDebug;
|
||||
nsBoxFrameInner* mInner;
|
||||
|
|
|
@ -60,6 +60,10 @@
|
|||
#include "nsIPref.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIEventStateManager.h"
|
||||
#include "nsITheme.h"
|
||||
#include "nsUnicharUtils.h"
|
||||
|
||||
|
@ -135,6 +139,11 @@ nsTextBoxFrame::AttributeChanged(nsIPresContext* aPresContext,
|
|||
Redraw(state);
|
||||
}
|
||||
|
||||
// If the accesskey changed, register for the new value
|
||||
// The old value has been unregistered in nsXULElement::SetAttr
|
||||
if (aAttribute == nsXULAtoms::accesskey || aAttribute == nsXULAtoms::control)
|
||||
RegUnregAccessKey(aPresContext, PR_TRUE);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -158,14 +167,28 @@ nsTextBoxFrame::Init(nsIPresContext* aPresContext,
|
|||
nsIStyleContext* aContext,
|
||||
nsIFrame* aPrevInFlow)
|
||||
{
|
||||
nsresult rv = nsLeafBoxFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
|
||||
nsresult rv = nsTextBoxFrameSuper::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
mState |= NS_STATE_NEED_LAYOUT;
|
||||
PRBool aResize;
|
||||
PRBool aRedraw;
|
||||
UpdateAttributes(aPresContext, nsnull, aResize, aRedraw); /* update all */
|
||||
|
||||
return rv;
|
||||
// register access key
|
||||
RegUnregAccessKey(aPresContext, PR_TRUE);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTextBoxFrame::Destroy(nsIPresContext* aPresContext)
|
||||
{
|
||||
// unregister access key
|
||||
RegUnregAccessKey(aPresContext, PR_FALSE);
|
||||
|
||||
return nsTextBoxFrameSuper::Destroy(aPresContext);
|
||||
}
|
||||
|
||||
PRBool
|
||||
|
@ -261,6 +284,7 @@ nsTextBoxFrame::UpdateAttributes(nsIPresContext* aPresContext,
|
|||
UpdateAccessTitle();
|
||||
aResize = PR_TRUE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -850,3 +874,49 @@ nsTextBoxFrame::GetFrameName(nsAString& aResult) const
|
|||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
// If you make changes to this function, check its counterparts
|
||||
// in nsBoxFrame and nsAreaFrame
|
||||
nsresult
|
||||
nsTextBoxFrame::RegUnregAccessKey(nsIPresContext* aPresContext,
|
||||
PRBool aDoReg)
|
||||
{
|
||||
// if we have no content, we can't do anything
|
||||
if (!mContent)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// check if we have a |control| attribute
|
||||
// do this check first because few elements have control attributes, and we
|
||||
// can weed out most of the elements quickly.
|
||||
|
||||
// XXXjag a side-effect is that we filter out anonymous <label>s
|
||||
// in e.g. <menu>, <menuitem>, <button>. These <label>s inherit
|
||||
// |accesskey| and would otherwise register themselves, overwriting
|
||||
// the content we really meant to be registered.
|
||||
if (!mContent->HasAttr(kNameSpaceID_None, nsXULAtoms::control))
|
||||
return NS_OK;
|
||||
|
||||
// see if we even have an access key
|
||||
nsAutoString accessKey;
|
||||
mContent->GetAttr(kNameSpaceID_None, nsXULAtoms::accesskey, accessKey);
|
||||
|
||||
if (accessKey.IsEmpty())
|
||||
return NS_OK;
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
// With a valid PresContext we can get the ESM
|
||||
// and (un)register the access key
|
||||
nsCOMPtr<nsIEventStateManager> esm;
|
||||
aPresContext->GetEventStateManager(getter_AddRefs(esm));
|
||||
|
||||
if (esm) {
|
||||
PRUint32 key = accessKey.First();
|
||||
if (aDoReg)
|
||||
rv = esm->RegisterAccessKey(nsnull, mContent, key);
|
||||
else
|
||||
rv = esm->UnregisterAccessKey(nsnull, mContent, key);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
|
|
@ -42,7 +42,8 @@
|
|||
|
||||
class nsAccessKeyInfo;
|
||||
|
||||
class nsTextBoxFrame : public nsLeafBoxFrame
|
||||
typedef nsLeafBoxFrame nsTextBoxFrameSuper;
|
||||
class nsTextBoxFrame : public nsTextBoxFrameSuper
|
||||
{
|
||||
public:
|
||||
|
||||
|
@ -63,6 +64,8 @@ public:
|
|||
nsIStyleContext* aContext,
|
||||
nsIFrame* asPrevInFlow);
|
||||
|
||||
NS_IMETHOD Destroy(nsIPresContext* aPresContext);
|
||||
|
||||
NS_IMETHOD AttributeChanged(nsIPresContext* aPresContext,
|
||||
nsIContent* aChild,
|
||||
PRInt32 aNameSpaceID,
|
||||
|
@ -118,6 +121,9 @@ protected:
|
|||
nsSize& aSize,
|
||||
nscoord& aAscent);
|
||||
|
||||
nsresult RegUnregAccessKey(nsIPresContext* aPresContext,
|
||||
PRBool aDoReg);
|
||||
|
||||
private:
|
||||
|
||||
PRBool AlwaysAppendAccessKey();
|
||||
|
@ -131,8 +137,10 @@ private:
|
|||
PRBool mNeedsRecalc;
|
||||
nsSize mTextSize;
|
||||
nscoord mAscent;
|
||||
|
||||
static PRBool gAlwaysAppendAccessKey;
|
||||
static PRBool gAccessKeyPrefInitialized;
|
||||
|
||||
}; // class nsTextBoxFrame
|
||||
|
||||
#endif /* nsTextBoxFrame_h___ */
|
||||
|
|
Загрузка…
Ссылка в новой задаче