look in associated command object while building for attribute changes and dispatching. rewrite to use nsIContent and atoms instead of nsIDOMNode and strings. r=saari/sr=sfraser. bug 71470

This commit is contained in:
pinkerton%netscape.com 2001-03-22 03:53:57 +00:00
Родитель ac07ded896
Коммит 7f51023c63
13 изменённых файлов: 843 добавлений и 1050 удалений

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -35,7 +35,6 @@
class nsIMenuBar; class nsIMenuBar;
class nsIMenuListener; class nsIMenuListener;
class nsIDOMElement;
// temporary hack to get apple menu -- sfraser, approved saari // temporary hack to get apple menu -- sfraser, approved saari
@ -68,14 +67,14 @@ public:
nsEventStatus MenuSelected(const nsMenuEvent & aMenuEvent); nsEventStatus MenuSelected(const nsMenuEvent & aMenuEvent);
nsEventStatus MenuDeselected(const nsMenuEvent & aMenuEvent); nsEventStatus MenuDeselected(const nsMenuEvent & aMenuEvent);
nsEventStatus MenuConstruct( const nsMenuEvent & aMenuEvent, nsIWidget * aParentWindow, nsEventStatus MenuConstruct( const nsMenuEvent & aMenuEvent, nsIWidget * aParentWindow,
void * menuNode, void * aWebShell); void* unused, void * aWebShell);
nsEventStatus MenuDestruct(const nsMenuEvent & aMenuEvent); nsEventStatus MenuDestruct(const nsMenuEvent & aMenuEvent);
nsEventStatus CheckRebuild(PRBool & aMenuEvent); nsEventStatus CheckRebuild(PRBool & aMenuEvent);
nsEventStatus SetRebuild(PRBool aMenuEvent); nsEventStatus SetRebuild(PRBool aMenuEvent);
// nsIMenu Methods // nsIMenu Methods
NS_IMETHOD Create ( nsISupports * aParent, const nsAReadableString &aLabel, const nsAReadableString &aAccessKey, NS_IMETHOD Create ( nsISupports * aParent, const nsAReadableString &aLabel, const nsAReadableString &aAccessKey,
nsIChangeManager* aManager, nsIWebShell* aShell, nsIDOMNode* aNode ) ; nsIChangeManager* aManager, nsIWebShell* aShell, nsIContent* aNode ) ;
NS_IMETHOD GetParent(nsISupports *&aParent); NS_IMETHOD GetParent(nsISupports *&aParent);
NS_IMETHOD GetLabel(nsString &aText); NS_IMETHOD GetLabel(nsString &aText);
NS_IMETHOD SetLabel(const nsAReadableString &aText); NS_IMETHOD SetLabel(const nsAReadableString &aText);
@ -92,7 +91,7 @@ public:
NS_IMETHOD SetNativeData(void* aData); NS_IMETHOD SetNativeData(void* aData);
NS_IMETHOD AddMenuListener(nsIMenuListener * aMenuListener); NS_IMETHOD AddMenuListener(nsIMenuListener * aMenuListener);
NS_IMETHOD RemoveMenuListener(nsIMenuListener * aMenuListener); NS_IMETHOD RemoveMenuListener(nsIMenuListener * aMenuListener);
NS_IMETHOD GetDOMNode(nsIDOMNode ** aMenuNode); NS_IMETHOD GetMenuContent(nsIContent ** aMenuNode);
NS_IMETHOD SetEnabled(PRBool aIsEnabled); NS_IMETHOD SetEnabled(PRBool aIsEnabled);
NS_IMETHOD GetEnabled(PRBool* aIsEnabled); NS_IMETHOD GetEnabled(PRBool* aIsEnabled);
NS_IMETHOD IsHelpMenu(PRBool* aIsEnabled); NS_IMETHOD IsHelpMenu(PRBool* aIsEnabled);
@ -114,11 +113,10 @@ protected:
PRUint32 mNumMenuItems; PRUint32 mNumMenuItems;
nsSupportsArray mMenuItemsArray; // array holds refs nsSupportsArray mMenuItemsArray; // array holds refs
nsIMenu* mMenuParent; // weak, my parent owns me nsISupports* mParent; // weak, my parent owns me
nsIMenuBar* mMenuBarParent;
nsIChangeManager* mManager; // weak ref, it will outlive us nsIChangeManager* mManager; // weak ref, it will outlive us
nsWeakPtr mWebShellWeakRef; // weak ref to webshell nsWeakPtr mWebShellWeakRef; // weak ref to webshell
nsCOMPtr<nsIDOMNode> mDOMNode; //strong ref nsCOMPtr<nsIContent> mMenuContent; // the |menu| tag, strong ref
nsCOMPtr<nsIMenuListener> mListener; nsCOMPtr<nsIMenuListener> mListener;
bool mConstructed; bool mConstructed;
@ -135,17 +133,16 @@ protected:
nsresult GetNextVisibleMenu(nsIMenu** outNextVisibleMenu); nsresult GetNextVisibleMenu(nsIMenu** outNextVisibleMenu);
// fetch the content node associated with the menupopup item // fetch the content node associated with the menupopup item
void GetMenuPopupElement ( nsIDOMNode** aResult ) ; void GetMenuPopupContent ( nsIContent** aResult ) ;
// fire handlers for oncreate/ondestroy // fire handlers for oncreate/ondestroy
PRBool OnDestroy() ; PRBool OnDestroy() ;
PRBool OnCreate() ; PRBool OnCreate() ;
void LoadMenuItem( nsIMenu * pParentMenu, nsIDOMElement * menuitemElement, void LoadMenuItem ( nsIMenu* pParentMenu, nsIContent* menuitemContent);
nsIDOMNode * menuitemNode, nsIWebShell * aWebShell); void LoadSubMenu( nsIMenu * pParentMenu, nsIContent* menuitemContent);
void LoadSubMenu( nsIMenu * pParentMenu, nsIDOMElement * menuElement, nsIDOMNode * menuNode);
nsEventStatus HelpMenuConstruct( const nsMenuEvent & aMenuEvent, nsIWidget* aParentWindow, nsEventStatus HelpMenuConstruct( const nsMenuEvent & aMenuEvent, nsIWidget* aParentWindow,
void* menuNode, void* aWebShell); void* unused, void* aWebShell);
MenuHandle NSStringNewMenu(short menuID, nsString& menuTitle); MenuHandle NSStringNewMenu(short menuID, nsString& menuTitle);

Просмотреть файл

@ -40,6 +40,8 @@
#include "nsIDocumentViewer.h" #include "nsIDocumentViewer.h"
#include "nsIDocumentObserver.h" #include "nsIDocumentObserver.h"
#include "nsWidgetAtoms.h"
#include "nsIDOMXULDocument.h" #include "nsIDOMXULDocument.h"
#include <Menus.h> #include <Menus.h>
@ -69,9 +71,7 @@ MenuHandle gLevel3HierMenu = nsnull;
MenuHandle gLevel4HierMenu = nsnull; MenuHandle gLevel4HierMenu = nsnull;
MenuHandle gLevel5HierMenu = nsnull; MenuHandle gLevel5HierMenu = nsnull;
#if !TARGET_CARBON
extern nsMenuStack gPreviousMenuStack; extern nsMenuStack gPreviousMenuStack;
#endif
extern PRInt16 gCurrentMenuDepth; extern PRInt16 gCurrentMenuDepth;
// #if APPLE_MENU_HACK // #if APPLE_MENU_HACK
@ -99,19 +99,16 @@ nsMenuBar::nsMenuBar()
{ {
gCurrentMenuDepth = 1; gCurrentMenuDepth = 1;
#if !TARGET_CARBON
nsPreviousMenuStackUnwind(nsnull, nsnull); nsPreviousMenuStackUnwind(nsnull, nsnull);
#endif
NS_INIT_REFCNT(); NS_INIT_REFCNT();
mNumMenus = 0; mNumMenus = 0;
mParent = nsnull; mParent = nsnull;
mIsMenuBarAdded = PR_FALSE; mIsMenuBarAdded = PR_FALSE;
mUnicodeTextRunConverter = nsnull; mUnicodeTextRunConverter = nsnull;
#if !TARGET_CARBON
MenuDefUPP mdef = NewMenuDefProc( nsDynamicMDEFMain ); MenuDefUPP mdef = NewMenuDefProc( nsDynamicMDEFMain );
InstallDefProc((short)nsMacResources::GetLocalResourceFile(), (ResType)'MDEF', (short)128, (Ptr) mdef ); InstallDefProc((short)nsMacResources::GetLocalResourceFile(), (ResType)'MDEF', (short)128, (Ptr) mdef );
#endif
mOriginalMacMBarHandle = nsnull; mOriginalMacMBarHandle = nsnull;
mMacMBarHandle = nsnull; mMacMBarHandle = nsnull;
@ -199,13 +196,9 @@ nsMenuBar::MenuSelected(const nsMenuEvent & aMenuEvent)
nsEventStatus eventStatus = nsEventStatus_eIgnore; nsEventStatus eventStatus = nsEventStatus_eIgnore;
nsCOMPtr<nsIMenuListener> menuListener; nsCOMPtr<nsIMenuListener> menuListener;
//((nsISupports*)mMenuVoidArray[i-1])->QueryInterface(NS_GET_IID(nsIMenuListener), (void**)&menuListener);
//printf("gPreviousMenuStack.Count() = %d \n", gPreviousMenuStack.Count());
#if !TARGET_CARBON
nsCOMPtr<nsIMenu> theMenu; nsCOMPtr<nsIMenu> theMenu;
gPreviousMenuStack.GetMenuAt(gPreviousMenuStack.Count() - 1, getter_AddRefs(theMenu)); gPreviousMenuStack.GetMenuAt(gPreviousMenuStack.Count() - 1, getter_AddRefs(theMenu));
menuListener = do_QueryInterface(theMenu); menuListener = do_QueryInterface(theMenu);
#endif
if (menuListener) { if (menuListener) {
//TODO: MenuSelected is the right thing to call... //TODO: MenuSelected is the right thing to call...
//eventStatus = menuListener->MenuSelected(aMenuEvent); //eventStatus = menuListener->MenuSelected(aMenuEvent);
@ -299,7 +292,8 @@ nsMenuBar::MenuConstruct( const nsMenuEvent & aMenuEvent, nsIWidget* aParentWind
void * menubarNode, void * aWebShell ) void * menubarNode, void * aWebShell )
{ {
mWebShellWeakRef = getter_AddRefs(NS_GetWeakReference(NS_STATIC_CAST(nsIWebShell*, aWebShell))); mWebShellWeakRef = getter_AddRefs(NS_GetWeakReference(NS_STATIC_CAST(nsIWebShell*, aWebShell)));
mDOMNode = NS_STATIC_CAST(nsIDOMNode*, menubarNode); // strong ref nsIDOMNode* aDOMNode = NS_STATIC_CAST(nsIDOMNode*, menubarNode);
mMenuBarContent = do_QueryInterface(aDOMNode); // strong ref
if(gFirstMenuBar) { if(gFirstMenuBar) {
gOriginalMenuBar = getter_AddRefs(NS_GetWeakReference((nsIMenuBar *)this)); gOriginalMenuBar = getter_AddRefs(NS_GetWeakReference((nsIMenuBar *)this));
@ -310,7 +304,6 @@ nsMenuBar::MenuConstruct( const nsMenuEvent & aMenuEvent, nsIWidget* aParentWind
MenuHandle macMenuHandle = ::NewMenu(2, "\psubmenu"); MenuHandle macMenuHandle = ::NewMenu(2, "\psubmenu");
if(macMenuHandle) { if(macMenuHandle) {
gLevel2HierMenu = macMenuHandle; gLevel2HierMenu = macMenuHandle;
#if !TARGET_CARBON
SInt8 state = ::HGetState((Handle)macMenuHandle); SInt8 state = ::HGetState((Handle)macMenuHandle);
::HLock((Handle)macMenuHandle); ::HLock((Handle)macMenuHandle);
gSystemMDEFHandle = (**macMenuHandle).menuProc; gSystemMDEFHandle = (**macMenuHandle).menuProc;
@ -318,14 +311,12 @@ nsMenuBar::MenuConstruct( const nsMenuEvent & aMenuEvent, nsIWidget* aParentWind
(**macMenuHandle).menuWidth = -1; (**macMenuHandle).menuWidth = -1;
(**macMenuHandle).menuHeight = -1; (**macMenuHandle).menuHeight = -1;
::HSetState((Handle)macMenuHandle, state); ::HSetState((Handle)macMenuHandle, state);
#endif
::InsertMenu(macMenuHandle, hierMenu); ::InsertMenu(macMenuHandle, hierMenu);
} }
macMenuHandle = ::NewMenu(3, "\psubmenu"); macMenuHandle = ::NewMenu(3, "\psubmenu");
if(macMenuHandle) { if(macMenuHandle) {
gLevel3HierMenu = macMenuHandle; gLevel3HierMenu = macMenuHandle;
#if !TARGET_CARBON
SInt8 state = ::HGetState((Handle)macMenuHandle); SInt8 state = ::HGetState((Handle)macMenuHandle);
::HLock((Handle)macMenuHandle); ::HLock((Handle)macMenuHandle);
gSystemMDEFHandle = (**macMenuHandle).menuProc; gSystemMDEFHandle = (**macMenuHandle).menuProc;
@ -333,14 +324,12 @@ nsMenuBar::MenuConstruct( const nsMenuEvent & aMenuEvent, nsIWidget* aParentWind
(**macMenuHandle).menuWidth = -1; (**macMenuHandle).menuWidth = -1;
(**macMenuHandle).menuHeight = -1; (**macMenuHandle).menuHeight = -1;
::HSetState((Handle)macMenuHandle, state); ::HSetState((Handle)macMenuHandle, state);
#endif
::InsertMenu(macMenuHandle, hierMenu); ::InsertMenu(macMenuHandle, hierMenu);
} }
macMenuHandle = ::NewMenu(4, "\psubmenu"); macMenuHandle = ::NewMenu(4, "\psubmenu");
if(macMenuHandle) { if(macMenuHandle) {
gLevel4HierMenu = macMenuHandle; gLevel4HierMenu = macMenuHandle;
#if !TARGET_CARBON
SInt8 state = ::HGetState((Handle)macMenuHandle); SInt8 state = ::HGetState((Handle)macMenuHandle);
::HLock((Handle)macMenuHandle); ::HLock((Handle)macMenuHandle);
gSystemMDEFHandle = (**macMenuHandle).menuProc; gSystemMDEFHandle = (**macMenuHandle).menuProc;
@ -348,14 +337,12 @@ nsMenuBar::MenuConstruct( const nsMenuEvent & aMenuEvent, nsIWidget* aParentWind
(**macMenuHandle).menuWidth = -1; (**macMenuHandle).menuWidth = -1;
(**macMenuHandle).menuHeight = -1; (**macMenuHandle).menuHeight = -1;
::HSetState((Handle)macMenuHandle, state); ::HSetState((Handle)macMenuHandle, state);
#endif
::InsertMenu(macMenuHandle, hierMenu); ::InsertMenu(macMenuHandle, hierMenu);
} }
macMenuHandle = ::NewMenu(5, "\psubmenu"); macMenuHandle = ::NewMenu(5, "\psubmenu");
if(macMenuHandle) { if(macMenuHandle) {
gLevel5HierMenu = macMenuHandle; gLevel5HierMenu = macMenuHandle;
#if !TARGET_CARBON
SInt8 state = ::HGetState((Handle)macMenuHandle); SInt8 state = ::HGetState((Handle)macMenuHandle);
::HLock((Handle)macMenuHandle); ::HLock((Handle)macMenuHandle);
gSystemMDEFHandle = (**macMenuHandle).menuProc; gSystemMDEFHandle = (**macMenuHandle).menuProc;
@ -363,7 +350,6 @@ nsMenuBar::MenuConstruct( const nsMenuEvent & aMenuEvent, nsIWidget* aParentWind
(**macMenuHandle).menuWidth = -1; (**macMenuHandle).menuWidth = -1;
(**macMenuHandle).menuHeight = -1; (**macMenuHandle).menuHeight = -1;
::HSetState((Handle)macMenuHandle, state); ::HSetState((Handle)macMenuHandle, state);
#endif
::InsertMenu(macMenuHandle, hierMenu); ::InsertMenu(macMenuHandle, hierMenu);
} }
} else { } else {
@ -382,43 +368,38 @@ nsMenuBar::MenuConstruct( const nsMenuEvent & aMenuEvent, nsIWidget* aParentWind
// set this as a nsMenuListener on aParentWindow // set this as a nsMenuListener on aParentWindow
aParentWindow->AddMenuListener((nsIMenuListener *)this); aParentWindow->AddMenuListener((nsIMenuListener *)this);
nsCOMPtr<nsIDOMNode> menuNode; PRInt32 count;
mDOMNode->GetFirstChild(getter_AddRefs(menuNode)); mMenuBarContent->ChildCount(count);
while (menuNode) for ( int i = 0; i < count; ++i ) {
{ nsCOMPtr<nsIContent> menu;
nsCOMPtr<nsIDOMElement> menuElement(do_QueryInterface(menuNode)); mMenuBarContent->ChildAt ( i, *getter_AddRefs(menu) );
if (menuElement) if ( menu ) {
{ nsCOMPtr<nsIAtom> tag;
nsAutoString menuNodeType; menu->GetTag ( *getter_AddRefs(tag) );
if (tag == nsWidgetAtoms::menu) {
nsAutoString menuName; nsAutoString menuName;
nsAutoString menuAccessKey(NS_LITERAL_STRING(" ")); nsAutoString menuAccessKey(NS_LITERAL_STRING(" "));
menu->GetAttribute(kNameSpaceID_None, nsWidgetAtoms::label, menuName);
menuElement->GetNodeName(menuNodeType); menu->GetAttribute(kNameSpaceID_None, nsWidgetAtoms::accesskey, menuAccessKey);
if (menuNodeType == NS_LITERAL_STRING("menu")) {
menuElement->GetAttribute(NS_LITERAL_STRING("label"), menuName);
menuElement->GetAttribute(NS_LITERAL_STRING("accesskey"), menuAccessKey);
// Don't create the whole menu yet, just add in the top level names // Don't create the whole menu yet, just add in the top level names
// Create nsMenu, the menubar will own it // Create nsMenu, the menubar will own it
nsCOMPtr<nsIMenu> pnsMenu ( do_CreateInstance(kMenuCID) ); nsCOMPtr<nsIMenu> pnsMenu ( do_CreateInstance(kMenuCID) );
if ( pnsMenu ) if ( pnsMenu ) {
{
pnsMenu->Create(NS_STATIC_CAST(nsIMenuBar*, this), menuName, menuAccessKey, pnsMenu->Create(NS_STATIC_CAST(nsIMenuBar*, this), menuName, menuAccessKey,
NS_STATIC_CAST(nsIChangeManager *, this), NS_STATIC_CAST(nsIChangeManager *, this),
NS_REINTERPRET_CAST(nsIWebShell*, aWebShell), menuNode); NS_REINTERPRET_CAST(nsIWebShell*, aWebShell), menu);
// Make nsMenu a child of nsMenuBar. nsMenuBar takes ownership // Make nsMenu a child of nsMenuBar. nsMenuBar takes ownership
AddMenu(pnsMenu); AddMenu(pnsMenu);
nsAutoString menuIDstring; nsAutoString menuIDstring;
menuElement->GetAttribute(NS_LITERAL_STRING("id"), menuIDstring); menu->GetAttribute(kNameSpaceID_None, nsWidgetAtoms::id, menuIDstring);
if(menuIDstring == NS_LITERAL_STRING("menu_Help")) { if ( menuIDstring == NS_LITERAL_STRING("menu_Help") ) {
nsMenuEvent event; nsMenuEvent event;
MenuHandle handle = nsnull; MenuHandle handle = nsnull;
#if !(defined(RHAPSODY) || defined(TARGET_CARBON))
::HMGetHelpMenuHandle(&handle); ::HMGetHelpMenuHandle(&handle);
#endif
event.mCommand = (unsigned int) handle; event.mCommand = (unsigned int) handle;
nsCOMPtr<nsIMenuListener> listener(do_QueryInterface(pnsMenu)); nsCOMPtr<nsIMenuListener> listener(do_QueryInterface(pnsMenu));
listener->MenuSelected(event); listener->MenuSelected(event);
@ -426,18 +407,14 @@ nsMenuBar::MenuConstruct( const nsMenuEvent & aMenuEvent, nsIWidget* aParentWind
} }
} }
} }
nsCOMPtr<nsIDOMNode> tempNode = menuNode; } // for each menu
tempNode->GetNextSibling(getter_AddRefs(menuNode));
} // end while (nsnull != menuNode)
// Give the aParentWindow this nsMenuBar to hold onto. // Give the aParentWindow this nsMenuBar to hold onto.
// The parent takes ownership // The parent takes ownership
aParentWindow->SetMenuBar(this); aParentWindow->SetMenuBar(this);
#ifdef XP_MAC
Handle tempMenuBar = ::GetMenuBar(); // Get a copy of the menu list Handle tempMenuBar = ::GetMenuBar(); // Get a copy of the menu list
SetNativeData((void*)tempMenuBar); SetNativeData((void*)tempMenuBar);
#endif
return nsEventStatus_eIgnore; return nsEventStatus_eIgnore;
} }
@ -493,20 +470,23 @@ NS_METHOD nsMenuBar::AddMenu(nsIMenu * aMenu)
if (appleMenu) if (appleMenu)
{ {
// this code reads the "label" attribute from the <menuitem/> with // this code reads the "label" attribute from the <menuitem/> with
// id="aboutName" and puts its value in the Apple Menu // id="aboutName" and puts its label in the Apple Menu
nsAutoString label; nsAutoString label;
nsCOMPtr<nsIDOMNode> domNode; nsCOMPtr<nsIContent> menu;
aMenu->GetDOMNode(getter_AddRefs(domNode)); aMenu->GetMenuContent(getter_AddRefs(menu));
if (domNode) { if (menu) {
nsCOMPtr<nsIDOMDocument> domDoc; nsCOMPtr<nsIDocument> doc;
domNode->GetOwnerDocument(getter_AddRefs(domDoc)); menu->GetDocument(*getter_AddRefs(doc));
if (domDoc) { if (doc) {
nsCOMPtr<nsIDOMDocument> domdoc ( do_QueryInterface(doc) );
if ( domdoc ) {
nsCOMPtr<nsIDOMElement> aboutMenuItem; nsCOMPtr<nsIDOMElement> aboutMenuItem;
domDoc->GetElementById(NS_LITERAL_STRING("aboutName"), getter_AddRefs(aboutMenuItem)); domdoc->GetElementById(NS_LITERAL_STRING("aboutName"), getter_AddRefs(aboutMenuItem));
if (aboutMenuItem) if (aboutMenuItem)
aboutMenuItem->GetAttribute(NS_LITERAL_STRING("label"), label); aboutMenuItem->GetAttribute(NS_LITERAL_STRING("label"), label);
} }
} }
}
::AppendMenu(appleMenu, "\pa"); ::AppendMenu(appleMenu, "\pa");
MenuHelpers::SetMenuItemText(appleMenu, 1, label, mUnicodeTextRunConverter); MenuHelpers::SetMenuItemText(appleMenu, 1, label, mUnicodeTextRunConverter);
@ -524,11 +504,10 @@ NS_METHOD nsMenuBar::AddMenu(nsIMenu * aMenu)
PRBool helpMenu; PRBool helpMenu;
aMenu->IsHelpMenu(&helpMenu); aMenu->IsHelpMenu(&helpMenu);
if(!helpMenu) { if(!helpMenu) {
nsCOMPtr<nsIDOMNode> domNode; nsCOMPtr<nsIContent> menu;
aMenu->GetDOMNode(getter_AddRefs(domNode)); aMenu->GetMenuContent(getter_AddRefs(menu));
nsCOMPtr<nsIDOMElement> domElement = do_QueryInterface(domNode);
nsAutoString menuHidden; nsAutoString menuHidden;
domElement->GetAttribute(NS_LITERAL_STRING("hidden"), menuHidden); menu->GetAttribute(kNameSpaceID_None, nsWidgetAtoms::hidden, menuHidden);
if( menuHidden != NS_LITERAL_STRING("true")) if( menuHidden != NS_LITERAL_STRING("true"))
::InsertMenu(menuHandle, 0); ::InsertMenu(menuHandle, 0);
} }
@ -615,10 +594,9 @@ NS_METHOD nsMenuBar::Paint()
if (isHelpMenu) if (isHelpMenu)
{ {
MenuHandle helpMenuHandle = nil; MenuHandle helpMenuHandle = nil;
#if !TARGET_CARBON
::HMGetHelpMenuHandle(&helpMenuHandle); ::HMGetHelpMenuHandle(&helpMenuHandle);
menu->SetNativeData((void*)helpMenuHandle); menu->SetNativeData((void*)helpMenuHandle);
#endif
nsMenuEvent event; nsMenuEvent event;
event.mCommand = (unsigned int) helpMenuHandle; event.mCommand = (unsigned int) helpMenuHandle;
nsCOMPtr<nsIMenuListener> listener = do_QueryInterface(menu); nsCOMPtr<nsIMenuListener> listener = do_QueryInterface(menu);
@ -725,8 +703,7 @@ NS_IMETHODIMP
nsMenuBar::ContentAppended( nsIDocument * aDocument, nsIContent * aContainer, nsMenuBar::ContentAppended( nsIDocument * aDocument, nsIContent * aContainer,
PRInt32 aNewIndexInContainer) PRInt32 aNewIndexInContainer)
{ {
nsCOMPtr<nsIContent> me ( do_QueryInterface(mDOMNode) ); if ( aContainer == mMenuBarContent ) {
if ( aContainer == me.get() ) {
//Register(aContainer, ); //Register(aContainer, );
//InsertMenu ( aNewIndexInContainer ); //InsertMenu ( aNewIndexInContainer );
} }
@ -819,8 +796,7 @@ NS_IMETHODIMP
nsMenuBar::ContentRemoved( nsIDocument * aDocument, nsIContent * aContainer, nsMenuBar::ContentRemoved( nsIDocument * aDocument, nsIContent * aContainer,
nsIContent * aChild, PRInt32 aIndexInContainer ) nsIContent * aChild, PRInt32 aIndexInContainer )
{ {
nsCOMPtr<nsIContent> me ( do_QueryInterface(mDOMNode) ); if ( aContainer == mMenuBarContent ) {
if ( aContainer == me.get() ) {
Unregister(aChild); Unregister(aChild);
RemoveMenu ( aIndexInContainer ); RemoveMenu ( aIndexInContainer );
} }
@ -846,8 +822,7 @@ NS_IMETHODIMP
nsMenuBar::ContentInserted( nsIDocument * aDocument, nsIContent * aContainer, nsMenuBar::ContentInserted( nsIDocument * aDocument, nsIContent * aContainer,
nsIContent * aChild, PRInt32 aIndexInContainer ) nsIContent * aChild, PRInt32 aIndexInContainer )
{ {
nsCOMPtr<nsIContent> me ( do_QueryInterface(mDOMNode) ); if ( aContainer == mMenuBarContent ) {
if ( aContainer == me.get() ) {
//Register(aChild, ); //Register(aChild, );
//InsertMenu ( aIndexInContainer ); //InsertMenu ( aIndexInContainer );
} }

Просмотреть файл

@ -82,7 +82,7 @@ public:
nsEventStatus MenuSelected(const nsMenuEvent & aMenuEvent); nsEventStatus MenuSelected(const nsMenuEvent & aMenuEvent);
nsEventStatus MenuDeselected(const nsMenuEvent & aMenuEvent); nsEventStatus MenuDeselected(const nsMenuEvent & aMenuEvent);
nsEventStatus MenuConstruct( const nsMenuEvent & aMenuEvent, nsIWidget * aParentWindow, nsEventStatus MenuConstruct( const nsMenuEvent & aMenuEvent, nsIWidget * aParentWindow,
void * menuNode, void * aWebShell); void* aDOMNode, void * aWebShell);
nsEventStatus MenuDestruct(const nsMenuEvent & aMenuEvent); nsEventStatus MenuDestruct(const nsMenuEvent & aMenuEvent);
nsEventStatus CheckRebuild(PRBool & aMenuEvent); nsEventStatus CheckRebuild(PRBool & aMenuEvent);
nsEventStatus SetRebuild(PRBool aMenuEvent); nsEventStatus SetRebuild(PRBool aMenuEvent);
@ -164,7 +164,7 @@ protected:
PRUint32 mNumMenus; PRUint32 mNumMenus;
nsSupportsArray mMenusArray; // holds refs nsSupportsArray mMenusArray; // holds refs
nsCOMPtr<nsIDOMNode> mDOMNode; nsCOMPtr<nsIContent> mMenuBarContent; // menubar content node, strong ref
nsIWidget * mParent; // weak ref nsIWidget * mParent; // weak ref
PRBool mIsMenuBarAdded; PRBool mIsMenuBarAdded;

Просмотреть файл

@ -42,6 +42,7 @@
#include "nsIDocumentObserver.h" #include "nsIDocumentObserver.h"
#include "nsIDOMXULDocument.h" #include "nsIDOMXULDocument.h"
#include "nsWidgetAtoms.h"
#include <Menus.h> #include <Menus.h>
#include <TextUtils.h> #include <TextUtils.h>
@ -243,19 +244,19 @@ nsMenuBarX::MenuConstruct( const nsMenuEvent & aMenuEvent, nsIWidget* aParentWin
// set this as a nsMenuListener on aParentWindow // set this as a nsMenuListener on aParentWindow
aParentWindow->AddMenuListener((nsIMenuListener *)this); aParentWindow->AddMenuListener((nsIMenuListener *)this);
nsCOMPtr<nsIDOMNode> menuNode; PRInt32 count;
mDOMNode->GetFirstChild(getter_AddRefs(menuNode)); mMenuBarContent->ChildCount(count);
while (menuNode) { for ( int i = 0; i < count; ++i ) {
nsCOMPtr<nsIDOMElement> menuElement(do_QueryInterface(menuNode)); nsCOMPtr<nsIContent> menu;
if (menuElement) { mMenuBarContent->ChildAt ( i, *getter_AddRefs(menu) );
nsAutoString menuNodeType; if ( menu ) {
nsCOMPtr<nsIAtom> tag;
menu->GetTag ( *getter_AddRefs(tag) );
if (tag == nsWidgetAtoms::menu) {
nsAutoString menuName; nsAutoString menuName;
nsAutoString menuAccessKey; menuAccessKey.AssignWithConversion(" "); nsAutoString menuAccessKey(NS_LITERAL_STRING(" "));
menu->GetAttribute(kNameSpaceID_None, nsWidgetAtoms::label, menuName);
menuElement->GetNodeName(menuNodeType); menu->GetAttribute(kNameSpaceID_None, nsWidgetAtoms::accesskey, menuAccessKey);
if (menuNodeType == NS_LITERAL_STRING("menu")) {
menuElement->GetAttribute(NS_LITERAL_STRING("label"), menuName);
menuElement->GetAttribute(NS_LITERAL_STRING("accesskey"), menuAccessKey);
// Don't create the whole menu yet, just add in the top level names // Don't create the whole menu yet, just add in the top level names
@ -264,19 +265,17 @@ nsMenuBarX::MenuConstruct( const nsMenuEvent & aMenuEvent, nsIWidget* aParentWin
if ( pnsMenu ) { if ( pnsMenu ) {
pnsMenu->Create(NS_STATIC_CAST(nsIMenuBar*, this), menuName, menuAccessKey, pnsMenu->Create(NS_STATIC_CAST(nsIMenuBar*, this), menuName, menuAccessKey,
NS_STATIC_CAST(nsIChangeManager *, this), NS_STATIC_CAST(nsIChangeManager *, this),
NS_REINTERPRET_CAST(nsIWebShell*, aWebShell), menuNode); NS_REINTERPRET_CAST(nsIWebShell*, aWebShell), menu);
// Make nsMenu a child of nsMenuBarX. nsMenuBarX takes ownership // Make nsMenu a child of nsMenuBar. nsMenuBar takes ownership
AddMenu(pnsMenu); AddMenu(pnsMenu);
nsAutoString menuIDstring; nsAutoString menuIDstring;
menuElement->GetAttribute(NS_LITERAL_STRING("id"), menuIDstring); menu->GetAttribute(kNameSpaceID_None, nsWidgetAtoms::id, menuIDstring);
if (menuIDstring == NS_LITERAL_STRING("menu_Help")) { if ( menuIDstring == NS_LITERAL_STRING("menu_Help") ) {
nsMenuEvent event; nsMenuEvent event;
MenuHandle handle = nsnull; MenuHandle handle = nsnull;
#if !(defined(RHAPSODY) || defined(TARGET_CARBON))
::HMGetHelpMenuHandle(&handle); ::HMGetHelpMenuHandle(&handle);
#endif
event.mCommand = (unsigned int) handle; event.mCommand = (unsigned int) handle;
nsCOMPtr<nsIMenuListener> listener(do_QueryInterface(pnsMenu)); nsCOMPtr<nsIMenuListener> listener(do_QueryInterface(pnsMenu));
listener->MenuSelected(event); listener->MenuSelected(event);
@ -284,9 +283,7 @@ nsMenuBarX::MenuConstruct( const nsMenuEvent & aMenuEvent, nsIWidget* aParentWin
} }
} }
} }
nsCOMPtr<nsIDOMNode> tempNode = menuNode; } // for each menu
tempNode->GetNextSibling(getter_AddRefs(menuNode));
} // end while (nsnull != menuNode)
// Give the aParentWindow this nsMenuBarX to hold onto. // Give the aParentWindow this nsMenuBarX to hold onto.
// The parent takes ownership // The parent takes ownership
@ -342,12 +339,11 @@ NS_METHOD nsMenuBarX::AddMenu(nsIMenu * aMenu)
PRBool helpMenu; PRBool helpMenu;
aMenu->IsHelpMenu(&helpMenu); aMenu->IsHelpMenu(&helpMenu);
if(!helpMenu) { if(!helpMenu) {
nsCOMPtr<nsIDOMNode> domNode; nsCOMPtr<nsIContent> menu;
aMenu->GetDOMNode(getter_AddRefs(domNode)); aMenu->GetMenuContent(getter_AddRefs(menu));
nsCOMPtr<nsIDOMElement> domElement = do_QueryInterface(domNode);
nsAutoString menuHidden; nsAutoString menuHidden;
domElement->GetAttribute(NS_LITERAL_STRING("hidden"), menuHidden); menu->GetAttribute(kNameSpaceID_None, nsWidgetAtoms::hidden, menuHidden);
if (menuHidden != NS_LITERAL_STRING("true")) { if( menuHidden != NS_LITERAL_STRING("true"))
Str255 title; Str255 title;
::InsertMenuItem(mRootMenu, ::GetMenuTitle(menuRef, title), mNumMenus); ::InsertMenuItem(mRootMenu, ::GetMenuTitle(menuRef, title), mNumMenus);
OSStatus status = ::SetMenuItemHierarchicalMenu(mRootMenu, mNumMenus, menuRef); OSStatus status = ::SetMenuItemHierarchicalMenu(mRootMenu, mNumMenus, menuRef);

Просмотреть файл

@ -162,7 +162,7 @@ protected:
PRUint32 mNumMenus; PRUint32 mNumMenus;
nsSupportsArray mMenusArray; // holds refs nsSupportsArray mMenusArray; // holds refs
nsCOMPtr<nsIDOMNode> mDOMNode; nsCOMPtr<nsIContent> mMenuBarContent; // menubar content node, strong ref
nsIWidget* mParent; // weak ref nsIWidget* mParent; // weak ref
PRBool mIsMenuBarAdded; PRBool mIsMenuBarAdded;

Просмотреть файл

@ -35,6 +35,13 @@
#include "nsStringUtil.h" #include "nsStringUtil.h"
#include "nsIDocument.h"
#include "nsIDOMDocument.h"
#include "nsINameSpaceManager.h"
#include "nsWidgetAtoms.h"
#include "nsIServiceManager.h"
#if DEBUG #if DEBUG
nsInstanceCounter gMenuItemCounter("nsMenuItem"); nsInstanceCounter gMenuItemCounter("nsMenuItem");
@ -66,13 +73,7 @@ nsMenuItem::nsMenuItem()
// //
nsMenuItem::~nsMenuItem() nsMenuItem::~nsMenuItem()
{ {
//printf("nsMenuItem::~nsMenuItem() called \n"); mManager->Unregister(mContent);
// if we're a radio menu, we've been registered to get AttributeChanged, so
// make sure we unregister when we go away.
//if (mMenuType == eRadio) {
nsCOMPtr<nsIContent> content = do_QueryInterface(mDOMNode);
mManager->Unregister(content);
//}
#if DEBUG #if DEBUG
--gMenuItemCounter; --gMenuItemCounter;
@ -82,22 +83,19 @@ nsMenuItem::~nsMenuItem()
NS_METHOD nsMenuItem::Create ( nsIMenu* aParent, const nsString & aLabel, PRBool aIsSeparator, NS_METHOD nsMenuItem::Create ( nsIMenu* aParent, const nsString & aLabel, PRBool aIsSeparator,
EMenuItemType aItemType, PRBool aEnabled, EMenuItemType aItemType, PRBool aEnabled,
nsIChangeManager* aManager, nsIWebShell* aShell, nsIDOMNode* aNode ) nsIChangeManager* aManager, nsIWebShell* aShell, nsIContent* aNode )
{ {
mDOMNode = aNode; // addref mContent = aNode; // addref
mMenuParent = aParent; // weak mMenuParent = aParent; // weak
mWebShellWeakRef = getter_AddRefs(NS_GetWeakReference(aShell)); mWebShellWeakRef = getter_AddRefs(NS_GetWeakReference(aShell));
mEnabled = aEnabled; mEnabled = aEnabled;
mMenuType = aItemType; mMenuType = aItemType;
// if we're a radio menu, register for AttributeChanged messages // register for AttributeChanged messages
mManager = aManager; mManager = aManager;
//if ( aItemType == eRadio ) {
nsCOMPtr<nsIContent> content = do_QueryInterface(mDOMNode);
nsCOMPtr<nsIChangeObserver> obs = do_QueryInterface(NS_STATIC_CAST(nsIChangeObserver*,this)); nsCOMPtr<nsIChangeObserver> obs = do_QueryInterface(NS_STATIC_CAST(nsIChangeObserver*,this));
mManager->Register(content, obs); // does not addref this mManager->Register(mContent, obs); // does not addref this
//}
mIsSeparator = aIsSeparator; mIsSeparator = aIsSeparator;
mLabel = aLabel; mLabel = aLabel;
@ -126,8 +124,8 @@ NS_METHOD nsMenuItem::SetChecked(PRBool aIsEnabled)
// update the content model. This will also handle unchecking our siblings // update the content model. This will also handle unchecking our siblings
// if we are a radiomenu // if we are a radiomenu
nsCOMPtr<nsIDOMElement> domElement = do_QueryInterface(mDOMNode); mContent->SetAttribute(kNameSpaceID_None, nsWidgetAtoms::checked,
domElement->SetAttribute(NS_LITERAL_STRING("checked"), mIsChecked ? NS_LITERAL_STRING("true") : NS_LITERAL_STRING("false")); mIsChecked ? NS_LITERAL_STRING("true") : NS_LITERAL_STRING("false"), PR_TRUE);
return NS_OK; return NS_OK;
} }
@ -274,10 +272,7 @@ NS_METHOD nsMenuItem::DoCommand()
nsCOMPtr<nsIPresContext> presContext; nsCOMPtr<nsIPresContext> presContext;
nsCOMPtr<nsIWebShell> webShell = do_QueryReferent(mWebShellWeakRef); nsCOMPtr<nsIWebShell> webShell = do_QueryReferent(mWebShellWeakRef);
if (!webShell) if (!webShell)
{
NS_ERROR("No web shell");
return nsEventStatus_eConsumeNoDefault; return nsEventStatus_eConsumeNoDefault;
}
MenuHelpers::WebShellToPresContext(webShell, getter_AddRefs(presContext)); MenuHelpers::WebShellToPresContext(webShell, getter_AddRefs(presContext));
nsEventStatus status = nsEventStatus_eIgnore; nsEventStatus status = nsEventStatus_eIgnore;
@ -285,20 +280,28 @@ NS_METHOD nsMenuItem::DoCommand()
event.eventStructType = NS_MOUSE_EVENT; event.eventStructType = NS_MOUSE_EVENT;
event.message = NS_MENU_ACTION; event.message = NS_MENU_ACTION;
nsCOMPtr<nsIContent> contentNode = do_QueryInterface(mDOMNode); // See if we have a command element. If so, we execute on the command instead
if (!contentNode) { // of on our content element.
NS_ERROR("DOM Node doesn't support the nsIContent interface required to handle DOM events."); nsAutoString command;
return rv; mContent->GetAttribute(kNameSpaceID_None, nsWidgetAtoms::command, command);
if (!command.IsEmpty()) {
nsCOMPtr<nsIDocument> doc;
mContent->GetDocument(*getter_AddRefs(doc));
nsCOMPtr<nsIDOMDocument> domDoc(do_QueryInterface(doc));
nsCOMPtr<nsIDOMElement> commandElt;
domDoc->GetElementById(command, getter_AddRefs(commandElt));
nsCOMPtr<nsIContent> commandContent(do_QueryInterface(commandElt));
if (commandContent)
commandContent->HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
} }
else
rv = contentNode->HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status); mContent->HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
return nsEventStatus_eConsumeNoDefault; return nsEventStatus_eConsumeNoDefault;
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
NS_METHOD nsMenuItem::GetModifiers(PRUint8 * aModifiers) NS_METHOD nsMenuItem::GetModifiers(PRUint8 * aModifiers)
{ {
nsresult res = NS_OK; nsresult res = NS_OK;
@ -338,39 +341,33 @@ NS_METHOD nsMenuItem::GetShortcutChar(nsString &aText)
// uncheck them all. // uncheck them all.
// //
void void
nsMenuItem :: UncheckRadioSiblings(nsIDOMElement* inCheckedElement) nsMenuItem :: UncheckRadioSiblings ( nsIContent* inCheckedContent )
{ {
nsCOMPtr<nsIDOMNode> checkedNode = do_QueryInterface(inCheckedElement);
nsAutoString myGroupName; nsAutoString myGroupName;
inCheckedElement->GetAttribute(NS_LITERAL_STRING("name"), myGroupName); inCheckedContent->GetAttribute(kNameSpaceID_None, nsWidgetAtoms::name, myGroupName);
if ( ! myGroupName.Length() ) // no groupname, nothing to do if ( ! myGroupName.Length() ) // no groupname, nothing to do
return; return;
nsCOMPtr<nsIDOMNode> parent; nsCOMPtr<nsIContent> parent;
checkedNode->GetParentNode(getter_AddRefs(parent)); inCheckedContent->GetParent(*getter_AddRefs(parent));
if (!parent ) if ( !parent )
return; return;
nsCOMPtr<nsIDOMNode> currSibling;
parent->GetFirstChild(getter_AddRefs(currSibling));
while ( currSibling ) {
// skip this node
if ( currSibling.get() != checkedNode ) {
nsCOMPtr<nsIDOMElement> currElement = do_QueryInterface(currSibling);
if ( !currElement )
break;
// loop over siblings
PRInt32 count;
parent->ChildCount(count);
for ( PRInt32 i = 0; i < count; ++i ) {
nsCOMPtr<nsIContent> sibling;
parent->ChildAt(i, *getter_AddRefs(sibling));
if ( sibling ) {
if ( sibling.get() != inCheckedContent ) { // skip this node
// if the current sibling is in the same group, clear it // if the current sibling is in the same group, clear it
nsAutoString currGroupName; nsAutoString currGroupName;
currElement->GetAttribute(NS_LITERAL_STRING("name"), currGroupName); sibling->GetAttribute(kNameSpaceID_None, nsWidgetAtoms::name, currGroupName);
if ( currGroupName == myGroupName ) if ( currGroupName == myGroupName )
currElement->SetAttribute(NS_LITERAL_STRING("checked"), NS_LITERAL_STRING("false")); sibling->SetAttribute(kNameSpaceID_None, nsWidgetAtoms::checked, NS_LITERAL_STRING("false"), PR_TRUE);
}
} }
// advance to the next node
nsIDOMNode* next;
currSibling->GetNextSibling(&next);
currSibling = dont_AddRef(next);
} // for each sibling } // for each sibling
} // UncheckRadioSiblings } // UncheckRadioSiblings
@ -384,32 +381,24 @@ nsMenuItem :: UncheckRadioSiblings(nsIDOMElement* inCheckedElement)
NS_IMETHODIMP NS_IMETHODIMP
nsMenuItem :: AttributeChanged ( nsIDocument *aDocument, PRInt32 aNameSpaceID, nsIAtom *aAttribute, nsMenuItem :: AttributeChanged ( nsIDocument *aDocument, PRInt32 aNameSpaceID, nsIAtom *aAttribute,
PRInt32 aHint) PRInt32 aHint )
{ {
nsCOMPtr<nsIAtom> checkedAtom = NS_NewAtom("checked"); if (aAttribute == nsWidgetAtoms::checked) {
nsCOMPtr<nsIAtom> disabledAtom = NS_NewAtom("disabled");
nsCOMPtr<nsIAtom> labelAtom = NS_NewAtom("label");
nsCOMPtr<nsIAtom> hiddenAtom = NS_NewAtom("hidden");
nsCOMPtr<nsIAtom> collapsedAtom = NS_NewAtom("collapsed");
if (aAttribute == checkedAtom.get())
{
// if we're a radio menu, uncheck our sibling radio items. No need to // if we're a radio menu, uncheck our sibling radio items. No need to
// do any of this if we're just a normal check menu. // do any of this if we're just a normal check menu.
if ( mMenuType == eRadio ) { if ( mMenuType == eRadio ) {
nsCOMPtr<nsIDOMElement> domElement = do_QueryInterface(mDOMNode);
nsAutoString checked; nsAutoString checked;
domElement->GetAttribute(NS_LITERAL_STRING("checked"), checked); mContent->GetAttribute(kNameSpaceID_None, nsWidgetAtoms::checked, checked);
if (checked == NS_LITERAL_STRING("true") ) if (checked == NS_LITERAL_STRING("true") )
UncheckRadioSiblings(domElement); UncheckRadioSiblings(mContent);
} }
nsCOMPtr<nsIMenuListener> listener = do_QueryInterface(mMenuParent); nsCOMPtr<nsIMenuListener> listener = do_QueryInterface(mMenuParent);
listener->SetRebuild(PR_TRUE); listener->SetRebuild(PR_TRUE);
} else if (aAttribute == disabledAtom.get() || }
aAttribute == hiddenAtom.get() || else if (aAttribute == nsWidgetAtoms::disabled || aAttribute == nsWidgetAtoms::hidden ||
aAttribute == collapsedAtom.get() ) { aAttribute == nsWidgetAtoms::collapsed ) {
nsCOMPtr<nsIMenuListener> listener = do_QueryInterface(mMenuParent); nsCOMPtr<nsIMenuListener> listener = do_QueryInterface(mMenuParent);
listener->SetRebuild(PR_TRUE); listener->SetRebuild(PR_TRUE);
} }
@ -422,7 +411,6 @@ nsMenuItem :: AttributeChanged ( nsIDocument *aDocument, PRInt32 aNameSpaceID, n
NS_IMETHODIMP NS_IMETHODIMP
nsMenuItem :: ContentRemoved(nsIDocument *aDocument, nsIContent *aChild, PRInt32 aIndexInContainer) nsMenuItem :: ContentRemoved(nsIDocument *aDocument, nsIContent *aChild, PRInt32 aIndexInContainer)
{ {
nsCOMPtr<nsIMenuListener> listener = do_QueryInterface(mMenuParent); nsCOMPtr<nsIMenuListener> listener = do_QueryInterface(mMenuParent);
listener->SetRebuild(PR_TRUE); listener->SetRebuild(PR_TRUE);
return NS_OK; return NS_OK;
@ -432,7 +420,6 @@ nsMenuItem :: ContentRemoved(nsIDocument *aDocument, nsIContent *aChild, PRInt32
NS_IMETHODIMP NS_IMETHODIMP
nsMenuItem :: ContentInserted(nsIDocument *aDocument, nsIContent *aChild, PRInt32 aIndexInContainer) nsMenuItem :: ContentInserted(nsIDocument *aDocument, nsIContent *aChild, PRInt32 aIndexInContainer)
{ {
nsCOMPtr<nsIMenuListener> listener = do_QueryInterface(mMenuParent); nsCOMPtr<nsIMenuListener> listener = do_QueryInterface(mMenuParent);
listener->SetRebuild(PR_TRUE); listener->SetRebuild(PR_TRUE);
return NS_OK; return NS_OK;

Просмотреть файл

@ -54,7 +54,7 @@ public:
// nsIMenuItem Methods // nsIMenuItem Methods
NS_IMETHOD Create ( nsIMenu* aParent, const nsString & aLabel, PRBool aIsSeparator, NS_IMETHOD Create ( nsIMenu* aParent, const nsString & aLabel, PRBool aIsSeparator,
EMenuItemType aItemType, PRBool aEnabled, EMenuItemType aItemType, PRBool aEnabled,
nsIChangeManager* aManager, nsIWebShell* aShell, nsIDOMNode* aNode ) ; nsIChangeManager* aManager, nsIWebShell* aShell, nsIContent* aNode ) ;
NS_IMETHOD GetLabel(nsString &aText); NS_IMETHOD GetLabel(nsString &aText);
NS_IMETHOD SetShortcutChar(const nsString &aText); NS_IMETHOD SetShortcutChar(const nsString &aText);
NS_IMETHOD GetShortcutChar(nsString &aText); NS_IMETHOD GetShortcutChar(nsString &aText);
@ -84,7 +84,7 @@ public:
protected: protected:
void UncheckRadioSiblings ( nsIDOMElement* inCheckedElement ) ; void UncheckRadioSiblings ( nsIContent* inCheckedElement ) ;
nsString mLabel; nsString mLabel;
nsString mKeyEquivalent; nsString mKeyEquivalent;
@ -96,7 +96,7 @@ protected:
nsCOMPtr<nsIMenuListener> mXULCommandListener; nsCOMPtr<nsIMenuListener> mXULCommandListener;
nsWeakPtr mWebShellWeakRef; // weak ref to webshell nsWeakPtr mWebShellWeakRef; // weak ref to webshell
nsCOMPtr<nsIDOMNode> mDOMNode; nsCOMPtr<nsIContent> mContent;
PRUint8 mModifiers; PRUint8 mModifiers;
PRPackedBool mIsSeparator; PRPackedBool mIsSeparator;

Просмотреть файл

@ -32,6 +32,9 @@
#include "nsIWidget.h" #include "nsIWidget.h"
#include "nsIMenuListener.h" #include "nsIMenuListener.h"
#include "nsDynamicMDEF.h" #include "nsDynamicMDEF.h"
#include "nsINameSpaceManager.h"
#include "nsWidgetAtoms.h"
#include "nsIServiceManager.h"
#include "nsStringUtil.h" #include "nsStringUtil.h"
@ -66,13 +69,7 @@ nsMenuItemX::nsMenuItemX()
// //
nsMenuItemX::~nsMenuItemX() nsMenuItemX::~nsMenuItemX()
{ {
//printf("nsMenuItemX::~nsMenuItemX() called \n"); mManager->Unregister(mContent);
// if we're a radio menu, we've been registered to get AttributeChanged, so
// make sure we unregister when we go away.
//if (mMenuType == eRadio) {
nsCOMPtr<nsIContent> content = do_QueryInterface(mDOMNode);
mManager->Unregister(content);
//}
#if DEBUG #if DEBUG
--gMenuItemCounterX; --gMenuItemCounterX;
@ -82,22 +79,19 @@ nsMenuItemX::~nsMenuItemX()
NS_METHOD nsMenuItemX::Create ( nsIMenu* aParent, const nsString & aLabel, PRBool aIsSeparator, NS_METHOD nsMenuItemX::Create ( nsIMenu* aParent, const nsString & aLabel, PRBool aIsSeparator,
EMenuItemType aItemType, PRBool aEnabled, EMenuItemType aItemType, PRBool aEnabled,
nsIChangeManager* aManager, nsIWebShell* aShell, nsIDOMNode* aNode ) nsIChangeManager* aManager, nsIWebShell* aShell, nsIContent* aNode )
{ {
mDOMNode = aNode; // addref mContent = aNode; // addref
mMenuParent = aParent; // weak mMenuParent = aParent; // weak
mWebShellWeakRef = getter_AddRefs(NS_GetWeakReference(aShell)); mWebShellWeakRef = getter_AddRefs(NS_GetWeakReference(aShell));
mEnabled = aEnabled; mEnabled = aEnabled;
mMenuType = aItemType; mMenuType = aItemType;
// if we're a radio menu, register for AttributeChanged messages // register for AttributeChanged messages
mManager = aManager; mManager = aManager;
//if ( aItemType == eRadio ) {
nsCOMPtr<nsIContent> content = do_QueryInterface(mDOMNode);
nsCOMPtr<nsIChangeObserver> obs = do_QueryInterface(NS_STATIC_CAST(nsIChangeObserver*,this)); nsCOMPtr<nsIChangeObserver> obs = do_QueryInterface(NS_STATIC_CAST(nsIChangeObserver*,this));
mManager->Register(content, obs); // does not addref this mManager->Register(mContent, obs); // does not addref this
//}
mIsSeparator = aIsSeparator; mIsSeparator = aIsSeparator;
mLabel = aLabel; mLabel = aLabel;
@ -126,8 +120,8 @@ NS_METHOD nsMenuItemX::SetChecked(PRBool aIsEnabled)
// update the content model. This will also handle unchecking our siblings // update the content model. This will also handle unchecking our siblings
// if we are a radiomenu // if we are a radiomenu
nsCOMPtr<nsIDOMElement> domElement = do_QueryInterface(mDOMNode); mContent->SetAttribute(kNameSpaceID_None, nsWidgetAtoms::checked,
domElement->SetAttribute(NS_LITERAL_STRING("checked"), mIsChecked ? NS_LITERAL_STRING("true") : NS_LITERAL_STRING("false")); mIsChecked ? NS_LITERAL_STRING("true") : NS_LITERAL_STRING("false"), PR_TRUE);
return NS_OK; return NS_OK;
} }
@ -274,27 +268,32 @@ NS_METHOD nsMenuItemX::DoCommand()
nsCOMPtr<nsIPresContext> presContext; nsCOMPtr<nsIPresContext> presContext;
nsCOMPtr<nsIWebShell> webShell = do_QueryReferent(mWebShellWeakRef); nsCOMPtr<nsIWebShell> webShell = do_QueryReferent(mWebShellWeakRef);
if (!webShell) if (!webShell)
{
NS_ERROR("No web shell");
return nsEventStatus_eConsumeNoDefault; return nsEventStatus_eConsumeNoDefault;
} MenuHelpers::WebShellToPresContext(webShell, getter_AddRefs(presContext));
MenuHelpersX::WebShellToPresContext(webShell, getter_AddRefs(presContext));
nsEventStatus status = nsEventStatus_eIgnore; nsEventStatus status = nsEventStatus_eIgnore;
nsMouseEvent event; nsMouseEvent event;
event.eventStructType = NS_MOUSE_EVENT; event.eventStructType = NS_MOUSE_EVENT;
event.message = NS_MENU_ACTION; event.message = NS_MENU_ACTION;
nsCOMPtr<nsIContent> contentNode = do_QueryInterface(mDOMNode); // See if we have a command element. If so, we execute on the command instead
if (!contentNode) { // of on our content element.
NS_ERROR("DOM Node doesn't support the nsIContent interface required to handle DOM events."); nsAutoString command;
return rv; mContent->GetAttribute(kNameSpaceID_None, nsWidgetAtoms::command, command);
if (!command.IsEmpty()) {
nsCOMPtr<nsIDocument> doc;
mContent->GetDocument(*getter_AddRefs(doc));
nsCOMPtr<nsIDOMDocument> domDoc(do_QueryInterface(doc));
nsCOMPtr<nsIDOMElement> commandElt;
domDoc->GetElementById(command, getter_AddRefs(commandElt));
nsCOMPtr<nsIContent> commandContent(do_QueryInterface(commandElt));
if (commandContent)
commandContent->HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
} }
else
rv = contentNode->HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status); mContent->HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
return nsEventStatus_eConsumeNoDefault; return nsEventStatus_eConsumeNoDefault;
} }
@ -340,37 +339,31 @@ NS_METHOD nsMenuItemX::GetShortcutChar(nsString &aText)
void void
nsMenuItemX :: UncheckRadioSiblings(nsIDOMElement* inCheckedElement) nsMenuItemX :: UncheckRadioSiblings(nsIDOMElement* inCheckedElement)
{ {
nsCOMPtr<nsIDOMNode> checkedNode = do_QueryInterface(inCheckedElement);
nsAutoString myGroupName; nsAutoString myGroupName;
inCheckedElement->GetAttribute(NS_LITERAL_STRING("name"), myGroupName); inCheckedContent->GetAttribute(kNameSpaceID_None, nsWidgetAtoms::name, myGroupName);
if ( ! myGroupName.Length() ) // no groupname, nothing to do if ( ! myGroupName.Length() ) // no groupname, nothing to do
return; return;
nsCOMPtr<nsIDOMNode> parent; nsCOMPtr<nsIContent> parent;
checkedNode->GetParentNode(getter_AddRefs(parent)); inCheckedContent->GetParent(*getter_AddRefs(parent));
if (!parent ) if ( !parent )
return; return;
nsCOMPtr<nsIDOMNode> currSibling;
parent->GetFirstChild(getter_AddRefs(currSibling));
while ( currSibling ) {
// skip this node
if ( currSibling.get() != checkedNode ) {
nsCOMPtr<nsIDOMElement> currElement = do_QueryInterface(currSibling);
if ( !currElement )
break;
// loop over siblings
PRInt32 count;
parent->ChildCount(count);
for ( PRInt32 i = 0; i < count; ++i ) {
nsCOMPtr<nsIContent> sibling;
parent->ChildAt(i, *getter_AddRefs(sibling));
if ( sibling ) {
if ( sibling.get() != inCheckedContent ) { // skip this node
// if the current sibling is in the same group, clear it // if the current sibling is in the same group, clear it
nsAutoString currGroupName; nsAutoString currGroupName;
currElement->GetAttribute(NS_LITERAL_STRING("name"), currGroupName); sibling->GetAttribute(kNameSpaceID_None, nsWidgetAtoms::name, currGroupName);
if ( currGroupName == myGroupName ) if ( currGroupName == myGroupName )
currElement->SetAttribute(NS_LITERAL_STRING("checked"), NS_LITERAL_STRING("false")); sibling->SetAttribute(kNameSpaceID_None, nsWidgetAtoms::checked, NS_LITERAL_STRING("false"), PR_TRUE);
}
} }
// advance to the next node
nsIDOMNode* next;
currSibling->GetNextSibling(&next);
currSibling = dont_AddRef(next);
} // for each sibling } // for each sibling
} // UncheckRadioSiblings } // UncheckRadioSiblings
@ -386,30 +379,22 @@ NS_IMETHODIMP
nsMenuItemX :: AttributeChanged ( nsIDocument *aDocument, PRInt32 aNameSpaceID, nsIAtom *aAttribute, nsMenuItemX :: AttributeChanged ( nsIDocument *aDocument, PRInt32 aNameSpaceID, nsIAtom *aAttribute,
PRInt32 aHint) PRInt32 aHint)
{ {
nsCOMPtr<nsIAtom> checkedAtom = NS_NewAtom("checked"); if (aAttribute == nsWidgetAtoms::checked) {
nsCOMPtr<nsIAtom> disabledAtom = NS_NewAtom("disabled");
nsCOMPtr<nsIAtom> labelAtom = NS_NewAtom("label");
nsCOMPtr<nsIAtom> hiddenAtom = NS_NewAtom("hidden");
nsCOMPtr<nsIAtom> collapsedAtom = NS_NewAtom("collapsed");
if (aAttribute == checkedAtom.get())
{
// if we're a radio menu, uncheck our sibling radio items. No need to // if we're a radio menu, uncheck our sibling radio items. No need to
// do any of this if we're just a normal check menu. // do any of this if we're just a normal check menu.
if ( mMenuType == eRadio ) { if ( mMenuType == eRadio ) {
nsCOMPtr<nsIDOMElement> domElement = do_QueryInterface(mDOMNode);
nsAutoString checked; nsAutoString checked;
domElement->GetAttribute(NS_LITERAL_STRING("checked"), checked); mContent->GetAttribute(kNameSpaceID_None, nsWidgetAtoms::checked, checked);
if (checked == NS_LITERAL_STRING("true") ) if (checked == NS_LITERAL_STRING("true") )
UncheckRadioSiblings(domElement); UncheckRadioSiblings(mContent);
} }
nsCOMPtr<nsIMenuListener> listener = do_QueryInterface(mMenuParent); nsCOMPtr<nsIMenuListener> listener = do_QueryInterface(mMenuParent);
listener->SetRebuild(PR_TRUE); listener->SetRebuild(PR_TRUE);
} else if (aAttribute == disabledAtom.get() || }
aAttribute == hiddenAtom.get() || else if (aAttribute == nsWidgetAtoms::disabled || aAttribute == nsWidgetAtoms::hidden ||
aAttribute == collapsedAtom.get() ) { aAttribute == nsWidgetAtoms::collapsed ) {
nsCOMPtr<nsIMenuListener> listener = do_QueryInterface(mMenuParent); nsCOMPtr<nsIMenuListener> listener = do_QueryInterface(mMenuParent);
listener->SetRebuild(PR_TRUE); listener->SetRebuild(PR_TRUE);
} }

Просмотреть файл

@ -54,7 +54,7 @@ public:
// nsIMenuItem Methods // nsIMenuItem Methods
NS_IMETHOD Create ( nsIMenu* aParent, const nsString & aLabel, PRBool aIsSeparator, NS_IMETHOD Create ( nsIMenu* aParent, const nsString & aLabel, PRBool aIsSeparator,
EMenuItemType aItemType, PRBool aEnabled, EMenuItemType aItemType, PRBool aEnabled,
nsIChangeManager* aManager, nsIWebShell* aShell, nsIDOMNode* aNode ) ; nsIChangeManager* aManager, nsIWebShell* aShell, nsIContent* aNode ) ;
NS_IMETHOD GetLabel(nsString &aText); NS_IMETHOD GetLabel(nsString &aText);
NS_IMETHOD SetShortcutChar(const nsString &aText); NS_IMETHOD SetShortcutChar(const nsString &aText);
NS_IMETHOD GetShortcutChar(nsString &aText); NS_IMETHOD GetShortcutChar(nsString &aText);
@ -96,7 +96,7 @@ protected:
nsCOMPtr<nsIMenuListener> mXULCommandListener; nsCOMPtr<nsIMenuListener> mXULCommandListener;
nsWeakPtr mWebShellWeakRef; // weak ref to webshell nsWeakPtr mWebShellWeakRef; // weak ref to webshell
nsCOMPtr<nsIDOMNode> mDOMNode; nsCOMPtr<nsIContent> mContent;
PRUint8 mModifiers; PRUint8 mModifiers;
PRPackedBool mIsSeparator; PRPackedBool mIsSeparator;

Просмотреть файл

@ -40,6 +40,11 @@
#include "nsString.h" #include "nsString.h"
#include "nsStringUtil.h" #include "nsStringUtil.h"
#include "nsINameSpaceManager.h"
#include "nsWidgetAtoms.h"
#include "nsIXBLService.h"
#include "nsIServiceManager.h"
#include <Appearance.h> #include <Appearance.h>
#include <TextUtils.h> #include <TextUtils.h>
#include <ToolUtils.h> #include <ToolUtils.h>
@ -112,8 +117,7 @@ nsMenuX::~nsMenuX()
::ReleaseMenu(mMacMenuHandle); ::ReleaseMenu(mMacMenuHandle);
// alert the change notifier we don't care no more // alert the change notifier we don't care no more
nsCOMPtr<nsIContent> content = do_QueryInterface(mDOMNode); mManager->Unregister(mMenuContent);
mManager->Unregister(content);
#if DEBUG #if DEBUG
--gMenuCounterX; --gMenuCounterX;
@ -126,18 +130,17 @@ nsMenuX::~nsMenuX()
// //
NS_METHOD NS_METHOD
nsMenuX::Create(nsISupports * aParent, const nsAReadableString &aLabel, const nsAReadableString &aAccessKey, nsMenuX::Create(nsISupports * aParent, const nsAReadableString &aLabel, const nsAReadableString &aAccessKey,
nsIChangeManager* aManager, nsIWebShell* aShell, nsIDOMNode* aNode ) nsIChangeManager* aManager, nsIWebShell* aShell, nsIContent* aNode )
{ {
mWebShellWeakRef = getter_AddRefs(NS_GetWeakReference(aShell)); mWebShellWeakRef = getter_AddRefs(NS_GetWeakReference(aShell));
mDOMNode = aNode; // strong ref mMenuContent = aNode;
// register this menu to be notified when changes are made to our content object // register this menu to be notified when changes are made to our content object
mManager = aManager; // weak ref mManager = aManager; // weak ref
nsCOMPtr<nsIContent> content (do_QueryInterface(aNode));
nsCOMPtr<nsIChangeObserver> changeObs ( do_QueryInterface(NS_STATIC_CAST(nsIChangeObserver*, this)) ); nsCOMPtr<nsIChangeObserver> changeObs ( do_QueryInterface(NS_STATIC_CAST(nsIChangeObserver*, this)) );
mManager->Register(content, changeObs); mManager->Register(mMenuContent, changeObs);
NS_ASSERTION ( mDOMNode, "Menu not given a dom node at creation time" ); NS_ASSERTION ( mMenuContent, "Menu not given a dom node at creation time" );
NS_ASSERTION ( mManager, "No change manager given, can't tell content model updates" ); NS_ASSERTION ( mManager, "No change manager given, can't tell content model updates" );
mParent = aParent; mParent = aParent;
@ -179,12 +182,9 @@ NS_METHOD nsMenuX::SetLabel(const nsAReadableString &aText)
mLabel = aText; mLabel = aText;
#if !TARGET_CARBON #if !TARGET_CARBON
// Look at the label and figure out if it is the "Help" menu
nsCOMPtr<nsIDOMElement> domElement = do_QueryInterface(mDOMNode);
if(domElement) {
nsAutoString menuIDstring; nsAutoString menuIDstring;
domElement->GetAttribute(NS_LITERAL_STRING("id"), menuIDstring); mMenuContent->GetAttribute(kNameSpaceID_None, nsWidgetAtoms::id, menuIDstring);
if (menuIDstring == NS_LITERAL_STRING("menu_Help")) if(menuIDstring == NS_LITERAL_STRING("menu_Help"))
{ {
mIsHelpMenu = PR_TRUE; mIsHelpMenu = PR_TRUE;
::HMGetHelpMenuHandle(&mMacMenuHandle); ::HMGetHelpMenuHandle(&mMacMenuHandle);
@ -195,12 +195,12 @@ NS_METHOD nsMenuX::SetLabel(const nsAReadableString &aText)
mHelpMenuOSItemsCount = numHelpItems; mHelpMenuOSItemsCount = numHelpItems;
for (int i=0; i < numHelpItems; ++i) for (int i=0; i < numHelpItems; ++i)
{ {
mMenuItemsArray.AppendElement(&gDummyMenuItemX); // owned nsDummyMenuItem* dummyItem = new nsDummyMenuItem;
mMenuItemsArray.AppendElement(dummyItem); // owned
} }
return NS_OK; return NS_OK;
} }
}
#endif #endif
// first time? create the menu handle, attach event handler to it. // first time? create the menu handle, attach event handler to it.
@ -619,7 +619,7 @@ nsEventStatus nsMenuX::MenuDeselected(const nsMenuEvent & aMenuEvent)
nsEventStatus nsMenuX::MenuConstruct( nsEventStatus nsMenuX::MenuConstruct(
const nsMenuEvent & aMenuEvent, const nsMenuEvent & aMenuEvent,
nsIWidget * aParentWindow, nsIWidget * aParentWindow,
void * menuNode, void * /* menuNode */,
void * aWebShell) void * aWebShell)
{ {
mConstructed = false; mConstructed = false;
@ -631,38 +631,30 @@ nsEventStatus nsMenuX::MenuConstruct(
//printf("nsMenuX::MenuConstruct called for %s = %d \n", mLabel.ToNewCString(), mMacMenuHandle); //printf("nsMenuX::MenuConstruct called for %s = %d \n", mLabel.ToNewCString(), mMacMenuHandle);
// Begin menuitem inner loop // Begin menuitem inner loop
// Now get the kids. Retrieve our menupopup child. // Retrieve our menupopup.
nsCOMPtr<nsIDOMNode> menuPopupNode; nsCOMPtr<nsIContent> menuPopup;
GetMenuPopupElement(getter_AddRefs(menuPopupNode)); GetMenuPopupContent(getter_AddRefs(menuPopup));
if (!menuPopupNode) if (!menuPopup)
return nsEventStatus_eIgnore; return nsEventStatus_eIgnore;
// Now get the kids // Iterate over the kids
nsCOMPtr<nsIDOMNode> menuitemNode; PRInt32 count;
menuPopupNode->GetFirstChild(getter_AddRefs(menuitemNode)); menuPopup->ChildCount(count);
for ( PRInt32 i = 0; i < count; ++i ) {
while (menuitemNode) nsCOMPtr<nsIContent> child;
{ menuPopup->ChildAt(i, *getter_AddRefs(child));
nsCOMPtr<nsIDOMElement> menuitemElement(do_QueryInterface(menuitemNode)); if ( child ) {
if (menuitemElement) {
nsAutoString label;
menuitemElement->GetAttribute(NS_LITERAL_STRING("label"), label);
//printf("label = %s \n", label.ToNewCString());
// depending on the type, create a menu item, separator, or submenu // depending on the type, create a menu item, separator, or submenu
nsAutoString menuitemNodeType; nsCOMPtr<nsIAtom> tag;
nsAutoString menuitemName; child->GetTag ( *getter_AddRefs(tag) );
menuitemElement->GetNodeName(menuitemNodeType); if ( tag == nsWidgetAtoms::menuitem )
if (menuitemNodeType == NS_LITERAL_STRING("menuitem")) LoadMenuItem(this, child);
LoadMenuItem(this, menuitemElement, menuitemNode, (nsIWebShell*)aWebShell); else if ( tag == nsWidgetAtoms::menuseparator )
else if (menuitemNodeType == NS_LITERAL_STRING("menuseparator"))
AddSeparator(); AddSeparator();
else if (menuitemNodeType == NS_LITERAL_STRING("menu")) else if ( tag == nsWidgetAtoms::menu )
LoadSubMenu(this, menuitemElement, menuitemNode); LoadSubMenu(this, child);
} }
nsCOMPtr<nsIDOMNode> oldmenuitemNode(menuitemNode); } // for each menu item
oldmenuitemNode->GetNextSibling(getter_AddRefs(menuitemNode));
} // end menu item innner loop
gConstructingMenu = PR_FALSE; gConstructingMenu = PR_FALSE;
mNeedsRebuild = PR_FALSE; mNeedsRebuild = PR_FALSE;
@ -675,60 +667,43 @@ nsEventStatus nsMenuX::MenuConstruct(
nsEventStatus nsMenuX::HelpMenuConstruct( nsEventStatus nsMenuX::HelpMenuConstruct(
const nsMenuEvent & aMenuEvent, const nsMenuEvent & aMenuEvent,
nsIWidget * aParentWindow, nsIWidget * aParentWindow,
void * menuNode, void * /* menuNode */,
void * aWebShell) void * aWebShell)
{ {
//printf("nsMenuX::MenuConstruct called for %s = %d \n", mLabel.ToNewCString(), mMacMenuHandle); //printf("nsMenuX::MenuConstruct called for %s = %d \n", mLabel.ToNewCString(), mMacMenuHandle);
// Begin menuitem inner loop
int numHelpItems = ::CountMenuItems(mMacMenuHandle); int numHelpItems = ::CountMenuItems(mMacMenuHandle);
for (int i=0; i < numHelpItems; ++i) for (int i=0; i < numHelpItems; ++i) {
{
mMenuItemsArray.AppendElement(&gDummyMenuItemX); mMenuItemsArray.AppendElement(&gDummyMenuItemX);
} }
// Now get the kids. Retrieve our menupopup child. // Retrieve our menupopup.
nsCOMPtr<nsIDOMNode> menuPopupNode; nsCOMPtr<nsIContent> menuPopup;
GetMenuPopupElement ( getter_AddRefs(menuPopupNode) ); GetMenuPopupContent(getter_AddRefs(menuPopup));
if (!menuPopupNode) if (!menuPopup)
return nsEventStatus_eIgnore; return nsEventStatus_eIgnore;
// Now get the kids // Iterate over the kids
nsCOMPtr<nsIDOMNode> menuitemNode; PRInt32 count;
menuPopupNode->GetFirstChild(getter_AddRefs(menuitemNode)); menuPopup->ChildCount(count);
for ( PRInt32 i = 0; i < count; ++i ) {
while (menuitemNode) nsCOMPtr<nsIContent> child;
{ menuPopup->ChildAt(i, *getter_AddRefs(child));
nsCOMPtr<nsIDOMElement> menuitemElement(do_QueryInterface(menuitemNode)); if ( child ) {
if (menuitemElement) { // depending on the type, create a menu item, separator, or submenu
nsAutoString menuitemNodeType; nsCOMPtr<nsIAtom> tag;
nsAutoString menuitemName; child->GetTag ( *getter_AddRefs(tag) );
if ( tag == nsWidgetAtoms::menuitem )
nsAutoString label; LoadMenuItem(this, child);
menuitemElement->GetAttribute(NS_LITERAL_STRING("label"), label); else if ( tag == nsWidgetAtoms::menuseparator )
//printf("label = %s \n", label.ToNewCString());
menuitemElement->GetNodeName(menuitemNodeType);
if (menuitemNodeType == NS_LITERAL_STRING("menuitem")) {
// LoadMenuItem
LoadMenuItem(this, menuitemElement, menuitemNode, (nsIWebShell*)aWebShell);
} else if (menuitemNodeType == NS_LITERAL_STRING("menuseparator")) {
AddSeparator(); AddSeparator();
} else if (menuitemNodeType == NS_LITERAL_STRING("menu")) { else if ( tag == nsWidgetAtoms::menu )
// Load a submenu LoadSubMenu(this, child);
LoadSubMenu(this, menuitemElement, menuitemNode);
} }
} } // for each menu item
nsCOMPtr<nsIDOMNode> oldmenuitemNode(menuitemNode);
oldmenuitemNode->GetNextSibling(getter_AddRefs(menuitemNode));
} // end menu item innner loop
//printf(" Done building, mMenuItemVoidArray.Count() = %d \n", mMenuItemVoidArray.Count()); //printf(" Done building, mMenuItemVoidArray.Count() = %d \n", mMenuItemVoidArray.Count());
//PreviousMenuStackUnwind(this, mMacMenuHandle);
//PushMenu(this);
return nsEventStatus_eIgnore; return nsEventStatus_eIgnore;
} }
@ -747,23 +722,7 @@ nsEventStatus nsMenuX::MenuDestruct(const nsMenuEvent & aMenuEvent)
// Close the node. // Close the node.
mNeedsRebuild = PR_TRUE; mNeedsRebuild = PR_TRUE;
} }
nsCOMPtr<nsIDOMElement> domElement = do_QueryInterface(mDOMNode); mMenuContent->UnsetAttribute(kNameSpaceID_None, nsWidgetAtoms::open, PR_TRUE);
if(!domElement) {
NS_ERROR("Unable to QI dom element.");
return nsEventStatus_eIgnore;
}
nsCOMPtr<nsIContent> contentNode = do_QueryInterface(domElement);
if (!contentNode) {
NS_ERROR("DOM Node doesn't support the nsIContent interface required to handle DOM events.");
return nsEventStatus_eIgnore;
}
nsCOMPtr<nsIDocument> document;
contentNode->GetDocument(*getter_AddRefs(document));
if(document)
domElement->RemoveAttribute(NS_LITERAL_STRING("open"));
} }
return nsEventStatus_eIgnore; return nsEventStatus_eIgnore;
@ -831,16 +790,17 @@ NS_METHOD nsMenuX::IsHelpMenu(PRBool* aIsHelpMenu)
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
/** /**
* Get DOMNode * Get GetMenuContent
* *
*/ */
NS_METHOD nsMenuX::GetDOMNode(nsIDOMNode ** aMenuNode) NS_METHOD nsMenu::GetMenuContent(nsIContent ** aMenuContent)
{ {
NS_ENSURE_ARG_POINTER(aMenuNode); NS_ENSURE_ARG_POINTER(aMenuContent);
NS_IF_ADDREF(*aMenuNode = mDOMNode); NS_IF_ADDREF(*aMenuContent = mMenuContent);
return NS_OK; return NS_OK;
} }
/* /*
Support for Carbon Menu Manager. Support for Carbon Menu Manager.
*/ */
@ -914,46 +874,34 @@ MenuHandle nsMenuX::NSStringNewMenu(short menuID, nsString& menuTitle)
//---------------------------------------- //----------------------------------------
void nsMenuX::LoadMenuItem( void nsMenuX::LoadMenuItem( nsIMenu* inParentMenu, nsIContent* inMenuItemContent )
nsIMenu * pParentMenu,
nsIDOMElement * menuitemElement,
nsIDOMNode * menuitemNode,
nsIWebShell * aWebShell)
{ {
if ( !inMenuItemContent )
return;
// if menu should be hidden, bail
nsAutoString hidden;
inMenuItemContent->GetAttribute(kNameSpaceID_None, nsWidgetAtoms::hidden, hidden);
if ( hidden == NS_LITERAL_STRING("true") )
return;
// Create nsMenuItem
nsCOMPtr<nsIMenuItem> pnsMenuItem = do_CreateInstance ( kMenuItemCID ) ;
if ( pnsMenuItem ) {
nsAutoString disabled; nsAutoString disabled;
nsAutoString checked; nsAutoString checked;
nsAutoString type; nsAutoString type;
nsAutoString menuitemName; nsAutoString menuitemName;
nsAutoString menuitemCmd; nsAutoString menuitemCmd;
nsAutoString hidden;
// if menu should be hidden, bail inMenuItemContent->GetAttribute(kNameSpaceID_None, nsWidgetAtoms::disabled, disabled);
menuitemElement->GetAttribute(NS_LITERAL_STRING("hidden"), hidden); inMenuItemContent->GetAttribute(kNameSpaceID_None, nsWidgetAtoms::checked, checked);
if ( hidden == NS_LITERAL_STRING("true") ) inMenuItemContent->GetAttribute(kNameSpaceID_None, nsWidgetAtoms::type, type);
return; inMenuItemContent->GetAttribute(kNameSpaceID_None, nsWidgetAtoms::label, menuitemName);
inMenuItemContent->GetAttribute(kNameSpaceID_None, nsWidgetAtoms::command, menuitemCmd);
menuitemElement->GetAttribute(NS_LITERAL_STRING("disabled"), disabled);
menuitemElement->GetAttribute(NS_LITERAL_STRING("checked"), checked);
menuitemElement->GetAttribute(NS_LITERAL_STRING("type"), type);
menuitemElement->GetAttribute(NS_LITERAL_STRING("label"), menuitemName);
menuitemElement->GetAttribute(NS_LITERAL_STRING("cmd"), menuitemCmd);
// Create nsMenuItem
nsCOMPtr<nsIMenuItem> pnsMenuItem = do_CreateInstance ( kMenuItemCID ) ;
if ( pnsMenuItem ) {
//printf("menuitem %s \n", menuitemName.ToNewCString()); //printf("menuitem %s \n", menuitemName.ToNewCString());
// Create MenuDelegate - this is the intermediator inbetween
// the DOM node and the nsIMenuItem
// The nsWebShellWindow wacthes for Document changes and then notifies the
// the appropriate nsMenuDelegate object
nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(menuitemNode));
if (!domElement) {
#if DEBUG_saari
SysBeep(30);
#endif
return;
}
PRBool enabled = ! (disabled == NS_LITERAL_STRING("true")); PRBool enabled = ! (disabled == NS_LITERAL_STRING("true"));
nsIMenuItem::EMenuItemType itemType = nsIMenuItem::eRegular; nsIMenuItem::EMenuItemType itemType = nsIMenuItem::eRegular;
@ -963,54 +911,42 @@ void nsMenuX::LoadMenuItem(
itemType = nsIMenuItem::eRadio; itemType = nsIMenuItem::eRadio;
nsCOMPtr<nsIWebShell> webShell = do_QueryReferent(mWebShellWeakRef); nsCOMPtr<nsIWebShell> webShell = do_QueryReferent(mWebShellWeakRef);
if (!webShell) { if (!webShell)
NS_ERROR("No webshell");
return; return;
}
// Create the item. DO NOT use passed in webshell because of messed up windows dynamic loading // Create the item.
// code. pnsMenuItem->Create(inParentMenu, menuitemName, PR_FALSE, itemType,
pnsMenuItem->Create(pParentMenu, menuitemName, PR_FALSE, itemType, enabled, mManager, webShell, inMenuItemContent);
enabled, mManager, webShell, menuitemNode);
// //
// Set key shortcut and modifiers // Set key shortcut and modifiers
// //
nsAutoString keyAtom; keyAtom.AssignWithConversion("key");
nsAutoString keyValue; nsAutoString keyValue;
domElement->GetAttribute(keyAtom, keyValue); inMenuItemContent->GetAttribute(kNameSpaceID_None, nsWidgetAtoms::key, keyValue);
// Try to find the key node. // Try to find the key node. Get the document so we can do |GetElementByID|
nsCOMPtr<nsIDocument> document; nsCOMPtr<nsIDocument> document;
nsCOMPtr<nsIContent> content = do_QueryInterface(domElement); inMenuItemContent->GetDocument(*getter_AddRefs(document));
content->GetDocument(*getter_AddRefs(document)); if ( !document )
if ( !document ) {
NS_ERROR("Unable to retrieve the document.");
return; return;
}
// Turn the document into a XUL document so we can use getElementById
nsCOMPtr<nsIDOMXULDocument> xulDocument = do_QueryInterface(document); nsCOMPtr<nsIDOMXULDocument> xulDocument = do_QueryInterface(document);
if ( !xulDocument ) { if ( !xulDocument )
NS_ERROR("not XUL!");
return; return;
}
nsCOMPtr<nsIDOMElement> keyElement; nsCOMPtr<nsIDOMElement> keyElement;
if (!keyValue.IsEmpty()) if (!keyValue.IsEmpty())
xulDocument->GetElementById(keyValue, getter_AddRefs(keyElement)); xulDocument->GetElementById(keyValue, getter_AddRefs(keyElement));
if ( keyElement ) { if ( keyElement ) {
nsCOMPtr<nsIContent> keyContent ( do_QueryInterface(keyElement) );
nsAutoString keyChar; keyChar.AssignWithConversion(" "); nsAutoString keyChar; keyChar.AssignWithConversion(" ");
nsAutoString keyAtom; keyAtom.AssignWithConversion("key"); keyContent->GetAttribute(kNameSpaceID_None, nsWidgetAtoms::key, keyChar);
keyElement->GetAttribute(keyAtom, keyChar);
if(keyChar != NS_LITERAL_STRING(" ")) if(keyChar != NS_LITERAL_STRING(" "))
pnsMenuItem->SetShortcutChar(keyChar); pnsMenuItem->SetShortcutChar(keyChar);
PRUint8 modifiers = knsMenuItemNoModifier; PRUint8 modifiers = knsMenuItemNoModifier;
nsAutoString modifiersStr; nsAutoString modifiersStr;
keyElement->GetAttribute(NS_LITERAL_STRING("modifiers"), modifiersStr); keyContent->GetAttribute(kNameSpaceID_None, nsWidgetAtoms::modifiers, modifiersStr);
char* str = modifiersStr.ToNewCString(); char* str = modifiersStr.ToNewCString();
char* newStr; char* newStr;
char* token = nsCRT::strtok( str, ", ", &newStr ); char* token = nsCRT::strtok( str, ", ", &newStr );
@ -1033,53 +969,49 @@ void nsMenuX::LoadMenuItem(
pnsMenuItem->SetModifiers ( modifiers ); pnsMenuItem->SetModifiers ( modifiers );
} }
if(checked == NS_LITERAL_STRING("true")) if ( checked == NS_LITERAL_STRING("true") )
pnsMenuItem->SetChecked(PR_TRUE); pnsMenuItem->SetChecked(PR_TRUE);
else else
pnsMenuItem->SetChecked(PR_FALSE); pnsMenuItem->SetChecked(PR_FALSE);
nsCOMPtr<nsISupports> supports ( do_QueryInterface(pnsMenuItem) ); nsCOMPtr<nsISupports> supports ( do_QueryInterface(pnsMenuItem) );
pParentMenu->AddItem(supports); // Parent now owns menu item inParentMenu->AddItem(supports); // Parent now owns menu item
} }
} }
void void
nsMenuX::LoadSubMenu( nsIMenu * pParentMenu, nsIDOMElement * menuElement, nsIDOMNode * menuNode ) nsMenuX::LoadSubMenu( nsIMenu * pParentMenu, nsIContent* inMenuItemContent )
{ {
// if menu should be hidden, bail // if menu should be hidden, bail
nsAutoString hidden; nsAutoString hidden;
menuElement->GetAttribute(NS_LITERAL_STRING("hidden"), hidden); inMenuItemContent->GetAttribute(kNameSpaceID_None, nsWidgetAtoms::hidden, hidden);
if ( hidden == NS_LITERAL_STRING("true") ) if ( hidden == NS_LITERAL_STRING("true") )
return; return;
nsAutoString menuName; nsAutoString menuName;
menuElement->GetAttribute(NS_LITERAL_STRING("label"), menuName); inMenuItemContent->GetAttribute(kNameSpaceID_None, nsWidgetAtoms::label, menuName);
//printf("Creating Menu [%s] \n", menuName.ToNewCString()); // this leaks //printf("Creating Menu [%s] \n", menuName.ToNewCString()); // this leaks
// Create nsMenuX // Create nsMenu
nsCOMPtr<nsIMenu> pnsMenu ( do_CreateInstance(kMenuCID) ); nsCOMPtr<nsIMenu> pnsMenu ( do_CreateInstance(kMenuCID) );
if (pnsMenu) if (pnsMenu) {
{
// Call Create // Call Create
nsCOMPtr<nsIWebShell> webShell = do_QueryReferent(mWebShellWeakRef); nsCOMPtr<nsIWebShell> webShell = do_QueryReferent(mWebShellWeakRef);
if (!webShell) { if (!webShell)
NS_ERROR("No web shell");
return; return;
}
nsCOMPtr<nsISupports> supports(do_QueryInterface(pParentMenu)); nsCOMPtr<nsISupports> supports(do_QueryInterface(pParentMenu));
pnsMenu->Create(supports, menuName, NS_LITERAL_STRING(""), mManager, webShell, menuNode); pnsMenu->Create(supports, menuName, NS_LITERAL_STRING(""), mManager, webShell, inMenuItemContent);
// set if it's enabled or disabled // set if it's enabled or disabled
nsAutoString disabled; nsAutoString disabled;
menuElement->GetAttribute(NS_LITERAL_STRING("disabled"), disabled); inMenuItemContent->GetAttribute(kNameSpaceID_None, nsWidgetAtoms::disabled, disabled);
if ( disabled == NS_LITERAL_STRING("true") ) if ( disabled == NS_LITERAL_STRING("true") )
pnsMenu->SetEnabled ( PR_FALSE ); pnsMenu->SetEnabled ( PR_FALSE );
else else
pnsMenu->SetEnabled ( PR_TRUE ); pnsMenu->SetEnabled ( PR_TRUE );
// Make nsMenuX a child of parent nsMenuX. The parent takes ownership // Make nsMenu a child of parent nsMenu. The parent takes ownership
nsCOMPtr<nsISupports> supports2 ( do_QueryInterface(pnsMenu) ); nsCOMPtr<nsISupports> supports2 ( do_QueryInterface(pnsMenu) );
pParentMenu->AddItem(supports2); pParentMenu->AddItem(supports2);
} }
@ -1107,30 +1039,75 @@ nsMenuX::OnCreate()
event.clickCount = 0; event.clickCount = 0;
event.widget = nsnull; event.widget = nsnull;
nsCOMPtr<nsIContent> popupContent;
GetMenuPopupContent(getter_AddRefs(popupContent));
nsCOMPtr<nsIWebShell> webShell = do_QueryReferent(mWebShellWeakRef); nsCOMPtr<nsIWebShell> webShell = do_QueryReferent(mWebShellWeakRef);
if (!webShell) { if (!webShell) {
NS_ERROR("No web shell"); NS_ERROR("No web shell");
return PR_FALSE; return PR_FALSE;
} }
nsCOMPtr<nsIPresContext> presContext; nsCOMPtr<nsIPresContext> presContext;
MenuHelpersX::WebShellToPresContext(webShell, getter_AddRefs(presContext) ); MenuHelpers::WebShellToPresContext(webShell, getter_AddRefs(presContext) );
if ( presContext ) if ( presContext ) {
{
nsresult rv = NS_OK; nsresult rv = NS_OK;
nsCOMPtr<nsIDOMNode> menuPopup; nsIContent* dispatchTo = popupContent ? popupContent : mMenuContent;
GetMenuPopupElement(getter_AddRefs(menuPopup)); rv = dispatchTo->HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
nsCOMPtr<nsIContent> popupContent ( do_QueryInterface(menuPopup) );
if ( popupContent )
rv = popupContent->HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
else {
nsCOMPtr<nsIContent> me (do_QueryInterface(mDOMNode));
if ( me )
rv = me->HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
}
if ( NS_FAILED(rv) || status == nsEventStatus_eConsumeNoDefault ) if ( NS_FAILED(rv) || status == nsEventStatus_eConsumeNoDefault )
return PR_FALSE; return PR_FALSE;
} }
// the menu is going to show and the oncreate handler has executed. We
// now need to walk our menu items, checking to see if any of them have
// a command attribute. If so, several apptributes must potentially
// be updated.
if (popupContent) {
nsCOMPtr<nsIDocument> doc;
popupContent->GetDocument(*getter_AddRefs(doc));
nsCOMPtr<nsIDOMDocument> domDoc(do_QueryInterface(doc));
PRInt32 count;
popupContent->ChildCount(count);
for (PRInt32 i = 0; i < count; i++) {
nsCOMPtr<nsIContent> grandChild;
popupContent->ChildAt(i, *getter_AddRefs(grandChild));
nsCOMPtr<nsIAtom> tag;
grandChild->GetTag(*getter_AddRefs(tag));
if (tag.get() == nsWidgetAtoms::menuitem) {
// See if we have a command attribute.
nsAutoString command;
grandChild->GetAttribute(kNameSpaceID_None, nsWidgetAtoms::command, command);
if (!command.IsEmpty()) {
// We do! Look it up in our document
nsCOMPtr<nsIDOMElement> commandElt;
domDoc->GetElementById(command, getter_AddRefs(commandElt));
nsCOMPtr<nsIContent> commandContent(do_QueryInterface(commandElt));
nsAutoString commandDisabled, menuDisabled;
commandContent->GetAttribute(kNameSpaceID_None, nsWidgetAtoms::disabled, commandDisabled);
grandChild->GetAttribute(kNameSpaceID_None, nsWidgetAtoms::disabled, menuDisabled);
if (!commandDisabled.Equals(menuDisabled)) {
// The menu's disabled state needs to be updated to match the command.
if (commandDisabled.IsEmpty())
grandChild->UnsetAttribute(kNameSpaceID_None, nsWidgetAtoms::disabled, PR_TRUE);
else grandChild->SetAttribute(kNameSpaceID_None, nsWidgetAtoms::disabled, commandDisabled, PR_TRUE);
}
nsAutoString commandValue, menuValue;
commandContent->GetAttribute(kNameSpaceID_None, nsWidgetAtoms::label, commandValue);
grandChild->GetAttribute(kNameSpaceID_None, nsWidgetAtoms::label, menuValue);
if (!commandValue.Equals(menuValue)) {
// The menu's label state needs to be updated to match the command.
// Note that (unlike the disabled state) if the command has *no* label, we
// assume the menu is supplying its own.
if (!commandValue.IsEmpty())
grandChild->SetAttribute(kNameSpaceID_None, nsWidgetAtoms::label, commandValue, PR_TRUE);
}
}
}
}
}
return PR_TRUE; return PR_TRUE;
} }
@ -1164,21 +1141,15 @@ nsMenuX::OnDestroy()
return PR_FALSE; return PR_FALSE;
} }
nsCOMPtr<nsIContent> popupContent;
GetMenuPopupContent(getter_AddRefs(popupContent));
nsCOMPtr<nsIPresContext> presContext; nsCOMPtr<nsIPresContext> presContext;
MenuHelpersX::WebShellToPresContext (webShell, getter_AddRefs(presContext) ); MenuHelpers::WebShellToPresContext (webShell, getter_AddRefs(presContext) );
if (presContext ) if (presContext ) {
{ nsresult rv = NS_OK;
nsresult rv; nsIContent* dispatchTo = popupContent ? popupContent : mMenuContent;
nsCOMPtr<nsIDOMNode> menuPopup; rv = dispatchTo->HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
GetMenuPopupElement(getter_AddRefs(menuPopup));
nsCOMPtr<nsIContent> popupContent ( do_QueryInterface(menuPopup) );
if ( popupContent )
rv = popupContent->HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
else {
nsCOMPtr<nsIContent> me ( do_QueryInterface(mDOMNode) );
if ( me )
rv = me->HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
}
mDestroyHandlerCalled = PR_TRUE; mDestroyHandlerCalled = PR_TRUE;
@ -1190,37 +1161,41 @@ nsMenuX::OnDestroy()
// //
// GetMenuPopupElement // GetMenuPopupContent
// //
// Find the |menupopup| child from the node representing this menu. It should be one // Find the |menupopup| child in the |popup| representing this menu. It should be one
// of a very few children so we won't be iterating over a bazillion menu items to find // of a very few children so we won't be iterating over a bazillion menu items to find
// it (so the strcmp won't kill us). // it (so the strcmp won't kill us).
// //
void void
nsMenuX::GetMenuPopupElement(nsIDOMNode** aResult) nsMenu::GetMenuPopupContent(nsIContent** aResult)
{ {
if (!aResult ) if (!aResult )
return; return;
*aResult = nsnull; *aResult = nsnull;
nsCOMPtr<nsIDOMNode> menuPopupNode;
mDOMNode->GetFirstChild(getter_AddRefs(menuPopupNode)); nsresult rv;
while (menuPopupNode) NS_WITH_SERVICE(nsIXBLService, xblService, "@mozilla.org/xbl;1", &rv);
{ if ( !xblService )
nsCOMPtr<nsIDOMElement> menuPopupElement(do_QueryInterface(menuPopupNode)); return;
if (menuPopupElement) {
nsAutoString menuPopupNodeType; PRInt32 count;
menuPopupElement->GetNodeName(menuPopupNodeType); mMenuContent->ChildCount(count);
if (menuPopupNodeType == NS_LITERAL_STRING("menupopup")) {
*aResult = menuPopupNode.get(); for (PRInt32 i = 0; i < count; i++) {
PRInt32 dummy;
nsCOMPtr<nsIContent> child;
mMenuContent->ChildAt(i, *getter_AddRefs(child));
nsCOMPtr<nsIAtom> tag;
xblService->ResolveTag(child, &dummy, getter_AddRefs(tag));
if (tag && tag.get() == nsWidgetAtoms::menupopup) {
*aResult = child.get();
NS_ADDREF(*aResult); NS_ADDREF(*aResult);
return; return;
} }
} }
nsCOMPtr<nsIDOMNode> oldMenuPopupNode(menuPopupNode);
oldMenuPopupNode->GetNextSibling(getter_AddRefs(menuPopupNode));
}
} // GetMenuPopupElement } // GetMenuPopupContent
nsresult nsresult
@ -1243,16 +1218,13 @@ nsMenuX::GetNextVisibleMenu(nsIMenu** outNextVisibleMenu)
menubarParent->GetMenuAt(i, *getter_AddRefs(thisMenu)); menubarParent->GetMenuAt(i, *getter_AddRefs(thisMenu));
if (!thisMenu) continue; if (!thisMenu) continue;
if (gotThisMenu) // we're looking for the next visible if (gotThisMenu) { // we're looking for the next visible
{ nsCOMPtr<nsIContent> menuContent;
nsCOMPtr<nsIDOMNode> menuNode; thisMenu->GetMenuContent(getter_AddRefs(menuContent));
thisMenu->GetDOMNode(getter_AddRefs(menuNode));
nsCOMPtr<nsIDOMElement> menuElement = do_QueryInterface(menuNode);
if (!menuElement) continue;
nsAutoString hiddenValue, collapsedValue; nsAutoString hiddenValue, collapsedValue;
menuElement->GetAttribute(NS_LITERAL_STRING("hidden"), hiddenValue); menuContent->GetAttribute(kNameSpaceID_None, nsWidgetAtoms::hidden, hiddenValue);
menuElement->GetAttribute(NS_LITERAL_STRING("collapsed"), collapsedValue); menuContent->GetAttribute(kNameSpaceID_None, nsWidgetAtoms::collapsed, collapsedValue);
if ( hiddenValue != NS_LITERAL_STRING("true") && collapsedValue != NS_LITERAL_STRING("true")) if ( hiddenValue != NS_LITERAL_STRING("true") && collapsedValue != NS_LITERAL_STRING("true"))
{ {
NS_IF_ADDREF(*outNextVisibleMenu = thisMenu); NS_IF_ADDREF(*outNextVisibleMenu = thisMenu);
@ -1260,10 +1232,8 @@ nsMenuX::GetNextVisibleMenu(nsIMenu** outNextVisibleMenu)
} }
} }
else // we're still looking for this else { // we're still looking for this
{ if (thisMenu.get() == (nsIMenu *)this) {
if (thisMenu.get() == (nsIMenu *)this)
{
gotThisMenu = PR_TRUE; gotThisMenu = PR_TRUE;
thisMenuIndex = i; thisMenuIndex = i;
} }
@ -1288,25 +1258,12 @@ nsMenuX::AttributeChanged(nsIDocument *aDocument, PRInt32 aNameSpaceID, nsIAtom
return NS_OK; return NS_OK;
// ignore the |open| attribute, which is by far the most common // ignore the |open| attribute, which is by far the most common
nsCOMPtr<nsIAtom> openAtom = NS_NewAtom("open"); if ( aAttribute == nsWidgetAtoms::open )
if ( aAttribute == openAtom.get() )
return NS_OK; return NS_OK;
nsCOMPtr<nsIAtom> disabledAtom = NS_NewAtom("disabled");
nsCOMPtr<nsIAtom> labelAtom = NS_NewAtom("label");
nsCOMPtr<nsIAtom> hiddenAtom = NS_NewAtom("hidden");
nsCOMPtr<nsIAtom> collapsedAtom = NS_NewAtom("collapsed");
nsCOMPtr<nsIDOMElement> domElement = do_QueryInterface(mDOMNode);
if(!domElement) {
NS_ERROR("Unable to QI dom element.");
return NS_OK;
}
nsCOMPtr<nsIMenuBar> menubarParent = do_QueryInterface(mParent); nsCOMPtr<nsIMenuBar> menubarParent = do_QueryInterface(mParent);
if (aAttribute == disabledAtom.get()) // disabled if(aAttribute == nsWidgetAtoms::disabled) {
{
mNeedsRebuild = PR_TRUE; mNeedsRebuild = PR_TRUE;
nsAutoString valueString; nsAutoString valueString;
@ -1318,8 +1275,7 @@ nsMenuX::AttributeChanged(nsIDocument *aDocument, PRInt32 aNameSpaceID, nsIAtom
::DrawMenuBar(); ::DrawMenuBar();
} }
else if (aAttribute == labelAtom.get()) // value else if(aAttribute == nsWidgetAtoms::label) {
{
mNeedsRebuild = PR_TRUE; mNeedsRebuild = PR_TRUE;
domElement->GetAttribute(NS_LITERAL_STRING("label"), mLabel); domElement->GetAttribute(NS_LITERAL_STRING("label"), mLabel);
@ -1336,13 +1292,12 @@ nsMenuX::AttributeChanged(nsIDocument *aDocument, PRInt32 aNameSpaceID, nsIAtom
::DrawMenuBar(); ::DrawMenuBar();
} }
else if(aAttribute == hiddenAtom.get() || aAttribute == collapsedAtom.get()) // hidden of collapsed else if(aAttribute == nsWidgetAtoms::hidden || aAttribute == nsWidgetAtoms::collapsed) {
{
mNeedsRebuild = PR_TRUE; mNeedsRebuild = PR_TRUE;
nsAutoString hiddenValue, collapsedValue; nsAutoString hiddenValue, collapsedValue;
domElement->GetAttribute(NS_LITERAL_STRING("hidden"), hiddenValue); mMenuContent->GetAttribute(kNameSpaceID_None, nsWidgetAtoms::hidden, hiddenValue);
domElement->GetAttribute(NS_LITERAL_STRING("collapsed"), collapsedValue); mMenuContent->GetAttribute(kNameSpaceID_None, nsWidgetAtoms::collapsed, collapsedValue);
if (hiddenValue == NS_LITERAL_STRING("true") || collapsedValue == NS_LITERAL_STRING("true")) { if (hiddenValue == NS_LITERAL_STRING("true") || collapsedValue == NS_LITERAL_STRING("true")) {
// hide this menu // hide this menu
NS_ASSERTION(PR_FALSE, "nsMenuX::AttributeChanged: WRITE HIDE CODE."); NS_ASSERTION(PR_FALSE, "nsMenuX::AttributeChanged: WRITE HIDE CODE.");

Просмотреть файл

@ -35,7 +35,6 @@
class nsIMenuBar; class nsIMenuBar;
class nsIMenuListener; class nsIMenuListener;
class nsIDOMElement;
//static PRInt16 mMacMenuIDCount; // use GetUniqueMenuID() //static PRInt16 mMacMenuIDCount; // use GetUniqueMenuID()
@ -67,7 +66,7 @@ public:
// nsIMenu Methods // nsIMenu Methods
NS_IMETHOD Create ( nsISupports * aParent, const nsAReadableString &aLabel, const nsAReadableString &aAccessKey, NS_IMETHOD Create ( nsISupports * aParent, const nsAReadableString &aLabel, const nsAReadableString &aAccessKey,
nsIChangeManager* aManager, nsIWebShell* aShell, nsIDOMNode* aNode ) ; nsIChangeManager* aManager, nsIWebShell* aShell, nsIContent* aNode ) ;
NS_IMETHOD GetParent(nsISupports *&aParent); NS_IMETHOD GetParent(nsISupports *&aParent);
NS_IMETHOD GetLabel(nsString &aText); NS_IMETHOD GetLabel(nsString &aText);
NS_IMETHOD SetLabel(const nsAReadableString &aText); NS_IMETHOD SetLabel(const nsAReadableString &aText);
@ -84,7 +83,7 @@ public:
NS_IMETHOD SetNativeData(void* aData); NS_IMETHOD SetNativeData(void* aData);
NS_IMETHOD AddMenuListener(nsIMenuListener * aMenuListener); NS_IMETHOD AddMenuListener(nsIMenuListener * aMenuListener);
NS_IMETHOD RemoveMenuListener(nsIMenuListener * aMenuListener); NS_IMETHOD RemoveMenuListener(nsIMenuListener * aMenuListener);
NS_IMETHOD GetDOMNode(nsIDOMNode ** aMenuNode); NS_IMETHOD GetMenuContent(nsIContent ** aMenuNode);
NS_IMETHOD SetEnabled(PRBool aIsEnabled); NS_IMETHOD SetEnabled(PRBool aIsEnabled);
NS_IMETHOD GetEnabled(PRBool* aIsEnabled); NS_IMETHOD GetEnabled(PRBool* aIsEnabled);
NS_IMETHOD IsHelpMenu(PRBool* aIsEnabled); NS_IMETHOD IsHelpMenu(PRBool* aIsEnabled);
@ -97,17 +96,16 @@ protected:
nsresult GetNextVisibleMenu(nsIMenu** outNextVisibleMenu); nsresult GetNextVisibleMenu(nsIMenu** outNextVisibleMenu);
// fetch the content node associated with the menupopup item // fetch the content node associated with the menupopup item
void GetMenuPopupElement ( nsIDOMNode** aResult ) ; void GetMenuPopupContent ( nsIContent** aResult ) ;
// fire handlers for oncreate/ondestroy // fire handlers for oncreate/ondestroy
PRBool OnDestroy() ; PRBool OnDestroy() ;
PRBool OnCreate() ; PRBool OnCreate() ;
void LoadMenuItem( nsIMenu * pParentMenu, nsIDOMElement * menuitemElement, void LoadMenuItem ( nsIMenu* pParentMenu, nsIContent* menuitemContent);
nsIDOMNode * menuitemNode, nsIWebShell * aWebShell); void LoadSubMenu( nsIMenu * pParentMenu, nsIContent* menuitemContent);
void LoadSubMenu( nsIMenu * pParentMenu, nsIDOMElement * menuElement, nsIDOMNode * menuNode);
nsEventStatus HelpMenuConstruct( const nsMenuEvent & aMenuEvent, nsIWidget* aParentWindow, nsEventStatus HelpMenuConstruct( const nsMenuEvent & aMenuEvent, nsIWidget* aParentWindow,
void* menuNode, void* aWebShell); void* unused, void* aWebShell);
MenuHandle NSStringNewMenu(short menuID, nsString& menuTitle); MenuHandle NSStringNewMenu(short menuID, nsString& menuTitle);
@ -121,7 +119,7 @@ protected:
// nsIMenuBar* mMenuBarParent; // nsIMenuBar* mMenuBarParent;
nsIChangeManager* mManager; // weak ref, it will outlive us nsIChangeManager* mManager; // weak ref, it will outlive us
nsWeakPtr mWebShellWeakRef; // weak ref to webshell nsWeakPtr mWebShellWeakRef; // weak ref to webshell
nsCOMPtr<nsIDOMNode> mDOMNode; // strong ref nsCOMPtr<nsIContent> mMenuContent; // the |menu| tag, strong ref
nsCOMPtr<nsIMenuListener> mListener; // strong ref nsCOMPtr<nsIMenuListener> mListener; // strong ref
// MacSpecific // MacSpecific

Просмотреть файл

@ -23,6 +23,7 @@
#include "nsToolkit.h" #include "nsToolkit.h"
#include "nsWindow.h" #include "nsWindow.h"
#include "nsGUIEvent.h" #include "nsGUIEvent.h"
#include "nsWidgetAtoms.h"
#include <Gestalt.h> #include <Gestalt.h>
#include <Appearance.h> #include <Appearance.h>
@ -162,6 +163,8 @@ nsToolkit::nsToolkit() : mInited(false)
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
nsToolkit::~nsToolkit() nsToolkit::~nsToolkit()
{ {
nsWidgetAtoms::ReleaseAtoms();
/* StopPumping decrements a refcount on gEventQueueHandler; a prelude toward /* StopPumping decrements a refcount on gEventQueueHandler; a prelude toward
stopping event handling. This is not something you want to do unless you've stopping event handling. This is not something you want to do unless you've
bloody well started event handling and incremented the refcount. That's bloody well started event handling and incremented the refcount. That's
@ -185,6 +188,9 @@ NS_IMETHODIMP nsToolkit::Init(PRThread */*aThread*/)
{ {
if (gEventQueueHandler) if (gEventQueueHandler)
gEventQueueHandler->StartPumping(); gEventQueueHandler->StartPumping();
nsWidgetAtoms::AddRefAtoms();
mInited = true; mInited = true;
return NS_OK; return NS_OK;
} }