Compare commits

..

5 Commits

Author SHA1 Message Date
Nick O'Leary
2350540a98 Introduce RED.utils.createSVGElement 2022-08-07 22:28:08 +01:00
Nick O'Leary
c021c4020e Add RED.utils.domSelection module 2022-08-07 22:27:29 +01:00
Nick O'Leary
11a6925ae4 Remove almost all d3 from palette.js 2022-08-05 23:08:09 +01:00
Nick O'Leary
24ff5262d9 Remove d3 from radialMenu 2022-08-05 23:07:39 +01:00
Nick O'Leary
c24d7fafa9 Remove d3 from keyboard.js 2022-08-05 21:19:45 +01:00
207 changed files with 1457 additions and 3835 deletions

View File

@@ -5,9 +5,6 @@ on:
release:
types: [published]
permissions:
contents: read
jobs:
generate:
name: 'Update node-red-docker image'

View File

@@ -6,14 +6,8 @@ on:
pull_request:
branches: [ master, dev ]
permissions:
contents: read
jobs:
build:
permissions:
checks: write # for coverallsapp/github-action to create new checks
contents: read # for actions/checkout to fetch code
runs-on: ubuntu-latest
strategy:
matrix:

View File

@@ -15,5 +15,5 @@
"shadow": true, // allow variable shadowing (re-use of names...)
"sub": true, // don't warn that foo['bar'] should be written as foo.bar
"proto": true, // allow setting of __proto__ in node < v0.12,
"esversion": 11 // allow es11(ES2020)
"esversion": 6 // allow es6
}

View File

@@ -1,128 +1,3 @@
#### 3.1.0-beta.1: Beta Release
Editor
- NEW: Locking Flows (#3938) @knolleary
- NEW: Improve UX around hiding flows via context menu (#3930) @knolleary
- NEW: Add support for inline image in markdown editor by drag and drop of an image file (#4006) @HiroyasuNishiyama
- NEW: Add support for mermaid diagram to markdown editor (#4007) @HiroyasuNishiyama
- NEW: Support uri fragments for nodes and groups including edit support (#3870) @knolleary
- NEW: Add global environment variable feature (#3941) @HiroyasuNishiyama
- Remember compact/pretty flow export user choice (#3974) @Steve-Mcl
- fix .red-ui-notification class (#4035) @xiaobinqt
- Fix border radius on Modules list header (#4038) @bonanitech
- fix workspace reference error in case of empty tabs (#4029) @HiroyasuNishiyama
- Disable delete tab menu when single tab exists (#4030) @HiroyasuNishiyama
- Disable hide all menu if all tabs hidden (#4031) @HiroyasuNishiyama
- fix hide subflow tooltip (#4033) @HiroyasuNishiyama
- Fix disabled menu items in project feature (#4027) @kazuhitoyokoi
- Let themes change radialMenu text colors (#3995) @bonanitech
- Add Japanese translations for v3.0.3 (#4012) @kazuhitoyokoi
- Add Japanese translation for v3.1.0-beta.0 (#3997) @kazuhitoyokoi
- Add Japanese translation for v3.1.0-beta.0 (#3916) @kazuhitoyokoi
- Hide subflow category after deleting subflow (#3980) @kazuhitoyokoi
- Prevent dbl-click opening node edit dialog with text selected (#3970) @knolleary
- Handle replacing unknown node inside group or subflow (#3921) @knolleary
- Fix #3939, red border red-ui-typedInput-container (#3949) @Steveorevo
- i18n item URL copy notification & add Japanese message (#3946) @HiroyasuNishiyama
- add Japanese message for item url copy actions (#3947) @HiroyasuNishiyama
- Fix autocomplete entry for responseUrl (#3884) @knolleary
- Fix Japanese translation for JSONata editor (#3872) @HiroyasuNishiyama
- Fix search type with spaces (#3841) @Steve-Mcl
- Fix error hanndling of JSONata expression editor for extended functions (#3871) @HiroyasuNishiyama
- Add button type to the adding SSH key button (#3866) @kazuhitoyokoi
- Check radio button as default in project dialog (#3879) @kazuhitoyokoi
- Add $clone as supported function (#3874) @HiroyasuNishiyama
- Env var jsonata (#3807) @HiroyasuNishiyama
- Add Japanese translation for v3.0.2 (#3852) @kazuhitoyokoi
Runtime
- Force IPv4 name resolution to have priority (#4019) @dceejay
- Fix async loading of modules containing both nodes and plugins (#3999) @knolleary
- Use main branch as default in project feature (#4036) @kazuhitoyokoi
- Rename package var to avoid strict mode error (#4020) @knolleary
- Fix typos in settings.js (#4013) @ypid
- Ensure credentials object is removed before returning node in getFlow request (#3971) @knolleary
- Ignore commit error in project feature (#3987) @kazuhitoyokoi
- Update dependencies (#3969) @knolleary
- Add check that node sends object rather than primitive type (#3909) @knolleary
- Ensure key_path is quoted in GIT_SSH_COMMAND in case of spaces in pathname (#3912) @knolleary
- Fix nodesDir scan when node package has js/html in sub dir to package.json (#3867) @Steve-Mcl
- Fix file permissions (#3917) @kazuhitoyokoi
- ci: add minimum GitHub token permissions for workflows (#3907) @boahc077
Nodes
- Catch: fix typo in catch.html (#3965) @we11adam
- Change: Fix change node overwriting msg with itself (#3899) @dceejay
- Comment node: Clarify where the text will appear (#4004) @dirkjanfaber
- CSV: change replace to replaceAll (#3990) @dceejay
- CSV node: check header properties for ' and " (#3920) @dceejay
- CSV: Fix for CSV undefined property (#3906) @dceejay
- Delay: let delay node handle both flush then reset (#3898) @dceejay
- Function: Limit number of ports in function node (#3886) @kazuhitoyokoi
- Function: Remove dot from variable name for external module in function node (#3880) @kazuhitoyokoi
- Function: add function node monaco types util and promisify (#3868) @Steve-Mcl
- HTTP In: Ensure msg.req.headers is enumerable (#3908) @knolleary
- HTTP Request: Support form-data arrays (#3991) @hardillb
- HTTP Request: Fix httprequest tests to be more lenient on error message (#3922) @knolleary
- HTTP Request: Add missing property to node object HTTPRequest (#3842) @hardillb
- HTTP Request/Response: Support sortable list on property UI of http request and http response nodes (#3857) @kazuhitoyokoi
- HTTP Response: Ensure statusCode is a number (#3894) @hardillb
- Inject: Allow Inject node to work with async context stores (#4021) @knolleary
- Join/Batch: Add count to join and batch node labels (#4028) @dceejay
- MQTT: Fix birth topic handling in MQTT node (#3905) @Steve-Mcl
- MQTT: Fix pull-down menus of MQTT configuration node (#3890) @kazuhitoyokoi
- MQTT: Prevent invalid mqtt birth topic crashing node-red (#3869) @Steve-Mcl
- MQTT: ensure sessionExpiry(Interval) is applied (#3840) @Steve-Mcl
- MQTT: Fix mqtt nodes not reconnecting on modified-flows deploy (#3992) @knolleary
- MQTT: fix single subscription mqtt node status (#3966) @Steve-Mcl
- Range: Add drop mode to range node (#3935) @dceejay
- Remove done from describe (#3873) @HiroyasuNishiyama
- Split node: avoid duplicate done call for buffer split (#4000) @knolleary
- Status: Fix typo in 25-status.html (#3981) @kazuhitoyokoi
- TCP Node: ensure newline substitution applies to whole message (#4009) @dceejay
- Template: Add information about environment variable to template node (#3882) @kazuhitoyokoi
- Trigger: Hide trigger node repeat send option if sending nothing (#4023) @dceejay
- Watch: fix watch node test on MacOS/ARM (#3942) @HiroyasuNishiyama
#### 3.0.2: Maintenance Release
Editor
- Fix workspace chart bottom property (#3812) @bonanitech
- Update german translation (#3802) @Dennis14e
- Support color reset to the default in subflow and group (#3801) @kazuhitoyokoi
- Allow generateNodeNames to handle names containing regex control chars (#3817) @knolleary
- Hide scrollbars until they're needed (#3808) @bonanitech
- Include junctions/groups when exporting subflows plus related fixes (#3816) @knolleary
- remove console.log (#3820) @Steve-Mcl
Runtime
- Register subflow module instance node with parent flow (#3818) @knolleary
Nodes
- HTTP Request: Allow HTTP Headers not in spec (#3776) @hardillb
#### 3.0.1: Maintenance Release
Editor
- Allow codeEditor theme to be set even if `codeEditor` is not set in settings.js (#3794) @Steve-Mcl
- Sys info (diagnostics report) amendments (#3793) @Steve-Mcl
- Allow `mode` and `title` to be omitted in `options` argument for `createEditor` (#3791) @Steve-Mcl
- Fix focus issues (#3789) @Steve-Mcl
- Ensure all typedInput buttons have button type set (#3788) @knolleary
- Do not flag hasUsers=false nodes as unused in search (#3787) @knolleary
- Properly position quick-add dialog in all cases (#3786) @knolleary
- Ensure quick-add dialog does not obscure ghost node when shifted (#3785) @knolleary
- Remove use of Object.hasOwn (#3784) @knolleary
#### 3.0.0: Milestone Release
Editor

View File

@@ -151,8 +151,8 @@ module.exports = function(grunt) {
"packages/node_modules/@node-red/editor-client/src/js/font-awesome.js",
"packages/node_modules/@node-red/editor-client/src/js/history.js",
"packages/node_modules/@node-red/editor-client/src/js/validators.js",
"packages/node_modules/@node-red/editor-client/src/js/ui/mermaid.js",
"packages/node_modules/@node-red/editor-client/src/js/ui/utils.js",
"packages/node_modules/@node-red/editor-client/src/js/ui/utils-domselection.js",
"packages/node_modules/@node-red/editor-client/src/js/ui/common/editableList.js",
"packages/node_modules/@node-red/editor-client/src/js/ui/common/treeList.js",
"packages/node_modules/@node-red/editor-client/src/js/ui/common/checkboxSet.js",
@@ -170,7 +170,6 @@ module.exports = function(grunt) {
"packages/node_modules/@node-red/editor-client/src/js/ui/diagnostics.js",
"packages/node_modules/@node-red/editor-client/src/js/ui/diff.js",
"packages/node_modules/@node-red/editor-client/src/js/ui/keyboard.js",
"packages/node_modules/@node-red/editor-client/src/js/ui/env-var.js",
"packages/node_modules/@node-red/editor-client/src/js/ui/workspaces.js",
"packages/node_modules/@node-red/editor-client/src/js/ui/statusBar.js",
"packages/node_modules/@node-red/editor-client/src/js/ui/view.js",
@@ -226,7 +225,7 @@ module.exports = function(grunt) {
"node_modules/jsonata/jsonata-es5.min.js",
"packages/node_modules/@node-red/editor-client/src/vendor/jsonata/formatter.js",
"packages/node_modules/@node-red/editor-client/src/vendor/ace/ace.js",
"packages/node_modules/@node-red/editor-client/src/vendor/ace/ext-language_tools.js"
"packages/node_modules/@node-red/editor-client/src/vendor/ace/ext-language_tools.js",
],
// "packages/node_modules/@node-red/editor-client/public/vendor/vendor.css": [
// // TODO: resolve relative resource paths in
@@ -235,9 +234,6 @@ module.exports = function(grunt) {
"packages/node_modules/@node-red/editor-client/public/vendor/ace/worker-jsonata.js": [
"node_modules/jsonata/jsonata-es5.min.js",
"packages/node_modules/@node-red/editor-client/src/vendor/jsonata/worker-jsonata.js"
],
"packages/node_modules/@node-red/editor-client/public/vendor/mermaid/mermaid.min.js": [
"node_modules/mermaid/dist/mermaid.min.js"
]
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "node-red",
"version": "3.1.0-beta.1",
"version": "3.1.0-beta.0",
"description": "Low-code programming for event-driven applications",
"homepage": "http://nodered.org",
"license": "Apache-2.0",
@@ -26,13 +26,13 @@
}
],
"dependencies": {
"acorn": "8.8.1",
"acorn": "8.7.1",
"acorn-walk": "8.2.0",
"ajv": "8.11.2",
"async-mutex": "0.4.0",
"ajv": "8.11.0",
"async-mutex": "0.3.2",
"basic-auth": "2.0.1",
"bcryptjs": "2.4.3",
"body-parser": "1.20.1",
"body-parser": "1.20.0",
"cheerio": "1.0.0-rc.10",
"clone": "2.1.2",
"content-type": "1.0.4",
@@ -40,16 +40,16 @@
"cookie-parser": "1.4.6",
"cors": "2.8.5",
"cronosjs": "1.7.1",
"denque": "2.1.0",
"express": "4.18.2",
"denque": "2.0.1",
"express": "4.18.1",
"express-session": "1.17.3",
"form-data": "4.0.0",
"fs-extra": "10.1.0",
"got": "11.8.5",
"hash-sum": "2.0.0",
"hpagent": "1.2.0",
"hpagent": "1.0.0",
"https-proxy-agent": "5.0.1",
"i18next": "21.10.0",
"i18next": "21.8.14",
"iconv-lite": "0.6.3",
"is-utf8": "0.2.1",
"js-yaml": "4.1.0",
@@ -60,7 +60,7 @@
"memorystore": "1.6.7",
"mime": "3.0.0",
"moment": "2.29.4",
"moment-timezone": "0.5.39",
"moment-timezone": "0.5.34",
"mqtt": "4.3.7",
"multer": "1.4.5-lts.1",
"mustache": "4.2.0",
@@ -73,19 +73,19 @@
"passport-http-bearer": "1.0.1",
"passport-oauth2-client-password": "0.1.2",
"raw-body": "2.5.1",
"semver": "7.3.8",
"tar": "6.1.12",
"tough-cookie": "4.1.2",
"uglify-js": "3.17.4",
"semver": "7.3.7",
"tar": "6.1.11",
"tough-cookie": "4.0.0",
"uglify-js": "3.16.2",
"uuid": "8.3.2",
"ws": "7.5.6",
"xml2js": "0.4.23"
},
"optionalDependencies": {
"bcrypt": "5.1.0"
"bcrypt": "5.0.1"
},
"devDependencies": {
"dompurify": "2.4.1",
"dompurify": "2.3.9",
"grunt": "1.5.3",
"grunt-chmod": "~1.1.1",
"grunt-cli": "~1.4.3",
@@ -108,14 +108,13 @@
"i18next-http-backend": "1.4.1",
"jquery-i18next": "1.2.1",
"jsdoc-nr-template": "github:node-red/jsdoc-nr-template",
"marked": "4.2.3",
"mermaid": "^9.3.0",
"marked": "4.0.18",
"minami": "1.2.3",
"mocha": "9.2.2",
"node-red-node-test-helper": "^0.3.0",
"nodemon": "2.0.20",
"nodemon": "2.0.19",
"proxy": "^1.0.2",
"sass": "1.56.1",
"sass": "1.53.0",
"should": "13.2.3",
"sinon": "11.1.2",
"stoppable": "^1.1.0",

View File

@@ -327,8 +327,9 @@ module.exports = {
themeContext.header.url = themePlugin.header.url || themeContext.header.url
}
}
theme.codeEditor = theme.codeEditor || {}
theme.codeEditor.options = Object.assign({}, themePlugin.monacoOptions, theme.codeEditor.options);
if(theme.codeEditor) {
theme.codeEditor.options = Object.assign({}, themePlugin.monacoOptions, theme.codeEditor.options);
}
}
activeThemeInitialised = true;
}

View File

@@ -1,6 +1,6 @@
{
"name": "@node-red/editor-api",
"version": "3.1.0-beta.1",
"version": "3.1.0-beta.0",
"license": "Apache-2.0",
"main": "./lib/index.js",
"repository": {
@@ -16,14 +16,14 @@
}
],
"dependencies": {
"@node-red/util": "3.1.0-beta.1",
"@node-red/editor-client": "3.1.0-beta.1",
"@node-red/util": "3.1.0-beta.0",
"@node-red/editor-client": "3.1.0-beta.0",
"bcryptjs": "2.4.3",
"body-parser": "1.20.1",
"body-parser": "1.20.0",
"clone": "2.1.2",
"cors": "2.8.5",
"express-session": "1.17.3",
"express": "4.18.2",
"express": "4.18.1",
"memorystore": "1.6.7",
"mime": "3.0.0",
"multer": "1.4.5-lts.1",
@@ -35,6 +35,6 @@
"ws": "7.5.6"
},
"optionalDependencies": {
"bcrypt": "5.1.0"
"bcrypt": "5.0.1"
}
}

77
packages/node_modules/@node-red/editor-client/locales/de/editor.json vendored Normal file → Executable file
View File

@@ -105,7 +105,7 @@
"search": "Flows durchsuchen",
"searchInput": "Flows durchsuchen",
"subflows": "Subflow",
"createSubflow": "Hinzufügen",
"createSubflow": "Subflow",
"selectionToSubflow": "Auswahl in Subflow umwandeln",
"flows": "Flow",
"add": "Hinzufügen",
@@ -152,8 +152,7 @@
"zoom-in": "Vergrößern",
"search-flows": "Flows durchsuchen",
"search-prev": "Vorherige",
"search-next": "Nächste",
"search-counter": "\"__term__\" __result__ von __count__"
"search-next": "Nächste"
},
"user": {
"loggedInAs": "Angemeldet als __name__",
@@ -169,11 +168,7 @@
}
},
"notification": {
"state": {
"flowsStopped": "Flows gestoppt",
"flowsStarted": "Flows gestartet"
},
"warning": "<strong>Warnung</strong>: __message__",
"warning": "<strong>Warnung:</strong> __message__",
"warnings": {
"undeployedChanges": "Node hat nicht übernommene (deploy) Änderungen",
"nodeActionDisabled": "Node-Aktionen deaktiviert",
@@ -182,15 +177,15 @@
"missing-modules": "<p>Flows angehalten aufgrund fehlender Module</p>",
"safe-mode": "<p>Flows sind im abgesicherten Modus gestoppt.</p><p>Flows können bearbeitet und übernommen (deploy) werden, um sie neu zu starten.</p>",
"restartRequired": "Node-RED muss neu gestartet werden, damit die Module nach Upgrade aktiviert werden",
"credentials_load_failed": "<p>Flows gestoppt, da die Credentials nicht entschlüsselt werden konnten.</p><p>Die Datei mit den Flow-Credentials ist verschlüsselt, aber der Schlüssel des Projekts fehlt oder ist ungültig.</p>",
"credentials_load_failed_reset": "<p>Die Credentials konnten nicht entschlüsselt werden.</p><p>Die Datei mit den Flow-Credentials ist verschlüsselt, aber der Schlüssel des Projekts fehlt oder ist ungültig.</p><p>Die Datei mit den Flow-Credentials wird bei der nächsten Übernahme (deploy) zurückgesetzt. Alle vorhandenen Flow-Credentials werden gelöscht.</p>",
"credentials_load_failed": "<p>Flows gestoppt, da die Berechtigungen nicht entschlüsselt werden konnten.</p><p>Die Datei mit dem Flow-Berechtigungen ist verschlüsselt, aber der Schlüssel des Projekts fehlt oder ist ungültig.</p>",
"credentials_load_failed_reset": "<p>Die Berechtigungen konnten nicht entschlüsselt werden.</p><p>Die Datei mit den Flow-Berechtigungen ist verschlüsselt, aber der Schlüssel des Projekts fehlt oder ist ungültig.</p><p>Die Datei mit den Flow-Berechtigungen wird bei der nächsten Übernahme (deploy) zurückgesetzt. Alle vorhandenen Flow-Berechtigungen werden gelöscht.</p>",
"missing_flow_file": "<p>Die Flow-Datei des Projekts wurde nicht gefunden.</p><p>Das Projekt ist nicht mit einer Flow-Datei konfiguriert.</p>",
"missing_package_file": "<p>Die Paket-Datei des Projekts wurde nicht gefunden.</p><p>In dem Projekt fehlt die 'package.json'-Datei.</p>",
"project_empty": "<p>Das Projekt ist leer.</p><p>Soll ein Standardsatz an Projektdateien erstellen werden?<br/>Andernfalls müssen die Dateien manuell außerhalb des Editors dem Projekt hinzugefügt werden.</p>",
"project_not_found": "<p>Das Projekt '__project__' wurde nicht gefunden.</p>",
"git_merge_conflict": "<p>Der automatische Merge der Änderungen ist fehlgeschlagen.</p><p>Die Merge-Konflikte müssen behoben und die Ergebnisse ins Repository übertragen werden (commit).</p>"
},
"error": "<strong>Fehler</strong>: __message__",
"error": "<strong>Fehler:</strong> __message__",
"errors": {
"lostConnection": "Verbindung zum Server verloren. Verbindung wird erneut hergestellt ...",
"lostConnectionReconnect": "Verbindung zum Server verloren. Wiederherstellung der Verbindung in __time__s.",
@@ -208,7 +203,7 @@
"pull": "Projekt '__project__' erneut geladen",
"revert": "Änderungen im Projekt '__project__' rückgängig gemacht",
"merge-complete": "Git-Merge abgeschlossen",
"setupCredentials": "Credentials einrichten",
"setupCredentials": "Berechtigungen einrichten",
"setupProjectFiles": "Projektdateien einrichten",
"no": "Nein, Danke",
"createDefault": "Standardprojektdateien erstellen",
@@ -216,7 +211,7 @@
},
"label": {
"manage-project-dep": "Projektabhängigkeiten verwalten",
"setup-cred": "Credentials einrichten",
"setup-cred": "Berechtigungen einrichten",
"setup-project": "Projektdateien einrichten",
"create-default-package": "Standardpaketdatei erstellen",
"no-thanks": "Nein, Danke",
@@ -300,10 +295,6 @@
"modifiedFlowsDesc": "Übernimmt nur Flows, die geänderte Nodes enthalten",
"modifiedNodes": "Geänderte Nodes",
"modifiedNodesDesc": "Übernimmt nur Nodes, die sich geändert haben",
"startFlows": "Start",
"startFlowsDesc": "Flows starten",
"stopFlows": "Stop",
"stopFlowsDesc": "Flows stoppen",
"restartFlows": "Flows neustarten",
"restartFlowsDesc": "Startet die aktuell übernommenen Flows (ohne vorheriges Deploy)",
"successfulDeploy": "Erfolgreich übernommen (deploy)",
@@ -385,7 +376,7 @@
"confirmDelete": "Sind Sie sicher mit dem Löschen dieses Subflows?",
"info": "Beschreibung",
"category": "Kategorie",
"module": "Modul",
"module": "Module",
"license": "Lizenz",
"licenseNone": "Keine",
"licenseOther": "Andere",
@@ -443,7 +434,7 @@
"icon": "Icon",
"inputType": "Eingangstyp",
"selectType": "Wähle Typen ...",
"loadCredentials": "Lade Node-Credentials",
"loadCredentials": "Lade Node-Berechtigungen",
"inputs": {
"input": "Eingang",
"select": "Auswahl",
@@ -459,7 +450,7 @@
"json": "JSON",
"bin": "buffer",
"env": "Umgebungsvariable",
"cred": "Credentials"
"cred": "Berechtigung"
},
"menu": {
"input": "Eingang",
@@ -479,7 +470,7 @@
"errors": {
"scopeChange": "Wenn Sie den Geltungsbereich (scope) ändern, wird er für Nodes in anderen Flows nicht verfügbar sein",
"invalidProperties": "Ungültige Eigenschaften:",
"credentialLoadFailed": "Laden der Node-Credentials fehlgeschlagen"
"credentialLoadFailed": "Laden der Node-Berechtigungen fehlgeschlagen"
}
},
"keyboard": {
@@ -692,8 +683,7 @@
"showHelp": "Hilfe zeigen",
"showInOutline": "Zeige im Editor",
"showTopics": "Zeige Hilfethemen",
"noHelp": "Kein Hilfethema ausgewählt",
"changeLog": "Änderungsprotokoll"
"noHelp": "Kein Hilfethema ausgewählt"
},
"config": {
"name": "Konfigurations-Node",
@@ -747,7 +737,7 @@
"addToProject": "Zu Projekt hinzufügen",
"files": "Dateien",
"flow": "Flow",
"credentials": "Credentials",
"credentials": "Berechtigungen",
"package": "Paket",
"packageCreate": "Datei wird erstellt beim Speichern der Änderungen",
"fileNotExist": "Datei existiert nicht",
@@ -760,7 +750,7 @@
"changeTheEncryptionKey": "Schlüssel ändern",
"currentKey": "Aktueller Schlüssel",
"newKey": "Neuer Schlüssel",
"credentialsAlert": "Dadurch werden alle vorhandenen Credentials gelöscht",
"credentialsAlert": "Dadurch werden alle vorhandenen Berechtigungen gelöscht",
"versionControl": "Versionsverwaltung (Git)",
"branches": "Branches",
"noBranches": "Keine Branches",
@@ -896,7 +886,7 @@
"date": "timestamp",
"jsonata": "JSONata",
"env": "Umgebungsvariable",
"cred": "Credentials"
"cred": "Berechtigung"
}
},
"editableList": {
@@ -1036,7 +1026,7 @@
"passphrase": "Passphrase",
"ssh-key-desc": "Bevor Sie ein Repository über SSH lokal klonen können, müssen Sie einen SSH-Schlüssel hinzufügen, um auf diesen zugreifen zu können",
"ssh-key-add": "SSH-Schlüssel hinzufügen",
"credential-key": "Schlüssel für Credentials",
"credential-key": "Schlüssel für Berechtigungen",
"cant-get-ssh-key": "Fehler! Der ausgewählte SSH-Schlüsselpfad kann nicht abgerufen werden",
"already-exists2": "bereits vorhanden",
"git-error": "Git-Fehler",
@@ -1048,27 +1038,27 @@
"create": "Erstellen Sie Ihre Projektdateien",
"desc0": "Ein Projekt enthält Ihre Flow-Dateien, eine README-Datei und die 'package.json'-Datei.",
"desc1": "Es kann alle anderen Dateien enthalten, die im Git-Repository verwaltet werden sollen.",
"desc2": "Ihre vorhandenen Flow- und Credential-Dateien werden in das Projekt kopiert.",
"desc2": "Ihre vorhandenen Flow- und Berechtigungs-Dateien werden in das Projekt kopiert.",
"flow-file": "Flow-Datei",
"credentials-file": "Datei mit Credentials"
"credentials-file": "Datei mit Berechtigungen"
},
"encryption-config": {
"setup": "Einrichtung der Verschlüsselung Ihrer Datei mit den Credentials",
"desc0": "Die Datei mit den Flow-Credentials kann verschlüsselt werden, um ihren Inhalt zu schützen.",
"desc1": "Wenn Sie diese Credentials in einem öffentlichen Repository speichern möchten, müssen Sie sie mit einen geheimen Schlüsselausdruck verschlüsseln.",
"desc2": "Die Datei mit den Flow-Credentials ist derzeit nicht verschlüsselt.",
"setup": "Einrichtung der Verschlüsselung Ihrer Datei mit den Berechtigungen",
"desc0": "Die Datei mit den Flow-Berechtigungen kann verschlüsselt werden, um ihren Inhalt zu schützen.",
"desc1": "Wenn Sie diese Berechtigungen in einem öffentlichen Repository speichern möchten, müssen Sie sie mit einen geheimen Schlüsselausdruck verschlüsseln.",
"desc2": "Die Datei mit den Flow-Berechtigungen ist derzeit nicht verschlüsselt.",
"desc3": "D.h. ihr Inhalt (z.B. Passwörter und Zugriffs-Tokens) kann von jedem mit Zugriff auf die Datei gelesen werden.",
"desc4": "Wenn Sie diese Credentials in einen öffentlichen Repository speichern möchten, müssen Sie diese verschlüsseln, indem Sie einen geheimen Schlüsselausdruck eingeben.",
"desc5": "Ihre Datei mit den Flow-Credentials wird derzeit mit dem Eintrag 'credentialSecret' Ihrer Einstellungsdatei als Schlüssel verschlüsselt.",
"desc6": "Die Datei mit den Flow-Credentials wird derzeit mit einem vom System generierten Schlüssel verschlüsselt. Sie sollten einen neuen geheimen Schlüssel für dieses Projekt vorgeben.",
"desc4": "Wenn Sie diese Berechtigungen in einen öffentlichen Repository speichern möchten, müssen Sie diese verschlüsseln, indem Sie einen geheimen Schlüsselausdruck eingeben.",
"desc5": "Ihre Datei mit den Flow-Berechtigungen wird derzeit mit dem Eintrag 'credentialSecret' Ihrer Einstellungsdatei als Schlüssel verschlüsselt.",
"desc6": "Die Datei mit den Flow-Berechtigungen wird derzeit mit einem vom System generierten Schlüssel verschlüsselt. Sie sollten einen neuen geheimen Schlüssel für dieses Projekt vorgeben.",
"desc7": "Der Schlüssel wird separat von den Projektdateien gespeichert. Sie müssen den Schlüssel angeben, damit dieses Projekt auch in einem anderen Node-RED-System verwendet werden kann.",
"credentials": "Credentials",
"credentials": "Berechtigung",
"enable": "Verschlüsselung aktivieren",
"disable": "Verschlüsselung deaktivieren",
"disabled": "deaktiviert",
"copy": "Vorhandenen Schlüssel ersetzen",
"use-custom": "Eigenen Schlüssel verwenden",
"desc8": "Die Datei mit den Credentials wird nicht verschlüsselt und ihr Inhalt kann leicht gelesen werden",
"desc8": "Die Datei mit den Berechtigungen wird nicht verschlüsselt, und ihr Inhalt kann leicht gelesen werden",
"create-project-files": "Projektdateien erstellen",
"create-project": "Projekt erstellen",
"already-exists": "bereits vorhanden",
@@ -1093,12 +1083,12 @@
"desc": "Beschreibung",
"opt": "Optional",
"flow-file": "Flow-Datei",
"credentials": "Credentials",
"credentials": "Berechtigungen",
"enable-encryption": "Verschlüsselung aktivieren",
"disable-encryption": "Verschlüsselung deaktivieren",
"encryption-key": "Schlüssel",
"desc0": "Eine Ausdruck, mit der Sie Ihre Credentials schützen",
"desc1": "Die Datei mit den Credentials wird nicht verschlüsselt und ihr Inhalt kann leicht gelesen werden",
"desc0": "Eine Floskel, mit der Sie Ihre Berechtigungen schützen",
"desc1": "Die Datei mit den Berechtigungen wird nicht verschlüsselt, und ihr Inhalt kann leicht gelesen werden",
"git-url": "Git-Repository-URL",
"protocols": "https://, ssh:// oder file://",
"auth-failed": "Authentifizierung fehlgeschlagen",
@@ -1108,7 +1098,7 @@
"passphrase": "Passphrase",
"desc2": "Bevor Sie ein Repository über SSH klonen können, müssen Sie einen SSH-Schlüssel hinzufügen, um auf diesen zu zugreifen",
"add-ssh-key": "Einen SSH-Schlüssel hinzufügen",
"credentials-encryption-key": "Schlüssel für Credentials",
"credentials-encryption-key": "Schlüssel für Berechtigungen",
"already-exists-2": "bereits vorhanden",
"git-error": "Git-Fehler",
"con-failed": "Verbindung fehlgeschlagen",
@@ -1166,8 +1156,7 @@
"tourGuide": {
"takeATour": "Tour starten",
"start": "Start",
"next": "Nächste",
"welcomeTours": "Welcome Tours"
"next": "Nächste"
},
"diagnostics": {
"title": "System-Informationen"

View File

View File

View File

@@ -53,30 +53,22 @@
"confirmDelete": "Confirm delete",
"delete": "Are you sure you want to delete '__label__'?",
"dropFlowHere": "Drop the flow here",
"dropImageHere": "Drop the image here",
"addFlow": "Add flow",
"addFlowToRight": "Add flow to the right",
"closeFlow": "Close flow",
"hideFlow": "Hide flow",
"hideOtherFlows": "Hide other flows",
"showAllFlows": "Show all flows (__count__ hidden)",
"showAllFlows": "Show all flows",
"hideAllFlows": "Hide all flows",
"hiddenFlows": "List __count__ hidden flow",
"hiddenFlows_plural": "List __count__ hidden flows",
"showLastHiddenFlow": "Reopen hidden flow",
"showLastHiddenFlow": "Show last hidden flow",
"listFlows": "List flows",
"listSubflows": "List subflows",
"status": "Status",
"enabled": "Enabled",
"disabled": "Disabled",
"info": "Description",
"selectNodes": "Click nodes to select",
"enableFlow": "Enable flow",
"disableFlow": "Disable flow",
"lockFlow": "Lock flow",
"unlockFlow": "Unlock flow",
"moveToStart": "Move flow to start",
"moveToEnd": "Move flow to end"
"selectNodes": "Click nodes to select"
},
"menu": {
"label": {
@@ -109,7 +101,6 @@
"displayStatus": "Show node status",
"displayConfig": "Configuration nodes",
"import": "Import",
"importExample": "Import Example Flow",
"export": "Export",
"search": "Search flows",
"searchInput": "search your flows",
@@ -506,7 +497,6 @@
"addRemoveNode": "Add/remove node from selection",
"editSelected": "Edit selected node",
"deleteSelected": "Delete selected nodes or link",
"deleteReconnect": "Delete and Reconnect",
"importNode": "Import nodes",
"exportNode": "Export nodes",
"nudgeNode": "Move selected nodes (1px)",
@@ -693,9 +683,7 @@
"empty": "empty",
"globalConfig": "Global Configuration Nodes",
"triggerAction": "Trigger action",
"find": "Find in workspace",
"copyItemUrl": "Copy item url",
"copyURL2Clipboard": "Copied url to clipboard"
"find": "Find in workspace"
},
"help": {
"name": "Help",
@@ -948,9 +936,6 @@
"invalid-expr": "Invalid JSONata expression:\n __message__",
"invalid-msg": "Invalid example JSON message:\n __message__",
"context-unsupported": "Cannot test context functions\n $flowContext or $globalContext",
"env-unsupported": "Cannot test $env function",
"moment-unsupported": "Cannot test $moment function",
"clone-unsupported": "Cannot test $clone function",
"eval": "Error evaluating expression:\n __message__"
}
},
@@ -996,10 +981,7 @@
"quote": "Quote",
"link": "Link",
"horizontal-rule": "Horizontal rule",
"toggle-preview": "Toggle preview",
"mermaid": {
"summary": "Mermaid Diagram"
}
"toggle-preview": "Toggle preview"
},
"bufferEditor": {
"title": "Buffer editor",
@@ -1221,10 +1203,5 @@
"node": "Node",
"junction": "Junction",
"linkNodes": "Link Nodes"
},
"env-var": {
"environment": "Environment",
"header": "Global Environment Variables",
"revert": "Revert"
}
}

View File

View File

View File

@@ -53,10 +53,8 @@
"confirmDelete": "削除の確認",
"delete": "本当に '__label__' を削除しますか?",
"dropFlowHere": "ここにフローをドロップしてください",
"dropImageHere": "ここに画像ファイルをドロップしてください",
"addFlow": "フローの追加",
"addFlowToRight": "右側にフローを追加",
"closeFlow": "フローを閉じる",
"hideFlow": "フローを非表示",
"hideOtherFlows": "他のフローを非表示",
"showAllFlows": "全てのフローを表示",
@@ -70,11 +68,7 @@
"enabled": "有効",
"disabled": "無効",
"info": "詳細",
"selectNodes": "ノードをクリックして選択",
"enableFlow": "フローを有効化",
"disableFlow": "フローを無効化",
"moveToStart": "フローを先頭へ移動",
"moveToEnd": "フローを最後へ移動"
"selectNodes": "ノードをクリックして選択"
},
"menu": {
"label": {
@@ -689,9 +683,7 @@
"empty": "空",
"globalConfig": "グローバル設定ノード",
"triggerAction": "アクションを実行",
"find": "ワークスペース内を検索",
"copyItemUrl": "要素のURLをコピー",
"copyURL2Clipboard": "URLをクリップボードにコピーしました"
"find": "ワークスペース内を検索"
},
"help": {
"name": "ヘルプ",
@@ -943,11 +935,8 @@
"errors": {
"invalid-expr": "不正なJSONata式:\n __message__",
"invalid-msg": "不正なJSONメッセージ例:\n __message__",
"context-unsupported": "$flowContext や $globalContextの\nコンテキスト関数をテストできません",
"env-unsupported": "$env関数はテストできません",
"moment-unsupported": "$moment関数はテストできません",
"clone-unsupported": "$clone関数はテストできません",
"eval": "式評価エラー:\n __message__"
"context-unsupported": "$flowContext や $globalContextの\nコンテキスト機能をテストできません",
"eval": "表現評価エラー:\n __message__"
}
},
"monaco": {
@@ -992,10 +981,7 @@
"quote": "引用",
"link": "リンク",
"horizontal-rule": "区切り線",
"toggle-preview": "プレビュー表示切替え",
"mermaid": {
"summary": "Mermaid図"
}
"toggle-preview": "プレビュー表示切替え"
},
"bufferEditor": {
"title": "バッファエディタ",
@@ -1182,7 +1168,8 @@
"takeATour": "ツアーを開始",
"start": "開始",
"next": "次へ",
"welcomeTours": "ウェルカムツアー"
"welcomeTours": "ウェルカムツアー",
"tours": "ツアー"
},
"diagnostics": {
"title": "システム情報"
@@ -1361,15 +1348,6 @@
"show-project-settings": "プロジェクト設定を表示",
"show-version-control-tab": "バージョンコントロールタブを表示",
"start-flows": "フローを開始",
"stop-flows": "フローを停止",
"copy-item-url": "要素のURLをコピー",
"copy-item-edit-url": "要素の編集URLをコピー",
"move-flow-to-start": "フローを先頭に移動",
"move-flow-to-end": "フローを末尾に移動"
},
"env-var": {
"environment": "環境変数",
"header": "大域環境変数",
"revert": "破棄"
"stop-flows": "フローを停止"
}
}

View File

View File

View File

View File

View File

View File

View File

@@ -1,6 +1,6 @@
{
"name": "@node-red/editor-client",
"version": "3.1.0-beta.1",
"version": "3.1.0-beta.0",
"license": "Apache-2.0",
"repository": {
"type": "git",

View File

@@ -14,7 +14,7 @@
* limitations under the License.
**/
/**
/**
* An API for undo / redo history buffer
* @namespace RED.history
*/
@@ -434,9 +434,7 @@ RED.history = (function() {
if (ev.node.type === 'tab' && ev.changes.hasOwnProperty('disabled')) {
$("#red-ui-tab-"+(ev.node.id.replace(".","-"))).toggleClass('red-ui-workspace-disabled',!!ev.node.disabled);
}
if (ev.node.type === 'tab' && ev.changes.hasOwnProperty('locked')) {
$("#red-ui-tab-"+(ev.node.id.replace(".","-"))).toggleClass('red-ui-workspace-locked',!!ev.node.locked);
$("#red-ui-workspace").toggleClass("red-ui-workspace-disabled",!!ev.node.disabled);
}
if (ev.subflow) {
inverseEv.subflow = {};

View File

@@ -19,6 +19,7 @@
* @namespace RED.nodes
*/
RED.nodes = (function() {
var PORT_TYPE_INPUT = 1;
var PORT_TYPE_OUTPUT = 0;
@@ -62,7 +63,6 @@ RED.nodes = (function() {
defaults: {
label: {value:""},
disabled: {value: false},
locked: {value: false},
info: {value: ""},
env: {value: []}
}
@@ -575,48 +575,15 @@ RED.nodes = (function() {
}
}
const nodeProxyHandler = {
get(node, prop) {
if (prop === '__isProxy__') {
return true
} else if (prop == '__node__') {
return node
}
return node[prop]
},
set(node, prop, value) {
if (node.z && (RED.nodes.workspace(node.z)?.locked || RED.nodes.subflow(node.z)?.locked)) {
if (
node._def.defaults[prop] ||
prop === 'z' ||
prop === 'l' ||
prop === 'd' ||
(prop === 'changed' && (!!node.changed) !== (!!value)) || // jshint ignore:line
((prop === 'x' || prop === 'y') && !node.resize && node.type !== 'group')
) {
throw new Error(`Cannot modified property '${prop}' of locked object '${node.type}:${node.id}'`)
}
}
node[prop] = value;
return true
}
}
function addNode(n) {
let newNode
if (!n.__isProxy__) {
newNode = new Proxy(n, nodeProxyHandler)
} else {
newNode = n
}
if (n.type.indexOf("subflow") !== 0) {
n["_"] = n._def._;
} else {
var subflowId = n.type.substring(8);
var sf = RED.nodes.subflow(subflowId);
if (sf) {
sf.instances.push(newNode);
sf.instances.push(sf);
}
n["_"] = RED._;
}
@@ -633,13 +600,12 @@ RED.nodes = (function() {
});
n.i = nextId+1;
}
allNodes.addNode(newNode);
allNodes.addNode(n);
if (!nodeLinks[n.id]) {
nodeLinks[n.id] = {in:[],out:[]};
}
}
RED.events.emit('nodes:add',newNode);
return newNode
RED.events.emit('nodes:add',n);
}
function addLink(l) {
if (nodeLinks[l.source.id]) {
@@ -902,7 +868,14 @@ RED.nodes = (function() {
var node;
if (allNodes.hasTab(id)) {
removedNodes = allNodes.getNodes(id).slice()
removedNodes = allNodes.getNodes(id).filter(n => {
if (n.type === 'junction') {
removedJunctions.push(n)
return false
} else {
return true
}
})
}
for (i in configNodes) {
if (configNodes.hasOwnProperty(i)) {
@@ -912,7 +885,6 @@ RED.nodes = (function() {
}
}
}
removedJunctions = RED.nodes.junctions(id)
for (i=0;i<removedNodes.length;i++) {
var result = removeNode(removedNodes[i].id);
@@ -1080,9 +1052,6 @@ RED.nodes = (function() {
node.type = n.type;
for (var d in n._def.defaults) {
if (n._def.defaults.hasOwnProperty(d)) {
if (d === 'locked' && !n.locked) {
continue
}
node[d] = n[d];
}
}
@@ -1362,6 +1331,7 @@ RED.nodes = (function() {
} else {
nodeSet = [sf];
}
console.log(nodeSet);
return createExportableNodeSet(nodeSet);
}
/**
@@ -1397,10 +1367,6 @@ RED.nodes = (function() {
exportedConfigNodes[n.id] = true;
}
});
subflowSet = subflowSet.concat(RED.nodes.junctions(subflowId))
subflowSet = subflowSet.concat(RED.nodes.groups(subflowId))
var exportableSubflow = createExportableNodeSet(subflowSet, exportedIds, exportedSubflows, exportedConfigNodes);
nns = exportableSubflow.concat(nns);
}
@@ -2002,7 +1968,7 @@ RED.nodes = (function() {
}
}
} else {
const keepNodesCurrentZ = reimport && n.z && (RED.workspaces.contains(n.z) || RED.nodes.subflow(n.z))
const keepNodesCurrentZ = reimport && n.z && RED.workspaces.contains(n.z)
if (!keepNodesCurrentZ && n.z && !workspace_map[n.z] && !subflow_map[n.z]) {
n.z = activeWorkspace;
}
@@ -2104,7 +2070,7 @@ RED.nodes = (function() {
node.id = getID();
} else {
node.id = n.id;
const keepNodesCurrentZ = reimport && node.z && (RED.workspaces.contains(node.z) || RED.nodes.subflow(node.z))
const keepNodesCurrentZ = reimport && node.z && RED.workspaces.contains(node.z)
if (!keepNodesCurrentZ && (node.z == null || (!workspace_map[node.z] && !subflow_map[node.z]))) {
if (createMissingWorkspace) {
if (missingWorkspace === null) {
@@ -2352,6 +2318,19 @@ RED.nodes = (function() {
if (n.g && !new_group_set.has(n.g)) {
delete n.g;
}
n.nodes = n.nodes.map(function(id) {
return node_map[id];
})
// Just in case the group references a node that doesn't exist for some reason
n.nodes = n.nodes.filter(function(v) {
if (v) {
// Repair any nodes that have forgotten they are in this group
if (v.g !== n.id) {
v.g = n.id;
}
}
return !!v
});
if (!n.g) {
groupDepthMap[n.id] = 0;
}
@@ -2374,22 +2353,21 @@ RED.nodes = (function() {
return groupDepthMap[A.id] - groupDepthMap[B.id];
});
for (i=0;i<new_groups.length;i++) {
new_groups[i] = addGroup(new_groups[i]);
node_map[new_groups[i].id] = new_groups[i]
n = new_groups[i];
addGroup(n);
}
for (i=0;i<new_junctions.length;i++) {
new_junctions[i] = addJunction(new_junctions[i]);
node_map[new_junctions[i].id] = new_junctions[i]
var junction = new_junctions[i];
addJunction(junction);
}
// Now the nodes have been fully updated, add them.
for (i=0;i<new_nodes.length;i++) {
new_nodes[i] = addNode(new_nodes[i])
node_map[new_nodes[i].id] = new_nodes[i]
var node = new_nodes[i];
addNode(node);
}
// Finally validate them all.
// This has to be done after everything is added so that any checks for
// dependent config nodes will pass
@@ -2397,39 +2375,6 @@ RED.nodes = (function() {
var node = new_nodes[i];
RED.editor.validateNode(node);
}
const lookupNode = (id) => {
const mappedNode = node_map[id]
if (!mappedNode) {
return null
}
if (mappedNode.__isProxy__) {
return mappedNode
} else {
return node_map[mappedNode.id]
}
}
// Update groups to reference proxy node objects
for (i=0;i<new_groups.length;i++) {
n = new_groups[i];
// bypass the proxy in case the flow is locked
n.__node__.nodes = n.nodes.map(lookupNode)
// Just in case the group references a node that doesn't exist for some reason
n.__node__.nodes = n.nodes.filter(function(v) {
if (v) {
// Repair any nodes that have forgotten they are in this group
if (v.g !== n.id) {
v.g = n.id;
}
}
return !!v
});
}
// Update links to use proxy node objects
for (i=0;i<new_links.length;i++) {
new_links[i].source = lookupNode(new_links[i].source.id) || new_links[i].source
new_links[i].target = lookupNode(new_links[i].target.id) || new_links[i].target
}
RED.workspaces.refresh();
@@ -2558,17 +2503,11 @@ RED.nodes = (function() {
junctions = {};
junctionsByZ = {};
var workspaceIds = Object.keys(workspaces);
// Ensure all workspaces are unlocked so we don't get any edit-protection
// preventing removal
workspaceIds.forEach(function(id) {
workspaces[id].locked = false
});
var subflowIds = Object.keys(subflows);
subflowIds.forEach(function(id) {
RED.subflow.removeSubflow(id)
});
var workspaceIds = Object.keys(workspaces);
workspaceIds.forEach(function(id) {
RED.workspaces.remove(workspaces[id]);
});
@@ -2589,14 +2528,10 @@ RED.nodes = (function() {
}
function addGroup(group) {
if (!group.__isProxy__) {
group = new Proxy(group, nodeProxyHandler)
}
groupsByZ[group.z] = groupsByZ[group.z] || [];
groupsByZ[group.z].push(group);
groups[group.id] = group;
RED.events.emit("groups:add",group);
return group
}
function removeGroup(group) {
var i = groupsByZ[group.z].indexOf(group);
@@ -2617,9 +2552,6 @@ RED.nodes = (function() {
}
function addJunction(junction) {
if (!junction.__isProxy__) {
junction = new Proxy(junction, nodeProxyHandler)
}
junctionsByZ[junction.z] = junctionsByZ[junction.z] || []
junctionsByZ[junction.z].push(junction)
junctions[junction.id] = junction;
@@ -2627,7 +2559,6 @@ RED.nodes = (function() {
nodeLinks[junction.id] = {in:[],out:[]};
}
RED.events.emit("junctions:add", junction)
return junction
}
function removeJunction(junction) {
var i = junctionsByZ[junction.z].indexOf(junction)
@@ -2812,7 +2743,6 @@ RED.nodes = (function() {
}
});
const nodeGroupMap = {}
var replaceNodeIds = Object.keys(replaceNodes);
if (replaceNodeIds.length > 0) {
var reimportList = [];
@@ -2823,12 +2753,6 @@ RED.nodes = (function() {
} else {
allNodes.removeNode(n);
}
if (n.g) {
// reimporting a node *without* including its group object
// will cause the g property to be cleared. Cache it
// here so we can restore it
nodeGroupMap[n.id] = n.g
}
reimportList.push(convertNode(n));
RED.events.emit('nodes:remove',n);
});
@@ -2850,18 +2774,6 @@ RED.nodes = (function() {
var newNodeMap = {};
result.nodes.forEach(function(n) {
newNodeMap[n.id] = n;
if (nodeGroupMap[n.id]) {
// This node is in a group - need to substitute the
// node reference inside the group
n.g = nodeGroupMap[n.id]
const group = RED.nodes.group(n.g)
if (group) {
var index = group.nodes.findIndex(gn => gn.id === n.id)
if (index > -1) {
group.nodes[index] = n
}
}
}
});
RED.nodes.eachLink(function(l) {
if (newNodeMap.hasOwnProperty(l.source.id)) {
@@ -2922,7 +2834,7 @@ RED.nodes = (function() {
},
addWorkspace: addWorkspace,
removeWorkspace: removeWorkspace,
getWorkspaceOrder: function() { return [...workspacesOrder] },
getWorkspaceOrder: function() { return workspacesOrder },
setWorkspaceOrder: function(order) { workspacesOrder = order; },
workspace: getWorkspace,

View File

@@ -249,35 +249,8 @@ var RED = (function() {
RED.nodes.import(nodes.flows);
RED.nodes.dirty(false);
RED.view.redraw(true);
if (/^#(flow|node|group)\/.+$/.test(currentHash)) {
const hashParts = currentHash.split('/')
const showEditDialog = hashParts.length > 2 && hashParts[2] === 'edit'
if (hashParts[0] === '#flow') {
RED.workspaces.show(hashParts[1], true);
if (showEditDialog) {
RED.workspaces.edit()
}
} else if (hashParts[0] === '#node') {
const nodeToShow = RED.nodes.node(hashParts[1])
if (nodeToShow) {
setTimeout(() => {
RED.view.reveal(nodeToShow.id)
window.location.hash = currentHash
if (showEditDialog) {
RED.editor.edit(nodeToShow)
}
}, 50)
}
} else if (hashParts[0] === '#group') {
const nodeToShow = RED.nodes.group(hashParts[1])
if (nodeToShow) {
RED.view.reveal(nodeToShow.id)
window.location.hash = currentHash
if (showEditDialog) {
RED.editor.editGroup(nodeToShow)
}
}
}
if (/^#flow\/.+$/.test(currentHash)) {
RED.workspaces.show(currentHash.substring(6),true);
}
if (RED.workspaces.count() > 0) {
const hiddenTabs = JSON.parse(RED.settings.getLocal("hiddenTabs")||"{}");
@@ -348,8 +321,6 @@ var RED = (function() {
loader.end()
RED.notify($("<p>").text(message));
RED.sidebar.info.refresh()
RED.menu.setDisabled('menu-item-projects-open',false);
RED.menu.setDisabled('menu-item-projects-settings',false);
});
});
return;
@@ -670,6 +641,11 @@ var RED = (function() {
]});
menuOptions.push({id:"menu-item-arrange-menu", label:RED._("menu.label.arrange"), options: [
{id: "menu-item-view-tools-move-to-back", label:RED._("menu.label.moveToBack"), disabled: true, onselect: "core:move-selection-to-back"},
{id: "menu-item-view-tools-move-to-front", label:RED._("menu.label.moveToFront"), disabled: true, onselect: "core:move-selection-to-front"},
{id: "menu-item-view-tools-move-backwards", label:RED._("menu.label.moveBackwards"), disabled: true, onselect: "core:move-selection-backwards"},
{id: "menu-item-view-tools-move-forwards", label:RED._("menu.label.moveForwards"), disabled: true, onselect: "core:move-selection-forwards"},
null,
{id: "menu-item-view-tools-align-left", label:RED._("menu.label.alignLeft"), disabled: true, onselect: "core:align-selection-to-left"},
{id: "menu-item-view-tools-align-center", label:RED._("menu.label.alignCenter"), disabled: true, onselect: "core:align-selection-to-center"},
{id: "menu-item-view-tools-align-right", label:RED._("menu.label.alignRight"), disabled: true, onselect: "core:align-selection-to-right"},
@@ -679,12 +655,7 @@ var RED = (function() {
{id: "menu-item-view-tools-align-bottom", label:RED._("menu.label.alignBottom"), disabled: true, onselect: "core:align-selection-to-bottom"},
null,
{id: "menu-item-view-tools-distribute-horizontally", label:RED._("menu.label.distributeHorizontally"), disabled: true, onselect: "core:distribute-selection-horizontally"},
{id: "menu-item-view-tools-distribute-veritcally", label:RED._("menu.label.distributeVertically"), disabled: true, onselect: "core:distribute-selection-vertically"},
null,
{id: "menu-item-view-tools-move-to-back", label:RED._("menu.label.moveToBack"), disabled: true, onselect: "core:move-selection-to-back"},
{id: "menu-item-view-tools-move-to-front", label:RED._("menu.label.moveToFront"), disabled: true, onselect: "core:move-selection-to-front"},
{id: "menu-item-view-tools-move-backwards", label:RED._("menu.label.moveBackwards"), disabled: true, onselect: "core:move-selection-backwards"},
{id: "menu-item-view-tools-move-forwards", label:RED._("menu.label.moveForwards"), disabled: true, onselect: "core:move-selection-forwards"}
{id: "menu-item-view-tools-distribute-veritcally", label:RED._("menu.label.distributeVertically"), disabled: true, onselect: "core:distribute-selection-vertically"}
]});
menuOptions.push(null);
@@ -777,7 +748,6 @@ var RED = (function() {
RED.deploy.init(RED.settings.theme("deployButton",null));
RED.keyboard.init(buildMainMenu);
RED.envVar.init();
RED.nodes.init();
RED.runtime.init()
@@ -796,7 +766,7 @@ var RED = (function() {
$('<div id="red-ui-header-shade" class="hide"></div>').appendTo(header);
$('<div id="red-ui-main-container" class="red-ui-sidebar-closed hide">'+
'<div id="red-ui-workspace"></div>'+
'<div id="red-ui-editor-stack" tabindex="-1"></div>'+
'<div id="red-ui-editor-stack"></div>'+
'<div id="red-ui-palette"></div>'+
'<div id="red-ui-sidebar"></div>'+
'<div id="red-ui-sidebar-separator"></div>'+

View File

@@ -423,10 +423,11 @@ RED.clipboard = (function() {
}
}
function showImportNodes(library = 'clipboard') {
function showImportNodes(mode) {
if (disabled) {
return;
}
mode = mode || "clipboard";
dialogContainer.empty();
dialogContainer.append($(importNodesDialog));
@@ -503,7 +504,7 @@ RED.clipboard = (function() {
$("#red-ui-clipboard-dialog-import-text").on("keyup", validateImport);
$("#red-ui-clipboard-dialog-import-text").on('paste',function() { setTimeout(validateImport,10)});
if (RED.workspaces.active() === 0 || RED.workspaces.isActiveLocked()) {
if (RED.workspaces.active() === 0) {
$("#red-ui-clipboard-dialog-import-opt-current").addClass('disabled').removeClass("selected");
$("#red-ui-clipboard-dialog-import-opt-new").addClass("selected");
} else {
@@ -532,8 +533,8 @@ RED.clipboard = (function() {
$("#red-ui-clipboard-dialog-import-file-upload").trigger("click");
})
tabs.activateTab("red-ui-clipboard-dialog-import-tab-"+library);
if (library === 'clipboard') {
tabs.activateTab("red-ui-clipboard-dialog-import-tab-"+mode);
if (mode === 'clipboard') {
setTimeout(function() {
$("#red-ui-clipboard-dialog-import-text").trigger("focus");
},100)
@@ -557,16 +558,13 @@ RED.clipboard = (function() {
});
}
/**
* Show the export dialog
* @params library which export destination to show
* @params mode whether to default to 'auto' (default) or 'flow'
**/
function showExportNodes(library = 'clipboard', mode = 'auto' ) {
function showExportNodes(mode) {
if (disabled) {
return;
}
mode = mode || "clipboard";
dialogContainer.empty();
dialogContainer.append($(exportNodesDialog));
@@ -656,12 +654,7 @@ RED.clipboard = (function() {
$("#red-ui-clipboard-dialog-tab-library-name").val("flows.json").select();
dialogContainer.i18n();
var format = RED.settings.flowFilePretty ? "red-ui-clipboard-dialog-export-fmt-full" : "red-ui-clipboard-dialog-export-fmt-mini";
const userFormat = RED.settings.get("editor.dialog.export.pretty")
if (userFormat === false || userFormat === true) {
format = userFormat ? "red-ui-clipboard-dialog-export-fmt-full" : "red-ui-clipboard-dialog-export-fmt-mini";
}
$("#red-ui-clipboard-dialog-export-fmt-group > a").on("click", function(evt) {
evt.preventDefault();
@@ -677,8 +670,7 @@ RED.clipboard = (function() {
var nodes = JSON.parse(flow);
format = $(this).attr('id');
const pretty = format === "red-ui-clipboard-dialog-export-fmt-full";
if (pretty) {
if (format === 'red-ui-clipboard-dialog-export-fmt-full') {
flow = JSON.stringify(nodes,null,4);
} else {
flow = JSON.stringify(nodes);
@@ -687,7 +679,6 @@ RED.clipboard = (function() {
setTimeout(function() { $("#red-ui-clipboard-dialog-export-text").scrollTop(0); },50);
$("#red-ui-clipboard-dialog-export-text").trigger("focus");
RED.settings.set("editor.dialog.export.pretty", pretty)
}
});
@@ -775,15 +766,12 @@ RED.clipboard = (function() {
}
}
}
if (mode === 'flow' && !$("#red-ui-clipboard-dialog-export-rng-flow").hasClass('disabled')) {
$("#red-ui-clipboard-dialog-export-rng-flow").trigger("click");
}
if (format === "red-ui-clipboard-dialog-export-fmt-full") {
$("#red-ui-clipboard-dialog-export-fmt-full").trigger("click");
} else {
$("#red-ui-clipboard-dialog-export-fmt-mini").trigger("click");
}
tabs.activateTab("red-ui-clipboard-dialog-export-tab-"+library);
tabs.activateTab("red-ui-clipboard-dialog-export-tab-"+mode);
var dialogHeight = 400;
var winHeight = $(window).height();
@@ -1278,17 +1266,15 @@ RED.clipboard = (function() {
RED.keyboard.add("#red-ui-drop-target", "escape" ,hideDropTarget);
$('#red-ui-workspace-chart').on("dragenter",function(event) {
if (!RED.workspaces.isActiveLocked() && (
$.inArray("text/plain",event.originalEvent.dataTransfer.types) != -1 ||
$.inArray("Files",event.originalEvent.dataTransfer.types) != -1)) {
if ($.inArray("text/plain",event.originalEvent.dataTransfer.types) != -1 ||
$.inArray("Files",event.originalEvent.dataTransfer.types) != -1) {
$("#red-ui-drop-target").css({display:'table'}).focus();
}
});
$('#red-ui-drop-target').on("dragover",function(event) {
if ($.inArray("text/plain",event.originalEvent.dataTransfer.types) != -1 ||
$.inArray("Files",event.originalEvent.dataTransfer.types) != -1 ||
RED.workspaces.isActiveLocked()) {
$.inArray("Files",event.originalEvent.dataTransfer.types) != -1) {
event.preventDefault();
}
})
@@ -1296,29 +1282,27 @@ RED.clipboard = (function() {
hideDropTarget();
})
.on("drop",function(event) {
if (!RED.workspaces.isActiveLocked()) {
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);
importNodes(data);
} else if ($.inArray("Files",event.originalEvent.dataTransfer.types) != -1) {
var files = event.originalEvent.dataTransfer.files;
if (files.length === 1) {
var file = files[0];
var reader = new FileReader();
reader.onload = (function(theFile) {
return function(e) {
importNodes(e.target.result);
};
})(file);
reader.readAsText(file);
}
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);
importNodes(data);
} else if ($.inArray("Files",event.originalEvent.dataTransfer.types) != -1) {
var files = event.originalEvent.dataTransfer.files;
if (files.length === 1) {
var file = files[0];
var reader = new FileReader();
reader.onload = (function(theFile) {
return function(e) {
importNodes(e.target.result);
};
})(file);
reader.readAsText(file);
}
} catch(err) {
// Ensure any errors throw above doesn't stop the drop target from
// being hidden.
}
} catch(err) {
// Ensure any errors throw above doesn't stop the drop target from
// being hidden.
}
hideDropTarget();
event.preventDefault();

View File

@@ -160,7 +160,7 @@
this.element.css("maxHeight",null);
}
if (this.options.height !== 'auto') {
this.uiContainer.css("overflow-y","auto");
this.uiContainer.css("overflow-y","scroll");
if (!isNaN(this.options.height)) {
this.uiHeight = this.options.height;
}

View File

@@ -94,8 +94,8 @@ RED.menu = (function() {
var link = $(linkContent).appendTo(item);
opt.link = link;
if (typeof opt.onselect === 'string' || opt.shortcut) {
var shortcut = opt.shortcut || RED.keyboard.getShortcut(opt.onselect);
if (typeof opt.onselect === 'string') {
var shortcut = RED.keyboard.getShortcut(opt.onselect);
if (shortcut && shortcut.key) {
opt.shortcutSpan = $('<span class="red-ui-popover-key">'+RED.keyboard.formatKey(shortcut.key, true)+'</span>').appendTo(link.find(".red-ui-menu-label"));
}

View File

@@ -141,29 +141,7 @@ RED.tabs = (function() {
})
}
if (options.contextmenu) {
wrapper.on('contextmenu', function(evt) {
let clickedTab
let target = evt.target
while(target.nodeName !== 'A' && target.nodeName !== 'UL' && target.nodeName !== 'BODY') {
target = target.parentNode
}
if (target.nodeName === 'A') {
const href = target.getAttribute('href')
if (href) {
clickedTab = tabs[href.slice(1)]
}
}
evt.preventDefault()
evt.stopPropagation()
RED.contextMenu.show({
x:evt.clientX-5,
y:evt.clientY-5,
options: options.contextmenu(clickedTab)
})
return false
})
}
var scrollLeft;
var scrollRight;
@@ -829,19 +807,19 @@ RED.tabs = (function() {
event.preventDefault();
removeTab(tab.id);
});
RED.popover.tooltip(closeLink,RED._("workspace.closeFlow"));
RED.popover.tooltip(closeLink,RED._("workspace.hideFlow"));
}
if (tab.hideable) {
li.addClass("red-ui-tabs-closeable")
var closeLink = $("<a/>",{href:"#",class:"red-ui-tab-close red-ui-tab-hide"}).appendTo(li);
closeLink.append('<i class="fa fa-eye" />');
closeLink.append('<i class="fa fa-eye-slash" />');
closeLink.on("click",function(event) {
event.preventDefault();
hideTab(tab.id);
});
RED.popover.tooltip(closeLink,RED._("workspace.hideFlow"));
}
// if (tab.hideable) {
// li.addClass("red-ui-tabs-closeable")
// var closeLink = $("<a/>",{href:"#",class:"red-ui-tab-close red-ui-tab-hide"}).appendTo(li);
// closeLink.append('<i class="fa fa-eye" />');
// closeLink.append('<i class="fa fa-eye-slash" />');
// closeLink.on("click",function(event) {
// event.preventDefault();
// hideTab(tab.id);
// });
// RED.popover.tooltip(closeLink,RED._("workspace.hideFlow"));
// }
var badges = $('<span class="red-ui-tabs-badges"></span>').appendTo(li);
if (options.onselect) {
@@ -960,9 +938,6 @@ RED.tabs = (function() {
activeIndex: function() {
return ul.find("li.active").index()
},
getTabIndex: function (id) {
return ul.find("a[href='#"+id+"']").parent().index()
},
contains: function(id) {
return ul.find("a[href='#"+id+"']").length > 0;
},

View File

@@ -90,10 +90,10 @@
optEl.append(generateSpans(srcMatch));
optEl.appendTo(element);
}
matches.push({
value: optVal,
label: element,
i: (valMatch.found ? valMatch.index : srcMatch.index)
matches.push({
value: optVal,
label: element,
i: (valMatch.found ? valMatch.index : srcMatch.index)
});
}
})
@@ -146,7 +146,7 @@
{ value: "reset", source: ["delay","trigger","join","rbe"] },
{ value: "responseCookies", source: ["http request"] },
{ value: "responseTopic", source: ["mqtt"] },
{ value: "responseUrl", source: ["http request"] },
{ value: "responseURL", source: ["http request"] },
{ value: "restartTimeout", source: ["join"] },
{ value: "retain", source: ["mqtt"] },
{ value: "schema", source: ["json"] },
@@ -501,7 +501,7 @@
this.options.types = this.options.types||Object.keys(allOptions);
}
this.selectTrigger = $('<button type="button" class="red-ui-typedInput-type-select" tabindex="0"></button>').prependTo(this.uiSelect);
this.selectTrigger = $('<button class="red-ui-typedInput-type-select" tabindex="0"></button>').prependTo(this.uiSelect);
$('<i class="red-ui-typedInput-icon fa fa-caret-down"></i>').toggle(this.options.types.length > 1).appendTo(this.selectTrigger);
this.selectLabel = $('<span class="red-ui-typedInput-type-label"></span>').appendTo(this.selectTrigger);
@@ -570,7 +570,7 @@
})
// explicitly set optionSelectTrigger display to inline-block otherwise jQ sets it to 'inline'
this.optionSelectTrigger = $('<button type="button" tabindex="0" class="red-ui-typedInput-option-trigger" style="display:inline-block"><span class="red-ui-typedInput-option-caret"><i class="red-ui-typedInput-icon fa fa-caret-down"></i></span></button>').appendTo(this.uiSelect);
this.optionSelectTrigger = $('<button tabindex="0" class="red-ui-typedInput-option-trigger" style="display:inline-block"><span class="red-ui-typedInput-option-caret"><i class="red-ui-typedInput-icon fa fa-caret-down"></i></span></button>').appendTo(this.uiSelect);
this.optionSelectLabel = $('<span class="red-ui-typedInput-option-label"></span>').prependTo(this.optionSelectTrigger);
// RED.popover.tooltip(this.optionSelectLabel,function() {
// return that.optionValue;
@@ -591,7 +591,7 @@
that.uiSelect.addClass('red-ui-typedInput-focus');
});
this.optionExpandButton = $('<button type="button" tabindex="0" class="red-ui-typedInput-option-expand" style="display:inline-block"></button>').appendTo(this.uiSelect);
this.optionExpandButton = $('<button tabindex="0" class="red-ui-typedInput-option-expand" style="display:inline-block"></button>').appendTo(this.uiSelect);
this.optionExpandButtonIcon = $('<i class="red-ui-typedInput-icon fa fa-ellipsis-h"></i>').appendTo(this.optionExpandButton);
this.type(this.typeField.val() || this.options.default||this.typeList[0].value);

View File

@@ -1,6 +1,21 @@
RED.contextMenu = (function () {
let menu;
function createMenu() {
// menu = RED.popover.menu({
// options: [
// {
// label: 'delete selection',
// onselect: function() {
// RED.actions.invoke('core:delete-selection')
// RED.view.focus()
// }
// },
// { label: 'world' }
// ],
// width: 200,
// })
}
function disposeMenu() {
$(document).off("mousedown.red-ui-workspace-context-menu");
@@ -13,164 +28,114 @@ RED.contextMenu = (function () {
if (menu) {
menu.remove()
}
let menuItems = []
if (options.options) {
menuItems = options.options
} else if (options.type === 'workspace') {
const selection = RED.view.selection()
const noSelection = !selection || Object.keys(selection).length === 0
const hasSelection = (selection.nodes && selection.nodes.length > 0);
const hasMultipleSelection = hasSelection && selection.nodes.length > 1;
const virtulLinks = (selection.links && selection.links.filter(e => !!e.link)) || [];
const wireLinks = (selection.links && selection.links.filter(e => !e.link)) || [];
const hasLinks = wireLinks.length > 0;
const isSingleLink = !hasSelection && hasLinks && wireLinks.length === 1
const isMultipleLinks = !hasSelection && hasLinks && wireLinks.length > 1
const canDelete = hasSelection || hasLinks
const isGroup = hasSelection && selection.nodes.length === 1 && selection.nodes[0].type === 'group'
const canEdit = !RED.workspaces.isActiveLocked()
const canRemoveFromGroup = hasSelection && !!selection.nodes[0].g
const isAllGroups = hasSelection && selection.nodes.filter(n => n.type !== 'group').length === 0
const hasGroup = hasSelection && selection.nodes.filter(n => n.type === 'group' ).length > 0
const offset = $("#red-ui-workspace-chart").offset()
let addX = options.x - offset.left + $("#red-ui-workspace-chart").scrollLeft()
let addY = options.y - offset.top + $("#red-ui-workspace-chart").scrollTop()
const selection = RED.view.selection()
const noSelection = !selection || Object.keys(selection).length === 0
const hasSelection = (selection.nodes && selection.nodes.length > 0);
const hasMultipleSelection = hasSelection && selection.nodes.length > 1;
const virtulLinks = (selection.links && selection.links.filter(e => !!e.link)) || [];
const wireLinks = (selection.links && selection.links.filter(e => !e.link)) || [];
const hasLinks = wireLinks.length > 0;
const isSingleLink = !hasSelection && hasLinks && wireLinks.length === 1
const isMultipleLinks = !hasSelection && hasLinks && wireLinks.length > 1
const canDelete = hasSelection || hasLinks
const isGroup = hasSelection && selection.nodes.length === 1 && selection.nodes[0].type === 'group'
if (RED.view.snapGrid) {
const gridSize = RED.view.gridSize()
addX = gridSize * Math.floor(addX / gridSize)
addY = gridSize * Math.floor(addY / gridSize)
}
const canRemoveFromGroup = hasSelection && !!selection.nodes[0].g
const offset = $("#red-ui-workspace-chart").offset()
menuItems.push(
{ onselect: 'core:show-action-list', onpostselect: function () { } }
)
let addX = options.x - offset.left + $("#red-ui-workspace-chart").scrollLeft()
let addY = options.y - offset.top + $("#red-ui-workspace-chart").scrollTop()
const insertOptions = []
menuItems.push({ label: RED._("contextMenu.insert"), options: insertOptions })
insertOptions.push(
{
label: RED._("contextMenu.node"),
onselect: function () {
RED.view.showQuickAddDialog({
position: [addX, addY],
touchTrigger: true,
splice: isSingleLink ? selection.links[0] : undefined,
// spliceMultiple: isMultipleLinks
})
},
disabled: !canEdit
},
(hasLinks) ? { // has least 1 wire selected
label: RED._("contextMenu.junction"),
onselect: 'core:split-wires-with-junctions',
disabled: !canEdit || !hasLinks
} : {
label: RED._("contextMenu.junction"),
onselect: function () {
const nn = {
_def: { defaults: {} },
type: 'junction',
z: RED.workspaces.active(),
id: RED.nodes.id(),
x: addX,
y: addY,
w: 0, h: 0,
outputs: 1,
inputs: 1,
dirty: true
if (RED.view.snapGrid) {
const gridSize = RED.view.gridSize()
addX = gridSize * Math.floor(addX / gridSize)
addY = gridSize * Math.floor(addY / gridSize)
}
const menuItems = [
{ onselect: 'core:show-action-list', onpostselect: function () { } },
{
label: RED._("contextMenu.insert"),
options: [
{
label: RED._("contextMenu.node"),
onselect: function () {
RED.view.showQuickAddDialog({
position: [addX, addY],
touchTrigger: true,
splice: isSingleLink ? selection.links[0] : undefined,
// spliceMultiple: isMultipleLinks
})
}
const historyEvent = {
dirty: RED.nodes.dirty(),
t: 'add',
junctions: [nn]
}
RED.nodes.addJunction(nn);
RED.history.push(historyEvent);
RED.nodes.dirty(true);
RED.view.select({nodes: [nn] });
RED.view.redraw(true)
},
disabled: !canEdit
},
{
label: RED._("contextMenu.linkNodes"),
onselect: 'core:split-wire-with-link-nodes',
disabled: !canEdit || !hasLinks
},
null,
{ onselect: 'core:show-import-dialog', label: RED._('common.label.import')},
{ onselect: 'core:show-examples-import-dialog', label: RED._('menu.label.importExample') }
)
if (hasSelection && canEdit) {
const nodeOptions = []
if (!hasMultipleSelection && !isGroup) {
nodeOptions.push(
{ onselect: 'core:show-node-help' },
null
)
}
nodeOptions.push(
{ onselect: 'core:enable-selected-nodes' },
{ onselect: 'core:disable-selected-nodes' },
null,
{ onselect: 'core:show-selected-node-labels' },
{ onselect: 'core:hide-selected-node-labels' }
)
menuItems.push({
label: RED._('sidebar.info.node'),
options: nodeOptions
})
menuItems.push({
label: RED._('sidebar.info.group'),
options: [
{ onselect: 'core:group-selection' },
{ onselect: 'core:ungroup-selection', disabled: !hasGroup },
null,
{ onselect: 'core:copy-group-style', disabled: !hasGroup },
{ onselect: 'core:paste-group-style', disabled: !hasGroup}
]
})
if (canRemoveFromGroup) {
menuItems[menuItems.length - 1].options.push(
null,
{ onselect: 'core:remove-selection-from-group', label: RED._("menu.label.groupRemoveSelection") }
)
}
}
if (canEdit && hasMultipleSelection) {
menuItems.push({
label: RED._('menu.label.arrange'),
options: [
{ label:RED._("menu.label.alignLeft"), onselect: "core:align-selection-to-left"},
{ label:RED._("menu.label.alignCenter"), onselect: "core:align-selection-to-center"},
{ label:RED._("menu.label.alignRight"), onselect: "core:align-selection-to-right"},
null,
{ label:RED._("menu.label.alignTop"), onselect: "core:align-selection-to-top"},
{ label:RED._("menu.label.alignMiddle"), onselect: "core:align-selection-to-middle"},
{ label:RED._("menu.label.alignBottom"), onselect: "core:align-selection-to-bottom"},
null,
{ label:RED._("menu.label.distributeHorizontally"), onselect: "core:distribute-selection-horizontally"},
{ label:RED._("menu.label.distributeVertically"), onselect: "core:distribute-selection-vertically"}
]
})
}
(hasLinks) ? { // has least 1 wire selected
label: RED._("contextMenu.junction"),
onselect: 'core:split-wires-with-junctions',
disabled: !hasLinks
} : {
label: RED._("contextMenu.junction"),
onselect: function () {
const nn = {
_def: { defaults: {} },
type: 'junction',
z: RED.workspaces.active(),
id: RED.nodes.id(),
x: addX,
y: addY,
w: 0, h: 0,
outputs: 1,
inputs: 1,
dirty: true
}
const historyEvent = {
dirty: RED.nodes.dirty(),
t: 'add',
junctions: [nn]
}
RED.nodes.addJunction(nn);
RED.history.push(historyEvent);
RED.nodes.dirty(true);
RED.view.select({nodes: [nn] });
RED.view.redraw(true)
}
},
{
label: RED._("contextMenu.linkNodes"),
onselect: 'core:split-wire-with-link-nodes',
disabled: !hasLinks
}
]
}
]
menuItems.push(
null,
{ onselect: 'core:undo', disabled: RED.history.list().length === 0 },
{ onselect: 'core:redo', disabled: RED.history.listRedo().length === 0 },
null,
{ onselect: 'core:cut-selection-to-internal-clipboard', label: RED._("keyboard.cutNode"), disabled: !hasSelection },
{ onselect: 'core:copy-selection-to-internal-clipboard', label: RED._("keyboard.copyNode"), disabled: !hasSelection },
{ onselect: 'core:paste-from-internal-clipboard', label: RED._("keyboard.pasteNode"), disabled: !RED.view.clipboard() },
{ onselect: 'core:delete-selection', disabled: !canDelete },
{ onselect: 'core:show-export-dialog', label: RED._("menu.label.export") },
{ onselect: 'core:select-all-nodes' }
)
if (hasSelection) {
menuItems.push(
null,
{ onselect: 'core:undo', disabled: RED.history.list().length === 0 },
{ onselect: 'core:redo', disabled: RED.history.listRedo().length === 0 },
null,
{ onselect: 'core:cut-selection-to-internal-clipboard', label: RED._("keyboard.cutNode"), disabled: !canEdit || !hasSelection },
{ onselect: 'core:copy-selection-to-internal-clipboard', label: RED._("keyboard.copyNode"), disabled: !hasSelection },
{ onselect: 'core:paste-from-internal-clipboard', label: RED._("keyboard.pasteNode"), disabled: !canEdit || !RED.view.clipboard() },
{ onselect: 'core:delete-selection', disabled: !canEdit || !canDelete },
{ onselect: 'core:delete-selection-and-reconnect', label: RED._('keyboard.deleteReconnect'), disabled: !canEdit || !canDelete },
{ onselect: 'core:show-export-dialog', label: RED._("menu.label.export") },
{ onselect: 'core:select-all-nodes' },
isGroup ?
{ onselect: 'core:ungroup-selection', disabled: !isGroup }
: { onselect: 'core:group-selection', disabled: !hasSelection }
)
if (canRemoveFromGroup) {
menuItems.push({ onselect: 'core:remove-selection-from-group', label: RED._("menu.label.groupRemoveSelection") })
}
}
var direction = "right";
@@ -179,7 +144,7 @@ RED.contextMenu = (function () {
($(window).width() -MENU_WIDTH)) {
direction = "left";
}
menu = RED.menu.init({
direction: direction,
onpreselect: function() {

View File

@@ -558,11 +558,6 @@ RED.deploy = (function() {
RED.notify('<p>' + RED._("deploy.successfulDeploy") + '</p>', "success");
}
RED.nodes.eachNode(function (node) {
const flow = node.z && (RED.nodes.workspace(node.z) || RED.nodes.subflow(node.z) || null);
const isLocked = flow ? flow.locked : false;
if (flow && isLocked) {
flow.locked = false;
}
if (node.changed) {
node.dirty = true;
node.changed = false;
@@ -574,9 +569,6 @@ RED.deploy = (function() {
if (node.credentials) {
delete node.credentials;
}
if (flow && isLocked) {
flow.locked = isLocked;
}
});
RED.nodes.eachConfig(function (confNode) {
confNode.changed = false;

View File

@@ -238,7 +238,6 @@ RED.editor = (function() {
var valid = validateNodeProperty(node, defaults, property,value);
if (((typeof valid) === "string") || !valid) {
input.addClass("input-error");
input.next(".red-ui-typedInput-container").addClass("input-error");
if ((typeof valid) === "string") {
var tooltip = input.data("tooltip");
if (tooltip) {
@@ -251,7 +250,6 @@ RED.editor = (function() {
}
} else {
input.removeClass("input-error");
input.next(".red-ui-typedInput-container").removeClass("input-error");
var tooltip = input.data("tooltip");
if (tooltip) {
input.data("tooltip", null);
@@ -1107,10 +1105,6 @@ RED.editor = (function() {
if (editing_node) {
RED.sidebar.info.refresh(editing_node);
RED.sidebar.help.show(editing_node.type, false);
//ensure focused element is NOT body (for keyboard scope to operate correctly)
if (document.activeElement.tagName === 'BODY') {
$('#red-ui-editor-stack').trigger('focus')
}
}
}
}
@@ -1853,15 +1847,11 @@ RED.editor = (function() {
workspace.disabled = disabled;
$("#red-ui-tab-"+(workspace.id.replace(".","-"))).toggleClass('red-ui-workspace-disabled',!!workspace.disabled);
if (workspace.id === RED.workspaces.active()) {
$("#red-ui-workspace").toggleClass("red-ui-workspace-disabled",!!workspace.disabled);
}
}
var locked = $("#node-input-locked").prop("checked");
if (workspace.locked !== locked) {
editState.changes.locked = workspace.locked;
editState.changed = true;
workspace.locked = locked;
$("#red-ui-tab-"+(workspace.id.replace(".","-"))).toggleClass('red-ui-workspace-locked',!!workspace.locked);
}
if (editState.changed) {
var historyEvent = {
t: "edit",
@@ -1902,7 +1892,6 @@ RED.editor = (function() {
var trayBody = tray.find('.red-ui-tray-body');
trayBody.parent().css('overflow','hidden');
var trayFooterLeft = $('<div class="red-ui-tray-footer-left"></div>').appendTo(trayFooter)
var trayFooterRight = $('<div class="red-ui-tray-footer-right"></div>').appendTo(trayFooter)
var nodeEditPanes = [
'editor-tab-flow-properties',
@@ -1917,18 +1906,6 @@ RED.editor = (function() {
disabledIcon: "fa-ban",
invertState: true
})
if (!workspace.hasOwnProperty("locked")) {
workspace.locked = false;
}
$('<input id="node-input-locked" type="checkbox">').prop("checked",workspace.locked).appendTo(trayFooterRight).toggleButton({
enabledLabel: 'Unlocked',
enabledIcon: "fa-unlock-alt",
disabledLabel: 'Locked',
disabledIcon: "fa-lock",
invertState: true
})
prepareEditDialog(trayBody, nodeEditPanes, workspace, {}, "node-input", defaultTab, function(_activeEditPanes) {
activeEditPanes = _activeEditPanes;
trayBody.i18n();

View File

@@ -45,9 +45,6 @@
selectedCodeEditor = RED.editor.codeEditor[defaultEditor];
initialised = selectedCodeEditor.init();
}
$('<div id="red-ui-image-drop-target"><div data-i18n="[append]workspace.dropImageHere"><i class="fa fa-download"></i><br></div></div>').appendTo('#red-ui-editor');
$("#red-ui-image-drop-target").hide();
}
function create(options) {
@@ -67,7 +64,6 @@
options = {};
}
var editor = null;
if (this.editor.type === MONACO) {
// compatibility (see above note)
if (!options.element && !options.id) {
@@ -78,14 +74,10 @@
console.warn("createEditor() options.element or options.id is not valid", options);
$("#dialog-form").append('<div id="' + options.id + '" style="display: none;" />');
}
editor = this.editor.create(options);
return this.editor.create(options);
} else {
editor = this.editor.create(options);//fallback to ACE
return this.editor.create(options);//fallback to ACE
}
if (options.mode === "ace/mode/markdown") {
RED.editor.customEditTypes['_markdown'].postInit(editor, options);
}
return editor;
}
return {

View File

@@ -100,7 +100,7 @@ RED.editor.codeEditor.monaco = (function() {
"node-red-util": {package: "node-red", module: "util", path: "node-red/util.d.ts" },
"node-red-func": {package: "node-red", module: "func", path: "node-red/func.d.ts" },
}
const defaultServerSideTypes = [ knownModules["node-red-util"], knownModules["node-red-func"], knownModules["globals"], knownModules["console"], knownModules["buffer"] , knownModules["util"] ];
const defaultServerSideTypes = [ knownModules["node-red-util"], knownModules["node-red-func"], knownModules["globals"], knownModules["console"], knownModules["buffer"] ];
const modulesCache = {};
@@ -764,7 +764,7 @@ RED.editor.codeEditor.monaco = (function() {
if(!options.stateId && options.stateId !== false) {
options.stateId = RED.editor.generateViewStateId("monaco", options, (options.mode || options.title || "").split("/").pop());
options.stateId = RED.editor.generateViewStateId("monaco", options, (options.mode || options.title).split("/").pop());
}
var el = options.element || $("#"+options.id)[0];
var toolbarRow = $("<div>").appendTo(el);

View File

@@ -76,9 +76,6 @@ RED.editor.colorPicker = RED.colorPicker = (function() {
var focusTarget = colorInput;
colorInput.on("change", function (e) {
var color = colorInput.val();
if (options.defaultValue && !color.match(/^([a-z]+|#[0-9a-fA-F]{6}|#[0-9a-fA-F]{3})$/)) {
color = options.defaultValue;
}
colorHiddenInput.val(color).trigger('change');
refreshDisplay(color);
});

View File

@@ -2,7 +2,7 @@ RED.editor.envVarList = (function() {
var currentLocale = 'en-US';
var DEFAULT_ENV_TYPE_LIST = ['str','num','bool','json','bin','env'];
var DEFAULT_ENV_TYPE_LIST_INC_CRED = ['str','num','bool','json','bin','env','cred','jsonata'];
var DEFAULT_ENV_TYPE_LIST_INC_CRED = ['str','num','bool','json','bin','env','cred'];
/**
* Create env var edit interface

View File

@@ -255,9 +255,6 @@
var currentExpression = expressionEditor.getValue();
var expr;
var usesContext = false;
var usesEnv = false;
var usesMoment = false;
var usesClone = false;
var legacyMode = /(^|[^a-zA-Z0-9_'".])msg([^a-zA-Z0-9_'"]|$)/.test(currentExpression);
$(".red-ui-editor-type-expression-legacy").toggle(legacyMode);
try {
@@ -270,18 +267,6 @@
usesContext = true;
return null;
});
expr.assign("env", function(name) {
usesEnv = true;
return null;
});
expr.assign("moment", function(name) {
usesMoment = true;
return null;
});
expr.assign("clone", function(name) {
usesClone = true;
return null;
});
} catch(err) {
testResultEditor.setValue(RED._("expressionEditor.errors.invalid-expr",{message:err.message}),-1);
return;
@@ -299,18 +284,6 @@
testResultEditor.setValue(RED._("expressionEditor.errors.context-unsupported"),-1);
return;
}
if (usesEnv) {
testResultEditor.setValue(RED._("expressionEditor.errors.env-unsupported"),-1);
return;
}
if (usesMoment) {
testResultEditor.setValue(RED._("expressionEditor.errors.moment-unsupported"),-1);
return;
}
if (usesClone) {
testResultEditor.setValue(RED._("expressionEditor.errors.clone-unsupported"),-1);
return;
}
var formattedResult;
if (result !== undefined) {

View File

@@ -14,61 +14,6 @@
* limitations under the License.
**/
(function() {
/**
* Converts dropped image file to date URL
*/
function file2base64Image(file, cb) {
var reader = new FileReader();
reader.onload = (function (fd) {
return function (e) {
cb(e.target.result);
};
})(file);
reader.readAsDataURL(file);
}
var initialized = false;
var currentEditor = null;
/**
* Initialize handler for image file drag events
*/
function initImageDrag(elem, editor) {
$(elem).on("dragenter", function (ev) {
ev.preventDefault();
$("#red-ui-image-drop-target").css({display:'table'}).focus();
currentEditor = editor;
});
if (!initialized) {
initialized = true;
$("#red-ui-image-drop-target").on("dragover", function (ev) {
ev.preventDefault();
}).on("dragleave", function (ev) {
$("#red-ui-image-drop-target").hide();
}).on("drop", function (ev) {
ev.preventDefault();
if ($.inArray("Files",ev.originalEvent.dataTransfer.types) != -1) {
var files = ev.originalEvent.dataTransfer.files;
if (files.length === 1) {
var file = files[0];
var name = file.name.toLowerCase();
if (name.match(/\.(apng|avif|gif|jpeg|png|svg|webp)$/)) {
file2base64Image(file, function (image) {
var session = currentEditor.getSession();
var img = `<img src="${image}"/>\n`;
var pos = session.getCursorPosition();
session.insert(pos, img);
$("#red-ui-image-drop-target").hide();
});
return;
}
}
}
$("#red-ui-image-drop-target").hide();
});
}
}
var toolbarTemplate = '<div style="margin-bottom: 5px">'+
'<span class="button-group">'+
@@ -169,7 +114,6 @@
var currentScrollTop = $(".red-ui-editor-type-markdown-panel-preview").scrollTop();
$(".red-ui-editor-type-markdown-panel-preview").html(RED.utils.renderMarkdown(expressionEditor.getValue()));
$(".red-ui-editor-type-markdown-panel-preview").scrollTop(currentScrollTop);
mermaid.init();
},200);
})
if (options.header) {
@@ -178,7 +122,6 @@
if (value) {
$(".red-ui-editor-type-markdown-panel-preview").html(RED.utils.renderMarkdown(expressionEditor.getValue()));
mermaid.init();
}
panels = RED.panels.create({
id:"red-ui-editor-type-markdown-panels",
@@ -205,14 +148,10 @@
});
RED.popover.tooltip($("#node-btn-markdown-preview"), RED._("markdownEditor.toggle-preview"));
if(!expressionEditor._initState) {
if (options.cursor) {
expressionEditor.gotoLine(options.cursor.row+1,options.cursor.column,false);
}
else {
expressionEditor.gotoLine(0, 0, false);
}
}
if (options.cursor && !expressionEditor._initState) {
expressionEditor.gotoLine(options.cursor.row+1,options.cursor.column,false);
}
dialogForm.i18n();
},
close: function() {
@@ -276,11 +215,7 @@
}
})
return toolbar;
},
postInit: function (editor, options) {
var elem = $("#"+options.id);
initImageDrag(elem, editor);
}
}
}
RED.editor.registerTypeEditor("_markdown", definition);
})();

View File

@@ -235,7 +235,6 @@
RED.editor.colorPicker.create({
id: "red-ui-editor-node-color",
value: color,
defaultValue: "#DDAA99",
palette: recommendedColors,
sortPalette: function (a, b) {return a.l - b.l;}
}).appendTo(colorRow);

View File

@@ -52,6 +52,8 @@
node.info = info;
}
$("#red-ui-tab-"+(node.id.replace(".","-"))).toggleClass('red-ui-workspace-disabled',!!node.disabled);
$("#red-ui-workspace").toggleClass("red-ui-workspace-disabled",!!node.disabled);
}
}
});

View File

@@ -1,175 +0,0 @@
RED.envVar = (function() {
function saveEnvList(list) {
const items = list.editableList("items")
const new_env = [];
items.each(function (i,el) {
var data = el.data('data');
var item;
if (data.nameField && data.valueField) {
item = {
name: data.nameField.val(),
value: data.valueField.typedInput("value"),
type: data.valueField.typedInput("type")
};
new_env.push(item);
}
});
return new_env;
}
function getGlobalConf(create) {
var gconf = null;
RED.nodes.eachConfig(function (conf) {
if (conf.type === "global-config") {
gconf = conf;
}
});
if ((gconf === null) && create) {
var cred = {
_ : {},
map: {}
};
gconf = {
id: RED.nodes.id(),
type: "global-config",
env: [],
name: "global-config",
label: "",
hasUsers: false,
users: [],
credentials: cred,
_def: RED.nodes.getType("global-config"),
};
RED.nodes.add(gconf);
}
return gconf;
}
function applyChanges(list) {
var gconf = getGlobalConf(false);
var new_env = [];
var items = list.editableList('items');
var credentials = gconf ? gconf.credentials : null;
if (!credentials) {
credentials = {
_ : {},
map: {}
};
}
items.each(function (i,el) {
var data = el.data('data');
if (data.nameField && data.valueField) {
var item = {
name: data.nameField.val(),
value: data.valueField.typedInput("value"),
type: data.valueField.typedInput("type")
};
if (item.name.trim() !== "") {
new_env.push(item);
if ((item.type === "cred") && (item.value !== "__PWRD__")) {
credentials.map[item.name] = item.value;
credentials.map["has_"+item.name] = (item.value !== "");
item.value = "__PWRD__";
}
}
}
});
if (gconf === null) {
gconf = getGlobalConf(true);
}
if ((JSON.stringify(new_env) !== JSON.stringify(gconf.env)) ||
(JSON.stringify(credentials) !== JSON.stringify(gconf.credentials))) {
gconf.env = new_env;
gconf.credentials = credentials;
RED.nodes.dirty(true);
}
}
function getSettingsPane() {
var gconf = getGlobalConf(false);
var env = gconf ? gconf.env : [];
var cred = gconf ? gconf.credentials : null;
if (!cred) {
cred = {
_ : {},
map: {}
};
}
var pane = $("<div/>", {
id: "red-ui-settings-tab-envvar",
class: "form-horizontal"
});
var content = $("<div/>", {
class: "form-row node-input-env-container-row"
}).css({
"margin": "10px"
}).appendTo(pane);
var label = $("<label></label>").css({
width: "100%"
}).appendTo(content);
$("<i/>", {
class: "fa fa-list"
}).appendTo(label);
$("<span/>").text(" "+RED._("env-var.header")).appendTo(label);
var list = $("<ol/>", {
id: "node-input-env-container"
}).appendTo(content);
var node = {
type: "",
env: env,
credentials: cred.map,
};
RED.editor.envVarList.create(list, node);
var buttons = $("<div/>").css({
"text-align": "right",
}).appendTo(content);
var revertButton = $("<button/>", {
class: "red-ui-button"
}).css({
}).text(RED._("env-var.revert")).appendTo(buttons);
var items = saveEnvList(list);
revertButton.on("click", function (ev) {
list.editableList("empty");
list.editableList("addItems", items);
});
return pane;
}
function init(done) {
if (!RED.user.hasPermission("settings.write")) {
RED.notify(RED._("user.errors.settings"),"error");
return;
}
RED.userSettings.add({
id:'envvar',
title: RED._("env-var.environment"),
get: getSettingsPane,
focus: function() {
var height = $("#red-ui-settings-tab-envvar").parent().height();
$("#node-input-env-container").editableList("height", (height -100));
},
close: function() {
var list = $("#node-input-env-container");
try {
applyChanges(list);
}
catch (e) {
console.log(e);
console.log(e.stack);
}
}
});
}
return {
init: init,
};
})();

View File

@@ -101,7 +101,6 @@ RED.group = (function() {
RED.editor.colorPicker.create({
id:"node-input-style-stroke",
value: style.stroke || defaultGroupStyle.stroke || "#a4a4a4",
defaultValue: "#a4a4a4",
palette: colorPalette,
cellPerRow: colorCount,
cellWidth: 16,
@@ -113,7 +112,6 @@ RED.group = (function() {
RED.editor.colorPicker.create({
id:"node-input-style-fill",
value: style.fill || defaultGroupStyle.fill ||"none",
defaultValue: "none",
palette: colorPalette,
cellPerRow: colorCount,
cellWidth: 16,
@@ -131,7 +129,6 @@ RED.group = (function() {
RED.editor.colorPicker.create({
id:"node-input-style-color",
value: style.color || defaultGroupStyle.color ||"#a4a4a4",
defaultValue: "#a4a4a4",
palette: colorPalette,
cellPerRow: colorCount,
cellWidth: 16,
@@ -188,8 +185,6 @@ RED.group = (function() {
var activateMerge = false;
var activateRemove = false;
var singleGroupSelected = false;
var locked = RED.workspaces.isActiveLocked()
if (activateGroup) {
singleGroupSelected = selection.nodes.length === 1 && selection.nodes[0].type === 'group';
selection.nodes.forEach(function (n) {
@@ -204,12 +199,12 @@ RED.group = (function() {
activateMerge = (selection.nodes.length > 1);
}
}
RED.menu.setDisabled("menu-item-group-group", locked || !activateGroup);
RED.menu.setDisabled("menu-item-group-ungroup", locked || !activateUngroup);
RED.menu.setDisabled("menu-item-group-merge", locked || !activateMerge);
RED.menu.setDisabled("menu-item-group-remove", locked || !activateRemove);
RED.menu.setDisabled("menu-item-group-group", !activateGroup);
RED.menu.setDisabled("menu-item-group-ungroup", !activateUngroup);
RED.menu.setDisabled("menu-item-group-merge", !activateMerge);
RED.menu.setDisabled("menu-item-group-remove", !activateRemove);
RED.menu.setDisabled("menu-item-edit-copy-group-style", !singleGroupSelected);
RED.menu.setDisabled("menu-item-edit-paste-group-style", locked || !activateUngroup);
RED.menu.setDisabled("menu-item-edit-paste-group-style", !activateUngroup);
});
RED.actions.add("core:group-selection", function() { groupSelection() })
@@ -266,7 +261,6 @@ RED.group = (function() {
}
}
function pasteGroupStyle() {
if (RED.workspaces.isActiveLocked()) { return }
if (RED.view.state() !== RED.state.DEFAULT) { return }
if (groupStyleClipboard) {
var selection = RED.view.selection();
@@ -301,7 +295,6 @@ RED.group = (function() {
}
function groupSelection() {
if (RED.workspaces.isActiveLocked()) { return }
if (RED.view.state() !== RED.state.DEFAULT) { return }
var selection = RED.view.selection();
if (selection.nodes) {
@@ -320,7 +313,6 @@ RED.group = (function() {
}
}
function ungroupSelection() {
if (RED.workspaces.isActiveLocked()) { return }
if (RED.view.state() !== RED.state.DEFAULT) { return }
var selection = RED.view.selection();
if (selection.nodes) {
@@ -344,7 +336,6 @@ RED.group = (function() {
}
function ungroup(g) {
if (RED.workspaces.isActiveLocked()) { return }
var nodes = [];
var parentGroup = RED.nodes.group(g.g);
g.nodes.forEach(function(n) {
@@ -371,7 +362,6 @@ RED.group = (function() {
}
function mergeSelection() {
if (RED.workspaces.isActiveLocked()) { return }
if (RED.view.state() !== RED.state.DEFAULT) { return }
var selection = RED.view.selection();
if (selection.nodes) {
@@ -441,7 +431,6 @@ RED.group = (function() {
}
function removeSelection() {
if (RED.workspaces.isActiveLocked()) { return }
if (RED.view.state() !== RED.state.DEFAULT) { return }
var selection = RED.view.selection();
if (selection.nodes) {
@@ -469,7 +458,6 @@ RED.group = (function() {
}
}
function createGroup(nodes) {
if (RED.workspaces.isActiveLocked()) { return }
if (nodes.length === 0) {
return;
}
@@ -492,7 +480,7 @@ RED.group = (function() {
}
group.z = nodes[0].z;
group = RED.nodes.addGroup(group);
RED.nodes.addGroup(group);
try {
addToGroup(group,nodes);
@@ -575,7 +563,6 @@ RED.group = (function() {
markDirty(group);
}
function removeFromGroup(group, nodes, reparent) {
if (RED.workspaces.isActiveLocked()) { return }
if (!Array.isArray(nodes)) {
nodes = [nodes];
}

View File

@@ -267,7 +267,7 @@ RED.keyboard = (function() {
return resolveKeyEvent(evt);
}
if (Object.keys(handler).length > 0) {
// check if there's a potential combined handler initiated by this keyCode
// check if there's a potential combined handler initiated by this keyCode
for (let h in handler) {
if (matchHandlerToEvent(evt,handler[h]) > -1) {
partialState = handler;
@@ -298,21 +298,21 @@ RED.keyboard = (function() {
return resolveKeyEvent(evt);
}
}
d3.select(window).on("keydown",function() {
document.addEventListener("keydown", function(event) {
if (!handlersActive) {
return;
}
if (metaKeyCodes[d3.event.keyCode]) {
if (metaKeyCodes[event.keyCode]) {
return;
}
var handler = resolveKeyEvent(d3.event);
var handler = resolveKeyEvent(event);
if (handler && handler.ondown) {
if (typeof handler.ondown === "string") {
RED.actions.invoke(handler.ondown);
} else {
handler.ondown();
}
d3.event.preventDefault();
event.preventDefault();
}
});

0
packages/node_modules/@node-red/editor-client/src/js/ui/library.js vendored Normal file → Executable file
View File

View File

@@ -1,46 +0,0 @@
// Mermaid diagram stub library for on-demand dynamic loading
// Will be overwritten after script loading by $.getScript
var mermaid = (function () {
var enabled /* = undefined */;
var initializing = false;
var initCalled = false;
function initialize(opt) {
if (enabled === undefined) {
if (RED.settings.markdownEditor &&
RED.settings.markdownEditor.mermaid) {
enabled = RED.settings.markdownEditor.mermaid.enabled;
}
else {
enabled = true;
}
}
if (enabled) {
initializing = true;
$.getScript("vendor/mermaid/mermaid.min.js",
function (data, stat, jqxhr) {
$(".mermaid").show();
// invoke loaded mermaid API
initializing = false;
mermaid.initialize(opt);
if (initCalled) {
mermaid.init();
initCalled = false;
}
});
}
}
function init() {
if (initializing) {
$(".mermaid").hide();
initCalled = true;
}
}
return {
initialize: initialize,
init: init,
};
})();

176
packages/node_modules/@node-red/editor-client/src/js/ui/palette.js vendored Normal file → Executable file
View File

@@ -175,19 +175,9 @@ RED.palette = (function() {
$('<button type="button" onclick="RED.workspaces.show(\''+type.substring(8).replace(/'/g,"\\'")+'\'); return false;" class="red-ui-button red-ui-button-small" style="float: right; margin-left: 5px;"><i class="fa fa-pencil"></i></button>').appendTo(popOverContent)
}
const safeType = type.replace(/'/g,"\\'");
const wrapStr = function (str) {
if(str.indexOf(' ') >= 0) {
return '"' + str + '"'
}
return str
}
var safeType = type.replace(/'/g,"\\'");
$('<button type="button"; return false;" class="red-ui-button red-ui-button-small" style="float: right; margin-left: 5px;"><i class="fa fa-search"></i></button>')
.appendTo(popOverContent)
.on('click', function() {
RED.search.show('type:' + wrapStr(safeType))
})
$('<button type="button" onclick="RED.search.show(\'type:'+safeType+'\'); return false;" class="red-ui-button red-ui-button-small" style="float: right; margin-left: 5px;"><i class="fa fa-search"></i></button>').appendTo(popOverContent)
$('<button type="button" onclick="RED.sidebar.help.show(\''+safeType+'\'); return false;" class="red-ui-button red-ui-button-small" style="float: right; margin-left: 5px;"><i class="fa fa-book"></i></button>').appendTo(popOverContent)
$('<p>',{style:"font-size: 0.8em"}).text(metaData).appendTo(popOverContent);
@@ -292,7 +282,6 @@ RED.palette = (function() {
var hoverGroup;
var paletteWidth;
var paletteTop;
var dropEnabled;
$(d).draggable({
helper: 'clone',
appendTo: '#red-ui-editor',
@@ -300,7 +289,6 @@ RED.palette = (function() {
revertDuration: 200,
containment:'#red-ui-main-container',
start: function() {
dropEnabled = !(RED.nodes.workspace(RED.workspaces.active())?.locked);
paletteWidth = $("#red-ui-palette").width();
paletteTop = $("#red-ui-palette").parent().position().top + $("#red-ui-palette-container").position().top;
hoverGroup = null;
@@ -311,100 +299,96 @@ RED.palette = (function() {
RED.view.focus();
},
stop: function() {
if (dropEnabled) {
d3.select('.red-ui-flow-link-splice').classed('red-ui-flow-link-splice',false);
if (hoverGroup) {
document.getElementById("group_select_"+hoverGroup.id).classList.remove("red-ui-flow-group-hovered");
}
if (activeGroup) {
document.getElementById("group_select_"+activeGroup.id).classList.remove("red-ui-flow-group-active-hovered");
}
if (spliceTimer) { clearTimeout(spliceTimer); spliceTimer = null; }
if (groupTimer) { clearTimeout(groupTimer); groupTimer = null; }
document.querySelectorAll(".red-ui-flow-link-splice").forEach(n => { n.classList.remove("red-ui-flow-link-splice") })
if (hoverGroup) {
document.getElementById("group_select_"+hoverGroup.id).classList.remove("red-ui-flow-group-hovered");
}
if (activeGroup) {
document.getElementById("group_select_"+activeGroup.id).classList.remove("red-ui-flow-group-active-hovered");
}
if (spliceTimer) { clearTimeout(spliceTimer); spliceTimer = null; }
if (groupTimer) { clearTimeout(groupTimer); groupTimer = null; }
},
drag: function(e,ui) {
var paletteNode = getPaletteNode(nt);
ui.originalPosition.left = paletteNode.offset().left;
if (dropEnabled) {
mouseX = ui.position.left - paletteWidth + (ui.helper.width()/2) + chart.scrollLeft();
mouseY = ui.position.top - paletteTop + (ui.helper.height()/2) + chart.scrollTop() + 10;
if (!groupTimer) {
groupTimer = setTimeout(function() {
mouseX = ui.position.left - paletteWidth + (ui.helper.width()/2) + chart.scrollLeft();
mouseY = ui.position.top - paletteTop + (ui.helper.height()/2) + chart.scrollTop() + 10;
if (!groupTimer) {
groupTimer = setTimeout(function() {
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");
}
if (group) {
document.getElementById("group_select_"+group.id).classList.add("red-ui-flow-group-hovered");
}
hoverGroup = group;
if (hoverGroup) {
$(ui.helper).data('group',hoverGroup);
} else {
$(ui.helper).removeData('group');
}
}
groupTimer = null;
},200)
}
if (def.inputs > 0 && def.outputs > 0) {
if (!spliceTimer) {
spliceTimer = setTimeout(function() {
var nodes = [];
var bestDistance = Infinity;
var bestLink = null;
if (chartSVG.getIntersectionList) {
var svgRect = chartSVG.createSVGRect();
svgRect.x = mouseX;
svgRect.y = mouseY;
svgRect.width = 1;
svgRect.height = 1;
nodes = chartSVG.getIntersectionList(svgRect,chartSVG);
} else {
// Firefox doesn't do getIntersectionList and that
// makes us sad
nodes = RED.view.getLinksAtPoint(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");
}
if (group) {
document.getElementById("group_select_"+group.id).classList.add("red-ui-flow-group-hovered");
}
hoverGroup = group;
if (hoverGroup) {
$(ui.helper).data('group',hoverGroup);
} else {
$(ui.helper).removeData('group');
}
}
groupTimer = null;
},200)
}
if (def.inputs > 0 && def.outputs > 0) {
if (!spliceTimer) {
spliceTimer = setTimeout(function() {
var nodes = [];
var bestDistance = Infinity;
var bestLink = null;
if (chartSVG.getIntersectionList) {
var svgRect = chartSVG.createSVGRect();
svgRect.x = mouseX;
svgRect.y = mouseY;
svgRect.width = 1;
svgRect.height = 1;
nodes = chartSVG.getIntersectionList(svgRect,chartSVG);
} else {
// Firefox doesn't do getIntersectionList and that
// makes us sad
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-mx)*(p.x-mx))+((p.y-my)*(p.y-my));
if (d2 < 200 && d2 < bestDistance) {
bestDistance = d2;
bestLink = nodes[i];
}
for (var i=0;i<nodes.length;i++) {
var node = nodes[i];
if (node.classList.contains('red-ui-flow-link-background') && !node.classList.contains('red-ui-flow-link-link')) {
var length = node.getTotalLength();
for (var j=0;j<length;j+=10) {
var p = node.getPointAtLength(j);
var d2 = ((p.x-mx)*(p.x-mx))+((p.y-my)*(p.y-my));
if (d2 < 200 && d2 < bestDistance) {
bestDistance = d2;
bestLink = node;
}
}
}
if (activeSpliceLink && activeSpliceLink !== bestLink) {
d3.select(activeSpliceLink.parentNode).classed('red-ui-flow-link-splice',false);
}
}
if (activeSpliceLink && activeSpliceLink !== bestLink) {
activeSpliceLink.parentNode.classList.remove('red-ui-flow-link-splice');
}
if (bestLink) {
bestLink.parentNode.classList.add('red-ui-flow-link-splice');
} else {
document.querySelectorAll(".red-ui-flow-link-splice").forEach(n => { n.classList.remove("red-ui-flow-link-splice") })
}
if (activeSpliceLink !== bestLink) {
if (bestLink) {
d3.select(bestLink.parentNode).classed('red-ui-flow-link-splice',true)
$(ui.helper).data('splice',d3.select(bestLink).data()[0]);
} else {
d3.select('.red-ui-flow-link-splice').classed('red-ui-flow-link-splice',false);
$(ui.helper).removeData('splice');
}
if (activeSpliceLink !== bestLink) {
if (bestLink) {
$(ui.helper).data('splice',d3.select(bestLink).data()[0]);
} else {
$(ui.helper).removeData('splice');
}
}
activeSpliceLink = bestLink;
spliceTimer = null;
},200);
}
}
activeSpliceLink = bestLink;
spliceTimer = null;
},200);
}
}
}
@@ -438,7 +422,6 @@ RED.palette = (function() {
categoryNode.find(".red-ui-palette-content").slideToggle();
categoryNode.find("i").toggleClass("expanded");
}
categoryNode.hide();
}
}
@@ -517,7 +500,6 @@ RED.palette = (function() {
currentCategoryNode.find(".red-ui-palette-content").slideToggle();
currentCategoryNode.find("i").toggleClass("expanded");
}
currentCategoryNode.hide();
}
}

View File

@@ -545,7 +545,7 @@ RED.projects = (function() {
var sshwarningRow = $('<div class="red-ui-projects-dialog-screen-create-row-auth-error-no-keys"></div>').hide().appendTo(subrow);
$('<div class="form-row"><i class="fa fa-warning"></i> '+RED._("projects.clone-project.ssh-key-desc")+'</div>').appendTo(sshwarningRow);
subrow = $('<div style="text-align: center">').appendTo(sshwarningRow);
$('<button type="button" class="red-ui-button red-ui-projects-dialog-button">'+RED._("projects.clone-project.ssh-key-add")+'</button>').appendTo(subrow).on("click", function(e) {
$('<button class="red-ui-button red-ui-projects-dialog-button">'+RED._("projects.clone-project.ssh-key-add")+'</button>').appendTo(subrow).on("click", function(e) {
e.preventDefault();
dialog.dialog( "close" );
RED.userSettings.show('gitconfig');
@@ -1171,11 +1171,11 @@ RED.projects = (function() {
row = $('<div class="form-row button-group"></div>').appendTo(container);
var openProject = $('<button type="button" data-type="open" class="red-ui-button red-ui-projects-dialog-button red-ui-projects-dialog-screen-create-type toggle"><i class="fa fa-archive fa-2x"></i><i style="position: absolute;" class="fa fa-folder-open"></i><br/>'+RED._("projects.create.open")+'</button>').appendTo(row);
var createAsEmpty = $('<button type="button" data-type="empty" class="red-ui-button red-ui-projects-dialog-button red-ui-projects-dialog-screen-create-type toggle"><i class="fa fa-archive fa-2x"></i><i style="position: absolute;" class="fa fa-asterisk"></i><br/>'+RED._("projects.create.create")+'</button>').appendTo(row);
// var createAsCopy = $('<button type="button" data-type="copy" class="red-ui-button red-ui-projects-dialog-button red-ui-projects-dialog-screen-create-type toggle"><i class="fa fa-archive fa-2x"></i><i class="fa fa-long-arrow-right fa-2x"></i><i class="fa fa-archive fa-2x"></i><br/>Copy existing</button>').appendTo(row);
var createAsClone = $('<button type="button" data-type="clone" class="red-ui-button red-ui-projects-dialog-button red-ui-projects-dialog-screen-create-type toggle"><i class="fa fa-archive fa-2x"></i><i style="position: absolute;" class="fa fa-git"></i><br/>'+RED._("projects.create.clone")+'</button>').appendTo(row);
// var createAsClone = $('<button type="button" data-type="clone" class="red-ui-button red-ui-projects-dialog-button red-ui-projects-dialog-screen-create-type toggle"><i class="fa fa-git fa-2x"></i><i class="fa fa-arrows-h fa-2x"></i><i class="fa fa-archive fa-2x"></i><br/>Clone Repository</button>').appendTo(row);
var openProject = $('<button data-type="open" class="red-ui-button red-ui-projects-dialog-button red-ui-projects-dialog-screen-create-type toggle"><i class="fa fa-archive fa-2x"></i><i style="position: absolute;" class="fa fa-folder-open"></i><br/>'+RED._("projects.create.open")+'</button>').appendTo(row);
var createAsEmpty = $('<button data-type="empty" class="red-ui-button red-ui-projects-dialog-button red-ui-projects-dialog-screen-create-type toggle"><i class="fa fa-archive fa-2x"></i><i style="position: absolute;" class="fa fa-asterisk"></i><br/>'+RED._("projects.create.create")+'</button>').appendTo(row);
// var createAsCopy = $('<button data-type="copy" class="red-ui-button red-ui-projects-dialog-button red-ui-projects-dialog-screen-create-type toggle"><i class="fa fa-archive fa-2x"></i><i class="fa fa-long-arrow-right fa-2x"></i><i class="fa fa-archive fa-2x"></i><br/>Copy existing</button>').appendTo(row);
var createAsClone = $('<button data-type="clone" class="red-ui-button red-ui-projects-dialog-button red-ui-projects-dialog-screen-create-type toggle"><i class="fa fa-archive fa-2x"></i><i style="position: absolute;" class="fa fa-git"></i><br/>'+RED._("projects.create.clone")+'</button>').appendTo(row);
// var createAsClone = $('<button data-type="clone" class="red-ui-button red-ui-projects-dialog-button red-ui-projects-dialog-screen-create-type toggle"><i class="fa fa-git fa-2x"></i><i class="fa fa-arrows-h fa-2x"></i><i class="fa fa-archive fa-2x"></i><br/>Clone Repository</button>').appendTo(row);
row.find(".red-ui-projects-dialog-screen-create-type").on("click", function(evt) {
evt.preventDefault();
container.find(".red-ui-projects-dialog-screen-create-type").removeClass('selected');
@@ -1271,7 +1271,7 @@ RED.projects = (function() {
var credentialsLeftBox = $('<div class="red-ui-projects-dialog-credentials-box-left">').appendTo(credentialsBox);
var credentialsEnabledBox = $('<div class="form-row red-ui-projects-dialog-credentials-box-enabled"></div>').appendTo(credentialsLeftBox);
$('<label class="red-ui-projects-edit-form-inline-label"><input type="radio" name="projects-encryption-type" value="enabled" checked> <i class="fa fa-lock"></i> <span>'+RED._("projects.encryption-config.enable")+'</span></label>').appendTo(credentialsEnabledBox);
$('<label class="red-ui-projects-edit-form-inline-label"><input type="radio" name="projects-encryption-type" value="enabled"> <i class="fa fa-lock"></i> <span>'+RED._("projects.encryption-config.enable")+'</span></label>').appendTo(credentialsEnabledBox);
var credentialsDisabledBox = $('<div class="form-row red-ui-projects-dialog-credentials-box-disabled disabled"></div>').appendTo(credentialsLeftBox);
$('<label class="red-ui-projects-edit-form-inline-label"><input type="radio" name="projects-encryption-type" value="disabled"> <i class="fa fa-unlock"></i> <span>'+RED._("projects.encryption-config.disable")+'</span></label>').appendTo(credentialsDisabledBox);
@@ -1397,7 +1397,7 @@ RED.projects = (function() {
var sshwarningRow = $('<div class="red-ui-projects-dialog-screen-create-row-auth-error-no-keys"></div>').hide().appendTo(subrow);
$('<div class="form-row"><i class="fa fa-warning"></i> '+RED._("projects.create.desc2")+'</div>').appendTo(sshwarningRow);
subrow = $('<div style="text-align: center">').appendTo(sshwarningRow);
$('<button type="button" class="red-ui-button red-ui-projects-dialog-button">'+RED._("projects.create.add-ssh-key")+'</button>').appendTo(subrow).on("click", function(e) {
$('<button class="red-ui-button red-ui-projects-dialog-button">'+RED._("projects.create.add-ssh-key")+'</button>').appendTo(subrow).on("click", function(e) {
e.preventDefault();
$('#red-ui-projects-dialog-cancel').trigger("click");
RED.userSettings.show('gitconfig');
@@ -1631,14 +1631,14 @@ RED.projects = (function() {
function deleteProject(row,name,done) {
var cover = $('<div class="red-ui-projects-dialog-project-list-entry-delete-confirm"></div>').on("click", function(evt) { evt.stopPropagation(); }).appendTo(row);
$('<span>').text(RED._("projects.delete.confirm")).appendTo(cover);
$('<button type="button" class="red-ui-button red-ui-projects-dialog-button">'+RED._("common.label.cancel")+'</button>')
$('<button class="red-ui-button red-ui-projects-dialog-button">'+RED._("common.label.cancel")+'</button>')
.appendTo(cover)
.on("click", function(e) {
e.stopPropagation();
cover.remove();
done(true);
});
$('<button type="button" class="red-ui-button red-ui-projects-dialog-button primary">'+RED._("common.label.delete")+'</button>')
$('<button class="red-ui-button red-ui-projects-dialog-button primary">'+RED._("common.label.delete")+'</button>')
.appendTo(cover)
.on("click", function(e) {
e.stopPropagation();
@@ -1822,7 +1822,7 @@ RED.projects = (function() {
header.addClass("selectable");
var tools = $('<div class="red-ui-projects-dialog-project-list-entry-tools"></div>').appendTo(header);
$('<button type="button" class="red-ui-button red-ui-projects-dialog-button red-ui-button-small" style="float: right;"><i class="fa fa-trash"></i></button>')
$('<button class="red-ui-button red-ui-projects-dialog-button red-ui-button-small" style="float: right;"><i class="fa fa-trash"></i></button>')
.appendTo(tools)
.on("click", function(e) {
e.stopPropagation();

View File

@@ -106,51 +106,38 @@ RED.search = (function() {
return val;
}
function extractType(val, flags) {
// extracts: type:XYZ & type:"X Y Z"
const regEx = /(?:type):\s*(?:"([^"]+)"|([^" ]+))/;
let m
while ((m = regEx.exec(val)) !== null) {
// avoid infinite loops with zero-width matches
if (m.index === regEx.lastIndex) {
regEx.lastIndex++;
}
val = val.replace(m[0]," ").trim()
const flag = m[2] || m[1] // quoted entries in capture group 1, unquoted in capture group 2
flags.type = flags.type || [];
flags.type.push(flag);
}
return val;
}
function search(val) {
const results = [];
const flags = {};
var results = [];
var typeFilter;
var m = /(?:^| )type:([^ ]+)/.exec(val);
if (m) {
val = val.replace(/(?:^| )type:[^ ]+/,"");
typeFilter = m[1];
}
var flags = {};
val = extractFlag(val,"invalid",flags);
val = extractFlag(val,"unused",flags);
val = extractFlag(val,"config",flags);
val = extractFlag(val,"subflow",flags);
val = extractFlag(val,"hidden",flags);
val = extractFlag(val,"modified",flags);
val = extractValue(val,"flow",flags);// flow:current or flow:<flow-id>
val = extractValue(val,"flow",flags);// flow:active or flow:<flow-id>
val = extractValue(val,"uses",flags);// uses:<node-id>
val = extractType(val,flags);// type:<node-type>
val = val.trim();
const hasFlags = Object.keys(flags).length > 0;
const hasTypeFilter = flags.type && flags.type.length > 0
var hasFlags = Object.keys(flags).length > 0;
if (flags.flow && flags.flow.indexOf("current") >= 0) {
let idx = flags.flow.indexOf("current");
flags.flow[idx] = RED.workspaces.active();//convert 'current' to active flow ID
flags.flow[idx] = RED.workspaces.active();//convert active to flow ID
}
if (flags.flow && flags.flow.length) {
flags.flow = [ ...new Set(flags.flow) ]; //deduplicate
}
if (val.length > 0 || hasFlags) {
if (val.length > 0 || typeFilter || hasFlags) {
val = val.toLowerCase();
let i;
let j;
let list = [];
const nodes = {};
var i;
var j;
var list = [];
var nodes = {};
let keys = [];
if (flags.uses) {
keys = flags.uses;
@@ -158,10 +145,10 @@ RED.search = (function() {
keys = Object.keys(index);
}
for (i=0;i<keys.length;i++) {
const key = keys[i];
const kpos = val ? keys[i].indexOf(val) : -1;
if (kpos > -1 || (val === "" && hasFlags)) {
const ids = Object.keys(index[key]||{});
var key = keys[i];
var kpos = keys[i].indexOf(val);
if (kpos > -1) {
var ids = Object.keys(index[key]||{});
for (j=0;j<ids.length;j++) {
var node = index[key][ids[j]];
var isConfigNode = node.node._def.category === "config" && node.node.type !== 'group';
@@ -169,7 +156,7 @@ RED.search = (function() {
continue;
}
if (flags.hasOwnProperty("invalid")) {
const nodeIsValid = !node.node.hasOwnProperty("valid") || node.node.valid;
var nodeIsValid = !node.node.hasOwnProperty("valid") || node.node.valid;
if (flags.invalid === nodeIsValid) {
continue;
}
@@ -199,8 +186,8 @@ RED.search = (function() {
}
}
if (flags.hasOwnProperty("unused")) {
const isUnused = (node.node.type === 'subflow' && node.node.instances.length === 0) ||
(isConfigNode && node.node.users.length === 0 && node.node._def.hasUsers !== false)
var isUnused = (node.node.type === 'subflow' && node.node.instances.length === 0) ||
(isConfigNode && node.node.users.length === 0)
if (flags.unused !== isUnused) {
continue;
}
@@ -210,16 +197,12 @@ RED.search = (function() {
continue;
}
}
let typeIndex = -1
if(hasTypeFilter) {
typeIndex = flags.type.indexOf(node.node.type)
}
if (!hasTypeFilter || typeIndex > -1) {
nodes[node.node.id] = nodes[node.node.id] || {
if (!typeFilter || node.node.type === typeFilter) {
nodes[node.node.id] = nodes[node.node.id] = {
node: node.node,
label: node.label
};
nodes[node.node.id].index = Math.min(nodes[node.node.id].index || Infinity, typeIndex > -1 ? typeIndex : kpos);
nodes[node.node.id].index = Math.min(nodes[node.node.id].index||Infinity,kpos);
}
}
}
@@ -555,7 +538,7 @@ RED.search = (function() {
$(previousActiveElement).trigger("focus");
}
previousActiveElement = null;
}
}
if(!keepSearchToolbar) {
clearActiveSearch();
}
@@ -647,7 +630,7 @@ RED.search = (function() {
$("#red-ui-sidebar-shade").on('mousedown',hide);
$("#red-ui-view-searchtools-close").on("click", function close() {
clearActiveSearch();
clearActiveSearch();
updateSearchToolbar();
});
$("#red-ui-view-searchtools-close").trigger("click");

View File

@@ -273,11 +273,6 @@ RED.subflow = (function() {
var subflowInstances = [];
if (activeSubflow) {
RED.nodes.filterNodes({type:"subflow:"+activeSubflow.id}).forEach(function(n) {
const parentFlow = RED.nodes.workspace(n.z)
const wasLocked = parentFlow && parentFlow.locked
if (wasLocked) {
parentFlow.locked = false
}
subflowInstances.push({
id: n.id,
changed: n.changed
@@ -290,9 +285,6 @@ RED.subflow = (function() {
n.resize = true;
n.dirty = true;
RED.editor.updateNodeProperties(n);
if (wasLocked) {
parentFlow.locked = true
}
});
RED.editor.validateNode(activeSubflow);
return {
@@ -439,7 +431,44 @@ RED.subflow = (function() {
$("#red-ui-subflow-delete").on("click", function(event) {
event.preventDefault();
RED.subflow.delete(RED.workspaces.active())
var subflow = RED.nodes.subflow(RED.workspaces.active());
if (subflow.instances.length > 0) {
var msg = $('<div>')
$('<p>').text(RED._("subflow.subflowInstances",{count: subflow.instances.length})).appendTo(msg);
$('<p>').text(RED._("subflow.confirmDelete")).appendTo(msg);
var confirmDeleteNotification = RED.notify(msg, {
modal: true,
fixed: true,
buttons: [
{
text: RED._('common.label.cancel'),
click: function() {
confirmDeleteNotification.close();
}
},
{
text: RED._('workspace.confirmDelete'),
class: "primary",
click: function() {
confirmDeleteNotification.close();
completeDelete();
}
}
]
});
return;
} else {
completeDelete();
}
function completeDelete() {
var startDirty = RED.nodes.dirty();
var historyEvent = removeSubflow(RED.workspaces.active());
historyEvent.t = 'delete';
historyEvent.dirty = startDirty;
RED.history.push(historyEvent);
}
});
refreshToolbar(activeSubflow);
@@ -452,51 +481,7 @@ RED.subflow = (function() {
$("#red-ui-workspace-toolbar").hide().empty();
$("#red-ui-workspace-chart").css({"margin-top": "0"});
}
function deleteSubflow(id) {
const subflow = RED.nodes.subflow(id || RED.workspaces.active());
if (!subflow) {
return
}
if (subflow.instances.length > 0) {
if (subflow.instances.some(sf => { const ws = RED.nodes.workspace(sf.z); return ws?ws.locked:false })) {
return
}
const msg = $('<div>')
$('<p>').text(RED._("subflow.subflowInstances",{count: subflow.instances.length})).appendTo(msg);
$('<p>').text(RED._("subflow.confirmDelete")).appendTo(msg);
const confirmDeleteNotification = RED.notify(msg, {
modal: true,
fixed: true,
buttons: [
{
text: RED._('common.label.cancel'),
click: function() {
confirmDeleteNotification.close();
}
},
{
text: RED._('workspace.confirmDelete'),
class: "primary",
click: function() {
confirmDeleteNotification.close();
completeDelete();
}
}
]
});
return;
} else {
completeDelete();
}
function completeDelete() {
const startDirty = RED.nodes.dirty();
const historyEvent = removeSubflow(subflow.id);
historyEvent.t = 'delete';
historyEvent.dirty = startDirty;
RED.history.push(historyEvent);
}
}
function removeSubflow(id, keepInstanceNodes) {
// TODO: A lot of this logic is common with RED.nodes.removeWorkspace
var removedNodes = [];
@@ -521,13 +506,6 @@ RED.subflow = (function() {
RED.nodes.groups(id).forEach(function(n) {
removedGroups.push(n);
})
var removedJunctions = RED.nodes.junctions(id)
for (var i=0;i<removedJunctions.length;i++) {
var removedEntities = RED.nodes.removeJunction(removedJunctions[i])
removedLinks = removedLinks.concat(removedEntities.links)
}
var removedConfigNodes = [];
for (var i=0;i<removedNodes.length;i++) {
var removedEntities = RED.nodes.remove(removedNodes[i].id);
@@ -558,7 +536,6 @@ RED.subflow = (function() {
nodes:removedNodes,
links:removedLinks,
groups: removedGroups,
junctions: removedJunctions,
subflows: [activeSubflow]
}
}
@@ -573,7 +550,7 @@ RED.subflow = (function() {
}
});
RED.events.on("view:selection-changed",function(selection) {
if (!selection.nodes || RED.workspaces.isActiveLocked()) {
if (!selection.nodes) {
RED.menu.setDisabled("menu-item-subflow-convert",true);
} else {
RED.menu.setDisabled("menu-item-subflow-convert",false);
@@ -636,9 +613,6 @@ RED.subflow = (function() {
}
function convertToSubflow() {
if (RED.workspaces.isActiveLocked()) {
return
}
var selection = RED.view.selection();
if (!selection.nodes) {
RED.notify(RED._("subflow.errors.noNodesSelected"),"error");
@@ -794,7 +768,7 @@ RED.subflow = (function() {
}
subflowInstance._def = RED.nodes.getType(subflowInstance.type);
RED.editor.validateNode(subflowInstance);
subflowInstance = RED.nodes.add(subflowInstance);
RED.nodes.add(subflowInstance);
if (containingGroup) {
RED.group.addToGroup(containingGroup, subflowInstance);
@@ -958,6 +932,7 @@ RED.subflow = (function() {
function buildEnvUIRow(row, tenv, ui, node) {
console.log(tenv, ui)
ui.label = ui.label||{};
if ((tenv.type === "cred" || (tenv.parent && tenv.parent.type === "cred")) && !ui.type) {
ui.type = "cred";
@@ -1348,10 +1323,7 @@ RED.subflow = (function() {
init: init,
createSubflow: createSubflow,
convertToSubflow: convertToSubflow,
// removeSubflow: Internal function to remove subflow
removeSubflow: removeSubflow,
// delete: Prompt user for confirmation
delete: deleteSubflow,
refresh: refresh,
removeInput: removeSubflowInput,
removeOutput: removeSubflowOutput,

View File

@@ -43,15 +43,12 @@ RED.sidebar.config = (function() {
var categories = {};
function getOrCreateCategory(name,parent,label,isLocked) {
function getOrCreateCategory(name,parent,label) {
name = name.replace(/\./i,"-");
if (!categories[name]) {
var container = $('<div class="red-ui-palette-category red-ui-sidebar-config-category" id="red-ui-sidebar-config-category-'+name+'"></div>').appendTo(parent);
var header = $('<div class="red-ui-sidebar-config-tray-header red-ui-palette-header"><i class="fa fa-angle-down expanded"></i></div>').appendTo(container);
let lockIcon
if (label) {
lockIcon = $('<span style="margin-right: 5px"><i class="fa fa-lock"/></span>').appendTo(header)
lockIcon.toggle(!!isLocked)
$('<span class="red-ui-palette-node-config-label"/>').text(label).appendTo(header);
} else {
$('<span class="red-ui-palette-node-config-label" data-i18n="sidebar.config.'+name+'">').appendTo(header);
@@ -65,7 +62,6 @@ RED.sidebar.config = (function() {
var icon = header.find("i");
var result = {
label: label,
lockIcon,
list: category,
size: function() {
return result.list.find("li:not(.red-ui-palette-node-config-none)").length
@@ -104,9 +100,6 @@ RED.sidebar.config = (function() {
});
categories[name] = result;
} else {
if (isLocked !== undefined && categories[name].lockIcon) {
categories[name].lockIcon.toggle(!!isLocked)
}
if (categories[name].label !== label) {
categories[name].list.parent().find('.red-ui-palette-node-config-label').text(label);
categories[name].label = label;
@@ -223,7 +216,7 @@ RED.sidebar.config = (function() {
RED.nodes.eachWorkspace(function(ws) {
validList[ws.id.replace(/\./g,"-")] = true;
getOrCreateCategory(ws.id,flowCategories,ws.label, ws.locked);
getOrCreateCategory(ws.id,flowCategories,ws.label);
})
RED.nodes.eachSubflow(function(sf) {
validList[sf.id.replace(/\./g,"-")] = true;
@@ -281,15 +274,6 @@ RED.sidebar.config = (function() {
changes: {},
dirty: RED.nodes.dirty()
}
for (let i = 0; i < selectedNodes.length; i++) {
let node = RED.nodes.node(selectedNodes[i])
if (node.z) {
let ws = RED.nodes.workspace(node.z)
if (ws && ws.locked) {
return
}
}
}
selectedNodes.forEach(function(id) {
var node = RED.nodes.node(id);
try {

View File

@@ -50,7 +50,7 @@ RED.sidebar.help = (function() {
tocPanel = $("<div>", {class: "red-ui-sidebar-help-toc"}).appendTo(stackContainer);
var helpPanel = $("<div>").css({
"overflow-y": "auto"
"overflow-y": "scroll"
}).appendTo(stackContainer);
panels = RED.panels.create({
@@ -141,8 +141,7 @@ RED.sidebar.help = (function() {
RED.events.on('registry:node-type-removed', queueRefresh);
RED.events.on('subflows:change', refreshSubflow);
RED.actions.add("core:show-help-tab", show);
RED.actions.add("core:show-node-help", showNodeHelp)
RED.actions.add("core:show-help-tab",show);
}
@@ -339,19 +338,6 @@ RED.sidebar.help = (function() {
resizeStack();
}
function showNodeHelp(node) {
if (!node) {
const selection = RED.view.selection()
if (selection.nodes && selection.nodes.length > 0) {
node = selection.nodes.find(n => n.type !== 'group' && n.type !== 'junction')
}
}
if (node) {
show(node.type, true)
}
}
// TODO: DRY - projects.js
function addTargetToExternalLinks(el) {
$(el).find("a").each(function(el) {

View File

@@ -221,22 +221,6 @@ RED.sidebar.info.outliner = (function() {
} else {
$('<div class="red-ui-info-outline-item-control-spacer">').appendTo(controls)
}
if (n.type === 'tab') {
var lockToggleButton = $('<button type="button" class="red-ui-info-outline-item-control-lock red-ui-button red-ui-button-small"><i class="fa fa-unlock-alt"></i><i class="fa fa-lock"></i></button>').appendTo(controls).on("click",function(evt) {
evt.preventDefault();
evt.stopPropagation();
if (n.locked) {
RED.workspaces.unlock(n.id)
} else {
RED.workspaces.lock(n.id)
}
})
RED.popover.tooltip(lockToggleButton,function() {
return RED._("common.label."+(n.locked?"unlock":"lock"));
});
} else {
$('<div class="red-ui-info-outline-item-control-spacer">').appendTo(controls)
}
controls.find("button").on("dblclick", function(evt) {
evt.preventDefault();
evt.stopPropagation();
@@ -380,8 +364,6 @@ RED.sidebar.info.outliner = (function() {
flowList.treeList.addChild(objects[ws.id])
objects[ws.id].element.toggleClass("red-ui-info-outline-item-disabled", !!ws.disabled)
objects[ws.id].treeList.container.toggleClass("red-ui-info-outline-item-disabled", !!ws.disabled)
objects[ws.id].element.toggleClass("red-ui-info-outline-item-locked", !!ws.locked)
objects[ws.id].treeList.container.toggleClass("red-ui-info-outline-item-locked", !!ws.locked)
updateSearch();
}
@@ -396,8 +378,6 @@ RED.sidebar.info.outliner = (function() {
existingObject.element.find(".red-ui-info-outline-item-label").text(label);
existingObject.element.toggleClass("red-ui-info-outline-item-disabled", !!n.disabled)
existingObject.treeList.container.toggleClass("red-ui-info-outline-item-disabled", !!n.disabled)
existingObject.element.toggleClass("red-ui-info-outline-item-locked", !!n.locked)
existingObject.treeList.container.toggleClass("red-ui-info-outline-item-locked", !!n.locked)
updateSearch();
}
function onFlowsReorder(order) {

View File

@@ -25,7 +25,6 @@ RED.sidebar.info = (function() {
var propertiesPanelHeaderLabel;
var propertiesPanelHeaderReveal;
var propertiesPanelHeaderHelp;
var propertiesPanelHeaderCopyLink;
var selectedObject;
@@ -68,20 +67,10 @@ RED.sidebar.info = (function() {
propertiesPanelHeaderIcon = $("<span>").appendTo(propertiesPanelHeader);
propertiesPanelHeaderLabel = $("<span>").appendTo(propertiesPanelHeader);
propertiesPanelHeaderCopyLink = $('<button type="button" class="red-ui-button red-ui-button-small"><i class="fa fa-link"></button>').css({
propertiesPanelHeaderHelp = $('<button class="red-ui-button red-ui-button-small"><i class="fa fa-book"></button>').css({
position: 'absolute',
top: '12px',
right: '32px'
}).on("click", function(evt) {
RED.actions.invoke('core:copy-item-url',selectedObject)
}).appendTo(propertiesPanelHeader);
RED.popover.tooltip(propertiesPanelHeaderCopyLink,RED._("sidebar.info.copyItemUrl"));
propertiesPanelHeaderHelp = $('<button type="button" class="red-ui-button red-ui-button-small"><i class="fa fa-book"></button>').css({
position: 'absolute',
top: '12px',
right: '56px'
}).on("click", function(evt) {
evt.preventDefault();
evt.stopPropagation();
@@ -91,7 +80,8 @@ RED.sidebar.info = (function() {
}).appendTo(propertiesPanelHeader);
RED.popover.tooltip(propertiesPanelHeaderHelp,RED._("sidebar.help.showHelp"));
propertiesPanelHeaderReveal = $('<button type="button" class="red-ui-button red-ui-button-small"><i class="fa fa-search"></button>').css({
propertiesPanelHeaderReveal = $('<button class="red-ui-button red-ui-button-small"><i class="fa fa-search"></button>').css({
position: 'absolute',
top: '12px',
right: '8px'
@@ -108,7 +98,7 @@ RED.sidebar.info = (function() {
propertiesPanelContent = $("<div>").css({
"flex":"1 1 auto",
"overflow-y":"auto",
"overflow-y":"scroll",
}).appendTo(propertiesPanel);
@@ -195,7 +185,6 @@ RED.sidebar.info = (function() {
propertiesPanelHeaderLabel.text("");
propertiesPanelHeaderReveal.hide();
propertiesPanelHeaderHelp.hide();
propertiesPanelHeaderCopyLink.hide();
return;
} else if (Array.isArray(node)) {
// Multiple things selected
@@ -207,7 +196,6 @@ RED.sidebar.info = (function() {
propertiesPanelHeaderLabel.text("Selection");
propertiesPanelHeaderReveal.hide();
propertiesPanelHeaderHelp.hide();
propertiesPanelHeaderCopyLink.hide();
selectedObject = null;
var types = {
@@ -289,11 +277,9 @@ RED.sidebar.info = (function() {
if (node.type === "tab" || node.type === "subflow") {
// If nothing is selected, but we're on a flow or subflow tab.
propertiesPanelHeaderHelp.hide();
propertiesPanelHeaderCopyLink.show();
} else if (node.type === "group") {
propertiesPanelHeaderHelp.hide();
propertiesPanelHeaderCopyLink.show();
propRow = $('<tr class="red-ui-help-info-row"><td>&nbsp;</td><td></td></tr>').appendTo(tableBody);
@@ -318,10 +304,8 @@ RED.sidebar.info = (function() {
}
} else if (node.type === 'junction') {
propertiesPanelHeaderHelp.hide();
propertiesPanelHeaderCopyLink.hide();
} else {
propertiesPanelHeaderHelp.show();
propertiesPanelHeaderCopyLink.show();
if (!subflowRegex) {
propRow = $('<tr class="red-ui-help-info-row"><td>'+RED._("sidebar.info.type")+'</td><td></td></tr>').appendTo(tableBody);
@@ -463,8 +447,7 @@ RED.sidebar.info = (function() {
el = el.next();
}
$(this).toggleClass('expanded',!isExpanded);
});
mermaid.init();
})
}
var tips = (function() {

View File

@@ -27,26 +27,24 @@ RED.touch.radialMenu = (function() {
function createRadial(obj,pos,options) {
isActive = true;
try {
touchMenu = d3.select("body").append("div").classed("red-ui-editor-radial-menu",true)
.on('touchstart',function() {
touchMenu = $('<div>', {class: 'red-ui-editor-radial-menu'}).appendTo('body')
.on('touchstart',function(evt) {
hide();
d3.event.preventDefault();
evt.preventDefault();
});
var menu = touchMenu.append("div")
.style({
var menu = $('<div>').appendTo(touchMenu).css({
top: (pos[1]-80)+"px",
left:(pos[0]-80)+"px",
});
var menuOpts = [];
var createMenuOpt = function(x,y,opt) {
opt.el = menu.append("div").classed("red-ui-editor-radial-menu-opt",true)
.style({
opt.el = $('<div>', {class: 'red-ui-editor-radial-menu-opt'}).appendTo(menu)
.css({
top: (y+80-25)+"px",
left:(x+80-25)+"px"
})
.classed("red-ui-editor-radial-menu-opt-disabled",!!opt.disabled)
.toggleClass("red-ui-editor-radial-menu-opt-disabled",!!opt.disabled)
opt.el.html(opt.name);
@@ -54,16 +52,16 @@ RED.touch.radialMenu = (function() {
opt.y = y;
menuOpts.push(opt);
opt.el.on('touchstart',function() {
opt.el.classed("red-ui-editor-radial-menu-opt-active",true)
d3.event.preventDefault();
d3.event.stopPropagation();
opt.el.on('touchstart',function(evt) {
opt.el.toggleClass("red-ui-editor-radial-menu-opt-active",true)
evt.preventDefault();
evt.stopPropagation();
});
opt.el.on('touchend',function() {
opt.el.on('touchend',function(evt) {
hide();
opt.onselect();
d3.event.preventDefault();
d3.event.stopPropagation();
evt.preventDefault();
evt.stopPropagation();
});
}
@@ -88,8 +86,8 @@ RED.touch.radialMenu = (function() {
}
obj.on('touchend.radial',function() {
obj.on('touchend.radial',null);
obj.on('touchmenu.radial',null);
obj.off('touchend.radial');
obj.off('touchmenu.radial');
if (activeOption) {
try {
@@ -103,9 +101,9 @@ RED.touch.radialMenu = (function() {
}
});
obj.on('touchmove.radial',function() {
obj.on('touchmove.radial',function(evt) {
try {
var touch0 = d3.event.touches.item(0);
var touch0 = evt.touches.item(0);
var p = [touch0.pageX - pos[0],touch0.pageY-pos[1]];
for (var i=0;i<menuOpts.length;i++) {
var opt = menuOpts[i];
@@ -119,7 +117,7 @@ RED.touch.radialMenu = (function() {
if (opt === activeOption) {
activeOption = null;
}
opt.el.classed("selected",false);
opt.el.toggleClass("selected",false);
}
}
}

View File

@@ -435,15 +435,10 @@ RED.tourGuide = (function() {
function listTour() {
return [
{
id: "3_1",
label: "3.1",
path: "./tours/welcome.js"
},
{
id: "3_0",
label: "3.0",
path: "./tours/3.0/welcome.js"
path: "./tours/welcome.js"
},
{
id: "2_2",

View File

@@ -269,8 +269,8 @@ RED.typeSearch = (function() {
moveCallback = opts.move;
RED.events.emit("type-search:open");
//shade.show();
if ($("#red-ui-main-container").height() - opts.y - 195 < 0) {
opts.y = opts.y - 275;
if ($("#red-ui-main-container").height() - opts.y - 150 < 0) {
opts.y = opts.y - 235;
}
dialog.css({left:opts.x+"px",top:opts.y+"px"}).show();
searchResultsDiv.slideDown(300);

View File

@@ -0,0 +1,61 @@
/**
* Modelled after `d3.selection` this provides a way to keep a mapping of
* DOM Nodes with a data collection.
*
* The goal here is not to reproduce d3 functionality as-is, but to provide an
* api that is specific to what we need to do
*
* const domSelection = RED.utils.domSelection(container, selector, createNode, eachNode)
*
* - container - a DOM Node that is the container of the DOM Nodes to track
* - selector - CSS selector to get the DOM nodes to track
* - createNode - function called when a DOM node must be created for a piece of data.
* `this` is the data item. Should return the DOM Node. It will
* get added to the container.
* - eachNode - function called for each DOM node/data item in the selection
*
* DomSelection.refresh(data) - called whenever the selection should be refreshed.
* Data is expected to be an array of objects that contain an 'id' property
*
*/
RED.utils.domSelection = (function() {
class DomSelection {
constructor(container, selector, createNode, eachNode) {
this.container = container
this.selector = selector
this.createNode = createNode
this.eachNode = eachNode
this.data = []
}
refresh(data) {
const domNodes = this.container.querySelectorAll(this.selector)
const domItems = new Map()
const dataLength = data.length
const domLength = domNodes.length
for (let i = 0; i < domLength; i++) {
const domNode = domNodes[i]
if (domNode.__data__) {
domItems.set(domNode.__data__.id, domNode)
}
}
for (let i = 0; i < dataLength; i++) {
const datum = data[i]
let domNode = domItems.get(datum.id)
if (!domNode) {
domNode = this.createNode.call(datum)
this.container.appendChild(domNode)
domNode.__data__ = datum
} else {
domItems.delete(datum.id)
}
this.eachNode.call(datum, domNode)
}
for (const remainingDomNodes of domItems) {
remainingDomNodes[1].remove()
}
}
}
return (container, selector, createNode, eachNode) => new DomSelection(container, selector, createNode, eachNode)
})()

View File

@@ -96,37 +96,6 @@ RED.utils = (function() {
}
}
var mermaidIsInitialized = false;
var mermaidIsEnabled /* = undefined */;
renderer.code = function (code, lang) {
if(lang === "mermaid") {
// mermaid diagram rendering
if (mermaidIsEnabled === undefined) {
if (RED.settings.markdownEditor &&
RED.settings.markdownEditor.mermaid) {
mermaidIsEnabled = RED.settings.markdownEditor.mermaid.enabled;
}
else {
mermaidIsEnabled = true;
}
}
if (mermaidIsEnabled) {
if (!mermaidIsInitialized) {
mermaidIsInitialized = true;
mermaid.initialize({startOnLoad:false});
}
return `<pre class='mermaid'>${code}</pre>`;
}
else {
return `<details><summary>${RED._("markdownEditor.mermaid.summary")}</summary><pre><code>${code}</code></pre></details>`;
}
}
else {
return "<pre><code>" +code +"</code></pre>";
}
};
window._marked.setOptions({
renderer: renderer,
gfm: true,
@@ -1428,6 +1397,17 @@ RED.utils = (function() {
return r;
}
function createSVGElement(tag, attrs = {}, parent) {
const element = document.createElementNS('http://www.w3.org/2000/svg', tag)
for (const k in attrs) {
element.setAttribute(k, attrs[k])
}
if (parent) {
parent.appendChild(element)
}
return element
}
return {
createObjectElement: createObjectElement,
getMessageProperty: getMessageProperty,
@@ -1451,6 +1431,7 @@ RED.utils = (function() {
getDarkerColor: getDarkerColor,
parseModuleList: parseModuleList,
checkModuleAllowed: checkModuleAllowed,
getBrowserInfo: getBrowserInfo
getBrowserInfo: getBrowserInfo,
createSVGElement: createSVGElement
}
})();

View File

@@ -91,8 +91,7 @@ RED.view.annotations = (function() {
function addAnnotation(id,evt) {
var opts = annotations[id];
evt.el.__annotations__ = evt.el.__annotations__ || [];
var annotationGroup = document.createElementNS("http://www.w3.org/2000/svg","g");
annotationGroup.setAttribute("class",opts.class || "");
var annotationGroup = RED.utils.createSVGElement("g", { class: opts.class || '' })
evt.el.__annotations__.push({
id:id,
element: annotationGroup

View File

@@ -15,133 +15,128 @@
**/
RED.view.navigator = (function() {
RED.view.navigator = (function() {
var nav_scale = 25;
var nav_width = 5000/nav_scale;
var nav_height = 5000/nav_scale;
var nav_scale = 25;
var nav_width = 5000/nav_scale;
var nav_height = 5000/nav_scale;
var navContainer;
var navBox;
var navBorder;
var scrollPos;
var scaleFactor;
var chartSize;
var dimensions;
var isDragging;
var isShowing = false;
var navContainer;
var navBox;
var navBorder;
var navVis;
var scrollPos;
var scaleFactor;
var chartSize;
var dimensions;
var isDragging;
var isShowing = false;
var domSelection
function refreshNodes() {
if (!isShowing) {
return;
}
var navNode = navVis.selectAll(".red-ui-navigator-node").data(RED.view.getActiveNodes(),function(d){return d.id});
navNode.exit().remove();
navNode.enter().insert("rect")
.attr('class','red-ui-navigator-node')
.attr("pointer-events", "none");
navNode.each(function(d) {
d3.select(this).attr("x",function(d) { return (d.x-d.w/2)/nav_scale })
.attr("y",function(d) { return (d.y-d.h/2)/nav_scale })
.attr("width",function(d) { return Math.max(9,d.w/nav_scale) })
.attr("height",function(d) { return Math.max(3,d.h/nav_scale) })
.attr("fill",function(d) { return RED.utils.getNodeColor(d.type,d._def);})
});
}
function onScroll() {
if (!isDragging) {
resizeNavBorder();
}
}
function resizeNavBorder() {
if (navBorder) {
scaleFactor = RED.view.scale();
chartSize = [ $("#red-ui-workspace-chart").width(), $("#red-ui-workspace-chart").height()];
scrollPos = [$("#red-ui-workspace-chart").scrollLeft(),$("#red-ui-workspace-chart").scrollTop()];
navBorder.attr('x',scrollPos[0]/nav_scale)
.attr('y',scrollPos[1]/nav_scale)
.attr('width',chartSize[0]/nav_scale/scaleFactor)
.attr('height',chartSize[1]/nav_scale/scaleFactor)
}
}
function toggle() {
if (!isShowing) {
isShowing = true;
$("#red-ui-view-navigate").addClass("selected");
resizeNavBorder();
refreshNodes();
$("#red-ui-workspace-chart").on("scroll",onScroll);
navContainer.fadeIn(200);
} else {
isShowing = false;
navContainer.fadeOut(100);
$("#red-ui-workspace-chart").off("scroll",onScroll);
$("#red-ui-view-navigate").removeClass("selected");
}
}
function refreshNodes() {
if (!isShowing) {
return;
}
domSelection.refresh(RED.view.getActiveNodes())
}
return {
init: function() {
function onScroll() {
if (!isDragging) {
resizeNavBorder();
}
}
function resizeNavBorder() {
if (navBorder) {
scaleFactor = RED.view.scale();
chartSize = [ $("#red-ui-workspace-chart").width(), $("#red-ui-workspace-chart").height()];
scrollPos = [$("#red-ui-workspace-chart").scrollLeft(),$("#red-ui-workspace-chart").scrollTop()];
$(window).on("resize", resizeNavBorder);
RED.events.on("sidebar:resize",resizeNavBorder);
RED.actions.add("core:toggle-navigator",toggle);
var hideTimeout;
navBorder.attr('x', scrollPos[0]/nav_scale)
navBorder.attr('y', scrollPos[1]/nav_scale)
navBorder.attr('width',chartSize[0]/nav_scale/scaleFactor)
navBorder.attr('height',chartSize[1]/nav_scale/scaleFactor)
}
}
function toggle() {
if (!isShowing) {
isShowing = true;
$("#red-ui-view-navigate").addClass("selected");
resizeNavBorder();
refreshNodes();
$("#red-ui-workspace-chart").on("scroll",onScroll);
navContainer.fadeIn(200);
} else {
isShowing = false;
navContainer.fadeOut(100);
$("#red-ui-workspace-chart").off("scroll",onScroll);
$("#red-ui-view-navigate").removeClass("selected");
}
}
navContainer = $('<div>').css({
"position":"absolute",
"bottom":$("#red-ui-workspace-footer").height(),
"right":0,
zIndex: 1
}).appendTo("#red-ui-workspace").hide();
return {
init: function() {
navBox = d3.select(navContainer[0])
.append("svg:svg")
.attr("width", nav_width)
.attr("height", nav_height)
.attr("pointer-events", "all")
.attr("id","red-ui-navigator-canvas")
$(window).on("resize", resizeNavBorder);
RED.events.on("sidebar:resize",resizeNavBorder);
RED.actions.add("core:toggle-navigator",toggle);
navBox.append("rect").attr("x",0).attr("y",0).attr("width",nav_width).attr("height",nav_height).style({
fill:"none",
stroke:"none",
pointerEvents:"all"
}).on("mousedown", function() {
// Update these in case they have changed
scaleFactor = RED.view.scale();
chartSize = [ $("#red-ui-workspace-chart").width(), $("#red-ui-workspace-chart").height()];
dimensions = [chartSize[0]/nav_scale/scaleFactor, chartSize[1]/nav_scale/scaleFactor];
var newX = Math.max(0,Math.min(d3.event.offsetX+dimensions[0]/2,nav_width)-dimensions[0]);
var newY = Math.max(0,Math.min(d3.event.offsetY+dimensions[1]/2,nav_height)-dimensions[1]);
navBorder.attr('x',newX).attr('y',newY);
isDragging = true;
$("#red-ui-workspace-chart").scrollLeft(newX*nav_scale*scaleFactor);
$("#red-ui-workspace-chart").scrollTop(newY*nav_scale*scaleFactor);
}).on("mousemove", function() {
if (!isDragging) { return }
if (d3.event.buttons === 0) {
isDragging = false;
return;
}
var newX = Math.max(0,Math.min(d3.event.offsetX+dimensions[0]/2,nav_width)-dimensions[0]);
var newY = Math.max(0,Math.min(d3.event.offsetY+dimensions[1]/2,nav_height)-dimensions[1]);
navBorder.attr('x',newX).attr('y',newY);
$("#red-ui-workspace-chart").scrollLeft(newX*nav_scale*scaleFactor);
$("#red-ui-workspace-chart").scrollTop(newY*nav_scale*scaleFactor);
}).on("mouseup", function() {
isDragging = false;
})
navContainer = $('<div>').css({
"position":"absolute",
"bottom":$("#red-ui-workspace-footer").height(),
"right":0,
zIndex: 1
}).appendTo("#red-ui-workspace").hide();
navBorder = navBox.append("rect").attr("class","red-ui-navigator-border")
navBox = $(RED.utils.createSVGElement('svg', {id: "red-ui-navigator-canvas", width: nav_width, height: nav_height, 'pointer-events': 'all'})).appendTo(navContainer)
navVis = navBox.append("svg:g")
const navBoxBody = $(RED.utils.createSVGElement("rect", { x: 0, y: 0, width: nav_width, height: nav_height, fill: 'none', stroke: 'none', 'pointer-events': 'all'}))
.css({'cursor': 'pointer'})
navBoxBody.on('mousedown',function(event) {
// Update these in case they have changed
scaleFactor = RED.view.scale();
chartSize = [ $("#red-ui-workspace-chart").width(), $("#red-ui-workspace-chart").height()];
dimensions = [chartSize[0]/nav_scale/scaleFactor, chartSize[1]/nav_scale/scaleFactor];
var newX = Math.max(0,Math.min(event.offsetX+dimensions[0]/2,nav_width)-dimensions[0]);
var newY = Math.max(0,Math.min(event.offsetY+dimensions[1]/2,nav_height)-dimensions[1]);
navBorder.attr('x',newX)
navBorder.attr('y',newY);
isDragging = true;
$("#red-ui-workspace-chart").scrollLeft(newX*nav_scale*scaleFactor);
$("#red-ui-workspace-chart").scrollTop(newY*nav_scale*scaleFactor);
}).on('mousemove', function(event) {
if (!isDragging) { return }
if (event.buttons === 0) {
isDragging = false;
return;
}
var newX = Math.max(0,Math.min(event.offsetX+dimensions[0]/2,nav_width)-dimensions[0]);
var newY = Math.max(0,Math.min(event.offsetY+dimensions[1]/2,nav_height)-dimensions[1]);
navBorder.attr('x',newX)
navBorder.attr('y',newY);
$("#red-ui-workspace-chart").scrollLeft(newX*nav_scale*scaleFactor);
$("#red-ui-workspace-chart").scrollTop(newY*nav_scale*scaleFactor);
}).on('mouseup', function() {
isDragging = false;
}).appendTo(navBox)
RED.statusBar.add({
id: "view-navigator",
align: "right",
element: $('<button class="red-ui-footer-button-toggle single" id="red-ui-view-navigate"><i class="fa fa-map-o"></i></button>')
})
navBorder = $(RED.utils.createSVGElement("rect", { "class": "red-ui-navigator-border" })).appendTo(navBox)
const navVis = $(RED.utils.createSVGElement('g')).appendTo(navBox)
domSelection = RED.utils.domSelection(navVis[0], '.red-ui-navigator-node', function() {
return RED.utils.createSVGElement('rect', { class: 'red-ui-navigator-node', 'pointer-events': 'none' })
}, function(node) {
node.setAttribute('x', (this.x-this.w/2)/nav_scale)
node.setAttribute('y', (this.y-this.h/2)/nav_scale)
node.setAttribute('width', Math.max(9,this.w/nav_scale))
node.setAttribute('height', Math.max(3,this.h/nav_scale))
node.setAttribute('fill', RED.utils.getNodeColor(this.type,this._def))
})
RED.statusBar.add({
id: "view-navigator",
align: "right",
element: $('<button class="red-ui-footer-button-toggle single" id="red-ui-view-navigate"><i class="fa fa-map-o"></i></button>')
})
$("#red-ui-view-navigate").on("click", function(evt) {
evt.preventDefault();

View File

@@ -15,7 +15,7 @@
**/
RED.view.tools = (function() {
'use strict';
function selectConnected(type) {
var selection = RED.view.selection();
var visited = new Set();
@@ -39,9 +39,6 @@ RED.view.tools = (function() {
}
function alignToGrid() {
if (RED.workspaces.isActiveLocked()) {
return
}
var selection = RED.view.selection();
if (selection.nodes) {
var changedNodes = [];
@@ -90,9 +87,6 @@ RED.view.tools = (function() {
}
function moveSelection(dx,dy) {
if (RED.workspaces.isActiveLocked()) {
return
}
if (moving_set === null) {
moving_set = [];
var selection = RED.view.selection();
@@ -159,9 +153,6 @@ RED.view.tools = (function() {
}
function setSelectedNodeLabelState(labelShown) {
if (RED.workspaces.isActiveLocked()) {
return
}
var selection = RED.view.selection();
var historyEvents = [];
var nodes = [];
@@ -448,9 +439,6 @@ RED.view.tools = (function() {
}
function alignSelectionToEdge(direction) {
// if (RED.workspaces.isActiveLocked()) {
// return
// }
var selection = RED.view.selection();
if (selection.nodes && selection.nodes.length > 1) {
@@ -551,10 +539,8 @@ RED.view.tools = (function() {
}
}
function distributeSelection(direction) {
if (RED.workspaces.isActiveLocked()) {
return
}
var selection = RED.view.selection();
if (selection.nodes && selection.nodes.length > 2) {
@@ -713,9 +699,6 @@ RED.view.tools = (function() {
}
function reorderSelection(dir) {
if (RED.workspaces.isActiveLocked()) {
return
}
var selection = RED.view.selection();
if (selection.nodes) {
var nodesToMove = [];
@@ -751,10 +734,8 @@ RED.view.tools = (function() {
}
}
function wireSeriesOfNodes() {
if (RED.workspaces.isActiveLocked()) {
return
}
var selection = RED.view.selection();
if (selection.nodes) {
if (selection.nodes.length > 1) {
@@ -795,9 +776,6 @@ RED.view.tools = (function() {
}
function wireNodeToMultiple() {
if (RED.workspaces.isActiveLocked()) {
return
}
var selection = RED.view.selection();
if (selection.nodes) {
if (selection.nodes.length > 1) {
@@ -845,9 +823,6 @@ RED.view.tools = (function() {
* @param {Object || Object[]} wires The wire(s) to split and replace with link-out, link-in nodes.
*/
function splitWiresWithLinkNodes(wires) {
if (RED.workspaces.isActiveLocked()) {
return
}
let wiresToSplit = wires || (RED.view.selection().links && RED.view.selection().links.filter(e => !e.link));
if (!wiresToSplit) {
return
@@ -902,6 +877,7 @@ RED.view.tools = (function() {
if(!nnLinkOut) {
const nLinkOut = RED.view.createNode("link out"); //create link node
nnLinkOut = nLinkOut.node;
nodeSrcMap[linkOutMapId] = nnLinkOut;
let yOffset = 0;
if(nSrc.outputs > 1) {
@@ -916,8 +892,7 @@ RED.view.tools = (function() {
updateNewNodePosXY(nSrc, nnLinkOut, false, RED.view.snapGrid, yOffset);
}
//add created node
nnLinkOut = RED.nodes.add(nnLinkOut);
nodeSrcMap[linkOutMapId] = nnLinkOut;
RED.nodes.add(nnLinkOut);
RED.editor.validateNode(nnLinkOut);
history.events.push(nLinkOut.historyEvent);
//connect node to link node
@@ -938,10 +913,10 @@ RED.view.tools = (function() {
if(!nnLinkIn) {
const nLinkIn = RED.view.createNode("link in"); //create link node
nnLinkIn = nLinkIn.node;
nodeTrgMap[nTrg.id] = nnLinkIn;
updateNewNodePosXY(nTrg, nnLinkIn, true, RED.view.snapGrid, 0);
//add created node
nnLinkIn = RED.nodes.add(nnLinkIn);
nodeTrgMap[nTrg.id] = nnLinkIn;
RED.nodes.add(nnLinkIn);
RED.editor.validateNode(nnLinkIn);
history.events.push(nLinkIn.historyEvent);
//connect node to link node
@@ -1016,9 +991,6 @@ RED.view.tools = (function() {
* @param {{ renameBlank: boolean, renameClash: boolean, generateHistory: boolean }} options Possible options are `renameBlank`, `renameClash` and `generateHistory`
*/
function generateNodeNames(node, options) {
if (RED.workspaces.isActiveLocked()) {
return
}
options = Object.assign({
renameBlank: true,
renameClash: true,
@@ -1043,7 +1015,7 @@ RED.view.tools = (function() {
const nodeDef = n._def || RED.nodes.getType(n.type)
if (nodeDef && nodeDef.defaults && nodeDef.defaults.name) {
const paletteLabel = RED.utils.getPaletteLabel(n.type, nodeDef)
const defaultNodeNameRE = new RegExp('^'+paletteLabel.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')+' (\\d+)$')
const defaultNodeNameRE = new RegExp('^'+paletteLabel+' (\\d+)$')
if (!typeIndex.hasOwnProperty(n.type)) {
const existingNodes = RED.nodes.filterNodes({type: n.type})
let maxNameNumber = 0;
@@ -1089,9 +1061,6 @@ RED.view.tools = (function() {
}
function addJunctionsToWires(wires) {
if (RED.workspaces.isActiveLocked()) {
return
}
let wiresToSplit = wires || (RED.view.selection().links && RED.view.selection().links.filter(e => !e.link));
if (!wiresToSplit) {
return
@@ -1162,7 +1131,7 @@ RED.view.tools = (function() {
var nodeGroups = new Set()
junction = RED.nodes.addJunction(junction)
RED.nodes.addJunction(junction)
addedJunctions.push(junction)
let newLink
if (gid === links[0].source.id+":"+links[0].sourcePort) {
@@ -1223,30 +1192,6 @@ RED.view.tools = (function() {
RED.view.redraw(true);
}
function copyItemUrl(node, isEdit) {
if (!node) {
const selection = RED.view.selection();
if (selection.nodes && selection.nodes.length > 0) {
node = selection.nodes[0]
}
}
if (node) {
let thingType = 'node'
if (node.type === 'group') {
thingType = 'group'
} else if (node.type === 'tab' || node.type === 'subflow') {
thingType = 'flow'
}
let url = `${window.location.origin}${window.location.pathname}#${thingType}/${node.id}`
if (isEdit) {
url += '/edit'
}
if (RED.clipboard.copyText(url)) {
RED.notify(RED._("sidebar.info.copyURL2Clipboard"), { timeout: 2000 })
}
}
}
return {
init: function() {
RED.actions.add("core:show-selected-node-labels", function() { setSelectedNodeLabelState(true); })
@@ -1313,9 +1258,6 @@ RED.view.tools = (function() {
RED.actions.add("core:generate-node-names", generateNodeNames )
RED.actions.add("core:copy-item-url", function (node) { copyItemUrl(node) })
RED.actions.add("core:copy-item-edit-url", function (node) { copyItemUrl(node, true) })
// RED.actions.add("core:add-node", function() { addNode() })
},
/**

549
packages/node_modules/@node-red/editor-client/src/js/ui/view.js vendored Normal file → Executable file
View File

@@ -54,7 +54,6 @@ RED.view = (function() {
var spliceTimer;
var groupHoverTimer;
var activeFlowLocked = false;
var activeSubflow = null;
var activeNodes = [];
var activeLinks = [];
@@ -212,7 +211,6 @@ RED.view = (function() {
evt.preventDefault()
evt.stopPropagation()
RED.contextMenu.show({
type: 'workspace',
x:evt.clientX-5,
y:evt.clientY-5
})
@@ -296,25 +294,13 @@ RED.view = (function() {
]
startTouchDistance = Math.sqrt((a*a)+(b*b));
} else {
var obj = d3.select(document.body);
touch0 = d3.event.touches.item(0);
var pos = [touch0.pageX,touch0.pageY];
startTouchCenter = [touch0.pageX,touch0.pageY];
startTouchDistance = 0;
var point = d3.touches(this)[0];
touchStartTime = setTimeout(function() {
touchStartTime = null;
showTouchMenu(obj,pos);
//lasso = eventLayer.append("rect")
// .attr("ox",point[0])
// .attr("oy",point[1])
// .attr("rx",2)
// .attr("ry",2)
// .attr("x",point[0])
// .attr("y",point[1])
// .attr("width",0)
// .attr("height",0)
// .attr("class","nr-ui-view-lasso");
showTouchMenu(document.body,pos);
},touchLongPressTimeout);
}
d3.event.preventDefault();
@@ -412,19 +398,8 @@ RED.view = (function() {
activeSubflow = RED.nodes.subflow(event.workspace);
if (activeSubflow) {
activeFlowLocked = activeSubflow.locked
} else {
var activeWorkspace = RED.nodes.workspace(event.workspace)
if (activeWorkspace) {
activeFlowLocked = activeWorkspace.locked
} else {
activeFlowLocked = true
}
}
RED.menu.setDisabled("menu-item-workspace-edit", activeFlowLocked || activeSubflow || event.workspace === 0);
RED.menu.setDisabled("menu-item-workspace-delete",activeFlowLocked || event.workspace === 0 || RED.workspaces.count() == 1 || activeSubflow);
RED.menu.setDisabled("menu-item-workspace-edit", activeSubflow || event.workspace === 0);
RED.menu.setDisabled("menu-item-workspace-delete",event.workspace === 0 || RED.workspaces.count() == 1 || activeSubflow);
if (workspaceScrollPositions[event.workspace]) {
chart.scrollLeft(workspaceScrollPositions[event.workspace].left);
@@ -451,15 +426,6 @@ RED.view = (function() {
redraw();
});
RED.events.on("flows:change", function(workspace) {
if (workspace.id === RED.workspaces.active()) {
activeFlowLocked = !!workspace.locked
$("#red-ui-workspace").toggleClass("red-ui-workspace-disabled",!!workspace.disabled);
$("#red-ui-workspace").toggleClass("red-ui-workspace-locked",!!workspace.locked);
}
})
RED.statusBar.add({
id: "view-zoom-controls",
align: "right",
@@ -517,9 +483,6 @@ RED.view = (function() {
chart.droppable({
accept:".red-ui-palette-node",
drop: function( event, ui ) {
if (activeFlowLocked) {
return
}
d3.event = event;
var selected_tool = $(ui.draggable[0]).attr("data-palette-type");
var result = createNode(selected_tool);
@@ -527,7 +490,9 @@ RED.view = (function() {
return;
}
var historyEvent = result.historyEvent;
var nn = RED.nodes.add(result.node);
var nn = result.node;
RED.nodes.add(nn);
var showLabel = RED.utils.getMessageProperty(RED.settings.get('editor'),"view.view-node-show-label");
if (showLabel !== undefined && (nn._def.hasOwnProperty("showLabel")?nn._def.showLabel:true) && !nn._def.defaults.hasOwnProperty("l")) {
@@ -654,9 +619,6 @@ RED.view = (function() {
RED.actions.add("core:copy-selection-to-internal-clipboard",copySelection);
RED.actions.add("core:cut-selection-to-internal-clipboard",function(){copySelection(true);deleteSelection();});
RED.actions.add("core:paste-from-internal-clipboard",function(){
if (RED.workspaces.isActiveLocked()) {
return
}
importNodes(clipboard,{generateIds: clipboardSource === 'copy', generateDefaultNames: clipboardSource === 'copy'});
});
@@ -665,27 +627,22 @@ RED.view = (function() {
RED.events.on("view:selection-changed", function(selection) {
var hasSelection = (selection.nodes && selection.nodes.length > 0);
var hasMultipleSelection = hasSelection && selection.nodes.length > 1;
var hasLinkSelected = selection.links && selection.links.length > 0;
var canEdit = !activeFlowLocked && hasSelection
var canEditMultiple = !activeFlowLocked && hasMultipleSelection
RED.menu.setDisabled("menu-item-edit-cut", !canEdit);
RED.menu.setDisabled("menu-item-edit-copy", !hasSelection);
RED.menu.setDisabled("menu-item-edit-select-connected", !hasSelection);
RED.menu.setDisabled("menu-item-view-tools-move-to-back", !canEdit);
RED.menu.setDisabled("menu-item-view-tools-move-to-front", !canEdit);
RED.menu.setDisabled("menu-item-view-tools-move-backwards", !canEdit);
RED.menu.setDisabled("menu-item-view-tools-move-forwards", !canEdit);
RED.menu.setDisabled("menu-item-edit-cut",!hasSelection);
RED.menu.setDisabled("menu-item-edit-copy",!hasSelection);
RED.menu.setDisabled("menu-item-edit-select-connected",!hasSelection);
RED.menu.setDisabled("menu-item-view-tools-move-to-back",!hasSelection);
RED.menu.setDisabled("menu-item-view-tools-move-to-front",!hasSelection);
RED.menu.setDisabled("menu-item-view-tools-move-backwards",!hasSelection);
RED.menu.setDisabled("menu-item-view-tools-move-forwards",!hasSelection);
RED.menu.setDisabled("menu-item-view-tools-align-left", !canEditMultiple);
RED.menu.setDisabled("menu-item-view-tools-align-center", !canEditMultiple);
RED.menu.setDisabled("menu-item-view-tools-align-right", !canEditMultiple);
RED.menu.setDisabled("menu-item-view-tools-align-top", !canEditMultiple);
RED.menu.setDisabled("menu-item-view-tools-align-middle", !canEditMultiple);
RED.menu.setDisabled("menu-item-view-tools-align-bottom", !canEditMultiple);
RED.menu.setDisabled("menu-item-view-tools-distribute-horizontally", !canEditMultiple);
RED.menu.setDisabled("menu-item-view-tools-distribute-veritcally", !canEditMultiple);
RED.menu.setDisabled("menu-item-edit-split-wire-with-links", activeFlowLocked || !hasLinkSelected);
RED.menu.setDisabled("menu-item-view-tools-align-left",!hasMultipleSelection);
RED.menu.setDisabled("menu-item-view-tools-align-center",!hasMultipleSelection);
RED.menu.setDisabled("menu-item-view-tools-align-right",!hasMultipleSelection);
RED.menu.setDisabled("menu-item-view-tools-align-top",!hasMultipleSelection);
RED.menu.setDisabled("menu-item-view-tools-align-middle",!hasMultipleSelection);
RED.menu.setDisabled("menu-item-view-tools-align-bottom",!hasMultipleSelection);
RED.menu.setDisabled("menu-item-view-tools-distribute-horizontally",!hasMultipleSelection);
RED.menu.setDisabled("menu-item-view-tools-distribute-veritcally",!hasMultipleSelection);
})
RED.actions.add("core:delete-selection",deleteSelection);
@@ -743,11 +700,11 @@ RED.view = (function() {
type: "badge",
class: "red-ui-flow-node-changed",
element: function() {
var changeBadge = document.createElementNS("http://www.w3.org/2000/svg","circle");
changeBadge.setAttribute("cx",5);
changeBadge.setAttribute("cy",5);
changeBadge.setAttribute("r",5);
return changeBadge;
return RED.utils.createSVGElement("circle", {
cx: 5,
cy: 5,
r: 5
})
},
show: function(n) { return n.changed||n.moved }
})
@@ -756,9 +713,9 @@ RED.view = (function() {
type: "badge",
class: "red-ui-flow-node-error",
element: function(d) {
var errorBadge = document.createElementNS("http://www.w3.org/2000/svg","path");
errorBadge.setAttribute("d","M 0,9 l 10,0 -5,-8 z");
return errorBadge
return RED.utils.createSVGElement("path", {
d: "M 0,9 l 10,0 -5,-8 z"
})
},
tooltip: function(d) {
if (d.validationErrors && d.validationErrors.length > 0) {
@@ -1075,7 +1032,7 @@ RED.view = (function() {
.attr("class", "nr-ui-view-lasso");
d3.event.preventDefault();
}
} else if (d3.event.altKey && !activeFlowLocked) {
} else if (d3.event.altKey) {
//Alt [+shift] held - Begin slicing
clearSelection();
mouse_mode = (d3.event.shiftKey) ? RED.state.SLICING_JUNCTION : RED.state.SLICING;
@@ -1089,9 +1046,6 @@ RED.view = (function() {
}
function showQuickAddDialog(options) {
if (activeFlowLocked) {
return
}
options = options || {};
var point = options.position || lastClickPosition;
var spliceLink = options.splice;
@@ -1105,15 +1059,12 @@ RED.view = (function() {
RED.view.redraw();
}
// `point` is the place in the workspace the mouse has clicked.
// This takes into account scrolling and scaling of the workspace.
var ox = point[0];
var oy = point[1];
// Need to map that to browser location to position the pop-up
const offset = $("#red-ui-workspace-chart").offset()
var clientX = (ox * scaleFactor) + offset.left - $("#red-ui-workspace-chart").scrollLeft()
var clientY = (oy * scaleFactor) + offset.top - $("#red-ui-workspace-chart").scrollTop()
var clientX = ox + offset.left - $("#red-ui-workspace-chart").scrollLeft()
var clientY = oy + offset.top - $("#red-ui-workspace-chart").scrollTop()
if (RED.settings.get("editor").view['view-snap-grid']) {
// eventLayer.append("circle").attr("cx",point[0]).attr("cy",point[1]).attr("r","2").attr('fill','red')
@@ -1274,11 +1225,6 @@ RED.view = (function() {
if (showLabel !== undefined && (nn._def.hasOwnProperty("showLabel")?nn._def.showLabel:true) && !nn._def.defaults.hasOwnProperty("l")) {
nn.l = showLabel;
}
if (nn.type === 'junction') {
nn = RED.nodes.addJunction(nn);
} else {
nn = RED.nodes.add(nn);
}
if (quickAddLink) {
var drag_line = quickAddLink;
var src = null,dst,src_port;
@@ -1381,7 +1327,11 @@ RED.view = (function() {
}
}
}
if (nn.type === 'junction') {
RED.nodes.addJunction(nn);
} else {
RED.nodes.add(nn);
}
RED.editor.validateNode(nn);
if (targetGroup) {
@@ -1639,18 +1589,16 @@ RED.view = (function() {
}
var d = (mouse_offset[0]-mousePos[0])*(mouse_offset[0]-mousePos[0]) + (mouse_offset[1]-mousePos[1])*(mouse_offset[1]-mousePos[1]);
if ((d > 3 && !dblClickPrimed) || (dblClickPrimed && d > 10)) {
mouse_mode = RED.state.MOVING_ACTIVE;
clickElapsed = 0;
if (!activeFlowLocked) {
mouse_mode = RED.state.MOVING_ACTIVE;
spliceActive = false;
if (movingSet.length() === 1) {
node = movingSet.get(0);
spliceActive = node.n.hasOwnProperty("_def") &&
((node.n.hasOwnProperty("inputs") && node.n.inputs > 0) || (!node.n.hasOwnProperty("inputs") && node.n._def.inputs > 0)) &&
((node.n.hasOwnProperty("outputs") && node.n.outputs > 0) || (!node.n.hasOwnProperty("outputs") && node.n._def.outputs > 0)) &&
RED.nodes.filterLinks({ source: node.n }).length === 0 &&
RED.nodes.filterLinks({ target: node.n }).length === 0;
}
spliceActive = false;
if (movingSet.length() === 1) {
node = movingSet.get(0);
spliceActive = node.n.hasOwnProperty("_def") &&
((node.n.hasOwnProperty("inputs") && node.n.inputs > 0) || (!node.n.hasOwnProperty("inputs") && node.n._def.inputs > 0)) &&
((node.n.hasOwnProperty("outputs") && node.n.outputs > 0) || (!node.n.hasOwnProperty("outputs") && node.n._def.outputs > 0)) &&
RED.nodes.filterLinks({ source: node.n }).length === 0 &&
RED.nodes.filterLinks({ target: node.n }).length === 0;
}
}
} else if (mouse_mode == RED.state.MOVING_ACTIVE || mouse_mode == RED.state.IMPORT_DRAGGING || mouse_mode == RED.state.DETACHED_DRAGGING) {
@@ -2495,7 +2443,6 @@ RED.view = (function() {
}
function editSelection() {
if (RED.workspaces.isActiveLocked()) { return }
if (movingSet.length() > 0) {
var node = movingSet.get(0).n;
if (node.type === "subflow") {
@@ -2511,9 +2458,6 @@ RED.view = (function() {
if (mouse_mode === RED.state.SELECTING_NODE) {
return;
}
if (activeFlowLocked) {
return
}
if (portLabelHover) {
portLabelHover.remove();
portLabelHover = null;
@@ -2829,7 +2773,6 @@ RED.view = (function() {
function detachSelectedNodes() {
if (RED.workspaces.isActiveLocked()) { return }
var selection = RED.view.selection();
if (selection.nodes) {
const {newLinks, removedLinks} = RED.nodes.detachNodes(selection.nodes);
@@ -2971,7 +2914,7 @@ RED.view = (function() {
mousedown_node = d;
mousedown_port_type = portType;
mousedown_port_index = portIndex || 0;
if (mouse_mode !== RED.state.QUICK_JOINING && !activeFlowLocked) {
if (mouse_mode !== RED.state.QUICK_JOINING) {
mouse_mode = RED.state.JOINING;
document.body.style.cursor = "crosshair";
if (evt.ctrlKey || evt.metaKey) {
@@ -3411,14 +3354,6 @@ RED.view = (function() {
}
if (dblClickPrimed && mousedown_node == d && clickElapsed > 0 && clickElapsed < dblClickInterval) {
mouse_mode = RED.state.DEFAULT;
if (RED.workspaces.isActiveLocked()) {
clickElapsed = 0;
d3.event.stopPropagation();
return
}
// Avoid dbl click causing text selection.
d3.event.preventDefault()
document.getSelection().removeAllRanges()
if (d.type != "subflow") {
if (/^subflow:/.test(d.type) && (d3.event.ctrlKey || d3.event.metaKey)) {
RED.workspaces.show(d.type.substring(8));
@@ -3742,6 +3677,7 @@ RED.view = (function() {
}
// selectedLinks.clear();
if (d3.event.button != 2) {
mouse_mode = RED.state.MOVING;
var mouse = d3.touches(this)[0]||d3.mouse(this);
mouse[0] += d.x-d.w/2;
mouse[1] += d.y-d.h/2;
@@ -3755,13 +3691,12 @@ RED.view = (function() {
}
function nodeTouchStart(d) {
if (RED.view.DEBUG) { console.warn("nodeTouchStart", mouse_mode,d); }
var obj = d3.select(this);
var touch0 = d3.event.touches.item(0);
var pos = [touch0.pageX,touch0.pageY];
startTouchCenter = [touch0.pageX,touch0.pageY];
startTouchDistance = 0;
touchStartTime = setTimeout(function() {
showTouchMenu(obj,pos);
showTouchMenu(this,pos);
},touchLongPressTimeout);
nodeMouseDown.call(this,d)
d3.event.preventDefault();
@@ -3920,12 +3855,11 @@ RED.view = (function() {
focusView();
d3.event.stopPropagation();
var obj = d3.select(document.body);
var touch0 = d3.event.touches.item(0);
var pos = [touch0.pageX,touch0.pageY];
touchStartTime = setTimeout(function() {
touchStartTime = null;
showTouchMenu(obj,pos);
showTouchMenu(document.body,pos);
},touchLongPressTimeout);
d3.event.preventDefault();
}
@@ -3934,7 +3868,6 @@ RED.view = (function() {
if (RED.view.DEBUG) {
console.warn("groupMouseUp", { mouse_mode, event: d3.event });
}
if (RED.workspaces.isActiveLocked()) { return }
if (dblClickPrimed && mousedown_group == g && clickElapsed > 0 && clickElapsed < dblClickInterval) {
mouse_mode = RED.state.DEFAULT;
RED.editor.editGroup(g);
@@ -4105,7 +4038,7 @@ RED.view = (function() {
function isButtonEnabled(d) {
var buttonEnabled = true;
var ws = RED.nodes.workspace(RED.workspaces.active());
if (ws && !ws.disabled && !d.d && !ws.locked) {
if (ws && !ws.disabled && !d.d) {
if (d._def.button.hasOwnProperty('enabled')) {
if (typeof d._def.button.enabled === "function") {
buttonEnabled = d._def.button.enabled.call(d);
@@ -4128,7 +4061,7 @@ RED.view = (function() {
}
var activeWorkspace = RED.workspaces.active();
var ws = RED.nodes.workspace(activeWorkspace);
if (ws && !ws.disabled && !d.d && !ws.locked) {
if (ws && !ws.disabled && !d.d) {
if (d._def.button.toggle) {
d[d._def.button.toggle] = !d[d._def.button.toggle];
d.dirty = true;
@@ -4143,7 +4076,7 @@ RED.view = (function() {
if (d.dirty) {
redraw();
}
} else if (!ws || !ws.locked){
} else {
if (activeSubflow) {
RED.notify(RED._("notification.warning", {message:RED._("notification.warnings.nodeActionDisabledSubflow")}),"warning");
} else {
@@ -4158,15 +4091,14 @@ RED.view = (function() {
function showTouchMenu(obj,pos) {
var mdn = mousedown_node;
var options = [];
const isActiveLocked = RED.workspaces.isActiveLocked()
options.push({name:"delete",disabled:(isActiveLocked || movingSet.length()===0 && selectedLinks.length() === 0),onselect:function() {deleteSelection();}});
options.push({name:"cut",disabled:(isActiveLocked || movingSet.length()===0),onselect:function() {copySelection(true);deleteSelection();}});
options.push({name:"copy",disabled:(isActiveLocked || movingSet.length()===0),onselect:function() {copySelection();}});
options.push({name:"paste",disabled:(isActiveLocked || clipboard.length===0),onselect:function() {importNodes(clipboard, {generateIds: true, touchImport: true});}});
options.push({name:"edit",disabled:(isActiveLocked || movingSet.length() != 1),onselect:function() { RED.editor.edit(mdn);}});
options.push({name:"delete",disabled:(movingSet.length()===0 && selectedLinks.length() === 0),onselect:function() {deleteSelection();}});
options.push({name:"cut",disabled:(movingSet.length()===0),onselect:function() {copySelection(true);deleteSelection();}});
options.push({name:"copy",disabled:(movingSet.length()===0),onselect:function() {copySelection();}});
options.push({name:"paste",disabled:(clipboard.length===0),onselect:function() {importNodes(clipboard, {generateIds: true, touchImport: true});}});
options.push({name:"edit",disabled:(movingSet.length() != 1),onselect:function() { RED.editor.edit(mdn);}});
options.push({name:"select",onselect:function() {selectAll();}});
options.push({name:"undo",disabled:(RED.history.depth() === 0),onselect:function() {RED.history.pop();}});
options.push({name:"add",disabled:isActiveLocked, onselect:function() {
options.push({name:"add",onselect:function() {
chartPos = chart.offset();
showQuickAddDialog({
position:[pos[0]-chartPos.left+chart.scrollLeft(),pos[1]-chartPos.top+chart.scrollTop()],
@@ -4301,13 +4233,14 @@ RED.view = (function() {
d.resize = true;
d.dirty = true;
var mainRect = document.createElementNS("http://www.w3.org/2000/svg","rect");
var mainRect = RED.utils.createSVGElement("rect", {
class: "red-ui-flow-subflow-port",
rx: 8,
ry: 8,
width: 40,
height: 40,
})
mainRect.__data__ = d;
mainRect.setAttribute("class", "red-ui-flow-subflow-port");
mainRect.setAttribute("rx", 8);
mainRect.setAttribute("ry", 8);
mainRect.setAttribute("width", 40);
mainRect.setAttribute("height", 40);
node[0][0].__mainRect__ = mainRect;
d3.select(mainRect)
.on("mouseup",nodeMouseUp)
@@ -4316,50 +4249,50 @@ RED.view = (function() {
.on("touchend",nodeTouchEnd)
nodeContents.appendChild(mainRect);
var output_groupEl = document.createElementNS("http://www.w3.org/2000/svg","g");
output_groupEl.setAttribute("x",0);
output_groupEl.setAttribute("y",0);
var output_groupEl = RED.utils.createSVGElement("g", { x: 0, y: 0 })
node[0][0].__outputLabelGroup__ = output_groupEl;
var output_output = document.createElementNS("http://www.w3.org/2000/svg","text");
output_output.setAttribute("class","red-ui-flow-port-label");
var output_output = RED.utils.createSVGElement("text", { class: "red-ui-flow-port-label" })
output_output.style["font-size"] = "10px";
output_output.textContent = "output";
output_groupEl.appendChild(output_output);
node[0][0].__outputOutput__ = output_output;
var output_number = document.createElementNS("http://www.w3.org/2000/svg","text");
output_number.setAttribute("class","red-ui-flow-port-label red-ui-flow-port-index");
output_number.setAttribute("x",0);
output_number.setAttribute("y",0);
var output_number = RED.utils.createSVGElement("text", {
class: "red-ui-flow-port-label red-ui-flow-port-index",
x: 0,
y: 0
})
output_number.textContent = d.i+1;
output_groupEl.appendChild(output_number);
node[0][0].__outputNumber__ = output_number;
var output_border = document.createElementNS("http://www.w3.org/2000/svg","path");
output_border.setAttribute("d","M 40 1 l 0 38")
output_border.setAttribute("class", "red-ui-flow-node-icon-shade-border")
var output_border = RED.utils.createSVGElement("path", {
d: "M 40 1 l 0 38",
class: "red-ui-flow-node-icon-shade-border"
})
output_groupEl.appendChild(output_border);
node[0][0].__outputBorder__ = output_border;
nodeContents.appendChild(output_groupEl);
var text = document.createElementNS("http://www.w3.org/2000/svg","g");
text.setAttribute("class","red-ui-flow-port-label");
text.setAttribute("transform","translate(38,0)");
text.setAttribute('style', 'fill : #888'); // hard coded here!
var text = RED.utils.createSVGElement("g", {
class: "red-ui-flow-port-label",
transform: "translate(38,0)",
style: 'fill : #888' // hard coded here!
})
node[0][0].__textGroup__ = text;
nodeContents.append(text);
var portEl = document.createElementNS("http://www.w3.org/2000/svg","g");
portEl.setAttribute('transform','translate(-5,15)')
var portEl = RED.utils.createSVGElement("g", { transform: 'translate(-5,15)'})
var port = document.createElementNS("http://www.w3.org/2000/svg","rect");
port.setAttribute("class","red-ui-flow-port");
port.setAttribute("rx",3);
port.setAttribute("ry",3);
port.setAttribute("width",10);
port.setAttribute("height",10);
var port = RED.utils.createSVGElement("rect", {
class: "red-ui-flow-port",
rx: 3,
ry: 3,
width: 10,
height: 10
})
portEl.appendChild(port);
port.__data__ = d;
@@ -4488,10 +4421,11 @@ RED.view = (function() {
}
for (var i=0; i<sn; i++) {
if (i===textLines.length) {
var line = document.createElementNS("http://www.w3.org/2000/svg","text");
line.setAttribute("class","red-ui-flow-node-label-text");
line.setAttribute("x",0);
line.setAttribute("y",i*24);
var line = RED.utils.createSVGElement("text", {
class: "red-ui-flow-node-label-text",
x: 0,
y: i*24
});
this.__textGroup__.appendChild(line);
}
textLines[i].textContent = sa[i];
@@ -4561,32 +4495,35 @@ RED.view = (function() {
d.resize = true;
if (d._def.button) {
var buttonGroup = document.createElementNS("http://www.w3.org/2000/svg","g");
var buttonGroup = RED.utils.createSVGElement("g", {
class: "red-ui-flow-node-button",
transform: "translate("+((d._def.align == "right") ? 94 : -25)+",2)"
})
buttonGroup.__data__ = d;
buttonGroup.setAttribute("transform", "translate("+((d._def.align == "right") ? 94 : -25)+",2)");
buttonGroup.setAttribute("class","red-ui-flow-node-button");
node[0][0].__buttonGroup__ = buttonGroup;
var bgBackground = document.createElementNS("http://www.w3.org/2000/svg","rect");
var bgBackground = RED.utils.createSVGElement("rect", {
class: "red-ui-flow-node-button-background",
rx: 5,
ry: 5,
width: 32,
height: node_height-4
})
bgBackground.__data__ = d;
bgBackground.setAttribute("class","red-ui-flow-node-button-background");
bgBackground.setAttribute("rx",5);
bgBackground.setAttribute("ry",5);
bgBackground.setAttribute("width",32);
bgBackground.setAttribute("height",node_height-4);
buttonGroup.appendChild(bgBackground);
node[0][0].__buttonGroupBackground__ = bgBackground;
var bgButton = document.createElementNS("http://www.w3.org/2000/svg","rect");
var bgButton = RED.utils.createSVGElement("rect", {
class: "red-ui-flow-node-button-button",
x: d._def.align == "right"? 11:5,
y: 4,
rx: 4,
ry: 4,
width: 16,
height: node_height-12,
fill: RED.utils.getNodeColor(d.type,d._def)
})
bgButton.__data__ = d;
bgButton.setAttribute("class","red-ui-flow-node-button-button");
bgButton.setAttribute("x", d._def.align == "right"? 11:5);
bgButton.setAttribute("y",4);
bgButton.setAttribute("rx",4);
bgButton.setAttribute("ry",4);
bgButton.setAttribute("width",16);
bgButton.setAttribute("height",node_height-12);
bgButton.setAttribute("fill", RED.utils.getNodeColor(d.type,d._def));
d3.select(bgButton)
.on("mousedown",function(d) {if (!lasso && isButtonEnabled(d)) {focusView();d3.select(this).attr("fill-opacity",0.2);d3.event.preventDefault(); d3.event.stopPropagation();}})
.on("mouseup",function(d) {if (!lasso && isButtonEnabled(d)) { d3.select(this).attr("fill-opacity",0.4);d3.event.preventDefault();d3.event.stopPropagation();}})
@@ -4607,12 +4544,13 @@ RED.view = (function() {
}
var mainRect = document.createElementNS("http://www.w3.org/2000/svg","rect");
var mainRect = RED.utils.createSVGElement("rect", {
class: "red-ui-flow-node "+(d.type == "unknown"?"red-ui-flow-node-unknown":""),
rx: 5,
ry: 5,
fill: RED.utils.getNodeColor(d.type,d._def)
})
mainRect.__data__ = d;
mainRect.setAttribute("class", "red-ui-flow-node "+(d.type == "unknown"?"red-ui-flow-node-unknown":""));
mainRect.setAttribute("rx", 5);
mainRect.setAttribute("ry", 5);
mainRect.setAttribute("fill", RED.utils.getNodeColor(d.type,d._def));
node[0][0].__mainRect__ = mainRect;
d3.select(mainRect)
.on("mouseup",nodeMouseUp)
@@ -4627,61 +4565,65 @@ RED.view = (function() {
if (d._def.icon) {
var icon_url = RED.utils.getNodeIcon(d._def,d);
var icon_groupEl = document.createElementNS("http://www.w3.org/2000/svg","g");
icon_groupEl.__data__ = d;
icon_groupEl.setAttribute("class","red-ui-flow-node-icon-group"+("right" == d._def.align?" red-ui-flow-node-icon-group-right":""));
icon_groupEl.setAttribute("x",0);
icon_groupEl.setAttribute("y",0);
var icon_groupEl = RED.utils.createSVGElement("g", {
class: "red-ui-flow-node-icon-group"+("right" == d._def.align?" red-ui-flow-node-icon-group-right":""),
x: 0,
y: 0
})
icon_groupEl.style["pointer-events"] = "none";
icon_groupEl.__data__ = d;
node[0][0].__iconGroup__ = icon_groupEl;
var icon_shade = document.createElementNS("http://www.w3.org/2000/svg","path");
icon_shade.setAttribute("x",0);
icon_shade.setAttribute("y",0);
icon_shade.setAttribute("class","red-ui-flow-node-icon-shade")
var icon_shade = RED.utils.createSVGElement("path", {
x: 0,
y: 0,
class: "red-ui-flow-node-icon-shade"
})
icon_groupEl.appendChild(icon_shade);
node[0][0].__iconShade__ = icon_shade;
var icon_group = d3.select(icon_groupEl)
createIconAttributes(icon_url, icon_group, d);
var icon_shade_border = document.createElementNS("http://www.w3.org/2000/svg","path");
icon_shade_border.setAttribute("d","right" != d._def.align ? "M 30 1 l 0 "+(d.h-2) : "M 0 1 l 0 "+(d.h-2) )
icon_shade_border.setAttribute("class", "red-ui-flow-node-icon-shade-border")
var icon_shade_border = RED.utils.createSVGElement("path", {
d: "right" != d._def.align ? "M 30 1 l 0 "+(d.h-2) : "M 0 1 l 0 "+(d.h-2),
class: "red-ui-flow-node-icon-shade-border"
})
icon_groupEl.appendChild(icon_shade_border);
node[0][0].__iconShadeBorder__ = icon_shade_border;
nodeContents.appendChild(icon_groupEl);
}
var text = document.createElementNS("http://www.w3.org/2000/svg","g");
text.setAttribute("class","red-ui-flow-node-label"+(hideLabel?" hide":"")+(d._def.align?" red-ui-flow-node-label-"+d._def.align:""));
text.setAttribute("transform","translate(38,0)");
// text.setAttribute("dy", ".3px");
// text.setAttribute("text-anchor",d._def.align !== "right" ? "start":"end");
var text = RED.utils.createSVGElement("g", {
class: "red-ui-flow-node-label"+(hideLabel?" hide":"")+(d._def.align?" red-ui-flow-node-label-"+d._def.align:""),
transform: "translate(38,0)"
// dy: ".3px",
// "text-anchor": d._def.align !== "right" ? "start":"end"
})
nodeContents.appendChild(text);
node[0][0].__textGroup__ = text;
var statusEl = document.createElementNS("http://www.w3.org/2000/svg","g");
// statusEl.__data__ = d;
statusEl.setAttribute("class","red-ui-flow-node-status-group");
var statusEl = RED.utils.createSVGElement("g", { class: "red-ui-flow-node-status-group" })
statusEl.style.display = "none";
node[0][0].__statusGroup__ = statusEl;
var statusRect = document.createElementNS("http://www.w3.org/2000/svg","rect");
statusRect.setAttribute("class","red-ui-flow-node-status");
statusRect.setAttribute("x",6);
statusRect.setAttribute("y",1);
statusRect.setAttribute("width",9);
statusRect.setAttribute("height",9);
statusRect.setAttribute("rx",2);
statusRect.setAttribute("ry",2);
statusRect.setAttribute("stroke-width","3");
var statusRect = RED.utils.createSVGElement("rect", {
class: "red-ui-flow-node-status",
x: 6,
y: 1,
width: 9,
height: 9,
rx: 2,
ry: 2,
"stroke-width": 3
})
statusEl.appendChild(statusRect);
node[0][0].__statusShape__ = statusRect;
var statusLabel = document.createElementNS("http://www.w3.org/2000/svg","text");
statusLabel.setAttribute("class","red-ui-flow-node-status-label");
statusLabel.setAttribute("x",20);
statusLabel.setAttribute("y",10);
var statusLabel = RED.utils.createSVGElement("text", {
class: "red-ui-flow-node-status-label",
x: 20,
y: 10
})
statusEl.appendChild(statusLabel);
node[0][0].__statusLabel__ = statusLabel;
@@ -4766,10 +4708,11 @@ RED.view = (function() {
}
for (var i=0; i<sn; i++) {
if (i===textLines.length) {
var line = document.createElementNS("http://www.w3.org/2000/svg","text");
line.setAttribute("class","red-ui-flow-node-label-text");
line.setAttribute("x",0);
line.setAttribute("y",i*24);
var line = RED.utils.createSVGElement("text", {
class: "red-ui-flow-node-label-text",
x: 0,
y: i*24
})
this.__textGroup__.appendChild(line);
}
textLines[i].textContent = sa[i];
@@ -4868,22 +4811,23 @@ RED.view = (function() {
for(var portIndex = 0; portIndex < numOutputs; portIndex++ ) {
var portGroup;
if (portIndex === this.__outputs__.length) {
portGroup = document.createElementNS("http://www.w3.org/2000/svg","g");
portGroup.setAttribute("class","red-ui-flow-port-output");
portGroup = RED.utils.createSVGElement("g", { class: "red-ui-flow-port-output" })
var portPort;
if (d.type === "link out") {
portPort = document.createElementNS("http://www.w3.org/2000/svg","circle");
portPort.setAttribute("cx",11);
portPort.setAttribute("cy",5);
portPort.setAttribute("r",5);
portPort.setAttribute("class","red-ui-flow-port red-ui-flow-link-port");
portPort = RED.utils.createSVGElement("circle", {
cx: 11,
cy: 5,
r: 5,
class: "red-ui-flow-port red-ui-flow-link-port"
})
} else {
portPort = document.createElementNS("http://www.w3.org/2000/svg","rect");
portPort.setAttribute("rx",3);
portPort.setAttribute("ry",3);
portPort.setAttribute("width",10);
portPort.setAttribute("height",10);
portPort.setAttribute("class","red-ui-flow-port");
portPort = RED.utils.createSVGElement("rect", {
rx: 3,
ry: 3,
width: 10,
height: 10,
class: "red-ui-flow-port"
})
}
portGroup.appendChild(portPort);
portGroup.__port__ = portPort;
@@ -4960,7 +4904,7 @@ RED.view = (function() {
if (d._def.button) {
var buttonEnabled = isButtonEnabled(d);
this.__buttonGroup__.classList.toggle("red-ui-flow-node-button-disabled", !buttonEnabled);
if (RED.runtime && RED.runtime.started !== undefined) {
if (RED.runtime && Object.hasOwn(RED.runtime,'started')) {
this.__buttonGroup__.classList.toggle("red-ui-flow-node-button-stopped", !RED.runtime.started);
}
@@ -5035,26 +4979,28 @@ RED.view = (function() {
var junction = d3.select(this);
var contents = document.createDocumentFragment();
// d.added = true;
var junctionBack = document.createElementNS("http://www.w3.org/2000/svg","rect");
junctionBack.setAttribute("class","red-ui-flow-junction-background");
junctionBack.setAttribute("x",-5);
junctionBack.setAttribute("y",-5);
junctionBack.setAttribute("width",10);
junctionBack.setAttribute("height",10);
junctionBack.setAttribute("rx",3);
junctionBack.setAttribute("ry",3);
var junctionBack = RED.utils.createSVGElement("rect", {
class: "red-ui-flow-junction-background",
x: -5,
y: -5,
width: 10,
height: 10,
rx: 3,
ry: 3
})
junctionBack.__data__ = d;
this.__junctionBack__ = junctionBack;
contents.appendChild(junctionBack);
var junctionInput = document.createElementNS("http://www.w3.org/2000/svg","rect");
junctionInput.setAttribute("class","red-ui-flow-junction-port red-ui-flow-junction-port-input");
junctionInput.setAttribute("x",-5);
junctionInput.setAttribute("y",-5);
junctionInput.setAttribute("width",10);
junctionInput.setAttribute("height",10);
junctionInput.setAttribute("rx",3);
junctionInput.setAttribute("ry",3);
var junctionInput = RED.utils.createSVGElement("rect", {
class: "red-ui-flow-junction-port red-ui-flow-junction-port-input",
x: -5,
y: -5,
width: 10,
height: 10,
rx: 3,
ry: 3
})
junctionInput.__data__ = d;
junctionInput.__portType__ = PORT_TYPE_INPUT;
junctionInput.__portIndex__ = 0;
@@ -5066,14 +5012,15 @@ RED.view = (function() {
this.__junctionInput__ = junctionInput;
contents.appendChild(junctionInput);
var junctionOutput = document.createElementNS("http://www.w3.org/2000/svg","rect");
junctionOutput.setAttribute("class","red-ui-flow-junction-port red-ui-flow-junction-port-output");
junctionOutput.setAttribute("x",-5);
junctionOutput.setAttribute("y",-5);
junctionOutput.setAttribute("width",10);
junctionOutput.setAttribute("height",10);
junctionOutput.setAttribute("rx",3);
junctionOutput.setAttribute("ry",3);
var junctionOutput = RED.utils.createSVGElement("rect", {
class: "red-ui-flow-junction-port red-ui-flow-junction-port-output",
x: -5,
y: -5,
width: 10,
height: 10,
rx: 3,
ry: 3,
})
junctionOutput.__data__ = d;
junctionOutput.__portType__ = PORT_TYPE_OUTPUT;
junctionOutput.__portIndex__ = 0;
@@ -5130,9 +5077,8 @@ RED.view = (function() {
var pathContents = document.createDocumentFragment();
d.added = true;
var pathBack = document.createElementNS("http://www.w3.org/2000/svg","path");
var pathBack = RED.utils.createSVGElement("path", { class: "red-ui-flow-link-background red-ui-flow-link-path"+(d.link?" red-ui-flow-link-link":"")})
pathBack.__data__ = d;
pathBack.setAttribute("class","red-ui-flow-link-background red-ui-flow-link-path"+(d.link?" red-ui-flow-link-link":""));
this.__pathBack__ = pathBack;
pathContents.appendChild(pathBack);
d3.select(pathBack)
@@ -5168,16 +5114,17 @@ RED.view = (function() {
}
})
var pathOutline = document.createElementNS("http://www.w3.org/2000/svg","path");
var pathOutline = RED.utils.createSVGElement("path", {
class: "red-ui-flow-link-outline red-ui-flow-link-path"
})
pathOutline.__data__ = d;
pathOutline.setAttribute("class","red-ui-flow-link-outline red-ui-flow-link-path");
this.__pathOutline__ = pathOutline;
pathContents.appendChild(pathOutline);
var pathLine = document.createElementNS("http://www.w3.org/2000/svg","path");
var pathLine = RED.utils.createSVGElement("path", {
class: "red-ui-flow-link-line red-ui-flow-link-path"+(d.link?" red-ui-flow-link-link":(activeSubflow?" red-ui-flow-subflow-link":""))
})
pathLine.__data__ = d;
pathLine.setAttribute("class","red-ui-flow-link-line red-ui-flow-link-path"+
(d.link?" red-ui-flow-link-link":(activeSubflow?" red-ui-flow-subflow-link":"")));
this.__pathLine__ = pathLine;
pathContents.appendChild(pathLine);
@@ -5657,24 +5604,7 @@ RED.view = (function() {
if (activeSubflow) {
activeSubflowChanged = activeSubflow.changed;
}
var filteredNodesToImport = nodesToImport;
var globalConfig = null;
var gconf = null;
RED.nodes.eachConfig(function (conf) {
if (conf.type === "global-config") {
gconf = conf;
}
});
if (gconf) {
filteredNodesToImport = nodesToImport.filter(function (n) {
return (n.type !== "global-config");
});
globalConfig = nodesToImport.find(function (n) {
return (n.type === "global-config");
});
}
var result = RED.nodes.import(filteredNodesToImport,{generateIds:options.generateIds, addFlow: addNewFlow, importMap: options.importMap});
var result = RED.nodes.import(nodesToImport,{generateIds:options.generateIds, addFlow: addNewFlow, importMap: options.importMap});
if (result) {
var new_nodes = result.nodes;
var new_links = result.links;
@@ -5806,50 +5736,6 @@ RED.view = (function() {
}
}
if (globalConfig) {
// merge global env to existing global-config
var env0 = gconf.env;
var env1 = globalConfig.env;
var newEnv = Array.from(env0);
var changed = false;
env1.forEach(function (item1) {
var index = newEnv.findIndex(function (item0) {
return (item0.name === item1.name);
});
if (index >= 0) {
var item0 = newEnv[index];
if ((item0.type !== item1.type) ||
(item0.value !== item1.value)) {
newEnv[index] = item1;
changed = true;
}
}
else {
newEnv.push(item1);
changed = true;
}
});
if(changed) {
gconf.env = newEnv;
var replaceEvent = {
t: "edit",
node: gconf,
changed: true,
changes: {
env: env0
}
};
historyEvent = {
t:"multi",
events: [
replaceEvent,
historyEvent,
]
};
}
}
RED.history.push(historyEvent);
updateActiveNodes();
@@ -5925,9 +5811,6 @@ RED.view = (function() {
if (mouse_mode === RED.state.SELECTING_NODE) {
return;
}
if (activeFlowLocked) {
return
}
var workspaceSelection = RED.workspaces.selection();
var changed = false;
if (workspaceSelection.length > 0) {
@@ -6255,9 +6138,7 @@ RED.view = (function() {
if (node.z && (node.type === "group" || node._def.category !== 'config')) {
node.dirty = true;
RED.workspaces.show(node.z);
if (node.type === "group" && !node.w && !node.h) {
_redraw();
}
var screenSize = [chart[0].clientWidth/scaleFactor,chart[0].clientHeight/scaleFactor];
var scrollPos = [chart.scrollLeft()/scaleFactor,chart.scrollTop()/scaleFactor];
var cx = node.x;

View File

@@ -58,9 +58,6 @@ RED.workspaces = (function() {
if (!ws.closeable) {
ws.hideable = true;
}
if (!ws.hasOwnProperty('locked')) {
ws.locked = false
}
workspace_tabs.addTab(ws,targetIndex);
var hiddenTabs = JSON.parse(RED.settings.getLocal("hiddenTabs")||"{}");
@@ -78,7 +75,6 @@ RED.workspaces = (function() {
type: "tab",
id: tabId,
disabled: false,
locked: false,
info: "",
label: RED._('workspace.defaultName',{number:workspaceIndex}),
env: [],
@@ -103,9 +99,6 @@ RED.workspaces = (function() {
if (workspaceTabCount === 1) {
return;
}
if (ws.locked) {
return
}
var workspaceOrder = RED.nodes.getWorkspaceOrder();
ws._index = workspaceOrder.indexOf(ws.id);
removeWorkspace(ws);
@@ -126,206 +119,13 @@ RED.workspaces = (function() {
RED.editor.editSubflow(subflow);
}
} else {
if (!workspace.locked) {
RED.editor.editFlow(workspace);
}
RED.editor.editFlow(workspace);
}
}
var workspace_tabs;
var workspaceTabCount = 0;
function getMenuItems(isMenuButton, tab) {
let hiddenFlows = new Set()
for (let i = 0; i < hideStack.length; i++) {
let ids = hideStack[i]
if (!Array.isArray(ids)) {
ids = [ids]
}
ids.forEach(id => {
if (RED.nodes.workspace(id)) {
hiddenFlows.add(id)
}
})
}
const hiddenflowCount = hiddenFlows.size;
let activeWorkspace = tab || RED.nodes.workspace(RED.workspaces.active()) || RED.nodes.subflow(RED.workspaces.active())
let isFlowDisabled = activeWorkspace ? activeWorkspace.disabled : false
const currentTabs = workspace_tabs.listTabs();
let flowCount = 0;
currentTabs.forEach(tab => {
if (RED.nodes.workspace(tab)) {
flowCount++;
}
});
let isCurrentLocked = RED.workspaces.isActiveLocked()
if (tab) {
isCurrentLocked = tab.locked
}
var menuItems = []
if (isMenuButton) {
menuItems.push({
id:"red-ui-tabs-menu-option-search-flows",
label: RED._("workspace.listFlows"),
onselect: "core:list-flows"
},
{
id:"red-ui-tabs-menu-option-search-subflows",
label: RED._("workspace.listSubflows"),
onselect: "core:list-subflows"
},
null)
}
menuItems.push(
{
id:"red-ui-tabs-menu-option-add-flow",
label: RED._("workspace.addFlow"),
onselect: "core:add-flow"
}
)
if (isMenuButton || !!tab) {
menuItems.push(
{
id:"red-ui-tabs-menu-option-add-flow-right",
label: RED._("workspace.addFlowToRight"),
shortcut: RED.keyboard.getShortcut("core:add-flow-to-right"),
onselect: function() {
RED.actions.invoke("core:add-flow-to-right", tab)
}
},
null
)
if (activeWorkspace && activeWorkspace.type === 'tab') {
menuItems.push(
isFlowDisabled ? {
label: RED._("workspace.enableFlow"),
shortcut: RED.keyboard.getShortcut("core:enable-flow"),
onselect: function() {
RED.actions.invoke("core:enable-flow", tab?tab.id:undefined)
},
disabled: isCurrentLocked
} : {
label: RED._("workspace.disableFlow"),
shortcut: RED.keyboard.getShortcut("core:disable-flow"),
onselect: function() {
RED.actions.invoke("core:disable-flow", tab?tab.id:undefined)
},
disabled: isCurrentLocked
},
isCurrentLocked? {
label: RED._("workspace.unlockFlow"),
shortcut: RED.keyboard.getShortcut("core:unlock-flow"),
onselect: function() {
RED.actions.invoke('core:unlock-flow', tab?tab.id:undefined)
}
} : {
label: RED._("workspace.lockFlow"),
shortcut: RED.keyboard.getShortcut("core:lock-flow"),
onselect: function() {
RED.actions.invoke('core:lock-flow', tab?tab.id:undefined)
}
},
null
)
}
const activeIndex = currentTabs.findIndex(id => (activeWorkspace && (id === activeWorkspace.id)));
menuItems.push(
{
label: RED._("workspace.moveToStart"),
shortcut: RED.keyboard.getShortcut("core:move-flow-to-start"),
onselect: function() {
RED.actions.invoke("core:move-flow-to-start", tab?tab.id:undefined)
},
disabled: activeIndex === 0
},
{
label: RED._("workspace.moveToEnd"),
shortcut: RED.keyboard.getShortcut("core:move-flow-to-end"),
onselect: function() {
RED.actions.invoke("core:move-flow-to-end", tab?tab.id:undefined)
},
disabled: activeIndex === currentTabs.length - 1
}
)
}
menuItems.push(null)
if (isMenuButton || !!tab) {
menuItems.push(
{
id:"red-ui-tabs-menu-option-add-hide-flows",
label: RED._("workspace.hideFlow"),
shortcut: RED.keyboard.getShortcut("core:hide-flow"),
onselect: function() {
RED.actions.invoke("core:hide-flow", tab)
}
},
{
id:"red-ui-tabs-menu-option-add-hide-other-flows",
label: RED._("workspace.hideOtherFlows"),
shortcut: RED.keyboard.getShortcut("core:hide-other-flows"),
onselect: function() {
RED.actions.invoke("core:hide-other-flows", tab)
}
}
)
}
menuItems.push(
{
id:"red-ui-tabs-menu-option-add-hide-all-flows",
label: RED._("workspace.hideAllFlows"),
onselect: "core:hide-all-flows",
disabled: (hiddenflowCount === flowCount)
},
{
id:"red-ui-tabs-menu-option-add-show-all-flows",
disabled: hiddenflowCount === 0,
label: RED._("workspace.showAllFlows", { count: hiddenflowCount }),
onselect: "core:show-all-flows"
},
{
id:"red-ui-tabs-menu-option-add-show-last-flow",
disabled: hideStack.length === 0,
label: RED._("workspace.showLastHiddenFlow"),
onselect: "core:show-last-hidden-flow"
}
)
if (tab) {
menuItems.push(
null,
{
label: RED._("common.label.delete"),
onselect: function() {
if (tab.type === 'tab') {
RED.workspaces.delete(tab)
} else if (tab.type === 'subflow') {
RED.subflow.delete(tab.id)
}
},
disabled: isCurrentLocked || (workspaceTabCount === 1)
},
{
label: RED._("menu.label.export"),
shortcut: RED.keyboard.getShortcut("core:show-export-dialog"),
onselect: function() {
RED.workspaces.show(tab.id)
RED.actions.invoke('core:show-export-dialog', null, 'flow')
}
}
)
}
// if (isMenuButton && hiddenflowCount > 0) {
// menuItems.unshift({
// label: RED._("workspace.hiddenFlows",{count: hiddenflowCount}),
// onselect: "core:list-hidden-flows"
// })
// }
return menuItems;
}
function createWorkspaceTabs() {
workspace_tabs = RED.tabs.create({
id: "red-ui-workspace-tabs",
@@ -337,9 +137,8 @@ RED.workspaces = (function() {
$("#red-ui-workspace-chart").show();
activeWorkspace = tab.id;
window.location.hash = 'flow/'+tab.id;
$("#red-ui-workspace").toggleClass("red-ui-workspace-disabled", !!tab.disabled);
$("#red-ui-workspace").toggleClass("red-ui-workspace-locked", !!tab.locked);
} else {
$("#red-ui-workspace").toggleClass("red-ui-workspace-disabled",!!tab.disabled);
} else {
$("#red-ui-workspace-chart").hide();
activeWorkspace = 0;
window.location.hash = '';
@@ -370,12 +169,6 @@ RED.workspaces = (function() {
if (tab.disabled) {
$("#red-ui-tab-"+(tab.id.replace(".","-"))).addClass('red-ui-workspace-disabled');
}
$('<span class="red-ui-workspace-locked-icon"><i class="fa fa-lock"></i> </span>').prependTo("#red-ui-tab-"+(tab.id.replace(".","-"))+" .red-ui-tab-label");
if (tab.locked) {
$("#red-ui-tab-"+(tab.id.replace(".","-"))).addClass('red-ui-workspace-locked');
}
RED.menu.setDisabled("menu-item-workspace-delete",activeWorkspace === 0 || workspaceTabCount <= 1);
if (workspaceTabCount === 1) {
showWorkspace();
@@ -396,19 +189,13 @@ RED.workspaces = (function() {
RED.history.push({
t:'reorder',
workspaces: {
from: oldOrder,
to: newOrder
from:oldOrder,
to:newOrder
},
dirty:RED.nodes.dirty()
});
// Only mark flows dirty if flow-order has changed (excluding subflows)
const filteredOldOrder = oldOrder.filter(id => !!RED.nodes.workspace(id))
const filteredNewOrder = newOrder.filter(id => !!RED.nodes.workspace(id))
if (JSON.stringify(filteredOldOrder) !== JSON.stringify(filteredNewOrder)) {
RED.nodes.dirty(true);
setWorkspaceOrder(newOrder);
}
RED.nodes.dirty(true);
setWorkspaceOrder(newOrder);
},
onselect: function(selectedTabs) {
RED.view.select(false)
@@ -427,12 +214,12 @@ RED.workspaces = (function() {
},
onhide: function(tab) {
hideStack.push(tab.id);
if (tab.type === "tab") {
var hiddenTabs = JSON.parse(RED.settings.getLocal("hiddenTabs")||"{}");
hiddenTabs[tab.id] = true;
RED.settings.setLocal("hiddenTabs",JSON.stringify(hiddenTabs));
RED.events.emit("workspace:hide",{workspace: tab.id})
}
var hiddenTabs = JSON.parse(RED.settings.getLocal("hiddenTabs")||"{}");
hiddenTabs[tab.id] = true;
RED.settings.setLocal("hiddenTabs",JSON.stringify(hiddenTabs));
RED.events.emit("workspace:hide",{workspace: tab.id})
},
onshow: function(tab) {
removeFromHideStack(tab.id);
@@ -447,8 +234,77 @@ RED.workspaces = (function() {
scrollable: true,
addButton: "core:add-flow",
addButtonCaption: RED._("workspace.addFlow"),
menu: function() { return getMenuItems(true) },
contextmenu: function(tab) { return getMenuItems(false, tab) }
menu: function() {
var menuItems = [
{
id:"red-ui-tabs-menu-option-search-flows",
label: RED._("workspace.listFlows"),
onselect: "core:list-flows"
},
{
id:"red-ui-tabs-menu-option-search-subflows",
label: RED._("workspace.listSubflows"),
onselect: "core:list-subflows"
},
null,
{
id:"red-ui-tabs-menu-option-add-flow",
label: RED._("workspace.addFlow"),
onselect: "core:add-flow"
},
{
id:"red-ui-tabs-menu-option-add-flow-right",
label: RED._("workspace.addFlowToRight"),
onselect: "core:add-flow-to-right"
},
null,
{
id:"red-ui-tabs-menu-option-add-hide-flows",
label: RED._("workspace.hideFlow"),
onselect: "core:hide-flow"
},
{
id:"red-ui-tabs-menu-option-add-hide-other-flows",
label: RED._("workspace.hideOtherFlows"),
onselect: "core:hide-other-flows"
},
{
id:"red-ui-tabs-menu-option-add-show-all-flows",
label: RED._("workspace.showAllFlows"),
onselect: "core:show-all-flows"
},
{
id:"red-ui-tabs-menu-option-add-hide-all-flows",
label: RED._("workspace.hideAllFlows"),
onselect: "core:hide-all-flows"
},
{
id:"red-ui-tabs-menu-option-add-show-last-flow",
label: RED._("workspace.showLastHiddenFlow"),
onselect: "core:show-last-hidden-flow"
}
]
let hiddenFlows = new Set()
for (let i = 0; i < hideStack.length; i++) {
let ids = hideStack[i]
if (!Array.isArray(ids)) {
ids = [ids]
}
ids.forEach(id => {
if (RED.nodes.workspace(id)) {
hiddenFlows.add(id)
}
})
}
const flowCount = hiddenFlows.size;
if (flowCount > 0) {
menuItems.unshift({
label: RED._("workspace.hiddenFlows",{count: flowCount}),
onselect: "core:list-hidden-flows"
})
}
return menuItems;
}
});
workspaceTabCount = 0;
}
@@ -499,33 +355,16 @@ RED.workspaces = (function() {
});
RED.actions.add("core:add-flow",function(opts) { addWorkspace(undefined,undefined,opts?opts.index:undefined)});
RED.actions.add("core:add-flow-to-right",function(workspace) {
let index
if (workspace) {
index = workspace_tabs.getTabIndex(workspace.id)+1
} else {
index = workspace_tabs.activeIndex()+1
}
addWorkspace(undefined,undefined,index)
});
RED.actions.add("core:add-flow-to-right",function(opts) { addWorkspace(undefined,undefined,workspace_tabs.activeIndex()+1)});
RED.actions.add("core:edit-flow",editWorkspace);
RED.actions.add("core:remove-flow",removeWorkspace);
RED.actions.add("core:enable-flow",enableWorkspace);
RED.actions.add("core:disable-flow",disableWorkspace);
RED.actions.add("core:lock-flow",lockWorkspace);
RED.actions.add("core:unlock-flow",unlockWorkspace);
RED.actions.add("core:move-flow-to-start", function(id) { moveWorkspace(id, 'start') });
RED.actions.add("core:move-flow-to-end", function(id) { moveWorkspace(id, 'end') });
RED.actions.add("core:hide-flow", function(workspace) {
let selection
if (workspace) {
selection = [workspace]
} else {
selection = workspace_tabs.selection();
if (selection.length === 0) {
selection = [{id:activeWorkspace}]
}
RED.actions.add("core:hide-flow", function() {
var selection = workspace_tabs.selection();
if (selection.length === 0) {
selection = [{id:activeWorkspace}]
}
var hiddenTabs = [];
selection.forEach(function(ws) {
@@ -539,15 +378,10 @@ RED.workspaces = (function() {
workspace_tabs.clearSelection();
})
RED.actions.add("core:hide-other-flows", function(workspace) {
let selection
if (workspace) {
selection = [workspace]
} else {
selection = workspace_tabs.selection();
if (selection.length === 0) {
selection = [{id:activeWorkspace}]
}
RED.actions.add("core:hide-other-flows", function() {
var selection = workspace_tabs.selection();
if (selection.length === 0) {
selection = [{id:activeWorkspace}]
}
var selected = new Set(selection.map(function(ws) { return ws.id }))
@@ -652,7 +486,7 @@ RED.workspaces = (function() {
}
function setWorkspaceState(id,disabled) {
var workspace = RED.nodes.workspace(id||activeWorkspace);
if (!workspace || workspace.locked) {
if (!workspace) {
return;
}
if (workspace.disabled !== disabled) {
@@ -687,58 +521,11 @@ RED.workspaces = (function() {
}
}
}
function lockWorkspace(id) {
setWorkspaceLockState(id,true);
}
function unlockWorkspace(id) {
setWorkspaceLockState(id,false);
}
function setWorkspaceLockState(id,locked) {
var workspace = RED.nodes.workspace(id||activeWorkspace);
if (!workspace) {
return;
}
if (workspace.locked !== locked) {
var changes = { locked: workspace.locked };
workspace.locked = locked;
$("#red-ui-tab-"+(workspace.id.replace(".","-"))).toggleClass('red-ui-workspace-locked',!!workspace.locked);
if (!id || (id === activeWorkspace)) {
$("#red-ui-workspace").toggleClass("red-ui-workspace-locked",!!workspace.locked);
}
var historyEvent = {
t: "edit",
changes:changes,
node: workspace,
dirty: RED.nodes.dirty()
}
workspace.changed = true;
RED.history.push(historyEvent);
RED.events.emit("flows:change",workspace);
RED.nodes.dirty(true);
// RED.sidebar.config.refresh();
// var selection = RED.view.selection();
// if (!selection.nodes && !selection.links && workspace.id === activeWorkspace) {
// RED.sidebar.info.refresh(workspace);
// }
// if (changes.hasOwnProperty('disabled')) {
// RED.nodes.eachNode(function(n) {
// if (n.z === workspace.id) {
// n.dirty = true;
// }
// });
// RED.view.redraw();
// }
}
}
function removeWorkspace(ws) {
if (!ws) {
ws = RED.nodes.workspace(activeWorkspace)
if (ws && !ws.locked) {
deleteWorkspace(RED.nodes.workspace(activeWorkspace));
}
deleteWorkspace(RED.nodes.workspace(activeWorkspace));
} else {
if (ws.locked) { return }
if (workspace_tabs.contains(ws.id)) {
workspace_tabs.removeTab(ws.id);
}
@@ -748,46 +535,16 @@ RED.workspaces = (function() {
}
}
function moveWorkspace(id, direction) {
const workspace = RED.nodes.workspace(id||activeWorkspace) || RED.nodes.subflow(id||activeWorkspace);
if (!workspace) {
return;
}
const currentOrder = workspace_tabs.listTabs()
const oldOrder = [...currentOrder]
const currentIndex = currentOrder.findIndex(id => id === workspace.id)
currentOrder.splice(currentIndex, 1)
if (direction === 'start') {
currentOrder.unshift(workspace.id)
} else if (direction === 'end') {
currentOrder.push(workspace.id)
}
const newOrder = setWorkspaceOrder(currentOrder)
if (JSON.stringify(newOrder) !== JSON.stringify(oldOrder)) {
RED.history.push({
t:'reorder',
workspaces: {
from:oldOrder,
to:newOrder
},
dirty:RED.nodes.dirty()
});
const filteredOldOrder = oldOrder.filter(id => !!RED.nodes.workspace(id))
const filteredNewOrder = newOrder.filter(id => !!RED.nodes.workspace(id))
if (JSON.stringify(filteredOldOrder) !== JSON.stringify(filteredNewOrder)) {
RED.nodes.dirty(true);
}
}
}
function setWorkspaceOrder(order) {
var newOrder = order.filter(id => !!RED.nodes.workspace(id))
var newOrder = order.filter(function(id) {
return RED.nodes.workspace(id) !== undefined;
})
var currentOrder = RED.nodes.getWorkspaceOrder();
if (JSON.stringify(newOrder) !== JSON.stringify(currentOrder)) {
RED.nodes.setWorkspaceOrder(newOrder);
RED.events.emit("flows:reorder",newOrder);
}
workspace_tabs.order(order);
return newOrder
}
function flashTab(tabId) {
@@ -833,10 +590,6 @@ RED.workspaces = (function() {
active: function() {
return activeWorkspace
},
isActiveLocked: function() {
var ws = RED.nodes.workspace(activeWorkspace) || RED.nodes.subflow(activeWorkspace)
return ws && ws.locked
},
selection: function() {
return workspace_tabs.selection();
},
@@ -893,8 +646,6 @@ RED.workspaces = (function() {
workspace_tabs.resize();
},
enable: enableWorkspace,
disable: disableWorkspace,
lock: lockWorkspace,
unlock: unlockWorkspace
disable: disableWorkspace
}
})();

View File

@@ -30,7 +30,7 @@
bottom: 0px;
left:0px;
right: 0px;
overflow-y: auto;
overflow-y: scroll;
}
.red-ui-debug-filter-box {
position:absolute;

View File

@@ -37,27 +37,3 @@
}
}
}
#red-ui-image-drop-target {
position: absolute;
top: 0; bottom: 0;
left: 0; right: 0;
background: var(--red-ui-dnd-background);
display:table;
width: 100%;
height: 100%;
display: none;
z-index:100;
div {
pointer-events: none;
display: table-cell;
vertical-align: middle;
text-align: center;
font-size: 40px;
color: var(--red-ui-dnd-color);
i {
pointer-events: none;
font-size: 80px;
}
}
}

View File

@@ -368,7 +368,7 @@ button.red-ui-button-small
border:1px solid var(--red-ui-secondary-border-color);
border-radius:5px;
height: calc(100% - 21px);
overflow-y: auto;
overflow-y: scroll;
background: var(--red-ui-secondary-background);
}
@@ -562,7 +562,7 @@ div.red-ui-button-small.red-ui-color-picker-opacity-slider-handle {
.red-ui-icon-list {
width: 308px;
height: 200px;
overflow-y: auto;
overflow-y: scroll;
line-height: 0px;
position: relative;
&.red-ui-icon-list-dark {

View File

@@ -68,9 +68,6 @@
stroke: var(--red-ui-node-border);
cursor: move;
stroke-width: 1;
.red-ui-workspace-locked & {
cursor: pointer;
}
}
.red-ui-workspace-select-mode {
g.red-ui-flow-node.red-ui-flow-node-hovered * {
@@ -290,11 +287,9 @@ g.red-ui-flow-node-selected {
text-anchor:start;
}
#red-ui-workspace:not(.red-ui-workspace-locked) {
.red-ui-flow-port-hovered {
stroke: var(--red-ui-port-selected-color);
fill: var(--red-ui-port-selected-color);
}
.red-ui-flow-port-hovered {
stroke: var(--red-ui-port-selected-color);
fill: var(--red-ui-port-selected-color);
}
.red-ui-flow-subflow-port {

View File

@@ -32,8 +32,7 @@
color: var(--red-ui-primary-text-color);
border: 1px solid var(--red-ui-notification-border-default);
border-left-width: 16px;
overflow: scroll;
max-height: 80vh;
overflow: hidden;
.ui-dialog-buttonset {
margin-top: 20px;
margin-bottom: 10px;

View File

@@ -26,7 +26,7 @@
}
}
#red-ui-project-settings-tab-settings {
overflow-y: auto;
overflow-y: scroll;
}
.red-ui-sidebar-vc-shade {
background: var(--red-ui-primary-background);
@@ -183,7 +183,7 @@
}
.red-ui-projects-dialog-project-list-inner-container {
flex-grow: 1 ;
overflow-y: auto;
overflow-y: scroll;
position:relative;
.red-ui-editableList-border {
border: none;

View File

@@ -41,7 +41,6 @@
height: 50px;
background: var(--red-ui-secondary-background);
border: 2px solid var(--red-ui-primary-border-color);
color: var(--red-ui-primary-text-color);
text-align: center;
line-height:50px;
@@ -52,7 +51,7 @@
.red-ui-editor-radial-menu-opt-disabled {
border-color: var(--red-ui-tertiary-border-color);
color: var(--red-ui-secondary-text-color-disabled);
color: var(--red-ui-tertiary-border-color);
}
.red-ui-editor-radial-menu-opt-active {
background: var(--red-ui-secondary-background-hover);

View File

@@ -20,7 +20,7 @@
bottom: 0;
left: 0;
right: 0;
overflow-y: auto;
overflow-y: scroll;
.red-ui-palette-category {
&:not(.expanded) button {

View File

@@ -467,9 +467,6 @@ div.red-ui-info-table {
.fa-eye {
display: none;
}
.fa-unlock-alt {
display: none;
}
}
.red-ui-info-outline-item-control-reveal,
.red-ui-info-outline-item-control-action {
@@ -503,25 +500,6 @@ div.red-ui-info-table {
display: none;
}
}
.fa-lock {
display: none;
}
.red-ui-info-outline-item.red-ui-info-outline-item-locked & {
.fa-lock {
display: inline-block;
}
.fa-unlock-alt {
display: none;
}
}
// If the parent is locked, do not show the display/action buttons when
// hovering in the outline
.red-ui-info-outline-item-locked .red-ui-info-outline-item & {
.red-ui-info-outline-item-control-disable,
.red-ui-info-outline-item-control-action {
display: none;
}
}
button {
margin-right: 3px
}
@@ -539,6 +517,8 @@ div.red-ui-info-table {
}
}
.red-ui-icons {
display: inline-block;
width: 18px;

View File

@@ -67,7 +67,7 @@
left: 0;
bottom: 0;
padding: 8px 20px 20px;
overflow-y: auto;
overflow-y: scroll;
}
.red-ui-settings-row {
padding: 5px 10px 2px;

View File

@@ -29,7 +29,7 @@
#red-ui-workspace-chart {
overflow: auto;
position: absolute;
bottom:26px;
bottom:25px;
top: 35px;
left:0px;
right:0px;
@@ -106,28 +106,6 @@
}
}
.red-ui-workspace-locked-icon {
display: none;
}
.red-ui-workspace-locked {
&.red-ui-tab {
// border-top-style: dashed;
// border-left-style: dashed;
// border-right-style: dashed;
// a {
// font-style: italic;
// color: var(--red-ui-tab-text-color-disabled-inactive) !important;
// }
// &.active a {
// font-weight: normal;
// color: var(--red-ui-tab-text-color-disabled-active) !important;
// }
.red-ui-workspace-locked-icon {
display: inline;
}
}
}
#red-ui-navigator-canvas {
position: absolute;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

View File

@@ -1,155 +0,0 @@
export default {
version: "3.0.0",
steps: [
{
titleIcon: "fa fa-map-o",
title: {
"en-US": "Welcome to Node-RED 3.0!",
"ja": "Node-RED 3.0へようこそ!"
},
description: {
"en-US": "<p>Let's take a moment to discover the new features in this release.</p>",
"ja": "<p>本リリースの新機能を見つけてみましょう。</p>"
}
},
{
title: {
"en-US": "Context Menu",
"ja": "コンテキストメニュー"
},
image: 'images/context-menu.png',
description: {
"en-US": `<p>The editor now has its own context menu when you
right-click in the workspace.</p>
<p>This makes many of the built-in actions much easier
to access.</p>`,
"ja": `<p>ワークスペースで右クリックすると、エディタに独自のコンテキストメニューが表示されるようになりました。</p>
<p>これによって多くの組み込み動作を、より簡単に利用できます。</p>`
}
},
{
title: {
"en-US": "Wire Junctions",
"ja": "分岐点をワイヤーに追加"
},
image: 'images/junction-slice.gif',
description: {
"en-US": `<p>To make it easier to route wires around your flows,
it is now possible to add junction nodes that give
you more control.</p>
<p>Junctions can be added to wires by holding both the Alt key and the Shift key
then click and drag the mouse across the wires.</p>`,
"ja": `<p>フローのワイヤーの経路をより制御しやすくするために、分岐点ノードを追加できるようになりました。</p>
<p>Altキーとシフトキーを押しながらマウスをクリックし、ワイヤーを横切るようにドラッグすることで、分岐点を追加できます。</p>`
},
},
{
title: {
"en-US": "Wire Junctions",
"ja": "分岐点をワイヤーに追加"
},
image: 'images/junction-quick-add.png',
description: {
"en-US": `<p>Junctions can also be added using the quick-add dialog.</p>
<p>The dialog is opened by holding the Ctrl (or Cmd) key when
clicking in the workspace.</p>`,
"ja": `<p>クイック追加ダイアログを用いて、分岐点を追加することもできます。</p>
<p>本ダイアログを開くには、Ctrl(またはCmd)キーを押しながら、ワークスペース上でクリックします。</p>`
},
},
{
title: {
"en-US": "Debug Path Tooltip",
"ja": "デバッグパスのツールチップ"
},
image: 'images/debug-path-tooltip.png',
description: {
"en-US": `<p>When hovering over a node name in the Debug sidebar, a
new tooltip shows the full location of the node.</p>
<p>This is useful when working with subflows, making it
much easier to identify exactly which node generated
the message.</p>
<p>Clicking on any item in the list will reveal it in
the workspace.</p>`,
"ja": `<p>デバックサイドバー内のノード名の上にマウスカーソルを乗せると、新たにツールチップが表示され、ノードの場所が分かるようになっています。</p>
<p>これは、サブフローを用いる時に役立つ機能であり、メッセージがどのノードから出力されたかを正確に特定することが遥かに簡単になります。</p>
<p>本リスト内の要素をクリックすると、ワークスペース内にその要素が表示されます。</p>`
},
},
{
title: {
"en-US": "Continuous Search",
"ja": "連続した検索"
},
image: 'images/continuous-search.png',
description: {
"en-US": `<p>When searching for things in the editor, a new toolbar in
the workspace provides options to quickly jump between
the search results.</p>`,
"ja": `<p>ワークスペース内の新しいツールバーにあるオプションによって、エディタ内を検索する際に、検索結果の間を素早く移動できます。</p>`
},
},
{
title: {
"en-US": "New wiring actions",
"ja": "新しいワイヤー操作"
},
image: "images/split-wire-with-links.gif",
description: {
"en-US": `<p>A new action has been added that will replace a wire with a pair of connected Link nodes:</p>
<ul>
<li><b><code>Split Wire With Link Nodes</code></b></li>
</ul>
<p>Actions can be accessed from the Action List in the main menu.</p>`,
"ja": `<p>ワイヤーを、接続されたLinkードのペアに置き換える動作が新たに追加されました:</p>
<ul>
<li><b><code>ワイヤーをlinkードで分割</code></b></li>
</ul>
<p>本アクションは、メインメニュー内の動作一覧から呼び出せます。</p>`,
},
},
{
title: {
"en-US": "Default node names",
"ja": "標準ノードの名前"
},
// image: "images/",
description: {
"en-US": `<p>Some nodes have been updated to generate a unique name when
new instances are added to the workspace. This applies to
<code>Debug</code>, <code>Function</code> and <code>Link</code> nodes.</p>
<p>A new action has also been added to generate default names for the selected
nodes:</p>
<ul>
<li><b><code>Generate Node Names</code></b></li>
</ul><p>Actions can be accessed from the Action List in the main menu.</p>
`,
"ja": `<p>一部のノードは、ワークスペース上に新インスタンスとして追加した際に、一意の名前を付けるよう変更されました。この変更は、<code>Debug</code>、<code>Function</code>、<code>Link</code>ノードに適用されています。</p>
<p>選択したノードに対して、標準の名前を生成する動作も新たに追加されました:</p>
<ul>
<li><b><code>ノード名を生成</code></b></li>
</ul><p>本アクションは、メインメニュー内の動作一覧から呼び出せます。</p>
`
}
},
{
title: {
"en-US": "Node Updates",
"ja": "ノードの更新"
},
// image: "images/",
description: {
"en-US": `<ul>
<li>The Debug node can be configured to count messages it receives</li>
<li>The Link Call node can use a message property to dynamically target the link it should call</li>
<li>The HTTP Request node can be preconfigured with HTTP headers</li>
</ul>`,
"ja": `<ul>
<li>Debugードは、受信したメッセージの数をカウントするよう設定できるようになりました。</li>
<li>Link Callードは、メッセージのプロパティによって、呼び出し対象のlinkを動的に指定できるようになりました。</li>
<li>HTTP Requestードは、HTTPヘッダを事前設定できるようになりました。</li>
</ul>`
}
}
]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 KiB

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 189 KiB

View File

@@ -1,97 +1,137 @@
export default {
version: "3.1.0-beta.1",
version: "3.0.0",
steps: [
{
titleIcon: "fa fa-map-o",
title: {
"en-US": "Welcome to Node-RED 3.1 Beta 1!",
// "ja": "Node-RED 3.1へようこそ!"
"en-US": "Welcome to Node-RED 3.0!",
"ja": "Node-RED 3.0へようこそ!"
},
description: {
"en-US": "<p>This is the first beta release for 3.1.0 and we have a few new features to tell you about.</p>",
// "ja": ""
"en-US": "<p>Let's take a moment to discover the new features in this release.</p>",
"ja": "<p>本リリースの新機能を見つけてみましょう。</p>"
}
},
{
title: {
"en-US": "Improved Context Menu",
// "ja": ""
"en-US": "Context Menu",
"ja": "コンテキストメニュー"
},
image: 'images/context-menu.png',
description: {
"en-US": `<p>The editor's context menu has been expanded to make lots more of
the built-in actions available.</p>
<p>Adding nodes, working with groups and plenty
of other useful tools are now just a click away.</p>
<p>The flow tab bar also has its own context menu to make working
with your flows much easier.</p>`,
// "ja": ``
"en-US": `<p>The editor now has its own context menu when you
right-click in the workspace.</p>
<p>This makes many of the built-in actions much easier
to access.</p>`,
"ja": `<p>ワークスペースで右クリックすると、エディタに独自のコンテキストメニューが表示されるようになりました。</p>
<p>これによって多くの組み込み動作を、より簡単に利用できます。</p>`
}
},
{
title: {
"en-US": "Hiding Flows",
// "ja": ""
"en-US": "Wire Junctions",
"ja": "分岐点をワイヤーに追加"
},
image: 'images/hiding-flows.png',
image: 'images/junction-slice.gif',
description: {
"en-US": `<p>Hiding flows is now done through the flow context menu.</p>
<p>The 'hide' button in previous releases has been removed from the tabs
as they were being clicked accidentally too often.</p>`,
// "ja": ``
"en-US": `<p>To make it easier to route wires around your flows,
it is now possible to add junction nodes that give
you more control.</p>
<p>Junctions can be added to wires by holding both the Alt key and the Shift key
then click and drag the mouse across the wires.</p>`,
"ja": `<p>フローのワイヤーの経路をより制御しやすくするために、分岐点ノードを追加できるようになりました。</p>
<p>Altキーとシフトキーを押しながらマウスをクリックし、ワイヤーを横切るようにドラッグすることで、分岐点を追加できます。</p>`
},
},
{
title: {
"en-US": "Locking Flows",
// "ja": ""
"en-US": "Wire Junctions",
"ja": "分岐点をワイヤーに追加"
},
image: 'images/locking-flows.png',
image: 'images/junction-quick-add.png',
description: {
"en-US": `<p>Flows can now be locked to prevent accidental changes being made.</p>
<p>When locked you cannot modify the nodes in any way.</p>
<p>The flow context menu provides the options to lock and unlock flows,
as well as in the Info sidebar explorer.</p>`,
// "ja": ``
"en-US": `<p>Junctions can also be added using the quick-add dialog.</p>
<p>The dialog is opened by holding the Ctrl (or Cmd) key when
clicking in the workspace.</p>`,
"ja": `<p>クイック追加ダイアログを用いて、分岐点を追加することもできます。</p>
<p>本ダイアログを開くには、Ctrl(またはCmd)キーを押しながら、ワークスペース上でクリックします。</p>`
},
},
{
title: {
"en-US": "Adding Images to node/flow descriptions",
// "ja": ""
"en-US": "Debug Path Tooltip",
"ja": "デバッグパスのツールチップ"
},
// image: 'images/debug-path-tooltip.png',
image: 'images/debug-path-tooltip.png',
description: {
"en-US": `<p>You can now add images to a node's or flows's description.</p>
<p>Simply drag the image into the text editor and it will get added inline.</p>
<p>When the description is shown in the Info sidebar, the image will be displayed.`,
// "ja": ``
"en-US": `<p>When hovering over a node name in the Debug sidebar, a
new tooltip shows the full location of the node.</p>
<p>This is useful when working with subflows, making it
much easier to identify exactly which node generated
the message.</p>
<p>Clicking on any item in the list will reveal it in
the workspace.</p>`,
"ja": `<p>デバックサイドバー内のノード名の上にマウスカーソルを乗せると、新たにツールチップが表示され、ノードの場所が分かるようになっています。</p>
<p>これは、サブフローを用いる時に役立つ機能であり、メッセージがどのノードから出力されたかを正確に特定することが遥かに簡単になります。</p>
<p>本リスト内の要素をクリックすると、ワークスペース内にその要素が表示されます。</p>`
},
},
{
title: {
"en-US": "Adding Mermaid Diagrams",
// "ja": ""
"en-US": "Continuous Search",
"ja": "連続した検索"
},
image: 'images/mermaid.png',
image: 'images/continuous-search.png',
description: {
"en-US": `<p>You can also add <a href="https://github.com/mermaid-js/mermaid">Mermaid</a> diagrams directly into your node or flow descriptions.</p>
<p>This gives you much richer options for documenting your flows.</p>`,
// "ja": ``
"en-US": `<p>When searching for things in the editor, a new toolbar in
the workspace provides options to quickly jump between
the search results.</p>`,
"ja": `<p>ワークスペース内の新しいツールバーにあるオプションによって、エディタ内を検索する際に、検索結果の間を素早く移動できます。</p>`
},
},
{
title: {
"en-US": "Managing Global Environment Variables",
// "ja": ""
"en-US": "New wiring actions",
"ja": "新しいワイヤー操作"
},
image: 'images/global-env-vars.png',
image: "images/split-wire-with-links.gif",
description: {
"en-US": `<p>You can set environment variables that apply to all nodes and flows in the new
'Global Environment Variables' section of User Settings.</p>`,
// "ja": ``
"en-US": `<p>A new action has been added that will replace a wire with a pair of connected Link nodes:</p>
<ul>
<li><b><code>Split Wire With Link Nodes</code></b></li>
</ul>
<p>Actions can be accessed from the Action List in the main menu.</p>`,
"ja": `<p>ワイヤーを、接続されたLinkードのペアに置き換える動作が新たに追加されました:</p>
<ul>
<li><b><code>ワイヤーをlinkードで分割</code></b></li>
</ul>
<p>本アクションは、メインメニュー内の動作一覧から呼び出せます。</p>`,
},
},
{
title: {
"en-US": "Default node names",
"ja": "標準ノードの名前"
},
// image: "images/",
description: {
"en-US": `<p>Some nodes have been updated to generate a unique name when
new instances are added to the workspace. This applies to
<code>Debug</code>, <code>Function</code> and <code>Link</code> nodes.</p>
<p>A new action has also been added to generate default names for the selected
nodes:</p>
<ul>
<li><b><code>Generate Node Names</code></b></li>
</ul><p>Actions can be accessed from the Action List in the main menu.</p>
`,
"ja": `<p>一部のノードは、ワークスペース上に新インスタンスとして追加した際に、一意の名前を付けるよう変更されました。この変更は、<code>Debug</code>、<code>Function</code>、<code>Link</code>ノードに適用されています。</p>
<p>選択したノードに対して、標準の名前を生成する動作も新たに追加されました:</p>
<ul>
<li><b><code>ノード名を生成</code></b></li>
</ul><p>本アクションは、メインメニュー内の動作一覧から呼び出せます。</p>
`
}
},
{
title: {
"en-US": "Node Updates",
@@ -99,9 +139,16 @@ export default {
},
// image: "images/",
description: {
"en-US": `<p>The core nodes have received lots of minor fixes, documentation updates and
small enhancements. Check the full changelog in the Help sidebar for a full list.</p>`,
// "ja": ``
"en-US": `<ul>
<li>The Debug node can be configured to count messages it receives</li>
<li>The Link Call node can use a message property to dynamically target the link it should call</li>
<li>The HTTP Request node can be preconfigured with HTTP headers</li>
</ul>`,
"ja": `<ul>
<li>Debugードは、受信したメッセージの数をカウントするよう設定できるようになりました。</li>
<li>Link Callードは、メッセージのプロパティによって、呼び出し対象のlinkを動的に指定できるようになりました。</li>
<li>HTTP Requestードは、HTTPヘッダを事前設定できるようになりました。</li>
</ul>`
}
}
]

View File

@@ -14,9 +14,6 @@ declare var msg: NodeMessage;
/** @type {string} the id of the incoming `msg` (alias of msg._msgid) */
declare const __msgid__:string;
declare const util:typeof import('util')
declare const promisify:typeof import('util').promisify
/**
* @typedef NodeStatus
* @type {object}

View File

@@ -160,7 +160,6 @@
'$base64encode':{ args:[ ]},
'$boolean':{ args:[ 'arg' ]},
'$ceil':{ args:[ 'number' ]},
'$clone': { args:[ 'arg' ]},
'$contains':{ args:[ 'str', 'pattern' ]},
'$count':{ args:[ 'array' ]},
'$decodeUrl':{ args:[ 'str' ]},

View File

@@ -95,64 +95,45 @@ module.exports = function(RED) {
}
this.on("input", function(msg, send, done) {
const errors = [];
let props = this.props;
var errors = [];
var props = this.props;
if (msg.__user_inject_props__ && Array.isArray(msg.__user_inject_props__)) {
props = msg.__user_inject_props__;
}
delete msg.__user_inject_props__;
props = [...props]
function evaluateProperty(doneEvaluating) {
if (props.length === 0) {
doneEvaluating()
return
}
const p = props.shift()
const property = p.p;
const value = p.v ? p.v : '';
const valueType = p.vt ? p.vt : 'str';
props.forEach(p => {
var property = p.p;
var value = p.v ? p.v : '';
var valueType = p.vt ? p.vt : 'str';
if (property) {
if (valueType === "jsonata") {
if (p.v) {
try {
var exp = RED.util.prepareJSONataExpression(p.v, node);
var val = RED.util.evaluateJSONataExpression(exp, msg);
RED.util.setMessageProperty(msg, property, val, true);
}
catch (err) {
errors.push(err.message);
}
}
evaluateProperty(doneEvaluating)
} else {
if (!property) return;
if (valueType === "jsonata") {
if (p.v) {
try {
RED.util.evaluateNodeProperty(value, valueType, node, msg, (err, newValue) => {
if (err) {
errors.push(err.toString())
} else {
RED.util.setMessageProperty(msg,property,newValue,true);
}
evaluateProperty(doneEvaluating)
})
} catch (err) {
errors.push(err.toString());
evaluateProperty(doneEvaluating)
var exp = RED.util.prepareJSONataExpression(p.v, node);
var val = RED.util.evaluateJSONataExpression(exp, msg);
RED.util.setMessageProperty(msg, property, val, true);
}
catch (err) {
errors.push(err.message);
}
}
} else {
evaluateProperty(doneEvaluating)
return;
}
try {
RED.util.setMessageProperty(msg,property,RED.util.evaluateNodeProperty(value, valueType, this, msg),true);
} catch (err) {
errors.push(err.toString());
}
});
if (errors.length) {
done(errors.join('; '));
} else {
send(msg);
done();
}
evaluateProperty(() => {
if (errors.length) {
done(errors.join('; '));
} else {
send(msg);
done();
}
})
});
}

View File

@@ -1,6 +1,6 @@
<script type="text/html" data-template-name="complete">
<div class="form-row node-input-target-row">
<button type="button" id="node-input-complete-target-select" class="red-ui-button" data-i18n="common.label.selectNodes"></button>
<button id="node-input-complete-target-select" class="red-ui-button" data-i18n="common.label.selectNodes"></button>
</div>
<div class="form-row node-input-target-row node-input-target-list-row" style="position: relative; min-height: 100px">
<div style="position: absolute; top: -30px; right: 0;"><input type="text" id="node-input-complete-target-filter"></div>

View File

@@ -4,7 +4,7 @@
<label style="width: auto" for="node-input-scope" data-i18n="catch.label.source"></label>
<select id="node-input-scope-select">
<option value="all" data-i18n="catch.scope.all"></option>
<option value="target" data-i18n="catch.scope.selected"></option>
<option value="target" data-i18n="catch.scope.selected"></options>
</select>
</div>
<div class="form-row node-input-uncaught-row">
@@ -12,7 +12,7 @@
<label for="node-input-uncaught" style="width: auto" data-i18n="catch.label.uncaught"></label>
</div>
<div class="form-row node-input-target-row">
<button type="button" id="node-input-catch-target-select" class="red-ui-button" data-i18n="common.label.selectNodes"></button>
<button id="node-input-catch-target-select" class="red-ui-button" data-i18n="common.label.selectNodes"></button>
</div>
<div class="form-row node-input-target-row node-input-target-list-row" style="position: relative; min-height: 100px">
<div style="position: absolute; top: -30px; right: 0;"><input type="text" id="node-input-catch-target-filter"></div>

View File

@@ -4,11 +4,11 @@
<label style="width: auto" for="node-input-scope" data-i18n="status.label.source"></label>
<select id="node-input-scope-select">
<option value="all" data-i18n="status.scope.all"></option>
<option value="target" data-i18n="status.scope.selected"></option>
<option value="target" data-i18n="status.scope.selected"></options>
</select>
</div>
<div class="form-row node-input-target-row">
<button type="button" id="node-input-status-target-select" class="red-ui-button" data-i18n="common.label.selectNodes"></button>
<button id="node-input-status-target-select" class="red-ui-button" data-i18n="common.label.selectNodes"></button>
</div>
<div class="form-row node-input-target-row node-input-target-list-row" style="position: relative; min-height: 100px">
<div style="position: absolute; top: -30px; right: 0;"><input type="text" id="node-input-status-target-filter"></div>

View File

@@ -1,27 +0,0 @@
<script type="text/html" data-template-name="global-config">
  <div class="form-row">
<label style="width: 100%"><span data-i18n="global-config.label.open-conf"></span>:</label>
</div>
<div class="form-row">
<button class="red-ui-button" type="button" id="node-input-edit-env-var" data-i18n="editor:env-var.header" style="margin-left: 20px"></button>
</div>
</script>
<script type="text/javascript">
RED.nodes.registerType('global-config',{
category: 'config',
defaults: {
name: { value: "" },
env: { value: [] },
},
credentials: {
map: { type: "map" }
},
oneditprepare: function() {
$('#node-input-edit-env-var').on('click', function(evt) {
RED.actions.invoke('core:show-user-settings', 'envvar')
});
},
hasUsers: false
});
</script>

View File

@@ -1,7 +0,0 @@
module.exports = function(RED) {
"use strict";
function GlobalConfigNode(n) {
RED.nodes.createNode(this,n);
}
RED.nodes.registerType("global-config", GlobalConfigNode);
}

View File

@@ -17,8 +17,6 @@
display: flex;
background: var(--red-ui-tertiary-background);
padding-right: 75px;
border-top-left-radius: 3px;
border-top-right-radius: 3px;
}
#node-input-libs-container-row .red-ui-editableList-header > div {
flex-grow: 1;
@@ -93,21 +91,21 @@
<div id="func-tab-init" style="display:none">
<div class="form-row node-text-editor-row" style="position:relative">
<div style="height: 250px; min-height:150px;" class="node-text-editor" id="node-input-init-editor" ></div>
<div style="position: absolute; right:0; bottom: calc(100% - 20px); z-Index: 10;"><button type="button" id="node-init-expand-js" class="red-ui-button red-ui-button-small"><i class="fa fa-expand"></i></button></div>
<div style="position: absolute; right:0; bottom: calc(100% - 20px); z-Index: 10;"><button id="node-init-expand-js" class="red-ui-button red-ui-button-small"><i class="fa fa-expand"></i></button></div>
</div>
</div>
<div id="func-tab-body" style="display:none">
<div class="form-row node-text-editor-row" style="position:relative">
<div style="height: 220px; min-height:150px;" class="node-text-editor" id="node-input-func-editor" ></div>
<div style="position: absolute; right:0; bottom: calc(100% - 20px); z-Index: 10;"><button type="button" id="node-function-expand-js" class="red-ui-button red-ui-button-small"><i class="fa fa-expand"></i></button></div>
<div style="position: absolute; right:0; bottom: calc(100% - 20px); z-Index: 10;"><button id="node-function-expand-js" class="red-ui-button red-ui-button-small"><i class="fa fa-expand"></i></button></div>
</div>
</div>
<div id="func-tab-finalize" style="display:none">
<div class="form-row node-text-editor-row" style="position:relative">
<div style="height: 250px; min-height:150px;" class="node-text-editor" id="node-input-finalize-editor" ></div>
<div style="position: absolute; right:0; bottom: calc(100% - 20px); z-Index: 10;"><button type="button" id="node-finalize-expand-js" class="red-ui-button red-ui-button-small"><i class="fa fa-expand"></i></button></div>
<div style="position: absolute; right:0; bottom: calc(100% - 20px); z-Index: 10;"><button id="node-finalize-expand-js" class="red-ui-button red-ui-button-small"><i class="fa fa-expand"></i></button></div>
</div>
</div>
@@ -296,7 +294,7 @@
if (val === "_custom_") {
val = $(this).val();
}
var varName = val.trim().replace(/^@/,"").replace(/@.*$/,"").replace(/[-_/\.].?/g, function(v) { return v[1]?v[1].toUpperCase():"" });
var varName = val.trim().replace(/^@/,"").replace(/@.*$/,"").replace(/[-_/].?/g, function(v) { return v[1]?v[1].toUpperCase():"" });
fvar.val(varName);
fvar.trigger("change");
@@ -453,13 +451,11 @@
tabs.activateTab("func-tab-body");
$( "#node-input-outputs" ).spinner({
min: 0,
max: 500,
min:0,
change: function(event, ui) {
var value = parseInt(this.value);
value = isNaN(value) ? 1 : value;
value = Math.max(value, parseInt($(this).attr("aria-valuemin")));
value = Math.min(value, parseInt($(this).attr("aria-valuemax")));
var value = this.value;
if (!value.match(/^\d+$/)) { value = 1; }
else if (value < this.min) { value = this.min; }
if (value !== this.value) { $(this).spinner("value", value); }
}
});

View File

@@ -318,7 +318,7 @@ module.exports = function(RED) {
}
var r = node.rules[currentRule];
if (r.t === "move") {
if ((r.tot !== r.pt) || (r.p.indexOf(r.to) !== -1) && (r.p !== r.to)) {
if ((r.tot !== r.pt) || (r.p.indexOf(r.to) !== -1)) {
applyRule(msg,{t:"set", p:r.to, pt:r.tot, to:r.p, tot:r.pt},(err,msg) => {
applyRule(msg,{t:"delete", p:r.p, pt:r.pt}, (err,msg) => {
completeApplyingRules(msg,currentRule,done);

View File

@@ -10,7 +10,6 @@
<option value="scale" data-i18n="range.scale.payload"></option>
<option value="clamp" data-i18n="range.scale.limit"></option>
<option value="roll" data-i18n="range.scale.wrap"></option>
<option value="drop" data-i18n="range.scale.drop"></option>
</select>
</div>
<br/>

View File

@@ -32,15 +32,11 @@ module.exports = function(RED) {
if (value !== undefined) {
var n = Number(value);
if (!isNaN(n)) {
if (node.action === "drop") {
if (n < node.minin) { done(); return; }
if (n > node.maxin) { done(); return; }
}
if (node.action === "clamp") {
if (node.action == "clamp") {
if (n < node.minin) { n = node.minin; }
if (n > node.maxin) { n = node.maxin; }
}
if (node.action === "roll") {
if (node.action == "roll") {
var divisor = node.maxin - node.minin;
n = ((n - node.minin) % divisor + divisor) % divisor + node.minin;
}

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