Compare commits
	
		
			1 Commits
		
	
	
		
			3.0.0-beta
			...
			move-out-s
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 746512b8b8 | 
							
								
								
									
										1
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
								
							
							
						
						| @@ -1 +0,0 @@ | ||||
| /packages/node_modules/** linguist-generated=false | ||||
							
								
								
									
										34
									
								
								.github/ISSUE_TEMPLATE.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,34 @@ | ||||
| <!-- | ||||
| ## Before you hit that Submit button.... | ||||
|  | ||||
| This issue tracker is for problems with the Node-RED runtime, the editor or the core nodes. | ||||
|  | ||||
| If your issue is: | ||||
|   - a general 'how-to' type question, | ||||
|   - a feature request or suggestion for a change, | ||||
|   - or problems with 3rd party (`node-red-contrib-`) nodes | ||||
|  | ||||
| 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. | ||||
|  | ||||
| ## So you have a real issue to raise... | ||||
|  | ||||
| To help us understand the issue, please fill-in as much of the following information as you can: | ||||
| --> | ||||
|  | ||||
| ### What are the steps to reproduce? | ||||
|  | ||||
| ### What happens? | ||||
|  | ||||
| ### What do you expect to happen? | ||||
|  | ||||
| ### Please tell us about your environment: | ||||
|  | ||||
| - [ ] Node-RED version: | ||||
| - [ ] node.js version: | ||||
| - [ ] npm version: | ||||
| - [ ] Platform/OS: | ||||
| - [ ] Browser: | ||||
							
								
								
									
										61
									
								
								.github/ISSUE_TEMPLATE/bug_report.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						| @@ -1,61 +0,0 @@ | ||||
| name: 🐞 Report a bug | ||||
| description: File a bug/issue on the core of Node-RED | ||||
| labels: [needs-triage] | ||||
| body: | ||||
| - type: markdown | ||||
|   attributes: | ||||
|     value: | | ||||
|         This issue tracker is for problems with the Node-RED runtime, the editor or the core nodes. | ||||
|  | ||||
|         If your issue is: | ||||
|           - a general 'how-to' type question, | ||||
|           - a feature request or suggestion for a change, | ||||
|           - or problems with 3rd party (`node-red-contrib-`) nodes | ||||
|  | ||||
|         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. | ||||
|  | ||||
|         To help us understand the issue, please fill-in as much of the following information as you can: | ||||
| - type: textarea | ||||
|   attributes: | ||||
|     label: Current Behavior | ||||
|     description: A clear & concise description of what you're experiencing. | ||||
|   validations: | ||||
|     required: false | ||||
| - type: textarea | ||||
|   attributes: | ||||
|     label: Expected Behavior | ||||
|     description: A clear & concise description of what you expected to happen. | ||||
|   validations: | ||||
|     required: false | ||||
| - type: textarea | ||||
|   attributes: | ||||
|     label: Steps To Reproduce | ||||
|     description: Steps to reproduce the behavior. | ||||
|   validations: | ||||
|     required: false | ||||
| - type: textarea | ||||
|   attributes: | ||||
|     label: Example flow | ||||
|     description: If you have a minimal example flow that demonstrates the issue, share it here. | ||||
|     value: | | ||||
|       ``` | ||||
|       paste your flow here | ||||
|       ``` | ||||
|   validations: | ||||
|     required: false | ||||
| - type: textarea | ||||
|   attributes: | ||||
|     label: Environment | ||||
|     description: Please tell us about your environment. Include any relevant information on how you are running Node-RED. | ||||
|     value: | | ||||
|         - Node-RED version: | ||||
|         - Node.js version: | ||||
|         - npm version: | ||||
|         - Platform/OS: | ||||
|         - Browser: | ||||
|   validations: | ||||
|     required: false | ||||
							
								
								
									
										14
									
								
								.github/ISSUE_TEMPLATE/config.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						| @@ -1,14 +0,0 @@ | ||||
| blank_issues_enabled: true | ||||
| contact_links: | ||||
|   - name: ❓ Questions | ||||
|     url: https://discourse.nodered.org | ||||
|     about: Ask your question on the Node-RED forum | ||||
|   - name: ⭐️ Feature Request | ||||
|     url: https://discourse.nodered.org/c/development/feature-requests | ||||
|     about: Discuss your request with the community | ||||
|   - name: 🗂 Documentation | ||||
|     url: https://nodered.org/docs | ||||
|     about: Go straight to the documentation | ||||
|   - name: 💬 Slack | ||||
|     url: https://nodered.org/slack | ||||
|     about: Chat about the project on our slack team | ||||
							
								
								
									
										2
									
								
								.github/PULL_REQUEST_TEMPLATE.md
									
									
									
									
										vendored
									
									
								
							
							
						
						| @@ -29,6 +29,6 @@ the [forum](https://discourse.nodered.org) or | ||||
| <!-- Put an `x` in the boxes that apply --> | ||||
|  | ||||
| - [ ] I have read the [contribution guidelines](https://github.com/node-red/node-red/blob/master/CONTRIBUTING.md) | ||||
| - [ ] For non-bugfix PRs, I have discussed this change on the forum/slack team. | ||||
| - [ ] For non-bugfix PRs, I have discussed this change on the mailing list/slack team. | ||||
| - [ ] I have run `grunt` to verify the unit tests pass | ||||
| - [ ] I have added suitable unit tests to cover the new/changed functionality | ||||
|   | ||||
							
								
								
									
										29
									
								
								.github/scripts/update-node-red-docker.js
									
									
									
									
										vendored
									
									
								
							
							
						
						| @@ -1,29 +0,0 @@ | ||||
| const fs = require("fs"); | ||||
|  | ||||
| const newVersion = require("../../package.json").version; | ||||
|  | ||||
| if (process.env.GITHUB_REF !== "refs/tags/"+newVersion) { | ||||
|     console.log(`GITHUB_REF doesn't match the package.json version: ${process.env.GITHUB_REF} !== ${newVersion}`); | ||||
|     process.exit(0); | ||||
| } | ||||
|  | ||||
| if (!/^\d+\.\d+\.\d+$/.test(newVersion)) { | ||||
|     console.log(`Not updating for a non-stable release - ${newVersion}`); | ||||
|     process.exit(0); | ||||
| } | ||||
|  | ||||
| const currentVersion = require("../../../node-red-docker/package.json").version; | ||||
|  | ||||
| console.log(`Update from ${currentVersion} to ${newVersion}`) | ||||
|  | ||||
| updateFile(__dirname+"/../../../node-red-docker/package.json", currentVersion, newVersion); | ||||
| updateFile(__dirname+"/../../../node-red-docker/docker-custom/package.json", currentVersion, newVersion); | ||||
| updateFile(__dirname+"/../../../node-red-docker/README.md", currentVersion, newVersion); | ||||
|  | ||||
| console.log(`::set-env name=newVersion::${newVersion}`); | ||||
|  | ||||
| function updateFile(path,from,to) { | ||||
|     let contents = fs.readFileSync(path,"utf8"); | ||||
|     contents = contents.replace(new RegExp(from.replace(/\./g,"\\."),"g"), to); | ||||
|     fs.writeFileSync(path, contents); | ||||
| } | ||||
							
								
								
									
										18
									
								
								.github/scripts/update-node-red-website.js
									
									
									
									
										vendored
									
									
								
							
							
						
						| @@ -1,18 +0,0 @@ | ||||
| const fs = require("fs"); | ||||
|  | ||||
| const newVersion = require("../../package.json").version; | ||||
|  | ||||
| if (process.env.GITHUB_REF !== "refs/tags/"+newVersion) { | ||||
|     console.log(`GITHUB_REF doesn't match the package.json version: ${process.env.GITHUB_REF} !== ${newVersion}`); | ||||
|     process.exit(0); | ||||
| } | ||||
|  | ||||
| if (!/^\d+\.\d+\.\d+$/.test(newVersion)) { | ||||
|     console.log(`Not updating for a non-stable release - ${newVersion}`); | ||||
|     process.exit(0); | ||||
| } | ||||
|  | ||||
| const path = __dirname+"/../../../node-red.github.io/index.html"; | ||||
| let contents = fs.readFileSync(path, "utf8"); | ||||
| contents = contents.replace(/<span class="node-red-latest-version">v\d+\.\d+\.\d+<\/span>/, `<span class="node-red-latest-version">v${newVersion}<\/span>` ); | ||||
| fs.writeFileSync(path, contents); | ||||
							
								
								
									
										59
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						| @@ -1,59 +0,0 @@ | ||||
| name: Publish Release | ||||
| env: | ||||
|   ACTIONS_ALLOW_UNSECURE_COMMANDS: true | ||||
| on: | ||||
|   release: | ||||
|     types: [published] | ||||
|  | ||||
| jobs: | ||||
|   generate: | ||||
|     name: 'Update node-red-docker image' | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: Check out node-red repository | ||||
|         uses: actions/checkout@v2 | ||||
|         with: | ||||
|             path: 'node-red' | ||||
|       - name: Check out node-red-docker repository | ||||
|         uses: actions/checkout@v2 | ||||
|         with: | ||||
|             repository: 'node-red/node-red-docker' | ||||
|             path: 'node-red-docker' | ||||
|       - name: Check out node-red.github.io repository | ||||
|         uses: actions/checkout@v2 | ||||
|         with: | ||||
|             repository: 'node-red/node-red.github.io' | ||||
|             path: 'node-red.github.io' | ||||
|       - uses: actions/setup-node@v1 | ||||
|         with: | ||||
|             node-version: '16' | ||||
|       - run: node ./node-red/.github/scripts/update-node-red-docker.js | ||||
|       - name: Create Docker Pull Request | ||||
|         uses: peter-evans/create-pull-request@v2 | ||||
|         with: | ||||
|           token: ${{ secrets.NR_REPO_TOKEN }} | ||||
|           committer: GitHub <noreply@github.com> | ||||
|           author: ${{ github.actor }} <${{ github.actor }}@users.noreply.github.com> | ||||
|           path: 'node-red-docker' | ||||
|           commit-message: 'Bump to ${{ env.newVersion }}' | ||||
|           title: '🚀 Update to Node-RED ${{ env.newVersion }} release' | ||||
|           body: | | ||||
|             Updates the Node-RED Docker repo for the ${{ env.newVersion }} release. | ||||
|  | ||||
|             Once this is merged, you will need to create a new release with the tag `v${{ env.newVersion }}`. | ||||
|  | ||||
|             This PR was auto-generated by a GitHub Action. Any questions, speak to @knolleary | ||||
|       - run: node ./node-red/.github/scripts/update-node-red-website.js | ||||
|       - name: Create Website Pull Request | ||||
|         uses: peter-evans/create-pull-request@v2 | ||||
|         with: | ||||
|           token: ${{ secrets.NR_REPO_TOKEN }} | ||||
|           committer: GitHub <noreply@github.com> | ||||
|           author: ${{ github.actor }} <${{ github.actor }}@users.noreply.github.com> | ||||
|           path: 'node-red.github.io' | ||||
|           commit-message: 'Bump to ${{ env.newVersion }}' | ||||
|           title: '🚀 Update to Node-RED ${{ env.newVersion }} release' | ||||
|           body: | | ||||
|             Updates the Node-RED Website repo for the ${{ env.newVersion }} release. | ||||
|  | ||||
|             This PR was auto-generated by a GitHub Action. Any questions, speak to @knolleary | ||||
							
								
								
									
										30
									
								
								.github/workflows/tests.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						| @@ -1,30 +0,0 @@ | ||||
| name: Run tests | ||||
|  | ||||
| on: | ||||
|   push: | ||||
|     branches: [ master, dev ] | ||||
|   pull_request: | ||||
|     branches: [ master, dev ] | ||||
|  | ||||
| jobs: | ||||
|   build: | ||||
|     runs-on: ubuntu-latest | ||||
|     strategy: | ||||
|       matrix: | ||||
|         node-version: [14, 16] | ||||
|     steps: | ||||
|     - uses: actions/checkout@v2 | ||||
|     - name: Use Node.js ${{ matrix.node-version }} | ||||
|       uses: actions/setup-node@v2 | ||||
|       with: | ||||
|         node-version: ${{ matrix.node-version }} | ||||
|     - name: Install Dependencies | ||||
|       run: npm install | ||||
|     - name: Run tests | ||||
|       run: | | ||||
|         npm run test | ||||
|     - name: Publish to coveralls.io | ||||
|       if: ${{ matrix.node-version == 14 }} | ||||
|       uses: coverallsapp/github-action@v1.1.2 | ||||
|       with: | ||||
|         github-token: ${{ github.token }} | ||||
							
								
								
									
										10
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						| @@ -7,9 +7,7 @@ | ||||
| .sessions.json | ||||
| .settings | ||||
| .tern-project | ||||
| .i18n-editor-metadata | ||||
| *.backup | ||||
| *.bak | ||||
| *_cred* | ||||
| coverage | ||||
| credentials.json | ||||
| @@ -19,11 +17,3 @@ node_modules | ||||
| public | ||||
| locales/zz-ZZ | ||||
| nodes/core/locales/zz-ZZ | ||||
| !packages/node_modules | ||||
| packages/node_modules/@node-red/editor-client/public | ||||
| !test/**/node_modules | ||||
| docs | ||||
| !packages/node_modules/**/docs | ||||
| .vscode | ||||
| .nyc_output | ||||
| sync.ffs_db | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| /Gruntfile.js | ||||
| /.git/* | ||||
| /lib/* | ||||
| *.backup | ||||
| /public/* | ||||
|   | ||||
							
								
								
									
										7
									
								
								.npmignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,7 @@ | ||||
| .settings | ||||
| .jshintignore | ||||
| .jshintrc | ||||
| .project | ||||
| .tern-project | ||||
| .travis.yml | ||||
| .git | ||||
							
								
								
									
										12
									
								
								.travis.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,12 @@ | ||||
| sudo: false | ||||
| language: node_js | ||||
| matrix: | ||||
|   include: | ||||
|     - node_js: "10" | ||||
|       script: | ||||
|         - ./node_modules/.bin/grunt && istanbul report text && ( cat coverage/lcov.info | $(npm get prefix)/bin/coveralls || true ) && rm -rf coverage | ||||
|       before_script: | ||||
|         - npm install -g istanbul coveralls | ||||
|     - node_js: "8" | ||||
|     - node_js: "6" | ||||
|     - node_js: "4" | ||||
							
								
								
									
										19
									
								
								API.md
									
									
									
									
									
								
							
							
						
						| @@ -1,19 +0,0 @@ | ||||
| Node-RED consists of 6 node modules under the `@node-red` scope, which are pulled together | ||||
| by the top-level `node-red` module. The typical scenario is where you are embedding Node-RED into your | ||||
| own application, in which case you would use the `node-red` module rather than any of the | ||||
| internal modules directly. | ||||
|  | ||||
| ```javascript | ||||
| let RED = require("node-red"); | ||||
| ``` | ||||
|  | ||||
|  | ||||
| Module | Description | ||||
| -------|------- | ||||
| [node-red](node-red.html) | the main module that pulls together all of the internal modules and provides the executable version of Node-RED | ||||
| [@node-red/editor-api](@node-red_editor-api.html) | an Express application that serves the Node-RED editor and provides the Admin HTTP API | ||||
| [@node-red/runtime](@node-red_runtime.html) | the core runtime of Node-RED | ||||
| [@node-red/util](@node-red_util.html) | common utilities for the Node-RED runtime and editor modules | ||||
| [@node-red/registry](@node-red_registry.html) | the internal node registry | ||||
| @node-red/nodes | the default set of core nodes. This module only contains the Node-RED nodes - it does not expose any APIs. | ||||
| @node-red/editor-client | the client-side resources of the Node-RED editor application | ||||
							
								
								
									
										1815
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						| @@ -26,7 +26,7 @@ relevant nodes, press Ctrl-E and copy the flow data from the Export dialog. | ||||
| At a minimum, please include: | ||||
|  | ||||
|  - Version of Node-RED - either release number if you downloaded a zip, or the first few lines of `git log` if you are cloning the repository directly. | ||||
|  - Version of Node.js - what does `node -v` say? | ||||
|  - Version of node.js - what does `node -v` say? | ||||
|  | ||||
| ## Feature requests | ||||
|  | ||||
| @@ -38,18 +38,13 @@ If you want to raise a pull-request with a new feature, or a refactoring | ||||
| of existing code, it may well get rejected if you haven't discussed it on | ||||
| the [forum](https://discourse.nodered.org) first. | ||||
|  | ||||
| All contributors need to sign the OpenJS Foundation's Contributor License Agreement. | ||||
| It is an online process and quick to do. If you raise a pull-request without | ||||
| having signed the CLA, you will be prompted to do so automatically. | ||||
| All contributors need to sign the JS Foundation's Contributor License Agreement. | ||||
| It is an online process and quick to do. You can read the details of the agreement | ||||
| here: https://cla.js.foundation/node-red/node-red. | ||||
|  | ||||
| If you raise a pull-request without having signed the CLA, you will be prompted | ||||
| to do so automatically. | ||||
|  | ||||
| ### Code Branches | ||||
|  | ||||
| When raising a PR for a fix or a new feature, it is important to target the right branch. | ||||
|  | ||||
|  - `master` - this is the main branch for the latest stable release of Node-RED. All bug fixes for that release should target this branch. | ||||
|  - `v1.x` - this is the maintenance branch for the 1.x stream. If a fix *only* applies to 1.x, then it should target this branch. If it applies to the current stable release as well, target `master` first. We will then decide if it needs to be back ported to the 1.x stream. | ||||
|  - `dev` - this is the branch for new feature development targeting the next milestone release. | ||||
|  | ||||
| ### Coding standards | ||||
|  | ||||
|   | ||||
							
								
								
									
										578
									
								
								Gruntfile.js
									
									
									
									
									
								
							
							
						
						| @@ -15,35 +15,17 @@ | ||||
|  **/ | ||||
|  | ||||
| var path = require("path"); | ||||
| var fs = require("fs-extra"); | ||||
| var sass = require("sass"); | ||||
|  | ||||
| module.exports = function(grunt) { | ||||
|  | ||||
|     var nodemonArgs = ["-V"]; | ||||
|     var nodemonArgs = ["-v"]; | ||||
|     var flowFile = grunt.option('flowFile'); | ||||
|     if (flowFile) { | ||||
|         nodemonArgs.push(flowFile); | ||||
|         process.env.NODE_RED_ENABLE_PROJECTS=false; | ||||
|     } | ||||
|     var userDir = grunt.option('userDir'); | ||||
|     if (userDir) { | ||||
|         nodemonArgs.push("-u"); | ||||
|         nodemonArgs.push(userDir); | ||||
|     } | ||||
|  | ||||
|     var browserstack = grunt.option('browserstack'); | ||||
|     if (browserstack) { | ||||
|         process.env.BROWSERSTACK = true; | ||||
|     } | ||||
|     var nonHeadless = grunt.option('non-headless'); | ||||
|     if (nonHeadless) { | ||||
|         process.env.NODE_RED_NON_HEADLESS = true; | ||||
|     } | ||||
|     const pkg = grunt.file.readJSON('package.json'); | ||||
|     process.env.NODE_RED_PACKAGE_VERSION = pkg.version; | ||||
|     grunt.initConfig({ | ||||
|         pkg: pkg, | ||||
|         pkg: grunt.file.readJSON('package.json'), | ||||
|         paths: { | ||||
|             dist: ".dist" | ||||
|         }, | ||||
| @@ -55,8 +37,8 @@ module.exports = function(grunt) { | ||||
|                 ui: 'bdd', | ||||
|                 reporter: 'spec' | ||||
|             }, | ||||
|             all: { src: ["test/unit/_spec.js","test/unit/**/*_spec.js","test/nodes/**/*_spec.js"] }, | ||||
|             core: { src: ["test/unit/_spec.js","test/unit/**/*_spec.js"]}, | ||||
|             all: { src: ['test/**/*_spec.js'] }, | ||||
|             core: { src: ["test/_spec.js","test/red/**/*_spec.js"]}, | ||||
|             nodes: { src: ["test/nodes/**/*_spec.js"]} | ||||
|         }, | ||||
|         webdriver: { | ||||
| @@ -64,19 +46,18 @@ module.exports = function(grunt) { | ||||
|                 configFile: 'test/editor/wdio.conf.js' | ||||
|             } | ||||
|         }, | ||||
|         nyc: { | ||||
|         mocha_istanbul: { | ||||
|             options: { | ||||
|                 cwd: '.', | ||||
|                 include: ['packages/node_modules/**'], | ||||
|                 excludeNodeModules: false, | ||||
|                 exclude: ['packages/node_modules/@node-red/editor-client/**'], | ||||
|                 reporter: ['lcov', 'html','text-summary'], | ||||
|                 reportDir: 'coverage', | ||||
|                 all: true | ||||
|                 globals: ['expect'], | ||||
|                 timeout: 3000, | ||||
|                 ignoreLeaks: false, | ||||
|                 ui: 'bdd', | ||||
|                 reportFormats: ['lcov','html'], | ||||
|                 print: 'both' | ||||
|             }, | ||||
|             all:   { cmd: false, args: ['grunt', 'simplemocha:all'] }, | ||||
|             core:  { options: { exclude:['packages/node_modules/@node-red/editor-client/**', 'packages/node_modules/@node-red/nodes/**']},cmd: false, args: ['grunt', 'simplemocha:core'] }, | ||||
|             nodes: { cmd: false, args: ['grunt', 'simplemocha:nodes'] } | ||||
|             all: { src: ["test/_spec.js","test/red/**/*_spec.js","test/nodes/**/*_spec.js"] }, | ||||
|             core: { src: ["test/_spec.js","test/red/**/*_spec.js"]}, | ||||
|             nodes: { src: ["test/nodes/**/*_spec.js"]} | ||||
|         }, | ||||
|         jshint: { | ||||
|             options: { | ||||
| @@ -92,20 +73,22 @@ module.exports = function(grunt) { | ||||
|                 //"loopfunc": true, // allow functions to be defined in loops | ||||
|                 //"sub": true       // don't warn that foo['bar'] should be written as foo.bar | ||||
|             }, | ||||
|             // all: [ | ||||
|             //     'Gruntfile.js', | ||||
|             //     'red.js', | ||||
|             //     'packages/**/*.js' | ||||
|             // ], | ||||
|             // core: { | ||||
|             //     files: { | ||||
|             //         src: [ | ||||
|             //             'Gruntfile.js', | ||||
|             //             'red.js', | ||||
|             //             'packages/**/*.js', | ||||
|             //         ] | ||||
|             //     } | ||||
|             // }, | ||||
|             all: [ | ||||
|                 'Gruntfile.js', | ||||
|                 'red.js', | ||||
|                 'red/**/*.js', | ||||
|                 'nodes/core/*/*.js', | ||||
|                 'editor/js/**/*.js' | ||||
|             ], | ||||
|             core: { | ||||
|                 files: { | ||||
|                     src: [ | ||||
|                         'Gruntfile.js', | ||||
|                         'red.js', | ||||
|                         'red/**/*.js' | ||||
|                     ] | ||||
|                 } | ||||
|             }, | ||||
|             nodes: { | ||||
|                 files: { | ||||
|                     src: [ 'nodes/core/*/*.js' ] | ||||
| @@ -113,7 +96,7 @@ module.exports = function(grunt) { | ||||
|             }, | ||||
|             editor: { | ||||
|                 files: { | ||||
|                     src: [ 'packages/node_modules/@node-red/editor-client/src/js/**/*.js' ] | ||||
|                     src: [ 'editor/js/**/*.js' ] | ||||
|                 } | ||||
|             }, | ||||
|             tests: { | ||||
| @@ -133,106 +116,79 @@ module.exports = function(grunt) { | ||||
|                 src: [ | ||||
|                     // Ensure editor source files are concatenated in | ||||
|                     // the right order | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/polyfills.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/jquery-addons.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/red.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/events.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/hooks.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/i18n.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/settings.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/user.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/comms.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/runtime.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/text/bidi.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/text/format.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/state.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/plugins.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/nodes.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/font-awesome.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/history.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/validators.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/utils.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/common/editableList.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/common/treeList.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/common/checkboxSet.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/common/menu.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/common/panels.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/common/popover.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/common/searchBox.js", | ||||
|                     "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/common/autoComplete.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/diagnostics.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/diff.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/keyboard.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/workspaces.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/statusBar.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/view.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/view-annotations.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/view-navigator.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/view-tools.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/sidebar.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/palette.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/tab-info.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/tab-info-outliner.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/tab-help.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/tab-config.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/tab-context.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/palette-editor.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/editor.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/editors/panes/*.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/editors/*.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/editors/code-editors/*.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/event-log.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/tray.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/clipboard.js", | ||||
|                     "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/contextMenu.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/group.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/userSettings.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/projects/projects.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/projects/projectSettings.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/projects/projectUserSettings.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/projects/tab-versionControl.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/touch/radialMenu.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/tour/*.js" | ||||
|                     "editor/js/red.js", | ||||
|                     "editor/js/events.js", | ||||
|                     "editor/js/i18n.js", | ||||
|                     "editor/js/settings.js", | ||||
|                     "editor/js/user.js", | ||||
|                     "editor/js/comms.js", | ||||
|                     "editor/js/text/bidi.js", | ||||
|                     "editor/js/text/format.js", | ||||
|                     "editor/js/ui/state.js", | ||||
|                     "editor/js/nodes.js", | ||||
|                     "editor/js/history.js", | ||||
|                     "editor/js/validators.js", | ||||
|                     "editor/js/ui/utils.js", | ||||
|                     "editor/js/ui/common/editableList.js", | ||||
|                     "editor/js/ui/common/checkboxSet.js", | ||||
|                     "editor/js/ui/common/menu.js", | ||||
|                     "editor/js/ui/common/panels.js", | ||||
|                     "editor/js/ui/common/popover.js", | ||||
|                     "editor/js/ui/common/searchBox.js", | ||||
|                     "editor/js/ui/common/tabs.js", | ||||
|                     "editor/js/ui/common/stack.js", | ||||
|                     "editor/js/ui/common/typedInput.js", | ||||
|                     "editor/js/ui/actions.js", | ||||
|                     "editor/js/ui/deploy.js", | ||||
|                     "editor/js/ui/diff.js", | ||||
|                     "editor/js/ui/keyboard.js", | ||||
|                     "editor/js/ui/workspaces.js", | ||||
|                     "editor/js/ui/view.js", | ||||
|                     "editor/js/ui/view-navigator.js", | ||||
|                     "editor/js/ui/sidebar.js", | ||||
|                     "editor/js/ui/palette.js", | ||||
|                     "editor/js/ui/tab-info.js", | ||||
|                     "editor/js/ui/tab-config.js", | ||||
|                     "editor/js/ui/palette-editor.js", | ||||
|                     "editor/js/ui/editor.js", | ||||
|                     "editor/js/ui/tray.js", | ||||
|                     "editor/js/ui/clipboard.js", | ||||
|                     "editor/js/ui/library.js", | ||||
|                     "editor/js/ui/notifications.js", | ||||
|                     "editor/js/ui/search.js", | ||||
|                     "editor/js/ui/typeSearch.js", | ||||
|                     "editor/js/ui/subflow.js", | ||||
|                     "editor/js/ui/userSettings.js", | ||||
|                     "editor/js/ui/projects/projects.js", | ||||
|                     "editor/js/ui/projects/projectSettings.js", | ||||
|                     "editor/js/ui/projects/projectUserSettings.js", | ||||
|                     "editor/js/ui/projects/tab-versionControl.js", | ||||
|                     "editor/js/ui/touch/radialMenu.js" | ||||
|                 ], | ||||
|                 dest: "packages/node_modules/@node-red/editor-client/public/red/red.js" | ||||
|                 dest: "public/red/red.js" | ||||
|             }, | ||||
|             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.5.1.min.js", | ||||
|                         "packages/node_modules/@node-red/editor-client/src/vendor/jquery/js/jquery-migrate-3.3.0.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", | ||||
|                         "node_modules/marked/marked.min.js", | ||||
|                         "node_modules/dompurify/dist/purify.min.js", | ||||
|                         "packages/node_modules/@node-red/editor-client/src/vendor/d3/d3.v3.min.js", | ||||
|                         "node_modules/i18next/i18next.min.js", | ||||
|                         "node_modules/i18next-http-backend/i18nextHttpBackend.min.js", | ||||
|                         "node_modules/jquery-i18next/jquery-i18next.min.js", | ||||
|                         "node_modules/jsonata/jsonata-es5.min.js", | ||||
|                         "packages/node_modules/@node-red/editor-client/src/vendor/jsonata/formatter.js", | ||||
|                         "packages/node_modules/@node-red/editor-client/src/vendor/ace/ace.js", | ||||
|                         "packages/node_modules/@node-red/editor-client/src/vendor/ace/ext-language_tools.js", | ||||
|                     "public/vendor/vendor.js": [ | ||||
|                         "editor/vendor/jquery/js/jquery-1.11.3.min.js", | ||||
|                         "editor/vendor/bootstrap/js/bootstrap.min.js", | ||||
|                         "editor/vendor/jquery/js/jquery-ui-1.10.3.custom.min.js", | ||||
|                         "editor/vendor/jquery/js/jquery.ui.touch-punch.min.js", | ||||
|                         "editor/vendor/marked/marked.min.js", | ||||
|                         "editor/vendor/d3/d3.v3.min.js", | ||||
|                         "editor/vendor/i18next/i18next.min.js" | ||||
|                     ], | ||||
|                     // "packages/node_modules/@node-red/editor-client/public/vendor/vendor.css": [ | ||||
|                     //     // TODO: resolve relative resource paths in | ||||
|                     //     //       bootstrap/FA/jquery | ||||
|                     // ], | ||||
|                     "packages/node_modules/@node-red/editor-client/public/vendor/ace/worker-jsonata.js": [ | ||||
|                     "public/vendor/vendor.css": [ | ||||
|                         // TODO: resolve relative resource paths in | ||||
|                         //       bootstrap/FA/jquery | ||||
|                     ], | ||||
|                     "public/vendor/jsonata/jsonata.min.js": [ | ||||
|                         "node_modules/jsonata/jsonata-es5.min.js", | ||||
|                         "packages/node_modules/@node-red/editor-client/src/vendor/jsonata/worker-jsonata.js" | ||||
|                         "editor/vendor/jsonata/formatter.js" | ||||
|                     ], | ||||
|                     "public/vendor/ace/worker-jsonata.js": [ | ||||
|                         "node_modules/jsonata/jsonata-es5.min.js", | ||||
|                         "editor/vendor/jsonata/worker-jsonata.js" | ||||
|                     ] | ||||
|                 } | ||||
|             } | ||||
| @@ -240,62 +196,63 @@ module.exports = function(grunt) { | ||||
|         uglify: { | ||||
|             build: { | ||||
|                 files: { | ||||
|                     'packages/node_modules/@node-red/editor-client/public/red/red.min.js': 'packages/node_modules/@node-red/editor-client/public/red/red.js', | ||||
|                     'packages/node_modules/@node-red/editor-client/public/red/main.min.js': 'packages/node_modules/@node-red/editor-client/public/red/main.js', | ||||
|                     'packages/node_modules/@node-red/editor-client/public/vendor/ace/mode-jsonata.js': 'packages/node_modules/@node-red/editor-client/src/vendor/jsonata/mode-jsonata.js', | ||||
|                     'packages/node_modules/@node-red/editor-client/public/vendor/ace/snippets/jsonata.js': 'packages/node_modules/@node-red/editor-client/src/vendor/jsonata/snippets-jsonata.js' | ||||
|                     'public/red/red.min.js': 'public/red/red.js', | ||||
|                     'public/red/main.min.js': 'public/red/main.js', | ||||
|                     'public/vendor/ace/mode-jsonata.js': 'editor/vendor/jsonata/mode-jsonata.js', | ||||
|                     'public/vendor/ace/snippets/jsonata.js': 'editor/vendor/jsonata/snippets-jsonata.js' | ||||
|                 } | ||||
|             } | ||||
|         }, | ||||
|         sass: { | ||||
|             build: { | ||||
|                 options: { | ||||
|                     implementation: sass, | ||||
|                     outputStyle: 'compressed' | ||||
|                 }, | ||||
|                 files: [{ | ||||
|                     dest: 'packages/node_modules/@node-red/editor-client/public/red/style.min.css', | ||||
|                     src: 'packages/node_modules/@node-red/editor-client/src/sass/style.scss' | ||||
|                     dest: 'public/red/style.min.css', | ||||
|                     src: 'editor/sass/style.scss' | ||||
|                 }, | ||||
|                 { | ||||
|                     dest: 'public/vendor/bootstrap/css/bootstrap.min.css', | ||||
|                     src: 'editor/vendor/bootstrap/css/bootstrap.css' | ||||
|                 }] | ||||
|             } | ||||
|         }, | ||||
|         jsonlint: { | ||||
|             messages: { | ||||
|                 src: [ | ||||
|                     'packages/node_modules/@node-red/nodes/locales/**/*.json', | ||||
|                     'packages/node_modules/@node-red/editor-client/locales/**/*.json', | ||||
|                     'packages/node_modules/@node-red/runtime/locales/**/*.json' | ||||
|                     'nodes/core/locales/en-US/messages.json', | ||||
|                     'red/api/locales/en-US/editor.json', | ||||
|                     'red/runtime/locales/en-US/runtime.json' | ||||
|                 ] | ||||
|             }, | ||||
|             keymaps: { | ||||
|                 src: [ | ||||
|                     'packages/node_modules/@node-red/editor-client/src/js/keymap.json' | ||||
|                     'editor/js/keymap.json' | ||||
|                 ] | ||||
|             } | ||||
|         }, | ||||
|         attachCopyright: { | ||||
|             js: { | ||||
|                 src: [ | ||||
|                     'packages/node_modules/@node-red/editor-client/public/red/red.min.js', | ||||
|                     'packages/node_modules/@node-red/editor-client/public/red/main.min.js' | ||||
|                     'public/red/red.min.js', | ||||
|                     'public/red/main.min.js' | ||||
|                 ] | ||||
|             }, | ||||
|             css: { | ||||
|                 src: [ | ||||
|                     'packages/node_modules/@node-red/editor-client/public/red/style.min.css' | ||||
|                     'public/red/style.min.css' | ||||
|                 ] | ||||
|             } | ||||
|         }, | ||||
|         clean: { | ||||
|             build: { | ||||
|                 src: [ | ||||
|                     "packages/node_modules/@node-red/editor-client/public/red", | ||||
|                     "packages/node_modules/@node-red/editor-client/public/index.html", | ||||
|                     "packages/node_modules/@node-red/editor-client/public/favicon.ico", | ||||
|                     "packages/node_modules/@node-red/editor-client/public/icons", | ||||
|                     "packages/node_modules/@node-red/editor-client/public/vendor", | ||||
|                     "packages/node_modules/@node-red/editor-client/public/types/node", | ||||
|                     "packages/node_modules/@node-red/editor-client/public/types/node-red", | ||||
|                     "public/red", | ||||
|                     "public/index.html", | ||||
|                     "public/favicon.ico", | ||||
|                     "public/icons", | ||||
|                     "public/vendor" | ||||
|                 ] | ||||
|             }, | ||||
|             release: { | ||||
| @@ -307,36 +264,30 @@ module.exports = function(grunt) { | ||||
|         watch: { | ||||
|             js: { | ||||
|                 files: [ | ||||
|                     'packages/node_modules/@node-red/editor-client/src/js/**/*.js' | ||||
|                     'editor/js/**/*.js' | ||||
|                 ], | ||||
|                 tasks: ['copy:build','concat',/*'uglify',*/ 'attachCopyright:js'] | ||||
|                 tasks: ['copy:build','concat','uglify','attachCopyright:js'] | ||||
|             }, | ||||
|             sass: { | ||||
|                 files: [ | ||||
|                     'packages/node_modules/@node-red/editor-client/src/sass/**/*.scss' | ||||
|                     'editor/sass/**/*.scss' | ||||
|                 ], | ||||
|                 tasks: ['sass','attachCopyright:css'] | ||||
|             }, | ||||
|             json: { | ||||
|                 files: [ | ||||
|                     'packages/node_modules/@node-red/nodes/locales/**/*.json', | ||||
|                     'packages/node_modules/@node-red/editor-client/locales/**/*.json', | ||||
|                     'packages/node_modules/@node-red/runtime/locales/**/*.json' | ||||
|                     'nodes/core/locales/en-US/messages.json', | ||||
|                     'red/api/locales/en-US/editor.json', | ||||
|                     'red/runtime/locales/en-US/runtime.json' | ||||
|                 ], | ||||
|                 tasks: ['jsonlint:messages'] | ||||
|             }, | ||||
|             keymaps: { | ||||
|                 files: [ | ||||
|                     'packages/node_modules/@node-red/editor-client/src/js/keymap.json' | ||||
|                     'editor/js/keymap.json' | ||||
|                 ], | ||||
|                 tasks: ['jsonlint:keymaps','copy:build'] | ||||
|             }, | ||||
|             tours: { | ||||
|                 files: [ | ||||
|                     'packages/node_modules/@node-red/editor-client/src/tours/**/*.js' | ||||
|                 ], | ||||
|                 tasks: ['copy:build'] | ||||
|             }, | ||||
|             misc: { | ||||
|                 files: [ | ||||
|                     'CHANGELOG.md' | ||||
| @@ -348,13 +299,12 @@ module.exports = function(grunt) { | ||||
|         nodemon: { | ||||
|             /* uses .nodemonignore */ | ||||
|             dev: { | ||||
|                 script: 'packages/node_modules/node-red/red.js', | ||||
|                 script: 'red.js', | ||||
|                 options: { | ||||
|                     args: nodemonArgs, | ||||
|                     ext: 'js,html,json', | ||||
|                     watch: [ | ||||
|                         'packages/node_modules', | ||||
|                         '!packages/node_modules/@node-red/editor-client' | ||||
|                         'red','nodes' | ||||
|                     ] | ||||
|                 } | ||||
|             } | ||||
| @@ -373,75 +323,69 @@ module.exports = function(grunt) { | ||||
|             build: { | ||||
|                 files:[ | ||||
|                     { | ||||
|                         src: 'packages/node_modules/@node-red/editor-client/src/js/main.js', | ||||
|                         dest: 'packages/node_modules/@node-red/editor-client/public/red/main.js' | ||||
|                         src: 'editor/js/main.js', | ||||
|                         dest: 'public/red/main.js' | ||||
|                     }, | ||||
|                     { | ||||
|                         src: 'packages/node_modules/@node-red/editor-client/src/js/keymap.json', | ||||
|                         dest: 'packages/node_modules/@node-red/editor-client/public/red/keymap.json' | ||||
|                         src: 'editor/js/keymap.json', | ||||
|                         dest: 'public/red/keymap.json' | ||||
|                     }, | ||||
|                     { | ||||
|                         cwd: 'packages/node_modules/@node-red/editor-client/src/images', | ||||
|                         cwd: 'editor/images', | ||||
|                         src: '**', | ||||
|                         expand: true, | ||||
|                         dest: 'packages/node_modules/@node-red/editor-client/public/red/images/' | ||||
|                         dest: 'public/red/images/' | ||||
|                     }, | ||||
|                     { | ||||
|                         cwd: 'packages/node_modules/@node-red/editor-client/src/vendor', | ||||
|                         cwd: 'editor/vendor', | ||||
|                         src: [ | ||||
|                             'ace/**', | ||||
|                             'jquery/css/base/**', | ||||
|                             'font-awesome/**', | ||||
|                             'monaco/dist/**', | ||||
|                             'monaco/types/extraLibs.js', | ||||
|                             'monaco/style.css', | ||||
|                             'monaco/monaco-bootstrap.js' | ||||
|                             //'bootstrap/css/**', | ||||
|                             'bootstrap/img/**', | ||||
|                             'jquery/css/**', | ||||
|                             'font-awesome/**' | ||||
|                         ], | ||||
|                         expand: true, | ||||
|                         dest: 'packages/node_modules/@node-red/editor-client/public/vendor/' | ||||
|                         dest: 'public/vendor/' | ||||
|                     }, | ||||
|                     { | ||||
|                         cwd: 'packages/node_modules/@node-red/editor-client/src', | ||||
|                         src: [ | ||||
|                             'types/node/*.ts', | ||||
|                             'types/node-red/*.ts', | ||||
|                         ], | ||||
|                         expand: true, | ||||
|                         dest: 'packages/node_modules/@node-red/editor-client/public/' | ||||
|                     }, | ||||
|                     { | ||||
|                         cwd: 'packages/node_modules/@node-red/editor-client/src/icons', | ||||
|                         cwd: 'editor/icons', | ||||
|                         src: '**', | ||||
|                         expand: true, | ||||
|                         dest: 'packages/node_modules/@node-red/editor-client/public/icons/' | ||||
|                         dest: 'public/icons/' | ||||
|                     }, | ||||
|                     { | ||||
|                         expand: true, | ||||
|                         src: ['packages/node_modules/@node-red/editor-client/src/index.html','packages/node_modules/@node-red/editor-client/src/favicon.ico'], | ||||
|                         dest: 'packages/node_modules/@node-red/editor-client/public/', | ||||
|                         src: ['editor/index.html','editor/favicon.ico'], | ||||
|                         dest: 'public/', | ||||
|                         flatten: true | ||||
|                     }, | ||||
|                     { | ||||
|                         src: 'CHANGELOG.md', | ||||
|                         dest: 'packages/node_modules/@node-red/editor-client/public/red/about' | ||||
|                     }, | ||||
|                     { | ||||
|                         src: 'CHANGELOG.md', | ||||
|                         dest: 'packages/node_modules/node-red/' | ||||
|                     }, | ||||
|                     { | ||||
|                         cwd: 'packages/node_modules/@node-red/editor-client/src/ace/bin/', | ||||
|                         src: '**', | ||||
|                         expand: true, | ||||
|                         dest: 'packages/node_modules/@node-red/editor-client/public/vendor/ace/' | ||||
|                     }, | ||||
|                     { | ||||
|                         cwd: 'packages/node_modules/@node-red/editor-client/src/tours', | ||||
|                         src: '**', | ||||
|                         expand: true, | ||||
|                         dest: 'packages/node_modules/@node-red/editor-client/public/red/tours/' | ||||
|                         dest: 'public/red/about' | ||||
|                     } | ||||
|                 ] | ||||
|             }, | ||||
|             release: { | ||||
|                 files: [{ | ||||
|                     mode: true, | ||||
|                     expand: true, | ||||
|                     src: [ | ||||
|                         '*.md', | ||||
|                         'LICENSE', | ||||
|                         'package.json', | ||||
|                         'settings.js', | ||||
|                         'red.js', | ||||
|                         'lib/.gitignore', | ||||
|                         'nodes/*.demo', | ||||
|                         'nodes/core/**', | ||||
|                         'red/**', | ||||
|                         'public/**', | ||||
|                         'editor/templates/**', | ||||
|                         'bin/**' | ||||
|                     ], | ||||
|                     dest: path.resolve('<%= paths.dist %>/node-red-<%= pkg.version %>') | ||||
|                 }] | ||||
|             } | ||||
|         }, | ||||
|         chmod: { | ||||
| @@ -450,95 +394,19 @@ module.exports = function(grunt) { | ||||
|             }, | ||||
|             release: { | ||||
|                 src: [ | ||||
|                     "packages/node_modules/@node-red/nodes/core/hardware/nrgpio", | ||||
|                     "packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/git/node-red-*sh" | ||||
|                     path.resolve('<%= paths.dist %>/node-red-<%= pkg.version %>/nodes/core/hardware/nrgpio*'), | ||||
|                     path.resolve('<%= paths.dist %>/node-red-<%= pkg.version %>/red/runtime/storage/localfilesystem/projects/git/node-red-*sh') | ||||
|                 ] | ||||
|             } | ||||
|         }, | ||||
|         'npm-command': { | ||||
|             options: { | ||||
|                 cmd: "pack", | ||||
|                 cwd: "<%= paths.dist %>/modules" | ||||
|             }, | ||||
|             'node-red': { options: { args: [__dirname+'/packages/node_modules/node-red'] } }, | ||||
|             '@node-red/editor-api': { options: { args: [__dirname+'/packages/node_modules/@node-red/editor-api'] } }, | ||||
|             '@node-red/editor-client': { options: { args: [__dirname+'/packages/node_modules/@node-red/editor-client'] } }, | ||||
|             '@node-red/nodes': { options: { args: [__dirname+'/packages/node_modules/@node-red/nodes'] } }, | ||||
|             '@node-red/registry': { options: { args: [__dirname+'/packages/node_modules/@node-red/registry'] } }, | ||||
|             '@node-red/runtime': { options: { args: [__dirname+'/packages/node_modules/@node-red/runtime'] } }, | ||||
|             '@node-red/util': { options: { args: [__dirname+'/packages/node_modules/@node-red/util'] } } | ||||
|  | ||||
|  | ||||
|         }, | ||||
|         mkdir: { | ||||
|             release: { | ||||
|                 options: { | ||||
|                     create: ['<%= paths.dist %>/modules'] | ||||
|                 }, | ||||
|             }, | ||||
|         }, | ||||
|         compress: { | ||||
|             release: { | ||||
|                 options: { | ||||
|                     archive: '<%= paths.dist %>/node-red-<%= pkg.version %>.zip' | ||||
|                 }, | ||||
|                 expand: true, | ||||
|                 cwd: 'packages/node_modules/', | ||||
|                 src: [ | ||||
|                     '**', | ||||
|                     '!@node-red/editor-client/src/**' | ||||
|                 ] | ||||
|             } | ||||
|         }, | ||||
|         jsdoc : { | ||||
|             modules: { | ||||
|                 src: [ | ||||
|                     'API.md', | ||||
|                     'packages/node_modules/node-red/lib/red.js', | ||||
|                     'packages/node_modules/@node-red/runtime/lib/index.js', | ||||
|                     'packages/node_modules/@node-red/runtime/lib/api/*.js', | ||||
|                     'packages/node_modules/@node-red/runtime/lib/events.js', | ||||
|                     'packages/node_modules/@node-red/runtime/lib/hooks.js', | ||||
|                     'packages/node_modules/@node-red/util/**/*.js', | ||||
|                     'packages/node_modules/@node-red/editor-api/lib/index.js', | ||||
|                     'packages/node_modules/@node-red/editor-api/lib/auth/index.js', | ||||
|                     'packages/node_modules/@node-red/registry/lib/index.js' | ||||
|                 ], | ||||
|                 options: { | ||||
|                     destination: 'docs', | ||||
|                     configure: './jsdoc.json', | ||||
|                     fred: "hi there" | ||||
|                 } | ||||
|             }, | ||||
|             _editor: { | ||||
|                 src: [ | ||||
|                     'packages/node_modules/@node-red/editor-client/src/js' | ||||
|                     ], | ||||
|                 options: { | ||||
|                     destination: 'packages/node_modules/@node-red/editor-client/docs', | ||||
|                     configure: './jsdoc.json' | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|         }, | ||||
|         jsdoc2md: { | ||||
|             runtimeAPI: { | ||||
|                 options: { | ||||
|                     separators: true | ||||
|                 }, | ||||
|                 src: [ | ||||
|                     'packages/node_modules/@node-red/runtime/lib/index.js', | ||||
|                     'packages/node_modules/@node-red/runtime/lib/api/*.js', | ||||
|                     'packages/node_modules/@node-red/runtime/lib/events.js' | ||||
|                 ], | ||||
|                 dest: 'packages/node_modules/@node-red/runtime/docs/api.md' | ||||
|             }, | ||||
|             nodeREDUtil: { | ||||
|                 options: { | ||||
|                     separators: true | ||||
|                 }, | ||||
|                 src: 'packages/node_modules/@node-red/util/**/*.js', | ||||
|                 dest: 'packages/node_modules/@node-red/util/docs/api.md' | ||||
|                 cwd: '<%= paths.dist %>/', | ||||
|                 src: ['node-red-<%= pkg.version %>/**'] | ||||
|             } | ||||
|         } | ||||
|     }); | ||||
| @@ -551,42 +419,18 @@ module.exports = function(grunt) { | ||||
|     grunt.loadNpmTasks('grunt-contrib-watch'); | ||||
|     grunt.loadNpmTasks('grunt-concurrent'); | ||||
|     grunt.loadNpmTasks('grunt-sass'); | ||||
|     grunt.loadNpmTasks('grunt-nodemon'); | ||||
|     grunt.loadNpmTasks('grunt-contrib-compress'); | ||||
|     grunt.loadNpmTasks('grunt-contrib-copy'); | ||||
|     grunt.loadNpmTasks('grunt-chmod'); | ||||
|     grunt.loadNpmTasks('grunt-jsonlint'); | ||||
|     if (fs.existsSync(path.join("node_modules", "grunt-webdriver"))) { | ||||
|         grunt.loadNpmTasks('grunt-webdriver'); | ||||
|     } | ||||
|     grunt.loadNpmTasks('grunt-jsdoc'); | ||||
|     grunt.loadNpmTasks('grunt-jsdoc-to-markdown'); | ||||
|     grunt.loadNpmTasks('grunt-npm-command'); | ||||
|     grunt.loadNpmTasks('grunt-mkdir'); | ||||
|     grunt.loadNpmTasks('grunt-simple-nyc'); | ||||
|  | ||||
|     grunt.registerMultiTask('nodemon', 'Runs a nodemon monitor of your node.js server.', function () { | ||||
|         const nodemon = require('nodemon'); | ||||
|         this.async(); | ||||
|         const options = this.options(); | ||||
|         options.script = this.data.script; | ||||
|         let callback; | ||||
|         if (options.callback) { | ||||
|             callback = options.callback; | ||||
|             delete options.callback; | ||||
|         } else { | ||||
|             callback = function(nodemonApp) { | ||||
|                 nodemonApp.on('log', function (event) { | ||||
|                     console.log(event.colour); | ||||
|                 }); | ||||
|             }; | ||||
|         } | ||||
|         callback(nodemon(options)); | ||||
|     }); | ||||
|     grunt.loadNpmTasks('grunt-mocha-istanbul'); | ||||
|     grunt.loadNpmTasks('grunt-webdriver'); | ||||
|  | ||||
|     grunt.registerMultiTask('attachCopyright', function() { | ||||
|         var files = this.data.src; | ||||
|         var copyright = "/**\n"+ | ||||
|             " * Copyright OpenJS Foundation and other contributors, https://openjsf.org/\n"+ | ||||
|             " * Copyright JS Foundation and other contributors, http://js.foundation\n"+ | ||||
|             " *\n"+ | ||||
|             " * Licensed under the Apache License, Version 2.0 (the \"License\");\n"+ | ||||
|             " * you may not use this file except in compliance with the License.\n"+ | ||||
| @@ -623,38 +467,6 @@ module.exports = function(grunt) { | ||||
|         } | ||||
|     }); | ||||
|  | ||||
|     grunt.registerTask('verifyPackageDependencies', function() { | ||||
|         var done = this.async(); | ||||
|         var verifyDependencies = require("./scripts/verify-package-dependencies.js"); | ||||
|         verifyDependencies().then(function(failures) { | ||||
|             if (failures.length > 0) { | ||||
|                 failures.forEach(f => grunt.log.error(f)); | ||||
|                 grunt.fail.fatal("Failed to verify package dependencies"); | ||||
|             } | ||||
|             done(); | ||||
|         }); | ||||
|     }); | ||||
|  | ||||
|     grunt.registerTask('verifyUiTestDependencies', function() { | ||||
|         if (!fs.existsSync(path.join("node_modules", "grunt-webdriver"))) { | ||||
|             grunt.fail.fatal('You need to install the UI test dependencies first.\nUse the script in "scripts/install-ui-test-dependencies.sh"'); | ||||
|             return false; | ||||
|         } | ||||
|     }); | ||||
|     grunt.registerTask('generatePublishScript', | ||||
|         'Generates a script to publish build output to npm', | ||||
|             function () { | ||||
|                 const done = this.async(); | ||||
|                 const generatePublishScript = require("./scripts/generate-publish-script.js"); | ||||
|                 generatePublishScript().then(function(output) { | ||||
|                     grunt.log.writeln(output); | ||||
|  | ||||
|                     const filePath = path.join(grunt.config.get('paths.dist'),"modules","publish.sh"); | ||||
|                     grunt.file.write(filePath,output); | ||||
|  | ||||
|                     done(); | ||||
|                 }); | ||||
|             }); | ||||
|     grunt.registerTask('setDevEnv', | ||||
|         'Sets NODE_ENV=development so non-minified assets are used', | ||||
|             function () { | ||||
| @@ -663,61 +475,37 @@ module.exports = function(grunt) { | ||||
|  | ||||
|     grunt.registerTask('default', | ||||
|         'Builds editor content then runs code style checks and unit tests on all components', | ||||
|         ['build','verifyPackageDependencies','jshint:editor','nyc:all']); | ||||
|  | ||||
|     grunt.registerTask('no-coverage', | ||||
|         'Builds editor content then runs code style checks and unit tests on all components without code coverage', | ||||
|         ['build','verifyPackageDependencies','jshint:editor','simplemocha:all']); | ||||
|  | ||||
|         ['build','jshint:editor','mocha_istanbul:all']); | ||||
|  | ||||
|     grunt.registerTask('test-core', | ||||
|         'Runs code style check and unit tests on core runtime code', | ||||
|         ['build','nyc:core']); | ||||
|         ['build','mocha_istanbul:core']); | ||||
|  | ||||
|     grunt.registerTask('test-editor', | ||||
|         'Runs code style check on editor code', | ||||
|         ['jshint:editor']); | ||||
|  | ||||
|     if (!fs.existsSync(path.join("node_modules", "grunt-webdriver"))) { | ||||
|         grunt.registerTask('test-ui', | ||||
|             'Builds editor content then runs unit tests on editor ui', | ||||
|             ['verifyUiTestDependencies']); | ||||
|     } else { | ||||
|         grunt.registerTask('test-ui', | ||||
|             'Builds editor content then runs unit tests on editor ui', | ||||
|             ['verifyUiTestDependencies','build','jshint:editor','webdriver:all']); | ||||
|     } | ||||
|     grunt.registerTask('test-ui', | ||||
|         'Builds editor content then runs unit tests on editor ui', | ||||
|         ['build','jshint:editor','webdriver:all']); | ||||
|  | ||||
|     grunt.registerTask('test-nodes', | ||||
|         'Runs unit tests on core nodes', | ||||
|         ['build','nyc:nodes']); | ||||
|         ['build','mocha_istanbul:nodes']); | ||||
|  | ||||
|     grunt.registerTask('build', | ||||
|         'Builds editor content', | ||||
|         ['clean:build','jsonlint','concat:build','concat:vendor','copy:build','uglify:build','sass:build','attachCopyright']); | ||||
|  | ||||
|     grunt.registerTask('build-dev', | ||||
|         'Developer mode: build dev version', | ||||
|         ['clean:build','concat:build','concat:vendor','copy:build','sass:build','setDevEnv']); | ||||
|  | ||||
|     grunt.registerTask('dev', | ||||
|         'Developer mode: run node-red, watch for source changes and build/restart', | ||||
|         ['build','setDevEnv','concurrent:dev']); | ||||
|  | ||||
|     grunt.registerTask('release', | ||||
|         'Create distribution zip file', | ||||
|         ['build','verifyPackageDependencies','clean:release','mkdir:release','chmod:release','compress:release','pack-modules','generatePublishScript']); | ||||
|  | ||||
|     grunt.registerTask('pack-modules', | ||||
|         'Create module pack files for release', | ||||
|         ['mkdir:release','npm-command']); | ||||
|  | ||||
|         ['build','clean:release','copy:release','chmod:release','compress:release']); | ||||
|  | ||||
|     grunt.registerTask('coverage', | ||||
|         'Run Istanbul code test coverage task', | ||||
|         ['build','nyc:all']); | ||||
|  | ||||
|     grunt.registerTask('docs', | ||||
|         'Generates API documentation', | ||||
|         ['jsdoc']); | ||||
|         ['build','mocha_istanbul:all']); | ||||
| }; | ||||
|   | ||||
							
								
								
									
										2
									
								
								LICENSE
									
									
									
									
									
								
							
							
						
						| @@ -1,4 +1,4 @@ | ||||
| Copyright OpenJS Foundation and other contributors, https://openjsf.org/ | ||||
| Copyright JS Foundation and other contributors, http://js.foundation | ||||
|  | ||||
|                                  Apache License | ||||
|                            Version 2.0, January 2004 | ||||
|   | ||||
							
								
								
									
										21
									
								
								README.md
									
									
									
									
									
								
							
							
						
						| @@ -2,12 +2,12 @@ | ||||
|  | ||||
| http://nodered.org | ||||
|  | ||||
| [](https://travis-ci.org/node-red/node-red) | ||||
| [](https://travis-ci.org/node-red/node-red) | ||||
| [](https://coveralls.io/r/node-red/node-red?branch=master) | ||||
|  | ||||
| Low-code programming for event-driven applications. | ||||
| A visual tool for wiring the Internet of Things. | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ## Quick Start | ||||
|  | ||||
| @@ -44,6 +44,9 @@ If you want to run the latest code from git, here's how to get started: | ||||
| 4. Run | ||||
|  | ||||
|         npm start | ||||
|    or | ||||
|  | ||||
|         node red.js | ||||
|  | ||||
| ## Contributing | ||||
|  | ||||
| @@ -56,15 +59,15 @@ This project adheres to the [Contributor Covenant 1.4](http://contributor-covena | ||||
|  | ||||
| ## Authors | ||||
|  | ||||
| Node-RED is a project of the [OpenJS Foundation](http://openjsf.org). | ||||
| Node-RED is a project of the [JS Foundation](http://js.foundation). | ||||
|  | ||||
| It is maintained by: | ||||
| It was created by [IBM Emerging Technology](https://www.ibm.com/blogs/emerging-technology/). | ||||
|  | ||||
| * Nick O'Leary [@knolleary](http://twitter.com/knolleary) | ||||
| * Dave Conway-Jones [@ceejay](http://twitter.com/ceejay) | ||||
|  | ||||
|  * Nick O'Leary [@knolleary](http://twitter.com/knolleary) | ||||
|  * Dave Conway-Jones [@ceejay](http://twitter.com/ceejay) | ||||
|  * And many others... | ||||
|  | ||||
|  | ||||
| ## Copyright and license | ||||
|  | ||||
| Copyright OpenJS Foundation and other contributors, https://openjsf.org under [the Apache 2.0 license](LICENSE). | ||||
| Copyright JS Foundation and other contributors, http://js.foundation under [the Apache 2.0 license](LICENSE). | ||||
|   | ||||
| @@ -1,5 +0,0 @@ | ||||
| # Security Policy | ||||
|  | ||||
| ## Reporting a Vulnerability | ||||
|  | ||||
| Please report any potential security issues to `team@nodered.org`. This will notify the core project team who will respond accordingly. | ||||
| @@ -1,4 +1,4 @@ | ||||
| #!/bin/sh | ||||
| #!/bin/bash | ||||
| # | ||||
| # Copyright JS Foundation and other contributors, http://js.foundation | ||||
| # | ||||
| @@ -29,16 +29,15 @@ do | ||||
| done | ||||
| 
 | ||||
| # Find the real location of this script | ||||
| CURRENT_PATH=$(pwd) | ||||
| SCRIPT_PATH=$(readlink -f "$0") | ||||
| CURRENT_PATH=`pwd` | ||||
| SCRIPT_PATH="${BASH_SOURCE[0]}"; | ||||
| while [ -h "${SCRIPT_PATH}" ]; do | ||||
|     cd "$(dirname "${SCRIPT_PATH}")" || exit 1 | ||||
|     P=$(basename "${SCRIPT_PATH}") | ||||
|     SCRIPT_PATH=$(readlink "${P}") | ||||
|     cd "`dirname "${SCRIPT_PATH}"`" | ||||
|     SCRIPT_PATH="$(readlink "`basename "${SCRIPT_PATH}"`")"; | ||||
| done | ||||
| cd "$(dirname "${SCRIPT_PATH}")" > /dev/null || exit 1 | ||||
| SCRIPT_PATH=$(pwd) | ||||
| cd "$CURRENT_PATH" || exit 1 | ||||
| cd "`dirname "${SCRIPT_PATH}"`" > /dev/null | ||||
| SCRIPT_PATH="`pwd`"; | ||||
| cd $CURRENT_PATH | ||||
| 
 | ||||
| # Run Node-RED | ||||
| exec /usr/bin/env node ${OPTIONS} ${SCRIPT_PATH}/../red.js ${ARGS} | ||||
| exec /usr/bin/env node $OPTIONS $SCRIPT_PATH/../red.js $ARGS | ||||
| Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB | 
							
								
								
									
										
											BIN
										
									
								
								editor/icons/alert.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 308 B | 
| Before Width: | Height: | Size: 603 B After Width: | Height: | Size: 603 B | 
| Before Width: | Height: | Size: 393 B After Width: | Height: | Size: 393 B | 
							
								
								
									
										
											BIN
										
									
								
								editor/icons/batch.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 712 B | 
| Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB | 
							
								
								
									
										
											BIN
										
									
								
								editor/icons/bridge-dash.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 508 B | 
							
								
								
									
										
											BIN
										
									
								
								editor/icons/bridge.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 575 B | 
							
								
								
									
										
											BIN
										
									
								
								editor/icons/cog.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 493 B | 
							
								
								
									
										
											BIN
										
									
								
								editor/icons/comment.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 601 B | 
							
								
								
									
										
											BIN
										
									
								
								editor/icons/db.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 459 B | 
							
								
								
									
										
											BIN
										
									
								
								editor/icons/debug.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 218 B | 
							
								
								
									
										
											BIN
										
									
								
								editor/icons/envelope.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 324 B | 
							
								
								
									
										
											BIN
										
									
								
								editor/icons/feed.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 378 B | 
							
								
								
									
										
											BIN
										
									
								
								editor/icons/file.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 255 B | 
							
								
								
									
										
											BIN
										
									
								
								editor/icons/function.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 457 B | 
							
								
								
									
										
											BIN
										
									
								
								editor/icons/hash.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 502 B | 
							
								
								
									
										
											BIN
										
									
								
								editor/icons/inject.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 449 B | 
							
								
								
									
										
											BIN
										
									
								
								editor/icons/join.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 253 B | 
| Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB | 
							
								
								
									
										
											BIN
										
									
								
								editor/icons/light.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 639 B | 
							
								
								
									
										
											BIN
										
									
								
								editor/icons/link-out.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 402 B | 
| Before Width: | Height: | Size: 414 B After Width: | Height: | Size: 414 B | 
| Before Width: | Height: | Size: 671 B After Width: | Height: | Size: 671 B | 
							
								
								
									
										
											BIN
										
									
								
								editor/icons/node-changed.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 386 B | 
							
								
								
									
										
											BIN
										
									
								
								editor/icons/node-error.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 386 B | 
							
								
								
									
										
											BIN
										
									
								
								editor/icons/parser-csv.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 413 B | 
							
								
								
									
										
											BIN
										
									
								
								editor/icons/parser-html.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 393 B | 
							
								
								
									
										
											BIN
										
									
								
								editor/icons/parser-json.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 467 B | 
							
								
								
									
										
											BIN
										
									
								
								editor/icons/parser-xml.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 393 B | 
							
								
								
									
										
											BIN
										
									
								
								editor/icons/parser-yaml.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 423 B | 
							
								
								
									
										
											BIN
										
									
								
								editor/icons/range.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 360 B | 
| Before Width: | Height: | Size: 736 B After Width: | Height: | Size: 736 B | 
							
								
								
									
										
											BIN
										
									
								
								editor/icons/rpi.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 482 B | 
							
								
								
									
										
											BIN
										
									
								
								editor/icons/serial.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 273 B | 
							
								
								
									
										
											BIN
										
									
								
								editor/icons/sort.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 793 B | 
							
								
								
									
										
											BIN
										
									
								
								editor/icons/split.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 256 B | 
							
								
								
									
										
											BIN
										
									
								
								editor/icons/subflow.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 439 B | 
							
								
								
									
										
											BIN
										
									
								
								editor/icons/swap.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 592 B | 
							
								
								
									
										
											BIN
										
									
								
								editor/icons/switch.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 509 B | 
							
								
								
									
										
											BIN
										
									
								
								editor/icons/template.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 488 B | 
							
								
								
									
										
											BIN
										
									
								
								editor/icons/timer.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 628 B | 
							
								
								
									
										
											BIN
										
									
								
								editor/icons/trigger.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 258 B | 
							
								
								
									
										
											BIN
										
									
								
								editor/icons/twitter.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 404 B | 
							
								
								
									
										
											BIN
										
									
								
								editor/icons/watch.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 591 B | 
							
								
								
									
										
											BIN
										
									
								
								editor/icons/white-globe.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 707 B | 
							
								
								
									
										
											BIN
										
									
								
								editor/images/deploy-flows-o.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 291 B | 
							
								
								
									
										
											BIN
										
									
								
								editor/images/deploy-flows.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 386 B | 
							
								
								
									
										
											BIN
										
									
								
								editor/images/deploy-full-o.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 289 B | 
							
								
								
									
										
											BIN
										
									
								
								editor/images/deploy-full.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 368 B | 
							
								
								
									
										
											BIN
										
									
								
								editor/images/deploy-nodes-o.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 290 B | 
							
								
								
									
										
											BIN
										
									
								
								editor/images/deploy-nodes.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 392 B | 
							
								
								
									
										
											BIN
										
									
								
								editor/images/grip.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 192 B | 
| Before Width: | Height: | Size: 8.3 KiB After Width: | Height: | Size: 8.3 KiB | 
| Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB | 
| Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB | 
							
								
								
									
										
											BIN
										
									
								
								editor/images/node-red.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 1019 B | 
							
								
								
									
										
											BIN
										
									
								
								editor/images/pw_maze_white.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 600 B | 
							
								
								
									
										
											BIN
										
									
								
								editor/images/subflow_tab.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 410 B | 
							
								
								
									
										
											BIN
										
									
								
								editor/images/typedInput/09.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 638 B | 
							
								
								
									
										
											BIN
										
									
								
								editor/images/typedInput/az.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 546 B | 
							
								
								
									
										
											BIN
										
									
								
								editor/images/typedInput/bin.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 638 B | 
							
								
								
									
										
											BIN
										
									
								
								editor/images/typedInput/bool.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 646 B | 
							
								
								
									
										
											BIN
										
									
								
								editor/images/typedInput/env.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 809 B | 
							
								
								
									
										
											BIN
										
									
								
								editor/images/typedInput/expr.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 563 B | 
							
								
								
									
										
											BIN
										
									
								
								editor/images/typedInput/json.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 588 B | 
							
								
								
									
										
											BIN
										
									
								
								editor/images/typedInput/re.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 502 B | 
| @@ -28,24 +28,14 @@ RED.comms = (function() { | ||||
| 
 | ||||
|     function connectWS() { | ||||
|         active = true; | ||||
|         var wspath; | ||||
| 
 | ||||
|         if (RED.settings.apiRootUrl) { | ||||
|             var m = /^(https?):\/\/(.*)$/.exec(RED.settings.apiRootUrl); | ||||
|             if (m) { | ||||
|                 console.log(m); | ||||
|                 wspath = "ws"+(m[1]==="https"?"s":"")+"://"+m[2]+"comms"; | ||||
|             } | ||||
|         } else { | ||||
|             var path = location.hostname; | ||||
|             var port = location.port; | ||||
|             if (port.length !== 0) { | ||||
|                 path = path+":"+port; | ||||
|             } | ||||
|             path = path+document.location.pathname; | ||||
|             path = path+(path.slice(-1) == "/"?"":"/")+"comms"; | ||||
|             wspath = "ws"+(document.location.protocol=="https:"?"s":"")+"://"+path; | ||||
|         var path = location.hostname; | ||||
|         var port = location.port; | ||||
|         if (port.length !== 0) { | ||||
|             path = path+":"+port; | ||||
|         } | ||||
|         path = path+document.location.pathname; | ||||
|         path = path+(path.slice(-1) == "/"?"":"/")+"comms"; | ||||
|         path = "ws"+(document.location.protocol=="https:"?"s":"")+"://"+path; | ||||
| 
 | ||||
|         var auth_tokens = RED.settings.get("auth-tokens"); | ||||
|         pendingAuth = (auth_tokens!=null); | ||||
| @@ -58,7 +48,7 @@ RED.comms = (function() { | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         ws = new WebSocket(wspath); | ||||
|         ws = new WebSocket(path); | ||||
|         ws.onopen = function() { | ||||
|             reconnectAttempts = 0; | ||||
|             if (errornotification) { | ||||
| @@ -75,39 +65,29 @@ RED.comms = (function() { | ||||
|         } | ||||
|         ws.onmessage = function(event) { | ||||
|             var message = JSON.parse(event.data); | ||||
|             if (message.auth) { | ||||
|                 if (pendingAuth) { | ||||
|                     if (message.auth === "ok") { | ||||
|             for (var m = 0; m < message.length; m++) { | ||||
|                 var msg = message[m]; | ||||
|                 if (pendingAuth && msg.auth) { | ||||
|                     if (msg.auth === "ok") { | ||||
|                         pendingAuth = false; | ||||
|                         completeConnection(); | ||||
|                     } else if (message.auth === "fail") { | ||||
|                     } else if (msg.auth === "fail") { | ||||
|                         // anything else is an error...
 | ||||
|                         active = false; | ||||
|                         RED.user.login({updateMenu:true},function() { | ||||
|                             connectWS(); | ||||
|                         }) | ||||
|                     } | ||||
|                 } else if (message.auth === "fail") { | ||||
|                     // Our current session has expired
 | ||||
|                     active = false; | ||||
|                     RED.user.login({updateMenu:true},function() { | ||||
|                         connectWS(); | ||||
|                     }) | ||||
|                 } | ||||
|             } else { | ||||
|                 // Otherwise, 'message' is an array of actual comms messages
 | ||||
|                 for (var m = 0; m < message.length; m++) { | ||||
|                     var msg = message[m]; | ||||
|                     if (msg.topic) { | ||||
|                         for (var t in subscriptions) { | ||||
|                             if (subscriptions.hasOwnProperty(t)) { | ||||
|                                 var re = new RegExp("^"+t.replace(/([\[\]\?\(\)\\\\$\^\*\.|])/g,"\\$1").replace(/\+/g,"[^/]+").replace(/\/#$/,"(\/.*)?")+"$"); | ||||
|                                 if (re.test(msg.topic)) { | ||||
|                                     var subscribers = subscriptions[t]; | ||||
|                                     if (subscribers) { | ||||
|                                         for (var i=0;i<subscribers.length;i++) { | ||||
|                                             subscribers[i](msg.topic,msg.data); | ||||
|                                         } | ||||
|                 else if (msg.topic) { | ||||
|                     for (var t in subscriptions) { | ||||
|                         if (subscriptions.hasOwnProperty(t)) { | ||||
|                             var re = new RegExp("^"+t.replace(/([\[\]\?\(\)\\\\$\^\*\.|])/g,"\\$1").replace(/\+/g,"[^/]+").replace(/\/#$/,"(\/.*)?")+"$"); | ||||
|                             if (re.test(msg.topic)) { | ||||
|                                 var subscribers = subscriptions[t]; | ||||
|                                 if (subscribers) { | ||||
|                                     for (var i=0;i<subscribers.length;i++) { | ||||
|                                         subscribers[i](msg.topic,msg.data); | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
| @@ -142,10 +122,10 @@ RED.comms = (function() { | ||||
|                         connectWS(); | ||||
|                     } else { | ||||
|                         var msg = RED._("notification.errors.lostConnectionReconnect",{time: connectCountdown})+' <a href="#">'+ RED._("notification.errors.lostConnectionTry")+'</a>'; | ||||
|                         errornotification.update(msg,{silent:true}); | ||||
|                         $(errornotification).find("a").on("click", function(e) { | ||||
|                         errornotification.update(msg); | ||||
|                         $(errornotification).find("a").click(function(e) { | ||||
|                             e.preventDefault(); | ||||
|                             errornotification.update(RED._("notification.errors.lostConnection"),{silent:true}); | ||||
|                             errornotification.update(RED._("notification.errors.lostConnection")); | ||||
|                             clearInterval(connectCountdownTimer); | ||||
|                             connectWS(); | ||||
|                         }) | ||||
| @@ -32,19 +32,14 @@ | ||||
|              } | ||||
|          } | ||||
|      } | ||||
|      function emit() { | ||||
|          var evt = arguments[0] | ||||
|          var args = Array.prototype.slice.call(arguments,1); | ||||
|          if (RED.events.DEBUG) { | ||||
|              console.warn(evt,args); | ||||
|          } | ||||
|      function emit(evt,arg) { | ||||
|          if (handlers[evt]) { | ||||
|              for (var i=0;i<handlers[evt].length;i++) { | ||||
|                  try { | ||||
|                      handlers[evt][i].apply(null, args); | ||||
|                      handlers[evt][i](arg); | ||||
|                  } catch(err) { | ||||
|                      console.warn("RED.events.emit error: ["+evt+"] "+(err.toString())); | ||||
|                      console.warn(err); | ||||
|                      console.log("RED.events.emit error: ["+evt+"] "+(err.toString())); | ||||
|                      console.log(err); | ||||
|                  } | ||||
|              } | ||||
| 
 | ||||
							
								
								
									
										332
									
								
								editor/js/history.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,332 @@ | ||||
| /** | ||||
|  * 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.history = (function() { | ||||
|     var undo_history = []; | ||||
|  | ||||
|     function undoEvent(ev) { | ||||
|         var i; | ||||
|         var len; | ||||
|         var node; | ||||
|         var subflow; | ||||
|         var modifiedTabs = {}; | ||||
|         if (ev) { | ||||
|             if (ev.t == 'multi') { | ||||
|                 len = ev.events.length; | ||||
|                 for (i=len-1;i>=0;i--) { | ||||
|                     undoEvent(ev.events[i]); | ||||
|                 } | ||||
|             } else if (ev.t == 'replace') { | ||||
|                 RED.nodes.clear(); | ||||
|                 var imported = RED.nodes.import(ev.config); | ||||
|                 imported[0].forEach(function(n) { | ||||
|                     if (ev.changed[n.id]) { | ||||
|                         n.changed = true; | ||||
|                     } | ||||
|                 }) | ||||
|  | ||||
|                 RED.nodes.version(ev.rev); | ||||
|             } else if (ev.t == 'add') { | ||||
|                 if (ev.nodes) { | ||||
|                     for (i=0;i<ev.nodes.length;i++) { | ||||
|                         node = RED.nodes.node(ev.nodes[i]); | ||||
|                         if (node.z) { | ||||
|                             modifiedTabs[node.z] = true; | ||||
|                         } | ||||
|                         RED.nodes.remove(ev.nodes[i]); | ||||
|                     } | ||||
|                 } | ||||
|                 if (ev.links) { | ||||
|                     for (i=0;i<ev.links.length;i++) { | ||||
|                         RED.nodes.removeLink(ev.links[i]); | ||||
|                     } | ||||
|                 } | ||||
|                 if (ev.workspaces) { | ||||
|                     for (i=0;i<ev.workspaces.length;i++) { | ||||
|                         RED.nodes.removeWorkspace(ev.workspaces[i].id); | ||||
|                         RED.workspaces.remove(ev.workspaces[i]); | ||||
|                     } | ||||
|                 } | ||||
|                 if (ev.subflows) { | ||||
|                     for (i=0;i<ev.subflows.length;i++) { | ||||
|                         RED.nodes.removeSubflow(ev.subflows[i]); | ||||
|                         RED.workspaces.remove(ev.subflows[i]); | ||||
|                     } | ||||
|                 } | ||||
|                 if (ev.subflow) { | ||||
|                     if (ev.subflow.instances) { | ||||
|                         ev.subflow.instances.forEach(function(n) { | ||||
|                             var node = RED.nodes.node(n.id); | ||||
|                             if (node) { | ||||
|                                 node.changed = n.changed; | ||||
|                                 node.dirty = true; | ||||
|                             } | ||||
|                         }); | ||||
|                     } | ||||
|                     if (ev.subflow.hasOwnProperty('changed')) { | ||||
|                         subflow = RED.nodes.subflow(ev.subflow.id); | ||||
|                         if (subflow) { | ||||
|                             subflow.changed = ev.subflow.changed; | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|                 if (ev.removedLinks) { | ||||
|                     for (i=0;i<ev.removedLinks.length;i++) { | ||||
|                         RED.nodes.addLink(ev.removedLinks[i]); | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|             } else if (ev.t == "delete") { | ||||
|                 if (ev.workspaces) { | ||||
|                     for (i=0;i<ev.workspaces.length;i++) { | ||||
|                         RED.nodes.addWorkspace(ev.workspaces[i]); | ||||
|                         RED.workspaces.add(ev.workspaces[i]); | ||||
|                     } | ||||
|                 } | ||||
|                 if (ev.subflow && ev.subflow.subflow) { | ||||
|                     RED.nodes.addSubflow(ev.subflow.subflow); | ||||
|                 } | ||||
|                 if (ev.subflowInputs && ev.subflowInputs.length > 0) { | ||||
|                     subflow = RED.nodes.subflow(ev.subflowInputs[0].z); | ||||
|                     subflow.in.push(ev.subflowInputs[0]); | ||||
|                     subflow.in[0].dirty = true; | ||||
|                 } | ||||
|                 if (ev.subflowOutputs && ev.subflowOutputs.length > 0) { | ||||
|                     subflow = RED.nodes.subflow(ev.subflowOutputs[0].z); | ||||
|                     ev.subflowOutputs.sort(function(a,b) { return a.i-b.i}); | ||||
|                     for (i=0;i<ev.subflowOutputs.length;i++) { | ||||
|                         var output = ev.subflowOutputs[i]; | ||||
|                         subflow.out.splice(output.i,0,output); | ||||
|                         for (var j=output.i+1;j<subflow.out.length;j++) { | ||||
|                             subflow.out[j].i++; | ||||
|                             subflow.out[j].dirty = true; | ||||
|                         } | ||||
|                         RED.nodes.eachLink(function(l) { | ||||
|                             if (l.source.type == "subflow:"+subflow.id) { | ||||
|                                 if (l.sourcePort >= output.i) { | ||||
|                                     l.sourcePort++; | ||||
|                                 } | ||||
|                             } | ||||
|                         }); | ||||
|                     } | ||||
|                 } | ||||
|                 if (ev.subflow && ev.subflow.hasOwnProperty('instances')) { | ||||
|                     ev.subflow.instances.forEach(function(n) { | ||||
|                         var node = RED.nodes.node(n.id); | ||||
|                         if (node) { | ||||
|                             node.changed = n.changed; | ||||
|                             node.dirty = true; | ||||
|                         } | ||||
|                     }); | ||||
|                 } | ||||
|                 if (subflow) { | ||||
|                     RED.nodes.filterNodes({type:"subflow:"+subflow.id}).forEach(function(n) { | ||||
|                         n.inputs = subflow.in.length; | ||||
|                         n.outputs = subflow.out.length; | ||||
|                         while (n.outputs > n.ports.length) { | ||||
|                             n.ports.push(n.ports.length); | ||||
|                         } | ||||
|                         n.resize = true; | ||||
|                         n.dirty = true; | ||||
|                     }); | ||||
|                 } | ||||
|                 if (ev.nodes) { | ||||
|                     for (i=0;i<ev.nodes.length;i++) { | ||||
|                         RED.nodes.add(ev.nodes[i]); | ||||
|                         modifiedTabs[ev.nodes[i].z] = true; | ||||
|                     } | ||||
|                 } | ||||
|                 if (ev.links) { | ||||
|                     for (i=0;i<ev.links.length;i++) { | ||||
|                         RED.nodes.addLink(ev.links[i]); | ||||
|                     } | ||||
|                 } | ||||
|                 if (ev.changes) { | ||||
|                     for (i in ev.changes) { | ||||
|                         if (ev.changes.hasOwnProperty(i)) { | ||||
|                             node = RED.nodes.node(i); | ||||
|                             if (node) { | ||||
|                                 for (var d in ev.changes[i]) { | ||||
|                                     if (ev.changes[i].hasOwnProperty(d)) { | ||||
|                                         node[d] = ev.changes[i][d]; | ||||
|                                     } | ||||
|                                 } | ||||
|                                 node.dirty = true; | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|  | ||||
|                 } | ||||
|             } else if (ev.t == "move") { | ||||
|                 for (i=0;i<ev.nodes.length;i++) { | ||||
|                     var n = ev.nodes[i]; | ||||
|                     n.n.x = n.ox; | ||||
|                     n.n.y = n.oy; | ||||
|                     n.n.dirty = true; | ||||
|                     n.n.moved = n.moved; | ||||
|                 } | ||||
|                 // A move could have caused a link splice | ||||
|                 if (ev.links) { | ||||
|                     for (i=0;i<ev.links.length;i++) { | ||||
|                         RED.nodes.removeLink(ev.links[i]); | ||||
|                     } | ||||
|                 } | ||||
|                 if (ev.removedLinks) { | ||||
|                     for (i=0;i<ev.removedLinks.length;i++) { | ||||
|                         RED.nodes.addLink(ev.removedLinks[i]); | ||||
|                     } | ||||
|                 } | ||||
|             } else if (ev.t == "edit") { | ||||
|                 for (i in ev.changes) { | ||||
|                     if (ev.changes.hasOwnProperty(i)) { | ||||
|                         if (ev.node._def.defaults && ev.node._def.defaults[i] && ev.node._def.defaults[i].type) { | ||||
|                             // This is a config node property | ||||
|                             var currentConfigNode = RED.nodes.node(ev.node[i]); | ||||
|                             if (currentConfigNode) { | ||||
|                                 currentConfigNode.users.splice(currentConfigNode.users.indexOf(ev.node),1); | ||||
|                             } | ||||
|                             var newConfigNode = RED.nodes.node(ev.changes[i]); | ||||
|                             if (newConfigNode) { | ||||
|                                 newConfigNode.users.push(ev.node); | ||||
|                             } | ||||
|                         } | ||||
|                         ev.node[i] = ev.changes[i]; | ||||
|                     } | ||||
|                 } | ||||
|                 if (ev.subflow) { | ||||
|                     if (ev.subflow.hasOwnProperty('inputCount')) { | ||||
|                         if (ev.node.in.length > ev.subflow.inputCount) { | ||||
|                             ev.node.in.splice(ev.subflow.inputCount); | ||||
|                         } else if (ev.subflow.inputs.length > 0) { | ||||
|                             ev.node.in = ev.node.in.concat(ev.subflow.inputs); | ||||
|                         } | ||||
|                     } | ||||
|                     if (ev.subflow.hasOwnProperty('outputCount')) { | ||||
|                         if (ev.node.out.length > ev.subflow.outputCount) { | ||||
|                             ev.node.out.splice(ev.subflow.outputCount); | ||||
|                         } else if (ev.subflow.outputs.length > 0) { | ||||
|                             ev.node.out = ev.node.out.concat(ev.subflow.outputs); | ||||
|                         } | ||||
|                     } | ||||
|                     if (ev.subflow.hasOwnProperty('instances')) { | ||||
|                         ev.subflow.instances.forEach(function(n) { | ||||
|                             var node = RED.nodes.node(n.id); | ||||
|                             if (node) { | ||||
|                                 node.changed = n.changed; | ||||
|                                 node.dirty = true; | ||||
|                             } | ||||
|                         }); | ||||
|                     } | ||||
|                     RED.editor.validateNode(ev.node); | ||||
|                     RED.nodes.filterNodes({type:"subflow:"+ev.node.id}).forEach(function(n) { | ||||
|                         n.inputs = ev.node.in.length; | ||||
|                         n.outputs = ev.node.out.length; | ||||
|                         RED.editor.updateNodeProperties(n); | ||||
|                         RED.editor.validateNode(n); | ||||
|                     }); | ||||
|                 } else { | ||||
|                     var outputMap; | ||||
|                     if (ev.outputMap) { | ||||
|                         outputMap = {}; | ||||
|                         for (var port in ev.outputMap) { | ||||
|                             if (ev.outputMap.hasOwnProperty(port) && ev.outputMap[port] !== "-1") { | ||||
|                                 outputMap[ev.outputMap[port]] = port; | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                     RED.editor.updateNodeProperties(ev.node,outputMap); | ||||
|                     RED.editor.validateNode(ev.node); | ||||
|                 } | ||||
|                 if (ev.links) { | ||||
|                     for (i=0;i<ev.links.length;i++) { | ||||
|                         RED.nodes.addLink(ev.links[i]); | ||||
|                     } | ||||
|                 } | ||||
|                 ev.node.dirty = true; | ||||
|                 ev.node.changed = ev.changed; | ||||
|             } else if (ev.t == "createSubflow") { | ||||
|                 if (ev.nodes) { | ||||
|                     RED.nodes.filterNodes({z:ev.subflow.subflow.id}).forEach(function(n) { | ||||
|                         n.z = ev.activeWorkspace; | ||||
|                         n.dirty = true; | ||||
|                     }); | ||||
|                     for (i=0;i<ev.nodes.length;i++) { | ||||
|                         RED.nodes.remove(ev.nodes[i]); | ||||
|                     } | ||||
|                 } | ||||
|                 if (ev.links) { | ||||
|                     for (i=0;i<ev.links.length;i++) { | ||||
|                         RED.nodes.removeLink(ev.links[i]); | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 RED.nodes.removeSubflow(ev.subflow.subflow); | ||||
|                 RED.workspaces.remove(ev.subflow.subflow); | ||||
|  | ||||
|                 if (ev.removedLinks) { | ||||
|                     for (i=0;i<ev.removedLinks.length;i++) { | ||||
|                         RED.nodes.addLink(ev.removedLinks[i]); | ||||
|                     } | ||||
|                 } | ||||
|             } else if (ev.t == "reorder") { | ||||
|                 if (ev.order) { | ||||
|                     RED.workspaces.order(ev.order); | ||||
|                 } | ||||
|             } | ||||
|             Object.keys(modifiedTabs).forEach(function(id) { | ||||
|                 var subflow = RED.nodes.subflow(id); | ||||
|                 if (subflow) { | ||||
|                     RED.editor.validateNode(subflow); | ||||
|                 } | ||||
|             }); | ||||
|  | ||||
|             RED.nodes.dirty(ev.dirty); | ||||
|             RED.view.redraw(true); | ||||
|             RED.palette.refresh(); | ||||
|             RED.workspaces.refresh(); | ||||
|             RED.sidebar.config.refresh(); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     return { | ||||
|         //TODO: this function is a placeholder until there is a 'save' event that can be listened to | ||||
|         markAllDirty: function() { | ||||
|             for (var i=0;i<undo_history.length;i++) { | ||||
|                 undo_history[i].dirty = true; | ||||
|             } | ||||
|         }, | ||||
|         list: function() { | ||||
|             return undo_history | ||||
|         }, | ||||
|         depth: function() { | ||||
|             return undo_history.length; | ||||
|         }, | ||||
|         push: function(ev) { | ||||
|             undo_history.push(ev); | ||||
|         }, | ||||
|         pop: function() { | ||||
|             var ev = undo_history.pop(); | ||||
|             undoEvent(ev); | ||||
|         }, | ||||
|         peek: function() { | ||||
|             return undo_history[undo_history.length-1]; | ||||
|         }, | ||||
|         clear: function() { | ||||
|             undo_history = []; | ||||
|         } | ||||
|     } | ||||
|  | ||||
| })(); | ||||
							
								
								
									
										86
									
								
								editor/js/i18n.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,86 @@ | ||||
| /** | ||||
|  * 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.i18n = (function() { | ||||
|  | ||||
|     return { | ||||
|         init: function(done) { | ||||
|             i18n.init({ | ||||
|                 resGetPath: 'locales/__ns__?lng=__lng__', | ||||
|                 dynamicLoad: false, | ||||
|                 load:'current', | ||||
|                 ns: { | ||||
|                     namespaces: ["editor","node-red","jsonata","infotips"], | ||||
|                     defaultNs: "editor" | ||||
|                 }, | ||||
|                 fallbackLng: ['en-US'], | ||||
|                 useCookie: false | ||||
|             },function() { | ||||
|                 done(); | ||||
|             }); | ||||
|             RED["_"] = function() { | ||||
|                 return i18n.t.apply(null,arguments); | ||||
|             } | ||||
|  | ||||
|         }, | ||||
|         loadCatalog: function(namespace,done) { | ||||
|             var languageList = i18n.functions.toLanguages(i18n.detectLanguage()); | ||||
|             var toLoad = languageList.length; | ||||
|             languageList.forEach(function(lang) { | ||||
|                 $.ajax({ | ||||
|                     headers: { | ||||
|                         "Accept":"application/json" | ||||
|                     }, | ||||
|                     cache: false, | ||||
|                     url: 'locales/'+namespace+'?lng='+lang, | ||||
|                     success: function(data) { | ||||
|                         i18n.addResourceBundle(lang,namespace,data); | ||||
|                         toLoad--; | ||||
|                         if (toLoad === 0) { | ||||
|                             done(); | ||||
|                         } | ||||
|                     } | ||||
|                 }); | ||||
|             }) | ||||
|  | ||||
|         }, | ||||
|  | ||||
|         loadNodeCatalogs: function(done) { | ||||
|             var languageList = i18n.functions.toLanguages(i18n.detectLanguage()); | ||||
|             var toLoad = languageList.length; | ||||
|  | ||||
|             languageList.forEach(function(lang) { | ||||
|                 $.ajax({ | ||||
|                     headers: { | ||||
|                         "Accept":"application/json" | ||||
|                     }, | ||||
|                     cache: false, | ||||
|                     url: 'locales/nodes?lng='+lang, | ||||
|                     success: function(data) { | ||||
|                         var namespaces = Object.keys(data); | ||||
|                         namespaces.forEach(function(ns) { | ||||
|                             i18n.addResourceBundle(lang,ns,data[ns]); | ||||
|                         }); | ||||
|                         toLoad--; | ||||
|                         if (toLoad === 0) { | ||||
|                             done(); | ||||
|                         } | ||||
|                     } | ||||
|                 }); | ||||
|             }) | ||||
|         } | ||||
|     } | ||||
| })(); | ||||
							
								
								
									
										43
									
								
								editor/js/keymap.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,43 @@ | ||||
| { | ||||
|     "*": { | ||||
|         "ctrl-shift-p":"core:manage-palette", | ||||
|         "ctrl-f": "core:search", | ||||
|         "ctrl-=": "core:zoom-in", | ||||
|         "ctrl--": "core:zoom-out", | ||||
|         "ctrl-0": "core:zoom-reset", | ||||
|         "ctrl-enter": "core:confirm-edit-tray", | ||||
|         "ctrl-escape": "core:cancel-edit-tray", | ||||
|         "ctrl-g i": "core:show-info-tab", | ||||
|         "ctrl-g d": "core:show-debug-tab", | ||||
|         "ctrl-g c": "core:show-config-tab", | ||||
|         "ctrl-e": "core:show-export-dialog", | ||||
|         "ctrl-i": "core:show-import-dialog", | ||||
|         "ctrl-space": "core:toggle-sidebar", | ||||
|         "ctrl-,": "core:show-user-settings", | ||||
|         "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" | ||||
|     }, | ||||
|     "workspace": { | ||||
|         "backspace": "core:delete-selection", | ||||
|         "delete": "core:delete-selection", | ||||
|         "enter": "core:edit-selected-node", | ||||
|         "ctrl-c": "core:copy-selection-to-internal-clipboard", | ||||
|         "ctrl-x": "core:cut-selection-to-internal-clipboard", | ||||
|         "ctrl-v": "core:paste-from-internal-clipboard", | ||||
|         "ctrl-z": "core:undo", | ||||
|         "ctrl-a": "core:select-all-nodes", | ||||
|         "shift-?": "core:show-help", | ||||
|         "up": "core:move-selection-up", | ||||
|         "right": "core:move-selection-right", | ||||
|         "down": "core:move-selection-down", | ||||
|         "left": "core:move-selection-left", | ||||
|         "shift-up": "core:step-selection-up", | ||||
|         "shift-right": "core:step-selection-right", | ||||
|         "shift-down": "core:step-selection-down", | ||||
|         "shift-left": "core:step-selection-left", | ||||
|         "ctrl-shift-j": "core:show-previous-tab", | ||||
|         "ctrl-shift-k": "core:show-next-tab" | ||||
|      } | ||||
| } | ||||
							
								
								
									
										501
									
								
								editor/js/main.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,501 @@ | ||||
| /** | ||||
|  * 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() { | ||||
|  | ||||
|     function appendNodeConfig(nodeConfig) { | ||||
|         var m = /<!-- --- \[red-module:(\S+)\] --- -->/.exec(nodeConfig.trim()); | ||||
|         var moduleId; | ||||
|         if (m) { | ||||
|             moduleId = m[1]; | ||||
|         } else { | ||||
|             moduleId = "unknown"; | ||||
|         } | ||||
|         try { | ||||
|             $("body").append(nodeConfig); | ||||
|         } catch(err) { | ||||
|             RED.notify(RED._("notification.errors.failedToAppendNode",{module:moduleId, error:err.toString()}),{ | ||||
|                 type: "error", | ||||
|                 timeout: 10000 | ||||
|             }); | ||||
|             console.log("["+moduleId+"] "+err.toString()); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     function loadNodeList() { | ||||
|         $.ajax({ | ||||
|             headers: { | ||||
|                 "Accept":"application/json" | ||||
|             }, | ||||
|             cache: false, | ||||
|             url: 'nodes', | ||||
|             success: function(data) { | ||||
|                 RED.nodes.setNodeList(data); | ||||
|                 RED.i18n.loadNodeCatalogs(function() { | ||||
|                     loadIconList(loadNodes); | ||||
|                 }); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     function loadIconList(done) { | ||||
|         $.ajax({ | ||||
|             headers: { | ||||
|                 "Accept":"application/json" | ||||
|             }, | ||||
|             cache: false, | ||||
|             url: 'icons', | ||||
|             success: function(data) { | ||||
|                 RED.nodes.setIconSets(data); | ||||
|                 if (done) { | ||||
|                     done(); | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     function loadNodes() { | ||||
|         $.ajax({ | ||||
|             headers: { | ||||
|                 "Accept":"text/html" | ||||
|             }, | ||||
|             cache: false, | ||||
|             url: 'nodes', | ||||
|             success: function(data) { | ||||
|                 var configs = data.trim().split(/(?=<!-- --- \[red-module:\S+\] --- -->)/); | ||||
|                 configs.forEach(function(data) { | ||||
|                     appendNodeConfig(data); | ||||
|                 }); | ||||
|  | ||||
|                 $("body").i18n(); | ||||
|                 $("#palette > .palette-spinner").hide(); | ||||
|                 $(".palette-scroll").removeClass("hide"); | ||||
|                 $("#palette-search").removeClass("hide"); | ||||
|                 loadFlows(function() { | ||||
|                     if (RED.settings.theme("projects.enabled",false)) { | ||||
|                         RED.projects.refresh(function(activeProject) { | ||||
|                             RED.sidebar.info.refresh() | ||||
|                             if (!activeProject) { | ||||
|                                 // Projects enabled but no active project | ||||
|                                 RED.menu.setDisabled('menu-item-projects-open',true); | ||||
|                                 RED.menu.setDisabled('menu-item-projects-settings',true); | ||||
|                                 if (activeProject === false) { | ||||
|                                     // User previously decline the migration to projects. | ||||
|                                 } else { // null/undefined | ||||
|                                     RED.projects.showStartup(); | ||||
|                                 } | ||||
|                             } | ||||
|                             completeLoad(); | ||||
|                         }); | ||||
|                     } else { | ||||
|                         // Projects disabled by the user | ||||
|                         RED.sidebar.info.refresh() | ||||
|                         completeLoad(); | ||||
|                     } | ||||
|                 }); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     function loadFlows(done) { | ||||
|         $.ajax({ | ||||
|             headers: { | ||||
|                 "Accept":"application/json", | ||||
|             }, | ||||
|             cache: false, | ||||
|             url: 'flows', | ||||
|             success: function(nodes) { | ||||
|                 if (nodes) { | ||||
|                     var currentHash = window.location.hash; | ||||
|                     RED.nodes.version(nodes.rev); | ||||
|                     RED.nodes.import(nodes.flows); | ||||
|                     RED.nodes.dirty(false); | ||||
|                     RED.view.redraw(true); | ||||
|                     if (/^#flow\/.+$/.test(currentHash)) { | ||||
|                         RED.workspaces.show(currentHash.substring(6)); | ||||
|                     } | ||||
|                 } | ||||
|                 done(); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     function completeLoad() { | ||||
|         var persistentNotifications = {}; | ||||
|         RED.comms.subscribe("notification/#",function(topic,msg) { | ||||
|             var parts = topic.split("/"); | ||||
|             var notificationId = parts[1]; | ||||
|             if (notificationId === "runtime-deploy") { | ||||
|                 // handled in ui/deploy.js | ||||
|                 return; | ||||
|             } | ||||
|             if (notificationId === "node") { | ||||
|                 // handled below | ||||
|                 return; | ||||
|             } | ||||
|             if (notificationId === "project-update") { | ||||
|                 RED.nodes.clear(); | ||||
|                 RED.history.clear(); | ||||
|                 RED.view.redraw(true); | ||||
|                 RED.projects.refresh(function() { | ||||
|                     loadFlows(function() { | ||||
|                         var project = RED.projects.getActiveProject(); | ||||
|                         var message = { | ||||
|                             "change-branch": RED._("notification.project.change-branch", {project: project.git.branches.local}), | ||||
|                             "merge-abort": RED._("notification.project.merge-abort"), | ||||
|                             "loaded": RED._("notification.project.loaded", {project: msg.project}), | ||||
|                             "updated": RED._("notification.project.updated", {project: msg.project}), | ||||
|                             "pull": RED._("notification.project.pull", {project: msg.project}), | ||||
|                             "revert": RED._("notification.project.revert", {project: msg.project}), | ||||
|                             "merge-complete": RED._("notification.project.merge-complete") | ||||
|                         }[msg.action]; | ||||
|                         RED.notify("<p>"+message+"</p>"); | ||||
|                         RED.sidebar.info.refresh() | ||||
|                     }); | ||||
|                 }); | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             if (msg.text) { | ||||
|                 msg.default = msg.text; | ||||
|                 var text = RED._(msg.text,msg); | ||||
|                 var options = { | ||||
|                     type: msg.type, | ||||
|                     fixed: msg.timeout === undefined, | ||||
|                     timeout: msg.timeout, | ||||
|                     id: notificationId | ||||
|                 } | ||||
|                 if (notificationId === "runtime-state") { | ||||
|                     if (msg.error === "missing-types") { | ||||
|                         text+="<ul><li>"+msg.types.join("</li><li>")+"</li></ul>"; | ||||
|                         if (!!RED.projects.getActiveProject()) { | ||||
|                             options.buttons = [ | ||||
|                                 { | ||||
|                                     text: RED._("notification.label.manage-project-dep"), | ||||
|                                     click: function() { | ||||
|                                         persistentNotifications[notificationId].hideNotification(); | ||||
|                                         RED.projects.settings.show('deps'); | ||||
|                                     } | ||||
|                                 } | ||||
|                             ] | ||||
|                         // } else if (RED.settings.theme('palette.editable') !== false) { | ||||
|                         } else { | ||||
|                             options.buttons = [ | ||||
|                                 { | ||||
|                                     text: RED._("common.label.close"), | ||||
|                                     click: function() { | ||||
|                                         persistentNotifications[notificationId].hideNotification(); | ||||
|                                     } | ||||
|                                 } | ||||
|                             ] | ||||
|                         } | ||||
|                     } else if (msg.error === "credentials_load_failed") { | ||||
|                         if (RED.settings.theme("projects.enabled",false)) { | ||||
|                             // projects enabled | ||||
|                             if (RED.user.hasPermission("projects.write")) { | ||||
|                                 options.buttons = [ | ||||
|                                     { | ||||
|                                         text: RED._("notification.label.setup-cred"), | ||||
|                                         click: function() { | ||||
|                                             persistentNotifications[notificationId].hideNotification(); | ||||
|                                             RED.projects.showCredentialsPrompt(); | ||||
|                                         } | ||||
|                                     } | ||||
|                                 ] | ||||
|                             } | ||||
|                         } else { | ||||
|                             options.buttons = [ | ||||
|                                 { | ||||
|                                     text: RED._("common.label.close"), | ||||
|                                     click: function() { | ||||
|                                         persistentNotifications[notificationId].hideNotification(); | ||||
|                                     } | ||||
|                                 } | ||||
|                             ] | ||||
|                         } | ||||
|                     } else if (msg.error === "missing_flow_file") { | ||||
|                         if (RED.user.hasPermission("projects.write")) { | ||||
|                             options.buttons = [ | ||||
|                                 { | ||||
|                                     text: RED._("notification.label.setup-project"), | ||||
|                                     click: function() { | ||||
|                                         persistentNotifications[notificationId].hideNotification(); | ||||
|                                         RED.projects.showFilesPrompt(); | ||||
|                                     } | ||||
|                                 } | ||||
|                             ] | ||||
|                         } | ||||
|                     } else if (msg.error === "missing_package_file") { | ||||
|                         if (RED.user.hasPermission("projects.write")) { | ||||
|                             options.buttons = [ | ||||
|                                 { | ||||
|                                     text: RED._("notification.label.create-default-package"), | ||||
|                                     click: function() { | ||||
|                                         persistentNotifications[notificationId].hideNotification(); | ||||
|                                         RED.projects.createDefaultPackageFile(); | ||||
|                                     } | ||||
|                                 } | ||||
|                             ] | ||||
|                         } | ||||
|                     } else if (msg.error === "project_empty") { | ||||
|                         if (RED.user.hasPermission("projects.write")) { | ||||
|                             options.buttons = [ | ||||
|                                 { | ||||
|                                     text: RED._("notification.label.no-thanks"), | ||||
|                                     click: function() { | ||||
|                                         persistentNotifications[notificationId].hideNotification(); | ||||
|                                     } | ||||
|                                 }, | ||||
|                                 { | ||||
|                                     text: RED._("notification.label.create-default-project"), | ||||
|                                     click: function() { | ||||
|                                         persistentNotifications[notificationId].hideNotification(); | ||||
|                                         RED.projects.createDefaultFileSet(); | ||||
|                                     } | ||||
|                                 } | ||||
|                             ] | ||||
|                         } | ||||
|                     } else if (msg.error === "git_merge_conflict") { | ||||
|                         RED.nodes.clear(); | ||||
|                         RED.sidebar.versionControl.refresh(true); | ||||
|                         if (RED.user.hasPermission("projects.write")) { | ||||
|                             options.buttons = [ | ||||
|                                 { | ||||
|                                     text: RED._("notification.label.show-merge-conflicts"), | ||||
|                                     click: function() { | ||||
|                                         persistentNotifications[notificationId].hideNotification(); | ||||
|                                         RED.sidebar.versionControl.showLocalChanges(); | ||||
|                                     } | ||||
|                                 } | ||||
|                             ] | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|                 if (!persistentNotifications.hasOwnProperty(notificationId)) { | ||||
|                     persistentNotifications[notificationId] = RED.notify(text,options); | ||||
|                 } else { | ||||
|                     persistentNotifications[notificationId].update(text,options); | ||||
|                 } | ||||
|             } else if (persistentNotifications.hasOwnProperty(notificationId)) { | ||||
|                 persistentNotifications[notificationId].close(); | ||||
|                 delete persistentNotifications[notificationId]; | ||||
|             } | ||||
|         }); | ||||
|         RED.comms.subscribe("status/#",function(topic,msg) { | ||||
|             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()}); | ||||
|                     } | ||||
|                 } | ||||
|                 node.status = msg; | ||||
|                 node.dirty = true; | ||||
|                 RED.view.redraw(); | ||||
|             } | ||||
|         }); | ||||
|         RED.comms.subscribe("notification/node/#",function(topic,msg) { | ||||
|             var i,m; | ||||
|             var typeList; | ||||
|             var info; | ||||
|             if (topic == "notification/node/added") { | ||||
|                 var addedTypes = []; | ||||
|                 msg.forEach(function(m) { | ||||
|                     var id = m.id; | ||||
|                     RED.nodes.addNodeSet(m); | ||||
|                     addedTypes = addedTypes.concat(m.types); | ||||
|                     RED.i18n.loadCatalog(id, function() { | ||||
|                         $.get('nodes/'+id, function(data) { | ||||
|                             appendNodeConfig(data); | ||||
|                         }); | ||||
|                     }); | ||||
|                 }); | ||||
|                 if (addedTypes.length) { | ||||
|                     typeList = "<ul><li>"+addedTypes.join("</li><li>")+"</li></ul>"; | ||||
|                     RED.notify(RED._("palette.event.nodeAdded", {count:addedTypes.length})+typeList,"success"); | ||||
|                 } | ||||
|                 loadIconList(); | ||||
|             } else if (topic == "notification/node/removed") { | ||||
|                 for (i=0;i<msg.length;i++) { | ||||
|                     m = msg[i]; | ||||
|                     info = RED.nodes.removeNodeSet(m.id); | ||||
|                     if (info.added) { | ||||
|                         typeList = "<ul><li>"+m.types.join("</li><li>")+"</li></ul>"; | ||||
|                         RED.notify(RED._("palette.event.nodeRemoved", {count:m.types.length})+typeList,"success"); | ||||
|                     } | ||||
|                 } | ||||
|                 loadIconList(); | ||||
|             } else if (topic == "notification/node/enabled") { | ||||
|                 if (msg.types) { | ||||
|                     info = RED.nodes.getNodeSet(msg.id); | ||||
|                     if (info.added) { | ||||
|                         RED.nodes.enableNodeSet(msg.id); | ||||
|                         typeList = "<ul><li>"+msg.types.join("</li><li>")+"</li></ul>"; | ||||
|                         RED.notify(RED._("palette.event.nodeEnabled", {count:msg.types.length})+typeList,"success"); | ||||
|                     } else { | ||||
|                         $.get('nodes/'+msg.id, function(data) { | ||||
|                             appendNodeConfig(data); | ||||
|                             typeList = "<ul><li>"+msg.types.join("</li><li>")+"</li></ul>"; | ||||
|                             RED.notify(RED._("palette.event.nodeAdded", {count:msg.types.length})+typeList,"success"); | ||||
|                         }); | ||||
|                     } | ||||
|                 } | ||||
|             } else if (topic == "notification/node/disabled") { | ||||
|                 if (msg.types) { | ||||
|                     RED.nodes.disableNodeSet(msg.id); | ||||
|                     typeList = "<ul><li>"+msg.types.join("</li><li>")+"</li></ul>"; | ||||
|                     RED.notify(RED._("palette.event.nodeDisabled", {count:msg.types.length})+typeList,"success"); | ||||
|                 } | ||||
|             } else if (topic == "node/upgraded") { | ||||
|                 RED.notify(RED._("palette.event.nodeUpgraded", {module:msg.module,version:msg.version}),"success"); | ||||
|                 RED.nodes.registry.setModulePendingUpdated(msg.module,msg.version); | ||||
|             } | ||||
|             // Refresh flow library to ensure any examples are updated | ||||
|             RED.library.loadFlowLibrary(); | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     function showAbout() { | ||||
|         $.get('red/about', function(data) { | ||||
|             var aboutHeader = '<div style="text-align:center;">'+ | ||||
|                                 '<img width="50px" src="red/images/node-red-icon.svg" />'+ | ||||
|                               '</div>'; | ||||
|  | ||||
|             RED.sidebar.info.set(aboutHeader+marked(data)); | ||||
|             RED.sidebar.info.show(); | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     function loadEditor() { | ||||
|         var menuOptions = []; | ||||
|         if (RED.settings.theme("projects.enabled",false)) { | ||||
|             menuOptions.push({id:"menu-item-projects-menu",label:RED._("menu.label.projects"),options:[ | ||||
|                 {id:"menu-item-projects-new",label:RED._("menu.label.projects-new"),disabled:false,onselect:"core:new-project"}, | ||||
|                 {id:"menu-item-projects-open",label:RED._("menu.label.projects-open"),disabled:false,onselect:"core:open-project"}, | ||||
|                 {id:"menu-item-projects-settings",label:RED._("menu.label.projects-settings"),disabled:false,onselect:"core:show-project-settings"} | ||||
|             ]}); | ||||
|         } | ||||
|  | ||||
|  | ||||
|         menuOptions.push({id:"menu-item-view-menu",label:RED._("menu.label.view.view"),options:[ | ||||
|             // {id:"menu-item-view-show-grid",setting:"view-show-grid",label:RED._("menu.label.view.showGrid"),toggle:true,onselect:"core:toggle-show-grid"}, | ||||
|             // {id:"menu-item-view-snap-grid",setting:"view-snap-grid",label:RED._("menu.label.view.snapGrid"),toggle:true,onselect:"core:toggle-snap-grid"}, | ||||
|             // {id:"menu-item-status",setting:"node-show-status",label:RED._("menu.label.displayStatus"),toggle:true,onselect:"core:toggle-status", selected: true}, | ||||
|             //null, | ||||
|             // {id:"menu-item-bidi",label:RED._("menu.label.view.textDir"),options:[ | ||||
|             //     {id:"menu-item-bidi-default",toggle:"text-direction",label:RED._("menu.label.view.defaultDir"),selected: true, onselect:function(s) { if(s){RED.text.bidi.setTextDirection("")}}}, | ||||
|             //     {id:"menu-item-bidi-ltr",toggle:"text-direction",label:RED._("menu.label.view.ltr"), onselect:function(s) { if(s){RED.text.bidi.setTextDirection("ltr")}}}, | ||||
|             //     {id:"menu-item-bidi-rtl",toggle:"text-direction",label:RED._("menu.label.view.rtl"), onselect:function(s) { if(s){RED.text.bidi.setTextDirection("rtl")}}}, | ||||
|             //     {id:"menu-item-bidi-auto",toggle:"text-direction",label:RED._("menu.label.view.auto"), onselect:function(s) { if(s){RED.text.bidi.setTextDirection("auto")}}} | ||||
|             // ]}, | ||||
|             // null, | ||||
|             {id:"menu-item-sidebar",label:RED._("menu.label.sidebar.show"),toggle:true,onselect:"core:toggle-sidebar", selected: true}, | ||||
|             null | ||||
|         ]}); | ||||
|         menuOptions.push(null); | ||||
|         menuOptions.push({id:"menu-item-import",label:RED._("menu.label.import"),options:[ | ||||
|             {id:"menu-item-import-clipboard",label:RED._("menu.label.clipboard"),onselect:"core:show-import-dialog"}, | ||||
|             {id:"menu-item-import-library",label:RED._("menu.label.library"),options:[]} | ||||
|         ]}); | ||||
|         menuOptions.push({id:"menu-item-export",label:RED._("menu.label.export"),options:[ | ||||
|             {id:"menu-item-export-clipboard",label:RED._("menu.label.clipboard"),onselect:"core:show-export-dialog"}, | ||||
|             {id:"menu-item-export-library",label:RED._("menu.label.library"),disabled:true,onselect:"core:library-export"} | ||||
|         ]}); | ||||
|         menuOptions.push(null); | ||||
|         menuOptions.push({id:"menu-item-search",label:RED._("menu.label.search"),onselect:"core:search"}); | ||||
|         menuOptions.push(null); | ||||
|         menuOptions.push({id:"menu-item-config-nodes",label:RED._("menu.label.displayConfig"),onselect:"core:show-config-tab"}); | ||||
|         menuOptions.push({id:"menu-item-workspace",label:RED._("menu.label.flows"),options:[ | ||||
|             {id:"menu-item-workspace-add",label:RED._("menu.label.add"),onselect:"core:add-flow"}, | ||||
|             {id:"menu-item-workspace-edit",label:RED._("menu.label.rename"),onselect:"core:edit-flow"}, | ||||
|             {id:"menu-item-workspace-delete",label:RED._("menu.label.delete"),onselect:"core:remove-flow"} | ||||
|         ]}); | ||||
|         menuOptions.push({id:"menu-item-subflow",label:RED._("menu.label.subflows"), options: [ | ||||
|             {id:"menu-item-subflow-create",label:RED._("menu.label.createSubflow"),onselect:"core:create-subflow"}, | ||||
|             {id:"menu-item-subflow-convert",label:RED._("menu.label.selectionToSubflow"),disabled:true,onselect:"core:convert-to-subflow"}, | ||||
|         ]}); | ||||
|         menuOptions.push(null); | ||||
|         if (RED.settings.theme('palette.editable') !== false) { | ||||
|             menuOptions.push({id:"menu-item-edit-palette",label:RED._("menu.label.editPalette"),onselect:"core:manage-palette"}); | ||||
|             menuOptions.push(null); | ||||
|         } | ||||
|  | ||||
|         menuOptions.push({id:"menu-item-user-settings",label:RED._("menu.label.settings"),onselect:"core:show-user-settings"}); | ||||
|         menuOptions.push(null); | ||||
|  | ||||
|         menuOptions.push({id:"menu-item-keyboard-shortcuts",label:RED._("menu.label.keyboardShortcuts"),onselect:"core:show-help"}); | ||||
|         menuOptions.push({id:"menu-item-help", | ||||
|             label: RED.settings.theme("menu.menu-item-help.label",RED._("menu.label.help")), | ||||
|             href: RED.settings.theme("menu.menu-item-help.url","http://nodered.org/docs") | ||||
|         }); | ||||
|         menuOptions.push({id:"menu-item-node-red-version", label:"v"+RED.settings.version, onselect: "core:show-about" }); | ||||
|  | ||||
|  | ||||
|         RED.view.init(); | ||||
|         RED.userSettings.init(); | ||||
|         RED.user.init(); | ||||
|         RED.library.init(); | ||||
|         RED.keyboard.init(); | ||||
|         RED.palette.init(); | ||||
|         if (RED.settings.theme('palette.editable') !== false) { | ||||
|             RED.palette.editor.init(); | ||||
|         } else { | ||||
|             console.log("Palette editor disabled"); | ||||
|         } | ||||
|  | ||||
|         RED.sidebar.init(); | ||||
|  | ||||
|         if (RED.settings.theme("projects.enabled",false)) { | ||||
|             RED.projects.init(); | ||||
|         } else { | ||||
|             console.log("Projects disabled"); | ||||
|         } | ||||
|  | ||||
|         RED.subflow.init(); | ||||
|         RED.workspaces.init(); | ||||
|         RED.clipboard.init(); | ||||
|         RED.search.init(); | ||||
|         RED.editor.init(); | ||||
|         RED.diff.init(); | ||||
|  | ||||
|         RED.menu.init({id:"btn-sidemenu",options: menuOptions}); | ||||
|  | ||||
|         RED.deploy.init(RED.settings.theme("deployButton",null)); | ||||
|         RED.notifications.init(); | ||||
|  | ||||
|         RED.actions.add("core:show-about", showAbout); | ||||
|         RED.nodes.init(); | ||||
|         RED.comms.connect(); | ||||
|  | ||||
|         $("#main-container").show(); | ||||
|         $(".header-toolbar").show(); | ||||
|  | ||||
|         loadNodeList(); | ||||
|     } | ||||
|  | ||||
|     $(function() { | ||||
|  | ||||
|         if ((window.location.hostname !== "localhost") && (window.location.hostname !== "127.0.0.1")) { | ||||
|             document.title = document.title+" : "+window.location.hostname; | ||||
|         } | ||||
|  | ||||
|         ace.require("ace/ext/language_tools"); | ||||
|  | ||||
|         RED.i18n.init(function() { | ||||
|             RED.settings.init(loadEditor); | ||||
|         }) | ||||
|     }); | ||||
| })(); | ||||
							
								
								
									
										1422
									
								
								editor/js/nodes.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -13,5 +13,4 @@ | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  **/ | ||||
| 
 | ||||
| module.exports = false | ||||
| var RED = {}; | ||||
| @@ -19,6 +19,7 @@ RED.settings = (function () { | ||||
| 
 | ||||
|     var loadedSettings = {}; | ||||
|     var userSettings = {}; | ||||
|     var settingsDirty = false; | ||||
|     var pendingSave; | ||||
| 
 | ||||
|     var hasLocalStorage = function () { | ||||
| @@ -36,7 +37,7 @@ RED.settings = (function () { | ||||
|         if (key === "auth-tokens") { | ||||
|             localStorage.setItem(key, JSON.stringify(value)); | ||||
|         } else { | ||||
|             RED.utils.setMessageProperty(userSettings,key,value); | ||||
|             userSettings[key] = value; | ||||
|             saveUserSettings(); | ||||
|         } | ||||
|     }; | ||||
| @@ -45,25 +46,16 @@ 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,defaultIfUndefined) { | ||||
|     var get = function (key) { | ||||
|         if (!hasLocalStorage()) { | ||||
|             return undefined; | ||||
|         } | ||||
|         if (key === "auth-tokens") { | ||||
|             return JSON.parse(localStorage.getItem(key)); | ||||
|         } else { | ||||
|             var v; | ||||
|             try { v = RED.utils.getMessageProperty(userSettings,key); } catch(err) {} | ||||
|             if (v === undefined) { | ||||
|                 try { v = RED.utils.getMessageProperty(RED.settings,key); } catch(err) {} | ||||
|             } | ||||
|             if (v === undefined) { | ||||
|                 v = defaultIfUndefined; | ||||
|             } | ||||
|             return v; | ||||
|             return userSettings[key]; | ||||
|         } | ||||
|     }; | ||||
| 
 | ||||
| @@ -97,22 +89,18 @@ RED.settings = (function () { | ||||
|         userSettings = data; | ||||
|     } | ||||
| 
 | ||||
|     var init = function (options, done) { | ||||
|     var init = function (done) { | ||||
|         var accessTokenMatch = /[?&]access_token=(.*?)(?:$|&)/.exec(window.location.search); | ||||
|         if (accessTokenMatch) { | ||||
|             var accessToken = accessTokenMatch[1]; | ||||
|             RED.settings.set("auth-tokens",{access_token: accessToken}); | ||||
|             window.location.search = ""; | ||||
|         } | ||||
|         RED.settings.apiRootUrl = options.apiRootUrl; | ||||
| 
 | ||||
|         $.ajaxSetup({ | ||||
|             beforeSend: function(jqXHR,settings) { | ||||
|                 // Only attach auth header for requests to relative paths
 | ||||
|                 if (!/^\s*(https?:|\/|\.)/.test(settings.url)) { | ||||
|                     if (options.apiRootUrl) { | ||||
|                         settings.url = options.apiRootUrl+settings.url; | ||||
|                     } | ||||
|                     var auth_tokens = RED.settings.get("auth-tokens"); | ||||
|                     if (auth_tokens) { | ||||
|                         jqXHR.setRequestHeader("Authorization","Bearer "+auth_tokens.access_token); | ||||
| @@ -125,7 +113,7 @@ RED.settings = (function () { | ||||
|         load(done); | ||||
|     } | ||||
| 
 | ||||
|     var refreshSettings = function(done) { | ||||
|     var load = function(done) { | ||||
|         $.ajax({ | ||||
|             headers: { | ||||
|                 "Accept": "application/json" | ||||
| @@ -135,37 +123,23 @@ RED.settings = (function () { | ||||
|             url: 'settings', | ||||
|             success: function (data) { | ||||
|                 setProperties(data); | ||||
|                 done(null, data); | ||||
|                 if (!RED.settings.user || RED.settings.user.anonymous) { | ||||
|                     RED.settings.remove("auth-tokens"); | ||||
|                 } | ||||
|                 console.log("Node-RED: " + data.version); | ||||
|                 loadUserSettings(done); | ||||
|             }, | ||||
|             error: function(jqXHR,textStatus,errorThrown) { | ||||
|                 if (jqXHR.status === 401) { | ||||
|                     if (/[?&]access_token=(.*?)(?:$|&)/.test(window.location.search)) { | ||||
|                         window.location.search = ""; | ||||
|                     } | ||||
|                     RED.user.login(function() { refreshSettings(done); }); | ||||
|                     RED.user.login(function() { load(done); }); | ||||
|                 } else { | ||||
|                     console.log("Unexpected error loading settings:",jqXHR.status,textStatus); | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
|     var load = function(done) { | ||||
|         refreshSettings(function(err, data) { | ||||
|             if (!err) { | ||||
|                 if (!RED.settings.user || RED.settings.user.anonymous) { | ||||
|                     RED.settings.remove("auth-tokens"); | ||||
|                 } | ||||
|                 console.log("Node-RED: " + data.version); | ||||
|                 console.groupCollapsed("Versions"); | ||||
|                 console.log("jQuery",$().jquery) | ||||
|                 console.log("jQuery UI",$.ui.version); | ||||
|                 if(window.ace) { console.log("ACE",ace.version); } | ||||
|                 if(window.monaco) { console.log("MONACO",monaco.version || "unknown"); } | ||||
|                 console.log("D3",d3.version); | ||||
|                 console.groupEnd(); | ||||
|                 loadUserSettings(done); | ||||
|             } | ||||
|         }) | ||||
|     }; | ||||
| 
 | ||||
|     function loadUserSettings(done) { | ||||
| @@ -226,28 +200,14 @@ RED.settings = (function () { | ||||
|             return defaultValue; | ||||
|         } | ||||
|     } | ||||
|     function getLocal(key) { | ||||
|         return localStorage.getItem(key) | ||||
|     } | ||||
|     function setLocal(key, value) { | ||||
|         localStorage.setItem(key, value); | ||||
|     } | ||||
|     function removeLocal(key) { | ||||
|         localStorage.removeItem(key) | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     return { | ||||
|         init: init, | ||||
|         load: load, | ||||
|         loadUserSettings: loadUserSettings, | ||||
|         refreshSettings: refreshSettings, | ||||
|         set: set, | ||||
|         get: get, | ||||
|         remove: remove, | ||||
|         theme: theme, | ||||
|         setLocal: setLocal, | ||||
|         getLocal: getLocal, | ||||
|         removeLocal: removeLocal | ||||
|         theme: theme | ||||
|     } | ||||
| })(); | ||||
| @@ -97,14 +97,14 @@ RED.text.bidi = (function() { | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Enforces the text direction for all the spans with style red-ui-text-bidi-aware under | ||||
|      * Enforces the text direction for all the spans with style bidiAware under | ||||
|      * workspace or sidebar div | ||||
|      */ | ||||
|     function enforceTextDirectionOnPage() { | ||||
|         $("#red-ui-workspace").find('span.red-ui-text-bidi-aware').each(function() { | ||||
|         $("#workspace").find('span.bidiAware').each(function() { | ||||
|             $(this).attr("dir", resolveBaseTextDir($(this).html())); | ||||
|         }); | ||||
|         $("#red-ui-sidebar").find('span.red-ui-text-bidi-aware').each(function() { | ||||
|         $("#sidebar").find('span.bidiAware').each(function() { | ||||
|             $(this).attr("dir", resolveBaseTextDir($(this).text())); | ||||
|         }); | ||||
|     } | ||||
| @@ -1242,7 +1242,7 @@ RED.text.format = (function() { | ||||
|             element.dispatchEvent(event); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|          | ||||
|         var range = selection.getRangeAt(0); | ||||
|         var tempRange = range.cloneRange(), startNode, startOffset; | ||||
|         startNode = range.startContainer; | ||||
| @@ -1304,7 +1304,7 @@ RED.text.format = (function() { | ||||
|     } | ||||
| 
 | ||||
|     return { | ||||
|         /*! | ||||
|         /** | ||||
|         * Returns the HTML representation of a given structured text | ||||
|         * @param text - the structured text | ||||
|         * @param type - could be one of filepath, url, email | ||||
| @@ -1315,7 +1315,7 @@ RED.text.format = (function() { | ||||
|         getHtml: function (text, type, args, isRtl, locale) { | ||||
|             return getHandler(type).format(text, args, isRtl, true, locale); | ||||
|         }, | ||||
|         /*! | ||||
|         /** | ||||
|         * Handle Structured text correct display for a given HTML element. | ||||
|         * @param element - the element  : should be of type div contenteditable=true | ||||
|         * @param type - could be one of filepath, url, email | ||||