node-red/packages/node_modules/@node-red/editor-api/lib/editor/theme.js

344 lines
12 KiB
JavaScript
Raw Normal View History

2015-04-13 01:11:11 +02:00
/**
* Copyright JS Foundation and other contributors, http://js.foundation
2015-04-13 01:11:11 +02:00
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
var express = require("express");
var util = require("util");
var path = require("path");
var fs = require("fs");
2015-04-13 23:15:15 +02:00
var clone = require("clone");
2015-04-13 01:11:11 +02:00
2015-04-13 23:15:15 +02:00
var defaultContext = {
2015-04-13 01:11:11 +02:00
page: {
title: "Node-RED",
2016-02-08 15:20:07 +01:00
favicon: "favicon.ico",
tabicon: {
icon: "red/images/node-red-icon-black.svg",
colour: "#8f0000"
},
version: require(path.join(__dirname,"../../package.json")).version
2015-04-13 01:11:11 +02:00
},
header: {
title: "Node-RED",
2019-06-21 17:08:43 +02:00
image: "red/images/node-red.svg"
},
asset: {
2021-10-04 18:53:14 +02:00
red: "red/red.min.js",
main: "red/main.min.js",
2021-04-29 17:53:59 +02:00
vendorMonaco: ""
}
2015-04-13 01:11:11 +02:00
};
var theme = null;
2015-04-13 23:15:15 +02:00
var themeContext = clone(defaultContext);
2015-04-13 01:11:11 +02:00
var themeSettings = null;
2021-01-26 14:35:40 +01:00
var activeTheme = null;
var activeThemeInitialised = false;
var runtimeAPI;
var themeApp;
2015-04-13 01:11:11 +02:00
function serveFile(app,baseUrl,file) {
try {
var stats = fs.statSync(file);
var url = baseUrl+path.basename(file);
//console.log(url,"->",file);
app.get(url,function(req, res) {
2015-07-15 23:43:24 +02:00
res.sendFile(file);
2015-04-13 01:11:11 +02:00
});
2015-04-13 11:37:30 +02:00
return "theme"+url;
2015-04-13 01:11:11 +02:00
} catch(err) {
//TODO: log filenotfound
return null;
}
}
2021-01-26 14:35:40 +01:00
function serveFilesFromTheme(themeValue, themeApp, directory, baseDirectory) {
var result = [];
if (themeValue) {
var array = themeValue;
if (!util.isArray(array)) {
array = [array];
}
2017-07-04 10:43:16 +02:00
for (var i=0;i<array.length;i++) {
2021-01-26 14:35:40 +01:00
let fullPath = array[i];
if (baseDirectory) {
fullPath = path.resolve(baseDirectory,array[i]);
if (fullPath.indexOf(path.resolve(baseDirectory)) !== 0) {
2021-01-26 14:35:40 +01:00
continue;
}
}
var url = serveFile(themeApp,directory,fullPath);
if (url) {
result.push(url);
}
}
}
return result
}
2015-04-13 01:11:11 +02:00
module.exports = {
2021-01-26 14:35:40 +01:00
init: function(settings, _runtimeAPI) {
runtimeAPI = _runtimeAPI;
2015-04-13 23:15:15 +02:00
themeContext = clone(defaultContext);
2021-10-04 18:53:14 +02:00
if (process.env.NODE_ENV == "development") {
themeContext.asset.red = "red/red.js";
themeContext.asset.main = "red/main.js";
}
2015-04-13 23:15:15 +02:00
themeSettings = null;
theme = settings.editorTheme || {};
themeContext.asset.vendorMonaco = "vendor/monaco/monaco-bootstrap.js"
if (theme.codeEditor && theme.codeEditor.lib === 'ace') {
themeContext.asset.vendorMonaco = ''
}
2021-01-26 14:35:40 +01:00
activeTheme = theme.theme;
},
2015-07-15 23:43:24 +02:00
app: function() {
2016-01-08 14:41:33 +01:00
var i;
var url;
themeSettings = {};
2015-07-15 23:43:24 +02:00
themeApp = express();
2015-07-15 23:43:24 +02:00
if (theme.page) {
2015-07-15 23:43:24 +02:00
themeContext.page.css = serveFilesFromTheme(
theme.page.css,
themeApp,
"/css/")
themeContext.page.scripts = serveFilesFromTheme(
theme.page.scripts,
themeApp,
"/scripts/")
2015-07-15 23:43:24 +02:00
if (theme.page.favicon) {
url = serveFile(themeApp,"/favicon/",theme.page.favicon)
if (url) {
themeContext.page.favicon = url;
}
2015-04-13 01:11:11 +02:00
}
2016-02-08 15:20:07 +01:00
if (theme.page.tabicon) {
let icon = theme.page.tabicon.icon || theme.page.tabicon
url = serveFile(themeApp,"/tabicon/", icon)
2016-02-08 15:20:07 +01:00
if (url) {
themeContext.page.tabicon.icon = url;
}
if (theme.page.tabicon.colour) {
themeContext.page.tabicon.colour = theme.page.tabicon.colour
2016-02-08 15:20:07 +01:00
}
}
2015-07-15 23:43:24 +02:00
themeContext.page.title = theme.page.title || themeContext.page.title;
// Store the resolved urls to these resources so nodes (such as Debug)
// can access them
theme.page._ = {
css: themeContext.page.css,
scripts: themeContext.page.scripts,
favicon: themeContext.page.favicon
}
}
2015-07-15 23:43:24 +02:00
if (theme.header) {
2015-07-15 23:43:24 +02:00
themeContext.header.title = theme.header.title || themeContext.header.title;
2015-07-15 23:43:24 +02:00
if (theme.header.hasOwnProperty("url")) {
themeContext.header.url = theme.header.url;
2015-04-13 01:11:11 +02:00
}
2015-07-15 23:43:24 +02:00
if (theme.header.hasOwnProperty("image")) {
if (theme.header.image) {
url = serveFile(themeApp,"/header/",theme.header.image);
if (url) {
themeContext.header.image = url;
}
} else {
themeContext.header.image = null;
}
}
}
2015-07-15 23:43:24 +02:00
if (theme.deployButton) {
if (theme.deployButton.type == "simple") {
themeSettings.deployButton = {
type: "simple"
}
if (theme.deployButton.label) {
themeSettings.deployButton.label = theme.deployButton.label;
}
if (theme.deployButton.icon) {
url = serveFile(themeApp,"/deploy/",theme.deployButton.icon);
2015-04-13 11:37:30 +02:00
if (url) {
themeSettings.deployButton.icon = url;
2015-04-13 11:37:30 +02:00
}
}
}
}
2015-07-15 23:43:24 +02:00
if (theme.hasOwnProperty("userMenu")) {
themeSettings.userMenu = theme.userMenu;
}
if (theme.login) {
if (theme.login.image) {
url = serveFile(themeApp,"/login/",theme.login.image);
if (url) {
themeContext.login = {
image: url
}
}
2015-04-13 14:55:17 +02:00
}
}
2021-01-26 14:35:40 +01:00
themeApp.get("/", async function(req,res) {
const themePluginList = await runtimeAPI.plugins.getPluginsByType({type:"node-red-theme"});
themeContext.themes = themePluginList.map(theme => theme.id);
res.json(themeContext);
})
2015-07-15 23:43:24 +02:00
if (theme.hasOwnProperty("menu")) {
themeSettings.menu = theme.menu;
2015-04-13 01:11:11 +02:00
}
if (theme.hasOwnProperty("palette")) {
themeSettings.palette = theme.palette;
}
if (theme.hasOwnProperty("projects")) {
themeSettings.projects = theme.projects;
}
if (theme.hasOwnProperty("keymap")) {
themeSettings.keymap = theme.keymap;
}
2021-01-26 14:35:40 +01:00
if (theme.theme) {
themeSettings.theme = theme.theme;
}
if (theme.hasOwnProperty("tours")) {
themeSettings.tours = theme.tours;
}
return themeApp;
2015-04-13 01:11:11 +02:00
},
2021-01-26 14:35:40 +01:00
context: async function() {
if (activeTheme && !activeThemeInitialised) {
const themePlugin = await runtimeAPI.plugins.getPlugin({
id:activeTheme
});
if (themePlugin) {
if (themePlugin.css) {
const cssFiles = serveFilesFromTheme(
themePlugin.css,
themeApp,
"/css/",
themePlugin.path
);
themeContext.page.css = cssFiles.concat(themeContext.page.css || [])
theme.page = theme.page || {_:{}}
theme.page._.css = cssFiles.concat(theme.page._.css || [])
2021-01-26 14:35:40 +01:00
}
if (themePlugin.scripts) {
const scriptFiles = serveFilesFromTheme(
themePlugin.scripts,
themeApp,
"/scripts/",
themePlugin.path
)
themeContext.page.scripts = scriptFiles.concat(themeContext.page.scripts || [])
theme.page = theme.page || {_:{}}
2021-07-07 15:12:58 +02:00
theme.page._.scripts = scriptFiles.concat(theme.page._.scripts || [])
2021-01-26 14:35:40 +01:00
}
// check and load page settings from theme
if (themePlugin.page) {
if (themePlugin.page.favicon && !theme.page.favicon) {
const result = serveFilesFromTheme(
[themePlugin.page.favicon],
themeApp,
"/",
themePlugin.path
)
if(result && result.length > 0) {
// update themeContext page favicon
themeContext.page.favicon = result[0]
theme.page = theme.page || {_:{}}
theme.page._.favicon = result[0]
}
}
if (themePlugin.page.tabicon && themePlugin.page.tabicon.icon && !theme.page.tabicon) {
const result = serveFilesFromTheme(
[themePlugin.page.tabicon.icon],
themeApp,
"/page/",
themePlugin.path
)
if(result && result.length > 0) {
// update themeContext page tabicon
themeContext.page.tabicon.icon = result[0]
themeContext.page.tabicon.colour = themeContext.page.tabicon.colour || themeContext.page.tabicon.colour
theme.page = theme.page || {_:{}}
theme.page._.tabicon = theme.page._.tabicon || {}
theme.page._.tabicon.icon = themeContext.page.tabicon.icon
theme.page._.tabicon.colour = themeContext.page.tabicon.colour
}
}
// if the plugin has a title AND the users settings.js does NOT
if (themePlugin.page.title && !theme.page.title) {
themeContext.page.title = themePlugin.page.title || themeContext.page.title
}
}
// check and load header settings from theme
if (themePlugin.header) {
if (themePlugin.header.image && !theme.header.image) {
const result = serveFilesFromTheme(
[themePlugin.header.image],
themeApp,
"/header/",
themePlugin.path
)
if(result && result.length > 0) {
// update themeContext header image
themeContext.header.image = result[0]
}
}
// if the plugin has a title AND the users settings.js does NOT have a title
if (themePlugin.header.title && !theme.header.title) {
themeContext.header.title = themePlugin.header.title || themeContext.header.title
}
// if the plugin has a header url AND the users settings.js does NOT
if (themePlugin.header.url && !theme.header.url) {
themeContext.header.url = themePlugin.header.url || themeContext.header.url
}
}
theme.codeEditor = theme.codeEditor || {}
theme.codeEditor.options = Object.assign({}, themePlugin.monacoOptions, theme.codeEditor.options);
2021-01-26 14:35:40 +01:00
}
activeThemeInitialised = true;
}
2015-04-13 01:11:11 +02:00
return themeContext;
},
settings: function() {
return themeSettings;
},
serveFile: function(baseUrl,file) {
return serveFile(themeApp,baseUrl,file);
2015-04-13 01:11:11 +02:00
}
}