mirror of
				https://github.com/node-red/node-red.git
				synced 2025-03-01 10:36:34 +00:00 
			
		
		
		
	Compare commits
	
		
			30 Commits
		
	
	
		
			4.0.0-beta
			...
			4752-add-r
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 526b3fda91 | ||
|  | 61b12f6bbe | ||
|  | d71b22412b | ||
|  | e408c6b376 | ||
|  | bf30c24e8e | ||
|  | 6c14ed0ef5 | ||
|  | 6d41ecdae0 | ||
|  | 3f89bc2733 | ||
|  | 87a25df162 | ||
|  | 341f43610a | ||
|  | 67cdf3ef96 | ||
|  | cd98f448e9 | ||
|  | fac79fd068 | ||
|  | da97c5d558 | ||
|  | ae7b9fe62e | ||
|  | e52c2911da | ||
|  | 07a29ff779 | ||
|  | 1b4a8ebe83 | ||
|  | abf2eacf18 | ||
|  | f808f4e2e8 | ||
|  | ca33d6b799 | ||
|  | 940740f15d | ||
|  | 51208fcd0c | ||
|  | 707152d82f | ||
|  | 5538f6dd8a | ||
|  | d601e2caa4 | ||
|  | 46fdf56c79 | ||
|  | 3e6f0acf79 | ||
|  | 7f93d943d7 | ||
|  | 12543d2c2a | 
| @@ -719,6 +719,7 @@ | ||||
|             "nodeHelp": "Node Help", | ||||
|             "showHelp": "Show help", | ||||
|             "showInOutline": "Show in outline", | ||||
|             "hideTopics": "Hide topics", | ||||
|             "showTopics": "Show topics", | ||||
|             "noHelp": "No help topic selected", | ||||
|             "changeLog": "Change Log" | ||||
| @@ -914,6 +915,8 @@ | ||||
|         } | ||||
|     }, | ||||
|     "typedInput": { | ||||
|         "selected": "__count__ selected", | ||||
|         "selected_plural": "__count__ selected", | ||||
|         "type": { | ||||
|             "str": "string", | ||||
|             "num": "number", | ||||
|   | ||||
| @@ -719,6 +719,7 @@ | ||||
|       "nodeHelp": "Aide sur les noeuds", | ||||
|       "showHelp": "Afficher l'aide", | ||||
|       "showInOutline": "Afficher dans les grandes lignes", | ||||
|       "hideTopics": "Masquer les sujets", | ||||
|       "showTopics": "Afficher les sujets", | ||||
|       "noHelp": "Aucune rubrique d'aide sélectionnée", | ||||
|       "changeLog": "Journal des modifications" | ||||
| @@ -914,6 +915,8 @@ | ||||
|     } | ||||
|   }, | ||||
|   "typedInput": { | ||||
|     "selected": "__count__ sélectionnée", | ||||
|     "selected_plural": "__count__ sélectionnées", | ||||
|     "type": { | ||||
|       "str": "chaîne de caractères", | ||||
|       "num": "nombre", | ||||
|   | ||||
| @@ -719,6 +719,7 @@ | ||||
|             "nodeHelp": "ノードヘルプ", | ||||
|             "showHelp": "ヘルプを表示", | ||||
|             "showInOutline": "アウトラインに表示", | ||||
|             "hideTopics": "トピックを非表示", | ||||
|             "showTopics": "トピックを表示", | ||||
|             "noHelp": "ヘルプのトピックが未選択", | ||||
|             "changeLog": "更新履歴" | ||||
|   | ||||
| @@ -736,10 +736,10 @@ | ||||
|                 var selected = {}; | ||||
|                 this.value().split(",").forEach(function(f) { | ||||
|                     selected[f] = true; | ||||
|                  }) | ||||
|                 }); | ||||
|                 menu.find('input[type="checkbox"]').each(function() { | ||||
|                     $(this).prop("checked",selected[$(this).data('value')]) | ||||
|                 }) | ||||
|                     $(this).prop("checked", selected[$(this).data('value')] || false); | ||||
|                 }); | ||||
|             } | ||||
|  | ||||
|  | ||||
| @@ -830,7 +830,7 @@ | ||||
|                         this.input.trigger('change',[this.propertyType,this.value()]); | ||||
|                     } | ||||
|                 } else { | ||||
|                     this.optionSelectLabel.text(o.length+" selected"); | ||||
|                     this.optionSelectLabel.text(RED._("typedInput.selected", { count: o.length })); | ||||
|                 } | ||||
|             } | ||||
|         }, | ||||
|   | ||||
| @@ -631,6 +631,7 @@ RED.deploy = (function() { | ||||
|             // Once deployed, cannot undo back to a clean state | ||||
|             RED.history.markAllDirty(); | ||||
|             RED.view.redraw(); | ||||
|             RED.sidebar.config.refresh(); | ||||
|             RED.events.emit("deploy"); | ||||
|         }).fail(function (xhr, textStatus, err) { | ||||
|             RED.nodes.dirty(true); | ||||
|   | ||||
| @@ -248,6 +248,8 @@ RED.editor = (function() { | ||||
|             var value = input.val(); | ||||
|             if (defaults[property].hasOwnProperty("format") && defaults[property].format !== "" && input[0].nodeName === "DIV") { | ||||
|                 value = input.text(); | ||||
|             } else if (input.attr("type") === "checkbox") { | ||||
|                 value = input.prop("checked"); | ||||
|             } | ||||
|             var valid = validateNodeProperty(node, defaults, property,value); | ||||
|             if (((typeof valid) === "string") || !valid) { | ||||
| @@ -741,9 +743,16 @@ RED.editor = (function() { | ||||
|             } | ||||
|  | ||||
|             try { | ||||
|                 var rc = editing_node._def.oneditsave.call(editing_node); | ||||
|                 const rc = editing_node._def.oneditsave.call(editing_node); | ||||
|                 if (rc === true) { | ||||
|                     editState.changed = true; | ||||
|                 } else if (typeof rc === 'object' && rc !== null ) { | ||||
|                     if (rc.changed === true) { | ||||
|                         editState.changed = true | ||||
|                     } | ||||
|                     if (Array.isArray(rc.history) && rc.history.length > 0) { | ||||
|                         editState.history = rc.history | ||||
|                     } | ||||
|                 } | ||||
|             } catch(err) { | ||||
|                 console.warn("oneditsave",editing_node.id,editing_node.type,err.toString()); | ||||
| @@ -914,6 +923,17 @@ RED.editor = (function() { | ||||
|                             dirty: startDirty | ||||
|                         } | ||||
|  | ||||
|                         if (editing_node.g) { | ||||
|                             const group = RED.nodes.group(editing_node.g); | ||||
|                             // Don't use RED.group.removeFromGroup as that emits | ||||
|                             // a change event on the node - but we're deleting it | ||||
|                             const index = group?.nodes.indexOf(editing_node) ?? -1; | ||||
|                             if (index > -1) { | ||||
|                                 group.nodes.splice(index, 1); | ||||
|                                 RED.group.markDirty(group); | ||||
|                             } | ||||
|                         } | ||||
|  | ||||
|                         RED.nodes.dirty(true); | ||||
|                         RED.view.redraw(true); | ||||
|                         RED.history.push(historyEvent); | ||||
| @@ -1015,7 +1035,7 @@ RED.editor = (function() { | ||||
|                                     } | ||||
|                                 }); | ||||
|                             } | ||||
|                             var historyEvent = { | ||||
|                             let historyEvent = { | ||||
|                                 t:'edit', | ||||
|                                 node:editing_node, | ||||
|                                 changes:editState.changes, | ||||
| @@ -1031,6 +1051,15 @@ RED.editor = (function() { | ||||
|                                     instances:subflowInstances | ||||
|                                 } | ||||
|                             } | ||||
|  | ||||
|                             if (editState.history) { | ||||
|                                 historyEvent = { | ||||
|                                     t: 'multi', | ||||
|                                     events: [ historyEvent, ...editState.history ], | ||||
|                                     dirty: wasDirty | ||||
|                                 } | ||||
|                             } | ||||
|  | ||||
|                             RED.history.push(historyEvent); | ||||
|                         } | ||||
|                         editing_node.dirty = true; | ||||
|   | ||||
| @@ -382,9 +382,11 @@ RED.sidebar.config = (function() { | ||||
|                 refreshConfigNodeList(); | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|         RED.popover.tooltip($('#red-ui-sidebar-config-filter-all'), RED._("sidebar.config.showAllConfigNodes")); | ||||
|         RED.popover.tooltip($('#red-ui-sidebar-config-filter-unused'), RED._("sidebar.config.showAllUnusedConfigNodes")); | ||||
|  | ||||
|         RED.popover.tooltip($('#red-ui-sidebar-config-collapse-all'), RED._("palette.actions.collapse-all")); | ||||
|         RED.popover.tooltip($('#red-ui-sidebar-config-expand-all'), RED._("palette.actions.expand-all")); | ||||
|     } | ||||
|  | ||||
|     function flashConfigNode(el) { | ||||
|   | ||||
| @@ -36,7 +36,13 @@ RED.sidebar.help = (function() { | ||||
|         toolbar = $("<div>", {class:"red-ui-sidebar-header red-ui-info-toolbar"}).appendTo(content); | ||||
|         $('<span class="button-group"><a id="red-ui-sidebar-help-show-toc" class="red-ui-button red-ui-button-small selected" href="#"><i class="fa fa-list-ul"></i></a></span>').appendTo(toolbar) | ||||
|         var showTOCButton = toolbar.find('#red-ui-sidebar-help-show-toc') | ||||
|         RED.popover.tooltip(showTOCButton,RED._("sidebar.help.showTopics")); | ||||
|         RED.popover.tooltip(showTOCButton, function () { | ||||
|             if ($(showTOCButton).hasClass('selected')) { | ||||
|                 return RED._("sidebar.help.hideTopics"); | ||||
|             } else { | ||||
|                 return RED._("sidebar.help.showTopics"); | ||||
|             } | ||||
|         }); | ||||
|         showTOCButton.on("click",function(e) { | ||||
|             e.preventDefault(); | ||||
|             if ($(this).hasClass('selected')) { | ||||
|   | ||||
| @@ -1190,6 +1190,7 @@ RED.view = (function() { | ||||
|  | ||||
|         if (d3.event.button === 1) { | ||||
|             // Middle Click pan | ||||
|             d3.event.preventDefault(); | ||||
|             mouse_mode = RED.state.PANNING; | ||||
|             mouse_position = [d3.event.pageX,d3.event.pageY] | ||||
|             scroll_position = [chart.scrollLeft(),chart.scrollTop()]; | ||||
|   | ||||
| @@ -37,7 +37,6 @@ ul.red-ui-sidebar-node-config-list { | ||||
|     } | ||||
|     .red-ui-palette-node { | ||||
|         // overflow: hidden; | ||||
|         cursor: default; | ||||
|         &.selected { | ||||
|             border-color: transparent; | ||||
|             box-shadow: 0 0 0 2px var(--red-ui-node-selected-color); | ||||
|   | ||||
| @@ -194,27 +194,46 @@ | ||||
|                 nodeMap[node.links[i]].new = true; | ||||
|             } | ||||
|         } | ||||
|         var n; | ||||
|         for (var id in nodeMap) { | ||||
|  | ||||
|         let editHistories = [] | ||||
|         let n; | ||||
|         for (let id in nodeMap) { | ||||
|             if (nodeMap.hasOwnProperty(id)) { | ||||
|                 n = RED.nodes.node(id); | ||||
|                 if (n) { | ||||
|                     editHistories.push({ | ||||
|                         t:'edit', | ||||
|                         node: n, | ||||
|                         changes: { | ||||
|                             links: [...n.links] | ||||
|                         }, | ||||
|                         changed: n.changed | ||||
|                     }) | ||||
|                     if (nodeMap[id].old && !nodeMap[id].new) { | ||||
|                         // Removed id | ||||
|                         i = n.links.indexOf(node.id); | ||||
|                         if (i > -1) { | ||||
|                             n.links.splice(i,1); | ||||
|                             n.changed = true | ||||
|                             n.dirty = true | ||||
|                         } | ||||
|                     } else if (!nodeMap[id].old && nodeMap[id].new) { | ||||
|                         // Added id | ||||
|                         i = n.links.indexOf(id); | ||||
|                         if (i === -1) { | ||||
|                             n.links.push(node.id); | ||||
|                             n.changed = true | ||||
|                             n.dirty = true | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         if (editHistories.length > 0) { | ||||
|             return { | ||||
|                 history: editHistories | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     function onAdd() { | ||||
| @@ -254,13 +273,14 @@ | ||||
|             onEditPrepare(this,"link out"); | ||||
|         }, | ||||
|         oneditsave: function() { | ||||
|             onEditSave(this); | ||||
|             const result = onEditSave(this); | ||||
|             // In case the name has changed, ensure any link call nodes on this | ||||
|             // tab are redrawn with the updated name | ||||
|             var localCallNodes = RED.nodes.filterNodes({z:RED.workspaces.active(), type:"link call"}); | ||||
|             localCallNodes.forEach(function(node) { | ||||
|                 node.dirty = true; | ||||
|             }); | ||||
|             return result | ||||
|         }, | ||||
|         onadd: onAdd, | ||||
|         oneditresize: resizeNodeList | ||||
| @@ -329,7 +349,7 @@ | ||||
|             onEditPrepare(this,"link in"); | ||||
|         }, | ||||
|         oneditsave: function() { | ||||
|             onEditSave(this); | ||||
|             return onEditSave(this); | ||||
|         }, | ||||
|         oneditresize: resizeNodeList | ||||
|     }); | ||||
| @@ -373,7 +393,7 @@ | ||||
|  | ||||
|         }, | ||||
|         oneditsave: function() { | ||||
|             onEditSave(this); | ||||
|             return onEditSave(this); | ||||
|         }, | ||||
|         onadd: onAdd, | ||||
|         oneditresize: resizeNodeList | ||||
|   | ||||
| @@ -462,9 +462,8 @@ function stop(type,diff,muteLog,isDeploy) { | ||||
|     if (type === 'nodes') { | ||||
|         stopList = diff.changed.concat(diff.removed); | ||||
|     } else if (type === 'flows') { | ||||
|         stopList = diff.changed.concat(diff.removed).concat(diff.linked); | ||||
|         stopList = diff.changed.concat(diff.removed).concat(diff.linked).concat(diff.rewired); | ||||
|     } | ||||
|  | ||||
|     events.emit("flows:stopping",{config: activeConfig, type: type, diff: diff}) | ||||
|  | ||||
|     // Stop the global flow object last | ||||
|   | ||||
| @@ -13,7 +13,7 @@ | ||||
| // 4. Edit your settings file to set the theme: | ||||
| //       editorTheme: { | ||||
| //           page: { | ||||
| //               css: "/path/to/file/generated/by/this/script" | ||||
| //               css: '/path/to/file/generated/by/this/script' | ||||
| //           } | ||||
| //       } | ||||
| // | ||||
| @@ -22,110 +22,69 @@ | ||||
|  | ||||
|  | ||||
|  | ||||
| const os = require("os"); | ||||
| const nopt = require("nopt"); | ||||
| const path = require("path"); | ||||
| const fs = require("fs-extra"); | ||||
| const sass = require("sass"); | ||||
| const os = require('os'); | ||||
| const nopt = require('nopt'); | ||||
| const path = require('path'); | ||||
| const fs = require('fs-extra'); | ||||
| const sass = require('sass'); | ||||
|  | ||||
| const knownOpts = { | ||||
|     "help": Boolean, | ||||
|     "long": Boolean, | ||||
|     "in": [path], | ||||
|     "out": [path] | ||||
|     'help': Boolean, | ||||
|     'long': Boolean, | ||||
|     'in': [path], | ||||
|     'out': [path] | ||||
| }; | ||||
| const shortHands = { | ||||
|     "?":["--help"] | ||||
|     '?':['--help'] | ||||
| }; | ||||
| nopt.invalidHandler = function(k,v,t) {} | ||||
|  | ||||
| const parsedArgs = nopt(knownOpts,shortHands,process.argv,2) | ||||
|  | ||||
| if (parsedArgs.help) { | ||||
|     console.log("Usage: build-custom-theme [-?] [--in FILE] [--out FILE]"); | ||||
|     console.log(""); | ||||
|     console.log("Options:"); | ||||
|     console.log("  --in  FILE  Custom colors sass file"); | ||||
|     console.log("  --out FILE  Where you write the result"); | ||||
|     console.log("  --long      Do not compress the output"); | ||||
|     console.log("  -?, --help  Show this help"); | ||||
|     console.log(""); | ||||
|     process.exit(); | ||||
|     showUsageAndExit(0) | ||||
| } | ||||
|  | ||||
|  | ||||
| const ruleRegex = /(\$.*?) *: *(\S[\S\s]*?);/g; | ||||
| var match; | ||||
|  | ||||
| const customColors = {}; | ||||
|  | ||||
| if (parsedArgs.in && fs.existsSync(parsedArgs.in)) { | ||||
|     let customColorsFile = fs.readFileSync(parsedArgs.in,"utf-8"); | ||||
|     while((match = ruleRegex.exec(customColorsFile)) !== null) { | ||||
|         customColors[match[1]] = match[2]; | ||||
| if (!parsedArgs.in) { | ||||
|     console.warn('Missing argument: in') | ||||
|     showUsageAndExit(1) | ||||
| } | ||||
| } | ||||
|  | ||||
| // Load base colours | ||||
| let colorsFile = fs.readFileSync(path.join(__dirname,"../packages/node_modules/@node-red/editor-client/src/sass/colors.scss"),"utf-8") | ||||
| let updatedColors = []; | ||||
|  | ||||
| while((match = ruleRegex.exec(colorsFile)) !== null) { | ||||
|     updatedColors.push(match[1]+": "+(customColors[match[1]]||match[2])+";") | ||||
| } | ||||
|  | ||||
|  | ||||
| (async function() { | ||||
|     const tmpDir = os.tmpdir(); | ||||
|     const workingDir = await fs.mkdtemp(`${tmpDir}${path.sep}`); | ||||
|     await fs.copy(path.join(__dirname,"../packages/node_modules/@node-red/editor-client/src/sass/"),workingDir) | ||||
|     await fs.writeFile(path.join(workingDir,"colors.scss"),updatedColors.join("\n")) | ||||
|  | ||||
|     const result = sass.renderSync({ | ||||
|         outputStyle: "expanded", | ||||
|         file: path.join(workingDir,"style-custom-theme.scss"), | ||||
|     }); | ||||
|     await fs.copy(path.join(__dirname, '../packages/node_modules/@node-red/editor-client/src/sass/'), workingDir); | ||||
|     await fs.copyFile(parsedArgs.in, path.join(workingDir,'colors.scss')); | ||||
|  | ||||
|     const css = result.css.toString() | ||||
|     const lines = css.split("\n"); | ||||
|     const colorCSS = [] | ||||
|     const nonColorCSS = []; | ||||
|     const output = sass.compile( | ||||
|         path.join(workingDir, 'style-custom-theme.scss'), | ||||
|         {style: parsedArgs.long === true ? 'expanded' : 'compressed'} | ||||
|     ); | ||||
|  | ||||
|     let inKeyFrameBlock = false; | ||||
|  | ||||
|     lines.forEach(l => { | ||||
|         if (inKeyFrameBlock) { | ||||
|             nonColorCSS.push(l); | ||||
|             if (/^}/.test(l)) { | ||||
|                 inKeyFrameBlock = false; | ||||
|             } | ||||
|         } else if (/^@keyframes/.test(l)) { | ||||
|             nonColorCSS.push(l); | ||||
|             inKeyFrameBlock = true; | ||||
|         } else if (!/^  /.test(l)) { | ||||
|             colorCSS.push(l); | ||||
|             nonColorCSS.push(l); | ||||
|         } else if (/color|border|background|fill|stroke|outline|box-shadow/.test(l)) { | ||||
|             colorCSS.push(l); | ||||
|         } else { | ||||
|             nonColorCSS.push(l); | ||||
|         } | ||||
|     }); | ||||
|  | ||||
|     const nrPkg = require("../package.json"); | ||||
|     const nrPkg = require('../package.json'); | ||||
|     const now = new Date().toISOString(); | ||||
|     const header = `/*\n* Theme generated with Node-RED ${nrPkg.version} on ${now}\n*/`; | ||||
|  | ||||
|     const header = `/* | ||||
|     * Theme generated with Node-RED ${nrPkg.version} on ${now} | ||||
|     */`; | ||||
|  | ||||
|     var output = sass.renderSync({outputStyle: parsedArgs.long?"expanded":"compressed",data:colorCSS.join("\n")}); | ||||
|     if (parsedArgs.out) { | ||||
|  | ||||
|         await fs.writeFile(parsedArgs.out,header+"\n"+output.css); | ||||
|         await fs.writeFile(parsedArgs.out, header+'\n'+output.css); | ||||
|     } else { | ||||
|         console.log(header); | ||||
|         console.log(output.css.toString()); | ||||
|     } | ||||
|  | ||||
|     await fs.remove(workingDir); | ||||
| })() | ||||
|  | ||||
| function showUsageAndExit (exitCode) { | ||||
|     console.log(''); | ||||
|     console.log('Usage: build-custom-theme [-?] [--in FILE] [--out FILE]'); | ||||
|     console.log(''); | ||||
|     console.log('Options:'); | ||||
|     console.log('  --in  FILE  Custom colors sass file'); | ||||
|     console.log('  --out FILE  Where you write the result'); | ||||
|     console.log('  --long      Do not compress the output'); | ||||
|     console.log('  -?, --help  Show this help'); | ||||
|     console.log(''); | ||||
|     process.exit(exitCode); | ||||
| } | ||||
		Reference in New Issue
	
	Block a user