luci-base: luci.js: add ability to add "preload" classes

Extend the LuCI bootstrap procedure to scan for class files in
/www/luci-static/preload/. Any JavaScript file found there will be
required automatically before setting up the view, allowing to stage
code that should run on every page load.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
(cherry picked from commit 0d0ad80fd1)
This commit is contained in:
Jo-Philipp Wich 2020-04-12 22:54:02 +02:00
parent 3c6dd6deec
commit 87468c5731

View file

@ -2087,7 +2087,8 @@
domParser = null,
originalCBIInit = null,
rpcBaseURL = null,
sysFeatures = null;
sysFeatures = null,
preloadClasses = null;
/* "preload" builtin classes to make the available via require */
var classes = {
@ -2486,6 +2487,55 @@
return Promise.resolve(sysFeatures);
},
probePreloadClasses: function() {
var sessionid = classes.rpc.getSessionID();
if (preloadClasses == null) {
try {
var data = JSON.parse(window.sessionStorage.getItem('preloadClasses'));
if (this.isObject(data) && this.isObject(data[sessionid]))
preloadClasses = data[sessionid];
}
catch (e) {}
}
if (!Array.isArray(preloadClasses)) {
preloadClasses = this.resolveDefault(classes.rpc.declare({
object: 'file',
method: 'list',
params: [ 'path' ],
expect: { 'entries': [] }
})(this.fspath(this.resource('preload'))), []).then(function(entries) {
var classes = [];
for (var i = 0; i < entries.length; i++) {
if (entries[i].type != 'file')
continue;
var m = entries[i].name.match(/(.+)\.js$/);
if (m)
classes.push('preload.%s'.format(m[1]));
}
try {
var data = {};
data[sessionid] = classes;
window.sessionStorage.setItem('preloadClasses', JSON.stringify(data));
}
catch (e) {}
preloadClasses = classes;
return classes;
});
}
return Promise.resolve(preloadClasses);
},
/**
* Test whether a particular system feature is available, such as
* hostapd SAE support or an installed firewall. The features are
@ -2577,7 +2627,18 @@
L.notifySessionExpiry();
});
return this.probeSystemFeatures().finally(this.initDOM);
return Promise.all([
this.probeSystemFeatures(),
this.probePreloadClasses()
]).finally(L.bind(function() {
var tasks = [];
if (Array.isArray(preloadClasses))
for (var i = 0; i < preloadClasses.length; i++)
tasks.push(this.require(preloadClasses[i]));
return Promise.all(tasks);
}, this)).finally(this.initDOM);
},
/* private */