Skip to content
This repository

GM_getResourceURL doesn't expose the mimetype anymore #1610

Closed
ConanLoxley opened this Issue August 24, 2012 · 8 comments

3 participants

ConanLoxley arantius ©TriMoon™
ConanLoxley

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

arantius
Collaborator

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

ConanLoxley

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: http://userscripts.org/scripts/review/138566
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"

arantius
Collaborator

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.
https://github.com/greasemonkey/greasemonkey/blob/master/modules/script.js#L459

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

ConanLoxley

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.

ConanLoxley ConanLoxley closed this August 26, 2012
ConanLoxley ConanLoxley reopened this August 26, 2012
arantius
Collaborator

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?

ConanLoxley

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

arantius
Collaborator

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 September 20, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.