Greasemonkey accessed by Bookmarklets

1,472 views
Skip to first unread message

GmUser

unread,
Dec 4, 2014, 12:18:54 AM12/4/14
to greasemon...@googlegroups.com
Is there ANY WAY to load a javascript library using Greasemonkey and have the functions executable by a bookmarklet?

(safely / securely, or relatively so)

Dave Land

unread,
Dec 4, 2014, 5:55:02 PM12/4/14
to greasemon...@googlegroups.com
Hi,

Good news: yes, there is.


If that doesn't cover it for you, google "greasemonkey jquery" or the name of your favorite library.

Dave

On Dec 3, 2014, at 9:18 PM, GmUser <pop...@p-t-b.com> wrote:

Is there ANY WAY to load a javascript library using Greasemonkey and have the functions executable by a bookmarklet?

(safely / securely, or relatively so)


--
You received this message because you are subscribed to the Google Groups "greasemonkey-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to greasemonkey-us...@googlegroups.com.
To post to this group, send email to greasemon...@googlegroups.com.
Visit this group at http://groups.google.com/group/greasemonkey-users.
For more options, visit https://groups.google.com/d/optout.

Klaus Johannes Rusch

unread,
Dec 4, 2014, 6:19:13 PM12/4/14
to greasemon...@googlegroups.com
On 2014-12-04 23:54, 'Dave Land' via greasemonkey-users wrote:
On Dec 3, 2014, at 9:18 PM, GmUser <pop...@p-t-b.com> wrote:

Is there ANY WAY to load a javascript library using Greasemonkey and have the functions executable by a bookmarklet?
You can load the script in the page context to give bookmarklets access, e.g.

// @include     http://*
// @include     https://*

(function () {
    j = document.createElement("SCRIPT");
    j.src = "//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js";
    document.getElementsByTagName("HEAD")[0].appendChild(j);
})();

-- 
Klaus Johannes Rusch
klaus...@atmedia.net
http://klausrusch.atmedia.net/

GmUser

unread,
Dec 4, 2014, 8:17:50 PM12/4/14
to greasemon...@googlegroups.com, klaus...@atmedia.net
Thanks.
That USED to be true.
I should have been more clear.
I have a "local" (server - LAMP) library I want to include in ALL pages.
(ideally, only when needed, when I click on a bookmarklet)
The library is located at http://127.0.0.1/....
This used to always work.
But now (due to some browser 'security fixes'), SOME https:// websites give an error if you try to
add a script object that points to somewhere that is not "secure".
Like facebook, twitter, and even google, just to name a few.
So I believe that attempting to do as you say will generate a security error.
I haven't tried it. I will. But I will be surprised if it works.
That is the problem I've been having trying to do it as a bookmarklet.
Unless Greasemonkey somehow overrides this security check.

GmUser

unread,
Dec 4, 2014, 8:20:25 PM12/4/14
to greasemon...@googlegroups.com
Thanks. See my reply below.

GmUser

unread,
Dec 8, 2014, 6:50:39 AM12/8/14
to greasemon...@googlegroups.com
This is at least part of the problem: (if not all of it)

https://github.com/blog/1477-content-security-policy

GmUser

unread,
Dec 8, 2014, 7:16:35 AM12/8/14
to greasemon...@googlegroups.com

GmUser

unread,
Dec 8, 2014, 7:22:40 AM12/8/14
to greasemon...@googlegroups.com

GmUser

unread,
May 9, 2015, 12:06:36 AM5/9/15
to greasemon...@googlegroups.com
I don't know why people who supposedly know how Greasemonkey works
couldn't have simply said, "Here's how you can do it."

It's not that hard. (if you know what you are doing)
I'm posting the information here in case it helps someone else.

You can find more info here: https://bugzilla.mozilla.org/show_bug.cgi?id=866522#c38
(Bug 866522 - Bookmarklets affected by CSP (Content Security Policy))

I FINALLY found a solution to my problem.

It's kind of "stupid", because, although you are limited in what URL
you can use to inject a script into certain CSP-protected documents,
you can insert ANY text DIRECTLY into the document. (now watch them
take that away from us, too) Of course, there is (still?) usually
some limit to the size of a saved bookmarklet, but I (needed to)
get around that. (plus the "squishing" and such needed in bookmarklets) The solution is fairly simple using a Greasemonkey userscript.
I don't know why people who supposedly know how the "new" stuff
in Gm works couldn't simply tell me how to do it. (?) I use the @resource command to access my 56K JavaScript library
file (which is loaded as a SNAPSHOT into the Gm directory that
holds the userscript upon installation -- there are some issues
with that and modifications/reload to the referenced source file --
so I directly edit the snapshot file), get the contents of it,
and directly insert that .JS file document text using the script object
.text property instead of the .src property. I also didn't want to load the library into every page, so I made
the bookmarklet "communicate" with the userscript and let it know
that it wants the library loaded, and then it executes the library
bookmarklet function after 1/5th of a second. This is the script I use to load my bookmarklets library now:
(with some names 'obfuscated') // ==UserScript== // @name Bookmarklet Library // @namespace choose-a-namespace.com // @description Loads bookmarklet library into page // @include * // @version 1.0 // @resource bmlib
http://www.blah-blah-blah.com/bookmarkletlibrary.js // @grant GM_getResourceText // @grant unsafeWindow // ==/UserScript== // NOTE that the library file is a STATIC SNAPSHOT saved into the directory that contains this userscript function checkLibraryLoadRequest() { if (typeof (unsafeWindow.Bm_bLibraryRequest) != 'undefined') { // value set as request from bookmarklet if (typeof (unsafeWindow.Bm_bLibraryLoaded) == 'undefined') { // value set inside library script var sBMLibSource = GM_getResourceText ('bmlib'); var oScript = document.createElement ('script'); oScript.type = 'text/javascript'; oScript.text = sBMLibSource; // document.getElementsByTagName ('head')[0].appendChild (oScript); document.body.appendChild (oScript); } } else { setTimeout (checkLibraryLoadRequest, 100); // check every 100 ms } return; } // checkLibraryLoadRequest checkLibraryLoadRequest(); // EXAMPLE Bookmarklet shell/template: // javascript:(function(){window.Bm_bLibraryRequest=true;setTimeout(function(){window['***FUNCTION-NAME***']();},200);})() /**********************************************************************/ At the top of the library script file I have: var Bm_bLibraryLoaded = true; // stops library from being loaded twice (just in case) And then my bookmarklets all have the format as the example above. I just change the "***FUNCTION-NAME***" value to the name of
the function I want to call in the library. I kept the "communication" between the userscript and the
bookmarklet simple. So far it has worked. Although one time
it may not have, so you might want to either decrease the
"check for request time" to 50 and/or increase the
"execute bookmarklet function" time to 250.
I haven't noticed any noticeable lag time because it's
only about 1/5th of a second. So far it works great. I can now execute my bookmarklets
from Twitter, Facebook, Google, and anywhere else and
and https:// "secure" website.
So I suppose this will work until someone does something
else to screw us over. btw -- I am using Pale Moon now ("old-style Firefox"),
so I don't know if there are any differences in Firefox, Chrome, etc.

GmUser

unread,
May 9, 2015, 1:40:40 AM5/9/15
to greasemon...@googlegroups.com
For the latest, most up-to-date information about this solution, see:

http://www.donnelly-house.net/programming/js/bookmarklets/bookmarklets.php

Reply all
Reply to author
Forward
0 new messages