The admin dropdown menus in our DNN 3.1.1 sites haven't been working in FireFox - they show up in the upper left hand corner of the screen (absolutely positioned at 0,0). A javascript change (in spmenu.js) fixed it for us.
I'm not sure if this somehow works for everyone else, or if DNN people don't use FireFox, or what. I checked the latest release (3.2 / 4.2) and they don't appear to have this fix, so here it is. I'm going to submit it as a bug and suggested fix to the DNN forums, too.
The problem is setting positions via javascript DOM manipulation without specifying the units:
oMenu.style.top = 100; //bad - no units specified
oMenu.style.top = 100 + 'px'; //good - units specified
The best I can tell, the units should be required, so FireFox is being correct in ignoring the improper settings. Anyhow, here's my altered spmenu.js. Of course, the original copyright applies, this is just a patch fix.
//------------------------------------------------------//
// Solution Partner's ASP.NET Hierarchical Menu Control //
// Copyright (c) 2002-2005 //
// Jon Henning - Solution Partner's Inc //
// jhenning@solpart.com - http://www.solpart.com //
// Compatible Menu Version: <Min: 1400> //
// <Max: 1.6.1.0> //
// <Script Version: 1610> //
//------------------------------------------------------//
var m_oSolpartMenu;
if (m_oSolpartMenu == null)
m_oSolpartMenu = new Array(); //stores all menu objects (SolpartMenu) in array
var m_spm_sBrowser;
var m_spm_sVersion;
function spm_initMyMenu(oXML, oCtl) //Creates SolpartMenu object and calls generate method
{
m_oSolpartMenu[oCtl.id] = new SolpartMenu(oCtl);
m_oSolpartMenu[oCtl.id].GenerateMenuHTML(oXML);
}
//------- Constructor -------//
function SolpartMenu(o)
{
__db(o.id + ' - constructor');
// var me = this; //allow attached events to reference this
//--- Data Properties ---//
this.systemImagesPath=spm_getAttr(o, 'SysImgPath', '');
this.iconImagesPath=spm_getAttr(o, 'IconImgPath', this.systemImagesPath);
this.xml = spm_getAttr(o, 'XML', '');
this.xmlFileName = spm_getAttr(o, 'XMLFileName', '');
//--- Appearance Properties ---//
this.fontStyle=spm_getAttr(o, 'FontStyle', 'font-family: arial;');
this.backColor=spm_getAttr(o, 'BackColor');
this.foreColor=spm_getAttr(o, 'ForeColor');
this.iconBackColor=spm_getAttr(o, 'IconBackColor');
this.hlColor=spm_getAttr(o, 'HlColor', '');
this.shColor=spm_getAttr(o, 'ShColor', '');
this.selColor=spm_getAttr(o, 'SelColor');
this.selForeColor=spm_getAttr(o, 'SelForeColor');
this.selBorderColor=spm_getAttr(o, 'SelBorderColor');
this.menuAlignment = spm_getAttr(o, 'MenuAlignment', 'Left');
this.display=spm_getAttr(o, 'Display', 'horizontal');
this.MBLeftHTML=spm_getAttr(o, 'MBLHTML', '');
this.MBRightHTML=spm_getAttr(o, 'MBRHTML', '');
this.rootArrow = spm_getAttr(o, 'RootArrow', '0');
this.rootArrowImage = spm_getAttr(o, 'RootArrowImage', '');
this.arrowImage = spm_getAttr(o, 'ArrowImage', '');
this.backImage=spm_getAttr(o, 'BackImage', '');
this.supportsTransitions = spm_getAttr(o, 'SupportsTrans', '0');
//--- Transition Properteis ---//
//this.menuEffectsStyle=spm_getAttr(o, 'MenuEffectsStyle', '');
this.menuTransitionLength=spm_getAttr(o, 'MenuTransitionLength', .3);
this.menuTransition=spm_getAttr(o, 'MenuTransition', 'None');
this.menuTransitionStyle=spm_getAttr(o, 'MenuTransitionStyle', '');
this.SolpartMenuTransitionObject = new SolpartMenuTransitionObject();
//--- Behavior Properteis ---//
this.moveable = spm_getAttr(o, 'Moveable', '0');
this.moDisplay=spm_getAttr(o, 'MODisplay', 'HighLight');
this.moExpand=spm_getAttr(o, 'MOExpand', "-1");
this.moutDelay=spm_getAttr(o, 'MOutDelay', "0");
this.minDelay=spm_getAttr(o, 'MInDelay', "0");
this.minDelayType=null;
this.minDelayTimer=null;
this.minDelayObj=null;
if (spm_browserType() == 'safari') //safari has issues with mouseoutdelay...
this.moutDelay = 5000;
this.target=spm_getAttr(o, 'target', "");
this.moScroll=spm_getAttr(o, 'MOScroll', "-1");
//--- Sizing Properties ---//
this.menuBarHeight=spm_fixUnit(spm_getAttr(o, 'MenuBarHeight', '0'));
this.menuItemHeight=spm_fixUnit(spm_getAttr(o, 'MenuItemHeight', '0'));
this.iconWidth=spm_fixUnit(spm_getAttr(o, 'IconWidth', '0'));
this.borderWidth=spm_getAttr(o, 'BorderWidth', '1');
//--- CSS Properties ---//
this.cssMenuContainer=spm_getAttr(o, 'CSSMenuContainer', '');
this.cssMenuBar=spm_getAttr(o, 'CSSMenuBar', '');
this.cssMenuItem=spm_getAttr(o, 'CSSMenuItem', '');
this.cssMenuIcon=spm_getAttr(o, 'CSSMenuIcon', '');
this.cssSubMenu=spm_getAttr(o, 'CSSSubMenu', '');
this.cssMenuBreak=spm_getAttr(o, 'CSSMenuBreak', '');
this.cssMenuItemSel=spm_getAttr(o, 'CSSMenuItemSel', '');
this.cssMenuArrow=spm_getAttr(o, 'CSSMenuArrow', '');
this.cssMenuRootArrow=spm_getAttr(o, 'CSSRootMenuArw', '');
this.cssMenuScrollItem=spm_getAttr(o, 'CSSScrollItem', '');
//for right to left (rtl) menus
this.direction = spm_getCurrentStyle(document.body, 'direction');
this.useIFrames=(spm_getAttr(o, 'useIFrames', '1') != '0' && spm_supportsIFrameTrick());
this.delaySubmenuLoad=(spm_getAttr(o, 'delaySubmenuLoad', '0') != '0' && spm_needsSubMenuDelay());
//---- methods ---//
//this.GenerateMenuHTML=__GenerateMenuHTML;
//----- private ----//
this._m_sNSpace = o.id; //stores namespace for menu
this._m_sOuterTables = ''; //stores HTML for sub menus
this._m_oDOM; //stores XML DOM object
this._m_oMenu = o; //stores container
this._m_oMenuMove; //stores control that is used for moving menu
this._m_oTblMenuBar; //stores menu container
this._m_aOpenMenuID = new Array(); //stores list of menus that are currently displayed
this._m_bMoving=false; //flag to determine menu is being dragged
this._m_dHideTimer = null; //used to time when mouse out occured to auto hide menu based on mouseoutdelay
this._m_oScrollingMenu = null; //used in scrolling menu on mouse over
//--- Exposed Events ---//
/*
this.onMenuComplete=spm_getAttr(o, 'OnMenuComplete', null); //fires once menu is done loading
this.onMenuBarClick=spm_getAttr(o, 'OnMenuBarClick', null); //fires once menu bar is clicked
this.onMenuItemClick=spm_getAttr(o, 'OnMenuItemClick', null); //fires once menu item is clicked
this.onMenuBarMouseOver=spm_getAttr(o, 'OnMenuBarMouseOver', null); //fires once mouse moves over menu bar
this.onMenuBarMouseOut=spm_getAttr(o, 'OnMenuBarMouseOut', null); //fires once mouse moves out of menu bar
this.onMenuItemMouseOver=spm_getAttr(o, 'OnMenuItemMouseOver', null); //fires once mouse moves over menu item
this.onMenuItemMouseOut=spm_getAttr(o, 'OnMenuItemMouseOut', null); //fires once mouse moves out of menu bar
*/
//--- Menu Moving currently disabled ---//
/*
this._menuhook_MouseMove=__menuhook_MouseMove;
this._menuhook_MouseDown=__menuhook_MouseDown;
this._menuhook_MouseUp=__menuhook_MouseUp;
this._document_MouseMove=__document_MouseMove;
this._document_MouseDown=__document_MouseDown;
this._document_MouseUp=__document_MouseUp;
this._bodyclick=__bodyclick;
this.menuhook_MouseMove=function(e) {me._menuhook_MouseMove(e);};
this.menuhook_MouseDown=function(e) {me._menuhook_MouseDown(e);};
this.menuhook_MouseUp=function(e) {me._menuhook_MouseUp(e);};
this.document_MouseMove=function(e) {me._document_MouseMove(e);};
this.document_MouseDown=function(e) {me._document_MouseDown(e);};
this.menuhook_MouseUp=function(e) {me._menuhook_MouseUp(e);};
this.bodyclick=function() {me._bodyclick();};
*/
__db(this._m_oMenu.id + ' - constructor end');
}
//--- Destroys interrnal object references ---//
SolpartMenu.prototype.destroy = function ()
{
this.systemImagesPath = null;
this.iconImagesPath = null;
this.xml = null;
this.xmlFileName = null;
//--- Appearance Properties ---//
this.fontStyle = null;
this.backColor = null;
this.foreColor = null;
this.iconBackColor = null;
this.hlColor = null;
this.shColor = null;
this.selColor = null;
this.selForeColor = null;
this.selBorderColor = null;
this.menuAlignment = null;
this.display = null;
this.rootArrow = null;
this.rootArrowImage = null;
this.arrowImage = null;
this.backImage = null;
//--- Transition Properteis ---//
//this.menuEffectsStyle = null;
this.menuTransitionLength = null;
this.menuTransition = null;
this.SolpartMenuTransitionObject = null;
//--- Behavior Properteis ---//
this.moveable = null;
this.moDisplay = null;
this.moExpand = null;
this.moutDelay = null;
//--- Sizing Properties ---//
this.menuBarHeight = null;
this.menuItemHeight = null;
this.iconWidth = null;
this.borderWidth = null;
//--- CSS Properties ---//
this.cssMenuContainer = null;
this.cssMenuBar = null;
this.cssMenuItem = null;
this.cssMenuIcon = null;
this.cssSubMenu = null;
this.cssMenuBreak = null;
this.cssMenuItemSel = null;
this.cssMenuArrow = null;
this.cssMenuRootArrow = null;
//---- methods ---//
//this.GenerateMenuHTML=__GenerateMenuHTML = null;
//----- private ----//
m_oSolpartMenu[this._m_sNSpace] = null;
this._m_sNSpace = null; //stores namespace for menu
this._m_sOuterTables = null; //stores HTML for sub menus
this._m_oDOM = null; //stores XML DOM object
this._m_oMenu = null; //stores container
this._m_oMenuMove = null; //stores control that is used for moving menu
this._m_oTblMenuBar = null; //stores menu container
this._m_aOpenMenuID = null; //stores list of menus that are currently displayed
this._m_bMoving = null; //flag to determine menu is being dragged
this._m_dHideTimer = null; //used to time when mouse out occured to auto hide menu based on mouseoutdelay
this._m_oScrollingMenu = null; //used in scrolling menu on mouse over
}
//--- static/shared members ---//
/*
SolpartMenu.prototype.menuhook_MouseMove=__menuhook_MouseMove;
SolpartMenu.prototype.menuhook_MouseDown=__menuhook_MouseDown;
SolpartMenu.prototype.menuhook_MouseUp=__menuhook_MouseUp;
SolpartMenu.prototype.document_MouseMove=__document_MouseMove;
SolpartMenu.prototype.document_MouseDown=__document_MouseDown;
SolpartMenu.prototype.document_MouseUp=__document_MouseUp;
*/
//--- xml document loaded (non-dataisland) ---//
SolpartMenu.prototype.onXMLLoad = function ()
{
this.GenerateMenuHTML(this._m_oDOM);
}
//--- Generates menu HTML through passed in XML DOM ---//
SolpartMenu.prototype.GenerateMenuHTML = function (oXML)
{
__db(this._m_oMenu.id + ' - GenerateMenuHTML');
//'Generates the main menu bar
var sHTML = '';
this._m_sOuterTables = '';
//this._m_oMenu.insertAdjacentElement('beforeBegin', );
//if (oXML.readyState != 'complete')
// return;
if (oXML == null)
{
if (this._m_oDOM == null)
{
oXML = spm_createDOMDoc();//document.implementation.createDocument("", "", null);
this._m_oDOM = oXML;
if (this.xml.length)
oXML.loadXML(this.xml);
if (this.xmlFileName.length)
{
oXML.onload = eval('onxmlload' + this._m_sNSpace); //'m_oSolpartMenu["' + this._m_sNSpace + '"].onXMLLoad'; this.onXMLLoad;
oXML.load(this.xmlFileName);
return; //async load
}
}
}
else
this._m_oDOM = oXML;
if (this.display == "vertical")
{
sHTML += '<table ID="tbl' + this._m_sNSpace + 'MenuBar" CELLPADDING=\'0\' CELLSPACING=\'0\' BORDER="0" CLASS="' + spm_fixCSSForMac(this.getIntCSSName('spmbctr') + this.cssMenuContainer) + '" HEIGHT="100%" STYLE="vertical-align: center;">\n'; //removed position: relative; for IE and display: block; for Opera
sHTML += MyIIf(this.MBLeftHTML.length, '<tr>\n <td>' + this.MBLeftHTML + '</td>\n</tr>\n', '');
sHTML += MyIIf(Number(this.moveable), '<tr>\n <td ID="td' + this._m_sNSpace + 'MenuMove" height=\'3px\' style=\'cursor: move; ' + spm_getMenuBorderStyle(this) + '\'>' + spm_getSpacer(this) + '</td>\n</tr>\n', '');
sHTML += this.GetMenuItems(this._m_oDOM.documentElement);
sHTML += ' <tr><td HEIGHT="100%">' + spm_getSpacer(this) + '</td>\n' ;
sHTML += ' </tr>\n';
sHTML += MyIIf(this.MBRightHTML.length, '<tr>\n <td>' + this.MBRightHTML + '</td>\n</tr>\n', '');
sHTML += '</table>\n';
}
else
{
sHTML += '<table ID="tbl' + this._m_sNSpace + 'MenuBar" CELLPADDING=\'0\' CELLSPACING=\'0\' BORDER="0" CLASS="' + spm_fixCSSForMac(this.getIntCSSName('spmbctr') + this.cssMenuContainer) + '" WIDTH="100%" STYLE="vertical-align: center; ">\n'; //removed position: relative; for IE and display: block; for Opera
sHTML += ' <tr>\n';
sHTML += MyIIf(this.MBLeftHTML.length, '<td>' + this.MBLeftHTML + '</td>\n', '');
sHTML += MyIIf(Number(this.moveable), ' <td ID="td' + this._m_sNSpace + 'MenuMove" width=\'3px\' style=\'cursor: move; ' + spm_getMenuBorderStyle(this) + '\'>' + spm_getSpacer(this) + '</td>\n', '');
sHTML += spm_getMenuSpacingImage('left', this);
sHTML += this.GetMenuItems(this._m_oDOM.documentElement);
sHTML += spm_getMenuSpacingImage('right', this);
sHTML += MyIIf(this.MBRightHTML.length, '<td>' + this.MBRightHTML + '</td>\n'