GM_getResourceURL doesn't expose the mimetype anymore #1610

ghost opened this Issue Aug 24, 2012 · 8 comments


None yet

2 participants

ghost commented Aug 24, 2012

With the pre-1.0 versions of Greasemonkey I was able to extract the mimetype of a resource by doing this

var mimeType = /data:(.+?);/.exec(GM_getResourceURL(resourceName))[1];

In version 1.0, the data: scheme has been replaced with a protocol handler: greasemonkey-script. Can I assume that greasemonkey-script indicates a script resource? Do you use different protocol handlers for css and images?

The API documentation on greasespot doesn't reflect this change yet. It still mentions the data: scheme


Can you help me understand why you need/want to detect this on the fly? How you used this in an existing script?

ghost commented Aug 25, 2012

I'll try to keep a long story short. What my script basically does is just inject other files (scripts/css/images) into an existing website. These injected scripts run inside the target page itself. There are some reasons to do this:

  • The target page and injected scripts are written against the Qooxoo framework. Every javascript class is inside its own file.
  • I don't want to merge all these separate files into one huge scripts, so each file is defined as an "@resource"
  • injected scripts run directly inside the page itself and 'escape' the restrictions of the sandbox

Since an "@resource" can be anything, I need to know a way to dynamically detect the mimetype because injecting a script is different from injecting a css or an image

You can have a look in my script:
There is a function loadExtensions (info is an instance of GM_info)

function loadExtensions(info) {

    if (("resources" in info) &&  (info.resources !== null)) {

        for (var i = 0; i < info.resources.length; i++) {
            var resourceName = info.resources[i];
            console.log('[lou-extensions] - register ' + resourceName);

            var text = GM_getResourceText(resourceName);

            //Putting a default value until GM devs provide me with a better way
            //var mimeType = /data:(.+?);/.exec(GM_getResourceURL(resourceName))[1];
            var mimeType = 'text/javascript';

            if(mimeType.indexOf('script') > -1 ) {
                injectScript(text, mimeType, resourceName);
            } else if(mimeType.indexOf('css') > -1) {
                injectStyle(text, mimeType, resourceName);
            else {
                console.log("Don't know how to inject a resource with mime-type: "
                    + mimeType + ". Resource name: " + resourceName);

I propose that GM_info not only gives me the names of the resources that are defined in a script, but also any other information you can derive, such as mimetype. For backwards compatibility it's probably best not to touch the existing GM_info.resources array, but maybe you could add a new array of 'resourceInfo' objects, containing 'name', 'url', 'mimetype' and maybe other information you could share about the "@resources"


The target page and injected scripts are written against ...

Are you saying you're generating a script on the fly? Otherwise I still don't understand why you don't know the mime type to expect at the time that you type the "// @resource" line.

it's probably best not to touch the existing GM_info.resources array

There isn't one.

Just says "// 'resources': ???,". So filling that in with something might be the fix for this, now that there is indeed information to be exposed.

ghost commented Aug 26, 2012

Indeed, GM_info doesn't have a 'resources' array. I forgot that I actually parse the GM_info.scriptMetaStr property and extend the GM_info object with a 'resources' array, containing the names of the elements in the '@resource' list.

I don't generate scripts on the fly, but I inject them into the target page on the fly (because I need to wait until a certain javascript function in the Qooxdoo framework has completed). The reason I need the mimetype is because my script is currently composed of about 50 sub-scripts and style sheets. The main script loops over my array of resource names, loads the content (GM_getResourceText) and checks the mimetype.

  • if mimetype == text/javascript, the script is injected in the page using script tags
  • if mimteype == css, the stylesheet is injected in the page using link tags

What this allows me to do is extend my script by simply adding a new '@resource' to the main script. The main script takes care to inject it correctly. So I avoid hardcoding this ad infinitum:

injectScript(GM_getResourceText(resource1), "text/javascript", 1);
injectScript(GM_getResourceText(resource2), "text/javascript", 2);
injectStyle(GM_getResourceText(resource3), "css", 3);
injectScript(GM_getResourceText(resource4), "text/javascript", 4);
injectScript(GM_getResourceText(resource...), "text/javascript", ...);

In previous versions of GM, I could extract the mimetype from the GM_getResourceURL

var mimeType = /data:(.+?);/.exec(GM_getResourceURL(resourceName))[1];

My only alternative at the moment is checking the file extension but since you did create this "data:" scheme in the past, I assumed you still have the code that determines the mimetype because (I assume) it was used there.

@ghost ghost closed this Aug 26, 2012
@ghost ghost reopened this Aug 26, 2012

if mimetype == text/javascript, the script is injected in the page using script tags
if mimteype == css, the stylesheet is injected in the page using link tags

This could as easily be accomplished with whether the name is foo_script or foo_style (or any other naming convention) couldn't it?

ghost commented Aug 27, 2012

Yes, it's indeed the workaround I have put in place since yesterday evening.

 If( file extension == ".js" ) injectAsJavascript
 If( file extension == ".css" ) injectAsStyleSheet

This method works fine. I had to do the same thing for my Chrome version anyway so I don't mind leaving that code in. The old GM way was just more elegant in my opinion :)

If there is no way of determining mimetype for resources in GM, you can just close this issue if you please


It's possible; the mime type (as reported by the server) is saved at install time, which is how it was put into the old data URI. But probably low priority at this point.

@arantius arantius closed this in d4007d9 Sep 20, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment