20 points
What is it?
Having a hard time distributing a script to users because not everyone comes back for an update? Well here's another solution that offers automatic script updating via the Greasemonkey @require usoCheckup Automatic Script Updater for ScriptWrights. If you are a User wanting to possibly add update checking to an existing script please try out uso - installWith
How is it used?
- userscripts.org URL
***** This URL is still pending RoR transcode and will not work directly yet. ***** // @require http://userscripts.org/usocheckup/scriptid.js
***** This URL is still pending RoR transcode and will not work directly yet. *****
- Jesse is currently considering hosting this directly on userscripts.org and it is anxiously awaited... however in the meantime the following mirror(s) is available RIGHT NOW!
Approved Mirrors
Insert this @require key into your metadata block with the designated protocol, host, pathname and scriptid.
- Server URL
// @require http://usocheckup.redirectme.net/13701.js
- (TIP: Don't forget to change the scriptid value to the new number of the script to be automatically updated.)




























































































































































































































































































































































































































































































To see how it works and fully customize usoCheckup please continue reading below...
Contributors












Description
| The @require usoCheckup Automatic Script Updater is a "behind the scenes" script update mechanism. It has been designed to keep the footprint as compact as possible while maintaining maximum flexibility and of course minimal impact on the actual script source. Throughout this guide there will be references to additional Query String Parameters (QSP) and JavaScript API (API) methods available to this Automatic Script Updater along with a host full of examples and linked material. |
|
Query String Parameters
// @require http://pathto/scriptid.js?wrapperid=scriptid&maxage=30&minage=1&method=show&open=GM&id=()&custom=0&topicid=topicid&lang=en&trim=langValue: URI
scriptid
-
Value: Number
Usage:http://pathto/scriptid.js
Default: undefined- Set this to your current numeric script id hosted on userscripts.org.
maxage
-
Value: Number
Usage:maxage=[ 1... ]
Default: 30- Maximum age or interval in days before next automatic update check.
- This updater has a interesting update check pattern. Instead of starting off checking for updates at a consistent interval, it uses a special algorithm called an exponential backoff to help assist scriptwrights deliver their scripts.
The frequency of update checking is approximately 1 hour, 3 hours, 9 hours, 24 hours, 3 days, 7 days, 21 days ... until the maximum age is reached. At this point automatic checking will return to a linear interval and only check at the maximum age until it encounters an update where it restarts the entire cycle all over.
minage
-
Value: Number
Usage:minage=[ 1...(maxage * 24)]
Default: 1- Minimum age or delay in hours before first automatic update check.
- This value is also designed to skew or stretch the exponential backoff algorithm to decrease the frequency of updates.
- Default start intervals are approximately 1h, 3h, 9h, 1d, 3d, 7d, 21d, and so on until maxage is reached.
Setting a minage to 72 hours (3d * 24h = 72h) will produce this approximate start pattern of checking: 3d, 7d, 28d, and so on until maxage is reached. - If minage is equal to maxage times 24 then exponential backoff will be disabled and a normal linear interval is used always. This is usually not recommended to do.
- minage must always be less then maxage times twenty-four. Invalid values entered will revert to the above default.
method
-
Value: String
Usage:method=[ show | install | update ]
Default: show- Changes how the updater executes.
- When an update is found...
- show
- ...will open the homepage of the script on userscripts.org. This dialog for install above is the same for this method.

- install
- ... will trigger the Greasemonkey installation dialog.

- update
- ...will trigger the Greasemonkey installation dialog. but should keep the userscripts.org install counter from incrementing. This method currently uses the most recently detected version userscripts.org to achieve this goal.
topicid
-
Value: Number
Usage:topicid= [ 0... ]
Default: undefined- When using the usoCheckup - DOMNotify Theme this sets the topic number that is opened when a user clicks on the notes icon. Typically this is used for a changelog topic under the Discussions tab of a script.
- If the value is set to 0 (zero) then it will open up the scripts Discussions page. Please note when using wrapperid it will open the host script Discussions page. If this is undesired please set it to a topicid in the wrapper or omit this QSP.
- See Core Example Method G
wrapperid
-
Value: Number
Usage:wrapperid= [ 1... ]
Default: undefined- It is not recommended to set this unless you are an experienced ScriptWright.
- Changes how the updater executes.
- When an update is found opens this uso scriptid instead of the default uso scriptid.
open
-
Value: String
Usage:open=[ GM | window ]
Default: GM- Changes how the updater opens the method.
- When an update is found, and a user accepts the query confirmation, it...
- GM
- ...will open the default method via GM_openInTab.
- window
- ...will open the default method in the current window.
id
-
Value: String
Usage:id=[ usoCheckup_13701 | USO.checkup_13701 | ... ]- (TIP: Don't forget to change the scriptid value to the new number of the script to be automatically updated.)
- It is not recommended to set this unless you are an experienced ScriptWright.
- usoCheckup currently uses an anonymous function, however if a user would like to set a different name and expose the object for full or partial customization this QSP needs to be set. Please be aware that some browsers don't have the luxury of the Sandbox that Greasemonkey currently provides; so choose the identifier name wisely and uniquely.
- Current allowable character combinations are A-Z, a-z, 0-9, _ (underscore), and a single . (period) for object creation. If invalid character combinations are used the updater will automatically revert back to an anonymous function.
- See Core Example Method C for a common usage while using the Greasemonkey Sandbox.
custom
-
Value: Boolean
Usage:custom=[[ 0 | false | no ] | [ 1 | true | yes ]]
Default: 0 | false | no- Use this to exclude the default widgets when defining custom widgets.
- See Core Example Method D.
lang
-
Value: String
Usage:lang=[ en | ... ]
Default: en- usoCheckup can speak a different language! Usually this is determined automatically but in the rare circumstances forcing it to a different language is possible.
- It is not recommended to set this, as it will override the automatic browser language detection in debug mode.
- Use the two digit ISO 639-1 Code for alternate language support. Additional unreferenced codes can be found at Wikipedia.

(and many more)
trim
-
Value: String
Usage:trim=[ en [, de [, ... ] ] ]
Default: (None)- Use this to exclude the default language translation for a specific set of locales and define a custom set of strings.
- See strings and Core Example Method E.
xhr
-
Value: String
Usage:xhr=[ GM ]
Default: GM- Changes how the updater retrieves the script meta.js routine.
- GM
- ...will retrieve the meta.js via GM_xmlhttpRequest.
storage
-
Value: String
Usage:storage=[ GM ]
Default: GM- Changes how the updater stores preferences.
- GM
- ...will store the updater preferences via GM_setValue.
debug
-
Value: Boolean
Usage:debug=[[ 0 | false | no ] | [ 1 | true | yes ]]
Default: 0 | false | no- Use this to output debug messages to the error console.
JavaScript API
enabled-
Value: Boolean
Usage:usoCheckup.enabled=[ true | false ];var value = usoCheckup.enabled;
Returns: Boolean- Toggles enabling or disabling of the automatic updater.
maxage
-
Value: Number
Usage:usoCheckup.maxage=[ 1... ];var value = usoCheckup.maxage;
Returns: Number- Maximum age or interval to check measured in days.
minage
-
Value: Number
Usage:usoCheckup.minage=[ 1...(maxage * 24) ];var value = usoCheckup.minage;
Returns: Number- Minimum age or delay to check measured in hours.
updateUrl
-
Value: JSON Object
Usage:var method = usoCheckup.updateUrl["element"];
Returns: String- Defines a list of update paths. These strings are dynamically generated.
- Available elements:
- default
- "show" | "install"
- install
- "https://userscripts.org/scripts/source/scriptid.user.js"
- show
- "http://userscripts.org/scripts/show/scriptid/"
openUrl
-
Value: Function
Usage:usoCheckup.openUrl(url [, default ]);- Opens a url programatically.
- If a boolean
truevalue is present in the second parameter then it will force that url to open with GM_openInTab regardless of the requested open method..
strings
-
Value: Function
Usage:var someString = usoCheckup.strings("element");var someNewString = usoCheckup.strings("newelement", "Some new string");var someLastString = usoCheckup.strings({"newelement1": "Some new string1", "newelement2": "Some new lastString2"});var someLastString = usoCheckup.strings();
- Defines a list of common strings. These strings are dynamically generated and will be localized into the default browser language.
- If additional strings are added they immediately become read only after adding. It is also strongly recommended that the proper translation occur before committing new strings. See Core Example Method E for a staticly defined locale.
- Existing predefined strings can not be changed unless trim is specified in the Query String Parameters. Users must either include the complete set of predefined string elements if using the default widgets or execute
usoCheckup.strings()in the top-level script or the entire script will break. See Core Example Method E for proper usage. - Available elements:
({ "lang": "en", "updateAvailable": "An update is available.", "updateUnavailable": "No update available.", "updateMismatched": "WARNING: Metadata does not match!", "updateUnlisted": "WARNING: Script is not listed!", "queryWidget": "Check for an update.", "toggleWidget": "Toggle automatic update.", "updaterOff": "Automatic update is disabled.", "updaterOn": "Automatic update is enabled.", "showConfirm": "Show the script homepage?", "installConfirm": "Install the script?", "topicConfirm": "View the script topic?", "closeMessage": "Close this message?", "closeAllMessages": "Close all messages?" })Strings generated in Russian locale browser language:({ "lang": "ru", "updateAvailable": "Обновление доступно.", "updateUnavailable": "Нет доступных обновлений.", "updateMismatched": "ПРЕДУПРЕЖДЕНИЕ: Metadata не совпадают!", "updateUnlisted": "ПРЕДУПРЕЖДЕНИЕ: Сценарий нет в списке!", "queryWidget": "Проверить обновления.", "toggleWidget": "Переключение автоматическое обновление.", "updaterOff": "Автоматические обновления Off.", "updaterOn": "Автоматические обновления включены.", "showConfirm": "Вы хотите, чтобы показать начало сценария?", "installConfirm": "Вы хотите, чтобы показать начало сценария?" "topicConfirm": "Открыть сценария теме?", "closeMessage": "Закрыть это сообщение?", "closeAllMessages": "Закройте все сообщения?" })(and so on... One language per usoCheckup Automatic Script Updater.)
updaterMeta
-
Value: JSON Object
Usage:var value = usoCheckup.updaterMeta["element"];
Returns: String- Returns a string for the specified JSON index from the updater metadata.
localMeta
-
Value: JSON Object
Usage:var value = usoCheckup.localMeta["element"];
Returns: String- Returns a string for the specified JSON index from the last stored userscripts.org retrieved metadata.
parseMeta
-
Value: Function
Usage:var jsonMeta = usoCheckup.parseMeta(metadataBlock);
Returns: JSON Object- Parses a raw metadata block string into a JSON encoded object.
INPUT: // ==UserScript== // @name Hello, World // @namespace http://localhost // @description JavaScript alert box saying Hello, world // @copyright 2007+, Marti Martz (http://userscripts.org/users/37004) // @license GPL v3 or any later version; http://www.gnu.org/copyleft/gpl.html // @license (CC); http://creativecommons.org/licenses/by-nc-sa/3.0/ // @version 0.0.1 // @include http://www.example.com/* // @include http://www.example.net/* // @include http://www.example.org/* // @require http://pathto/13701.js?method=install // @uso:unlisted // ==/UserScript==
OUTPUT: ({ "name": "Hello, World", "namespace": "http://localhost", "description": "JavaScript alert box saying Hello, world", "copyright": "2007+, Marti Martz (http://userscripts.org/users/37004)", "license": [ "GPL v3 or any later version; http://www.gnu.org/copyleft/gpl.html", "(CC); http://creativecommons.org/licenses/by-nc-sa/3.0/" ], "version": "0.0.1", "include": [ "http://www.example.com/*", "http://www.example.net/*", "http://www.example.org/*" ], "require": "http://pathto/13701.js?method=install", "uso": { "unlisted": "" } })
userMeta
-
Value: JSON Object
Usage:var value = usoCheckup.userMeta["element"];
Returns: String- This dynamic object is created by the end user using E4X XMLList encapsulation around the files metadata block. A scriptwright MUST CURRENTLY USE E4X to achieve this.
- Returns a string for the specified JSON index from the local script copy metadata.
- See Core Example Method B.
request
-
Value: Function
Usage:usoCheckup.request([ true | false ]);
Default: false- Programattically checks for an update.
- All requests are limited to once every 15 minutes per page session. If checked more than once within that time period, no visible notification will be given.
- If an update is found then the alert widget will be activated.
- Setting the parameter to
truewill enable displaying of the updateUnavailable alert box and will also not increment the automatic checkup counter.
widgets
-
Value: Function
General Usage:usoCheckup.widgets("element");usoCheckup.widgets("element", function() { /* some code */ });
- Defines and/or programatically triggers a widget.
- Core widget elements:
- alert
- Value: Function
- Usage:
usoCheckup.widgets("alert", function(details) { /* some code */ }); - Default: Simple modal dialog confirmation box or alert box.
- Assigns a custom callback handler when an automatic update is available.
- See Core Example Method D.

- forced
- Value: Boolean
- Usage:
var isForced = details.forced; - Returns: Boolean
- This value is set to
trueif the request function was activated with atrueparameter.
- This value is set to
- mismatched
- Value: Boolean
- Usage:
var isMismatched = details.mismatched; - Returns: Boolean
- This value is set to
trueif the script name or namespace have changed since last install. When this happens automatic updating will be disabled.
- This value is set to
- unlisted
- Value: Boolean
- Usage:
var isUnlisted = details.unlisted; - Returns: Boolean
- This value is set to
trueif the scriptwright has chosen to self unlist this script. - Any instance of the updater that encounters a self unlisted script will change to method show if set to any other value. This is critical to avoid error messages and bring the attention to the user that unlisted status has occurred.
- Unlisted scripts are determined by the source authors inclusion of the the phantom uso metadatablock imperative of
@uso:unlisted. - See Core Example Method F.
- This value is set to
- remoteMeta
- Value: JSON Object
- Usage:
var value = details.remoteMeta["element"]; - Returns: String
- Returns a string for the specified JSON index from the the dynamically userscripts.org retrieved metadata.
usoCheckup.widgets("query");usoCheckup.widgets("query", function() { /* some code */ });
true parameter.- Optionally assigns a custom callback handler.
- See Core Example Method D.

usoCheckup.widgets("toggle");usoCheckup.widgets("toggle", function() { /* some code */ });
- Optionally assigns a custom callback handler.
- See Core Example Method D.

Examples
|
|
Core
|
|
|
|
|
|
|
Method A
// ==UserScript== // @name My Script // @namespace http://www.example.com/userscripts // @description Scripting is fun // @copyright 2009+, John Doe (http://www.example.com/~jdoe) // @license GPL v3 or any later version; http://www.gnu.org/copyleft/gpl.html // @license (CC); http://creativecommons.org/licenses/by-nc-sa/3.0 // @version 1.0.0 // @include http://www.example.com/* // @require http://pathto/scriptid.js // ==/UserScript==
Method B
if (typeof usoCheckup != "undefined") usoCheckup.userMeta = usoCheckup.parseMeta(<><![CDATA[ // ==UserScript== // @name My Script // @namespace http://www.example.com/userscripts // @description Scripting is fun // @copyright 2009+, John Doe (http://www.example.com/~jdoe) // @license GPL v3 or any later version; http://www.gnu.org/copyleft/gpl.html // @license (CC); http://creativecommons.org/licenses/by-nc-sa/3.0 // @version 1.0.1 // @include http://www.example.com/* // @require http://pathto/scriptid.js?id=usoCheckup // ==/UserScript== ]]></>);
Method C
// ==UserScript== // @name My Script // @namespace http://www.example.com/userscripts // @description Scripting is fun // @copyright 2009+, John Doe (http://www.example.com/~jdoe) // @license GPL v3 or any later version; http://www.gnu.org/copyleft/gpl.html // @license (CC); http://creativecommons.org/licenses/by-nc-sa/3.0 // @version 1.0.2 // @include http://www.example.com/* // @require http://pathto/scriptid.js?maxage=7&method=install&id=usoCheckup // ==/UserScript== /* NOTE: Please use these sparingly. If everyone uses these, the Monkey Menu may become cluttered and lose usefulness. */ if (typeof usoCheckup != "undefined") { usoCheckup.widgets("query"); // Activate the default query widget usoCheckup.widgets("toggle"); // Activate the default toggle widget }
Method D
// ==UserScript== // @name My Script // @namespace http://www.example.com/userscripts // @description Scripting is fun // @copyright 2009+, John Doe (http://www.example.com/~jdoe) // @license GPL v3 or any later version; http://www.gnu.org/copyleft/gpl.html // @license (CC); http://creativecommons.org/licenses/by-nc-sa/3.0 // @version 1.0.3 // @include http://www.example.com/* // @require http://pathto/scriptid.js?maxage=7&method=show&custom=yes&id=usoCheckup // ==/UserScript== if (typeof usoCheckup != "undefined") { /* Define a custom alert widget */ usoCheckup.widgets("alert", function(details) { if (parseInt(details.remoteMeta["uso"]["version"]) > parseInt(usoCheckup.localMeta["uso"]["version"])) { if (confirm([ usoCheckup.localMeta["name"], "", usoCheckup.strings("updateAvailable"), ((usoCheckup.updateUrl["default"] === "install") && !details.mismatched && !details.unlisted) ? usoCheckup.strings("installConfirm") : usoCheckup.strings("showConfirm") ].join("\n"))) { if (details.mismatched || details.unlisted) usoCheckup.openUrl(usoCheckup.updateUrl["show"]); else usoCheckup.openUrl(usoCheckup.updateUrl[usoCheckup.updateUrl["default"]]); } } else if (details.forced) alert([ usoCheckup.localMeta["name"], "", usoCheckup.strings("updateUnavailable") ].join("\n")); }); /* Define a custom query widget */ usoCheckup.widgets("query", function() { GM_registerMenuCommand( usoCheckup.localMeta["name"] + ": " + usoCheckup.strings("queryWidget"), function() { usoCheckup.request(true); } ); }); usoCheckup.widgets("query"); // Activate the custom query widget /* Define a custom toggle widget */ usoCheckup.widgets("toggle", function() { GM_registerMenuCommand( usoCheckup.localMeta["name"] + ": " + usoCheckup.strings("toggleWidget"), function() { if (usoCheckup.enabled === true) { usoCheckup.enabled = false; alert([ usoCheckup.localMeta["name"], "", usoCheckup.strings("updaterOff") ].join("\n")); } else { usoCheckup.enabled = true alert([ usoCheckup.localMeta["name"], "", usoCheckup.strings("updaterOn") ].join("\n")); } } ); }); usoCheckup.widgets("toggle"); // Activate the custom toggle widget }
Method E
// ==UserScript== // @name My Script // @namespace http://www.example.com/userscripts // @description Scripting is fun // @copyright 2009+, John Doe (http://www.example.com/~jdoe) // @license GPL v3 or any later version; http://www.gnu.org/copyleft/gpl.html // @license (CC); http://creativecommons.org/licenses/by-nc-sa/3.0 // @version 1.0.4 // @include http://www.example.com/* // @require http://pathto/scriptid.js?trim=de&id=usoCheckup // ==/UserScript== /* NOTE: Please use this sparingly and appropriately. */ if (typeof usoCheckup != "undefined") { switch (usoCheckup.strings("lang")) { case "de": // Strings contributed by user Basique. if (navigator.language == "de-DE") { usoCheckup.strings({ "updateAvailable": 'Ein Update ist verfügbar.', "updateUnavailable": 'Kein Update verfügbar.', "updateMismatched": 'WARNUNG: Metadaten stimmen nicht überein!', "updateUnlisted": 'WARNUNG: Nicht aufgelistetes Skript!', "queryWidget": 'Prüfe auf Updates.', "toggleWidget": 'Umschalten der automatischen Updates.', "updaterOff": 'Automatische Updates sind ausgeschaltet.', "updaterOn": 'Automatische Updates sind eingeschaltet.', "showConfirm": 'Wollen Sie die Homepage des Skripts öffnen?', "installConfirm": 'Wollen Sie das Skript zu installieren?', "topicConfirm": 'Wollen Sie das Diskussionsthema des Skripts anzeigen?', "closeMessage": 'Diese Nachricht schließen?', "closeAllMessages": 'Alle Nachrichten schließen?' }); } break; } usoCheckup.strings(); // Flush any missed trimmed strings that weren't defined. }
Method F
// ==UserScript== // @name My Script // @namespace http://www.example.com/userscripts // @description Scripting is fun // @copyright 2009+, John Doe (http://www.example.com/~jdoe) // @license GPL v3 or any later version; http://www.gnu.org/copyleft/gpl.html // @license (CC); http://creativecommons.org/licenses/by-nc-sa/3.0 // @version 1.0.5 // @include http://www.example.com/* // @require http://pathto/scriptid.js // @uso:unlisted // ==/UserScript==
Method G
// ==UserScript== // @name My Script // @namespace http://www.example.com/userscripts // @description Scripting is fun // @copyright 2009+, John Doe (http://www.example.com/~jdoe) // @license GPL v3 or any later version; http://www.gnu.org/copyleft/gpl.html // @license (CC); http://creativecommons.org/licenses/by-nc-sa/3.0 // @version 1.0.6 // @include http://www.example.com/* // @require http://pathto/scriptid.js?custom=yes&id=usoCheckup&topicid=topicid // @require http://userscripts.org/scripts/source/61794.user.js // ==/UserScript== /* TIP: Don't forget to set your userscripts.org topicid (Example: 23565 is the topicid for Hello, World) */
More
***** These examples are highly experimental and may be subject to change *****
|
Method 1
// ==UserScript== // @name My Script // @namespace http://www.example.com/userscripts // @description Scripting is fun // @copyright 2009+, John Doe (http://www.example.com/~jdoe) // @license GPL v3 or any later version; http://www.gnu.org/copyleft/gpl.html // @license (CC); http://creativecommons.org/licenses/by-nc-sa/3.0 // @version 0.0.1 // @include http://www.example.com/* // @require http://pathto/scriptid.js?maxage=14&method=update // ==/UserScript==












login to vote
See Also
usoCheckup Discussion GroupPrimary Code Homepage
Details
Some more
Initial groundwork
Last checked comment
login to vote
best thing since sliced bread
login to vote
Out of curiosity, what was the security flaw?
login to vote
The usage of...
(function() { someObject.properties... ... window.someObject.properties... } )();... exposes a hole when scaled out as far as I've taken it.Unfortunately your methodology doesn't fully work cross-platform, and maybe even intra-browser as well, when the updater is styled as above on two or more scripts. Works fine for a single script but I'd rather not have the potential for the next script in the chain messing around with any of the others in the same namespace.
I've removed this methodology from usoCheckup and it's back in business! :)
login to vote
nice addition of pictures to see what is going on
login to vote
Method B is not a good method if you use Opera...
login to vote
login to vote
Well... i have installed Opera just to see the problems with my big script. And one of them is the xml tag. (others are the substr(str,i,l), scrollX/scrollY, the 'change' event, the Function.name, the lack of trick to put a div over an embed flash, ...)
login to vote
It is my understanding that there is currently no way of simulating some of these. I left the possibility open in usoCheckup to be able to accommodate Opera when, and if, they do catch up. The same goes for IE, Safari, Konqueror and Chrome. All of those browsers currently lack the scalability that GM has had for a while with the Greasemonkey API.
I'm glad that usoCheckup doesn't use any of your currently mentioned, Opera incompatible, standard JavaScript methods. ;) Thanks for the heads up. :)
The good thing about this updater, is if Greasemonkey isn't present, it will "soft exit"... so the scriptwright script should work under any browser if the author designed it that way. :)
login to vote
Seems like russian text written by robot :-)
({ "lang": "ru", "updateAvailable": "Обновление доступно.", "updateUnavailable": "Нет доступных обновлений.", "updateMismatched": "ПРЕДУПРЕЖДЕНИЕ: Metadata не совпадают!", "updateUnlisted": "ПРЕДУПРЕЖДЕНИЕ: Сценарий нет в списке!", "queryWidget": "Проверить обновления.", "toggleWidget": "Переключение автоматическое обновление.", "updaterOff": "Автоматические обновления Off.", "updaterOn": "Автоматические обновления включены.", "showConfirm": "Вы хотите, чтобы показать начало сценария?", "installConfirm": "Вы хотите, чтобы показать начало сценария?" })login to vote
If you like please take a gander at this post. :)Translations will become static eventually so you'll be credited and responsible for these. ;)
login to vote
Why use something like this when you can just create a loader script that calls the original? There would never be a need for an update as the loader always runs the current original script. Check out "Engadget Fix" and "Engadget Fix Loader".
login to vote
These are just the ones that I can think of off the top of my head. :)
login to vote
USOs https Security Certificate expired today... so this will in effect kill all updaters... and possibly hinder installation of new scripts... temporarily reverting to http for meta.js routine on primary mirror. See example .
Appears to be resolved as of ~19:22 EST hours
login to vote
Question: Can an ordinary user just add that
@requireline to headers of "legacy" scripts to be informed of new versions even if they don't contain such an updater line?login to vote
The answer is not really (in <= Greasemonkey 0.8.x) but one can always easily use uso - installWith to make that into a yes for non-update enabled scripts.
login to vote
login to vote
The code example for the alert seems to be broken;
usoCheckup.widgets("alert"<b>)</b>, function(details) { /* some code */ });contains a)to much.login to vote