Is there any way that my script can retrieve metadata values that are declared in its own header? I don't see anything promising in the API, except perhaps GM_getValue()
. That would of course involve a special name syntax. I have tried, for example: GM_getValue("@name")
.
The motivation here is to avoid redundant specification.
If GM metadata is not directly accessible, perhaps there's a way to read the body of the script itself. It's certainly in memory somewhere, and it wouldn't be too awfully hard to parse for "// @"
. (That may be necessary in my case any way, since the value I'm really interested in is @version
, which is an extended value read by userscripts.org.)
This answer is out of date : As of Greasemonkey 0.9.16 (Feb 2012) please see Brock's answer regarding GM_info
Yes. A very simple example is:
var metadata=<>
// ==UserScript==
// @name Reading metadata
// @namespace http://www.afunamatata.com/greasemonkey/
// @description Read in metadata from the header
// @version 0.9
// @include https://stackoverflow.com/questions/104568/accessing-greasemonkey-metadata-from-within-your-script
// ==/UserScript==
</>.toString();
GM_log(metadata);
See this thread on the greasemonkey-users group for more information. A more robust implementation can be found near the end.
Use the GM_info
object, which was added to Greasemonkey in version 0.9.16.
For example, if You run this script:
// ==UserScript==
// @name _GM_info demo
// @namespace Stack Overflow
// @description Tell me more about me, me, ME!
// @include http://stackoverflow.com/questions/*
// @version 8.8
// ==/UserScript==
unsafeWindow.console.clear ();
unsafeWindow.console.log (GM_info);
It will output this object:
{
version: (new String("0.9.18")),
scriptWillUpdate: false,
script: {
description: "Tell me more about me, me, ME!",
excludes: [],
includes: ["http://stackoverflow.com/questions/*"],
matches: [],
name: "_GM_info demo",
namespace: "Stack Overflow",
'run-at': "document-end",
unwrap: false,
version: "8.8"
},
scriptMetaStr: "// @name _GM_info demo\r\n// @namespace Stack Overflow\r\n// @description Tell me more about me, me, ME!\r\n// @include http://stackoverflow.com/questions/*\r\n// @version 8.8\r\n"
}
Building on Athena's answer, here is my generalized solution that yields an object of name/value pairs, each representing a metadata property. Note that certain properties can have multiple values, (@include, @exclude, @require, @resource), therefore my parser captures those as Arrays - or in the case of @resource, as a subordinate Object of name/value pairs.
var scriptMetadata = parseMetadata(.toString());
function parseMetadata(headerBlock)
{
// split up the lines, omitting those not containing "// @"
function isAGmParm(element) { return /\/\/ @/.test(element); }
var lines = headerBlock.split(/[\r\n]+/).filter(isAGmParm);
// initialize the result object with empty arrays for the enumerated properties
var metadata = { include: [], exclude: [], require: [], resource: {} };
for each (var line in lines)
{
[line, name, value] = line.match(/\/\/ @(\S+)\s*(.*)/);
if (metadata[name] instanceof Array)
metadata[name].push(value);
else if (metadata[name] instanceof Object) {
[rName, rValue] = value.split(/\s+/); // each resource is named
metadata[name][rName] = rValue;
}
else
metadata[name] = value;
}
return metadata;
}
// example usage
GM_log("version: " + scriptMetadata["version"]);
GM_log("res1: " + scriptMetadata["resource"]["res1"]);
This is working nicely in my scripts.
EDIT: Added @resource and @require, which were introduced in Greasemonkey 0.8.0.
EDIT: FF5+ compatibility, Array.filter() no longer accepts a regular expression