0

My company's website uses the Metronic Horizontal Menu admin panel, but it's an older version that uses a Gear instead of the user profile picture and name. Before Firefox 30, this Greasemonkey script was working and would move the "My Profile" and "Log Out" buttons under the user profile/name, while keeping "My Calendar", "My Inbox", and "My Tasks" inside the gear icon dropdown. Here's my Greasemonkey code:

// ==UserScript==
// @name        Fix User Dropdown
// @description Fixes the user dropdown to match current version.
// @include     mywebsite.com
// @version     2.0.0
// @require         https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js
// @require         https://gist.github.com/raw/2625891/waitForKeyElements.js
// @grant               GM_addStyle
// @grant               GM.getValue
// ==/UserScript==
//- The @grant directives are needed to restore the proper sandbox.

waitForKeyElements (".topMenu1", addUserDropdown, true);

function addUserDropdown(jNode) {
  $('#greetingName').remove();
  var userSession = unsafeWindow.userSession;
  var userId = userSession.id;
  var firstName = userSession.firstName;
  var lastName = userSession.lastName;
  var fullName = firstName + ' ' + lastName;
  var accountId = userSession.accountId;

  $('.top-menu .nav').prepend(
        '<li class="dropdown dropdown-user dropdown-dark">' + 
            '<a data-close-others="true" data-hover="dropdown" data-toggle="dropdown" class="dropdown-toggle username username-hide-mobile floatRight" href="#" style="padding:10px;border-right:1px solid #000;margin:5px;">' + 
                fullName + 
            '</a>' + 
            '<ul id="userPersonalMenu" class="dropdown-menu dropdown-menu-default">' + 
                '<li>' + 
                    '<a href="/user/editor?id=' + userId + '&amp;accountId=' + accountId + '" id="greetingNameLink">' + 
                    '<i class="icon-settings"></i> My Profile </a>' + 
                '</li>' + 
                '<li>' + 
                    '<a href="/logout">' + 
                    '<i class="icon-key"></i> Log Out </a>' + 
                '</li>' + 
            '</ul>' + 
        '</li>');

  $('.dropdown-toggle').dropdownHover({});

  return null;
}

This is what happens:

username repeated multiple times

It never ever prints "CANCEL FOUND", which defies logic as far as I'm concerned since the call stack should still resolve. It then proceeds to draw the user's name ("Nick" in the example) infinitely across the screen from right-to-left and then top-to-bottom.

I was hoping that setting bWaitOnce to true would fix this, but no dice.

NobleUplift
  • 5,631
  • 8
  • 45
  • 87
  • 1
    That is **not** WFKE! You've altered the code without understanding how jQuery's `data` works, hence the "loop". You can change WFKE to lose the jQuery dependency, but (1) Not quite like that, (2) I have never found the need -- over thousands of scripts and 10's of thousands of pages, (3) Bypassing jQ to store a node's state makes the script more vulnerable to interference from other scripts, or the page itself. Admittedly, not a huge increase in risk, but completely unnecessary. – Brock Adams May 14 '18 at 21:03
  • @BrockAdams Sorry, I added the debugging because I thought that would make it easier to diagnose the issue. I disabled the two scripts that we fixed last week, removed the function from my GM script, and refreshed my page, but it's still appending my code infinitely to the menu. – NobleUplift May 14 '18 at 21:28
  • 1
    Are you saying that the code, above, **EXACTLY** as shown at the time of this comment, produces that output on FF60 + GM4+? If so, comment out the `return null;` line. Also, try the code in Tampermonkey on FF, and maybe TM on Chrome. ... Any chance that the `.topMenu1` node is getting deleted and recreated? ... May have to see the actual page or an MCVE. – Brock Adams May 14 '18 at 21:37
  • I just upgraded to FF60 and installed Tampermonkey, and good news, I figured out what's causing the issue (but not why), it's the `$('.dropdown-toggle').dropdownHover({});` line. [This is the function's source.](https://github.com/CWSpear/bootstrap-hover-dropdown/blob/v2.0.1/bootstrap-hover-dropdown.js) – NobleUplift May 14 '18 at 21:59
  • A ha! I took what I learned from my last question and added `// @require https://raw.githubusercontent.com/CWSpear/bootstrap-hover-dropdown/master/bootstrap-hover-dropdown.js` to my Tampermonkey script and it works! (kind of) The "on hover" functions if I hover over the Gear first, but if I hover over the user's name, it does not display. Though I'm insatiably curious as to why it was on infinite repeat in the old version, having 95% of my scripts' functionality back is good enough for me. Thank you very much!\ – NobleUplift May 14 '18 at 22:11
  • Okay, it's good that you got your script mostly back. (And hopefully learned to avoid GM4.) ... ... But not seeing how to salvage this particular question yet... – Brock Adams May 14 '18 at 22:34
  • Is it possible that the `setTimeout` method in [the older version of the file (compare)](https://github.com/CWSpear/bootstrap-hover-dropdown/compare/v2.0.1...master) was deleting the timeouts set by `waitForKeyElements.js`? – NobleUplift May 16 '18 at 17:18
  • No, it couldn't interfere via that particular mechanism. (Also, that 2.0.1 version uses `setTimeout` while WFKE relies on `setInterval`.) – Brock Adams May 16 '18 at 19:08

1 Answers1

0

I added:

// @require https://raw.githubusercontent.com/CWSpear/bootstrap-hover-dropdown/master/bootstrap-hover-dropdown.js

To the top of my user script to fetch the most recent version of the hover dropdown and it worked!

Moral of the story, check which page dependencies your user script uses and make sure they are compatible with *Monkey.

NobleUplift
  • 5,631
  • 8
  • 45
  • 87