Search code examples
javascriptfirefoxgreasemonkey-4

How do I fix an infinite loop in a hacked version of waitForKeyElements?


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.


Solution

  • 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.