1

I have this problem with a script not executing on mobile twitter. I have tried it on many versions of Firefox including FF5, FF8, and FF9.

I have used the latest versions of Greasemonkey. Right now I have FF9 with GM 0.9.10. I do not have any problems executing the script on the normal twitter but on mobile it does not work. Maybe has something to do with HTTPS?

Here is the script:

// ==UserScript==
// @name           Twitter Mobile
// @namespace      http://www.test.com
// @include        https://mobile.twitter.com/*
// @require        http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js
// ==/UserScript==

function MainLoop() {

if(typeof unsafeWindow.jQuery == 'undefined') {
    window.setTimeout(MainLoop, 100);
    return;
}

var $ = unsafeWindow.jQuery;

$(document).ready(function(){
          //do something here
});
window.setTimeout(MainLoop, 2000);
}

MainLoop();

I have tried everything possible. Also, checked the @require alternatives and tried them. I do not know why it refuses to execute.

Brock Adams
  • 90,639
  • 22
  • 233
  • 295
None None
  • 195
  • 1
  • 3
  • 9

3 Answers3

0

mobile.twitter.com returns the following HTTP header in its response:

X-Content-Security-Policy: allow 'self'; img-src *.twitter.com *.twimg.com maps.google.com data:; media-src *.twitter.com *.twimg.com; style-src *.twitter.com *.twimg.com; frame-ancestors *.twitter.com; script-src *.twitter.com *.twimg.com api-secure.recaptcha.net; report-uri https://mobile.twitter.com/csp_violation_report

This header defines a Content Security Policy. The important part here is script-src *.twitter.com *.twimg.com api-secure.recaptcha.net, this restricts the scripts on this page to a few domains. Scripts from other domains cannot be loaded, not even by GreaseMonkey (and if you open the Error Console you will see the corresponding warnings).

I suggest that you paste jQuery into your GreaseMonkey script instead of trying to inject it into the web page. This will increase the size of your script but at least you will be able to use it reliably - and you will no longer need to wait for jQuery to load.

Side-note: I guess that Twitter is testing CSP on the mobile site where it has less impact before deploying it on the main site as well. So your script for the main site might also stop working soon.

Wladimir Palant
  • 56,865
  • 12
  • 98
  • 126
  • 1
    That's not true, Greasemonkey `@require` directives load almost any script, from any site, just fine on mobile.twitter.com. Also the OP is clearly not trying to inject anything. In fact, he was trying, erroneously, to use the page's jQuery, but mobile.twitter.com either does not use jQuery or masks it. (And the CSP blocks anything that calls `eval()` in the page scope.) – Brock Adams Aug 31 '11 at 06:36
  • @Brock: I didn't imagine the CSP warnings. Greasemonkey tries to inject that script and fails - regardless of whether the OP's code is correct. – Wladimir Palant Aug 31 '11 at 06:47
  • Any warnings were probably related to `unsafeWindow.jQuery`, since there is no `jQuery` object accessible to the page. That's not injection; Creating objects under `unsafeWindow` or creating ` – Brock Adams Aug 31 '11 at 06:52
  • @Brock: Please go read the CSP link I gave in my answer. CSP prevents script injections, nothing else. – Wladimir Palant Aug 31 '11 at 06:56
  • I was already familiar with that doc. AND, it is widely [documented that CSP blocks `eval()`](http://people.mozilla.com/~bsterne/content-security-policy/details.html) and a host of other things. Try it on twitter mobile and see for yourself. – Brock Adams Aug 31 '11 at 07:06
  • Thanks a lot for letting me know about the CSP, Wladimir. Very cool feature. I have tried disabling the CSP and the code did not work either. Though, when I replaced it with another code that injects jquery to the header. The code worked only when CSP was disabled. I have got the other code from: http://userscripts.org/scripts/review/107271 (replacing the main code with my twitter code ofc). Though, Brock's code works either way (whether CSP is disabled or not). Thanks again for telling about the CSP feature. – None None Aug 31 '11 at 18:13
0

All that MainLoop stuff is not required, and also forcing the wrong instance of jQuery.

Please do the following:

  1. Switch back to the latest stable version of Firefox (Currently version 6).

  2. Delete everything after // ==/UserScript== in the script except the //do something here part.

    1. Do not use unsafeWindow.jQuery.
    2. You do not need any $(document).ready calls; Greasemonkey executes at the proper time by default.
    3. Delete the current setTimeout() calls; they are counter productive.


  3. Change the @require directive to:

    // @require http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js
    


  4. Paste or link to the complete script! The current script is probably failing mostly because it's checking for something on the page that is AJAXed-in.
    get around that with code like this:

    //--- This handles both page-load delays, and AJAX changes.
    setInterval (function() { checkForTweetbox (); }, 500);
    
    function checkForTweetbox () {
        var tweetbox = document.querySelector ('div.tweet-box textarea');
        if (tweetbox) {
            if (! tweetbox.weHaveProcessed) {
                tweetbox.weHaveProcessed    = true;
                alert ('New tweet-box found!');
            }
        }
    }
    

In fact, this script works perfectly well:

// ==UserScript==
// @name            _mobile twitter
// @include         https://mobile.twitter.com/*
// @require         http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js
// ==/UserScript==

setInterval (function() { checkForTweetbox (); }, 500);

function checkForTweetbox () {
    var tweetbox = document.querySelector ('#message_text');
    if (tweetbox) {
        if (! tweetbox.weHaveProcessed) {
            tweetbox.weHaveProcessed    = true;
            tweetbox.value              = 'GM\'s jQuery version is: ' + $.fn.jquery;
        }
    }
}

If you are logged into twitter mobile, it will preload a tweet in the message box (but not send).

Brock Adams
  • 90,639
  • 22
  • 233
  • 295
  • Thanks a lot for the code, Brock. Well the code inside checkForTweetbox did not work for me but I replaced it with my twitter code and it worked. The code from above, I did not write it myself except for the code that manipulated twitter. I copied it from a website. So, I do not know what it does exactly. Though, it used to work earlier on twitter mobile then it suddenly stopped. I am really curious on why that code used to work earlier and it does not work now. Also, it is still working on the main twitter. Thanks again for the efficient code. – None None Aug 31 '11 at 18:04
  • It apparently stopped working because Twitter mobile stopped using -- or changed how they use -- jQuery. The GM script used an overly complicated and overly brittle approach. In fact, this question is a good practical example of why not to code that way. (^_^) – Brock Adams Aug 31 '11 at 23:53
0

Edit: as Brock noticed, this answer is obsolete as of GreaseMonkey 0.9.0.

A @require tag is only processed the first time a script is installed. So changing the @require line does not do anything, as nothing will be downloaded after the script has been installed.

See also How can I use jQuery in Greasemonkey?

Community
  • 1
  • 1
wimh
  • 15,072
  • 6
  • 47
  • 98
  • 1
    That information, and that link, are obsolete. [As of GM 0.9.0, if the `@require` directive is changed, the script will be refreshed.](http://wiki.greasespot.net/Metadata_Block#.40require) – Brock Adams Aug 31 '11 at 07:10