Is there a way to tell a Tampermonkey
script running in Chromium
to use a relative @require
file path? For example, if I have the following script header:
// ==UserScript==
// @name test
// @namespace http://tampermonkey.net/
// @version 0.1
// @description test script
// @author me
// @match *://*/*
// @require file://relative/path/to/external.js
// @grant GM_setValue
// @grant GM_getValue
// ==/UserScript==
Am I able to use @require
with file://
and make it relative to my user's Chromium profile or the Tampermonkey extension directory? If that's not possible, is there a way to pass a parameter to the Tampermonkey script at time of Chromium launch or include the external .js file in a different way inside the script?
To clarify, I'm trying to create a Kiosk system and the users need the ability to specify which dashboards are displayed and some of those require logins. I want to allow them to specify the required information in an external .js file. Here is the code and example external file.
sample logins.js
var config =
{
"sites": [
{
"description": "All X dashboards",
"site": "https://dashboards.X.com/index.php?return=",
"username": "username",
"password": "password",
"form": "form-login",
"username_field": "login",
"password_field": "password",
"submit_button": "button-login",
"redirect": ""
}
};
Tampermonkey script that uses external file
// ==UserScript==
// @name test
// @namespace http://tampermonkey.net/
// @version 0.1
// @description test script
// @author me
// @match *://*/*
// @require file://relative/path/to/logins.js
// @grant GM_setValue
// @grant GM_getValue
// ==/UserScript==
var delay = 500;
var attempts = 0;
var maxAttempts = 40;
(function() {
'use strict';
var url = GM_getValue("redirect");
if (url !== undefined && url !== null)
{
GM_setValue("redirect", null);
document.location.href = url;
return;
}
var site = null;
for (var i = 0, len = config.sites.length; i < len; i++)
{
if (document.location.href.includes(config.sites[i].site))
{
site = config.sites[i];
break;
}
}
if (site === null)
return;
setTimeout(doLogin.bind(null, site), delay);
})();
function doLogin(site)
{
var form = document.forms[site.form];
if (!form)
form = document.forms[0];
var username = form[site.username_field];
var password = form[site.password_field];
if (!form || !username || !password)
{
attempts++;
if (attempts > maxAttempts)
return;
setTimeout(doLogin.bind(null, site), delay);
}
username.value = site.username;
password.value = site.password;
var login = form[site.submit_button];
if (site.redirect && site.redirect.length > 0)
GM_setValue("redirect", site.redirect);
if (login)
login.click();
else
form.submit();
}
Due to the nature of the kiosk and Chromium, I would like to have this path relative and not absolute since being absolute would mean I have to hard code a path and hard coding anything is bad.
Doing some testing with scripts and Process Monitor
, I don't believe there's a way to do an actual relative path, but if I specify file:///filename.js
or even try to make that relative by using something like file:///../filename.js
, Chromium
will attempt to read the file from the directory that contains chrome.exe
.
For my purposes, the path to the chrome.exe
file is known and controlled by me, I can place my "relative" path scripts in that directory and reference them as file:///filename.js
Again, just to be clear in case someone else finds this useful. If I have my chrome.exe
file in c:\kiosk\chrome\chrome.exe and I use @require file:///filename.js then chrome will attempt to load:
c:\kiosk\chrome\filename.js
This will also work for any relative path inside the chrome directory, i.e. file:///scripts/filename.js will resolve to c:\kiosk\chrome\scripts\filename.js