2

I'm just trying to add a couple of buttons, which when clicked a bootstrap dialogbox/modal should pop up. Something like this demo: http://jsbin.com/wiruhepere/1/edit?html,css,js,output

However when applying this using greasemonkey/tampermonkey on a real website, let's say stackoverflow: It's not working at all !!

I'm suspecting some script/css conflict maybe but I don't have the knowledge to track that down :<

What I'm looking for is:

  1. Make the modal appear when clicking on the "Delete" button
  2. When clicking on "OK" to confirm, grab/intercept that answer to do some other stuffs...

Please bear in mind I'm a beginner in this, so if soemthing isn't clear enough, feel free to ask :-)

Updated GM code based on wOxxOm comments:

// ==UserScript==
// @name        Bootstrap Test
// @namespace   http://tampermonkey.net/
// @description Why the hell the modal isnt working :<
// @author      Enissay
// @include     http://stackoverflow.com/*
// @include     https://stackoverflow.com/*
// @resource    jqueryJS https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js
// @resource    bootstrapJS https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js
// @resource    buttonCSS https://raw.githubusercontent.com/necolas/css3-github-buttons/master/gh-buttons.css
// @resource    bootstrapCSS https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css
// @resource    githubButtonIconSet https://raw.githubusercontent.com/necolas/css3-github-buttons/master/gh-icons.png
// @grant       GM_addStyle
// @grant       GM_getResourceText
// @grant       GM_getResourceURL
// ==/UserScript==

(function() {
    //--- Inject scripts & css including myCode/Func
    $("head").append("<script>" + GM_getResourceText("jqueryJS") + "</script>");
    $("head").append("<script>" + GM_getResourceText("bootstrapJS") + "</script>");
    $("head").append("<style>" + GM_getResourceText("bootstrapCSS") + "</style>");

    var githubButtonIconSet = GM_getResourceURL ("githubButtonIconSet");
    var buttonCSS = GM_getResourceText("buttonCSS");
    buttonCSS = buttonCSS.replace (/gh-icons\.png/g, githubButtonIconSet);
    $("head").append("<style>" + GM_getResourceText(buttonCSS) + "</style>");

    $("body").append("<script>("+myFunc+")();</script>");
})();

function myFunc () {
(function() {
    'use strict';
    var deleteButtonHtml = `
<div class="button-group">
    <button type="button" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal">
        Launch demo modal
    </button>

    <a href="#" class="button icon edit">Edit</a>
    <a href="#" class="button icon remove danger">Delete</a>
</div>
`;
    var modalHtml = `
<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
        <h4 class="modal-title" id="myModalLabel">Modal title</h4>
      </div>
      <div class="modal-body">
        ...
      </div>
      <div class="modal-footer">

        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        <button type="button" class="btn btn-primary">Save changes</button>
      </div>
    </div>
  </div>
</div>
`;

    //--- Add nodes to page
    $("body").prepend(deleteButtonHtml);
    $("body").prepend(modalHtml);

    //--- Attach event to button
    $(".button-group").find(".remove").click(function(evt){
        //debugger;
        $('#myModal').modal({
            keyboard: true
        });
    });
})();
}

Initial GM code bellow:

// ==UserScript==
// @name        Bootstrap Test
// @namespace   http://tampermonkey.net/
// @description Why the hell the modal isnt working :<
// @author      Enissay
// @include     http://stackoverflow.com/*
// @require     https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js
// @require     https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js
// @resource    buttonCSS https://raw.githubusercontent.com/necolas/css3-github-buttons/master/gh-buttons.css
// @resource    bootstrapCSS https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css
// @resource    githubButtonIconSet https://raw.githubusercontent.com/necolas/css3-github-buttons/master/gh-icons.png
// @grant       GM_addStyle
// @grant       GM_getResourceText
// @grant       GM_getResourceURL
// ==/UserScript==

(function() {
    'use strict';

    var deleteButtonHtml = `
<div class="button-group">
    <button type="button" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal">
        Launch demo modal
    </button>

    <a href="#" class="button icon edit">Edit</a>
    <a href="#" class="button icon remove danger">Delete</a>
</div>
`;
    var modalHtml = `
<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
        <h4 class="modal-title" id="myModalLabel">Modal title</h4>
      </div>
      <div class="modal-body">
        ...
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        <button type="button" class="btn btn-primary">Save changes</button>
      </div>
    </div>
  </div>
</div>
`;
    //--- Add nodes to page
    $("body").prepend(deleteButtonHtml);
    $("body").prepend(modalHtml);

    //--- Attach event to button
    $(".button-group").find(".remove").click(function(evt){
        $('#myModal').modal({
            keyboard: false
        });
    });


    //--- Style our newly added elements using CSS.
    GM_addStyle (GM_getResourceText ("bootstrapCSS"));
    var githubButtonIconSet = GM_getResourceURL ("githubButtonIconSet");
    var buttonCSS = GM_getResourceText("buttonCSS");
    buttonCSS = buttonCSS.replace (/gh-icons\.png/g, githubButtonIconSet);
    GM_addStyle(buttonCSS);
})();
Enissay
  • 4,969
  • 3
  • 29
  • 56
  • 1
    StackOverflow can use https, so add a copy of the `@include` line with https. You should see your script in the popup of GM/TM if it runs on a page. Also, try debugging, it's very easy in Tampermonkey: just add `debugger;` inside the code and reload the page with devtools (F12 key) opened. – wOxxOm Aug 23 '16 at 20:45
  • @wOxxOm I updated my code (check above) based on your consctructive comments and here's what I got: http://i.imgur.com/wJQYkLW.png it's not centered as in the demo with the nice grayed background (note that Bootstrap needs the latest jQuery wich break some SO's commands/stuffs) – Enissay Aug 23 '16 at 21:22
  • Apparently, SO styles apply to some of the injected html elements. You'll need to reset them somehow, for example via [`all:initial` CSS property](http://stackoverflow.com/a/31317986/3959875) inside a rule matching your injected elements with a high CSS specificity like `#myModal * { all:initial }` As for jQuery, try its `jQuery.noConflict` and bootstrap will be able to use it. – wOxxOm Aug 23 '16 at 21:28
  • @wOxxOm Thanks a lot for assistance :-) – Enissay Aug 25 '16 at 11:05

1 Answers1

6

There's so many things wrong with the script, let me list them:

  • Manually appending javascript to DOM - for requiring other javascript resources, use @require such as:

    // @require     https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js
    
  • Mistaking string and a variable - bellow, you're using getResourceText but giving it a CSS string, not resource name:

    var buttonCSS = GM_getResourceText("buttonCSS");
    buttonCSS = buttonCSS.replace (/gh-icons\.png/g, githubButtonIconSet);
    // Button CSS does not contain name of resource, but actual CSS
    $("head").append("<style>" + GM_getResourceText(buttonCSS) + "</style>");
    
  • Unnecesary closures - this doesn't cause any errors, but why would you wrap whole function body in self invoking closure? This is crazy:

    // WARNING: Crazy code, do not use!
    function myFunc() {
        (function() {
    
        })()
    }
    
  • Executing function by appending it to HTML - while not exactly an error in general, people just normally do this to call myFunction:

    // Call my function
    myFunction();
    

    Not sure why did you do this instead:

    $("body").append("<script>("+myFunction+")();</script>");
    

    This also cannot work, because greasemonkey variable scope is hidden from global scope. So it is impossible to call myFunction from HTML. This means in your case it just cannot work.

I fixed most of the problems for you, but you still need to figure out how to resolve CSS conflicts for the dialog on stackoverflow, that problem is out of scope of answer to your question.

The script below works on http://blank.org:

// ==UserScript==
// @name        Bootstrap Test
// @namespace   http://tampermonkey.net/
// @description Why the hell the modal isnt working :<
// @author      Enissay, Tomas Zato (http://stackoverflow.com/users/607407/tom%c3%a1%c5%a1-zato)
// @include     /https?:\/\/stackoverflow\.com\/*/
// @include     http://blank.org/*
// @require     https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js
// @require     https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js
// @resource    buttonCSS https://raw.githubusercontent.com/necolas/css3-github-buttons/master/gh-buttons.css
// @resource    bootstrapCSS https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css
// @resource    githubButtonIconSet https://raw.githubusercontent.com/necolas/css3-github-buttons/master/gh-icons.png
// @grant       GM_addStyle
// @grant       GM_getResourceText
// @grant       GM_getResourceURL
// ==/UserScript==
console.log("Start");

document.head.appendChild(cssElement(GM_getResourceURL ("githubButtonIconSet")));
document.head.appendChild(cssElement(GM_getResourceURL ("buttonCSS")));
document.head.appendChild(cssElement(GM_getResourceURL ("bootstrapCSS")));

function cssElement(url) {
  var link = document.createElement("link");
  link.href = url;
  link.rel="stylesheet";
  link.type="text/css";
  return link;
}

function myFunc () {
    'use strict';
    var deleteButtonHtml = `
<div class="button-group">
    <button type="button" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal">
        Launch demo modal
    </button>

    <a href="#" class="button icon edit">Edit</a>
    <a href="#" class="button icon remove danger">Delete</a>
</div>
`;
    var modalHtml = `
<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
        <h4 class="modal-title" id="myModalLabel">Modal title</h4>
      </div>
      <div class="modal-body">
        ...
      </div>
      <div class="modal-footer">

        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        <button type="button" class="btn btn-primary">Save changes</button>
      </div>
    </div>
  </div>
</div>
`;

    //--- Add nodes to page
    $("body").prepend(deleteButtonHtml);
    $("body").prepend(modalHtml);
    //--- Attach event to button
    // NOT NECESSARY, bootsrap creates event listeners automatically
    /*$(".button-group").find("button").click(function(evt){
        console.log("Click.", $('#myModal'));
        $('#myModal').modal("show");
    });   */
}
myFunc();
Tomáš Zato
  • 50,171
  • 52
  • 268
  • 778
  • Well, thank you for correcting these common mistakes for me at least, and I learned a lot from your example... As for bootstrap, I just realised that the website I'm working on (in the work's internal network) has already an old version of it, hence why it has a weird behaviour when importing another one... Now it's fixed and thanks to your guidelines it's more clean :-) – Enissay Aug 25 '16 at 11:04