mirror of
https://github.com/node-red/node-red.git
synced 2025-03-01 10:36:34 +00:00
Compare commits
10 Commits
3.1.3
...
4503-fix-c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d876146ea5 | ||
|
|
50627cd697 | ||
|
|
d7345d5bc6 | ||
|
|
f0a9b0cf69 | ||
|
|
26ddb5c1b7 | ||
|
|
82f8b64599 | ||
|
|
7f24de442f | ||
|
|
8365310ca7 | ||
|
|
74ff0599d1 | ||
|
|
e1f2e0656b |
@@ -51,7 +51,7 @@ module.exports = {
|
|||||||
|
|
||||||
var ui = require("./ui");
|
var ui = require("./ui");
|
||||||
|
|
||||||
ui.init(runtimeAPI);
|
ui.init(settings, runtimeAPI);
|
||||||
|
|
||||||
const editorApp = apiUtil.createExpressApp(settings)
|
const editorApp = apiUtil.createExpressApp(settings)
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
**/
|
**/
|
||||||
|
const crypto = require('crypto')
|
||||||
var express = require('express');
|
var express = require('express');
|
||||||
var fs = require("fs");
|
var fs = require("fs");
|
||||||
var path = require("path");
|
var path = require("path");
|
||||||
@@ -24,13 +25,16 @@ var apiUtils = require("../util");
|
|||||||
var theme = require("./theme");
|
var theme = require("./theme");
|
||||||
|
|
||||||
var runtimeAPI;
|
var runtimeAPI;
|
||||||
|
let settings;
|
||||||
var editorClientDir = path.dirname(require.resolve("@node-red/editor-client"));
|
var editorClientDir = path.dirname(require.resolve("@node-red/editor-client"));
|
||||||
var defaultNodeIcon = path.join(editorClientDir,"public","red","images","icons","arrow-in.svg");
|
var defaultNodeIcon = path.join(editorClientDir,"public","red","images","icons","arrow-in.svg");
|
||||||
var editorTemplatePath = path.join(editorClientDir,"templates","index.mst");
|
var editorTemplatePath = path.join(editorClientDir,"templates","index.mst");
|
||||||
var editorTemplate;
|
var editorTemplate;
|
||||||
|
let cacheBuster
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
init: function(_runtimeAPI) {
|
init: function(_settings, _runtimeAPI) {
|
||||||
|
settings = _settings;
|
||||||
runtimeAPI = _runtimeAPI;
|
runtimeAPI = _runtimeAPI;
|
||||||
editorTemplate = fs.readFileSync(editorTemplatePath,"utf8");
|
editorTemplate = fs.readFileSync(editorTemplatePath,"utf8");
|
||||||
Mustache.parse(editorTemplate);
|
Mustache.parse(editorTemplate);
|
||||||
@@ -91,6 +95,12 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
editor: async function(req,res) {
|
editor: async function(req,res) {
|
||||||
|
if (!cacheBuster) {
|
||||||
|
// settings.instanceId is set asynchronously to the editor-api
|
||||||
|
// being initiaised. So we defer calculating the cacheBuster hash
|
||||||
|
// until the first load of the editor
|
||||||
|
cacheBuster = crypto.createHash('md5').update(`${settings.version || 'version'}-${settings.instanceId || 'instanceId'}`).digest("hex").substring(0,12)
|
||||||
|
}
|
||||||
|
|
||||||
let sessionMessages;
|
let sessionMessages;
|
||||||
if (req.session && req.session.messages) {
|
if (req.session && req.session.messages) {
|
||||||
@@ -99,6 +109,7 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
res.send(Mustache.render(editorTemplate,{
|
res.send(Mustache.render(editorTemplate,{
|
||||||
sessionMessages,
|
sessionMessages,
|
||||||
|
cacheBuster,
|
||||||
...await theme.context()
|
...await theme.context()
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -109,7 +109,6 @@
|
|||||||
"selectionToSubflow": "Auswahl in Subflow umwandeln",
|
"selectionToSubflow": "Auswahl in Subflow umwandeln",
|
||||||
"flows": "Flow",
|
"flows": "Flow",
|
||||||
"add": "Hinzufügen",
|
"add": "Hinzufügen",
|
||||||
"rename": "Umbenennen",
|
|
||||||
"delete": "Löschen",
|
"delete": "Löschen",
|
||||||
"keyboardShortcuts": "Tastenkürzel",
|
"keyboardShortcuts": "Tastenkürzel",
|
||||||
"login": "Anmelden",
|
"login": "Anmelden",
|
||||||
|
|||||||
@@ -122,7 +122,6 @@
|
|||||||
"selectionToSubflow": "Selection to Subflow",
|
"selectionToSubflow": "Selection to Subflow",
|
||||||
"flows": "Flows",
|
"flows": "Flows",
|
||||||
"add": "Add",
|
"add": "Add",
|
||||||
"rename": "Rename",
|
|
||||||
"delete": "Delete",
|
"delete": "Delete",
|
||||||
"keyboardShortcuts": "Keyboard shortcuts",
|
"keyboardShortcuts": "Keyboard shortcuts",
|
||||||
"login": "Login",
|
"login": "Login",
|
||||||
|
|||||||
@@ -122,7 +122,6 @@
|
|||||||
"selectionToSubflow": "Convertir en sous-flux",
|
"selectionToSubflow": "Convertir en sous-flux",
|
||||||
"flows": "Flux",
|
"flows": "Flux",
|
||||||
"add": "Ajouter",
|
"add": "Ajouter",
|
||||||
"rename": "Renommer",
|
|
||||||
"delete": "Supprimer",
|
"delete": "Supprimer",
|
||||||
"keyboardShortcuts": "Raccourcis clavier",
|
"keyboardShortcuts": "Raccourcis clavier",
|
||||||
"login": "Se connecter",
|
"login": "Se connecter",
|
||||||
|
|||||||
@@ -122,7 +122,6 @@
|
|||||||
"selectionToSubflow": "選択部分をサブフロー化",
|
"selectionToSubflow": "選択部分をサブフロー化",
|
||||||
"flows": "フロー",
|
"flows": "フロー",
|
||||||
"add": "フローを新規追加",
|
"add": "フローを新規追加",
|
||||||
"rename": "フロー名を変更",
|
|
||||||
"delete": "フローを削除",
|
"delete": "フローを削除",
|
||||||
"keyboardShortcuts": "ショートカットキーの説明",
|
"keyboardShortcuts": "ショートカットキーの説明",
|
||||||
"login": "ログイン",
|
"login": "ログイン",
|
||||||
|
|||||||
@@ -79,7 +79,6 @@
|
|||||||
"selectionToSubflow": "서브 플로우 선택",
|
"selectionToSubflow": "서브 플로우 선택",
|
||||||
"flows": "플로우",
|
"flows": "플로우",
|
||||||
"add": "추가",
|
"add": "추가",
|
||||||
"rename": "이름변경",
|
|
||||||
"delete": "삭제",
|
"delete": "삭제",
|
||||||
"keyboardShortcuts": "단축키",
|
"keyboardShortcuts": "단축키",
|
||||||
"login": "로그인",
|
"login": "로그인",
|
||||||
|
|||||||
@@ -109,7 +109,6 @@
|
|||||||
"selectionToSubflow": "Seleção para subfluxo",
|
"selectionToSubflow": "Seleção para subfluxo",
|
||||||
"flows": "Fluxos",
|
"flows": "Fluxos",
|
||||||
"add": "Adicionar",
|
"add": "Adicionar",
|
||||||
"rename": "Renomear",
|
|
||||||
"delete": "Apagar",
|
"delete": "Apagar",
|
||||||
"keyboardShortcuts": "Atalhos do teclado",
|
"keyboardShortcuts": "Atalhos do teclado",
|
||||||
"login": "Ingressar",
|
"login": "Ingressar",
|
||||||
|
|||||||
@@ -95,7 +95,6 @@
|
|||||||
"selectionToSubflow": "Выделение в подпоток",
|
"selectionToSubflow": "Выделение в подпоток",
|
||||||
"flows": "Потоки",
|
"flows": "Потоки",
|
||||||
"add": "Добавить",
|
"add": "Добавить",
|
||||||
"rename": "Переименовать",
|
|
||||||
"delete": "Удалить",
|
"delete": "Удалить",
|
||||||
"keyboardShortcuts": "Сочетания клавиш",
|
"keyboardShortcuts": "Сочетания клавиш",
|
||||||
"login": "Войти",
|
"login": "Войти",
|
||||||
|
|||||||
@@ -120,7 +120,6 @@
|
|||||||
"selectionToSubflow": "将选择部分更改为子流程",
|
"selectionToSubflow": "将选择部分更改为子流程",
|
||||||
"flows": "流程",
|
"flows": "流程",
|
||||||
"add": "增加",
|
"add": "增加",
|
||||||
"rename": "重命名",
|
|
||||||
"delete": "删除",
|
"delete": "删除",
|
||||||
"keyboardShortcuts": "键盘快捷方式",
|
"keyboardShortcuts": "键盘快捷方式",
|
||||||
"login": "登录",
|
"login": "登录",
|
||||||
|
|||||||
@@ -120,7 +120,6 @@
|
|||||||
"selectionToSubflow": "將選擇部分更改為子流程",
|
"selectionToSubflow": "將選擇部分更改為子流程",
|
||||||
"flows": "流程",
|
"flows": "流程",
|
||||||
"add": "增加",
|
"add": "增加",
|
||||||
"rename": "重新命名",
|
|
||||||
"delete": "刪除",
|
"delete": "刪除",
|
||||||
"keyboardShortcuts": "鍵盤快速鍵",
|
"keyboardShortcuts": "鍵盤快速鍵",
|
||||||
"login": "登入",
|
"login": "登入",
|
||||||
|
|||||||
@@ -39,15 +39,16 @@
|
|||||||
console.warn(evt,args);
|
console.warn(evt,args);
|
||||||
}
|
}
|
||||||
if (handlers[evt]) {
|
if (handlers[evt]) {
|
||||||
for (var i=0;i<handlers[evt].length;i++) {
|
let cpyHandlers = [...handlers[evt]];
|
||||||
|
|
||||||
|
for (var i=0;i<cpyHandlers.length;i++) {
|
||||||
try {
|
try {
|
||||||
handlers[evt][i].apply(null, args);
|
cpyHandlers[i].apply(null, args);
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
console.warn("RED.events.emit error: ["+evt+"] "+(err.toString()));
|
console.warn("RED.events.emit error: ["+evt+"] "+(err.toString()));
|
||||||
console.warn(err);
|
console.warn(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -722,7 +722,7 @@ var RED = (function() {
|
|||||||
menuOptions.push({id:"menu-item-config-nodes",label:RED._("menu.label.displayConfig"),onselect:"core:show-config-tab"});
|
menuOptions.push({id:"menu-item-config-nodes",label:RED._("menu.label.displayConfig"),onselect:"core:show-config-tab"});
|
||||||
menuOptions.push({id:"menu-item-workspace",label:RED._("menu.label.flows"),options:[
|
menuOptions.push({id:"menu-item-workspace",label:RED._("menu.label.flows"),options:[
|
||||||
{id:"menu-item-workspace-add",label:RED._("menu.label.add"),onselect:"core:add-flow"},
|
{id:"menu-item-workspace-add",label:RED._("menu.label.add"),onselect:"core:add-flow"},
|
||||||
{id:"menu-item-workspace-edit",label:RED._("menu.label.rename"),onselect:"core:edit-flow"},
|
{id:"menu-item-workspace-edit",label:RED._("menu.label.edit"),onselect:"core:edit-flow"},
|
||||||
{id:"menu-item-workspace-delete",label:RED._("menu.label.delete"),onselect:"core:remove-flow"}
|
{id:"menu-item-workspace-delete",label:RED._("menu.label.delete"),onselect:"core:remove-flow"}
|
||||||
]});
|
]});
|
||||||
menuOptions.push({id:"menu-item-subflow",label:RED._("menu.label.subflows"), options: [
|
menuOptions.push({id:"menu-item-subflow",label:RED._("menu.label.subflows"), options: [
|
||||||
|
|||||||
@@ -484,7 +484,7 @@ RED.palette = (function() {
|
|||||||
var currentLabel = paletteNode.attr("data-palette-label");
|
var currentLabel = paletteNode.attr("data-palette-label");
|
||||||
var currentInfo = paletteNode.attr("data-palette-info");
|
var currentInfo = paletteNode.attr("data-palette-info");
|
||||||
|
|
||||||
if (currentLabel !== sf.name || currentInfo !== sf.info) {
|
if (currentLabel !== sf.name || currentInfo !== sf.info || sf.in.length > 0 || sf.out.length > 0) {
|
||||||
paletteNode.attr("data-palette-info",sf.info);
|
paletteNode.attr("data-palette-info",sf.info);
|
||||||
setLabel(sf.type+":"+sf.id,paletteNode,sf.name,RED.utils.renderMarkdown(sf.info||""));
|
setLabel(sf.type+":"+sf.id,paletteNode,sf.name,RED.utils.renderMarkdown(sf.info||""));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,24 +24,24 @@
|
|||||||
<title>{{ page.title }}</title>
|
<title>{{ page.title }}</title>
|
||||||
<link rel="icon" type="image/png" href="{{ page.favicon }}">
|
<link rel="icon" type="image/png" href="{{ page.favicon }}">
|
||||||
<link rel="mask-icon" href="{{ page.tabicon.icon }}" color="{{ page.tabicon.colour }}">
|
<link rel="mask-icon" href="{{ page.tabicon.icon }}" color="{{ page.tabicon.colour }}">
|
||||||
<link rel="stylesheet" href="vendor/jquery/css/base/jquery-ui.min.css?v={{ page.version }}">
|
<link rel="stylesheet" href="vendor/jquery/css/base/jquery-ui.min.css?v={{ cacheBuster }}">
|
||||||
<link rel="stylesheet" href="vendor/font-awesome/css/font-awesome.min.css?v={{ page.version }}">
|
<link rel="stylesheet" href="vendor/font-awesome/css/font-awesome.min.css?v={{ cacheBuster }}">
|
||||||
<link rel="stylesheet" href="red/style.min.css?v={{ page.version }}">
|
<link rel="stylesheet" href="red/style.min.css?v={{ cacheBuster }}">
|
||||||
{{#page.css}}
|
{{#page.css}}
|
||||||
<link rel="stylesheet" href="{{.}}">
|
<link rel="stylesheet" href="{{.}}">
|
||||||
{{/page.css}}
|
{{/page.css}}
|
||||||
{{#asset.vendorMonaco}}
|
{{#asset.vendorMonaco}}
|
||||||
<link rel="stylesheet" href="vendor/monaco/style.css?v={{ page.version }}">
|
<link rel="stylesheet" href="vendor/monaco/style.css?v={{ cacheBuster }}">
|
||||||
{{/asset.vendorMonaco}}
|
{{/asset.vendorMonaco}}
|
||||||
</head>
|
</head>
|
||||||
<body spellcheck="false">
|
<body spellcheck="false">
|
||||||
<div id="red-ui-editor"></div>
|
<div id="red-ui-editor"></div>
|
||||||
<script src="vendor/vendor.js?v={{ page.version }}"></script>
|
<script src="vendor/vendor.js?v={{ cacheBuster }}"></script>
|
||||||
{{#asset.vendorMonaco}}
|
{{#asset.vendorMonaco}}
|
||||||
<script src="{{ asset.vendorMonaco }}?v={{ page.version }}"></script>
|
<script src="{{ asset.vendorMonaco }}?v={{ cacheBuster }}"></script>
|
||||||
{{/asset.vendorMonaco}}
|
{{/asset.vendorMonaco}}
|
||||||
<script src="{{ asset.red }}?v={{ page.version }}"></script>
|
<script src="{{ asset.red }}?v={{ cacheBuster }}"></script>
|
||||||
<script src="{{ asset.main }}?v={{ page.version }}"></script>
|
<script src="{{ asset.main }}?v={{ cacheBuster }}"></script>
|
||||||
{{# page.scripts }}
|
{{# page.scripts }}
|
||||||
<script src="{{.}}"></script>
|
<script src="{{.}}"></script>
|
||||||
{{/ page.scripts }}
|
{{/ page.scripts }}
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ var express = require("express");
|
|||||||
var path = require('path');
|
var path = require('path');
|
||||||
var fs = require("fs");
|
var fs = require("fs");
|
||||||
var os = require("os");
|
var os = require("os");
|
||||||
|
const crypto = require("crypto")
|
||||||
|
|
||||||
const {log,i18n,events,exec,util,hooks} = require("@node-red/util");
|
const {log,i18n,events,exec,util,hooks} = require("@node-red/util");
|
||||||
|
|
||||||
@@ -51,7 +52,7 @@ var adminApi = {
|
|||||||
var nodeApp;
|
var nodeApp;
|
||||||
var adminApp;
|
var adminApp;
|
||||||
var server;
|
var server;
|
||||||
|
let userSettings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialise the runtime module.
|
* Initialise the runtime module.
|
||||||
@@ -61,8 +62,9 @@ var server;
|
|||||||
* better abstracted.
|
* better abstracted.
|
||||||
* @memberof @node-red/runtime
|
* @memberof @node-red/runtime
|
||||||
*/
|
*/
|
||||||
function init(userSettings,httpServer,_adminApi) {
|
function init(_userSettings,httpServer,_adminApi) {
|
||||||
server = httpServer;
|
server = httpServer;
|
||||||
|
userSettings = _userSettings
|
||||||
|
|
||||||
if (server && server.on) {
|
if (server && server.on) {
|
||||||
// Add a listener to the upgrade event so that we can properly timeout connection
|
// Add a listener to the upgrade event so that we can properly timeout connection
|
||||||
@@ -134,7 +136,12 @@ function start() {
|
|||||||
.then(function() { return settings.load(storage)})
|
.then(function() { return settings.load(storage)})
|
||||||
.then(function() { return library.init(runtime)})
|
.then(function() { return library.init(runtime)})
|
||||||
.then(function() {
|
.then(function() {
|
||||||
|
if (settings.available()) {
|
||||||
|
if (settings.get('instanceId') === undefined) {
|
||||||
|
settings.set('instanceId', crypto.randomBytes(8).toString('hex'))
|
||||||
|
}
|
||||||
|
userSettings.instanceId = settings.get('instanceId') || ''
|
||||||
|
}
|
||||||
if (log.metric()) {
|
if (log.metric()) {
|
||||||
runtimeMetricInterval = setInterval(function() {
|
runtimeMetricInterval = setInterval(function() {
|
||||||
reportMetrics();
|
reportMetrics();
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ describe("api/editor/ui", function() {
|
|||||||
var app;
|
var app;
|
||||||
|
|
||||||
before(function() {
|
before(function() {
|
||||||
ui.init({
|
ui.init({}, {
|
||||||
nodes: {
|
nodes: {
|
||||||
getIcon: function(opts) {
|
getIcon: function(opts) {
|
||||||
return new Promise(function(resolve,reject) {
|
return new Promise(function(resolve,reject) {
|
||||||
|
|||||||
Reference in New Issue
Block a user