Search code examples
javascriptjiragreasemonkey

JIRA.bind() is not working in Greasemonkey


As the title says, I am unable to get the JIRA.bind() call working from my Greasemonkey script and I am running out of ideas why and what to try else.

I am running JIRA 6.4.14 and Greasemonkey 3.9 in Firefox 50.1.0.

If I open JIRA and execute this line in the Firefox built-in console, it works and "GO" is displayed after committing an inline change:

JIRA.bind(JIRA.Events.INLINE_EDIT_SAVE_COMPLETE, function(e, context, reason){alert("GO");})

So, I thought it should be no problem to port this command into Greasemonkey:

unsafeWindow.JIRA.bind(unsafeWindow.JIRA.Events.INLINE_EDIT_SAVE_COMPLETE, function(e, context, reason){alert("GO");})

But nothing happens, when I do the exact same inline edit. The line itself is executed, I "alerted" before and after and both popups came up.

I tried some other variations of the call, all without success

unsafeWindow.JIRA.bind(unsafeWindow.JIRA.Events.INLINE_EDIT_SAVE_COMPLETE, function(e, context, reason){ unsafeWindow.alert("GO");})
unsafeWindow.AJS.$(unsafeWindow.JIRA.bind(unsafeWindow.JIRA.Events.INLINE_EDIT_SAVE_COMPLETE, function(e, context, reason){alert("GO");}))
unsafeWindow.JIRA.bind(unsafeWindow.JIRA.Events.INLINE_EDIT_SAVE_COMPLETE, function(){ alert("GO");})
// While 'fooBar' is a simple function doing the alert("go")
unsafeWindow.JIRA.bind(unsafeWindow.JIRA.Events.INLINE_EDIT_SAVE_COMPLETE, function(){ fooBar })

Does anyone know how to make the bind work?


Trying the exportFunction did not solved the issue:

$(document).ready(function() {

    unsafeWindow.JIRA.bind(unsafeWindow.JIRA.Events.INLINE_EDIT_SAVE_COMPLETE, function(e, context, reason){ foobar });

});

function foobar()
{
    alert("GO");
}

exportFunction(foobar, unsafeWindow);

SOLUTION:

Thank you Brock Adams and wOxxOm for your help!

This snipped is working just fine and printing both messages "Binding" and "Go".

$(document).ready(function() {

    // Write a log message from inside of the GM script
    anotherMethod("Binding");

    // Bind the exported foobar to the JIRA event
    unsafeWindow.JIRA.bind(
        unsafeWindow.JIRA.Events.INLINE_EDIT_SAVE_COMPLETE,
        unsafeWindow.foobar
    );

});

// Implementation of the foobar function
function foobar(e, context, reason)
{
    anotherMethod("Go");
}

// Another method, that will get called from the GM script and the exported foobar
function anotherMethod(msg)
{
    console.log(msg);
}

// Export foobar to the unsafeWindow to make it accessible for JIRA
unsafeWindow.foobar = exportFunction(foobar, unsafeWindow);

Solution

  • Refer to How to access `window` (Target page) objects when @grant values are set?.

    Everything in the .bind() call must reside in the target page scope, so you can't use dynamic function () {...} code like that.

    Bind your callback like so:

    function mySaveComplete (e, context, reason) {
        //alert ("GO");
        console.log ("Go");
    }
    unsafeWindow.mySaveComplete = exportFunction (mySaveComplete, unsafeWindow);
    
    unsafeWindow.JIRA.bind (
        unsafeWindow.JIRA.Events.INLINE_EDIT_SAVE_COMPLETE,
        unsafeWindow.mySaveComplete
    );
    

    However, I don't have access to a JIRA test bed. In certain situations, you may have to inject the code, as the linked answer states.
    In that case, see also: How to call Greasemonkey's GM_ functions from code that must run in the target page scope?