1
0
mirror of https://github.com/node-red/node-red.git synced 2023-10-10 13:36:53 +02:00

Merge branch 'dev' into get-got

This commit is contained in:
Nick O'Leary 2021-06-09 09:59:23 +01:00 committed by GitHub
commit 133df75bd4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
243 changed files with 43788 additions and 1320 deletions

View File

@ -4,6 +4,9 @@ addons:
language: node_js
matrix:
include:
- node_js: "16"
script:
- ./node_modules/.bin/grunt no-coverage
- node_js: "14"
script:
- ./node_modules/.bin/grunt && ( cat coverage/lcov.info | $(npm get prefix)/bin/coveralls || true ) && rm -rf coverage
@ -13,6 +16,7 @@ matrix:
- node_js: "12"
script:
- ./node_modules/.bin/grunt no-coverage
allow_failures:
- node_js: "16"
script:
- ./node_modules/.bin/grunt no-coverage

14
API.md
View File

@ -1,8 +1,12 @@
Node-RED Modules
---
Node-RED consists of 6 node modules under the `@node-red` scope, which are pulled together
by the top-level `node-red` module. The typical scenario is where you are embedding Node-RED into your
own application, in which case you would use the `node-red` module rather than any of the
internal modules directly.
```javascript
let RED = require("node-red");
```
Node-RED provides a set of node modules that implement different parts of the
application.
Module | Description
-------|-------
@ -11,5 +15,5 @@ Module | Description
[@node-red/runtime](@node-red_runtime.html) | the core runtime of Node-RED
[@node-red/util](@node-red_util.html) | common utilities for the Node-RED runtime and editor modules
[@node-red/registry](@node-red_registry.html) | the internal node registry
@node-red/nodes | the default set of core nodes
@node-red/nodes | the default set of core nodes. This module only contains the Node-RED nodes - it does not expose any APIs.
@node-red/editor-client | the client-side resources of the Node-RED editor application

View File

@ -1,3 +1,101 @@
### 1.3.5 Maintenance Release
Editor
- Open subflow tab next to active tab rather than at the end
- Shrink default notification box
- Support mousewheel scroll in tab bar
- Revert some of #2967 to fix treeList gutter width calculation
- Prevent unknown node from breaking editor
- Stop module with missing types from preventing editor load
- Handle sidebar tab that no longer exists when setting first active
- Fix plugin loading when browser sends unrecognised lang
- Prevent error whilst drag/drop importing from leaving dropTarget visible Fixes #2982
- Fix scaling issues when dragging nodes into scaled workspace
- Fix incorrect shortcut keys in info tips (#2980) @kazuhitoyokoi
- Reduce code duplication around node/label generation
- Fix theme handling when no editorTheme.page setting
- Fix jshint error in treeList
Runtime
- Fix error handling in runtime/lib/api/nodes
- Add Node 16 with sass fixed
- Migrate from node-sass to sass (#2984)
- Fix "installRetry" was declared a constant and changed (#2974) @aheissenberger
Nodes
- Function: Fix 'SyntaxError' in Function node when last line of on-stop is a comment
- Function: Fix Function tab label names in the node help text Closes #2978
- Function: Update Japanese info text of function node (#2985) @HiroyasuNishiyama
### 1.3.4 Maintenance Release
Editor
- Allow nodes to access resolved theme files Fixes #2968
- Fix importing node to currently flow rather than match its old z value
- Don't let 'escape' whilst moving nodes interrupt things Fixes #2960
- Sort context stores in TypedInput and ensure default first Fixes #2954
- Fix margin between nodes on palette (#2947) @kazuhitoyokoi
- Ensure typedInput option is selected in dropdown menu Part of #2945
- Ensure typedInput without value has focus class removed Closes #2945
- TreeList: Fix remove item when depth=0 and wrong gutter calc (#2967) @hanc2006
Runtime
- Handle subflow modules that contain subflows
- Timeout http upgrade requests that are not otherwise handled Fixes #2956
- Fix error on auto commit for no flow change (#2957) @HiroyasuNishiyama
Nodes
- CSV: Fix CSV handling of special chars as separators
- Delay: Give delay node random mina nd max more space so you can see complete value
- Exec: fix grunt fail on exec node test (#2964) @HiroyasuNishiyama
- Function: Ensure function expand button is above vertical scrollbar Fixes #2955
- Inject: Fix inject node output tooltip extra property count
### 1.3.3: Maintenance Release
Editor
- Fix package semver comparison to allow >1 version increment
- Prevent TypedInput label overflowing element Fixes #2941
- Remove TypedInput from tab focus when only one type available
- Make typedInput.disable more consistent in behaviour Fixes #2942
- Fix project credential secret reset handling Part of #2868
Runtime
- Export package version in Grunt file so docs template can access
Nodes
- CSV: ensure CSV node can send false as string
- HTTPIn: handle application/x-protobuf as Buffer type (#2935 #2938) @hardillb
- MQTT: Ensure mqtt-close message is published when closing mqtt nodes
### 1.3.2: Maintenance Release
Runtime
- Handle package.json without dependencies section
Editor
- Fix variable reference error in editableList Fixes #2933
- Fix handling of user-provided keymap Fixes #2926
- Ensure theme login image is passed through to api response Fixes #2929
- Add Japanese translations for Node-RED v1.3.1 (#2930) @kazuhitoyokoi
Nodes
- CSV: Fix CSV parsing with other than , separator
- File out: Fix timing of msg.send to be after close
- Function: describe `node.outputCount` in help text
- MQTT: Fix MQTT Broker TLS config row layout Fixes #2927
- Split: add comment to info re $N being number of messages arriving
### 1.3.1: Maintenance Release

View File

@ -16,7 +16,7 @@
var path = require("path");
var fs = require("fs-extra");
var sass = require("node-sass");
var sass = require("sass");
module.exports = function(grunt) {
@ -40,8 +40,10 @@ module.exports = function(grunt) {
if (nonHeadless) {
process.env.NODE_RED_NON_HEADLESS = true;
}
const pkg = grunt.file.readJSON('package.json');
process.env.NODE_RED_PACKAGE_VERSION = pkg.version;
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
pkg: pkg,
paths: {
dist: ".dist"
},
@ -135,6 +137,7 @@ module.exports = function(grunt) {
"packages/node_modules/@node-red/editor-client/src/js/jquery-addons.js",
"packages/node_modules/@node-red/editor-client/src/js/red.js",
"packages/node_modules/@node-red/editor-client/src/js/events.js",
"packages/node_modules/@node-red/editor-client/src/js/hooks.js",
"packages/node_modules/@node-red/editor-client/src/js/i18n.js",
"packages/node_modules/@node-red/editor-client/src/js/settings.js",
"packages/node_modules/@node-red/editor-client/src/js/user.js",
@ -179,6 +182,7 @@ module.exports = function(grunt) {
"packages/node_modules/@node-red/editor-client/src/js/ui/palette-editor.js",
"packages/node_modules/@node-red/editor-client/src/js/ui/editor.js",
"packages/node_modules/@node-red/editor-client/src/js/ui/editors/*.js",
"packages/node_modules/@node-red/editor-client/src/js/ui/editors/code-editors/*.js",
"packages/node_modules/@node-red/editor-client/src/js/ui/event-log.js",
"packages/node_modules/@node-red/editor-client/src/js/ui/tray.js",
"packages/node_modules/@node-red/editor-client/src/js/ui/clipboard.js",
@ -283,7 +287,9 @@ module.exports = function(grunt) {
"packages/node_modules/@node-red/editor-client/public/index.html",
"packages/node_modules/@node-red/editor-client/public/favicon.ico",
"packages/node_modules/@node-red/editor-client/public/icons",
"packages/node_modules/@node-red/editor-client/public/vendor"
"packages/node_modules/@node-red/editor-client/public/vendor",
"packages/node_modules/@node-red/editor-client/public/types/node",
"packages/node_modules/@node-red/editor-client/public/types/node-red",
]
},
release: {
@ -373,11 +379,24 @@ module.exports = function(grunt) {
src: [
'ace/**',
'jquery/css/base/**',
'font-awesome/**'
'font-awesome/**',
'monaco/dist/**',
'monaco/types/extraLibs.js',
'monaco/style.css',
'monaco/monaco-bootstrap.js'
],
expand: true,
dest: 'packages/node_modules/@node-red/editor-client/public/vendor/'
},
{
cwd: 'packages/node_modules/@node-red/editor-client/src',
src: [
'types/node/*.ts',
'types/node-red/*.ts',
],
expand: true,
dest: 'packages/node_modules/@node-red/editor-client/public/'
},
{
cwd: 'packages/node_modules/@node-red/editor-client/src/icons',
src: '**',
@ -469,7 +488,8 @@ module.exports = function(grunt) {
],
options: {
destination: 'docs',
configure: './jsdoc.json'
configure: './jsdoc.json',
fred: "hi there"
}
},
_editor: {

View File

@ -26,30 +26,32 @@
}
],
"dependencies": {
"ajv": "6.12.6",
"acorn": "8.3.0",
"acorn-walk": "8.1.0",
"ajv": "8.6.0",
"async-mutex": "0.3.1",
"basic-auth": "2.0.1",
"bcryptjs": "2.4.3",
"body-parser": "1.19.0",
"cheerio": "0.22.0",
"cheerio": "1.0.0-rc.10",
"clone": "2.1.2",
"content-type": "1.0.4",
"cookie": "0.4.1",
"cookie-parser": "1.4.5",
"cors": "2.8.5",
"cron": "1.7.2",
"cronosjs": "1.7.1",
"denque": "1.5.0",
"express": "4.17.1",
"express-session": "1.17.1",
"express-session": "1.17.2",
"form-data": "4.0.0",
"fs-extra": "9.1.0",
"fs-extra": "10.0.0",
"fs.notify": "0.0.4",
"got": "11.8.2",
"hash-sum": "2.0.0",
"hpagent": "0.1.1",
"https-proxy-agent": "5.0.0",
"i18next": "20.2.1",
"iconv-lite": "0.6.2",
"i18next": "20.3.1",
"iconv-lite": "0.6.3",
"is-utf8": "0.2.1",
"js-yaml": "3.14.0",
"json-stringify-safe": "5.0.1",
@ -62,7 +64,7 @@
"mqtt": "4.2.6",
"multer": "1.4.2",
"mustache": "4.2.0",
"node-red-admin": "^0.2.6",
"node-red-admin": "0.2.7",
"nopt": "5.0.0",
"oauth2orize": "1.11.0",
"on-headers": "1.0.2",
@ -74,19 +76,19 @@
"semver": "7.3.5",
"tar": "6.1.0",
"tough-cookie": "4.0.0",
"uglify-js": "3.13.3",
"uglify-js": "3.13.9",
"uuid": "8.3.2",
"ws": "6.2.1",
"ws": "7.4.6",
"xml2js": "0.4.23"
},
"optionalDependencies": {
"bcrypt": "5.0.1"
},
"devDependencies": {
"dompurify": "2.2.7",
"grunt": "1.3.0",
"dompurify": "2.2.9",
"grunt": "1.4.1",
"grunt-chmod": "~1.1.1",
"grunt-cli": "~1.4.2",
"grunt-cli": "~1.4.3",
"grunt-concurrent": "3.0.0",
"grunt-contrib-clean": "~2.0.0",
"grunt-contrib-compress": "2.0.0",
@ -103,18 +105,18 @@
"grunt-sass": "~3.1.0",
"grunt-simple-mocha": "~0.4.1",
"grunt-simple-nyc": "^3.0.1",
"i18next-http-backend": "1.2.1",
"i18next-http-backend": "1.2.6",
"jquery-i18next": "1.2.1",
"jsdoc-nr-template": "github:node-red/jsdoc-nr-template",
"marked": "2.0.1",
"marked": "2.0.7",
"minami": "1.2.3",
"mocha": "8.3.2",
"mocha": "8.4.0",
"node-red-node-test-helper": "^0.2.7",
"node-sass": "^5.0.0",
"nodemon": "2.0.7",
"proxy": "^1.0.2",
"sass": "1.34.1",
"should": "13.2.3",
"sinon": "10.0.1",
"sinon": "11.1.1",
"stoppable": "^1.1.0",
"supertest": "6.1.3"
},

View File

@ -39,6 +39,15 @@ module.exports = {
var adminApp = express();
var defaultServerSettings = {
"x-powered-by": false
}
var serverSettings = Object.assign({},defaultServerSettings,settings.httpServerOptions||{});
for (var eOption in serverSettings) {
adminApp.set(eOption, serverSettings[eOption]);
}
// Flows
adminApp.get("/flows",needsPermission("flows.read"),flows.get,apiUtil.errorHandler);
adminApp.post("/flows",needsPermission("flows.write"),flows.post,apiUtil.errorHandler);

View File

@ -17,9 +17,8 @@ module.exports = {
})
} else {
opts.lang = apiUtils.determineLangFromHeaders(req.acceptsLanguages());
if (/[^a-z\-\*]/i.test(opts.lang)) {
res.json({});
return;
if (/[^0-9a-z=\-\*]/i.test(opts.lang)) {
opts.lang = "en-US";
}
runtimeAPI.plugins.getPluginConfigs(opts).then(function(configs) {
res.send(configs);
@ -32,9 +31,8 @@ module.exports = {
lang: req.query.lng,
req: apiUtils.getRequestLogObject(req)
}
if (/[^a-z\-\*]/i.test(opts.lang)) {
res.json({});
return;
if (/[^0-9a-z=\-\*]/i.test(opts.lang)) {
opts.lang = "en-US";
}
runtimeAPI.plugins.getPluginCatalogs(opts).then(function(result) {
res.json(result);

View File

@ -90,7 +90,7 @@ function getToken(req,res,next) {
return server.token()(req,res,next);
}
function login(req,res) {
async function login(req,res) {
var response = {};
if (settings.adminAuth) {
var mergedAdminAuth = Object.assign({}, settings.adminAuth, settings.adminAuth.module);
@ -116,8 +116,9 @@ function login(req,res) {
response.prompts[0].image = theme.serveFile('/login/',mergedAdminAuth.strategy.image);
}
}
if (theme.context().login && theme.context().login.image) {
response.image = theme.context().login.image;
let themeContext = await theme.context();
if (themeContext.login && themeContext.login.image) {
response.image = themeContext.login.image;
}
}
res.json(response);

View File

@ -64,10 +64,12 @@ module.exports = {
}
});
}
if (settings.httpServerOptions) {
for (var eOption in settings.httpServerOptions) {
editorApp.set(eOption, settings.httpServerOptions[eOption]);
var defaultServerSettings = {
"x-powered-by": false
}
var serverSettings = Object.assign({},defaultServerSettings,settings.httpServerOptions||{});
for (var eOption in serverSettings) {
editorApp.set(eOption, serverSettings[eOption]);
}
editorApp.get("/",ensureRuntimeStarted,ui.ensureSlash,ui.editor);

View File

@ -33,7 +33,7 @@ var defaultContext = {
asset: {
red: (process.env.NODE_ENV == "development")? "red/red.js":"red/red.min.js",
main: (process.env.NODE_ENV == "development")? "red/main.js":"red/main.min.js",
vendorMonaco: ""
}
};
@ -93,6 +93,7 @@ module.exports = {
themeContext = clone(defaultContext);
themeSettings = null;
theme = settings.editorTheme || {};
themeContext.asset.vendorMonaco = ((theme.codeEditor || {}).lib === "monaco") ? "vendor/monaco/monaco-bootstrap.js" : "";
activeTheme = theme.theme;
},
@ -129,6 +130,14 @@ module.exports = {
}
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
}
}
if (theme.header) {
@ -223,6 +232,8 @@ module.exports = {
themePlugin.path
);
themeContext.page.css = cssFiles.concat(themeContext.page.css || [])
theme.page = theme.page || {_:{}}
theme.page._.css = cssFiles.concat(theme.page._.css || [])
}
if (themePlugin.scripts) {
const scriptFiles = serveFilesFromTheme(
@ -232,6 +243,8 @@ module.exports = {
themePlugin.path
)
themeContext.page.scripts = scriptFiles.concat(themeContext.page.scripts || [])
theme.page = theme.page || {_:{}}
theme.page._.scripts = cssFiles.concat(theme.page._.scripts || [])
}
}
activeThemeInitialised = true;

View File

@ -64,6 +64,14 @@ function init(settings,_server,storage,runtimeAPI) {
}
}
var defaultServerSettings = {
"x-powered-by": false
}
var serverSettings = Object.assign({},defaultServerSettings,settings.httpServerOptions||{});
for (var eOption in serverSettings) {
adminApp.set(eOption, serverSettings[eOption]);
}
auth.init(settings,storage);
var maxApiRequestSize = settings.apiMaxLength || '5mb';

View File

@ -22,7 +22,7 @@
"body-parser": "1.19.0",
"clone": "2.1.2",
"cors": "2.8.5",
"express-session": "1.17.1",
"express-session": "1.17.2",
"express": "4.17.1",
"memorystore": "1.6.6",
"mime": "2.5.2",
@ -32,7 +32,7 @@
"passport-http-bearer": "1.0.1",
"passport-oauth2-client-password": "0.1.2",
"passport": "0.4.1",
"ws": "6.2.1"
"ws": "7.4.6"
},
"optionalDependencies": {
"bcrypt": "5.0.1"

View File

@ -111,6 +111,7 @@
"projects-open": "Open",
"projects-settings": "Project Settings",
"showNodeLabelDefault": "Show label of newly added nodes",
"codeEditor": "Code Editor",
"groups": "Groups",
"groupSelection": "Group selection",
"ungroupSelection": "Ungroup selection",
@ -885,6 +886,9 @@
"eval": "Error evaluating expression:\n __message__"
}
},
"monaco": {
"setTheme": "Set theme"
},
"jsEditor": {
"title": "JavaScript editor"
},

View File

@ -52,8 +52,8 @@
"desc": "Finds occurrences of `pattern` within `str` and replaces them with `replacement`.\n\nThe optional `limit` parameter is the maximum number of replacements."
},
"$now": {
"args":"",
"desc":"Generates a timestamp in ISO 8601 compatible format and returns it as a string."
"args":"$[picture [, timezone]]",
"desc":"Generates a timestamp in ISO 8601 compatible format and returns it as a string. If the optional picture and timezone parameters are supplied, then the current timestamp is formatted as described by the `$fromMillis()` function"
},
"$base64encode": {
"args":"string",

View File

@ -524,8 +524,8 @@
"title": "パレットの管理",
"palette": "パレット",
"times": {
"seconds": "秒前",
"minutes": "分前",
"seconds": "秒前",
"minutes": "分前",
"minutesV": "__count__ 分前",
"hoursV": "__count__ 時間前",
"hoursV_plural": "__count__ 時間前",

View File

@ -648,7 +648,7 @@
},
"context": {
"name": "上下文数据",
"label": "上下",
"label": "上下",
"none": "未选择",
"refresh": "刷新以加载",
"empty": "空",

View File

@ -66,12 +66,14 @@ RED.history = (function() {
var importedResult = RED.nodes.import(ev.config,{importMap: importMap})
inverseEv = {
t: 'replace',
config: importedResult.removedNodes
config: importedResult.removedNodes,
dirty: RED.nodes.dirty()
}
}
} else if (ev.t == 'add') {
inverseEv = {
t: "delete",
dirty: RED.nodes.dirty()
};
if (ev.nodes) {
inverseEv.nodes = [];
@ -158,7 +160,8 @@ RED.history = (function() {
} else if (ev.t == "delete") {
inverseEv = {
t: "add"
t: "add",
dirty: RED.nodes.dirty()
};
if (ev.workspaces) {
inverseEv.workspaces = [];
@ -300,11 +303,12 @@ RED.history = (function() {
} else if (ev.t == "move") {
inverseEv = {
t: 'move',
nodes: []
nodes: [],
dirty: RED.nodes.dirty()
};
for (i=0;i<ev.nodes.length;i++) {
var n = ev.nodes[i];
var rn = {n: n.n, ox: n.n.x, oy: n.n.y, dirty: true, moved: n.moved};
var rn = {n: n.n, ox: n.n.x, oy: n.n.y, dirty: true, moved: n.n.moved};
inverseEv.nodes.push(rn);
n.n.x = n.ox;
n.n.y = n.oy;
@ -336,7 +340,9 @@ RED.history = (function() {
} else if (ev.t == "edit") {
inverseEv = {
t: "edit",
changes: {}
changes: {},
changed: ev.node.changed,
dirty: RED.nodes.dirty()
};
inverseEv.node = ev.node;
for (i in ev.changes) {
@ -552,7 +558,8 @@ RED.history = (function() {
} else if (ev.t == "reorder") {
inverseEv = {
t: 'reorder',
order: RED.nodes.getWorkspaceOrder()
order: RED.nodes.getWorkspaceOrder(),
dirty: RED.nodes.dirty()
};
if (ev.order) {
RED.workspaces.order(ev.order);

View File

@ -0,0 +1,156 @@
RED.hooks = (function() {
var VALID_HOOKS = [
]
var hooks = { }
var labelledHooks = { }
function add(hookId, callback) {
var parts = hookId.split(".");
var id = parts[0], label = parts[1];
// if (VALID_HOOKS.indexOf(id) === -1) {
// throw new Error("Invalid hook '"+id+"'");
// }
if (label && labelledHooks[label] && labelledHooks[label][id]) {
throw new Error("Hook "+hookId+" already registered")
}
var hookItem = {cb:callback, previousHook: null, nextHook: null }
var tailItem = hooks[id];
if (tailItem === undefined) {
hooks[id] = hookItem;
} else {
while(tailItem.nextHook !== null) {
tailItem = tailItem.nextHook
}
tailItem.nextHook = hookItem;
hookItem.previousHook = tailItem;
}
if (label) {
labelledHooks[label] = labelledHooks[label]||{};
labelledHooks[label][id] = hookItem;
}
}
function remove(hookId) {
var parts = hookId.split(".");
var id = parts[0], label = parts[1];
if ( !label) {
throw new Error("Cannot remove hook without label: "+hookId)
}
if (labelledHooks[label]) {
if (id === "*") {
// Remove all hooks for this label
var hookList = Object.keys(labelledHooks[label]);
for (var i=0;i<hookList.length;i++) {
removeHook(hookList[i],labelledHooks[label][hookList[i]])
}
delete labelledHooks[label];
} else if (labelledHooks[label][id]) {
removeHook(id,labelledHooks[label][id])
delete labelledHooks[label][id];
if (Object.keys(labelledHooks[label]).length === 0){
delete labelledHooks[label];
}
}
}
}
function removeHook(id,hookItem) {
var previousHook = hookItem.previousHook;
var nextHook = hookItem.nextHook;
if (previousHook) {
previousHook.nextHook = nextHook;
} else {
hooks[id] = nextHook;
}
if (nextHook) {
nextHook.previousHook = previousHook;
}
hookItem.removed = true;
if (!previousHook && !nextHook) {
delete hooks[id];
}
}
function trigger(hookId, payload, done) {
var hookItem = hooks[hookId];
if (!hookItem) {
if (done) {
done();
}
return;
}
function callNextHook(err) {
if (!hookItem || err) {
if (done) { done(err) }
return err;
}
if (hookItem.removed) {
hookItem = hookItem.nextHook;
return callNextHook();
}
var callback = hookItem.cb;
if (callback.length === 1) {
try {
let result = callback(payload);
if (result === false) {
// Halting the flow
if (done) { done(false) }
return result;
}
hookItem = hookItem.nextHook;
return callNextHook();
} catch(e) {
console.warn(e);
if (done) { done(e);}
return e;
}
} else {
// There is a done callback
try {
callback(payload,function(result) {
if (result === undefined) {
hookItem = hookItem.nextHook;
callNextHook();
} else {
if (done) { done(result)}
}
})
} catch(e) {
console.warn(e);
if (done) { done(e) }
return e;
}
}
}
return callNextHook();
}
function clear() {
hooks = {}
labelledHooks = {}
}
function has(hookId) {
var parts = hookId.split(".");
var id = parts[0], label = parts[1];
if (label) {
return !!(labelledHooks[label] && labelledHooks[label][id])
}
return !!hooks[id]
}
return {
has: has,
clear: clear,
add: add,
remove: remove,
trigger: trigger
}
})();

View File

@ -86,6 +86,10 @@ RED.nodes = (function() {
}
},
addNodeSet: function(ns) {
if (!ns.types) {
// A node has been loaded without any types. Ignore it.
return;
}
ns.added = false;
nodeSets[ns.id] = ns;
for (var j=0;j<ns.types.length;j++) {
@ -206,8 +210,11 @@ RED.nodes = (function() {
})();
function getID() {
// return Math.floor(Math.random()*15728640 + 1048576).toString(16)
return (1+Math.random()*4294967295).toString(16);
var bytes = [];
for (var i=0;i<8;i++) {
bytes.push(Math.round(0xff*Math.random()).toString(16).padStart(2,'0'));
}
return bytes.join("");
}
function parseNodePropertyTypeString(typeString) {
@ -687,11 +694,23 @@ RED.nodes = (function() {
/**
* Converts a node to an exportable JSON Object
**/
function convertNode(n, exportCreds) {
function convertNode(n, opts) {
var exportCreds = true;
var exportDimensions = false;
if (opts === false) {
exportCreds = false;
} else if (typeof opts === "object") {
if (opts.hasOwnProperty("credentials")) {
exportCreds = opts.credentials;
}
if (opts.hasOwnProperty("dimensions")) {
exportDimensions = opts.dimensions;
}
}
if (n.type === 'tab') {
return convertWorkspace(n);
}
exportCreds = exportCreds || false;
var node = {};
node.id = n.id;
node.type = n.type;
@ -764,6 +783,19 @@ RED.nodes = (function() {
if (n._def.category != "config") {
node.x = n.x;
node.y = n.y;
if (exportDimensions) {
if (!n.hasOwnProperty('w')) {
// This node has not yet been drawn in the view. So we need
// to explicitly calculate its dimensions. Store the result
// on the node as if it had been drawn will save us doing
// it again
var dimensions = RED.view.calculateNodeDimensions(n);
n.w = dimensions[0];
n.h = dimensions[1];
}
node.w = n.w;
node.h = n.h;
}
node.wires = [];
for(var i=0;i<n.outputs;i++) {
node.wires.push([]);
@ -803,7 +835,21 @@ RED.nodes = (function() {
return node;
}
function convertSubflow(n, exportCreds) {
function convertSubflow(n, opts) {
var exportCreds = true;
var exportDimensions = false;
if (opts === false) {
exportCreds = false;
} else if (typeof opts === "object") {
if (opts.hasOwnProperty("credentials")) {
exportCreds = opts.credentials;
}
if (opts.hasOwnProperty("dimensions")) {
exportDimensions = opts.dimensions;
}
}
var node = {};
node.id = n.id;
node.type = n.type;
@ -975,11 +1021,10 @@ RED.nodes = (function() {
return nns;
}
//TODO: rename this (createCompleteNodeSet)
function createCompleteNodeSet(exportCredentials) {
if (exportCredentials === undefined) {
exportCredentials = true;
}
// Create the Flow JSON for the current configuration
// opts.credentials (whether to include (known) credentials) - default: true
// opts.dimensions (whether to include node dimensions) - default: false
function createCompleteNodeSet(opts) {
var nns = [];
var i;
for (i=0;i<workspacesOrder.length;i++) {
@ -989,22 +1034,22 @@ RED.nodes = (function() {
}
for (i in subflows) {
if (subflows.hasOwnProperty(i)) {
nns.push(convertSubflow(subflows[i], exportCredentials));
nns.push(convertSubflow(subflows[i], opts));
}
}
for (i in groups) {
if (groups.hasOwnProperty(i)) {
nns.push(convertNode(groups[i]));
nns.push(convertNode(groups[i], opts));
}
}
for (i in configNodes) {
if (configNodes.hasOwnProperty(i)) {
nns.push(convertNode(configNodes[i], exportCredentials));
nns.push(convertNode(configNodes[i], opts));
}
}
for (i in nodes) {
if (nodes.hasOwnProperty(i)) {
nns.push(convertNode(nodes[i], exportCredentials));
nns.push(convertNode(nodes[i], opts));
}
}
return nns;
@ -1424,6 +1469,8 @@ RED.nodes = (function() {
nid = getID();
workspace_map[n.id] = nid;
n.id = nid;
} else {
workspace_map[n.id] = n.id;
}
addWorkspace(n);
RED.workspaces.add(n);
@ -1523,7 +1570,7 @@ RED.nodes = (function() {
}
}
} else {
if (n.z && !workspaces[n.z] && !subflow_map[n.z]) {
if (n.z && !workspace_map[n.z] && !subflow_map[n.z]) {
n.z = activeWorkspace;
}
}
@ -1621,7 +1668,7 @@ RED.nodes = (function() {
node.id = getID();
} else {
node.id = n.id;
if (node.z == null || (!workspaces[node.z] && !subflow_map[node.z])) {
if (node.z == null || (!workspace_map[node.z] && !subflow_map[node.z])) {
if (createMissingWorkspace) {
if (missingWorkspace === null) {
missingWorkspace = RED.workspaces.add(null,true);

View File

@ -711,7 +711,7 @@ var RED = (function() {
throw new Error("RED already initialised");
}
initialised = true;
ace.require("ace/ext/language_tools");
if(window.ace) { window.ace.require("ace/ext/language_tools"); }
options = options || {};
options.apiRootUrl = options.apiRootUrl || "";
if (options.apiRootUrl && !/\/$/.test(options.apiRootUrl)) {

View File

@ -143,7 +143,8 @@ RED.settings = (function () {
console.groupCollapsed("Versions");
console.log("jQuery",$().jquery)
console.log("jQuery UI",$.ui.version);
console.log("ACE",ace.version);
if(window.ace) { console.log("ACE",ace.version); }
if(window.monaco) { console.log("MONACO",monaco.version || "unknown"); }
console.log("D3",d3.version);
console.groupEnd();
loadUserSettings(done);

View File

@ -1186,22 +1186,6 @@ RED.clipboard = (function() {
}
}
function getNodeLabelText(n) {
var label = n.name || n.type+": "+n.id;
if (n._def.label) {
try {
label = (typeof n._def.label === "function" ? n._def.label.call(n) : n._def.label)||"";
} catch(err) {
console.log("Definition error: "+n.type+".label",err);
}
}
var newlineIndex = label.indexOf("\\n");
if (newlineIndex > -1) {
label = label.substring(0,newlineIndex)+"...";
}
return label;
}
function getFlowLabel(n) {
n = JSON.parse(JSON.stringify(n));
n._def = RED.nodes.getType(n.type) || {};
@ -1227,16 +1211,8 @@ RED.clipboard = (function() {
if (n._def) {
n._ = n._def._;
}
var div = $('<div>',{class:"red-ui-info-outline-item"});
RED.utils.createNodeIcon(n).appendTo(div);
var contentDiv = $('<div>',{class:"red-ui-search-result-description"}).appendTo(div);
var labelText = getNodeLabelText(n);
var label = $('<div>',{class:"red-ui-search-result-node-label red-ui-info-outline-item-label"}).appendTo(contentDiv);
if (labelText) {
label.text(labelText)
} else {
label.html(n.type)
}
var div = $('<div>',{class:"red-ui-node-list-item"});
RED.utils.createNodeIcon(n,true).appendTo(div);
return div;
}
@ -1284,6 +1260,7 @@ RED.clipboard = (function() {
hideDropTarget();
})
.on("drop",function(event) {
try {
if ($.inArray("text/plain",event.originalEvent.dataTransfer.types) != -1) {
var data = event.originalEvent.dataTransfer.getData("text/plain");
data = data.substring(data.indexOf('['),data.lastIndexOf(']')+1);
@ -1301,6 +1278,10 @@ RED.clipboard = (function() {
reader.readAsText(file);
}
}
} catch(err) {
// Ensure any errors throw above doesn't stop the drop target from
// being hidden.
}
hideDropTarget();
event.preventDefault();
});

View File

@ -18,7 +18,7 @@
/**
* options:
* - addButton : boolean|string - text for add label, default 'add'
* - buttons : array - list of custom buttons (objects with fields 'label', 'icon', 'title', 'click')
* - buttons : array - list of custom buttons (objects with fields 'id', 'label', 'icon', 'title', 'click')
* - height : number|'auto'
* - resize : function - called when list as a whole is resized
* - resizeItem : function(item) - called to resize individual item
@ -71,7 +71,7 @@
var buttons = this.options.buttons || [];
if (this.options.addButton !== false) {
var addLabel, addTittle;
var addLabel, addTitle;
if (typeof this.options.addButton === 'string') {
addLabel = this.options.addButton
} else {
@ -94,7 +94,7 @@
}
buttons.forEach(function(button) {
var element = $('<a href="#" class="red-ui-button red-ui-button-small red-ui-editableList-addButton" style="margin-top: 4px; margin-right: 5px;"></a>')
var element = $('<button type="button" class="red-ui-button red-ui-button-small red-ui-editableList-addButton" style="margin-top: 4px; margin-right: 5px;"></button>')
.appendTo(that.topContainer)
.on("click", function(evt) {
evt.preventDefault();
@ -103,6 +103,9 @@
}
});
if (button.id) {
element.attr("id", button.id);
}
if (button.title) {
element.attr("title", button.title);
}

View File

@ -100,7 +100,22 @@ RED.tabs = (function() {
if (options.scrollable) {
wrapper.addClass("red-ui-tabs-scrollable");
scrollContainer.addClass("red-ui-tabs-scroll-container");
scrollContainer.on("scroll",updateScroll);
scrollContainer.on("scroll",function(evt) {
// Generated by trackpads - not mousewheel
updateScroll(evt);
});
scrollContainer.on("wheel", function(evt) {
if (evt.originalEvent.deltaX === 0) {
// Prevent the scroll event from firing
evt.preventDefault();
// Assume this is wheel event which might not trigger
// the scroll event, so do things manually
var sl = scrollContainer.scrollLeft();
sl -= evt.originalEvent.deltaY;
scrollContainer.scrollLeft(sl);
}
})
scrollLeft = $('<div class="red-ui-tab-button red-ui-tab-scroll red-ui-tab-scroll-left"><a href="#" style="display:none;"><i class="fa fa-caret-left"></i></a></div>').appendTo(wrapper).find("a");
scrollLeft.on('mousedown',function(evt) { scrollEventHandler(evt,'-=150') }).on('click',function(evt){ evt.preventDefault();});
scrollRight = $('<div class="red-ui-tab-button red-ui-tab-scroll red-ui-tab-scroll-right"><a href="#" style="display:none;"><i class="fa fa-caret-right"></i></a></div>').appendTo(wrapper).find("a");
@ -770,6 +785,9 @@ RED.tabs = (function() {
count: function() {
return ul.find("li.red-ui-tab").length;
},
activeIndex: function() {
return ul.find("li.active").index()
},
contains: function(id) {
return ul.find("a[href='#"+id+"']").length > 0;
},

View File

@ -312,6 +312,7 @@
}
if (child.depth !== parent.depth+1) {
child.depth = parent.depth+1;
// var labelPaddingWidth = ((child.gutter ? child.gutter[0].offsetWidth + 2 : 0) + (child.depth * 20));
var labelPaddingWidth = ((child.gutter?child.gutter.width()+2:0)+(child.depth*20));
child.treeList.labelPadding.width(labelPaddingWidth+'px');
if (child.element) {
@ -348,6 +349,18 @@
that._selected.delete(item);
delete item.treeList;
delete that._items[item.id];
if(item.depth === 0) {
for(var key in that._items) {
if (that._items.hasOwnProperty(key)) {
var child = that._items[key];
if(child.parent && child.parent.id === item.id) {
delete that._items[key].treeList;
delete that._items[key];
}
}
}
that._data = that._data.filter(function(data) { return data.id !== item.id})
}
}
item.treeList.insertChildAt = function(newItem,position,select) {
newItem.parent = item;
@ -480,7 +493,10 @@
if (item.treeList.container) {
$(item.element).remove();
$(element).appendTo(item.treeList.label);
var labelPaddingWidth = (item.gutter?item.gutter.width()+2:0)+(item.depth*20);
// using the JQuery Object, the gutter width will
// be wrong when the element is reattached the second time
var labelPaddingWidth = (item.gutter ? item.gutter[0].offsetWidth + 2 : 0) + (item.depth * 20);
$(element).css({
width: "calc(100% - "+(labelPaddingWidth+20+(item.icon?20:0))+"px)"
})
@ -517,6 +533,7 @@
}
var labelPaddingWidth = (item.gutter?item.gutter.width()+2:0)+(depth*20);
// var labelPaddingWidth = (item.gutter ? item.gutter[0].offsetWidth + 2 : 0) + (depth * 20)
item.treeList.labelPadding = $('<span>').css({
display: "inline-block",
width: labelPaddingWidth+'px'

View File

@ -15,7 +15,7 @@
**/
(function($) {
var contextParse = function(v,defaultStore) {
var parts = RED.utils.parseContextKey(v, defaultStore);
var parts = RED.utils.parseContextKey(v, defaultStore&&defaultStore.value);
return {
option: parts.store,
value: parts.key
@ -279,6 +279,14 @@
var contextStores = RED.settings.context.stores;
var contextOptions = contextStores.map(function(store) {
return {value:store,label: store, icon:'<i class="red-ui-typedInput-icon fa fa-database"></i>'}
}).sort(function(A,B) {
if (A.value === RED.settings.context.default) {
return -1;
} else if (B.value === RED.settings.context.default) {
return 1;
} else {
return A.value.localeCompare(B.value);
}
})
if (contextOptions.length < 2) {
allOptions.flow.options = [];
@ -389,6 +397,11 @@
evt.stopPropagation();
}).on('focus', function() {
that.uiSelect.addClass('red-ui-typedInput-focus');
}).on('blur', function() {
var opt = that.typeMap[that.propertyType];
if (opt.hasValue === false) {
that.uiSelect.removeClass('red-ui-typedInput-focus');
}
})
// explicitly set optionSelectTrigger display to inline-block otherwise jQ sets it to 'inline'
@ -438,7 +451,11 @@
});
this._showMenu(this.optionMenu,this.optionSelectTrigger);
var selectedOption = this.optionMenu.find("[value='"+this.optionValue+"']");
var targetValue = this.optionValue;
if (this.optionValue === null || this.optionValue === undefined) {
targetValue = this.value();
}
var selectedOption = this.optionMenu.find("[value='"+targetValue+"']");
if (selectedOption.length === 0) {
selectedOption = this.optionMenu.children(":first");
}
@ -669,6 +686,11 @@
that.typeMap[result.value] = result;
return result;
});
if (this.typeList.length < 2) {
this.selectTrigger.attr("tabindex", -1)
} else {
this.selectTrigger.attr("tabindex", 0)
}
this.selectTrigger.toggleClass("disabled", this.typeList.length === 1);
this.selectTrigger.find(".fa-caret-down").toggle(this.typeList.length > 1)
if (this.menu) {
@ -768,6 +790,11 @@
if (opt.hasValue === false || (opt.showLabel !== false && !opt.icon)) {
this.selectLabel.text(opt.label);
}
if (opt.label) {
this.selectTrigger.attr("title",opt.label);
} else {
this.selectTrigger.attr("title","");
}
if (opt.hasValue === false) {
this.selectTrigger.addClass("red-ui-typedInput-full-width");
} else {
@ -1004,16 +1031,17 @@
this.uiSelect.hide();
},
disable: function(val) {
if(val === true) {
if(val === undefined || !!val ) {
this.uiSelect.attr("disabled", "disabled");
} else if (val === false) {
this.uiSelect.attr("disabled", null); //remove attr
} else {
this.uiSelect.attr("disabled", val); //user value
this.uiSelect.attr("disabled", null); //remove attr
}
},
enable: function() {
this.uiSelect.attr("disabled", null); //remove attr
},
disabled: function() {
return this.uiSelect.attr("disabled");
return this.uiSelect.attr("disabled") === "disabled";
}
});
})(jQuery);

View File

@ -1525,6 +1525,7 @@ var buildingEditDialog = false;
console.log("oneditresize",editing_node.id,editing_node.type,err.toString());
}
}
if (nodeInfoEditor) {nodeInfoEditor.resize();} //markdown editor doesnt size up without this - idkw!?
},
open: function(tray, done) {
if (editing_node.hasOwnProperty('outputs')) {
@ -2759,98 +2760,11 @@ var buildingEditDialog = false;
}
}
function createEditor(options) {
var el = options.element || $("#"+options.id)[0];
var toolbarRow = $("<div>").appendTo(el);
el = $("<div>").appendTo(el).addClass("red-ui-editor-text-container")[0];
var editor = ace.edit(el);
editor.setTheme("ace/theme/tomorrow");
var session = editor.getSession();
session.on("changeAnnotation", function () {
var annotations = session.getAnnotations() || [];
var i = annotations.length;
var len = annotations.length;
while (i--) {
if (/doctype first\. Expected/.test(annotations[i].text)) { annotations.splice(i, 1); }
else if (/Unexpected End of file\. Expected/.test(annotations[i].text)) { annotations.splice(i, 1); }
}
if (len > annotations.length) { session.setAnnotations(annotations); }
});
if (options.mode) {
session.setMode(options.mode);
}
if (options.foldStyle) {
session.setFoldStyle(options.foldStyle);
} else {
session.setFoldStyle('markbeginend');
}
if (options.options) {
editor.setOptions(options.options);
} else {
editor.setOptions({
enableBasicAutocompletion:true,
enableSnippets:true,
tooltipFollowsMouse: false
});
}
if (options.readOnly) {
editor.setOption('readOnly',options.readOnly);
editor.container.classList.add("ace_read-only");
}
if (options.hasOwnProperty('lineNumbers')) {
editor.renderer.setOption('showGutter',options.lineNumbers);
}
editor.$blockScrolling = Infinity;
if (options.value) {
session.setValue(options.value,-1);
}
if (options.globals) {
setTimeout(function() {
if (!!session.$worker) {
session.$worker.send("setOptions", [{globals: options.globals, maxerr:1000}]);
}
},100);
}
if (options.mode === 'ace/mode/markdown') {
$(el).addClass("red-ui-editor-text-container-toolbar");
editor.toolbar = customEditTypes['_markdown'].buildToolbar(toolbarRow,editor);
if (options.expandable !== false) {
var expandButton = $('<button type="button" class="red-ui-button" style="float: right;"><i class="fa fa-expand"></i></button>').appendTo(editor.toolbar);
RED.popover.tooltip(expandButton, RED._("markdownEditor.expand"));
expandButton.on("click", function(e) {
e.preventDefault();
var value = editor.getValue();
RED.editor.editMarkdown({
value: value,
width: "Infinity",
cursor: editor.getCursorPosition(),
complete: function(v,cursor) {
editor.setValue(v, -1);
editor.gotoLine(cursor.row+1,cursor.column,false);
setTimeout(function() {
editor.focus();
},300);
}
})
});
}
var helpButton = $('<button type="button" class="red-ui-editor-text-help red-ui-button red-ui-button-small"><i class="fa fa-question"></i></button>').appendTo($(el).parent());
RED.popover.create({
target: helpButton,
trigger: 'click',
size: "small",
direction: "left",
content: RED._("markdownEditor.format"),
autoClose: 50
});
session.setUseWrapMode(true);
}
return editor;
}
return {
init: function() {
ace.config.set('basePath', 'vendor/ace');
if(window.ace) { window.ace.config.set('basePath', 'vendor/ace'); }
RED.tray.init();
RED.actions.add("core:confirm-edit-tray", function() {
$(document.activeElement).blur();
@ -2862,6 +2776,8 @@ var buildingEditDialog = false;
$("#node-dialog-cancel").trigger("click");
$("#node-config-dialog-cancel").trigger("click");
});
//console.log("packages/node_modules/@node-red/editor-client/src/js/ui/editor.js ? init()") //TODO: Remove
RED.editor.codeEditor.init();
},
edit: showEditDialog,
editConfig: showEditConfigNodeDialog,
@ -2908,9 +2824,14 @@ var buildingEditDialog = false;
/**
* Create a editor ui component
* @param {object} options - the editor options
* @function
* @returs The code editor
* @memberof RED.editor
*/
createEditor: createEditor
createEditor: function(options) {
return RED.editor.codeEditor.create(options);
},
get customEditTypes() {
return customEditTypes;
}
}
})();

View File

@ -0,0 +1,107 @@
/**
* Copyright JS Foundation and other contributors, http://js.foundation
*
* 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.
**/
/**
* @namespace RED.editor.codeEditor
*/
RED.editor.codeEditor = (function() {
const MONACO = "monaco";
const ACE = "ace";
const defaultEditor = ACE;
const DEFAULT_SETTINGS = { lib: defaultEditor, options: {} };
var selectedCodeEditor = null;
var initialised = false;
function init() {
var codeEditorSettings = RED.editor.codeEditor.settings;
var editorChoice = codeEditorSettings.lib === MONACO ? MONACO : ACE;
try {
var browser = RED.utils.getBrowserInfo();
selectedCodeEditor = RED.editor.codeEditor[editorChoice];
//fall back to default code editor if there are any issues
if (!selectedCodeEditor || (editorChoice === MONACO && (browser.ie || !window.monaco))) {
selectedCodeEditor = RED.editor.codeEditor[defaultEditor];
}
initialised = selectedCodeEditor.init();
} catch (error) {
selectedCodeEditor = null;
console.warn("Problem initialising '" + editorChoice + "' code editor", error);
}
if(!initialised) {
selectedCodeEditor = RED.editor.codeEditor[defaultEditor];
initialised = selectedCodeEditor.init();
}
}
function create(options) {
//TODO: (quandry - for consideration)
// Below, I had to create a hidden element if options.id || options.element is not in the DOM
// I have seen 1 node calling `this.editor = RED.editor.createEditor()` with an
// invalid (non existing html element selector) (e.g. node-red-contrib-components does this)
// This causes monaco to throw an error when attempting to hook up its events to the dom & the rest of the 'oneditperapre'
// code is thus skipped.
// In ACE mode, creating an ACE editor (with an invalid ID) allows the editor to be created (but obviously there is no UI)
// Because one (or more) contrib nodes have left this bad code in place, how would we handle this?
// For compatibility, I have decided to create a hidden element so that at least an editor is created & errors do not occur.
// IMO, we should warn and exit as it is a coding error by the contrib author.
if (!options) {
console.warn("createEditor() options are missing");
options = {};
}
if (this.editor.type === MONACO) {
// compatibility (see above note)
if (!options.element && !options.id) {
options.id = 'node-backwards-compatability-dummy-editor';
}
options.element = options.element || $("#" + options.id)[0];
if (!options.element) {
console.warn("createEditor() options.element or options.id is not valid", options);
$("#dialog-form").append('<div id="' + options.id + '" style="display: none;" />');
}
return this.editor.create(options);
} else {
return this.editor.create(options);//fallback to ACE
}
}
return {
init: init,
/**
* Get editor settings object
* @memberof RED.editor.codeEditor
*/
get settings() {
return RED.settings.get('codeEditor') || DEFAULT_SETTINGS;
},
/**
* Get user selected code editor
* @return {string} Returns
* @memberof RED.editor.codeEditor
*/
get editor() {
return selectedCodeEditor;
},
/**
* Create a editor ui component
* @param {object} options - the editor options
* @memberof RED.editor.codeEditor
*/
create: create
}
})();

View File

@ -0,0 +1,153 @@
/*
* 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.
**/
/**
* @namespace RED.editor.codeEditor.ace
*/
RED.editor.codeEditor.ace = (function() {
const type = "ace";
var initialised = false;
var initOptions = {};
function init(options) {
initOptions = options || {};
initialised = true;
return initialised;
}
function create(options) {
var editorSettings = RED.editor.codeEditor.settings || {};
var el = options.element || $("#"+options.id)[0];
var toolbarRow = $("<div>").appendTo(el);
el = $("<div>").appendTo(el).addClass("red-ui-editor-text-container")[0];
var editor = window.ace.edit(el);
editor.setTheme(editorSettings.theme || initOptions.theme || "ace/theme/tomorrow");
var session = editor.getSession();
session.on("changeAnnotation", function () {
var annotations = session.getAnnotations() || [];
var i = annotations.length;
var len = annotations.length;
while (i--) {
if (/doctype first\. Expected/.test(annotations[i].text)) { annotations.splice(i, 1); }
else if (/Unexpected End of file\. Expected/.test(annotations[i].text)) { annotations.splice(i, 1); }
}
if (len > annotations.length) { session.setAnnotations(annotations); }
});
if (options.mode) {
session.setMode(options.mode);
}
if (options.foldStyle) {
session.setFoldStyle(options.foldStyle);
} else {
session.setFoldStyle('markbeginend');
}
if (options.options) {
editor.setOptions(options.options);
} else {
editor.setOptions({
enableBasicAutocompletion:true,
enableSnippets:true,
tooltipFollowsMouse: false
});
}
if (options.readOnly) {
editor.setOption('readOnly',options.readOnly);
editor.container.classList.add("ace_read-only");
}
if (options.hasOwnProperty('lineNumbers')) {
editor.renderer.setOption('showGutter',options.lineNumbers);
}
editor.$blockScrolling = Infinity;
if (options.value) {
session.setValue(options.value,-1);
}
if (options.globals) {
setTimeout(function() {
if (!!session.$worker) {
session.$worker.send("setOptions", [{globals: options.globals, maxerr:1000}]);
}
},100);
}
if (options.mode === 'ace/mode/markdown') {
$(el).addClass("red-ui-editor-text-container-toolbar");
editor.toolbar = RED.editor.customEditTypes['_markdown'].buildToolbar(toolbarRow,editor);
if (options.expandable !== false) {
var expandButton = $('<button type="button" class="red-ui-button" style="float: right;"><i class="fa fa-expand"></i></button>').appendTo(editor.toolbar);
RED.popover.tooltip(expandButton, RED._("markdownEditor.expand"));
expandButton.on("click", function(e) {
e.preventDefault();
var value = editor.getValue();
RED.editor.editMarkdown({
value: value,
width: "Infinity",
cursor: editor.getCursorPosition(),
complete: function(v,cursor) {
editor.setValue(v, -1);
editor.gotoLine(cursor.row+1,cursor.column,false);
setTimeout(function() {
editor.focus();
},300);
}
})
});
}
var helpButton = $('<button type="button" class="red-ui-editor-text-help red-ui-button red-ui-button-small"><i class="fa fa-question"></i></button>').appendTo($(el).parent());
RED.popover.create({
target: helpButton,
trigger: 'click',
size: "small",
direction: "left",
content: RED._("markdownEditor.format"),
autoClose: 50
});
session.setUseWrapMode(true);
}
editor._destroy = editor.destroy;
editor.destroy = function() {
try {
this._destroy();
} catch (e) { }
$(el).remove();
$(toolbarRow).remove();
}
editor.type = type;
return editor;
}
return {
/**
* Editor type
* @memberof RED.editor.codeEditor.ace
*/
get type() { return type; },
/**
* Editor initialised
* @memberof RED.editor.codeEditor.ace
*/
get initialised() { return initialised; },
/**
* Initialise code editor
* @param {object} options - initialisation options
* @memberof RED.editor.codeEditor.ace
*/
init: init,
/**
* Create a code editor
* @param {object} options - the editor options
* @memberof RED.editor.codeEditor.ace
*/
create: create
}
})();

File diff suppressed because it is too large Load Diff

View File

@ -121,6 +121,8 @@
var currentFunctionMarker = null;
expressionEditor.getSession().setValue(value||"",-1);
//ace only (monaco has jsonata tokeniser)
if(expressionEditor.type == "ace") {
expressionEditor.on("changeSelection", function() {
var c = expressionEditor.getCursorPosition();
var token = expressionEditor.getSession().getTokenAt(c.row,c.column);
@ -187,7 +189,7 @@
}
}
});
}
dialogForm.i18n();
$("#red-ui-editor-type-expression-func-insert").on("click", function(e) {
e.preventDefault();
@ -343,6 +345,7 @@
}
expressionEditor.destroy();
testDataEditor.destroy();
testResultEditor.destroy();
},
show: function() {}
}

View File

@ -602,10 +602,10 @@
},
close: function() {
// expressionEditor.destroy();
if (options.onclose) {
options.onclose();
}
expressionEditor.destroy();
},
show: function() {}
}

View File

@ -73,6 +73,7 @@ RED.eventLog = (function() {
var trayBody = tray.find('.red-ui-tray-body');
var dialogForm = RED.editor.buildEditForm(tray.find('.red-ui-tray-body'),'dialog-form',type,'editor');
eventLogEditor = RED.editor.createEditor({
mode:"ace/mode/shell",
id: 'red-ui-event-log-editor',
value: backlog.join("\n"),
lineNumbers: false,

View File

@ -119,7 +119,7 @@ RED.keyboard = (function() {
} else {
mergedKeymap[action] = [{
scope: themeKeymap[action].scope || "*",
key: [themeKeymap[action].key],
key: themeKeymap[action].key,
user: false
}]
if (mergedKeymap[action][0].scope === "workspace") {

View File

@ -27,7 +27,7 @@ RED.library = (function() {
'<div class="red-ui-panel" id="red-ui-library-dialog-load-browser"></div>'+
'<div class="red-ui-panel">'+
'<div id="red-ui-library-dialog-load-preview">'+
'<div class="red-ui-panel" id="red-ui-library-dialog-load-preview-text"></div>'+
'<div class="red-ui-panel" id="red-ui-library-dialog-load-preview-text" style="position:relative; height: 50%; overflow-y: hidden;"></div>'+
'<div class="red-ui-panel" id="red-ui-library-dialog-load-preview-details">'+
'<table id="red-ui-library-dialog-load-preview-details-table" class="red-ui-info-table"></table>'+
'</div>'+
@ -216,11 +216,16 @@ RED.library = (function() {
{ id:'node-input-'+options.type+'-menu-open-library',
label: RED._("library.openLibrary"),
onselect: function() {
libraryEditor = ace.edit('red-ui-library-dialog-load-preview-text',{
useWorker: false
});
libraryEditor.setTheme("ace/theme/tomorrow");
var editorOpts = {
id: 'red-ui-library-dialog-load-preview-text',
mode: options.mode,
readOnly: true,
highlightActiveLine: false,
highlightGutterLine: false,
contextmenu: false
}
libraryEditor = RED.editor.createEditor(editorOpts); //use red.editor
if(libraryEditor.isACE) {
if (options.mode) {
libraryEditor.getSession().setMode(options.mode);
}
@ -231,6 +236,7 @@ RED.library = (function() {
});
libraryEditor.renderer.$cursorLayer.element.style.opacity=0;
libraryEditor.$blockScrolling = Infinity;
}
activeLibrary = options;
var listing = [];
@ -809,11 +815,12 @@ RED.library = (function() {
open: function(e) {
RED.keyboard.disable();
$(this).parent().find(".ui-dialog-titlebar-close").hide();
libraryEditor.resize();
},
close: function(e) {
RED.keyboard.enable();
if (libraryEditor) {
libraryEditor.destroy();
libraryEditor.remove();
libraryEditor = null;
}
}

View File

@ -331,7 +331,7 @@ RED.palette.editor = (function() {
nodeEntry.versionSpan.html(moduleInfo.version+' <i class="fa fa-long-arrow-right"></i> '+moduleInfo.pending_version).appendTo(nodeEntry.metaRow)
nodeEntry.updateButton.text(RED._('palette.editor.updated')).addClass('disabled').css('display', 'inline-block');
} else if (loadedIndex.hasOwnProperty(module)) {
if (semVerCompare(loadedIndex[module].version,moduleInfo.version) === 1) {
if (semVerCompare(loadedIndex[module].version,moduleInfo.version) > 0) {
nodeEntry.updateButton.show();
nodeEntry.updateButton.text(RED._('palette.editor.update',{version:loadedIndex[module].version}));
} else {

View File

@ -320,12 +320,12 @@ RED.palette = (function() {
var paletteNode = getPaletteNode(nt);
ui.originalPosition.left = paletteNode.offset().left;
mouseX = ui.position.left - paletteWidth + (ui.helper.width()/2) + chart.scrollLeft();
mouseY = ui.position.top - paletteTop + (ui.helper.height()/2) + chart.scrollTop();
mouseY = ui.position.top - paletteTop + (ui.helper.height()/2) + chart.scrollTop() + 10;
if (!groupTimer) {
groupTimer = setTimeout(function() {
mouseX /= RED.view.scale();
mouseY /= RED.view.scale();
var group = RED.view.getGroupAtPoint(mouseX,mouseY);
var mx = mouseX / RED.view.scale();
var my = mouseY / RED.view.scale();
var group = RED.view.getGroupAtPoint(mx,my);
if (group !== hoverGroup) {
if (hoverGroup) {
document.getElementById("group_select_"+hoverGroup.id).classList.remove("red-ui-flow-group-hovered");
@ -357,23 +357,20 @@ RED.palette = (function() {
svgRect.width = 1;
svgRect.height = 1;
nodes = chartSVG.getIntersectionList(svgRect,chartSVG);
mouseX /= RED.view.scale();
mouseY /= RED.view.scale();
} else {
// Firefox doesn't do getIntersectionList and that
// makes us sad
mouseX /= RED.view.scale();
mouseY /= RED.view.scale();
nodes = RED.view.getLinksAtPoint(mouseX,mouseY);
}
var mx = mouseX / RED.view.scale();
var my = mouseY / RED.view.scale();
for (var i=0;i<nodes.length;i++) {
var node = d3.select(nodes[i]);
if (node.classed('red-ui-flow-link-background') && !node.classed('red-ui-flow-link-link')) {
var length = nodes[i].getTotalLength();
for (var j=0;j<length;j+=10) {
var p = nodes[i].getPointAtLength(j);
var d2 = ((p.x-mouseX)*(p.x-mouseX))+((p.y-mouseY)*(p.y-mouseY));
var d2 = ((p.x-mx)*(p.x-mx))+((p.y-my)*(p.y-my));
if (d2 < 200 && d2 < bestDistance) {
bestDistance = d2;
bestLink = nodes[i];

View File

@ -928,11 +928,11 @@ RED.projects.settings = (function() {
saveDisabled = isFlowInvalid || credFileLabelText.text()==="";
if (credentialSecretExistingInput.is(":visible")) {
if (credentialSecretExistingRow.is(":visible")) {
credentialSecretExistingInput.toggleClass("input-error", credentialSecretExistingInput.val() === "");
saveDisabled = saveDisabled || credentialSecretExistingInput.val() === "";
}
if (credentialSecretNewInput.is(":visible")) {
if (credentialSecretNewRow.is(":visible")) {
credentialSecretNewInput.toggleClass("input-error", credentialSecretNewInput.val() === "");
saveDisabled = saveDisabled || credentialSecretNewInput.val() === "";
}
@ -1130,7 +1130,7 @@ RED.projects.settings = (function() {
}
if (credentialSecretResetButton.hasClass('selected') || credentialSecretEditButton.hasClass('selected')) {
payload.credentialSecret = credentialSecretNewInput.val();
if (credentialSecretExistingInput.is(":visible")) {
if (credentialSecretExistingRow.is(":visible")) {
payload.currentCredentialSecret = credentialSecretExistingInput.val();
}
}

View File

@ -199,7 +199,7 @@ RED.sidebar = (function() {
id = RED.settings.get("editor.sidebar.order",["info", "help", "version-control", "debug"])[0]
}
if (id) {
if (!containsTab(id)) {
if (!containsTab(id) && knownTabs[id]) {
sidebar_tabs.addTab(knownTabs[id]);
}
sidebar_tabs.activateTab(id);

View File

@ -230,10 +230,17 @@ RED.sidebar.help = (function() {
}
function getNodeLabel(n) {
var div = $('<div>',{class:"red-ui-info-outline-item"});
RED.utils.createNodeIcon(n).appendTo(div);
var contentDiv = $('<div>',{class:"red-ui-search-result-description"}).appendTo(div);
$('<div>',{class:"red-ui-search-result-node-label red-ui-info-outline-item-label"}).text(n.name||n._def.paletteLabel||n.type).appendTo(contentDiv);
var div = $('<div>',{class:"red-ui-node-list-item"});
var icon = RED.utils.createNodeIcon(n).appendTo(div);
var label = n.name;
if (!label && n._def.paletteLabel) {
try {
label = (typeof n._def.paletteLabel === "function" ? n._def.paletteLabel.call(n._def) : n._def.paletteLabel)||"";
} catch (err) {
}
}
label = label || n.type;
$('<div>',{class:"red-ui-node-label"}).text(n.name||n.type).appendTo(icon);
return div;
}
@ -250,6 +257,13 @@ RED.sidebar.help = (function() {
helpText = RED.nodes.getNodeHelp(nodeType)||('<span class="red-ui-help-info-none">'+RED._("sidebar.info.none")+'</span>');
var _def = RED.nodes.registry.getNodeType(nodeType);
title = (_def && _def.paletteLabel)?_def.paletteLabel:nodeType;
if (typeof title === "function") {
try {
title = _def.paletteLabel.call(_def);
} catch(err) {
title = nodeType;
}
}
}
setInfoText(title, helpText, helpSection);

View File

@ -73,36 +73,11 @@ RED.sidebar.info.outliner = (function() {
return item;
}
function getNodeLabelText(n) {
var label = n.name || n.type+": "+n.id;
if (n._def.label) {
try {
label = (typeof n._def.label === "function" ? n._def.label.call(n) : n._def.label)||"";
} catch(err) {
console.log("Definition error: "+n.type+".label",err);
}
}
var newlineIndex = label.indexOf("\\n");
if (newlineIndex > -1) {
label = label.substring(0,newlineIndex)+"...";
}
return label;
}
function getNodeLabel(n) {
var div = $('<div>',{class:"red-ui-info-outline-item"});
RED.utils.createNodeIcon(n).appendTo(div);
var contentDiv = $('<div>',{class:"red-ui-search-result-description"}).appendTo(div);
var labelText = getNodeLabelText(n);
var label = $('<div>',{class:"red-ui-search-result-node-label red-ui-info-outline-item-label"}).appendTo(contentDiv);
if (labelText) {
label.text(labelText)
} else {
label.html("&nbsp;")
}
var div = $('<div>',{class:"red-ui-node-list-item red-ui-info-outline-item"});
RED.utils.createNodeIcon(n, true).appendTo(div);
div.find(".red-ui-node-label").addClass("red-ui-info-outline-item-label")
addControls(n, div);
return div;
}
@ -430,7 +405,7 @@ RED.sidebar.info.outliner = (function() {
var existingObject = objects[n.id];
var parent = n.g||n.z||"__global__";
var nodeLabelText = getNodeLabelText(n);
var nodeLabelText = RED.utils.getNodeLabel(n,n.name || (n.type+": "+n.id));
if (nodeLabelText) {
existingObject.element.find(".red-ui-info-outline-item-label").text(nodeLabelText);
} else {

View File

@ -477,7 +477,7 @@ RED.sidebar.info = (function() {
return;
}
}
while ((m=/(\[(.*?)\])/.exec(tip))) {
while ((m=/(\[([a-z]*?)\])/.exec(tip))) {
tip = tip.replace(m[1],RED.keyboard.formatKey(m[2]));
}
tipBox.html(tip).fadeIn(200);
@ -499,7 +499,7 @@ RED.sidebar.info = (function() {
if (tipCount === -1) {
do {
tipCount++;
} while(RED._("infotips:info.tip"+tipCount)!=="infotips:info.tip"+tipCount);
} while(RED._("infotips:info.tip"+tipCount)!=="info.tip"+tipCount);
}
startTimeout = setTimeout(setTip,startDelay);
}

View File

@ -166,6 +166,8 @@ RED.tray = (function() {
setTimeout(function() {
// Delay resetting the flag, so we don't close prematurely
openingTray = false;
raiseTrayZ();
handleWindowResize();//cause call to monaco layout
},200);
body.find(":focusable:first").trigger("focus");
@ -206,6 +208,17 @@ RED.tray = (function() {
}
}
//raise tray z-index to prevent editor context menu being clipped by sidebar
function raiseTrayZ() {
setTimeout(function(){
$('#red-ui-editor-stack').css("zIndex","13");
},300);
}
//lower tray z-index back to original place for correct slide animation (related to fix for editor context menu clipped by sidebar)
function lowerTrayZ(){
$('#red-ui-editor-stack').css("zIndex","9");
}
return {
init: function init() {
editorStack = $("#red-ui-editor-stack");
@ -221,6 +234,7 @@ RED.tray = (function() {
});
},
show: function show(options) {
lowerTrayZ();
if (!options) {
if (stack.length > 0) {
var tray = stack[stack.length-1];
@ -252,6 +266,7 @@ RED.tray = (function() {
},
hide: function hide() {
lowerTrayZ();
if (stack.length > 0) {
var tray = stack[stack.length-1];
tray.tray.css({
@ -266,15 +281,16 @@ RED.tray = (function() {
},
resize: handleWindowResize,
close: function close(done) {
lowerTrayZ(); //lower tray z-index for correct animation
if (stack.length > 0) {
var tray = stack.pop();
tray.tray.css({
right: -(tray.tray.width()+10)+"px"
});
setTimeout(function() {
if (tray.options.close) {
tray.options.close();
}
try {
if (tray.options.close) { tray.options.close(); }
} catch (ex) { }
tray.tray.remove();
if (stack.length > 0) {
var oldTray = stack[stack.length-1];
@ -284,6 +300,8 @@ RED.tray = (function() {
handleWindowResize();
oldTray.tray.css({right:0});
if (oldTray.options.show) {
raiseTrayZ();
handleWindowResize();//cause call to monaco layout
oldTray.options.show();
}
},0);

View File

@ -178,8 +178,14 @@ RED.utils = (function() {
RED.popover.tooltip(pinPath,RED._("node-red:debug.sidebar.pinPath"));
}
if (extraTools) {
extraTools.addClass("red-ui-debug-msg-tools-other");
extraTools.appendTo(tools);
var t = extraTools;
if (typeof t === 'function') {
t = t(key,msg);
}
if (t) {
t.addClass("red-ui-debug-msg-tools-other");
t.appendTo(tools);
}
}
}
function checkExpanded(strippedKey,expandPaths,minRange,maxRange) {
@ -476,7 +482,8 @@ RED.utils = (function() {
rootPath: rootPath,
expandPaths: expandPaths,
ontoggle: ontoggle,
exposeApi: exposeApi
exposeApi: exposeApi,
tools: tools
}
).appendTo(row);
}
@ -504,8 +511,8 @@ RED.utils = (function() {
rootPath: rootPath,
expandPaths: expandPaths,
ontoggle: ontoggle,
exposeApi: exposeApi
exposeApi: exposeApi,
tools: tools
}
).appendTo(row);
}
@ -553,8 +560,8 @@ RED.utils = (function() {
rootPath: rootPath,
expandPaths: expandPaths,
ontoggle: ontoggle,
exposeApi: exposeApi
exposeApi: exposeApi,
tools: tools
}
).appendTo(row);
}
@ -875,6 +882,7 @@ RED.utils = (function() {
}
function getDefaultNodeIcon(def,node) {
def = def || {};
var icon_url;
if (node && node.type === "subflow") {
icon_url = "node-red/subflow.svg";
@ -912,6 +920,7 @@ RED.utils = (function() {
}
function getNodeIcon(def,node) {
def = def || {};
if (node && node.type === '_selection_') {
return "font-awesome/fa-object-ungroup";
} else if (node && node.type === 'group') {
@ -999,6 +1008,7 @@ RED.utils = (function() {
}
function getNodeColor(type, def) {
def = def || {};
var result = def.color;
var paletteTheme = RED.settings.theme('palette.theme') || [];
if (paletteTheme.length > 0) {
@ -1125,9 +1135,11 @@ RED.utils = (function() {
imageIconElement.css("backgroundImage", "url("+iconUrl+")");
}
function createNodeIcon(node) {
function createNodeIcon(node, includeLabel) {
var container = $('<span class="red-ui-node-icon-container">');
var def = node._def;
var nodeDiv = $('<div>',{class:"red-ui-search-result-node"})
var nodeDiv = $('<div>',{class:"red-ui-node-icon"})
if (node.type === "_selection_") {
nodeDiv.addClass("red-ui-palette-icon-selection");
} else if (node.type === "group") {
@ -1147,9 +1159,20 @@ RED.utils = (function() {
}
var icon_url = RED.utils.getNodeIcon(def,node);
var iconContainer = $('<div/>',{class:"red-ui-palette-icon-container"}).appendTo(nodeDiv);
RED.utils.createIconElement(icon_url, iconContainer, true);
return nodeDiv;
RED.utils.createIconElement(icon_url, nodeDiv, true);
nodeDiv.appendTo(container);
if (includeLabel) {
var labelText = RED.utils.getNodeLabel(node,node.name || (node.type+": "+node.id));
var label = $('<div>',{class:"red-ui-node-label"}).appendTo(container);
if (labelText) {
label.text(labelText)
} else {
label.html("&nbsp;")
}
}
return container;
}
function getDarkerColor(c) {
@ -1234,6 +1257,23 @@ RED.utils = (function() {
}
return false;
}
function getBrowserInfo() {
var r = {}
try {
var ua = navigator.userAgent;
r.ua = ua;
r.browser = /Edge\/\d+/.test(ua) ? 'ed' : /MSIE 9/.test(ua) ? 'ie9' : /MSIE 10/.test(ua) ? 'ie10' : /MSIE 11/.test(ua) ? 'ie11' : /MSIE\s\d/.test(ua) ? 'ie?' : /rv\:11/.test(ua) ? 'ie11' : /Firefox\W\d/.test(ua) ? 'ff' : /Chrom(e|ium)\W\d|CriOS\W\d/.test(ua) ? 'gc' : /\bSafari\W\d/.test(ua) ? 'sa' : /\bOpera\W\d/.test(ua) ? 'op' : /\bOPR\W\d/i.test(ua) ? 'op' : typeof MSPointerEvent !== 'undefined' ? 'ie?' : '';
r.os = /Windows NT 10/.test(ua) ? "win10" : /Windows NT 6\.0/.test(ua) ? "winvista" : /Windows NT 6\.1/.test(ua) ? "win7" : /Windows NT 6\.\d/.test(ua) ? "win8" : /Windows NT 5\.1/.test(ua) ? "winxp" : /Windows NT [1-5]\./.test(ua) ? "winnt" : /Mac/.test(ua) ? "mac" : /Linux/.test(ua) ? "linux" : /X11/.test(ua) ? "nix" : "";
r.touch = 'ontouchstart' in document.documentElement;
r.mobile = /IEMobile|Windows Phone|Lumia/i.test(ua) ? 'w' : /iPhone|iP[oa]d/.test(ua) ? 'i' : /Android/.test(ua) ? 'a' : /BlackBerry|PlayBook|BB10/.test(ua) ? 'b' : /Mobile Safari/.test(ua) ? 's' : /webOS|Mobile|Tablet|Opera Mini|\bCrMo\/|Opera Mobi/i.test(ua) ? 1 : 0;
r.tablet = /Tablet|iPad/i.test(ua);
r.ie = /MSIE \d|Trident.*rv:/.test(navigator.userAgent);
r.android = /android/i.test(navigator.userAgent);
} catch (error) { }
return r;
}
return {
createObjectElement: buildMessageElement,
getMessageProperty: getMessageProperty,
@ -1255,6 +1295,7 @@ RED.utils = (function() {
createNodeIcon: createNodeIcon,
getDarkerColor: getDarkerColor,
parseModuleList: parseModuleList,
checkModuleAllowed: checkModuleAllowed
checkModuleAllowed: checkModuleAllowed,
getBrowserInfo: getBrowserInfo
}
})();

View File

@ -1476,15 +1476,15 @@ RED.view = (function() {
var mouseY = node.n.y;
if (outer[0][0].getIntersectionList) {
var svgRect = outer[0][0].createSVGRect();
svgRect.x = mouseX;
svgRect.y = mouseY;
svgRect.x = mouseX*scaleFactor;
svgRect.y = mouseY*scaleFactor;
svgRect.width = 1;
svgRect.height = 1;
nodes = outer[0][0].getIntersectionList(svgRect, outer[0][0]);
} else {
// Firefox doesn"t do getIntersectionList and that
// makes us sad
nodes = RED.view.getLinksAtPoint(mouseX,mouseY);
nodes = RED.view.getLinksAtPoint(mouseX*scaleFactor,mouseY*scaleFactor);
}
for (var i=0;i<nodes.length;i++) {
if (d3.select(nodes[i]).classed("red-ui-flow-link-background")) {
@ -1751,7 +1751,6 @@ RED.view = (function() {
}
}
if (mouse_mode == RED.state.IMPORT_DRAGGING) {
RED.keyboard.remove("escape");
updateActiveNodes();
RED.nodes.dirty(true);
}
@ -1786,6 +1785,9 @@ RED.view = (function() {
}
function selectNone() {
if (mouse_mode === RED.state.MOVING || mouse_mode === RED.state.MOVING_ACTIVE) {
return;
}
if (mouse_mode === RED.state.IMPORT_DRAGGING) {
clearSelection();
RED.history.pop();
@ -3443,6 +3445,7 @@ RED.view = (function() {
}
}
function getGroupAt(x,y) {
// x,y expected to be in node-co-ordinate space
var candidateGroups = {};
for (var i=0;i<activeGroups.length;i++) {
var g = activeGroups[i];
@ -3786,7 +3789,9 @@ RED.view = (function() {
}
var node = nodeLayer.selectAll(".red-ui-flow-node-group").data(activeNodes,function(d){return d.id});
node.exit().remove();
node.exit().each(function(d,i) {
RED.hooks.trigger("viewRemoveNode",{node:d,el:this})
}).remove();
var nodeEnter = node.enter().insert("svg:g")
.attr("class", "red-ui-flow-node red-ui-flow-node-group")
@ -3960,6 +3965,7 @@ RED.view = (function() {
});
node.each(function(d,i) {
if (d.dirty) {
var self = this;
var thisNode = d3.select(this);
var isLink = (d.type === "link in" || d.type === "link out")
@ -4070,7 +4076,15 @@ RED.view = (function() {
var inputPorts = thisNode.selectAll(".red-ui-flow-port-input");
if ((!isLink || (showAllLinkPorts === -1 && !activeLinkNodes[d.id])) && d.inputs === 0 && !inputPorts.empty()) {
inputPorts.remove();
inputPorts.each(function(d,i) {
RED.hooks.trigger("viewRemovePort",{
node:d,
el:self,
port:d3.select(this)[0][0],
portType: "input",
portIndex: 0
})
}).remove();
} else if (((isLink && (showAllLinkPorts===PORT_TYPE_INPUT||activeLinkNodes[d.id]))|| d.inputs === 1) && inputPorts.empty()) {
var inputGroup = thisNode.append("g").attr("class","red-ui-flow-port-input");
var inputGroupPorts;
@ -4083,12 +4097,17 @@ RED.view = (function() {
} else {
inputGroupPorts = inputGroup.append("rect").attr("class","red-ui-flow-port").attr("rx",3).attr("ry",3).attr("width",10).attr("height",10)
}
inputGroup[0][0].__port__ = inputGroupPorts[0][0];
inputGroupPorts[0][0].__data__ = this.__data__;
inputGroupPorts[0][0].__portType__ = PORT_TYPE_INPUT;
inputGroupPorts[0][0].__portIndex__ = 0;
inputGroupPorts.on("mousedown",function(d){portMouseDown(d,PORT_TYPE_INPUT,0);})
.on("touchstart",function(d){portMouseDown(d,PORT_TYPE_INPUT,0);d3.event.preventDefault();})
.on("mouseup",function(d){portMouseUp(d,PORT_TYPE_INPUT,0);} )
.on("touchend",function(d){portMouseUp(d,PORT_TYPE_INPUT,0);d3.event.preventDefault();} )
.on("mouseover",function(d){portMouseOver(d3.select(this),d,PORT_TYPE_INPUT,0);})
.on("mouseout",function(d) {portMouseOut(d3.select(this),d,PORT_TYPE_INPUT,0);});
RED.hooks.trigger("viewAddPort",{node:d,el: this, port: inputGroup[0][0], portType: "input", portIndex: 0})
}
var numOutputs = d.outputs;
if (isLink && d.type === "link out") {
@ -4103,6 +4122,13 @@ RED.view = (function() {
// Remove extra ports
while (this.__outputs__.length > numOutputs) {
var port = this.__outputs__.pop();
RED.hooks.trigger("viewRemovePort",{
node:d,
el:this,
port:port,
portType: "output",
portIndex: this.__outputs__.length
})
port.remove();
}
for(var portIndex = 0; portIndex < numOutputs; portIndex++ ) {
@ -4126,6 +4152,7 @@ RED.view = (function() {
portPort.setAttribute("class","red-ui-flow-port");
}
portGroup.appendChild(portPort);
portGroup.__port__ = portPort;
portPort.__data__ = this.__data__;
portPort.__portType__ = PORT_TYPE_OUTPUT;
portPort.__portIndex__ = portIndex;
@ -4138,6 +4165,7 @@ RED.view = (function() {
this.appendChild(portGroup);
this.__outputs__.push(portGroup);
RED.hooks.trigger("viewAddPort",{node:d,el: this, port: portGroup, portType: "output", portIndex: portIndex})
} else {
portGroup = this.__outputs__[portIndex];
}
@ -4226,6 +4254,8 @@ RED.view = (function() {
// });
}
RED.hooks.trigger("viewAddNode",{node:d,el:this})
if (d.dirtyStatus) {
redrawStatus(d,this);
}
@ -5014,6 +5044,30 @@ RED.view = (function() {
}
return selection;
}
function calculateNodeDimensions(node) {
var result = [node_width,node_height];
try {
var isLink = (node.type === "link in" || node.type === "link out")
var hideLabel = node.hasOwnProperty('l')?!node.l : isLink;
var label = RED.utils.getNodeLabel(node, node.type);
var labelParts = getLabelParts(label, "red-ui-flow-node-label");
if (hideLabel) {
result[1] = Math.max(node_height,(node.outputs || 0) * 15);
} else {
result[1] = Math.max(6+24*labelParts.lines.length,(node.outputs || 0) * 15, 30);
}
if (hideLabel) {
result[0] = node_height;
} else {
result[0] = Math.max(node_width,20*(Math.ceil((labelParts.width+50+(node._def.inputs>0?7:0))/20)) );
}
}catch(err) {
console.log("Error",node);
}
return result;
}
return {
init: init,
state:function(state) {
@ -5079,6 +5133,9 @@ RED.view = (function() {
return scaleFactor;
},
getLinksAtPoint: function(x,y) {
// x,y must be in SVG co-ordinate space
// if they come from a node.x/y, they will need to be scaled using
// scaleFactor first.
var result = [];
var links = outer.selectAll(".red-ui-flow-link-background")[0];
for (var i=0;i<links.length;i++) {
@ -5242,6 +5299,7 @@ RED.view = (function() {
return clipboard
},
redrawStatus: redrawStatus,
showQuickAddDialog:showQuickAddDialog
showQuickAddDialog:showQuickAddDialog,
calculateNodeDimensions: calculateNodeDimensions
};
})();

View File

@ -493,7 +493,11 @@ RED.workspaces = (function() {
if (!workspace_tabs.contains(id)) {
var sf = RED.nodes.subflow(id);
if (sf) {
addWorkspace({type:"subflow",id:id,icon:"red/images/subflow_tab.svg",label:sf.name, closeable: true});
addWorkspace(
{type:"subflow",id:id,icon:"red/images/subflow_tab.svg",label:sf.name, closeable: true},
null,
workspace_tabs.activeIndex()+1
);
} else {
return;
}

View File

@ -149,7 +149,7 @@ body {
.red-ui-font-code {
font-family: $monospace-font;
font-size: $primary-font-size;
color: $info-text-code-color;
color: $text-color-code;
white-space: nowrap;
}
@ -158,7 +158,7 @@ body {
font-size: $primary-font-size;
padding: 0px;
margin: 1px;
color: $info-text-code-color;
color: $text-color-code;
white-space: nowrap;
}

View File

@ -48,15 +48,22 @@ $tertiary-text-color: #aaa;//#90f;
// Heading text
$header-text-color: #444;//#f00;
$text-color-warning: #AD1625;
$text-color-green: #3a3;
$text-color-error: #AD1625;
$text-color-warning: #CAB200;
$text-color-success: #3a3;
$text-color-code: #AD1625;
$text-color-link: #0088cc;
$primary-border-color: #bbbbbb;//#f00;
$secondary-border-color: #dddddd;//#0f0;
$tertiary-border-color: #ccc;//#00f;
$form-background: $secondary-background;
$border-color-error: #DF2935;
$border-color-warning: #FFCF70;
$border-color-success: #4B8400;
$form-background: $secondary-background;
$form-placeholder-color: $tertiary-text-color;
$form-text-color: $primary-text-color;
$form-text-color-disabled: $secondary-text-color-disabled;
@ -257,16 +264,13 @@ $headerMenuCaret: #C7C7C7;
$vcCommitShaColor: #c38888;
$info-text-code-color: #AD1625;
$info-text-link-color: #0088cc;
$dnd-background: rgba(0,0,0,0.3);
$dnd-color: #fff;
$notification-border-default: #325C80;
$notification-border-success: #4B8400;
$notification-border-warning: #D74108;
$notification-border-error: $text-color-warning;
$notification-border-success: $border-color-success;
$notification-border-warning: $border-color-warning;
$notification-border-error: $border-color-error;
$debug-message-background: $secondary-background;
$debug-message-background-hover: $secondary-background-selected;
@ -282,11 +286,16 @@ $debug-message-text-color-msg-type-number: #2033d6;
$debug-message-border: #eee;
$debug-message-border-hover: #999;
$debug-message-border-warning: #ffdf9d;
$debug-message-border-error: #f99;
$debug-message-border-warning: $border-color-warning;
$debug-message-border-error: $border-color-error;
$group-default-fill: none;
$group-default-fill-opacity: 1;
$group-default-stroke: #999;
$group-default-stroke-opacity: 1;
$group-default-label-color: #a4a4a4;
// Deprecated
$text-color-green: $text-color-success;
$info-text-code-color: $text-color-code;
$info-text-link-color: $text-color-link;

View File

@ -500,7 +500,7 @@ ul.red-ui-deploy-dialog-confirm-list {
width: 30px;
margin-right: 10px;
&.fa-check {
color: $text-color-green;
color: $text-color-success;
}
&.fa-exclamation {
color: $secondary-text-color;

View File

@ -222,7 +222,7 @@ button.red-ui-tray-resize-button {
}
.form-warning {
border-color: $text-color-warning;
border-color: $text-color-error;
}
}

View File

@ -255,11 +255,11 @@ g.red-ui-flow-node-selected {
}
}
@each $current-color in red green yellow blue grey gray {
.red-ui-flow-node-status-dot-#{$current-color} {
.red-ui-flow-node-status-dot-#{""+$current-color} {
fill: map-get($node-status-colors,$current-color);
stroke: map-get($node-status-colors,$current-color);
}
.red-ui-flow-node-status-ring-#{$current-color} {
.red-ui-flow-node-status-ring-#{""+$current-color} {
fill: $view-background;
stroke: map-get($node-status-colors,$current-color);
}

View File

@ -395,6 +395,7 @@
select[readonly],
textarea[readonly] {
cursor: not-allowed;
color: $form-text-color-disabled;
background-color: $form-input-background-disabled;
}

View File

@ -51,9 +51,8 @@
}
.red-ui-clipboard-dialog-tab-clipboard {
textarea {
color: $secondary-text-color-active !important;
resize: none;
width: 100%;
border-radius: 4px;

View File

@ -25,7 +25,7 @@
.red-ui-notification {
box-sizing: border-box;
position: relative;
padding: 14px 18px;
padding: 8px 18px 0px;
margin-bottom: 4px;
box-shadow: 0 1px 1px 1px $shadow;
background-color: $secondary-background;
@ -35,6 +35,7 @@
overflow: hidden;
.ui-dialog-buttonset {
margin-top: 20px;
margin-bottom: 10px;
}
}
.red-ui-notification p:first-child {

View File

@ -174,7 +174,7 @@
display: block;
text-align: center;
padding: 12px 8px;
color: $text-color-warning;
color: $text-color-code;
&:hover {
text-decoration: none;

View File

@ -134,7 +134,7 @@
&:not(.red-ui-palette-node-config):not(.red-ui-palette-node-small):first-child {
margin-top: 15px;
}
&:not(.red-ui-palette-node-config):not(.red-ui-palette-node-small):first-child {
&:not(.red-ui-palette-node-config):not(.red-ui-palette-node-small):last-child {
margin-bottom: 15px;
}
}
@ -229,3 +229,90 @@
left: 1px;
}
}
////////////////
.red-ui-node-list-item {
display: inline-block;
padding: 0;
font-size: 13px;
border: none;
}
.red-ui-node-icon {
display: inline-block;
width: 24px;
height: 20px;
line-height: 20px;
margin-top: 1px;
// width: 30px;
// height: 25px;
border-radius: 3px;
border: 1px solid $node-border;
background-position: 5% 50%;
background-repeat: no-repeat;
background-size: contain;
position: relative;
background-color: $node-icon-background-color;
text-align: center;
.red-ui-palette-icon {
width: 20px;
}
.red-ui-palette-icon-fa {
font-size: 14px;
position: relative;
top: -1px;
left: 0px;
}
&.red-ui-palette-icon-flow,
&.red-ui-palette-icon-group,
&.red-ui-palette-icon-selection {
background: none;
border-color: transparent;
.red-ui-palette-icon-container {
background: none;
}
.red-ui-palette-icon-fa {
color: $secondary-text-color;
font-size: 16px;
}
}
}
.red-ui-node-icon-container {
display: inline-flex;
align-items: center;
}
.red-ui-node-icon-container.red-ui-node-icon-small {
.red-ui-node-icon {
width: 18px;
height: 15px;
line-height: 15px;
.red-ui-palette-icon {
width: 15px;
}
.red-ui-palette-icon-fa {
font-size: 11px;
}
.red-ui-icons-flow {
width: 14px;
}
&.red-ui-palette-icon-flow {
margin-top: -2px;
}
&.red-ui-palette-icon-group .red-ui-palette-icon-fa {
font-size: 14px;
}
}
.red-ui-node-label {
}
}
.red-ui-node-label {
white-space: nowrap;
margin-left: 4px;
color: $secondary-text-color;
}

View File

@ -103,7 +103,7 @@
left: -1px;
}
.red-ui-search-result-description {
margin-left:28px;
margin-left:8px;
}
.red-ui-search-result-node-label {
color: $secondary-text-color;
@ -133,7 +133,8 @@
}
.red-ui-search-result {
padding: 8px 2px 8px 5px;
display: block;
display: flex;
align-items: start;
cursor: pointer;
color: $list-item-color;
background: $list-item-background;
@ -156,12 +157,7 @@
display: table;
clear: both;
}
.red-ui-palette-icon-fa {
top: 6px;
left: 3px;
}
}
.red-ui-search-result-node {
display: inline-block;
width: 30px;
@ -180,8 +176,9 @@
}
.red-ui-search-result-node-description {
margin-left: 40px;
margin-left: 10px;
margin-right: 5px;
flex-grow: 1;
}
.red-ui-search-result-node-label {
color: $primary-text-color;

View File

@ -46,7 +46,7 @@
right: 315px;
bottom:10px;
width: 7px;
z-index: 11;
// z-index: 11;
background: $primary-background url(images/grip.png) no-repeat 50% 50%;
cursor: col-resize;
}
@ -134,6 +134,7 @@ button.red-ui-sidebar-header-button-toggle {
right: calc(100%);
border-top-left-radius: 5px;
border-bottom-left-radius: 5px;
z-index: 13;
}
.red-ui-sidebar-control-left {
@include red-ui-sidebar-control;

View File

@ -15,6 +15,7 @@
**/
@import "colors";
@import "variables";
@import "mixins";
@import "base";

View File

@ -125,13 +125,13 @@ div.red-ui-info-table {
line-height: 1.5em;
a {
color: $info-text-link-color;
color: $text-color-link;
text-decoration: none;
}
a:hover,
a:focus {
color: $info-text-link-color;
color: $text-color-link;
text-decoration: underline;
}
@ -176,7 +176,7 @@ div.red-ui-info-table {
font-family: $monospace-font;
font-weight: normal;
margin: 5px 3px 1px;
color: $text-color-warning;
color: $text-color-code;
white-space: nowrap;
&.optional {
font-style: italic;
@ -326,13 +326,17 @@ div.red-ui-info-table {
border-bottom: 1px solid $secondary-border-color;
}
}
.red-ui-info-outline,.red-ui-sidebar-help-toc, #red-ui-clipboard-dialog-import-conflicts-list, #red-ui-clipboard-dialog-export-tab-clipboard-preview {
.red-ui-info-outline,
// TODO: remove these classes for 2.0. Keeping in 1.x for backwards compatibility
// of theme generators.
.red-ui-sidebar-help-toc, #red-ui-clipboard-dialog-import-conflicts-list, #red-ui-clipboard-dialog-export-tab-clipboard-preview
{
.red-ui-info-outline-item {
display: inline-block;
padding: 0;
font-size: 13px;
border: none;
.red-ui-palette-icon-fa {
&:not(.red-ui-node-list-item) .red-ui-palette-icon-fa {
position: relative;
top: 1px;
left: 0px;

View File

@ -24,7 +24,7 @@
margin: 0;
vertical-align: middle;
box-sizing: border-box;
overflow:visible;
overflow: hidden;
position: relative;
&[disabled] {
input, button {

View File

@ -0,0 +1,86 @@
:root {
--red-ui-primary-font: #{$primary-font};
--red-ui-primary-font-size: #{$primary-font-size};
--red-ui-monospace-font: #{$monospace-font};
--red-ui-primary-background: #{$primary-background};
--red-ui-secondary-background: #{$secondary-background};
--red-ui-secondary-background-selected: #{$secondary-background-selected};
--red-ui-secondary-background-inactive: #{$secondary-background-inactive};
--red-ui-secondary-background-hover: #{$secondary-background-hover};
--red-ui-secondary-background-disabled: #{$secondary-background-disabled};
--red-ui-tertiary-background: #{$tertiary-background};
--red-ui-shadow: #{$shadow};
// Main body text
--red-ui-primary-text-color: #{$primary-text-color};
// UI control label text
--red-ui-secondary-text-color: #{$secondary-text-color};
--red-ui-secondary-text-color-focus: #{$secondary-text-color-focus};
--red-ui-secondary-text-color-hover: #{$secondary-text-color-hover};
--red-ui-secondary-text-color-active: #{$secondary-text-color-active};
--red-ui-secondary-text-color-selected: #{$secondary-text-color-selected};
--red-ui-secondary-text-color-inactive: #{$secondary-text-color-inactive};
--red-ui-secondary-text-color-disabled: #{$secondary-text-color-disabled};
--red-ui-secondary-text-color-disabled-active: #{$secondary-text-color-disabled-active};
--red-ui-secondary-text-color-disabled-inactive: #{$secondary-text-color-disabled-inactive};
// Sub label text
--red-ui-tertiary-text-color: #{$tertiary-text-color};
// Heading text
--red-ui-header-text-color: #{$header-text-color};
--red-ui-text-color-error: #{$text-color-error};
--red-ui-text-color-warning: #{$text-color-warning};
--red-ui-text-color-success: #{$text-color-success};
--red-ui-text-color-code: #{$text-color-code};
--red-ui-text-color-link: #{$text-color-link};
--red-ui-primary-border-color: #{$primary-border-color};
--red-ui-secondary-border-color: #{$secondary-border-color};
--red-ui-tertiary-border-color: #{$tertiary-border-color};
--red-ui-border-color-error: #{$border-color-error};
--red-ui-border-color-warning: #{$border-color-warning};
--red-ui-border-color-success: #{$border-color-success};
--red-ui-form-background: #{$form-background};
--red-ui-form-placeholder-color: #{$form-placeholder-color};
--red-ui-form-text-color: #{$form-text-color};
--red-ui-form-text-color-disabled: #{$form-text-color-disabled};
--red-ui-form-input-border-color: #{$form-input-border-color};
--red-ui-form-input-border-color-focus: #{$form-input-focus-color};
--red-ui-form-input-border-color-selected: #{$form-input-border-selected-color};
--red-ui-form-input-border-color-error: #{$form-input-border-error-color};
--red-ui-form-input-background: #{$form-input-background};
--red-ui-form-input-background-disabled: #{$form-input-background-disabled};
--red-ui-form-button-background: #{$form-button-background};
--red-ui-form-tips-background: #{$form-tips-background};
--red-ui-list-item-color: #{$list-item-color};
--red-ui-list-item-secondary-color: #{$list-item-secondary-color};
--red-ui-list-item-background: #{$list-item-background};
--red-ui-list-item-background-disabled: #{$list-item-background-disabled};
--red-ui-list-item-background-hover: #{$list-item-background-hover};
--red-ui-list-item-background-selected: #{$list-item-background-selected};
--red-ui-list-item-border-selected: #{$list-item-border-selected};
--red-ui-shade-color: #{$shade-color};
--red-ui-node-link-port-background: #{$node-link-port-background};
--red-ui-node-status-error-border: #{$node-status-error-border};
--red-ui-node-status-error-background: #{$node-status-error-background};
--red-ui-node-status-changed-border: #{$node-status-changed-border};
--red-ui-node-status-changed-background: #{$node-status-changed-background};
--red-ui-node-selected-color: #{$node-selected-color};
--red-ui-port-selected-color: #{$port-selected-color};
}

View File

@ -0,0 +1,39 @@
node and node-red types for intellisense for monaco
---------------------------------------------------
node-js and node-red types are included in node-red for monaco and any other editor to provide intellisense in the code editor
as node-js v14 is the default recommended target as of writing, the most popular node-js types (see below) have been taken from most up-to-date types from `@types/node` and minified using `dts-minify`
* buffer.d.ts
* console.d.ts
* crypto.d.ts
* fs.d.ts
* globals.d.ts
* http.d.ts
* net.d.ts
* os.d.ts
* process.d.ts
* querystring.d.ts
* string_decoder.d.ts
* url.d.ts
* zlib.d.ts
These are placed in `node_modules/@node-red/editor-client/src/`
The grunt task will place this default set of typings in `node_modules/@node-red/editor-client/public/types/` for consumption by the code editor.
# Instructions
See packages/node_modules/@node-red/editor-client/src/vendor/monaco/README.md
# Alternative / Manual Installation
* `npm install --save @types/node@14.14.43`
* (optional) minify using `dts-minify`
* copy files from `node_modules/@node-red/editor-client/src/` to `(node-red-src)/packages/node_modules/@node-red/editor-client/src/types/node`
* update types for node-red in files to match src definitions...
* (node-red-src)/packages/node_modules/@node-red/editor-client/src/types/node-red/func.d.ts
* (node-red-src)/packages/node_modules/@node-red/editor-client/src/types/node-red/util.d.ts

View File

@ -0,0 +1,108 @@
/* NOTE: Do not edit directly! This file is generated using \`npm run update-types\` in https://github.com/Steve-Mcl/monaco-editor-esm-i18n */
interface NodeMessage {
topic?: string;
payload?: any;
_msgid?: string;
[other: string]: any; //permit other properties
}
/** @type {NodeMessage} the `msg` object */
declare var msg: NodeMessage;
/** @type {string} the id of the incoming `msg` (alias of msg._msgid) */
declare const __msgid__:string;
/**
* @typedef NodeStatus
* @type {object}
* @property {string} [fill] The fill property can be: red, green, yellow, blue or grey.
* @property {string} [shape] The shape property can be: ring or dot.
* @property {string} [text] The text to display
*/
interface NodeStatus {
/** The fill property can be: red, green, yellow, blue or grey */
fill?: string,
/** The shape property can be: ring or dot */
shape?: string,
/** The text to display */
text?: string
}
declare class node {
/**
* Send 1 or more messages asynchronously
* @param {object | object[]} msg The msg object
* @param {Boolean} [clone=true] Flag to indicate the `msg` should be cloned. Default = `true`
* @example Send 1 msg to output 1
* ```javascript
* node.send({ payload: "a" });
* ```
* @example Send 2 msg to 2 outputs
* ```javascript
* node.send([{ payload: "output1" }, { payload: "output2" }]);
* ```
* @example Send 3 msg to output 1
* ```javascript
* node.send([[{ payload: 1 }, { payload: 2 }, { payload: 3 }]]);
* ```
* @see node-red documentation [writing-functions: sending messages asynchronously](https://nodered.org/docs/user-guide/writing-functions#sending-messages-asynchronously)
*/
static send(msg:object, clone?:Boolean);
/** Inform runtime this instance has completed its operation */
static done();
/** Send an error to the console and debug side bar. Include `msg` in the 2nd parameter to trigger the catch node. */
static error(err:string|Error, msg?:object);
/** Log a warn message to the console and debug sidebar */
static warn(warning:string|Object);
/** Log an info message to the console (not sent to sidebar)' */
static log(info:string|Object);
/** Set the status icon and text underneath the node.
* @param {NodeStatus} status - The status object `{fill, shape, text}`
* @example clear node status
* ```javascript
* node.status({});
* ```
* @example set node status to red ring with text
* ```javascript
* node.status({fill:"red",shape:"ring",text:"error"})
* ```
* @see node-red documentation [writing-functions: adding-status](https://nodered.org/docs/user-guide/writing-functions#adding-status)
*/
static status(status:NodeStatus);
/** the id of this node */
public readonly id:string;
/** the name of this node */
public readonly name:string;
/** the number of outputs of this node */
public readonly outputCount:Number;
}
declare class context {
/** Get a value from context */
static get(name:string, store?:string);
/** Store a value in context */
static set(name:string, value:any, store?:string);
/** Get an array of the keys in the context store */
static keys(store?:string):Array<string> ;
}
declare class flow {
/** Get a value from flow context */
static get(name:string, store?:string);
/** Store a value in flow context */
static set(name:string, value:any, store?:string);
/** Get an array of the keys in the flow context store */
static keys(store?:string):Array<string> ;
}
declare class global {
/** Get a value from global context */
static get(name:string, store?:string);
/** Store a value in global context */
static set(name:string, value:any, store?:string);
/** Get an array of the keys in the global context store */
static keys(store?:string):Array<string> ;
}
declare class env {
/** Get an environment variable value */
static get(name:string);
}

View File

@ -0,0 +1,211 @@
/* NOTE: Do not edit directly! This file is generated using \`npm run update-types\` in https://github.com/Steve-Mcl/monaco-editor-esm-i18n */
/*
How to generate...
1. Generate from packages\node_modules\@node-red\util\lib\util.js using `npx typescript` and a tsconfig.json of...
{
"files": ["packages/node_modules/@node-red/util/lib/util.js"],
"compilerOptions": {
"allowJs": true,
"declaration": true,
"emitDeclarationOnly": true,
"outDir": "types",
"strict": false,
"moduleResolution": "node"
}
}
2. remove all the `export ` statements
3. Wrap the remaining code in declare namespace RED { declare namespace util { ... } }
4. check . adjust types like String --> string, Object --> object etc (where appropriate)
*/
declare namespace RED {
/**
* Utility functions for the node-red function sandbox
*/
namespace util {
/**
* Encode an object to JSON without losing information about non-JSON types
* such as Buffer and Function.
*
* *This function is closely tied to its reverse within the editor*
*
* @param {Object} msg
* @param {Object} opts
* @return {Object} the encoded object
* @memberof @node-red/util_util
*/
function encodeObject(msg: any, opts: any): any;
/**
* Converts the provided argument to a String, using type-dependent
* methods.
*
* @param {any} o - the property to convert to a String
* @return {string} the stringified version
* @memberof @node-red/util_util
*/
function ensureString(o: any): string;
/**
* Converts the provided argument to a Buffer, using type-dependent
* methods.
*
* @param {any} o - the property to convert to a Buffer
* @return {string} the Buffer version
* @memberof @node-red/util_util
*/
function ensureBuffer(o: any): string;
/**
* Safely clones a message object. This handles msg.req/msg.res objects that must
* not be cloned.
*
* @param {object} msg - the message object to clone
* @return {object} the cloned message
* @memberof @node-red/util_util
*/
function cloneMessage(msg: object): object;
/**
* Compares two objects, handling various JavaScript types.
*
* @param {any} obj1
* @param {any} obj2
* @return {boolean} whether the two objects are the same
* @memberof @node-red/util_util
*/
function compareObjects(obj1: any, obj2: any): boolean;
/**
* Generates a psuedo-unique-random id.
* @return {string} a random-ish id
* @memberof @node-red/util_util
*/
function generateId(): string;
/**
* Gets a property of a message object.
*
* Unlike {@link @node-red/util-util.getObjectProperty}, this function will strip `msg.` from the
* front of the property expression if present.
*
* @param {object} msg - the message object
* @param {string} expr - the property expression
* @return {any} the message property, or undefined if it does not exist
* @throws Will throw an error if the *parent* of the property does not exist
* @memberof @node-red/util_util
*/
function getMessageProperty(msg: object, expr: string): any;
/**
* Sets a property of a message object.
*
* Unlike {@link @node-red/util-util.setObjectProperty}, this function will strip `msg.` from the
* front of the property expression if present.
*
* @param {object} msg - the message object
* @param {string} prop - the property expression
* @param {any} [value] - the value to set
* @param {boolean} [createMissing] - whether to create missing parent properties
* @memberof @node-red/util_util
*/
function setMessageProperty(msg: object, prop: string, value?: any, createMissing?: boolean): boolean;
/**
* Gets a property of an object.
*
* Given the object:
*
* {
* "pet": {
* "type": "cat"
* }
* }
*
* - `pet.type` will return `"cat"`.
* - `pet.name` will return `undefined`
* - `car` will return `undefined`
* - `car.type` will throw an Error (as `car` does not exist)
*
* @param {object} msg - the object
* @param {string} expr - the property expression
* @return {any} the object property, or undefined if it does not exist
* @throws Will throw an error if the *parent* of the property does not exist
* @memberof @node-red/util_util
*/
function getObjectProperty(msg: object, expr: string): any;
/**
* Sets a property of an object.
*
* @param {object} msg - the object
* @param {string} prop - the property expression
* @param {any} [value] - the value to set
* @param {boolean} [createMissing] - whether to create missing parent properties
* @memberof @node-red/util_util
*/
function setObjectProperty(msg: object, prop: string, value?: any, createMissing?: boolean): boolean;
/**
* Evaluates a property value according to its type.
*
* @param {string} value - the raw value
* @param {string} type - the type of the value
* @param {Node} node - the node evaluating the property
* @param {Object} msg - the message object to evaluate against
* @param {Function} callback - (optional) called when the property is evaluated
* @return {any} The evaluated property, if no `callback` is provided
* @memberof @node-red/util_util
*/
function evaluateNodeProperty(value: string, type: string, node: Node, msg: any, callback: Function): any;
/**
* Parses a property expression, such as `msg.foo.bar[3]` to validate it
* and convert it to a canonical version expressed as an Array of property
* names.
*
* For example, `a["b"].c` returns `['a','b','c']`
*
* @param {string} str - the property expression
* @return {any[]} the normalised expression
* @memberof @node-red/util_util
*/
function normalisePropertyExpression(str: string): any[];
/**
* Normalise a node type name to camel case.
*
* For example: `a-random node type` will normalise to `aRandomNodeType`
*
* @param {string} name - the node type
* @return {string} The normalised name
* @memberof @node-red/util_util
*/
function normaliseNodeTypeName(name: string): string;
/**
* Prepares a JSONata expression for evaluation.
* This attaches Node-RED specific functions to the expression.
*
* @param {string} value - the JSONata expression
* @param {Node} node - the node evaluating the property
* @return {any} The JSONata expression that can be evaluated
* @memberof @node-red/util_util
*/
function prepareJSONataExpression(value: string, node: Node): any;
/**
* Evaluates a JSONata expression.
* The expression must have been prepared with {@link @node-red/util-util.prepareJSONataExpression}
* before passing to this function.
*
* @param {Object} expr - the prepared JSONata expression
* @param {Object} msg - the message object to evaluate against
* @param {Function} callback - (optional) called when the expression is evaluated
* @return {any} If no callback was provided, the result of the expression
* @memberof @node-red/util_util
*/
function evaluateJSONataExpression(expr: any, msg: any, callback: Function): any;
/**
* Parses a context property string, as generated by the TypedInput, to extract
* the store name if present.
*
* For example, `#:(file)::foo` results in ` { store: "file", key: "foo" }`.
*
* @param {string} key - the context property string to parse
* @return {any} The parsed property
* @memberof @node-red/util_util
*/
function parseContextStore(key: string): any;
}
}

View File

@ -0,0 +1 @@
declare module'node:buffer'{export*from'buffer';}declare module'buffer'{export const INSPECT_MAX_BYTES:number;export const kMaxLength:number;export const kStringMaxLength:number;export const constants:{MAX_LENGTH:number;MAX_STRING_LENGTH:number;};const BuffType:typeof Buffer;export type TranscodeEncoding="ascii"|"utf8"|"utf16le"|"ucs2"|"latin1"|"binary";export function transcode(source:Uint8Array,fromEnc:TranscodeEncoding,toEnc:TranscodeEncoding):Buffer;export const SlowBuffer:{new(size:number):Buffer;prototype:Buffer;};export{BuffType as Buffer};}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
declare module'node:console'{export=console;}declare module'console'{import{InspectOptions}from'node:util';global{interface Console{Console:NodeJS.ConsoleConstructor;assert(value:any,message?:string,...optionalParams:any[]):void;clear():void;count(label?:string):void;countReset(label?:string):void;debug(message?:any,...optionalParams:any[]):void;dir(obj:any,options?:InspectOptions):void;dirxml(...data:any[]):void;error(message?:any,...optionalParams:any[]):void;group(...label:any[]):void;groupCollapsed(...label:any[]):void;groupEnd():void;info(message?:any,...optionalParams:any[]):void;log(message?:any,...optionalParams:any[]):void;table(tabularData:any,properties?:ReadonlyArray<string>):void;time(label?:string):void;timeEnd(label?:string):void;timeLog(label?:string,...data:any[]):void;trace(message?:any,...optionalParams:any[]):void;warn(message?:any,...optionalParams:any[]):void;profile(label?:string):void;profileEnd(label?:string):void;timeStamp(label?:string):void;}var console:Console;namespace NodeJS{interface ConsoleConstructorOptions{stdout:WritableStream;stderr?:WritableStream;ignoreErrors?:boolean;colorMode?:boolean|'auto';inspectOptions?:InspectOptions;}interface ConsoleConstructor{prototype:Console;new(stdout:WritableStream,stderr?:WritableStream,ignoreErrors?:boolean):Console;new(options:ConsoleConstructorOptions):Console;}interface Global{console:typeof console;}}}export=console;}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
declare module'node:dgram'{export*from'dgram';}declare module'dgram'{import{AddressInfo}from'node:net';import*as dns from'node:dns';import EventEmitter=require('node:events');interface RemoteInfo{address:string;family:'IPv4'|'IPv6';port:number;size:number;}interface BindOptions{port?:number;address?:string;exclusive?:boolean;fd?:number;}type SocketType="udp4"|"udp6";interface SocketOptions{type:SocketType;reuseAddr?:boolean;ipv6Only?:boolean;recvBufferSize?:number;sendBufferSize?:number;lookup?:(hostname:string,options:dns.LookupOneOptions,callback:(err:NodeJS.ErrnoException|null,address:string,family:number)=>void)=>void;}function createSocket(type:SocketType,callback?:(msg:Buffer,rinfo:RemoteInfo)=>void):Socket;function createSocket(options:SocketOptions,callback?:(msg:Buffer,rinfo:RemoteInfo)=>void):Socket;class Socket extends EventEmitter{addMembership(multicastAddress:string,multicastInterface?:string):void;address():AddressInfo;bind(port?:number,address?:string,callback?:()=>void):void;bind(port?:number,callback?:()=>void):void;bind(callback?:()=>void):void;bind(options:BindOptions,callback?:()=>void):void;close(callback?:()=>void):void;connect(port:number,address?:string,callback?:()=>void):void;connect(port:number,callback:()=>void):void;disconnect():void;dropMembership(multicastAddress:string,multicastInterface?:string):void;getRecvBufferSize():number;getSendBufferSize():number;ref():this;remoteAddress():AddressInfo;send(msg:string|Uint8Array|ReadonlyArray<any>,port?:number,address?:string,callback?:(error:Error|null,bytes:number)=>void):void;send(msg:string|Uint8Array|ReadonlyArray<any>,port?:number,callback?:(error:Error|null,bytes:number)=>void):void;send(msg:string|Uint8Array|ReadonlyArray<any>,callback?:(error:Error|null,bytes:number)=>void):void;send(msg:string|Uint8Array,offset:number,length:number,port?:number,address?:string,callback?:(error:Error|null,bytes:number)=>void):void;send(msg:string|Uint8Array,offset:number,length:number,port?:number,callback?:(error:Error|null,bytes:number)=>void):void;send(msg:string|Uint8Array,offset:number,length:number,callback?:(error:Error|null,bytes:number)=>void):void;setBroadcast(flag:boolean):void;setMulticastInterface(multicastInterface:string):void;setMulticastLoopback(flag:boolean):void;setMulticastTTL(ttl:number):void;setRecvBufferSize(size:number):void;setSendBufferSize(size:number):void;setTTL(ttl:number):void;unref():this;addSourceSpecificMembership(sourceAddress:string,groupAddress:string,multicastInterface?:string):void;dropSourceSpecificMembership(sourceAddress:string,groupAddress:string,multicastInterface?:string):void;addListener(event:string,listener:(...args:any[])=>void):this;addListener(event:"close",listener:()=>void):this;addListener(event:"connect",listener:()=>void):this;addListener(event:"error",listener:(err:Error)=>void):this;addListener(event:"listening",listener:()=>void):this;addListener(event:"message",listener:(msg:Buffer,rinfo:RemoteInfo)=>void):this;emit(event:string|symbol,...args:any[]):boolean;emit(event:"close"):boolean;emit(event:"connect"):boolean;emit(event:"error",err:Error):boolean;emit(event:"listening"):boolean;emit(event:"message",msg:Buffer,rinfo:RemoteInfo):boolean;on(event:string,listener:(...args:any[])=>void):this;on(event:"close",listener:()=>void):this;on(event:"connect",listener:()=>void):this;on(event:"error",listener:(err:Error)=>void):this;on(event:"listening",listener:()=>void):this;on(event:"message",listener:(msg:Buffer,rinfo:RemoteInfo)=>void):this;once(event:string,listener:(...args:any[])=>void):this;once(event:"close",listener:()=>void):this;once(event:"connect",listener:()=>void):this;once(event:"error",listener:(err:Error)=>void):this;once(event:"listening",listener:()=>void):this;once(event:"message",listener:(msg:Buffer,rinfo:RemoteInfo)=>void):this;prependListener(event:string,listener:(...args:any[])=>void):this;prependListener(event:"close",listener:()=>void):this;prependListener(event:"connect",listener:()=>void):this;prependListener(event:"error",listener:(err:Error)=>void):this;prependListener(event:"listening",listener:()=>void):this;prependListener(event:"message",listener:(msg:Buffer,rinfo:RemoteInfo)=>void):this;prependOnceListener(event:string,listener:(...args:any[])=>void):this;prependOnceListener(event:"close",listener:()=>void):this;prependOnceListener(event:"connect",listener:()=>void):this;prependOnceListener(event:"error",listener:(err:Error)=>void):this;prependOnceListener(event:"listening",listener:()=>void):this;prependOnceListener(event:"message",listener:(msg:Buffer,rinfo:RemoteInfo)=>void):this;}}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
declare module'node:domain'{export*from'domain';}declare module'domain'{import EventEmitter=require('node:events');global{namespace NodeJS{interface Domain extends EventEmitter{run<T>(fn:(...args:any[])=>T,...args:any[]):T;add(emitter:EventEmitter|Timer):void;remove(emitter:EventEmitter|Timer):void;bind<T extends Function>(cb:T):T;intercept<T extends Function>(cb:T):T;}}}interface Domain extends NodeJS.Domain{}class Domain extends EventEmitter{members:Array<EventEmitter|NodeJS.Timer>;enter():void;exit():void;}function create():Domain;}

View File

@ -0,0 +1 @@
declare module'node:events'{import EventEmitter=require('events');export=EventEmitter;}declare module'events'{interface EventEmitterOptions{captureRejections?:boolean;}interface NodeEventTarget{once(event:string|symbol,listener:(...args:any[])=>void):this;}interface DOMEventTarget{addEventListener(event:string,listener:(...args:any[])=>void,opts?:{once:boolean}):any;}interface EventEmitter extends NodeJS.EventEmitter{}class EventEmitter{constructor(options?:EventEmitterOptions);static once(emitter:NodeEventTarget,event:string|symbol):Promise<any[]>;static once(emitter:DOMEventTarget,event:string):Promise<any[]>;static on(emitter:NodeJS.EventEmitter,event:string):AsyncIterableIterator<any>;static listenerCount(emitter:NodeJS.EventEmitter,event:string|symbol):number;static readonly errorMonitor:unique symbol;static readonly captureRejectionSymbol:unique symbol;static captureRejections:boolean;static defaultMaxListeners:number;}import internal=require('events');namespace EventEmitter{export{internal as EventEmitter};}global{namespace NodeJS{interface EventEmitter{addListener(event:string|symbol,listener:(...args:any[])=>void):this;on(event:string|symbol,listener:(...args:any[])=>void):this;once(event:string|symbol,listener:(...args:any[])=>void):this;removeListener(event:string|symbol,listener:(...args:any[])=>void):this;off(event:string|symbol,listener:(...args:any[])=>void):this;removeAllListeners(event?:string|symbol):this;setMaxListeners(n:number):this;getMaxListeners():number;listeners(event:string|symbol):Function[];rawListeners(event:string|symbol):Function[];emit(event:string|symbol,...args:any[]):boolean;listenerCount(event:string|symbol):number;prependListener(event:string|symbol,listener:(...args:any[])=>void):this;prependOnceListener(event:string|symbol,listener:(...args:any[])=>void):this;eventNames():Array<string|symbol>;}}}export=EventEmitter;}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
declare module'node:os'{export*from'os';}declare module'os'{interface CpuInfo{model:string;speed:number;times:{user:number;nice:number;sys:number;idle:number;irq:number;};}interface NetworkInterfaceBase{address:string;netmask:string;mac:string;internal:boolean;cidr:string|null;}interface NetworkInterfaceInfoIPv4 extends NetworkInterfaceBase{family:"IPv4";}interface NetworkInterfaceInfoIPv6 extends NetworkInterfaceBase{family:"IPv6";scopeid:number;}interface UserInfo<T>{username:T;uid:number;gid:number;shell:T;homedir:T;}type NetworkInterfaceInfo=NetworkInterfaceInfoIPv4|NetworkInterfaceInfoIPv6;function hostname():string;function loadavg():number[];function uptime():number;function freemem():number;function totalmem():number;function cpus():CpuInfo[];function type():string;function release():string;function networkInterfaces():NodeJS.Dict<NetworkInterfaceInfo[]>;function homedir():string;function userInfo(options:{encoding:'buffer'}):UserInfo<Buffer>;function userInfo(options?:{encoding:BufferEncoding}):UserInfo<string>;type SignalConstants={[key in NodeJS.Signals]:number;};namespace constants{const UV_UDP_REUSEADDR:number;namespace signals{}const signals:SignalConstants;namespace errno{const E2BIG:number;const EACCES:number;const EADDRINUSE:number;const EADDRNOTAVAIL:number;const EAFNOSUPPORT:number;const EAGAIN:number;const EALREADY:number;const EBADF:number;const EBADMSG:number;const EBUSY:number;const ECANCELED:number;const ECHILD:number;const ECONNABORTED:number;const ECONNREFUSED:number;const ECONNRESET:number;const EDEADLK:number;const EDESTADDRREQ:number;const EDOM:number;const EDQUOT:number;const EEXIST:number;const EFAULT:number;const EFBIG:number;const EHOSTUNREACH:number;const EIDRM:number;const EILSEQ:number;const EINPROGRESS:number;const EINTR:number;const EINVAL:number;const EIO:number;const EISCONN:number;const EISDIR:number;const ELOOP:number;const EMFILE:number;const EMLINK:number;const EMSGSIZE:number;const EMULTIHOP:number;const ENAMETOOLONG:number;const ENETDOWN:number;const ENETRESET:number;const ENETUNREACH:number;const ENFILE:number;const ENOBUFS:number;const ENODATA:number;const ENODEV:number;const ENOENT:number;const ENOEXEC:number;const ENOLCK:number;const ENOLINK:number;const ENOMEM:number;const ENOMSG:number;const ENOPROTOOPT:number;const ENOSPC:number;const ENOSR:number;const ENOSTR:number;const ENOSYS:number;const ENOTCONN:number;const ENOTDIR:number;const ENOTEMPTY:number;const ENOTSOCK:number;const ENOTSUP:number;const ENOTTY:number;const ENXIO:number;const EOPNOTSUPP:number;const EOVERFLOW:number;const EPERM:number;const EPIPE:number;const EPROTO:number;const EPROTONOSUPPORT:number;const EPROTOTYPE:number;const ERANGE:number;const EROFS:number;const ESPIPE:number;const ESRCH:number;const ESTALE:number;const ETIME:number;const ETIMEDOUT:number;const ETXTBSY:number;const EWOULDBLOCK:number;const EXDEV:number;const WSAEINTR:number;const WSAEBADF:number;const WSAEACCES:number;const WSAEFAULT:number;const WSAEINVAL:number;const WSAEMFILE:number;const WSAEWOULDBLOCK:number;const WSAEINPROGRESS:number;const WSAEALREADY:number;const WSAENOTSOCK:number;const WSAEDESTADDRREQ:number;const WSAEMSGSIZE:number;const WSAEPROTOTYPE:number;const WSAENOPROTOOPT:number;const WSAEPROTONOSUPPORT:number;const WSAESOCKTNOSUPPORT:number;const WSAEOPNOTSUPP:number;const WSAEPFNOSUPPORT:number;const WSAEAFNOSUPPORT:number;const WSAEADDRINUSE:number;const WSAEADDRNOTAVAIL:number;const WSAENETDOWN:number;const WSAENETUNREACH:number;const WSAENETRESET:number;const WSAECONNABORTED:number;const WSAECONNRESET:number;const WSAENOBUFS:number;const WSAEISCONN:number;const WSAENOTCONN:number;const WSAESHUTDOWN:number;const WSAETOOMANYREFS:number;const WSAETIMEDOUT:number;const WSAECONNREFUSED:number;const WSAELOOP:number;const WSAENAMETOOLONG:number;const WSAEHOSTDOWN:number;const WSAEHOSTUNREACH:number;const WSAENOTEMPTY:number;const WSAEPROCLIM:number;const WSAEUSERS:number;const WSAEDQUOT:number;const WSAESTALE:number;const WSAEREMOTE:number;const WSASYSNOTREADY:number;const WSAVERNOTSUPPORTED:number;const WSANOTINITIALISED:number;const WSAEDISCON:number;const WSAENOMORE:number;const WSAECANCELLED:number;const WSAEINVALIDPROCTABLE:number;const WSAEINVALIDPROVIDER:number;const WSAEPROVIDERFAILEDINIT:number;const WSASYSCALLFAILURE:number;const WSASERVICE_NOT_FOUND:number;const WSATYPE_NOT_FOUND:number;const WSA_E_NO_MORE:number;const WSA_E_CANCELLED:number;const WSAEREFUSED:number;}namespace priority{const PRIORITY_LOW:number;const PRIORITY_BELOW_NORMAL:number;const PRIORITY_NORMAL:number;const PRIORITY_ABOVE_NORMAL:number;const PRIORITY_HIGH:number;const PRIORITY_HIGHEST:number;}}function arch():string;function version():string;function platform():NodeJS.Platform;function tmpdir():string;const EOL:string;function endianness():"BE"|"LE";function getPriority(pid?:number):number;function setPriority(priority:number):void;function setPriority(pid:number,priority:number):void;}

View File

@ -0,0 +1 @@
declare module'node:path'{import path=require('path');export=path;}declare module'path'{namespace path{interface ParsedPath{root:string;dir:string;base:string;ext:string;name:string;}interface FormatInputPathObject{root?:string;dir?:string;base?:string;ext?:string;name?:string;}interface PlatformPath{normalize(p:string):string;join(...paths:string[]):string;resolve(...pathSegments:string[]):string;isAbsolute(p:string):boolean;relative(from:string,to:string):string;dirname(p:string):string;basename(p:string,ext?:string):string;extname(p:string):string;readonly sep:string;readonly delimiter:string;parse(p:string):ParsedPath;format(pP:FormatInputPathObject):string;toNamespacedPath(path:string):string;readonly posix:PlatformPath;readonly win32:PlatformPath;}}const path:path.PlatformPath;export=path;}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
declare module'node:querystring'{export*from'querystring';}declare module'querystring'{interface StringifyOptions{encodeURIComponent?:(str:string)=>string;}interface ParseOptions{maxKeys?:number;decodeURIComponent?:(str:string)=>string;}interface ParsedUrlQuery extends NodeJS.Dict<string|string[]>{}interface ParsedUrlQueryInput extends NodeJS.Dict<string|number|boolean|ReadonlyArray<string>|ReadonlyArray<number>|ReadonlyArray<boolean>|null>{}function stringify(obj?:ParsedUrlQueryInput,sep?:string,eq?:string,options?:StringifyOptions):string;function parse(str:string,sep?:string,eq?:string,options?:ParseOptions):ParsedUrlQuery;const encode:typeof stringify;const decode:typeof parse;function escape(str:string):string;function unescape(str:string):string;}

View File

@ -0,0 +1 @@
declare module'node:url'{export*from'url';}declare module'url'{import{ParsedUrlQuery,ParsedUrlQueryInput}from'node:querystring';interface UrlObject{auth?:string|null;hash?:string|null;host?:string|null;hostname?:string|null;href?:string|null;pathname?:string|null;protocol?:string|null;search?:string|null;slashes?:boolean|null;port?:string|number|null;query?:string|null|ParsedUrlQueryInput;}interface Url{auth:string|null;hash:string|null;host:string|null;hostname:string|null;href:string;path:string|null;pathname:string|null;protocol:string|null;search:string|null;slashes:boolean|null;port:string|null;query:string|null|ParsedUrlQuery;}interface UrlWithParsedQuery extends Url{query:ParsedUrlQuery;}interface UrlWithStringQuery extends Url{query:string|null;}function parse(urlStr:string):UrlWithStringQuery;function parse(urlStr:string,parseQueryString:false|undefined,slashesDenoteHost?:boolean):UrlWithStringQuery;function parse(urlStr:string,parseQueryString:true,slashesDenoteHost?:boolean):UrlWithParsedQuery;function parse(urlStr:string,parseQueryString:boolean,slashesDenoteHost?:boolean):Url;function format(URL:URL,options?:URLFormatOptions):string;function format(urlObject:UrlObject|string):string;function resolve(from:string,to:string):string;function domainToASCII(domain:string):string;function domainToUnicode(domain:string):string;function fileURLToPath(url:string|URL):string;function pathToFileURL(url:string):URL;interface URLFormatOptions{auth?:boolean;fragment?:boolean;search?:boolean;unicode?:boolean;}class URL{constructor(input:string,base?:string|URL);hash:string;host:string;hostname:string;href:string;readonly origin:string;password:string;pathname:string;port:string;protocol:string;search:string;readonly searchParams:URLSearchParams;username:string;toString():string;toJSON():string;}class URLSearchParams implements Iterable<[string,string]>{constructor(init?:URLSearchParams|string|NodeJS.Dict<string|ReadonlyArray<string>>|Iterable<[string,string]>|ReadonlyArray<[string,string]>);append(name:string,value:string):void;delete(name:string):void;entries():IterableIterator<[string,string]>;forEach(callback:(value:string,name:string,searchParams:this)=>void):void;get(name:string):string|null;getAll(name:string):string[];has(name:string):boolean;keys():IterableIterator<string>;set(name:string,value:string):void;sort():void;toString():string;values():IterableIterator<string>;[Symbol.iterator]():IterableIterator<[string,string]>;}}

View File

@ -0,0 +1,29 @@
How to build the custom MONACO editor Node-RED
----------------------------------------------
### Building monaco
#### Setup build environment
cd /tmp/
git clone https://github.com/steve-mcl/monaco-editor-esm-i18n.git
#### Run the build
cd /tmp/monaco-editor-esm-i18n
npm install
npm build
#### Copy the built versions back
cd /tmp/monaco-editor-esm-i18n
cp -r output/monaco/dist \
<node-red-source-directory>/packages/node_modules/@node-red/editor-client/src/vendor/monaco/
cd /tmp/monaco-editor-esm-i18n
cp -r output/types \
<node-red-source-directory>/packages/node_modules/@node-red/editor-client/src/

View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2016 - present Microsoft Corporation
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,283 @@
THIRD-PARTY SOFTWARE NOTICES AND INFORMATION
Do Not Translate or Localize
This project incorporates components from the projects listed below. The original copyright notices and the licenses
under which Microsoft received such components are set forth below. Microsoft reserves all rights not expressly granted
herein, whether by implication, estoppel or otherwise.
%% nodejs path library (https://github.com/nodejs/node/tree/43dd49c9782848c25e5b03448c8a0f923f13c158)
=========================================
Copyright Joyent, Inc. and other Node contributors.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to permit
persons to whom the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
=========================================
END OF nodejs path library NOTICES AND INFORMATION
%% string_scorer version 0.1.20 (https://github.com/joshaven/string_score)
=========================================
This software is released under the MIT license:
Copyright (c) Joshaven Potter
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
=========================================
END OF string_scorer NOTICES AND INFORMATION
%% chjj-marked NOTICES AND INFORMATION BEGIN HERE
=========================================
The MIT License (MIT)
Copyright (c) 2011-2014, Christopher Jeffrey (https://github.com/chjj/)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
=========================================
END OF chjj-marked NOTICES AND INFORMATION
%% typescript version 2.7.2 (https://github.com/Microsoft/TypeScript)
=========================================
Copyright (c) Microsoft Corporation. All rights reserved.
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
You must give any other recipients of the Work or Derivative Works a copy of this License; and
You must cause any modified files to carry prominent notices stating that You changed the files; and
You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
=========================================
END OF typescript NOTICES AND INFORMATION
%% HTML 5.1 W3C Working Draft version 08 October 2015 (http://www.w3.org/TR/2015/WD-html51-20151008/)
=========================================
Copyright © 2015 W3C® (MIT, ERCIM, Keio, Beihang). This software or document includes material copied
from or derived from HTML 5.1 W3C Working Draft (http://www.w3.org/TR/2015/WD-html51-20151008/.)
THIS DOCUMENT IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING, BUT
NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, OR TITLE; THAT THE CONTENTS OF
THE DOCUMENT ARE SUITABLE FOR ANY PURPOSE; NOR THAT THE IMPLEMENTATION OF SUCH CONTENTS WILL NOT INFRINGE ANY THIRD PARTY
PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE
DOCUMENT OR THE PERFORMANCE OR IMPLEMENTATION OF THE CONTENTS THEREOF.
The name and trademarks of copyright holders may NOT be used in advertising or publicity pertaining to this document or its contents
without specific, written prior permission. Title to copyright in this document will at all times remain with copyright holders.
=========================================
END OF HTML 5.1 W3C Working Draft NOTICES AND INFORMATION
%% JS Beautifier version 1.6.2 (https://github.com/beautify-web/js-beautify)
=========================================
The MIT License (MIT)
Copyright (c) 2007-2017 Einar Lielmanis, Liam Newman, and contributors.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
=========================================
END OF js-beautify NOTICES AND INFORMATION
%% Ionic documentation version 1.2.4 (https://github.com/driftyco/ionic-site)
=========================================
Copyright Drifty Co. http://drifty.com/.
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
You must give any other recipients of the Work or Derivative Works a copy of this License; and
You must cause any modified files to carry prominent notices stating that You changed the files; and
You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
=========================================
END OF Ionic documentation NOTICES AND INFORMATION
%% vscode-swift version 0.0.1 (https://github.com/owensd/vscode-swift)
=========================================
The MIT License (MIT)
Copyright (c) 2015 David Owens II
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
=========================================
END OF vscode-swift NOTICES AND INFORMATION

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More