From 87468c5731d973b6f2315936d2d5760d9cf65961 Mon Sep 17 00:00:00 2001 From: Jo-Philipp Wich Date: Sun, 12 Apr 2020 22:54:02 +0200 Subject: [PATCH] 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 (cherry picked from commit 0d0ad80fd1b96ff2c33392387320ad518640782b) --- .../htdocs/luci-static/resources/luci.js | 65 ++++++++++++++++++- 1 file changed, 63 insertions(+), 2 deletions(-) diff --git a/modules/luci-base/htdocs/luci-static/resources/luci.js b/modules/luci-base/htdocs/luci-static/resources/luci.js index 954a8aa2b..ea656e21c 100644 --- a/modules/luci-base/htdocs/luci-static/resources/luci.js +++ b/modules/luci-base/htdocs/luci-static/resources/luci.js @@ -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 */ -- 2.25.1