diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 000000000..6f4000e54 --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,30 @@ +## 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 [mailing list](https://groups.google.com/forum/#!forum/node-red), [slack team](https://nodered.org/slack) or ask 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: diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 000000000..cf5fefe4f --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,30 @@ +## Before you hit that Submit button.... + +Please read our [contribution guidelines](https://github.com/node-red/node-red/blob/master/CONTRIBUTING.md) +before submitting a pull-request. + +## Types of changes + +What types of changes does your code introduce? +_Put an `x` in the boxes that apply_ + +- [ ] Bugfix (non-breaking change which fixes an issue) +- [ ] New feature (non-breaking change which adds functionality) + +If you want to raise a pull-request with a new feature, or a refactoring +of existing code, it **may well get rejected** if it hasn't been discussed on +the [mailing list](https://groups.google.com/forum/#!forum/node-red) or +[slack team](https://nodered.org/slack) first. + + +## Proposed changes + +Describe the nature of this change. What problem does it address? + +## Checklist +_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 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 diff --git a/.travis.yml b/.travis.yml index 574685a99..03dd0938c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,7 +11,6 @@ addons: - gcc-4.8 node_js: - "8" - - "7" - "6" - "4" script: diff --git a/Gruntfile.js b/Gruntfile.js index e12928caf..0dc1fda52 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -41,6 +41,11 @@ module.exports = function(grunt) { core: { src: ["test/_spec.js","test/red/**/*_spec.js"]}, nodes: { src: ["test/nodes/**/*_spec.js"]} }, + webdriver: { + all: { + configFile: 'test/editor/wdio.conf.js' + } + }, mocha_istanbul: { options: { globals: ['expect'], @@ -419,6 +424,7 @@ module.exports = function(grunt) { grunt.loadNpmTasks('grunt-chmod'); grunt.loadNpmTasks('grunt-jsonlint'); grunt.loadNpmTasks('grunt-mocha-istanbul'); + grunt.loadNpmTasks('grunt-webdriver'); grunt.registerMultiTask('attachCopyright', function() { var files = this.data.src; @@ -478,6 +484,10 @@ module.exports = function(grunt) { 'Runs code style check on editor code', ['jshint:editor']); + 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','mocha_istanbul:nodes']); diff --git a/README.md b/README.md index 2ec86ece9..64e191733 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ A visual tool for wiring the Internet of Things. Check out http://nodered.org/docs/getting-started/ for full instructions on getting started. -1. `sudo npm install -g node-red` +1. `sudo npm install -g --unsafe-perm node-red` 2. `node-red` 3. Open diff --git a/editor/icons/sort.png b/editor/icons/sort.png new file mode 100644 index 000000000..f0fb7ead2 Binary files /dev/null and b/editor/icons/sort.png differ diff --git a/editor/js/comms.js b/editor/js/comms.js index 1e5328862..6340deb50 100644 --- a/editor/js/comms.js +++ b/editor/js/comms.js @@ -64,27 +64,31 @@ RED.comms = (function() { } } ws.onmessage = function(event) { - var msg = JSON.parse(event.data); - if (pendingAuth && msg.auth) { - if (msg.auth === "ok") { - pendingAuth = false; - completeConnection(); - } else if (msg.auth === "fail") { - // anything else is an error... - active = false; - RED.user.login({updateMenu:true},function() { - connectWS(); - }) + var message = JSON.parse(event.data); + 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 (msg.auth === "fail") { + // anything else is an error... + active = false; + RED.user.login({updateMenu:true},function() { + connectWS(); + }) + } } - } 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
  • ")+"
  • "; RED.notify(RED._("palette.event.nodeAdded", {count:addedTypes.length})+typeList,"success"); } + loadIconList(); } else if (topic == "notification/node/removed") { for (i=0;i 0 && n.outputLabels && !/^\s*$/.test(n.outputLabels.join(""))) { node.outputLabels = n.outputLabels.slice(); } + if (!n._def.defaults.hasOwnProperty("icon") && n.icon) { + var defIcon = RED.utils.getDefaultNodeIcon(n._def, n); + if (n.icon !== defIcon.module+"/"+defIcon.file) { + node.icon = n.icon; + } + } } return node; } @@ -915,6 +928,7 @@ RED.nodes = (function() { wires:n.wires, inputLabels: n.inputLabels, outputLabels: n.outputLabels, + icon: n.icon, changed:false, _config:{} }; @@ -1273,6 +1287,9 @@ RED.nodes = (function() { enableNodeSet: registry.enableNodeSet, disableNodeSet: registry.disableNodeSet, + setIconSets: registry.setIconSets, + getIconSets: registry.getIconSets, + registerType: registry.registerNodeType, getType: registry.getNodeType, convertNode: convertNode, diff --git a/editor/js/ui/common/typedInput.js b/editor/js/ui/common/typedInput.js index e481c6ef4..304a0da35 100644 --- a/editor/js/ui/common/typedInput.js +++ b/editor/js/ui/common/typedInput.js @@ -99,7 +99,7 @@ this.uiSelect = this.elementDiv.wrap( "
    " ).parent(); var attrStyle = this.element.attr('style'); var m; - if ((m = /width\s*:\s*(\d+(%|px))/i.exec(attrStyle)) !== null) { + if ((m = /width\s*:\s*(calc\s*\(.*\)|\d+(%|px))/i.exec(attrStyle)) !== null) { this.element.css('width','100%'); this.uiSelect.width(m[1]); this.uiWidth = null; @@ -354,10 +354,27 @@ return this.element.val(); } else { if (this.typeMap[this.propertyType].options) { - if (this.typeMap[this.propertyType].options.indexOf(value) === -1) { - value = ""; + var validValue = false; + var label; + for (var i=0;i
    ').appendTo(dialogForm); + var iconDiv = $("#node-settings-icon"); + $('