Merge branch 'dev' into pr_2165
							
								
								
									
										7
									
								
								.github/ISSUE_TEMPLATE/-anything-else.md
									
									
									
									
										vendored
									
									
								
							
							
						
						| @@ -7,8 +7,11 @@ assignees: '' | ||||
|  | ||||
| --- | ||||
|  | ||||
| Please use the [Node-RED Forum](https://discourse.nodered.org) or [slack team](https://nodered.org/slack). | ||||
| Please DO NOT raise an issue. | ||||
|  | ||||
| You could also consider asking a question on [Stack Overflow](https://stackoverflow.com/questions/tagged/node-red) and tag it `node-red`. | ||||
| We DO NOT use the issue tracker for general support or feature requests. Only bug reports should be raised here using the 'Bug report' template. | ||||
|  | ||||
| For general support, please use the [Node-RED Forum](https://discourse.nodered.org) or [slack team](https://nodered.org/slack). You could also consider asking a question on [Stack Overflow](https://stackoverflow.com/questions/tagged/node-red) and tag it `node-red`.  | ||||
| That way the whole Node-RED user community can help, rather than rely on the core development team. | ||||
|  | ||||
| For feature requests, please use the Node-RED Forum](https://discourse.nodered.org). Many ideas have already been discussed there and you should search that for your request before starting a new discussion. | ||||
|   | ||||
							
								
								
									
										67
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						| @@ -1,3 +1,70 @@ | ||||
| #### 1.0.0-beta.2: Beta Release | ||||
|  | ||||
| Runtime | ||||
|  - Fix length calculation when loading library file | ||||
|  | ||||
| #### 1.0.0-beta.1: Beta Release | ||||
|  | ||||
| Runtime | ||||
|  - Update runtime apis to support multiple libraries | ||||
|  - Add Node 12 to travis (allow_failures) | ||||
|  - Bump all dependencies Fixes #2152 | ||||
|  | ||||
| Editor | ||||
|  - [BREAKING] complete overhaul of editor DOM/CSS structure | ||||
|  - [BREAKING] Get rid of Bootstrap | ||||
|  - Simplify index.mst to a single div to insert the editor | ||||
|  - Append node configs to div rather than body | ||||
|  - Only redraw node status when it has changed | ||||
|  - Minimise work done to calculate node label widths | ||||
|  - Allow script tags with src to reference esm modules | ||||
|  - Upgrade to jq 3.4.1 / jq-ui 1.12.1 | ||||
|  - Allow editor language to be chosen in editor settings | ||||
|  - Only NLS status text that starts with a letter Fixes #2128 | ||||
|  - Fix display of link node list within subflow Fixes #2140 | ||||
|  - Blur the active element when closing edit dialog via action Fixes #2097 | ||||
|  - Trigger change evnt on typedInput when type changes and options present Fixes #2160 | ||||
|  - Move library import/export to single dialog | ||||
|  - Move type-library dialogs to new style dialog | ||||
|  - Fix node drag and drop animation | ||||
|  - let status be simple text if wanted | ||||
|  - Add workspace statusBar | ||||
|  - Complete refresh of German translations | ||||
|  - Fix memory leak in Debug sidebar #2163 | ||||
|  - Introduce toggleButton and move flow-disabled to use it | ||||
|  - Allow RED.settings.get/set to use full property desc | ||||
|  - Add auto-refresh toggle to context sidebar | ||||
|  - Add build-custom-theme script | ||||
|  - Add RED.view.selectNodes api for node selection whilst editing | ||||
|  - Add node-select to typedInput | ||||
|  | ||||
| Nodes | ||||
|  - http request node: warn user if msg.requestTimeout == 0 | ||||
|  - hide delay node reset label on deploy | ||||
|  - Fix CSV regex to treat strings starting e as text | ||||
|  - Add "don't parse numbers" option to csv node | ||||
|  - Add expand editor button to Template node | ||||
|  - Update catch/status nodes to use selectNodes api and treeList | ||||
|  | ||||
| #### 0.20.7: Maintenance Release | ||||
|  | ||||
|  - Update jsonata to 1.6.5 which should fix #2183 | ||||
|  - Ensure the subflow stop promise is waiting for before restarting | ||||
|  - Properly escape node types in palette | ||||
|  | ||||
| #### 0.20.6: Maintenance Release | ||||
|  | ||||
|  - Revealing node position needs to account for zoom level Fixes #2172 | ||||
|  - stop join tripping up if last message of buffer is blank. | ||||
|  - Improve handling of file upload in request node | ||||
|  - Handle subflow internal node wired to a non-existant node Fixes #2202 | ||||
|  - Do not save subflow env vars with blank names | ||||
|  - Don't allow a link node virtual wire to connect to normal port | ||||
|  - Clear HTTP Request node authType when auth disabled Fixes #2215 | ||||
|  - Fix parsing of content-type header Fixes #2216 | ||||
|  - Fix join node reset issue with merging objects | ||||
|  - Copy data-i18n attribute on TypedInput Fixes #2211 | ||||
|  | ||||
| #### 0.20.5: Maintenance Release | ||||
|  | ||||
|  - Revert error handling in palette manager | ||||
|   | ||||
| @@ -145,6 +145,7 @@ module.exports = function(grunt) { | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/common/tabs.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/common/stack.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/common/toggleButton.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/actions.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/deploy.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/diff.js", | ||||
| @@ -168,6 +169,7 @@ module.exports = function(grunt) { | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/library.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/notifications.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/search.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/actionList.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/typeSearch.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/subflow.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/userSettings.js", | ||||
| @@ -182,7 +184,7 @@ module.exports = function(grunt) { | ||||
|             vendor: { | ||||
|                 files: { | ||||
|                     "packages/node_modules/@node-red/editor-client/public/vendor/vendor.js": [ | ||||
|                         "packages/node_modules/@node-red/editor-client/src/vendor/jquery/js/jquery-3.3.1.min.js", | ||||
|                         "packages/node_modules/@node-red/editor-client/src/vendor/jquery/js/jquery-3.4.1.min.js", | ||||
|                         "packages/node_modules/@node-red/editor-client/src/vendor/jquery/js/jquery-migrate-3.0.1.min.js", | ||||
|                         "packages/node_modules/@node-red/editor-client/src/vendor/jquery/js/jquery-ui.min.js", | ||||
|                         "packages/node_modules/@node-red/editor-client/src/vendor/jquery/js/jquery.ui.touch-punch.min.js", | ||||
|   | ||||
							
								
								
									
										33
									
								
								package.json
									
									
									
									
									
								
							
							
						
						| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "node-red", | ||||
|     "version": "0.21.0-alpha.0", | ||||
|     "version": "1.0.0-beta.2", | ||||
|     "description": "A visual tool for wiring the Internet of Things", | ||||
|     "homepage": "http://nodered.org", | ||||
|     "license": "Apache-2.0", | ||||
| @@ -31,25 +31,26 @@ | ||||
|         "cheerio": "0.22.0", | ||||
|         "clone": "2.1.2", | ||||
|         "content-type": "1.0.4", | ||||
|         "cookie": "0.3.1", | ||||
|         "cookie": "0.4.0", | ||||
|         "cookie-parser": "1.4.4", | ||||
|         "cors": "2.8.5", | ||||
|         "cron": "1.7.1", | ||||
|         "denque": "1.4.1", | ||||
|         "express": "4.16.4", | ||||
|         "express-session": "1.16.1", | ||||
|         "fs-extra": "7.0.1", | ||||
|         "express": "4.17.1", | ||||
|         "express-session": "1.16.2", | ||||
|         "fs-extra": "8.1.0", | ||||
|         "fs.notify": "0.0.4", | ||||
|         "hash-sum": "1.0.2", | ||||
|         "hash-sum": "2.0.0", | ||||
|         "https-proxy-agent": "2.2.1", | ||||
|         "i18next": "15.1.0", | ||||
|         "iconv-lite": "0.4.24", | ||||
|         "i18next": "15.1.2", | ||||
|         "iconv-lite": "0.5.0", | ||||
|         "is-utf8": "0.2.1", | ||||
|         "js-yaml": "3.13.1", | ||||
|         "json-stringify-safe": "5.0.1", | ||||
|         "jsonata": "1.6.4", | ||||
|         "jsonata": "1.6.5", | ||||
|         "media-typer": "1.1.0", | ||||
|         "memorystore": "1.6.1", | ||||
|         "mime": "2.4.2", | ||||
|         "mime": "2.4.4", | ||||
|         "mqtt": "2.18.8", | ||||
|         "multer": "1.4.1", | ||||
|         "mustache": "3.0.1", | ||||
| @@ -62,19 +63,19 @@ | ||||
|         "passport": "0.4.0", | ||||
|         "passport-http-bearer": "1.0.1", | ||||
|         "passport-oauth2-client-password": "0.1.2", | ||||
|         "raw-body": "2.4.0", | ||||
|         "raw-body": "2.4.1", | ||||
|         "request": "2.88.0", | ||||
|         "semver": "6.0.0", | ||||
|         "uglify-js": "3.5.9", | ||||
|         "semver": "6.2.0", | ||||
|         "uglify-js": "3.6.0", | ||||
|         "when": "3.7.8", | ||||
|         "ws": "6.2.1", | ||||
|         "xml2js": "0.4.19" | ||||
|     }, | ||||
|     "optionalDependencies": { | ||||
|         "bcrypt": "3.0.5" | ||||
|         "bcrypt": "3.0.6" | ||||
|     }, | ||||
|     "devDependencies": { | ||||
|         "grunt": "~1.0.3", | ||||
|         "grunt": "~1.0.4", | ||||
|         "grunt-chmod": "~1.1.1", | ||||
|         "grunt-cli": "~1.3.2", | ||||
|         "grunt-concurrent": "~2.3.1", | ||||
| @@ -108,7 +109,7 @@ | ||||
|         "wdio-mocha-framework": "^0.6.4", | ||||
|         "wdio-spec-reporter": "^0.1.5", | ||||
|         "webdriverio": "^4.14.1", | ||||
|         "node-red-node-test-helper": "^0.2.2", | ||||
|         "node-red-node-test-helper": "^0.2.3", | ||||
|         "jsdoc-nr-template": "node-red/jsdoc-nr-template" | ||||
|     }, | ||||
|     "engines": { | ||||
|   | ||||
| @@ -56,7 +56,7 @@ function expireSessions() { | ||||
|     } | ||||
|     if (nextExpiry < Number.MAX_SAFE_INTEGER) { | ||||
|         // Allow 5 seconds grace | ||||
|         expiryTimeout = setTimeout(expireSessions,(nextExpiry - Date.now()) + 5000) | ||||
|         expiryTimeout = setTimeout(expireSessions,Math.min(2147483647,(nextExpiry - Date.now()) + 5000)) | ||||
|     } | ||||
|     if (modified) { | ||||
|         return storage.saveSessions(sessions); | ||||
| @@ -129,7 +129,7 @@ module.exports = { | ||||
|             sessions[accessToken] = session; | ||||
|  | ||||
|             if (!expiryTimeout) { | ||||
|                 expiryTimeout = setTimeout(expireSessions,(accessTokenExpiresAt - Date.now()) + 5000) | ||||
|                 expiryTimeout = setTimeout(expireSessions,Math.min(2147483647,(accessTokenExpiresAt - Date.now()) + 5000)) | ||||
|             } | ||||
|  | ||||
|             return storage.saveSessions(sessions).then(function() { | ||||
|   | ||||
| @@ -28,7 +28,7 @@ var defaultContext = { | ||||
|     }, | ||||
|     header: { | ||||
|         title: "Node-RED", | ||||
|         image: "red/images/node-red.png" | ||||
|         image: "red/images/node-red.svg" | ||||
|     }, | ||||
|     asset: { | ||||
|         red: (process.env.NODE_ENV == "development")? "red/red.js":"red/red.min.js", | ||||
|   | ||||
| @@ -25,7 +25,7 @@ var theme = require("./theme"); | ||||
|  | ||||
| var runtimeAPI; | ||||
| var editorClientDir = path.dirname(require.resolve("@node-red/editor-client")); | ||||
| var defaultNodeIcon = path.join(editorClientDir,"public","red","images","icons","arrow-in.png"); | ||||
| var defaultNodeIcon = path.join(editorClientDir,"public","red","images","icons","arrow-in.svg"); | ||||
| var editorTemplatePath = path.join(editorClientDir,"templates","index.mst"); | ||||
| var editorTemplate; | ||||
|  | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@node-red/editor-api", | ||||
|     "version": "0.21.0-alpha.0", | ||||
|     "version": "1.0.0-beta.2", | ||||
|     "license": "Apache-2.0", | ||||
|     "main": "./lib/index.js", | ||||
|     "repository": { | ||||
| @@ -16,16 +16,16 @@ | ||||
|         } | ||||
|     ], | ||||
|     "dependencies": { | ||||
|         "@node-red/util": "0.21.0-alpha.0", | ||||
|         "@node-red/editor-client": "0.21.0-alpha.0", | ||||
|         "@node-red/util": "1.0.0-beta.2", | ||||
|         "@node-red/editor-client": "1.0.0-beta.2", | ||||
|         "bcryptjs": "2.4.3", | ||||
|         "body-parser": "1.19.0", | ||||
|         "clone": "2.1.2", | ||||
|         "cors": "2.8.5", | ||||
|         "express-session": "1.16.1", | ||||
|         "express": "4.16.4", | ||||
|         "express-session": "1.16.2", | ||||
|         "express": "4.17.1", | ||||
|         "memorystore": "1.6.1", | ||||
|         "mime": "2.4.2", | ||||
|         "mime": "2.4.4", | ||||
|         "mustache": "3.0.1", | ||||
|         "oauth2orize": "1.11.0", | ||||
|         "passport-http-bearer": "1.0.1", | ||||
| @@ -35,6 +35,6 @@ | ||||
|         "ws": "6.2.1" | ||||
|     }, | ||||
|     "optionalDependencies": { | ||||
|         "bcrypt": "3.0.5" | ||||
|         "bcrypt": "3.0.6" | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -48,9 +48,9 @@ | ||||
|       }, | ||||
|       "settings" : "Einstellungen", | ||||
|       "userSettings" : "Benutzereinstellungen", | ||||
|       "nodes" : "Knoten", | ||||
|       "displayStatus" : "Knotenstatus anzeigen", | ||||
|       "displayConfig" : "Konfigurationsknoten", | ||||
|       "nodes" : "Nodes", | ||||
|       "displayStatus" : "Nodestatus anzeigen", | ||||
|       "displayConfig" : "Konfigurations-Node", | ||||
|       "import" : "Import", | ||||
|       "export" : "Exportieren", | ||||
|       "search" : "Flows durchsuchen", | ||||
| @@ -84,17 +84,17 @@ | ||||
|     "notAuthorized" : "Keine Berechtigung", | ||||
|     "errors" : { | ||||
|       "settings" : "Sie müssen angemeldet sein, um auf die Einstellungen zuzugreifen.", | ||||
|       "deploy" : "Sie müssen angemeldet sein, um Änderungen implementieren zu können.", | ||||
|       "deploy" : "Sie müssen angemeldet sein, um Änderungen anwenden zu können.", | ||||
|       "notAuthorized" : "Sie müssen angemeldet sein, um diese Aktion ausführen zu können." | ||||
|     } | ||||
|   }, | ||||
|   "notification" : { | ||||
|     "warning" : "<strong> Warnung </strong>: __message__", | ||||
|     "warnings" : { | ||||
|       "undeployedChanges" : "Knoten hat nicht implementierte Änderungen", | ||||
|       "nodeActionDisabled" : "In Subflow inaktivierte Knotenaktionen", | ||||
|       "missing-types" : "<p> Die Flows wurden aufgrund fehlender Knotentypen gestoppt. </p>", | ||||
|       "restartRequired" : "Knoten-RED muss erneut gestartet werden, damit aufgerüstete Module aktiviert werden können", | ||||
|       "undeployedChanges" : "Node hat nicht implementierte Änderungen", | ||||
|       "nodeActionDisabled" : "In Subflow inaktivierte Nodeaktionen", | ||||
|       "missing-types" : "<p> Die Flows wurden aufgrund fehlender Nodetypen gestoppt. </p>", | ||||
|       "restartRequired" : "Node-RED muss erneut gestartet werden, damit aufgerüstete Module aktiviert werden können", | ||||
|       "credentials_load_failed" : "<p> Die Flows wurden gestoppt, da die Berechtigungsnachweise nicht entschlüsselt werden konnten. </p> <p> Die Datei mit dem Datenflowberechtigungsnachweis ist verschlüsselt, aber der Verschlüsselungsschlüssel des Projekts fehlt oder ist ungültig. </p>", | ||||
|       "credentials_load_failed_reset" : "<p> Die Berechtigungsnachweise konnten nicht entschlüsselt werden </p> <p> Die Datei mit dem Flow-Berechtigungsnachweis ist verschlüsselt, aber der Chiffrierschlüssel des Projekts fehlt oder ist ungültig. </p> <p> Die Datei des Flow-Berechtigungsnachweises wird bei der nächsten Implementierung zurückgesetzt. Alle vorhandenen Datenflowberechtigungsnachweise werden gelöscht. </p>", | ||||
|       "missing_flow_file" : "<p> Die Projektflowdatei wurde nicht gefunden. </p> <p> Das Projekt ist nicht mit einer Flow-Datei konfiguriert. </p>", | ||||
| @@ -134,18 +134,18 @@ | ||||
|   }, | ||||
|   "clipboard" : { | ||||
|     "clipboard" : "Zwischenablage", | ||||
|     "nodes" : "Knoten", | ||||
|     "pasteNodes" : "Knoten hier einfügen", | ||||
|     "importNodes" : "Knoten importieren", | ||||
|     "exportNodes" : "Knoten in Zwischenablage exportieren", | ||||
|     "nodes" : "Nodes", | ||||
|     "pasteNodes" : "Nodes hier einfügen", | ||||
|     "importNodes" : "Nodes importieren", | ||||
|     "exportNodes" : "Nodes in Zwischenablage exportieren", | ||||
|     "importUnrecognised" : "Importierter Typ nicht erkannt:", | ||||
|     "importUnrecognised_plural" : "Importierte Typen nicht erkannt:", | ||||
|     "nodesExported" : "Knoten, die in die Zwischenablage exportiert wurden", | ||||
|     "nodeCopied" : "__count__ Knoten kopiert", | ||||
|     "nodeCopied_plural" : "__count__ Knoten kopiert", | ||||
|     "nodesExported" : "Nodes, die in die Zwischenablage exportiert wurden", | ||||
|     "nodeCopied" : "__count__ Node kopiert", | ||||
|     "nodeCopied_plural" : "__count__ Nodes kopiert", | ||||
|     "invalidFlow" : "Ungültiger Nachrichtenflow: __message__", | ||||
|     "export" : { | ||||
|       "selected" : "Ausgewählte Knoten", | ||||
|       "selected" : "Ausgewählte Nodes", | ||||
|       "current" : "Aktueller Flow", | ||||
|       "all" : "alle Flows", | ||||
|       "compact" : "kompakt", | ||||
| @@ -161,16 +161,16 @@ | ||||
|     "copyMessageValue_truncated" : "Abgeschnittene Wert kopiert" | ||||
|   }, | ||||
|   "deploy" : { | ||||
|     "deploy" : "Implementieren", | ||||
|     "deploy" : "deploy", | ||||
|     "full" : "Voll", | ||||
|     "fullDesc" : "Implementiert alles im Arbeitsbereich", | ||||
|     "modifiedFlows" : "Geänderte Flows", | ||||
|     "modifiedFlowsDesc" : "Implementiert nur Flows, die geänderte Knoten enthalten.", | ||||
|     "modifiedNodes" : "Geänderte Knoten", | ||||
|     "modifiedNodesDesc" : "Implementiert nur Knoten, die sich geändert haben.", | ||||
|     "modifiedFlowsDesc" : "Implementiert nur Flows, die geänderte Nodes enthalten.", | ||||
|     "modifiedNodes" : "Geänderte Nodes", | ||||
|     "modifiedNodesDesc" : "Implementiert nur Nodes, die sich geändert haben.", | ||||
|     "successfulDeploy" : "Erfolgreich implementiert", | ||||
|     "deployFailed" : "Implementieren fehlgeschlagen: __message__", | ||||
|     "unusedConfigNodes" : "Sie haben einige nicht verwendete Konfigurationsknoten.", | ||||
|     "deployFailed" : "Deploy fehlgeschlagen: __message__", | ||||
|     "unusedConfigNodes" : "Sie haben einige nicht verwendete Konfigurations-Nodes.", | ||||
|     "unusedConfigNodesLink" : "Klicken Sie hier, um sie zu sehen", | ||||
|     "errors" : { | ||||
|       "noResponse" : "Keine Antwort vom Server" | ||||
| @@ -178,16 +178,16 @@ | ||||
|     "confirm" : { | ||||
|       "button" : { | ||||
|         "ignore" : "Ignorieren", | ||||
|         "confirm" : "Implementieren bestätigen", | ||||
|         "confirm" : "Deploy bestätigen", | ||||
|         "review" : "Änderungen prüfen", | ||||
|         "cancel" : "Abbrechen", | ||||
|         "merge" : "Zusammenführen", | ||||
|         "overwrite" : "Ignorieren & implementieren" | ||||
|         "overwrite" : "Ignorieren & deployen" | ||||
|       }, | ||||
|       "undeployedChanges" : "Sie haben nicht implementierte Änderungen.\n\nWenn Sie diese Seite verlassen, gehen diese Änderungen verloren.", | ||||
|       "improperlyConfigured" : "Der Arbeitsbereich enthält einige Knoten, die nicht ordnungsgemäß konfiguriert sind:", | ||||
|       "unknown" : "Der Arbeitsbereich enthält einige unbekannte Knotentypen:", | ||||
|       "confirm" : "Sind Sie sicher, dass Sie implementieren möchten?", | ||||
|       "improperlyConfigured" : "Der Arbeitsbereich enthält einige Nodes, die nicht ordnungsgemäß konfiguriert sind:", | ||||
|       "unknown" : "Der Arbeitsbereich enthält einige unbekannte Node-Typen:", | ||||
|       "confirm" : "Sind Sie sicher, dass Sie deployen möchten?", | ||||
|       "doNotWarn" : "warnen Sie nicht noch einmal.", | ||||
|       "conflict" : "Auf dem Server wird eine aktuellere Gruppe von Datenflüssen ausgeführt.", | ||||
|       "backgroundUpdate" : "Die Datenflüsse auf dem Server wurden aktualisiert.", | ||||
| @@ -200,7 +200,7 @@ | ||||
|   "diff" : { | ||||
|     "unresolvedCount" : "__count__ unaufgelöster Konflikt", | ||||
|     "unresolvedCount_plural" : "__count__ unaufgelöste Konflikte", | ||||
|     "globalNodes" : "Globale Knoten", | ||||
|     "globalNodes" : "Globale Nodes", | ||||
|     "flowProperties" : "Flow-Eigenschaften", | ||||
|     "type" : { | ||||
|       "added" : "hinzugefügt", | ||||
| @@ -212,8 +212,8 @@ | ||||
|       "movedTo" : "verschoben zu __id__", | ||||
|       "movedFrom" : "verschoben von __id__" | ||||
|     }, | ||||
|     "nodeCount" : "__count__, Knoten", | ||||
|     "nodeCount_plural" : "__count__-Knoten", | ||||
|     "nodeCount" : "__count__, Node", | ||||
|     "nodeCount_plural" : "__count__-Nodes", | ||||
|     "local" : "Lokale Änderungen", | ||||
|     "remote" : "Ferne Änderungen", | ||||
|     "reviewChanges" : "Änderungen prüfen", | ||||
| @@ -239,7 +239,7 @@ | ||||
|     "category" : "Kategorie", | ||||
|     "format" : "Markdown-Format", | ||||
|     "errors" : { | ||||
|       "noNodesSelected" : "<strong> Subflow kann nicht erstellt werden </strong>: Es wurden keine Knoten ausgewählt.", | ||||
|       "noNodesSelected" : "<strong> Subflow kann nicht erstellt werden </strong>: Es wurden keine Nodes ausgewählt.", | ||||
|       "multipleInputsToSelection" : "<strong> Subflow kann nicht erstellt werden </strong>: Mehrere Eingaben zur Auswahl" | ||||
|     } | ||||
|   }, | ||||
| @@ -249,13 +249,13 @@ | ||||
|     "configUpdate" : "Aktualisieren", | ||||
|     "configDelete" : "Löschen", | ||||
|     "nodesUse" : "__count__node verwendet diese Konfiguration", | ||||
|     "nodesUse_plural" : "__count__ -Knoten verwenden diese Konfiguration", | ||||
|     "addNewConfig" : "Neuen __type__config-Knoten hinzufügen", | ||||
|     "editNode" : "__type__ Knoten bearbeiten", | ||||
|     "editConfig" : "__type__config-Knoten bearbeiten", | ||||
|     "nodesUse_plural" : "__count__ -Nodes verwenden diese Konfiguration", | ||||
|     "addNewConfig" : "Neuen __type__config-Node hinzufügen", | ||||
|     "editNode" : "__type__ Node bearbeiten", | ||||
|     "editConfig" : "__type__config-Node bearbeiten", | ||||
|     "addNewType" : "Neuen __type__ hinzufügen ...", | ||||
|     "nodeProperties" : "Knoteneigenschaften", | ||||
|     "portLabels" : "Knoteneinstellungen", | ||||
|     "nodeProperties" : "Node-Eigenschaften", | ||||
|     "portLabels" : "Node-Einstellungen", | ||||
|     "labelInputs" : "Eingänge", | ||||
|     "labelOutputs" : "Ausgänge", | ||||
|     "settingIcon" : "Symbol", | ||||
| @@ -264,7 +264,7 @@ | ||||
|     "searchIcons" : "Suchsymbole", | ||||
|     "useDefault" : "Standardwert verwenden", | ||||
|     "errors" : { | ||||
|       "scopeChange" : "Wenn Sie den Geltungsbereich ändern, wird er für Knoten in anderen Nachrichtenflüssen, die ihn verwenden, nicht verfügbar sein." | ||||
|       "scopeChange" : "Wenn Sie den Geltungsbereich ändern, wird er für Nodes in anderen Nachrichtenflüssen, die ihn verwenden, nicht verfügbar sein." | ||||
|     } | ||||
|   }, | ||||
|   "keyboard" : { | ||||
| @@ -276,19 +276,19 @@ | ||||
|     "unassigned" : "Nicht zugeordnet", | ||||
|     "global" : "global", | ||||
|     "workspace" : "Arbeitsbereich", | ||||
|     "selectAll" : "Alle Knoten auswählen", | ||||
|     "selectAllConnected" : "Alle verbundenen Knoten auswählen", | ||||
|     "addRemoveNode" : "Knoten aus Auswahl hinzufügen/entfernen", | ||||
|     "editSelected" : "Ausgewählten Knoten bearbeiten", | ||||
|     "deleteSelected" : "Ausgewählte Knoten oder ausgewählten Link löschen", | ||||
|     "importNode" : "Knoten importieren", | ||||
|     "exportNode" : "Knoten exportieren", | ||||
|     "nudgeNode" : "Ausgewählte Knoten verschieben (1px)", | ||||
|     "moveNode" : "Ausgewählte Knoten verschieben (20px)", | ||||
|     "selectAll" : "Alle Nodes auswählen", | ||||
|     "selectAllConnected" : "Alle verbundenen Nodes auswählen", | ||||
|     "addRemoveNode" : "Node aus Auswahl hinzufügen/entfernen", | ||||
|     "editSelected" : "Ausgewählten Node bearbeiten", | ||||
|     "deleteSelected" : "Ausgewählte Node oder ausgewählten Link löschen", | ||||
|     "importNode" : "Node importieren", | ||||
|     "exportNode" : "Node exportieren", | ||||
|     "nudgeNode" : "Ausgewählte Nodes verschieben (1px)", | ||||
|     "moveNode" : "Ausgewählte Nodes verschieben (20px)", | ||||
|     "toggleSidebar" : "Seitenleiste ein-/ausschalten", | ||||
|     "copyNode" : "Ausgewählte Knoten kopieren", | ||||
|     "cutNode" : "Ausgewählte Knoten ausschneiden", | ||||
|     "pasteNode" : "Knoten einfügen", | ||||
|     "copyNode" : "Ausgewählte Nodes kopieren", | ||||
|     "cutNode" : "Ausgewählte Nodes ausschneiden", | ||||
|     "pasteNode" : "Node einfügen", | ||||
|     "undoChange" : "Letzte Änderung rückgängig machen", | ||||
|     "searchBox" : "Suchfeld öffnen", | ||||
|     "managePalette" : "Palette verwalten" | ||||
| @@ -301,7 +301,7 @@ | ||||
|     "unnamedType" : "Unbenannt __type__", | ||||
|     "dialogSaveOverwrite" : "Ein __libraryType__ mit dem Namen __libraryName__ ist bereits vorhanden. Überschreiben?", | ||||
|     "invalidFilename" : "Ungültiger Dateiname", | ||||
|     "savedNodes" : "Gespeicherte Knoten", | ||||
|     "savedNodes" : "Gespeicherte Nodes", | ||||
|     "savedType" : "Gespeichert __type__", | ||||
|     "saveFailed" : "Speichern fehlgeschlagen: __message__", | ||||
|     "types": { | ||||
| @@ -310,11 +310,11 @@ | ||||
|   }, | ||||
|   "palette" : { | ||||
|     "noInfo" : "Keine Informationen verfügbar", | ||||
|     "filter" : "Filterknoten", | ||||
|     "filter" : "Filter Nodes", | ||||
|     "search" : "Suchmodule", | ||||
|     "addCategory" : "Neu hinzufügen ...", | ||||
|     "label" : { | ||||
|       "subflows" : "untergeordnete Nachrichtenflüsse", | ||||
|       "subflows" : "Subflows", | ||||
|       "input" : "Eingabe", | ||||
|       "output" : "Ausgabe", | ||||
|       "function" : "Funktion", | ||||
| @@ -324,15 +324,15 @@ | ||||
|       "advanced" : "fortgeschritten" | ||||
|     }, | ||||
|     "event" : { | ||||
|       "nodeAdded" : "Knoten zur Palette hinzugefügt:", | ||||
|       "nodeAdded_plural" : "Die Palette wurde der Palette hinzugefügt.", | ||||
|       "nodeRemoved" : "Knoten aus Palette entfernt:", | ||||
|       "nodeRemoved_plural" : "Knoten aus Palette entfernt:", | ||||
|       "nodeEnabled" : "Knoten aktiviert:", | ||||
|       "nodeEnabled_plural" : "Knoten aktiviert:", | ||||
|       "nodeDisabled" : "Knoten inaktiviert:", | ||||
|       "nodeDisabled_plural" : "Knoten inaktiviert:", | ||||
|       "nodeUpgraded" : "Knotenmodul __module__ aktualisiert auf Version __version__" | ||||
|       "nodeAdded" : "Node zur Palette hinzugefügt:", | ||||
|       "nodeAdded_plural" : "Die Nodes wurde der Palette hinzugefügt.", | ||||
|       "nodeRemoved" : "Node aus Palette entfernt:", | ||||
|       "nodeRemoved_plural" : "Nodes aus Palette entfernt:", | ||||
|       "nodeEnabled" : "Node aktiviert:", | ||||
|       "nodeEnabled_plural" : "Nodes aktiviert:", | ||||
|       "nodeDisabled" : "Node inaktiviert:", | ||||
|       "nodeDisabled_plural" : "Nodes inaktiviert:", | ||||
|       "nodeUpgraded" : "Node-Modul __module__ aktualisiert auf Version __version__" | ||||
|     }, | ||||
|     "editor" : { | ||||
|       "title" : "Palette verwalten", | ||||
| @@ -356,8 +356,8 @@ | ||||
|         "yearsMonthsV" : "____ Jahre, __count__ Monat vor", | ||||
|         "yearsMonthsV_plural" : "____ Jahre, __count__ Monaten" | ||||
|       }, | ||||
|       "nodeCount" : "__label__, Knoten", | ||||
|       "nodeCount_plural" : "__label__ Knoten", | ||||
|       "nodeCount" : "__label__, Node", | ||||
|       "nodeCount_plural" : "__label__ Nodes", | ||||
|       "moduleCount" : "__count__ Modul verfügbar", | ||||
|       "moduleCount_plural" : "__count__-Module verfügbar", | ||||
|       "inuse" : "im Gebrauch", | ||||
| @@ -371,14 +371,14 @@ | ||||
|       "install" : "installieren", | ||||
|       "installed" : "installiert", | ||||
|       "loading" : "Kataloge werden geladen ...", | ||||
|       "tab-nodes" : "Knoten", | ||||
|       "tab-nodes" : "Nodes", | ||||
|       "tab-install" : "installieren", | ||||
|       "sort" : "Sortierung:", | ||||
|       "sortAZ" : "a-z", | ||||
|       "sortRecent" : "kürzlich", | ||||
|       "more" : "+ __count__ mehr", | ||||
|       "errors" : { | ||||
|         "catalogLoadFailed" : "<p> Fehler beim Laden des Knotenkatalogs. </p> <p> Weitere Informationen finden Sie in der Browserkonsole. </p>", | ||||
|         "catalogLoadFailed" : "<p> Fehler beim Laden des Node-Katalogs. </p> <p> Weitere Informationen finden Sie in der Browserkonsole. </p>", | ||||
|         "installFailed" : "<p> Installation fehlgeschlagen: __module__ </p> <p> __message__ </p> <p> Überprüfen Sie das Protokoll auf weitere Informationen. </p>", | ||||
|         "removeFailed" : "<p> Entfernen fehlgeschlagen: __module__ </p> <p> __message__ </p> <p> Überprüfen Sie das Protokoll auf weitere Informationen. </p>", | ||||
|         "updateFailed" : "<p> Aktualisierung fehlgeschlagen: __module__ </p> <p> __message__ </p> <p> Überprüfen Sie das Protokoll auf weitere Informationen. </p>", | ||||
| @@ -387,22 +387,22 @@ | ||||
|       }, | ||||
|       "confirm" : { | ||||
|         "install" : { | ||||
|           "body" : "<p> Installieren von '__module__' </p> <p> Vor der Installation von lesen Sie bitte die Dokumentation des Knotens. Einige Knoten haben Abhängigkeiten, die nicht automatisch aufgelöst werden können und einen Neustart von 'Node-RED' erfordern. </p>", | ||||
|           "title" : "Knoten installieren" | ||||
|           "body" : "<p> Installieren von '__module__' </p> <p> Vor der Installation von lesen Sie bitte die Dokumentation des Nodes. Einige Nodes haben Abhängigkeiten, die nicht automatisch aufgelöst werden können und einen Neustart von 'Node-RED' erfordern. </p>", | ||||
|           "title" : "Nodes installieren" | ||||
|         }, | ||||
|         "remove" : { | ||||
|           "body" : "<p> Entfernen von '__module__' </p> <p>-Der Knoten deinstalliert ihn aus Node-RED. Der Knoten kann weiterhin Ressourcen verwenden, bis Node-RED erneut gestartet wird. </p>", | ||||
|           "title" : "Knoten entfernen" | ||||
|           "body" : "<p> Entfernen von '__module__' </p> <p>-Der Node deinstalliert ihn aus Node-RED. Der Node kann weiterhin Ressourcen verwenden, bis Node-RED erneut gestartet wird. </p>", | ||||
|           "title" : "Nodes entfernen" | ||||
|         }, | ||||
|         "update" : { | ||||
|           "body" : "<p> Aktualisieren von '__module__' </p> <p> Für die Aktualisierung des Knotens ist ein Neustart von 'Node-RED' erforderlich, damit die Aktualisierung abgeschlossen werden kann. Dies muss manuell geschehen. </p>", | ||||
|           "title" : "Knoten aktualisieren" | ||||
|           "body" : "<p> Aktualisieren von '__module__' </p> <p> Für die Aktualisierung des Nodes ist ein Neustart von 'Node-RED' erforderlich, damit die Aktualisierung abgeschlossen werden kann. Dies muss manuell geschehen. </p>", | ||||
|           "title" : "Nodes aktualisieren" | ||||
|         }, | ||||
|         "cannotUpdate" : { | ||||
|           "body" : "Es ist eine Aktualisierung für diesen Knoten verfügbar, aber sie ist nicht an einer Position installiert, die vom Palettenmanager aktualisiert werden kann. <br/> <br/> Weitere Informationen zum Aktualisieren dieses Knotens finden Sie in der Dokumentation." | ||||
|           "body" : "Es ist eine Aktualisierung für diesen Node verfügbar, aber sie ist nicht an einer Position installiert, die vom Palettenmanager aktualisiert werden kann. <br/> <br/> Weitere Informationen zum Aktualisieren dieses Nodes finden Sie in der Dokumentation." | ||||
|         }, | ||||
|         "button" : { | ||||
|           "review" : "Knoteninformationen öffnen", | ||||
|           "review" : "Node-Informationen öffnen", | ||||
|           "install" : "installieren", | ||||
|           "remove" : "Entfernen", | ||||
|           "update" : "Aktualisieren" | ||||
| @@ -412,10 +412,10 @@ | ||||
|   }, | ||||
|   "sidebar" : { | ||||
|     "info" : { | ||||
|       "name" : "Knoteninformationen", | ||||
|       "name" : "Node-Informationen", | ||||
|       "tabName" : "Name", | ||||
|       "label" : "info", | ||||
|       "node" : "Knoten", | ||||
|       "node" : "Node", | ||||
|       "type" : "Typ", | ||||
|       "id" : "ID", | ||||
|       "status" : "Status", | ||||
| @@ -431,16 +431,16 @@ | ||||
|       "showLess" : "Weniger anzeigen", | ||||
|       "flow" : "Flow", | ||||
|       "selection" : "Auswahl", | ||||
|       "nodes" : "__count__ Knoten", | ||||
|       "nodes" : "__count__ Nodes", | ||||
|       "flowDesc" : "Beschreibung des Flows", | ||||
|       "subflowDesc" : "Beschreibung des Subflows", | ||||
|       "nodeHelp" : "Knotenhilfe", | ||||
|       "nodeHelp" : "Node-Hilfe", | ||||
|       "none" : "Keine", | ||||
|       "arrayItems" : "__count__ items", | ||||
|       "showTips" : "Sie können die Tipps in der Anzeige \"Einstellungen\" öffnen." | ||||
|     }, | ||||
|     "config" : { | ||||
|       "name" : "Konfigurationsknoten", | ||||
|       "name" : "Konfigurations-Node", | ||||
|       "label" : "Konfiguration", | ||||
|       "global" : "Bei allen Flows", | ||||
|       "none" : "keine", | ||||
| @@ -456,7 +456,7 @@ | ||||
|       "none" : "keine ausgewählt", | ||||
|       "refresh" : "Aktualisierung zum Laden", | ||||
|       "empty" : "leer", | ||||
|       "node" : "Knoten", | ||||
|       "node" : "Node", | ||||
|       "flow" : "Flow", | ||||
|       "global" : "Global" | ||||
|     }, | ||||
| @@ -604,13 +604,13 @@ | ||||
|   }, | ||||
|   "typedInput" : { | ||||
|     "type" : { | ||||
|       "str" : "Zeichenfolge", | ||||
|       "num" : "Anzahl", | ||||
|       "str" : "String", | ||||
|       "num" : "Number", | ||||
|       "re" : "Regulärer Ausdruck", | ||||
|       "bool" : "boolean", | ||||
|       "json" : "JSON", | ||||
|       "bin" : "Puffer", | ||||
|       "date" : "Zeitmarke", | ||||
|       "bin" : "Buffer", | ||||
|       "date" : "timestamp", | ||||
|       "jsonata" : "Ausdruck", | ||||
|       "env" : "env, Variable" | ||||
|     } | ||||
| @@ -620,7 +620,7 @@ | ||||
|   }, | ||||
|   "search" : { | ||||
|     "empty" : "Keine Übereinstimmungen gefunden", | ||||
|     "addNode" : "Knoten hinzufügen ..." | ||||
|     "addNode" : "Node hinzufügen ..." | ||||
|   }, | ||||
|   "expressionEditor" : { | ||||
|     "functions" : "Funktionen", | ||||
| @@ -652,10 +652,10 @@ | ||||
|     "title" : "Markdown-Editor" | ||||
|   }, | ||||
|   "bufferEditor" : { | ||||
|     "title" : "Puffereditor", | ||||
|     "title" : "Buffereditor", | ||||
|     "modeString" : "Als UTF-8-Zeichenfolge bearbeiten", | ||||
|     "modeArray" : "Als JSON-Array bearbeiten", | ||||
|     "modeDesc" : "<h3> Puffereditor </h3> <p> Der Puffertyp wird als JSON-Array mit Bytewerten gespeichert. Der Editor versucht, den eingegebenen Wert als JSON-Array zu parsen. Wenn es sich nicht um ein gültiges JSON handelt, wird es als UTF-8-Zeichenfolge behandelt und in ein Array der einzelnen Zeichencodepunkte konvertiert. </p> <p> Beispiel: Der Wert  <code> Hello World </code>  wird in das JSON-Array konvertiert: <pre> [ 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100] </pre> </p>" | ||||
|     "modeDesc" : "<h3> Buffereditor </h3> <p> Der Buffertyp wird als JSON-Array mit Bytewerten gespeichert. Der Editor versucht, den eingegebenen Wert als JSON-Array zu parsen. Wenn es sich nicht um ein gültiges JSON handelt, wird es als UTF-8-Zeichenfolge behandelt und in ein Array der einzelnen Zeichencodepunkte konvertiert. </p> <p> Beispiel: Der Wert  <code> Hello World </code>  wird in das JSON-Array konvertiert: <pre> [ 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100] </pre> </p>" | ||||
|   }, | ||||
|   "projects" : { | ||||
|     "config-git" : "Git-Client konfigurieren", | ||||
|   | ||||
| @@ -1,23 +1,23 @@ | ||||
| { | ||||
|   "info" : { | ||||
|     "tip0" : "Sie können die ausgewählten Knoten oder Verbindungen mit {{ core:delete-selection }} entfernen.", | ||||
|     "tip1" : "Suche nach Knoten mit {{ core:search }}", | ||||
|     "tip0" : "Sie können die ausgewählten Nodes oder Verbindungen mit {{ core:delete-selection }} entfernen.", | ||||
|     "tip1" : "Suche nach Nodes mit {{ core:search }}", | ||||
|     "tip2" : "{{ core:toggle-sidebar }} schaltet die Ansicht dieser Seitenleiste ein.", | ||||
|     "tip3" : "Sie können Ihre Palette von Knoten mit {{ core:manage-palette }} verwalten.", | ||||
|     "tip4" : "Ihre Flow-Konfigurationsknoten werden in der Seitenleiste angezeigt. Es kann über das Menü oder mit {{ core:show-config-tab }} aufgerufen werden.", | ||||
|     "tip3" : "Sie können Ihre Palette von Nodes mit {{ core:manage-palette }} verwalten.", | ||||
|     "tip4" : "Ihre Flow-Konfigurations-Nodes werden in der Seitenleiste angezeigt. Es kann über das Menü oder mit {{ core:show-config-tab }} aufgerufen werden.", | ||||
|     "tip5" : "Aktiviert oder inaktiviert diese Tipps von der Option in den Einstellungen", | ||||
|     "tip6" : "Verschieben Sie die ausgewählten Knoten mit Hilfe der [left] [up] [down] und [right] Tasten. Halten Sie [Shift] gedrückt, um das Fenster weiter zu schieben", | ||||
|     "tip7" : "Wenn Sie einen Knoten auf eine Verbindung ziehen, wird er in die Verbindung eingefügt.", | ||||
|     "tip8" : "Die ausgewählten Knoten exportieren oder die aktuelle Registerkarte mit {{ core:show-export-dialog }}", | ||||
|     "tip6" : "Verschieben Sie die ausgewählten Nodes mit Hilfe der [left] [up] [down] und [right] Tasten. Halten Sie [Shift] gedrückt, um das Fenster weiter zu schieben", | ||||
|     "tip7" : "Wenn Sie einen Node auf eine Verbindung ziehen, wird er in die Verbindung eingefügt.", | ||||
|     "tip8" : "Die ausgewählten Nodes exportieren oder die aktuelle Registerkarte mit {{ core:show-export-dialog }}", | ||||
|     "tip9" : "Importieren Sie einen Flow, indem Sie sein JSON in den Editor ziehen oder mit {{ core:show-import-dialog }}.", | ||||
|     "tip10" : "[Umschalt] [Klicken] und ziehen Sie auf einen Knotenanschluss, um alle angeschlossenen Verbindungen oder nur die ausgewählte zu verschieben.", | ||||
|     "tip10" : "[Umschalt] [Klicken] und ziehen Sie auf einen Node-Anschluss, um alle angeschlossenen Verbindungen oder nur die ausgewählte zu verschieben.", | ||||
|     "tip11" : "Die Registerkarte \"Info\" mit {{ core:show-info-tab }} oder der Registerkarte \"Debug\" mit {{ core:show-debug-tab }} anzeigen", | ||||
|     "tip12" : "[ctrl] [Klicken] in den Arbeitsbereich, um den Schnellhinzufügedialog zu öffnen.", | ||||
|     "tip13" : "Halten Sie [ctrl] gedrückt, wenn Sie auf einem Knotenanschluss klicken, um eine Schnellverbindung zu aktivieren.", | ||||
|     "tip14" : "Halten Sie [Umschalt] gedrückt, wenn Sie auf einen Knoten klicken, um auch alle verbundenen Knoten auszuwählen.", | ||||
|     "tip15" : "Halten Sie [ctrl] gedrückt, wenn Sie auf einen Knoten klicken, um ihn aus der aktuellen Auswahl hinzuzufügen oder zu entfernen.", | ||||
|     "tip13" : "Halten Sie [ctrl] gedrückt, wenn Sie auf einem Node-Anschluss klicken, um eine Schnellverbindung zu aktivieren.", | ||||
|     "tip14" : "Halten Sie [Umschalt] gedrückt, wenn Sie auf einen Node klicken, um auch alle verbundenen Nodes auszuwählen.", | ||||
|     "tip15" : "Halten Sie [ctrl] gedrückt, wenn Sie auf einen Node klicken, um ihn aus der aktuellen Auswahl hinzuzufügen oder zu entfernen.", | ||||
|     "tip16" : "Indexzungen wechseln mit {{ core:show-previous-tab }} und {{ core:show-next-tab }}", | ||||
|     "tip17" : "Sie können die Änderungen im Editierrahmen des Knotens mit {{ core:confirm-edit-tray }} bestätigen oder sie mit {{ core:cancel-edit-tray }} abbrechen.", | ||||
|     "tip18" : "Durch Drücken von {{ core:edit-selected-node }} wird der erste Knoten in der aktuellen Auswahl bearbeitet." | ||||
|     "tip17" : "Sie können die Änderungen im Editierrahmen des Nodes mit {{ core:confirm-edit-tray }} bestätigen oder sie mit {{ core:cancel-edit-tray }} abbrechen.", | ||||
|     "tip18" : "Durch Drücken von {{ core:edit-selected-node }} wird der erste Node in der aktuellen Auswahl bearbeitet." | ||||
|   } | ||||
| } | ||||
| @@ -53,7 +53,7 @@ | ||||
|   }, | ||||
|   "$now" : { | ||||
|     "args" : "", | ||||
|     "desc" : "Generiert eine Zeitmarke im ISO-8601-kompatiblen Format und gibt sie als Zeichenfolge zurück." | ||||
|     "desc" : "Generiert einen Zeitstempel im ISO-8601-kompatiblen Format und gibt sie als Zeichenfolge zurück." | ||||
|   }, | ||||
|   "$base64encode" : { | ||||
|     "args" : "Zeichenfolge", | ||||
| @@ -201,7 +201,7 @@ | ||||
|   }, | ||||
|   "$fromMillis" : { | ||||
|     "args" : "Anzahl", | ||||
|     "desc" : "Konvertieren Sie eine Zahl, die Millisekunden seit der Unix-Epoche (1. Januar 1970 (UTC)) in eine Zeitmarkenzeichenfolge im ISO 8601-Format darstellt." | ||||
|     "desc" : "Konvertieren Sie eine Zahl, die Millisekunden seit der Unix-Epoche (1. Januar 1970 (UTC)) enthält in eine Zeitangabe im ISO 8601-Format." | ||||
|   }, | ||||
|   "$formatNumber" : { | ||||
|     "args" : "Zahl, Bild [, Optionen]", | ||||
| @@ -212,8 +212,8 @@ | ||||
|     "desc" : "Transformiere die `Zahl` in eine Zeichenfolge und formatiert sie in eine ganze Zahl, die in der durch das `radix` -Argument angegebenen Zahlenbasis dargestellt wird. Wenn 'radix' nicht angegeben wird, wird standardmäßig die Basis 10 verwendet. 'radix` kann zwischen 2 und 36 liegen, andernfalls wird ein Fehler ausgelöst." | ||||
|   }, | ||||
|   "$toMillis" : { | ||||
|     "args" : "Zeitmarke", | ||||
|     "desc" : "Konvertieren Sie eine Zeichenfolge `Zeitmarke' im ISO 8601-Format in die Anzahl der Millisekunden seit der Unix-Epoche (1. Januar 1970 (UTC)) als Zahl. Es wird ein Fehler ausgelöst, wenn die Zeichenfolge nicht das richtige Format hat." | ||||
|     "args" : "timestamp", | ||||
|     "desc" : "Konvertieren Sie eine Zeitangabe im ISO 8601-Format in die Anzahl der Millisekunden seit der Unix-Epoche (1. Januar 1970 (UTC)) als Zahl. Es wird ein Fehler ausgelöst, wenn die Zeichenfolge nicht das richtige Format hat." | ||||
|   }, | ||||
|   "$env" : { | ||||
|     "args" : "arg", | ||||
|   | ||||
| @@ -28,7 +28,8 @@ | ||||
|         "status": "Status", | ||||
|         "enabled": "Enabled", | ||||
|         "disabled":"Disabled", | ||||
|         "info": "Description" | ||||
|         "info": "Description", | ||||
|         "selectNodes": "Click nodes to select" | ||||
|     }, | ||||
|     "menu": { | ||||
|         "label": { | ||||
| @@ -350,7 +351,8 @@ | ||||
|         "pasteNode": "Paste nodes", | ||||
|         "undoChange": "Undo the last change performed", | ||||
|         "searchBox": "Open search box", | ||||
|         "managePalette": "Manage palette" | ||||
|         "managePalette": "Manage palette", | ||||
|         "actionList":"Action list" | ||||
|     }, | ||||
|     "library": { | ||||
|         "library": "Library", | ||||
| @@ -364,6 +366,7 @@ | ||||
|         "savedNodes": "Saved nodes", | ||||
|         "savedType": "Saved __type__", | ||||
|         "saveFailed": "Save failed: __message__", | ||||
|         "newFolder": "New folder", | ||||
|         "types": { | ||||
|             "local": "Local", | ||||
|             "examples": "Examples" | ||||
| @@ -528,7 +531,10 @@ | ||||
|             "node": "Node", | ||||
|             "flow": "Flow", | ||||
|             "global": "Global", | ||||
|             "deleteConfirm": "Are you sure you want to delete this item?" | ||||
|             "deleteConfirm": "Are you sure you want to delete this item?", | ||||
|             "autoRefresh": "Auto-refresh", | ||||
|             "refrsh": "Refresh", | ||||
|             "delete": "Delete" | ||||
|         }, | ||||
|         "palette": { | ||||
|             "name": "Palette management", | ||||
| @@ -729,9 +735,21 @@ | ||||
|     "jsEditor": { | ||||
|         "title": "JavaScript editor" | ||||
|     }, | ||||
|     "textEditor": { | ||||
|         "title": "Text editor" | ||||
|     }, | ||||
|     "jsonEditor": { | ||||
|         "title": "JSON editor", | ||||
|         "format": "format JSON" | ||||
|         "format": "format JSON", | ||||
|         "rawMode": "Edit JSON", | ||||
|         "uiMode": "Visual editor", | ||||
|         "insertAbove": "Insert above", | ||||
|         "insertBelow": "Insert below", | ||||
|         "addItem": "Add item", | ||||
|         "copyPath": "Copy path to item", | ||||
|         "expandItems": "Expand items", | ||||
|         "collapseItems": "Collapse items", | ||||
|         "duplicate": "Duplicate" | ||||
|     }, | ||||
|     "markdownEditor": { | ||||
|         "title": "Markdown editor", | ||||
| @@ -924,5 +942,12 @@ | ||||
|         "description": "Description", | ||||
|         "appearance": "Appearance", | ||||
|         "env": "Environment Variables" | ||||
|     }, | ||||
|     "languages" : { | ||||
|         "de": "German", | ||||
|         "en-US": "English", | ||||
|         "ja": "Japanese", | ||||
|         "ko": "Korean", | ||||
|         "zh-CN": "Chinese(Simplified)" | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -28,7 +28,8 @@ | ||||
|         "status": "状態", | ||||
|         "enabled": "有効", | ||||
|         "disabled": "無効", | ||||
|         "info": "詳細" | ||||
|         "info": "詳細", | ||||
|         "selectNodes": "ノードをクリックして選択" | ||||
|     }, | ||||
|     "menu": { | ||||
|         "label": { | ||||
| @@ -42,7 +43,9 @@ | ||||
|                 "defaultDir": "標準", | ||||
|                 "ltr": "左から右", | ||||
|                 "rtl": "右から左", | ||||
|                 "auto": "文脈" | ||||
|                 "auto": "文脈", | ||||
|                 "language": "表示言語", | ||||
|                 "browserDefault": "ブラウザのデフォルト" | ||||
|             }, | ||||
|             "sidebar": { | ||||
|                 "show": "サイドバーを表示" | ||||
| @@ -179,7 +182,11 @@ | ||||
|             "all": "全てのタブ", | ||||
|             "compact": "インデントのないJSONフォーマット", | ||||
|             "formatted": "インデント付きのJSONフォーマット", | ||||
|             "copy": "書き出し" | ||||
|             "copy": "書き出し", | ||||
|             "export": "ライブラリに書き出し", | ||||
|             "exportAs": "書き出し先", | ||||
|             "overwrite": "更新", | ||||
|             "exists": "<p><b>\"__file__\"</b>は既に存在します。</p><p>更新しますか?</p>" | ||||
|         }, | ||||
|         "import": { | ||||
|             "import": "読み込み先", | ||||
| @@ -315,7 +322,8 @@ | ||||
|         "show": "表示", | ||||
|         "hide": "非表示", | ||||
|         "errors": { | ||||
|             "scopeChange": "スコープの変更は、他のフローで使われているノードを無効にします" | ||||
|             "scopeChange": "スコープの変更は、他のフローで使われているノードを無効にします", | ||||
|             "invalidProperties": "プロパティが不正です:" | ||||
|         } | ||||
|     }, | ||||
|     "keyboard": { | ||||
| @@ -351,12 +359,15 @@ | ||||
|         "saveToLibrary": "ライブラリへ保存", | ||||
|         "typeLibrary": "__type__ ライブラリ", | ||||
|         "unnamedType": "名前なし __type__", | ||||
|         "exportedToLibrary": "ライブラリにノードを書き出しました", | ||||
|         "dialogSaveOverwrite": "__libraryName__ という __libraryType__ は既に存在しています 上書きしますか?", | ||||
|         "invalidFilename": "不正なファイル名", | ||||
|         "savedNodes": "フローを保存しました", | ||||
|         "savedType": "__type__ を保存しました", | ||||
|         "saveFailed": "保存に失敗しました: __message__", | ||||
|         "newFolder": "新規フォルダ", | ||||
|         "types": { | ||||
|             "local": "ローカル", | ||||
|             "examples": "サンプル" | ||||
|         } | ||||
|     }, | ||||
| @@ -519,7 +530,8 @@ | ||||
|             "node": "Node", | ||||
|             "flow": "Flow", | ||||
|             "global": "Global", | ||||
|             "deleteConfirm": "データを削除しても良いですか?" | ||||
|             "deleteConfirm": "データを削除しても良いですか?", | ||||
|             "autoRefresh": "自動更新" | ||||
|         }, | ||||
|         "palette": { | ||||
|             "name": "パレットの管理", | ||||
| @@ -719,6 +731,9 @@ | ||||
|     "jsEditor": { | ||||
|         "title": "JavaScriptエディタ" | ||||
|     }, | ||||
|     "textEditor": { | ||||
|         "title": "テキストエディタ" | ||||
|     }, | ||||
|     "jsonEditor": { | ||||
|         "title": "JSONエディタ", | ||||
|         "format": "JSONフォーマット" | ||||
| @@ -914,5 +929,12 @@ | ||||
|         "description": "説明", | ||||
|         "appearance": "外観", | ||||
|         "env": "環境変数" | ||||
|     }, | ||||
|     "languages" : { | ||||
|         "de": "ドイツ語", | ||||
|         "en-US": "英語", | ||||
|         "ja": "日本語", | ||||
|         "ko": "韓国語", | ||||
|         "zh-CN": "中国語(簡体)" | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@node-red/editor-client", | ||||
|     "version": "0.21.0-alpha.0", | ||||
|     "version": "1.0.0-beta.2", | ||||
|     "license": "Apache-2.0", | ||||
|     "repository": { | ||||
|         "type": "git", | ||||
|   | ||||
| Before Width: | Height: | Size: 291 B | 
							
								
								
									
										1
									
								
								packages/node_modules/@node-red/editor-client/src/images/deploy-flows-o.svg
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1 @@ | ||||
| <svg width="27" height="18" xmlns="http://www.w3.org/2000/svg"><g color="#000"><path fill="#fff" d="M0 5.002h10v5H0zM17 .002h10v5H17z"/><path d="M17 13.002h10v5H17z"/></g><path d="M9.5 7.502h2l4-5h2" fill="none" stroke="#fff" stroke-width="1.5"/></svg> | ||||
| After Width: | Height: | Size: 252 B | 
| Before Width: | Height: | Size: 386 B | 
							
								
								
									
										1
									
								
								packages/node_modules/@node-red/editor-client/src/images/deploy-flows.svg
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1 @@ | ||||
| <svg width="32" height="32" xmlns="http://www.w3.org/2000/svg"><path color="#000" fill="#8c101c" d="M0 .002h32v32H0z"/><g color="#000"><path fill="#fff" d="M2 13.002h10v5H2zM19 8.002h10v5H19z"/><path d="M19 21.002h10v5H19z"/></g><path d="M11.5 15.502h2l4-5h2" fill="none" stroke="#fff" stroke-width="1.5"/></svg> | ||||
| After Width: | Height: | Size: 312 B | 
| Before Width: | Height: | Size: 289 B | 
							
								
								
									
										1
									
								
								packages/node_modules/@node-red/editor-client/src/images/deploy-full-o.svg
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1 @@ | ||||
| <svg width="27" height="18" xmlns="http://www.w3.org/2000/svg"><g fill="#fff" color="#000"><path d="M0 5h10v5H0zM17 0h10v5H17zM17 13h10v5H17z"/></g><path d="M9.5 7.5h2l4-5h2" fill="none" stroke="#fff" stroke-width="1.5"/></svg> | ||||
| After Width: | Height: | Size: 227 B | 
| Before Width: | Height: | Size: 368 B | 
							
								
								
									
										1
									
								
								packages/node_modules/@node-red/editor-client/src/images/deploy-full.svg
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1 @@ | ||||
| <svg width="32" height="32" xmlns="http://www.w3.org/2000/svg"><path color="#000" fill="#8c101c" d="M0 0h32v32H0z"/><g fill="#fff" color="#000"><path d="M2 13h10v5H2zM19 8h10v5H19zM19 21h10v5H19z"/></g><path d="M11.5 15.5h2l4-5h2" fill="none" stroke="#fff" stroke-width="1.5"/></svg> | ||||
| After Width: | Height: | Size: 283 B | 
| Before Width: | Height: | Size: 290 B | 
							
								
								
									
										1
									
								
								packages/node_modules/@node-red/editor-client/src/images/deploy-nodes-o.svg
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1 @@ | ||||
| <svg width="27" height="18" xmlns="http://www.w3.org/2000/svg"><path color="#000" d="M0 5.002h10v5H0zM17 13.002h10v5H17z"/><path d="M9.5 7.502h2l4-5h2" fill="none" stroke="#000" stroke-width="1.5"/><path color="#000" fill="#fff" d="M17 .002h10v5H17z"/></svg> | ||||
| After Width: | Height: | Size: 258 B | 
| Before Width: | Height: | Size: 392 B | 
							
								
								
									
										1
									
								
								packages/node_modules/@node-red/editor-client/src/images/deploy-nodes.svg
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1 @@ | ||||
| <svg width="32" height="32" xmlns="http://www.w3.org/2000/svg"><path color="#000" fill="#8c101c" d="M0 .002h32v32H0z"/><path color="#000" d="M2 13.002h10v5H2zM19 21.002h10v5H19z"/><path d="M11.5 15.502h2l4-5h2" fill="none" stroke="#000" stroke-width="1.5"/><path color="#000" fill="#fff" d="M19 8.002h10v5H19z"/></svg> | ||||
| After Width: | Height: | Size: 318 B | 
| Before Width: | Height: | Size: 1015 B | 
							
								
								
									
										1
									
								
								packages/node_modules/@node-red/editor-client/src/images/deploy-reload.svg
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1 @@ | ||||
| <svg width="32" height="32" xmlns="http://www.w3.org/2000/svg"><g color="#000"><path fill="#8c101c" d="M0 .006h32v32H0z"/><path d="M11.81 25.429a10.02 10.02 0 0 0 4.19.914c5.562 0 10.107-4.545 10.107-10.106S21.562 6.131 16 6.131 5.895 10.676 5.895 16.237h3.368c0-3.74 2.997-6.737 6.738-6.737s6.737 2.996 6.737 6.737-2.996 6.738-6.737 6.738a6.775 6.775 0 0 1-2.533-.486l1.43-3.48-6.947 1.317 2.13 8.485z" fill="#fff" style="isolation:auto;mix-blend-mode:normal;text-decoration-color:#000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/></g></svg> | ||||
| After Width: | Height: | Size: 606 B | 
| Before Width: | Height: | Size: 393 B | 
							
								
								
									
										1
									
								
								packages/node_modules/@node-red/editor-client/src/images/icons/arrow-in.svg
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1 @@ | ||||
| <svg width="40" height="60" xmlns="http://www.w3.org/2000/svg"><path d="M18 5v12H7v26h11v12l14-25z" fill="#fff"/></svg> | ||||
| After Width: | Height: | Size: 120 B | 
| Before Width: | Height: | Size: 386 B | 
| Before Width: | Height: | Size: 386 B | 
| Before Width: | Height: | Size: 1019 B | 
							
								
								
									
										1
									
								
								packages/node_modules/@node-red/editor-client/src/images/node-red.svg
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1 @@ | ||||
| <svg width="46.994" height="18.006" xmlns="http://www.w3.org/2000/svg"><g stroke="#d6d6d6"><g fill="#9e3131" stroke-linejoin="round" stroke-width="3.847" transform="matrix(.25848 0 0 .2614 -63.87 -108.483)"><rect x="249.04" y="435.92" width="50.294" height="22.953" ry="6.608"/><rect x="345.63" y="416.93" width="50.294" height="22.953" ry="6.608"/><rect x="376.71" y="459.01" width="50.294" height="22.953" ry="6.608"/></g><path d="M301.04 447.43c24.406.184 7.107-18.84 42.708-19.03M374.82 470.48c-46.966.538-28.989-22.664-73.619-22.944" fill="none" stroke-width="5.771" transform="matrix(.25848 0 0 .2614 -63.87 -108.483)"/></g></svg> | ||||
| After Width: | Height: | Size: 636 B | 
| Before Width: | Height: | Size: 600 B | 
| Before Width: | Height: | Size: 410 B | 
							
								
								
									
										1
									
								
								packages/node_modules/@node-red/editor-client/src/images/subflow_tab.svg
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1 @@ | ||||
| <svg width="40" height="40" xmlns="http://www.w3.org/2000/svg"><path d="M25 16h7c.58 0 1-.42 1-1v-2c0-.58-.42-1-1-1h-7c-.58 0-1 .42-1 1v2c0 .58.42 1 1 1zM8 28h7c.58 0 1-.42 1-1v-2c0-.58-.42-1-1-1H8c-.58 0-1 .42-1 1v2c0 .58.42 1 1 1zm-.416 11C5.624 39 4 37.375 4 35.416V4.582C4 2.622 5.625 1 7.584 1h24.832C34.376 1 36 2.623 36 4.582v30.834C36 37.376 34.375 39 32.416 39zM32 27H19c0 2.19-1.81 4-4 4H7v4.416c0 .35.235.584.584.584h24.832c.35 0 .584-.235.584-.584v-8.417zm1-2v-6h-8c-2.19 0-4-1.81-4-4h-1c-4.333-.002-8.667.004-13 0v6h8c2.19 0 4 1.81 4 4h13zm0-16V4.582c0-.35-.235-.582-.584-.582H7.584C7.234 4 7 4.233 7 4.582v8.417c4.333.002 8.667.001 13 .001h1c0-2.19 1.81-4 4-4z" color="#000" fill="#333"/></svg> | ||||
| After Width: | Height: | Size: 708 B | 
| Before Width: | Height: | Size: 638 B | 
							
								
								
									
										1
									
								
								packages/node_modules/@node-red/editor-client/src/images/typedInput/09.svg
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1 @@ | ||||
| <svg width="26" height="36" xmlns="http://www.w3.org/2000/svg"><path d="M14.16 27.38l1.555-.144c.132.731.383 1.261.755 1.591.371.33.848.494 1.429.494.497 0 .931-.114 1.303-.341.377-.228.686-.53.926-.908.24-.383.44-.899.602-1.546a8.122 8.122 0 0 0 .233-2.3 3.732 3.732 0 0 1-1.33 1.258 3.605 3.605 0 0 1-1.815.476c-1.09 0-2.013-.395-2.768-1.186s-1.133-1.834-1.133-3.128c0-1.336.393-2.411 1.178-3.226.79-.815 1.78-1.223 2.966-1.223.856 0 1.638.231 2.345.692.713.462 1.253 1.12 1.618 1.978.372.85.557 2.085.557 3.702 0 1.684-.182 3.026-.548 4.027-.365.994-.91 1.752-1.636 2.274-.719.52-1.563.781-2.534.781-1.03 0-1.872-.284-2.525-.853-.654-.576-1.046-1.381-1.178-2.418zm6.624-5.815c0-.928-.249-1.666-.746-2.21-.492-.546-1.085-.819-1.78-.819-.719 0-1.345.294-1.878.881s-.8 1.348-.8 2.283c0 .839.252 1.522.755 2.05.51.52 1.135.781 1.878.781.75 0 1.363-.26 1.843-.782.485-.527.728-1.255.728-2.184zM4.858 10.466c0-1.558.158-2.81.476-3.757.324-.952.8-1.686 1.429-2.201.635-.516 1.432-.773 2.39-.773.708 0 1.328.143 1.861.431.533.282.974.692 1.321 1.231.348.534.62 1.187.818 1.96.198.767.297 1.803.297 3.11 0 1.545-.16 2.794-.477 3.747-.317.947-.794 1.68-1.429 2.202-.629.515-1.426.773-2.39.773-1.27 0-2.268-.456-2.993-1.366-.869-1.097-1.303-2.882-1.303-5.357zm1.662 0c0 2.163.252 3.604.755 4.323.51.713 1.136 1.07 1.879 1.07.743 0 1.366-.36 1.87-1.079.508-.719.763-2.157.763-4.314 0-2.169-.255-3.61-.764-4.323-.503-.713-1.132-1.07-1.887-1.07-.743 0-1.336.315-1.78.944-.557.803-.836 2.286-.836 4.45z" fill="#444"/></svg> | ||||
| After Width: | Height: | Size: 1.5 KiB | 
| Before Width: | Height: | Size: 546 B | 
							
								
								
									
										1
									
								
								packages/node_modules/@node-red/editor-client/src/images/typedInput/az.svg
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1 @@ | ||||
| <svg width="26" height="36" xmlns="http://www.w3.org/2000/svg"><path d="M13.27 29.15l6.733-8.143h-6.235V19.3h8.8v1.559l-6.69 8.09h6.892v1.707h-9.5zm4.909-10.125zM6.577 12.58q0 .827.604 1.304.605.478 1.432.478 1.007 0 1.95-.467 1.59-.774 1.59-2.534V9.824q-.349.222-.9.37-.552.15-1.082.213l-1.155.148q-1.04.138-1.56.435-.88.498-.88 1.59zM11.2 8.721q.657-.085.88-.551.127-.255.127-.732 0-.975-.7-1.41-.689-.445-1.983-.445-1.495 0-2.12.805-.35.446-.456 1.326H5.167q.053-2.1 1.357-2.916 1.315-.827 3.043-.827 2.004 0 3.255.763 1.24.764 1.24 2.375v6.542q0 .297.117.477.127.18.52.18.127 0 .286-.01.159-.021.34-.053v1.41q-.446.127-.68.16-.233.031-.636.031-.986 0-1.43-.7-.234-.37-.33-1.05-.583.764-1.675 1.326t-2.407.562q-1.58 0-2.587-.954-.996-.965-.996-2.407 0-1.58.986-2.45.986-.869 2.587-1.07zm-1.58-4.75z" fill="#444"/></svg> | ||||
| After Width: | Height: | Size: 822 B | 
| Before Width: | Height: | Size: 638 B | 
							
								
								
									
										1
									
								
								packages/node_modules/@node-red/editor-client/src/images/typedInput/bin.svg
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1 @@ | ||||
| <svg width="26" height="36" xmlns="http://www.w3.org/2000/svg"><path d="M18.8 33.9c3.328 0 4.776-2.603 4.776-7.066s-1.448-7.066-4.776-7.066-4.776 2.603-4.776 7.066S15.473 33.9 18.8 33.9zm0-1.429c-2.192 0-3.073-1.781-3.073-4.522v-2.23c0-2.741.88-4.523 3.073-4.523s3.073 1.782 3.073 4.522v2.231c0 2.74-.88 4.522-3.073 4.522zm-6.306 1.194v-1.429H8.892V20.002H6.328l-3.621 3.386.959 1.038 3.445-3.21h.137v11.02H3.333v1.429zm11.2-17.7v-1.429h-3.602V2.302h-2.564l-3.621 3.386.959 1.038 3.445-3.21h.137v11.02h-3.915v1.429zM7.5 16.2c3.327 0 4.776-2.603 4.776-7.066S10.828 2.068 7.5 2.068 2.725 4.67 2.725 9.134 4.173 16.2 7.5 16.2zm0-1.429c-2.193 0-3.074-1.781-3.074-4.522V8.02c0-2.741.881-4.523 3.074-4.523s3.073 1.782 3.073 4.522v2.231c0 2.74-.881 4.522-3.073 4.522z" fill="#444"/></svg> | ||||
| After Width: | Height: | Size: 781 B | 
| Before Width: | Height: | Size: 646 B | 
							
								
								
									
										1
									
								
								packages/node_modules/@node-red/editor-client/src/images/typedInput/bool.svg
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1 @@ | ||||
| <svg width="26" height="36" xmlns="http://www.w3.org/2000/svg"><path d="M9.96 21.98a5 5 0 1 1 6.11-7.917zm3.035-13.973c-5.512 0-10 4.488-10 10s4.488 9.998 10 9.998 10-4.486 10-9.998-4.488-10-10-10zm0 1.816c4.53 0 8.182 3.655 8.182 8.184s-3.652 8.182-8.182 8.182-8.181-3.653-8.181-8.182 3.652-8.184 8.181-8.184z" color="#000" fill="#444"/></svg> | ||||
| After Width: | Height: | Size: 345 B | 
| Before Width: | Height: | Size: 809 B | 
							
								
								
									
										1
									
								
								packages/node_modules/@node-red/editor-client/src/images/typedInput/env.svg
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1 @@ | ||||
| <svg width="26" height="36" xmlns="http://www.w3.org/2000/svg"><path d="M14.33 27.19q2.916-.136 4.024-2.131.58-1.024.58-2.37 0-2.132-1.569-3.24-.904-.648-3.035-1.228zM8.55 10.736q0 1.688 1.108 2.643 1.125.955 3.018 1.33V6.695q-2.234.085-3.189 1.364-.937 1.279-.937 2.677zm-3.07.205q0-2.592 1.893-4.672 1.91-2.08 5.337-2.115V1.887h1.62V4.12q3.393.239 5.2 2.012 1.825 1.757 1.91 4.655h-2.984q-.119-1.296-.699-2.233-1.074-1.723-3.427-1.808v8.287q3.956 1.108 5.371 2.08 2.302 1.603 2.302 4.74 0 4.536-2.95 6.446-1.637 1.057-4.723 1.398v3.308h-1.62v-3.308q-4.962-.324-6.735-3.513-.972-1.722-.972-4.655h3.018q.136 2.336.733 3.41 1.057 1.927 3.922 2.166v-9.293q-3.683-.699-5.44-2.336Q5.48 13.84 5.48 10.941z" fill="#444"/></svg> | ||||
| After Width: | Height: | Size: 722 B | 
| Before Width: | Height: | Size: 563 B | 
							
								
								
									
										1
									
								
								packages/node_modules/@node-red/editor-client/src/images/typedInput/expr.svg
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1 @@ | ||||
| <svg width="26" height="36" xmlns="http://www.w3.org/2000/svg"><g transform="translate(-337.103 -913.25) scale(1.2585)" fill="#444" stroke-width=".795"><circle cx="284.36" cy="733.68" r="1.5" color="#000" style="isolation:auto;mix-blend-mode:normal"/><circle cx="284.33" cy="740.74" r="1.5" color="#000" style="isolation:auto;mix-blend-mode:normal"/><path d="M276.18 727.78l4.396-1.565v18.515c-.711 2.606-2.922 4.394-5.812 5.812l-4.135 1.974-.559-1.192 3.353-1.639c1.459-.724 2.689-1.87 2.869-4.955z" fill-rule="evenodd"/></g></svg> | ||||
| After Width: | Height: | Size: 532 B | 
| Before Width: | Height: | Size: 588 B | 
							
								
								
									
										1
									
								
								packages/node_modules/@node-red/editor-client/src/images/typedInput/json.svg
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1 @@ | ||||
| <svg width="26" height="36" xmlns="http://www.w3.org/2000/svg"><path d="M15 5.225v-1.92h2.24q.608 0 1.216.288.608.256 1.12.8.48.512.8 1.312.32.768.32 1.792v5.824q0 .832.224 1.536t.608 1.216q.352.48.832.768.48.256.992.256v2.176q-.512 0-.992.256t-.832.736q-.384.48-.608 1.184t-.224 1.568v5.792q0 1.024-.32 1.792-.32.8-.8 1.312-.512.544-1.12.8-.608.288-1.216.288H15v-1.92h1.6q.48 0 .768-.256.288-.224.48-.64.16-.384.224-.896.064-.48.064-.96v-5.824q0-1.216.352-2.016.32-.8.768-1.28.448-.512.928-.736.448-.224.736-.256v-.096q-.288-.064-.736-.32-.48-.256-.928-.768t-.768-1.28q-.352-.8-.352-1.92V7.977q0-.512-.064-.992-.064-.512-.224-.896-.192-.384-.48-.608-.288-.256-.768-.256zm-3.648 0v-1.92h-2.24q-.608 0-1.216.288-.608.256-1.12.8-.48.512-.8 1.312-.32.768-.32 1.792v5.824q0 .832-.224 1.536t-.608 1.216q-.352.48-.832.768-.48.256-.992.256v2.176q.512 0 .992.256t.832.736q.384.48.608 1.184t.224 1.568v5.792q0 1.024.32 1.792.32.8.8 1.312.512.544 1.12.8.608.288 1.216.288h2.24v-1.92h-1.6q-.48 0-.768-.256-.288-.224-.48-.64-.16-.384-.224-.896-.064-.48-.064-.96v-5.824q0-1.216-.352-2.016-.32-.8-.768-1.28-.448-.512-.928-.736-.448-.224-.736-.256v-.096q.288-.064.736-.32.48-.256.928-.768t.768-1.28q.352-.8.352-1.92V7.977q0-.512.064-.992.064-.512.224-.896.192-.384.48-.608.288-.256.768-.256z" fill="#444"/></svg> | ||||
| After Width: | Height: | Size: 1.3 KiB | 
| Before Width: | Height: | Size: 502 B | 
							
								
								
									
										1
									
								
								packages/node_modules/@node-red/editor-client/src/images/typedInput/re.svg
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1 @@ | ||||
| <svg width="26" height="36" xmlns="http://www.w3.org/2000/svg"><path d="M2 19h5v5H2zm16.099-3.304v-5.659h-2.654v5.66l-5.309-2.004-.901 2.404L14.543 18l-3.255 4.557 2.254 1.553 3.255-4.808 3.455 4.808 2.054-1.553L19 18l5.46-1.903-1.002-2.404z" color="#000" fill="#444444"/></svg> | ||||
| After Width: | Height: | Size: 279 B | 
							
								
								
									
										1
									
								
								packages/node_modules/@node-red/editor-client/src/images/typedInput/target.svg
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1 @@ | ||||
| <svg width="26" height="36" xmlns="http://www.w3.org/2000/svg"><path d="M11 5v5.77a7.542 7.542 0 0 0-5.234 5.25L1 16c-1.432 1.397-1.232 2.722 0 4l4.75-.078a7.542 7.542 0 0 0 5.22 5.297L11 31c1.316 1.303 2.649 1.363 4 0l.009-5.775A7.542 7.542 0 0 0 20.228 20H25c1.261-1.294 1.404-2.623 0-4l-4.774-.01a7.542 7.542 0 0 0-5.23-5.22L15 5c-1.3-1.273-2.63-1.393-4 0zm2 7.499c3.05 0 5.5 2.45 5.5 5.5s-2.45 5.5-5.5 5.5-5.5-2.45-5.5-5.5 2.45-5.5 5.5-5.5z" color="#000" fill="#444"/></svg> | ||||
| After Width: | Height: | Size: 479 B | 
| @@ -214,6 +214,10 @@ RED.history = (function() { | ||||
|                         ev.node[i] = ev.changes[i]; | ||||
|                     } | ||||
|                 } | ||||
|                 if (ev.node.type === 'tab' && ev.changes.hasOwnProperty('disabled')) { | ||||
|                     $("#red-ui-tab-"+(ev.node.id.replace(".","-"))).toggleClass('red-ui-workspace-disabled',!!ev.node.disabled); | ||||
|                     $("#red-ui-workspace").toggleClass("red-ui-workspace-disabled",!!ev.node.disabled); | ||||
|                 } | ||||
|                 if (ev.subflow) { | ||||
|                     if (ev.subflow.hasOwnProperty('inputCount')) { | ||||
|                         if (ev.node.in.length > ev.subflow.inputCount) { | ||||
|   | ||||
| @@ -51,7 +51,7 @@ RED.i18n = (function() { | ||||
|  | ||||
|         }, | ||||
|         loadNodeCatalog: function(namespace,done) { | ||||
|             var languageList = i18n.functions.toLanguages(i18n.detectLanguage()); | ||||
|             var languageList = i18n.functions.toLanguages(localStorage.getItem("editor-language")||i18n.detectLanguage()); | ||||
|             var toLoad = languageList.length; | ||||
|             languageList.forEach(function(lang) { | ||||
|                 $.ajax({ | ||||
| @@ -73,7 +73,7 @@ RED.i18n = (function() { | ||||
|         }, | ||||
|  | ||||
|         loadNodeCatalogs: function(done) { | ||||
|             var languageList = i18n.functions.toLanguages(i18n.detectLanguage()); | ||||
|             var languageList = i18n.functions.toLanguages(localStorage.getItem("editor-language")||i18n.detectLanguage()); | ||||
|             var toLoad = languageList.length; | ||||
|  | ||||
|             languageList.forEach(function(lang) { | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "*": { | ||||
|         "ctrl-shift-p":"core:manage-palette", | ||||
|         "alt-shift-p":"core:manage-palette", | ||||
|         "ctrl-f": "core:search", | ||||
|         "ctrl-shift-f": "core:list-flows", | ||||
|         "ctrl-=": "core:zoom-in", | ||||
| @@ -8,6 +8,7 @@ | ||||
|         "ctrl-0": "core:zoom-reset", | ||||
|         "ctrl-enter": "core:confirm-edit-tray", | ||||
|         "ctrl-escape": "core:cancel-edit-tray", | ||||
|         "ctrl-d": "core:deploy-flows", | ||||
|         "ctrl-g i": "core:show-info-tab", | ||||
|         "ctrl-g d": "core:show-debug-tab", | ||||
|         "ctrl-g c": "core:show-config-tab", | ||||
| @@ -17,11 +18,13 @@ | ||||
|         "ctrl-space": "core:toggle-sidebar", | ||||
|         "ctrl-p": "core:toggle-palette", | ||||
|         "ctrl-,": "core:show-user-settings", | ||||
|         "ctrl-alt-l": "core:clear-debug-messages", | ||||
|         "ctrl-alt-r": "core:show-remote-diff", | ||||
|         "ctrl-alt-n": "core:new-project", | ||||
|         "ctrl-alt-o": "core:open-project", | ||||
|         "ctrl-g v": "core:show-version-control-tab", | ||||
|         "ctrl-shift-l": "core:show-event-log" | ||||
|         "ctrl-shift-l": "core:show-event-log", | ||||
|         "ctrl-shift-p":"core:show-action-list" | ||||
|     }, | ||||
|     "red-ui-sidebar-node-config": { | ||||
|         "backspace": "core:delete-config-selection", | ||||
|   | ||||
| @@ -17,6 +17,8 @@ RED.nodes = (function() { | ||||
|  | ||||
|     var node_defs = {}; | ||||
|     var nodes = []; | ||||
|     var nodeTabMap = {}; | ||||
|  | ||||
|     var configNodes = {}; | ||||
|     var links = []; | ||||
|     var defaultWorkspace; | ||||
| @@ -213,6 +215,11 @@ RED.nodes = (function() { | ||||
|                 n.i = nextId+1; | ||||
|             } | ||||
|             nodes.push(n); | ||||
|             if (nodeTabMap[n.z]) { | ||||
|                 nodeTabMap[n.z][n.id] = n; | ||||
|             } else { | ||||
|                 console.warn("Node added to unknown tab/subflow:",n); | ||||
|             } | ||||
|         } | ||||
|         RED.events.emit('nodes:add',n); | ||||
|     } | ||||
| @@ -246,6 +253,9 @@ RED.nodes = (function() { | ||||
|             node = getNode(id); | ||||
|             if (node) { | ||||
|                 nodes.splice(nodes.indexOf(node),1); | ||||
|                 if (nodeTabMap[node.z]) { | ||||
|                     delete nodeTabMap[node.z][node.id]; | ||||
|                 } | ||||
|                 removedLinks = links.filter(function(l) { return (l.source === node) || (l.target === node); }); | ||||
|                 removedLinks.forEach(function(l) {links.splice(links.indexOf(l), 1); }); | ||||
|                 var updatedConfigNode = false; | ||||
| @@ -300,6 +310,8 @@ RED.nodes = (function() { | ||||
|  | ||||
|     function addWorkspace(ws,targetIndex) { | ||||
|         workspaces[ws.id] = ws; | ||||
|         nodeTabMap[ws.id] = {}; | ||||
|  | ||||
|         ws._def = RED.nodes.getType('tab'); | ||||
|         if (targetIndex === undefined) { | ||||
|             workspacesOrder.push(ws.id); | ||||
| @@ -312,6 +324,7 @@ RED.nodes = (function() { | ||||
|     } | ||||
|     function removeWorkspace(id) { | ||||
|         delete workspaces[id]; | ||||
|         delete nodeTabMap[ws.id]; | ||||
|         workspacesOrder.splice(workspacesOrder.indexOf(id),1); | ||||
|  | ||||
|         var removedNodes = []; | ||||
| @@ -357,12 +370,14 @@ RED.nodes = (function() { | ||||
|             sf.name = subflowName; | ||||
|         } | ||||
|         subflows[sf.id] = sf; | ||||
|         nodeTabMap[sf.id] = {}; | ||||
|  | ||||
|         RED.nodes.registerType("subflow:"+sf.id, { | ||||
|             defaults:{ | ||||
|                 name:{value:""}, | ||||
|                 env:{value:[]} | ||||
|             }, | ||||
|             icon: function() { return sf.icon||"subflow.png" }, | ||||
|             icon: function() { return sf.icon||"subflow.svg" }, | ||||
|             category: sf.category || "subflows", | ||||
|             inputs: sf.in.length, | ||||
|             outputs: sf.out.length, | ||||
| @@ -393,6 +408,7 @@ RED.nodes = (function() { | ||||
|     } | ||||
|     function removeSubflow(sf) { | ||||
|         delete subflows[sf.id]; | ||||
|         delete nodeTabMap[sf.id]; | ||||
|         registry.removeNodeType("subflow:"+sf.id); | ||||
|     } | ||||
|  | ||||
| @@ -463,7 +479,9 @@ RED.nodes = (function() { | ||||
|         node.id = n.id; | ||||
|         node.type = n.type; | ||||
|         node.z = n.z; | ||||
|  | ||||
|         if (n.d === true) { | ||||
|             node.d = true; | ||||
|         } | ||||
|         if (node.type == "unknown") { | ||||
|             for (var p in n._orig) { | ||||
|                 if (n._orig.hasOwnProperty(p)) { | ||||
| @@ -581,7 +599,7 @@ RED.nodes = (function() { | ||||
|             node.outputLabels = n.outputLabels.slice(); | ||||
|         } | ||||
|         if (n.icon) { | ||||
|             if (n.icon !== "node-red/subflow.png") { | ||||
|             if (n.icon !== "node-red/subflow.svg") { | ||||
|                 node.icon = n.icon; | ||||
|             } | ||||
|         } | ||||
| @@ -967,6 +985,9 @@ RED.nodes = (function() { | ||||
|                         users:[], | ||||
|                         _config:{} | ||||
|                     }; | ||||
|                     if (n.hasOwnProperty('d')) { | ||||
|                         configNode.d = n.d; | ||||
|                     } | ||||
|                     for (d in def.defaults) { | ||||
|                         if (def.defaults.hasOwnProperty(d)) { | ||||
|                             configNode[d] = n[d]; | ||||
| @@ -1016,6 +1037,9 @@ RED.nodes = (function() { | ||||
|                     if (n.hasOwnProperty('l')) { | ||||
|                         node.l = n.l; | ||||
|                     } | ||||
|                     if (n.hasOwnProperty('d')) { | ||||
|                         node.d = n.d; | ||||
|                     } | ||||
|                     if (createNewIds) { | ||||
|                         if (subflow_blacklist[n.z]) { | ||||
|                             continue; | ||||
| @@ -1258,12 +1282,13 @@ RED.nodes = (function() { | ||||
|     // TODO: supports filter.z|type | ||||
|     function filterNodes(filter) { | ||||
|         var result = []; | ||||
|         var searchSet = nodes; | ||||
|         if (filter.hasOwnProperty("z") && Object.hasOwnProperty("values") && nodeTabMap.hasOwnProperty(filter.z) ) { | ||||
|             searchSet = Object.values(nodeTabMap[filter.z]); | ||||
|         } | ||||
|  | ||||
|         for (var n=0;n<nodes.length;n++) { | ||||
|             var node = nodes[n]; | ||||
|             if (filter.hasOwnProperty("z") && node.z !== filter.z) { | ||||
|                 continue; | ||||
|             } | ||||
|         for (var n=0;n<searchSet.length;n++) { | ||||
|             var node = searchSet[n]; | ||||
|             if (filter.hasOwnProperty("type") && node.type !== filter.type) { | ||||
|                 continue; | ||||
|             } | ||||
| @@ -1331,6 +1356,7 @@ RED.nodes = (function() { | ||||
|     function clear() { | ||||
|         nodes = []; | ||||
|         links = []; | ||||
|         nodeTabMap = {}; | ||||
|         configNodes = {}; | ||||
|         workspacesOrder = []; | ||||
|         var subflowIds = Object.keys(subflows); | ||||
|   | ||||
| @@ -107,9 +107,12 @@ var RED = (function() { | ||||
|     } | ||||
|  | ||||
|     function loadNodes() { | ||||
|         var lang = localStorage.getItem("editor-language")||i18n.detectLanguage(); | ||||
|  | ||||
|         $.ajax({ | ||||
|             headers: { | ||||
|                 "Accept":"text/html" | ||||
|                 "Accept":"text/html", | ||||
|                 "Accept-Language": lang | ||||
|             }, | ||||
|             cache: false, | ||||
|             url: 'nodes', | ||||
| @@ -350,10 +353,8 @@ var RED = (function() { | ||||
|             var parts = topic.split("/"); | ||||
|             var node = RED.nodes.node(parts[1]); | ||||
|             if (node) { | ||||
|                 if (msg.hasOwnProperty("text")) { | ||||
|                     if (msg.text[0] !== ".") { | ||||
|                         msg.text = node._(msg.text.toString(),{defaultValue:msg.text.toString()}); | ||||
|                     } | ||||
|                 if (msg.hasOwnProperty("text") && /^[a-zA-Z]/.test(msg.text)) { | ||||
|                     msg.text = node._(msg.text.toString(),{defaultValue:msg.text.toString()}); | ||||
|                 } | ||||
|                 node.status = msg; | ||||
|                 node.dirtyStatus = true; | ||||
| @@ -450,6 +451,7 @@ var RED = (function() { | ||||
|             {id:"menu-item-palette",label:RED._("menu.label.palette.show"),toggle:true,onselect:"core:toggle-palette", selected: true}, | ||||
|             {id:"menu-item-sidebar",label:RED._("menu.label.sidebar.show"),toggle:true,onselect:"core:toggle-sidebar", selected: true}, | ||||
|             {id:"menu-item-event-log",label:RED._("eventLog.title"),onselect:"core:show-event-log"}, | ||||
|             {id:"menu-item-action-list",label:RED._("keyboard.actionList"),onselect:"core:show-action-list"}, | ||||
|             null | ||||
|         ]}); | ||||
|         menuOptions.push(null); | ||||
| @@ -520,6 +522,7 @@ var RED = (function() { | ||||
|         RED.subflow.init(); | ||||
|         RED.clipboard.init(); | ||||
|         RED.search.init(); | ||||
|         RED.actionList.init(); | ||||
|         RED.editor.init(); | ||||
|         RED.diff.init(); | ||||
|  | ||||
|   | ||||
| @@ -37,7 +37,7 @@ RED.settings = (function () { | ||||
|         if (key === "auth-tokens") { | ||||
|             localStorage.setItem(key, JSON.stringify(value)); | ||||
|         } else { | ||||
|             userSettings[key] = value; | ||||
|             RED.utils.setMessageProperty(userSettings,key,value); | ||||
|             saveUserSettings(); | ||||
|         } | ||||
|     }; | ||||
| @@ -46,16 +46,25 @@ RED.settings = (function () { | ||||
|      * If the key is not set in the localStorage it returns <i>undefined</i> | ||||
|      * Else return the JSON parsed value | ||||
|      * @param key | ||||
|      * @param defaultIfUndefined | ||||
|      * @returns {*} | ||||
|      */ | ||||
|     var get = function (key) { | ||||
|     var get = function (key,defaultIfUndefined) { | ||||
|         if (!hasLocalStorage()) { | ||||
|             return undefined; | ||||
|         } | ||||
|         if (key === "auth-tokens") { | ||||
|             return JSON.parse(localStorage.getItem(key)); | ||||
|         } else { | ||||
|             return userSettings[key]; | ||||
|             try { | ||||
|                 var v = RED.utils.getMessageProperty(userSettings,key); | ||||
|                 if (v === undefined) { | ||||
|                     v = defaultIfUndefined; | ||||
|                 } | ||||
|             } catch(err) { | ||||
|                 v = defaultIfUndefined; | ||||
|             } | ||||
|             return v; | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|   | ||||
							
								
								
									
										230
									
								
								packages/node_modules/@node-red/editor-client/src/js/ui/actionList.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,230 @@ | ||||
| /** | ||||
|  * Copyright JS Foundation and other contributors, http://js.foundation | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  **/ | ||||
| RED.actionList = (function() { | ||||
|  | ||||
|     var disabled = false; | ||||
|     var dialog = null; | ||||
|     var searchInput; | ||||
|     var searchResults; | ||||
|     var selected = -1; | ||||
|     var visible = false; | ||||
|  | ||||
|     var filterTerm = ""; | ||||
|     var filterTerms = []; | ||||
|     var previousActiveElement; | ||||
|  | ||||
|     function ensureSelectedIsVisible() { | ||||
|         var selectedEntry = searchResults.find("li.selected"); | ||||
|         if (selectedEntry.length === 1) { | ||||
|             var scrollWindow = searchResults.parent(); | ||||
|             var scrollHeight = scrollWindow.height(); | ||||
|             var scrollOffset = scrollWindow.scrollTop(); | ||||
|             var y = selectedEntry.position().top; | ||||
|             var h = selectedEntry.height(); | ||||
|             if (y+h > scrollHeight) { | ||||
|                 scrollWindow.animate({scrollTop: '-='+(scrollHeight-(y+h)-10)},50); | ||||
|             } else if (y<0) { | ||||
|                 scrollWindow.animate({scrollTop: '+='+(y-10)},50); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     function createDialog() { | ||||
|         dialog = $("<div>",{id:"red-ui-actionList",class:"red-ui-search"}).appendTo("#red-ui-main-container"); | ||||
|         var searchDiv = $("<div>",{class:"red-ui-search-container"}).appendTo(dialog); | ||||
|         searchInput = $('<input type="text" data-i18n="[placeholder]keyboard.filterActions">').appendTo(searchDiv).searchBox({ | ||||
|             change: function() { | ||||
|                 filterTerm = $(this).val().trim(); | ||||
|                 filterTerms = filterTerm.split(" "); | ||||
|                 searchResults.editableList('filter'); | ||||
|                 searchResults.find("li.selected").removeClass("selected"); | ||||
|                 var children = searchResults.children(":visible"); | ||||
|                 if (children.length) { | ||||
|                     $(children[0]).addClass('selected'); | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|         searchInput.on('keydown',function(evt) { | ||||
|             var selectedChild; | ||||
|             if (evt.keyCode === 40) { | ||||
|                 // Down | ||||
|                 selectedChild = searchResults.find("li.selected"); | ||||
|                 if (!selectedChild.length) { | ||||
|                     var children = searchResults.children(":visible"); | ||||
|                     if (children.length) { | ||||
|                         $(children[0]).addClass('selected'); | ||||
|                     } | ||||
|                 } else { | ||||
|                     var nextChild = selectedChild.nextAll(":visible").first(); | ||||
|                     if (nextChild.length) { | ||||
|                         selectedChild.removeClass('selected'); | ||||
|                         nextChild.addClass('selected'); | ||||
|                     } | ||||
|                 } | ||||
|                 ensureSelectedIsVisible(); | ||||
|                 evt.preventDefault(); | ||||
|             } else if (evt.keyCode === 38) { | ||||
|                 // Up | ||||
|                 selectedChild = searchResults.find("li.selected"); | ||||
|                 var nextChild = selectedChild.prevAll(":visible").first(); | ||||
|                 if (nextChild.length) { | ||||
|                     selectedChild.removeClass('selected'); | ||||
|                     nextChild.addClass('selected'); | ||||
|                 } | ||||
|                 ensureSelectedIsVisible(); | ||||
|                 evt.preventDefault(); | ||||
|             } else if (evt.keyCode === 13) { | ||||
|                 // Enter | ||||
|                 selectedChild = searchResults.find("li.selected"); | ||||
|                 selectCommand(searchResults.editableList('getItem',selectedChild)); | ||||
|             } | ||||
|         }); | ||||
|         searchInput.i18n(); | ||||
|  | ||||
|         var searchResultsDiv = $("<div>",{class:"red-ui-search-results-container"}).appendTo(dialog); | ||||
|         searchResults = $('<ol>',{style:"position: absolute;top: 5px;bottom: 5px;left: 5px;right: 5px;"}).appendTo(searchResultsDiv).editableList({ | ||||
|             addButton: false, | ||||
|             addItem: function(container,i,action) { | ||||
|                 if (action.id === undefined) { | ||||
|                     $('<div>',{class:"red-ui-search-empty"}).text(RED._('search.empty')).appendTo(container); | ||||
|                 } else { | ||||
|                     var div = $('<a>',{href:'#',class:"red-ui-search-result"}).appendTo(container); | ||||
|                     var contentDiv = $('<div>',{class:"red-ui-search-result-action"}).appendTo(div); | ||||
|  | ||||
|  | ||||
|                     $('<div>').text(action.label).appendTo(contentDiv); | ||||
|                     // $('<div>',{class:"red-ui-search-result-node-type"}).text(node.type).appendTo(contentDiv); | ||||
|                     // $('<div>',{class:"red-ui-search-result-node-id"}).text(node.id).appendTo(contentDiv); | ||||
|                     if (action.key) { | ||||
|                         $('<div>',{class:"red-ui-search-result-action-key"}).html(RED.keyboard.formatKey(action.key)).appendTo(contentDiv); | ||||
|                     } | ||||
|                     div.on("click", function(evt) { | ||||
|                         evt.preventDefault(); | ||||
|                         selectCommand(action); | ||||
|                     }); | ||||
|                 } | ||||
|             }, | ||||
|             scrollOnAdd: false, | ||||
|             filter: function(item) { | ||||
|                 if (filterTerm !== "") { | ||||
|                     var pos=0; | ||||
|                     for (var i=0;i<filterTerms.length;i++) { | ||||
|                         var j = item._label.indexOf(filterTerms[i],pos); | ||||
|                         if (j > -1) { | ||||
|                             pos = j; | ||||
|                         } else { | ||||
|                             return false; | ||||
|                         } | ||||
|                     } | ||||
|                     return true; | ||||
|                 } | ||||
|                 return true; | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     function selectCommand(command) { | ||||
|         hide(); | ||||
|         if (command) { | ||||
|             RED.actions.invoke(command.id); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     function show(v) { | ||||
|         if (disabled) { | ||||
|             return; | ||||
|         } | ||||
|         if (!visible) { | ||||
|             previousActiveElement = document.activeElement; | ||||
|             RED.keyboard.add("*","escape",function(){hide()}); | ||||
|             $("#red-ui-header-shade").show(); | ||||
|             $("#red-ui-editor-shade").show(); | ||||
|             $("#red-ui-palette-shade").show(); | ||||
|             $("#red-ui-sidebar-shade").show(); | ||||
|             $("#red-ui-sidebar-separator").hide(); | ||||
|             if (dialog === null) { | ||||
|                 createDialog(); | ||||
|             } | ||||
|             dialog.slideDown(300); | ||||
|             searchInput.searchBox('value',v) | ||||
|             searchResults.editableList('empty'); | ||||
|             results = []; | ||||
|             var actions = RED.actions.list(); | ||||
|             actions.sort(function(A,B) { | ||||
|                 return A.id.localeCompare(B.id); | ||||
|             }); | ||||
|             actions.forEach(function(action) { | ||||
|                 action.label = action.id.replace(/:/,": ").replace(/-/g," ").replace(/(^| )./g,function() { return arguments[0].toUpperCase()}); | ||||
|                 action._label = action.label.toLowerCase(); | ||||
|                 searchResults.editableList('addItem',action) | ||||
|             }) | ||||
|             RED.events.emit("actionList:open"); | ||||
|             visible = true; | ||||
|         } | ||||
|         searchInput.trigger("focus"); | ||||
|         var children = searchResults.children(":visible"); | ||||
|         if (children.length) { | ||||
|             $(children[0]).addClass('selected'); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     function hide() { | ||||
|         if (visible) { | ||||
|             RED.keyboard.remove("escape"); | ||||
|             visible = false; | ||||
|             $("#red-ui-header-shade").hide(); | ||||
|             $("#red-ui-editor-shade").hide(); | ||||
|             $("#red-ui-palette-shade").hide(); | ||||
|             $("#red-ui-sidebar-shade").hide(); | ||||
|             $("#red-ui-sidebar-separator").show(); | ||||
|             if (dialog !== null) { | ||||
|                 dialog.slideUp(200,function() { | ||||
|                     searchInput.searchBox('value',''); | ||||
|                 }); | ||||
|             } | ||||
|             RED.events.emit("actionList:close"); | ||||
|             if (previousActiveElement) { | ||||
|                 $(previousActiveElement).trigger("focus"); | ||||
|                 previousActiveElement = null; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     function init() { | ||||
|         RED.actions.add("core:show-action-list",show); | ||||
|  | ||||
|         RED.events.on("editor:open",function() { disabled = true; }); | ||||
|         RED.events.on("editor:close",function() { disabled = false; }); | ||||
|         RED.events.on("search:open",function() { disabled = true; }); | ||||
|         RED.events.on("search:close",function() { disabled = false; }); | ||||
|         RED.events.on("type-search:open",function() { disabled = true; }); | ||||
|         RED.events.on("type-search:close",function() { disabled = false; }); | ||||
|  | ||||
|         $("#red-ui-header-shade").on('mousedown',hide); | ||||
|         $("#red-ui-editor-shade").on('mousedown',hide); | ||||
|         $("#red-ui-palette-shade").on('mousedown',hide); | ||||
|         $("#red-ui-sidebar-shade").on('mousedown',hide); | ||||
|     } | ||||
|  | ||||
|     return { | ||||
|         init: init, | ||||
|         show: show, | ||||
|         hide: hide | ||||
|     }; | ||||
|  | ||||
| })(); | ||||
| @@ -26,6 +26,7 @@ RED.clipboard = (function() { | ||||
|     var currentPopoverError; | ||||
|     var activeTab; | ||||
|     var libraryBrowser; | ||||
|     var examplesBrowser; | ||||
|  | ||||
|     function setupDialogs() { | ||||
|         dialog = $('<div id="red-ui-clipboard-dialog" class="hide"><form class="dialog-form form-horizontal"></form></div>') | ||||
| @@ -58,7 +59,7 @@ RED.clipboard = (function() { | ||||
|                             element.setAttribute('download', "flows.json"); | ||||
|                             element.style.display = 'none'; | ||||
|                             document.body.appendChild(element); | ||||
|                             element.trigger("click"); | ||||
|                             element.click(); | ||||
|                             document.body.removeChild(element); | ||||
|                             $( this ).dialog( "close" ); | ||||
|                         } | ||||
| @@ -139,10 +140,15 @@ RED.clipboard = (function() { | ||||
|                         text: RED._("common.label.import"), | ||||
|                         click: function() { | ||||
|                             var addNewFlow = ($("#red-ui-clipboard-dialog-import-opt > a.selected").attr('id') === 'red-ui-clipboard-dialog-import-opt-new'); | ||||
|                             if (activeTab === "red-ui-clipboard-dialog-red-ui-clipboard-dialog-import-opt-clipboard") { | ||||
|                             if (activeTab === "red-ui-clipboard-dialog-import-tab-clipboard") { | ||||
|                                 RED.view.importNodes($("#red-ui-clipboard-dialog-import-text").val(),addNewFlow); | ||||
|                             } else { | ||||
|                                 var selectedPath = libraryBrowser.getSelected(); | ||||
|                                 var selectedPath; | ||||
|                                 if (activeTab === "red-ui-clipboard-dialog-import-tab-library") { | ||||
|                                     selectedPath = libraryBrowser.getSelected(); | ||||
|                                 } else { | ||||
|                                     selectedPath = examplesBrowser.getSelected(); | ||||
|                                 } | ||||
|                                 if (selectedPath.path) { | ||||
|                                     $.get('library/'+selectedPath.library+'/'+selectedPath.type+'/'+selectedPath.path, function(data) { | ||||
|                                         RED.view.importNodes(data,addNewFlow); | ||||
| @@ -214,9 +220,8 @@ RED.clipboard = (function() { | ||||
|                             '<textarea id="red-ui-clipboard-dialog-import-text"></textarea>'+ | ||||
|                         '</div>'+ | ||||
|                     '</div>'+ | ||||
|                     '<div id="red-ui-clipboard-dialog-import-tab-library" class="red-ui-clipboard-dialog-tab-library">'+ | ||||
|                         '<div id="red-ui-clipboard-dialog-import-tab-library-browser"></div>'+ | ||||
|                     '</div>'+ | ||||
|                     '<div id="red-ui-clipboard-dialog-import-tab-library" class="red-ui-clipboard-dialog-tab-library"></div>'+ | ||||
|                     '<div id="red-ui-clipboard-dialog-import-tab-examples" class="red-ui-clipboard-dialog-tab-library"></div>'+ | ||||
|                 '</div>'+ | ||||
|             '</div>'+ | ||||
|             '<div class="form-row">'+ | ||||
| @@ -386,30 +391,49 @@ RED.clipboard = (function() { | ||||
|             id: "red-ui-clipboard-dialog-import-tab-library", | ||||
|             label: RED._("library.library") | ||||
|         }); | ||||
|  | ||||
|         tabs.activateTab("red-ui-clipboard-dialog-import-tab-"+mode); | ||||
|         if (mode === 'clipboard') { | ||||
|             setTimeout(function() { | ||||
|                 $("#red-ui-clipboard-dialog-import-text").trigger("focus"); | ||||
|             },100) | ||||
|         } | ||||
|  | ||||
|         tabs.addTab({ | ||||
|             id: "red-ui-clipboard-dialog-import-tab-examples", | ||||
|             label: RED._("library.types.examples") | ||||
|         }); | ||||
|  | ||||
|         $("#red-ui-clipboard-dialog-tab-library-name").on("keyup", validateExportFilename); | ||||
|         $("#red-ui-clipboard-dialog-tab-library-name").on('paste',function() { setTimeout(validateExportFilename,10)}); | ||||
|         $("#red-ui-clipboard-dialog-export").button("enable"); | ||||
|  | ||||
|         libraryBrowser = RED.library.createBrowser({ | ||||
|             container: $("#red-ui-clipboard-dialog-import-tab-library-browser"), | ||||
|             container: $("#red-ui-clipboard-dialog-import-tab-library"), | ||||
|             onselect: function(file) { | ||||
|                 if (file && file.label && !file.children) { | ||||
|                     $("#red-ui-clipboard-dialog-ok").button("enable"); | ||||
|                 } else { | ||||
|                     $("#red-ui-clipboard-dialog-ok").button("disable"); | ||||
|                 } | ||||
|             }, | ||||
|             onconfirm: function(item) { | ||||
|                 if (item && item.label && !item.children) { | ||||
|                     $("#red-ui-clipboard-dialog-ok").trigger("click"); | ||||
|                 } | ||||
|             } | ||||
|         }) | ||||
|         loadFlowLibrary(libraryBrowser,true); | ||||
|         loadFlowLibrary(libraryBrowser,"local",RED._("library.types.local")); | ||||
|  | ||||
|         examplesBrowser = RED.library.createBrowser({ | ||||
|             container: $("#red-ui-clipboard-dialog-import-tab-examples"), | ||||
|             onselect: function(file) { | ||||
|                 if (file && file.label && !file.children) { | ||||
|                     $("#red-ui-clipboard-dialog-ok").button("enable"); | ||||
|                 } else { | ||||
|                     $("#red-ui-clipboard-dialog-ok").button("disable"); | ||||
|                 } | ||||
|             }, | ||||
|             onconfirm: function(item) { | ||||
|                 if (item && item.label && !item.children) { | ||||
|                     $("#red-ui-clipboard-dialog-ok").trigger("click"); | ||||
|                 } | ||||
|             } | ||||
|         }) | ||||
|         loadFlowLibrary(examplesBrowser,"_examples_",RED._("library.types.examples")); | ||||
|  | ||||
|  | ||||
|         dialogContainer.i18n(); | ||||
|  | ||||
| @@ -443,6 +467,14 @@ RED.clipboard = (function() { | ||||
|             $("#red-ui-clipboard-dialog-import-file-upload").trigger("click"); | ||||
|         }) | ||||
|  | ||||
|         tabs.activateTab("red-ui-clipboard-dialog-import-tab-"+mode); | ||||
|         if (mode === 'clipboard') { | ||||
|             setTimeout(function() { | ||||
|                 $("#red-ui-clipboard-dialog-import-text").trigger("focus"); | ||||
|             },100) | ||||
|         } | ||||
|  | ||||
|  | ||||
|         dialog.dialog("option","title",RED._("clipboard.importNodes")).dialog("open"); | ||||
|         popover = RED.popover.create({ | ||||
|             target: $("#red-ui-clipboard-dialog-import-text"), | ||||
| @@ -489,8 +521,6 @@ RED.clipboard = (function() { | ||||
|             label: RED._("library.library") | ||||
|         }); | ||||
|  | ||||
|         tabs.activateTab("red-ui-clipboard-dialog-export-tab-"+mode); | ||||
|  | ||||
|         $("#red-ui-clipboard-dialog-tab-library-name").on("keyup", validateExportFilename); | ||||
|         $("#red-ui-clipboard-dialog-tab-library-name").on('paste',function() { setTimeout(validateExportFilename,10)}); | ||||
|         $("#red-ui-clipboard-dialog-export").button("enable"); | ||||
| @@ -504,7 +534,7 @@ RED.clipboard = (function() { | ||||
|                 } | ||||
|             } | ||||
|         }) | ||||
|         loadFlowLibrary(libraryBrowser,false); | ||||
|         loadFlowLibrary(libraryBrowser,"local",RED._("library.types.local")); | ||||
|  | ||||
|         $("#red-ui-clipboard-dialog-tab-library-name").val("flows.json").select(); | ||||
|  | ||||
| @@ -606,6 +636,7 @@ RED.clipboard = (function() { | ||||
|         } else { | ||||
|             $("#red-ui-clipboard-dialog-export-fmt-mini").trigger("click"); | ||||
|         } | ||||
|         tabs.activateTab("red-ui-clipboard-dialog-export-tab-"+mode); | ||||
|         dialog.dialog("option","title",RED._("clipboard.exportNodes")).dialog( "open" ); | ||||
|  | ||||
|         $("#red-ui-clipboard-dialog-export-text").trigger("focus"); | ||||
| @@ -615,38 +646,37 @@ RED.clipboard = (function() { | ||||
|  | ||||
|     } | ||||
|  | ||||
|     function loadFlowLibrary(browser,includeExamples) { | ||||
|         var listing = []; | ||||
|         if (includeExamples) { | ||||
|             listing.push({ | ||||
|                 library: "_examples_", | ||||
|                 type: "flows", | ||||
|                 icon: 'fa fa-hdd-o', | ||||
|                 label: RED._("library.types.examples"), | ||||
|                 path: "", | ||||
|                 children: function(item,done) { | ||||
|                     RED.library.loadLibraryFolder("_examples_","flows","",function(children) { | ||||
|                         item.children = children; | ||||
|                         done(children); | ||||
|                     }) | ||||
|                 } | ||||
|             }) | ||||
|         } | ||||
|         listing.push({ | ||||
|             library: "local", | ||||
|     function loadFlowLibrary(browser,library,label) { | ||||
|         // if (includeExamples) { | ||||
|         //     listing.push({ | ||||
|         //         library: "_examples_", | ||||
|         //         type: "flows", | ||||
|         //         icon: 'fa fa-hdd-o', | ||||
|         //         label: RED._("library.types.examples"), | ||||
|         //         path: "", | ||||
|         //         children: function(done,item) { | ||||
|         //             RED.library.loadLibraryFolder("_examples_","flows","",function(children) { | ||||
|         //                 item.children = children; | ||||
|         //                 done(children); | ||||
|         //             }) | ||||
|         //         } | ||||
|         //     }) | ||||
|         // } | ||||
|         browser.data([{ | ||||
|             library: library, | ||||
|             type: "flows", | ||||
|             icon: 'fa fa-hdd-o', | ||||
|             label: RED._("library.types.local"), | ||||
|             label: label, | ||||
|             path: "", | ||||
|             expanded: true, | ||||
|             children: function(item,done) { | ||||
|                 RED.library.loadLibraryFolder("local","flows","",function(children) { | ||||
|             children: function(done, item) { | ||||
|                 RED.library.loadLibraryFolder(library,"flows","",function(children) { | ||||
|                     item.children = children; | ||||
|                     done(children); | ||||
|                 }) | ||||
|             } | ||||
|         }) | ||||
|         browser.data(listing); | ||||
|         }], true); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     function hideDropTarget() { | ||||
| @@ -700,17 +730,20 @@ RED.clipboard = (function() { | ||||
|         init: function() { | ||||
|             setupDialogs(); | ||||
|  | ||||
|             $('<input type="text" id="red-ui-clipboard-hidden">').appendTo("#red-ui-editor"); | ||||
|             $('<input type="text" id="red-ui-clipboard-hidden" tabIndex="-1">').appendTo("#red-ui-editor"); | ||||
|  | ||||
|             RED.actions.add("core:show-export-dialog",exportNodes); | ||||
|             RED.actions.add("core:show-import-dialog",importNodes); | ||||
|  | ||||
|             RED.actions.add("core:library-export",function() { exportNodes('library') }); | ||||
|             RED.actions.add("core:show-library-export-dialog",function() { exportNodes('library') }); | ||||
|             RED.actions.add("core:show-library-import-dialog",function() { importNodes('library') }); | ||||
|  | ||||
|             RED.events.on("editor:open",function() { disabled = true; }); | ||||
|             RED.events.on("editor:close",function() { disabled = false; }); | ||||
|             RED.events.on("search:open",function() { disabled = true; }); | ||||
|             RED.events.on("search:close",function() { disabled = false; }); | ||||
|             RED.events.on("actionList:open",function() { disabled = true; }); | ||||
|             RED.events.on("actionList:close",function() { disabled = false; }); | ||||
|             RED.events.on("type-search:open",function() { disabled = true; }); | ||||
|             RED.events.on("type-search:close",function() { disabled = false; }); | ||||
|  | ||||
|   | ||||
| @@ -32,6 +32,7 @@ | ||||
|  *   - scrollOnAdd : boolean - whether to scroll to newly added items | ||||
|  * methods: | ||||
|  *   - addItem(itemData) | ||||
|  *   - insertItemAt : function(data,index) - add an item at the specified index | ||||
|  *   - removeItem(itemData) | ||||
|  *   - width(width) | ||||
|  *   - height(height) | ||||
| @@ -185,6 +186,7 @@ | ||||
|             } | ||||
|         }, | ||||
|         _destroy: function() { | ||||
|             this.topContainer.remove(); | ||||
|         }, | ||||
|         _refreshFilter: function() { | ||||
|             var that = this; | ||||
| @@ -230,7 +232,7 @@ | ||||
|             this.uiHeight = desiredHeight; | ||||
|             this._resize(); | ||||
|         }, | ||||
|         addItem: function(data) { | ||||
|         insertItemAt: function(data,index) { | ||||
|             var that = this; | ||||
|             data = data || {}; | ||||
|             var li = $('<li>'); | ||||
| @@ -248,7 +250,13 @@ | ||||
|                 }); | ||||
|             } | ||||
|             if (!added) { | ||||
|                 li.appendTo(this.element); | ||||
|                 if (index <= 0) { | ||||
|                     li.prependTo(this.element); | ||||
|                 } else if (index > that.element.children().length-1) { | ||||
|                     li.appendTo(this.element); | ||||
|                 } else { | ||||
|                     li.insertBefore(this.element.children().eq(index)); | ||||
|                 } | ||||
|             } | ||||
|             var row = $('<div/>').addClass("red-ui-editableList-item-content").appendTo(li); | ||||
|             row.data('data',data); | ||||
| @@ -293,6 +301,9 @@ | ||||
|                 },0); | ||||
|             } | ||||
|         }, | ||||
|         addItem: function(data) { | ||||
|             this.insertItemAt(data,this.element.children().length) | ||||
|         }, | ||||
|         addItems: function(items) { | ||||
|             for (var i=0; i<items.length;i++) { | ||||
|                 this.addItem(items[i]); | ||||
| @@ -312,6 +323,7 @@ | ||||
|         }, | ||||
|         empty: function() { | ||||
|             this.element.empty(); | ||||
|             this.uiContainer.scrollTop(0); | ||||
|         }, | ||||
|         filter: function(filter) { | ||||
|             if (filter !== undefined) { | ||||
| @@ -335,6 +347,14 @@ | ||||
|             if (items.length > 0) { | ||||
|                 this.uiContainer.scrollTop(this.uiContainer.scrollTop()+items.position().top) | ||||
|             } | ||||
|         }, | ||||
|         getItem: function(li) { | ||||
|             var el = li.find(".red-ui-editableList-item-content"); | ||||
|             if (el.length) { | ||||
|                 return el.data('data'); | ||||
|             } else { | ||||
|                 return null; | ||||
|             } | ||||
|         } | ||||
|     }); | ||||
| })(jQuery); | ||||
|   | ||||
| @@ -71,7 +71,7 @@ RED.menu = (function() { | ||||
|  | ||||
|             } | ||||
|             if (opt.icon !== undefined) { | ||||
|                 if (/\.png/.test(opt.icon)) { | ||||
|                 if (/\.(png|svg)/.test(opt.icon)) { | ||||
|                     linkContent += '<img src="'+opt.icon+'"/> '; | ||||
|                 } else { | ||||
|                     linkContent += '<i class="'+(opt.icon?opt.icon:'" style="display: inline-block;"')+'"></i> '; | ||||
| @@ -98,21 +98,10 @@ RED.menu = (function() { | ||||
|                         return; | ||||
|                     } | ||||
|                     if (opt.toggle) { | ||||
|                         var selected = isSelected(opt.id); | ||||
|                         if (typeof opt.toggle === "string") { | ||||
|                             if (!selected) { | ||||
|                                 for (var m in menuItems) { | ||||
|                                     if (menuItems.hasOwnProperty(m)) { | ||||
|                                         var mi = menuItems[m]; | ||||
|                                         if (mi.id != opt.id && opt.toggle == mi.toggle) { | ||||
|                                             setSelected(mi.id,false); | ||||
|                                         } | ||||
|                                     } | ||||
|                                 } | ||||
|                                 setSelected(opt.id,true); | ||||
|                             } | ||||
|                         if (opt.toggle === true) { | ||||
|                             setSelected(opt.id, !isSelected(opt.id)); | ||||
|                         } else { | ||||
|                             setSelected(opt.id, !selected); | ||||
|                             setSelected(opt.id, true); | ||||
|                         } | ||||
|                     } else { | ||||
|                         triggerAction(opt.id); | ||||
| @@ -209,8 +198,9 @@ RED.menu = (function() { | ||||
|     } | ||||
|  | ||||
|     function setSelected(id,state) { | ||||
|         var alreadySet = false; | ||||
|         if (isSelected(id) == state) { | ||||
|             return; | ||||
|             alreadySet = true; | ||||
|         } | ||||
|         var opt = menuItems[id]; | ||||
|         if (state) { | ||||
| @@ -218,10 +208,26 @@ RED.menu = (function() { | ||||
|         } else { | ||||
|             $("#"+id).removeClass("active"); | ||||
|         } | ||||
|         if (opt && opt.onselect) { | ||||
|             triggerAction(opt.id,state); | ||||
|         if (opt) { | ||||
|             if (opt.toggle && typeof opt.toggle === "string") { | ||||
|                 if (state) { | ||||
|                     for (var m in menuItems) { | ||||
|                         if (menuItems.hasOwnProperty(m)) { | ||||
|                             var mi = menuItems[m]; | ||||
|                             if (mi.id != opt.id && opt.toggle == mi.toggle) { | ||||
|                                 setSelected(mi.id,false); | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             if (!alreadySet && opt.onselect) { | ||||
|                 triggerAction(opt.id,state); | ||||
|             } | ||||
|         } | ||||
|         if (!alreadySet) { | ||||
|             RED.settings.set(opt.setting||("menu-"+opt.id), state); | ||||
|         } | ||||
|         RED.settings.set(opt.setting||("menu-"+opt.id), state); | ||||
|     } | ||||
|  | ||||
|     function toggleSelected(id) { | ||||
|   | ||||
| @@ -52,6 +52,11 @@ RED.popover = (function() { | ||||
|  | ||||
|         var openPopup = function(instant) { | ||||
|             if (active) { | ||||
|                 var existingPopover = target.data("red-ui-popover"); | ||||
|                 if (options.tooltip && existingPopover) { | ||||
|                     active = false; | ||||
|                     return; | ||||
|                 } | ||||
|                 div = $('<div class="red-ui-popover"></div>'); | ||||
|                 if (size !== "default") { | ||||
|                     div.addClass("red-ui-popover-size-"+size); | ||||
| @@ -122,7 +127,10 @@ RED.popover = (function() { | ||||
|                     } | ||||
|                 } | ||||
|                 div.addClass('red-ui-popover-'+d).css({top: top, left: left}); | ||||
|  | ||||
|                 if (existingPopover) { | ||||
|                     existingPopover.close(true); | ||||
|                 } | ||||
|                 target.data("red-ui-popover",res) | ||||
|                 if (instant) { | ||||
|                     div.show(); | ||||
|                 } else { | ||||
| @@ -142,6 +150,7 @@ RED.popover = (function() { | ||||
|                         }); | ||||
|                     } | ||||
|                     div = null; | ||||
|                     target.removeData("red-ui-popover",res) | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| @@ -236,6 +245,7 @@ RED.popover = (function() { | ||||
|                 } | ||||
|             } | ||||
|             return RED.popover.create({ | ||||
|                 tooltip: true, | ||||
|                 target:target, | ||||
|                 trigger: "hover", | ||||
|                 size: "small", | ||||
|   | ||||
| @@ -87,6 +87,7 @@ | ||||
|                         that._trigger("change"); | ||||
|                     },this.options.delay); | ||||
|                 } else { | ||||
|                     this.lastSent = this.element.val(); | ||||
|                     this._trigger("change"); | ||||
|                 } | ||||
|             } | ||||
|   | ||||
							
								
								
									
										100
									
								
								packages/node_modules/@node-red/editor-client/src/js/ui/common/toggleButton.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,100 @@ | ||||
| /** | ||||
|  * Copyright JS Foundation and other contributors, http://js.foundation | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  **/ | ||||
| (function($) { | ||||
|  | ||||
| /** | ||||
|  * options: | ||||
|  *   - invertState   : boolean - if "true" the button will show "enabled" when the | ||||
|  *                             checkbox is not selected and vice versa. | ||||
|  *   - enabledIcon   : string - the icon for "enabled" state, default "fa-check-square-o" | ||||
|  *   - enabledLabel  : string - the label for "enabled" state, default "Enabled" ("editor:workspace.enabled") | ||||
|  *   - disabledIcon  : string - the icon for "disabled" state, default "fa-square-o" | ||||
|  *   - disabledLabel : string - the label for "disabled" state, default "Disabled" ("editor:workspace.disabled") | ||||
|  *   - baseClass     : string - the base css class to apply, default "red-ui-button" (alternative eg "red-ui-sidebar-header-button") | ||||
|  *   - class         : string - additional classes to apply to the button - eg "red-ui-button-small" | ||||
|  * methods: | ||||
|  *   - | ||||
|  */ | ||||
|     $.widget( "nodered.toggleButton", { | ||||
|         _create: function() { | ||||
|             var that = this; | ||||
|  | ||||
|             var invertState = false; | ||||
|             if (this.options.hasOwnProperty("invertState")) { | ||||
|                 invertState = this.options.invertState; | ||||
|             } | ||||
|             var baseClass = this.options.baseClass || "red-ui-button"; | ||||
|             var enabledIcon = this.options.enabledIcon || "fa-check-square-o"; | ||||
|             var disabledIcon = this.options.disabledIcon || "fa-square-o"; | ||||
|             var enabledLabel = this.options.enabledLabel || RED._("editor:workspace.enabled"); | ||||
|             var disabledLabel = this.options.disabledLabel || RED._("editor:workspace.disabled"); | ||||
|  | ||||
|             this.element.css("display","none"); | ||||
|             this.element.on("focus", function() { | ||||
|                 that.button.focus(); | ||||
|             }); | ||||
|             this.button = $('<button type="button" class="red-ui-toggleButton '+baseClass+' toggle single"><i class="fa"></i> <span></span></button>'); | ||||
|             if (this.options.class) { | ||||
|                 this.button.addClass(this.options.class) | ||||
|             } | ||||
|             this.element.after(this.button); | ||||
|             this.buttonIcon = this.button.find("i"); | ||||
|             this.buttonLabel = this.button.find("span"); | ||||
|  | ||||
|             // Quick hack to find the maximum width of the button | ||||
|             this.button.addClass("selected"); | ||||
|             this.buttonIcon.addClass(enabledIcon); | ||||
|             this.buttonLabel.text(enabledLabel); | ||||
|             var width = this.button.width(); | ||||
|             this.button.removeClass("selected"); | ||||
|             this.buttonIcon.removeClass(enabledIcon); | ||||
|             that.buttonIcon.addClass(disabledIcon); | ||||
|             that.buttonLabel.text(disabledLabel); | ||||
|             width = Math.max(width,this.button.width()); | ||||
|             this.buttonIcon.removeClass(disabledIcon); | ||||
|  | ||||
|             // Fix the width of the button so it doesn't jump around when toggled | ||||
|             if (width > 0) { | ||||
|                 this.button.width(Math.ceil(width)); | ||||
|             } | ||||
|  | ||||
|             this.button.on("click",function(e) { | ||||
|                 e.stopPropagation(); | ||||
|                 if (that.buttonIcon.hasClass(disabledIcon)) { | ||||
|                     that.element.prop("checked",!invertState); | ||||
|                 } else { | ||||
|                     that.element.prop("checked",invertState); | ||||
|                 } | ||||
|                 that.element.trigger("change"); | ||||
|             }) | ||||
|  | ||||
|             this.element.on("change", function(e) { | ||||
|                 if ($(this).prop("checked") !== invertState) { | ||||
|                     that.button.addClass("selected"); | ||||
|                     that.buttonIcon.addClass(enabledIcon); | ||||
|                     that.buttonIcon.removeClass(disabledIcon); | ||||
|                     that.buttonLabel.text(enabledLabel); | ||||
|                 } else { | ||||
|                     that.button.removeClass("selected"); | ||||
|                     that.buttonIcon.addClass(disabledIcon); | ||||
|                     that.buttonIcon.removeClass(enabledIcon); | ||||
|                     that.buttonLabel.text(disabledLabel); | ||||
|                 } | ||||
|             }) | ||||
|             this.element.trigger("change"); | ||||
|         } | ||||
|     }); | ||||
| })(jQuery); | ||||
| @@ -18,32 +18,70 @@ | ||||
| /** | ||||
|  * options: | ||||
|  *   - data : array - initial items to display in tree | ||||
|  *   - multi : boolean - if true, .selected will return an array of results | ||||
|  *                       otherwise, returns the first selected item | ||||
|  *   - sortable: boolean/string - TODO: see editableList | ||||
|  *   - rootSortable: boolean - if 'sortable' is set, then setting this to | ||||
|  *                             false, prevents items being sorted to the | ||||
|  *                             top level of the tree | ||||
|  * | ||||
|  * methods: | ||||
|  *   - data(items) - clears existing items and replaces with new data | ||||
|  * | ||||
|  * events: | ||||
|  *   - treelistselect : function(event, item) {} | ||||
|  * | ||||
|  *   - treelistconfirm : function(event,item) {} | ||||
|  *   - treelistchangeparent: function(event,item, oldParent, newParent) {} | ||||
|  * | ||||
|  * data: | ||||
|  * [ | ||||
|  *     { | ||||
|  *         label: 'Local', // label for the item | ||||
|  *         sublabel: 'Local', // a sub-label for the item | ||||
|  *         icon: 'fa fa-rocket', // (optional) icon for the item | ||||
|  *         selected: true/false, // (optional) if present, display checkbox accordingly | ||||
|  *         children: [] | function(item,done) // (optional) an array of child items, or a function | ||||
|  *         children: [] | function(done,item) // (optional) an array of child items, or a function | ||||
|  *                                       // that will call the `done` callback with an array | ||||
|  *                                       // of child items | ||||
|  *         expanded: true/false, // show the child items by default | ||||
|  *         deferBuild: true/false, // don't build any ui elements for the item's children | ||||
|  *                                    until it is expanded by the user. | ||||
|  *         element: // custom dom element to use for the item - ignored if `label` is set | ||||
|  *     } | ||||
|  * ] | ||||
|  * | ||||
|  * | ||||
|  * | ||||
|  * var treeList = $("<div>").css({width: "100%", height: "100%"}).treeList({data:[...]}) | ||||
|  * treeList.on('treelistselect', function(e,item) { console.log(item)}) | ||||
|  * treeList.treeList('data',[ ... ] ) | ||||
|  * | ||||
|  * | ||||
|  * After `data` has been added to the tree, each item is augmented the following | ||||
|  * properties and functions: | ||||
|  * | ||||
|  *   item.parent - set to the parent item | ||||
|  *   item.treeList.container | ||||
|  *   item.treeList.label - the label element for the item | ||||
|  *   item.treeList.depth - the depth in the tree (0 == root) | ||||
|  *   item.treeList.parentList  - the editableList instance this item is in | ||||
|  *   item.treeList.remove() - removes the item from the tree | ||||
|  *   item.treeList.makeLeaf(detachChildElements) - turns an element with children into a leaf node, | ||||
|  *                                                 removing the UI decoration etc. | ||||
|  *                                                 detachChildElements - any children with custom | ||||
|  *                                                 elements will be detached rather than removed | ||||
|  *                                                 so jQuery event handlers are preserved in case | ||||
|  *                                                 the child elements need to be reattached later | ||||
|  *   item.treeList.makeParent(children) - turns an element into a parent node, adding the necessary | ||||
|  *                                        UI decoration. | ||||
|  *   item.treeList.insertChildAt(newItem,position,select) - adds a child item an the specified position. | ||||
|  *                                                          Optionally selects the item after adding. | ||||
|  *   item.treeList.addChild(newItem,select) - appends a child item. | ||||
|  *                                            Optionally selects the item after adding. | ||||
|  *   item.treeList.expand(done) - expands the parent item to show children. Optional 'done' callback. | ||||
|  *   item.treeList.collapse() - collapse the parent item to hide children. | ||||
|  * | ||||
|  * | ||||
|  * | ||||
|  * | ||||
|  */ | ||||
|  | ||||
|     $.widget( "nodered.treeList", { | ||||
| @@ -61,6 +99,18 @@ | ||||
|                 } | ||||
|                 var target; | ||||
|                 switch(evt.keyCode) { | ||||
|                     case 13: // ENTER | ||||
|                         if (selected.children) { | ||||
|                             if (selected.treeList.container.hasClass("expanded")) { | ||||
|                                 selected.treeList.collapse() | ||||
|                             } else { | ||||
|                                 selected.treeList.expand() | ||||
|                             } | ||||
|                         } else { | ||||
|                             that._trigger("confirm",null,selected) | ||||
|                         } | ||||
|  | ||||
|                     break; | ||||
|                     case 37: // LEFT | ||||
|                         if (selected.children&& selected.treeList.container.hasClass("expanded")) { | ||||
|                             selected.treeList.collapse() | ||||
| @@ -102,20 +152,30 @@ | ||||
|             }); | ||||
|             this._data = []; | ||||
|  | ||||
|             this._topList = $('<ol>').css({ | ||||
|             this._topList = $('<ol class="red-ui-treeList-list">').css({ | ||||
|                 position:'absolute', | ||||
|                 top: 0, | ||||
|                 left:0, | ||||
|                 right:0, | ||||
|                 bottom:0 | ||||
|             }).appendTo(wrapper).editableList({ | ||||
|             }).appendTo(wrapper); | ||||
|  | ||||
|             var topListOptions = { | ||||
|                 addButton: false, | ||||
|                 scrollOnAdd: false, | ||||
|                 height: '100%', | ||||
|                 addItem: function(container,i,item) { | ||||
|                     that._addSubtree(that._topList,container,item,0); | ||||
|                 } | ||||
|             }) | ||||
|             }; | ||||
|             if (this.options.rootSortable !== false && !!this.options.sortable) { | ||||
|                 topListOptions.sortable = this.options.sortable; | ||||
|                 topListOptions.connectWith = '.red-ui-treeList-sortable'; | ||||
|                 this._topList.addClass('red-ui-treeList-sortable'); | ||||
|             } | ||||
|             this._topList.editableList(topListOptions) | ||||
|  | ||||
|  | ||||
|             if (this.options.data) { | ||||
|                 this.data(this.options.data); | ||||
|             } | ||||
| @@ -157,23 +217,82 @@ | ||||
|         }, | ||||
|         _addChildren: function(container,parent,children,depth) { | ||||
|             var that = this; | ||||
|             var subtree = $('<ol>').appendTo(container).editableList({ | ||||
|             var subtree = $('<ol class="red-ui-treeList-list">').appendTo(container).editableList({ | ||||
|                 connectWith: ".red-ui-treeList-sortable", | ||||
|                 sortable: that.options.sortable, | ||||
|                 addButton: false, | ||||
|                 scrollOnAdd: false, | ||||
|                 height: 'auto', | ||||
|                 addItem: function(container,i,item) { | ||||
|                     that._addSubtree(subtree,container,item,depth+1); | ||||
|                 }, | ||||
|                 sortItems: function(data) { | ||||
|                     var children = []; | ||||
|                     var reparented = []; | ||||
|                     data.each(function() { | ||||
|                         var child = $(this).data('data'); | ||||
|                         children.push(child); | ||||
|                         var evt = that._fixDepths(parent,child); | ||||
|                         if (evt) { | ||||
|                             reparented.push(evt); | ||||
|                         } | ||||
|                     }) | ||||
|                     if (Array.isArray(parent.children)) { | ||||
|                         parent.children = children; | ||||
|                     } | ||||
|                     reparented.forEach(function(evt) { | ||||
|                         that._trigger("changeparent",null,evt); | ||||
|                     }); | ||||
|                     that._trigger("sort",null,parent); | ||||
|                 } | ||||
|             }); | ||||
|             if (!!that.options.sortable) { | ||||
|                 subtree.addClass('red-ui-treeList-sortable'); | ||||
|             } | ||||
|             for (var i=0;i<children.length;i++) { | ||||
|                 children[i].parent = parent; | ||||
|                 subtree.editableList('addItem',children[i]) | ||||
|             } | ||||
|             return subtree; | ||||
|         }, | ||||
|         _fixDepths: function(parent,child) { | ||||
|             // If child has just been moved into parent in the UI | ||||
|             // this will fix up the internal data structures to match. | ||||
|             // The calling function must take care of getting child | ||||
|             // into the parent.children array. The rest is up to us. | ||||
|             var that = this; | ||||
|             var reparentedEvent = null; | ||||
|             if (child.parent !== parent) { | ||||
|                 reparented = true; | ||||
|                 var oldParent = child.parent; | ||||
|                 child.parent = parent; | ||||
|                 reparentedEvent = { | ||||
|                     item: child, | ||||
|                     old: oldParent, | ||||
|                 } | ||||
|             } | ||||
|             if (child.depth !== parent.depth+1) { | ||||
|                 child.depth = parent.depth+1; | ||||
|                 var labelPaddingWidth = ((child.gutter?child.gutter.width()+2:0)+(child.depth*20)); | ||||
|                 child.treeList.labelPadding.width(labelPaddingWidth+'px'); | ||||
|                 if (child.element) { | ||||
|                     $(child.element).css({ | ||||
|                         width: "calc(100% - "+(labelPaddingWidth+20+(child.icon?20:0))+"px)" | ||||
|                     }) | ||||
|                 } | ||||
|                 // This corrects all child item depths | ||||
|                 if (child.children && Array.isArray(child.children)) { | ||||
|                     child.children.forEach(function(item) { | ||||
|                         that._fixDepths(child,item); | ||||
|                     }) | ||||
|                 } | ||||
|             } | ||||
|             return reparentedEvent; | ||||
|         }, | ||||
|         _addSubtree: function(parentList, container, item, depth) { | ||||
|             var that = this; | ||||
|             item.treeList = {}; | ||||
|             item.treeList.depth = depth; | ||||
|             item.treeList.container = container; | ||||
|  | ||||
|             item.treeList.parentList = parentList; | ||||
| @@ -182,87 +301,80 @@ | ||||
|                 if (item.parent) { | ||||
|                     var index = item.parent.children.indexOf(item); | ||||
|                     item.parent.children.splice(index,1) | ||||
|                     that._trigger("sort",null,item.parent); | ||||
|                 } | ||||
|             } | ||||
|             var labelNodeType = "<div>"; | ||||
|             // if (item.children && item.hasOwnProperty('selected')) { | ||||
|             //     labelNodeType = "<div>"; | ||||
|             // } | ||||
|             var label = $(labelNodeType,{class:"red-ui-treeList-label"}).appendTo(container); | ||||
|  | ||||
|             var label = $("<div>",{class:"red-ui-treeList-label"}).appendTo(container); | ||||
|             item.treeList.label = label; | ||||
|             if (item.class) { | ||||
|                 label.addClass(item.class); | ||||
|             } | ||||
|             label.css({ | ||||
|                 paddingLeft: (depth*15)+'px' | ||||
|             }) | ||||
|             if (item.gutter) { | ||||
|                 item.gutter.css({ | ||||
|                     position: 'absolute' | ||||
|                 }).appendTo(label) | ||||
|  | ||||
|             } | ||||
|             var labelPaddingWidth = (item.gutter?item.gutter.width()+2:0)+(depth*20); | ||||
|             item.treeList.labelPadding = $('<span>').css({ | ||||
|                 display: "inline-block", | ||||
|                 width:  labelPaddingWidth+'px' | ||||
|             }).appendTo(label); | ||||
|  | ||||
|             label.on('mouseover',function(e) { that._trigger('itemmouseover',e,item); }) | ||||
|             label.on('mouseout',function(e) { that._trigger('itemmouseout',e,item); }) | ||||
|             label.on('mouseenter',function(e) { that._trigger('itemmouseenter',e,item); }) | ||||
|             label.on('mouseleave',function(e) { that._trigger('itemmouseleave',e,item); }) | ||||
|  | ||||
|             if (item.children) { | ||||
|                 item.treeList.addChild = function(newItem,select) { | ||||
|                     item.treeList.childList.editableList('addItem',newItem) | ||||
|                     newItem.parent = item; | ||||
|                     item.children.push(newItem); | ||||
|                     if (select) { | ||||
|                         setTimeout(function() { | ||||
|                             that.select(newItem) | ||||
|                         },100); | ||||
|                     } | ||||
|             item.treeList.makeLeaf = function(detachChildElements) { | ||||
|                 if (!treeListIcon.children().length) { | ||||
|                     // Already a leaf | ||||
|                     return | ||||
|                 } | ||||
|                 item.treeList.expand = function(done) { | ||||
|                     if (container.hasClass("expanded")) { | ||||
|                         done && done(); | ||||
|                         return; | ||||
|                     } | ||||
|                     if (!container.hasClass("built") && typeof item.children === 'function') { | ||||
|                         container.addClass('built'); | ||||
|                         var childrenAdded = false; | ||||
|                         var spinner; | ||||
|                         var startTime = 0; | ||||
|                         item.children(item,function(children) { | ||||
|                             childrenAdded = true; | ||||
|                             item.treeList.childList = that._addChildren(container,item,children,depth).hide(); | ||||
|                             var delta = Date.now() - startTime; | ||||
|                             if (delta < 400) { | ||||
|                                 setTimeout(function() { | ||||
|                                     item.treeList.childList.slideDown('fast'); | ||||
|                                     if (spinner) { | ||||
|                                         spinner.remove(); | ||||
|                                     } | ||||
|                                 },400-delta); | ||||
|                             } else { | ||||
|                                 item.treeList.childList.slideDown('fast'); | ||||
|                                 if (spinner) { | ||||
|                                     spinner.remove(); | ||||
|                 if (detachChildElements && item.children) { | ||||
|                     var detachChildren = function(item) { | ||||
|                         if (item.children) { | ||||
|                             item.children.forEach(function(child) { | ||||
|                                 if (child.element) { | ||||
|                                     child.element.detach(); | ||||
|                                 } | ||||
|                             } | ||||
|                             done && done(); | ||||
|                             that._trigger("childrenloaded",null,item) | ||||
|                         }); | ||||
|                         if (!childrenAdded) { | ||||
|                             startTime = Date.now(); | ||||
|                             spinner = $('<div class="red-ui-treeList-spinner">').css({ | ||||
|                                 "background-position": (35+depth*15)+'px 50%' | ||||
|                             }).appendTo(container); | ||||
|                                 if (child.gutter) { | ||||
|                                     child.gutter.detach(); | ||||
|                                 } | ||||
|                                 detachChildren(child); | ||||
|                             }); | ||||
|                         } | ||||
|  | ||||
|                     } else { | ||||
|                         item.treeList.childList.slideDown('fast'); | ||||
|                         done && done(); | ||||
|                     } | ||||
|                     container.addClass("expanded"); | ||||
|                     detachChildren(item); | ||||
|                 } | ||||
|                 item.treeList.collapse = function() { | ||||
|                     item.treeList.childList.slideUp('fast'); | ||||
|                     container.removeClass("expanded"); | ||||
|                 treeListIcon.empty(); | ||||
|                 if (!item.deferBuild) { | ||||
|                     item.treeList.childList.remove(); | ||||
|                     delete item.treeList.childList; | ||||
|                 } | ||||
|  | ||||
|                 $('<span class="red-ui-treeList-icon"><i class="fa fa-angle-right" /></span>').appendTo(label); | ||||
|                 label.off("click.red-ui-treeList-expand"); | ||||
|                 treeListIcon.off("click.red-ui-treeList-expand"); | ||||
|                 delete item.children; | ||||
|                 container.removeClass("expanded"); | ||||
|             } | ||||
|             item.treeList.makeParent = function(children) { | ||||
|                 if (treeListIcon.children().length) { | ||||
|                     // Already a parent because we've got the angle-right icon | ||||
|                     return; | ||||
|                 } | ||||
|                 $('<i class="fa fa-angle-right" />').appendTo(treeListIcon); | ||||
|                 treeListIcon.on("click.red-ui-treeList-expand", function(e) { | ||||
|                         e.stopPropagation(); | ||||
|                         e.preventDefault(); | ||||
|                         if (container.hasClass("expanded")) { | ||||
|                             item.treeList.collapse(); | ||||
|                         } else { | ||||
|                             item.treeList.expand(); | ||||
|                         } | ||||
|                     }); | ||||
|                 // $('<span class="red-ui-treeList-icon"><i class="fa fa-folder-o" /></span>').appendTo(label); | ||||
|                 label.on("click", function(e) { | ||||
|                 label.on("click.red-ui-treeList-expand", function(e) { | ||||
|                     if (container.hasClass("expanded")) { | ||||
|                         if (item.hasOwnProperty('selected') || label.hasClass("selected")) { | ||||
|                             item.treeList.collapse(); | ||||
| @@ -271,36 +383,151 @@ | ||||
|                         item.treeList.expand(); | ||||
|                     } | ||||
|                 }) | ||||
|             } else { | ||||
|                 $('<span class="red-ui-treeList-icon"></span>').appendTo(label); | ||||
|                 if (!item.children) { | ||||
|                     item.children = children||[]; | ||||
|                     item.treeList.childList = that._addChildren(container,item,item.children,depth).hide(); | ||||
|                 } | ||||
|             } | ||||
|             item.treeList.insertChildAt = function(newItem,position,select) { | ||||
|                 newItem.parent = item; | ||||
|                 item.children.splice(position,0,newItem); | ||||
|  | ||||
|                 if (!item.deferBuild) { | ||||
|                     item.treeList.childList.editableList('insertItemAt',newItem,position) | ||||
|                     if (select) { | ||||
|                         setTimeout(function() { | ||||
|                             that.select(newItem) | ||||
|                         },100); | ||||
|                     } | ||||
|                     that._trigger("sort",null,item); | ||||
|                 } | ||||
|             } | ||||
|             item.treeList.addChild = function(newItem,select) { | ||||
|                 item.treeList.insertChildAt(newItem,item.children.length,select); | ||||
|             } | ||||
|             item.treeList.expand = function(done) { | ||||
|                 if (!item.children) { | ||||
|                     return; | ||||
|                 } | ||||
|                 if (container.hasClass("expanded")) { | ||||
|                     done && done(); | ||||
|                     return; | ||||
|                 } | ||||
|                 if (!container.hasClass("built") && (item.deferBuild || typeof item.children === 'function')) { | ||||
|                     container.addClass('built'); | ||||
|                     var childrenAdded = false; | ||||
|                     var spinner; | ||||
|                     var startTime = 0; | ||||
|                     var completeBuild = function(children) { | ||||
|                         childrenAdded = true; | ||||
|                         item.treeList.childList = that._addChildren(container,item,children,depth).hide(); | ||||
|                         var delta = Date.now() - startTime; | ||||
|                         if (delta < 400) { | ||||
|                             setTimeout(function() { | ||||
|                                 item.treeList.childList.slideDown('fast'); | ||||
|                                 if (spinner) { | ||||
|                                     spinner.remove(); | ||||
|                                 } | ||||
|                             },400-delta); | ||||
|                         } else { | ||||
|                             item.treeList.childList.slideDown('fast'); | ||||
|                             if (spinner) { | ||||
|                                 spinner.remove(); | ||||
|                             } | ||||
|                         } | ||||
|                         done && done(); | ||||
|                         that._trigger("childrenloaded",null,item) | ||||
|                     } | ||||
|                     if (typeof item.children === 'function') { | ||||
|                         item.children(completeBuild,item); | ||||
|                     } else { | ||||
|                         delete item.deferBuild; | ||||
|                         completeBuild(item.children); | ||||
|                     } | ||||
|                     if (!childrenAdded) { | ||||
|                         startTime = Date.now(); | ||||
|                         spinner = $('<div class="red-ui-treeList-spinner">').css({ | ||||
|                             "background-position": (35+depth*20)+'px 50%' | ||||
|                         }).appendTo(container); | ||||
|                     } | ||||
|  | ||||
|                 } else { | ||||
|                     if (that._loadingData) { | ||||
|                         item.treeList.childList.show(); | ||||
|                     } else { | ||||
|                         item.treeList.childList.slideDown('fast'); | ||||
|                     } | ||||
|                     done && done(); | ||||
|                 } | ||||
|                 container.addClass("expanded"); | ||||
|             } | ||||
|             item.treeList.collapse = function() { | ||||
|                 if (!item.children) { | ||||
|                     return; | ||||
|                 } | ||||
|                 item.treeList.childList.slideUp('fast'); | ||||
|                 container.removeClass("expanded"); | ||||
|             } | ||||
|  | ||||
|             var treeListIcon = $('<span class="red-ui-treeList-icon"></span>').appendTo(label); | ||||
|             if (item.children) { | ||||
|                 item.treeList.makeParent(); | ||||
|             } | ||||
|  | ||||
|             if (item.hasOwnProperty('selected')) { | ||||
|                 var selectWrapper = $('<span class="red-ui-treeList-icon"></span>').appendTo(label); | ||||
|                 var cb = $('<input class="red-ui-treeList-checkbox" type="checkbox">').prop('checked',item.selected).appendTo(selectWrapper); | ||||
|                 label.toggleClass("selected",item.selected); | ||||
|                 cb.on('click', function(e) { | ||||
|                     e.stopPropagation(); | ||||
|                 }); | ||||
|                 cb.on('change', function(e) { | ||||
|                     item.selected = this.checked; | ||||
|                     label.toggleClass("selected",this.checked); | ||||
|                     that._trigger("select",e,item); | ||||
|                 }) | ||||
|                 if (!item.children) { | ||||
|                     label.on("click", function(e) { | ||||
|                         e.stopPropagation(); | ||||
|                         cb.trigger("click"); | ||||
|                     }) | ||||
|                 } | ||||
|                 item.treeList.select = function(v) { | ||||
|                     if (v !== item.selected) { | ||||
|                         cb.trigger("click"); | ||||
|                     } | ||||
|                 } | ||||
|             } else { | ||||
|                 label.on("click", function(e) { | ||||
|                     that._topList.find(".selected").removeClass("selected"); | ||||
|                     label.addClass("selected"); | ||||
|                     that._trigger("select",e,item) | ||||
|                 }) | ||||
|                 label.on("dblclick", function(e) { | ||||
|                     if (!item.children) { | ||||
|                         that._trigger("confirm",e,item); | ||||
|                     } | ||||
|                 }) | ||||
|             } | ||||
|             if (item.icon) { | ||||
|                 $('<span class="red-ui-treeList-icon"><i class="'+item.icon+'" /></span>').appendTo(label); | ||||
|             } | ||||
|             if (item.label) { | ||||
|                 $('<span class="red-ui-treeList-label-text"></span>').text(item.label).appendTo(label); | ||||
|             if (item.hasOwnProperty('label') || item.hasOwnProperty('sublabel')) { | ||||
|                 if (item.hasOwnProperty('label')) { | ||||
|                     $('<span class="red-ui-treeList-label-text"></span>').text(item.label).appendTo(label); | ||||
|                 } | ||||
|                 if (item.hasOwnProperty('sublabel')) { | ||||
|                     $('<span class="red-ui-treeList-sublabel-text"></span>').text(item.sublabel).appendTo(label); | ||||
|                 } | ||||
|  | ||||
|             } else if (item.element) { | ||||
|                 $(item.element).appendTo(label); | ||||
|                 $(item.element).css({ | ||||
|                     width: "calc(100% - "+(labelPaddingWidth+20+(item.icon?20:0))+"px)" | ||||
|                 }) | ||||
|             } | ||||
|             if (item.children) { | ||||
|                 if (Array.isArray(item.children)) { | ||||
|                 if (Array.isArray(item.children) && !item.deferBuild) { | ||||
|                     item.treeList.childList = that._addChildren(container,item,item.children,depth).hide(); | ||||
|                 } | ||||
|                 if (item.expanded) { | ||||
| @@ -312,12 +539,17 @@ | ||||
|             this._topList.editableList('empty'); | ||||
|         }, | ||||
|         data: function(items) { | ||||
|             var that = this; | ||||
|             if (items !== undefined) { | ||||
|                 this._data = items; | ||||
|                 this._topList.editableList('empty'); | ||||
|                 this._loadingData = true; | ||||
|                 for (var i=0; i<items.length;i++) { | ||||
|                     this._topList.editableList('addItem',items[i]); | ||||
|                 } | ||||
|                 setTimeout(function() { | ||||
|                     delete that._loadingData; | ||||
|                 },200); | ||||
|                 this._trigger("select") | ||||
|  | ||||
|             } else { | ||||
| @@ -338,8 +570,19 @@ | ||||
|  | ||||
|         }, | ||||
|         selected: function() { | ||||
|             var s = this._topList.find(".selected").parent().data('data'); | ||||
|             return s; | ||||
|             var s = this._topList.find(".selected"); | ||||
|             if (this.options.multi) { | ||||
|                 var res = []; | ||||
|                 s.each(function() { | ||||
|                     res.push($(this).parent().data('data')); | ||||
|                 }) | ||||
|                 return res; | ||||
|             } | ||||
|             if (s.length) { | ||||
|                 return s.parent().data('data'); | ||||
|             } else { | ||||
|                 return undefined; | ||||
|             } | ||||
|         } | ||||
|     }); | ||||
|  | ||||
|   | ||||
| @@ -32,6 +32,12 @@ | ||||
|             return v; | ||||
|         } | ||||
|     } | ||||
|     var mapDeprecatedIcon = function(icon) { | ||||
|         if (/^red\/images\/typedInput\/.+\.png$/.test(icon)) { | ||||
|             icon = icon.replace(/.png$/,".svg"); | ||||
|         } | ||||
|         return icon; | ||||
|     } | ||||
|     var allOptions = { | ||||
|         msg: {value:"msg",label:"msg.",validate:RED.utils.validatePropertyExpression}, | ||||
|         flow: {value:"flow",label:"flow.",hasValue:true, | ||||
| @@ -46,13 +52,13 @@ | ||||
|             parse: contextParse, | ||||
|             export: contextExport | ||||
|         }, | ||||
|         str: {value:"str",label:"string",icon:"red/images/typedInput/az.png"}, | ||||
|         num: {value:"num",label:"number",icon:"red/images/typedInput/09.png",validate:/^[+-]?[0-9]*\.?[0-9]*([eE][-+]?[0-9]+)?$/}, | ||||
|         bool: {value:"bool",label:"boolean",icon:"red/images/typedInput/bool.png",options:["true","false"]}, | ||||
|         str: {value:"str",label:"string",icon:"red/images/typedInput/az.svg"}, | ||||
|         num: {value:"num",label:"number",icon:"red/images/typedInput/09.svg",validate:/^[+-]?[0-9]*\.?[0-9]*([eE][-+]?[0-9]+)?$/}, | ||||
|         bool: {value:"bool",label:"boolean",icon:"red/images/typedInput/bool.svg",options:["true","false"]}, | ||||
|         json: { | ||||
|             value:"json", | ||||
|             label:"JSON", | ||||
|             icon:"red/images/typedInput/json.png", | ||||
|             icon:"red/images/typedInput/json.svg", | ||||
|             validate: function(v) { try{JSON.parse(v);return true;}catch(e){return false;}}, | ||||
|             expand: function() { | ||||
|                 var that = this; | ||||
| @@ -74,12 +80,12 @@ | ||||
|                 }) | ||||
|             } | ||||
|         }, | ||||
|         re: {value:"re",label:"regular expression",icon:"red/images/typedInput/re.png"}, | ||||
|         re: {value:"re",label:"regular expression",icon:"red/images/typedInput/re.svg"}, | ||||
|         date: {value:"date",label:"timestamp",hasValue:false}, | ||||
|         jsonata: { | ||||
|             value: "jsonata", | ||||
|             label: "expression", | ||||
|             icon: "red/images/typedInput/expr.png", | ||||
|             icon: "red/images/typedInput/expr.svg", | ||||
|             validate: function(v) { try{jsonata(v);return true;}catch(e){return false;}}, | ||||
|             expand:function() { | ||||
|                 var that = this; | ||||
| @@ -94,7 +100,7 @@ | ||||
|         bin: { | ||||
|             value: "bin", | ||||
|             label: "buffer", | ||||
|             icon: "red/images/typedInput/bin.png", | ||||
|             icon: "red/images/typedInput/bin.svg", | ||||
|             expand: function() { | ||||
|                 var that = this; | ||||
|                 RED.editor.editBuffer({ | ||||
| @@ -108,7 +114,56 @@ | ||||
|         env: { | ||||
|             value: "env", | ||||
|             label: "env variable", | ||||
|             icon: "red/images/typedInput/env.png" | ||||
|             icon: "red/images/typedInput/env.svg" | ||||
|         }, | ||||
|         node: { | ||||
|             value: "node", | ||||
|             label: "node", | ||||
|             icon: "red/images/typedInput/target.svg", | ||||
|             valueLabel: function(container,value) { | ||||
|                 var node = RED.nodes.node(value); | ||||
|                 var nodeDiv = $('<div>',{class:"red-ui-search-result-node"}).css({ | ||||
|                     "margin-top": "2px", | ||||
|                     "margin-left": "3px" | ||||
|                 }).appendTo(container); | ||||
|                 var nodeLabel = $('<span>').css({ | ||||
|                     "line-height": "32px", | ||||
|                     "margin-left": "6px" | ||||
|                 }).appendTo(container); | ||||
|                 if (node) { | ||||
|                     var colour = RED.utils.getNodeColor(node.type,node._def); | ||||
|                     var icon_url = RED.utils.getNodeIcon(node._def,node); | ||||
|                     if (node.type === 'tab') { | ||||
|                         colour = "#C0DEED"; | ||||
|                     } | ||||
|                     nodeDiv.css('backgroundColor',colour); | ||||
|                     var iconContainer = $('<div/>',{class:"red-ui-palette-icon-container"}).appendTo(nodeDiv); | ||||
|                     RED.utils.createIconElement(icon_url, iconContainer, true); | ||||
|                     var l = RED.utils.getNodeLabel(node,node.id); | ||||
|                     nodeLabel.text(l); | ||||
|                 } else { | ||||
|                     nodeDiv.css({ | ||||
|                         'backgroundColor': '#eee', | ||||
|                         'border-style' : 'dashed' | ||||
|                     }); | ||||
|  | ||||
|                 } | ||||
|             }, | ||||
|             expand: function() { | ||||
|                 var that = this; | ||||
|                 RED.tray.hide(); | ||||
|                 RED.view.selectNodes({ | ||||
|                     single: true, | ||||
|                     selected: [that.value()], | ||||
|                     onselect: function(selection) { | ||||
|                         that.value(selection.id); | ||||
|                         RED.tray.show(); | ||||
|                     }, | ||||
|                     oncancel: function() { | ||||
|                         RED.tray.show(); | ||||
|                     } | ||||
|                 }) | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
|     var nlsd = false; | ||||
| @@ -160,7 +215,7 @@ | ||||
|                 that.input.css("margin"+d,0); | ||||
|             }); | ||||
|  | ||||
|             ["type","placeholder"].forEach(function(d) { | ||||
|             ["type","placeholder","autocomplete","data-i18n"].forEach(function(d) { | ||||
|                 var m = that.element.attr(d); | ||||
|                 that.input.attr(d,m); | ||||
|             }); | ||||
| @@ -176,6 +231,8 @@ | ||||
|  | ||||
|             this.selectLabel = $('<span class="red-ui-typedInput-type-label"></span>').appendTo(this.selectTrigger); | ||||
|  | ||||
|             this.valueLabelContainer = $('<div class="red-ui-typedInput-value-label">').appendTo(this.uiSelect) | ||||
|  | ||||
|             this.types(this.options.types); | ||||
|  | ||||
|             if (this.options.typeField) { | ||||
| @@ -198,9 +255,15 @@ | ||||
|                 that.validate(); | ||||
|                 that.element.val(that.value()); | ||||
|                 that.element.trigger('change',that.propertyType,that.value()); | ||||
|             }); | ||||
|             this.input.on('keydown', function(evt) { | ||||
|                 if (evt.keyCode >= 37 && evt.keyCode <= 40) { | ||||
|                     evt.stopPropagation(); | ||||
|                 } | ||||
|             }) | ||||
|             this.selectTrigger.on("click", function(event) { | ||||
|                 event.preventDefault(); | ||||
|                 event.stopPropagation(); | ||||
|                 that._showTypeMenu(); | ||||
|             }); | ||||
|             this.selectTrigger.on('keydown',function(evt) { | ||||
| @@ -208,6 +271,7 @@ | ||||
|                     // Down | ||||
|                     that._showTypeMenu(); | ||||
|                 } | ||||
|                 evt.stopPropagation(); | ||||
|             }).on('focus', function() { | ||||
|                 that.uiSelect.addClass('red-ui-typedInput-focus'); | ||||
|             }) | ||||
| @@ -220,12 +284,14 @@ | ||||
|             }); | ||||
|             this.optionSelectTrigger.on("click", function(event) { | ||||
|                 event.preventDefault(); | ||||
|                 event.stopPropagation(); | ||||
|                 that._showOptionSelectMenu(); | ||||
|             }).on('keydown', function(evt) { | ||||
|                 if (evt.keyCode === 40) { | ||||
|                     // Down | ||||
|                     that._showOptionSelectMenu(); | ||||
|                 } | ||||
|                 evt.stopPropagation(); | ||||
|             }).on('blur', function() { | ||||
|                 that.uiSelect.removeClass('red-ui-typedInput-focus'); | ||||
|             }).on('focus', function() { | ||||
| @@ -293,7 +359,7 @@ | ||||
|                     if (opt.icon.indexOf("<") === 0) { | ||||
|                         $(opt.icon).prependTo(op); | ||||
|                     } else if (opt.icon.indexOf("/") !== -1) { | ||||
|                         $('<img>',{src:opt.icon,style:"margin-right: 4px; height: 18px;"}).prependTo(op); | ||||
|                         $('<img>',{src:mapDeprecatedIcon(opt.icon),style:"margin-right: 4px; height: 18px;"}).prependTo(op); | ||||
|                     } else { | ||||
|                         $('<i>',{class:"red-ui-typedInput-icon "+opt.icon}).prependTo(op); | ||||
|                     } | ||||
| @@ -306,6 +372,7 @@ | ||||
|  | ||||
|                 op.on("click", function(event) { | ||||
|                     event.preventDefault(); | ||||
|                     event.stopPropagation(); | ||||
|                     callback(opt.value); | ||||
|                     that._hideMenu(menu); | ||||
|                 }); | ||||
| @@ -325,9 +392,11 @@ | ||||
|                     // UP | ||||
|                     $(this).children(":focus").prev().trigger("focus"); | ||||
|                 } else if (evt.keyCode === 27) { | ||||
|                     // ESCAPE | ||||
|                     evt.preventDefault(); | ||||
|                     that._hideMenu(menu); | ||||
|                 } | ||||
|                 evt.stopPropagation(); | ||||
|             }) | ||||
|  | ||||
|  | ||||
| @@ -370,20 +439,27 @@ | ||||
|                 }) | ||||
|             }); | ||||
|         }, | ||||
|         _getLabelWidth: function(label) { | ||||
|         _getLabelWidth: function(label, done) { | ||||
|             var labelWidth = label.outerWidth(); | ||||
|             if (labelWidth === 0) { | ||||
|                 var container = $('<div class="red-ui-typedInput-container"></div>').css({ | ||||
|                 var wrapper = $('<div class="red-ui-editor"></div>').css({ | ||||
|                     position:"absolute", | ||||
|                     top:0 | ||||
|                     "white-space": "nowrap", | ||||
|                     top:-2000 | ||||
|                 }).appendTo(document.body); | ||||
|                 var container = $('<div class="red-ui-typedInput-container"></div>').appendTo(wrapper); | ||||
|                 var newTrigger = label.clone().appendTo(container); | ||||
|                 labelWidth = newTrigger.outerWidth(); | ||||
|                 container.remove(); | ||||
|                 setTimeout(function() { | ||||
|                     labelWidth = newTrigger.outerWidth(); | ||||
|                     wrapper.remove(); | ||||
|                     done(labelWidth); | ||||
|                 },50) | ||||
|             } else { | ||||
|                 done(labelWidth); | ||||
|             } | ||||
|             return labelWidth; | ||||
|         }, | ||||
|         _resize: function() { | ||||
|             var that = this; | ||||
|             if (this.uiWidth !== null) { | ||||
|                 this.uiSelect.width(this.uiWidth); | ||||
|             } | ||||
| @@ -392,44 +468,44 @@ | ||||
|                 this.selectTrigger.addClass("red-ui-typedInput-full-width"); | ||||
|             } else { | ||||
|                 this.selectTrigger.removeClass("red-ui-typedInput-full-width"); | ||||
|                 var labelWidth = this._getLabelWidth(this.selectTrigger); | ||||
|                 this.elementDiv.css('left',labelWidth+"px"); | ||||
|                 if (this.optionExpandButton.is(":visible")) { | ||||
|                     this.elementDiv.css('right',"22px"); | ||||
|                 } else { | ||||
|                     this.elementDiv.css('right','0'); | ||||
|                     this.input.css({ | ||||
|                         'border-top-right-radius': '4px', | ||||
|                         'border-bottom-right-radius': '4px' | ||||
|                     }); | ||||
|                 } | ||||
|  | ||||
|                 // if (this.optionSelectTrigger) { | ||||
|                 //     this.optionSelectTrigger.css({'left':(labelWidth)+"px",'width':'calc( 100% - '+labelWidth+'px )'}); | ||||
|                 // } | ||||
|  | ||||
|                 if (this.optionSelectTrigger) { | ||||
|                     if (type && type.options && type.hasValue === true) { | ||||
|                         this.optionSelectLabel.css({'left':'auto'}) | ||||
|                         var lw = this._getLabelWidth(this.optionSelectLabel); | ||||
|                         this.optionSelectTrigger.css({'width':(23+lw)+"px"}); | ||||
|                         this.elementDiv.css('right',(23+lw)+"px"); | ||||
|                         this.input.css({ | ||||
|                             'border-top-right-radius': 0, | ||||
|                             'border-bottom-right-radius': 0 | ||||
|                         }); | ||||
|                 this._getLabelWidth(this.selectTrigger, function(labelWidth) { | ||||
|                     that.elementDiv.css('left',labelWidth+"px"); | ||||
|                     that.valueLabelContainer.css('left',labelWidth+"px"); | ||||
|                     if (that.optionExpandButton.is(":visible")) { | ||||
|                         that.elementDiv.css('right',"22px"); | ||||
|                         that.valueLabelContainer.css('right',"22px"); | ||||
|                     } else { | ||||
|                         this.optionSelectLabel.css({'left':'0'}) | ||||
|                         this.optionSelectTrigger.css({'width':'calc( 100% - '+labelWidth+'px )'}); | ||||
|                         if (!this.optionExpandButton.is(":visible")) { | ||||
|                             this.elementDiv.css({'right':0}); | ||||
|                             this.input.css({ | ||||
|                                 'border-top-right-radius': '4px', | ||||
|                                 'border-bottom-right-radius': '4px' | ||||
|                         that.elementDiv.css('right','0'); | ||||
|                         that.valueLabelContainer.css('right','0'); | ||||
|                         that.input.css({ | ||||
|                             'border-top-right-radius': '4px', | ||||
|                             'border-bottom-right-radius': '4px' | ||||
|                         }); | ||||
|                     } | ||||
|                     if (that.optionSelectTrigger) { | ||||
|                         if (type && type.options && type.hasValue === true) { | ||||
|                             that.optionSelectLabel.css({'left':'auto'}) | ||||
|                             that._getLabelWidth(that.optionSelectLabel, function(lw) { | ||||
|                                 that.optionSelectTrigger.css({'width':(23+lw)+"px"}); | ||||
|                                 that.elementDiv.css('right',(23+lw)+"px"); | ||||
|                                 that.input.css({ | ||||
|                                     'border-top-right-radius': 0, | ||||
|                                     'border-bottom-right-radius': 0 | ||||
|                                 }); | ||||
|                             }); | ||||
|                         } else { | ||||
|                             that.optionSelectLabel.css({'left':'0'}) | ||||
|                             that.optionSelectTrigger.css({'width':'calc( 100% - '+labelWidth+'px )'}); | ||||
|                             if (!that.optionExpandButton.is(":visible")) { | ||||
|                                 that.elementDiv.css({'right':0}); | ||||
|                                 that.input.css({ | ||||
|                                     'border-top-right-radius': '4px', | ||||
|                                     'border-bottom-right-radius': '4px' | ||||
|                                 }); | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|                 }); | ||||
|             } | ||||
|         }, | ||||
|         _updateOptionSelectLabel: function(o) { | ||||
| @@ -440,7 +516,7 @@ | ||||
|                     $(o.icon).prependTo(this.optionSelectLabel); | ||||
|                 } else if (o.icon.indexOf("/") !== -1) { | ||||
|                     // url | ||||
|                     $('<img>',{src:o.icon,style:"height: 18px;"}).prependTo(this.optionSelectLabel); | ||||
|                     $('<img>',{src:mapDeprecatedIcon(o.icon),style:"height: 18px;"}).prependTo(this.optionSelectLabel); | ||||
|                 } else { | ||||
|                     // icon class | ||||
|                     $('<i>',{class:"red-ui-typedInput-icon "+o.icon}).prependTo(this.optionSelectLabel); | ||||
| @@ -461,6 +537,7 @@ | ||||
|                 this.optionMenu.remove(); | ||||
|             } | ||||
|             this.menu.remove(); | ||||
|             this.uiSelect.remove(); | ||||
|         }, | ||||
|         types: function(types) { | ||||
|             var that = this; | ||||
| @@ -519,9 +596,15 @@ | ||||
|                     if (!selectedOption) { | ||||
|                         selectedOption = {value:""} | ||||
|                     } | ||||
|                     this.input.val(value); | ||||
|                     this._updateOptionSelectLabel(selectedOption) | ||||
|                 } else { | ||||
|                     this.input.val(value); | ||||
|                 } | ||||
|                 if (this.typeMap[this.propertyType].valueLabel) { | ||||
|                     this.valueLabelContainer.empty(); | ||||
|                     this.typeMap[this.propertyType].valueLabel.call(this,this.valueLabelContainer,value); | ||||
|                 } | ||||
|                 this.input.val(value); | ||||
|                 this.input.trigger('change',this.type(),value); | ||||
|             } | ||||
|         }, | ||||
| @@ -544,9 +627,11 @@ | ||||
|                         } | ||||
|                         else if (opt.icon.indexOf("/") !== -1) { | ||||
|                             image = new Image(); | ||||
|                             image.onload = function() { that._resize(); } | ||||
|                             image.onerror = function() { that._resize(); } | ||||
|                             image.name = opt.icon; | ||||
|                             image.src = opt.icon; | ||||
|                             $('<img>',{src:opt.icon,style:"margin-right: 4px;height: 18px;"}).prependTo(this.selectLabel); | ||||
|                             image.src = mapDeprecatedIcon(opt.icon); | ||||
|                             $('<img>',{src:mapDeprecatedIcon(opt.icon),style:"margin-right: 4px;height: 18px;"}).prependTo(this.selectLabel); | ||||
|                         } | ||||
|                         else { | ||||
|                             $('<i>',{class:"red-ui-typedInput-icon "+opt.icon}).prependTo(this.selectLabel); | ||||
| @@ -566,8 +651,10 @@ | ||||
|                             this.optionSelectTrigger.show(); | ||||
|                             if (!opt.hasValue) { | ||||
|                                 this.elementDiv.hide(); | ||||
|                                 this.valueLabelContainer.hide(); | ||||
|                             } else { | ||||
|                                 this.elementDiv.show(); | ||||
|                                 this.valueLabelContainer.hide(); | ||||
|                             } | ||||
|                             this.activeOptions = {}; | ||||
|                             opt.options.forEach(function(o) { | ||||
| @@ -647,6 +734,7 @@ | ||||
|                                 } | ||||
|                             } | ||||
|                         } | ||||
|                         this.input.trigger('change',this.propertyType,this.value()); | ||||
|                     } else { | ||||
|                         if (this.optionSelectTrigger) { | ||||
|                             this.optionSelectTrigger.hide(); | ||||
| @@ -655,11 +743,18 @@ | ||||
|                             this.oldValue = this.input.val(); | ||||
|                             this.input.val(""); | ||||
|                             this.elementDiv.hide(); | ||||
|                             this.valueLabelContainer.hide(); | ||||
|                         } else if (opt.valueLabel) { | ||||
|                             this.valueLabelContainer.show(); | ||||
|                             this.valueLabelContainer.empty(); | ||||
|                             opt.valueLabel.call(this,this.valueLabelContainer,this.input.val()); | ||||
|                             this.elementDiv.hide(); | ||||
|                         } else { | ||||
|                             if (this.oldValue !== undefined) { | ||||
|                                 this.input.val(this.oldValue); | ||||
|                                 delete this.oldValue; | ||||
|                             } | ||||
|                             this.valueLabelContainer.hide(); | ||||
|                             this.elementDiv.show(); | ||||
|                         } | ||||
|                         if (this.optionExpandButton) { | ||||
| @@ -676,10 +771,7 @@ | ||||
|                         } | ||||
|                         this.input.trigger('change',this.propertyType,this.value()); | ||||
|                     } | ||||
|                     if (image) { | ||||
|                         image.onload = function() { that._resize(); } | ||||
|                         image.onerror = function() { that._resize(); } | ||||
|                     } else { | ||||
|                     if (!image) { | ||||
|                         this._resize(); | ||||
|                     } | ||||
|                 } | ||||
|   | ||||
| @@ -17,9 +17,9 @@ | ||||
| RED.deploy = (function() { | ||||
|  | ||||
|     var deploymentTypes = { | ||||
|         "full":{img:"red/images/deploy-full-o.png"}, | ||||
|         "nodes":{img:"red/images/deploy-nodes-o.png"}, | ||||
|         "flows":{img:"red/images/deploy-flows-o.png"} | ||||
|         "full":{img:"red/images/deploy-full-o.svg"}, | ||||
|         "nodes":{img:"red/images/deploy-nodes-o.svg"}, | ||||
|         "flows":{img:"red/images/deploy-flows-o.svg"} | ||||
|     } | ||||
|  | ||||
|     var ignoreDeployWarnings = { | ||||
| @@ -44,7 +44,7 @@ RED.deploy = (function() { | ||||
|      *   type: "default" - Button with drop-down options - no further customisation available | ||||
|      *   type: "simple"  - Button without dropdown. Customisations: | ||||
|      *      label: the text to display - default: "Deploy" | ||||
|      *      icon : the icon to use. Null removes the icon. default: "red/images/deploy-full-o.png" | ||||
|      *      icon : the icon to use. Null removes the icon. default: "red/images/deploy-full-o.svg" | ||||
|      */ | ||||
|     function init(options) { | ||||
|         options = options || {}; | ||||
| @@ -54,7 +54,7 @@ RED.deploy = (function() { | ||||
|             $('<li><span class="red-ui-deploy-button-group button-group">'+ | ||||
|               '<a id="red-ui-header-button-deploy" class="red-ui-deploy-button disabled" href="#">'+ | ||||
|                 '<span class="red-ui-deploy-button-content">'+ | ||||
|                  '<img id="red-ui-header-button-deploy-icon" src="red/images/deploy-full-o.png"> '+ | ||||
|                  '<img id="red-ui-header-button-deploy-icon" src="red/images/deploy-full-o.svg"> '+ | ||||
|                  '<span>'+RED._("deploy.deploy")+'</span>'+ | ||||
|                 '</span>'+ | ||||
|                 '<span class="red-ui-deploy-button-spinner hide">'+ | ||||
| @@ -65,17 +65,17 @@ RED.deploy = (function() { | ||||
|               '</span></li>').prependTo(".red-ui-header-toolbar"); | ||||
|               RED.menu.init({id:"red-ui-header-button-deploy-options", | ||||
|                   options: [ | ||||
|                       {id:"deploymenu-item-full",toggle:"deploy-type",icon:"red/images/deploy-full.png",label:RED._("deploy.full"),sublabel:RED._("deploy.fullDesc"),selected: true, onselect:function(s) { if(s){changeDeploymentType("full")}}}, | ||||
|                       {id:"deploymenu-item-flow",toggle:"deploy-type",icon:"red/images/deploy-flows.png",label:RED._("deploy.modifiedFlows"),sublabel:RED._("deploy.modifiedFlowsDesc"), onselect:function(s) {if(s){changeDeploymentType("flows")}}}, | ||||
|                       {id:"deploymenu-item-node",toggle:"deploy-type",icon:"red/images/deploy-nodes.png",label:RED._("deploy.modifiedNodes"),sublabel:RED._("deploy.modifiedNodesDesc"),onselect:function(s) { if(s){changeDeploymentType("nodes")}}}, | ||||
|                       {id:"deploymenu-item-full",toggle:"deploy-type",icon:"red/images/deploy-full.svg",label:RED._("deploy.full"),sublabel:RED._("deploy.fullDesc"),selected: true, onselect:function(s) { if(s){changeDeploymentType("full")}}}, | ||||
|                       {id:"deploymenu-item-flow",toggle:"deploy-type",icon:"red/images/deploy-flows.svg",label:RED._("deploy.modifiedFlows"),sublabel:RED._("deploy.modifiedFlowsDesc"), onselect:function(s) {if(s){changeDeploymentType("flows")}}}, | ||||
|                       {id:"deploymenu-item-node",toggle:"deploy-type",icon:"red/images/deploy-nodes.svg",label:RED._("deploy.modifiedNodes"),sublabel:RED._("deploy.modifiedNodesDesc"),onselect:function(s) { if(s){changeDeploymentType("nodes")}}}, | ||||
|                       null, | ||||
|                       {id:"deploymenu-item-reload", icon:"red/images/deploy-reload.png",label:RED._("deploy.restartFlows"),sublabel:RED._("deploy.restartFlowsDesc"),onselect:"core:restart-flows"}, | ||||
|                       {id:"deploymenu-item-reload", icon:"red/images/deploy-reload.svg",label:RED._("deploy.restartFlows"),sublabel:RED._("deploy.restartFlowsDesc"),onselect:"core:restart-flows"}, | ||||
|  | ||||
|                   ] | ||||
|               }); | ||||
|         } else if (type == "simple") { | ||||
|             var label = options.label || RED._("deploy.deploy"); | ||||
|             var icon = 'red/images/deploy-full-o.png'; | ||||
|             var icon = 'red/images/deploy-full-o.svg'; | ||||
|             if (options.hasOwnProperty('icon')) { | ||||
|                 icon = options.icon; | ||||
|             } | ||||
| @@ -99,7 +99,13 @@ RED.deploy = (function() { | ||||
|         }); | ||||
|  | ||||
|         RED.actions.add("core:deploy-flows",save); | ||||
|         RED.actions.add("core:restart-flows",restart); | ||||
|         if (type === "default") { | ||||
|             RED.actions.add("core:restart-flows",restart); | ||||
|             RED.actions.add("core:set-deploy-type-to-full",function() { RED.menu.setSelected("deploymenu-item-full",true);}); | ||||
|             RED.actions.add("core:set-deploy-type-to-modified-flows",function() { RED.menu.setSelected("deploymenu-item-flow",true); }); | ||||
|             RED.actions.add("core:set-deploy-type-to-modified-nodes",function() { RED.menu.setSelected("deploymenu-item-node",true); }); | ||||
|         } | ||||
|  | ||||
|  | ||||
|  | ||||
|         RED.events.on('nodes:change',function(state) { | ||||
|   | ||||
| @@ -399,7 +399,7 @@ RED.diff = (function() { | ||||
|                             diff: localDiff, | ||||
|                             def: { | ||||
|                                 defaults:{}, | ||||
|                                 icon:"subflow.png", | ||||
|                                 icon:"subflow.svg", | ||||
|                                 category: "subflows", | ||||
|                                 color: "#da9" | ||||
|                             }, | ||||
| @@ -422,7 +422,7 @@ RED.diff = (function() { | ||||
|                             diff: localDiff, | ||||
|                             def: { | ||||
|                                 defaults:{}, | ||||
|                                 icon:"subflow.png", | ||||
|                                 icon:"subflow.svg", | ||||
|                                 category: "subflows", | ||||
|                                 color: "#da9" | ||||
|                             }, | ||||
| @@ -443,7 +443,7 @@ RED.diff = (function() { | ||||
|                                 remoteDiff: remoteDiff, | ||||
|                                 def: { | ||||
|                                     defaults:{}, | ||||
|                                     icon:"subflow.png", | ||||
|                                     icon:"subflow.svg", | ||||
|                                     category: "subflows", | ||||
|                                     color: "#da9" | ||||
|                                 }, | ||||
| @@ -549,7 +549,7 @@ RED.diff = (function() { | ||||
|         if (def === undefined) { | ||||
|             if (/^subflow:/.test(node.type)) { | ||||
|                 def = { | ||||
|                     icon:"subflow.png", | ||||
|                     icon:"subflow.svg", | ||||
|                     category: "subflows", | ||||
|                     color: "#da9", | ||||
|                     defaults:{name:{value:""}} | ||||
|   | ||||
| @@ -513,6 +513,8 @@ RED.editor = (function() { | ||||
|                 label = RED._("expressionEditor.title"); | ||||
|             } else if (node.type === '_js') { | ||||
|                 label = RED._("jsEditor.title"); | ||||
|             } else if (node.type === '_text') { | ||||
|                 label = RED._("textEditor.title"); | ||||
|             } else if (node.type === '_json') { | ||||
|                 label = RED._("jsonEditor.title"); | ||||
|             } else if (node.type === '_markdown') { | ||||
| @@ -565,13 +567,13 @@ RED.editor = (function() { | ||||
|                             type: "text", | ||||
|                             style: "margin-left: 5px; width: calc(40% - 8px)", | ||||
|                             placeholder: RED._("common.label.name") | ||||
|                         }).appendTo(row).val(opt.name); | ||||
|                         }).attr("autocomplete","disable").appendTo(row).val(opt.name); | ||||
|                     } | ||||
|                     var valueField = $('<input/>',{ | ||||
|                         class: "node-input-env-value", | ||||
|                         type: "text", | ||||
|                         style: "margin-left: 5px; width: calc(60% - 8px)" | ||||
|                     }).appendTo(row) | ||||
|                     }).attr("autocomplete","disable").appendTo(row) | ||||
|  | ||||
|                     valueField.typedInput({default:'str', | ||||
|                                            types:['str','num','bool','json','bin','env'] | ||||
| @@ -665,17 +667,19 @@ RED.editor = (function() { | ||||
|             list.each(function(i) { | ||||
|                 var entry = $(this); | ||||
|                 var item = entry.data('data'); | ||||
|                 var name = item.parent?item.name:entry.find(".node-input-env-name").val(); | ||||
|                 var valueInput = entry.find(".node-input-env-value"); | ||||
|                 var value = valueInput.typedInput("value"); | ||||
|                 var type = valueInput.typedInput("type"); | ||||
|                 if (!item.parent || (item.parent.value !== value || item.parent.type !== type)) { | ||||
|                     var item = { | ||||
|                         name: name, | ||||
|                         type: type, | ||||
|                         value: value | ||||
|                     }; | ||||
|                     env.push(item); | ||||
|                 var name = (item.parent?item.name:entry.find(".node-input-env-name").val()).trim(); | ||||
|                 if (name !== "") { | ||||
|                     var valueInput = entry.find(".node-input-env-value"); | ||||
|                     var value = valueInput.typedInput("value"); | ||||
|                     var type = valueInput.typedInput("type"); | ||||
|                     if (!item.parent || (item.parent.value !== value || item.parent.type !== type)) { | ||||
|                         var item = { | ||||
|                             name: name, | ||||
|                             type: type, | ||||
|                             value: value | ||||
|                         }; | ||||
|                         env.push(item); | ||||
|                     } | ||||
|                 } | ||||
|             }); | ||||
|             return env; | ||||
| @@ -719,6 +723,7 @@ RED.editor = (function() { | ||||
|         $('<input type="password" style="display: none;" />').prependTo(dialogForm); | ||||
|         $('<input type="text" style="display: none;" />').prependTo(dialogForm); | ||||
|         dialogForm.on("submit", function(e) { e.preventDefault();}); | ||||
|         dialogForm.find('input').attr("autocomplete","disable"); | ||||
|         return dialogForm; | ||||
|     } | ||||
|  | ||||
| @@ -950,34 +955,19 @@ RED.editor = (function() { | ||||
|  | ||||
|         $('<div class="form-row">'+ | ||||
|             '<label for="node-input-show-label-btn" data-i18n="editor.label"></label>'+ | ||||
|             '<button type="button" id="node-input-show-label-btn" class="red-ui-button" style="min-width: 80px; text-align: left;" type="button"><i id="node-input-show-label-btn-i" class="fa fa-toggle-on"></i> <span id="node-input-show-label-label"></span></button> '+ | ||||
|             '<input type="checkbox" id="node-input-show-label" style="display: none;"/>'+ | ||||
|             '<input type="checkbox" id="node-input-show-label"/>'+ | ||||
|         '</div>').appendTo(dialogForm); | ||||
|  | ||||
|         var setToggleState = function(state) { | ||||
|             var i = $("#node-input-show-label-btn-i"); | ||||
|             if (!state) { | ||||
|                 i.addClass('fa-toggle-off'); | ||||
|                 i.removeClass('fa-toggle-on'); | ||||
|                 $("#node-input-show-label").prop("checked",false); | ||||
|                 $("#node-input-show-label-label").text(RED._("editor.hide")); | ||||
|             } else { | ||||
|                 i.addClass('fa-toggle-on'); | ||||
|                 i.removeClass('fa-toggle-off'); | ||||
|                 $("#node-input-show-label").prop("checked",true); | ||||
|                 $("#node-input-show-label-label").text(RED._("editor.show")); | ||||
|             } | ||||
|         } | ||||
|         dialogForm.find('#node-input-show-label-btn').on("click",function(e) { | ||||
|             e.preventDefault(); | ||||
|             var i = $("#node-input-show-label-btn-i"); | ||||
|             setToggleState(i.hasClass('fa-toggle-off')); | ||||
|         $("#node-input-show-label").toggleButton({ | ||||
|             enabledLabel: RED._("editor.show"), | ||||
|             disabledLabel: RED._("editor.hide") | ||||
|         }) | ||||
|  | ||||
|         if (!node.hasOwnProperty("l")) { | ||||
|             // Show label if type not link | ||||
|             node.l = !/^link (in|out)$/.test(node._def.type); | ||||
|         } | ||||
|         setToggleState(node.l); | ||||
|         $("#node-input-show-label").prop("checked",node.l).trigger("change"); | ||||
|  | ||||
|         // If a node has icon property in defaults, the icon of the node cannot be modified. (e.g, ui_button node in dashboard) | ||||
|         if ((!node._def.defaults || !node._def.defaults.hasOwnProperty("icon"))) { | ||||
| @@ -1066,7 +1056,7 @@ RED.editor = (function() { | ||||
|         hasNonBlankLabel = false; | ||||
|         newValue = new Array(editing_node.outputs); | ||||
|         outputLabels.each(function() { | ||||
|             var index = $(this).attr('id').substring(23); // red-ui-editor-node-label-form-output-<index> | ||||
|             var index = $(this).attr('id').substring("red-ui-editor-node-label-form-output-".length); | ||||
|             if (outputMap && outputMap.hasOwnProperty(index)) { | ||||
|                 index = parseInt(outputMap[index]); | ||||
|                 if (index === -1) { | ||||
| @@ -1391,6 +1381,20 @@ RED.editor = (function() { | ||||
|                                 node.l = true; | ||||
|                             } | ||||
|                         } | ||||
|                         if ($("#node-input-node-disabled").prop('checked')) { | ||||
|                             if (node.d !== true) { | ||||
|                                 changes.d = node.d; | ||||
|                                 changed = true; | ||||
|                                 node.d = true; | ||||
|                             } | ||||
|                         } else { | ||||
|                             if (node.d === true) { | ||||
|                                 changes.d = node.d; | ||||
|                                 changed = true; | ||||
|                                 delete node.d; | ||||
|                             } | ||||
|                         } | ||||
|  | ||||
|                         node.resize = true; | ||||
|  | ||||
|                         var oldInfo = node.info; | ||||
| @@ -1493,6 +1497,14 @@ 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) | ||||
|  | ||||
|                 $('<input id="node-input-node-disabled" type="checkbox">').prop("checked",!!node.d).appendTo(trayFooterLeft).toggleButton({ | ||||
|                     enabledIcon: "fa-circle-thin", | ||||
|                     disabledIcon: "fa-ban", | ||||
|                     invertState: true | ||||
|                 }) | ||||
|  | ||||
|                 var editorTabEl = $('<ul></ul>').appendTo(trayBody); | ||||
|                 var editorContent = $('<div></div>').appendTo(trayBody); | ||||
|  | ||||
| @@ -1670,9 +1682,17 @@ RED.editor = (function() { | ||||
|                 var trayHeader = tray.find(".red-ui-tray-header"); | ||||
|                 var trayBody = tray.find('.red-ui-tray-body'); | ||||
|                 var trayFooter = tray.find(".red-ui-tray-footer"); | ||||
|                 var userCountDiv; | ||||
|  | ||||
|                 var trayFooterLeft = $('<div class="red-ui-tray-footer-left"></div>').appendTo(trayFooter) | ||||
|  | ||||
|                 $('<input id="node-config-input-node-disabled" type="checkbox">').prop("checked",!!editing_config_node.d).appendTo(trayFooterLeft).toggleButton({ | ||||
|                     enabledIcon: "fa-circle-thin", | ||||
|                     disabledIcon: "fa-ban", | ||||
|                     invertState: true | ||||
|                 }) | ||||
|  | ||||
|                 if (node_def.hasUsers !== false) { | ||||
|                     userCountDiv = $('<div class="red-ui-tray-footer-left"><i class="fa fa-info-circle"></i> <span></span></div>').prependTo(trayFooter); | ||||
|                     $('<span><i class="fa fa-info-circle"></i> <span id="red-ui-editor-config-user-count"></span></span>').css("margin-left", "10px").appendTo(trayFooterLeft); | ||||
|                 } | ||||
|                 trayFooter.append('<span class="red-ui-tray-footer-right"><span id="red-ui-editor-config-scope-warning" data-i18n="[title]editor.errors.scopeChange"><i class="fa fa-warning"></i></span><select id="red-ui-editor-config-scope"></select></span>'); | ||||
|  | ||||
| @@ -1766,8 +1786,8 @@ RED.editor = (function() { | ||||
|                             } | ||||
|                         }); | ||||
|                     } | ||||
|                     if (node_def.hasUsers !== false && userCountDiv) { | ||||
|                         userCountDiv.find("span").text(RED._("editor.nodesUse", {count:editing_config_node.users.length})).parent().show(); | ||||
|                     if (node_def.hasUsers !== false) { | ||||
|                         $("#red-ui-editor-config-user-count").text(RED._("editor.nodesUse", {count:editing_config_node.users.length})).parent().show(); | ||||
|                     } | ||||
|                     trayBody.i18n(); | ||||
|                     trayFooter.i18n(); | ||||
| @@ -1902,6 +1922,16 @@ RED.editor = (function() { | ||||
|                     editing_config_node.label = configTypeDef.label; | ||||
|                     editing_config_node.z = scope; | ||||
|  | ||||
|                     if ($("#node-config-input-node-disabled").prop('checked')) { | ||||
|                         if (editing_config_node.d !== true) { | ||||
|                             editing_config_node.d = true; | ||||
|                         } | ||||
|                     } else { | ||||
|                         if (editing_config_node.d === true) { | ||||
|                             delete editing_config_node.d; | ||||
|                         } | ||||
|                     } | ||||
|  | ||||
|                     if (scope) { | ||||
|                         // Search for nodes that use this one that are no longer | ||||
|                         // in scope, so must be removed | ||||
| @@ -2056,7 +2086,7 @@ RED.editor = (function() { | ||||
|                 RED.nodes.eachConfig(function(config) { | ||||
|                     if (config.type == type && (!config.z || config.z === activeWorkspace.id)) { | ||||
|                         var label = RED.utils.getNodeLabel(config,config.id); | ||||
|                         config.__label__ = label; | ||||
|                         config.__label__ = label+(config.d?" ["+RED._("workspace.disabled")+"]":""); | ||||
|                         configNodes.push(config); | ||||
|                     } | ||||
|                 }); | ||||
| @@ -2126,7 +2156,7 @@ RED.editor = (function() { | ||||
|                             changed = true; | ||||
|                         } | ||||
|                         var icon = $("#red-ui-editor-node-icon").text()||""; | ||||
|                         if ((editing_node.icon === undefined && icon !== "node-red/subflow.png") || | ||||
|                         if ((editing_node.icon === undefined && icon !== "node-red/subflow.svg") || | ||||
|                             (editing_node.icon !== undefined && editing_node.icon !== icon)) { | ||||
|                             changes.icon = editing_node.icon; | ||||
|                             editing_node.icon = icon; | ||||
| @@ -2456,6 +2486,7 @@ RED.editor = (function() { | ||||
|         editExpression: function(options) { showTypeEditor("_expression", options) }, | ||||
|         editJSON: function(options) { showTypeEditor("_json", options) }, | ||||
|         editMarkdown: function(options) { showTypeEditor("_markdown", options) }, | ||||
|         editText: function(options) { showTypeEditor("_text", options) }, | ||||
|         editBuffer: function(options) { showTypeEditor("_buffer", options) }, | ||||
|         buildEditForm: buildEditForm, | ||||
|         validateNode: validateNode, | ||||
|   | ||||
| @@ -16,7 +16,419 @@ | ||||
| (function() { | ||||
|  | ||||
|  | ||||
|     var template = '<script type="text/x-red" data-template-name="_json"><div class="form-row" style="margin-bottom: 3px; text-align: right;"><button id="node-input-json-reformat" class="red-ui-button red-ui-button-small"><span data-i18n="jsonEditor.format"></span></button></div><div class="form-row node-text-editor-row"><div style="height: 200px;min-height: 150px;" class="node-text-editor" id="node-input-json"></div></div></script>'; | ||||
|     // var template = '<script type="text/x-red" data-template-name="_json"></script>'; | ||||
|     var template = '<script type="text/x-red" data-template-name="_json">'+ | ||||
|         '<ul id="red-ui-editor-type-json-tabs"></ul>'+ | ||||
|         '<div id="red-ui-editor-type-json-tab-raw" class="red-ui-editor-type-json-tab-content hide">'+ | ||||
|             '<div class="form-row" style="margin-bottom: 3px; text-align: right;">'+ | ||||
|                 '<button id="node-input-json-reformat" class="red-ui-button red-ui-button-small"><span data-i18n="jsonEditor.format"></span></button>'+ | ||||
|             '</div>'+ | ||||
|             '<div class="form-row node-text-editor-row">'+ | ||||
|                 '<div style="height: 200px;min-height: 150px;" class="node-text-editor" id="node-input-json"></div>'+ | ||||
|             '</div>'+ | ||||
|         '</div>'+ | ||||
|         '<div id="red-ui-editor-type-json-tab-ui" class="red-ui-editor-type-json-tab-content hide">'+ | ||||
|             '<div id="red-ui-editor-type-json-tab-ui-container"></div>'+ | ||||
|         '</div>'+ | ||||
|     '</script>'; | ||||
|  | ||||
|     var activeTab; | ||||
|  | ||||
|     function insertNewItem(parent,index,copyIndex) { | ||||
|         var newValue = ""; | ||||
|  | ||||
|         if (parent.children.length > 0) { | ||||
|             switch (parent.children[Math.max(0,Math.min(parent.children.length-1,copyIndex))].type) { | ||||
|                 case 'string': newValue = ""; break; | ||||
|                 case 'number': newValue = 0; break; | ||||
|                 case 'boolean': newValue = true; break; | ||||
|                 case 'null': newValue = null; break; | ||||
|                 case 'object': newValue = {}; break; | ||||
|                 case 'array': newValue = []; break; | ||||
|             } | ||||
|         } | ||||
|         var newKey; | ||||
|         if (parent.type === 'array') { | ||||
|             newKey = parent.children.length; | ||||
|         } else { | ||||
|             var usedKeys = {}; | ||||
|             parent.children.forEach(function(child) { usedKeys[child.key] = true }) | ||||
|             var keyRoot = "item"; | ||||
|             var keySuffix = 2; | ||||
|             newKey = keyRoot; | ||||
|             while(usedKeys[newKey]) { | ||||
|                 newKey = keyRoot+"-"+(keySuffix++); | ||||
|             } | ||||
|         } | ||||
|         var newItem = handleItem(newKey,newValue,parent.depth+1,parent); | ||||
|         parent.treeList.insertChildAt(newItem, index, true); | ||||
|         parent.treeList.expand(); | ||||
|     } | ||||
|     function showObjectMenu(button,item) { | ||||
|         var elementPos = button.offset(); | ||||
|         var options = []; | ||||
|         if (item.parent) { | ||||
|             options.push({id:"red-ui-editor-type-json-menu-insert-above", icon:"fa fa-toggle-up", label:RED._('jsonEditor.insertAbove'),onselect:function(){ | ||||
|                 var index = item.parent.children.indexOf(item); | ||||
|                 insertNewItem(item.parent,index,index); | ||||
|             }}); | ||||
|             options.push({id:"red-ui-editor-type-json-menu-insert-below", icon:"fa fa-toggle-down", label:RED._('jsonEditor.insertBelow'),onselect:function(){ | ||||
|                 var index = item.parent.children.indexOf(item)+1; | ||||
|                 insertNewItem(item.parent,index,index-1); | ||||
|             }}); | ||||
|         } | ||||
|         if (item.type === 'array' || item.type === 'object') { | ||||
|             options.push({id:"red-ui-editor-type-json-menu-add-child", icon:"fa fa-plus", label:RED._('jsonEditor.addItem'),onselect:function(){ | ||||
|                 insertNewItem(item,item.children.length,item.children.length-1); | ||||
|             }}); | ||||
|         } | ||||
|         if (item.parent) { | ||||
|             options.push({id:"red-ui-editor-type-json-menu-copy-path", icon:"fa fa-terminal", label:RED._('jsonEditor.copyPath'),onselect:function(){ | ||||
|                 var i = item; | ||||
|                 var path = ""; | ||||
|                 var newPath; | ||||
|                 while(i.parent) { | ||||
|                     if (i.parent.type === "array") { | ||||
|                         newPath = "["+i.key+"]"; | ||||
|                     } else { | ||||
|                         if (/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(i.key)) { | ||||
|                             newPath = i.key; | ||||
|                         } else { | ||||
|                             newPath = "[\""+i.key.replace(/"/,"\\\"")+"\"]" | ||||
|                         } | ||||
|                     } | ||||
|                     path = newPath+(path.length>0 && path[0] !== "["?".":"")+path; | ||||
|                     i = i.parent; | ||||
|                 } | ||||
|                 RED.clipboard.copyText(path,item.element,"clipboard.copyMessagePath"); | ||||
|             }}); | ||||
|  | ||||
|             options.push({id:"red-ui-editor-type-json-menu-duplicate", icon:"fa fa-copy", label:RED._("jsonEditor.duplicate"),onselect:function(){ | ||||
|                 var newKey = item.key; | ||||
|                 if (item.parent.type === 'array') { | ||||
|                     newKey = parent.children.length; | ||||
|                 } else { | ||||
|                     var m = /^(.*?)(-(\d+))?$/.exec(newKey); | ||||
|                     var usedKeys = {}; | ||||
|                     item.parent.children.forEach(function(child) { usedKeys[child.key] = true }) | ||||
|                     var keyRoot = m[1]; | ||||
|                     var keySuffix = 2; | ||||
|                     if (m[3] !== undefined) { | ||||
|                         keySuffix = parseInt(m[3]); | ||||
|                     } | ||||
|                     newKey = keyRoot; | ||||
|                     while(usedKeys[newKey]) { | ||||
|                         newKey = keyRoot+"-"+(keySuffix++); | ||||
|                     } | ||||
|                 } | ||||
|                 var newItem = handleItem(newKey,convertToObject(item),item.parent.depth+1,item.parent); | ||||
|                 var index = item.parent.children.indexOf(item)+1; | ||||
|  | ||||
|                 item.parent.treeList.insertChildAt(newItem, index, true); | ||||
|                 item.parent.treeList.expand(); | ||||
|             }}); | ||||
|  | ||||
|             options.push({id:"red-ui-editor-type-json-menu-delete", icon:"fa fa-times", label:RED._('common.label.delete'),onselect:function(){ | ||||
|                 item.treeList.remove(); | ||||
|             }}); | ||||
|         } | ||||
|         if (item.type === 'array' || item.type === 'object') { | ||||
|             options.push(null) | ||||
|             options.push({id:"red-ui-editor-type-json-menu-expand-children",icon:"fa fa-angle-double-down", label:RED._('jsonEditor.expandItems'),onselect:function(){ | ||||
|                 item.treeList.expand(); | ||||
|                 item.children.forEach(function(child) { | ||||
|                     child.treeList.expand(); | ||||
|                 }) | ||||
|             }}); | ||||
|             options.push({id:"red-ui-editor-type-json-menu-collapse-children",icon:"fa fa-angle-double-up", label:RED._('jsonEditor.collapseItems'),onselect:function(){ | ||||
|                 item.children.forEach(function(child) { | ||||
|                     child.treeList.collapse(); | ||||
|                 }) | ||||
|             }}); | ||||
|         } | ||||
|  | ||||
|         var menuOptionMenu = RED.menu.init({ | ||||
|             id:"red-ui-editor-type-json-menu", | ||||
|             options: options | ||||
|         }); | ||||
|         menuOptionMenu.css({ | ||||
|             position: "absolute" | ||||
|         }) | ||||
|         menuOptionMenu.on('mouseleave', function(){ $(this).hide() }); | ||||
|         menuOptionMenu.on('mouseup', function() { $(this).hide() }); | ||||
|         menuOptionMenu.appendTo("body"); | ||||
|         var top = elementPos.top; | ||||
|         var height = menuOptionMenu.height(); | ||||
|         var winHeight = $(window).height(); | ||||
|         if (top+height > winHeight) { | ||||
|             top -= (top+height)-winHeight + 20; | ||||
|         } | ||||
|         menuOptionMenu.css({ | ||||
|             top: top+"px", | ||||
|             left: elementPos.left+"px" | ||||
|         }) | ||||
|         menuOptionMenu.show(); | ||||
|     } | ||||
|  | ||||
|     function parseObject(obj,depth,parent) { | ||||
|         var result = []; | ||||
|         for (var prop in obj) { | ||||
|             if (obj.hasOwnProperty(prop)) { | ||||
|                 result.push(handleItem(prop,obj[prop],depth,parent)); | ||||
|             } | ||||
|         } | ||||
|         return result; | ||||
|     } | ||||
|     function parseArray(obj,depth,parent) { | ||||
|         var result = []; | ||||
|         var l = obj.length; | ||||
|         for (var i=0;i<l;i++) { | ||||
|             result.push(handleItem(i,obj[i],depth,parent)); | ||||
|         } | ||||
|         return result; | ||||
|     } | ||||
|     function handleItem(key,val,depth,parent) { | ||||
|         var item = {depth:depth, type: typeof val}; | ||||
|         var container = $('<span class="red-ui-editor-type-json-editor-label">'); | ||||
|         if (key != null) { | ||||
|             item.key = key; | ||||
|             var keyText; | ||||
|             if (typeof key === 'string') { | ||||
|                 keyText = '"'+key+'"'; | ||||
|             } else { | ||||
|                 keyText = key; | ||||
|             } | ||||
|             var keyLabel = $('<span class="red-ui-debug-msg-object-key red-ui-editor-type-json-editor-label-key">').text(keyText).appendTo(container); | ||||
|             keyLabel.addClass('red-ui-debug-msg-type-'+(typeof key)); | ||||
|             if (parent && parent.type === "array") { | ||||
|                 keyLabel.addClass("red-ui-editor-type-json-editor-label-array-key") | ||||
|             } | ||||
|  | ||||
|             keyLabel.on("click", function(evt) { | ||||
|                 if (item.parent.type === 'array') { | ||||
|                     return; | ||||
|                 } | ||||
|                 evt.preventDefault(); | ||||
|                 evt.stopPropagation(); | ||||
|                 var w = Math.max(150,keyLabel.width()); | ||||
|                 var keyInput = $('<input type="text" class="red-ui-editor-type-json-editor-key">').css({width:w+"px"}).val(""+item.key).insertAfter(keyLabel).typedInput({types:['str']}); | ||||
|                 $(document).on("mousedown.nr-ui-json-editor", function(evt) { | ||||
|                     var typedInputElement = keyInput.next(".red-ui-typedInput-container")[0]; | ||||
|                     var target = evt.target; | ||||
|                     while (target.nodeName !== 'BODY' && target !== typedInputElement && !$(target).hasClass("red-ui-typedInput-options")) { | ||||
|                         target = target.parentElement; | ||||
|                     } | ||||
|                     if (target.nodeName === 'BODY') { | ||||
|                         var newKey = keyInput.typedInput("value"); | ||||
|                         item.key = newKey; | ||||
|                         var keyText; | ||||
|                         if (typeof newKey === 'string') { | ||||
|                             keyText = '"'+newKey+'"'; | ||||
|                         } else { | ||||
|                             keyText = newKey; | ||||
|                         } | ||||
|                         keyLabel.text(keyText); | ||||
|                         keyInput.remove(); | ||||
|                         keyLabel.show(); | ||||
|                         $(document).off("mousedown.nr-ui-json-editor"); | ||||
|                         $(document).off("keydown.nr-ui-json-editor"); | ||||
|                     } | ||||
|                 }); | ||||
|                 $(document).on("keydown.nr-ui-json-editor",function(evt) { | ||||
|                     if (evt.keyCode === 27) { | ||||
|                         // Escape | ||||
|                         keyInput.remove(); | ||||
|                         keyLabel.show(); | ||||
|                         $(document).off("mousedown.nr-ui-json-editor"); | ||||
|                         $(document).off("keydown.nr-ui-json-editor"); | ||||
|                     } | ||||
|                 }); | ||||
|                 keyLabel.hide(); | ||||
|             }); | ||||
|             $('<span>').text(" : ").appendTo(container); | ||||
|         } | ||||
|  | ||||
|         if (Array.isArray(val)) { | ||||
|             item.expanded = depth < 2; | ||||
|             item.type = "array"; | ||||
|             item.deferBuild = depth >= 2; | ||||
|             item.children = parseArray(val,depth+1,item); | ||||
|         } else if (val !== null && item.type === "object") { | ||||
|             item.expanded = depth < 2; | ||||
|             item.children = parseObject(val,depth+1,item); | ||||
|             item.deferBuild = depth >= 2; | ||||
|         } else { | ||||
|             item.value = val; | ||||
|             if (val === null) { | ||||
|                 item.type = 'null' | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         var valType; | ||||
|         var valValue = ""; | ||||
|         var valClass; | ||||
|         switch(item.type) { | ||||
|             case 'string': valType = 'str'; valValue = '"'+item.value+'"'; valClass = "red-ui-debug-msg-type-string"; break; | ||||
|             case 'number': valType = 'num'; valValue = item.value; valClass = "red-ui-debug-msg-type-number";break; | ||||
|             case 'boolean': valType = 'bool'; valValue = item.value; valClass = "red-ui-debug-msg-type-other";break; | ||||
|             case 'null': valType = item.type; valValue = item.type; valClass = "red-ui-debug-msg-type-null";break; | ||||
|             case 'object': | ||||
|                 valType = item.type; | ||||
|                 valValue = item.type;//+"{"+item.children.length+"}"; | ||||
|                 valClass = "red-ui-debug-msg-type-meta"; | ||||
|             break; | ||||
|             case 'array': | ||||
|                 valType = item.type; | ||||
|                 valValue = item.type+"["+item.children.length+"]"; | ||||
|                 valClass = "red-ui-debug-msg-type-meta"; | ||||
|             break; | ||||
|         } | ||||
|         // | ||||
|         var orphanedChildren; | ||||
|         var valueLabel = $('<span class="red-ui-editor-type-json-editor-label-value">').addClass(valClass).text(valValue).appendTo(container); | ||||
|         valueLabel.on("click", function(evt) { | ||||
|             evt.preventDefault(); | ||||
|             evt.stopPropagation(); | ||||
|             if (valType === 'str') { | ||||
|                 valValue = valValue.substring(1,valValue.length-1); | ||||
|             } else if (valType === 'array') { | ||||
|                 valValue = ""; | ||||
|             } else if (valType === 'object') { | ||||
|                 valValue = ""; | ||||
|             } | ||||
|             var w = Math.max(150,valueLabel.width()); | ||||
|             var val = $('<input type="text" class="red-ui-editor-type-json-editor-value">').css({width:w+"px"}).val(""+valValue).insertAfter(valueLabel).typedInput({ | ||||
|                 types:[ | ||||
|                     'str','num','bool', | ||||
|                     {value:"null",label:"null",hasValue:false}, | ||||
|                     {value:"array",label:"array",hasValue:false}, | ||||
|                     {value:"object",label:"object",hasValue:false} | ||||
|                 ], | ||||
|                 default: valType | ||||
|             }); | ||||
|             $(document).on("mousedown.nr-ui-json-editor", function(evt) { | ||||
|                 var typedInputElement = val.next(".red-ui-typedInput-container")[0]; | ||||
|                 var target = evt.target; | ||||
|                 while (target.nodeName !== 'BODY' && target !== typedInputElement && !$(target).hasClass("red-ui-typedInput-options")) { | ||||
|                     target = target.parentElement; | ||||
|                 } | ||||
|                 if (target.nodeName === 'BODY') { | ||||
|                     valType = val.typedInput("type"); | ||||
|                     valValue = val.typedInput("value"); | ||||
|                     if (valType === 'num') { | ||||
|                         valValue = valValue.trim(); | ||||
|                         if (isNaN(valValue)) { | ||||
|                             valType = 'str'; | ||||
|                         } else if (valValue === "") { | ||||
|                             valValue = 0; | ||||
|                         } | ||||
|                     } | ||||
|                     item.value = valValue; | ||||
|                     var valClass; | ||||
|                     switch(valType) { | ||||
|                         case 'str':    item.children && (orphanedChildren = item.children); item.treeList.makeLeaf(true); item.type = "string";  valClass = "red-ui-debug-msg-type-string"; valValue = '"'+valValue+'"'; break; | ||||
|                         case 'num':    item.children && (orphanedChildren = item.children); item.treeList.makeLeaf(true); item.type = "number";  valClass = "red-ui-debug-msg-type-number"; break; | ||||
|                         case 'bool':   item.children && (orphanedChildren = item.children); item.treeList.makeLeaf(true); item.type = "boolean"; valClass = "red-ui-debug-msg-type-other";  item.value = (valValue === "true"); break; | ||||
|                         case 'null':   item.children && (orphanedChildren = item.children); item.treeList.makeLeaf(true); item.type = "null";    valClass = "red-ui-debug-msg-type-null"; item.value = valValue = "null"; break; | ||||
|                         case 'object': | ||||
|                             item.treeList.makeParent(orphanedChildren); | ||||
|                             item.type = "object"; | ||||
|                             valClass = "red-ui-debug-msg-type-meta"; | ||||
|                             item.value = valValue = "object"; | ||||
|                             item.children.forEach(function(child,i) { | ||||
|                                 if (child.hasOwnProperty('_key')) { | ||||
|                                     child.key = child._key; | ||||
|                                     delete child._key; | ||||
|                                     var keyText; | ||||
|                                     var keyLabel = child.element.find(".red-ui-editor-type-json-editor-label-key"); | ||||
|                                     keyLabel.removeClass("red-ui-editor-type-json-editor-label-array-key"); | ||||
|                                     if (typeof child.key === 'string') { | ||||
|                                         keyText = '"'+child.key+'"'; | ||||
|                                         keyLabel.addClass('red-ui-debug-msg-type-string'); | ||||
|                                         keyLabel.removeClass('red-ui-debug-msg-type-number'); | ||||
|                                     } else { | ||||
|                                         keyText = child.key; | ||||
|                                         keyLabel.removeClass('red-ui-debug-msg-type-string'); | ||||
|                                         keyLabel.addClass('red-ui-debug-msg-type-number'); | ||||
|                                     } | ||||
|                                     keyLabel.text(keyText); | ||||
|                                 } | ||||
|                             }) | ||||
|                             break; | ||||
|                         case 'array': | ||||
|                             item.treeList.makeParent(orphanedChildren); | ||||
|                             item.type = "array"; | ||||
|                             valClass = "red-ui-debug-msg-type-meta"; | ||||
|                             item.value = valValue = "array["+(item.children.length)+"]"; | ||||
|                             item.children.forEach(function(child,i) { | ||||
|                                 child._key = child.key; | ||||
|                                 child.key = i; | ||||
|                                 child.element.find(".red-ui-editor-type-json-editor-label-key") | ||||
|                                     .addClass("red-ui-editor-type-json-editor-label-array-key") | ||||
|                                     .text(""+child.key) | ||||
|                                     .removeClass('red-ui-debug-msg-type-string') | ||||
|                                     .addClass('red-ui-debug-msg-type-number'); | ||||
|                             }) | ||||
|                             break; | ||||
|                     } | ||||
|                     valueLabel.text(valValue).removeClass().addClass("red-ui-editor-type-json-editor-label-value "+valClass); | ||||
|                     val.remove(); | ||||
|                     valueLabel.show(); | ||||
|                     $(document).off("mousedown.nr-ui-json-editor"); | ||||
|                     $(document).off("keydown.nr-ui-json-editor"); | ||||
|                 } | ||||
|             }) | ||||
|  | ||||
|             $(document).on("keydown.nr-ui-json-editor",function(evt) { | ||||
|                 if (evt.keyCode === 27) { | ||||
|                     // Escape | ||||
|                     val.remove(); | ||||
|                     valueLabel.show(); | ||||
|                     if (valType === 'str') { | ||||
|                         valValue = '"'+valValue+'"'; | ||||
|                     } | ||||
|                     $(document).off("mousedown.nr-ui-json-editor"); | ||||
|                     $(document).off("keydown.nr-ui-json-editor"); | ||||
|                 } | ||||
|             }); | ||||
|             valueLabel.hide(); | ||||
|         }) | ||||
|         item.gutter = $('<span class="red-ui-editor-type-json-editor-item-gutter"></span>'); | ||||
|  | ||||
|         if (parent) {//red-ui-editor-type-json-editor-item-handle | ||||
|             $('<span class="red-ui-editor-type-json-editor-item-handle"><i class="fa fa-bars"></span>').appendTo(item.gutter); | ||||
|         } else { | ||||
|             $('<span></span>').appendTo(item.gutter); | ||||
|         } | ||||
|         $('<button type="button" class="editor-button editor-button-small"><i class="fa fa-caret-down"></button>').appendTo(item.gutter).on("click", function(evt) { | ||||
|             evt.preventDefault(); | ||||
|             evt.stopPropagation(); | ||||
|             showObjectMenu($(this), item); | ||||
|         }); | ||||
|         item.element = container; | ||||
|         return item; | ||||
|     } | ||||
|     function convertToObject(item) { | ||||
|         var element; | ||||
|         switch (item.type) { | ||||
|             case 'string': element = item.value; break; | ||||
|             case 'number': element = Number(item.value); break; | ||||
|             case 'boolean': element = item.value; break; | ||||
|             case 'null': element = null; break; | ||||
|             case 'object': | ||||
|                 element = {}; | ||||
|                 item.children.forEach(function(child) { | ||||
|                     element[child.key] = convertToObject(child); | ||||
|                 }) | ||||
|             break; | ||||
|             case 'array': | ||||
|                 element = item.children.map(function(child) { | ||||
|                     return convertToObject(child); | ||||
|                 }) | ||||
|             break; | ||||
|         } | ||||
|         return element; | ||||
|     } | ||||
|  | ||||
|     var definition = { | ||||
|         show: function(options) { | ||||
| @@ -41,9 +453,11 @@ | ||||
|                     return false; | ||||
|                 } | ||||
|             } | ||||
|             var rootNode; | ||||
|  | ||||
|             var trayOptions = { | ||||
|                 title: options.title, | ||||
|                 width: "inherit", | ||||
|                 width: options.width||700, | ||||
|                 buttons: [ | ||||
|                     { | ||||
|                         id: "node-dialog-cancel", | ||||
| @@ -60,25 +474,60 @@ | ||||
|                             if (options.requireValid && !checkValid()) { | ||||
|                                 return; | ||||
|                             } | ||||
|                             onComplete(expressionEditor.getValue()); | ||||
|                             var result; | ||||
|                             if (activeTab === "json-ui") { | ||||
|                                 if (rootNode) { | ||||
|                                     result = JSON.stringify(convertToObject(rootNode),null,4); | ||||
|                                 } else { | ||||
|                                     result = expressionEditor.getValue(); | ||||
|                                 } | ||||
|                             } else if (activeTab === "json-raw") { | ||||
|                                 result = expressionEditor.getValue(); | ||||
|                             } | ||||
|                             onComplete && onComplete(result); | ||||
|                             RED.tray.close(); | ||||
|                         } | ||||
|                     } | ||||
|                 ], | ||||
|                 resize: function(dimensions) { | ||||
|                     var rows = $("#dialog-form>div:not(.node-text-editor-row)"); | ||||
|                     var editorRow = $("#dialog-form>div.node-text-editor-row"); | ||||
|                     var height = $("#dialog-form").height(); | ||||
|                     for (var i=0;i<rows.size();i++) { | ||||
|                         height -= $(rows[i]).outerHeight(true); | ||||
|                     } | ||||
|                     height -= (parseInt($("#dialog-form").css("marginTop"))+parseInt($("#dialog-form").css("marginBottom"))); | ||||
|                     $(".node-text-editor").css("height",height+"px"); | ||||
|                     var height = $(".red-ui-editor-type-json-tab-content").height(); | ||||
|                     $(".node-text-editor").css("height",(height-45)+"px"); | ||||
|                     expressionEditor.resize(); | ||||
|                 }, | ||||
|                 open: function(tray) { | ||||
|                     var trayBody = tray.find('.red-ui-tray-body'); | ||||
|                     var dialogForm = RED.editor.buildEditForm(tray.find('.red-ui-tray-body'),'dialog-form',type,'editor'); | ||||
|  | ||||
|                     var container = $("#red-ui-editor-type-json-tab-ui-container").css({"height":"100%"}); | ||||
|                     var filterDepth = Infinity; | ||||
|                     var list = $('<div class="red-ui-debug-msg-payload red-ui-editor-type-json-editor">').appendTo(container).treeList({ | ||||
|                         rootSortable: false, | ||||
|                         sortable: ".red-ui-editor-type-json-editor-item-handle", | ||||
|                     }).on("treelistchangeparent", function(event, evt) { | ||||
|                         if (evt.old.type === 'array') { | ||||
|                             evt.old.element.find(".red-ui-editor-type-json-editor-label-type").text("array["+evt.old.children.length+"]"); | ||||
|                         } | ||||
|                         if (evt.item.parent.type === 'array') { | ||||
|                             evt.item.parent.element.find(".red-ui-editor-type-json-editor-label-type").text("array["+evt.item.parent.children.length+"]"); | ||||
|                         } | ||||
|                     }).on("treelistsort", function(event, item) { | ||||
|                         item.children.forEach(function(child,i) { | ||||
|                             if (item.type === 'array') { | ||||
|                                 child.key = i; | ||||
|                                 child.element.find(".red-ui-editor-type-json-editor-label-key") | ||||
|                                 .text(child.key) | ||||
|                                 .removeClass('red-ui-debug-msg-type-string') | ||||
|                                 .addClass('red-ui-debug-msg-type-number'); | ||||
|                             } else { | ||||
|                                 child.element.find(".red-ui-editor-type-json-editor-label-key") | ||||
|                                     .text('"'+child.key+'"') | ||||
|                                     .removeClass('red-ui-debug-msg-type-number') | ||||
|                                     .addClass('red-ui-debug-msg-type-string'); | ||||
|                             } | ||||
|                         }) | ||||
|                     }); | ||||
|  | ||||
|  | ||||
|                     expressionEditor = RED.editor.createEditor({ | ||||
|                         id: 'node-input-json', | ||||
|                         value: "", | ||||
| @@ -103,9 +552,56 @@ | ||||
|                         expressionEditor.getSession().setValue(v||"",-1); | ||||
|                     }); | ||||
|                     dialogForm.i18n(); | ||||
|  | ||||
|                     var finishedBuild = false; | ||||
|                     var tabs = RED.tabs.create({ | ||||
|                         element: $("#red-ui-editor-type-json-tabs"), | ||||
|                         onchange:function(tab) { | ||||
|                             activeTab = tab.id; | ||||
|                             $(".red-ui-editor-type-json-tab-content").hide(); | ||||
|                             if (finishedBuild) { | ||||
|                                 if (tab.id === "json-raw") { | ||||
|                                     if (rootNode) { | ||||
|                                         var result = JSON.stringify(convertToObject(rootNode),null,4); | ||||
|                                         expressionEditor.getSession().setValue(result||"",-1); | ||||
|                                     } | ||||
|  | ||||
|                                 } else if (tab.id === "json-ui") { | ||||
|                                     var raw = expressionEditor.getValue().trim() ||"{}"; | ||||
|                                     try { | ||||
|                                         var parsed = JSON.parse(raw); | ||||
|                                         rootNode = handleItem(null,parsed,0,null); | ||||
|                                         rootNode.class = "red-ui-editor-type-json-root-node" | ||||
|                                         list.treeList('data',[rootNode]); | ||||
|                                     } catch(err) { | ||||
|                                         rootNode = null; | ||||
|                                         list.treeList('data',[{ | ||||
|                                             label: "Invalid JSON: "+err.toString() | ||||
|                                         }]); | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                             tab.content.show(); | ||||
|                             trayOptions.resize(); | ||||
|                         } | ||||
|                     }) | ||||
|  | ||||
|                     tabs.addTab({ | ||||
|                         id: 'json-raw', | ||||
|                         label: RED._('jsonEditor.rawMode'), | ||||
|                         content: $("#red-ui-editor-type-json-tab-raw") | ||||
|                     }); | ||||
|                     tabs.addTab({ | ||||
|                         id: 'json-ui', | ||||
|                         label: RED._('jsonEditor.uiMode'), | ||||
|                         content: $("#red-ui-editor-type-json-tab-ui") | ||||
|                     }); | ||||
|                     finishedBuild = true; | ||||
|  | ||||
|  | ||||
|                 }, | ||||
|                 close: function() { | ||||
|                     expressionEditor.destroy(); | ||||
|                     // expressionEditor.destroy(); | ||||
|                     if (options.onclose) { | ||||
|                         options.onclose(); | ||||
|                     } | ||||
|   | ||||
							
								
								
									
										90
									
								
								packages/node_modules/@node-red/editor-client/src/js/ui/editors/text.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,90 @@ | ||||
| /** | ||||
|  * Copyright JS Foundation and other contributors, http://js.foundation | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  **/ | ||||
| (function() { | ||||
|  | ||||
|  | ||||
|     var template = '<script type="text/x-red" data-template-name="_text"><div class="form-row node-text-editor-row"><div style="height: 200px;min-height: 150px;" class="node-text-editor" id="node-input-text"></div></div></script>'; | ||||
|  | ||||
|     var definition = { | ||||
|         show: function(options) { | ||||
|             var value = options.value; | ||||
|             var onComplete = options.complete; | ||||
|             var type = "_text" | ||||
|             if ($("script[data-template-name='"+type+"']").length === 0) { | ||||
|                 $(template).appendTo("#red-ui-editor-node-configs"); | ||||
|             } | ||||
|             RED.view.state(RED.state.EDITING); | ||||
|             var expressionEditor; | ||||
|             var changeTimer; | ||||
|  | ||||
|             var trayOptions = { | ||||
|                 title: options.title, | ||||
|                 width: options.width||"inherit", | ||||
|                 buttons: [ | ||||
|                     { | ||||
|                         id: "node-dialog-cancel", | ||||
|                         text: RED._("common.label.cancel"), | ||||
|                         click: function() { | ||||
|                             RED.tray.close(); | ||||
|                         } | ||||
|                     }, | ||||
|                     { | ||||
|                         id: "node-dialog-ok", | ||||
|                         text: RED._("common.label.done"), | ||||
|                         class: "primary", | ||||
|                         click: function() { | ||||
|                             onComplete(expressionEditor.getValue(),expressionEditor.getCursorPosition()); | ||||
|                             RED.tray.close(); | ||||
|                         } | ||||
|                     } | ||||
|                 ], | ||||
|                 resize: function(dimensions) { | ||||
|                     var rows = $("#dialog-form>div:not(.node-text-editor-row)"); | ||||
|                     var editorRow = $("#dialog-form>div.node-text-editor-row"); | ||||
|                     var height = $("#dialog-form").height(); | ||||
|                     // for (var i=0;i<rows.size();i++) { | ||||
|                     //     height -= $(rows[i]).outerHeight(true); | ||||
|                     // } | ||||
|                     // height -= (parseInt($("#dialog-form").css("marginTop"))+parseInt($("#dialog-form").css("marginBottom"))); | ||||
|                     $(".node-text-editor").css("height",height+"px"); | ||||
|                     expressionEditor.resize(); | ||||
|                 }, | ||||
|                 open: function(tray) { | ||||
|                     var trayBody = tray.find('.red-ui-tray-body'); | ||||
|                     var dialogForm = RED.editor.buildEditForm(tray.find('.red-ui-tray-body'),'dialog-form',type,'editor'); | ||||
|                     expressionEditor = RED.editor.createEditor({ | ||||
|                         id: 'node-input-text', | ||||
|                         value: "", | ||||
|                         mode:"ace/mode/"+(options.mode||"text") | ||||
|                     }); | ||||
|                     expressionEditor.getSession().setValue(value||"",-1); | ||||
|                     if (options.cursor) { | ||||
|                         expressionEditor.gotoLine(options.cursor.row+1,options.cursor.column,false); | ||||
|                     } | ||||
|                 }, | ||||
|                 close: function() { | ||||
|                     expressionEditor.destroy(); | ||||
|                     if (options.onclose) { | ||||
|                         options.onclose(); | ||||
|                     } | ||||
|                 }, | ||||
|                 show: function() {} | ||||
|             } | ||||
|             RED.tray.show(trayOptions); | ||||
|         } | ||||
|     } | ||||
|     RED.editor.registerTypeEditor("_text", definition); | ||||
| })(); | ||||
| @@ -19,7 +19,7 @@ RED.keyboard = (function() { | ||||
|  | ||||
|     var handlers = {}; | ||||
|     var partialState; | ||||
| RED.h = handlers; | ||||
|  | ||||
|     var keyMap = { | ||||
|         "left":37, | ||||
|         "up":38, | ||||
|   | ||||
| @@ -133,7 +133,7 @@ RED.library = (function() { | ||||
|                         icon: 'fa fa-folder', | ||||
|                         label: d, | ||||
|                         path: root+d+"/", | ||||
|                         children: function(item,done) { | ||||
|                         children: function(done, item) { | ||||
|                             loadLibraryFolder(library,type,root+d+"/", function(children) { | ||||
|                                 item.children = children; // TODO: should this be done by treeList for us | ||||
|                                 done(children); | ||||
| @@ -225,14 +225,19 @@ RED.library = (function() { | ||||
|                             expanded: true, | ||||
|                             writable: false, | ||||
|                             children: [{ | ||||
|                                 library: "local", | ||||
|                                 type: options.url, | ||||
|                                 icon: 'fa fa-cube', | ||||
|                                 label: options.type, | ||||
|                                 path: options.type+"/", | ||||
|                                 path: "", | ||||
|                                 expanded: true, | ||||
|                                 children: items | ||||
|                             }] | ||||
|                         }] | ||||
|                         loadLibraryBrowser.data(listing); | ||||
|                         setTimeout(function() { | ||||
|                             loadLibraryBrowser.select(listing[0].children[0]); | ||||
|                         },200); | ||||
|                     }); | ||||
|                     libraryEditor = ace.edit('red-ui-library-dialog-load-preview-text',{ | ||||
|                         useWorker: false | ||||
| @@ -262,24 +267,31 @@ RED.library = (function() { | ||||
|                     if (filename === "") { | ||||
|                         filename = "unnamed-"+options.type; | ||||
|                     } | ||||
|                     $("#red-ui-library-dialog-save-filename").attr("value",filename+".js"); | ||||
|                     $("#red-ui-library-dialog-save-filename").attr("value",filename+"."+(options.ext||"txt")); | ||||
|  | ||||
|                     loadLibraryFolder("local",options.url, "", function(items) { | ||||
|                         var listing = [{ | ||||
|                             icon: 'fa fa-archive', | ||||
|                             library: "local", | ||||
|                             type: options.url, | ||||
|                             icon: 'fa fa-hdd-o', | ||||
|                             label: RED._("library.types.local"), | ||||
|                             path: "", | ||||
|                             expanded: true, | ||||
|                             writable: false, | ||||
|                             children: [{ | ||||
|                                 library: "local", | ||||
|                                 type: options.url, | ||||
|                                 icon: 'fa fa-cube', | ||||
|                                 label: options.type, | ||||
|                                 path: options.type+"/", | ||||
|                                 path: "", | ||||
|                                 expanded: true, | ||||
|                                 children: items | ||||
|                             }] | ||||
|                         }] | ||||
|                         saveLibraryBrowser.data(listing); | ||||
|                         setTimeout(function() { | ||||
|                             saveLibraryBrowser.select(listing[0].children[0]); | ||||
|                         },200); | ||||
|                     }); | ||||
|                     $( "#red-ui-library-dialog-save" ).dialog( "open" ); | ||||
|                 } | ||||
| @@ -299,6 +311,10 @@ RED.library = (function() { | ||||
|                 if (options.onselect) { | ||||
|                     options.onselect(item); | ||||
|                 } | ||||
|             }).on('treelistconfirm', function(event, item) { | ||||
|                 if (options.onconfirm) { | ||||
|                     options.onconfirm(item); | ||||
|                 } | ||||
|             }); | ||||
|         var itemTools = $("<div>").css({position: "absolute",bottom:"6px",right:"8px"}); | ||||
|         var menuButton = $('<button class="red-ui-button red-ui-button-small" type="button"><i class="fa fa-ellipsis-h"></i></button>') | ||||
| @@ -309,7 +325,7 @@ RED.library = (function() { | ||||
|  | ||||
|                 var menuOptionMenu = RED.menu.init({id:"red-ui-library-browser-menu", | ||||
|                     options: [ | ||||
|                         {id:"red-ui-library-browser-menu-addFolder",label:"New folder", onselect: function() { | ||||
|                         {id:"red-ui-library-browser-menu-addFolder",label:RED._("library.newFolder"), onselect: function() { | ||||
|                             var defaultFolderName = "new-folder"; | ||||
|                             var defaultFolderNameMatches = {}; | ||||
|  | ||||
| @@ -406,17 +422,22 @@ RED.library = (function() { | ||||
|         } | ||||
|  | ||||
|         return { | ||||
|             select: function(item) { | ||||
|                 dirList.treeList('select',item); | ||||
|             }, | ||||
|             getSelected: function() { | ||||
|                 return dirList.treeList('selected'); | ||||
|             }, | ||||
|             focus: function() { | ||||
|                 dirList.focus(); | ||||
|             }, | ||||
|             data: function(content) { | ||||
|             data: function(content,selectFirst) { | ||||
|                 dirList.treeList('data',content); | ||||
|                 // setTimeout(function() { | ||||
|                 //     dirList.treeList('select',content[0]); | ||||
|                 // },100); | ||||
|                 if (selectFirst) { | ||||
|                     setTimeout(function() { | ||||
|                         dirList.treeList('select',content[0]); | ||||
|                     },100); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| @@ -424,8 +445,8 @@ RED.library = (function() { | ||||
|     return { | ||||
|         init: function() { | ||||
|  | ||||
|             $(_librarySave).appendTo("#red-ui-editor"); | ||||
|             $(_libraryLookup).appendTo("#red-ui-editor"); | ||||
|             $(_librarySave).appendTo("#red-ui-editor").i18n(); | ||||
|             $(_libraryLookup).appendTo("#red-ui-editor").i18n(); | ||||
|  | ||||
|             $( "#red-ui-library-dialog-save" ).dialog({ | ||||
|                 title: RED._("library.saveToLibrary"), | ||||
| @@ -459,7 +480,7 @@ RED.library = (function() { | ||||
|  | ||||
|             saveLibraryBrowser = RED.library.createBrowser({ | ||||
|                 container: $("#red-ui-library-dialog-save-browser"), | ||||
|                 addFolderButton: true, | ||||
|                 folderTools: true, | ||||
|                 onselect: function(item) { | ||||
|                     if (item.label) { | ||||
|                         if (!item.children) { | ||||
| @@ -482,6 +503,11 @@ RED.library = (function() { | ||||
|                 autoOpen: false, | ||||
|                 width: 800, | ||||
|                 resizable: false, | ||||
|                 classes: { | ||||
|                     "ui-dialog": "red-ui-editor-dialog", | ||||
|                     "ui-dialog-titlebar-close": "hide", | ||||
|                     "ui-widget-overlay": "red-ui-editor-dialog" | ||||
|                 }, | ||||
|                 buttons: [ | ||||
|                     { | ||||
|                         text: RED._("common.label.cancel"), | ||||
| @@ -545,11 +571,17 @@ RED.library = (function() { | ||||
|             }); | ||||
|             RED.panels.create({ | ||||
|                 container:$("#red-ui-library-dialog-load-panes"), | ||||
|                 dir: "horizontal" | ||||
|                 dir: "horizontal", | ||||
|                 resize: function() { | ||||
|                     libraryEditor.resize(); | ||||
|                 } | ||||
|             }); | ||||
|             RED.panels.create({ | ||||
|                 container:$("#red-ui-library-dialog-load-preview"), | ||||
|                 dir: "vertical" | ||||
|                 dir: "vertical", | ||||
|                 resize: function() { | ||||
|                     libraryEditor.resize(); | ||||
|                 } | ||||
|             }); | ||||
|         }, | ||||
|         create: createUI, | ||||
|   | ||||
| @@ -24,7 +24,7 @@ RED.notifications = (function() { | ||||
|     var myNotification = RED.notify("This is the message to display",{ | ||||
|         modal: true, | ||||
|         fixed: true, | ||||
|         type: 'warning', | ||||
|         type: 'warning', // 'compact', 'success', 'warning', 'error' | ||||
|         buttons: [ | ||||
|             { | ||||
|                 text: "cancel", | ||||
| @@ -103,7 +103,7 @@ RED.notifications = (function() { | ||||
|             $(n).append(msg); | ||||
|         } | ||||
|         if (options.buttons) { | ||||
|             var buttonSet = $('<div style="margin-top: 20px;" class="ui-dialog-buttonset"></div>').appendTo(n) | ||||
|             var buttonSet = $('<div class="ui-dialog-buttonset"></div>').appendTo(n) | ||||
|             options.buttons.forEach(function(buttonDef) { | ||||
|                 var b = $('<button>').html(buttonDef.text).on("click", buttonDef.click).appendTo(buttonSet); | ||||
|                 if (buttonDef.id) { | ||||
|   | ||||
| @@ -149,13 +149,12 @@ RED.palette = (function() { | ||||
|         RED.utils.createIconElement(icon_url, iconContainer, true); | ||||
|     } | ||||
|  | ||||
|     function escapeNodeType(nt) { | ||||
|         return nt.replace(" ","_").replace(".","_").replace(":","_"); | ||||
|     function getPaletteNode(type) { | ||||
|         return $(".red-ui-palette-node[data-palette-type='"+type+"']"); | ||||
|     } | ||||
|  | ||||
|      | ||||
|     function addNodeType(nt,def) { | ||||
|         var nodeTypeId = escapeNodeType(nt); | ||||
|         if ($("#red-ui-palette-node_"+nodeTypeId).length) { | ||||
|         if (getPaletteNode(nt).length) { | ||||
|             return; | ||||
|         } | ||||
|         if (exclusion.indexOf(def.category)===-1) { | ||||
| @@ -164,9 +163,7 @@ RED.palette = (function() { | ||||
|             var category = def.category.replace(/ /g,"_"); | ||||
|             var rootCategory = category.split("-")[0]; | ||||
|  | ||||
|             var d = document.createElement("div"); | ||||
|             d.id = "red-ui-palette-node_"+nodeTypeId; | ||||
|             d.type = nt; | ||||
|             var d = $('<div>',{class:"red-ui-palette-node"}).attr("data-palette-type",nt).data('category',rootCategory); | ||||
|  | ||||
|             var label = /^(.*?)([ -]in|[ -]out)?$/.exec(nt)[1]; | ||||
|             if (typeof def.paletteLabel !== "undefined") { | ||||
| @@ -182,7 +179,6 @@ RED.palette = (function() { | ||||
|                      + (((!def.align && def.inputs !== 0 && def.outputs === 0) || "right" === def.align) ? " red-ui-palette-label-right" : "") | ||||
|             }).appendTo(d); | ||||
|  | ||||
|             d.className="red-ui-palette-node"; | ||||
|  | ||||
|             if (def.icon) { | ||||
|                 var icon_url = RED.utils.getNodeIcon(def); | ||||
| @@ -193,36 +189,35 @@ RED.palette = (function() { | ||||
|                 RED.utils.createIconElement(icon_url, iconContainer, true); | ||||
|             } | ||||
|  | ||||
|             d.style.backgroundColor = RED.utils.getNodeColor(nt,def); | ||||
|             d.css("backgroundColor", RED.utils.getNodeColor(nt,def)); | ||||
|  | ||||
|             if (def.outputs > 0) { | ||||
|                 var portOut = document.createElement("div"); | ||||
|                 portOut.className = "red-ui-palette-port red-ui-palette-port-output"; | ||||
|                 d.appendChild(portOut); | ||||
|                 d.append(portOut); | ||||
|             } | ||||
|  | ||||
|             if (def.inputs > 0) { | ||||
|                 var portIn = document.createElement("div"); | ||||
|                 portIn.className = "red-ui-palette-port red-ui-palette-port-input"; | ||||
|                 d.appendChild(portIn); | ||||
|                 d.append(portIn); | ||||
|             } | ||||
|  | ||||
|             createCategory(def.category,rootCategory,category,(coreCategories.indexOf(rootCategory) !== -1)?"node-red":def.set.id); | ||||
|  | ||||
|             $("#red-ui-palette-"+category).append(d); | ||||
|  | ||||
|             $(d).data('category',rootCategory); | ||||
|  | ||||
|             d.onmousedown = function(e) { e.preventDefault(); }; | ||||
|             d.on("mousedown", function(e) { e.preventDefault();}); | ||||
|  | ||||
|             var popover = RED.popover.create({ | ||||
|                 target:$(d), | ||||
|                 target:d, | ||||
|                 trigger: "hover", | ||||
|                 width: "300px", | ||||
|                 content: "hi", | ||||
|                 delay: { show: 750, hide: 50 } | ||||
|             }); | ||||
|             $(d).data('popover',popover); | ||||
|  | ||||
|             d.data('popover',popover); | ||||
|  | ||||
|             // $(d).popover({ | ||||
|             //     title:d.type, | ||||
| @@ -232,14 +227,17 @@ RED.palette = (function() { | ||||
|             //     html: true, | ||||
|             //     container:'body' | ||||
|             // }); | ||||
|             $(d).on("click", function() { | ||||
|             d.on("click", function() { | ||||
|                 RED.view.focus(); | ||||
|                 var helpText; | ||||
|                 if (nt.indexOf("subflow:") === 0) { | ||||
|                     helpText = marked(RED.nodes.subflow(nt.substring(8)).info||"")||('<span class="red-ui-help-info-none">'+RED._("sidebar.info.none")+'</span>'); | ||||
|                 } else { | ||||
|                     helpText = $("script[data-help-name='"+d.type+"']").html()||('<span class="red-ui-help-info-none">'+RED._("sidebar.info.none")+'</span>'); | ||||
|                     helpText = $("script[data-help-name='"+d.attr("data-palette-type")+"']").html()||('<span class="red-ui-help-info-none">'+RED._("sidebar.info.none")+'</span>'); | ||||
|                 } | ||||
|                 // Don't look too closely. RED.sidebar.info.set will set the 'Description' | ||||
|                 // section of the sidebar. Pass in the title of the Help section so it looks | ||||
|                 // right. | ||||
|                 RED.sidebar.info.set(helpText,RED._("sidebar.info.nodeHelp")); | ||||
|             }); | ||||
|             var chart = $("#red-ui-workspace-chart"); | ||||
| @@ -330,13 +328,13 @@ RED.palette = (function() { | ||||
|  | ||||
|             var nodeInfo = null; | ||||
|             if (nt.indexOf("subflow:") === 0) { | ||||
|                 $(d).on("dblclick", function(e) { | ||||
|                 d.on("dblclick", function(e) { | ||||
|                     RED.workspaces.show(nt.substring(8)); | ||||
|                     e.preventDefault(); | ||||
|                 }); | ||||
|                 nodeInfo = marked(def.info||""); | ||||
|             } | ||||
|             setLabel(nt,$(d),label,nodeInfo); | ||||
|             setLabel(nt,d,label,nodeInfo); | ||||
|  | ||||
|             var categoryNode = $("#red-ui-palette-container-"+rootCategory); | ||||
|             if (categoryNode.find(".red-ui-palette-node").length === 1) { | ||||
| @@ -347,8 +345,7 @@ RED.palette = (function() { | ||||
|     } | ||||
|  | ||||
|     function removeNodeType(nt) { | ||||
|         var nodeTypeId = escapeNodeType(nt); | ||||
|         var paletteNode = $("#red-ui-palette-node_"+nodeTypeId); | ||||
|         var paletteNode = getPaletteNode(nt); | ||||
|         var categoryNode = paletteNode.closest(".red-ui-palette-category"); | ||||
|         paletteNode.remove(); | ||||
|         if (categoryNode.find(".red-ui-palette-node").length === 0) { | ||||
| @@ -360,8 +357,7 @@ RED.palette = (function() { | ||||
|     } | ||||
|  | ||||
|     function hideNodeType(nt) { | ||||
|         var nodeTypeId = escapeNodeType(nt); | ||||
|         var paletteNode = $("#red-ui-palette-node_"+nodeTypeId); | ||||
|         var paletteNode = getPaletteNode(nt); | ||||
|         paletteNode.hide(); | ||||
|         var categoryNode = paletteNode.closest(".red-ui-palette-category"); | ||||
|         var cl = categoryNode.find(".red-ui-palette-node"); | ||||
| @@ -373,8 +369,7 @@ RED.palette = (function() { | ||||
|     } | ||||
|  | ||||
|     function showNodeType(nt) { | ||||
|         var nodeTypeId = escapeNodeType(nt); | ||||
|         var paletteNode = $("#red-ui-palette-node_"+nodeTypeId); | ||||
|         var paletteNode = getPaletteNode(nt); | ||||
|         var categoryNode = paletteNode.closest(".red-ui-palette-category"); | ||||
|         categoryNode.show(); | ||||
|         paletteNode.show(); | ||||
| @@ -382,7 +377,7 @@ RED.palette = (function() { | ||||
|  | ||||
|     function refreshNodeTypes() { | ||||
|         RED.nodes.eachSubflow(function(sf) { | ||||
|             var paletteNode = $("#red-ui-palette-node_subflow_"+sf.id.replace(".","_")); | ||||
|             var paletteNode = getPaletteNode('subflow:'+sf.id); | ||||
|             var portInput = paletteNode.find(".red-ui-palette-port-input"); | ||||
|             var portOutput = paletteNode.find(".red-ui-palette-port-output"); | ||||
|  | ||||
| @@ -396,7 +391,6 @@ RED.palette = (function() { | ||||
|                   + (((!sf._def.align && sf.in.length !== 0 && sf.out.length === 0) || "right" === sf._def.align) ? " red-ui-palette-icon-container-right" : "") | ||||
|               ); | ||||
|  | ||||
|  | ||||
|             if (portInput.length === 0 && sf.in.length > 0) { | ||||
|                 var portIn = document.createElement("div"); | ||||
|                 portIn.className = "red-ui-palette-port red-ui-palette-port-input"; | ||||
| @@ -446,7 +440,8 @@ RED.palette = (function() { | ||||
|         var re = new RegExp(val.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'),'i'); | ||||
|         $("#red-ui-palette-container .red-ui-palette-node").each(function(i,el) { | ||||
|             var currentLabel = $(el).find(".red-ui-palette-label").text(); | ||||
|             if (val === "" || re.test(el.id) || re.test(currentLabel)) { | ||||
|             var type = $(el).attr("data-palette-type"); | ||||
|             if (val === "" || re.test(type) || re.test(currentLabel)) { | ||||
|                 $(this).show(); | ||||
|             } else { | ||||
|                 $(this).hide(); | ||||
| @@ -459,8 +454,10 @@ RED.palette = (function() { | ||||
|                         .find(".red-ui-palette-node") | ||||
|                         .filter(function() { return $(this).css('display') !== 'none'}).length === 0) { | ||||
|                     categoryContainers[category].close(); | ||||
|                     categoryContainers[category].container.slideUp(); | ||||
|                 } else { | ||||
|                     categoryContainers[category].open(); | ||||
|                     categoryContainers[category].container.show(); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| @@ -539,9 +536,6 @@ RED.palette = (function() { | ||||
|             sidebarControls.hide(); | ||||
|         }) | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|         var categoryList = coreCategories; | ||||
|         if (RED.settings.paletteCategories) { | ||||
|             categoryList = RED.settings.paletteCategories; | ||||
|   | ||||
| @@ -25,6 +25,7 @@ RED.search = (function() { | ||||
|     var index = {}; | ||||
|     var keys = []; | ||||
|     var results = []; | ||||
|     var previousActiveElement; | ||||
|  | ||||
|  | ||||
|     function indexProperty(node,label,property) { | ||||
| @@ -216,7 +217,7 @@ RED.search = (function() { | ||||
|                     var iconContainer = $('<div/>',{class:"red-ui-palette-icon-container"}).appendTo(nodeDiv); | ||||
|                     RED.utils.createIconElement(icon_url, iconContainer, true); | ||||
|  | ||||
|                     var contentDiv = $('<div>',{class:"red-ui-search-result-description"}).appendTo(div); | ||||
|                     var contentDiv = $('<div>',{class:"red-ui-search-result-node-description"}).appendTo(div); | ||||
|                     if (node.z) { | ||||
|                         var workspace = RED.nodes.workspace(node.z); | ||||
|                         if (!workspace) { | ||||
| @@ -253,6 +254,7 @@ RED.search = (function() { | ||||
|             return; | ||||
|         } | ||||
|         if (!visible) { | ||||
|             previousActiveElement = document.activeElement; | ||||
|             RED.keyboard.add("*","escape",function(){hide()}); | ||||
|             $("#red-ui-header-shade").show(); | ||||
|             $("#red-ui-editor-shade").show(); | ||||
| @@ -286,6 +288,10 @@ RED.search = (function() { | ||||
|                 }); | ||||
|             } | ||||
|             RED.events.emit("search:close"); | ||||
|             if (previousActiveElement) { | ||||
|                 $(previousActiveElement).trigger("focus"); | ||||
|                 previousActiveElement = null; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -296,6 +302,8 @@ RED.search = (function() { | ||||
|         RED.events.on("editor:close",function() { disabled = false; }); | ||||
|         RED.events.on("type-search:open",function() { disabled = true; }); | ||||
|         RED.events.on("type-search:close",function() { disabled = false; }); | ||||
|         RED.events.on("actionList:open",function() { disabled = true; }); | ||||
|         RED.events.on("actionList:close",function() { disabled = false; }); | ||||
|  | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -24,5 +24,6 @@ RED.state = { | ||||
|     IMPORT: 7, | ||||
|     IMPORT_DRAGGING: 8, | ||||
|     QUICK_JOINING: 9, | ||||
|     PANNING: 10 | ||||
|     PANNING: 10, | ||||
|     SELECTING_NODE: 11 | ||||
| } | ||||
|   | ||||
| @@ -53,6 +53,9 @@ RED.sidebar.config = (function() { | ||||
|             } | ||||
|             $('<span class="red-ui-sidebar-node-config-filter-info"></span>').appendTo(header); | ||||
|             category = $('<ul class="red-ui-palette-content red-ui-sidebar-node-config-list"></ul>').appendTo(container); | ||||
|             category.on("click", function(e) { | ||||
|                 $(content).find(".red-ui-palette-node").removeClass("selected"); | ||||
|             }); | ||||
|             container.i18n(); | ||||
|             var icon = header.find("i"); | ||||
|             var result = { | ||||
| @@ -139,11 +142,17 @@ RED.sidebar.config = (function() { | ||||
|                     currentType = node.type; | ||||
|                 } | ||||
|  | ||||
|                 var entry = $('<li class="red-ui-palette-node red-ui-palette-node-config red-ui-palette-node_id_'+node.id.replace(/\./g,"-")+'"></li>').appendTo(list); | ||||
|                 var entry = $('<li class="red-ui-palette-node_id_'+node.id.replace(/\./g,"-")+'"></li>').appendTo(list); | ||||
|                 var nodeDiv = $('<div class="red-ui-palette-node-config red-ui-palette-node"></div>').appendTo(entry); | ||||
|                 entry.data('node',node.id); | ||||
|                 $('<div class="red-ui-palette-label"></div>').text(label).appendTo(entry); | ||||
|                 var label = $('<div class="red-ui-palette-label"></div>').text(label).appendTo(nodeDiv); | ||||
|                 if (node.d) { | ||||
|                     nodeDiv.addClass("red-ui-palette-node-config-disabled"); | ||||
|                     $('<i class="fa fa-ban"></i>').prependTo(label); | ||||
|                 } | ||||
|  | ||||
|                 if (node._def.hasUsers !== false) { | ||||
|                     var iconContainer = $('<div/>',{class:"red-ui-palette-icon-container red-ui-palette-icon-container-right"}).appendTo(entry); | ||||
|                     var iconContainer = $('<div/>',{class:"red-ui-palette-icon-container red-ui-palette-icon-container-right"}).appendTo(nodeDiv); | ||||
|                     if (node.users.length === 0) { | ||||
|                         iconContainer.text(0); | ||||
|                     } else { | ||||
| @@ -155,10 +164,11 @@ RED.sidebar.config = (function() { | ||||
|                     } | ||||
|                     RED.popover.tooltip(iconContainer,RED._('editor.nodesUse',{count:node.users.length})); | ||||
|                     if (node.users.length === 0) { | ||||
|                         entry.addClass("red-ui-palette-node-config-unused"); | ||||
|                         nodeDiv.addClass("red-ui-palette-node-config-unused"); | ||||
|                     } | ||||
|                 } | ||||
|                 entry.on('click',function(e) { | ||||
|                 nodeDiv.on('click',function(e) { | ||||
|                     e.stopPropagation(); | ||||
|                     RED.view.select(false); | ||||
|                     if (e.metaKey) { | ||||
|                         $(this).toggleClass("selected"); | ||||
| @@ -168,11 +178,12 @@ RED.sidebar.config = (function() { | ||||
|                     } | ||||
|                     RED.sidebar.info.refresh(node); | ||||
|                 }); | ||||
|                 entry.on('dblclick',function(e) { | ||||
|                 nodeDiv.on('dblclick',function(e) { | ||||
|                     e.stopPropagation(); | ||||
|                     RED.editor.editConfig("", node.type, node.id); | ||||
|                 }); | ||||
|                 var userArray = node.users.map(function(n) { return n.id }); | ||||
|                 entry.on('mouseover',function(e) { | ||||
|                 nodeDiv.on('mouseover',function(e) { | ||||
|                     RED.nodes.eachNode(function(node) { | ||||
|                         if( userArray.indexOf(node.id) != -1) { | ||||
|                             node.highlighted = true; | ||||
| @@ -181,7 +192,7 @@ RED.sidebar.config = (function() { | ||||
|                     }); | ||||
|                     RED.view.redraw(); | ||||
|                 }); | ||||
|                 entry.on('mouseout',function(e) { | ||||
|                 nodeDiv.on('mouseout',function(e) { | ||||
|                     RED.nodes.eachNode(function(node) { | ||||
|                         if(node.highlighted) { | ||||
|                             node.highlighted = false; | ||||
| @@ -251,7 +262,7 @@ RED.sidebar.config = (function() { | ||||
|         RED.actions.add("core:delete-config-selection", function() { | ||||
|             var selectedNodes = []; | ||||
|             $(content).find(".red-ui-palette-node.selected").each(function() { | ||||
|                 selectedNodes.push($(this).data('node')); | ||||
|                 selectedNodes.push($(this).parent().data('node')); | ||||
|             }); | ||||
|             if (selectedNodes.length > 0) { | ||||
|                 var historyEvent = { | ||||
|   | ||||
| @@ -20,7 +20,7 @@ RED.sidebar.context = (function() { | ||||
|  | ||||
|     var localCache = {}; | ||||
|  | ||||
|  | ||||
|     var flowAutoRefresh; | ||||
|     var nodeSection; | ||||
|     // var subflowSection; | ||||
|     var flowSection; | ||||
| @@ -34,10 +34,20 @@ RED.sidebar.context = (function() { | ||||
|         content = $("<div>").css({"position":"relative","height":"100%"}); | ||||
|         content.className = "red-ui-sidebar-context" | ||||
|  | ||||
|         var header = $('<div class="red-ui-sidebar-header"></div>').appendTo(content); | ||||
|  | ||||
|         var autoUpdate = RED.settings.get("editor.context.refresh",false); | ||||
|         flowAutoRefresh = $('<input type="checkbox">').prop("checked",autoUpdate).appendTo(header).toggleButton({ | ||||
|             baseClass: "red-ui-sidebar-header-button", | ||||
|             enabledLabel: RED._("sidebar.context.autoRefresh"), | ||||
|             disabledLabel: RED._("sidebar.context.autoRefresh") | ||||
|         }).on("change", function() { | ||||
|             var value = $(this).prop("checked"); | ||||
|             RED.settings.set("editor.context.refresh",value); | ||||
|         }); | ||||
|  | ||||
|         var footerToolbar = $('<div></div>'); | ||||
|  | ||||
|  | ||||
|  | ||||
|         var stackContainer = $("<div>",{class:"red-ui-sidebar-context-stack"}).appendTo(content); | ||||
|         sections = RED.stack.create({ | ||||
|             container: stackContainer | ||||
| @@ -63,6 +73,7 @@ RED.sidebar.context = (function() { | ||||
|                 evt.preventDefault(); | ||||
|                 updateNode(currentNode, true); | ||||
|             }) | ||||
|         RED.popover.tooltip(bg,RED._("sidebar.context.refrsh")); | ||||
|  | ||||
|         // subflowSection  = sections.add({ | ||||
|         //     title: "Subflow", | ||||
| @@ -77,7 +88,7 @@ RED.sidebar.context = (function() { | ||||
|         //         evt.stopPropagation(); | ||||
|         //         evt.preventDefault(); | ||||
|         //     }) | ||||
|         // | ||||
|         // RED.popover.tooltip(bg,RED._("sidebar.context.refrsh")); | ||||
|         // subflowSection.container.hide(); | ||||
|  | ||||
|         flowSection = sections.add({ | ||||
| @@ -95,8 +106,9 @@ RED.sidebar.context = (function() { | ||||
|             .on("click", function(evt) { | ||||
|                 evt.stopPropagation(); | ||||
|                 evt.preventDefault(); | ||||
|                 updateFlow(currentFlow); | ||||
|                 updateFlow(currentFlow, true); | ||||
|             }) | ||||
|         RED.popover.tooltip(bg,RED._("sidebar.context.refrsh")); | ||||
|  | ||||
|         globalSection = sections.add({ | ||||
|             title: RED._("sidebar.context.global"), | ||||
| @@ -116,7 +128,7 @@ RED.sidebar.context = (function() { | ||||
|                 evt.preventDefault(); | ||||
|                 updateEntry(globalSection,"context/global","global"); | ||||
|             }) | ||||
|  | ||||
|         RED.popover.tooltip(bg,RED._("sidebar.context.refrsh")); | ||||
|  | ||||
|         RED.actions.add("core:show-context-tab",show); | ||||
|  | ||||
| @@ -162,8 +174,13 @@ RED.sidebar.context = (function() { | ||||
|         RED.events.on("workspace:change", function(event) { | ||||
|             updateFlow(RED.nodes.workspace(event.workspace)); | ||||
|         }) | ||||
|  | ||||
|         updateEntry(globalSection,"context/global","global"); | ||||
|         if (autoUpdate) { | ||||
|             updateEntry(globalSection,"context/global","global"); | ||||
|         } else { | ||||
|             $(globalSection.table).empty(); | ||||
|             $('<tr class="red-ui-help-info-row red-ui-search-empty blank" colspan="2"><td data-i18n="sidebar.context.refresh"></td></tr>').appendTo(globalSection.table).i18n(); | ||||
|             globalSection.timestamp.html(" "); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
| @@ -190,15 +207,20 @@ RED.sidebar.context = (function() { | ||||
|                 $('<tr class="red-ui-help-info-row red-ui-search-empty blank" colspan="2"><td data-i18n="sidebar.context.none"></td></tr>').appendTo(nodeSection.table).i18n(); | ||||
|             } | ||||
|             nodeSection.timestamp.html(" "); | ||||
|  | ||||
|         } | ||||
|     } | ||||
|     function updateFlow(flow) { | ||||
|     function updateFlow(flow, force) { | ||||
|         currentFlow = flow; | ||||
|         if (flow) { | ||||
|             updateEntry(flowSection,"context/flow/"+flow.id,flow.id); | ||||
|         if (force || flowAutoRefresh.prop("checked")) { | ||||
|             if (flow) { | ||||
|                 updateEntry(flowSection,"context/flow/"+flow.id,flow.id); | ||||
|             } else { | ||||
|                 updateEntry(flowSection) | ||||
|             } | ||||
|         } else { | ||||
|             updateEntry(flowSection) | ||||
|             $(flowSection.table).empty(); | ||||
|             $('<tr class="red-ui-help-info-row red-ui-search-empty blank" colspan="2"><td data-i18n="sidebar.context.refresh"></td></tr>').appendTo(flowSection.table).i18n(); | ||||
|             flowSection.timestamp.html(" "); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -252,6 +274,7 @@ RED.sidebar.context = (function() { | ||||
|                             } | ||||
|                         }) | ||||
|                     }); | ||||
|                     RED.popover.tooltip(refreshItem,RED._("sidebar.context.refrsh")); | ||||
|                     var deleteItem = $('<button class="red-ui-button red-ui-button-small"><i class="fa fa-trash"></i></button>').appendTo(tools).on("click", function(e) { | ||||
|                         e.preventDefault(); | ||||
|                         e.stopPropagation(); | ||||
| @@ -304,6 +327,7 @@ RED.sidebar.context = (function() { | ||||
|                         popover.open(); | ||||
|  | ||||
|                     }); | ||||
|                     RED.popover.tooltip(deleteItem,RED._("sidebar.context.delete")); | ||||
|                     var payload = v.msg; | ||||
|                     var format = v.format; | ||||
|                     RED.utils.createObjectElement(RED.utils.decodeObject(payload,format), { | ||||
|   | ||||
| @@ -128,6 +128,7 @@ RED.sidebar.info = (function() { | ||||
|         $(propertiesSection.content).empty(); | ||||
|         $(infoSection.content).empty(); | ||||
|         $(helpSection.content).empty(); | ||||
|         infoSection.title.text(RED._("sidebar.info.desc")); | ||||
|  | ||||
|         var propRow; | ||||
|  | ||||
| @@ -464,7 +465,7 @@ RED.sidebar.info = (function() { | ||||
|         propertiesSection.container.hide(); | ||||
|         helpSection.container.hide(); | ||||
|         infoSection.container.show(); | ||||
|         //helpSection.title.text(title||RED._("sidebar.info.info")); | ||||
|         infoSection.title.text(title||RED._("sidebar.info.desc")); | ||||
|         setInfoText(html,infoSection.content); | ||||
|         $(".red-ui-sidebar-info-stack").scrollTop(0); | ||||
|     } | ||||
|   | ||||
| @@ -18,15 +18,19 @@ RED.tray = (function() { | ||||
|     var stack = []; | ||||
|     var editorStack; | ||||
|     var openingTray = false; | ||||
|     var stackHidden = false; | ||||
|  | ||||
|     function resize() { | ||||
|  | ||||
|     } | ||||
|     function showTray(options) { | ||||
|         var el = $('<div class="red-ui-tray"></div>'); | ||||
|         var header = $('<div class="red-ui-tray-header"></div>').appendTo(el); | ||||
|         // `editor-tray-header` is deprecated - use red-ui-tray-body instead | ||||
|         var header = $('<div class="red-ui-tray-header editor-tray-header"></div>').appendTo(el); | ||||
|         var bodyWrapper = $('<div class="red-ui-tray-body-wrapper"></div>').appendTo(el); | ||||
|         var body = $('<div class="red-ui-tray-body"></div>').appendTo(bodyWrapper); | ||||
|         // `editor-tray-body` is deprecated - use red-ui-tray-body instead | ||||
|         var body = $('<div class="red-ui-tray-body editor-tray-body"></div>').appendTo(bodyWrapper); | ||||
|         // `editor-tray-footer` is deprecated - use red-ui-tray-footer instead | ||||
|         var footer = $('<div class="red-ui-tray-footer"></div>').appendTo(el); | ||||
|         var resizer = $('<div class="red-ui-tray-resize-handle"></div>').appendTo(el); | ||||
|         // var growButton = $('<a class="red-ui-tray-resize-button" style="cursor: w-resize;"><i class="fa fa-angle-left"></i></a>').appendTo(resizer); | ||||
| @@ -217,7 +221,19 @@ RED.tray = (function() { | ||||
|             }); | ||||
|         }, | ||||
|         show: function show(options) { | ||||
|             if (stack.length > 0 && !options.overlay) { | ||||
|             if (!options) { | ||||
|                 if (stack.length > 0) { | ||||
|                     var tray = stack[stack.length-1]; | ||||
|                     tray.tray.css({right:0}); | ||||
|                     $("#red-ui-header-shade").show(); | ||||
|                     $("#red-ui-editor-shade").show(); | ||||
|                     $("#red-ui-palette-shade").show(); | ||||
|                     $(".red-ui-sidebar-shade").show(); | ||||
|                     stackHidden = false; | ||||
|                 } | ||||
|             } else if (stackHidden) { | ||||
|                 throw new Error("Cannot add to stack whilst hidden"); | ||||
|             } else if (stack.length > 0 && !options.overlay) { | ||||
|                 var oldTray = stack[stack.length-1]; | ||||
|                 if (options.width === "inherit") { | ||||
|                     options.width = oldTray.tray.width(); | ||||
| @@ -235,6 +251,19 @@ RED.tray = (function() { | ||||
|             } | ||||
|  | ||||
|         }, | ||||
|         hide: function hide() { | ||||
|             if (stack.length > 0) { | ||||
|                 var tray = stack[stack.length-1]; | ||||
|                 tray.tray.css({ | ||||
|                     right: -(tray.tray.width()+10)+"px" | ||||
|                 }); | ||||
|                 $("#red-ui-header-shade").hide(); | ||||
|                 $("#red-ui-editor-shade").hide(); | ||||
|                 $("#red-ui-palette-shade").hide(); | ||||
|                 $(".red-ui-sidebar-shade").hide(); | ||||
|                 stackHidden = true; | ||||
|             } | ||||
|         }, | ||||
|         resize: handleWindowResize, | ||||
|         close: function close(done) { | ||||
|             if (stack.length > 0) { | ||||
|   | ||||
| @@ -13,6 +13,7 @@ RED.typeSearch = (function() { | ||||
|     var activeFilter = ""; | ||||
|     var addCallback; | ||||
|     var cancelCallback; | ||||
|     var moveCallback; | ||||
|  | ||||
|     var typesUsed = {}; | ||||
|  | ||||
| @@ -44,6 +45,14 @@ RED.typeSearch = (function() { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     function moveDialog(dx,dy) { | ||||
|         var pos = dialog.position(); | ||||
|         pos.top = (pos.top + dy)+"px"; | ||||
|         pos.left = (pos.left + dx)+"px"; | ||||
|         dialog.css(pos); | ||||
|         moveCallback(dx,dy); | ||||
|  | ||||
|     } | ||||
|     function createDialog() { | ||||
|         dialog = $("<div>",{id:"red-ui-type-search",class:"red-ui-search red-ui-type-search"}).appendTo("#red-ui-main-container"); | ||||
|         var searchDiv = $("<div>",{class:"red-ui-search-container"}).appendTo(dialog); | ||||
| @@ -55,7 +64,19 @@ RED.typeSearch = (function() { | ||||
|         }); | ||||
|         searchInput.on('keydown',function(evt) { | ||||
|             var children = searchResults.children(":visible"); | ||||
|             if (children.length > 0) { | ||||
|             if (evt.keyCode === 40 && evt.shiftKey) { | ||||
|                 evt.preventDefault(); | ||||
|                 moveDialog(0,10); | ||||
|             } else if (evt.keyCode === 38 && evt.shiftKey) { | ||||
|                 evt.preventDefault(); | ||||
|                 moveDialog(0,-10); | ||||
|             } else if (evt.keyCode === 39 && evt.shiftKey) { | ||||
|                 evt.preventDefault(); | ||||
|                 moveDialog(10,0); | ||||
|             } else if (evt.keyCode === 37 && evt.shiftKey) { | ||||
|                 evt.preventDefault(); | ||||
|                 moveDialog(-10,0); | ||||
|             } else if (children.length > 0) { | ||||
|                 if (evt.keyCode === 40) { | ||||
|                     // Down | ||||
|                     if (selected < children.length-1) { | ||||
| @@ -68,7 +89,6 @@ RED.typeSearch = (function() { | ||||
|                     ensureSelectedIsVisible(); | ||||
|                     evt.preventDefault(); | ||||
|                 } else if (evt.keyCode === 38) { | ||||
|                     // Up | ||||
|                     if (selected > 0) { | ||||
|                         if (selected < children.length) { | ||||
|                             $(children[selected]).removeClass('selected'); | ||||
| @@ -79,6 +99,7 @@ RED.typeSearch = (function() { | ||||
|                     ensureSelectedIsVisible(); | ||||
|                     evt.preventDefault(); | ||||
|                 } else if ((evt.metaKey || evt.ctrlKey) && evt.keyCode === 13 ) { | ||||
|                     evt.preventDefault(); | ||||
|                     // (ctrl or cmd) and enter | ||||
|                     var index = Math.max(0,selected); | ||||
|                     if (index < children.length) { | ||||
| @@ -90,8 +111,12 @@ RED.typeSearch = (function() { | ||||
|                             addCallback(n.type,true); | ||||
|                         } | ||||
|                         $("#red-ui-type-search-input").val("").trigger("keyup"); | ||||
|                         setTimeout(function() { | ||||
|                             $("#red-ui-type-search-input").focus(); | ||||
|                         },100); | ||||
|                     } | ||||
|                 } else if (evt.keyCode === 13) { | ||||
|                     evt.preventDefault(); | ||||
|                     // Enter | ||||
|                     var index = Math.max(0,selected); | ||||
|                     if (index < children.length) { | ||||
| @@ -99,6 +124,12 @@ RED.typeSearch = (function() { | ||||
|                         confirm($(children[index]).find(".red-ui-editableList-item-content").data('data')); | ||||
|                     } | ||||
|                 } | ||||
|             } else { | ||||
|                 if (evt.keyCode === 13 ) { | ||||
|                     // Stop losing focus if [Cmd]-Enter is pressed on an empty list | ||||
|                     evt.stopPropagation(); | ||||
|                     evt.preventDefault(); | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
|  | ||||
| @@ -137,7 +168,7 @@ RED.typeSearch = (function() { | ||||
|                 if (object.separator) { | ||||
|                     container.addClass("red-ui-search-result-separator") | ||||
|                 } | ||||
|                 var div = $('<a>',{href:'#',class:"red-ui-search-result"}).appendTo(container); | ||||
|                 var div = $('<div>',{class:"red-ui-search-result"}).appendTo(container); | ||||
|  | ||||
|                 var nodeDiv = $('<div>',{class:"red-ui-search-result-node"}).appendTo(div); | ||||
|                 var colour = RED.utils.getNodeColor(object.type,def); | ||||
| @@ -219,6 +250,7 @@ RED.typeSearch = (function() { | ||||
|         refreshTypeList(opts); | ||||
|         addCallback = opts.add; | ||||
|         cancelCallback = opts.cancel; | ||||
|         moveCallback = opts.move; | ||||
|         RED.events.emit("type-search:open"); | ||||
|         //shade.show(); | ||||
|         if ($("#red-ui-main-container").height() - opts.y - 150 < 0) { | ||||
| @@ -283,7 +315,7 @@ RED.typeSearch = (function() { | ||||
|     function refreshTypeList(opts) { | ||||
|         var i; | ||||
|         searchResults.editableList('empty'); | ||||
|         searchInput.searchBox('value',''); | ||||
|         searchInput.searchBox('value','').focus(); | ||||
|         selected = -1; | ||||
|         var common = [ | ||||
|             'inject','debug','function','change','switch' | ||||
|   | ||||
| @@ -101,10 +101,19 @@ RED.userSettings = (function() { | ||||
|         RED.tray.show(trayOptions); | ||||
|     } | ||||
|  | ||||
|     function localeToName(lc) { | ||||
|         var name = RED._("languages."+lc); | ||||
|         return {text: (name ? name : lc), val: lc}; | ||||
|     } | ||||
|  | ||||
|     function compText(a, b) { | ||||
|         return a.text.localeCompare(b.text); | ||||
|     } | ||||
|      | ||||
|     var viewSettings = [ | ||||
|         { | ||||
|             options: [ | ||||
|                 {setting:"editor-language",local: true, label:"menu.label.view.language",options:function(done){ done([{val:'',text:RED._('menu.label.view.browserDefault')}].concat(RED.settings.theme("languages"))) }}, | ||||
|                 {setting:"editor-language",local: true, label:"menu.label.view.language",options:function(done){ done([{val:'',text:RED._('menu.label.view.browserDefault')}].concat(RED.settings.theme("languages").map(localeToName).sort(compText))) }}, | ||||
|             ] | ||||
|         },{ | ||||
|             title: "menu.label.view.grid", | ||||
|   | ||||
| @@ -125,12 +125,14 @@ RED.utils = (function() { | ||||
|                 e.stopPropagation(); | ||||
|                 RED.clipboard.copyText(key,copyPath,"clipboard.copyMessagePath"); | ||||
|             }) | ||||
|             RED.popover.tooltip(copyPath,RED._("node-red:debug.sidebar.copyPath")); | ||||
|         } | ||||
|         var copyPayload = $('<button class="red-ui-button red-ui-button-small"><i class="fa fa-clipboard"></i></button>').appendTo(copyTools).on("click", function(e) { | ||||
|             e.preventDefault(); | ||||
|             e.stopPropagation(); | ||||
|             RED.clipboard.copyText(msg,copyPayload,"clipboard.copyMessageValue"); | ||||
|         }) | ||||
|         RED.popover.tooltip(copyPayload,RED._("node-red:debug.sidebar.copyPayload")); | ||||
|         if (strippedKey !== undefined && strippedKey !== '') { | ||||
|             var isPinned = pinnedPaths[sourceId].hasOwnProperty(strippedKey); | ||||
|  | ||||
| @@ -149,6 +151,7 @@ RED.utils = (function() { | ||||
|                 } | ||||
|             }).toggleClass("selected",isPinned); | ||||
|             obj.toggleClass("red-ui-debug-msg-row-pinned",isPinned); | ||||
|             RED.popover.tooltip(pinPath,RED._("node-red:debug.sidebar.pinPath")); | ||||
|         } | ||||
|         if (extraTools) { | ||||
|             extraTools.addClass("red-ui-debug-msg-tools-other"); | ||||
| @@ -722,6 +725,62 @@ RED.utils = (function() { | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|     function setMessageProperty(msg,prop,value,createMissing) { | ||||
|         if (typeof createMissing === 'undefined') { | ||||
|             createMissing = (typeof value !== 'undefined'); | ||||
|         } | ||||
|         if (prop.indexOf('msg.')===0) { | ||||
|             prop = prop.substring(4); | ||||
|         } | ||||
|         var msgPropParts = normalisePropertyExpression(prop); | ||||
|         var depth = 0; | ||||
|         var length = msgPropParts.length; | ||||
|         var obj = msg; | ||||
|         var key; | ||||
|         for (var i=0;i<length-1;i++) { | ||||
|             key = msgPropParts[i]; | ||||
|             if (typeof key === 'string' || (typeof key === 'number' && !Array.isArray(obj))) { | ||||
|                 if (obj.hasOwnProperty(key)) { | ||||
|                     obj = obj[key]; | ||||
|                 } else if (createMissing) { | ||||
|                     if (typeof msgPropParts[i+1] === 'string') { | ||||
|                         obj[key] = {}; | ||||
|                     } else { | ||||
|                         obj[key] = []; | ||||
|                     } | ||||
|                     obj = obj[key]; | ||||
|                 } else { | ||||
|                     return null; | ||||
|                 } | ||||
|             } else if (typeof key === 'number') { | ||||
|                 // obj is an array | ||||
|                 if (obj[key] === undefined) { | ||||
|                     if (createMissing) { | ||||
|                         if (typeof msgPropParts[i+1] === 'string') { | ||||
|                             obj[key] = {}; | ||||
|                         } else { | ||||
|                             obj[key] = []; | ||||
|                         } | ||||
|                         obj = obj[key]; | ||||
|                     } else { | ||||
|                         return null; | ||||
|                     } | ||||
|                 } else { | ||||
|                     obj = obj[key]; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         key = msgPropParts[length-1]; | ||||
|         if (typeof value === "undefined") { | ||||
|             if (typeof key === 'number' && Array.isArray(obj)) { | ||||
|                 obj.splice(key,1); | ||||
|             } else { | ||||
|                 delete obj[key] | ||||
|             } | ||||
|         } else { | ||||
|             obj[key] = value; | ||||
|         } | ||||
|     } | ||||
|     function separateIconPath(icon) { | ||||
|         var result = {module: "", file: ""}; | ||||
|         if (icon) { | ||||
| @@ -743,13 +802,13 @@ RED.utils = (function() { | ||||
|     function getDefaultNodeIcon(def,node) { | ||||
|         var icon_url; | ||||
|         if (node && node.type === "subflow") { | ||||
|             icon_url = "node-red/subflow.png"; | ||||
|             icon_url = "node-red/subflow.svg"; | ||||
|         } else if (typeof def.icon === "function") { | ||||
|             try { | ||||
|                 icon_url = def.icon.call(node); | ||||
|             } catch(err) { | ||||
|                 console.log("Definition error: "+def.type+".icon",err); | ||||
|                 icon_url = "arrow-in.png"; | ||||
|                 icon_url = "arrow-in.svg"; | ||||
|             } | ||||
|         } else { | ||||
|             icon_url = def.icon; | ||||
| @@ -779,11 +838,11 @@ RED.utils = (function() { | ||||
|  | ||||
|     function getNodeIcon(def,node) { | ||||
|         if (def.category === 'config') { | ||||
|             return RED.settings.apiRootUrl+"icons/node-red/cog.png" | ||||
|             return RED.settings.apiRootUrl+"icons/node-red/cog.svg" | ||||
|         } else if (node && node.type === 'tab') { | ||||
|             return RED.settings.apiRootUrl+"icons/node-red/subflow.png" | ||||
|             return RED.settings.apiRootUrl+"icons/node-red/subflow.svg" | ||||
|         } else if (node && node.type === 'unknown') { | ||||
|             return RED.settings.apiRootUrl+"icons/node-red/alert.png" | ||||
|             return RED.settings.apiRootUrl+"icons/node-red/alert.svg" | ||||
|         } else if (node && node.icon) { | ||||
|             var iconPath = separateIconPath(node.icon); | ||||
|             if (isIconExists(iconPath)) { | ||||
| @@ -792,6 +851,11 @@ RED.utils = (function() { | ||||
|                 } else { | ||||
|                     return RED.settings.apiRootUrl+"icons/" + node.icon; | ||||
|                 } | ||||
|             } else if (iconPath.module !== "font-awesome" && /.png$/i.test(iconPath.file)) { | ||||
|                 iconPath.file = iconPath.file.replace(/.png$/,".svg"); | ||||
|                 if (isIconExists(iconPath)) { | ||||
|                     return RED.settings.apiRootUrl+"icons/" + node.icon.replace(/.png$/,".svg"); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
| @@ -802,17 +866,32 @@ RED.utils = (function() { | ||||
|             } else { | ||||
|                 return RED.settings.apiRootUrl+"icons/"+iconPath.module+"/"+iconPath.file; | ||||
|             } | ||||
|         } else { | ||||
|             // This could be a non-core node trying to use a core icon. | ||||
|             iconPath.module = 'node-red'; | ||||
|         } | ||||
|  | ||||
|         if (/.png$/i.test(iconPath.file)) { | ||||
|             var originalFile = iconPath.file; | ||||
|             iconPath.file = iconPath.file.replace(/.png$/,".svg"); | ||||
|             if (isIconExists(iconPath)) { | ||||
|                 return RED.settings.apiRootUrl+"icons/"+iconPath.module+"/"+iconPath.file; | ||||
|             } | ||||
|             iconPath.file = originalFile; | ||||
|         } | ||||
|  | ||||
|         // This could be a non-core node trying to use a core icon. | ||||
|         iconPath.module = 'node-red'; | ||||
|         if (isIconExists(iconPath)) { | ||||
|             return RED.settings.apiRootUrl+"icons/"+iconPath.module+"/"+iconPath.file; | ||||
|         } | ||||
|         if (/.png$/i.test(iconPath.file)) { | ||||
|             iconPath.file = iconPath.file.replace(/.png$/,".svg"); | ||||
|             if (isIconExists(iconPath)) { | ||||
|                 return RED.settings.apiRootUrl+"icons/"+iconPath.module+"/"+iconPath.file; | ||||
|             } else if (def.category === 'subflows') { | ||||
|                 return RED.settings.apiRootUrl+"icons/node-red/subflow.png"; | ||||
|             } else { | ||||
|                 return RED.settings.apiRootUrl+"icons/node-red/arrow-in.png"; | ||||
|             } | ||||
|         } | ||||
|         if (def.category === 'subflows') { | ||||
|             return RED.settings.apiRootUrl+"icons/node-red/subflow.svg"; | ||||
|         } | ||||
|         return RED.settings.apiRootUrl+"icons/node-red/arrow-in.svg"; | ||||
|     } | ||||
|  | ||||
|     function getNodeLabel(node,defaultLabel) { | ||||
| @@ -948,7 +1027,7 @@ RED.utils = (function() { | ||||
|                 return; | ||||
|             } | ||||
|             // If the specified name is not defined in font-awesome, show arrow-in icon. | ||||
|             iconUrl = RED.settings.apiRootUrl+"icons/node-red/arrow-in.png" | ||||
|             iconUrl = RED.settings.apiRootUrl+"icons/node-red/arrow-in.svg" | ||||
|         } | ||||
|         var imageIconElement = $('<div/>',{class:"red-ui-palette-icon"}).appendTo(iconContainer); | ||||
|         imageIconElement.css("backgroundImage", "url("+iconUrl+")"); | ||||
| @@ -957,6 +1036,7 @@ RED.utils = (function() { | ||||
|     return { | ||||
|         createObjectElement: buildMessageElement, | ||||
|         getMessageProperty: getMessageProperty, | ||||
|         setMessageProperty: setMessageProperty, | ||||
|         normalisePropertyExpression: normalisePropertyExpression, | ||||
|         validatePropertyExpression: validatePropertyExpression, | ||||
|         separateIconPath: separateIconPath, | ||||
|   | ||||
| @@ -77,6 +77,8 @@ RED.view = (function() { | ||||
|         quickAddLink = null, | ||||
|         showAllLinkPorts = -1; | ||||
|  | ||||
|     var selectNodesOptions; | ||||
|  | ||||
|     var clipboard = ""; | ||||
|  | ||||
|     // Note: these are the permitted status colour aliases. The actual RGB values | ||||
| @@ -326,7 +328,7 @@ RED.view = (function() { | ||||
|             accept:".red-ui-palette-node", | ||||
|             drop: function( event, ui ) { | ||||
|                 d3.event = event; | ||||
|                 var selected_tool = ui.draggable[0].type; | ||||
|                 var selected_tool = $(ui.draggable[0]).attr("data-palette-type"); | ||||
|                 var result = addNode(selected_tool); | ||||
|                 if (!result) { | ||||
|                     return; | ||||
| @@ -408,6 +410,8 @@ RED.view = (function() { | ||||
|         RED.actions.add("core:zoom-in",zoomIn); | ||||
|         RED.actions.add("core:zoom-out",zoomOut); | ||||
|         RED.actions.add("core:zoom-reset",zoomZero); | ||||
|         RED.actions.add("core:enable-selected-nodes", function() { setSelectedNodeState(false)}); | ||||
|         RED.actions.add("core:disable-selected-nodes", function() { setSelectedNodeState(true)}); | ||||
|  | ||||
|         RED.actions.add("core:toggle-show-grid",function(state) { | ||||
|             if (state === undefined) { | ||||
| @@ -640,6 +644,7 @@ RED.view = (function() { | ||||
|  | ||||
|         nn.w = node_width; | ||||
|         nn.h = Math.max(node_height,(nn.outputs||0) * 15); | ||||
|         nn.resize = true; | ||||
|  | ||||
|         var historyEvent = { | ||||
|             t:"add", | ||||
| @@ -665,6 +670,10 @@ RED.view = (function() { | ||||
|  | ||||
|     function canvasMouseDown() { | ||||
|         var point; | ||||
|         if (mouse_mode === RED.state.SELECTING_NODE) { | ||||
|             d3.event.stopPropagation(); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if (d3.event.button === 1) { | ||||
|             // Middle Click pan | ||||
| @@ -766,6 +775,15 @@ RED.view = (function() { | ||||
|                     x:d3.event.clientX-mainPos.left-node_width/2 - (ox-point[0]), | ||||
|                     y:d3.event.clientY-mainPos.top+ node_height/2 + 5 - (oy-point[1]), | ||||
|                     filter: filter, | ||||
|                     move: function(dx,dy) { | ||||
|                         if (ghostNode) { | ||||
|                             var pos = d3.transform(ghostNode.attr("transform")).translate; | ||||
|                             ghostNode.attr("transform","translate("+(pos[0]+dx)+","+(pos[1]+dy)+")") | ||||
|                             point[0] += dx; | ||||
|                             point[1] += dy; | ||||
|                             rebuildQuickAddLink(); | ||||
|                         } | ||||
|                     }, | ||||
|                     cancel: function() { | ||||
|                         if (quickAddLink) { | ||||
|                             if (quickAddLink.el) { | ||||
| @@ -1026,6 +1044,11 @@ RED.view = (function() { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if (mouse_mode === RED.state.SELECTING_NODE) { | ||||
|             d3.event.stopPropagation(); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if (mouse_mode != RED.state.QUICK_JOINING && mouse_mode != RED.state.IMPORT_DRAGGING && !mousedown_node && selected_link == null) { | ||||
|             return; | ||||
|         } | ||||
| @@ -1231,6 +1254,10 @@ RED.view = (function() { | ||||
|             resetMouseVars(); | ||||
|             return | ||||
|         } | ||||
|         if (mouse_mode === RED.state.SELECTING_NODE) { | ||||
|             d3.event.stopPropagation(); | ||||
|             return; | ||||
|         } | ||||
|         if (mouse_mode === RED.state.QUICK_JOINING) { | ||||
|             return; | ||||
|         } | ||||
| @@ -1351,27 +1378,42 @@ RED.view = (function() { | ||||
|  | ||||
|     function zoomIn() { | ||||
|         if (scaleFactor < 2) { | ||||
|             scaleFactor += 0.1; | ||||
|             RED.view.navigator.resize(); | ||||
|             redraw(); | ||||
|             zoomView(scaleFactor+0.1); | ||||
|         } | ||||
|     } | ||||
|     function zoomOut() { | ||||
|         if (scaleFactor > 0.3) { | ||||
|             scaleFactor -= 0.1; | ||||
|             RED.view.navigator.resize(); | ||||
|             redraw(); | ||||
|             zoomView(scaleFactor-0.1); | ||||
|         } | ||||
|     } | ||||
|     function zoomZero() { | ||||
|         scaleFactor = 1; | ||||
|     function zoomZero() { zoomView(1); } | ||||
|  | ||||
|     function zoomView(factor) { | ||||
|         var screenSize = [chart.width(),chart.height()]; | ||||
|         var scrollPos = [chart.scrollLeft(),chart.scrollTop()]; | ||||
|         var center = [(scrollPos[0] + screenSize[0]/2)/scaleFactor,(scrollPos[1] + screenSize[1]/2)/scaleFactor]; | ||||
|         scaleFactor = factor; | ||||
|         var newCenter = [(scrollPos[0] + screenSize[0]/2)/scaleFactor,(scrollPos[1] + screenSize[1]/2)/scaleFactor]; | ||||
|         var delta = [(newCenter[0]-center[0])*scaleFactor,(newCenter[1]-center[1])*scaleFactor] | ||||
|         chart.scrollLeft(scrollPos[0]-delta[0]); | ||||
|         chart.scrollTop(scrollPos[1]-delta[1]); | ||||
|  | ||||
|         RED.view.navigator.resize(); | ||||
|         redraw(); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     function selectAll() { | ||||
|         if (mouse_mode === RED.state.SELECTING_NODE && selectNodesOptions.single) { | ||||
|             return; | ||||
|         } | ||||
|         RED.nodes.eachNode(function(n) { | ||||
|             if (n.z == RED.workspaces.active()) { | ||||
|                 if (mouse_mode === RED.state.SELECTING_NODE) { | ||||
|                     if (selectNodesOptions.filter && !selectNodesOptions.filter(n)) { | ||||
|                         return; | ||||
|                     } | ||||
|                 } | ||||
|                 if (!n.selected) { | ||||
|                     n.selected = true; | ||||
|                     n.dirty = true; | ||||
| @@ -1379,7 +1421,7 @@ RED.view = (function() { | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
|         if (activeSubflow) { | ||||
|         if (mouse_mode !== RED.state.SELECTING_NODE && activeSubflow) { | ||||
|             activeSubflow.in.forEach(function(n) { | ||||
|                 if (!n.selected) { | ||||
|                     n.selected = true; | ||||
| @@ -1404,7 +1446,9 @@ RED.view = (function() { | ||||
|         } | ||||
|  | ||||
|         selected_link = null; | ||||
|         updateSelection(); | ||||
|         if (mouse_mode !== RED.state.SELECTING_NODE) { | ||||
|             updateSelection(); | ||||
|         } | ||||
|         redraw(); | ||||
|     } | ||||
|  | ||||
| @@ -1538,6 +1582,9 @@ RED.view = (function() { | ||||
|         } | ||||
|     } | ||||
|     function deleteSelection() { | ||||
|         if (mouse_mode === RED.state.SELECTING_NODE) { | ||||
|             return; | ||||
|         } | ||||
|         if (portLabelHover) { | ||||
|             portLabelHover.remove(); | ||||
|             portLabelHover = null; | ||||
| @@ -1714,6 +1761,9 @@ RED.view = (function() { | ||||
|     } | ||||
|  | ||||
|     function copySelection() { | ||||
|         if (mouse_mode === RED.state.SELECTING_NODE) { | ||||
|             return; | ||||
|         } | ||||
|         var nodes = []; | ||||
|         var selection = RED.workspaces.selection(); | ||||
|         if (selection.length > 0) { | ||||
| @@ -1758,16 +1808,18 @@ RED.view = (function() { | ||||
|         return calculateTextDimensions(str,className,offset,0)[0]; | ||||
|     } | ||||
|  | ||||
|     var textDimensionPlaceholder = {}; | ||||
|     function calculateTextDimensions(str,className,offsetW,offsetH) { | ||||
|         var sp = document.createElement("span"); | ||||
|         sp.className = className; | ||||
|         sp.style.position = "absolute"; | ||||
|         sp.style.top = "-1000px"; | ||||
|         sp.textContent = (str||""); | ||||
|         document.body.appendChild(sp); | ||||
|         var w = sp.offsetWidth; | ||||
|         var h = sp.offsetHeight; | ||||
|         document.body.removeChild(sp); | ||||
|         if (!textDimensionPlaceholder[className]) { | ||||
|             textDimensionPlaceholder[className] = document.createElement("span"); | ||||
|             textDimensionPlaceholder[className].className = className; | ||||
|             textDimensionPlaceholder[className].style.position = "absolute"; | ||||
|             textDimensionPlaceholder[className].style.top = "-1000px"; | ||||
|             document.getElementById("red-ui-editor").appendChild(textDimensionPlaceholder[className]); | ||||
|         } | ||||
|         textDimensionPlaceholder[className].textContent = (str||""); | ||||
|         var w = textDimensionPlaceholder[className].offsetWidth; | ||||
|         var h = textDimensionPlaceholder[className].offsetHeight; | ||||
|         return [offsetW+w,offsetH+h]; | ||||
|     } | ||||
|  | ||||
| @@ -1803,7 +1855,10 @@ RED.view = (function() { | ||||
|         if (d3.event.button === 1) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if (mouse_mode === RED.state.SELECTING_NODE) { | ||||
|             d3.event.stopPropagation(); | ||||
|             return; | ||||
|         } | ||||
|         mousedown_node = d; | ||||
|         mousedown_port_type = portType; | ||||
|         mousedown_port_index = portIndex || 0; | ||||
| @@ -1821,6 +1876,10 @@ RED.view = (function() { | ||||
|     } | ||||
|  | ||||
|     function portMouseUp(d,portType,portIndex) { | ||||
|         if (mouse_mode === RED.state.SELECTING_NODE) { | ||||
|             d3.event.stopPropagation(); | ||||
|             return; | ||||
|         } | ||||
|         var i; | ||||
|         if (mouse_mode === RED.state.QUICK_JOINING && drag_lines.length > 0) { | ||||
|             if (drag_lines[0].node === d) { | ||||
| @@ -1882,7 +1941,7 @@ RED.view = (function() { | ||||
|                     } | ||||
|                     var link = {source: src, sourcePort:src_port, target: dst}; | ||||
|                     if (drag_line.virtualLink) { | ||||
|                         if (/^link (in|out)$/.test(src.type) && /^link (in|out)$/.test(dst.type)) { | ||||
|                         if (/^link (in|out)$/.test(src.type) && /^link (in|out)$/.test(dst.type) && src.type !== dst.type) { | ||||
|                             if (src.links.indexOf(dst.id) === -1 && dst.links.indexOf(src.id) === -1) { | ||||
|                                 var oldSrcLinks = $.extend(true,{},{v:src.links}).v | ||||
|                                 var oldDstLinks = $.extend(true,{},{v:dst.links}).v | ||||
| @@ -2073,7 +2132,7 @@ RED.view = (function() { | ||||
|         var labelHeight2 = labelHeight - 4; | ||||
|         var path; | ||||
|         var lx; | ||||
|         var ly = -labelHeight/2+3; | ||||
|         var ly = -labelHeight/2; | ||||
|         var anchor; | ||||
|         if (direction === "left") { | ||||
|             path = "M0 0 l -5 -5 v -"+(labelHeight1)+" q 0 -2 -2 -2 h -"+labelWidth+" q -2 0 -2 2 v "+(labelHeight2)+" q 0 2 2 2 h "+labelWidth+" q 2 0 2 -2 v -"+(labelHeight1)+" l 5 -5"; | ||||
| @@ -2086,7 +2145,7 @@ RED.view = (function() { | ||||
|         } else if (direction === "top") { | ||||
|             path = "M0 0 l 5 -5 h "+(labelWidth1)+" q 2 0 2 -2 v -"+labelHeight+" q 0 -2 -2 -2 h -"+(labelWidth2)+" q -2 0 -2 2 v "+labelHeight+" q 0 2 2 2 h "+(labelWidth1)+" l 5 5" | ||||
|             lx = -labelWidth/2 + 6; | ||||
|             ly = -labelHeight-lineHeight+10; | ||||
|             ly = -labelHeight-lineHeight+12; | ||||
|             anchor = "start"; | ||||
|         } | ||||
|         tooltip.append("path").attr("d",path); | ||||
| @@ -2103,6 +2162,10 @@ RED.view = (function() { | ||||
|     } | ||||
|  | ||||
|     function portMouseOver(port,d,portType,portIndex) { | ||||
|         if (mouse_mode === RED.state.SELECTING_NODE) { | ||||
|             d3.event.stopPropagation(); | ||||
|             return; | ||||
|         } | ||||
|         clearTimeout(portLabelHoverTimeout); | ||||
|         var active = (mouse_mode!=RED.state.JOINING && mouse_mode != RED.state.QUICK_JOINING) || // Not currently joining - all ports active | ||||
|                      ( | ||||
| @@ -2134,6 +2197,10 @@ RED.view = (function() { | ||||
|         port.classed("red-ui-flow-port-hovered",active); | ||||
|     } | ||||
|     function portMouseOut(port,d,portType,portIndex) { | ||||
|         if (mouse_mode === RED.state.SELECTING_NODE) { | ||||
|             d3.event.stopPropagation(); | ||||
|             return; | ||||
|         } | ||||
|         clearTimeout(portLabelHoverTimeout); | ||||
|         if (portLabelHover) { | ||||
|             portLabelHover.remove(); | ||||
| @@ -2143,6 +2210,10 @@ RED.view = (function() { | ||||
|     } | ||||
|  | ||||
|     function nodeMouseUp(d) { | ||||
|         if (mouse_mode === RED.state.SELECTING_NODE) { | ||||
|             d3.event.stopPropagation(); | ||||
|             return; | ||||
|         } | ||||
|         if (dblClickPrimed && mousedown_node == d && clickElapsed > 0 && clickElapsed < 750) { | ||||
|             mouse_mode = RED.state.DEFAULT; | ||||
|             if (d.type != "subflow") { | ||||
| @@ -2217,6 +2288,32 @@ RED.view = (function() { | ||||
|         } else if (mouse_mode == RED.state.QUICK_JOINING) { | ||||
|             d3.event.stopPropagation(); | ||||
|             return; | ||||
|         } else if (mouse_mode === RED.state.SELECTING_NODE) { | ||||
|             d3.event.stopPropagation(); | ||||
|             if (selectNodesOptions.single) { | ||||
|                 selectNodesOptions.done(d); | ||||
|                 return; | ||||
|             } | ||||
|             if (d.selected) { | ||||
|                 d.selected = false; | ||||
|                 for (i=0;i<moving_set.length;i+=1) { | ||||
|                     if (moving_set[i].n === d) { | ||||
|                         moving_set.splice(i,1); | ||||
|                         break; | ||||
|                     } | ||||
|                 } | ||||
|             } else { | ||||
|                 if (!selectNodesOptions.filter || selectNodesOptions.filter(d)) { | ||||
|                     d.selected = true; | ||||
|                     moving_set.push({n:d}); | ||||
|                 } | ||||
|             } | ||||
|             d.dirty = true; | ||||
|             redraw(); | ||||
|             // if (selectNodesOptions && selectNodesOptions.onselect) { | ||||
|             //     selectNodesOptions.onselect(moving_set.map(function(n) { return n.n;})) | ||||
|             // } | ||||
|             return; | ||||
|         } | ||||
|         mousedown_node = d; | ||||
|         var now = Date.now(); | ||||
| @@ -2281,7 +2378,7 @@ RED.view = (function() { | ||||
|     function isButtonEnabled(d) { | ||||
|         var buttonEnabled = true; | ||||
|         var ws = RED.nodes.workspace(RED.workspaces.active()); | ||||
|         if (ws && !ws.disabled) { | ||||
|         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); | ||||
| @@ -2296,9 +2393,13 @@ RED.view = (function() { | ||||
|     } | ||||
|  | ||||
|     function nodeButtonClicked(d) { | ||||
|         if (mouse_mode === RED.state.SELECTING_NODE) { | ||||
|             d3.event.stopPropagation(); | ||||
|             return; | ||||
|         } | ||||
|         var activeWorkspace = RED.workspaces.active(); | ||||
|         var ws = RED.nodes.workspace(activeWorkspace); | ||||
|         if (ws && !ws.disabled) { | ||||
|         if (ws && !ws.disabled && !d.d) { | ||||
|             if (d._def.button.toggle) { | ||||
|                 d[d._def.button.toggle] = !d[d._def.button.toggle]; | ||||
|                 d.dirty = true; | ||||
| @@ -2362,14 +2463,22 @@ RED.view = (function() { | ||||
|                 .attr("class","red-ui-flow-node-icon") | ||||
|                 .attr("x",0) | ||||
|                 .attr("width","30") | ||||
|                 .attr("height","30"); | ||||
|                 .attr("height","30") | ||||
|                 .style("display","none"); | ||||
|  | ||||
|             var img = new Image(); | ||||
|             img.src = iconUrl; | ||||
|             img.onload = function() { | ||||
|                 icon.attr("width",Math.min(img.width,30)); | ||||
|                 icon.attr("height",Math.min(img.height,30)); | ||||
|                 icon.attr("x",15-Math.min(img.width,30)/2); | ||||
|                 var largestEdge = Math.max(img.width,img.height); | ||||
|                 var scaleFactor = 1; | ||||
|                 if (largestEdge > 30) { | ||||
|                     scaleFactor = 30/largestEdge; | ||||
|                 } | ||||
|                 var width = img.width * scaleFactor; | ||||
|                 var height = img.height * scaleFactor; | ||||
|                 icon.attr("width",width); | ||||
|                 icon.attr("height",height); | ||||
|                 icon.attr("x",15-width/2); | ||||
|                 icon.attr("xlink:href",iconUrl); | ||||
|                 icon.style("display",null); | ||||
|                 //if ("right" == d._def.align) { | ||||
| @@ -2522,7 +2631,7 @@ RED.view = (function() { | ||||
|                 subflowOutputs.each(function(d,i) { | ||||
|                     if (d.dirty) { | ||||
|                         var output = d3.select(this); | ||||
|                         output.selectAll(".red-ui-flow-subflow-port").classed("red-ui-flow-node-selected",function(d) { return d.selected; }) | ||||
|                         output.classed("red-ui-flow-node-selected",function(d) { return d.selected; }) | ||||
|                         output.selectAll(".red-ui-flow-port-index").text(function(d){ return d.i+1}); | ||||
|                         output.attr("transform", function(d) { return "translate(" + (d.x-d.w/2) + "," + (d.y-d.h/2) + ")"; }); | ||||
|                         dirtyNodes[d.id] = d; | ||||
| @@ -2532,7 +2641,7 @@ RED.view = (function() { | ||||
|                 subflowInputs.each(function(d,i) { | ||||
|                     if (d.dirty) { | ||||
|                         var input = d3.select(this); | ||||
|                         input.selectAll(".red-ui-flow-subflow-port").classed("red-ui-flow-node-selected",function(d) { return d.selected; }) | ||||
|                         input.classed("red-ui-flow-node-selected",function(d) { return d.selected; }) | ||||
|                         input.attr("transform", function(d) { return "translate(" + (d.x-d.w/2) + "," + (d.y-d.h/2) + ")"; }); | ||||
|                         dirtyNodes[d.id] = d; | ||||
|                         d.dirty = false; | ||||
| @@ -2541,7 +2650,7 @@ RED.view = (function() { | ||||
|                 subflowStatus.each(function(d,i) { | ||||
|                     if (d.dirty) { | ||||
|                         var output = d3.select(this); | ||||
|                         output.selectAll(".red-ui-flow-subflow-port").classed("red-ui-flow-node-selected",function(d) { return d.selected; }) | ||||
|                         output.classed("red-ui-flow-node-selected",function(d) { return d.selected; }) | ||||
|                         output.selectAll(".red-ui-flow-port-index").text(function(d){ return d.i+1}); | ||||
|                         output.attr("transform", function(d) { return "translate(" + (d.x-d.w/2) + "," + (d.y-d.h/2) + ")"; }); | ||||
|                         dirtyNodes[d.id] = d; | ||||
| @@ -2569,10 +2678,12 @@ RED.view = (function() { | ||||
|                     var hideLabel = d.hasOwnProperty('l')?!d.l : isLink; | ||||
|                     node.attr("id",d.id); | ||||
|                     var l = RED.utils.getNodeLabel(d); | ||||
|                     if (hideLabel) { | ||||
|                         d.w = node_height; | ||||
|                     } else { | ||||
|                         d.w = Math.max(node_width,20*(Math.ceil((calculateTextWidth(l, "red-ui-flow-node-label", 50)+(d._def.inputs>0?7:0))/20)) ); | ||||
|                     if (d.resize || d.w === undefined) { | ||||
|                         if (hideLabel) { | ||||
|                             d.w = node_height; | ||||
|                         } else { | ||||
|                             d.w = Math.max(node_width,20*(Math.ceil((calculateTextWidth(l, "red-ui-flow-node-label", 50)+(d._def.inputs>0?7:0))/20)) ); | ||||
|                         } | ||||
|                     } | ||||
|                     d.h = Math.max(node_height,(d.outputs||0) * 15); | ||||
|  | ||||
| @@ -2649,9 +2760,14 @@ RED.view = (function() { | ||||
|                             nodeMouseUp.call(this,d); | ||||
|                         }) | ||||
|                         .on("mouseover",function(d) { | ||||
|                             if (mouse_mode === 0) { | ||||
|                                 var nodeBody = d3.select(this); | ||||
|                                 nodeBody.classed("node_hovered",true); | ||||
|                             if (mouse_mode === 0 || mouse_mode === RED.state.SELECTING_NODE) { | ||||
|                                 if (mouse_mode === RED.state.SELECTING_NODE && selectNodesOptions && selectNodesOptions.filter) { | ||||
|                                     if (selectNodesOptions.filter(d)) { | ||||
|                                         node.classed("red-ui-flow-node-hovered",true); | ||||
|                                     } | ||||
|                                 } else { | ||||
|                                     node.classed("red-ui-flow-node-hovered",true); | ||||
|                                 } | ||||
|                                 clearTimeout(portLabelHoverTimeout); | ||||
|                                 if (d.hasOwnProperty('l')?!d.l : (d.type === "link in" || d.type === "link out")) { | ||||
|                                     portLabelHoverTimeout = setTimeout(function() { | ||||
| @@ -2693,8 +2809,7 @@ RED.view = (function() { | ||||
|                             } | ||||
|                         }) | ||||
|                         .on("mouseout",function(d) { | ||||
|                             var nodeBody = d3.select(this); | ||||
|                             nodeBody.classed("node_hovered",false); | ||||
|                             node.classed("red-ui-flow-node-hovered",false); | ||||
|                             clearTimeout(portLabelHoverTimeout); | ||||
|                             if (portLabelHover) { | ||||
|                                 portLabelHover.remove(); | ||||
| @@ -2824,15 +2939,16 @@ RED.view = (function() { | ||||
|                             d.resize = false; | ||||
|                         } | ||||
|                         var thisNode = d3.select(this); | ||||
|                         thisNode.classed("red-ui-flow-node-disabled", function(d) { return d.d === true}); | ||||
|                         thisNode.classed("red-ui-flow-subflow",function(d) { return activeSubflow != null; }) | ||||
|  | ||||
|                         //thisNode.selectAll(".centerDot").attr({"cx":function(d) { return d.w/2;},"cy":function(d){return d.h/2}}); | ||||
|                         thisNode.attr("transform", function(d) { return "translate(" + (d.x-d.w/2) + "," + (d.y-d.h/2) + ")"; }); | ||||
|                         if (mouse_mode != RED.state.MOVING_ACTIVE) { | ||||
|                             thisNode.classed("red-ui-flow-node-selected",function(d) { return d.selected }) | ||||
|                             thisNode.selectAll(".red-ui-flow-node") | ||||
|                                 .attr("width",function(d){return d.w}) | ||||
|                                 .attr("height",function(d){return d.h}) | ||||
|                                 .classed("red-ui-flow-node-selected",function(d) { return d.selected; }) | ||||
|                                 .classed("red-ui-flow-node-highlighted",function(d) { return d.highlighted; }) | ||||
|                             ; | ||||
|                             if ((!d._def.align && d.inputs !== 0 && d.outputs === 0) || "right" === d._def.align) { | ||||
| @@ -3048,7 +3164,7 @@ RED.view = (function() { | ||||
|                                 } else { | ||||
|                                     thisNode.selectAll(".red-ui-flow-node-status-group").attr("transform","translate(3,"+(d.h+3)+")"); | ||||
|                                     var statusClass = "red-ui-flow-node-status-"+(d.status.shape||"dot")+"-"+d.status.fill; | ||||
|                                     thisNode.selectAll(".red-ui-flow-node-status").attr("class","red-ui-flow-node-status "+statusClass); | ||||
|                                     thisNode.selectAll(".red-ui-flow-node-status").style("display","inline").attr("class","red-ui-flow-node-status "+statusClass); | ||||
|                                 } | ||||
|                                 if (d.status.text) { | ||||
|                                     thisNode.selectAll(".red-ui-flow-node-status-label").text(d.status.text); | ||||
| @@ -3077,6 +3193,10 @@ RED.view = (function() { | ||||
|                 l.append("svg:path").attr("class","red-ui-flow-link-background red-ui-flow-link-path") | ||||
|                    .classed("red-ui-flow-link-link", function(d) { return d.link }) | ||||
|                    .on("mousedown",function(d) { | ||||
|                        if (mouse_mode === RED.state.SELECTING_NODE) { | ||||
|                            d3.event.stopPropagation(); | ||||
|                            return; | ||||
|                        } | ||||
|                         mousedown_link = d; | ||||
|                         clearSelection(); | ||||
|                         selected_link = mousedown_link; | ||||
| @@ -3086,6 +3206,10 @@ RED.view = (function() { | ||||
|                         d3.event.stopPropagation(); | ||||
|                     }) | ||||
|                     .on("touchstart",function(d) { | ||||
|                         if (mouse_mode === RED.state.SELECTING_NODE) { | ||||
|                             d3.event.stopPropagation(); | ||||
|                             return; | ||||
|                         } | ||||
|                         mousedown_link = d; | ||||
|                         clearSelection(); | ||||
|                         selected_link = mousedown_link; | ||||
| @@ -3135,6 +3259,7 @@ RED.view = (function() { | ||||
|                         } | ||||
|                         return path; | ||||
|                     }); | ||||
|                     link.classed("red-ui-flow-node-disabled", function(d) { return d.source.d || d.target.d; }); | ||||
|                 } | ||||
|             }) | ||||
|  | ||||
| @@ -3301,6 +3426,9 @@ RED.view = (function() { | ||||
|      *  - attached to mouse for placing - "IMPORT_DRAGGING" | ||||
|      */ | ||||
|     function importNodes(newNodesStr,addNewFlow,touchImport) { | ||||
|         if (mouse_mode === RED.state.SELECTING_NODE) { | ||||
|             return; | ||||
|         } | ||||
|         try { | ||||
|             var activeSubflowChanged; | ||||
|             if (activeSubflow) { | ||||
| @@ -3462,6 +3590,48 @@ RED.view = (function() { | ||||
|         //TODO: subscribe/unsubscribe here | ||||
|         redraw(); | ||||
|     } | ||||
|     function setSelectedNodeState(isDisabled) { | ||||
|         if (mouse_mode === RED.state.SELECTING_NODE) { | ||||
|             return; | ||||
|         } | ||||
|         var workspaceSelection = RED.workspaces.selection(); | ||||
|         var changed = false; | ||||
|         if (workspaceSelection.length > 0) { | ||||
|             // TODO: toggle workspace state | ||||
|         } else if (moving_set.length > 0) { | ||||
|             var historyEvents = []; | ||||
|             for (var i=0;i<moving_set.length;i++) { | ||||
|                 var node = moving_set[i].n; | ||||
|                 if (isDisabled != node.d) { | ||||
|                     historyEvents.push({ | ||||
|                         t: "edit", | ||||
|                         node: node, | ||||
|                         changed: node.changed, | ||||
|                         changes: { | ||||
|                             d: node.d | ||||
|                         } | ||||
|                     }); | ||||
|                     if (isDisabled) { | ||||
|                         node.d = true; | ||||
|                     } else { | ||||
|                         delete node.d; | ||||
|                     } | ||||
|                     node.dirty = true; | ||||
|                     node.changed = true; | ||||
|                 } | ||||
|             } | ||||
|             if (historyEvents.length > 0) { | ||||
|                 RED.history.push({ | ||||
|                     t:"multi", | ||||
|                     events: historyEvents, | ||||
|                     dirty:RED.nodes.dirty() | ||||
|                 }) | ||||
|                 RED.nodes.dirty(true) | ||||
|             } | ||||
|         } | ||||
|         RED.view.redraw(); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     return { | ||||
|         init: init, | ||||
| @@ -3532,12 +3702,12 @@ RED.view = (function() { | ||||
|                     node.dirty = true; | ||||
|                     RED.workspaces.show(node.z); | ||||
|  | ||||
|                     var screenSize = [chart.width(),chart.height()]; | ||||
|                     var scrollPos = [chart.scrollLeft(),chart.scrollTop()]; | ||||
|                     var screenSize = [chart.width()/scaleFactor,chart.height()/scaleFactor]; | ||||
|                     var scrollPos = [chart.scrollLeft()/scaleFactor,chart.scrollTop()/scaleFactor]; | ||||
|  | ||||
|                     if (node.x < scrollPos[0] || node.y < scrollPos[1] || node.x > screenSize[0]+scrollPos[0] || node.y > screenSize[1]+scrollPos[1]) { | ||||
|                         var deltaX = '-='+((scrollPos[0] - node.x) + screenSize[0]/2); | ||||
|                         var deltaY = '-='+((scrollPos[1] - node.y) + screenSize[1]/2); | ||||
|                         var deltaX = '-='+(((scrollPos[0] - node.x) + screenSize[0]/2)*scaleFactor); | ||||
|                         var deltaY = '-='+(((scrollPos[1] - node.y) + screenSize[1]/2)*scaleFactor); | ||||
|                         chart.animate({ | ||||
|                             scrollLeft: deltaX, | ||||
|                             scrollTop: deltaY | ||||
| @@ -3576,6 +3746,70 @@ RED.view = (function() { | ||||
|         }, | ||||
|         getActiveNodes: function() { | ||||
|             return activeNodes; | ||||
|         }, | ||||
|         selectNodes: function(options) { | ||||
|             $("#red-ui-workspace-tabs-shade").show(); | ||||
|             $("#red-ui-palette-shade").show(); | ||||
|             $("#red-ui-sidebar-shade").show(); | ||||
|             $("#red-ui-header-shade").show(); | ||||
|             $("#red-ui-workspace").addClass("red-ui-workspace-select-mode"); | ||||
|  | ||||
|             mouse_mode = RED.state.SELECTING_NODE; | ||||
|             clearSelection(); | ||||
|             if (options.selected) { | ||||
|                 console.log(options.selected); | ||||
|                 options.selected.forEach(function(id) { | ||||
|                     var n = RED.nodes.node(id); | ||||
|                     if (n) { | ||||
|                         n.selected = true; | ||||
|                         n.dirty = true; | ||||
|                         moving_set.push({n:n}); | ||||
|                     } | ||||
|                 }) | ||||
|             } | ||||
|             redraw(); | ||||
|             selectNodesOptions = options||{}; | ||||
|             var closeNotification = function() { | ||||
|                 clearSelection(); | ||||
|                 $("#red-ui-workspace-tabs-shade").hide(); | ||||
|                 $("#red-ui-palette-shade").hide(); | ||||
|                 $("#red-ui-sidebar-shade").hide(); | ||||
|                 $("#red-ui-header-shade").hide(); | ||||
|                 $("#red-ui-workspace").removeClass("red-ui-workspace-select-mode"); | ||||
|                 resetMouseVars(); | ||||
|                 notification.close(); | ||||
|             } | ||||
|             selectNodesOptions.done = function(selection) { | ||||
|                 closeNotification(); | ||||
|                 if (selectNodesOptions.onselect) { | ||||
|                     selectNodesOptions.onselect(selection); | ||||
|                 } | ||||
|             } | ||||
|             var buttons = [{ | ||||
|                 text: RED._("common.label.cancel"), | ||||
|                 click: function(e) { | ||||
|                     closeNotification(); | ||||
|                     if (selectNodesOptions.oncancel) { | ||||
|                         selectNodesOptions.oncancel(); | ||||
|                     } | ||||
|                 } | ||||
|             }]; | ||||
|             if (!selectNodesOptions.single) { | ||||
|                 buttons.push({ | ||||
|                     text: RED._("common.label.done"), | ||||
|                     class: "primary", | ||||
|                     click: function(e) { | ||||
|                         var selection = moving_set.map(function(n) { return n.n;}); | ||||
|                         selectNodesOptions.done(selection); | ||||
|                     } | ||||
|                 }); | ||||
|             } | ||||
|             var notification = RED.notify(selectNodesOptions.prompt || RED._("workspace.selectNodes"),{ | ||||
|                 modal: false, | ||||
|                 fixed: true, | ||||
|                 type: "compact", | ||||
|                 buttons: buttons | ||||
|             }) | ||||
|         } | ||||
|     }; | ||||
| })(); | ||||
|   | ||||
| @@ -60,6 +60,13 @@ RED.workspaces = (function() { | ||||
|  | ||||
|     function showEditWorkspaceDialog(id) { | ||||
|         var workspace = RED.nodes.workspace(id); | ||||
|         if (!workspace) { | ||||
|             var subflow = RED.nodes.subflow(id); | ||||
|             if (subflow) { | ||||
|                 RED.editor.editSubflow(subflow); | ||||
|             } | ||||
|             return; | ||||
|         } | ||||
|         RED.view.state(RED.state.EDITING); | ||||
|         var tabflowEditor; | ||||
|         var trayOptions = { | ||||
| @@ -158,9 +165,8 @@ RED.workspaces = (function() { | ||||
|                 '</div>').appendTo(dialogForm); | ||||
|  | ||||
|                 $('<div class="form-row">'+ | ||||
|                     '<label for="node-input-disabled-btn" data-i18n="editor:workspace.status"></label>'+ | ||||
|                     '<button type="button" id="node-input-disabled-btn" class="red-ui-button"><i class="fa fa-toggle-on"></i> <span id="node-input-disabled-label"></span></button> '+ | ||||
|                     '<input type="checkbox" id="node-input-disabled" style="display: none;"/>'+ | ||||
|                     '<label for="node-input-disabled" data-i18n="editor:workspace.status"></label>'+ | ||||
|                     '<input type="checkbox" id="node-input-disabled"/>'+ | ||||
|                 '</div>').appendTo(dialogForm); | ||||
|  | ||||
|                 var row = $('<div class="form-row node-text-editor-row">'+ | ||||
| @@ -190,33 +196,16 @@ RED.workspaces = (function() { | ||||
|                     }) | ||||
|                 }); | ||||
|  | ||||
|                 dialogForm.find('#node-input-disabled-btn').on("click",function(e) { | ||||
|                     var i = $(this).find("i"); | ||||
|                     if (i.hasClass('fa-toggle-off')) { | ||||
|                         i.addClass('fa-toggle-on'); | ||||
|                         i.removeClass('fa-toggle-off'); | ||||
|                         $("#node-input-disabled").prop("checked",false); | ||||
|                         $("#node-input-disabled-label").text(RED._("editor:workspace.enabled")); | ||||
|                     } else { | ||||
|                         i.addClass('fa-toggle-off'); | ||||
|                         i.removeClass('fa-toggle-on'); | ||||
|                         $("#node-input-disabled").prop("checked",true); | ||||
|                         $("#node-input-disabled-label").text(RED._("editor:workspace.disabled")); | ||||
|                     } | ||||
|                 }) | ||||
|  | ||||
|                 if (workspace.hasOwnProperty("disabled")) { | ||||
|                     $("#node-input-disabled").prop("checked",workspace.disabled); | ||||
|                     if (workspace.disabled) { | ||||
|                         dialogForm.find("#node-input-disabled-btn i").removeClass('fa-toggle-on').addClass('fa-toggle-off'); | ||||
|                         $("#node-input-disabled-label").text(RED._("editor:workspace.disabled")); | ||||
|                     } else { | ||||
|                         $("#node-input-disabled-label").text(RED._("editor:workspace.enabled")); | ||||
|                     } | ||||
|                 } else { | ||||
|                     workspace.disabled = false; | ||||
|                     $("#node-input-disabled-label").text(RED._("editor:workspace.enabled")); | ||||
|                 } | ||||
|                 $("#node-input-disabled").toggleButton({ | ||||
|                     enabledIcon: "fa-circle-thin", | ||||
|                     disabledIcon: "fa-ban", | ||||
|                     invertState: true | ||||
|                 }) | ||||
|  | ||||
|                 $('<input type="text" style="display: none;" />').prependTo(dialogForm); | ||||
|                 dialogForm.on("submit", function(e) { e.preventDefault();}); | ||||
| @@ -328,6 +317,7 @@ RED.workspaces = (function() { | ||||
|  | ||||
|     function init() { | ||||
|         $('<ul id="red-ui-workspace-tabs"></ul>').appendTo("#red-ui-workspace"); | ||||
|         $('<div id="red-ui-workspace-tabs-shade" class="hide"></div>').appendTo("#red-ui-workspace"); | ||||
|         $('<div id="red-ui-workspace-chart" tabindex="1"></div>').appendTo("#red-ui-workspace"); | ||||
|         $('<div id="red-ui-workspace-toolbar"></div>').appendTo("#red-ui-workspace"); | ||||
|         $('<div id="red-ui-workspace-footer" class="red-ui-component-footer"></div>').appendTo("#red-ui-workspace"); | ||||
| @@ -351,6 +341,8 @@ RED.workspaces = (function() { | ||||
|         RED.actions.add("core:add-flow",function(opts) { addWorkspace(undefined,undefined,opts?opts.index:undefined)}); | ||||
|         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:list-flows",function() { | ||||
|             RED.actions.invoke("core:search","type:tab "); | ||||
| @@ -363,6 +355,48 @@ RED.workspaces = (function() { | ||||
|         showEditWorkspaceDialog(id||activeWorkspace); | ||||
|     } | ||||
|  | ||||
|     function enableWorkspace(id) { | ||||
|         setWorkspaceState(id,false); | ||||
|     } | ||||
|     function disableWorkspace(id) { | ||||
|         setWorkspaceState(id,true); | ||||
|     } | ||||
|     function setWorkspaceState(id,disabled) { | ||||
|         var workspace = RED.nodes.workspace(id||activeWorkspace); | ||||
|         if (!workspace) { | ||||
|             return; | ||||
|         } | ||||
|         if (workspace.disabled !== disabled) { | ||||
|             var changes = { disabled: workspace.disabled }; | ||||
|             workspace.disabled = disabled; | ||||
|             $("#red-ui-tab-"+(workspace.id.replace(".","-"))).toggleClass('red-ui-workspace-disabled',!!workspace.disabled); | ||||
|             $("#red-ui-workspace").toggleClass("red-ui-workspace-disabled",!!workspace.disabled); | ||||
|             var historyEvent = { | ||||
|                 t: "edit", | ||||
|                 changes:changes, | ||||
|                 node: workspace, | ||||
|                 dirty: RED.nodes.dirty() | ||||
|             } | ||||
|             workspace.changed = true; | ||||
|             RED.history.push(historyEvent); | ||||
|             RED.nodes.dirty(true); | ||||
|             RED.sidebar.config.refresh(); | ||||
|             var selection = RED.view.selection(); | ||||
|             if (!selection.nodes && !selection.links) { | ||||
|                 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) { | ||||
|             deleteWorkspace(RED.nodes.workspace(activeWorkspace)); | ||||
| @@ -405,7 +439,7 @@ RED.workspaces = (function() { | ||||
|             if (!workspace_tabs.contains(id)) { | ||||
|                 var sf = RED.nodes.subflow(id); | ||||
|                 if (sf) { | ||||
|                     addWorkspace({type:"subflow",id:id,icon:"red/images/subflow_tab.png",label:sf.name, closeable: true}); | ||||
|                     addWorkspace({type:"subflow",id:id,icon:"red/images/subflow_tab.svg",label:sf.name, closeable: true}); | ||||
|                 } else { | ||||
|                     return; | ||||
|                 } | ||||
| @@ -426,6 +460,8 @@ RED.workspaces = (function() { | ||||
|         }, | ||||
|         resize: function() { | ||||
|             workspace_tabs.resize(); | ||||
|         } | ||||
|         }, | ||||
|         enable: enableWorkspace, | ||||
|         disable: disableWorkspace | ||||
|     } | ||||
| })(); | ||||
|   | ||||
| @@ -34,10 +34,10 @@ $shadow: rgba(0, 0, 0, 0.2); | ||||
| $primary-text-color: #555;//#0f0; | ||||
| // UI control label text | ||||
| $secondary-text-color: #888;//#00f; | ||||
| $secondary-text-color-focus: #999;//#009; | ||||
| $secondary-text-color-focus: #666;//#009; | ||||
| $secondary-text-color-hover: #666;//#006; | ||||
| $secondary-text-color-active: #666;//#006; | ||||
| $secondary-text-color-selected: #AAA;//#00A; | ||||
| $secondary-text-color-selected: #666;//#00A; | ||||
| $secondary-text-color-inactive: #666;//#006; | ||||
| $secondary-text-color-disabled: #bbb;//#00C; | ||||
| $secondary-text-color-disabled-active: #999;//#009; | ||||
| @@ -90,6 +90,7 @@ $event-log-selection-background: #999; | ||||
|  | ||||
|  | ||||
| $list-item-color: $primary-text-color; | ||||
| $list-item-secondary-color: $secondary-text-color; | ||||
| $list-item-background: $secondary-background; | ||||
| $list-item-background-disabled: $secondary-background-inactive; | ||||
| $list-item-background-hover: $secondary-background-hover; | ||||
| @@ -185,6 +186,7 @@ $view-lasso-stroke: #ff7f0e; | ||||
| $view-lasso-fill: rgba(20,125,255,0.1); | ||||
|  | ||||
| $view-background: $secondary-background; | ||||
| $view-select-mode-background: $secondary-background-selected; | ||||
| $view-grid-color: #eee; | ||||
|  | ||||
| $node-label-color: #333; | ||||
| @@ -222,10 +224,10 @@ $node-status-colors: ( | ||||
| $node-selected-color: #ff7f0e; | ||||
| $port-selected-color: #ff7f0e; | ||||
|  | ||||
| $link-color: #888; | ||||
| $link-link-color: #ccc; | ||||
| $link-color: #999; | ||||
| $link-link-color: #aaa; | ||||
| $link-disabled-color: #ccc; | ||||
| $link-link-active-color: #ff7f0e; | ||||
| $link-subflow-color: #bbb; | ||||
| $link-unknown-color: #f00; | ||||
|  | ||||
| $clipboard-textarea-background: #F3E7E7; | ||||
|   | ||||
| @@ -221,7 +221,7 @@ | ||||
|     padding: 4px 2px 2px; | ||||
|     position: relative; | ||||
|     &.red-ui-debug-msg-row-pinned { | ||||
|         background: $list-item-border-selected; | ||||
|         background: $secondary-background-selected; | ||||
|     } | ||||
| } | ||||
| .red-ui-debug-msg-expandable { | ||||
|   | ||||
| @@ -43,7 +43,8 @@ | ||||
|         overflow: hidden; | ||||
|         background-color: $menuDivider; | ||||
|     } | ||||
|     & > li > a { | ||||
|     & > li > a, | ||||
|     & > li > a:focus { | ||||
|         display: block; | ||||
|         padding: 4px 0 4px 32px; | ||||
|         clear: both; | ||||
| @@ -51,6 +52,7 @@ | ||||
|         line-height: 20px; | ||||
|         color: $menuColor; | ||||
|         white-space: normal !important; | ||||
|         outline: none; | ||||
|     } | ||||
|  | ||||
|     & > .active > a, | ||||
|   | ||||
| @@ -79,15 +79,20 @@ | ||||
| .red-ui-tray-footer { | ||||
|     @include component-footer; | ||||
|     height: 35px; | ||||
|     font-size: 12px !important; | ||||
|     font-size: 14px !important; | ||||
|     line-height: 35px; | ||||
|     vertical-align: middle; | ||||
|  | ||||
|     button { | ||||
|         @include editor-button; | ||||
|         padding: 3px 7px; | ||||
|         font-size: 11px; | ||||
|     button.red-ui-button { | ||||
|         padding: 0px 8px; | ||||
|         height: 26px; | ||||
|         line-height: 26px; | ||||
|         &.toggle:not(.selected) { | ||||
|             color: $workspace-button-color-selected !important; | ||||
|             background: $workspace-button-background-active; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     .red-ui-tray-footer-left { | ||||
|         display:inline-block; | ||||
|         margin-right: 20px; | ||||
| @@ -461,3 +466,116 @@ button.red-ui-button-small | ||||
|         margin: 2px; | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| .red-ui-editor input.red-ui-editor-type-json-editor-key { | ||||
|     width: 150px; | ||||
| } | ||||
|  | ||||
| .red-ui-editor-type-json-editor { | ||||
|     height: calc(100% - 10px); | ||||
|     .red-ui-treeList-container { | ||||
|         background: $secondary-background; | ||||
|     } | ||||
|     .red-ui-treeList-label { | ||||
|         padding-top: 0; | ||||
|         padding-bottom: 0; | ||||
|         white-space: nowrap; | ||||
|         min-height: 35px; | ||||
|         .red-ui-treeList-icon:before { | ||||
|             content:''; | ||||
|             display: inline-block; | ||||
|             height: 35px; | ||||
|             vertical-align: middle; | ||||
|         } | ||||
|         > span, > span > span { | ||||
|             vertical-align: middle; | ||||
|         } | ||||
|         &:hover, &:hover .red-ui-treeList-sublabel-text { | ||||
|             background: $secondary-background-disabled; | ||||
|             .red-ui-editor-type-json-editor-item-gutter { | ||||
|                 > span, > button { | ||||
|                     display: inline-block; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         &.selected { | ||||
|             .red-ui-editor-type-json-editor-item-gutter { | ||||
|                 background: $secondary-background-hover; | ||||
|             } | ||||
|             &:hover { | ||||
|                 .red-ui-editor-type-json-editor-item-gutter { | ||||
|                     background: $secondary-background-selected; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         &.red-ui-editor-type-json-root-node { | ||||
|             .red-ui-editor-type-json-editor-item-gutter { | ||||
|                 > span, > button { | ||||
|                     display: inline-block; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| .red-ui-editor-type-json-editor-controls { | ||||
|     height: 34px; | ||||
|     line-height: 34px; | ||||
|     display: none; | ||||
| } | ||||
| .red-ui-editor-type-json-editor-key { | ||||
|     width: 100px; | ||||
| } | ||||
| .red-ui-editor-type-json-editor-label { | ||||
|     display: inline-block; | ||||
|     white-space: pre-wrap; | ||||
| } | ||||
| .red-ui-editor-type-json-editor-label-value { | ||||
|     min-width: 200px; | ||||
| } | ||||
| .red-ui-editor-type-json-editor-label-value, | ||||
| .red-ui-editor-type-json-editor-label-key { | ||||
|     display: inline-block; | ||||
|     box-sizing: border-box; | ||||
|     min-height: 34px; | ||||
|     line-height: 30px; | ||||
|     padding: 0 2px; | ||||
|     border: 2px solid rgba(0,0,0,0); | ||||
|     border-radius: 3px; | ||||
|     &:not(.red-ui-editor-type-json-editor-label-array-key):hover { | ||||
|         border-color: $list-item-background-hover; | ||||
|         border-style: dashed; | ||||
|     } | ||||
| } | ||||
| .red-ui-editor-type-json-editor-item-gutter { | ||||
|     width: 48px; | ||||
|     padding-left: 4px; | ||||
|  | ||||
|     height: 100%; | ||||
|     line-height: 35px; | ||||
|     color: $tertiary-text-color; | ||||
|     background: $secondary-background-disabled; | ||||
|     > span { | ||||
|         display: inline-block; | ||||
|         height: 35px; | ||||
|         line-height: 35px; | ||||
|         width: 20px; | ||||
|         text-align:center; | ||||
|     } | ||||
|     > span, > button { | ||||
|         display: none; | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| .red-ui-editor-type-json-editor-item-handle { | ||||
|     cursor: move; | ||||
| } | ||||
| .red-ui-editor-type-json-tab-content { | ||||
|     position: relative; | ||||
|     height: calc(100% - 40px); | ||||
| } | ||||
|  | ||||
| button.red-ui-toggleButton.toggle { | ||||
|     text-align: left; | ||||
| } | ||||
|   | ||||
| @@ -54,6 +54,23 @@ | ||||
|     cursor: move; | ||||
|     stroke-width: 1; | ||||
| } | ||||
| .red-ui-workspace-select-mode { | ||||
|     g.red-ui-flow-node.red-ui-flow-node-hovered * { | ||||
|         cursor: pointer !important | ||||
|     } | ||||
|     g.red-ui-flow-node, g.red-ui-flow-link { | ||||
|         opacity: 0.5; | ||||
|     } | ||||
|     g.red-ui-flow-node.red-ui-flow-node-hovered:not(.red-ui-flow-node-selected) { | ||||
|         opacity: 0.9; | ||||
|         .red-ui-flow-node { | ||||
|             stroke-width: 2; | ||||
|             stroke: $node-selected-color !important; | ||||
|             stroke-dasharray: 10, 4; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| .red-ui-flow-node-unknown { | ||||
|     stroke-dasharray:10,4; | ||||
|     stroke: $node-border-unknown; | ||||
| @@ -115,32 +132,56 @@ | ||||
|     stroke-linecap: round; | ||||
| } | ||||
|  | ||||
| .red-ui-flow-node-selected { | ||||
|     stroke-width: 2; | ||||
|     stroke: $node-selected-color !important; | ||||
| g.red-ui-flow-node-selected { | ||||
|     .red-ui-workspace-select-mode & { | ||||
|         opacity: 1; | ||||
|     } | ||||
|     .red-ui-flow-node,.red-ui-flow-subflow-port { | ||||
|         stroke-width: 2; | ||||
|         stroke: $node-selected-color !important; | ||||
|     } | ||||
| } | ||||
| .red-ui-flow-node-highlighted { | ||||
|     border-color: $node-selected-color !important; | ||||
|     border-style: dashed !important; | ||||
|     stroke: $node-selected-color; | ||||
|     stroke-width: 2; | ||||
|     stroke-dasharray: 10, 4; | ||||
|     stroke-dasharray: 8, 3; | ||||
| } | ||||
|  | ||||
| .red-ui-flow-subflow .red-ui-flow-node { | ||||
|     stroke-dasharray:8, 3; | ||||
| } | ||||
| .red-ui-workspace-disabled { | ||||
|     .red-ui-flow-link-line { | ||||
|         stroke-dasharray: 10,5 !important; | ||||
|         stroke-width: 2 !important; | ||||
|         stroke: $link-subflow-color; | ||||
|     } | ||||
|     .red-ui-flow-node { | ||||
|         stroke-dasharray: 10,4; | ||||
|     } | ||||
| } | ||||
|  | ||||
| .red-ui-workspace-disabled { | ||||
|     .red-ui-flow-node { | ||||
|         stroke-dasharray: 8, 3; | ||||
|         fill-opacity: 0.5; | ||||
|     } | ||||
|     .red-ui-flow-link-line { | ||||
|         stroke-dasharray: 10,8 !important; | ||||
|         stroke-width: 2 !important; | ||||
|         stroke: $link-disabled-color; | ||||
|     } | ||||
|     .red-ui-flow-port { | ||||
|         fill-opacity: 1; | ||||
|         stroke-dasharray: none; | ||||
|     } | ||||
| } | ||||
| .red-ui-flow-node-disabled { | ||||
|     &.red-ui-flow-node, .red-ui-flow-node { | ||||
|         stroke-dasharray: 8, 3; | ||||
|         fill-opacity: 0.5; | ||||
|     } | ||||
|     &.red-ui-flow-link-line { | ||||
|         stroke-dasharray: 10,8 !important; | ||||
|         stroke-width: 2 !important; | ||||
|         stroke: $link-disabled-color; | ||||
|     } | ||||
|     .red-ui-flow-port { | ||||
|         fill-opacity: 1; | ||||
|         stroke-dasharray: none; | ||||
|     } | ||||
| } | ||||
| @each $current-color in red green yellow blue grey { | ||||
|     .red-ui-flow-node-status-dot-#{$current-color} { | ||||
|         fill: map-get($node-status-colors,$current-color); | ||||
| @@ -166,7 +207,6 @@ | ||||
| } | ||||
|  | ||||
| .red-ui-flow-subflow-port { | ||||
|     stroke-dasharray: 5,5; | ||||
|     fill: $node-background-placeholder; | ||||
|     stroke: $node-border; | ||||
| } | ||||
| @@ -186,12 +226,14 @@ | ||||
| } | ||||
| .red-ui-flow-link-link { | ||||
|     stroke-width: 2; | ||||
|     stroke-dasharray: 10,5; | ||||
|     stroke: $link-link-color; | ||||
|     fill: none; | ||||
|     stroke-dasharray: 15,2; | ||||
|     // pointer-events: none; | ||||
|     stroke-dasharray: 25,4; | ||||
| } | ||||
| .red-ui-flow-link-off-flow { | ||||
|     stroke-width: 2; | ||||
| } | ||||
|  | ||||
| .red-ui-flow-link-port { | ||||
|     fill: $node-link-port-background; | ||||
|     stroke: $link-link-color; | ||||
| @@ -203,11 +245,6 @@ | ||||
| .red-ui-flow-link-group:hover { | ||||
|     cursor: pointer; | ||||
| } | ||||
| .red-ui-flow-subflow-link { | ||||
|     stroke: $link-subflow-color; | ||||
|     stroke-dasharray: 10,5; | ||||
|     stroke-width: 2; | ||||
| } | ||||
|  | ||||
| .red-ui-flow-link-outline { | ||||
|     stroke: $view-background; | ||||
|   | ||||
| @@ -219,19 +219,20 @@ | ||||
|                 text-indent: 0px; | ||||
|             } | ||||
|         } | ||||
|         > li > a:hover, | ||||
|         > li > a:focus, | ||||
|         > li:hover > a, | ||||
|         > li:focus > a { | ||||
|             background: $header-menu-item-hover !important; | ||||
|         } | ||||
|         li.divider { | ||||
|         li.red-ui-menu-divider { | ||||
|             background: $headerMenuItemDivider; | ||||
|             border-bottom-color: $header-menu-item-hover; | ||||
|         } | ||||
|         li.disabled a { | ||||
|             color:  $header-menu-color-disabled; | ||||
|         } | ||||
|         > li.disabled:hover > a, | ||||
|         > li.disabled:focus > a { | ||||
|         > li.disabled > a:hover, | ||||
|         > li.disabled > a:focus { | ||||
|             background: none !important; | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -26,6 +26,10 @@ | ||||
|     box-shadow: none; | ||||
| } | ||||
|  | ||||
| .ui-widget-header { | ||||
|     color: $header-text-color; | ||||
| } | ||||
|  | ||||
| /* jQuery Theme overrides */ | ||||
| .ui-tabs .ui-tabs-panel { | ||||
|     padding: 0px; | ||||
|   | ||||
| @@ -61,7 +61,7 @@ | ||||
|     padding: 0; | ||||
|     background: $form-input-background; | ||||
|     &>div { | ||||
|         height: calc(100% - 20px) | ||||
|         height: 100%; | ||||
|     } | ||||
| } | ||||
| .red-ui-clipboard-dialog-box { | ||||
| @@ -88,14 +88,11 @@ | ||||
|     width: calc(100% - 120px); | ||||
| } | ||||
| #red-ui-clipboard-dialog-export-tab-library-browser { | ||||
|     height: calc(100% - 40px); | ||||
|     margin-bottom: 10px; | ||||
|     height: calc(100% - 60px); | ||||
|     margin-bottom: 13px; | ||||
|     border-bottom: 1px solid $primary-border-color; | ||||
|     box-sizing: border-box; | ||||
| } | ||||
| #red-ui-clipboard-dialog-import-tab-library { | ||||
|     height: 100%; | ||||
| } | ||||
| #red-ui-clipboard-dialog-import-tab-library-browser { | ||||
|     height: 100%; | ||||
|     box-sizing: border-box; | ||||
|   | ||||
| @@ -151,6 +151,9 @@ | ||||
|             margin-bottom: 0; | ||||
|             cursor: default; | ||||
|         } | ||||
|         &:not(.selected) { | ||||
|             margin-top: 1px; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @mixin editor-button { | ||||
| @@ -189,7 +192,7 @@ | ||||
|     right: 0; | ||||
|     height: 25px; | ||||
|     line-height: 25px; | ||||
|     padding: 0 10px; | ||||
|     padding: 0 6px; | ||||
|     user-select: none; | ||||
|  | ||||
|     .button-group:not(:last-child) { | ||||
|   | ||||
| @@ -33,6 +33,9 @@ | ||||
|     border: 1px solid $notification-border-default; | ||||
|     border-left-width: 16px; | ||||
|     overflow: hidden; | ||||
|     .ui-dialog-buttonset { | ||||
|         margin-top: 20px; | ||||
|     } | ||||
| } | ||||
| .red-ui-notification p:first-child { | ||||
|     font-size: 1.1em; | ||||
| @@ -55,6 +58,18 @@ | ||||
|     border-color: $notification-border-error; | ||||
| } | ||||
|  | ||||
| .red-ui-notification-compact { | ||||
|     p { | ||||
|         margin: 0; | ||||
|     } | ||||
|     .ui-dialog-buttonset { | ||||
|         margin-top: 0; | ||||
|         position: absolute; | ||||
|         top: 8px; | ||||
|         right: 10px; | ||||
|     } | ||||
| } | ||||
|  | ||||
| .red-ui-notification-shake-horizontal { | ||||
|     -webkit-animation: red-ui-notification-shake-horizontal 0.3s steps(2, end) both; | ||||
|             animation: red-ui-notification-shake-horizontal 0.3s steps(2, end) both; | ||||
|   | ||||
| @@ -165,7 +165,7 @@ | ||||
|     } | ||||
|  | ||||
| } | ||||
| .red-ui-search-result-description { | ||||
| .red-ui-search-result-node-description { | ||||
|     margin-left: 40px; | ||||
|     margin-right: 5px; | ||||
| } | ||||
| @@ -193,3 +193,14 @@ | ||||
|     font-style: italic; | ||||
|     color: $form-placeholder-color; | ||||
| } | ||||
|  | ||||
| .red-ui-search-result-action { | ||||
|     color: $primary-text-color; | ||||
| } | ||||
| .red-ui-search-result-action-key { | ||||
|     position: absolute; | ||||
|     top: 9px; | ||||
|     right: 0; | ||||
|     margin-right: 10px; | ||||
|     color: $tertiary-text-color; | ||||
| } | ||||
|   | ||||